经过大量研究和实验,我可以分享我的经验来回答我自己的问题。
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 .
这在我的主文件夹中创建了一个名为 ~/mozilla-tts 的文件夹,其中包含 Mozilla TTS 代码。该文件夹设置为虚拟环境,这意味着只要我通过~/mozilla-tts/bin/python 执行python 命令并通过~/mozilla-tts/bin/pip 执行PIP,Python 将仅使用该虚拟环境中存在的包。这消除了在运行pip 时需要 root 权限(因为我们不影响系统范围的包),并且它确保没有包冲突。得分!
训练模型的先决条件
为了在训练模型时获得最佳结果,您需要:
- 简短的录音(至少 100 个),它们是:
- 16 位单声道 PCM WAV 格式。
- 在 1 到 10 秒之间。
- 采样率为 22050 Hz。
- 尽量减少背景噪音和失真。
- 在开头、中间和结尾都没有长时间的停顿。
-
metadata.csv 文件引用每个 WAV 文件并指示 WAV 文件中所说的文本。
- 为您的数据集和所选声码器(例如 Tacotron、WavGrad 等)量身定制的配置文件。
- 具有快速 CPU 的机器(理想情况下是支持 CUDA 和至少 12 GB GPU RAM 的 nVidia GPU;如果 GPU RAM 少于 8 GB,则无法有效使用 CUDA)。
- 大量 RAM(最好至少 16 GB RAM)。
准备音频文件
如果您的音频源格式与 WAV 格式不同,您需要使用 Audacity 或 SoX 等程序将文件转换为 WAV 格式。您还应该剪掉一些音频部分,这些声音只是噪音、嗯、啊,以及来自扬声器的其他声音,这些声音并不是您正在训练的单词。
如果您的音频源不完美(即有一些背景噪音)、格式不同,或者恰好是更高的采样率或不同的分辨率(例如 24 位、32 位等) ,您可以执行一些清理和转换。这是一个基于来自 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,脚本会自动将转换后的结果放到@987654345 @。
准备元数据
Mozilla TTS 支持多种不同的数据加载器,但最常见的一种是 LJSpeech。要使用它,我们可以组织我们的数据集以遵循 LJSpeech 约定。
首先,组织你的文件,使你有这样的结构:
- metadata.csv
- wavs/
- audio1.wav
- audio2.wav
...
- last_audio.wav
音频文件的命名似乎并不重要。但是,文件必须位于名为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
请注意:
- 没有标题行。
- 这些列通过管道符号 (|) 连接在一起。
- 每个 WAV 文件应该有一行。
- WAV 文件名在第一列,没有
wavs/ 文件夹前缀,也没有.wav 后缀。
- WAV 中所说内容的文字描述写在第二列中,所有数字和缩写都拼写出来。
(我确实观察到 Mozilla TTS 文档中的步骤让您将元数据文件打乱,然后将其拆分为“训练”集(metadata_train.csv)和“验证”集(metadata_val.csv),但没有repo 中提供的示例配置实际上配置为使用这些文件。我已经提交了an issue,因为它对初学者来说是令人困惑/违反直觉的。)
准备config.json 文件
您需要准备一个配置文件,描述如何配置您的自定义 TTS。在准备训练、执行训练和从您的自定义 TTS 生成音频时,Mozilla TTS 的多个部分都使用此文件。不幸的是,虽然这个文件非常重要,但 Mozilla TTS 的文档在很大程度上掩盖了如何自定义这个文件。
首先,从 Mozilla 存储库创建 the default Tacotron config.json file 的副本。然后,请务必至少自定义 audio.stats_path、output_path、phoneme_cache_path 和 datasets.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,但它会运行得更慢。