π» Kitten-TTS
A 24MB local TTS that runs on your CPU β but check the version before you run it
- audio
The name is pure vibes, but KittenTTS is real: this single node drops a sub-25MB, 15-million-parameter text-to-speech model into your ComfyUI graph and turns a text string into spoken audio on CPU. No GPU, no API key, no cloud. You type a line, pick one of eight voices, and out comes a raw 24kHz waveform. For a diffusion rig where audio is usually an afterthought bolted on via lipsync pipelines, that's genuinely handy - you can generate narration or dialogue for a video workflow without leaving the graph.
The honest caveat up front: this is a developer preview model. The HF card says so itself, and the Reddit reaction to KittenTTS has been "wow, that size" followed by "β¦but it sounds like it's speaking through paper." It's remarkably good for 24MB. It is not ElevenLabs. If you need broadcast-quality VO, look elsewhere; if you need a quick voice track on a local machine with no internet once the model is downloaded, this is one of the few options that just works.
How it works
Under the hood this is a wrapper around KittenML/kitten-tts-nano-0.1, an ONNX export of the KittenML nano model. The pipeline is: your text gets phonemized to IPA via espeak-ng, tokenized into the model's vocab, then pushed through an ONNX session along with a style embedding pulled from voices.npz (each of the eight voices is just a vector in that file) and a fixed speed of 1.0. Out the other end comes a numpy waveform. That's the whole thing - one small ONNX file plus a few KB of voice embeddings, no big PyTorch stack. The CPU-only design is the whole point: it's built to run "literally everywhere," per the model card.
One thing worth knowing: the node returns a bare numpy array, not a saved file and not a fancy audio object. It's labeled AUDIO so it will try to wire into whatever audio nodes your ComfyUI build has, but there's no built-in preview or save button here - plan to grab the waveform and write it out with your own audio node, or script it directly with the model's generate_to_file.
The inputs that matter
There are only two, and you'll set both every time:
- text - the string to speak. Plain English is the safe zone; the phonemizer is an espeak-ng English-IPA step, so heavy non-English text will get mangled.
- voice - pick from
expr-voice-2-m/fthroughexpr-voice-5-m/f. Them/fis the gendered register, and 2β5 are the different character timbres. There's no clone-your-own option yet; you get these eight and you like it.
Installing it
ComfyUI Manager is the easy path: search "KittenTTS" and install. Or clone it by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/Lovzu/ComfyUI-KittenTTS
then restart ComfyUI and let Manager (or the pack's requirements) resolve dependencies. Fair warning: the requirements.txt is not lightweight - spacy, onnxruntime, misaki, soundfile, num2words, huggingface_hub, and espeakng_loader, which is what provides the espeak-ng engine and its Python module. If you're already in the custom-node dependency-hell spiral, this pack adds one more layer of it. The model itself (~24MB) downloads automatically from Hugging Face on your first run, so you need internet exactly once; after that it's fully local.
Where people get burned
Two things, and both are real as of the current code.
First, the packaging bug: the shipped generate_voice.py defines a function misspelled genarate_audio, while nodes.py imports generate_audio. The node loads fine, then the first run dies with ImportError: cannot import name 'generate_audio'. The one-line fix is in the module file - rename the function to generate_audio (or change the import to match the typo, your call). If you hit this, it's not you; it's a typo.
Second, first-run dependency failures. If your first execution dies with No module named 'espeakng' or a missing-binary error, the espeakng_loader install didn't land properly - reinstall the requirements and restart ComfyUI before assuming the node is broken.
And third, lower your quality expectations before you run it. It's a 15M-parameter preview model. It'll read your line clearly, and then you'll notice the buzzy, papery texture on anything long. For a test track or a placeholder voice it's perfect. For anything you'd put in front of a client, budget time to swap in a bigger TTS.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| model_name | COMBO | KittenML/kitten-tts-mini-0.8 (80M) | Mini=80MB best quality, Micro=40MB balanced, Nano=15M lightweight, Int8=19MB smallest |
| device | COMBO | auto | Auto: GPU if available. CUDA: force GPU. CPU: force CPU. |
| text | STRING | Hello, this is a test of KittenTTS text to speech synthesis. | Text to convert to speech. Long text auto-split into sentences. |
| voice | COMBO | Jasper | Jasper/Bruno/Hugo/Leo=male. Bella/Luna/Rosie/Kiki=female. |
| speed | FLOAT | 1.00.5β2 | 1.0=normal, <1.0=slower, >1.0=faster. Recommended: 0.8-1.2 |
| keep_loaded | BOOLEAN | true | Keep model in memory for faster re-use. Disable to free RAM/VRAM. |
| output_stereo | BOOLEAN | false | Output stereo (2ch) instead of mono. Some pipelines need stereo. |
| clean_text | BOOLEAN | true | Normalize text: numbersβwords, expand abbreviations. Keep ON. |
| custom_modelopt | STRING | Custom HuggingFace model ID (e.g., 'user/my-model'). Overrides dropdown. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| audio | AUDIO | β |