SemBridge Singing
Real singing synthesis, provided you write the melody yourself
- model
- prompt_audio
- audio
- report
Local audio has two mature corners - generic speech and instrumental music - and one that barely exists in public discussion: singing voice synthesis. Text-to-speech models say words. Music models like ACE-Step hum a melody and produce mush where the vocals should be. SemBridge Singing is the narrow path between them: you hand it lyrics already attached to notes, and it sings those notes in a voice you can either leave to the seed or supply yourself.
Manage your expectations about the interface first. This is not a MIDI importer. It will not read a .mid file, it will not align lyrics for you, and no widget will fix that. The model needs syllables already sitting on pitches, and writing that alignment is your job. Once you accept that, it works surprisingly well - the author's pitch check on the demo clip came out at a median error of 0.15 semitone against the written notes, seven of seven notes inside a semitone, no octave slip.
The score format
One note per line inside the score box: lyric pitch seconds, with an optional fourth field for note type.
twin 60 0.4
kle 60 0.4
star 67 0.9
<SP> 0 0.3
Pitch is a MIDI number, 60 = middle C. Seconds is the note length and the model quantises to 25 ms. <SP> with pitch 0 is a rest. note_type 3 means "this note continues the previous lyric onto a new pitch" - that's how you get melisma, and it's what the official examples use. Lines beginning with # are comments. The official JSON note list also works, so you can generate scores from a script and paste them in.
Run your score through Score Preview first. Same parser, no model load, and it hands you the patch bounds so you know whether the generator has room for your phrase.
How the generation is bounded
The interesting input here is length_control, and not the two patch numbers. On from_score, which is the default, the node works the limits out from the score itself: minimum 0.5× and maximum 1.8× the score length in patches, where one patch is 80 ms. That's the rule the official singing examples follow, and it's why you can mostly ignore min_new_patches and max_new_patches - they only apply when you switch to manual.
max_new_patches is a ceiling, never a target. The model stops when it thinks the phrase is done, so raising it to 800 doesn't make your song longer, it just lets a confused run go on for longer. If a render hits the cap and ends mid-word, that's a hook or an over-ambitious score, not a length you can tune upward.
flow_steps defaults to 20 here rather than the 10 used for speech, matching the official singing setting. Leave it. cfg_value sits at 2.0 and temperature at 1.0, both the model's own defaults. Nobody has published a reason to move them, and I haven't found a sweet spot worth recommending.
The decoder is where SemBridge's design shows: auto picks the native causal decoder for speech and BigVGAN-Large for singing and mixed.
Voice control, if you want it
By default you get whatever voice the seed gives you - one voice per seed, no reference needed. To sing in a specific voice, connect a clip to prompt_audio and give prompt_text the exact transcript of that recording. For a sung reference, the transcript is the score token string, which is what Score Preview's token_string output is for.
The pairing is mandatory: audio without text raises an error rather than guessing, and text without audio raises too. Only the first item of a batch is used. prompt_task tells the model whether the reference is speech or singing; auto already resolves to singing on this node, so you rarely touch it. The model card asks you to only use recordings you have the right to use, and to disclose synthetic audio. Worth actually doing.
Outputs
audio is a standard ComfyUI AUDIO - mono, 44.1 kHz, clamped to [-1, 1] - so it goes into Save Audio, any audio post-processing node, or a lip-sync/latent-audio pipeline downstream. report is a JSON string with the decoder actually used, patches_generated, stopped_early, audio_seconds, generation_seconds, realtime_factor and peak VRAM. Handy when you're debugging a run that cut off early: if stopped_early is true and the patch count is well under max, the model ended it by choice.
Install
Standard for the pack - clone into custom_nodes, install soundfile, download the ~4.3 GB weights, restart.
cd ComfyUI/custom_nodes
git clone https://github.com/hiroki-abe-58/ComfyUI-SemBridge
python -m pip install -r ComfyUI-SemBridge/requirements.txt
python ComfyUI-SemBridge/tools/download_model.py --models-dir ComfyUI/models/sembridge
Don't pip install sembridge - its metadata pins torch below 2.9 and the model code is already vendored in the pack. There's a ready graph at workflows/gui/singing_basic.json.
Where it stumbles
It clips. The output is clamped, never scaled down, and in the author's 18-request automatic test five clips touched full scale and one had 2% of samples clamped. Check levels before you ship anything and normalise in post. Loudness varies a lot in general - official examples run from -12 to -31 dBFS RMS - so a fixed post gain won't save you either.
High register is weak. Scores with wide leaps up in MIDI 72–79 failed on all three seeds tried, missing by 2.4 to 4.2 semitones, and one run never stopped and went to the length cap. The same test stayed within about half a semitone in the median down in MIDI 48–72. Humbling, but useful: write for the lower octaves.
It's not real time. Singing and mixed generation run at roughly 2.3 to 2.8 seconds of compute per second of audio, so a 30-second chorus is over a minute of waiting on a 5090. Iterate on short phrases.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| model | SEMBRIDGE_MODEL | — | |
| score | STRING | la 60 0.5 la 62 0.5 la 64 1.0 <SP> 0 0.4 | One note per line: lyric pitch duration_seconds [note_type]. Lines starting with # are ignored. A JSON list of {text, pitch, duration, note_type} also works. |
| length_control | COMBO | from_score | from_score: min/max patches = 0.5x / 1.8x the score length, as in the official singing examples. manual: use the two values below. |
| seed | INT | 420–18446744073709550000 | Fixes the reference-audio sampling and the generation. Same model, request, seed, settings and environment give the same audio. |
| decoder | COMBO | auto | auto = the official default (native causal decoder for speech, BigVGAN-Large for singing and mixed). native / bigvgan force one decoder for any task. |
| max_new_patches | INT | 5001–8000 | Used when length_control = manual. One patch is 80 ms of audio. max_new_patches=500 is a 40 s upper bound, not a target length: generation stops earlier when the model decides the text is finished. |
| min_new_patches | INT | 20–8000 | Used when length_control = manual. |
| flow_steps | INT | 202–100 | Flow-matching steps per patch. The official singing examples use 20. |
| cfg_value | FLOAT | 2.00–10 | — |
| temperature | FLOAT | 1.000–2 | — |
| prompt_audioopt | AUDIO | Optional reference recording of a voice you have the right to use. Only the first item of a batch is used. | |
| prompt_textopt | STRING | The exact transcript of prompt_audio. For a sung reference use the score token string (see SemBridge Score Preview). | |
| prompt_taskopt | COMBO | auto | What the reference is: spoken or sung. auto = singing for the Singing node, speech otherwise. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| audio | AUDIO | — |
| report | STRING | — |