The Problem

Most TTS models require hundreds of millions of parameters and GPU inference. TinyTTS fits a complete end-to-end English TTS pipeline into ~1.6M parameters and a ~3.4 MB ONNX model, targeting CPU-only edge devices and embedded systems.

What This Does

TinyTTS is a full text-to-speech stack: text normalization, grapheme-to-phoneme conversion, acoustic modeling, and waveform synthesis in one model. The Python package (tiny_tts/) handles training and inference; the npm-package/ directory offers pure Node.js inference via ONNX Runtime with zero Python dependency.

The repo includes ONNX exports (onnx/), a pre-trained checkpoint (checkpoints/G.pth), sample audio (samples/), and benchmark scripts comparing against Piper, Kokoro, and other small TTS models.

How It Is Wired

Execution starts at two entry points. The Python API path: synthesize_audio in app.py:19 reaches 19 functions, routing through speak in tiny_tts/__init__.py, which calls the model's infer method. The CLI path: main in benchmark_onnx.py:70 reaches 28 functions, routing through synthesize in tiny_tts/infer.py to the same model.infer call. Both paths leave the process in two hops: entry → synthesis function → model inference.

The module graph shows no circular dependencies across 30 internal modules and 47 import edges. tiny_tts/nn/__init__.py is the hub (7 importers, 0 dependencies); tiny_tts/utils/config.py similarly serves 6 importers. The widest blast radius sits in tiny_tts/nn/commons.py — its flatten_pad_shape is called from 7 places, insert_blanks from 4. tiny_tts/infer.py is the most unstable core module (instability 0.6), importing 6 modules while being imported by 4.

File responsibilities: tiny_tts/nn/modules.py owns the neural network layers (25 functions, 12 classes); tiny_tts/models/synthesizer.py builds the model (649 lines, 20 functions); tiny_tts/text/english.py handles phonemization (9 functions); tiny_tts/infer_onnx.py provides the ONNX inference path. The filesystem effects are minimal: benchmark.py and benchmark_onnx.py read/write files; no database or network calls exist in the traced paths.

How To Use It

# Python
pip install tiny-tts
tiny-tts --checkpoint G.pth --text "Hello world" --device cpu

# Node.js
npm install tiny-tts

Python API:

from tiny_tts import TinyTTS
tts = TinyTTS()
tts.speak("Hello, this is a test.", output_path="hello.wav", speed=1.0)

The ONNX model auto-downloads from HuggingFace on first npm use. Source installs require torch, torchaudio, soundfile, g2p-en, transformers, numba per requirements.txt.

Code Health & Issues

Static analysis found 8 issues (1 high, 7 medium). The high-severity finding: 21 duplicated 6-line code blocks across 6 files including tiny_tts/__init__.py, tiny_tts/infer.py, and tiny_tts/models/synthesizer.py — extract shared helpers. Medium findings: deep nesting (depth 6) in tiny_tts/models/synthesizer.py and tiny_tts/alignment/core.py; synthesizer.py at 649 lines; setup.py opens files without context managers.

SDLC gaps: no test suite across 30 source files, no CI configuration, no lockfile (npm), and three large binaries (19.1 MB checkpoint, 14.1 MB and 13.8 MB ONNX files) committed directly. A license file exists; no secrets were found.

The Bottom Line

TinyTTS is a genuinely small, working TTS model with clean module boundaries and no circular dependencies. The missing test suite and CI are the main risks for anyone extending it. Use it for CPU-constrained or embedded TTS where a 200 MB model is unacceptable; skip it if you need production-grade reliability guarantees.