YuE2 Edit Track
Re-sing four bars without re-rendering the whole song
- audio
- options
- audio
Here's the thing nobody tells you about local music generation: every change is a whole new song. One clumsy line in the second verse, and you either live with it or roll the dice again and lose the mix and the performance you had. YuE2 Edit Track closes that gap.
What it actually does
You hand it a song this pack has sung, open a track window, drag over a stretch of bars, and press one of the buttons: Retake, Cut, Notes, Go on or Break. What comes back is the whole song with that stretch changed - and everything outside the edit is the old recording to the sample.
That's the pitch masked inpainting has always had on the image side: an instruction-editing model redraws your picture nicely but won't leave the rest alone. It matters more for audio, because music tooling in ComfyUI is still thin and bolted on - ACE-Step is the community's open Suno, good at instrumentals and embarrassing on vocals. YuE2-3B aims at that weakness.
How the mechanism works
The node doesn't edit arbitrary audio. It works on songs the pack remembers: every song YuE2 generates has its score, tokens and latents stashed under ComfyUI/user/yue2_comfy/songs, and the node finds the right one by the sound you wire in. A FLAC or WAV from Save Audio is found again after a restart; an MP3 isn't, because lossy encoding changes nearly every sample.
Then Edit track... draws the waveform with the bars and sections of the song's own score over it. Those bars need the voice separator (0.85 GB) to find - chroma alone put a rock song's bars 14 seconds off. The acoustic stage then redraws a window of roughly 40 seconds around your edit instead of regenerating minutes.
The inputs that matter
Only one input is required: takes (1 to 4, default 2) - how many times a retake, a change of words, a change of notes or a song that goes on sings the same stretch, so there's something to compare. A cut and a move have one result each.
audio is optional and it's the one to understand. It takes the output of YuE2 Generate Song, YuE2 Render Plan or YuE2 Decode Latents, or a FLAC/WAV of one via Load Audio. The square beside it (use_audio) is the switch: untick it and the node edits the song picked with Saved songs... instead, and skips the node feeding it - after a restart, that's one bar edited in seconds instead of minutes re-singing a song you already had.
options carries only what the run decides - device, offload, low_vram, vae, quantization, attention backend, download, keep_model_loaded. How the song was sung, cot and sampling included, comes from the song itself, so an edit sounds like the track it belongs to. edits and song_key sit hidden behind the window buttons; you don't type them. The output is audio, 48 kHz stereo, wired into Save Audio. It's an output node, so you can press Run with nothing downstream and just render.
Installing it
ComfyUI Manager, search YuE2-ComfyUI, or by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/pytraveler/YuE2-ComfyUI
Restart the server - ComfyUI caches imports, so a clone or update is never live until it does. The only hard dependency the pack adds is tiktoken, and if it's missing the node prints the pip line for the interpreter ComfyUI runs on, which a bare pip install doesn't reach in a portable build.
Weights download themselves on first use: 7.26 GB for the YuE2 checkpoint, or 3.69 GB for the INT8 build. Editing adds the 0.85 GB voice separator, 1.84 GB for the Qwen3-ForcedAligner the first time you change words, and 3.8 GB for the Qwen3-ASR that hears the takes; download: off prints the links instead. Remembered songs want up to 4 GiB in ComfyUI's user folder.
Where people get burned
The big one: you can only edit songs this pack sang. A recording YuE2 never generated can't be edited - transcribe it or load its MIDI first, then sing it. A vocals_only song is refused too; edit the full song and pull the voice out afterwards.
Then expectations. Takes live in that session's memory only, so a workflow reopened in a fresh ComfyUI sings just the take its list kept - the same seed gives it back. Break... came out free of the voice in 7 of 12 tries and a rap had one over every attempt, so don't assume silence. A song sung with cot off has no score and no bars: you select by seconds, and notes, going on, moves and breaks are off the table.
Cost-wise it's no worse than singing the song was: on a four-minute song a retake of a few bars took about 10 seconds on a 5090 and a move 19, against roughly 100 to re-sing it, at 10.9 GiB reserved with offload: auto and 3.1 GiB with low_vram. And the YuE2 weights are CC BY-NC 4.0, so no commercial songs.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| takes | INT | 21–4 | How many times a retake, a change of words or a change of notes sings the same stretch, so there is something to choose between. New words keep the take heard singing the most of them, the join deciding a tie. A retake or a change of notes does the same with the words the song sings there when Qwen3-ASR and the word aligner are already on the machine -- they come with the first change of words -- and otherwise keeps the take whose join the model likes best. A song that goes on sings this many takes as well, each writing its own score, and keeps one that ended the song by itself, heard singing the most of the new words. The track window plays them all and lets you keep another, which costs nothing -- they are all already sung. They are sung once and kept in this session's memory. A workflow opened in a fresh ComfyUI sings only the take its list kept, however many it once compared; the window shows the others and sings one on request, a seed always giving back the same take. A cut ignores this, and so does a move: each is the same however often it is made. |
| audioopt | AUDIO | A song this pack has sung: the output of 'YuE2 Generate Song', 'YuE2 Render Plan' or 'YuE2 Decode Latents', or a FLAC or WAV of one loaded with 'Load Audio'. Optional: with nothing joined here the node opens the song chosen with 'Saved songs...'. An MP3 or another lossy file changes nearly every sample, and the song behind it is not found. The square beside this input on the node switches it off: the song chosen with 'Saved songs...' is edited instead, and whatever sings into this input is not run for this node. | |
| editsopt | STRING | The edits to make, as a JSON list, written by the track window. Empty means no edits: the node hands the song on as it is and draws the track. Each edit is {'op': 'retake', 'cut', 'words', 'notes', 'extend' or 'move'} with either 'bars': [first, stop] counting from 0, the second bar not included, or 'seconds': [from, to] for a song sung with cot 'off', which has no score. A retake also takes a 'seed', how many 'takes' to sing, and which 'take' to keep. A change of words takes those too, and 'lines': [first, stop] of the words with the 'text' they become; without bars or seconds it is sung where those lines are. A change of notes, 'notes', takes a seed and takes as well, and the whole 'score' the song is to have, as the score editor leaves it: without bars it is sung over the bars whose notes that score changes, and with bars only the music of those bars is taken from it. A song that goes on, 'extend', takes a seed and takes, and the 'text' it goes on with, empty for a new ending alone; it selects no bars, going on from where the singing ends. A 'move' takes the bars of whole sections and 'to', the bar line they go to: where another section starts, or the number of bars for the end. | |
| optionsopt | YUE2_OPTIONS | Optional. Only what this run decides is read from it -- 'device', 'offload', 'low_vram', 'vae', 'quantization', 'attention_backend', 'download' and 'keep_model_loaded'. How the song was sung, 'cot' and the sampling among it, comes from the song itself. | |
| song_keyopt | STRING | Which remembered song to edit when nothing is joined to 'audio'. Written by the 'Saved songs...' button on the node, which shows what this install has sung and what each one is. The song comes back from its latents, the last stage of singing it and nothing more: about a second and a half for four minutes, against minutes to sing it again. The sound it makes is the same performance but not the same file to the bit, so the song answers to that sound too. With 'Keep each song's sound beside it' switched on in the 'Saved songs...' window, the sound is read off the disk instead, which is faster still and is the song's own file to the bit. A song joined to 'audio' wins over this field: the graph is what the run is about, and the field is what to do when there is no graph above this node yet. | |
| use_audioopt | BOOLEAN | true | Whether the song joined to 'audio' is the one edited; the square beside that input on the node is this switch. Switched off, the node edits the song chosen with 'Saved songs...' and leaves the link where it is -- and the node above is not run for it at all, so a song sung before a restart is not sung again to edit one bar of it. A run of the whole workflow still runs every node that something else needs, such as a 'Save Audio' joined to the same song. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| audio | AUDIO | — |