Instructions to use litert-community/Kokoro-82M with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- LiteRT
How to use litert-community/Kokoro-82M with LiteRT:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
Kokoro-82M β LiteRT (free-text, bucketed)
β οΈ Labeled preview β FP32, CPU. Arbitrary free text β speech (not a single baked sentence). The neural graphs are LiteRT
.tflite; two small steps run host-side (the hn-NSF source STFT and the final iSTFT overlap-add). GPU + quantization are the next steps.
A LiteRT (.tflite) conversion of
hexgrad/Kokoro-82M (StyleTTS2 + ISTFTNet) for
on-device free-text text-to-speech (arbitrary text in, 24 kHz speech out). Audio fidelity
β 0.9994 magnitude-spectrogram correlation to the PyTorch reference (verified across multiple
held-out sentences, not just the export sample).
Kokoro has one data-dependent length (the durationβalignment expansion L = sum(pred_dur)),
which litert_torch cannot keep dynamic (the LSTM sequence axis specializes). It is therefore
split into three fixed-bucket bundles with host steps between them, so arbitrary text works
by left-padding to the bucket and trimming the output (longer text is split into sentences
host-side, each β€ the bucket):
text --(G2P, host)--> phoneme ids
1. kokoro_predictor.tflite : ids[1,128], ref_s[1,256], attn[1,128] -> duration, d, t_en
host: pred_dur = round(duration); alignment one-hot aln[1,128,512]; frame_mask[1,512]
2. kokoro_prosody.tflite : d, t_en, aln, ref_s, frame_mask -> asr, F0, N
host: har = STFT(SineGen(f0_upsamp(F0))) (the hn-NSF excitation)
3. kokoro_vocoder.tflite : asr, F0, N, har, ref_s, frame_mask -> spec, phase
host: iSTFT overlap-add(spec, phase) -> 24 kHz waveform; trim to L*600
Files
| File | Precision | Size | Role |
|---|---|---|---|
kokoro_predictor.tflite |
fp32 | ~91 MB | PL-BERT + duration/text encoders (masked unrolled bi-LSTMs) |
kokoro_prosody.tflite |
fp32 | ~37 MB | shared prosody LSTM + F0/N (masked) |
kokoro_vocoder.tflite |
fp32 | ~236 MB | iSTFTNet decoder β magnitude/phase spectrogram |
istft_Wr_f32.bin, istft_Wi_f32.bin |
fp32 | 880 B each | inverse-DFT bases for the host-side iSTFT |
kokoro_82m_fixedlen_fp32.tflite |
fp32 | ~338 MB | single-graph fixed-length demo build used by the litert-samples text_to_speech sample (see below) |
Token bucket T = 128, frame bucket L = 512 (β 12.8 s of audio per chunk at 24 kHz).
Bundles are voice-independent β the voice is the ref_s input (a voices/*.pt from the
base repo, indexed by token-sequence length).
Fixed-length demo build (litert-samples)
kokoro_82m_fixedlen_fp32.tflite is the earlier single-graph build (fixed-length input, baked
demo sentence length, spec+phase out, host-side iSTFT) kept for the official
litert-samples text_to_speech sample,
which downloads it by this name. Measured on Pixel 8a (fp32, CPU, 4 threads): RTF β 1.8
(~6.6 s to synthesize 3.7 s of audio) β quantization is the path to realtime on-device.
Specs
| Task | Text-to-speech (English), free text, 24 kHz mono |
| Source | hexgrad/Kokoro-82M (StyleTTS2 + ISTFTNet) |
| Fidelity | magspec-corr 0.9994 vs PyTorch (waveform corr β 0.98 β the bounded bucket pad-boundary effect; the spectrum is what's perceived) |
| Runtime | CPU (LiteRT CompiledModel API) |
How it was converted
- Stock official converter (
litert_torch), general path β Kokoro is StyleTTS2/ISTFTNet, not a transformer LLM, so the Generative-API re-authoring path does not apply. - Three fixed-bucket bundles because the dynamic alignment length can't stay symbolic through the converter (the dynamic-LSTM wall). Every workaround is load-bearing and numerically faithful: the 6 bidirectional LSTMs are unrolled as masked bi-LSTMs that carry state through right-padding (a fused
nn.LSTMleaks pad tokens into the backward pass and wrecks prosody); the 58 AdaIN InstanceNorms normalize over real frames only so bucket pad frames don't poison the statistics; the hn-NSF source STFT runs host-side (its atan2 phase flips at the F0β0 pad boundary on-device). - iSTFT runs host-side (vocoder emits spec+phase): the in-graph conv-transpose iSTFT hits a converter weight-dedup bug that fuses the cos/sin DFT bases. The host overlap-add (no learned weights) is numerically exact.
Training data
Inherited from hexgrad/Kokoro-82M: a few hundred hours of permissive / non-copyrighted audio β public-domain audio, audio under permissive licenses (e.g. Koniwa tnc CC BY 3.0, SIWIS CC BY 4.0), and synthetic audio from large-provider TTS β paired with IPA phoneme labels. No proprietary or scraped personal recordings, no custom voice clones. This LiteRT artifact is a format conversion of the released weights and introduces no additional training data.
PII
No personally identifiable information is included. Per the base model's disclosure the training audio is permissive / public-domain / synthetic rather than scraped personal recordings; to the best of our knowledge the released weights contain no PII, and the conversion adds none.
Front-end (free-text G2P)
For arbitrary text with no dropped words (names, brands, numbers), pair with the neural grapheme-to-phoneme front-end: litert-community/Kokoro-G2P-en-US.
Sample / code
- Official Android sample (Interpreter API, fixed-length demo build): google-ai-edge/litert-samples #159
- Conversion / pipeline code: https://github.com/john-rocky/LiteRT-Models
Roadmap
- GPU: the attention's fused-QKV >4-D layout + mask
EQUAL/SELECTkeep it on CPU; decomposing attention to β€4-D would let it ride the GPU delegate. In-graph iSTFT on GPU additionally needs an FFT kernel in the LiteRT GPU delegate (ML Drift). - Quantization (int8/int4) is the obvious next step.
Status
Labeled preview β the converted model is parity-verified. The official litert-samples
text_to_speech sample (fixed-length demo build) is in review at
google-ai-edge/litert-samples #159;
a free-text sample (3-bundle + G2P front-end) is in progress.
Performance
Measured on an Apple M4 Max, CPU/XNNPACK at 8 threads, ai-edge-litert 2.1.6 β median of 15 warm runs per graph, with zero-filled inputs of each graph's declared static shape. Run-to-run spread stayed within 5%.
| Graph | Warm median | First call |
|---|---|---|
kokoro_predictor.tflite |
51.9 ms | 417.1 ms |
kokoro_prosody.tflite |
38.9 ms | 491.4 ms |
kokoro_vocoder.tflite |
396.1 ms | 561.2 ms |
kokoro_82m_fixedlen_fp32.tflite (demo build) |
165.0 ms | 415.8 ms |
The three-bundle chain costs 487 ms of graph time per chunk, and the vocoder is 81% of it. That figure deliberately excludes the host-side iSTFT overlap-add that turns the spectrogram and phase into a waveform, and the free-text G2P front-end β both run outside these graphs β so it is a floor for the chunk, not an end-to-end synthesis time. No end-to-end RTF is quoted for this Mac because the host stages were not measured here.
The Pixel 8a figure quoted above for the fixed-length demo build (RTF β 1.8, fp32, CPU, 4 threads) is an end-to-end number on a different device and includes those host stages, so it is not comparable to the per-graph column.
Android (Pixel 8a)
Android figures use the standard TFLite benchmark_model on a Pixel 8a (Tensor G3, Android 16) β 5 warm-up runs then 20 timed runs, CPU at 4 threads.
| Graph | GPU (OpenCL) | CPU (XNNPACK, 4 threads) |
|---|---|---|
kokoro_82m_fixedlen_fp32.tflite |
did not run | 5501 ms |
kokoro_predictor.tflite |
did not run | 2432 ms |
kokoro_prosody.tflite |
did not run | 539 ms |
kokoro_vocoder.tflite |
did not run | 17067 ms |
4 of these graphs do not load on the OpenCL delegate at all, so on this Pixel 8a the CPU column is the only number for them. Nothing here is faster on the GPU; run the three-bundle pipeline on the CPU on Android β the one accelerator row recorded since is the fixed-length demo build on a Galaxy S26 Hexagon NPU (see Snapdragon NPU (Hexagon) below).
Snapdragon NPU (Hexagon)
kokoro_82m_fixedlen_fp32.tfliteβ the NPU runs it at 1150.4 ms. The GPU does not β the benchmark process was killed, most likely out of memory.kokoro_predictor.tfliteβ neither accelerator produced a usable row on the S26. Both ended the same way: the benchmark process was killed, most likely out of memory.kokoro_prosody.tfliteβ neither accelerator produced a usable row on the S26. NPU: the on-device compile never returned inside the sweep's 1500 s timeout. GPU: the benchmark process was killed, most likely out of memory.kokoro_vocoder.tfliteβ neither accelerator produced a usable row on the S26. NPU: the benchmark process was killed, most likely out of memory. GPU:LiteRtException: Failed to compile model.
| file | backend | compiled | inference (median / min) | load |
|---|---|---|---|---|
kokoro_82m_fixedlen_fp32.tflite |
NPU (Hexagon v81) | on-device JIT | 1150.4 ms / 1096.2 ms | 3037 ms |
Measured on a Samsung Galaxy S26 (Snapdragon 8 Elite Gen 5 / SM8850, Hexagon v81, Android 16) with LiteRT CompiledModel 2.2.0, one accelerator per process, 5 warm-up runs then N=50 timed runs, median reported. The run held thermal status NONE throughout. Headroom 0.67β0.78, where 1.0 is the throttling threshold.
The NPU rows ran the published file unchanged. LiteRT compiled it for the Hexagon on the device at first load. That first compile took 24.3 min here. The load column above is the cached load every later run pays. Recipe and the runtime libraries it needs: NPU guide.
GPU wiring: GPU guide.
Raspberry Pi 5 (CPU)
Measured on a Raspberry Pi 5 Model B Rev 1.1 (8 GB, Raspberry Pi OS 64-bit) with the LiteRT benchmark_model tool from litert-cli-nightly 0.2.0.dev20260805: CPU inference (XNNPACK, 4 threads), 3 invocations per file of 10 warm-up plus 50 timed runs (the tool caps a phase at 150 s, so very slow graphs run fewer β the Runs column is the actual timed total). The latency is the median across invocations; the spread is the minβmax over all timed runs. No thermal throttling occurred during these runs (vcgencmd get_throttled stayed 0x0).
| File | Inference (median) | Spread (minβmax) | Runs | Peak memory |
|---|---|---|---|---|
kokoro_82m_fixedlen_fp32.tflite |
3,122.2 ms | 3,111.7β3,174.8 ms | 146 | 1903 MB |
kokoro_predictor.tflite |
606.4 ms | 602.9β613.6 ms | 150 | 4854 MB |
kokoro_prosody.tflite |
436.9 ms | 429.4β457.6 ms | 150 | 3788 MB |
kokoro_vocoder.tflite |
11,939.4 ms | 11,912.8β12,000.2 ms | 39 | 985 MB |
License
Apache-2.0, inherited from hexgrad/Kokoro-82M.
- Downloads last month
- 634