Metadata-Version: 2.4
Name: ming-tts-mnn
Version: 0.1.3
Summary: Ming-3.0-tts-0.5B on MNN: zero-shot text-to-speech on the CPU, one command.
Author: yunfengwang
License: MIT License
        
        Copyright (c) 2025 inclusionAI
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
Project-URL: Homepage, https://huggingface.co/yunfengwang/Ming-3.0-tts-0.5B-MNN
Project-URL: Model (original), https://huggingface.co/inclusionAI/Ming-3.0-tts-0.5B
Keywords: tts,text-to-speech,voice-cloning,mnn,cpu,ming
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.24
Requires-Dist: mnn>=3.6.1
Requires-Dist: tokenizers>=0.20
Requires-Dist: huggingface_hub>=0.23
Provides-Extra: modelscope
Requires-Dist: modelscope>=1.20; extra == "modelscope"
Dynamic: license-file

# ming-tts-mnn

Zero-shot text-to-speech on the CPU, one command.  This package runs
[Ming-3.0-tts-0.5B](https://huggingface.co/inclusionAI/Ming-3.0-tts-0.5B) through
[MNN](https://github.com/alibaba/MNN) graphs converted from the released weights.

```bash
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

```bash
# 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

```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](https://huggingface.co/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.

## 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>
