The Problem
Most open-source TTS models require GPU inference, heavy Python dependencies, and complex deployment stacks. MOSS-TTS-Nano targets the opposite: a 0.1B-parameter multilingual speech model that runs realtime on CPU, with an ONNX runtime path that removes the PyTorch dependency entirely. It also includes voice cloning and a finetuning pipeline, making it a practical option for lightweight product integration.
What This Does
The repository contains three sub-projects: the core moss_tts_nano package (CLI and defaults), an ONNX export and CPU runtime path (onnx/, onnx_tts_runtime.py, ort_cpu_runtime.py), and a finetuning/ pipeline for adapting the model to custom voices. Two Flask apps (app.py, app_onnx.py) provide web demos, and examples/android_onnx_runtime/ contains a Kotlin Android app using ONNX Runtime.
The ONNX path is the headline feature: it claims ~2x efficiency over the PyTorch version and runs on a single CPU core. The onnx/export_hf_to_tts_onnx.py script handles conversion from Hugging Face models, and onnx_tts_runtime.py manages model directory resolution and manifest validation.
How It Is Wired
Execution starts at three entry points: main in app.py (reaches 172 functions), _run_generate and _run_serve in moss_tts_nano/cli.py (each reaches 176). The main in app.py is the most connected hub, called from 5 places and reaching 172 functions. The module graph shows no circular dependencies across 21 internal modules and 23 import edges.
The traced paths show the system's external effects: main -> export_onnx writes files via output_path.parent.mkdir, _run -> _maybe_delete_file unlinks paths, and _synthesize -> synthesize creates output directories. The onnx/export_hf_to_tts_onnx.py script runs external commands and performs cryptographic operations (likely for model signing or checksumming).
Key files and their responsibilities: app.py owns the web demo and model loading state machine (63 functions, 6 classes), ort_cpu_runtime.py handles ONNX execution providers and tensor operations, text_normalization_pipeline.py is a central dependency (imported by 4 modules) for preprocessing, and moss_tts_nano/defaults.py is the most stable module (4 importers, 0 dependencies). The highest-risk functions are snapshot (called from 10 places) and _maybe_delete_file (7 places) — changes to these ripple widely.
How To Use It
Setup: Install dependencies via pip install -r requirements.txt (or pip install -e . using pyproject.toml). No lockfile is present, so pin versions manually for reproducible builds.
Running: The CLI is the primary entry point:
python -m moss_tts_nano
# or
python moss_tts_nano/cli.py
For the ONNX path, export first:
python onnx/export_hf_to_tts_onnx.py --help
The Flask demos start via python app.py (PyTorch) or python app_onnx.py (ONNX). The Android example builds with Gradle via ./gradlew assembleDebug in examples/android_onnx_runtime/.
Configuration: Model paths are resolved via _resolve_model_dir_path in onnx_tts_runtime.py, which checks for a manifest file. No environment variables are documented; configuration is argument-driven.
Real-World Use
A practical deployment: a voice assistant service that needs on-device TTS without GPU. Export the model to ONNX, run app_onnx.py as a Flask microservice, and have clients POST text with a voice cloning reference audio. The Android example shows the same runtime embedded in a mobile app, using MossOnnxDemoEngine.kt to handle inference directly on-device.
Code Health & Issues
Static analysis found 21 issues (6 high, 15 medium) across 6 categories:
- High - Deep nesting (9 instances):
app.py,app_onnx.py,MossOnnxDemoEngine.kthave max indentation depth of 9, making control flow hard to follow. - High - Oversized files (4):
app.pyat 2659 lines, plusort_cpu_runtime.pyandonnx/export_moss_tts_browser_onnx.pyneed splitting by responsibility. - High - Duplicated code (55 repeated 6-line blocks across 8 files): extract shared helpers.
- Medium - Broad exception handling (5 instances): bare
exceptinapp.py,app_onnx.py,moss_tts_nano_runtime.py. - Medium - File opened without context manager:
onnx_tts_runtime.py. - Medium - High branching density:
finetuning/common.pyhas 42 branch points over 124 lines.
SDLC gaps: no test files, no CI/CD, no lockfile, no Dependabot. The finetuning/ directory has a run_train.sh but no test coverage. License is present; no committed secrets detected.
The Bottom Line
MOSS-TTS-Nano delivers on its core promise: a genuinely small, CPU-runnable TTS model with a clean ONNX path that removes PyTorch from inference. The codebase is functional but needs maintenance — no tests, no CI, and several files are too large for safe modification. Worth adopting if you need lightweight multilingual TTS with voice cloning, but budget time for adding a test suite and CI before production use.