Nodes/ComfyUI-ChatTTS/ChatTTS Seed-Based Speaker
ComfyUI Node

ChatTTS Seed-Based Speaker

Reproducible ChatTTS speakers

By neverbiasu·Created about a year ago·Updated about a year ago· 4
ChatTTS Seed-Based Speaker
  • model
  • DICT
seed42

Here's the thing about ChatTTS that confuses people coming from image generation: it doesn't have a list of named voices. There are no checkpoints to browse. A voice is a random point in speaker-embedding space, and the model rolls a new one every time you don't pin it down. This node is your pin - it turns a plain integer into a consistent, reusable voice.

Wire model from the loader in, set a seed, and the Seed-Based Speaker returns a DICT holding a speaker embedding. Feed that dict into the Sampler's speaker_params input and you get the same character run after run. Change the seed, get a different voice. It's the cheapest way to audition voices in the pack: bump the seed, rerun, and listen for one you like.

How it works

ChatTTS's speaker is a 768-dimensional embedding drawn from a learned distribution - sample_random_speaker() rolls one. The trick this node plays is locking the PyTorch RNG to your seed around that call, so the same seed always draws the same embedding. It also verifies the embedding decodes cleanly and stashes the seed alongside it, so the Sampler can reproduce both the voice and the prosody when you re-run.

That last bit matters more than it sounds. The Sampler reads the seed key out of this dict and uses it as the manual seed for inference too. So a seed-based speaker isn't just a fixed voice - it's a fixed performance, as close to deterministic as TTS gets. Same seed, same speaker params, same text: same audio. That's the property that makes one workflow reproducible across your whole setup.

What you set

Only two inputs, and only one you'll touch:

  • model - the MODEL output from ChatTTSLoader.
  • seed (default 42) - the entire voice. You can think of it as a voice ID. Nobody's keeping a registry of "which seed sounds like what," so audition freely.

The output DICT contains the embedding (spk_emb), the seed, and a source marker. All you do is wire it into the Sampler.

The workflow

ChatTTSLoader → ChatTTS_SeedBasedSpeaker → ChatTTS_Sampler → PreviewAudio

One practical tip: when you land on a seed you like, write it down or save the profile. There's a Save Speaker Profile node in the same pack that writes this dict to disk, which matters because nothing about ChatTTS guarantees a seed maps to the same voice across model versions. If you update the weights, that perfect voice may vanish - a saved profile is the only durable record.

Caveats

The DICT output type means nothing shows up in the preview until it's connected, which makes beginners think it's broken. It isn't. And note this node needs a loaded model - there's no point running it standalone, because the sampling happens through the model object itself. Seed-based speakers are also random voices, so if you want something that resembles a specific person, you want the Voice Extractor instead, which pulls an embedding out of a reference recording.

Categorychattts

Inputs (2)

NameTypeDefaultDescription
modelMODEL
seedINT420–2147483647

Outputs (1)

NameTypeDescription
DICTDICT