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

Guy*_*ock 3 audio text-to-speech sox mozilla-deepspeech

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

我有一些问题:

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

Guy*_*ock 9

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

Mozilla TTS Docker 镜像可以用于训练吗(TL;DR:“否”)

Mozilla TTS docker 镜像确实适合播放,似乎不适合用于训练。至少,即使在容器内运行 shell 时,我也无法进行培训。但是在弄清楚是什么导致 PIP 不满意之后,在 Ubuntu 中启动和运行 Mozilla TTS 的过程变得非常简单。

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

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

我在 WSL 上运行 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 .
Run Code Online (Sandbox Code Playgroud)

~/mozilla-tts在我的主文件夹中创建了一个文件夹,其中包含 Mozilla TTS 代码。该文件夹设置为虚拟环境,这意味着只要我执行 python 命令 via~/mozilla-tts/bin/python和 PIP via ~/mozilla-tts/bin/pip,Python 将只使用该虚拟环境中存在的包。这样就无需在运行时成为 root 用户pip(因为我们不会影响系统范围的包),并确保不会发生包冲突。分数!

训练模型的先决条件

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

  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 格式不同,则需要使用AudacitySoX等程序将文件转换为 WAV 格式。您还应该修剪掉来自扬声器的只是噪音、嗯、啊和其他声音的音频部分,这些声音并不是您正在训练的真正单词。

如果您的音频源不完美(即有一些背景噪音)、格式不同,或者恰好是更高的采样率或不同的分辨率(例如 24 位、32 位等),您可以执行一些清理和转换。这是一个基于Mozilla TTS Discourse 论坛早期脚本的脚本

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("")
Run Code Online (Sandbox Code Playgroud)

要使用上面的脚本,您需要检查并构建RNNoise 项目

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
Run Code Online (Sandbox Code Playgroud)

您还需要安装 SoX:

sudo apt install sox
Run Code Online (Sandbox Code Playgroud)

而且,您需要pyloudnorm通过./bin/pip.

然后,只需自定义脚本,使其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
Run Code Online (Sandbox Code Playgroud)

音频文件的命名似乎并不重要。但是,这些文件必须位于名为wavs. wavs如果需要,您可以在内部使用子文件夹。

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
Run Code Online (Sandbox Code Playgroud)

注意:

  • 没有标题行。
  • 这些列使用管道符号 (|) 连接在一起。
  • 每个 WAV 文件应该有一行。
  • WAV 文件名在第一列中,没有wavs/文件夹前缀,也没有.wav后缀。
  • WAV 中所说内容的文字描述写在第二列中,所有数字和缩写都拼写出来。

(我确实观察到 Mozilla TTS 文档中的步骤让您将元数据文件打乱,然后将其拆分为“训练”集(metadata_train.csv)和“验证”集(metadata_val.csv),但是回购中提供的示例配置都不是实际上配置为使用这些文件。我已经提交了一个关于这个的问题,因为它对初学者来说是令人困惑/违反直觉的。)

准备config.json文件

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

首先,从 Mozilla 存储库创建默认 Tacotronconfig.json文件的副本。然后,一定要定制至少audio.stats_pathoutput_pathphoneme_cache_path,和datasets.path文件。

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

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

准备 scale_stats.npy

大多数训练配置依赖于一个名为的统计文件scale_stats.npy,该文件是基于训练集生成的。您可以使用./TTS/bin/compute_statistics.pyMozilla TTS 存储库中的脚本来生成此文件。此脚本需要您的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
Run Code Online (Sandbox Code Playgroud)

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

训练模型

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

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

./bin/python ./TTS/bin/train_tacotron.py --config_path /path/to/your/project/config.json
Run Code Online (Sandbox Code Playgroud)

这个过程需要几个小时,甚至几天。如果您的机器支持 CUDA 并对其进行了正确配置,则该过程将比仅依靠 CPU 运行得更快。

如果您收到与“信号错误”或“接收到信号”相关的任何错误,这通常表明您的机器没有足够的内存来进行操作。您可以使用较少的并行度运行训练,但运行速度会慢得多。

  • @Bira 如果你正在做“迁移学习”(即构建像 LJSpeech 这样的现有模型),你可以获得 100,000 左右的 Epoch。如果你从头开始训练,你需要数千小时的音频,它可能采取500,000或更多。 (2认同)