pocket-tts
Librarykyutai-labs/pocket-tts
A lightweight text-to-speech library that runs efficiently on CPUs.
Overview
Kyutai's Pocket TTS is a compact text-to-speech library with 100M parameters, designed for CPU inference. It supports multiple languages, voice cloning, audio streaming, and low-latency generation. Provides both a Python API and a CLI for easy use.
README Preview
# Pocket TTS\n\n\n\nA lightweight text-to-speech (TTS) application designed to run efficiently on CPUs.\nForget about the hassle of using GPUs and web APIs serving TTS models. With Kyutai's Pocket TTS, generating audio is just a pip install and a function call away.\n\nSupports Python 3.10, 3.11, 3.12, 3.13 and 3.14. Requires PyTorch 2.5+. Does not require the gpu version of PyTorch.\n\n[🔊 Demo](https://kyutai.org/pocket-tts) | \n[🐱💻GitHub Repository](https://github.com/kyutai-labs/pocket-tts) | \n[🤗 Hugging Face Model Card](https://huggingface.co/kyutai/pocket-tts) | \n[⚙️ Tech report](https://kyutai.org/blog/2026-01-13-pocket-tts) |\n[📄 Paper](https://arxiv.org/abs/2509.06926) | \n[📚 Documentation](https://kyutai-labs.github.io/pocket-tts/)\n\n\n## Main takeaways\n* Runs on CPU\n* Small model size, 100M parameters\n* Audio streaming\n* Low latency, ~200ms to get the first audio chunk\n* Faster than real-time, ~6x real-time on a CPU of MacBook Air M4\n* Uses only 2 CPU cores\n* Python API and CLI\n* Voice cloning\n* Multi-language support: english, french, german, portuguese, italian, spanish\n* Can handle infinitely long text inputs\n* [Can run on client-side in the browser](#in-browser-implementations)\n\nAdditional languages may be added in the future.\n\n## Trying it from the website, without installing anything\n\nNavigate to the [Kyutai website](https://kyutai.org/pocket-tts) to try it out directly in your browser. You can input text, select different voices, and generate speech without any installation.\n\n## Trying it with the CLI\n\n### The `generate` command\nYou can use pocket-tts directly from the command line. We recommend using\n`uv` as it installs any dependencies on the fly in an isolated environment (uv installation instructions [here](https://docs.astral.sh/uv/getting-started/installation/#standalone-installer)).\nYou can also use `pip install pocket-tts` to install it manually.\n\nThis will generate a wav file `./tts_output.wav` saying the
FAQ (5)
TroubleshootingHow do I fix PocketTTS finetuning error "no readable samples ... (0 failures)" with a small dataset?
The manifest paths are usually fine. The length-bucketing loader does not emit batches until each loader shard contains at least num_bucket_batches × batch_size samples. With the old defaults, this required 20 × 64 × 6 = 7,680 utterances per GPU. Smaller shards produced the misleading 0 failures error.
Upgrade to a version containing PR #342, which lowers the defaults to num_bucket_batches: 5 and loader_procs: 3 and validates train/validation manifests at startup.
For very small finetuning datasets, disable bucketing and reduce loader processes in finetune.yaml:
data:
num_bucket_batches: 1 # 1 disables length bucketing
loader_procs: 1
batch_size: 8 # must be no larger than the smallest train/validation shard
The requirement per GPU is:
num_bucket_batches × batch_size × loader_procs
With num_bucket_batches: 1 and loader_procs: 1, each split only needs at least batch_size readable entries. Make sure the validation manifest also meets this size because validation uses the training batch size; otherwise the run fails at the first validation step. Alternatively, add more validation samples or increase the dataset size.
TroubleshootingHow to fix French Pocket TTS garbling or cutting off one- or two-word utterances?
This is caused by early EOS termination: for some French voices, the EOS logit can reach about -3 during the leading pause, crossing the default -4 threshold before speech is generated, so short texts end prematurely.
Fix by updating to the release containing the PR **"Ignore EOS on the first 6 generated frames"** and the new French models. Then use either:
- --language french — loads the new 6-layer French model
- french_24l — loads the new 24-layer French model
Immediate workaround if you cannot update: never synthesize fewer than three words. In streaming mode, concatenate a too-short chunk with the next chunk before synthesis. This reduced the reported failure rate from about 40% for 1–2 words to about 2% for 3+ words.
Adding a lead-in filler word did not help, and quantize=True made the issue worse on Apple Silicon.
TroubleshootingWhy do Spanish, French, or english_2026-01 TTS models use temperature 0.7 and produce erratic prosody?
Those shipped YAML configs omit default_temperature, so TTSModel.load_model() falls back to the schema default of 0.7 instead of the tuned English value 0.3. The fix changes the schema default to 0.3, making all shipped models sample at 0.3 while still allowing per-config overrides. After upgrading to a release containing the fix for #322, verify with:
m = TTSModel.load_model(language="spanish")
print(m.temp) # should be 0.3As a workaround on older versions, add the following to the affected config (for example
spanish.yaml, french.yaml, or english_2026-01.yaml):default_temperature: 0.3TroubleshootingHow do I stop Pocket TTS generation when a client disconnects from /tts mid-stream?
Upgrade to a Pocket TTS release containing PR #228. The fix creates a per-request threading.Event, passes it into generate_audio_stream(), and sets it when the client disconnects. The generation loop in generate_data_with_state checks this event and exits through its normal termination path instead of decoding the remaining text. If applying the fix manually: 1) create stop_event = threading.Event() for each request, 2) pass it to generate_audio_stream(..., stop_event=stop_event), 3) set stop_event.set() in the disconnect/cancellation handler, 4) check the event inside the generation loop and stop before running another tts_model request. This prevents wasted CPU and avoids concurrent use of the non-thread-safe model; reported interrupt-to-next-reply latency drops from about 7.9 s to 0.27 s.
TroubleshootingHow do I fix pocket-tts export-voice failing because of an invalid Hugging Face token?
The failure can be caused by a stale HF_TOKEN environment variable. Remove it and run the export again.
PowerShell (current terminal):
Remove-Item Env:HF_TOKEN
To remove it permanently from your Windows user environment:
[Environment]::SetEnvironmentVariable("HF_TOKEN", $null, "User")
Restart your terminal, verify it is empty with echo $env:HF_TOKEN, then rerun:
pocket-tts export-voice .\turtle_sample.wav turtle.safetensors
If voice cloning requires authentication, replace the stale token with a valid one from Hugging Face instead:
$env:HF_TOKEN = "hf_your_valid_token"Or set it permanently with
[Environment]::SetEnvironmentVariable("HF_TOKEN", "hf_your_valid_token", "User") and restart the terminal.