Model reference · open weights
sanoTTS is an open-weight audio or speech model from ampixa. AxForge deploys and operates it for you on dedicated EU-owned hardware — with the licence handled where one is required.
Available as managed deployment — configured and operated for you on dedicated EU hardware, quoted per deployment.
What it is
| Released by | ampixa |
|---|---|
| Type | Audio & music |
| Task | Text→speech |
| Runs with | sanotts |
| Released | 2026-07-13 |
| Popularity | 1k downloads / month |
| Licence | Open, with conditions |
About
sano (सानो) — Nepali for "small." A family of tiny neural text-to-speech voices — 294k to 2.27M 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.
| Parameter range | 294,279 – 2,272,145 |
| 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 | 337 KB to 8.7 MB, zero dependencies (espeak-ng phonemizer included) |
| Coverage | 11 voices across 6 languages — English, Nepali (नेपाली), Hindi (हिन्दी), Vietnamese (Tiếng Việt), Indonesian (Bahasa), Chinese (中文) |
| License | open source, GPL-3.0 |
Live demo: tts.ampixa.com/sanoTTS — every voice synthesizes your text live in the browser, no server, no upload.
Both packages stream their weights from this repo by default.
import sanotts
sanotts.synthesize("Hello world", voice="heart") # downloads heart/ from here
import { SanoTTS } from 'sanotts-web'; // fetches web/voices/ from here
const tts = await SanoTTS.load();
const result = await tts.synthesize('Hello world', { voice: 'heart' });
Python needs sanotts >= 0.3.0, the browser sanotts-web >= 0.3.0. Both fall
back to the GitHub releases or the Pages host if Hugging Face cannot be
reached, so an outage here cannot break an install. Python packages land in
~/.cache/sanotts/; set SANOTTS_VOICE_SOURCE=hf or =github to pin one
host. In the browser, passing voiceBase yourself turns the fallback off, so
a self-hosted deployment never quietly reaches back to our servers.
Two clips per voice are in this repo's samples/ folder; one is embedded
below. "Package here" means this repo carries that voice's weights. The three
languages without one currently ship only through the
browser demo and the GitHub repo's
web/voices/ — their packages haven't been exported yet.
| Voice | Language | Params | SCOREQ | Package here | Sample |
|---|---|---|---|---|---|
| heart | English 🇺🇸 | 2.27 M | 3.48 | heart/ | |
| hfc | English 🇺🇸 | 1.83 M | 3.94 | hfc-en-1p8m/ | |
| amy | English 🇺🇸 | 1.46 M | 4.13 | amy-en-1p46m/ | |
| kristin | English 🇺🇸 | 1.40 M | 4.09 | kristin-en-1p4m/ | |
| amy-small | English 🇺🇸 | 1.08 M | 3.70 | amy-en-1p1m/ | |
| robot (on-device, int8) | English 🇺🇸 | 567 k | — | not packaged here (int8 MCU format) | |
| heart-nano | English 🇺🇸 | 294 k | 2.29 | heartnano/ | |
| 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 |
SCOREQ is a no-reference naturalness predictor, higher is better; it is only reported for the English voices, which share one 24-sentence eval set. The other languages haven't been scored against a comparable reference yet.
Size does not order this table, and we are not going to pretend it does.
amy at 1.46M scores higher than heart at 2.27M because they come from
different teachers and different architectures, not because one is bigger.
amy and the voices above it are the piperlite lineage, distilled from a
Piper/VITS teacher at 22.05 kHz. heart and heart-nano are the newer
nano lineage — 24 kHz, mel-100 → ConvNeXt1D → iSTFT, distilled from a
Kokoro teacher through a frozen Vocos — which is the one that quantizes to
int8 and runs on a microcontroller. The two are not interchangeable and the
sanotts package picks the right runtime for you.
The heart and heart-nano scores were re-measured on 2026-09-04; the eval
set, checkpoint hashes, exact commands and all 24 per-clip scores are in
evidence/heart-diverse24-remeasure-20260904.json.
They were scored on the float32 reference render. The shipped heart-nano
int8 export tracks that render at 0.981 waveform correlation, and heart
ships as float32 because its int8 export reached only 0.951 against a 0.98
gate.
The "robot" row is the 567,008-parameter model that runs on the ESP32-S3.
| Platform | Install | Then |
|---|---|---|
| Python | pip install sanotts | sanotts say "Hello" --voice heart -o hello.wav |
| Web (npm) | npm install sanotts-web | const tts = await SanoTTS.load(); await tts.synthesize('Hello', {voice:'heart'}) |
| 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 | the voice packages above, downloaded for you by pip install sanotts |
| Browser | nothing | tts.ampixa.com/sanoTTS |
Pip voices: heart, hfc, amy-1p8m, amy, kristin, vi, id,
amy-1p1m, heart-nano. Pure numpy infer
From the published model card. Full card on the HuggingFace links in the sidebar.
How it works
Using it via the API
Once AxForge deploys sanotts for you, it answers on the OpenAI-compatible API — the same base URL and keys as every other model. (sanotts below is illustrative; you get the exact model name on deployment.)
$ curl -sS https://api.axforge.ai/v1/audio/transcriptions \ -H "Authorization: Bearer $AXFORGE_API_KEY" \ -F model="sanotts" -F file=@audio.mp3
Create an account — your API key is available in the console. 3M free tokens every 30 days with every new account.