Protoface Eleven v3 · Text to Speech
The voice everyone benchmarks against, wired into your graph
- audio
- files
- run id
What this node actually is
ElevenLabs is the bar every open TTS model gets measured against. When Chatterbox shipped, the whole "is it actually as good as ElevenLabs" argument happened because ElevenLabs is the fixed reference point - closed, paid, and the thing people reach for when a local model's prosody isn't good enough for a client. This node is that, as a ComfyUI node: type text, get an AUDIO object you can wire into the rest of your graph.
It lives in the Protoface pack - a beta (0.1.0) extension that wraps a pile of hosted models behind native ComfyUI nodes. Nothing runs locally: no checkpoint, no VRAM, just ComfyUI 0.41.0+, Python 3.10+, and a key.
Why you'd reach for it: a talking-head pipeline, a narrated short, or a voice track for a clip where you want the last 5% of delivery quality. Where you wouldn't: 200 iterations of a script, because paying per character gets old fast. The open route - Kokoro for speed, Chatterbox or F5-TTS when quality matters - is free after the download. The honest split is drafts local, final takes here.
How it works
The pack generates every model/task node from the provider's public request schema rather than hand-writing per-model code, which is why the controls here look exactly like ElevenLabs' request body. On queue the adapter validates the payload, submits the job, polls it, and materialises the result as a native AUDIO.
The part worth understanding is generation_id. It is not a seed. Fixed means "this is the same request I already asked for" - requeue and you get the recorded job back instead of paying twice. Bump it and you're buying a new generation. The pack journals the request identity before submission so a crash mid-job doesn't become a second charge.
The inputs that matter
- text is the whole script, and the tooltip is unusually useful: one character equals one token, ceiling of 10,000 characters, and you can drop
<#x#>between words to insert a pause of 0.01–99.99 seconds. That one trick fixes more bad reads than any slider. - voice_id defaults to
Aliceand is, on this node, a plain text field rather than a dropdown - unlike the pack's voice-changer node, which gives you a combo. You're expected to know your voice name or ID. - stability (default 0.5) trades consistency for expressiveness. High stability, flatter and safer; low stability, more performance and more chance of a wobble.
- similarity (default 1) is enhancement of clarity and closeness to the target speaker. The author's own note admits very high values can produce artifacts, so if a voice sounds metallic or unnaturally sharp, walk this down before blaming the script.
- use_speaker_boost defaults on and normalises text - it's what stops "1984" being read as "one nine eight four" in awkward places.
Outputs and where they go
audio is a list of native AUDIO - a list because the API can return several takes. Wire it into Save/Preview Audio, or straight into another Protoface node's audio input: LTX 2.5 Fast takes an audio_url media input, so "generate narration, then lip-sync video" is two nodes and a wire. Downstream nodes map over the list, so a save node gets called once per result.
files is a PROTOFACE_FILE list holding every original asset, and run id is the string you give Protoface Resume Run if the job finishes after your browser gave up.
Install
Manager is the least painful path: search Protoface, install protoface-nodes, restart, reload the browser. If the Registry index hasn't caught up, do it by hand from the ComfyUI directory:
git clone --branch v0.1.0 --depth 1 https://github.com/protoface-ai/protoface-comfyui.git custom_nodes/protoface
python -m pip install -r custom_nodes/protoface/requirements.txt
Use ComfyUI's own interpreter - python_embeded/python.exe on Windows portable, the managed environment on Desktop. Dependencies are light: httpx, jsonschema, Pillow, av. Then click Protoface in the lower-right and paste your key. It lives in server memory only, so it's gone after a restart - for a headless box set PROTOFACE_API_KEY_FILE instead.
Where people get burned
Requeueing after a restart without the key re-entered looks like an auth failure, not a bug. Re-enter it.
Editing the text and expecting the same generation_id to be free. It won't be. Changed text, changed voice, changed stability - all new paid requests. The generation id only protects an unchanged request.
A job that times out. Don't bump generation_id to "retry" - that's a new charge. Keep the scope and id, requeue, or feed the run id to Resume Run. The default job timeout is two hours, so a timeout usually means the provider is slow, not that the request died.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | Text to convert to speech. Every character is 1 token. Maximum 10000 characters. Use <#x#> between words to control pause duration (0.01-99.99s). | |
| similarity | FLOAT | 1.00–1 | High enhancement boosts overall voice clarity and target speaker similarity. Very high values can cause artifacts, so adjusting this setting to find the optimal value is encouraged. |
| stability | FLOAT | 0.50–1 | Voice stability (0-1) Default value: 0.5 |
| use_speaker_boost | BOOLEAN | true | This parameter supports English text normalization, which improves performance in number-reading scenarios. |
| voice_id | STRING | Alice | The voice to use for speech generation |
| generation_id | INT | 00–9007199254740991 | Keep fixed to reuse/resume this paid job. Increment for a fresh paid generation; independent of the model seed. |
| request_scope | STRING | Automatically assigned per node. Headless clients must supply a stable unique workflow/node ID. This is not a secret. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| audio | AUDIO | — |
| files | PROTOFACE_FILE | — |
| run id | STRING | — |