注:作者居住在韩国,部分内容包含韩国特有的背景。

这是 hayakoe 系列的第一篇正文。前言性质的文章可以在 hayakoe — 打造好用又快的 TTS 库 — 引言 查看。

引言中简单提到的一个话题是「重新选择了模型」。Part 1 我想把这个过程讲得更详细一些。

大致可以分成三个阶段:

  1. 浏览其他库候选,最终又回到 SBV2 的过程
  2. 数据集构建(这两年环境改善了不少)
  3. 训练设置和检查点评估

1. 也看看其他库

2年前写 用 Bert-VITS2 制作自己的 TTS 时,日语 TTS 库的选择基本只有 Bert-VITS2 一个候选。但2年过去,语音合成领域已经发展了不少。

反正都要花时间动手,那就把其他候选也看一下比较合理,于是我评估了两个号称韩语支持不错的候选。

GPT-SoVITS

最先看的是 GPT-SoVITS。它支持韩语 / 英语 / 日语,而且只需要往预训练模型里输入几秒钟的短音频样本,就能用那个音色生成发话——零样本推理这一点很有吸引力。

我先在没有训练的情况下用零样本试了试,结果在两个方面都不太满意:

  • 发话自然度不够。 合成出来的音色比较平淡,情感 / 语调的衔接不够流畅。
  • 韩语发话不自然。 把日语说话人的样本拿来发韩语,结果是「勉强能说」,但很难说自然。感觉像是日本人勉强读着韩文..?

零样本时已经不满意的音质,再训练一次也不太可能有质的飞跃。反正我想做的本来就是日语而不是韩语发话,所以判断再多看几个候选更划算,没有继续训练就转向了下一个。

Qwen-TTS / 自回归系列

引言里也简单提过,自回归系列的 Qwen-TTS 也是候选之一。不过这个在音质验证之前,单是计算量本身就太大、难以实时使用,这是它一次性出局的原因(详情请参考 引言 )。

音质方面也不算特别满意。可能因为是零样本,想要的细节出不来。大致是御宅的话就懂吧?

最终还是 Style-Bert-VITS2

把候选都看了一圈之后,最终还是回到了音质和速度平衡最好的 Style-Bert-VITS2 (JP-Extra v2.7.0)。SBV2 是 Bert-VITS2 的后继版本,2年前我已经走过一遍类似的训练 / 使用流程,这一点也很重要。

2. 数据集构建 — 这两年环境改善了不少

数据集方面,我手头有自己之前积累的语音数据集,直接拿来用了。2年前写过类似工作的文章,所以大致流程比较熟悉。经过资料整理和质量验证,最终收集到约 1,500 个样本。

不过这两年语音处理工具的环境进化了不少。最让我印象深刻的是,像人声分离(UVR — Ultimate Vocal Remover)这类工具,已经不需要再单独安装一个 GUI 程序了。

2年前这件事还挺麻烦的。UVR 是 Windows 应用,所以得直接安装它,然后还要在应用里点「下载模型」按钮单独获取模型文件,之后才能跑文件夹级别的批处理。现在用 audio-separator 这类库,就能从 HuggingFace 拿模型,用一行 Python 代码跑起来。

python
from audio_separator.separator import Separator

separator = Separator()
separator.load_model("model_bs_roformer_ep_317_sdr_12.9755.ckpt")
separator.separate("input.wav")

这看起来可能是个小差别,但当你要处理 1,500 个样本时,省掉 GUI 点击 / 文件夹管理 / 进度确认这些杂活,差距会非常明显。更重要的是,可以把这一步直接整合进训练流水线,往后添加新数据时再跑一次同样的代码就行了。

3. Style-Bert-VITS2 的训练

训练本身就直接用了 SBV2 自带的 webui。

  • 采样率: 44.1 kHz
  • batch_size: 2 (RTX 3080 / 10GB VRAM 基准)
  • learning rate: 1e-4
  • eval_interval: 5,000 step
  • 目标 epoch: 500(实际跑到约 88 epoch 时就停了)
  • 训练数据: 约 1,500 个样本

其实没必要全部跑满 500 epoch。过了一定 step 之后,音质就不再提升,或者反而开始出现过拟合迹象,所以在合适的时候停下来,进入了评估阶段。

4. 检查点评估 — 我直接全都听了一遍

要最准确地判断每个检查点的音质变化,最终方法就是直接听。SBV2 在训练中也会把 mel reconstruction loss、KL divergence、duration loss、generator / discriminator loss、WavLM adversarial loss 这些 loss 输出到 tensorboard。但这些数值变低,跟音色听起来自然是另一回事。最终最重要的还是我自己耳朵听起来自然不自然。

反正是自己用的模型,评估方法就走简单路线。

  • 从 5,000 step 到 50,000 step,每 5,000 step 抽一个,共抽 10 个检查点
  • 准备 短 / 中 / 长 三段文本,每个检查点都合成一遍
  • 把得到的 30 个样本整理成 HTML matrix,在一页上对比试听
              short    medium    long
ckpt 5k       ▶ wav    ▶ wav     ▶ wav
ckpt 10k      ▶ wav    ▶ wav     ▶ wav
ckpt 15k      ▶ wav    ▶ wav     ▶ wav
ckpt 20k      ▶ wav    ▶ wav     ▶ wav
...
ckpt 50k      ▶ wav    ▶ wav     ▶ wav

每个单元格里是合成的 wav 文件,可以横向比较同一段文本,纵向比较不同 step 的音色。合成花了一些时间,但评估本身就是戴着耳机依次听完,是个机械的工作。

直接全部听完之后,15,000 step(约 epoch 34) 的音质最自然。再往后的 step 音色会出现微妙变化,或者发话音调变得单调,所以这一步就是 sweet spot。

这只是我个人耳朵的判断。其他人来评估可能更喜欢另一个 step,文本不同结果也会有些差异。但反正是自己一个人用的模型,这样就够了。

Part 1 总结

Part 1 整理了在看完其他模型候选之后,最终又回到 Style-Bert-VITS2 (JP-Extra v2.7.0) 的理由,以及在此基础上数据集 / 训练 / 检查点评估是怎么进行的。

简而言之 — 其他候选(GPT-SoVITS、Qwen-TTS 等)要么零样本音质上达不到想要的细节,要么计算量太大无法实时,最终落到了 音质 / 速度 / 熟悉度的平衡 最好的 SBV2。

不过,直接用训练好的 SBV2 模型,仍然有 RAM 5GB、CPU 推理 1.09× 这些限制。下一篇会讲我是怎么把这部分压下来的。

Part 2 — 内存减半,速度提到 1.5 倍的故事 继续。