Coqui TTS 新手入门指南:从零训练 GlowTTS、HiFi-GAN 并合成语音
【免费下载链接】TTS🐸💬 - a deep learning toolkit for Text-to-Speech, battle-tested in research and production项目地址: https://gitcode.com/GitHub_Trending/tt/TTS
本指南面向首次接触 Coqui TTS 开源项目的新手,完整梳理"环境安装 → 下载数据 → 训练 TTS 模型 → 训练 Vocoder → 终端合成/网页试听"的端到端流程,并对照当前仓库的源码(recipes 下的训练脚本、TTS/bin 下的 CLI 入口)逐行讲解每个环节的配置含义与运行方式。读完本文,你将能独立跑通 LJSpeech 数据集上的 GlowTTS(声学模型)与 HiFi-GAN(声码器)训练,并掌握tts与tts-server两条语音合成使用路径。
本文是对仓库文档 docs/source/tutorial_for_nervous_beginners.md 的完整展开与源码级补充。
一、环境安装:两种模式任选其一
Coqui TTS 提供了两种安装方式,适用于不同角色。
面向纯使用场景(推荐仅用于语音合成):直接安装 PyPI 发布包即可,命令会在环境中注册tts与tts-server两个可执行入口:
$ pip install TTS面向开发者场景(需要改代码、跑训练实验):建议从源码克隆并以可编辑模式安装,这样你对源码的改动会即时生效:
$ git clone https://github.com/coqui-ai/TTS $ cd TTS $ pip install -e .从 setup.py 可以看出,该项目要求 Python 版本满足>= 3.9, < 3.12,安装前请确认解释器版本符合要求。另外该安装包还会借助 Cython 编译 TTS/tts/utils/monotonic_align/core.pyx 扩展模块,这是 GlowTTS 等模型做单调对齐时用到的核心算子,首次安装时会自动构建。
两个命令行入口也是在 setup.py 中通过console_scripts声明的:
tts→TTS.bin.synthesize:maintts-server→TTS.server.server:main
也就是说,只要安装成功,tts和tts-server就属于可直接调用的终端命令。
二、训练一个 TTS 模型(以 GlowTTS + LJSpeech 为例)
TTS 模型负责把文本转成中间声学表征(通常是梅尔频谱)。下面以 GlowTTS 在 LJSpeech 数据集上的训练为例,拆解训练脚本的每个组成部分。
2.1 数据集准备
LJSpeech 是单说话人英文语音数据集,仓库在 TTS/utils/downloaders.py 中提供了官方下载助手:它会从数据源下载LJSpeech-1.1.tar.bz2并自动解压到目标目录。
$ python -c 'from TTS.utils.downloaders import download_ljspeech; download_ljspeech("../recipes/ljspeech/");'上面的"../recipes/ljspeech/"是下载目录参数,按你的偏好改即可。解压后数据集结构应包含metadata.csv(文本-音频清单)与wavs/(音频目录),这正是后续训练脚本与 config 所引用的路径结构。
2.2 纯 Python 方式:编写 train.py
与很多"配置驱动"的训练框架不同,Coqui TTS 的训练脚本本身就是一段可读的 Python 代码,通过具名对象完成装配。完整脚本见 recipes/ljspeech/glow_tts/train_glowtts.py,下面按逻辑分段讲解。
1) 定义数据集配置:使用BaseDatasetConfig描述数据集的 formatter、清单文件名与所在路径。
dataset_config = BaseDatasetConfig( formatter="ljspeech", meta_file_train="metadata.csv", path=os.path.join(output_path, "../LJSpeech-1.1/") )formatter:告诉数据加载器用哪个解析器去读数据集元数据(ljspeech 格式解析见 TTS/tts/datasets/formatters.py);meta_file_train:训练清单文件名,对应下载数据里的metadata.csv;path:数据集根目录,脚本里用os.path.join(output_path, "../LJSpeech-1.1/")表示"与训练脚本同级的 LJSpeech-1.1 目录"。
2) 初始化训练配置:GlowTTSConfig继承了所有模型共用的BaseTTSConfig(见 TTS/tts/configs/shared_configs.py),配置了训练循环、文本前端与数据集:
config = GlowTTSConfig( batch_size=32, eval_batch_size=16, num_loader_workers=4, num_eval_loader_workers=4, run_eval=True, test_delay_epochs=-1, epochs=1000, text_cleaner="phoneme_cleaners", use_phonemes=True, phoneme_language="en-us", phoneme_cache_path=os.path.join(output_path, "phoneme_cache"), print_step=25, print_eval=False, mixed_precision=True, output_path=output_path, datasets=[dataset_config], )关键参数的含义如下:
| 参数 | 作用 | 参考值/说明 |
|---|---|---|
batch_size/eval_batch_size | 训练/验证批大小 | 32 / 16,根据显存调整 |
num_loader_workers/num_eval_loader_workers | 训练/验证数据加载子进程数 | 4 |
run_eval | 训练过程中是否周期性跑验证 | True |
test_delay_epochs | 延迟多少个 epoch 才开始验证 | -1表示一上来就验证 |
epochs | 最大训练轮数 | GlowTTS 训练常配置为 1000,配合早停实际收敛远早于此 |
text_cleaner | 文本清洗器 | 教程示例脚本为phoneme_cleaners(CLI JSON 示例用的是english_cleaners,二者对应不同的文本前端策略,见下文说明) |
use_phonemes | 是否使用音素而非字符序列 | True |
phoneme_language | 音素化所用语言 | "en-us" |
phoneme_cache_path | 音素缓存目录,避免重复音素化 | 建议放脚本同级的phoneme_cache |
print_step | 每多少步打印一次训练日志 | 25 |
print_eval | 是否打印验证结果 | False |
mixed_precision | 是否开启混合精度训练以省显存 | 本脚本开为True |
output_path | 实验产物(checkpoint、TensorBoard 日志等)输出目录 | 本脚本为当前目录 |
datasets | 数据集配置列表(支持多数据集) | [dataset_config] |
此外GlowTTSConfig本身还封装了大量模型结构超参,例如编码器类型encoder_type(默认rel_pos_transformers)、解码器隐藏通道数hidden_channels_dec、时长预测器通道hidden_channels_dp、推理噪声尺度inference_noise_scale等,完整字段定义可查阅 TTS/tts/configs/glow_tts_config.py。
3) 初始化音频处理器与分词器:
ap = AudioProcessor.init_from_config(config) tokenizer, config = TTSTokenizer.init_from_config(config)AudioProcessor负责音频读写与特征提取(梅尔频谱等),其参数从 config 内嵌的音频配置读取,实现位于 TTS/utils/audio/processor.py;TTSTokenizer把文本转成 token ID 序列;当 config 未显式给出字符表时,init_from_config会把默认字符集写回 config。可参考 TTS/tts/utils/text/tokenizer.py。
4) 加载数据样本:
train_samples, eval_samples = load_tts_samples( dataset_config, eval_split=True, eval_split_max_size=config.eval_split_max_size, eval_split_size=config.eval_split_size, )每个样本是一个[text, audio_file_path, speaker_name]列表。load_tts_samples的实现位于 TTS/tts/datasets/init.py,它内部会调用注册表里formatter对应的解析函数,并在返回前完成训练/验证集的切分。
5) 初始化模型并交给 Trainer:
model = GlowTTS(config, ap, tokenizer, speaker_manager=None) trainer = Trainer( TrainerArgs(), config, output_path, model=model, train_samples=train_samples, eval_samples=eval_samples ) trainer.fit()speaker_manager用于多说话人模型;LJSpeech 是单说话人数据,传None;Trainer是 TTS 统一复用的训练器,来自外部trainer包,提供混合精度、分布式训练、checkpoint 与 TensorBoard 日志等能力。这里传入空TrainerArgs(),所有命令行参数走默认值。
6) 运行训练脚本:
$ CUDA_VISIBLE_DEVICES=0 python train.py除一次性启动外,Trainer内置三种常用断点续训/迁移场景:
# 从某个历史实验目录恢复训练(自动沿用其 config 与最新 checkpoint) $ CUDA_VISIBLE_DEVICES=0 python train.py --continue_path path/to/previous/run/folder/ # 从指定 checkpoint 恢复(常用于断点续训或微调) $ CUDA_VISIBLE_DEVICES=0 python train.py --restore_path path/to/model/checkpoint.pth # 多 GPU 分布式训练(trainer.distribute 会自动按每卡分配数据与同步梯度) $ CUDA_VISIBLE_DEVICES=0,1,2 python -m trainer.distribute --script train.py
--continue_path的语义差异在 TTS/bin/train_tts.py 中也有体现:该 CLI 若给定continue_path,会直接加载上一轮实验的config.json,从而实现无缝续训。
2.3 CLI 方式:config.json + train_tts.py
除了 Python 脚本,项目仍保留了"配置 JSON + 通用入口"的经典 CLI 训练方式。做法是先写一个config.json:
{ "run_name": "my_run", "model": "glow_tts", "batch_size": 32, "eval_batch_size": 16, "num_loader_workers": 4, "num_eval_loader_workers": 4, "run_eval": true, "test_delay_epochs": -1, "epochs": 1000, "text_cleaner": "english_cleaners", "use_phonemes": false, "phoneme_language": "en-us", "phoneme_cache_path": "phoneme_cache", "print_step": 25, "print_eval": true, "mixed_precision": false, "output_path": "recipes/ljspeech/glow_tts/", "datasets":[{"formatter": "ljspeech", "meta_file_train":"metadata.csv", "path": "recipes/ljspeech/LJSpeech-1.1/"}] }这份 JSON 与 2.2 节 Python 脚本配置是等价的(注意此例中text_cleaner为english_cleaners且use_phonemes=false,即以字符/grapheme 为建模单元;而 2.2 节官方脚本用phoneme_cleaners+use_phonemes=true,以音素为建模单元——两种文本前端都可行,选择会影响训练效果与推理时对文本规范化的要求)。随后执行:
$ CUDA_VISIBLE_DEVICES="0" python TTS/bin/train_tts.py --config_path config.json其运行逻辑在 TTS/bin/train_tts.py 中一目了然:解析命令行后通过load_config(args.config_path)载入 JSON,register_config/setup_model依据"model": "glow_tts"自动装配对应模型类,再load_tts_samples加载数据并用同一个Trainer启动trainer.fit()。这意味着"CLI 方式"与"纯 Python 方式"底层走的是完全相同的训练管线,只是配置载入方式不同。
仓库还针对各模型维护了多份 recipe 配置,例如 recipes/ljspeech/vits_tts、recipes/ljspeech/tacotron2-DDC 等,都可以用同样的config_path方式训练,作为换模型的参考。
三、训练一个 Vocoder 模型(以 HiFi-GAN 为例)
TTS 模型输出的是声学特征,真正转成可听波形需要声码器(vocoder)。以 HiFi-GAN 为例,训练脚本为 recipes/ljspeech/hifigan/train_hifigan.py,其装配流程与 GlowTTS 几乎一一对应,只是换成了生成对抗网络(GAN)的配置与模型:
config = HifiganConfig( batch_size=32, eval_batch_size=16, num_loader_workers=4, num_eval_loader_workers=4, run_eval=True, test_delay_epochs=5, epochs=1000, seq_len=8192, pad_short=2000, use_noise_augment=True, eval_split_size=10, print_step=25, print_eval=False, mixed_precision=False, lr_gen=1e-4, lr_disc=1e-4, data_path=os.path.join(output_path, "../LJSpeech-1.1/wavs/"), output_path=output_path, ) ap = AudioProcessor(**config.audio.to_dict()) eval_samples, train_samples = load_wav_data(config.data_path, config.eval_split_size) model = GAN(config, ap) trainer = Trainer( TrainerArgs(), config, output_path, model=model, train_samples=train_samples, eval_samples=eval_samples ) trainer.fit()与 TTS 模型训练的差异点:
| 差异 | 说明 |
|---|---|
| 训练样本来源 | 声码器只吃波形,因此用load_wav_data(见 TTS/vocoder/datasets/preprocess.py)直接按目录扫描 wav 文件,无需metadata.csv;eval_split_size=10表示从全量中抽出若干文件做验证 |
| 关键训练超参 | seq_len=8192为每个样本截取的采样点长度;pad_short=2000对过短音频补零;use_noise_augment是否对输入做噪声增强 |
| 双学习率 | GAN 的生成器与判别器分开配置学习率lr_gen/lr_disc(均取 1e-4) |
| 模型与配置类 | HifiganConfig与GAN,定义见 TTS/vocoder/configs/hifigan_config.py 与 TTS/vocoder/models/gan.py |
启动方式与 TTS 模型一致:python train_hifigan.py(支持--continue_path/--restore_path/ 多卡)。
需要补充说明的是,仓库在声码器侧也保留了通用 CLI 入口:既然 TTS 模型可经 TTS/bin/train_tts.py 训练,声码器同样可以用 TTS/bin/train_vocoder.py 配合
config.json走 CLI 训练,两种训练对象在该 bin 层已被统一封装。
四、合成语音:tts 终端命令
完成(或直接使用预训练)模型后,即可在终端直接合成语音。安装时注册的tts命令是最快的上手路径:
$ tts -h # 查看所有命令行参数 $ tts --list_models # 列出可用的预训练 TTS 模型与声码器tts的实现入口对应 TTS/bin/synthesize.py(即setup.py中tts命令指向的TTS.bin.synthesize:main)。配合--list_models返回的模型名,可把--model_name/--vocoder_name指到具体的预训练权重;输入文本、输出音频路径等均通过参数指定。若未单独指定声码器,合成器会自动选用与 TTS 模型匹配的默认声码器;完整合成管线(含 mel → 波形的级联)由 TTS/utils/synthesizer.py 提供。
该 GIF 展示了tts命令在终端完成文本输入与语音生成的完整过程。仓库自带的端到端测试 tests/inference_tests/test_synthesize.py 也覆盖了"文本 → 波形"的合成链路,可作为命令行用法的自动化对照。
五、合成语音:tts-server 网页演示
若想用浏览器图形界面快速试听各模型,可启动本地演示服务器:
$ tts-server -h # 查看帮助 $ tts-server --list_models # 列出可选模型启动后按终端提示在浏览器打开本地地址,即可选模型、填文本、点"合成"并在线试听。tts-server的实现位于 TTS/server/server.py,其前端模板在 TTS/server/templates(含 index.html 与 results 详情页),这些模板会随 pip 包一并安装(见 setup.py 的package_data)。仓库另有 tests/bash_tests/test_demo_server.sh 用于自动化校验服务器能否正常启动与响应。
六、总结与下一步
把整条链路串起来看:download_ljspeech获取数据 →BaseDatasetConfig+GlowTTSConfig描述训练任务 →AudioProcessor/TTSTokenizer完成特征与文本预处理 →load_tts_samples切分数据 →GlowTTS模型训练得到"文本→梅尔"映射 →HiFi-GAN声码器把梅尔还原为波形 → 最终通过tts或tts-server对外提供合成服务。这四步覆盖了 Coqui TTS 从入门到实战的最短闭环。
若希望继续深入,建议按需查阅同一仓库的以下资料:
- 更系统的模型文档与 API 说明:docs/source/models/glow_tts.md、docs/source/main_classes/model_api.md;
- 数据集格式化规范:docs/source/formatting_your_dataset.md(决定
formatter如何编写)与 docs/source/tts_datasets.md; - 详细训练参数:以 GlowTTS 为例查看 TTS/tts/configs/glow_tts_config.py,公共参数见 TTS/config/init.py 中的
BaseTrainingConfig/BaseAudioConfig/BaseDatasetConfig; - 更多现成 recipe 与对应测试:多语言/多模型训练入口统一位于 recipes,可对照相应 recipe 目录下的
train_*.py使用。
【免费下载链接】TTS🐸💬 - a deep learning toolkit for Text-to-Speech, battle-tested in research and production项目地址: https://gitcode.com/GitHub_Trending/tt/TTS
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考