CosyVoiceInference
Clone a Voice From a Few Seconds of Audio — Zero Shot, Cross-Lingual, or Instructed
- model
- prompt_audio
- tts_speech
This is the node that does the actual talking in the CosyVoice half of the pack. Feed it the TTS_MODEL from CosyVoiceModelLoader, a short reference clip of a voice, and the text you want spoken, and you get back synthesized speech in that voice. The whole point of CosyVoice is speaker similarity from almost no reference - a few seconds is enough, and unlike many TTS pipelines it doesn't need you to re-train or fine-tune anything.
The engine behind it is CosyVoice2 (Alibaba FunAudioLLM), which the community knows as the pick when the reference voice's language and identity matter more than English-first polish. The wider ComfyUI TTS landscape leans on Chatterbox and Kokoro, but CosyVoice's Chinese strength and cross-lingual cloning are exactly the niche this pack fills. (CosyVoice 3 is out in the wild since late 2025, but this pack pins 2.)
The three modes
inference_type is an enum, default zero_shot:
- zero_shot - the classic clone path. You provide a reference clip (
prompt_audio) and its transcript (prompt_text), plus the text to speak. - cross_lingual - same voice, different language. It uses the reference clip but not its transcript, so you can have an English speaker say Chinese (or vice versa). The pack's example runs zero_shot, but this is the mode to try when the reference and target languages differ.
- instruct - pass an instruction (
instruct_text) that shapes delivery - whisper it, sound excited, read like a news anchor. CosyVoice calls this itsinstruct2path and it's the closest you get to emotion control without training.
Inputs that matter
prompt_audio- AUDIO, the reference voice. Any ComfyUI audio works; the sample uses aLoadAudionode. The node squeezes it to mono and writes it to a temp wav internally.prompt_text- the transcript of that clip. For zero_shot, accuracy here matters more than you'd think; a wrong transcript visibly degrades the clone.tts_text- what you want synthesized.speed- FLOAT 0.5–1.5, step 0.1, default 1.0. 0.8 is a noticeably calmer read, 1.3 starts to sound rushed.instruct_text- only used ininstructmode.
Output is tts_speech (AUDIO) at the model's native rate (CosyVoice2's vocoder outputs 22.05 kHz), ready for SaveAudioAdvanced or any audio sink. IS_CHANGED returns a fresh timestamp on every call, so the node never caches - each queue run re-synthesizes, which means your preview is always current.
The is_japanese trap
The is_japanese optional toggle is a stub in the shipped code: tick it on and the node returns a silent audio clip instead of speech. There's no Japanese mode hiding behind it - it's an unfinished branch. Leave it unchecked. (Amusingly, the FishSpeech half of this same pack has the polarity flipped: that node returns silence when the toggle is off. Different packs, different footguns.)
Where it fits
The pack's example workflow is worth studying: LoadAudio → CosyVoiceModelLoader → CosyVoiceInference (zero_shot) → ConditionalBranchAudio → SaveAudioAdvanced, sharing the reference audio and text with a parallel FishSpeech chain so you can A/B the two engines through one output. Install the pack first - clone with --recursive into custom_nodes/, Python 3.12 env, the CUDA 12.8 constraints - then grab CosyVoice2-0.5B into models/tts/. If the loader works but you get empty output, the toggle above is your first suspect.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| model | TTS_MODEL | — | |
| inference_type | COMBO | zero_shot | 3 options: zero_shot, cross_lingual, instruct |
| speed | FLOAT | 1.00.5–1.5 | — |
| prompt_audio | AUDIO | — | |
| prompt_text | STRING | 怎么会离开呢,嗯?是觉得姐姐这里吸引不了你吗,还是说有其他的人更吸引。你带我看看他是什么样子的,然后,我会让你下一次见不到他。 | — |
| tts_text | STRING | 你好,我是通义生成式语音大模型,请问有什么可以帮您的吗 | — |
| instruct_textopt | STRING | — | |
| is_japaneseopt | BOOLEAN | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| tts_speech | AUDIO | — |