ComfyUI Node

Match Song Form

When the model's sections and your lyrics disagree

By jplenio·Created about a month ago·Updated about 15 hours ago· 96
Match Song Form
    • score
    • report
    ◄score—►
    ◄lyrics—►
    ◄alternative—►

    Two writers are involved in a Plenio song, and they don't talk to each other. One writes the lyrics with its own section tags - verse, chorus, bridge. The other is YuE2 planning the score, which decides where its sung sections go. Nothing forces those two structures to line up. When they don't, your chorus words get sung on the verse melody, or a section of lyrics has no music under it. Match Song Form reconciles them before anything is rendered.

    It's a small, unglamorous node with one job, and it's the reason the YuE2 Plan block exists at all. If you're generating anything with singing, it's doing work on every run, whether you notice it or not.

    How it works

    The node compares the plan's sung sections with the lyrics' form. Three things can happen, in order of preference.

    If the sections are the same kind in the same shape, the plan is used as it stands. If they're not the same kind but can be put in the lyrics' order, the sections are moved so the chorus words land on the chorus melody. If the kinds differ, the plan's sections can be named after the lyrics instead. Whichever of those works first is the one you get.

    When none of them work, the node asks for the alternative input - a second plan made with the next seed - and that request only happens then. It's a lazy input: if the first plan fits, no second plan is ever produced. Two plans in hand, the better one wins, and any section kind neither plan has takes a related section's melody, so a bridge borrows a verse's.

    The restraint matters: only the sections move. YuE2's notes stay exactly where the model put them. This is a re-arrangement of structure, not a rewrite of music. Instrumentals, a score with no singing, and planning switched off all pass straight through unchanged.

    Inputs and outputs

    • score - YuE2's plan. Empty when planning is off, in which case nothing happens and that's correct.
    • lyrics - the lyrics the plan was made from, i.e. Song Sheet · Text's plan_lyrics. Wiring the wrong set of lyrics here is the way to make this node look broken.
    • alternative - the second plan with the next seed. Lazy; requested only when the first one won't fit.

    Outputs: score (your plan in the lyrics' song form) onward to the sheet and the render, and report telling you what was compared, what was tried, and what changed. Read the report when a song's structure feels off - it's usually more informative than staring at the piano roll.

    Installing it

    Part of the pack; no separate install and no Python dependencies.

    cd ComfyUI/custom_nodes
    git clone https://github.com/jplenio/Plenio-Music-Production-System
    

    Or through Manager (Custom Nodes Manager → Plenio Music Production System) or comfy node install comfyui-plenio-music. Restart and run 0 · System Check. It needs ComfyUI 0.37.0 or newer, because the templates lean on ComfyUI's native YuE2, MiniMax Music 3, SheetSage2 and text-generation nodes rather than bundling their own.

    If you're coming from the older Music Production Toolkit: this is a new package with new node IDs, both can coexist, and saved workflows don't migrate. Start from the templates.

    When it misbehaves

    This node is unusually hard to break, which is worth knowing before you go hunting for a bug in the wrong place.

    If it seems to do nothing, verify the lyrics input is the same text the plan was built from. The whole comparison is between two structures, and feeding it a lyric set the plan never saw gives you a match that can't be made - the section names won't correspond and the fallback logic has nothing to work with.

    Structural problems that aren't this node's fault are worth ruling out too. Section tags live in the lyrics - the Song Sheet's lyrics lane and tag buttons are where you add them, and there's an [Instrumental] tag for a wordless section between sung ones. If your lyrics have no tags at all, or tags you typed by hand that don't match anything else in the project, the matching has very little to go on.

    And if the check itself throws an internal error, the run does not stop: the plan is used as it is and you get a warning in the report saying so, with the traceback in the console. Every sung YuE2 song goes through this node, so failing loudly would break songs that are otherwise fine - but it does mean a bad report is easy to miss. Check the reports when you're comparing takes.

    CategoryPlenio/Score

    Inputs (3)

    NameTypeDefaultDescription
    scoreSTRINGYuE2's plan (empty when planning is off).
    lyricsSTRINGThe lyrics the plan was made from (Song Sheet · Text's plan_lyrics).
    alternativeoptSTRINGA second plan with the next seed; requested only when the first does not fit.

    Outputs (2)

    NameTypeDescription
    scoreSTRINGThe score in the lyrics' song form.
    reportPLENIO_REPORTWhat was compared, tried and changed.