IMS Toucan是一款用于教授、训练和使用最先进的语音合成模型的工具包,由**德国斯图加特大学自然语言处理研究所(IMS)**开发。所有内容都基于纯Python和PyTorch,以尽可能简单和适合初学者,但又尽可能强大。
链接 🦚
预生成音频
互动演示
您还可以在Huggingface上设计一个不存在的说话者的声音🤗
数据集
我们还在Huggingface上发布了一套大规模多语言TTS数据集🤗
安装 🦉
这些说明应可用于大多数情况,但我听说有些例子中espeak行为异常,有时重新安装可以解决,有时则不然。此外,M1和M2 MacBook需要非常不同的安装流程,我对此不太熟悉。
基本要求
建议使用Python 3.10版本。
要安装此工具包,将其克隆到您要使用的机器上(如果打算在该机器上训练模型,则至少应有一个支持cuda的GPU。用于推理时,不需要GPU)。
如果您使用Linux,您应该安装以下软件包,或者如果尚未安装,可以使用apt-get来安装(在大多数发行版中,它们已预安装):
libsndfile1
espeak-ng
ffmpeg
libasound-dev
libportaudio2
libsqlite3-dev
导航到已克隆的目录。我们建议创建并激活一个虚拟环境以安装基本要求。以下命令总结了在Linux下需要做的所有事情。如果您使用的是Windows,请查看venv文档以更改第二行。
python -m venv <path_to_where_you_want_your_env_to_be>
source <path_to_where_you_want_your_env_to_be>/bin/activate
pip install --no-cache-dir -r requirements.txt
每次重新使用该工具时,运行第二行以再次激活虚拟环境,例如在您期间注销后。要使用GPU,只需在Linux机器上不需要做任何其他操作。在Windows机器上,请查看官方PyTorch网站上的启用GPU支持的安装命令。
存储配置
如果您不希望预训练和训练的模型以及预处理数据集时生成的缓存文件存储在默认的子文件夹中,您可以通过编辑Utility/storage_config.py
来全局设置相应的目录(路径可以是相对于库根目录的相对路径或绝对路径)。
预训练模型
您不需要使用预训练模型,但它可以极大地加快进度。运行run_model_downloader.py
脚本以自动从发布页面下载它们,并将它们放置在适当的位置并命名。
[可选] eSpeak-NG
eSpeak-NG是一个可选要求,它在许多语言中处理许多特殊情况,因此最好有它。
在大多数Linux环境中,它将已安装,如果未安装且您有足够的权限,可以简单地运行以下命令来安装它:
apt-get install espeak-ng
对于Windows,他们在GitHub发布页面上提供了一个方便的.msi安装文件。安装后,在非linux系统上,您还需要通过设置环境变量PHONEMIZER_ESPEAK_LIBRARY
来告诉phonemizer库您的espeak安装位置,具体内容请参见此问题。
对于Mac,安装过程可复杂得多。感谢Sang Hyun Park,这里提供了一份在Mac上安装eSpeak-NG的指南: 对于M1 Macs,最方便的方法是通过MacPorts的espeak-ng端口来安装您的系统。MacPorts本身可以从MacPorts网站安装,它还需要Apple的XCode。安装XCode和MacPorts后,可以通过以下命令安装espeak-ng端口:
sudo port install espeak-ng
如Windows安装说明所述,espeak-ng安装需要设置一个变量给phonemizer库。该环境变量是PHONEMIZER_ESPEAK_LIBRARY
,如上面链接的GitHub线程中所述。然而,Mac上需要设置的安装文件是.dylib文件,而不是.dll文件。要找到espeak-ng库文件,可以运行port contents espeak-ng
。需要的特定文件名为libespeak-ng.dylib
。
推理 🦢
您可以使用InferenceInterfaces/ToucanTTSInterface.py
加载您训练好的模型或预训练模型。只需用正确的目录句柄创建一个对象来标识您要使用的模型。其余部分将在后台自动完成。您可能需要使用set_language和set_speaker_embedding函数设置语言嵌入或说话者嵌入。大多数内容应该是自解释的。
一个InferenceInterface包含创建音频的方法。它们是read_to_file和read_aloud。
-
read_to_file接收一个字符串列表和一个文件名作为输入。它将合成列表中的句子并在中间加上短暂停顿,并将其写入您提供的文件路径。
-
read_aloud只接收一个字符串,将其转换为语音并立即使用系统的扬声器播放。如果您设置了可选参数view为True,则会弹出一个可视化窗口,您需要关闭它以继续程序。
其使用例子见run_interactive_demo.py和run_text_to_file_reader.py。
有一些简单的缩放参数可以控制时长、音高曲线的变化和能量曲线的变化。您可以在使用互动演示或阅读器时更改代码中的参数,或者在使用界面时直接传递参数。
创建新配方(训练管道) 🐣
在名为Utility的目录中,有一个名为path_to_transcript_dicts.py
的文件。在此文件中,您应该编写一个函数,该函数返回一个字典,字典中的键是数据集中每个音频文件的绝对路径,值是相应音频文件的文本转录内容。
然后进入目录TrainingInterfaces/Recipes。如果您只想在单个数据集上微调,复制finetuning_example_simple.py
文件;如果您想在多个数据集上(甚至多种语言上)微调,复制finetuning_example_multilingual.py
文件。我们将使用这个副本作为参考,只做必要的更改以使用新数据集。找到对prepare_tts_corpus函数的调用。用刚创建的path_to_transcript_dict替换使用的路径。然后将相应缓存目录的名称更改为与数据集匹配的名称。还要注意变量save_dir,这是用于保存检查点的默认值,您可以在以后通过命令行参数覆盖它,以便从检查点微调并因此保存到不同的目录。最后,将在数据集创建和训练循环函数调用中使用的lang参数更改为与您的数据匹配的ISO 639-3语言ID。
微调示例中传递给训练循环的参数是为了从预训练模型进行微调的情况。如果要从头开始训练,请参考具有ToucanTTS名称的其他管道,并查看其中使用的参数。
完成后,我们几乎完成了,现在只需要将其提供给顶层的run_training_pipeline.py
文件。在该文件中,导入您刚刚创建的管道的run函数,并赋予它一个有意义的名称。然后在pipeline_dict中,将导入的函数作为值,并使用一个合适的缩写作为键。
训练模型 🦜
一旦创建了配方,训练就非常简单了:
python run_training_pipeline.py <shorthand of the pipeline>
您可以提供以下任何参数,但不必(尽管进行训练时至少应该指定一个GPU ID)。
--gpu_id <ID of the GPU you wish to use, as displayed with nvidia-smi, default is cpu. If multiple GPUs are provided (comma separated), then distributed training will be used, but the script has to be started with torchrun.>
--resume_checkpoint <path to a checkpoint to load>
--resume (if this is present, the furthest checkpoint available will be loaded automatically)
--finetune (if this is present, the provided checkpoint will be fine-tuned on the data from this pipeline)
--model_save_dir <path to a directory where the checkpoints should be saved>
--wandb (if this is present, the logs will be synchronized to your weights&biases account, if you are logged in on the command line)
--wandb_resume_id <the id of the run you want to resume, if you are using weights&biases (you can find the id in the URL of the run)>
对于多GPU训练,您必须提供多个GPU id(用逗号分隔)并使用torchrun启动脚本。您还必须指定GPU的数量。这必须与您提供的ID数量匹配。注意:torchrun与nohup不兼容!使用tmux来保持脚本在注销shell后继续运行。
torchrun --standalone --nproc_per_node=4 --nnodes=1 run_training_pipeline.py <shorthand of the pipeline> --gpu_id "0,1,2,3"
每个epoch(或者某些步长计数之后),某些日志将写入控制台和Weights and Biases网站(如果您已登录并设置了标志)。如果出现cuda内存不足错误,您需要减少在运行的管道中调用training_loop的参数中给出的批量大小。尝试以小步骤减少批量大小,直到不再出现cuda内存不足错误为止。
在您指定的保存目录中将出现检查点文件和频谱图可视化数据。由于检查点文件非常大,仅保留最近的五个。训练步骤的数量高度依赖于您使用的数据,以及您是从预训练检查点进行微调还是从头开始训练。数据越少,需要的步骤越少,以防止可能的崩溃。如果您想提前停止,只需终止进程,因为所有子进程都是守护进程,所有子进程应随之终止。如果有一些残留进程,可以使用以下命令找到并手动终止它们。
fuser -v /dev/nvidia*
每次保存检查点时,还会创建一个可用于推理的压缩版本,它命名为_best.py_
常见问题 🐓
以下是用户提出的一些问题:
- 如何判断我的数据是否有异常值或类似问题?-- 有一个评分器可以查找甚至移除数据集中损失值异常高的样本,查看
run_scorer.py
。 - 我的错误消息显示 GPU0,虽然我指定了一个不同的 GPU -- GPU选择的工作方式是指定的GPU被设置为唯一可见的设备,以避免后台进程意外运行在不同的GPU上。所以程序内部会命名设备为GPU0,因为它是唯一可见的GPU。实际上它正在运行你指定的GPU。
- read_to_file 产生奇怪的输出 -- 检查一下你是否传递了一个列表或字符串给这个方法。由于字符串是可以迭代的,它可能不会抛出错误,但预计应该传递的是一个字符串列表。
UserWarning: Detected call of lr_scheduler.step() before optimizer.step().
-- 我们使用了一个自定义的调度器,而Torch错误地认为我们调用调度器和优化器的顺序是错的。只需忽略这个警告,它完全没有意义。WARNING[XFORMERS]: xFormers can't load C++/CUDA extensions. [...]
-- 另一个无意义的警告。我们实际上并不使用xFormers,它只是我们某个依赖项的依赖项的一部分,但没有在任何地方使用。The torchaudio backend is switched to 'soundfile'. Note that 'sox_io' is not supported on Windows. [...]
-- 只发生在Windows下,不影响任何功能。WARNING:phonemizer:words count mismatch on 200.0% of the lines (2/1) [...]
-- 我们不知道为什么espeak开始给出这个警告,但它似乎不影响任何功能,所以看起来可以忽略。- 损失变成
NaN
-- 默认的学习率适用于干净的数据。如果你的数据不太干净,可以使用评分器查找有问题的样本,或降低学习率。最常见的问题是语音中有停顿,但文本中没有任何提示。这就是为什么ASR语料库通常很难用于TTS,它们省略了标点符号。
免责声明 🦆
FastSpeech 2和GST的基本PyTorch模块取自 ESPnet,HiFi-GAN的PyTorch模块取自ParallelWaveGAN仓库。 MatchaTTS中概述的基于ConditionalFlowMatching的PostNet相关的部分模块取自官方MatchaTTS代码库以及StableTTS代码库。 对于字素到音素的转换,我们依赖上述的eSpeak-NG以及transphone。 我们使用encodec,一个神经网络音频编解码器作为中间表示,以节省训练数据的空间。
引用 🐧
如果你发现这个仓库有用,考虑给它一个star。大量star会让我开心,也很有激励作用 :)
工具包介绍 [相关代码和模型]
@inproceedings{lux2021toucan,
year = 2021,
title = {{The IMS Toucan system for the Blizzard Challenge 2021}},
author = {Florian Lux and Julia Koch and Antje Schweitzer and Ngoc Thang Vu},
booktitle = {Blizzard Challenge Workshop},
publisher = {ISCA Speech Synthesis SIG}
}
添加发音特征和元学习预训练[相关代码和模型]
@inproceedings{lux2022laml,
year = 2022,
title = {{Language-Agnostic Meta-Learning for Low-Resource Text-to-Speech with Articulatory Features}},
author = {Florian Lux and Ngoc Thang Vu},
booktitle = {ACL}
}
添加精确的韵律克隆能力[相关代码和模型]
@inproceedings{lux2022cloning,
year = 2022,
title = {{Exact Prosody Cloning in Zero-Shot Multispeaker Text-to-Speech}},
author = {Lux, Florian and Koch, Julia and Vu, Ngoc Thang},
booktitle = {SLT},
publisher = {IEEE}
}
添加语言嵌入和词语边界[相关代码和模型]
@inproceedings{lux2022lrms,
year = 2022,
title = {{Low-Resource Multilingual and Zero-Shot Multispeaker TTS}},
author = {Florian Lux and Julia Koch and Ngoc Thang Vu},
booktitle = {AACL}
}
添加可控的发音人嵌入生成[相关代码和模型]
@inproceedings{lux2023controllable,
year = 2023,
title = {{Low-Resource Multilingual and Zero-Shot Multispeaker TTS}},
author = {Florian Lux and Pascal Tilli and Sarina Meyer and Ngoc Thang Vu},
booktitle = {Interspeech}
publisher = {ISCA}
}
我们对Blizzard Challenge 2023的贡献[相关代码和模型]
@inproceedings{lux2023controllable,
year = 2023,
title = {{The IMS Toucan System for the Blizzard Challenge 2023}},
author = {Florian Lux and Julia Koch and Sarina Meyer and Thomas Bott and Nadja Schauffler and Pavel Denisov and Antje Schweitzer and Ngoc Thang Vu},
booktitle = {Blizzard Challenge Workshop},
publisher = {ISCA Speech Synthesis SIG}
}
推出首个覆盖7000多种语言的TTS系统[相关代码和模型]
@inproceedings{lux2024massive,
year = 2024,
title = {{Meta Learning Text-to-Speech Synthesis in over 7000 Languages}},
author = {Florian Lux and Sarina Meyer and Lyonel Behringer and Frank Zalkow and Phat Do and Matt Coler and Emanuël A. P. Habets and Ngoc Thang Vu},
booktitle = {Interspeech}
publisher = {ISCA}
}