Qwen TTS Speaker Bank
Reuse saved voices without rebuilding them every time
- speaker_prompts
Qwen TTS Speaker Bank is the node you reach for once you've gotten Qwen3-TTS working and you're tired of rebuilding voices. It collects voices you've already saved, presents them as dropdowns, and hands a whole cast of speakers to the pack's Multi Speaker node as one dictionary. One node in, several voices out - that's the point.
It sits in the newest corner of Vantage Nodes: the Qwen3-TTS audio stack (Alibaba's open TTS line, in the same family as Qwen-Image and Wan). This isn't a lone utility; it's one piece of a pipeline - download models, build voices, then speak. The Speaker Bank is the part that makes multi-voice dialogue repeatable instead of a per-line nightmare.
How it works
When you save a voice with the pack's Voice Clone Prompt node, it stores a voice_prompt.pt file (plus a meta.json) inside custom_nodes/Vantage-Nodes/custom_voices/<voice-name>/. The Speaker Bank scans that folder on load and turns the folder names into dropdown choices. On run, it:
- Orders the speakers -
speaker_1always comes first, then any extras from the (JavaScript-managed)speakers_jsonblob. - Loads each voice's
voice_prompt.ptfrom disk on CPU. - Returns a dictionary mapping speaker name → voice prompt.
That dict feeds directly into the speaker_prompts input of QwenTTSMultiSpeakerNode, which uses it to cast dialogue. That node's script format is worth knowing: each line starts with a speaker tag, optionally with gap/volume/mode: [narrator] Once upon a time... or [hero, 300, 0.9, overlap] It's me! Speaker names are matched case-insensitively against the dict.
Inputs:
speaker_1(enum) - the required first speaker. If you haven't saved any custom voices yet, this dropdown shows only<none>.speakers_json(STRING, hidden) - managed by the node's JS for speakers 2+.
Output: speaker_prompts (DICT).
The honest setup cost
Before this node does anything, the rest of the stack has to exist, and that's where the friction lives:
- Models. The pack's downloader pulls four Qwen3-TTS-12Hz repos from Hugging Face (tokenizer, 1.7B Base, VoiceDesign, CustomVoice) into
ComfyUI/models/qwen-tts. That's multiple gigabytes and the reason this pack'srequirements.txtreads like a shopping list - torchaudio, librosa, soundfile, onnxruntime and friends. - Voices. The Speaker Bank has nothing to select until you've created at least one voice via Voice Clone Prompt and saved it to
custom_voices.
And the community consensus on Qwen3-TTS voice cloning in ComfyUI is... it works, eventually. Search results turn up real threads of people getting stuttering or garbled clones and debugging dependency quirks across whatever custom node they used. The speaker bank itself is the tidy, boring part of the stack - the model-side voice creation is where you'll iterate. Expect to spend the effort there, and the bank is where it pays off.
Gotchas
- "No speakers selected" or a dropdown that only offers
<none>: you haven't saved a custom voice yet. Do the voice-clone step first. - First run is a big download. Give the model download time and disk space before you assume it's hung.
- The output is a
DICT, not an AUDIO - if you wire it to a preview expecting sound, nothing plays.
Installation
Same pack, same path. ComfyUI Manager: search "Vantage Nodes." Or:
cd ComfyUI/custom_nodes
git clone https://github.com/vantagewithai/Vantage-Nodes.git
pip install -r requirements.txt
Restart ComfyUI. Unlike the pack's pure utility nodes, the TTS corner genuinely needs that full requirements.txt - and the model download on top of it.
Troubleshooting
- Dropdown shows
<none>: no saved voices found incustom_voices. Create one first. RuntimeError: Saved voice not found: the folder name in the dropdown no longer matches a directory - the voices folder was moved or cleaned.- Speaker name errors in Multi Speaker: the name in
[brackets]must match a key in the Speaker Bank output (case-insensitively).
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| speaker_1 | COMBO | 1 options: <none> | |
| speakers_json | STRING | {} | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| speaker_prompts | DICT | — |