Run High-Quality TTS Locally on CPU with Kokoro
Kokoro packs realistic multi-language speech synthesis into an 82M parameter model that runs comfortably on CPU. No GPU needed, OpenAI-compatible API, ~50 voices — and it fits in a 5 GB container.
# Run High-Quality TTS Locally on CPU with Kokoro
TL;DR: Kokoro-82M is an open-weight TTS model that produces genuinely realistic speech in multiple languages — and it runs on CPU. A 12-year-old i7-4770K renders a sentence in under 5 seconds. It ships as a single Docker container with an OpenAI-compatible API, ~50 voices, and zero cloud dependencies. If you've ever wanted local speech synthesis that doesn't sound like a robot from 2005, this is it.The State of Local TTS
Just a few years ago, realistic local speech generation felt like science fiction. You had two choices: pay per character to cloud APIs (ElevenLabs, OpenAI TTS, Google Cloud TTS), or accept that local models sounded like a Speak & Spell having a stroke.
That's changed. Kokoro — an 82 million parameter model from hexgrad — delivers speech quality that's genuinely competitive with commercial APIs, and it does it on hardware that was obsolete before ChatGPT existed.
The model recently hit the top of Hacker News (344 points, 72 comments), driven by a detailed write-up from Ariya Hidayat. The takeaway was simple: you don't need a GPU for high-quality TTS anymore.
Why This Matters
The value proposition of local TTS isn't just about cost (though at under $1 per million characters on hosted APIs, it's absurdly cheap). It's about three things that cloud TTS can't solve:
1. Privacy. Every time you send text to a cloud TTS API, you're sending someone a transcript of what you want spoken. For anything sensitive — medical dictation, legal documents, private messages — that's a non-starter. Local TTS keeps the text on your machine. 2. Latency. Network round-trips add 200-500ms before the first audio byte arrives. For interactive applications (voice assistants, real-time narration, accessibility tools), that lag is noticeable and annoying. Local inference has microseconds of overhead. 3. Offline capability. Airplanes, remote clinics, field work, spotty WiFi. Cloud APIs are dead in the water without connectivity. Local models keep working.Combine Kokoro with a local LLM and you've got a fully offline, fully private voice assistant pipeline. No API keys, no usage quotas, no data leaving your machine.
Getting Started: One Command
The simplest way to run Kokoro is through Kokoro-FastAPI, a Dockerized wrapper that bundles the model, the inference server, and a simple web UI into a single container:
# Docker
docker run -p 8880:8880 ghcr.io/remsky/kokoro-fastapi-cpu
# Podman (no daemon, rootless)
podman run -p 8880:8880 ghcr.io/remsky/kokoro-fastapi-cpu
That's it. The container is about 5 GB (pre-downloaded voice models are bundled), and once it's running, you've got:
- A web UI at
http://localhost:8880/webfor quick testing - An OpenAI-compatible speech API at
http://localhost:8880/v1/audio/speech
The OpenAI compatibility is the killer feature here. If you already have code that calls OpenAI's TTS endpoint, switching to Kokoro is a one-line base URL change.
Using the API
Since Kokoro-FastAPI mimics the OpenAI speech API, the integration is trivial.
JavaScript:// Save as speak.js — requires Node.js 18+
const response = await fetch(
`${process.env.TTS_API_BASE_URL || 'http://127.0.0.1:8880/v1'}/audio/speech`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
model: 'kokoro',
input: 'Good morning! How are you today?',
voice: 'af_heart',
response_format: 'mp3'
})
}
);
const buffer = Buffer.from(await response.arrayBuffer());
require('fs').writeFileSync('output.mp3', buffer);
console.log('Saved to output.mp3');
Python:
import os
import requests
api_base = os.environ.get('TTS_API_BASE_URL', 'http://127.0.0.1:8880/v1')
response = requests.post(
f"{api_base}/audio/speech",
json={
"model": "kokoro",
"input": "Good morning! How are you today?",
"voice": "af_heart",
"response_format": "mp3"
}
)
with open('output.mp3', 'wb') as f:
f.write(response.content)
print('Saved to output.mp3')
The full example repo is at github.com/remotebrowser/speak — it includes auto-playback via SoX if you have it installed.
Voice Selection
Kokoro ships with about 50 distinct voices across 8 languages (English, Mandarin, Hindi, Japanese, Korean, French, Italian, Brazilian Portuguese). The English voices are the most polished, with both American and British accents available.
Notable English voices:
| Voice ID | Character | Accent |
|---|---|---|
af_heart | Female, warm | American |
af_bella | Female, clear | American |
am_adam | Male, neutral | American |
am_eric | Male, deeper | American |
bf_emma | Female, pleasant | British |
bm_george | Male, measured | British |
Full list: huggingface.co/hexgrad/Kokoro-82M/blob/main/VOICES.md
Switching voices is just changing the voice parameter in your API call. No re-downloading, no separate model files — all voices are in the container already.
Performance: CPU Benchmarks
Here's where it gets impressive. Ariya Hidayat benchmarked a short test paragraph across different CPUs:
> Jupiter is the largest and most massive planet in our solar system. This gas giant, made mostly of hydrogen and helium, is known for its Great Red Spot — a massive storm observed for centuries.
| CPU | Generation Time | Released |
|---|---|---|
| Intel Core i7-4770K | 4.7 seconds | 2013 |
| Apple M2 Pro | 4.5 seconds | 2023 |
| AMD Ryzen 7 8745HS | 1.5 seconds | 2024 |
The i7-4770K is twelve years old. It was released when the iPhone 5S was cutting edge and "AI" meant the pathfinding in Starcraft II. It still renders a full paragraph of speech in under 5 seconds.
For perspective: that's roughly real-time for spoken output. The paragraph above takes about 5 seconds to read aloud. So even on ancient hardware, Kokoro keeps pace with human speech.
On modern CPUs, it's 3-4x faster than real-time. The Ryzen 7 8745HS (a laptop chip) renders in 1.5 seconds what takes a human 5 seconds to speak.
Architecture: What's Under the Hood
Kokoro uses the StyleTTS 2 architecture (arXiv:2306.07691), which separates style modeling from acoustic generation. The key insight is that speech has two components: what you're saying (the phonemes) and how you're saying it (the style — pitch, rhythm, timbre). StyleTTS 2 models these independently, which is why 82M parameters can produce results that rival models 10x the size.
Training cost was about $1,000 in A100 GPU hours — total. Not per run. Total. That's a weekend on a single rented GPU. The model is Apache 2.0 licensed, so you can deploy it commercially, modify it, or embed it in your own products.
Under the hood, Kokoro uses misaki for grapheme-to-phoneme conversion (G2P), which handles the messy work of turning written text into pronunciation guides. It supports IPA (International Phonetic Alphabet) annotations for custom pronunciations, which is useful for domain-specific terminology, names, or homographs.
Practical Use Cases
The HN thread surfaced several real-world deployments that are worth highlighting:
Accessibility. Multiple commenters are using Kokoro for screen readers and assistive tech. One built a full pipeline for generating spoken versions of articles and blog posts. The privacy angle is critical here — assistive tech often reads sensitive content (emails, messages, medical info), and cloud TTS APIs mean that content leaves the device. Article narration.bronco21016 on HN described a setup where Kokoro reads articles and blog posts, serving them as an RSS podcast for morning commutes. Combined with a content pipeline (RSS → text extraction → TTS → podcast feed), you've got a personalized news radio that never touches a cloud service.
Language learning. With 8 languages and ~50 voices, Kokoro is useful for generating pronunciation examples. The IPA annotation support means you can force specific pronunciations for trickier words.
Voice assistants. When paired with a local LLM (Llama, Mistral, or even a quantized model on CPU), Kokoro provides the speech output side of a fully offline voice assistant. Ask a question → local LLM generates text → Kokoro speaks the answer. No internet required.
Chrome extension. SambhavGupta built a Chrome extension that uses Kokoro to read webpages aloud with simultaneous text highlighting. No copy-paste, no container management — just click and listen.
Limitations to Know About
Kokoro isn't perfect, and there are a few sharp edges worth knowing before you build on it:
1. Single-word handling. The model struggles with isolated words. Assudobash1 noted on HN, asking Kokoro to say "six" often produces "ah-six-ah" — extra phonemes bleeding from start and end tokens. The workaround is to embed the word in a carrier phrase, then crop the output using word-level timestamps.
2. English is the focus. While it supports 8 languages, the English voices are noticeably more natural. Non-English voices are functional but less polished. If your primary use case is, say, Japanese or Hindi, set expectations accordingly.
3. No emotion control. Unlike commercial APIs (ElevenLabs has "excited," "whisper," etc.), Kokoro doesn't expose style knobs beyond voice selection. It's one voice, one tone, consistently.
4. Container size. At 5 GB, the Docker image isn't tiny. If you're deploying to edge devices or have bandwidth constraints, you'll want to look at the standalone Python package instead of the container.
5. It's TTS only — no STT. If you need both text-to-speech and speech-to-text, check out Speaches, which bundles Kokoro TTS with Whisper STT in a single container. Two birds, one stone.
The Bigger Picture: Local-First AI
Kokoro is part of a broader shift that's been building momentum throughout 2025 and 2026. The local-first AI stack is now real:
| Layer | Cloud Option | Local Option |
|---|---|---|
| LLM | GPT-5, Claude | Llama 4, GLM 5.2, Mistral |
| TTS | ElevenLabs, OpenAI TTS | Kokoro-82M |
| STT | Whisper API, Deepgram | Whisper.cpp, parakeet-rs |
| Embeddings | OpenAI, Cohere | jina-embeddings, nomic |
| Vision | GPT-5V, Claude Vision | Llama Vision, Qwen-VL |
You can now build a fully offline, fully private AI pipeline that handles text, speech, and vision — all running on consumer hardware. No API keys, no usage quotas, no vendor lock-in, no data exfiltration.
This isn't just a hobbyist curiosity. It's a re-architecture of where AI compute lives. For applications with privacy requirements (healthcare, legal, finance), offline-first environments (field work, embedded systems), or cost sensitivity (high-volume consumer apps), the local stack is already viable.
Kokoro is one piece of that — and at 82M parameters, it's one of the smallest and most accessible pieces to adopt.
Get Started
# 1. Pull and run the container
podman run -p 8880:8880 ghcr.io/remsky/kokoro-fastapi-cpu
# 2. Open the web UI
open http://localhost:8880/web
# 3. Or call the API directly
curl http://localhost:8880/v1/audio/speech \
-H "Content-Type: application/json" \
-d '{"model":"kokoro","input":"Hello world","voice":"af_heart"}' \
--output hello.mp3
That's three commands from zero to spoken audio. No GPU, no cloud account, no credit card.
Resources:
- Kokoro on HuggingFace
- Kokoro-FastAPI Docker image
- Ariya Hidayat's original write-up
- Speaches (TTS + STT combined)
- HN discussion
I'd like to thank my sponsor for making this content possible. If you'd like to support independent technical analysis, consider signing up for the newsletter.