zerotts 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- zerotts-0.1.0/LICENSE +21 -0
- zerotts-0.1.0/NOTICE +36 -0
- zerotts-0.1.0/PKG-INFO +350 -0
- zerotts-0.1.0/README.md +306 -0
- zerotts-0.1.0/pyproject.toml +85 -0
- zerotts-0.1.0/setup.cfg +4 -0
- zerotts-0.1.0/src/zerotts/__init__.py +26 -0
- zerotts-0.1.0/src/zerotts/audio.py +57 -0
- zerotts-0.1.0/src/zerotts/chunking.py +270 -0
- zerotts-0.1.0/src/zerotts/cli.py +162 -0
- zerotts-0.1.0/src/zerotts/codec.py +154 -0
- zerotts-0.1.0/src/zerotts/hub.py +93 -0
- zerotts-0.1.0/src/zerotts/synthesizer.py +458 -0
- zerotts-0.1.0/src/zerotts/text_norm/__init__.py +11 -0
- zerotts-0.1.0/src/zerotts/text_norm/data/LICENSE.soe-vinorm +21 -0
- zerotts-0.1.0/src/zerotts/text_norm/data/abbreviations.txt +2258 -0
- zerotts-0.1.0/src/zerotts/text_norm/vi_normalizer.py +620 -0
- zerotts-0.1.0/src/zerotts/tokenizer.py +139 -0
- zerotts-0.1.0/src/zerotts/voices.py +129 -0
- zerotts-0.1.0/src/zerotts.egg-info/PKG-INFO +350 -0
- zerotts-0.1.0/src/zerotts.egg-info/SOURCES.txt +26 -0
- zerotts-0.1.0/src/zerotts.egg-info/dependency_links.txt +1 -0
- zerotts-0.1.0/src/zerotts.egg-info/entry_points.txt +2 -0
- zerotts-0.1.0/src/zerotts.egg-info/requires.txt +26 -0
- zerotts-0.1.0/src/zerotts.egg-info/top_level.txt +1 -0
- zerotts-0.1.0/tests/test_synthesis.py +81 -0
- zerotts-0.1.0/tests/test_tokenizer.py +57 -0
- zerotts-0.1.0/tests/test_vi_normalizer.py +238 -0
zerotts-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ZeroWeight AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
zerotts-0.1.0/NOTICE
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
ZeroTTS
|
|
2
|
+
Copyright (c) 2026 ZeroWeight AI
|
|
3
|
+
Licensed under the MIT License (see LICENSE).
|
|
4
|
+
|
|
5
|
+
------------------------------------------------------------------------------
|
|
6
|
+
This product redistributes third-party components.
|
|
7
|
+
------------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
MOSS-Audio-Tokenizer-Nano
|
|
10
|
+
Copyright the OpenMOSS Team.
|
|
11
|
+
Licensed under the Apache License, Version 2.0.
|
|
12
|
+
Full text: LICENSES/MOSS-Audio-Tokenizer-Apache-2.0.txt
|
|
13
|
+
|
|
14
|
+
The ZeroTTS weights repository (huggingface.co/zeroweight-ai/ZeroTTS) bundles
|
|
15
|
+
the ONNX **decoder** graphs of MOSS-Audio-Tokenizer-Nano under onnx/codec/, so
|
|
16
|
+
that ZeroTTS has no runtime dependency on an external model repository. The
|
|
17
|
+
encoder graphs are not redistributed. The graphs are unmodified except for the
|
|
18
|
+
removal of the encoder entries from the accompanying metadata file.
|
|
19
|
+
|
|
20
|
+
Upstream: https://github.com/OpenMOSS/MOSS-Audio-Tokenizer
|
|
21
|
+
https://huggingface.co/OpenMOSS-Team/MOSS-Audio-Tokenizer-Nano-ONNX
|
|
22
|
+
|
|
23
|
+
------------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
soe-vinorm
|
|
26
|
+
Copyright (c) vinhdq842.
|
|
27
|
+
Licensed under the MIT License.
|
|
28
|
+
Full text: src/zerotts/text_norm/data/LICENSE.soe-vinorm
|
|
29
|
+
|
|
30
|
+
src/zerotts/text_norm/vi_normalizer.py adapts soe-vinorm's Vietnamese number,
|
|
31
|
+
date, time, version and fraction expansion rules, and vendors its abbreviation
|
|
32
|
+
table as data/abbreviations.txt. None of soe-vinorm's machinery is carried over
|
|
33
|
+
— that project tags tokens with a CRF and disambiguates acronyms with an ONNX
|
|
34
|
+
scorer, both downloaded at runtime; this module is pure stdlib regex.
|
|
35
|
+
|
|
36
|
+
Upstream: https://github.com/vinhdq842/soe-vinorm
|
zerotts-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: zerotts
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Lightweight Vietnamese Zero-Shot Text-to-Speech (TTS) with real-time streaming and voice cloning.
|
|
5
|
+
Author: ZeroWeight AI
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/zeroweight-ai/ZeroTTS
|
|
8
|
+
Project-URL: Weights, https://huggingface.co/zeroweight-ai/ZeroTTS
|
|
9
|
+
Project-URL: Benchmark, https://huggingface.co/datasets/zeroweight-ai/ZeroBench-TTS
|
|
10
|
+
Keywords: tts,text-to-speech,vietnamese,onnx,speech-synthesis,lightweight,voice clone
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
|
|
16
|
+
Requires-Python: >=3.9
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
License-File: NOTICE
|
|
20
|
+
Requires-Dist: numpy>=1.23
|
|
21
|
+
Requires-Dist: onnxruntime>=1.17.0
|
|
22
|
+
Requires-Dist: tokenizers>=0.20.0
|
|
23
|
+
Requires-Dist: huggingface_hub>=0.23.0
|
|
24
|
+
Requires-Dist: soundfile>=0.12.1
|
|
25
|
+
Requires-Dist: scipy>=1.10.0
|
|
26
|
+
Provides-Extra: webui
|
|
27
|
+
Requires-Dist: gradio>=4.44.0; extra == "webui"
|
|
28
|
+
Requires-Dist: fastapi>=0.110; extra == "webui"
|
|
29
|
+
Requires-Dist: uvicorn>=0.27; extra == "webui"
|
|
30
|
+
Requires-Dist: requests>=2.31; extra == "webui"
|
|
31
|
+
Provides-Extra: eval
|
|
32
|
+
Requires-Dist: torch>=2.4.0; extra == "eval"
|
|
33
|
+
Requires-Dist: torchaudio>=2.4.0; extra == "eval"
|
|
34
|
+
Requires-Dist: transformers>=4.44.0; extra == "eval"
|
|
35
|
+
Requires-Dist: huggingface_hub>=0.23; extra == "eval"
|
|
36
|
+
Requires-Dist: datasets>=2.19; extra == "eval"
|
|
37
|
+
Requires-Dist: librosa>=0.10; extra == "eval"
|
|
38
|
+
Requires-Dist: pandas>=2.0; extra == "eval"
|
|
39
|
+
Requires-Dist: jiwer>=3.0; extra == "eval"
|
|
40
|
+
Provides-Extra: dev
|
|
41
|
+
Requires-Dist: pytest>=7.4; extra == "dev"
|
|
42
|
+
Requires-Dist: ruff>=0.5; extra == "dev"
|
|
43
|
+
Dynamic: license-file
|
|
44
|
+
|
|
45
|
+
<div align="center">
|
|
46
|
+
|
|
47
|
+
<img src="docs/assets/banner.png" alt="ZeroTTS — Vietnamese zero-shot text-to-speech" width="100%">
|
|
48
|
+
|
|
49
|
+
# ZeroTTS
|
|
50
|
+
|
|
51
|
+
### Vietnamese Zero-Shot Text-to-Speech (TTS) with real-time streaming and voice cloning from seconds of audio. Fast, natural, and optimised for CPU inference.
|
|
52
|
+
|
|
53
|
+
[](https://pypi.org/project/zerotts/)
|
|
54
|
+
[](LICENSE)
|
|
55
|
+
[](https://onnxruntime.ai/)
|
|
56
|
+
[](https://huggingface.co/zeroweight-ai/ZeroTTS)
|
|
57
|
+
[](https://huggingface.co/datasets/zeroweight-ai/ZeroBench-TTS)
|
|
58
|
+
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
**The most accurate open Vietnamese TTS we know of — 4× fewer word errors than
|
|
62
|
+
the next open model**, and it runs faster than real time on a laptop CPU.
|
|
63
|
+
|
|
64
|
+
* 🗣️ **Zero-shot voice cloning** — cloned from as little as 3 seconds of reference
|
|
65
|
+
audio (up to 30 seconds). No fine-tuning, no per-speaker training.
|
|
66
|
+
* ⚡ **Real-time on CPU, streaming** — ~2× faster than real time (RTF 0.5×),
|
|
67
|
+
first audio chunk in ~70 ms. No GPU required.
|
|
68
|
+
* 🇻🇳 **Built for Vietnamese** — tones, code-switched English, and a built-in
|
|
69
|
+
normalizer that reads `31/12/2026` and `ZeroTTS` the way a person would.
|
|
70
|
+
|
|
71
|
+
## Samples
|
|
72
|
+
|
|
73
|
+
<table>
|
|
74
|
+
<tr>
|
|
75
|
+
<td width="33%" align="center"><b>Two-speaker conversation</b></td>
|
|
76
|
+
<td width="33%" align="center"><b>Long-form narration</b></td>
|
|
77
|
+
<td width="33%" align="center"><b>News read, code-switched English</b></td>
|
|
78
|
+
</tr>
|
|
79
|
+
<tr>
|
|
80
|
+
<td width="33%"><video src="https://github.com/user-attachments/assets/7f97b370-4544-4df7-9165-ffad8a08eb90" controls width="100%"></video></td>
|
|
81
|
+
<td width="33%"><video src="https://github.com/user-attachments/assets/3c80a328-11cc-4815-b3fb-97ca8d994401" controls width="100%"></video></td>
|
|
82
|
+
<td width="33%"><video src="https://github.com/user-attachments/assets/9a5f6125-3ac3-4f09-81f1-986f38e18f69" controls width="100%"></video></td>
|
|
83
|
+
</tr>
|
|
84
|
+
</table>
|
|
85
|
+
|
|
86
|
+
## Contents
|
|
87
|
+
|
|
88
|
+
1. [Samples](#samples)
|
|
89
|
+
2. [Install](#install)
|
|
90
|
+
3. [Usage](#usage)
|
|
91
|
+
4. [Voices — and voice cloning](#voices--and-voice-cloning)
|
|
92
|
+
5. [Benchmarks](#benchmarks)
|
|
93
|
+
6. [Web UI](#web-ui)
|
|
94
|
+
7. [Browser demo](#browser-demo)
|
|
95
|
+
8. [How it works](#how-it-works)
|
|
96
|
+
9. [Credits](#credits)
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Install
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
pip install zerotts
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
That pulls `numpy`, `onnxruntime`, `tokenizers`, `huggingface_hub`, `soundfile`,
|
|
107
|
+
`scipy` — and nothing else. Weights download from the Hub on first use
|
|
108
|
+
(~900 MB, cached under `HF_HOME`).
|
|
109
|
+
|
|
110
|
+
Optional extras:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
pip install "zerotts[webui]" # Gradio demo
|
|
114
|
+
pip install "zerotts[eval]" # benchmark scorers — these DO need torch
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The `eval` extra is the only thing in this repo that installs PyTorch, and it is
|
|
118
|
+
for *measuring* quality, not for generating audio.
|
|
119
|
+
|
|
120
|
+
## Usage
|
|
121
|
+
|
|
122
|
+
## Web UI
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
pip install "zerotts[webui]"
|
|
126
|
+
python webui/app.py # http://localhost:7860
|
|
127
|
+
python webui/app.py --model ./local_dir # a local model directory
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Voice picker, streaming playback, long-form segmentation, and the generation
|
|
131
|
+
settings above.
|
|
132
|
+
|
|
133
|
+
## Browser demo
|
|
134
|
+
|
|
135
|
+
[`js/`](js/) runs the same model client-side with `onnxruntime-web` — no server,
|
|
136
|
+
no upload. See [docs/BROWSER.md](docs/BROWSER.md).
|
|
137
|
+
|
|
138
|
+
Note the download: the weights are **fp32 and not quantized**, so the demo fetches
|
|
139
|
+
~900 MB once and persists it (OPFS/Cache API). That is a deliberate
|
|
140
|
+
quality-over-size choice; it targets desktop broadband, not mobile data.
|
|
141
|
+
|
|
142
|
+
### Python
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
from zerotts import ZeroTTS
|
|
146
|
+
|
|
147
|
+
tts = ZeroTTS.from_pretrained("zeroweight-ai/ZeroTTS")
|
|
148
|
+
|
|
149
|
+
print(tts.list_voices())
|
|
150
|
+
|
|
151
|
+
# One shot
|
|
152
|
+
audio = tts.synthesize("Hôm nay trời đẹp quá.", voice="maichi")
|
|
153
|
+
tts.save_audio(audio, "out.wav")
|
|
154
|
+
|
|
155
|
+
# Streaming — first chunk arrives in ~70 ms
|
|
156
|
+
import queue
|
|
157
|
+
|
|
158
|
+
import numpy as np
|
|
159
|
+
import sounddevice as sd # pip install sounddevice
|
|
160
|
+
|
|
161
|
+
TEXT = ("Đây là chế độ phát trực tuyến. Âm thanh được tạo ra và phát ngay lập tức, "
|
|
162
|
+
"không cần chờ toàn bộ đoạn văn hoàn thành. Nhờ vậy, người nghe chỉ mất "
|
|
163
|
+
"khoảng 70 mili giây là đã nghe thấy câu đầu tiên, ngay cả khi mô "
|
|
164
|
+
"hình đang chạy trên CPU của một chiếc laptop bình thường.")
|
|
165
|
+
|
|
166
|
+
pending, tail = queue.Queue(), np.zeros(0, dtype="float32")
|
|
167
|
+
|
|
168
|
+
def feed(outdata, frames, _time, _status):
|
|
169
|
+
global tail
|
|
170
|
+
while len(tail) < frames and not pending.empty():
|
|
171
|
+
tail = np.concatenate([tail, pending.get_nowait()])
|
|
172
|
+
n = min(frames, len(tail))
|
|
173
|
+
outdata[:n, 0] = tail[:n]
|
|
174
|
+
outdata[n:] = 0
|
|
175
|
+
tail = tail[n:]
|
|
176
|
+
|
|
177
|
+
with sd.OutputStream(samplerate=tts.sample_rate, channels=1,
|
|
178
|
+
dtype="float32", callback=feed):
|
|
179
|
+
for chunk in tts.synthesize_stream(TEXT, voice="maichi"):
|
|
180
|
+
pending.put(chunk.reshape(-1)) # chunk is (1, n) float32 at 48 kHz
|
|
181
|
+
while not pending.empty() or len(tail):
|
|
182
|
+
sd.sleep(50) # let the buffer drain before closing
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Dates, clock times, fractions and acronyms are expanded to spoken Vietnamese
|
|
186
|
+
before synthesis:
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
from zerotts import normalize_vi_text
|
|
190
|
+
|
|
191
|
+
normalize_vi_text("Ngày 23/8/2024 lúc 15h30, giá 1.250.000")
|
|
192
|
+
# 'Ngày hai mươi ba tháng tám năm hai nghìn không trăm hai mươi tư lúc
|
|
193
|
+
# mười lăm giờ ba mươi phút, giá một triệu hai trăm năm mươi nghìn'
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
`synthesize()` does **not** apply it — it is a separate step so you stay in
|
|
197
|
+
control (the expansions are Vietnamese words, so they are wrong for English
|
|
198
|
+
text). The CLI and web UI apply it by default; `zerotts say --no_text_norm`
|
|
199
|
+
turns it off.
|
|
200
|
+
|
|
201
|
+
Long input should be segmented — the model is trained on utterances, not
|
|
202
|
+
paragraphs:
|
|
203
|
+
|
|
204
|
+
```python
|
|
205
|
+
from zerotts.chunking import chunk_text, clean_segment_punctuation, normalize_punctuation
|
|
206
|
+
|
|
207
|
+
segments = [clean_segment_punctuation(s)
|
|
208
|
+
for s in chunk_text(normalize_punctuation(long_text), max_chunk_sec=15)]
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Command line
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
zerotts voices
|
|
215
|
+
zerotts say "Xin chào các bạn." --voice maichi -o hello.wav
|
|
216
|
+
zerotts say "$(cat article.txt)" --voice maichi --chunk -o article.wav
|
|
217
|
+
zerotts bench --voice maichi
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Generation settings
|
|
221
|
+
|
|
222
|
+
| Argument | Default | Effect |
|
|
223
|
+
|---|---|---|
|
|
224
|
+
| `voice` | `None` | Voice pack name. `None` = the model's unconditional voice, which is *not* stable across runs. |
|
|
225
|
+
| `cfg_scale` | `1.0` | `>1` guides toward the voice's identity, at 2× the per-frame cost. |
|
|
226
|
+
| `audio_temperature` | `0.8` | |
|
|
227
|
+
| `audio_topk` / `audio_topp` | `25` / `0.95` | |
|
|
228
|
+
| `audio_repetition_penalty` | `1.2` | Benchmarked default. `1.0` measurably raises WER and leaves more dead air. |
|
|
229
|
+
| `eoa_extra_frames` | `1` | Frames of trailing audio kept after the model signals stop. `0` clips the last phone's release. |
|
|
230
|
+
|
|
231
|
+
Defaults are the exact settings the [benchmark numbers](#benchmarks) were
|
|
232
|
+
produced with, so out-of-the-box output matches the published scores.
|
|
233
|
+
|
|
234
|
+
## Voices — and voice cloning
|
|
235
|
+
|
|
236
|
+
A voice in ZeroTTS is a small array of speaker latents, shape
|
|
237
|
+
`(1, n_voice_queries, d_model)`. That array is the *entire* speaker
|
|
238
|
+
conditioning — there is no reference transcript, no in-context audio prompt, no
|
|
239
|
+
teacher-forced frames. It ships as a `.npz` inside the weights repo.
|
|
240
|
+
|
|
241
|
+
> ### Voice cloning is not available in this release
|
|
242
|
+
>
|
|
243
|
+
> Those latents are produced by a voice encoder that reads a reference clip, and
|
|
244
|
+
> **the voice encoder is not published**. This package can load voices; it cannot
|
|
245
|
+
> create them from audio. There is no flag that turns this on.
|
|
246
|
+
>
|
|
247
|
+
> To get latents for your own speaker, visit
|
|
248
|
+
> **[zeroweight.ai](https://zeroweight.ai)** or get in touch.
|
|
249
|
+
|
|
250
|
+
The boundary is narrower than it sounds: latents obtained that way are just a
|
|
251
|
+
`.npz`, so they drop into `voices/<name>/voice.npz` and work with no code change.
|
|
252
|
+
|
|
253
|
+
Eight presets ship with the weights, each tagged by gender, age and register so
|
|
254
|
+
you can pick one by ear or by filter — `maichi` (Mai Chi) is the default used
|
|
255
|
+
throughout this README. Full list, tags, and preview clips:
|
|
256
|
+
[docs/VOICES.md](docs/VOICES.md).
|
|
257
|
+
|
|
258
|
+
```python
|
|
259
|
+
tts.list_voices() # ['maichi', 'baotrang', ...]
|
|
260
|
+
v = tts.load_voice("maichi")
|
|
261
|
+
v.emb.shape # (1, 10, 768)
|
|
262
|
+
v.display_name, v.gender, v.tags # 'Mai Chi', 'nữ', ['nữ', 'trẻ', 'kể chuyện', ...]
|
|
263
|
+
|
|
264
|
+
# A latent array from anywhere works directly
|
|
265
|
+
audio = tts.synthesize("…", voice=my_latents)
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Benchmarks
|
|
269
|
+
|
|
270
|
+
Measured on **[ZeroBench-TTS](https://huggingface.co/datasets/zeroweight-ai/ZeroBench-TTS)**
|
|
271
|
+
|
|
272
|
+
Every system reads **normalized text** — dates, numbers and acronyms already
|
|
273
|
+
spoken out, from the benchmark's own curated reading.
|
|
274
|
+
|
|
275
|
+
| | **ZeroTTS** | OmniVoice | XTTS-v2-vietnamse | viXTTS |
|
|
276
|
+
|---|:-:|:-:|:-:|:-:|
|
|
277
|
+
| **WER** ↓ | **0.56 %** | 2.12 % | 7.27 % | 8.61 % |
|
|
278
|
+
| **Naturalness** (UTMOS) ↑ | **2.91** | 2.75 | 2.49 | 2.34 |
|
|
279
|
+
| **Voice similarity** (SSIM) ↑ | 0.938 | **0.951** | 0.941 | 0.935 |
|
|
280
|
+
| **Dead air** (excess silence) ↓ | **0.029 s** | 0.386 s | 0.568 s | 0.215 s |
|
|
281
|
+
| **RTF, CPU** ↓ | **0.50×** | 6.12× | 0.71× | 0.73× |
|
|
282
|
+
| **Time to first audio, CPU** ↓ | **~70 ms** | ~34 s | ~6.1 s | ~5.1 s |
|
|
283
|
+
| Size | **202 M** params, 0.86 GB fp32, CPU | 3.1 GB, GPU | 1.9 GB, GPU | 1.9 GB, GPU |
|
|
284
|
+
|
|
285
|
+
**4× fewer word errors than the next-best system**, and the fastest of the four
|
|
286
|
+
on CPU. The gap is much wider in latency than in throughput: the two XTTS
|
|
287
|
+
fine-tunes also beat real time (0.71×) but need seconds to emit their first
|
|
288
|
+
sample, while OmniVoice is 6× *slower* than real time. All three are sized and
|
|
289
|
+
tuned for a GPU, and it shows.
|
|
290
|
+
|
|
291
|
+
Full comparison tables, per-subset breakdowns, and CPU speed methodology:
|
|
292
|
+
**[docs/BENCHMARKS.md](https://github.com/zeroweight-ai/ZeroTTS/blob/main/docs/BENCHMARKS.md)**
|
|
293
|
+
|
|
294
|
+
### Speed — CPU
|
|
295
|
+
|
|
296
|
+
RTF (realtime factor, wall-clock synthesis time ÷ output audio duration — lower
|
|
297
|
+
is faster; below 1× is faster than real time) and time-to-first-audio, all
|
|
298
|
+
measured **on CPU**, single request, 8 inference threads pinned to a dedicated
|
|
299
|
+
core pool (no other synthesis running concurrently). Three Vietnamese samples —
|
|
300
|
+
short (26 chars), medium (77 chars), long (227 chars) — each run 6 times with
|
|
301
|
+
the first 2 (cold-cache) discarded; figures below are the mean of the
|
|
302
|
+
remaining 4.
|
|
303
|
+
|
|
304
|
+
| | **ZeroTTS** | OmniVoice | XTTS-v2-vietnamse | viXTTS |
|
|
305
|
+
|---|:-:|:-:|:-:|:-:|
|
|
306
|
+
| RTF — short | **0.51×** | 10.87× | 0.70× | 0.71× |
|
|
307
|
+
| RTF — medium | **0.47×** | 4.82× | 0.70× | 0.70× |
|
|
308
|
+
| RTF — long | **0.53×** | 2.67× | 0.71× | 0.78× |
|
|
309
|
+
| TTFA — short | **53 ms** | 21.7 s | 4.02 s | 2.45 s |
|
|
310
|
+
| TTFA — medium | **66 ms** | 28.9 s | 4.02 s | 3.72 s |
|
|
311
|
+
| TTFA — long | **89 ms** | 52.3 s | 10.3 s | 9.22 s |
|
|
312
|
+
|
|
313
|
+
ZeroTTS's time-to-first-audio comes from its real streaming path — first audio frame,
|
|
314
|
+
not first full utterance. The three baselines have no working CPU streaming
|
|
315
|
+
path, so their TTFA is the time to the complete utterance.
|
|
316
|
+
|
|
317
|
+
## Credits
|
|
318
|
+
|
|
319
|
+
Speech codec: **[MOSS-Audio-Tokenizer-Nano](https://github.com/OpenMOSS/MOSS-Audio-Tokenizer)**
|
|
320
|
+
by the OpenMOSS team, Apache-2.0. ZeroTTS bundles its ONNX **decoder** graphs in
|
|
321
|
+
the weights repo so there is no external runtime dependency; see
|
|
322
|
+
[NOTICE](NOTICE) and [LICENSES/](LICENSES/).
|
|
323
|
+
|
|
324
|
+
```bibtex
|
|
325
|
+
@misc{gong2026mossaudiotokenizerscalingaudiotokenizers,
|
|
326
|
+
title={MOSS-Audio-Tokenizer: Scaling Audio Tokenizers for Future Audio Foundation Models},
|
|
327
|
+
author={Yitian Gong and Kuangwei Chen and Zhaoye Fei and Xiaogui Yang and Ke Chen
|
|
328
|
+
and Yang Wang and Kexin Huang and Mingshu Chen and Ruixiao Li
|
|
329
|
+
and Qingyuan Cheng and Shimin Li and Xipeng Qiu},
|
|
330
|
+
year={2026}, eprint={2602.10934}, archivePrefix={arXiv}, primaryClass={cs.SD}
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
Vietnamese text normalization adapts the expansion rules and abbreviation table
|
|
335
|
+
of **[soe-vinorm](https://github.com/vinhdq842/soe-vinorm)** (MIT), reimplemented
|
|
336
|
+
as pure stdlib regex so the inference path keeps its no-torch, no-download
|
|
337
|
+
guarantee. See [NOTICE](NOTICE).
|
|
338
|
+
|
|
339
|
+
Benchmark reference audio comes from
|
|
340
|
+
[VIVOS](https://huggingface.co/datasets/AILAB-VNUHCM/vivos),
|
|
341
|
+
[viVoice](https://huggingface.co/datasets/capleaf/viVoice),
|
|
342
|
+
[phoaudiobook](https://huggingface.co/datasets/thivux/phoaudiobook) and
|
|
343
|
+
[Emilia](https://huggingface.co/datasets/amphion/Emilia-Dataset).
|
|
344
|
+
ASR scoring uses [PhoWhisper](https://huggingface.co/vinai/PhoWhisper-large) (VinAI).
|
|
345
|
+
|
|
346
|
+
## License
|
|
347
|
+
|
|
348
|
+
Code and weights: **MIT**. The bundled MOSS codec decoder is Apache-2.0.
|
|
349
|
+
The ZeroBench-TTS *dataset* is CC-BY-NC-4.0 (it redistributes audio from the
|
|
350
|
+
corpora above) — that applies to the benchmark, not to ZeroTTS.
|