Nodes/IAMCCS-nodes/IAMCCS KittenTTS 2 · Voice / Emotion / Clone
ComfyUI Node

IAMCCS KittenTTS 2 · Voice / Emotion / Clone

Emotional tags, cloned voices, and a second Python that you have to install

By IAMCCS·Created about a year ago·Updated a day ago· 119
IAMCCS KittenTTS 2 · Voice / Emotion / Clone
  • reference
  • AUDIO
◄model▾►
◄text[tender] Welcome to the cinema.►
◄speakerBruno►
◄preset▾►
◄device▾►
◄decoder▾►
◄seed42►
◄max_new_tokens1000►
◄normalize_englishfalse►
◄keep_loadedfalse►
◄reference_text►

KittenTTS is the small-model corner of open TTS - people recommended v1 precisely because it's tiny, with the standing caveat that it can't clone. Version 2 adds cloning, emotion tags and emphasis. The honest catch: it doesn't run in ComfyUI's own Python, and the node makes you notice immediately.

Why you'd reach for it

The TTS decision tree in audio-generation.md is three jobs wearing one name: a good generic voice fast, a cloned specific voice, and a face that moves to a voice. KittenTTS 2 sits in the middle-left: a lightweight checkpoint family with built-in speakers and optional reference cloning.

The tradeoff against the heavyweight corner is the usual one: less absolute fidelity, far less fuss. Against Kokoro-class models you get cloning and native style tags - [tender] in the prompt text is the flagship feature, and it's why the default text reads [tender] Welcome to the cinema.

How it works

This is where KittenTTS 2 differs from every other node in the pack, and where the failures cluster.

IAMCCS_KittenTTS2 does not load the model into ComfyUI's process. It writes your request to a temp folder and talks to a persistent child interpreter - iamccs_kitten_tts2_worker.py - over JSON lines, using a Python executable read from a pan-runtime.json file sitting next to the model directory. If that config file isn't there, you get Kitten runtime is not configured. Run the PAN KittenTTS 2 installer. and nothing else happens.

Why bother? Because audio models in ComfyUI are a dependency-conflict factory, and a separate interpreter is the honest fix: the worker never touches Comfy's torch, never upgrades your transformers, and never breaks three image models to add a voice.

The worker also sets HF_HUB_OFFLINE=1 and its own cache dirs, so nothing phone-homes mid-generation, and picks the backend per device: kittenml for auto/cuda/cpu, kitten_tts_cpp for cpu-fast.

One more mechanic that surprises people: before generating, the node calls unload_all_models() and empties Comfy's cache. Your image checkpoint gets evicted to make room. Fine - even welcome - on a 12 GB card; if you hop between image and voice in one graph, expect the reload.

The inputs that matter

  • text - up to 20,000 characters. Emotion tags like [tender] and emphasis markup go inline. This is the fun part.
  • speaker - populated from the voices JSON of whatever model directories are installed; defaults to Bruno.
  • preset - stable or expressive. Start stable, move to expressive when you want a take with more movement in it.
  • device - auto, cuda, cpu, cpu-fast. cpu-fast uses the C++ backend and, per the source, cannot clone: fast CPU supports built-in speakers only.
  • decoder - student_w4 or default. student_w4 is the small/quantized decoder; try default if a take sounds thin.
  • max_new_tokens, seed, normalize_english - the last one helps when your script is full of numbers and abbreviations.
  • keep_loaded - leaves the child process alive between runs. Turn it on while you're iterating; turn it off when you're done, because it's a python process holding weights.
  • reference + reference_text (optional) - the cloning route, and reference_text is not optional in practice: a 5–30 second clip plus its exact transcript, or the node refuses.

Output is a single Comfy AUDIO - straight into Save Audio, a preview, or a lip-sync/video branch.

Installing it

Install the pack via Manager (search IAMCCS Nodes) or:

cd ComfyUI/custom_nodes
git clone https://github.com/IAMCCS/IAMCCS-nodes.git

Then two extra steps that the node cannot do for you:

  1. Put the model directory under ComfyUI/models/kitten_tts2 (or point extra_model_paths.yaml at it - the node registers that folder on import). A valid model directory is one containing a config.json with "type": "KITTEN2"; subdirectories are scanned too, which is handy for keeping several models side by side.
  2. Run the PAN KittenTTS 2 installer to create the runtime environment and its pan-runtime.json. Without it the node loads and then refuses to run.

Restart ComfyUI and hard-refresh once afterwards.

Where people get burned

The model dropdown says not installed. The scanner found no directory with a KITTEN2 config. Check the folder, check config.json is actually there, then refresh ComfyUI.

"The configured Kitten Python runtime is missing. Run the PAN installer." The pan-runtime.json exists but points at an interpreter that's gone - usually a venv you deleted or moved.

A 30-minute wall. The runtime has a hard timeout, and the node kills the child rather than hanging forever. Long scripts want the text split.

Cloning silently ignored on cpu-fast. By design. Switch to auto or cuda.

A failed take with almost no explanation. The worker's tracebacks go to pan-runtime.log beside the model directory, not into the ComfyUI console. That file is the first place to look.

One licence note the author puts on the node itself: KittenTTS is a community model under its own terms - check the bundled notice before you point it at a paid job.

CategoryIAMCCS/Audio/KittenTTS 2

Inputs (12)

NameTypeDefaultDescription
modelCOMBO1 options: not installed
textSTRING[tender] Welcome to the cinema.—
speakerCOMBOBruno1 options: Bruno
presetCOMBO2 options: stable, expressive
deviceCOMBO4 options: auto, cuda, cpu, cpu-fast
decoderCOMBO2 options: student_w4, default
seedINT420–18446744073709550000—
max_new_tokensINT100050–4000—
normalize_englishBOOLEANfalse—
keep_loadedBOOLEANfalse—
referenceoptAUDIO—
reference_textoptSTRING—

Outputs (1)

NameTypeDescription
AUDIOAUDIO—