任何行动都比不采取行动好。
背景
之前和同事看到了 B 站上一些有关语音合成的视频,B 站的 up主演示了用自己的音频素材训练成特定模型,然后就可以自动给小说配音,效果还是挺不错的。
演示视频在这里:【Bert -VITS2 】效果远超VITS的新项目!效果展示\经验总结
讨论了一下之后,感觉可以在游戏项目中尝试一下,比如给游戏中的 NPC 来配音。目前,项目中有不少配音演员配的对话音频,可以拿过来训练。
AI配音流程
语音合成,学名叫 Text to Speech,简写为 TTS,故名思义,就是将文字转化为语音的技术。在这个过程中,AI 可以模仿人类说话。
在此之前,需要根据特定人的语音素材训练出一个特定的模型,然后由模型来推理出文字对应的音频。整个流程如下:

和人类学说话一样,机器也需要通过大量的语音片段作为"听力材料",才能学会发音技巧。以及还得学会一些语言规则,比如语法和韵律,才能像人类一样,说话语气、语境,能表达出字面之外的表意。不然,机器只会说出生硬、没有情感、不连贯的话(就像一些动漫或游戏作品中机器人角色的对话)。
音合成技术目前主要应用在读书软件、导航软件、对话问答系统、配音等中。
根据调研,目前效果比较好的开源基础TTS模型是:Bert-VITS2,也是上面视频中up主使用的模型。
该模型的训练数据需要:
- 原始语音,长度最好短于20秒,如果噪音较大,还需要做预处理,去掉噪声
- 语音对应的文本
数据准备:语音标注文字
现在很多待训练的音频素材往往没有对应的文字,因此我们需要对每一个音频做文字标注,如果音频数量比较多,人工去听音频然后标注对应的文字,这个工作量太大。因此很有必要用一些工具来做自动标注。
目前可以做自动标注的方法有几种:
- openAI 开源的 whisper 项目,可以将音频识别成文字,支持多国语言
- 基于 whipser 的 whisperX 项目
- 字节跳动的飞书妙计产品
- 阿里云提供的 ASR(Audio Speed Recognition)
尝试了 OpenAI 的 whisper,效果尚可。飞书妙计效果更好,但是目前应该只支持手动单个音频处理。
whisper 的语音识别
whisper 的使用比较简单,通过 python(>= python3.9.9 版本)安装好包之后就可以直接用了。
whisper 提供了对多种语言的支持,其大部分训练用的语料是英文的,中文的语料没有那么多。
因此如想要提高中文识别效果,可以在其提供的 tiny、base、small、medium、large 多种模型中选择 medium 及以上。越大的模型效果越好,但是速度也越慢,这里我们选 medium 来测试:
bash
$ whisper youraudio.wav --language Chinese --model medium
测试下来,发现输出的是繁体中文。因此最好还要加上 prompt 来提示 whisper 输出简体中文(果然符合 openAI 的一贯思路):
bash
$ whisper youraudio.wav --language Chinese --model medium --initial_prompt "以下是普通话的句子。"
如果要批量来标注多个语音,可以在命令行输入多个语音文件名:
bash
$ whisper sample1.wav sample2.wav sample3.wav --language Chinese --model medium --initial_prompt "以下是普通话的句子。"
如果语音文件非常多,就可能达到命令行最多255个字符的限制。如果用 bat 文件来循环调用命令行,那每一次执行就要加载一次模型,效率不会太高。
此时我们可以考虑用 whisper 项目提供的 python API:
python
import whisper
import os
# 只加载一次模型,可以使用 device 参数指定用 cpu 还是 cuda(gpu)
# gpu 跑快一些
model = whisper.load_model("medium", device="cpu")
f = open("result.list", 'w', encoding="utf-8")
for root, dirs, files in os.walk("."):
count = 0
for i in files:
filename = os.path.join(root, i)
# print(filename)
if not i.endswith("wav"):
continue
count = count+1
result = model.transcribe(filename, initial_prompt="以下是普通话的句子。")
content = "{} | {}\n".format(i, result['text'])
f.write(content)
f.close()
实际测试下来,几百个音频文件用 cpu 来跑,10 小时左右也能跑完。
结果如下:

识别结果纠正
给所有的音频素材标注完文本之后,我们还遇到一个问题:因为游戏是中国古代背景,人物语音会有不少文邹邹的文字或专有名词,因此识别错误率还是有的。
例如,某个音频自动识别标注出的文本如下:
爱情 前来觐见,所谓何事?
明显不太对,正确的原始文本是:
爱卿 前来觐见,所为何事?
可以看到,大部分文字是对的,只有少部分词汇不对,此时就需要想办法将识别出的文字和原始文本做相似度匹配。(原始语音和原始文本并没有对应起来,否则就不用标记啦)
如果连原始文本也没有,那可能要将标注出的初稿结合其他工具来做修正,比如很多编辑器或云文档也提供纠正错字的功能:

但对于特定词汇可能就识别不出来,需要人工来辅助校验。
关于使用相似度匹配算法,来结合原始文本来纠正自动标注文本的方法,具体如何实施,我们下次继续聊。