ComfyUI Node

KyutaiTTS

Local TTS in ComfyUI without an API key — Kyutai's open 1.6B voices, as one node

By BobRandomNumber·Created about a year ago·Updated about a year ago· 6
KyutaiTTS
    • AUDIO
    textHey there! How are you?
    model_path
    voice_model
    device
    n_q32
    temp0.6
    cfg_coef2.0
    padding_between1
    seed0

    ComfyUI is a great place to generate images and video, but audio is a wasteland. Most TTS workflows end up bolted onto the side - a Python script, a separate program, a cloud API that costs money and phones home. This node is the answer if you want a voice inside the graph: it runs Kyutai TTS 1.6b en_fr, the open-source model Kyutai dropped in July 2025, entirely locally. No API key, no network call, no account. You type text, you get a standard ComfyUI AUDIO output at 24 kHz that plugs straight into a core SaveAudio node.

    One honest caveat up front: this is not the real-time streaming the model was designed for. Kyutai's intended implementation (the delayed-streams-modeling repo) streams tokens as text arrives. This node does the batch version - generate a block of audio, decode it, hand it over. The author says plainly they built it to "generate large amounts quickly at acceptable quality" for their own use. If you want a live voice assistant, keep looking; if you want a long paragraph of natural speech for a video, a podcast, or a narration track, this is exactly the tool.

    The voice gotcha nobody warns you about

    Here's the part that trips up people coming from ElevenLabs or XTTS: Kyutai open-sourced the TTS model but deliberately did not release the voice-embedding model. Their rationale - only clone voices consensually - means you can't feed the node your own 10-second sample. Instead, you pick from the curated voice models in the kyutai/tts-voices repo, built from consenting speakers in the Expresso and VCTK datasets. The release thread on r/StableDiffusion was genuinely split over this ("you can also clone voices" vs. "no you can't, they kept that to themselves"), so know what you're getting into. You get a solid set of natural English and French voices; you just don't get your voice.

    How it works

    Under the hood it's Kyutai's Moshi family: the [email protected] weights (the TTS backbone), the Mimi neural audio codec weights (tokenizer-e351c8d8-checkpoint125.safetensors), and a sentencepiece-style text tokenizer. The node ships a vendored copy of the moshi source, loads the model from a local folder, generates audio token frames autoregressively, then decodes each frame through Mimi back to PCM at 24 kHz. Your chosen voice model is used as a conditioning signal - that's what cfg_coef controls, classifier-free guidance steering the output toward that speaker.

    Notable implementation detail: the node monkey-patches moshi.modules.rope.apply_rope to disable torch._dynamo on it, dodging a PyTorch compile crash that hit Windows users. If you hit an OverflowError, that patch is the thing that didn't apply.

    The inputs that actually matter

    • text - what to say, multiline. Long paragraphs are fine; that's the whole point.
    • model_path - a folder path (use the folder-picker). It must contain exactly these four files: [email protected], tokenizer-e351c8d8-checkpoint125.safetensors, tokenizer_spm_8k_en_fr_audio.model, and config.json. The node checks for those names literally.
    • voice_model - a dropdown populated from your models/loras folder. Voice models go in loras (subdirectories work).
    • device - cuda or cpu. A 1.6B model on CPU is slow; if you have a GPU, use it.
    • temp (0.6) - sampling temperature; lower is flatter, higher is more expressive.
    • cfg_coef (2.0) - guidance strength toward the voice. 0 disables it.
    • n_q (32) - how many of Mimi's codebook levels the model generates. Default is full quality; dropping it trades quality for speed.
    • padding_between (1) and seed - inter-sentence silence and reproducibility, respectively.

    The single output, AUDIO, is a {waveform, sample_rate: 24000} dict. Wire it into SaveAudio (the bundled example workflow does exactly this) and you're done.

    Installing it

    Easiest route is ComfyUI Manager - search for ComfyUI-KyutaiTTS (it's registered on the Comfy Registry). Or manually:

    cd ComfyUI/custom_nodes
    git clone https://github.com/BobRandomNumber/ComfyUI-KyutaiTTS.git
    pip install -r requirements.txt
    

    The requirements file is a single line - sphn<0.2, the tokenizer package. Everything else (torch, etc.) rides on your existing ComfyUI install, which is refreshingly light. Then the model downloads, which is where the real size is:

    1. Grab all files from kyutai/tts-1.6b-en_fr and put them in a folder like ComfyUI/models/checkpoints/KyutaiTTS.
    2. Download a few voices from kyutai/tts-voices into ComfyUI/models/loras.
    3. Restart ComfyUI, add the node via Add Node → Kyutai → KyutaiTTS, point model_path at that folder.

    Troubleshooting

    • FileNotFoundError - the most common failure by far. Either model_path doesn't point at the folder with the four files, the files have the wrong names (download the main branch, don't rename anything), or the voice model isn't under models/loras. Double-check all three.
    • OverflowError at load time - the rope monkey-patch failed, usually a torch/moshi mismatch. Update torch and make sure the vendored moshi_src didn't get clobbered.
    • Audio sounds robotic or too clean - it's outputting at 24 kHz raw. The README notes some post-processing can help; an upsampler or EQ after SaveAudio goes a long way if you're polishing for production.

    It's a niche, early pack from a small author - expect a little rough edge. But it's one of the few ways to get genuinely good, local, long-form TTS inside the ComfyUI graph, and that alone makes it worth a slot in your workflow.

    CategoryKyutai

    Inputs (9)

    NameTypeDefaultDescription
    textSTRINGHey there! How are you?
    model_pathSTRING
    voice_modelCOMBO0 options:
    deviceCOMBO2 options: cuda, cpu
    n_qINT32
    tempFLOAT0.60–1
    cfg_coefFLOAT2.00–10
    padding_betweenINT1
    seedINT00–4294967295

    Outputs (1)

    NameTypeDescription
    AUDIOAUDIO