CSM Text-to-Speech with Context
CSM's voice cloning, where the magic actually lives
- audio_context
- audio
Plain CSM Text-to-Speech gives you a very good synthetic voice. This node is how you make it someone's voice. CSM Text-to-Speech with Context does the thing that made the Maya demo famous: you hand it a few seconds of reference audio and it keeps talking in that same voice, with the same rhythm, the same little pauses. That's the whole reason CSM-1B became the darling of the local TTS scene.
The catch: it only works if you feed it right. This is the fiddly node of the pack, and it's worth understanding the mechanism before you wire it up.
How it works
CSM-1B is autoregressive - it doesn't clone a voice by encoding it, it continues it. Your reference clip gets tokenized into two parts: the words (from your transcription, tagged with a speaker id) and the audio itself (run through the Mimi codec). The new text is appended as the next "turn" in the same token sequence, and the model keeps going, staying in the voice it just heard. Give it one style, it continues in that style. This is also why context-based CSM sounds more natural than most zero-shot clones - it's literally speaking as a continuation of real audio.
The inputs that matter
- audio_context - the reference clip, as ComfyUI
AUDIO. Comes from Load Audio with Transcription. - context_transcription - the exact words spoken in the clip. This one matters more than any other field in the pack. The model aligns text to audio, so if your transcription is off, the voice comes out garbled. The code refuses to run with an empty transcription (Russian error,
Транскрипция контекста пуста), but it can't save you from a wrong one. - context_speaker and speaker - the speaker slots for the reference and the new utterance. Keep them the same (say, both 0) unless you want the model to shift persona mid-stream.
- text - what the voice says next.
- temperature / topk - defaults 0.7 / 100. Sesame's own reference runs a lower top-k; if the cloned voice drifts or gets twitchy, drop both.
- max_audio_length_ms - cap on the new audio, default 90 s.
Outputs and wiring
A single audio output. The canonical wiring is:
Load Audio with Transcription ──► audio_context ─┐
(transcription/speaker) │
Load CSM Checkpoint ──► model_path ──────────────┼──► CSM Text-to-Speech with Context ──► audio
Load CSM Tokenizer ──► tokenizer_path ───────────┘
Common issues
- Reference clip too long. Context audio and text share one 2048-token window with the output budget. A 30-second reference clip eats most of it, and you'll hit an
input too longerror. Keep the reference to 10–20 seconds. - Transcription doesn't match. This is the #1 source of bad output and it's silent - the model just produces mush in a vague approximation of the voice. Type the clip's words exactly, hesitations included.
- Sample rate drift. The loader node resamples context to 24 kHz for you. If you bypass it and wire audio from elsewhere, make sure it's 24 kHz mono or the codec gets confused.
Installation
Same pack as the base TTS node - thezveroboy/ComfyUI-CSM-Nodes. Clone it into custom_nodes and install its requirements.txt, or search "ComfyUI-CSM-Nodes" in ComfyUI Manager, then restart. You also need the ckpt.pt weights from sesame/csm-1b in ComfyUI/models/sesame/ and a Llama-3.2-1B tokenizer in ComfyUI/models/sesame_tokenizer/. Full detail is in the CSM Text-to-Speech article.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | — | |
| model_path | STRING | — | |
| tokenizer_path | STRING | — | |
| sample_rate | INT | 240008000–48000 | — |
| audio_context | AUDIO | — | |
| context_transcription | STRING | — | |
| context_speaker | INT | 00–10 | — |
| 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 | — |