- 人工智能
- 语音
- 音频
【免费下载链接】PaddleSpeech
Easy-to-use Speech Toolkit including Self-Supervised Learning model, SOTA/Streaming ASR with punctuation, Streaming TTS with text frontend, Speaker Verification System, End-to-End Speech Translation and Keyword Spotting. Won NAACL2022 Best Demo Award.
本文以 PaddleSpeech 仓库中 examples/csmsc/tts3_rhy 为例,系统讲解如何训练一个带韵律(rhythm)信息的 FastSpeech2 语音合成模型:从 CSMSC 数据集的准备、MFA 韵律时长对齐结果的获取,到数据预处理、模型训练、多声码器合成与端到端静态图推理的完整流程。读完本文,你将掌握 PaddleSpeech 中"节奏版 TTS"的完整落地路径,理解sp1~sp4韵律标签如何在音素序列中发挥作用,并能独立修改配置、选择声码器完成合成实验。
示例概览:什么是"节奏版" FastSpeech2
常规的 FastSpeech2 以音素序列 + 时长 + 基频 + 能量为条件生成梅尔谱,但音素本身不携带韵律停顿信息。tts3_rhy 在 FastSpeech2 基础上引入韵律标记(rhythm tags),用sp1/sp2/sp3/sp4等特殊音素表示不同层级的停顿/节奏边界,使合成语音的断句与节奏更接近真人朗读。
该示例位于 examples/csmsc/tts3_rhy,目录中包含:
- conf/default.yaml:训练与特征提取配置
- local/preprocess.sh:数据预处理脚本
- local/train.sh:模型训练脚本
- local/synthesize.sh:基于
metadata.jsonl的波形合成脚本 - local/synthesize_e2e.sh:端到端(文本 → 波形)合成脚本
- run.sh:一键执行入口
- path.sh:环境变量初始化
它与基础版 examples/csmsc/tts3/README.md(FastSpeech2 with CSMSC)共享绝大多数流程,核心差异在于:训练数据中多出一份带韵律标签的时长文件(durations.txt),且端到端合成时启用韵律前端。从源码结构看,韵律能力由 paddlespeech/t2s/frontend/rhy_prediction/rhy_predictor.py 中的RhyPredictor与 paddlespeech/t2s/frontend/zh_frontend.py 的use_rhy开关支撑(后文详述)。
数据集准备:CSMSC 与 MFA 韵律对齐结果
1. 下载并解压 CSMSC
从 CSMSC(Chinese Standard Mandarin Speech Corpus,中文标准普通话语音库)官方渠道下载数据集,解压到~/datasets目录,得到数据目录~/datasets/BZNSYP。后续所有脚本均以此路径为数据集根目录。
2. 获取 MFA 对齐结果(含韵律时长)
FastSpeech2 训练需要每个音素的**时长(duration)**标注,本示例通过蒙特利尔强制对齐工具 MFA(Montreal Forced Aligner)从文本与音频的强制对齐结果中导出。有两种途径:
途径一:直接下载韵律版对齐结果
下载仓库发布的baker_alignment_tone.zip(韵律版 MFA 对齐结果),解压后得到目录./baker_alignment_tone。README 中约定该目录即为后续预处理脚本的输入。
途径二:参照 mfa 示例自行训练
参考 examples/other/mfa/README.md 训练自己的 MFA 模型。需要注意:在run.sh的前两条命令中加上--rhy-with-duration标志,才能获得含韵律信息的时长结果。该标志的实现位于 examples/other/mfa/local/generate_lexicon.py 与 examples/other/mfa/local/reorganize_baker.py,后者在rhy_dur=True时读取ProsodyLabeling/000001-010000_rhy.txt韵律标注文件,并通过insert_rhy/normalize_rhy把韵律边界以sp前缀音素的形式插入文本。
目前--rhy-with-duration仅支持 CSMSC 数据集;在 MFA 的韵律标签中,#被替换为sp(即sp1~sp4等节奏音素),以便与 MFA 音素集对齐。
一键运行 run.sh 与阶段控制
假设数据集路径为~/datasets/BZNSYP,MFA 结果为./baker_alignment_tone,运行:
./run.shrun.sh(examples/csmsc/tts3_rhy/run.sh)会依次执行:
- source path:通过
source path.sh初始化环境; - 预处理数据集:生成
dump目录; - 训练模型:产出
exp/default/checkpoints/下的 ckpt; - 合成 wav:既可从
metadata.jsonl合成,也可从文本文件端到端合成; - 静态图模型推理:通过
synthesize_e2e.sh导出并使用静态图模型。
run.sh 中的默认参数与 4 个 stage 的对应关系:
| 变量/Stage | 默认值 | 作用 |
|---|---|---|
gpus | 0,1 | 训练/合成使用的 GPU 编号 |
stage/stop_stage | 0/100 | 阶段范围控制 |
conf_path | conf/default.yaml | 配置文件 |
train_output_path | exp/default | 实验输出目录 |
ckpt_name | snapshot_iter_153.pdz | 合成使用的模型参数文件 |
| stage 0 | — | ./local/preprocess.sh ${conf_path}预处理 |
| stage 1 | — | ./local/train.sh ${conf_path} ${train_output_path}训练 |
| stage 2 | — | ./local/synthesize.sh合成(声码器默认 pwgan,编号 0) |
| stage 3 | — | ./local/synthesize_e2e.sh端到端合成(编号 0/1/3/4) |
如需只运行某一阶段,可显式指定范围,例如只做预处理:
./run.sh --stage 0 --stop-stage 0也可以直接传入参数(如./run.sh 0 0),但脚本注释明确说明:参数方式与--stage/--stop-stage方式不可混用。参数解析由 utils/parse_options.sh 完成。
path.sh 环境初始化
path.sh 通过realpath ${PWD}/../../../定位仓库根目录MAIN_ROOT,并将其与MAIN_ROOT/utils加入PATH;同时设置PYTHONPATH指向仓库根目录,避免LC_ALL=C环境下 Python 的 Unicode 解码问题(通过PYTHONIOENCODING=UTF-8缓解)。脚本关键变量:
MAIN_ROOT:仓库根目录;BIN_DIR=${MAIN_ROOT}/paddlespeech/t2s/exps/fastspeech2:FastSpeech2 相关 Python 入口所在目录。
数据预处理全流程拆解
预处理入口为 local/preprocess.sh,内部包含 4 个子阶段,输入./baker_alignment_tone与~/datasets/BZNSYP/,输出dump目录。
子阶段 0:从 MFA 结果生成时长文件
python3 ${MAIN_ROOT}/utils/gen_duration_from_textgrid.py \ --inputdir=./baker_alignment_tone \ --output=durations.txt \ --config=${config_path}读取 MFA 的 TextGrid 对齐结果,逐句计算每个音素(含sp1~sp4韵律音素)的持续时长,汇总为durations.txt,供后续特征提取时写入metadata.jsonl。
子阶段 1:特征提取
python3 ${BIN_DIR}/preprocess.py \ --dataset=baker \ --rootdir=~/datasets/BZNSYP/ \ --dumpdir=dump \ --dur-file=durations.txt \ --config=${config_path} \ --num-cpu=20 \ --cut-sil=True按配置文件提取每句的梅尔谱(speech)、基频(pitch)与能量(energy)特征,并依据durations.txt写入音素时长;--cut-sil=True表示裁剪句首尾静音段。数据被划分为train、dev、test三部分。
子阶段 2:计算归一化统计量
python3 ${MAIN_ROOT}/utils/compute_statistics.py \ --metadata=dump/train/raw/metadata.jsonl \ --field-name="speech" # 同理对 "pitch"、"energy" 各执行一次仅基于训练集(dump/train/raw/metadata.jsonl)计算 speech、pitch、energy 三个特征的均值与方差,分别保存为dump/train/speech_stats.npy、pitch_stats.npy、energy_stats.npy。dev、test后续统一复用训练集的统计量,避免信息泄漏。
子阶段 3:归一化与 id 映射
python3 ${BIN_DIR}/normalize.py \ --metadata=dump/train/raw/metadata.jsonl \ --dumpdir=dump/train/norm \ --speech-stats=dump/train/speech_stats.npy \ --pitch-stats=dump/train/pitch_stats.npy \ --energy-stats=dump/train/energy_stats.npy \ --phones-dict=dump/phone_id_map.txt \ --speaker-dict=dump/speaker_id_map.txt # dev、test 同理,但 stats 一律使用 train 的统计量将特征归一化,并把音素/说话人映射为离散 id,生成dump/phone_id_map.txt与dump/speaker_id_map.txt。
dump 目录结构与 metadata.jsonl
预处理完成后得到如下目录结构:
dump ├── dev │ ├── norm │ └── raw ├── phone_id_map.txt ├── speaker_id_map.txt ├── test │ ├── norm │ └── raw └── train ├── energy_stats.npy ├── norm ├── pitch_stats.npy ├── raw └── speech_stats.npy每个子集(train/dev/test)下都有raw(原始特征)与norm(归一化特征)两个子目录;raw中存放每句的 speech、pitch、energy 特征文件,norm中存放对应的归一化版本。
每个子目录中还包含一个metadata.jsonl,是一张"表状"的逐行 JSON 文件,每行对应一条 utterance,包含字段:phones(音素序列)、text_lengths、speech_lengths、durations、speech 特征路径、pitch 特征路径、energy 特征路径、speaker、utterance id。在节奏版中,phones序列里会出现sp1~sp4等韵律音素,其时长也一并记录在durations中——这正是模型学到节奏的关键输入。训练/验证时批处理函数会从该文件读取并组装 batch,相关实现可参考 paddlespeech/t2s/datasets/am_batch_fn.py(其中tones字段的处理对应带声调/韵律标注的数据)。
核心配置 default.yaml 深度解读
conf/default.yaml 是本实验唯一的配置入口,同时作用于特征提取、模型结构与训练过程。以下逐段说明。
特征提取设置(FEATURE EXTRACTION SETTING)
| 参数 | 默认值 | 说明 |
|---|---|---|
fs | 24000 | 采样率(Hz) |
n_fft | 2048 | FFT 点数 |
n_shift | 300 | 帧移(采样点),约 12.5ms |
win_length | 1200 | 窗长(采样点),约 50ms;若为 null 则等同n_fft |
window | "hann" | 窗函数类型 |
fmin/fmax | 80/7600 | Mel 滤波器组最低/最高频率(Hz) |
n_mels | 80 | Mel 频带数 |
f0min/f0max | 80/400 | 基频提取的下/上限(Hz),仅对使用 pitch 特征的模型(如 FastSpeech2)生效 |
注意n_shift=300、win_length=1200与fs=24000的配合:帧移 12.5ms、窗长 50ms,是常见的中文 TTS 前端参数组合。
模型设置(MODEL SETTING)
- Transformer 骨架:
adim: 384(注意力维度)、aheads: 2(注意力头数)、elayers: 4/dlayers: 4(编码器/解码器层数)、eunits: 1536/dunits: 1536(FFN 隐层单元数);位置前馈层类型conv1d、卷积核3。 - 时长预测器(duration predictor):
duration_predictor_layers: 2、duration_predictor_chans: 256、duration_predictor_kernel_size: 3。 - 后处理网络(postnet):
postnet_layers: 5、postnet_filts: 5、postnet_chans: 256。 - 位置编码:
use_scaled_pos_enc: True,编码器/解码器均normalize_before: True,reduction_factor: 1,初始化方式xavier_uniform,编码/解码缩放位置编码初始 alpha 均为1.0。 - Transformer dropout:编码器与解码器的 layer / positional / attention dropout 均为
0.2。 - 基频预测器(pitch predictor):
pitch_predictor_layers: 5、pitch_predictor_chans: 256、pitch_predictor_kernel_size: 5、pitch_predictor_dropout: 0.5;pitch 嵌入卷积核1、dropout0.0,且stop_gradient_from_pitch_predictor: True(pitch 预测器到编码器的梯度默认截断)。 - 能量预测器(energy predictor):
energy_predictor_layers: 2、energy_predictor_chans: 256、energy_predictor_kernel_size: 3、energy_predictor_dropout: 0.5;energy 嵌入卷积核1、dropout0.0,stop_gradient_from_energy_predictor: False。
更新器 / 优化器 / 训练设置
updater.use_masking: True:损失计算时对 padding 部分做掩码,避免无意义位置的梯度;optimizer.optim: adam、optimizer.learning_rate: 0.001;max_epoch: 1000、num_snapshots: 5:最多 1000 个 epoch,最多保留 5 个快照;seed: 10086:随机种子。
模型训练
训练入口为 local/train.sh:
python3 ${BIN_DIR}/train.py \ --train-metadata=dump/train/norm/metadata.jsonl \ --dev-metadata=dump/dev/norm/metadata.jsonl \ --config=${config_path} \ --output-dir=${train_output_path} \ --ngpu=1 \ --phones-dict=dump/phone_id_map.txt参数含义(与基础版 examples/csmsc/tts3/README.md 中train.py的 help 输出一致):
--config:YAML 格式配置文件,覆盖默认配置;--train-metadata/--dev-metadata:必须使用dump目录下train、dev的norm子目录中的metadata.jsonl;--output-dir:实验输出目录,checkpoint 保存在其下的checkpoints/中;--ngpu:GPU 数量,0表示使用 CPU;--phones-dict:音素词表文件(dump/phone_id_map.txt)。
默认实验输出目录为exp/default,配合run.sh中的gpus=0,1即可多卡训练;训练过程中的 ckpt 统一存放在exp/default/checkpoints/下。
波形合成:两种方式与声码器选择
方式一:基于 metadata.jsonl 合成
local/synthesize.sh 调用${BIN_DIR}/../synthesize.py(即 paddlespeech/t2s/exps/synthesize.py),读取dump/test/norm/metadata.jsonl逐句合成波形:
CUDA_VISIBLE_DEVICES=${gpus} ./local/synthesize.sh ${conf_path} ${train_output_path} ${ckpt_name} 0最后一个数字参数控制声码器:0~4分别对应{pwgan, multi band melgan, style melgan, hifigan, wavernn}。核心调用参数(以 pwgan 为例):
python3 ${BIN_DIR}/../synthesize.py \ --am=fastspeech2_csmsc \ --am_config=${config_path} \ --am_ckpt=${train_output_path}/checkpoints/${ckpt_name} \ --am_stat=dump/train/speech_stats.npy \ --voc=pwgan_csmsc \ --voc_config=pwg_baker_ckpt_0.4/pwg_default.yaml \ --voc_ckpt=pwg_baker_ckpt_0.4/pwg_snapshot_iter_400000.pdz \ --voc_stat=pwg_baker_ckpt_0.4/pwg_stats.npy \ --test_metadata=dump/test/norm/metadata.jsonl \ --output_dir=${train_output_path}/test \ --phones_dict=dump/phone_id_map.txt其中--am_ckpt指向训练产出的 FastSpeech2 参数(默认snapshot_iter_153.pdz),--am_stat为梅尔谱归一化统计量,声码器相关路径需预先下载对应预训练模型并解压(如pwg_baker_ckpt_0.4目录)。
方式二:端到端(文本 → 波形)合成与静态图推理
local/synthesize_e2e.sh 调用${BIN_DIR}/../synthesize_e2e.py(paddlespeech/t2s/exps/synthesize_e2e.py),从纯文本直接合成语音,这是节奏版与基础版最大的不同点:
python3 ${BIN_DIR}/../synthesize_e2e.py \ --am=fastspeech2_csmsc \ --am_config=${config_path} \ --am_ckpt=${train_output_path}/checkpoints/${ckpt_name} \ --am_stat=dump/train/speech_stats.npy \ --voc=pwgan_csmsc \ --voc_config=pwg_baker_ckpt_0.4/pwg_default.yaml \ --voc_ckpt=pwg_baker_ckpt_0.4/pwg_snapshot_iter_400000.pdz \ --voc_stat=pwg_baker_ckpt_0.4/pwg_stats.npy \ --lang=zh \ --text=${BIN_DIR}/../../assets/sentences.txt \ --output_dir=${train_output_path}/test_e2e \ --phones_dict=dump/phone_id_map.txt \ --inference_dir=${train_output_path}/inference \ --use_rhy=True关键参数:
--lang=zh:中文文本前端;--text:待合成的文本文件(默认使用仓库内置的sentences.txt测试句集);--inference_dir:导出静态图(inference 模型)的目录;--use_rhy=True:开启韵律前端,使文本先经过韵律预测再转音素序列,这是"节奏版"合成的开关。
韵律前端的工作原理
从源码可以确认,--use_rhy参数在 paddlespeech/t2s/exps/synthesize_e2e.py 中定义为run rhythm frontend or not。开启后,中文前端 paddlespeech/t2s/frontend/zh_frontend.py 会:
- 实例化
RhyPredictor(use_rhy=True时创建,见 zh_frontend.py 中self.rhy_predictor = RhyPredictor()); - 对每个文本片段调用
get_prediction预测韵律边界; - 通过
pinyin_align把预测出的韵律标签(如sp1)对齐回拼音序列,生成sp1~sp4韵律音素(zh_frontend.py 中self.rhy_phns = ['sp1', 'sp2', 'sp3', 'sp4'])。
韵律预测器实现在 paddlespeech/t2s/frontend/rhy_prediction/rhy_predictor.py:加载rhy_e2e预训练模型与其配置文件rhy_default.yaml、词表rhy_token,构建rhy_dict将韵律类别映射为'sp' + str(i + 1)形式;make_rhy_dict与pinyin_align共同完成"预测结果 → 音素序列"的插入。也就是说,训练阶段通过 MFA 韵律标签学习节奏,推理阶段则用独立的韵律预测模型在纯文本上生成同样的标签,两端闭合。
声码器切换说明
run.shstage 2 注释明确:合成时可传0~4选择{pwgan, multi band melgan, style melgan, hifigan, wavernn};而 stage 3 端到端合成只支持0/1/3/4(style melgan 的动静转换在脚本注释中标注为"尚未就绪",且其端到端分支未启用--inference_dir)。各声码器预训练模型路径(如mb_melgan_csmsc_ckpt_0.1.1、hifigan_csmsc_ckpt_0.1.1、wavernn_csmsc_ckpt_0.2.0)均已在 synthesize.sh 与 synthesize_e2e.sh 中预置,按需下载解压即可替换。
预训练模型与文件清单
仓库为节奏版端到端 FastSpeech2 提供了预训练 checkpoint:fastspeech2_rhy_csmsc_ckpt_1.3.0.zip。解压后的目录结构如下:
fastspeech2_rhy_csmsc_ckpt_1.3.0 ├── default.yaml # 训练 fastspeech2 使用的默认配置 ├── phone_id_map.txt # 训练时的音素词表 ├── snapshot_iter_153000.pdz # 模型参数与优化器状态 ├── durations.txt # preprocess.sh 的中间产物(时长文件) ├── energy_stats.npy ├── pitch_stats.npy └── speech_stats.npy # 训练时用于归一化梅尔谱的统计量可以看出,该包既包含可直接用于合成的模型与词表,也保留了durations.txt与三项统计量,方便使用者复现预处理或继续微调。
与基础版 tts3 的差异小结
| 环节 | 基础版 tts3 | 节奏版 tts3_rhy |
|---|---|---|
| 时长来源 | 普通 MFA 对齐结果 | 带韵律标签的 MFA 结果(baker_alignment_tone.zip),音素中含sp1~sp4 |
| MFA 训练 | 常规命令 | 需加--rhy-with-duration(mfa 示例) |
| 端到端合成 | 普通文本前端 | --use_rhy=True,经RhyPredictor预测韵律后再转音素 |
| 预训练模型 | fastspeech2_csmsc_ckpt系列 | fastspeech2_rhy_csmsc_ckpt_1.3.0 |
如需更细粒度地自定义前端、批量数据格式或训练细节,可继续阅读 examples/other/mfa/README.md、paddlespeech/t2s/frontend/zh_frontend.py 以及 paddlespeech/t2s/datasets/preprocess_utils.py(其中get_phones_tones展示了从训练数据收集音素/声调集合并生成 id 映射的过程)。按本文流程完成 stage 0~3 后,即可在exp/default/test与exp/default/test_e2e中分别拿到"按标注合成"与"文本端到端合成"的波形结果,并通过--inference_dir得到可部署的静态图模型。
- 人工智能
- 语音
- 音频
【免费下载链接】PaddleSpeech
Easy-to-use Speech Toolkit including Self-Supervised Learning model, SOTA/Streaming ASR with punctuation, Streaming TTS with text frontend, Speaker Verification System, End-to-End Speech Translation and Keyword Spotting. Won NAACL2022 Best Demo Award.
相关推荐
PaddleSpeech:节奏信息增强版 FastSpeech2(tts3_rhy)CSMSC 训练与推理实战指南
PaddleSpeech:节奏信息增强版 FastSpeech2(tts3_rhy)CSMSC 训练与推理实战指南 本文围绕 PaddleSpeech 中 ex
人工智能语音音频NLP媒体生成PaddleSpeech 中文韵律预测实战:基于 ERNIE 与 CSMSC/AISHELL-3 的韵律标注、训练与 TTS 前端集成
PaddleSpeech 中文韵律预测实战:基于 ERNIE 与 CSMSC/AISHELL 3 的韵律标注、训练与 TTS 前端集成 本文围绕 PaddleS
人工智能语音音频NLP媒体生成PaddleSpeech 实战:基于 CSMSC 语料训练与部署 VITS 端到端语音合成模型
PaddleSpeech 实战:基于 CSMSC 语料训练与部署 VITS 端到端语音合成模型 本篇技术指南以 examples/csmsc/vits http
人工智能语音音频
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考