Kitten TTS
New: Free Kitten TTS API available at https://platform.kittenml.com
Kitten TTS is an open-source text-to-speech library. Its flagship model, KittenTTS 2, is a 1.7B-parameter 1-bit speech language model with in-context voice cloning and expression control: give it five seconds of anyone's voice and it speaks your text in that voice. It runs realtime on a CPU!
The library also ships the original lightweight legacy models,
15M-80M parameters, which run on CPU without a GPU. Both families load through the same
KittenTTS(...) constructor.
Commercial support is available. For integration assistance, custom voices, or enterprise licensing, contact us.
Table of Contents
- Features
- Available Models
- Demo
- Quick Start
- Voice cloning
- Expression controls
- Running on CPU
- Running with vLLM
- Long text and streaming
- Documentation
- System Requirements
- Commercial Support
- Community and Support
- License
Features
- Voice cloning -- Clone any speaker from 5-30 seconds of audio, no fine-tuning
- 47 built-in voices -- Including the eight from KittenTTS 0.8 and nine non-English
- Multilingual -- 20 languages: English, Arabic, Chinese, French, German, Hindi, Italian, Portuguese, Russian, Spanish, Japanese, Korean, Turkish, Dutch, Swedish, Danish, Finnish, Swahili, Greek, Hebrew
- Expression control --
[emotion]tags, inline<event>tags, and(((emphasis)))spans - Decoding presets -- Trade stability against expressiveness per request
- Long-form text -- Sentence-aware chunking with seamless joins
- Text preprocessing -- Numbers, currencies, dates, units and abbreviations expanded automatically
- 24 kHz output -- High-quality audio at a standard sample rate
- Runs without a GPU
- Runs real time on a CPU -- Check Running on CPU
- Optimized C++ inference for CPU -- Our fork of llama.cpp
Available Models
KittenTTS 2 -- speech language model:
| Model | Parameters | Size | Voices | Download |
|---|---|---|---|---|
| kitten-tts-2 | 1.7B | 506 MiB | 47 + cloning | KittenML/kitten-tts-2 |
Lightweight ONNX -- runs on CPU, no GPU required:
| Model | Parameters | Size | Download |
|---|---|---|---|
| kitten-tts-mini | 80M | 80 MB | KittenML/kitten-tts-mini-0.8 |
| kitten-tts-micro | 40M | 41 MB | KittenML/kitten-tts-micro-0.8 |
| kitten-tts-nano | 15M | 56 MB | KittenML/kitten-tts-nano-0.8 |
| kitten-tts-nano (int8) | 15M | 25 MB | KittenML/kitten-tts-nano-0.8-int8 |
Demo
https://github.com/user-attachments/assets/c42c236b-7b7d-41d6-944b-7527a5f30626
Try it online
Try Kitten TTS directly in your browser on KittenML Platform.
Quick Start
Prerequisites
- Python 3.9 or later
- A CUDA GPU with roughly 8 GB free, or a CPU with about 6 GB of RAM
- About 1 GB of disk space for the model, or 506 MiB with the smaller weights
Installation
pip install kittenml
That is the whole install. KittenTTS 2 is the default model, voice cloning is included, and no Hugging Face login is needed -- every weight the model uses ships in its own repository. It also pulls the small ONNX runtime, so the lightweight models work from the same install.
Basic usage
from kittenml import KittenTTS
import soundfile as sf
m = KittenTTS("KittenML/kitten-tts-2")
audio = m.generate("One day, a little girl named Lily found a needle in her room.",
voice="Bruno")
sf.write("output.wav", audio, m.sample_rate)
To run Kitten-TTS 2 on a CPU, please refer to Running on CPU
m.available_voices lists all 47 built-in voices, described in
voices and expression. Bella, Jasper, Luna, Bruno, Rosie, Hugo,
Kiki and Leo are the same speakers as in KittenTTS 0.8, so code written against the ONNX models
keeps working.
The weights come in two sizes. The default is 947 MiB and lossless; weights="emb4" is 506 MiB
because it quantises the token embedding, which costs a little quality. Only the one you ask for
is downloaded.
m = KittenTTS("KittenML/kitten-tts-2", weights="emb4") # half the download
# Trade stability against expressiveness
audio = m.generate("Hello, world.", voice="Luna", preset="expressive")
# Save directly to a file
m.generate_to_file("Hello, world.", "output.wav", voice="Bruno")
Voice cloning
Pass reference= instead of voice= — same method, the recording just replaces the built-in
speaker. Give it 5-30 seconds of a single speaker. The transcript is part of the prompt, but you
do not have to type it; Whisper fills it in when omitted.
audio = m.generate("This is my own voice, cloned.", reference="my_voice.wav")
# Supplying the transcript skips the Whisper pass
audio = m.generate("This is my own voice.", reference="my_voice.wav",
reference_text="what is actually said in the clip")
The reference feeds the model by two independent routes -- a speaker embedding through the model's projection head, and the clip itself as codec tokens in the prompt -- so identity survives even when one route is weak.
Measured on the built-in voices: a generated clip scores 0.49-0.72 speaker similarity against its own reference and 0.01-0.18 against the other 37, and cloning an unseen recording scores 0.81 against that recording.
Expression controls
Beta. Emotion control steers delivery rather than guaranteeing it, and the effect varies by voice and by sentence.
audio = m.generate(
"[joyful] We actually won the grant <laugh> I can (((hardly))) believe it!",
voice="Kiki",
preset="expressive",
)
A leading [emotion] tag, inline <event> tags and (((emphasis))) spans reach the model as
markup rather than being spoken, and automatically enable its expression conditioning. Ten
emotions and ten vocal events are recognised -- see
voices and expression for the full lists and what is not
covered.
Running on CPU
Kitten-TTS 2 runs on CPU out of the box — device is auto-detected — but the fastest way is
kitten-tts-2-cpp, our llama.cpp fork. It reads
the GGUF weights in the model repository's cpp/ directory. You can use the Python bindings too:
pip install kitten_tts_cpp
from kitten_tts_cpp import KittenTTS
model = KittenTTS("KittenML/kitten-tts-2", decoder="student_w4", threads=8)
model.generate_to_file("One day, a little girl named Lily found a needle in her room.", "hello.wav", voice="Bruno")
print(model.last_report) # Generation timings and token IDs.
Kitten-TTS 2 C++ is in beta. Please report any issues you encounter.
Running with vLLM
For GPU inference with vLLM on Linux and an NVIDIA CUDA GPU with compute capability 8.0 or newer (Ampere or later, for bfloat16), install the optional backend. GPUs with compute capability 7.5 can use a float16 fallback that is supported but not the optimal path (vLLM guide).
pip install "kittenml[vllm]"
Select backend="vllm":
from kittenml import KittenTTS
def main():
m = KittenTTS("KittenML/kitten-tts-2", backend="vllm",
vllm_options={"quantization": "w4a16"})
m.generate_to_file("Hello there.", "output.wav", voice="Bruno")
print("Saved output.wav")
if __name__ == "__main__":
main()
Keep the main guard when running a script: vLLM starts a worker process. The same
voices, decoders, weight choices and generation arguments apply. The example
uses 4-bit language-model weights ("quantization": "w4a16"): the same weights, exactly, in about
2 GB less GPU memory, and faster for single requests. Leave out vllm_options to run in bf16; see
4-bit weights. See the
vLLM guide for memory settings and benchmarks.
Long text and streaming
Long input is split on sentence boundaries and synthesized chunk by chunk, then joined with silence trimming and short edge fades so the seams are inaudible. This is automatic: the model is reliable on short inputs but truncates or drifts into repetition when asked for a whole script in one pass.
To start playing before the whole thing is ready, stream it:
for chunk in m.generate_stream(long_text, voice="Luna"):
play(chunk) # each chunk is a numpy array at m.sample_rate
It takes the same arguments as generate, so reference= streams a cloned voice too.
Streaming is chunk-level, not token-level: a chunk is generated and vocoded in full before it is yielded, so the first chunk still costs its own generation time. On an A100, a 936-character passage yielded its first 21 s of audio after 17 s and finished 54 s of audio in 42 s of wall clock -- so playback keeps ahead of generation, but there is a real initial delay.
Two consequences worth knowing:
- Short text does not stream. Input that fits in one chunk (under roughly 380 characters,
and short trailing pieces get merged into their neighbour) yields exactly one chunk, so
generate_streambehaves likegenerate. - Chunks are yielded raw.
generatepost-processes the seams -- trimming each segment's edge silence, adding short fades and one consistent pause -- which a streaming caller cannot do without waiting for the next chunk. Concatenating streamed chunks directly gives slightly rougher joins thangenerateon the same text.
Documentation
| API reference | Every argument to generate, streaming, and the advanced knobs |
| Voices and expression | The 47 voices, emotion and vocal-event tags, the ten languages |
| Decoders | How audio is decoded, and the smaller quantised decoders |
| Text normalization | How written text becomes spoken text |
| Architecture | What the model is, package layout, vendored components |
| Lightweight ONNX models | The CPU models, 15M-80M parameters, and their API |
System Requirements
KittenTTS 2
- Operating system: Linux, Windows or Mac
- Python: 3.9 or later
A virtual environment (conda, venv, or similar) is recommended to avoid dependency conflicts.
Commercial Support
We offer commercial support for teams integrating Kitten TTS into their products. This includes integration assistance, custom voice development, and enterprise licensing.
Contact us or email info@stellonlabs.com to discuss your requirements.
Community and Support
- Discord: Join the community
- Website: kittenml.com
- Custom support: Request form
- Email: info@stellonlabs.com
- Issues: GitHub Issues
License
This project is licensed under the Apache License 2.0. That covers the code in this repository.
The models are licensed separately and their terms may differ. Each model repository carries its own licensing, so check the one you intend to use before relying on it — do not assume the code's license extends to the weights.
KittenTTS 2 is released under the Stellon Labs Community License
Metadata
Release files for kittenml 0.9.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| kittenml-0.9.5.tar.gz | 154.4 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| kittenml-0.9.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 297.7 kB
Release files / kittenml-0.9.5.tar.gz
| Download URL | kittenml-0.9.5.tar.gz |
|---|---|
| Size | 154.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
78d4dff4938710b61a9edb95257edfa510ae012d4732797f0b6a2ef0a0f14f9f
|
|
BLAKE2b-256 checksum How to use checksums |
26815836eff96cd8c63c2874d8b6da22213878ef32c6d5e572d575c1ac59f7e0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Release files / kittenml-0.9.5-py3-none-any.whl
| Download URL | kittenml-0.9.5-py3-none-any.whl |
|---|---|
| Size | 143.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2f3655c3e4f45167e388c34240bf5bd14918dbf6cf6fcb83a130c9d680c298af
|
|
BLAKE2b-256 checksum How to use checksums |
6ee8c669d644fbfc5d0f857057e048b95d16c417cecefe88a7d115d5bfd2bad9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Security for kittenml 0.9.5
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.