现场是这样的。用 CosyVoice2-0.5B 做零样本音色克隆,参考音频是手机录的 48kHz m4a,直接传进 inference_zero_shot,报 sample rate must be 16000,换成另一段 16k 的 wav 就正常。

中间走过弯路,把「重采样用了默认的高质量滤波器但通道数没降」当成主因,改完现象没变。

真正麻烦的地方在于,几个原因的现象几乎一样。模型要求参考音频与提示音频统一为 16kHz 单声道;m4a 容器里的音频流实际是 44.1kHz,文件名看不出;参考音频长度超过 30 秒,尾部被截断导致特征漂移。

上来先用 ffprobe 查清真实采样率与声道

ffprobe -v error -show_entries stream=sample_rate,channels -of csv=p=0 ref.m4a

转成 16k 单声道 wav 并裁到 10 秒

ffmpeg -i ref.m4a -ar 16000 -ac 1 -t 10 -c:a pcm_s16le ref16k.wav

再往下用转换后的文件重跑零样本合成

python -c "import sys;sys.path.insert(0,'CosyVoice');from cosyvoice.cli.cosyvoice import CosyVoice2;m=CosyVoice2('pretrained_models/CosyVoice2-0.5B');print(len(list(m.inference_zero_shot('今天我们来聊聊缓存','希望你以后能够做的比我还好呦。',ref16k.wav,stream=False)))"

剩下的就是输出音频再核对一次格式是否可播

ffprobe -v error -show_entries stream=sample_rate,channels -of csv=p=0 out.wav

别只看报错消失,验证要多做一步。合成请求正常返回,输出 wav 为 16k 单声道,试听音色与参考音频接近,日志里不再出现采样率断言。

容易忽略的是,克隆类模型的参考音频要求写死在预处理里,先做一次 ffprobe 再转码,比反复换参考文件省时间。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。

作者 9823189