IndexTTS 2.5 Speech Generation
Cloning a voice in ComfyUI with IndexTTS 2.5, start to finish
- model
- speaker_audio
- emotion
- sampling
- Generated Audio
This is the node you actually came for. IndexTTS 2.5 Speech Generation is the whole point of the pack: feed it a clip of someone talking plus a line of text, and it returns audio of that person saying that line - zero-shot voice cloning, no fine-tuning, no API key. Give it a 0.25-second reference and it'll do it; give it ten seconds of someone reading a podcast and it'll do it better. Output is a standard ComfyUI AUDIO signal, which means it drops straight into audio save nodes, VHS, or anything else that eats audio.
If you've poked around ComfyUI's TTS scene before, this is the same territory as F5-TTS or Chatterbox, but from the IndexTTS side of the fence - and the 2.5 release is where that family went properly multilingual (Chinese, English, Japanese, Spanish, Arabic) and added the emotion machinery covered in its sibling node. For local voice cloning in a ComfyUI workflow, this is currently one of the strongest options, with the usual caveat that TTS packs like this live at the edge of the ecosystem: they work great and break in their own special dependency-shaped ways.
How it works
The pipeline is: reference audio in → normalize → clone voice while synthesizing your text → audio out. The cloning is baked into the model's forward pass, not grafted on after - the model conditions on the reference's speaker embedding, which is why it needs so little of it.
The one design decision worth understanding is loudness. The reference gets de-DC'd and normalized to −20 dBFS (gated-RMS, peak-limited at −3 dBFS) before the model sees it, so cloning is stable no matter how quiet or loud your sample is. Meanwhile the original loudness is remembered, and the Output Normalization dropdown decides what the result does with it:
- match reference (default) - output is scaled back to the same loudness as your reference. Loud in, loud out.
- rms -16 dB - fixed broadcast-style level, which is what you want when stitching several segments into one file so the volume doesn't jump between them.
- peak -1 dB - peak normalization only.
- off - raw model output.
That normalization was added in the pack's 2.0.0 update, and it's genuinely the difference between "this clone is too quiet / blows my ears off" and "this just works."
The inputs that matter
- Speaker Reference Audio (
speaker_audio, anAUDIOinput) - wire up any audio that contains the voice to clone. - Text to Synthesize - plain text, supports ComfyUI dynamic prompt syntax, and you can force pronunciations inline with the
<字|读音>notation for names or tricky words. - Language - one of
ZH/EN/JA/ES/AR. Match it to the text. - Duration Factor (0.5–2.0) - smaller is faster; useful when you need to cram a line into a timed video.
- seed - your standard determinism knob, with control-after-generate.
Then the two optional wires that unlock the rest of the pack: Emotion Control (leave unconnected and it follows the reference's voice) and Sampling Config (leave unconnected for the pack's stable defaults). You don't need either to get good output on day one.
Where people get burned
First, the reference clip matters more than any other setting. Community testing of the IndexTTS family found that loud, dynamic, expressive samples - podcast energy - clone dramatically better than quiet, flat ones like a hushed audiobook take. If your clone sounds dead, the fix is usually a livelier reference, not more settings. Second, the family has a documented allergy to apostrophes: "don't" can garble where "dont" doesn't. If a line comes out mangled, that's the first thing to try. Third, if you're on the boundary of your VRAM, the Model Loader's release_after_run toggle beats fighting OOM errors mid-render.
Install the pack, pull the ~5GB model into models/TTS/IndexTTS-2.5/, restart, and you're up:
cd ComfyUI/custom_nodes
git clone https://github.com/xiaozhuguang/Comfyui-indextts25-xzg.git
python -m pip install -r custom_nodes/Comfyui-indextts25-xzg/requirements.txt
python scripts/download_models.py --source huggingface --accept-license
The transformers<5.0 pin is load-bearing - if another plugin upgrades you to 5.x, you'll hit ImportError: cannot import name 'OffloadedCache', and the fix is reinstalling the pinned version. Do that, restart, and you've got a voice clone running locally in a node graph.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| model | XZG_INDEXTTS25_MODEL | — | |
| speaker_audio | AUDIO | — | |
| text | STRING | Welcome to IndexTTS 2.5. | — |
| language | COMBO | ZH | 5 options: ZH, EN, JA, ES, AR |
| duration_factor | FLOAT | 1.000.5–2 | — |
| seed | INT | 00–18446744073709550000 | — |
| output_normalization | COMBO | match reference | match reference: the output is scaled to the same gated-RMS level as the speaker reference audio you fed in (loud in = loud out). rms -16 dB: fixed broadcast level with -1 dB peak ceiling. peak -1 dB: peak normalization only. off: raw model output. |
| emotionopt | XZG_INDEXTTS25_EMOTION | Follows the voice reference when not connected. | |
| samplingopt | XZG_INDEXTTS25_SAMPLING | Uses stable defaults when not connected. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| Generated Audio | AUDIO | — |