The MediaPipe Text-to-Speech task lets you synthesize natural-sounding speech audio from
text directly on-device using open-weight neural text-to-speech
models (Kokoro-82M, PocketTTS 100M, or Phonon 31M), each packaged in
a single .litertlm bundle. The task operates as a headless PCM audio
generator, returning normalized 24 kHz mono 32-bit floating-point (float32)
audio samples that your application can play through platform audio APIs, save
as WAV files, or pass to downstream audio pipelines.
- Input: UTF-8 text string (single sentence, multi-sentence paragraph, or
incremental text deltas pushed using
TtsStream) and optional per-utteranceSynthesisOptions. - Output:
AudioResult(unary) or a stream ofAudioChunkbuffers (streaming) containing normalized 32-bit float mono PCM samples in[-1.0, 1.0]at24,000 Hz.
Key capabilities of the MediaPipe Text-to-Speech task include:
- Single-file
.litertlmdeployment: Packages each model's weights, text-processing data, and voice embeddings into a single.litertlmbundle. - Low-latency streaming speech synthesis: Streams
AudioChunkbuffers clause-by-clause (synthesizeStream/synthesize_stream) as each clause finishes vocoding so audio playback starts after the first clause, and supports incremental token-by-token input (openStream/start_streamwithpushTextandfinishInput) for real-time LLM-to-TTS pipelines. - Per-utterance voice switching: Switch between bundled voices on a
per-utterance basis using
SynthesisOptionswithout reloading the model. With Kokoro-82M, switching takes less than 1 ms. - Automatic sentence chunking: Splits multi-sentence paragraphs at clause
and sentence boundaries (
.,!,?,;,:,\n) so long inputs stay within the model's context window. - Immediate barge-in cancellation: Thread-safe, lock-free
cancel()API aborts in-flight unary or streaming synthesis within milliseconds when a user interrupts or a coroutine, async sequence, or task is canceled.
Get Started
Start using this task by following one of these implementation guides for your target platform. These platform-specific guides walk you through a basic implementation of this task, including a recommended model, and code example with recommended configuration options:
| Platform | Code Example | Guide |
|---|---|---|
| Android | Code example | Guide |
| iOS | Code example | Guide |
| Python | Colab | Guide |
How it works
For Kokoro-82M, the MediaPipe Text-to-Speech task uses a multi-stage runtime pipeline:
- Sentence segmentation (
ExtractNextChunk): Multi-sentence input text (or incremental text pushed usingTtsStream) is segmented at punctuation boundaries (max_buffer_size = 200characters) to fit the acoustic model's token capacity. - Grapheme-to-Phoneme (G2P) frontend: Converts normalized text into phoneme token IDs using the phonetic dictionaries bundled in the model for each supported language.
- Acoustic stage (
KokoroAcousticStage): Runs the LiteRT acoustic model conditioned on the selected voice's510 x 256style embedding vector to predict duration tokens, pitch (F0) and energy contours, and 512-channel acoustic features. - Neural vocoder stage (
KokoroVocoderStage): Runs the ISTFTNet-based LiteRT vocoder model (accelerated on CPU using XNNPACK or hybrid CPU+GPU) to convert the acoustic features and contours into a 24 kHz monofloat32PCM waveform. During streaming synthesis, each clause's vocodedAudioChunkis emitted immediately withMultiStagedSession::ProcessNext(), while unary synthesis drains the stream into a single concatenatedAudioResult.
PocketTTS 100M and Phonon 31M use a different architecture: a Flow-LM transformer generates audio latents, and a Mimi neural audio decoder converts them into 24 kHz audio. Both models run on CPU.
Models
The MediaPipe Text-to-Speech task requires a speech synthesis model in the LiteRT-LM
(.litertlm) format. Models aren't included in the MediaPipe Tasks libraries.
Download one of the following pre-packaged model bundles from Hugging Face,
store it on the device, and pass the local path to
BaseOptions.model_asset_path.
| Model | Model Bundle | Size | Quantization | Delegate | License | Supported Locales | Recommended Use Case |
|---|---|---|---|---|---|---|---|
| Kokoro-82M | kokoro_int8_gpu_fp16.litertlm |
~295 MB | INT8 acoustic + FP16 GPU vocoder | GPU | Apache 2.0 | All nine locales (en-US, en-GB, es, fr-FR, it, pt-BR, hi, cmn, ja) |
Multilingual on-device speech synthesis across mobile, desktop, and web. |
| PocketTTS 100M | pocket_tts_int8.litertlm |
~760 MB | INT8 | CPU | CC BY 4.0 | Seven locales (en-US, fr-FR, de-DE, es-ES, it-IT, pt-BR, nl-NL) |
Multilingual speech synthesis on CPU. |
| PocketTTS 100M (English) | pocket_tts_en_int8.litertlm |
~163 MB | INT8 | CPU | CC BY 4.0 | en-US |
English speech synthesis on CPU with a smaller download. |
| Phonon 31M | phonon_int8.litertlm |
~87 MB | INT8 | CPU | Apache 2.0 | en-US |
English speech synthesis with the smallest download. |
Supported languages and voices
Each model bundle includes its own set of voices. You can enumerate the voices
in the loaded .litertlm bundle at runtime using listVoices() /
list_voices().
Kokoro-82M voices
Kokoro-82M includes 54 pre-packaged voice embeddings across nine locales
(eight languages). Each voice ID uses a two-letter prefix
<lang_char><gender_char>_<name> (for example, af_heart = American English
Female "Heart", ef_dora = Spanish Female "Dora").
| Language | BCP 47 Language Tag | Prefix | Bundled Voice IDs (54 Total) |
|---|---|---|---|
| English (American) | en-US |
af_, am_ |
Female (11): af_alloy, af_aoede, af_bella, af_heart (default), af_jessica, af_kore, af_nicole, af_nova, af_river, af_sarah, af_skyMale (9): am_adam, am_echo, am_eric, am_fenrir, am_liam, am_michael, am_onyx, am_puck, am_santa |
| English (British) | en-GB |
bf_, bm_ |
Female (4): bf_alice, bf_emma, bf_isabella, bf_lilyMale (4): bm_daniel, bm_fable, bm_george, bm_lewis |
| Spanish | es |
ef_, em_ |
Female (1): ef_doraMale (2): em_alex, em_santa |
| French | fr-FR |
ff_ |
Female (1): ff_siwis |
| Hindi | hi |
hf_, hm_ |
Female (2): hf_alpha, hf_betaMale (2): hm_omega, hm_psi |
| Italian | it |
if_, im_ |
Female (1): if_saraMale (1): im_nicola |
| Portuguese (Brazilian) | pt-BR |
pf_, pm_ |
Female (1): pf_doraMale (2): pm_alex, pm_santa |
| Mandarin Chinese | zh-CN / cmn |
zf_, zm_ |
Female (4): zf_xiaobei, zf_xiaoni, zf_xiaoxiao, zf_xiaoyiMale (4): zm_yunjian, zm_yunxi, zm_yunxia, zm_yunyang |
| Japanese | ja |
jf_, jm_ |
Female (4): jf_alpha, jf_gongitsune, jf_nezumi, jf_tebukuroMale (1): jm_kumo |
PocketTTS 100M voices
Each PocketTTS voice speaks one language. The multilingual bundle
(pocket_tts_int8.litertlm) includes all of the following voices, and the
English bundle (pocket_tts_en_int8.litertlm) includes only English voices.
| Language | BCP 47 Language Tag | Voice IDs |
|---|---|---|
| English | en-US |
alba (default), azelma, cosette, eponine, fantine, javert, jean, marius |
| French | fr-FR |
estelle |
| German | de-DE |
juergen |
| Spanish | es-ES |
lola |
| Italian | it-IT |
giovanni |
| Portuguese (Brazilian) | pt-BR |
rafael |
| Dutch | nl-NL |
daan |
As with Kokoro-82M, set only voice_id when you switch voices. If you also set
a locale that doesn't match the voice's language, the task uses the default
voice for that locale instead.
Phonon 31M voices
Phonon 31M speaks English (en-US) only. It includes five voices:
freya (default), claire, lucas, lukas, and sofia.
Model license and attribution
Kyutai publishes PocketTTS under the Creative Commons Attribution 4.0 (CC-BY-4.0) license. If you distribute an app that uses a PocketTTS model, give appropriate credit to Kyutai, for example in your app's open source notices.
Task configuration
Task options (TextToSpeechOptions)
| Option Name | Description | Value Range | Default Value |
|---|---|---|---|
base_options.model_asset_path |
Path (or URL on Web) to a supported .litertlm model bundle (see Models). Keep the original filename, which the task uses to detect the model type. |
String / Path | Required |
base_options.delegate |
Hardware acceleration delegate used by the LiteRT runtime. When set to GPU, the Kokoro acoustic stage executes on CPU (XNNPACK) and the neural vocoder executes on GPU (OpenCL/Metal/WebGPU) with CPU fallback. PocketTTS and Phonon always run on CPU. | BaseOptions.Delegate.CPU, BaseOptions.Delegate.GPU |
BaseOptions.Delegate.CPU |
speaking_rate |
Speaking rate multiplier applied to synthesized audio (1.0 represents normal speaking speed). |
Float (0.1, 4.0] |
1.0 |
target_bucket |
Target sequence-length bucket for the Kokoro acoustic/vocoder graph (for example, 64, 128, or 256 tokens). Smaller buckets reduce synthesis latency for short sentences; 0 uses the model's default capacity. PocketTTS and Phonon ignore this option. |
0, 64, 128, 256 |
0 |
default_voice_id |
Default voice ID (for example, "af_heart" for Kokoro-82M, "alba" for PocketTTS, or "freya" for Phonon). Can be overridden per utterance using SynthesisOptions. |
String (Optional) | The model's default voice |
default_locale |
Optional default BCP 47 language tag (for example, "en-US", "es", "zh-CN"). When omitted, the task automatically infers the language from the selected voice. |
BCP 47 String (Optional) | Inferred from voice |
cache_directory |
Writable directory path used to persist unpacked phonetic dictionary assets and LiteRT XNNPACK weight caches across runs for faster cold starts. Used by Kokoro-82M. | Directory Path (Optional) | "" |
Per-utterance options (SynthesisOptions)
| Option Name | Description | Default Value |
|---|---|---|
voice_id |
Overrides the voice profile for a single synthesize call (for example, switching from "af_heart" to "ef_dora" in under 1 ms without reloading model weights). |
null / None (uses task default) |
locale |
Optional BCP 47 locale override for a single utterance. Leave unset (null / None) when switching voices so the engine automatically resolves the voice's target language from the voice ID. |
null / None (inferred from voiceId) |