如何开始在 Ubuntu 20.04 上使用 Mozilla TTS 训练自定义语音模型?

How do I get started training a custom voice model with Mozilla TTS on Ubuntu 20.04?

我想使用我录制的音频样本在 Mozilla TTS 中创建自定义语音,但不确定如何开始。 Mozilla TTS 项目有文档和教程,但我无法将各个部分放在一起——似乎缺少一些基本信息,初学者需要知道这些信息才能开始。

我有一些问题:

  1. 我看到有一个用于 Mozilla TTS 的 Docker 图像,但它的文档涵盖了创建语音但没有提到训练。我可以使用 Docker 图像进行训练吗?
  2. 如果我不能使用 Docker 图像进行训练,我如何在我的系统上使用 Python 3 获得 Mozilla TTS 运行ning 的功能副本?我已尝试按照项目提供的命令进行操作,但出现依赖项错误、版本冲突或有关没有足够权限安装包的错误。
  3. 训练模型需要哪些信息?我需要什么音频格式?我看到我需要一个 metadata.csv 文件——我需要在该文件中放入什么?我在配置文件中自定义什么?
  4. 大多数配置都引用了一个 scale_stats.npy 文件——我该如何生成它?
  5. 如何运行训练?

经过大量的研究和实验,我可以分享我的经验来回答我自己的问题。

可以使用 Mozilla TTS Docker 图像进行训练吗(TL;DR:“否”)

Mozilla TTS docker 图像确实适合播放,似乎不适合用于训练。至少,即使在容器内 运行ning 一个 shell 时,我也无法进行培训。但是在找出导致 PIP 不愉快的原因之后,在 Ubuntu 中启动 Mozilla TTS 和 运行ning 的过程变得非常简单。

使用 Python 3、PIP 和虚拟环境安装 Mozilla TTS

Mozilla TTS 的文档没有提及任何关于虚拟环境的内容,但恕我直言,它确实应该提及。虚拟环境确保您机器上不同 Python-based 应用程序的依赖关系不会发生冲突。

我在 WSL 上 运行ning Ubuntu 20.04,所以 Python 3 已经安装。鉴于此,在我的 主文件夹 中,以下是我用来获取 Mozilla TTS 工作副本的命令:

sudo apt-get install espeak

git clone https://github.com/mozilla/TTS mozilla-tts
python3 -m venv mozilla-tts

cd mozilla-tts
./bin/pip install -e .

这在我的主文件夹中创建了一个名为 ~/mozilla-tts 的文件夹,其中包含 Mozilla TTS 代码。该文件夹设置为虚拟环境,这意味着只要我通过 ~/mozilla-tts/bin/python 执行 python 命令并通过 ~/mozilla-tts/bin/pip 执行 PIP,Python 将仅使用存在的包在那个虚拟环境中。这消除了在 运行ning pip 时成为 root 的需要(因为我们不影响 system-wide 包),并且它确保没有包冲突。得分!

训练模型的先决条件

为了在训练模型时获得最佳结果,您需要:

  1. 简短的录音(至少 100 个)是:
    • 16 位单声道 PCM WAV 格式。
    • 每次 1 到 10 秒。
    • 采样率为 22050 Hz。
    • 尽量减少背景噪音和失真。
    • 开头、中间和结尾都没有长时间的沉默。
  2. 一个 metadata.csv 文件,它引用每个 WAV 文件并指示 WAV 文件中说出的文本。
  3. 为您的数据集和所选声码器(例如 Tacotron、WavGrad 等)量身定制的配置文件。
  4. 具有快速 CPU 的机器(最好是具有 CUDA 支持的 nVidia GPU 和至少 12 GB 的 GPU RAM;如果您的 GPU RAM 少于 8 GB,则无法有效地使用 CUDA)。
  5. 大量 RAM(最好至少 16 GB RAM)。

正在准备音频文件

如果您的音频源格式不同于 WAV,您将需要使用 Audacity or SoX 之类的程序将文件转换为 WAV 格式。您还应该 trim 去除扬声器中的噪音、嗯、啊和其他声音,而不是您正在训练的真正单词。

如果您的音频源不完美(即有一些背景噪音)、格式不同、采样率更高或分辨率不同(例如 24 位、32 位等) .),你可以进行一些clean-up和转换。这是一个基于来自 Mozilla TTS Discourse 论坛的 earlier script 的脚本:

from pathlib import Path

import os
import subprocess
import soundfile as sf
import pyloudnorm as pyln
import sys

src = sys.argv[1]
rnn = "/PATH/TO/rnnoise_demo"

paths = Path(src).glob("**/*.wav")

for filepath in paths:
    target_filepath=Path(str(filepath).replace("original", "converted"))
    target_dir=os.path.dirname(target_filepath)

    if (str(filepath) == str(target_filepath)):
        raise ValueError("Source and target path are identical: " + str(target_filepath))

    print("From: " + str(filepath))
    print("To: " + str(target_filepath))

    # Stereo to Mono; upsample to 48000Hz
    subprocess.run(["sox", filepath, "48k.wav", "remix", "-", "rate", "48000"])
    subprocess.run(["sox", "48k.wav", "-c", "1", "-r", "48000", "-b", "16", "-e", "signed-integer", "-t", "raw", "temp.raw"]) # convert wav to raw
    subprocess.run([rnn, "temp.raw", "rnn.raw"]) # apply rnnoise
    subprocess.run(["sox", "-r", "48k", "-b", "16", "-e", "signed-integer", "rnn.raw", "-t", "wav", "rnn.wav"]) # convert raw back to wav

    subprocess.run(["mkdir", "-p", str(target_dir)])
    subprocess.run(["sox", "rnn.wav", str(target_filepath), "remix", "-", "highpass", "100", "lowpass", "7000", "rate", "22050"]) # apply high/low pass filter and change sr to 22050Hz

    data, rate = sf.read(target_filepath)

    # peak normalize audio to -1 dB
    peak_normalized_audio = pyln.normalize.peak(data, -1.0)

    # measure the loudness first
    meter = pyln.Meter(rate) # create BS.1770 meter
    loudness = meter.integrated_loudness(data)

    # loudness normalize audio to -25 dB LUFS
    loudness_normalized_audio = pyln.normalize.loudness(data, loudness, -25.0)

    sf.write(target_filepath, data=loudness_normalized_audio, samplerate=22050)

    print("")

要使用上面的脚本,您需要签出并构建 the RNNoise project:

sudo apt update
sudo apt-get install build-essential autoconf automake gdb git libffi-dev zlib1g-dev libssl-dev

git clone https://github.com/xiph/rnnoise.git
cd rnnoise
./autogen.sh
./configure
make

您还需要安装 SoX:

sudo apt install sox

并且,您需要通过 ./bin/pip 安装 pyloudnorm

然后,自定义脚本,让rnn指向rnnoise_demo命令的路径即可(构建RNNoise后,可以在examples文件夹中找到)。然后,运行 脚本,传递源路径——您拥有 WAV 文件的文件夹——作为第一个命令行参数。 确保“原创”一词出现在路径中的某处。脚本会自动将转换后的文件放在相应的路径下,将original改为converted; 例如,如果你的源路径是/path/to/files/original,脚本会自动将转换后的结果放入 /path/to/files/converted.

准备元数据

Mozilla TTS 支持多种不同的数据加载器,但最常见的一种是 LJSpeech。要使用它,我们可以组织我们的数据集以遵循 LJSpeech 约定。

首先,组织您的文件,使您拥有如下结构:

- metadata.csv
- wavs/
  - audio1.wav
  - audio2.wav
  ...
  - last_audio.wav

音频文件的命名似乎并不重要。但是,文件 必须 位于名为 wavs 的文件夹中。如果需要,您可以在 wavs 中使用 sub-folders。

metadata.csv 文件应采用以下格式:

audio1|line that's spoken in the first file
audio2|line that's spoken in the second file
last_audio|line that's spoken in the last file

注意:

  • 没有 header 行。
  • 列用竖线符号 (|) 连接在一起。
  • 每个 WAV 文件应该有一行。
  • WAV 文件名在第一列,没有 wavs/ 文件夹前缀,也没有 .wav 后缀。
  • 文字说明在 WAV 中所说的内容写在第二列中,所有数字和缩写 spelled-out.

(我确实观察到 Mozilla TTS 文档中的步骤让您随机播放元数据文件,然后将其拆分为“训练”集(metadata_train.csv)和“验证”集(metadata_val.csv),但是 repo 中提供的 none 示例配置实际上配置为使用这些文件。我已经提交了 an issue,因为它 confusing/counter-intuitive 适合初学者。)

正在准备 config.json 文件

您需要准备一个描述如何配置自定义 TTS 的配置文件。在准备训练、执行训练和从自定义 TTS 生成音频时,Mozilla TTS 的多个部分会使用此文件。不幸的是,虽然这个文件非常重要,但 Mozilla TTS 的文档在很大程度上掩盖了如何自定义这个文件。

首先,从 Mozilla 存储库创建 the default Tacotron config.json file 的副本。然后,请务必至少自定义 audio.stats_pathoutput_pathphoneme_cache_pathdatasets.path 文件。

如果您愿意,可以自定义其他参数,但默认值是一个很好的起点。例如,您可以更改 run_name 以控制包含数据集的文件夹的命名。

不要更改 datasets.name 参数(将其设置为“ljspeech”);否则你会得到与未定义数据集类型相关的奇怪错误。 数据集 name 似乎指的是所使用的 数据加载器 的类型,而不是你所谓的数据集。同样,我没有冒险更改 model 设置,因为我还不知道系统如何使用该值。

准备中scale_stats.npy

大多数训练配置依赖于一个名为 scale_stats.npy 的统计文件,该文件是根据训练集生成的。您可以使用 Mozilla TTS 存储库中的 ./TTS/bin/compute_statistics.py 脚本来生成此文件。此脚本需要您的 config.json 文件作为输入,这是一个很好的步骤,可以全面检查到目前为止一切看起来是否良好。

如果您在本教程开始时创建的 Mozilla TTS 文件夹中(调整路径以适合您的项目),您可以 运行 下面是一个命令示例:

./bin/python ./TTS/bin/compute_statistics.py --config_path /path/to/your/project/config.json --out_path /path/to/your/project/scale_stats.npy

如果成功,这将在/path/to/your/project/scale_stats.npy 下生成一个scale_stats.npy 文件。 确保 config.json 文件的 audio.stats_path 设置中的路径与此路径匹配。

训练模型

现在是关键时刻 -- 是时候开始训练您的模型了!

如果您在本教程开始时创建的 Mozilla TTS 文件夹中(调整路径以适合您的项目),下面是您可以 运行 训练 Tacotron 模型的命令示例:

./bin/python ./TTS/bin/train_tacotron.py --config_path /path/to/your/project/config.json

这个过程即使不是几天,也需要几个小时。如果您的机器支持 CUDA 并且配置正确,则该过程 运行 比您仅依靠 CPU 更快。

如果您收到与“信号错误”或“收到信号”相关的任何错误,这通常表示您的机器没有足够的内存来进行操作。你可以 run the training with less parallelism 但它会 运行 慢得多。