语音转换接收一段录音和一位参考说话人,产出用参考说话人的声音说出的同样内容。整条流水线中不涉及任何文本:输入是音频,输出也是音频,模型从不读取或生成转录文本。这正是它与文本转语音(TTS)的区别——TTS 从文本出发,没有需要保留的源录音。语音转换回答的是一个更窄的问题:给定这段录音,让它听起来像另一个人,同时保持词语不变。
这个更窄的任务有实际用途。把一段录音配音成一个统一的声音,而无需请第二位配音演员。在保留逐字内容的同时,对一段采访或客服通话中的说话人做匿名化处理。当一个 TTS 系统各语言的底层声音是各自独立训练的、原本听起来像不同的人时,为其输出赋予一个跨语言统一、稳定的身份。
voiceclonnx 在同一套 Python API 背后实现了其中 10 个引擎,全部运行在 onnxruntime 上,推理时不需要 PyTorch。这些引擎并不能互相替代。它们来自不同的模型家族,选择其中一个意味着选择一种权衡,而不是选出一个赢家。
API 一览
from voiceclonnx import VoiceCloner
cloner = VoiceCloner(engine="facodec")
out = cloner.clone_voice("source.wav", "reference.wav", "out.wav")
print(cloner.sample_rate) # 16000
clone_voice(audio, reference_voice, out_path) 接收源录音、一段 5 到 30 秒的目标说话人参考片段,以及一个输出路径,返回转换后 WAV 文件的路径。切换引擎只需切换 engine= 字符串;调用形态不变。有一个引擎 rvc 是例外——它接收的是一个 .onnx 声音模型的路径,而不是一段参考录音,详见下文。pip install voiceclonnx 会拉取全部 10 个引擎;模型会在首次使用时从 Hugging Face 下载。
两个维度,而非一个分数
有两个数字描述一次转换的效果好坏,而它们并不同步变化。
词错误率(WER) 衡量可懂度:原句中有多少内容得以保留,判断方式是把输出重新喂给一个语音识别器,与源转录文本比较。0% 的 WER 意味着每一个词都正确保留了下来。
说话人相似度 衡量身份:输出听起来是否真的像目标说话人,而不是原说话人。它的计算方式是:从输出和参考片段中各提取一个说话人嵌入——一段声音音色的紧凑数字指纹,即在相同音高和响度下让一个声音听起来不同于另一个声音的那种音质——然后用余弦相似度比较两者。分数为 1.0 意味着音色完全相同;voiceclonnx 自己的基线——把源音频未转换的副本拿去与目标对比——落在 0.09,因此任何显著高于这个数字的分数,都说明真的做了转换工作。
voiceclonnx 为每个引擎都发布了这两个数字,测量方式是把同一个句子转换成两个参考声音。WER 来自 faster-whisper;说话人相似度来自一个 wespeaker-resnet34 嵌入模型(并与另外两个模型做了交叉核对)。把两者并排放在一起,一个规律就出现了:没有哪个引擎能同时在两栏都拔得头筹。
| 引擎 | 家族 | WER | 目标相似度 |
|---|---|---|---|
focalcodec | kNN 特征替换 | 15-19% | 0.61 |
lscodec | 说话人解耦编解码器 | ~35% | 0.54 |
chatterbox | 自回归编解码语言模型 | 4-8% | 0.54 |
knnvc | kNN 特征替换 | 12-15% | 0.49 |
facodec | 因式分解编解码器 | 0% | 0.44 |
openvoice | 音色迁移 | 0% | 0.37 |
bicodec | 语义加全局 token | 12% | 0.29 |
triaan | Triple-AAN | 4% | 0.29 |
cosyvoice | 流匹配 | 8% | 0.21 |
(rvc 把任意源音频转换到一个固定的、由社区训练的声音,而非一个任意的参考片段,因此不适合放进这张表里比较;详见下文。)
按行来读这张表,而不是试图找出唯一的最佳一行。facodec 和 openvoice 落在 0% WER——每个词都保留了下来——相似度中等。focalcodec 和 lscodec 则位于另一端:这一组中最强的音色迁移,代价是让 15-35% 的词出错。chatterbox 是唯一一个在两个维度上同时表现不错的引擎(4-8% WER,0.54 相似度),这是它架构的一个特性,下文会讲到。
为什么这些家族表现各异
这些引擎分属不同的方法路线,而方法路线预示了它们在上表中会落在哪个位置。
kNN 特征替换(knnvc、focalcodec)。源音频被切成短帧,每一帧由一个预训练的自监督编码器转换成一个特征向量。对每一个源帧,算法在目标说话人特征池中找出 k 个最近邻帧并将其加权平均代入,逐帧替换源音频的音色,同时把底层的音素内容留在编码器自身表示所提取出的位置不动。这里没有一个学习出来的、把一种声音映射到另一种声音的解码器——替换是一次最近邻查找——这正是音色迁移可以做得如此激进的原因(focalcodec 达到 0.61 相似度),代价是偶尔会把在目标池中匹配较差的帧弄得含糊不清,这就体现为 WER。
因式分解编解码器(facodec)。一种神经音频编解码器——一个把语音压缩成紧凑 token 序列、再重建出来的模型——经过训练,把这些 token 显式拆分为独立的内容流和音色流。因为内容是一条专属的流,解码器能高保真地重建词语;只有音色流会被替换为目标说话人的音色。正是这种显式的分离,让 facodec 达到 0% WER:内容保留不与任何其他目标竞争。
音色迁移(openvoice)。一个转换模块在一个独立的编码器已经固定了语言内容之后,改变音调轮廓和音色,精神上与因式分解编解码器方法类似,但实现为在 mel 频谱图上的一次色彩迁移步骤,而非在离散 token 上操作。它同样达到 0% WER,相似度略低于 facodec。
自回归编解码语言模型(chatterbox)。一个自回归语言模型,以目标说话人的嵌入为条件,逐个预测编解码 token,很像一个文本转语音语言模型,只不过条件是源录音的内容 token 而非文本。因为它把韵律(节奏、重音、语调)作为同一个自回归过程的一部分生成出来,而不是直接从源音频复制过来,它可以把说话风格与音色一并带过来——这正是文档中提到它给出”最强源到目标转变”的原因——也是唯一一个在可懂度和相似度上同时表现良好的引擎。
流匹配(cosyvoice)。一个连续的生成过程,通过一个常微分方程(ODE)求解器迭代若干步(ode_steps,默认 10 步),把噪声逐步细化为目标 mel 频谱图。它的内容编码器是为跨语言迁移设计的,这种通用性很可能正是它的目标相似度得分在这组引擎中最低的原因:这种表示为语言无关性做了优化,而非为最紧密的说话人匹配。
说话人解耦编解码器(lscodec)。与 facodec 类似,是一个经过训练把内容与说话人身份分离的编解码器,但调优方向是进一步推高相似度,直接以内容流的精度为代价,落在约 35% 的 WER,相似度是这组中第二高的。
Triple-AAN 与语义加全局 token 编解码器(triaan、bicodec)在两个维度上都居中:WER 中等,相似度中等,两个方向都没有明显偏向。
多对一编解码器加声码器(rvc)。构建在 ContentVec(一个内容编码器)之上,接入一个 VITS 声码器,针对每个目标声音单独训练,而不是接受任意的参考片段。这个引擎的 reference_voice 参数是一个 .onnx RVC 模型文件的路径或一个 Hugging Face 仓库 ID,而不是一个音频文件:
cloner = VoiceCloner(engine="rvc")
out = cloner.clone_voice("source.wav", "/path/to/myvoice.onnx", "out.wav")
因为每个 RVC 模型都是针对一个目标声音训练的,它在推理时不接受参考片段,也不与那些任意对任意的引擎用同一个相似度基准来打分。它测得的 38% WER 反映的是一个社区训练模型样本的表现,而非这个架构本身的普遍水平——质量取决于那个具体模型是怎么训练出来的。Hugging Face 上有数千个社区 RVC 声音,可以直接按仓库 ID 加载。
如何决定用哪一个
快速、通用的流水线。 从 facodec 或 openvoice 开始。两者测得的 WER 都是 0%,相似度中等(分别为 0.44 和 0.37),而且都提供一个未记录质量下降的 INT8 量化变体——传入 quantized=True 即可获得一个更小、更快的模型。
最大化说话人相似度。 如果用例能接受 15-19% 的 WER,就用 focalcodec(0.61 相似度,测得的最高值);如果不能接受,就用 chatterbox(0.54 相似度,4-8% WER)。chatterbox 还运行在 24 kHz,是这组任意对任意转换引擎中最高的输出采样率——rvc 可以跑到 48 kHz,但仅限于上文提到的多对一模式。
低资源硬件。 knnvc 在 INT8 下磁盘占用约 123 MB,是这组中体积最小的,相似度 0.49,WER 12-15%——对内存受限的场景是一个合理的权衡。不是每个引擎都能干净地量化:focalcodec 和 cosyvoice 文档中记录了在 INT8 下会出现质量下降,因此这两个应保持在 fp32。
引擎未经训练覆盖的语言。 cosyvoice 的内容编码器是为跨语言迁移而构建的,这正是文档中给出的、在同语言转换调优引擎之外选用它的理由,尽管它测得的相似度(0.21)是九个可直接比较引擎中最低的。
声音身份优先于逐字精确。 lscodec 在编解码器家族的引擎中提供最强的音色迁移(0.54,与 chatterbox 并列),代价是在可比较的这组引擎中 WER 最高(约 35%)。当目标是”这听起来像不像目标说话人”、而输出中偶尔出现的词语错误可以容忍时,选它。
一个固定的社区声音,而非任意片段。 rvc,使用一个预训练的 .onnx 声音模型,而非一段参考录音。
先要核实的非商用限制。 bicodec 的权重采用 CC BY-NC-SA 4.0 许可。其他每一个引擎的权重都是 MIT、Apache-2.0 或 CC BY 4.0 许可。在把你所部署的具体权重用于商业用途之前,请先核实其许可证。
它做不好什么,以及不该用在谁身上
以上每一个数字都带着同一条提醒:这些数字描述的是一句英语示例句子在两个特定参考声音之间转换的结果。换一种语言、一段噪声更大的源录音、一段更短或质量更差的参考片段,或是一位声音与某引擎训练数据中的一切都相去甚远的源说话人,都会让这些数字发生变化,而且通常是往更差的方向变。这些引擎都不是解决低质量源录音的万能药——其中几个会愉快地转换音色,同时把源音频中的噪声原封不动地带过来,因为噪声有自己的声学特征,内容/音色分离并不总能干净地把它分开。
语音转换还带来一个真实的风险,这个风险和它的近亲——用于 TTS 的声音克隆——已经迫使这个团队认真思考过:把一段录音转换成听起来像一个真实、可识别的人,无论本意是否如此,这本身就是一项具备冒充能力的技术。这个团队对合成声音普遍采用的规则——在把一个真实人物的声音用作供体或目标之前先取得明确许可,在无法取得许可时改用公共领域录音或一个刻意原创的声音——在这里毫无例外地适用。从同意的角度看,一段真实人物的参考片段与一整套针对其声音的训练集并无不同;它只是需要少得多的素材就能产出一个可用的结果,这是需要更加谨慎、而非更少谨慎的理由。
如果语音转换是你正在构建的某条流水线的一部分,欢迎通过 /zh/contact 联系我们,或看看我们提供的服务。