Skip to main content

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 --seed for reproducible output.
  • 44.1 kHz mono, 16-bit wav. The model is MIT licensed; so is this port.

Changes

  • 0.1.3 — removed the int4mix tier (-p now accepts fp16, 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 pin int4mix, switch to int8.
  • 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-mnn is the documented way to run it.

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)

Source distribution for ming-tts-mnn 0.1.3
File Size Uploaded Provenance
ming_tts_mnn-0.1.3.tar.gz 419.0 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for ming-tts-mnn 0.1.3
File Interpreter ABI Platform
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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page