PaddleSpeech Multi-Band MelGAN 神经声码器:训练模块源码解析与 CSMSC 实战
2026/9/24 13:51:15 网站建设 项目流程
  • 人工智能
  • 语音
  • 音频
  • NLP
  • 媒体生成

【免费下载链接】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/paddlepaddle/PaddleSpeech
点击查看免费下载

本篇文章聚焦飞桨 PaddleSpeech 中paddlespeech.t2s.exps.gan_vocoder.multi_band_melgan这一 API 模块,深入解析 Multi-Band MelGAN 神经声码器(GAN Vocoder)在 PaddleSpeech 中的训练实现:从 API 文档页 出发,逐一讲解训练入口脚本、生成器与多尺度判别器结构、PQMF 子带编解码原理、全频带/子带双路 STFT 损失与对抗损失的组合策略,并结合examples/csmsc/voc3给出从数据预处理、模型训练到波形合成的完整可复现流程。读完本文,你将掌握如何用 PaddleSpeech 训练、评估与部署 Multi-Band MelGAN 声码器,并理解其与 FastSpeech2 声学模型级联成完整 TTS 系统的方式。

一、模块定位:API 文档与代码的对应关系

在 PaddleSpeech 的 API 参考文档中,paddlespeech.t2s.exps.gan_vocoder.multi_band_melgan.rst 是 Sphinx 自动生成的模块文档页,核心内容如下:

.. automodule:: paddlespeech.t2s.exps.gan_vocoder.multi_band_melgan :members: :undoc-members: :show-inheritance:

并通过toctree引入其唯一子模块 multi_band_melgan.train.rst。虽然.rst文件本身只是automodule指令的占位页,但它实际承载的内容就是被引用的 Python 模块的全部公开成员。该模块在仓库中的真实代码位于 paddlespeech/t2s/exps/gan_vocoder/multi_band_melgan/:

  • __init__.py:包初始化文件;
  • train.py:Multi-Band MelGAN 的训练入口脚本,即本 API 文档页的主体。

从源码结构看,该模块属于paddlespeech/t2s/exps/gan_vocoder/实验代码体系,与hifiganstyle_melganparallel_wavegan等声码器训练脚本并列,是 PaddleSpeech TTS 子系统中"声码器(Vocoder)"环节的实现之一。对应的模型实现位于 paddlespeech/t2s/models/melgan/melgan.py(生成器/判别器)、multi_band_melgan_updater.py(训练更新器/评估器)与 paddlespeech/t2s/modules/pqmf.py(子带滤波器组)。

二、训练入口:train.py的参数与主流程

训练脚本的命令行接口由 train.py 中的argparse定义,与examples/csmsc/voc3/README.md中给出的帮助信息一致:

usage: train.py [-h] [--config CONFIG] [--train-metadata TRAIN_METADATA] [--dev-metadata DEV_METADATA] [--output-dir OUTPUT_DIR] [--ngpu NGPU] Train a Multi-Band MelGAN model. optional arguments: --config CONFIG Multi-Band MelGAN config file. --train-metadata training data. --dev-metadata dev data. --output-dir output dir. --ngpu if ngpu == 0, use cpu.

各参数作用如下:

参数说明
--configYAML 格式的模型配置文件,训练时以它为唯一配置来源,运行时通过yacs.config.CfgNode(yaml.safe_load(f))解析为CfgNode对象
--train-metadata训练集metadata.jsonl文件路径(预处理后dump/train/norm/下)
--dev-metadata验证集metadata.jsonl文件路径(dump/dev/norm/下)
--output-dir实验输出目录,checkpoint 保存在其checkpoints/子目录
--ngpu使用的 GPU 数量;ngpu == 0时使用 CPU

主流程main()在读取配置后做了设备分派:当ngpu > 1时调用dist.spawn(train_sp, (args, config), nprocs=args.ngpu)启动多进程分布式训练,否则直接执行train_sp(args, config)train_sp内部的核心步骤依次为:

  1. 运行环境初始化:根据是否编译 CUDA 以及args.ngpu决定paddle.set_device("cpu"/"gpu");当world_size > 1时调用paddle.distributed.init_parallel_env()初始化并行环境;
  2. 随机种子固定:调用seed_everything(config.seed),代码注释明确指出"it is a must for multiprocess training"(多进程训练必须固定种子以保证可复现);
  3. 数据集构建:用jsonlines读取 metadata,构造DataTable,字段为["wave", "feats"],转换器均为np.load——即 metadata 中记录的是.npy文件的路径,加载得到波形数组与 mel 频谱数组;
  4. DataLoader 与裁剪:训练/验证集均使用DistributedBatchSampler,并用Clip批处理函数按batch_max_stepsn_shift(hop size)对波形与特征做长度裁剪(Clip定义于 paddlespeech/t2s/datasets/vocoder_batch_fn.py);
  5. 模型构建:实例化MelGANGeneratorMelGANMultiScaleDiscriminator,多卡时用DataParallel包装;
  6. 损失与优化器:构建MultiResolutionSTFTLoss(全频带)、MultiResolutionSTFTLoss(子带)、生成器/判别器对抗损失、PQMF 模块,并为生成器与判别器分别配置MultiStepDecay学习率调度器与Adam优化器;
  7. 组装 Trainer:将MBMelGANUpdaterMBMelGANEvaluatorTrainer组合,注册VisualDLSnapshot扩展,按stop_trigger=(config.train_max_steps, "iteration")停止训练。

值得一提的实现细节是:训练脚本为生成器单独支持了梯度裁剪generator_grad_normnn.ClipGradByGlobalNorm,当值大于 0 时启用,否则为None不裁剪),并注释说明"Compared to multi_band_melgan.v1 config, Adam optimizer without gradient norm is used",即不同版本配置对梯度裁剪策略有差异。

三、生成器与判别器:melgan.py中的网络结构

Multi-Band MelGAN 的生成器与判别器定义在 paddlespeech/t2s/models/melgan/melgan.py(头文件注明"Modified from espnet")。

3.1 MelGANGenerator:子带输出的生成器

MelGANGenerator(melgan.py#L32)的构造函数参数即配置文件中generator_params的字段:

  • in_channels:输入 mel 频谱通道数,默认 80(与n_mels一致);
  • out_channels:输出通道数,默认 1;在 Multi-Band 场景下,它等于子带数 subbands(默认 4),源码注释明确指出"the number of sub-band is out_channels in multi-band melgan";
  • kernel_size:首尾卷积核大小,默认 7,要求为奇数(非因果卷积时断言(kernel_size - 1) % 2 == 0);
  • channels:初始卷积通道数,需满足channels >= prod(upsample_scales)channels % 2**len(upsample_scales) == 0
  • upsample_scales:上采样倍数列表,默认[8, 8, 2, 2],其乘积决定了 mel 帧到波形的总上采样倍率;
  • stack_kernel_size/stacks:残差堆叠中空洞卷积核大小(默认 3)与堆叠层数(默认 3),空洞率按dilation = stack_kernel_size ** j递增;
  • nonlinear_activation:默认leakyrelu,参数negative_slope=0.2
  • pad/pad_params:默认Pad1D+reflect反射填充;
  • use_weight_norm:默认True,通过apply_weight_norm()递归对全部Conv1D/Conv2D/Conv1DTranspose层应用权重归一化;
  • use_causal_conv:是否使用因果卷积(CausalConv1D/CausalConv1DTranspose),用于流式(streaming)场景;
  • init_type:默认xavier_uniform

网络按upsample_scales逐级堆叠:每级包含激活层 → 转置卷积(通道数逐级减半)→stacksResidualStack,最后接激活层、反射填充与输出卷积,并以nn.Tanh()作为最终非线性激活(当use_final_nonlinear_activation=True)。参数重置reset_parameters()遵循官方实现,使用均值为 0、标准差 0.02 的正态分布重采样卷积权重。

Multi-Band 的关键体现在推理路径inference()(melgan.py#L258):生成器输出张量形状为(B, out_channels, T ** prod(upsample_scales)),即每个子带一路波形;当out_channels > 1时,构造时会在生成器内部挂载self.pqmf = PQMF(subbands=out_channels)inference()中对子带输出执行pqmf(out)(即 synthesis 合成),把多路子带信号重建成全频带波形。

3.2 MelGANMultiScaleDiscriminator:三尺度判别器

判别器采用 MelGAN 的多尺度结构(melgan.py#L406),默认scales=3:输入波形先经AvgPool1Dkernel_size=4, stride=2, padding=1)逐级下采样得到多个尺度,每个尺度共享同一MelGANDiscriminator子网络。子网络结构为:首层卷积(核大小取kernel_sizes乘积,如 5×3=15)→ 多个下采样卷积层(核大小downsample_scale * 10 + 1,分组卷积groups=in_chs // 4)→ 两个末层卷积。forward返回每一层输出构成的列表(用于后续可选的 feature matching loss),各尺度输出由判别器对抗损失统一处理。

四、PQMF:子带分析与合成的基础模块

Multi-Band MelGAN 之所以能"多带",核心依赖伪正交镜像滤波器组 PQMF(Pseudo-Quadrature Mirror Filter),实现于 paddlespeech/t2s/modules/pqmf.py。该模块基于近完美重建(near-perfect-reconstruction)伪 QMF 滤波器组设计,默认参数subbands=4, taps=62, cutoff_ratio=0.142, beta=9.0(原型滤波器由design_prototype_filter用 Kaiser 窗法设计,注释说明 cutoff_ratio 与 beta 是针对 4 子带优化的)。

  • analysis(x):把全频带波形(B, 1, T)分解为(B, subbands, T // subbands)的子带信号;
  • synthesis(x):把子带信号重建为全频带波形(B, 1, T)
  • forward(x)synthesis,注释说明"when converting dygraph to static graph, can not use self.pqmf.synthesis directly",即静态图转换时的兼容处理。

在训练脚本中,PQMF 以PQMF(subbands=config["generator_params"]["out_channels"])实例化并作为criterion_pqmf传入 updater:全频带波形由pqmf.analysis(wav)得到子带目标,生成器的子带输出wav_mb_通过pqmf.synthesis(wav_mb_)重建为全频带波形以计算全频带损失。这样,生成器在子带域输出、以"子带域+全频带域"双重监督进行优化。

五、训练策略:MBMelGANUpdaterMBMelGANEvaluator

训练与评估的核心逻辑封装在 multi_band_melgan_updater.py 中,分为MBMelGANUpdater(继承StandardUpdater)与MBMelGANEvaluator(继承StandardEvaluator)两个类。

5.1 生成器更新:多分辨率 STFT 损失 + 对抗损失

update_core中生成器更新流程如下:

  1. 生成器以 mel 频谱为输入输出子带波形wav_(形状(B, out_channels, T ** prod(upsample_scales))),再经criterion_pqmf.synthesis得到全频带波形;
  2. 全频带 Multi-resolution STFT losscriterion_stft(wav_, wav)返回频谱收敛损失sc_loss与 log-STFT 幅度损失mag_loss
  3. 子带 Multi-resolution STFT loss:先pqmf.analysis(wav)得到子带目标wav_mb,再与生成器子带输出wav_mb_计算sub_sc_losssub_mag_loss
  4. 辅助损失按论文 Eq.(9) 组合:aux_loss += 0.5 * (sc_loss + mag_loss)(全频带与子带各 0.5 系数),最终gen_loss += aux_loss * lambda_aux
  5. 当迭代步数超过discriminator_train_start_steps后加入对抗损失:gen_loss += lambda_adv * adv_loss,其中adv_loss = criterion_gen_adv(p_)p_为判别器对生成波形wav_的判定;
  6. 反向传播后optimizer_g.step()scheduler_g.step()同步推进。

训练过程中通过report()记录train/spectral_convergence_losstrain/log_stft_magnitude_losstrain/sub_spectral_convergence_losstrain/sub_log_stft_magnitude_losstrain/adversarial_losstrain/generator_loss等指标,这些指标与examples/csmsc/voc3/README.md中给出的评估表列名(eval/spectral_convergence_loss等)一一对应。

5.2 判别器更新与"慢启动"策略

判别器更新在state.iteration > discriminator_train_start_steps时触发(默认配置为 200000 步,见下节配置)。为了提升生成质量,判别器更新前会用paddle.no_grad()重新计算wav_(代码注释 "re-compute wav_ which leads better quality"),然后分别计算真实波形与生成波形(detach()后的)的判别输出,得到real_lossfake_loss,二者之和为dis_loss

MBMelGANUpdater构造函数还预留了generator_train_start_steps=0lambda_aux=1.0lambda_adv=1.0等参数,其中lambda_aux是辅助(STFT)损失的平衡系数,lambda_adv是对抗损失平衡系数,二者在train.py中从配置读取并传入。

5.3 评估器:与训练一致的指标口径

MBMelGANEvaluator.evaluate_core在验证集上同步计算对抗损失、全频带/子带 STFT 损失与判别器损失,指标以eval/前缀记录。train.py中评估器通过trainer.extend(evaluator, trigger=(config.eval_interval_steps, 'iteration'))注册,即每eval_interval_steps步在验证集上评估一次;VisualDL(1, 'iteration')频率记录训练曲线;Snapshot(max_size=config.num_snapshots)save_interval_steps保存快照。

六、配置文件详解:以 CSMSC 为例

examples/csmsc/voc3是仓库中基于中文标准女声库 CSMSC(Chinese Standard Mandarin Speech Copus)训练 Multi-Band MelGAN 的完整示例,其配置文件 examples/csmsc/voc3/conf/default.yaml 中的关键参数如下。

特征提取设置(与声学模型对齐):

参数含义
fs24000采样率 24kHz
n_fft2048FFT 点数
n_shift300帧移(hop size),约 12.5ms
win_length1200窗长,约 50ms
window"hann"窗函数
n_mels80mel 滤波器组个数
fmin/fmax80 / 7600mel 频率上下限(Hz)

生成器架构generator_params):

generator_params: in_channels: 80 # 输入 mel 通道数,与 n_mels 一致 out_channels: 4 # 输出子带数(Multi-Band 核心参数) kernel_size: 7 # 首尾卷积核大小 channels: 384 # 初始卷积通道数 upsample_scales: [5, 5, 3] # 上采样倍数,prod × out_channels == n_shift stack_kernel_size: 3 # 残差堆中空洞卷积核大小 stacks: 4 # 单个残差堆的堆叠层数 use_weight_norm: True # 是否使用权重归一化 use_causal_conv: False # 是否使用因果卷积 use_final_nonlinear_activation: True

注意注释强调prod(upsample_scales) x out_channels == n_shift(5×5×3×4 = 300 = n_shift),这正是 Multi-Band MelGAN 的分辨率约束:每个子带负责四分之一带宽,子带 hop 相应缩小。

判别器架构scales: 3(三尺度)、kernel_sizes: [5, 3]channels: 16max_downsample_channels: 512downsample_scales: [4, 4, 4]、激活为leakyrelunegative_slope: 0.2)。

损失配置use_stft_loss: True且全频带stft_loss_paramsfft_sizes: [1024, 2048, 512]hop_sizes: [120, 240, 50]win_lengths: [600, 1200, 240]use_subband_stft_loss: True且子带损失fft_sizes: [384, 683, 171]hop_sizes: [30, 60, 10]win_lengths: [150, 300, 60]——子带损失的各窗口尺寸约为全频带的三分之一左右,与 4 子带划分相适配。lambda_adv: 2.5为对抗损失平衡系数,use_feat_match_loss: False表示本配置未使用特征匹配损失。

优化器与调度:生成器与判别器均为Adamepsilon: 1.0e-7weight_decay: 0.0),学习率 1.0e-3,MultiStepDecaymilestones: [100000, 200000, 300000, 400000, 500000, 600000]处以gamma: 0.5逐级衰减;generator_grad_norm: -1discriminator_grad_norm: -1表示本配置不启用全局梯度裁剪。

训练步数discriminator_train_start_steps: 200000(前 20 万步只训练生成器)、train_max_steps: 1000000save_interval_steps: 5000eval_interval_steps: 1000;数据侧batch_size: 64batch_max_steps: 16200(需能被n_shift整除)、num_workers: 2;其他num_snapshots: 10seed: 42

七、端到端实操:从数据到合成

7.1 数据准备与预处理

按照 examples/csmsc/voc3/README.md,首先从 CSMSC 官网下载数据集解压到~/datasets/BZNSYP,并使用 MFA(Montreal Forced Aligner)对齐结果切除音频边缘静音。随后执行:

./run.sh --stage 0 --stop-stage 0 # 只做数据预处理 # 或直接 ./run.sh 依次完成预处理、训练、合成

预处理脚本./local/preprocess.sh ${conf_path}结束后会在当前目录生成dump目录,结构如下:

dump ├── dev │ ├── norm │ └── raw ├── test │ ├── norm │ └── raw └── train ├── norm ├── raw └── feats_stats.npy

数据集被划分为traindevtest三部分,各含raw(log 幅度 mel 频谱)与norm(归一化后频谱)子目录;归一化统计量由训练集计算得到,存于dump/train/feats_stats.npy。每个子目录下还有metadata.jsonl,是记录音频 id 与频谱文件路径的表格式文件,即训练脚本--train-metadata/--dev-metadata的输入。

7.2 模型训练

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

./local/train.sh实际调用${BIN_DIR}/train.py(即上文的训练脚本),--train-metadata--dev-metadata分别指向dump/train/normdump/dev/norm下的metadata.jsonl--output-dir为实验输出目录,checkpoint 保存于其checkpoints/目录。

7.3 波形合成

合成分为两种模式:

  1. 从 metadata 合成./local/synthesize.sh调用synthesize.py):参数包括--generator-type(取值{pwgan, mb_melgan, style_melgan, ...})、--config--checkpoint--test-metadata--output-dir--ngpu
  2. 端到端从文本合成./local/synthesize_e2e.sh调用synthesize_e2e.py):通过--am指定声学模型(如fastspeech2_csmsc)、--voc指定声码器(如mb_melgan_csmsc),并配套提供--am_config--am_ckpt--am_stat--phones_dict--voc_config--voc_ckpt--voc_stat等文件,形成"FastSpeech2 声学模型 + Multi-Band MelGAN 声码器"的完整 TTS 链路。仓库中examples/csmsc/tts3等端到端示例即采用这一组合,run.sh中的--stage/--stop-stage机制允许按阶段单独执行。

7.4 微调(Fine-tuning)

由于 Multi-Band MelGAN 输入没有噪声项,直接用真实频谱训练时音质仍有提升空间。README 记录了参照 HiFiGAN 思想的微调方案:先下载预训练 FastSpeech2 模型,用其预测的 mel 频谱(配合真实对齐时长)与训练阶段使用的真实波形重新构造dump_finetune数据集(波形软链接自原dump,频谱换为声学模型预测的 ground-truth-aligned mel,并复用原feats_stats.npy做归一化),然后基于conf/finetune.yaml从预训练 checkpoint 继续训练。微调前需将预训练模型放入${output-dir}/checkpoints并编写records.jsonl指明其路径与迭代步数(如{"time": "...", "path": ".../snapshot_iter_1000000.pdz", "iteration": 1000000}),最后执行./finetune.sh

7.5 预训练与导出产物

README 提供的预训练/导出产物覆盖多种部署形态,包括普通 checkpoint(mb_melgan_csmsc_ckpt)、微调模型(mb_melgan_baker_finetune_ckpt)、静态图模型(_static_)、PIR 静态模型(需paddlepaddle>=3.0.0b2且设置FLAGS_enable_pir_api=1)、ONNX 模型与 Paddle-Lite 模型(_pdlite_)。每个 Multi-Band MelGAN 发布包均包含三件套:default.yaml(训练配置)、feats_stats.npy(频谱归一化统计量)与snapshot_iter_1000000.pdz(生成器参数)。

八、总结

PaddleSpeech 的paddlespeech.t2s.exps.gan_vocoder.multi_band_melgan模块承载了 Multi-Band MelGAN 声码器的完整训练闭环。通过本文可以梳理出该实现的几条主线:

  • 多带架构:生成器直接输出 4 个子带波形(out_channels=4),由 PQMF 负责子带分解(analysis)与全频带重建(synthesis),使整体上采样负担分摊到子带,降低模型计算量;
  • 双路频谱监督:全频带与子带各一路 Multi-Resolution STFT 损失,按论文 Eq.(9) 以 0.5 系数加权组合,配合延迟 20 万步启动的对抗损失与三尺度判别器共同优化;
  • 工程完备性:支持多卡分布式训练、VisualDL 可视化、快照保存、动态图/静态图转换兼容,并配套从数据预处理、训练、合成到微调、多种部署产物导出的完整示例(examples/csmsc/voc3);
  • 生态集成:作为 TTS 声码器环节,可与 FastSpeech2 等声学模型级联(--voc mb_melgan_csmsc)实现文本到语音的端到端合成。

对希望深入源码的读者,建议按 train.py → multi_band_melgan_updater.py → melgan.py → pqmf.py 的顺序阅读,再结合 default.yaml 与 voc3/README.md 跑通一个 CSMSC 训练实验,即可完整掌握该声码器的原理与实战方法。

  • 人工智能
  • 语音
  • 音频
  • NLP
  • 媒体生成

【免费下载链接】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/paddlepaddle/PaddleSpeech
点击查看免费下载

相关推荐

上一篇:Skia图形引擎安装与配置完全指南
下一篇:终极指南:如何使用Skia图形库快速构建高性能2D应用

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

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

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

立即咨询