sanoTTS / README.md
voidash's picture
Rebuild model card: samples table with embedded audio players, install table, links
dd52a31 verified
|
Raw
History Blame Contribute Delete
9.52 kB
metadata
license: gpl-3.0
language:
  - en
  - ne
  - hi
  - vi
  - id
  - zh
pipeline_tag: text-to-speech
tags:
  - text-to-speech
  - tiny
  - microcontroller
  - esp32
  - wasm
  - piper
  - distillation
library_name: sanotts

sanoTTS — a tiny neural voice that runs anywhere

sano (सानो) — Nepali for "small." A family of tiny neural text-to-speech voices — 745k to 1.8M parameters — that run with no cloud and no NPU: real-time on a ~$3 ESP32-S3 (out a GPIO into an LM386 and a speaker), or live in the browser via WASM.

text in → ESP32 → speech out

Smallest neural TTS family known 745k – 1.8M parameters
Runs real-time on a $3 microcontroller ESP32-S3, out a GPIO into an LM386
Runs in the browser WebAssembly, no server
Per-voice footprint under 4 MB, zero dependencies (espeak-ng phonemizer included)
Coverage 9 voices across 6 languages — English, Nepali (नेपाली), Hindi (हिन्दी), Vietnamese (Tiếng Việt), Indonesian (Bahasa), Chinese (中文)
License open source, GPL-3.0

Live demo: ampixa.github.io/sanoTTS — every voice synthesizes your text live in the browser, no server, no upload.

Samples

One clip per voice below (a second clip per voice is in this repo's samples/ folder). "Package here" means this HF repo carries that voice's raw fp16 weights; the three without one currently only ship through the browser demo and the GitHub repo's web/voices/ — their HF packages haven't been exported yet.

Voice Language Params SCOREQ Package here Sample
amy English 🇺🇸 1.46 M 4.13 amy-en-1p46m/
kristin English 🇺🇸 1.40 M 4.09 kristin-en-1p4m/
hfc English 🇺🇸 1.83 M 3.94 hfc-en-1p8m/
amy-small English 🇺🇸 1.08 M 3.70 amy-en-1p1m/
robot (on-device, int8) English 🇺🇸 745 k not packaged here (int8 MCU format, not fp16)
Indonesian Bahasa 1.46 M id-newstts-1p46m/
Vietnamese Tiếng Việt 1.46 M vi-vais1000-1p46m/
Nepali नेपाली 1.47 M not exported yet — see web/voices/nepali/ in the GitHub repo
Hindi हिन्दी 1.50 M not exported yet — see web/voices/hindi/ in the GitHub repo
Chinese 中文 1.50 M not exported yet — see web/voices/chinese/ in the GitHub repo

The "robot" row is the same 745k-parameter model that runs on the ESP32-S3 — bit-exact with the chip's own output. SCOREQ is only reported for the English voices, which share a common eval set; the other languages haven't been scored against a comparable reference yet.

Install & use

Platform Install Then
Python pip install sanotts sanotts say "Hello" --voice amy -o hello.wav
Web (npm) npm install sanotts-web const tts = await SanoTTS.load(); await tts.synthesize('Hello', {voice:'amy'})
Web (no build) copy dist/ + voices/ see Deploy on your own site in the GitHub README
Arduino / PlatformIO zip-install or lib_deps = https://github.com/Ampixa/sanoTTS.git arduino/README.md
Hugging Face this repo voice packages above, manifest.json + weights.fp16.bin per voice
Browser nothing ampixa.github.io/sanoTTS

Pip voices: amy, amy-1p1m, amy-1p8m, kristin, hfc, vi, id — fetched from the voices-v1 release into ~/.cache/sanotts/. Pure numpy inference, no torch, no onnxruntime.

How it stacks up

Open small-scale TTS on an honest gate — a diverse 24-sentence set scored with the same no-reference suite (SCOREQ / UTMOS are naturalness predictors, DNSMOS-SIG is signal quality; higher is better). Parameter counts are inference-time and exclude the shared external G2P.

Size comparison: sanoTTS 0.75M-1.8M params vs TinyTTS 1.62M vs Inflect Nano 4.63M vs Kokoro 82M, linear axis

Kokoro is 45x larger than our largest voice, and 110x larger than our smallest. Shipped-file sizes: sanoTTS amy 2.8 MB fp16 and TinyTTS 3.5 MB fp16, both verified from the released files; Kokoro's ~330 MB fp32 is its widely cited public figure.

System Params SCOREQ UTMOS DNS-SIG
sanoTTS (amy) 1.46 M 4.13 4.10 3.61
TinyTTS 1.62 M 3.94 3.65 3.62
Inflect Nano 4.63 M 3.81 3.65 3.58
Kitten TTS nano 15 M 3.02 3.58 3.43
reference (~15 M) ~15 M 4.71 4.47 3.65
Kokoro 82 M 4.89 4.52 3.69

sanoTTS is the smallest model here and the best on naturalness (SCOREQ and UTMOS) among everything up to 15M params — beating TinyTTS while being smaller. On DNSMOS-SIG, TinyTTS edges us by 0.01 — no single metric tells the whole story. It's the only one that runs a full neural stack on a $3 MCU. The frontier only pulls ahead at ~15M-class models and Kokoro (82M, 60x larger) — a gap we don't claim to close. Reproduce it with tools/eval_mos_all.py + tools/eval_scorecard.py in the GitHub repo.

How it works

text → duration → acoustic → decoder → audio

espeak-ng provides phoneme IDs; a duration model predicts timing; an acoustic model predicts generator latents; a decoder renders 22 kHz audio. The web voices (amy, kristin, hfc, and the other languages) use a compact time-domain decoder running in fp32; the 745k on-device model instead uses a quantized int8 iSTFT decoder, sized to fit and run in real time on the ESP32-S3. All models are distilled from a Piper/VITS teacher — see docs/distillation-recipe.md in the GitHub repo for the full recipe.

Deploy

Links

License

GPLv3 — see LICENSE. The pipeline builds on GPLv3 components (notably espeak-ng for G2P, and piper), so the project as a whole is GPLv3.

Copyright (C) 2026 Ampixa.

Files here

Each voice directory is a self-contained fp16 package (weights.fp16.bin + manifest.json + piper-phoneme-config.json + sibilant-injection calibration where applicable), consumable by the sanotts Python package and the portable C runtime. samples/ holds the audio clips embedded above (mp3, one or two per voice + the on-device mcu-745k.mp3).