Music · Verlaengern 4 · Pruefen
Check the LLM's solo before it becomes part of your song
- render_abc
- render_lyrics
- max_seconds
- part_json
- report
Step 4 of 6 (Pruefen, "check it"), and the name is honest. The model wrote pitches; this node decides whether they're usable, drops them into the rhythm template, and assembles the score that actually gets rendered.
It is the least glamorous node in the chain and the one you'll open most often, because everything that can go wrong with an LLM - wrong number of notes, notes outside the key, malformed JSON, sections it forgot to answer - surfaces here as a repair number in a report instead of as a ruined render three minutes later.
What it does with the draft
The mechanics, in order. Parse the LLM's JSON. For each new section, fill the rhythm template with the model's pitches; tonart_strikt (on by default) snaps any out-of-key note to the nearest tone of the song's scale - turn it off and chromatic notes survive, which the tooltip fairly calls braver and riskier. Silence the vocal if the song is instrumental, so a re-render can't invent a singer. Repair bars that still disagree with the template's note counts. Validate against the song's meters, and list anything that doesn't add up.
Then it builds the two things the renderer needs. render_abc is the overlap + new material + a short outro of rest bars, in that order. That outro is not decoration: YuE2, when you append to an existing song, tends to stop dead on the last note, and the resting bars give it somewhere to land. render_lyrics is the matching section tags for exactly those rendered sections, so YuE2 is being told about the overlap too and stays in the right structural place.
Here's the detail that makes the whole multi-part trick work: the saved score does not include those outro bars. Only the render score does. The stored score ends at real material, because that's the end the next part continues from.
max_seconds is a length hint for the render - the material duration with 25% headroom plus 15 seconds. part_json is the parcel the commit step reads. report is the part you read.
The lazy input that saves you a model load
llm_text is optional and lazy: it's only requested when the plan says an LLM is needed. In Loop mode the whole LLM branch of your graph never executes. That's a real win on a machine that's already holding a diffusion model and a song model in VRAM - pair it with the needs_llm boolean from the Plan node and the LLM stays cold.
Reading the report
It reports where the material came from - llm, loop, or fallback - plus the new sections and their duration and the overlap length. fallback means the LLM's answer was unusable and the template was used unchanged: you get a valid render that is a repeat of the source section, which sounds like the chain ignored your instructions. It didn't. The reply was bad JSON.
Warnings are listed separately; bars that had to be repaired show up in the notes with a per-section breakdown.
Outputs, and where they go
render_abc and render_lyrics feed your YuE2 render node. max_seconds goes to whatever the render node exposes as a length cap. part_json goes to FVM_SongExtendCommit along with the rendered audio. report goes to a Show Text node during your first runs - and to your eyeballs on every run after that, ideally.
Install
ComfyUI Manager, search comfyui-fvmtools, or:
cd ComfyUI/custom_nodes
git clone https://github.com/ping1979ping/comfyui-FVMtools
Restart; the node is in Add Node → FVMtools/music/extend. Nothing to download, no Python dependencies beyond numpy.
Common issues
The appended part is a repeat of the previous one. Check report for fallback. Most often the model wrapped its JSON in prose or markdown fences. Constrain its output; a small obedient instruct model beats a big reasoning one here.
A note sounds off. Either the model wrote something chromatic, or tonart_strikt snapped it to a scale tone that isn't what you wanted. Try turning it off, listen, and decide which was worse.
The render is truncated. max_seconds is a hint, not a lock - what matters is whether YuE2 rendered enough new material, and that's checked in the Commit node. If renders keep coming up short, add a section to sections_to_add rather than fighting the cap.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| plan_json | STRING | — | |
| tonart_strikt | BOOLEAN | true | Tonartfremde LLM-Toene auf den naechsten Ton der Tonleiter ziehen. Aus = chromatische Toene bleiben (mutiger, aber riskanter). |
| llm_textopt | STRING | — |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| render_abc | STRING | — |
| render_lyrics | STRING | — |
| max_seconds | FLOAT | — |
| part_json | STRING | — |
| report | STRING | — |