语音合成

简介

语音合成技术的本质是将文本信息转化成语音信息,如果我们要将这句文本信息变成语音信息,首先需要在语音合成数据库里面挑选出这句文本信息所包含的元素,挑选完元素之后将这些元素按照一定的顺序组合排列,最后再输出我们想要合成的那句语音信息。语音合成的原理是将输入文本分析得到的信息,从预先录制和标注好的语音库中挑选合适的单元,进行少量的调整(也可以不进行调整),然后拼接得到最终的合成语音,其中用来进行单元挑选的信息可以是前端分析得到的韵律文本,也可以是生成的声学参数(比如基频、时长和谱参数),或者两者兼有。

​ 语音合成的方法主要分为三类:波形合成法、参数合成法和规则合成法。

​ 波形合成法是对波形进行编码或编辑。 波形合成法是相对简单,通常只能合成有限词汇的语音段。 波形合成法一般有两种形式,一种是波形编码合成,它类似于语音编码中的波形编解码方法,该方法直接把要合成的语音发音波形进行存储,或者进行波形编码压缩后存储,合成重放时再解码组合输出。另一种是波形编辑合成,它把波形编辑技术用于语音合成,通过选取音库中采取自然语言的合成单元的波形,对这些波形进行编辑拼接后输出。

​ 参数合成法是从数字信号处理,统计学等角度,对声码器提取的声学特征参数进行统计建模,然后把模型预测得到的声学特征参数输入声码器完成语音合成。传统参数语音合成方法是基于统计学习和决策树的隐马尔科夫-高斯混合模型 (HMM)。 HMM 对声音特征的适应性和鲁棒性高、需要较小的计算代价和在训练数据较少的时候有更好的表现等诸多优点,使其长期成为语音合成方法的主流技术。

​ 规则合成法通过语音学规则产生语音。 合成的词汇表不是事先确定,系统中存储的是最小的语音单位的声学参数,以及由音素组成音节、由音节组成词、由词组成句子和控制音调、轻重音等韵律的各种规则。 给出待合成的文本数据后,合成系统利用规则自动地将他们转换成连续的语音声波。

​ 本节使用的语音合成算法为VITS,VITS是一种结合变分推理(variational inference)、标准化流(normalizing flows)和对抗训练的高表现力语音合成模型。VITS通过隐变量而非频谱串联起来语音合成中的声学模型和声码器,在隐变量上进行建模,从而消除两个模型之间的不匹配问题,实现真正意义的端到端语音合成。VITS的好处是VAE擅长捕捉句子整体的韵律特征,而Flow擅长重建音频的细节特征;将两者整合,进行多任务训练,实现参数与优势共享。

硬件平台

机器硬件:OriginBot(导航版/视觉版)
PC主机:Windows(>=10)/Ubuntu(>=20.04)
扩展硬件:X3语音版

操作步骤

用VITS算法训练模型

本次VITS的训练教程根据你的电脑的版本选择,本实验以windows训练单人数据集为例。首先是前期准备工作:

​ 1、安装Conda来搭建Python虚拟环境。Conda官网

​ 2、下载音频处理软件(包括Au或者类似软件都可以)

​ 首先准备数据集,选择希尔贝壳语音数据库(也可以自己选择其他数据集)。进入官网下载数据集。AISHELL-3是由北京贝壳科技有限公司发布的大规模高保真多说话人普通话语音语料库。它可用于训练多说话者文本到语音 (TTS) 系统。该语料库包含大约 85 小时的情感中性录音,由 218 位以中文普通话为母语的人所说,总共 88035 条话语。他们的辅助属性,如性别、年龄组和本地口音在语料库中被明确标记和提供。因此,汉字级别和拼音级别的成绩单与录音一起提供。通过专业的语音标注和严格的声调韵律质检,字音转写准确率在98%以上。

​ 通过git项目下载,如果没有git,进入VITS项目网站下载

git clone https://github.com/CjangCjengh/vits.git

​ 进入下载的VITS项目,删除所有文件,新建list.txt,list_val.txt。文件编码必须是UTF-8。
然后需要对音频进行处理,音频要求:无背景音(自行搜索如何去背景音、去噪、去BGM)、吐字清晰、无明显情感波动、语速适中、音量大小均衡。如果不符合要求将会影响训练出的模型质量。 使用Au(或者其他音频处理软件)处理数据集的音频(格式请严格处理为单声道、22050Hz,PCM 16bit)

​ 接下来进行音频的分割处理,下载audio-slicer项目,使用Conda虚拟环境进行处理:
conda create -n slicer python=3.7
conda activate slicer

#进入audio-slicer安装相关依赖,如果出现依赖冲突,可以自行选择版本命令安装或者按需修改
pip install -r requirements.txt
#将Au处理过的音频移动到当前目录
python slicer.py 这里填你命名的文件

然后将分割后的文件(不包括原文件)移动到前面的wavs目录,然后进行文本整理,打开filelists目录中的list.txt(训练集)和list_val.txt(验证集)。

关于数据量,个人建议训练集五百条十秒长的语音起步,越多更好;验证集大概为训练集十分之一左右,另外,两个txt文件都必须不带任何空行,末尾也不可以,否则后面预处理会报错out of range

​ 文件的处理可以参考一下简单的python脚本来处理,这里以希尔贝壳语音数据集的处理为例:

import re

def convert_text(text):
    # 使用正则表达式匹配拼音和数字字符
    pattern = re.compile(r'\b[a-z]+\d*\b|\s')
    # 将匹配到的内容替换为空字符串
    result = re.sub(pattern, '', text)
    # # 在 ".wav" 后面加上 "|"
    # result = result.replace('.wav', '.wav|')
    return result

def convert_text2(text):
    pattern = re.compile(r'\.')
    # pattern = r'\.'
    result = re.sub(pattern, r'.wav|', text)
    # 在结果前面加上 "wav/"
    result = 'wavs/' + result + '。\n'
    return result


with open('list_val_copy.txt', 'r' , encoding="utf-8") as f:
    with open('list_val.txt', 'w' , encoding="utf-8") as f1:
        for line in f:
            line2 = convert_text(line)
            line2 = convert_text2(line2)
            f1.write(line2)

完成前期准备工作之后,开始搭建VITS环境进行训练。

conda create -n vits_gsh python==3.7
conda activate vits_gsh  

接下来使用nvidia-smi确定显卡驱动版本,查看CUDA驱动是否正常,根据CUDA驱动安装torch。进入pytorch官网根据对应的版本进行安装。

pip install -r requirements.txt

​ 然后conda到monotonic_align文件夹,输入以下命令

python setup.py build_ext --inplace

​ 如果出现“可能丢失数据”字样,并且该文件夹没有再嵌套一个monotonic_align文件夹,但是多出来了build文件夹,将build文件夹中的lib开头的文件夹中的monotonic_align文件夹移动到最外层的monotonic_align文件夹即可。

​ 修改项目文件(以训练中文模型为例),根据configs文件夹中给出的例子生成一份属于自己的config.json放在此目录。其中data部分的前两行要改成我们前面保存list.txt和list_val.txt路径”filelists/list.txt.cleaned”和”filelists/list_val.txt.cleaned”。text_cleaners因为我们是中文模型,保持默认即可。 然后n_speakers说话人数,因为是单人改为0即可。最后的speaker这行也可以删掉。
因为下载下来的项目代码默认cleaner并非是中文cleaner,所以我们需要处理一下py代码。打开text文件夹下的symbols.py,注释掉japanese_cleaners2,去掉chinese_cleaners的注释。
接下来打开cleaners.py,注释掉与中文cleaner无关的import。
然后进行预处理,回到项目目录,打开preprocess.py,修改第9行的路径并将第十行的english_cleaners2改为chinese_cleaners,这样预处理默认就是中文cleaner了。

python preprocess.py --text_index 1

​ 跑完预处理就可以准备开始训练了,修改train.py,原train.py代码并不适合Windows跑(Linux请跳过此步),开跑会直接报nccl错,所以我们需要修改,将67行的nccl改为gloo。然后开始训练。

python train.py -c 存放config.json的目录\config.json -m 自定义模型名  

​ 如报错RuntimeError: Expected to have finished reduction in the prior iteration before starting a new one. This error indicates that your module has parameters that were not used in producing loss.,打开train.py,将104和105行模型的参数后加上find_unused_parameters=True

​ 如果正常saving保存pth文件以及Epoch迭代,那么就是在进行正常训练。Epoch后面的数字为迭代数。pth模型文件保存在项目文件夹上一级目录drive中的MyDrive文件夹中。自动保存会仅保留当前最新两次进度,所以不用担心占用过大空间。

​ 在模型训练好后,既可以开始TTS推理了,这里以MoeGoe为例,下载最新版的MoeGoe.7z解压到任意目录,接着下载GUI启动器放到MoeGoe同目录。然后打开MoeGoe_GUI.exe,打开文件选择MoeGoe解压目录中的MoeGoe.exe,打开模型选择前文中的pth模型文件(仅需要打开开头为G的)。打开配置选择模型同目录的config.json即可。然后再语音合成中输入要合成音频的文本,参数设置可调节语速,选择说话人,选择保存路径就会自动开始TTS推理了

在OriginBot上实现语音

连接语音扩展板及免驱声卡,OriginBot安装aplay

sudo apt-get install alsa-utils sox
#可以使用如下指令调节音量,进入调节界面后按F6选择需要调节的设备,上下箭头来调节音量
alsamixer
#举一个播放wav语音的例子
aplay -D plughw:0,0 trash.wav

此时就可以播放语音了。