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.kt have max indentation depth of 9, making control flow hard to follow.
  • High - Oversized files (4): app.py at 2659 lines, plus ort_cpu_runtime.py and onnx/export_moss_tts_browser_onnx.py need splitting by responsibility.
  • High - Duplicated code (55 repeated 6-line blocks across 8 files): extract shared helpers.
  • Medium - Broad exception handling (5 instances): bare except in app.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.py has 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.