CSM Text-to-Speech
The viral 'Maya' TTS voice, running inside your ComfyUI graph
- audio
"Text-to-speech" undersells this. It makes you think of a robot reading a manual, and this is not that. CSM Text-to-Speech runs Sesame's CSM-1B model - the open weights behind the "Maya" voice demo that went around in early 2025 and made everyone ask how TTS could sound that human. No API, no key, no cloud. A couple of gigabytes of weights, running in your own ComfyUI graph.
This is the node you reach for when you want a workflow that ends in spoken audio instead of pixels - narration over a video, dialogue for a scene, a character voice for a comic. It's one of the genuinely impressive local TTS models out there, and it pairs with the context version for voice cloning.
How it works
CSM-1B is small by LLM standards: a Llama-3.2-1B backbone plus a 100M decoder. Instead of emitting text tokens, it emits audio tokens - 32 parallel codebooks from Meta's Mimi codec, which get decoded back into a 24 kHz waveform. The pack's code builds the model with torchtune, loads ckpt.pt in bfloat16, and wraps it in a cached Generator. First generation after a restart is slow because the model has to load (it also pulls the kyutai/mimi codec from HuggingFace once); after that it stays cached in memory, so subsequent runs are fast.
The inputs that matter
- model_path and tokenizer_path - feed these from Load CSM Checkpoint and Load CSM Tokenizer rather than hand-typing paths. The node validates them and throws if they don't point at a real file.
- text - what the voice says. CSM loves natural phrasing, commas, even "um"s; it reads well-written text much better than flat sentences.
- speaker - an id from 0–10 that gets embedded as a speaker token. With no context clip this nudges the timbre rather than cloning anyone. Real voice control comes from the context variant.
- temperature / topk - sampling knobs. Defaults are 0.7 / 100. Lower both and the voice gets steadier and more monotone; raise them and it gets more expressive and more likely to go off the rails.
- max_audio_length_ms - hard cap on output length, default 90 seconds.
One input to not touch: sample_rate. CSM always generates at 24 kHz regardless - this node just stamps the value you pick onto the output. Change it to 48000 and you've mislabeled a 24 kHz file, which plays back wrong in editors. Leave it at 24000.
Outputs
A single audio output in ComfyUI's AUDIO format - a {waveform, sample_rate} dict that wires straight into any audio save/preview node.
How to install
It's a normal custom node pack:
cd ComfyUI/custom_nodes
git clone https://github.com/thezveroboy/ComfyUI-CSM-Nodes
pip install -r ComfyUI-CSM-Nodes/requirements.txt
(Or use ComfyUI Manager and search "ComfyUI-CSM-Nodes".) Then restart ComfyUI. The heavy dependencies are torch, torchaudio, transformers, tokenizers, torchtune, and torchao - the same stack as most local audio work.
The models are the fiddly part:
- Download
ckpt.ptfrom sesame/csm-1b intoComfyUI/models/sesame/(create the folder - it won't exist). - Download the Llama-3.2-1B tokenizer files (e.g. from unsloth/Llama-3.2-1B) into
ComfyUI/models/sesame_tokenizer/<some-dir>/. The tokenizer loader picks subdirectories, so give it its own folder.
Common issues
- Russian-language errors. The pack's checks throw messages like
Текст пуст!(text is empty) ormodel_path некорректен!(invalid model path). If you see Cyrillic, an input check fired - usually a path node not wired. - First run is brutally slow. That's the model loading plus the Mimi codec download. Subsequent generations are fast. Don't blame the node.
- bfloat16 on an older GPU. The code loads weights in bf16 unconditionally, which needs an Ampere-or-newer GPU. On older cards you'll hit errors rather than slow speed.
- Long prompts bump into CSM's 2048-token window (
input too longerror). Keep text short-ish, especially when feeding context.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | — | |
| model_path | STRING | — | |
| tokenizer_path | STRING | — | |
| sample_rate | INT | 240008000–48000 | — |
| speakeropt | INT | 00–10 | — |
| max_audio_length_msopt | FLOAT | 90000.001000–300000 | — |
| temperatureopt | FLOAT | 0.700.1–2 | — |
| topkopt | INT | 1001–200 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| audio | AUDIO | — |