Compose Misheard Check
Your Cover Is About to Sing the ASR's Typo. Ask a Local LLM Which Word It Misheard
- report
- brief
- prompt
- schema
Here's a trap in AI covers nobody warns you about. You feed Plenio a recording, it transcribes the sung words with an ASR, hands them to YuE2 - and YuE2 sings them exactly as transcribed, typos included. Singing is hard for speech recognition: vowels stretch, consonants get swallowed, and "wonderful" comes out "willing down". Then your cover sings "willing down" for four minutes.
Compose Misheard Check is the first half of the fix: it writes the question you'd ask a language model to spot the mishearing. Apply Misheard Check is the second half, and it does the distrusting.
What it is
One node, one job: take an ASR'd lyrics draft, present it to a writer model properly, hand back two strings. No sampling, no audio, no clever scoring - it formats a prompt and emits a JSON schema, and everything interesting happens in the nodes either side of it.
The prompt is specific to the problem. It says a speech recogniser wrote these lyrics down, that recognisers mishear sung words as other words that sound alike, and that words in [brackets] are the ones it wasn't sure of. Then the draft, numbered by line, and the ask: find the words most likely misheard, say what was most likely sung - it must fit the line's meaning, sound like what was heard, same syllable count. Change nothing else. Don't improve, don't rewrite. Names, slang, repetitions and ad-libs stay.
That paragraph is the design philosophy in miniature: the writer is a fresh intern, the node is the senior who wrote the brief.
The inputs that matter
- lyrics - required. The draft Transcribe Lyrics produced (its
lyricsoutput) - the raw hearing, not your edit. - report - optional but load-bearing.
Transcribe Lyrics' report carries which words the ASR heard with low confidence, and that's where the brackets come from - without it the writer works blind. The node also checks the report was made from exactly this text before trusting its markings. - brief - optional, and it's the gate: only a Cover Brief set to original lyrics makes sense here. Hand it a Song Brief, new lyrics or an instrumental and it refuses to build a question at all. Its title names the song for the writer.
- language - optional. The language
Transcribe Lyricsheard; only used when the brief doesn't already name one.
Outputs: prompt (STRING) and schema (STRING, the answer's JSON shape).
Wiring it
Two ways - on the stock templates you only need the second.
You don't. The pack ships it inside the subgraph Plenio · Fix Misheard Words, in the LYRICS group of the 2 · YuE2 · Cover template - Compose, a switch, the writer, Apply, all cabled. Use the subgraph.
Rolling your own, so: prompt goes to the prompt input of ComfyUI's native Generate Text node, or to Local LLM together with schema on its schema input. Local LLM takes both; Generate Text can't take a schema, which is why the prompt ends with Answer with JSON only: {"fixes": [...]}. Either way the text lands on Apply's answer, usually through a switch so you can swap writers.
On model choice: this is exactly the job a small local LLM is good at - short, structured rewriting with a schema to pin the output. An 8B GGUF is plenty, and the pack's Local LLM node runs any GGUF from ComfyUI/models/LLM in a llama.cpp server it starts for the draft and shuts down after, freeing the GPU for the music model. The classic failure isn't model size, it's dirty output - a chatty model that prepends "Here are the corrections:" and hands Apply prose it can't parse.
Install
Same pack, same steps as every other node in it:
cd ComfyUI/custom_nodes
git clone https://github.com/jplenio/Plenio-Music-Production-System
Or ComfyUI Manager → search Plenio Music Production System. Restart. ComfyUI 0.37.0 or newer, no Python packages. On this path the weights are the writer (Gemma 4 through native text generation, or your own GGUF) plus the ASR assets Plenio fetches on first use - Qwen3-ASR 1.7B and Qwen3-ForcedAligner 0.6B, about 6 GB into models/plenio/asr.
When it seems to do nothing
That's usually correct. When the lyrics aren't a cover's original lyrics - instrumental, new lyrics, a plain song, a draft with no sung words, or a draft that's 30%+ Chinese/Japanese characters - the prompt comes out empty and Apply passes the lyrics straight through. No writer call, no corrections. Deliberate no-op, easy to mistake for a broken graph.
The other one: if the answer isn't JSON with a fixes list, Apply reports exactly that and corrects nothing. Writer problem - lower the temperature, confirm the schema is connected on Local LLM, or pick a model that can hold a format for 200 lines.
And the early-adopter note: nobody on reddit has written about this pack yet - zero threads in our corpus. The repo's docs are the support forum.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| lyrics | STRING | The lyrics draft Transcribe Lyrics made from the source's singing (its 'lyrics' output). | |
| reportopt | PLENIO_REPORT | Transcribe Lyrics' report: which words it heard unsure (they are marked for the writer). | |
| briefopt | PLENIO_BRIEF | The Cover Brief: only original lyrics are checked; its title names the song for the writer. | |
| languageopt | STRING | The language Transcribe Lyrics heard (its 'language' output). |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| prompt | STRING | The question for the writer model. |
| schema | STRING | The answer's JSON schema, for Local LLM. |