Nodes/ComfyUI-GGUF-Loader/OmniVoice Voice Clone TTS ⚡
ComfyUI Node

OmniVoice Voice Clone TTS ⚡

Ten good seconds of audio is the whole trick

By ChrisColeTech·Created 2 months ago·Updated 3 days ago· 26
OmniVoice Voice Clone TTS ⚡
  • omnivoice_model
  • ref_audio
  • whisper_model
  • audio
◄textHello! This is a test of voice cloning with OmniVoice.►
◄ref_text►
◄steps32►
◄guidance_scale2.0►
◄t_shift0.10►
◄speed1.0►
◄duration0.0►
◄seed0►
◄position_temperature5.0►
◄class_temperature0.0►
◄layer_penalty_factor5.0►
◄denoisetrue►
◄preprocess_prompttrue►
◄postprocess_outputtrue►
◄instruct►

Everyone's first TTS workflow is the same: you type a sentence, you get a voice, it sounds like a GPS unit. That's not what you want. What you want is that voice - the one in the clip you already have - reading your new line. This node is the shortest path to that in ComfyUI, and unlike most zero-shot cloning setups, it doesn't care which of OmniVoice's 600+ languages you're feeding it.

OmniVoice (k2-fsa) is a diffusion-language-model TTS, which puts it in a different family from the fast vocoder stuff - Kokoro is the real-time, 82M-parameter, "plausible generic voice" option; OmniVoice is the multilingual, cloning-first one that wants a few GB of VRAM and a couple dozen sampling steps. If your job is narration or character dialogue and the voice has to be a specific voice, this is the node.

What it does, mechanically

Two things happen before the model runs, and both of them are about your reference clip.

First, the audio gets normalized. ref_audio is a Comfy AUDIO value, and whatever comes in - stereo, 44.1 kHz, 48 kHz - is downmixed to mono and resampled to 24 kHz before it touches the model. That resample uses soxr if it's installed and a plain torch linear interpolation if it isn't. Install soxr. It's one small package and it's the difference between a clean reference and an aliased one.

Second, if you leave ref_text empty it goes looking for a transcript: your connected whisper_model first, then a local Whisper folder in models/audio_encoders/, then OmniVoice's own internal ASR. Before any of that, if preprocess_prompt is on and the clip runs past 20 seconds, it silence-trims the reference to at most 15 - a rambling two-minute reference is worse input than a tight ten-second one.

Then it generates, seeds everything from seed, and hands you back mono AUDIO at 24 kHz.

The inputs that actually matter

You set four things and ignore the rest for your first week.

ref_audio is required here, not optional - that's the main difference from the Longform node. The tooltip says 3–15 seconds of clear speech, and the code agrees loudly: it warns on anything under a second or over thirty. Treat 8–12 seconds of clean, single-speaker, no-music audio as the target.

text is what the cloned voice will say. ref_text is the transcript of the reference clip - not your prompt. Leave it empty and it gets transcribed for you; fill it in by hand when you know exactly what's being said, because the transcript is part of the conditioning, and a transcript that carries the clip's real pacing beats a flat auto-transcript.

Then the samplers. steps defaults to 32 and that's a fine place to be; guidance_scale defaults to 2.0, which is low by image-model standards and correct here. seed is the trap: 0 means random, so every queue gives you a different take. Fine while you're exploring, terrible once you've got a good one - pin a real number before you walk away.

speed (0.5–2.0) is the length dial you'll actually use. duration defaults to 0, meaning "decide from the text"; setting it asks for a fixed-length read, which is a different and fussier request.

instruct is the dialect/style field, and it's the honest weak spot. The tooltip warns it takes model-supported comma-separated values, and the code errors clearly on anything else. Even when valid, community reports on OmniVoice's emotional tags - the [laughter], [sigh], [question-oh] family - are that they're hit-or-miss and sometimes get read aloud as words. Don't build a deliverable on them. denoise, preprocess_prompt and postprocess_output stay on; t_shift, position_temperature, class_temperature and layer_penalty_factor are for people chasing a specific defect, not for you yet.

Wiring it up

Output is a single audio socket. That goes to SaveAudio or PreviewAudio if speech is the deliverable, or into CreateVideo's audio input if you're driving an avatar - the standard local talking-head pipeline is TTS first, then an audio-driven model like InfiniteTalk or MultiTalk for the face, and the voice is never the bottleneck. The GPU budget is always the picture.

cd ComfyUI/custom_nodes
git clone https://github.com/ChrisColeTech/ComfyUI-GGUF-Loader
cd ComfyUI-GGUF-Loader
python -m pip install omnivoice==0.2.1 "transformers>=5.3.0" soxr

ComfyUI Manager finds it as ComfyUI-GGUF-Loader. You need CCTechOmniVoiceModelsLoader upstream feeding omnivoice_model - this node doesn't load weights by itself, and the model auto-downloads (a few GB) the first time the loader runs. No Whisper install is required unless you want to supply your own via whisper_model.

Where people get burned

ref_audio carries no valid sample_rate means something upstream built an audio dict without a usable rate - usually a LoadAudio on an odd file, not a bug in the node.

The bigger one is dependency aftermath. transformers>=5.3.0 is a real floor, deliberately not hidden behind an import-time installer - and in an install already held together by three other packs' pins, that bump is how you break something that worked yesterday. If unrelated nodes start failing after you install this, look there first.

And the last one isn't an error at all: a rushed, noisy, clipped reference produces a rushed, noisy, clipped voice, and no amount of steps fixes it. The reference is the voice.

Category🤖 CCTech/OmniVoice

Inputs (18)

NameTypeDefaultDescription
omnivoice_modelOMNIVOICE_MODEL—
textSTRINGHello! This is a test of voice cloning with OmniVoice.—
ref_audioAUDIO3-15 seconds of clear speech works best.
ref_textSTRINGReference transcript. Empty uses connected/local/internal Whisper.
stepsINT324–64—
guidance_scaleFLOAT2.00–10—
t_shiftFLOAT0.100–1—
speedFLOAT1.00.5–2—
durationFLOAT0.00–60—
seedINT00–2147483647Random seed. 0 = random.
position_temperatureFLOAT5.00–20—
class_temperatureFLOAT0.00–5—
layer_penalty_factorFLOAT5.00–20—
denoiseBOOLEANtrue—
preprocess_promptBOOLEANtrue—
postprocess_outputBOOLEANtrue—
instructSTRINGA model-supported comma-separated dialect/style instruction.
whisper_modeloptWHISPER_ASR—

Outputs (1)

NameTypeDescription
audioAUDIO—