Nodes/IndexTTS 2 / 2.5/IndexTTS 2 / 2.5 Synthesize
ComfyUI Node

IndexTTS 2 / 2.5 Synthesize

Clone a voice from a few seconds of audio and make it say anything — IndexTTS 2/2.5 Synthesize

By joyfoxai·Created about a month ago·Updated 25 days ago· 1
IndexTTS 2 / 2.5 Synthesize
  • model
  • speaker_audio
  • emotion_audio
  • audio
text欢迎使用 IndexTTS 2.5。
languageZH
emotion_modesame_as_speaker
emotion_weight0.65
extra_emotion_text
happy0.00
angry0.00
sad0.00
fearful0.00
disgusted0.00
melancholic0.00
surprised0.00
calm0.00
emotion_randomfalse
duration_factor1.00
interval_silence_ms200
text_normalizationtrue
max_text_tokens_per_segment120
do_sampletrue
temperature0.8
top_p0.80
top_k30
num_beams3
repetition_penalty10.0
length_penalty0.0
max_mel_tokens1500
seed0

This is the node you actually came for. IndexTTS 2 / 2.5 Synthesize is where the joyfoxai/ComfyUI-Index-TTS-25 pack turns a few seconds of someone's voice plus some text into new speech in that voice - narration, dubbing, a character that says whatever you want. It's zero-shot voice cloning, all local, no API key. The KB's audio essay sums up the state of play: open TTS closed the cloning gap, and IndexTTS 2.5 is one of the few open models that also does it across multiple languages (ZH, EN, JA, AR, ES - where IndexTTS 2 is limited to ZH/EN).

It's the star of the pack, but it needs the Model Loader feeding it a model handle and a Load Audio node for the reference clip. The pipeline is tiny: Loader → Synthesize → Preview/Save Audio.

How it works

Under the hood the node writes your speaker_audio to a temp WAV, calls IndexTTS's infer() with your text, language and emotion settings, and converts the raw result back into a standard ComfyUI AUDIO. Two details are worth knowing because they explain real-world behavior:

  • The clipping fix. TorchAudio 2.9 changed how it saves int16 PCM and can turn IndexTTS output into a fully-clipped, harsh/near-white-noise WAV. This node normalizes the native int16 result to float, so you shouldn't hear that. If you do get garbage, your setup lost that normalization.
  • Reproducibility. The seed input seeds Python's random, NumPy, and torch at once - same seed, same audio.

The inputs that matter

The schema is long - roughly 30 inputs - but most have sane defaults. A beginner sets these:

  • model - from the Model Loader. Non-negotiable.
  • speaker_audio - your reference clip. This is the make-or-break input, see troubleshooting.
  • text - what the voice should say.
  • language - ZH/EN/JA/AR/ES on 2.5. Pick JA on IndexTTS 2 and it errors out - that's by design, v2 only does ZH/EN.
  • emotion_mode - five options, default same_as_speaker (match the reference's mood). reference_audio needs the optional emotion_audio input connected; emotion_vector lights up the eight sliders (happy, angry, sad, fearful, disgusted, melancholic, surprised, calm); emotion_text infers emotion from the synthesized text; extra_emotion_text reads it from a separate field. emotion_weight (0.65) scales whatever mode you picked.

Beyond that: duration_factor (0.5–2.0, 2.5 only) is your speed dial, interval_silence_ms sets the gap between segments, and do_sample/temperature/top_p/top_k/num_beams/repetition_penalty are GPT-tokenizer sampling knobs - the defaults are fine for a first run. Both duration_factor and text_normalization are silently ignored on IndexTTS 2, so don't panic when nothing changes.

The output

One output, audio (type AUDIO). Wire it to Preview Audio or Save Audio, or feed it into a talking-head pipeline (InfiniteTalk, Wan S2V, MMAudio-style foley).

Getting good clones - the part people actually struggle with

The community's hard-won lesson with IndexTTS is that the reference audio dominates the result. Loud, dynamic, expressive references - podcast-style speech - clone far better than quiet, slow, monotone ones. If your clone sounds weak or flat, don't touch the node settings first; swap in a livelier reference clip. On IndexTTS 2, words with apostrophes (don't, it's) historically get mangled - write them as dont, its. And since bf16 on v2 is secretly FP16, thin output on an IndexTTS 2 model is a sign to try fp32 on the Loader.

Install

Same as the rest of the pack - clone, install requirements into ComfyUI's Python, download models:

cd ComfyUI/custom_nodes
git clone https://github.com/joyfoxai/ComfyUI-Index-TTS-25.git
cd ComfyUI
python -m pip install -r custom_nodes/ComfyUI-Index-TTS-25/requirements.txt
cd custom_nodes/ComfyUI-Index-TTS-25
./download_models.sh all

Then restart ComfyUI; the nodes live under right-click → audio → IndexTTS. If the model loads but synthesis fails, the usual culprits are missing fugashi/unidic-lite (Japanese deps, needed even for Chinese), or an incomplete model download - re-run the download script.

Errors you'll hit and what they mean

  • Text must not be empty - obvious, but the node won't guess.
  • emotion_audio must be connected in reference_audio mode - you picked a mode without wiring its input. Either connect emotion_audio or switch modes.
  • extra_emotion_text must not be empty in extra_emotion_text mode - same deal on the text side.
  • IndexTTS 2 + a non-ZH/EN language → explicit error telling you it needs 2.5. Fair.

It's not perfect, it's not ElevenLabs, and this pack is young. But for local, private, no-key voice cloning that you fully control, it's genuinely good - and it finally gives ComfyUI a real multilingual voice.

Categoryaudio/IndexTTS

Inputs (30)

NameTypeDefaultDescription
modelINDEXTTS25_MODEL
speaker_audioAUDIO
textSTRING欢迎使用 IndexTTS 2.5。
languageCOMBOZH5 options: ZH, EN, JA, AR, ES
emotion_modeCOMBOsame_as_speaker5 options: same_as_speaker, reference_audio, emotion_vector, emotion_text, extra_emotion_text
emotion_weightFLOAT0.650–1
extra_emotion_textSTRING
happyFLOAT0.000–1
angryFLOAT0.000–1
sadFLOAT0.000–1
fearfulFLOAT0.000–1
disgustedFLOAT0.000–1
melancholicFLOAT0.000–1
surprisedFLOAT0.000–1
calmFLOAT0.000–1
emotion_randomBOOLEANfalse
duration_factorFLOAT1.000.5–2
interval_silence_msINT2000–5000
text_normalizationBOOLEANtrue
max_text_tokens_per_segmentINT12020–400
do_sampleBOOLEANtrue
temperatureFLOAT0.80.1–2
top_pFLOAT0.800–1
top_kINT300–100
num_beamsINT31–10
repetition_penaltyFLOAT10.00.1–20
length_penaltyFLOAT0.0-2–2
max_mel_tokensINT150050–4096
seedINT00–9223372036854776000
emotion_audiooptAUDIO

Outputs (1)

NameTypeDescription
audioAUDIO