Fish Audio S2.1 Pro
Give your ComfyUI workflow a voice — cloud TTS that can clone one
- speech
- audioSettings
- referenceVoices
- audio
This is the node that turns your ComfyUI canvas into something with a voice. Fish Audio S2.1 Pro is a cloud text-to-speech model, and this node drops it straight into your graph: you feed it text (plus an optional voice to clone), it runs on Runware's servers, and out the other end comes a ComfyUI-native AUDIO output you can wire into Preview Audio, Save Audio, or a video that needs a voiceover.
The catch is the framing: this isn't the usual ComfyUI flow. Nothing is local. There's no model file to download, no --fp16 juggling, no VRAM budget to watch - the request goes to Runware's API and comes back as audio. That's the whole point of the pack, and for TTS specifically it's a huge win, because good voice-cloning models have always been finicky to run locally. S2.1 Pro is a newer generation of Fish's speech model, and the audio quality is genuinely good - expressive, with decent control over pacing and emotion.
How it works
The node itself is a thin generated class in ComfyUI-Runware that sends an audioInference request to the Runware API and decodes the returned file into an AUDIO tensor ({waveform, sample_rate}), using soundfile first, falling back to torchaudio. Two of the interesting settings on this node are about how S2.1 splits up your text. settings.chunkLength (100–300, default 300) is the text segment size for processing, and settings.conditionOnPreviousChunks (on by default) feeds earlier chunks back as context so the voice stays consistent across a long script. Keep that on - it's what stops a multi-paragraph narration from drifting mid-way.
The inputs that actually matter
speech- a typed socket from the Runware Speech builder (Runware/Params). It needstextand avoice(there's a long dropdown of named voices; pick one or leave the default). For multi-speaker dialogue you can use tags like[Sam] Hello [Bob] Hi there, and provider markup like[laughs]works too.referenceVoices- the Runware Reference Voices builder. This is the voice-cloning path: give it a reference audio clip (1–90 seconds, as a URL or UUID) plus an exact transcript of what's spoken, and it clones that voice. This is the feature people actually reach for this node for.numberResults(1–4) - generates variations with different seeds. Cheap way to get a few takes.settings.temperature(0–1, default 0.7) - expressiveness of the speech. Lower = flatter and more robotic, higher = livelier. If a voice sounds like it's reading a legal disclaimer, nudge this up.settings.latency-low/normal/balancedquality trade-off. Leave it unless you're doing real-time-ish work.outputFormat- MP3 (default), WAV, FLAC, or OGG. Pick WAV or FLAC if you're going to edit the audio afterwards; MP3 if it's a quick sketch.
The single output is audio, an AUDIO object. Wire it into Save Audio or into a video composition node. Note the audio output only stays native if soundfile or torchaudio is installed - soundfile is in the pack's requirements.txt, so you're usually fine; without it the node degrades to returning a saved file path instead.
Installing
ComfyUI Manager → search Runware → install → restart, or:
cd ComfyUI/custom_nodes
git clone https://github.com/Runware/ComfyUI-Runware
pip install -r ComfyUI-Runware/requirements.txt
Then set your API key - ComfyUI Settings → Runware API key, the RUNWARE_API_KEY env var, or runware auth login once. No model downloads.
Where people get burned
The classic mistake is forgetting the transcript must match the reference clip. The node doesn't know what your voice sample says; you tell it, and if you lie (or guess), the clone comes out garbled. Also remember every run costs a few fractions of a cent - the title bar shows it (e.g. $0.00078 · NSFW: no), which is a handy habit to glance at before you fire off numberResults: 4 on a ten-minute script. And if you see a "No Runware API key" error, that's the missing-key path - nothing to do with the model itself.
Inputs (18)
| Name | Type | Default | Description |
|---|---|---|---|
| speech | RUNWARE_SPEECH | — | |
| audioSettingsopt | RUNWARE_AUDIOSETTINGS | — | |
| referenceVoicesopt | RUNWARE_REFERENCEVOICES | — | |
| numberResultsopt | INT | 11–4 | Number of results to generate. Each result uses a different seed, producing variations of the same parameters. |
| settings.chunkLengthopt | INT | 300100–300 | Text segment size for processing. |
| settings.conditionOnPreviousChunksopt | BOOLEAN | true | Previous audio context for voice consistency across chunks. |
| settings.earlyStopThresholdopt | FLOAT | 1.000–1 | Early stopping threshold for batch processing. |
| settings.latencyopt | COMBO | normal | Latency / quality trade-off. |
| settings.maxTokensopt | INT | 10241–4294967295 | Maximum audio tokens to generate per text chunk. |
| settings.minChunkLengthopt | INT | 500–100 | Minimum characters before splitting into a new chunk. |
| settings.normalizeopt | BOOLEAN | true | Text normalization for English and Chinese. Improves stability for numbers. |
| settings.normalizeLoudnessopt | BOOLEAN | true | Normalize output loudness for consistent perceived volume. |
| settings.repetitionPenaltyopt | FLOAT | 1.200–2 | Penalty for repeating audio patterns. |
| settings.temperatureopt | FLOAT | 0.700–1 | Expressiveness of the generated speech. |
| settings.topPopt | FLOAT | 0.700.0001–1 | Nucleus sampling parameter that controls diversity by limiting the probability mass. Lower values make outputs more focused, higher values increase diversity. |
| ttlopt | BOOLEAN | false | Enable to set ttl. Off uses the model's default. |
| ttl_valueopt | INT | 60 | Time-to-live (TTL) in seconds for generated content. Only applies when `outputType` is `URL`. |
| outputFormatopt | COMBO | MP3 | File format for the generated audio. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| audio | AUDIO | — |