ming-tts-mnn
Zero-shot text-to-speech on the CPU, one command. This package runs Ming-3.0-tts-0.5B through MNN graphs converted from the released weights.
uvx --from ming-tts-mnn ming-tts "傍晚的风从山口吹过来,远处的云慢慢染成了金色。" -o hello.wav
uvx creates an isolated environment, installs the package, runs it, and leaves your
Python alone. The first run also downloads one precision tier (fp16 by default,
~2.9 GB including the shared assets) from HuggingFace and caches it; every later run
is offline. The package itself is code only.
What you get
- 44.1 kHz output, Chinese and English, punctuation-aware sentence splitting.
- Zero-shot voice cloning: pass any 5–20 s wav plus its transcript.
- No GPU, no PyTorch, no ONNX Runtime — the whole model (LLM backbone, flow-matching head, aggregator, VAE encoder/decoder, CAM++ speaker encoder) runs on MNN.
-p |
size | what it is |
|---|---|---|
fp16 |
2.63 GB | the default; step-level difference from the fp32 original is below the original's own bf16 rounding |
int8 |
1.52 GB | recommended; about as close to the original as the original's own bf16 run is |
int4 |
0.77 GB | all 4-bit; smallest, and useful when 1.5 GB is still too much, but the timbre and articulation get noticeably coarser |
int8 is the recommended default for real use: on 16 extra test texts (12 sentences
and 4 paragraphs, all sampled with the same seed as fp16) its CAM++ speaker cosine
stayed between 0.932 and 0.996, and Whisper transcribed all 16 clips. int4 also
transcribed 16/16 and did not loop in that run, but its cosine dropped to 0.828–0.927
and the loss is audible. Long, out-of-domain text is still the risky case for
int4 — it can repeat or cut off — so keep int8 unless memory is the hard limit.
Command line
# default voice: a bundled sample prompt (clones that speaker)
uvx --from ming-tts-mnn ming-tts "今天天气不错。" -o out.wav
# clone your own voice
uvx --from ming-tts-mnn ming-tts "今天天气不错。" --prompt-wav me.wav --prompt-text "这是我录音说的话。" -o out.wav
# no prompt at all: the model's own average voice
uvx --from ming-tts-mnn ming-tts "Hello from the other side." --no-prompt -o out.wav
# smaller download, recommended
uvx --from ming-tts-mnn ming-tts "今天天气不错。" -p int8
# smallest download
uvx --from ming-tts-mnn ming-tts "今天天气不错。" -p int4
# download only, then run offline later
uvx --from ming-tts-mnn ming-tts --download-only -p int8
Useful flags: -l/--language (default: detected from the text), --cfg (2.0),
--seed (0), --threads (MNN's default), --max-length (characters per fragment,
50), --source modelscope, --model-dir (use an already downloaded tree).
Python
from ming_tts_mnn import MingTTSMNN
tts = MingTTSMNN.from_pretrained("int8") # downloads once, then cached
wav = tts.synthesize("傍晚的风从山口吹过来。") # float32, 44.1 kHz
wav, info = tts.synthesize("今天天气不错。", return_info=True)
# voice cloning
wav = tts.synthesize("Read this in my voice.",
prompt_wav="me.wav",
prompt_text="这是我录音说的话。")
MingTTSMNN(model_dir, precision=...) skips the download when you already have the
files (layout: assets/, tokenizer/, <precision>/*.mnn).
Speed
Measured on an Apple M5 Pro with 4 MNN threads: a 3–6 s Chinese sentence takes
1–2× its own duration (RTF 1.1–2.0), depending on how many autoregressive steps the
stop head decides on. The flow-matching head dominates — ten DiT evaluations per
latent step to the LM's one — so per-step cost is identical across tiers. int8 and
int4 do finish faster end to end (about 12% and 18% at the same 40 decode steps),
but that comes from the one-off prefill/encoder/vocoder work, not from the autoregressive
loop; int4 is primarily a disk and memory saving.
Files and cache
Weights come from
yunfengwang/Ming-3.0-tts-0.5B-MNN
(mirror: yunfeng/Ming-3.0-tts-0.5B-MNN on ModelScope). They live in the standard
HuggingFace cache (~/.cache/huggingface/hub), so HF_HOME and HF_HUB_CACHE work
as usual. Downloading int4 fetches only that tier plus the shared assets and
tokenizer.
Notes
- The release stops an utterance when a learned stop head crosses 0.5. That decision is discrete and sensitive to accumulated rounding, so two runs that differ only in arithmetic can differ in length by a few tenths of a second — including the original's own fp32 vs bf16 runs.
--temperature 0(the default) still draws flow-matching noise; use--seedfor reproducible output.- 44.1 kHz mono, 16-bit wav. The model is MIT licensed; so is this port.
Changes
- 0.1.3 — removed the
int4mixtier (-pnow acceptsfp16,int8,int4). It existed to prove that the long-text regression comes from the LM's 4-bit error floor rather than the flow-matching head, and once that was established it was dead weight in the CLI, the weight repo and the docs. If you pinint4mix, switch toint8. - 0.1.2 — documentation only, no code change. The Speed section now reports the measured cost per decode step instead of a bare RTF range: at a fixed 40 steps the quantized tiers finish 12% (int8) and 18% (int4) sooner than fp16, but per-step cost is the same in all three because the flow-matching head, not the LM, dominates.
- 0.1.1 — dropped the mixed-precision tier;
uvx --from ming-tts-mnnis the documented way to run it.
Links
- Converted weights: https://huggingface.co/yunfengwang/Ming-3.0-tts-0.5B-MNN
- Original model: https://huggingface.co/inclusionAI/Ming-3.0-tts-0.5B
Metadata
Release files for ming-tts-mnn 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| ming_tts_mnn-0.1.3.tar.gz | 419.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ming_tts_mnn-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 837.6 kB
Release files / ming_tts_mnn-0.1.3.tar.gz
| Download URL | ming_tts_mnn-0.1.3.tar.gz |
|---|---|
| Size | 419.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e6c6b91bcabaeac0d16ab67ccb98af83434c941b8e0d3ed54369cb5a8ce765f5
|
|
BLAKE2b-256 checksum How to use checksums |
de8263cc10567631d9808eee705b383b574721d7ab20880c0cd7a71285918deb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / ming_tts_mnn-0.1.3-py3-none-any.whl
| Download URL | ming_tts_mnn-0.1.3-py3-none-any.whl |
|---|---|
| Size | 418.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
83064f242e8572f0da0a84a733031d0b9c61976606f1ad30fa90f4a5ae42f261
|
|
BLAKE2b-256 checksum How to use checksums |
d739741fd9f3ad8d43d4cae15151bb72319fb384fc5336db39087c1bf872ec91
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Security for ming-tts-mnn 0.1.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.