Nodes/SC YuE2 ABC Helpers/SC YuE2 ABC Length Search
ComfyUI Node

SC YuE2 ABC Length Search

10.

By ShantyCircuit·Created 16 days ago·Updated 16 days ago· 0
SC YuE2 ABC Length Search
  • clip
  • abc
  • report
  • seconds
  • seed_used
◄style►
◄lyrics►
◄seed0►
◄new_seed_each_runfalse►
◄modefull►
◄target_minutes3►
◄target_seconds30►
◄upper_t_seconds10►
◄lower_t_seconds10►
◄max_attempts5►
◄max_tempo_change_percent0►
◄on_failurestop workflow►
◄max_abc_tokens8192►
◄temperature0.70►
◄top_p0.90►
◄top_k30►
◄repetition_penalty1.005►
◄penalty_window100►

Song generators don't do deadlines. Ask YuE2 for a three-minute sea shanty and you'll get four minutes and twelve seconds of it, and there's no length field to argue with - length falls out of how many bars the model decided to write. SC YuE2 ABC Length Search is a drop-in replacement for the built-in YuE2 Generate ABC node that re-rolls until a score actually fits the length you wanted.

It's the one node in this pack I'd call genuinely clever, and the one with the best chance of eating your afternoon if you set it up wrong.

Why length is a search problem

YuE2 in ComfyUI is two stages: Generate ABC writes a text score in ABC notation, Generate Music renders audio from it. Length is determined at the score stage - bars times meter over tempo - so the only way to hit a target without editing the score is to try another seed and hope. That's a loop, and loops are what computers are for. The community's own framing of local music gen is that it's fast, cheap and slightly uncontrollable; this node is the control. Remember that the score stage is an LLM pass over your lyrics, so every attempt costs real tokens.

What it does under the hood

It calls ComfyUI's own YuE2GenerateABC node directly, once per attempt, incrementing the seed each time. Each returned score is parsed and measured with the same arithmetic the Song Length node uses, then compared against an acceptance window: your target plus upper_t_seconds above and lower_t_seconds below. Default target 3:30 with 10 seconds either side accepts 3:20 to 3:40.

Generated scores are cached for the session - keyed on everything that affects generation, up to 256 of them - so re-trying a seed you already tried is instant rather than a second full generation. Cancel is respected between attempts. If nothing fits and on_failure is set to stop workflow, it hands downstream nodes an execution blocker, so Generate Music never runs and you don't burn GPU rendering a song you've already rejected.

The inputs you'll actually touch

  • clip - the YuE2 model, from a CheckpointLoaderSimple on yue2_3b_bf16.safetensors. Same as what Generate ABC takes.
  • style and lyrics - identical to the built-in node. style is where genre, instrumentation, key and bpm go.
  • target_minutes / target_seconds - the two-part target. That's it, no seconds-per-bar math required.
  • upper_t_seconds / lower_t_seconds - tolerance. Set upper_t_seconds to 0 and the target becomes a hard ceiling, which is what you want for anything with a fixed slot.
  • max_attempts - how many rolls. 0 means keep going until one fits, which is honest but can run a long time.
  • max_tempo_change_percent - the interesting one. Instead of throwing away a near miss, it nudges the score's global tempo to pull it into range. Direction is automatic and the sign doesn't matter; 0 (the default) never touches tempo.
  • on_failure - stop workflow or use closest.
  • mode, seed, new_seed_each_run - new_seed_each_run gives you a different song every queue; leave it off and re-queueing reuses the winning seed, because the node writes the winning seed back into the seed box.

The advanced knobs (max_abc_tokens, temperature, top_p, top_k, repetition_penalty, penalty_window) are the same sampling settings as the built-in node. max_abc_tokens at its default 8192 is effectively your hard length ceiling - very long songs need it raised.

Four outputs: abc (into Fix Meter, Song Length, or Generate Music), report (attempt-by-attempt log plus a section table), seconds, and seed_used.

Install

Recent ComfyUI required - this pack needs the V3 node API and the built-in YuE2 nodes, and the node will raise a clear "YuE2GenerateABC was not found" error if yours predates them. No Python packages.

cd ComfyUI/custom_nodes
git clone https://github.com/ShantyCircuit/ComfyUI-SC-YuE2-ABC-Helpers

Restart, then Ctrl+Shift+R. Manager search: SC YuE2 ABC Helpers. Everything lands under ShantyCircuit/YuE2.

Reading the node while it works

It has its own run button, so you can search for a score without rendering any audio - do that first, always. The log updates after every attempt, the node goes green on a fit and red on a miss (it resets to normal on the next run), and the "new search (random seed)" button picks a fresh starting seed. After a failed run the seed box advances past the seeds already tried, so the next queue continues the search instead of repeating it.

Where people get burned

Every attempt is a full score generation. A 5-attempt search means five songs' worth of tokens before a single second of audio exists, and with max_attempts at 0 plus a tight window you can spin for a long while on a wordy lyric. Start with a loose window, tighten once you know what the model tends to produce.

Two smaller things: if the text box and colours don't appear, the js folder didn't come along with __init__.py and/or the browser is serving cached scripts - hard refresh, then check the console. And if the chosen score has a meter glitch, the report will say so; that's a job for SC YuE2 ABC Fix Meter, not another search.

CategoryShantyCircuit/YuE2

Inputs (19)

NameTypeDefaultDescription
clipCLIP—
styleSTRING—
lyricsSTRING—
seedINT00–9007199254740991Seed the search starts from. After each run it is set to the seed of the chosen score, so queueing again reuses that score. Use the 'new search' button to start from a fresh seed.
new_seed_each_runBOOLEANfalsePick a random starting seed every time the workflow is queued. Turn off to reuse the last winning score.
modeCOMBOfull2 options: full, melody
target_minutesINT30–15Target length (minutes part).
target_secondsINT300–59Target length (seconds part).
upper_t_secondsFLOAT100–120How far over the target is still acceptable. 0 = the target is a hard ceiling.
lower_t_secondsFLOAT100–120How far under the target is still acceptable.
max_attemptsINT50–1000Each attempt generates a new score with the next seed. 0 = keep trying until a score fits (press Cancel to stop).
max_tempo_change_percentFLOAT0-30–30How much the tempo may change to bring a near miss toward the target. The direction is automatic: scores that are too long are sped up, too short ones are slowed down. The sign doesn't matter (10 and -10 both allow up to 10% either way). 0 = never change the tempo.
on_failureCOMBOstop workflowIf no attempt fits: 'stop workflow' skips the nodes that use the abc output (no render); 'use closest' passes on the closest score anyway.
max_abc_tokensINT81921–20000—
temperatureFLOAT0.700–5—
top_pFLOAT0.900.01–1—
top_kINT301–32768—
repetition_penaltyFLOAT1.0050.01–10—
penalty_windowINT1001–20000—

Outputs (4)

NameTypeDescription
abcSTRING—
reportSTRING—
secondsFLOAT—
seed_usedINT—