Qwen3-TTS SenseVoice ASR 🗣️
Have a voice but no transcript? SenseVoice ASR transcribes it — and sniffs the emotion
- audio
- text
- suggested_instruct
Voice cloning in this pack has one awkward requirement: you need to know what the reference clip says, because ref_text is required unless you flip on x-vector mode (and x-vector costs you some similarity). But half the reference audio you'll find doesn't come with a transcript - especially if it's in a language you don't read. That's what this node is for: it's a speech-to-text (ASR) node built on Alibaba's SenseVoiceSmall, and it turns any AUDIO into text.
The interesting part is the second output. SenseVoice tags speech with emotion markers, and the node converts those into a suggested_instruct - a ready-made emotion instruction ("speak in a happy and cheerful tone", etc.) you can feed straight back into generation. So it's not just a transcription tool, it's a "read the feeling of this clip and hand me the instruction that reproduces it" tool.
What goes in and out
audio- anyAUDIO(a reference clip, a podcast excerpt, a take you generated and want to re-annotate).model_id- a single choice,iic/SenseVoiceSmall, which auto-downloads on first use intoComfyUI/models/TTS/SenseVoiceSmall/via ModelScope.language-auto(default), pluszn,en,ja,ko,yuefor forcing a language. In practiceautohandles most clean clips.
Outputs: text (STRING, the cleaned transcript with the model's internal tags stripped) and suggested_instruct (STRING - an emotion instruction, or empty if the clip reads as neutral).
How it works
It's a FunASR AutoModel wrapper. The node writes your audio to a temp wav, runs model.generate() with inverse-text-normalization on, and pulls the raw text out of the result. SenseVoice emits emotion tokens like <|HAPPY|>, <|ANGRY|>, <|SAD|>; the node detects those and maps them to this pack's built-in emotion instructions (happy/angry/sad map cleanly; anything else degrades gracefully to a generic "speak in a X tone" fallback). The ASR model is cached in memory between runs and only reloaded if the model_id changes, so repeat transcriptions are fast.
Where it fits in a cloning workflow
Load reference clip ─> Qwen3TTSSenseVoiceASR ─┬─> text ──────────> ref_text
└─> suggested_instruct ─> instruct
│
Qwen3TTSLoader (Base) ─> Qwen3TTSVoiceClonePrompt ─> voice_clone_prompt ─> Qwen3TTSVoiceClone
That's the loop that saves you: transcribe the clip, feed the transcript into the clone prompt, and if you want the delivery to match the original's mood, wire suggested_instruct into the generation node's instruct input. You've gone from "a clip I found" to "that voice, saying my words, with the same feeling" without typing a single line of the reference text.
Gotchas
- It needs
funasrandmodelscopeinstalled. Both are in the pack'srequirements.txt, so a normal install covers it - but if you skimped and the node errors with "Please install funasr", that's the fix (pip install funasr torchaudio). - The model downloads via ModelScope on first run. Same story as the main models: fine in China, occasionally slow elsewhere. No HuggingFace fallback here - it's hard-coded to the ModelScope download.
- Emotion detection is a bonus, not a guarantee. SenseVoice catches the big three (happy/angry/sad) well; a subtly annoyed or flatly tired clip will likely come back with an empty
suggested_instruct. Don't read the absence as a bug. - Transcript quality tracks audio quality. Clean, single-speaker clips transcribe well. Noisy or overlapping audio produces garbage, and garbage
ref_textpoisons the clone - so pre-clean the clip if you can. - Same pack-wide install: clone
wanaigc/ComfyUI-Qwen3-TTS,pip install -r requirements.txt, restart ComfyUI.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| audio | AUDIO | — | |
| model_id | COMBO | 1 options: iic/SenseVoiceSmall | |
| language | COMBO | auto | 6 options: auto, zn, en, ja, ko, yue |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| text | STRING | — |
| suggested_instruct | STRING | — |