Model reference · open weights
Matcha-TTS is an open-weight audio or speech model from litert-community. 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 | litert-community |
|---|---|
| Type | Audio & music |
| Task | Text→speech |
| Runs with | litert |
| Released | 2026-06-26 |
| Popularity | 1k downloads / month |
| Licence | Open weights |
About
LiteRT is Google's on-device runtime, the new name for TensorFlow Lite (Android: com.google.ai.edge.litert:litert), and litert-torch, the renamed ai-edge-torch, is its PyTorch converter: a PyTorch model converted unmodified with litert_torch.convert matched the original to 4e-7 on a Galaxy S26 (measured, LiteRT 2.2.0, Android 16, 2026-09-05).
Measured on device (edge-compat, dp_g2p_matcha_fp16): Raspberry Pi 5 · LiteRT 2.2.0.dev20260804 · CPU/XNNPACK, 4 threads · 22.0 ms p50 (2026-08-31); browser · Chromium 151 on M4 Max · LiteRT.js 2.5.3 · WebGPU · 136 ms p50 (2026-08-11). Record: https://github.com/john-rocky/edge-compat/blob/main/cards/matcha-tts__dp_g2p_matcha_fp16/CARD.md
Measured on device (edge-compat, matcha_decoder_fp16): Raspberry Pi 5 · LiteRT 2.2.0.dev20260804 · CPU/XNNPACK, 4 threads · 69.7 ms p50 (2026-08-31); browser · Chromium 151 on M4 Max · LiteRT.js 2.5.3 · WebGPU · 9.55 ms p50 · output differs from CPU (max rel diff 6e+03) (2026-08-11). Record: https://github.com/john-rocky/edge-compat/blob/main/cards/matcha-tts__matcha_decoder_fp16/CARD.md
Measured on device (edge-compat, matcha_textenc_fp16): Raspberry Pi 5 · LiteRT 2.2.0.dev20260804 · CPU/XNNPACK, 4 threads · 38.7 ms p50 (2026-08-31); browser · Chromium 151 on M4 Max · LiteRT.js 2.5.3 · WebGPU · 5.99 ms p50 · output matches CPU (2026-08-11). Record: https://github.com/john-rocky/edge-compat/blob/main/cards/matcha-tts__matcha_textenc_fp16/CARD.md
Measured on device (edge-compat, matcha_vocoder_fp16): Raspberry Pi 5 · LiteRT 2.2.0.dev20260804 · CPU/XNNPACK, 4 threads · 5825 ms p50 (2026-08-31); browser · Chromium 151 on M4 Max · LiteRT.js 2.5.3 · WebGPU · 104 ms p50 · output differs from CPU (max rel diff 0.22) (2026-08-11). Record: https://github.com/john-rocky/edge-compat/blob/main/cards/matcha-tts__matcha_vocoder_fp16/CARD.md
On-device English text-to-speech for Android via LiteRT CompiledModel. This is the
FFT-free TTS lane: Matcha-TTS pairs a
conditional flow-matching (CFM) acoustic model with a HiFi-GAN time-domain vocoder, so
there is no FFT/iSTFT anywhere in the synthesis path. 22.05 kHz, LJSpeech voice.
Try it in your browser: john-rocky.github.io/page-demos/matcha-tts —
the same four .tflite files below running on LiteRT.js
(text encoder + vocoder on WebGPU, decoder on WASM). Nothing to install; inference runs on your machine.
Converted from the official matcha_ljspeech + hifigan_T2_v1 checkpoints with
litert-torch, re-authored to be ML-Drift-GPU-clean
(per-graph tflite-vs-torch corr 1.000000; end-to-end waveform corr ≥0.99). fp16 weights.
| File | Size | In → Out | Delegate (Pixel 8a) |
|---|---|---|---|
matcha_textenc_fp16.tflite | 15 MB | emb[1,256,192] + mask[1,1,256] → mu[1,80,256], logw[1,1,256] | GPU |
matcha_decoder_fp16.tflite | 23 MB | x,mu[1,80,512] + t_sin[1,160] + mask[1,1,512] → v[1,80,512] | CPU¹ |
matcha_vocoder_fp16.tflite | 29 MB | mel[1,80,512] → wav[1,1,131072] | GPU |
dp_g2p_matcha_fp16.tflite | 26 MB | text[1,96] (char ids) → logits[1,96,64] (IPA) | CPU |
emb.bin | 0.1 MB | phoneme embedding table (178×192 f32, host lookup) | host |
g2p_dict.txt.gz | 1.8 MB | 275k-entry espeak-IPA dictionary (primary G2P) | host |
config.json, g2p_meta.json | — | symbols, shapes, mel stats, G2P tokenizer tables | host |
¹ The CFM decoder runs on the CompiledModel CPU delegate. It converts GPU-clean and is correct on CPU, but the Mali ML Drift GPU delegate mis-fuses the decoder's transformer blocks at large activation magnitude (the same block is correct as a standalone GPU graph, corr 0.984, but collapses to corr 0.006 fused — a graph-fusion bug, not a bad op). text encoder + vocoder run on the GPU; the GPU vocoder dominates wall time so the pipeline stays realtime (RTF ~0.8).
text --G2P(CPU dict+neural)--> phoneme ids
--host: embed + intersperse + pad--> text_encoder(GPU) -> mu, logw
--host: durations + length-regulator--> mu_y[1,80,T]
--host: Euler ODE loop (N steps)--> decoder(CPU) x N -> v
--host: denormalize--> vocoder(GPU) -> waveform
Fixed shapes (256 phonemes, 512 mel frames ≈ 5.9 s); a runtime float mask makes padded positions a no-op so one compiled graph handles any length.
Android (Kotlin, LiteRT CompiledModel)
fun load(name: String, acc: Accelerator) = // models staged in filesDir
CompiledModel.create(File(filesDir, name).absolutePath, CompiledModel.Options(acc), null)
val textenc = load("matcha_textenc_fp16.tflite", Accelerator.GPU)
val decoder = load("matcha_decoder_fp16.tflite", Accelerator.CPU) // Mali mis-fuses this graph on GPU
val vocoder = load("matcha_vocoder_fp16.tflite", Accelerator.GPU)
val teIn = textenc.createInputBuffers(); val teOut = textenc.createOutputBuffers()
teIn[0].writeFloat(emb) // [1,256,192] host phoneme-embedding lookup (emb.bin), blanks interspersed
teIn[1].writeFloat(tmask) // [1,1,256] 1 = real phoneme position
textenc.run(teIn, teOut) // -> mu[1,80,256], logw[1,1,256]
// host: durations ceil(exp(logw))·0.95 -> length-regulate mu -> mu_y[1,80,512]; 10 Euler steps of
// decoder(x, mu_y, t_sin[1,160], ymask[1,1,512]); mel = x·2.116101 − 5.536622 -> vocoder -> wav.
// Full pipeline: the text_to_speech (Matcha-TTS) sample in google-ai-edge/litert-samples.
Python (desktop verification)
import gzip, json, math, numpy as np, soundfile as sf
from ai_edge_litert.interpreter import Interpreter
MAXT, MAXM, LS = 256, 512, 0.95
cfg = json.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 matcha-tts for you, it answers on the OpenAI-compatible API — the same base URL and keys as every other model. (matcha-tts 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="matcha-tts" -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.