LyricForge ACE-Step Generator
Caption, lyrics, BPM and key from one keyword box
- caption
- lyrics
- bpm
- key_scale
ACE-Step (ByteDance's open, Apache-2.0 text-to-music diffusion model) doesn't want comma-separated tags the way HeartMuLa does - it wants a natural-language caption, plus a lyric line, a BPM, and a key/scale, and it wants them precise. That's a lot of stuff to write by hand before you've generated a single second of audio. The LyricForge ACE-Step Generator is the sibling node that does the whole description job in one shot: type a keyword sentence, get back a caption, full lyrics, a BPM integer, and a key/scale string. It's not a music model either - it's the text-prep layer that sits between you and the ACE-Step text encoder.
How it works: identical plumbing to its HeartMuLa sibling - build a system prompt, POST to an OpenAI-compatible /v1/chat/completions endpoint, parse the reply. The difference is what the prompt demands. For ACE-Step it specifies the caption recipe (genre, mood, instruments, sound texture, era reference, vocal character), then BPM ranges by tempo feel (ballad 60–80, up-tempo 110–140, fast dance 140–180) and a mood-to-key mapping (bright/positive → major, sad/dark → minor). The parser then pulls out CAPTION, BPM (coerced to an int), KEY_SCALE (normalized to things like A minor or F# minor), and LYRICS with ACE-Step's structure tags - including its own sections like [Build], [Drop] and [Breakdown], not just [Verse 1] / [Chorus].
The inputs are the shared pack set: keywords (multiline), plus api_endpoint / api_key / model - which default to LM Studio values (http://localhost:1234, key lm-studio, model local-model). Change all three if you're not running LM Studio; the endpoint gets /v1/chat/completions appended automatically. Optional: language (Japanese/English/Chinese), song_structure (Standard/Short/Extended), temperature (0–2, default 0.7).
The outputs and the wiring are where this node earns its keep - four of them:
caption→ thecaptioninput onTextEncodeAceStepAudio1.5lyrics→ thelyricsinput on the same encoderbpm(an actual INT) → thebpminputkey_scale→ here's the gotcha the README is upfront about: ACE-Step's key/scale input is a COMBO (dropdown), so you cannot wire a string into it. You read the value and select it by hand in the ACE-Step node. Annoying, but it's a one-time per-run copy, and the value's right there on the node.
From there the flow is standard: TextEncodeAceStepAudio1.5 → KSampler → VAEDecodeAudio → Save Audio.
Install: same as the rest of the pack -
cd ComfyUI/custom_nodes/
git clone https://github.com/knishika62/ComfyUI-LyricForge.git
cd ComfyUI-LyricForge
pip install -r requirements.txt
restart, and you're done. The only dependency is requests. The heavy lifting is all elsewhere: you still need the ACE-Step 1.5 checkpoint (multi-GB) and its ComfyUI node, which this pack does not install. The README documents this node's caption/BPM/key behavior in detail in ACESTEP_ANALYSIS.md if you want the spec.
Reality check on the BPM and key: they're guesses - the LLM infers them from your keywords and mood, it doesn't analyze anything. They're a genuinely good starting point for a caption-driven workflow, but treat them as suggestions, not the finished arrangement; you'll often nudge the BPM yourself after hearing the first take. Same shared caveats as the sibling node: the API call is synchronous with a 120s timeout (UI freezes while it thinks - normal), and any failure surfaces as literal Error: ... strings in the outputs with a fallback of 120 BPM / C major. If that's what you see, the console is telling you exactly which call failed. And the quality ceiling is your LLM - a weak local model produces generic captions, so don't blame the node when a 3B model phones it in.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| keywords | STRING | j-pop 冬の歌 女性ボーカル 雪 カフェ | — |
| api_endpoint | STRING | http://localhost:1234/v1/chat/completions | — |
| api_key | STRING | lm-studio | — |
| model | STRING | local-model | — |
| languageopt | COMBO | Japanese | 3 options: Japanese, English, Chinese |
| song_structureopt | COMBO | Standard | 3 options: Standard, Short, Extended |
| temperatureopt | FLOAT | 0.70–2 | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| caption | STRING | — |
| lyrics | STRING | — |
| bpm | INT | — |
| key_scale | STRING | — |