Song Generation Suite
The AI that writes the song so your AI can sing it
- clip
- conditioning
- latent_audio
- ACE_LANGUAGE
- TAGS
- LYRICS
- FULL_OUTPUT
- PROMPT_USED
The hard part of making music in ComfyUI with ACE-Step 1.5 isn't the sampling - it's writing the prompt. Native ACE-Step text2music wants a long, comma-laced tags string plus a structured lyric block with [Verse], [Chorus], [Bridge] tags in a specific format, and it's genuinely fiddly to get right by hand. Song Generation Suite takes a one-line idea (and optional lyrics of your own), runs it through a local LLM, and hands you back finished ACE conditioning ready to drop into a KSampler. That's the whole job, and it does it well.
It's a small, brand-new pack from pmarmotte2, and it's honest about being a convenience wrapper: it doesn't load ACE for you, calls no API, and needs no key. What it adds is a songwriter that lives inside your graph.
How it works
Two stages, one node. First it builds a detailed songwriting prompt - topic, vocal profile, genre, structure - and feeds it to a HuggingFace causal LM, by default Qwen2.5-3B-Instruct, which returns a music-tags string plus bracket-structured lyrics. Then it post-processes that output: strips the tags prefix, cleans up the text, and enforces the [Intro]/[Verse]/… tag ordering - the thing that makes ACE lyrics land like a song instead of a paragraph.
Second, it encodes what it wrote. The clip input you wired from an ACE 1.5 Checkpoint Loader gets called with the full ACE tokenize signature - tags, lyrics, bpm, duration, timesignature, language, keyscale, seed - and the result becomes real CONDITIONING with lyrics_strength baked in. There's a try/except fallback to a minimal tokenize(tags, lyrics=…) if your clip doesn't support the extended signature, so the node won't crash on a non-ACE CLIP. It'll just be dumber.
The node also builds your empty audio latent for you - a zero tensor shaped [batch_size, 64, duration × 48000 / 1920], which is exactly the latent shape ACE-Step expects. So duration and batch_size map straight onto the latent; no separate EmptyLatentAudio node needed.
The inputs that actually matter
There are a lot of knobs (27 inputs, and most you'll never touch). The ones worth setting:
- song_topic - your idea. "A bittersweet country ballad about a dog that learns to drive" is a great input; empty is a sad one.
- music_style (25 genres) plus music_style_custom for hybrids the dropdown can't express.
- lyrics + strict_user_lyrics - drop in your own words and the LLM will enforce them exactly by default.
- model / quantization - the big VRAM knob. 3B in FP16 is ~6GB on top of your ACE checkpoint;
4-bit (VRAM-friendly)is the right call on a 12GB card. 7B is for people with headroom. - seed - reproduces both the LLM output and the sampler.
- lyrics_strength - how hard the conditioning pushes the sampled audio toward the lyrics.
Outputs: conditioning → KSampler positive (and through ConditioningZeroOut for the negative), latent_audio → KSampler latent, plus four debug strings - TAGS, LYRICS, FULL_OUTPUT, PROMPT_USED. Those last two are gold when the song comes out wrong: you can see exactly what the LLM was asked and what it returned.
Installing it
ComfyUI Manager - search "Comfyui-Song-Generation-Suite" - or the manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/pmarmotte2/Comfyui-Song-Generation-Suite
cd Comfyui-Song-Generation-Suite
pip install -r requirements.txt
Then restart ComfyUI. Gotcha: the README's own install block says git clone https://github.com/YOURNAME/SongGenerationSuite.git - yes, literally YOURNAME, a placeholder nobody filled in. Copy-pasting that fails; use the URL above. Requirements pull in transformers, huggingface_hub, accelerate, sentencepiece, and bitsandbytes (optional, for 4/8-bit, and occasionally a pain on Windows). The node does not fetch the ACE-Step 1.5 checkpoint - you need that separately. And the first run downloads the Qwen weights from HuggingFace, so budget for it.
Troubleshooting
- "transformers is not installed" - the node imports transformers lazily and errors loudly if it's missing, which almost always means you installed requirements into the wrong Python. ComfyUI's venv, remember.
- Pick "Custom (HF repo id)" and leave the field empty → hard RuntimeError. Fill a real repo id or stick to the built-ins.
- VRAM pressure - Qwen and the ACE checkpoint share your card.
4-bitquantization andkeep_model_loaded: false(unloads the LLM after each run) are your levers. - Song sounds nothing like the lyrics - check TAGS/LYRICS first. If the LLM produced weak tags, no sampler can rescue that; it's a pipeline failure upstream, and the debug outputs exist precisely to show you it.
ACE-Step 1.5's native ComfyUI text2music already works fine on its own. This node exists because you shouldn't be hand-writing [Verse 1] blocks at 2 a.m. - and if that's you, this is your pack.
Inputs (27)
| Name | Type | Default | Description |
|---|---|---|---|
| clip | CLIP | — | |
| song_topic | STRING | — | |
| lead_singer_sex | COMBO | Male | 5 options: Not specified, Male, Female, Non-binary, Other |
| music_style | COMBO | Country | 25 options: Heavy Metal, Hard Rock, Pop, Synth Pop, Electro, EDM, +19 |
| music_style_custom | STRING | — | |
| lyrics | STRING | — | |
| strict_user_lyrics | BOOLEAN | true | — |
| lyrics_language | COMBO | English | 23 options: English, Japanese, Chinese, Spanish, German, French, +17 |
| seed | INT | 00–18446744073709550000 | — |
| bpm | INT | 12010–300 | — |
| duration | FLOAT | 120.00–2000 | — |
| batch_size | INT | 11–4096 | — |
| timesignature | COMBO | 4 | 4 options: 2, 3, 4, 6 |
| keyscale | STRING | C major | — |
| lyrics_strength | FLOAT | 1.000–10 | — |
| model | COMBO | Qwen2.5-3B-Instruct | 4 options: Qwen2.5-3B-Instruct, Qwen2.5-7B-Instruct, Qwen2.5-1.5B-Instruct, Custom (HF repo id) |
| custom_model_repo_id | STRING | — | |
| quantization | COMBO | None (FP16) | 3 options: None (FP16), 8-bit (Balanced), 4-bit (VRAM-friendly) |
| attention_mode | COMBO | auto | 3 options: auto, flash_attention_2, sdpa |
| use_torch_compile | BOOLEAN | false | — |
| device | COMBO | auto | 3 options: auto, cuda, cpu |
| max_tokens | INT | 110064–4096 | — |
| temperature | FLOAT | 0.700.1–1.2 | — |
| top_p | FLOAT | 0.900–1 | — |
| num_beams | INT | 11–8 | — |
| repetition_penalty | FLOAT | 1.100.5–2 | — |
| keep_model_loaded | BOOLEAN | true | — |
Outputs (7)
| Name | Type | Description |
|---|---|---|
| conditioning | CONDITIONING | — |
| latent_audio | LATENT | — |
| ACE_LANGUAGE | STRING | — |
| TAGS | STRING | — |
| LYRICS | STRING | — |
| FULL_OUTPUT | STRING | — |
| PROMPT_USED | STRING | — |