musicar-L

A 464M-parameter autoregressive transformer that writes multi-instrument MIDI one note at a time, pretrained on 8.3B notes of public MIDI data.

Parameters Context Instruments Training notes License
464.24M 2,048 notes 129 (128 General MIDI programs + drums) 8.3B (GigaMIDI, Aria-MIDI, Discover MIDI) CC BY-NC-SA 4.0

Architecture of musicar-L

Model summary

musicar-L is the project's pretrained multi-instrument model. Each sequence position is one whole note, and five cascade output heads choose its time shift, instrument, pitch, duration and velocity one after another. It is a pretrained model only: it has no text captions, and besides a MIDI prompt its only controls are two optional window conditions (the set of instruments and the notes per second). It is the base of the project's captioned model, musicar-L-caption.

Smaller bases of the same family: musicar-S-piano and musicar-S.

Model details

Developed by Dmytro Hilei
Model type Decoder-only transformer, autoregressive over notes (symbolic music, MIDI)
Parameters 464.24M: trunk 445.98M, cascade heads 16.28M, embeddings 1.99M
Architecture 28 pre-norm blocks, width 1152: RMSNorm → causal self-attention (18 heads × 64, full attention; Q, K, V from one Linear 1152 → 3456; QK-norm = RMSNorm over each head's queries and keys; RoPE; output Linear 1152 → 1152) → residual add; RMSNorm → SwiGLU feed-forward (gate and up 1152 → 3072, down 3072 → 1152) → residual add; final RMSNorm. Five cascade output heads: Δt → instrument → pitch → duration → velocity
Cascade heads Head i reads a running state z₀ = h_t (the trunk state), z_i = z_{i−1} + E_i(a_i), where E_i embeds the value chosen by head i (tables of 512, 129, 130 and 512 rows × 1152; the last head needs none); each head is LayerNorm → Linear 1152 → 1152 → GELU → Linear 1152 → 1152 (+ residual) → LayerNorm → Linear 1152 → V. a_i is the true value in training (teacher forcing) and the sampled value in generation
Tokenization One compound token per note on a 20 ms grid: delta-time = time since the previous note's onset (512 steps of 20 ms), instrument (129), pitch (130: 128 MIDI pitches + BOS + EOS), duration (512 steps of 20 ms), velocity (32 levels); delta-time and duration are clipped at 10.22 s. The notes of all tracks are merged into one sequence in onset order; a drum note's pitch is the drum sound. No bar, beat or tempo tokens
Input embedding Pitch, velocity, duration and delta-time tables of width 288 (130, 32, 512 and 512 rows), concatenated (1152) → Linear 1152 → 1152; an instrument table (129 × 1152) added per note; the optional window conditions added at every position: the window's instrument set (129-dim multi-hot → Linear 129 → 1152) and its notes per second (a table of 16 rows: 15 levels + "none")
Instruments 129: the 128 General MIDI programs + drums
Context 2,048 notes (about 1–4 minutes of music)
Positions RoPE (rotary position embedding, base 10,000) in every attention layer; no position table
Special tokens, conditions BOS / EOS (pitch values 128 / 129) mark the start and end of a piece; window conditions as above, "none" = unconditional
Precision of the weights bfloat16
License CC BY-NC-SA 4.0
Code https://github.com/DmytroHilei/Music_generative_model

How to use

From a clone of the code repository, with its environment installed (README, "Setup"):

hf download Dimitri-206265/musicar-L --local-dir checkpoints/musicar-L
.venv/bin/python generate.py --checkpoint checkpoints/musicar-L/model_bf16.pt --sample-instruments \
    --max-new-tokens 1000 --output samples/musicar-L.mid

One token is one note, so this writes up to 1,000 new notes, starting from the start-of-piece token (BOS); if the model ends the piece earlier, the output stops at its EOS (--min-notes forbids an early end). --sample-instruments lets the instrument head choose each note's instrument; without it every note is piano. --instruments limits the choice (a list of General MIDI programs such as 0,33,25,128, where 128 = drums, or prompt = the prompt's own instruments) and --instrument-temperature sets a separate temperature for it. --prompt file.mid continues the first --prompt-notes notes (default 64) of a MIDI file. The window conditions are set with --cond-instruments (a program list, prompt or none; by default the prompt's instruments when the prompt has them, else none) and --cond-density (notes per second, prompt or none, the default). Sampling: --temperature (default 0.85), --top-k, --top-p. Past 2,048 notes the KV cache is rebuilt from the most recent notes every --slide notes (default 512). generate.py also renders an MP3 unless --no-mp3 is given (needs fluidsynth, ffmpeg and a General MIDI soundfont).

Loading the pickle-free files directly:

import json
from safetensors.torch import load_file
from musicar.model.gpt import GPT, MusicConfig

cfg = json.load(open("checkpoints/musicar-L/config.json"))
model = GPT(MusicConfig(**cfg["model_args"]))
model.load_state_dict(load_file("checkpoints/musicar-L/model.safetensors"))
model.eval()

MusicConfig defaults to training settings (dropout 0.2), so call model.eval() before inference; musicar.model.checkpoint.load_model does this for model_bf16.pt. Sampling with the KV cache is musicar.generation.sampling.generate.

Intended use

  • Research on symbolic music generation: multi-instrument modelling, sampling, conditioning.
  • Continuing a MIDI prompt (piano or multi-instrument), or generating from the start token.
  • A base for fine-tuning: the project's fine-tunes on Ukrainian songs (piano arrangements and multi-track) start from it, and so does the captioned model musicar-L-caption.

Out of scope:

  • Commercial use (see License).
  • Text-conditioned generation: this checkpoint has no caption input; musicar-L-caption adds one.
  • Audio: the model reads and writes MIDI notes, not sound.

Training data

Dataset Sampling weight What it is License note
GigaMIDI (arXiv:2502.17726) 0.4 Large web collection of multi-track MIDI (its own training split) Non-commercial (the project's notes list CC BY-NC 4.0); check GigaMIDI's own terms (Hugging Face Metacreation/GigaMIDI)
Aria-MIDI, deduplicated (arXiv:2504.15071) 0.3 Piano transcriptions from recordings; its notes enter as piano CC BY-NC-SA 4.0 (non-commercial)
Discover MIDI (Hugging Face) 0.3 Large MIDI collection, deduplicated against GigaMIDI and within itself CC BY-NC-SA (non-commercial)

Each training window of 2,048 notes is drawn from one dataset by these weights. BOS / EOS mark where pieces start and end, and pieces shorter than a window share windows. Pitches are transposed at random by up to ±5 semitones (drums are not transposed). The run saw 8.3B notes, about 1.8 passes over the data on average (about 4.5 over Aria-MIDI). None of the project's audio-derived transcriptions of Ukrainian songs were used.

Training procedure

Initialization From scratch
Steps 126,582
Batch 65,536 notes per step (32 windows × 2,048 notes)
Notes seen 8.3B (≈ 1.8 epochs on average; Aria-MIDI ≈ 4.5)
Data mix GigaMIDI 0.4, Aria-MIDI 0.3, Discover MIDI 0.3
Objective Sum of the five cross-entropies (Δt, instrument, pitch, duration, velocity), teacher forcing
Optimizer Muon (Moonlight scaling, momentum 0.95) for the weight matrices of the transformer blocks, AdamW (β 0.9, 0.95) for the rest; one learning rate for both; weight decay 0.1; gradient clipping 1.0
Learning rate 10⁻³, WSD schedule: 1,000 warmup steps, constant, then 1 − √ decay to 0 over the last 20% of the steps
Regularization Dropout 0, label smoothing 0; both window conditions replaced by "none" in 15% of the windows, so "none" stays usable
Precision bf16 autocast with fp8 (torchao float8) matmuls in the transformer blocks, torch.compile; the checkpoint holds bf16 weights
Hardware, time One rented RTX 5090, about 41 h
Config config/pretrain/long_450m.py (launched through cloud/run/launch.sh)

Evaluation

Metric: teacher-forced next-note cross-entropy on held-out validation windows of 2,048 notes, in nats per note, summed over the four note attributes (Δt, pitch, duration, velocity); the instrument head's cross-entropy is reported separately. Lower is better. It measures how well the model predicts real music, not how good its samples sound; it is not a listening test. One run.

Validation set: clean GigaMIDI validation, i.e. GigaMIDI's validation split without the files whose notes also occur in its training split. The window conditions are measured on each validation window.

Clean GigaMIDI validation Cross-entropy (nats / note)
First evaluation (step 2,000, 0.13B notes) 2.807
Step 100,000, just before the cooldown 1.876
End of training (8.3B notes) 1.679 (Δt 0.170, pitch 0.367, duration 0.644, velocity 0.497)
End of training, both window conditions "none" 1.681
Instrument head, end of training 0.117

The diagram (section 6) shows every evaluation of the run, one every 2,000 steps.

Comparison with other open models

What was found and tested

The project's evidence sheet (findings.tex in the code repository): the comparison below is its section 1.

Every system wrote MIDI for one frozen prompt set, and every file was read back from the MIDI and scored the same way, per note and per second (never per token), with each model at its authors' sampling settings. Code: eval/compare/head2head.py and eval/compare/h2h_baselines/ in the code repository. One seed per system.

Continuation of real multi-instrument music (32 clean GigaMIDI validation prompts of 128 notes with at least 3 instruments; up to 1,000 new notes each, the first 1,000 scored, a continuation that ends sooner scored as it is). D = weighted gap in six row statistics of density and instrument use (one instrument taking over, top-instrument share, notes per second 0.20 each; out-of-band instruments, instrument count 0.15 each; runaway 0.10) to the real continuations of the same files, each divided by the real rows' spread (with a floor); lower = closer to the real continuations on these statistics. Runaway = share of rows above 40 notes per second. The last column scores the first 200 new notes only:

System Parameters Notes / s Instruments Runaway D D, first 200 notes
Real continuation 24.0 7.7 0.16 0 0
musicar-L (temperature 0.9) 464M 23.5 6.9 0.13 0.121 0.090
musicar-L-caption (no caption) 477M 12.8 7.8 0.06 0.218 0.198
Anticipatory Music Transformer, large (arXiv:2306.08620) 780M 21.2 7.4 0.06 0.289 0.239
SkyTNT midi-model tv2o-medium 234M 22.9 5.3 0.16 0.314 0.184
Music-Llama (SkyTNT architecture) 457M 28.9 5.7 0.25 0.357 0.218
Moonbeam (arXiv:2505.15559), temperature 0.9, top-p 0.95 (its README) 839M 49.5 8.9 0.31 0.703 0.322
Moonbeam, temperature 0.6, top-p 0.9 (its completion example) 839M 85.9 5.3 0.06 1.316 0.525

Moonbeam's context (1,024 notes) is shorter than prompt + continuation; past it the harness restarts its window on the last 768 notes (the head-to-head's scheme, not the authors'). At temperature 0.9 its notes per second climb inside the first window, before any restart: rows above 40 notes per second are 16% over its first 200 new notes and 46% over new notes 447-894 (real continuations 13% and 18%). At 0.6 the density stays flat except in 2 files that stack notes on one onset (most of its mean), and it repeats itself more: 46% of its new pitched notes sit inside exact copies of 16 or more chords (real continuations 5%). Over the first 200 notes every model is closer to the real continuations; SkyTNT, Music-Llama and Moonbeam gain most.

Solo-piano continuation (32 prompts from the project's held-out split of Aria-MIDI, which Aria may have seen in training; up to 1,000 new notes each, the real continuations all 1,000 long). With one instrument, D here measures only how close the note rate is to the real one (and runaway):

System Parameters Notes / s Runaway D D, first 200 notes
Real continuation 7.95 0 0 0
musicar-L (temperature 0.9) 464M 8.95 0 0.040 0.019
Aria medium, continuation weights (arXiv:2506.23869) 659M 9.99 0.03 0.096 0.067

On the same prompts the project's 108M piano-cover fine-tune (not released) is closer still in note rate (D 0.018; 0.006 over the first 200 notes); its 450M piano-cover fine-tune of this model (not released), which writes short covers that end, is further (0.177; 0.078).

Limitations and biases

  • The data lean toward Western popular and classical music in General MIDI instrumentation; other traditions, and instruments outside General MIDI, are thin or missing.
  • GigaMIDI is collected from the web, so its quality varies, and the model learns from all of it.
  • Aria-MIDI is transcribed from recordings, so it contains transcription errors (missed, extra or mistimed notes), which the model learns as if they were music.
  • Control is limited to the prompt and the two window conditions (instrument set, notes per second): no control of genre, mood or form, and no text input.
  • Long pieces lose structure: past 2,048 notes the window slides and earlier material leaves the context, and time is absolute (no bars or beats).
  • Sampling can run away into very dense passages: when continuing 12 Ukrainian songs (one seed; temperature 0.9, top-p 0.9, Δt bias 0.1, conditioned on the prompt's instruments), 3 of the 12 continuations reached 45 to 179 notes per second.
  • Only notes are modelled: no tempo, pedal or other controller events; velocity has 32 levels and time a 20 ms grid.
  • Generated output may reproduce passages from the training data.

Future work

Done: the captioned fine-tune (F1) of this model (a short first stage on a laptop RTX 5060, then about 14 h on one rented RTX 5090), released as musicar-L-caption: captions from a frozen multilingual LaBSE encoder in English and Ukrainian, section captions that change during a piece, and length control. It keeps full attention: grouped-query attention was tested for it and dropped, because merging the heads broke this QK-norm model (held-out cross-entropy 2.01 → 6.57).

Planned, not done:

  • F2: a captioned fine-tune on about 5,400 Ukrainian songs transcribed from audio.
  • Later: regenerating parts of a piece (infilling), and inference on small devices (int8 / int4 on a Raspberry Pi 5); a grouped-query attention conversion would be its own optional step.
  • A listening test against the other open models of the comparison above.

Files

File What it is
model_bf16.pt Training checkpoint: bf16 weights + model_args + the training config. This is what the repository's scripts load (generate.py --checkpoint, train.py with init_from='finetune')
model.safetensors + config.json The same weights without pickle; config.json holds model_args
diagram.png The architecture diagram above
findings.png The project's evidence sheet: comparison with other models (section 1), training curves

License

CC BY-NC-SA 4.0. The training data are under non-commercial terms (Aria-MIDI CC BY-NC-SA 4.0, Discover MIDI CC BY-NC-SA, GigaMIDI non-commercial), so the model is released under the same non-commercial, share-alike terms. Check GigaMIDI's own terms before any reuse.

Citation

@misc{hilei2026musicar,
  author       = {Dmytro Hilei},
  title        = {musicar: autoregressive symbolic music models},
  year         = {2026},
  howpublished = {\url{https://github.com/DmytroHilei/Music_generative_model}},
  note         = {musicar-L}
}

Please also cite the training datasets: GigaMIDI (arXiv:2502.17726), Aria-MIDI (arXiv:2504.15071) and Discover MIDI (Hugging Face).

Downloads last month
82
Safetensors
Model size
0.5B params
Tensor type
BF16
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for Dimitri-206265/musicar-L

Finetunes
1 model

Datasets used to train Dimitri-206265/musicar-L

Papers for Dimitri-206265/musicar-L