ROCm Seed Voice Conversion
Same words, different voice — the node that re-sings a track in someone else's timbre
- source_audio
- reference_audio
- audio
- accompaniment
Voice conversion is not text-to-speech, and conflating the two is why people bounce off this node. TTS invents a performance from a script; this keeps the one you already have - words, timing, breaths, and melody if it's a sung take - and swaps the timbre underneath. Feed it a recording and a voice, get the recording back in that voice.
Where it sits in the audio pile
Audio is the thinnest layer in ComfyUI: node packs bolted onto a stack that was never built for sound. TTS is the crowded, essentially solved corner (Chatterbox, Kokoro, F5). Voice conversion is a different job with a thinner toolchain. The long-standing open answer is RVC, which needs a trained model per voice. Seed-VC is zero-shot - a few seconds of reference, no training run - so if you want to audition nine voices in an afternoon, this is the shortcut.
A voice is also a legally protected thing in a growing pile of jurisdictions - Tennessee's ELVIS Act was the first state law to extend a right of publicity to AI simulations of a person's voice, and several states cover cloned voices explicitly. Get consent.
How it actually works
Two pipelines sit inside the node. Speech mode (f0_condition off) conditions a flow-matching DiT on whisper-small features plus a CAM++ speaker embedding, and BigVGAN vocodes the result at 22.05 kHz. Singing mode (f0_condition on) switches to a 44.1 kHz F0-conditioned model with RMVPE pitch extraction, so the melody survives the voice swap. Long sources are chunked into 30-second windows with a ~745 ms crossfade, which is why prompt_length is a seam knob as much as a speed knob.
The inputs that matter
Two are required: source_audio (what you keep, downmixed to mono) and reference_audio (the voice to adopt - 3 to 25 seconds, truncated past 25). Then, roughly in order of impact:
f0_condition- the switch that matters. Off for speech, on for singing; it also decides the output sample rate.precision- leave it onfp16. The vocoder dominates runtime, and half precision is the AMD win: ~6x faster vocoding, ~2x end to end on gfx1151.steps(30) andinference_cfg_rate(0.7). Under ~16 steps, detail smears. A CFG rate of 0 disables guidance and halves sampling cost.prompt_length(10 s) - how much reference goes in as the in-context prompt. Shorter is faster and seams less; timbre and pitch matching still use the full reference.separate_source- split vocal from instrumental first (mel-band roformer karaoke) and convert only the vocal.
Singing-only: auto_f0_adjust (matches source pitch level to the reference, on), pitch_shift (±24 semitones, for when the reference sits much lower or higher), vibrato_transfer (1.0 copies the source's vibrato and glides; 0 for the raw model). speed rescales output duration, and unload_model frees the models after the run - leave it off, reloading costs ~30 seconds.
Outputs and wiring
audio is the converted take, same length as the source - wire it to SaveAudio. accompaniment is the instrumental when separate_source is on; the core AudioMerge node puts the song back together. With separation off it's a silent same-length track rather than None, so leaving it wired breaks nothing.
LoadAudio(source) ──> source_audio
LoadAudio(ref) ──> reference_audio ──> ROCmSeedVoiceConversion ──> SaveAudio / AudioMerge
Installing it
ComfyUI Manager, search rocm-ninodes - or clone it. It's built for AMD/ROCm but isn't AMD-only; it uses whatever torch device it finds.
cd ComfyUI/custom_nodes
git clone https://github.com/iGavroche/rocm-ninodes.git ComfyUI-ROCM-Optimized-VAE
cd ComfyUI-ROCM-Optimized-VAE && python install.py
install.py pip-installs the pack's requirements (numpy, Pillow, psutil, gguf, safetensors, plus librosa and scipy for this node); torch, torchaudio, transformers and PyYAML come from your ComfyUI environment. separate_source additionally wants pip install audio-separator, deliberately absent from requirements. Coming from v1, run uv run python tools/upgrade_to_v2.py first, then restart completely. The node lands under 🎛 ROCm/audio.
The models are the real install
Seven things have to exist under ComfyUI/models/TTS/: four Plachta/Seed-VC checkpoints (DiT_seed_v2_uvit_whisper_small_wavenet_bigvgan_pruned.pth, DiT_seed_v2_uvit_whisper_base_f0_44k_bigvgan_pruned_ft_ema_v2.pth, campplus_cn_common.bin, rmvpe.pt), the openai/whisper-small folder, and the two nvidia BigVGAN vocoder folders (bigvgan_v2_22khz_80band_256x, bigvgan_v2_44khz_128band_512x). hf download <repo> --local-dir models/TTS/… fetches each.
Two traps. The BigVGAN folders must physically exist - a missing path is treated as a Hugging Face repo id and fails. And the singing checkpoint must be the _ft_ema_v2 file; the old name isn't loaded any more. With separate_source on, the ~1.7 GB karaoke checkpoint downloads itself into models/TTS/Seed-VC/separator/ on first use.
Where it goes wrong
The node isn't in the menu. The console prints ROCmSeedVoiceConversion unavailable: … when a vendored import fails - usually transformers, torchaudio or yaml missing from the ComfyUI environment. One bad import hides the node instead of exploding it, so read the console before reinstalling anything.
FileNotFoundError under models/TTS/Seed-VC. One of the four checkpoints isn't where it expects. By far the most common failure, and always a path problem.
Garbage pitch on a full mix in singing mode. RMVPE will happily track the bass line and the converted vocal wanders. Turn on separate_source, or split upstream, so only the vocal reaches the pitch tracker.
precision=fp16 doing nothing. It's conditional on a GPU device; on CPU or MPS the vocoder stays fp32 and you're in for a long wait. This is a GPU node pretending to be polite about it.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| source_audio | AUDIO | Recording whose content and rhythm are kept. | |
| reference_audio | AUDIO | Voice to adopt (3-25 s; longer is truncated to 25 s). | |
| steps | INT | 301–200 | Flow-matching steps. Below ~16 starts smearing detail. |
| speed | FLOAT | 1.000.25–4 | Length adjust factor on the output duration. |
| inference_cfg_rate | FLOAT | 0.700–1 | Classifier-free guidance rate. 0 disables it and halves sampling cost. |
| prompt_length | FLOAT | 10.03–25 | Seconds of reference used as the in-context prompt. Shorter = fewer chunk seams and faster; timbre and pitch matching still use the full reference. |
| f0_condition | BOOLEAN | false | Required for singing voice conversion; uses the 44.1 kHz F0 model. |
| auto_f0_adjust | BOOLEAN | true | Match the source pitch level to the reference. F0 model only. |
| pitch_shift | INT | 0-24–24 | Extra semitone shift on the source pitch. F0 model only. |
| vibrato_transfer | FLOAT | 1.000–1 | Copy the source's vibrato and note glides onto the converted vocal. 0 keeps the raw model output; lower for a more literal pitch. F0 model only. |
| precision | COMBO | fp16 | fp16 runs the BigVGAN vocoder at half precision; ~6x faster on gfx1151. |
| unload_model | BOOLEAN | false | Free the loaded models after this run. Keep off: reloading costs ~30 s. |
| separate_source | BOOLEAN | false | Split the source into vocal + instrumental first; converts the vocal and outputs the instrumental on the accompaniment socket. Needs audio-separator. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| audio | AUDIO | — |
| accompaniment | AUDIO | — |