☰
PaddleSpeech 中的 ERNIE-SAT:基于 AISHELL-3 的语音合成与语音编辑实战指南
2026/9/25 5:34:36 网站建设 项目流程
  • 人工智能
  • 语音
  • 音频

【免费下载链接】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.

项目地址:https://gitcode.com/gh_mirrors/pa/PaddleSpeech
点击查看免费下载

本文围绕 PaddleSpeech 仓库中examples/aishell3/ernie_sat示例展开,系统讲解 ERNIE-SAT 语音-文本联合预训练框架在 AISHELL-3 数据集上的完整落地流程:从 MFA 强制对齐结果准备、数据预处理、模型训练,到基于 HiFi-GAN 声码器的波形合成,以及端到端的语音合成(Speech Synthesis)与语音编辑(Speech Editing)任务实现。读完本文,你可以独立跑通从run.sh各 stage 的预处理/训练/推理命令,理解conf/default.yaml中关键配置的来源与含义,并掌握语音编辑中“对齐—掩码—时长预测—生成”的底层推理链路。

一、ERNIE-SAT 模型框架

ERNIE-SAT 是一个语音-文本联合预训练框架(参见论文ERNIE-SAT: Speech-Text Joint Pre-training with Speech-Text Joint Masked Language Modeling),在跨语种多说话人语音合成与跨语种语音编辑任务上取得了当时领先的成果。它可以应用于语音编辑、个性化语音合成(Personalized Speech Synthesis)与声音克隆(Voice Cloning)等一系列场景。

ERNIE-SAT 提出两个核心创新点:

  • 跨语言个性化软音素映射:在预训练过程中,使用中文与英文的音素(phoneme)作为输入,实现跨语言、个性化的软音素映射;
  • 语音-文本联合掩码学习(Speech-Text Joint Masked Learning):通过对语音和文本同时进行掩码建模,实现语音帧与音素之间的细粒度对齐。

从源码结构看,模型实现位于 ernie_sat.py,核心是一个“编码器-解码器”结构:

  • 编码器(encoder_type: conformer):接收语音 mel 频谱与音素序列,输入层类型为sega_mlm,即在掩码语言建模(MLM)的同时对语音做分段(segment)处理,以支持跨说话人、跨语种的联合预训练;
  • 解码器(decoder_type: conformer):自回归地生成目标 mel 频谱帧;
  • 后处理网络(PostNet):由 5 层、256 通道、5 个滤波器的 CNN 堆叠,用于细化频谱细节(对应配置中postnet_layers/postnet_filts/postnet_chans)。

训练与评估循环由 ernie_sat_updater.py 中的训练 updater 与评估 updater 承担,掩码概率、音素片段长度等均来自训练配置。

二、数据集准备

2.1 下载并解压 AISHELL-3

需要 AISHELL-3 中文多说话人数据集(来自其官方网站),解压后目录结构应位于~/datasets/data_aishell3。

2.2 获取 MFA 强制对齐结果

语音-文本对齐依赖 Montreal Forced Aligner(MFA):官方提供了针对 AISHELL-3 的带声调对齐结果aishell3_alignment_tone.tar.gz(存放于 PaddleSpeech 的 CDN 资源),解压后放到示例目录下作为./aishell3_alignment_tone。如果不想直接使用现成对齐结果,也可以参考仓库中的 MFA 训练示例 自行训练 MFA 模型并生成 TextGrid 对齐(该示例基于 MFA 1.x)。

三、数据预处理(stage 0)

假设数据集路径为~/datasets/data_aishell3,MFA 对齐结果路径为./aishell3_alignment_tone,预处理入口为:

./local/preprocess.sh ${conf_path}

结合 preprocess.sh 源码,该脚本内部串联了 4 个步骤:

  1. 生成时长标注:调用 gen_duration_from_textgrid.py,从 MFA 的 TextGrid 结果解析出逐音素时长,输出durations.txt(--inputdir=./aishell3_alignment_tone);
  2. 提取语音特征:调用 preprocess.py,参数--dataset=aishell3 --rootdir=~/datasets/data_aishell3/ --dumpdir=dump --dur-file=durations.txt --cut-sil=True,按配置的 mel 参数提取每句话的 log-mel 特征,并裁掉静音段;
  3. 统计特征均值与方差:调用 compute_statistics.py,对dump/train/raw/metadata.jsonl中speech字段计算统计量,生成dump/train/speech_stats.npy;
  4. 归一化与 ID 映射:调用 normalize.py,train/dev/test 三个子集分别归一化到各自的norm目录。关键点:dev 与 test 均使用训练集的统计量dump/train/speech_stats.npy,避免数据泄漏;同时把音素、说话人转换为 ID,生成dump/phone_id_map.txt与dump/speaker_id_map.txt。

预处理完成后,当前目录生成dump文件夹,结构如下:

dump ├── dev │ ├── norm │ └── raw ├── phone_id_map.txt ├── speaker_id_map.txt ├── test │ ├── norm │ └── raw └── train ├── norm ├── raw └── speech_stats.npy

数据集被切分为train、dev、test三部分,各自包含raw(原始特征)与norm(归一化特征)两个子目录;归一化统计量保存在dump/train/speech_stats.npy。

每个子目录下还有metadata.jsonl表格化文件,每行记录一条样本的:音素序列(phones)、文本长度(text_lengths)、语音长度(speech_lengths)、逐音素时长(durations)、语音特征路径、说话人(speaker)以及样本 ID。这个文件既是训练输入,也是后续推理阶段“从 metadata 合成”的直接数据源。

四、模型训练(stage 1)

CUDA_VISIBLE_DEVICES=${gpus} ./local/train.sh ${conf_path} ${train_output_path}

train.sh 实际调用的是 train.py,关键入参为--train-metadata=dump/train/norm/metadata.jsonl、--dev-metadata=dump/dev/norm/metadata.jsonl、--config、--output-dir、--ngpu=8、--phones-dict=dump/phone_id_map.txt。训练产出的各ckpt位于${train_output_path}/checkpoints/目录。

4.1 关键配置解读(conf/default.yaml)

完整配置见 default.yaml。官方备注:该配置在 8 卡 A100(80GB 显存)上验证,训练约需 3 天;可按机器情况调整batch_size、num_workers以及local/train.sh中的ngpu。核心配置项:

特征提取设置

参数取值说明
fs24000采样率
n_fft2048FFT 大小(样本数)
n_shift300帧移,即 12.5ms
win_length1200窗长,即 50ms
window"hann"窗函数
fmin/fmax80 / 7600Mel 滤波器组频率范围
n_mels80Mel 维数
mean_phn_span8MLM 掩码时平均覆盖的音素片段长度
mlm_prob0.8掩码语言建模概率

模型结构设置:编码器与解码器均为 Conformer,enc_input_layer: sega_mlm(分段式 MLM 输入),enc_pre_speech_layer: 0;两侧attention_dim=384、attention_heads=2、linear_units=1536、num_blocks=4,dropout 统一 0.2;位置编码使用legacy_rel_pos相对位置编码,前馈层为conv1d(核大小 3),激活为 swish,并启用 Macaron 风格 Conformer(macaron_style: true)。后处理网络postnet_layers=5、postnet_filts=5、postnet_chans=256。

优化器与训练设置:scheduler_params.d_model=384、warmup_steps=4000、grad_clip=1.0;batch_size=40、num_workers=8、max_epoch=1500、num_snapshots=50、seed=0。

词表设置:token_list是 AISHELL-3 音素(带声调拼音)加特殊符号的完整词表,包括<blank>、<unk>、<sos/eos>以及全部音素(如a1、ian4、eng2、sp等),推理脚本据此把音素字符串映射为 ID(映射不到词表的音素会用sp替换)。

五、波形合成(stage 2)

合成交体采用 HiFi-GAN 作为神经声码器。需要先下载预训练 HiFi-GAN 模型hifigan_aishell3_ckpt_0.2.0.zip(PaddleSpeech 已发布模型资源)并解压:

unzip hifigan_aishell3_ckpt_0.2.0.zip

HiFi-GAN checkpoint 包含以下文件:

hifigan_aishell3_ckpt_0.2.0 ├── default.yaml # 训练 HiFi-GAN 使用的默认配置 ├── feats_stats.npy # HiFi-GAN 训练时归一化频谱所用统计量 └── snapshot_iter_2500000.pdz # HiFi-GAN 生成器参数

synthesize.sh 调用 synthesize.py,从dump/test/norm/metadata.jsonl读取测试集样本,用 ERNIE-SAT 生成 mel 频谱后经 HiFi-GAN 还原波形,输出到${train_output_path}/test:

CUDA_VISIBLE_DEVICES=${gpus} ./local/synthesize.sh ${conf_path} ${train_output_path} ${ckpt_name}

其中--erniesat_stat指向dump/train/speech_stats.npy(反归一化 mel 用),--voc_stat指向声码器训练时的feats_stats.npy(反归一化声码器输入频谱用),两者不可混用。脚本还设置了FLAGS_allocator_strategy=naive_best_fit与FLAGS_fraction_of_gpu_memory_to_use=0.01以控制 GPU 显存占用。

六、端到端语音合成与语音编辑(stage 3)

这是 ERNIE-SAT 示例最有特色的部分:./run.sh --stage 3 --stop-stage 3 --gpus 0调用 synthesize_e2e.sh,脚本默认同时执行语音合成(--task_name=synthesize,把输入文本转换为语音)与语音编辑(--task_name=edit,按新文本内容修改已有语音)两类任务。

6.1 环境准备:MFA、FastSpeech2 与源音频

准备对齐器:下载 MFA 1.0.1 的 Linux 预编译包并解压,修复lib下的 Python 动态库软链接(ln -snf libpython3.6m.so.1.0 libpython3.6m.so);再下载 AISHELL-3 与 VCTK 两个 MFA 对齐模型(aishell3_model.zip、vctk_model.zip)以及词表(AISHELL-3 的simple.lexicon、英文的cmudict-0.7b),统一放在tools/aligner目录下。

准备预训练 FastSpeech2 模型:ERNIE-SAT 在推理时借用FastSpeech2 的时长预测器(duration predictor)来估计新增音素的时长。需要下载并解压fastspeech2_conformer_baker_ckpt_0.5.zip(中文,Baker 数据集)与fastspeech2_nosil_ljspeech_ckpt_0.5.zip(英文,LJSpeech 数据集)到download/目录。

准备源数据:从 PaddleSpeech 已发布模型资源下载source/目录下的示例音频,覆盖中英文、多说话人场景:

mkdir source cd source # 下载 SSB03540307.wav、SSB03540428.wav(AISHELL-3 中文) # LJ050-0278.wav(LJSpeech 英文) # p243_313.wav、p299_096.wav(VCTK 英文) # this_was_not_the_show_for_me.wav # README.md(各音频对应的文本) cd ../

每段音频的原文文本记录在source/README.md中,--old_str必须与之保持一致。

6.2 合成与编辑命令及参数

s ynthesize_e2e.sh的两段命令分别对应两个任务,核心参数:

参数说明
--task_namesynthesize(语音合成)或edit(语音编辑)
--wav_path源音频路径,如source/SSB03540307.wav
--old_str--wav_path音频对应的原文本
--new_str目标文本;合成任务中会拼在原文本之后,编辑任务中用于替换old_str片段
--source_lang/--target_lang源/目标语言。AISHELL-3 训练的模型二者均应为zh
--duration_adjust是否启用时长校准(默认 True)
--output_name输出 wav 路径

脚本内置的两个示例:

  • 合成:源音频SSB03540307.wav(“请播放歌曲小苹果”),--new_str='歌曲真好听',输出exp/pred_gen.wav;
  • 编辑:源音频SSB03540428.wav(“今天天气很好”),--old_str='今天天气很好',--new_str='今天心情很好',输出exp/pred_edit.wav。

可以自行修改--wav_path、--old_str、--new_str,其中--old_str应是对应音频的文本,--new_str应按任务需求设计;对 AISHELL-3 训练的模型,--source_lang与--target_lang均应为zh。

6.3 底层推理链路解析

从 synthesize_e2e.py 源码可以看到端到端任务的完整链路:

  1. 文本转音素:若语言为中文,先用pypinyin把文本转为带声调拼音(TONE3风格、开启变调与轻声处理);合成任务下new_str = old_str + ' ' + new_str,即目标句 = 原句 + 新增句;
  2. MFA 对齐:get_phns_spans(align.py)对源音频与目标文本做强制对齐,输出逐音素起止时间(mfa_start/mfa_end)、新旧音素序列,以及需要替换的片段span_to_repl与需要新增的片段span_to_add;
  3. 时长预测与校准:调用eval_durs(基于 FastSpeech2 时长预测器)估计新旧音素时长;get_dur_adj_factor用 MFA 真实时长校正预测偏差,prep_feats_with_dur中还额外乘了 1.25 的膨胀系数,再取整得到帧数级时长;
  4. 构造编辑后的波形:把原音频中待替换区间wav_left_idx ~ wav_right_idx(由对齐时间 ×n_shift换算采样点)替换为静音段,静音长度由 FastSpeech2 预测的新音素总时长决定,即new_wav = [原音频前段, 静音占位段, 原音频后段];
  5. 提取 mel 并归一化:对编辑后的波形提取 log-mel(LogMelFBank,参数与conf/default.yaml一致),并用dump/train/speech_stats.npy归一化;
  6. 掩码生成:get_span_bdy分别算出原音频被替换区间与新音频占位区间在帧级的边界(old_span_bdy/new_span_bdy),作为 masked_pos 送入模型;
  7. 模型推理与声码:get_am_inference加载 ERNIE-SAT(am='erniesat_dataset'),模型inference接口对span_bdy指定的区间自回归生成 mel;再由get_voc_inference加载的 HiFi-GAN 还原为波形,最终sf.write输出结果。

也就是说,“编辑”并非简单地局部重合成:模型同时看到了原句的语音上下文、被掩码的目标区间、以及音素级的对齐信息,从而生成音色一致、时长衔接自然的新音频。

七、一键运行与 stage 划分

run.sh通过parse_options.sh解析--stage/--stop-stage,默认stage=0、stop_stage=100,默认 GPU 列表为 0~7:

./run.sh # 完整流程:预处理 -> 训练 -> 合成 -> e2e 合成/编辑 ./run.sh --stage 0 --stop-stage 0 # 仅数据预处理 ./run.sh --stage 3 --stop-stage 3 --gpus 0 # 仅 e2e 语音合成与语音编辑

各 stage 对应关系:stage 0 数据预处理(local/preprocess.sh);stage 1 模型训练(local/train.sh);stage 2 基于metadata.jsonl的测试集合成(local/synthesize.sh);stage 3 端到端语音合成与语音编辑(local/synthesize_e2e.sh)。路径与 BIN_DIR 在 path.sh 中导出:MODEL=ernie_sat,BIN_DIR=${MAIN_ROOT}/paddlespeech/t2s/exps/ernie_sat,即所有 Python 入口脚本均来自 paddlespeech/t2s/exps/ernie_sat。

八、预训练模型与评估结果

官方发布了 AISHELL-3 训练的 ERNIE-SAT 预训练模型erniesat_aishell3_ckpt_1.2.0.zip(PaddleSpeech CDN),下载解压后即可跳过训练,直接配合 stage 2/3 的推理脚本使用。官方评估结果:

ModelStepeval/mlm_losseval/loss
default8(gpu) x 28950051.72378251.723782

九、小结

  • 流程主线:MFA 对齐 →durations.txt→ mel 特征提取 → 统计量与归一化 → Conformer 编码器-解码器 + PostNet 的联合 MLM 训练 → HiFi-GAN 声码;
  • 可复现入口:run.sh 的 4 个 stage 与 local 下的 4 个脚本,Python 实现集中在 paddlespeech/t2s/exps/ernie_sat 与 paddlespeech/t2s/models/ernie_sat;
  • 语音编辑的关键:MFA 对齐 + FastSpeech2 时长预测 + 帧级掩码区间,三者的组合决定了编辑位置的定位与新增时长的准确性,这也是使用示例时--old_str必须与源音频文本严格一致的原因。

适用前提与限制:配置按 8 卡 A100 80GB 验证(约 3 天),小规模机器需下调batch_size、ngpu等参数;MFA 预编译包基于 Linux 且依赖 Python 3.6 动态库;AISHELL-3 训练的模型推理时--source_lang/--target_lang均应设为zh。

  • 人工智能
  • 语音
  • 音频

【免费下载链接】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.

项目地址:https://gitcode.com/gh_mirrors/pa/PaddleSpeech
点击查看免费下载

相关推荐

上一篇:终极歌词获取指南:免费快速搞定网易云QQ音乐歌词下载与格式转换
下一篇:掌握Hydra游戏启动器:10个提升效率的实用快捷键全解析

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询