index-tts-2.5-onnx
IndexTTS-2.5 voice cloning on ONNX Runtime — fp32, bit-exact against the PyTorch CPU reference, torch-free, and ships as a one-click uvx package that auto-downloads the weights from Hugging Face. Runs anywhere ONNX Runtime runs: Linux / Windows / macOS, x86 / ARM, CPU or NVIDIA GPU (CUDA).
- Voice cloning from a short reference clip (≤15 s) — Chinese / English / Japanese / Cantonese, including mixed-language text with numbers and abbreviations.
- Bit-exact fp32: greedy decoding reproduces the PyTorch CPU reference acoustic tokens exactly (73/73 and 83/83 on the verification fixtures); every stage matches at cosine ≥ 0.9999.
- Torch-free: numpy + onnxruntime only. No PyTorch, no MLX, no MNN.
- CPU + CUDA:
--device autopicks CUDA whenonnxruntime-gpuis installed, otherwise CPU.
Platform: any OS with Python 3.10+. For NVIDIA GPUs install
onnxruntime-gpuinstead ofonnxruntime.
Features
- Zero-shot voice cloning — supply any ≤15 s clean reference; the timbre and speaking style are carried into the output. Build the speaker once and reuse it across unlimited lines.
- Multilingual + code-switching —
zh,en,ja,yue, and mixed text in a single sentence (e.g.Use the CPU or GPU, 都可以). - Text normalization — numbers, abbreviations and symbols are read out correctly via
wetext(e.g.2025 年→ “二零二五年”,100 万→ “一百万”). Disable with--no-normalization. - Rich decoding controls — greedy or sampling (
top_k/top_p/temperature/seed),repetition_penalty,duration_factor(speech rate), and the flow-matching solver knobs (n_timesteps,cfg_rate). - Auto-download — weights pull from Hugging Face on first run and are cached for reuse; CLI and Python API share the same cache.
- Timing report — every
synthprints load / clone / synth time, RTF, and a per-stage breakdown.
Install / one-click run
No install needed with uv:
uvx index-tts-2.5-onnx synth \
--ref /path/to/voice.wav \
--text "大家好, this is IndexTTS running on ONNX Runtime." \
--out out.wav
The first run downloads the fp32 models (~7 GB) from Hugging Face into the standard HF cache (~/.cache/huggingface); later runs reuse it.
For an NVIDIA GPU, install the GPU build of ONNX Runtime and pass --device cuda (or leave auto, which detects it):
uv pip install onnxruntime-gpu # replaces onnxruntime
uvx --from index-tts-2.5-onnx --with onnxruntime-gpu index-tts-2.5-onnx synth \
--ref voice.wav --text "..." --device cuda
Or install into an environment:
pip install index-tts-2.5-onnx # CPU
pip install index-tts-2.5-onnx onnxruntime-gpu # + CUDA
Pre-download the weights ahead of time:
uvx index-tts-2.5-onnx download
CLI usage
index-tts-2.5-onnx synth --ref REF.wav --text "..." --out out.wav [options]
| Option | Default | Description |
|---|---|---|
--ref |
(required) | Reference audio to clone (≤15 s, clear speech). |
--text |
(required) | Text to synthesize (zh/en/ja/yue, mixed OK). |
--out |
output.wav |
Output WAV path (22050 Hz, int16). |
--lang |
zh |
Language hint: zh, en, ja, yue. |
--device |
auto |
auto / cpu / cuda / coreml. auto = CUDA if available, else CPU. |
--threads |
4 |
CPU intra-op threads. |
--greedy |
off | Greedy decoding (deterministic). |
--seed |
random | RNG seed for sampling. |
--top-k / --top-p / --temperature |
30 / 0.8 / 0.8 |
Sampling controls. |
--repetition-penalty |
10.0 |
Repetition penalty. |
--max-mel-tokens |
1500 |
Max acoustic tokens per segment. |
--duration-factor |
1.0 |
Speech-rate multiplier. |
--n-timesteps / --cfg-rate |
25 / 0.7 |
Flow-matching solver controls. |
--model-dir |
auto | Use a local weight dir instead of downloading. |
--no-normalization |
off | Disable text normalization. |
Python API
from index_tts_2_5_onnx import IndexTTS
tts = IndexTTS(device="auto") # auto-downloads weights on first use
sr, pcm = tts.clone(
"AI 模型在 2025 年处理了 100 万条数据。",
ref_audio_path="voice.wav",
out="clone.wav", # optional; also returns pcm
lang="zh",
)
# Reuse one cloned voice across many lines (build the speaker once):
spk = tts.build_speaker("voice.wav")
for i, line in enumerate(["第一句。", "Second sentence.", "第三句。"]):
sr, pcm = tts.clone(line, ref_audio_path=None, spk=spk, out=f"line{i}.wav")
synthesize(...) returns the raw int16 PCM array (numpy) at tts.sample_rate (22050 Hz); clone(...) additionally writes a WAV when out is given. Use your own reference audio only with permission — see License.
Speed
CPU (Apple M5 Pro, 4 threads, fp32): GPT step ≈ 16 ms/token, CFM step ≈ 138 ms, BigVGAN ≈ 4.9 s for a ~3 s clip — end-to-end RTF ≈ 3.3. The BigVGAN vocoder dominates on ONNX Runtime CPU; if you need fast CPU inference, use the MNN build (same pipeline, ~6× faster vocoder). On Apple Silicon, use index-tts-2.5-mlx (GPU, faster than real-time). CUDA EP is the fast path on NVIDIA GPUs.
Quality / effect
Numeric fidelity — the fp32 ONNX graphs are bit-exact against the PyTorch CPU reference: every verification stage passes at cosine = 1.0000, greedy decoding reproduces the reference acoustic tokens exactly (fx0 73/73, fx1 83/83), and the vocoder output matches at mel-spectrogram SNR ≈ 85 dB (inaudible). Output audio is for practical purposes identical to running the official PyTorch model on CPU.
Why no int8? Every ONNX Runtime CPU quantization scheme was evaluated and rejected on measurement: dynamic QInt8 quantization flips GPT greedy argmax (only 26% of reference acoustic tokens survive — the decode drifts), and MatMulNBits weight-only int8 both degrades GPT logits (cos 0.985) and runs slower than fp32 on this pipeline. So this distribution ships fp32 only — quality is the feature here. For smaller/faster quantized builds see the MNN (ARM/CPU) and MLX (Apple Silicon) packages.
A note on coreml: the provider is selectable but not recommended — every stage benchmarked slower than CPU, and the CFM estimator graph does not run on it.
How it works
Pipeline: text frontend (tiktoken + wetext normalization) → w2v-bert semantic features → semantic codec → GPT autoregressive acoustic tokens → length regulator → flow-matching CFM (DiT) → BigVGAN vocoder → 22050 Hz WAV. The orchestration (samplers, solvers, DSP) is numpy; the heavy networks are ONNX graphs exported from the PyTorch reference and verified stage-by-stage.
Model weights: yunfengwang/IndexTTS-2.5-onnx (fp32).
License
Code in this package is provided under the same terms as the upstream project. IndexTTS-2.5 model weights are subject to the original Bilibili IndexTTS license — see the upstream model card. Use voice cloning responsibly and only with consent from the voice owner.
Metadata
Release files for index-tts-2.5-onnx 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| index_tts_2_5_onnx-0.1.0.tar.gz | 21.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| index_tts_2_5_onnx-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 48.5 kB
Release files / index_tts_2_5_onnx-0.1.0.tar.gz
| Download URL | index_tts_2_5_onnx-0.1.0.tar.gz |
|---|---|
| Size | 21.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a73b9b4c13ac70b816c1fa2446e953fbbd5465cc6e2edf8ce0ea1eb14c0bf433
|
|
BLAKE2b-256 checksum How to use checksums |
6e3d3ce8fdbd86610a016267d77fdb77fd2567797efa672b81b97d552c0d058d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / index_tts_2_5_onnx-0.1.0-py3-none-any.whl
| Download URL | index_tts_2_5_onnx-0.1.0-py3-none-any.whl |
|---|---|
| Size | 27.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
85d0e9521426d3dde8a61eb1df18e9c4744bbb12d686b59eda6fdbaa7f788a40
|
|
BLAKE2b-256 checksum How to use checksums |
e40e906f964c049e4f0f2d900f6221be0ed50a56283f68a791814f704b6bb2d2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|