Signed-off-by: Sysy <1370724210@qq.com> Co-authored-by: Yueqian Lin <70319226+linyueqian@users.noreply.github.com>
11 KiB
IndexTTS-2.5 for multilingual voice-cloned TTS on 1x GPU
Summary
- Vendor: IndexTeam
- Model:
IndexTeam/IndexTTS-2.5 - Task: Multilingual text-to-speech with voice cloning, emotion control, and native speed control
- Mode: Online serving with the OpenAI-compatible
/v1/audio/speechAPI, or offline inference throughOmni - Maintainer: Community
When to use this recipe
Use this recipe to serve IndexTTS-2.5 as a two-stage TTS system. Stage 0 is an autoregressive talker; Stage 1 uses EnhancedCodec, S2Mel CFM/DiT, and BigVGAN to produce 22.05 kHz mono speech. Each request supplies synthesis text and reference audio, or an uploaded audio voice, for zero-shot voice cloning.
IndexTTS-2.5 adds multilingual text processing and model-native speed control to the IndexTTS-2 serving contract.
References
- Upstream model: IndexTeam/IndexTTS-2.5 on Hugging Face
- Online serving example:
examples/online_serving/text_to_speech/README.md#indextts-2-and-indextts-25 - Offline inference example:
examples/offline_inference/text_to_speech/README.md#indextts-2-and-indextts-25 - OpenAI-compatible client:
examples/online_serving/text_to_speech/indextts2/speech_client.py - Standard deploy config:
vllm_omni/deploy/indextts2_5.yaml
Hardware Support
GPU
1x NVIDIA H20 96GB
Environment
- OS: Linux
- Python: 3.10+
- Driver / runtime: NVIDIA CUDA environment
- vLLM version: Match the repository requirements for your checkout
- vLLM-Omni version or commit: Use the commit you are deploying from
Install vLLM-Omni with the IndexTTS text-processing dependencies:
pip install 'vllm-omni[indextts2]'
Obtain the native IndexTTS-2.5 bundle and point MODEL at its root. The model
loader accepts the upstream nested checkpoints/ layout.
Command
Start the standard code-only server from the repository root:
MODEL_VERSION=2.5 \
MODEL=/path/to/indextts-2.5 \
bash examples/online_serving/text_to_speech/indextts2/run_server.sh
This selects vllm_omni/deploy/indextts2_5.yaml, which uses
use_gpt_latent=false. To launch directly:
vllm serve /path/to/indextts-2.5 \
--omni \
--trust-remote-code \
--port 8092 \
--deploy-config vllm_omni/deploy/indextts2_5.yaml
Optional: NVIDIA MPS for higher single-GPU throughput
Stage 0 and Stage 1 run in separate processes on the same GPU. Enabling NVIDIA Multi-Process Service (MPS) can improve steady-state throughput by allowing work from both stages to overlap more effectively. MPS is an opt-in deployment optimization: this recipe does not start it automatically, and the gain depends on the request mix and concurrency, so benchmark it with the intended workload before enabling it in production.
Pay attention to CUDA device renumbering. For example, if the MPS control
daemon is started with physical CUDA_VISIBLE_DEVICES=1, that GPU is exposed
to MPS clients as logical device 0; launch the server with
CUDA_VISIBLE_DEVICES=0, not 1. Use a dedicated MPS pipe/log directory when
the host is shared with other services, and stop only the MPS daemon owned by
this deployment.
Verification
Send a multilingual voice-cloning request with the bundled client. Local audio paths are converted to base64 data URLs before transmission:
python examples/online_serving/text_to_speech/indextts2/speech_client.py \
--api-base http://localhost:8092 \
--model-version 2.5 \
--model /path/to/indextts-2.5 \
--lang zh \
--text "你好,这是 IndexTTS-2.5 语音合成测试。" \
--ref-audio /path/to/reference.wav \
--output indextts2_5.wav
Native speed control
The public speed field is handled natively. Its accepted range is
[0.5, 2.0]; values above 1.0 produce shorter, faster speech. The serving
adapter converts the API convention to the model-native control with
duration_factor = 1.0 / speed, so speed=1.25 uses
duration_factor=0.8:
python examples/online_serving/text_to_speech/indextts2/speech_client.py \
--api-base http://localhost:8092 \
--model-version 2.5 \
--model /path/to/indextts-2.5 \
--speed 1.25 \
--text "这是使用模型原生语速控制的测试。" \
--ref-audio /path/to/reference.wav \
--output indextts2_5_speed.wav
Upload and reuse a named voice
Upload a reference recording once when callers should reuse the same voice
without sending ref_audio on every request. consent is required by the
voice-storage API:
curl -X POST http://localhost:8092/v1/audio/voices \
-F "audio_sample=@/path/to/reference.wav" \
-F "consent=user-consent-id" \
-F "name=indextts_demo_voice" \
-F "speaker_description=IndexTTS-2.5 demonstration voice"
Confirm that the voice was stored, then synthesize with its name instead of a reference-audio payload:
curl http://localhost:8092/v1/audio/voices
python examples/online_serving/text_to_speech/indextts2/speech_client.py \
--api-base http://localhost:8092 \
--model-version 2.5 \
--model /path/to/indextts-2.5 \
--voice indextts_demo_voice \
--lang zh \
--text "你好,这是复用已上传音色的语音合成测试。" \
--output indextts2_5_named_voice.wav
There are no built-in text-only preset voices. Each named IndexTTS voice must first be created from an uploaded reference recording.
Multilingual synthesis and text normalization
The client accepts zh (Mandarin), en (English), zhen (mixed Chinese and
English), ja (Japanese), and yue (Cantonese). The following commands use
the same reference voice across all supported language modes:
CLIENT=examples/online_serving/text_to_speech/indextts2/speech_client.py
MODEL=/path/to/indextts-2.5
REF_AUDIO=/path/to/reference.wav
python "$CLIENT" --model-version 2.5 --model "$MODEL" \
--ref-audio "$REF_AUDIO" --lang zh \
--text "你好,这是中文语音合成测试。" --output indextts2_5_zh.wav
python "$CLIENT" --model-version 2.5 --model "$MODEL" \
--ref-audio "$REF_AUDIO" --lang en \
--text "Hello, this is an English speech synthesis test." \
--output indextts2_5_en.wav
python "$CLIENT" --model-version 2.5 --model "$MODEL" \
--ref-audio "$REF_AUDIO" --lang zhen \
--text "Hello,欢迎使用 IndexTTS 二点五。" --output indextts2_5_zhen.wav
python "$CLIENT" --model-version 2.5 --model "$MODEL" \
--ref-audio "$REF_AUDIO" --lang ja \
--text "こんにちは、これは日本語の音声合成テストです。" \
--output indextts2_5_ja.wav
python "$CLIENT" --model-version 2.5 --model "$MODEL" \
--ref-audio "$REF_AUDIO" --lang yue \
--text "你好,呢段係粵語語音合成測試。" --output indextts2_5_yue.wav
Text normalization is enabled by default. Disable it only when the input is already written exactly as it should be spoken:
python examples/online_serving/text_to_speech/indextts2/speech_client.py \
--model-version 2.5 --model /path/to/indextts-2.5 \
--ref-audio /path/to/reference.wav --lang en --no-text-normalization \
--text "The temperature is twenty five degrees." \
--output indextts2_5_pre_normalized.wav
For raw HTTP requests, put the same language and text-normalization controls
under extra_params:
curl http://localhost:8092/v1/audio/speech \
-H "Content-Type: application/json" \
-d '{
"model": "/path/to/indextts-2.5",
"input": "This is an IndexTTS-2.5 test.",
"response_format": "wav",
"speed": 1.0,
"ref_audio": "data:audio/wav;base64,<BASE64_ENCODED_AUDIO>",
"extra_params": {
"lang": "en",
"text_normalization": true
}
}' \
--output indextts2_5_en.wav
Emotion control
IndexTTS-2.5 supports an explicit eight-value emotion vector, an emotion text
description, or a separate emotion-reference recording. Use one source at a
time. Vector values are ordered as happy, angry, sad, afraid,
disgusted, melancholic, surprised, and calm; each value must be in
[0, 1.2]. emo_alpha controls the strength in [0, 1].
Use an explicit emotion vector for deterministic control:
python examples/online_serving/text_to_speech/indextts2/speech_client.py \
--model-version 2.5 --model /path/to/indextts-2.5 \
--ref-audio /path/to/reference.wav --lang zh \
--text "今天真是令人开心的一天!" \
--emo-vector 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 \
--emo-alpha 0.8 --output indextts2_5_happy_vector.wav
Infer the emotion from a natural-language description with use_emo_text:
python examples/online_serving/text_to_speech/indextts2/speech_client.py \
--model-version 2.5 --model /path/to/indextts-2.5 \
--ref-audio /path/to/reference.wav --lang zh \
--text "我们终于完成了这项工作!" \
--use-emo-text --emo-text "开心、兴奋而且充满活力" \
--emo-alpha 0.8 --output indextts2_5_happy_text.wav
Transfer emotion from a recording while retaining the speaker identity from
ref_audio:
python examples/online_serving/text_to_speech/indextts2/speech_client.py \
--model-version 2.5 --model /path/to/indextts-2.5 \
--ref-audio /path/to/reference.wav --lang zh \
--text "请用情绪参考音频中的表达方式朗读这句话。" \
--emo-audio /path/to/emotion_reference.wav \
--emo-alpha 0.8 --output indextts2_5_emotion_audio.wav
If multiple emotion sources are supplied, the official precedence is
use_emo_text > emo_vector > emo_audio > the emotion in the speaker
reference. --use-random is also available for exploratory random emotion
prototypes, but should not be used when reproducible conditioning is required.
For offline inference:
python examples/offline_inference/text_to_speech/indextts2/end2end.py \
--model /path/to/indextts-2.5 \
--model-version 2.5 \
--lang zh \
--speed 1.0 \
--text "你好,这是离线语音合成测试。" \
--ref-audio /path/to/reference.wav
Notes
- Hardware scope: the standard recipe has been exercised on one NVIDIA H200. It does not claim an unverified throughput or quality result.
- Audio output: 22.05 kHz mono WAV.
- Voice cloning: reference audio is required on the documented raw request
path. Alternatively,
voicemay name an uploaded audio voice; there is no built-in text-only preset voice. - Native speed: serving maps
speedto the model's duration factor and skips generic waveform speed adjustment, so speed is applied exactly once. - Languages: common codes include
zh,en,zhen(mixed Chinese/English),ja, andyue;Mandarinis accepted as an alias forzh. - Japanese normalization:
jatokenization does not automatically expand numbers, dates, or percentages. Write these inputs as readable Japanese text before inference. - Emotion controls:
use_emo_text,emo_vector, andemo_audioare alternative conditioning modes. Their precedence isuse_emo_text>emo_vector>emo_audio> the speaker-reference emotion. - Sampling difference: Stage 0 uses plain vLLM sampling, not the upstream
default
num_beams=3beam search. Use upstreamnum_beams=1for parity comparisons; output may differ from the official beam-search result.