Views
No views yet
muscriptor library.muscriptor-medium balances quality and footprint. For the best transcription quality use muscriptor-large (≈1.3B); for the smallest/fastest option use muscriptor-small (≈100M).muscriptor package (it uses huggingface_hub to fetch weights automatically):1pip install git+https://github.com/muscriptor/muscriptor.git
2# TODO (PyPI release forthcoming: pip install muscriptor)1from pathlib import Path
2from muscriptor import TranscriptionModel
3
4# "medium" resolves to hf://MuScriptor/muscriptor-medium and downloads on first use.
5model = TranscriptionModel.load_model("medium")
6
7# Get a MIDI file directly:
8Path("out.mid").write_bytes(model.transcribe_to_midi("audio.wav"))
9
10# Or stream note events as they are transcribed:
11for event in model.transcribe("audio.wav"):
12 print(event) # NoteStartEvent / NoteEndEvent / ProgressEventload_model accepts a size keyword ("small"/"medium"/"large"), a local .safetensors path, or an hf:// / https:// URL. Weights loaded by size keyword (or any hf:// URL) are cached in the standard Hugging Face cache (~/.cache/huggingface/hub, configurable via HF_HOME); weights fetched from a plain http(s):// URL are cached under ~/.cache/muscriptor/. Input audio can be WAV or any format libsndfile reads (mp3, flac, ogg, m4a, …); it is resampled to 16 kHz mono internally.muscriptor transcribe --model medium audio.wav -o out.middim=1024, num_heads=16, num_layers=24).n_fft=2048, hop 160 → 100 Hz frame rate, 512 mel bins). The spectrogram is projected to the model dimension and used as a prefix condition.MT3_FULL_PLUS taxonomy. Decoding is greedy (argmax) by default, with optional classifier-free guidance (CFG).| Repo | Params | dim | heads | layers | Notes |
|---|---|---|---|---|---|
muscriptor-small | ≈100M | 768 | 12 | 14 | smallest / fastest |
muscriptor-medium | ≈300M | 1024 | 16 | 24 | this model · good trade-off |
muscriptor-large | ≈1.3B | 1536 | 24 | 48 | best quality |
MT3_FULL_PLUS 36-group instrument taxonomy limits instrument granularity.1from muscriptor.tokenizer.mt3 import MT3_FULL_PLUS_GROUP_NAMES
2
3# `instrument_group` is a space-separated string of MT3_FULL_PLUS group IDs.
4# Convert readable group names to IDs:
5names = ["acoustic_piano", "acoustic_guitar", "acoustic_bass"]
6instrument_group = " ".join(str(MT3_FULL_PLUS_GROUP_NAMES[n]) for n in names) # -> "0 4 7"
7
8# Only expect piano, acoustic guitar and bass in this track:
9model.transcribe_to_midi("audio.wav", instrument_group=instrument_group)1muscriptor transcribe --model medium --instruments "acoustic_piano,acoustic_guitar,acoustic_bass" audio.wav -o out.mid
2muscriptor list-instruments # show all available group namesmir_eval on D_Test, the authors' held-out test set of 372 multi-instrument tracks.D_Real only, CFG = 2):| Variant | Params | Onset | Frame | Offset | Drums | Multi |
|---|---|---|---|---|---|---|
muscriptor-small | 100M | 51.2 | 67.2 | 38.7 | 41.5 | 38.2 |
muscriptor-medium | 300M | 52.4 | 68.0 | 40.3 | 42.0 | 39.7 |
muscriptor-large | 1.3B | 53.2 | 68.7 | 41.0 | 42.5 | 40.5 |
muscriptor-large and the paper for per-dataset results.1@inproceedings{muscriptor2026,
2 title = {MuScriptor: An Open Model for Multi-Instrument Music Transcription},
3 author = {Rouard, Simon and Krause, Michael and Roebel, Axel and
4 Simon-Gabriel, Carl-Johann and D{\'e}fossez, Alexandre},
5 year = {2026},
6 note = {Kyutai, Mirelo AI, IRCAM}
7}