Commit ·
2efa78b
0
Parent(s):
Duplicate from cocktailpeanut/muscriptor-small
Browse filesCo-authored-by: cocktail peanut <cocktailpeanut@users.noreply.huggingface.co>
- .gitattributes +35 -0
- README.md +163 -0
- config.json +8 -0
- model.safetensors +3 -0
.gitattributes
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
README.md
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: cc-by-nc-4.0
|
| 3 |
+
library_name: muscriptor
|
| 4 |
+
tags:
|
| 5 |
+
- music
|
| 6 |
+
- music-transcription
|
| 7 |
+
- automatic-music-transcription
|
| 8 |
+
- amt
|
| 9 |
+
- audio-to-midi
|
| 10 |
+
- midi
|
| 11 |
+
- music-information-retrieval
|
| 12 |
+
- transformer
|
| 13 |
+
- pytorch
|
| 14 |
+
---
|
| 15 |
+
|
| 16 |
+
# MuScriptor — small (≈100M)
|
| 17 |
+
|
| 18 |
+
**MuScriptor** is an open-weight model for **general-purpose, multi-instrument automatic music transcription (AMT)**: it converts a music recording (any genre, multiple simultaneous instruments) into a stream of notes played. This repository hosts the **small** variant (≈100M parameters), the fastest and most lightweight checkpoint.
|
| 19 |
+
|
| 20 |
+
`muscriptor-small` is the smallest/fastest option, suitable for lower-resource settings. For higher quality use [`muscriptor-medium`](https://huggingface.co/MuScriptor/muscriptor-medium) (≈300M, good trade-off) or [`muscriptor-large`](https://huggingface.co/MuScriptor/muscriptor-large) (≈1.3B, best quality).
|
| 21 |
+
|
| 22 |
+
- Developed by [Mirelo](https://www.mirelo.ai/) x [kyutai](https://kyutai.org/)
|
| 23 |
+
- 📄 Paper: *MuScriptor: An Open Model for Multi-Instrument Music Transcription* — Rouard, Krause, Roebel, Simon-Gabriel, Défossez (2026). _<!-- TODO: add arXiv link once public; it will auto-cross-link on the Hub -->_
|
| 24 |
+
- 💻 Code: <https://github.com/muscriptor/muscriptor>
|
| 25 |
+
- 🔊 Audio samples: <https://muscriptor.github.io>
|
| 26 |
+
|
| 27 |
+
## Table of contents
|
| 28 |
+
|
| 29 |
+
- [Quickstart](#quickstart)
|
| 30 |
+
- [Model description](#model-description)
|
| 31 |
+
- [Model variants](#model-variants)
|
| 32 |
+
- [Intended uses & limitations](#intended-uses--limitations)
|
| 33 |
+
- [Instrument conditioning](#instrument-conditioning)
|
| 34 |
+
- [Training](#training)
|
| 35 |
+
- [Evaluation](#evaluation)
|
| 36 |
+
- [Citation](#citation)
|
| 37 |
+
- [License](#license)
|
| 38 |
+
|
| 39 |
+
## Quickstart
|
| 40 |
+
|
| 41 |
+
Install the `muscriptor` package (it uses `huggingface_hub` to fetch weights automatically):
|
| 42 |
+
|
| 43 |
+
```bash
|
| 44 |
+
pip install git+https://github.com/muscriptor/muscriptor.git
|
| 45 |
+
# TODO (PyPI release forthcoming: pip install muscriptor)
|
| 46 |
+
```
|
| 47 |
+
|
| 48 |
+
### Python
|
| 49 |
+
|
| 50 |
+
```python
|
| 51 |
+
from pathlib import Path
|
| 52 |
+
from muscriptor import TranscriptionModel
|
| 53 |
+
|
| 54 |
+
# "small" resolves to hf://MuScriptor/muscriptor-small and downloads on first use.
|
| 55 |
+
model = TranscriptionModel.load_model("small")
|
| 56 |
+
|
| 57 |
+
# Get a MIDI file directly:
|
| 58 |
+
Path("out.mid").write_bytes(model.transcribe_to_midi("audio.wav"))
|
| 59 |
+
|
| 60 |
+
# Or stream note events as they are transcribed:
|
| 61 |
+
for event in model.transcribe("audio.wav"):
|
| 62 |
+
print(event) # NoteStartEvent / NoteEndEvent / ProgressEvent
|
| 63 |
+
```
|
| 64 |
+
|
| 65 |
+
`load_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.
|
| 66 |
+
|
| 67 |
+
### CLI
|
| 68 |
+
|
| 69 |
+
```bash
|
| 70 |
+
muscriptor transcribe --model small audio.wav -o out.mid
|
| 71 |
+
```
|
| 72 |
+
|
| 73 |
+
## Model description
|
| 74 |
+
|
| 75 |
+
MuScriptor performs transcription by **autoregressively predicting a MIDI-like token sequence** given the mel-spectrogram of a short audio segment, following the sequence-to-sequence AMT paradigm (cf. MT3). It deliberately avoids complex architectural tweaks in favor of a simple, decoder-only Transformer.
|
| 76 |
+
|
| 77 |
+
- **Architecture:** decoder-only Transformer (this variant: `dim=768`, `num_heads=12`, `num_layers=14`).
|
| 78 |
+
- **Input:** raw waveform (16 kHz, mono) of a 5-second segment → mel-spectrogram (STFT `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.
|
| 79 |
+
- **Output tokenization:** MT3-like note events; the 128 MIDI programs are mapped to **36 instrument subgroups** using the `MT3_FULL_PLUS` taxonomy. Decoding is greedy (argmax) by default, with optional classifier-free guidance (CFG).
|
| 80 |
+
- **Inference:** audio is processed in 5-second chunks; note events are emitted in temporal order. Optional **instrument conditioning** stabilizes predictions across chunk boundaries and lets you restrict/customize the transcription (see below).
|
| 81 |
+
|
| 82 |
+
**Note on the representation:** the tokenizer recovers onset/offset timing, pitch, and instrument, but **not velocity**. It also cannot represent two notes of the same pitch and instrument sounding at the same time. Drums are onset-only.
|
| 83 |
+
|
| 84 |
+
## Model variants
|
| 85 |
+
|
| 86 |
+
| Repo | Params | `dim` | heads | layers | Notes |
|
| 87 |
+
|---|---|---|---|---|---|
|
| 88 |
+
| [`muscriptor-small`](https://huggingface.co/MuScriptor/muscriptor-small) | ≈100M | 768 | 12 | 14 | **this model** · smallest / fastest |
|
| 89 |
+
| [`muscriptor-medium`](https://huggingface.co/MuScriptor/muscriptor-medium) | ≈300M | 1024 | 16 | 24 | good trade-off |
|
| 90 |
+
| [`muscriptor-large`](https://huggingface.co/MuScriptor/muscriptor-large) | ≈1.3B | 1536 | 24 | 48 | best quality |
|
| 91 |
+
|
| 92 |
+
All variants share the same input pipeline, tokenizer, and training recipe; they differ only in latent dimension, attention heads, and depth.
|
| 93 |
+
|
| 94 |
+
## Intended uses & limitations
|
| 95 |
+
|
| 96 |
+
**Intended uses**
|
| 97 |
+
- General-purpose transcription of real, multi-instrument music across genres (classical → heavy metal) into MIDI.
|
| 98 |
+
- A building block for music information retrieval (chord/key recognition), musicological analysis, generative-modeling data pipelines, and tools for musicians.
|
| 99 |
+
- Lower-resource / latency-sensitive settings where the larger variants are too heavy.
|
| 100 |
+
|
| 101 |
+
**Out of scope / use with care**
|
| 102 |
+
- Not a substitute for a hand-annotated score; expect errors, especially on dense mixes, unusual timbres, and heavily processed audio.
|
| 103 |
+
- Velocity/dynamics are **not** produced (see note above).
|
| 104 |
+
- Onset/offset precision is lower for some styles (e.g. choral music), and exact offsets are inherently harder than onsets.
|
| 105 |
+
- Being the smallest variant, it trades transcription accuracy for speed and footprint relative to `medium`/`large`.
|
| 106 |
+
|
| 107 |
+
**Limitations & biases**
|
| 108 |
+
- Training data skews toward pop and Western classical music, and the instrument distribution is long-tailed (piano/guitar/bass/drums are most frequent). Rare instruments and underrepresented genres may be transcribed less reliably.
|
| 109 |
+
- The fixed `MT3_FULL_PLUS` 36-group instrument taxonomy limits instrument granularity.
|
| 110 |
+
- Simultaneous same-pitch/same-instrument notes cannot be represented by the tokenizer.
|
| 111 |
+
|
| 112 |
+
## Instrument conditioning
|
| 113 |
+
|
| 114 |
+
The model can be told which instrument groups are present in the track. Supplying the correct set improves quantitative scores and produces more coherent instrument assignments across segments.
|
| 115 |
+
|
| 116 |
+
```python
|
| 117 |
+
from muscriptor.tokenizer.mt3 import MT3_FULL_PLUS_GROUP_NAMES
|
| 118 |
+
|
| 119 |
+
# `instrument_group` is a space-separated string of MT3_FULL_PLUS group IDs.
|
| 120 |
+
# Convert readable group names to IDs:
|
| 121 |
+
names = ["acoustic_piano", "acoustic_guitar", "acoustic_bass"]
|
| 122 |
+
instrument_group = " ".join(str(MT3_FULL_PLUS_GROUP_NAMES[n]) for n in names) # -> "0 4 7"
|
| 123 |
+
|
| 124 |
+
# Only expect piano, acoustic guitar and bass in this track:
|
| 125 |
+
model.transcribe_to_midi("audio.wav", instrument_group=instrument_group)
|
| 126 |
+
```
|
| 127 |
+
|
| 128 |
+
```bash
|
| 129 |
+
muscriptor transcribe --model small --instruments "acoustic_piano,acoustic_guitar,acoustic_bass" audio.wav -o out.mid
|
| 130 |
+
muscriptor list-instruments # show all available group names
|
| 131 |
+
```
|
| 132 |
+
|
| 133 |
+
## Evaluation
|
| 134 |
+
|
| 135 |
+
Metrics are instrument-agnostic F1 scores computed with [`mir_eval`](https://github.com/craffel/mir_eval) on `D_Test`, the authors' held-out test set of 372 multi-instrument tracks.
|
| 136 |
+
|
| 137 |
+
**Model-size comparison** (F1 ↑; from the paper's scaling study, models trained on `D_Real` only, CFG = 2):
|
| 138 |
+
|
| 139 |
+
| Variant | Params | Onset | Frame | Offset | Drums | Multi |
|
| 140 |
+
|---|---|---|---|---|---|---|
|
| 141 |
+
| **`muscriptor-small`** | **100M** | **51.2** | **67.2** | **38.7** | **41.5** | **38.2** |
|
| 142 |
+
| `muscriptor-medium` | 300M | 52.4 | 68.0 | 40.3 | 42.0 | 39.7 |
|
| 143 |
+
| `muscriptor-large` | 1.3B | 53.2 | 68.7 | 41.0 | 42.5 | 40.5 |
|
| 144 |
+
|
| 145 |
+
These numbers come from the model-size ablation, which trains on real audio **only**. The **released checkpoints additionally use synthetic pre-training and RL post-training**, which improve real-world quality substantially beyond these figures. See [`muscriptor-large`](https://huggingface.co/MuScriptor/muscriptor-large) and the paper for per-dataset results.
|
| 146 |
+
|
| 147 |
+
## Citation
|
| 148 |
+
|
| 149 |
+
```bibtex
|
| 150 |
+
@inproceedings{muscriptor2026,
|
| 151 |
+
title = {MuScriptor: An Open Model for Multi-Instrument Music Transcription},
|
| 152 |
+
author = {Rouard, Simon and Krause, Michael and Roebel, Axel and
|
| 153 |
+
Simon-Gabriel, Carl-Johann and D{\'e}fossez, Alexandre},
|
| 154 |
+
year = {2026},
|
| 155 |
+
note = {Kyutai, Mirelo AI, IRCAM}
|
| 156 |
+
}
|
| 157 |
+
```
|
| 158 |
+
|
| 159 |
+
<!-- TODO: replace with the final published citation (venue / arXiv id) once available. -->
|
| 160 |
+
|
| 161 |
+
## License
|
| 162 |
+
|
| 163 |
+
Code released under the [MIT License](https://github.com/muscriptor/muscriptor/blob/main/LICENSE). Weights released under CC-BY-NC.
|
config.json
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"model_type": "muscriptor",
|
| 3 |
+
"variant": "small",
|
| 4 |
+
"dim": 768,
|
| 5 |
+
"num_heads": 12,
|
| 6 |
+
"num_layers": 14,
|
| 7 |
+
"card": 1393
|
| 8 |
+
}
|
model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:bbd482c786b895cf7d8f44185073d951adae2ebb8a66f82ca84cd1f84569549c
|
| 3 |
+
size 411888600
|