cosyvoice: instruct field is Chinese-context-only — English directives get vocalized
#7
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Symptom
Calling
POST /v1/audio/speechwith English text ininstructproduces audio that sounds like Chinese-flavored phonemes reading the English directive aloud, rather than English speech in the requested tone.User-reported example, request:
Audible result: a string of Chinese-sounding speech, not the English
input.Root cause (verified 2026-04-24)
The neosun/cosyvoice wrapper maps the
instructfield to CosyVoice'sinference_instruct2, which expects a Chinese-template directive of the form:(per FunAudioLLM/CosyVoice upstream docs; see the model card on HF).
When
instructis set, the wrapper concatenates the user value into that template position. English directives (or any non-Chinese-template text) get treated as content rather than direction — the model vocalizes them with Chinese phoneme tendencies.Empirical bracket
Five variants tested, byte-for-byte response sizes against
voice=9053c5a52f80, model=cosyvoice-v3:instructvalue""(empty string)"speak with cold contempt""用冷酷蔑视的语气说""Use English. Speak with cold contempt.""用冷酷蔑视的语气朗读以下英文"C/D/G/I all producing identical 192,078-byte responses confirms the wrapper's instruct path is deterministic on string length and not sensitive to English-vs-Chinese semantics — the model is stuck in a Chinese-context branch regardless of input.
In contrast, XML inline tags work cleanly:
<angry>You should leave now.</angry><sad>You should leave now.</sad>Workaround
For English content: use XML inline tags exclusively. Do not pass
instruct(orinstruct_texton/api/tts) for English work. README updated.Possible upstream paths
neosun100/cosyvoice-docker.inference_instruct_enor similar.Likely outcome: keep XML-tag pattern, file upstream issue when motivated.
Web-search update
This is the same upstream bug as FunAudioLLM/CosyVoice#1790 ("Fun-CosyVoice3-0.5B-2512 generates Chinese speech instead of Russian regardless of input language") — closed 2026-04-14 with no posted fix. Users on that thread tried, all unsuccessfully:
inference_zero_shotwith target-language reference + transcriptinference_cross_lingualinference_instruct2with explicit language directive<|ru|>So the bug is in the model checkpoint (Fun-CosyVoice3-0.5B-2512), not the neosun wrapper specifically — the wrapper's
instructpath makes it worse but the underlying Chinese bias affects every inference function.Wrapper-side details we mapped
Reading
/app/app.pyinside the running container:/v1/audio/speechwith a custom voice →inference_zero_shotwithprompt_text = f"<|endofprompt|>{custom_voice_transcript}"(a wrapper-side fix for upstream #967/#1704 audio-repetition)./v1/audio/speechwithinstructset →inference_instruct2(the Chinese-template path documented in the README)./api/ttswithmode=cross_lingual→inference_cross_lingualdirectly, no<|endofprompt|>prefix./api/ttswithmode=sftrequires a registeredspk_id;/api/speakersreturns[]on this image, so no preset English speakers exist.Workaround triage (empirically, voice =
9053c5a52f80, GLaDOS English clone)All three of these return 200 + valid 24kHz mono WAV:
/api/ttscross_lingual/api/ttszero_shot+ explicitprompt_text/v1/audio/speechbut with caller-controlled prompt/api/ttscross_lingual+model=cosyvoice-v2Listening required to know which (if any) actually produce English audio. User report pending.
Fallbacks if no variant works
Tagging this issue stays open pending user-side audition of X1/X2/X3.