ZONOS2 Voice Generation
ZONOS2's plain text-to-speech node
- zonos2_model
- audio
This is the node to reach for when you just want to hear what ZONOS2 sounds like. Wire the zonos2_model output from the ZONOS2 Model Loader into it, type some text, and you get a mono ComfyUI AUDIO at 44.1 kHz out the other end. No API, no key, no voice reference required - the whole thing runs on your GPU.
It's the plain-text branch of the pack. If you want the party trick, that's the ZONOS2 Voice Clone node. But the generation node is where you sanity-check that the model loaded right and the settings you're about to reuse actually behave.
How it works
Under the hood this is a real autoregressive language model, just over audio instead of words. Your text gets tokenized as UTF-8 bytes, and a sparse MoE backbone generates DAC code frames - discrete audio tokens at 44.1 kHz - which a Descript DAC decoder turns back into a waveform. That's why the sampling knobs look like they were lifted off an image sampler: temperature, top_k, top_p, min_p, plus a repetition penalty tuned for audio (ZONOS2's stock sampling pipeline uses Min-P at 0.18 by default, with top_p disabled - leave it that way).
The model also accepts a pile of "quality conditioning" buckets - speaking_rate, loudness_lufs, estimated_snr, maximum_pause, estimated_bandlimit_hz, leading_silence, trailing_silence. Each is a dropdown of ranges (bytes-per-second, LUFS, dB, seconds) and every one defaults to default, which means "don't condition on this." Real talk: a beginner should ignore all seven. They're for matching the model's output to a recording's characteristics, not for day-to-day use.
The inputs that actually matter
text- what to say. Anything not empty works; the integration uses ZONOS2's raw UTF-8 path, so written numbers and dates won't always be normalized the way you'd want - "2026" may read as digits. This is a model-level quirk, not a bug.max_new_tokens(default 1024, up to 6000) - the ceiling on how many audio frames get generated. Output stops early when the model emits end-of-audio, so if your clip keeps cutting off mid-sentence, raise this.temperature(default 1.15),top_k(106),min_p(0.18) - the randomness stack. Lower temperature for steadier delivery, around 0.8–1.0 if a voice is drifting run to run.seed- 0 means random; set a positive value to make a run repeatable. Worth doing once you find a delivery you like.
The single output is audio, a native ComfyUI AUDIO at 44.1 kHz. It feeds straight into ComfyUI's Save Audio / SaveAudioMP3 nodes, or into any audio-consuming node in your video workflow.
Installing and the first run
You'll need the whole pack: ComfyUI Manager → search ZONOS2 TTS, or:
cd ComfyUI/custom_nodes
git clone https://github.com/Saganaki22/Zonos2_TTS-ComfyUI.git
../venv/bin/python Zonos2_TTS-ComfyUI/install.py
Restart, then let the loader pull the model. Watch the Transformers version - the pack needs 5.0–5.12 (baseline 5.3.0) and won't run on 4.x, and install.py won't upgrade it for you. And be patient with the first generation: loading the ~14 GiB BF16 checkpoint plus the DAC takes a while, and it's normal for the first load to look frozen.
Troubleshooting
- Output stops too early → raise
max_new_tokens; the model can legitimately end early on its own. - Sounds wobbly or unstable run to run → try
temperaturearound 0.8–1.0 and set a fixed seed. - Numbers and dates read wrong → the raw UTF-8 path doesn't do full NeMo text normalization; spell out tricky values or run text through a normalizer upstream.
- CUDA OOM → the loader's FP8 preset is the memory-saver; also unload other models and lower
max_new_tokens.
One honest caveat: with no voice reference, this node runs without any speaker embedding at all, so you get ZONOS2's bare, un-conditioned voice. It's great for testing and for narrator-agnostic audio. The moment you want a specific voice, that's the clone node's job.
Inputs (18)
| Name | Type | Default | Description |
|---|---|---|---|
| zonos2_model | ZONOS2_MODEL | Connect the zonos2_model output from ZONOS2 Model Loader. | |
| text | STRING | Hello! This is ZONOS2 running natively inside ComfyUI. | UTF-8 text to synthesize. |
| max_new_tokens | INT | 102432–6000 | Maximum DAC-code frames the model may generate. More frames allow longer speech but increase generation time and KV-cache memory. Generation can stop earlier when ZONOS2 emits end-of-audio. |
| temperature | FLOAT | 1.150–2 | Sampling randomness. Lower values are steadier; higher values add variation but can reduce clarity. 0 uses greedy sampling. The official ZONOS2 default is 1.15. |
| top_k | INT | 1060–1026 | Keep only the K most likely tokens in each audio codebook before sampling. 0 disables Top-K filtering. The official default is 106. |
| top_p | FLOAT | 0.000–1 | Keep the smallest token set whose combined probability reaches this value. 0 disables Top-P filtering. ZONOS2 normally uses Min-P instead. |
| min_p | FLOAT | 0.180–1 | Remove tokens whose probability is below this fraction of the most likely token. 0 disables Min-P. The official default is 0.18. |
| repetition_window | INT | 500–512 | Number of recent generated frames checked for repeated audio tokens. 0 disables repetition tracking. |
| repetition_penalty | FLOAT | 1.201–2 | Reduces the probability of recently generated tokens to discourage loops. 1.0 disables the penalty. The official default is 1.2. |
| repetition_codebooks | INT | 8-1–9 | Apply repetition penalty to this many codebooks starting from codebook 0. -1 applies it to all 9; 0 disables it for every codebook. The official default is 8. |
| speaking_rate | COMBO | default | Optional ZONOS2 speaking-rate conditioning in cleaned UTF-8 bytes per second. Lower ranges generally produce slower speech. Default leaves speaking rate unconditioned. |
| loudness_lufs | COMBO | default | Optional target integrated loudness in LUFS. More-negative ranges are quieter; less-negative ranges are louder. Default leaves loudness unconditioned. |
| estimated_snr | COMBO | default | Optional estimated signal-to-noise ratio in dB. Higher ranges bias toward cleaner audio; lower ranges can reproduce noisier recording characteristics. Default leaves SNR unconditioned. |
| maximum_pause | COMBO | default | Optional maximum internal pause duration in seconds. Lower ranges favor tighter delivery; higher ranges permit longer pauses. Default leaves maximum pause unconditioned. |
| estimated_bandlimit_hz | COMBO | default | Optional estimated recording bandlimit in Hz. Higher ranges bias toward wider-band, brighter audio; lower ranges can sound more bandwidth-limited. Default leaves bandlimit unconditioned. |
| leading_silence | COMBO | default | Optional amount of silence before speech begins. Default leaves leading silence unconditioned. |
| trailing_silence | COMBO | 3: 0.25-0.5 | Requested silence after speech ends. Bucket 3 (0.25-0.5 seconds) is the official ZONOS2 default. Select default to leave it unconditioned. |
| seed | INT | 00–9223372036854776000 | Sampling seed. A positive value makes generation repeatable for identical inputs and settings. 0 uses the current random state. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| audio | AUDIO | Generated mono speech as native ComfyUI AUDIO at 44.1 kHz. |