NotaGen Run
Write a Bach-style piano piece from ComfyUI — sheet music and all
- audio
- score
- message
The one thing that surprises people about this node: it doesn't generate music the way ACEStep or other audio models do. NotaGenRun writes sheet music - actual notation in ABC format - and then renders that notation into an MP3 and PNG pages of score you can look at. So when you pick "Bach, Johann Sebastian", you're not getting a Bach clone, you're getting new music written in the style of Bach's era and instrumentation, complete with readable sheet music. It's a weird, delightful, and genuinely underrated corner of ComfyUI.
What it is
It's the entire billwuhao/ComfyUI_NotaGen pack in a single node: a wrapper around NotaGen, a transformer trained on the MuseScore ABC-notation corpus for symbolic music generation. All you do is pick a model, a period, a composer, and an instrumentation, hit run, and out come audio, score images, and a text message. It's a one-trick pack - which is fine, because the trick is cool.
How it works
NotaGen is a two-level GPT: a patch-level encoder that predicts musical patches (bars), and a char-level decoder that fills in the ABC characters within each patch. A Patchilizer tokenizes the ABC into these patches, and generation is a standard autoregressive loop with top_k/top_p/temperature sampling. When the context window fills up, the node "streams" - it trims the middle of the generated tune body and re-encodes, so long pieces keep going without blowing past the window.
Your period/composer/instrumentation prompt becomes three %-prefixed metadata lines in the ABC. The node then converts the ABC to MusicXML with a bundled abc2xml.py, and shells out to MuseScore (mscore on Linux, MuseScore4 on Windows) to render that XML into the MP3 and PNG pages. That external dependency is the whole story of this node's gotchas. Everything is also saved as .abc/.xml files under ComfyUI/output/notagen_original and notagen_interleaved, so you can reopen the notation in a real score editor.
Inputs that matter
Most of the dropdowns are self-explanatory, but three things matter more than the rest:
- model - pick which NotaGen checkpoint.
notagenx.pthis the default and shares the biggest config (20 encoder layers, hidden 1280) withnotagen_large.pth;smallandmediumare lighter and faster. You only need the one you actually select. - custom_prompt - the free-text field. Its tooltip is the whole contract: format must be
<period>|<composer>|<instrumentation>, separated by|, in that strict order. It overrides the three dropdowns when filled, so blank it if you want to use the dropdowns. - seed -
0means "don't seed" (the code only seeds when it's non-zero), so 0 gives you a different piece every run.
The rest are sampling knobs you've seen a hundred times: temperature (default 0.8), top_k (50), top_p (0.95). Raise temperature for more adventurous harmony, keep it low if you want something that sounds like it could actually be from the period. unload_model (default on) frees VRAM after each run - turn it off if you're generating repeatedly and want to skip reloading the checkpoint each time.
Outputs
Three of them: audio (an AUDIO waveform you wire into any audio preview/save node - the node loads it from the rendered MP3 via torchaudio), score (an IMAGE batch, one white-background PNG per page of sheet music - preview it or save with a normal image node), and message (a STRING telling you where the .abc/.xml files landed).
Installing it
The ComfyUI Manager route: search "ComfyUI_NotaGen" and install. Or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/billwuhao/ComfyUI_NotaGen.git
cd ComfyUI_NotaGen
pip install -r requirements.txt # or ./python_embeded/python.exe -m pip ...
Requirements are wandb, abctoolkit, samplings, pyparsing, and transformers>=4.40 - that last one is worth flagging, because it installs into the same environment as all your other nodes and can bump a pinned transformers version sideways. Then the model. Drop whichever weight you want into ComfyUI/models/TTS/NotaGen and rename it exactly: notagenx.pth, notagen_small.pth, notagen_medium.pth, or notagen_large.pth. (Yes, models/TTS - it's not a TTS model, that's just where this pack looks. One of those running jokes nobody fixed.)
Then the actual gotcha: you need MuseScore 4 installed as a real app. It's not a pip package. Windows: add the MuseScore bin folder (e.g. C:\Program Files\MuseScore 4\bin) to your system PATH and restart ComfyUI - the pack used to want you to type the path in manually, but since 2025-04 it just uses PATH. Linux: sudo apt install musescore plus the libxcb* libraries; on headless servers also sudo apt install xvfb, which the node will spawn itself to render under.
Common issues
The failure you'll actually hit is "Conversion of .mp3 and .png failed, try again or check if MuseScore4 installation was successful" - MuseScore isn't found on PATH, or is the wrong version, or (Linux server) there's no display and no Xvfb. The node retries conversion up to 6 times and then raises, so a missing MuseScore shows up as repeated failed runs rather than a clean error. Missing model weights throw before that, pointing at models/TTS/NotaGen. And don't expect instant results: generation has a 20-minute per-attempt cap and long pieces stream through several context rewrites, so a full orchestral movement on a CPU will test your patience.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| model | COMBO | notagenx.pth | 4 options: notagenx.pth, notagen_small.pth, notagen_medium.pth, notagen_large.pth |
| period | COMBO | Romantic | 3 options: Baroque, Classical, Romantic |
| composer | COMBO | Bach, Johann Sebastian | 62 options: Bach, Johann Sebastian, Corelli, Arcangelo, Handel, George Frideric, Scarlatti, Domenico, Vivaldi, Antonio, Beethoven, Ludwig van, +56 |
| instrumentation | COMBO | Keyboard | 6 options: Chamber, Choral, Keyboard, Orchestral, Vocal-Orchestral, Art Song |
| custom_prompt | STRING | Romantic | Bach, Johann Sebastian | Keyboard | Custom prompt must follow format: <period>|<composer>|<instrumentation> |
| unload_model | BOOLEAN | true | — |
| temperature | FLOAT | 0.80–5 | — |
| top_k | INT | 50 | — |
| top_p | FLOAT | 0.950–1 | — |
| seed | INT | 00–18446744073709550000 | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| audio | AUDIO | — |
| score | IMAGE | — |
| message | STRING | — |