arkennemasis Qwen3-TTS (voice clone)
Voice cloning in ComfyUI, no cloud account, no transformers downgrade
- reference_audio
- audio
- report
Qwen3-TTS is one of the better open voice-cloning models around, and it's been a pain in ComfyUI since day one: the model is pinned to a transformers version that's incompatible with modern ComfyUI, so every published wrapper tells you to downgrade - which then breaks the eleven other node packs depending on the current one. The community threads about it are full of "I've been waiting patiently while they fix it." ArkQwenTTS is the fix that refuses to downgrade anything. Wire in 5–30 seconds of someone speaking, feed it your text, and it speaks in that voice, locally, on your GPU, no account.
Why the subprocess matters
The node runs the model in a child process with its own private transformers in vendor/tts_env, put first on sys.path only there. Same interpreter, same torch, same CUDA - the one conflicting package differs, and only inside that worker. The pack tried shimming the API changes in-process first and the model diverged inside attention. Chasing transformers internals is not something anyone should maintain, so they didn't.
That means the setup is a one-off, and it's not automatic. vendor/ isn't committed (114 MB, and redistributing someone else's package is a deliberate no), so a fresh clone has to build it once:
python_embeded\python.exe -m pip install -t ComfyUI\custom_nodes\comfyui-arkennemasis\vendor\tts_env ^
--no-deps "transformers==4.57.3" "huggingface-hub>=0.34.0,<1.0" "tokenizers>=0.22.0,<=0.23.0"
Then the models, into ComfyUI's own tree:
huggingface-cli download Qwen/Qwen3-TTS-12Hz-0.6B-Base --local-dir ComfyUI\models\qwen-tts\Qwen3-TTS-12Hz-0.6B-Base
The inputs that matter
model- a folder underComfyUI/models/qwen-tts. A Base model is clone-only: it has no preset voices, soreference_audiomust be connected or the node stops immediately and says so. For preset voices you want a CustomVoice model.text- what to say.language- Auto lets the model decide; explicit choices are there if you know.seed- each run re-seeds, and generation is retried up to three times with fresh seeds, because the model occasionally never emits end-of-speech and generates until something stops it. Re-running the same seed reproduces the exact same runaway.reference_audio- the voice to clone. 5–30 s of clean speech is plenty.reference_text- a transcript of the reference clip. Supplying it gives a closer clone; blank uses x-vector-only mode, which still works.timeout_seconds(180) - per attempt, and it's a runaway detector, not a budget: a 24-word line takes ~30 s including the ~2.5 GB weight load.
audio comes out as a ComfyUI AUDIO tensor ready to feed the video side of the pack.
Common issues
- "No models under ComfyUI/models/qwen-tts" - you haven't downloaded a model yet. That's the drop-down being honest.
- Base model, no reference audio - stops immediately with a clear message. Connect the clip.
- Seems to hang - it refuses to fall back to CPU, because CPU synthesis is ~40× slower and reads exactly like a hang. Check the GPU is actually being used.
Don't downgrade your main transformers to make this work - that's the entire point of the vendored subprocess, and breaking your other packs to feed this one is the trap the README is explicitly warning you about.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | What to say. | |
| model | COMBO | A folder under ComfyUI/models/qwen-tts. Voice cloning needs a *Base* model. | |
| language | COMBO | 'Auto' lets the model decide from the text. | |
| seed | INT | 00–18446744073709550000 | — |
| reference_audioopt | AUDIO | The voice to clone. 5-30 seconds of clean speech is plenty. A *Base* model REQUIRES this. | |
| reference_textopt | STRING | A transcript of the reference clip. Supplying it gives a closer clone; leaving it blank uses x-vector-only mode, which still works. | |
| timeout_secondsopt | INT | 18060–3600 | Per attempt, and there are 3 attempts with fresh seeds. A 24-word line takes about 30 s including the ~2.5 GB weight load, so 180 s is six times over — it is a runaway detector, not a budget. It was 600 s, which meant one looping line cost 10 minutes before failing. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| audio | AUDIO | — |
| report | STRING | — |