- 人工智能
- 语音
- 音频
- 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.
本文以仓库中tests/benchmark/pwgan/目录下的基准测试文档与配套脚本为主体,完整拆解 PaddleSpeech 中 Parallel WaveGAN(pwgan)声码器训练基准的执行方式:从./run_all.sh的一键入口,到依赖安装、数据集下载预处理、单卡/多卡批量压测,以及训练日志中avg_ips性能指标的产生与解析机制,帮助读者理解如何在标准环境下复现并解读 pwgan 的训练性能数据。
基准测试的定位与整体执行方式
tests/benchmark/pwgan/是 PaddleSpeech 针对 Parallel WaveGAN 声码器训练性能提供的标准基准目录,原始文档见 pwgan 基准说明。按该文档描述,执行方式非常简单:
./run_all.sh即可运行。文档给出的执行逻辑分为五步:
cd到../../../(即项目工作根目录);- 安装
paddlespeech/t2s所需依赖; - 从 BOS 下载数据集并解压缩;
- 预处理数据集为训练 pwg 所需格式,保存到
dump文件夹底下; - 按照不同的参数执行
run_benchmark.sh脚本。
这五步恰好对应 run_all.sh 中stage=0到stop_stage=100控制的四个阶段块。脚本顶部有两处关键注释值得注意:
LOG_PATH_INDEX_DIR环境变量可由 benchmark 系统指定,不需要跑 profile 时它指向存放 speed 结果的目录,脚本默认回退到$(pwd);- 脚本提供了一个“可稳定复现性能”的执行路径,默认在标准 docker 环境内运行:Python 3.7 + paddle 2.1.2,对应镜像
paddlepaddle/paddle:latest-gpu-cuda10.1-cudnn7。
因此在自行复现前,需要先明确 GPU 数量、CUDA/cuDNN 版本与 paddle 版本是否与上述基线一致,否则测得的吞吐数据不可直接比较。
run_all.sh 分阶段流程详解
阶段 0:依赖安装
stage=0 stop_stage=100 sed -i '/set\ -xe/d' run_benchmark.sh cd ../../../ if [ ${stage} -le 0 ] && [ ${stop_stage} -ge 0 ]; then sudo apt-get install libsndfile1 pip install -e . pushd examples/csmsc/voc1 source path.sh popd fi这一阶段做三件事:安装音频底层依赖libsndfile1;以可编辑模式安装当前仓库(pip install -e .);进入 examples/csmsc/voc1 并source path.sh加载该 TTS 声码器示例所需的 Python 包环境。
另外注意sed -i '/set\ -xe/d' run_benchmark.sh这一行:它会在正式执行前把run_benchmark.sh中的set -xe调试行删除,避免批量压测时任何一条命令的非零返回导致整个基准中断。这是一个面向自动化批量执行的工程化处理。
阶段 1:数据集下载
wget https://weixinxcxdb.oss-cn-beijing.aliyuncs.com/gwYinPinKu/BZNSYP.rar mkdir BZNSYP unrar x BZNSYP.rar BZNSYP wget https://paddlespeech.cdn.bcebos.com/Parakeet/benchmark/durations.txt基准使用 BZNSYP 中文语音数据集(注意脚本中的下载 URL 与解压缩目录均为仓库脚本中的原始配置,实际执行时依赖对应镜像源可用)。同时下载durations.txt作为切分时长参考文件,供后续预处理阶段使用。
阶段 2:数据预处理为 pwgan 训练格式
python paddlespeech/t2s/exps/gan_vocoder/preprocess.py --rootdir=BZNSYP/ --dumpdir=dump --num-cpu=20 --cut-sil=True --dur-file=durations.txt --config=examples/csmsc/voc1/conf/default.yaml python utils/compute_statistics.py --metadata=dump/train/raw/metadata.jsonl --field-name="feats" python paddlespeech/t2s/exps/gan_vocoder/normalize.py --metadata=dump/train/raw/metadata.jsonl --dumpdir=dump/train/norm --stats=dump/train/feats_stats.npy python paddlespeech/t2s/exps/gan_vocoder/normalize.py --metadata=dump/dev/raw/metadata.jsonl --dumpdir=dump/dev/norm --stats=dump/train/feats_stats.npy python paddlespeech/t2s/exps/gan_vocoder/normalize.py --metadata=dump/test/raw/metadata.jsonl --dumpdir=dump/test/norm --stats=dump/train/feats_stats.npy这一步正是文档中“预处理数据集为训练 pwg 所需格式,保存到 dump 文件夹”的具体落地,处理链路为:
- preprocess.py:以 examples/csmsc/voc1/conf/default.yaml 中的特征提取参数为准,从
BZNSYP/抽取 mel 特征与波形片段,--cut-sil=True启用静音切除,--dur-file指定切分时长表,20 个 CPU 并行,输出dump/{train,dev,test}/raw/metadata.jsonl; - compute_statistics.py:对训练集
feats字段计算统计量,落盘为dump/train/feats_stats.npy; - normalize.py:train/dev/test 三个子集统一使用训练集统计量做归一化,输出到
dump/*/norm/。
这里使用训练集统计量归一化验证/测试集的做法与常规 ML 工程实践一致,可以避免数据泄漏导致的统计偏置。
阶段 3:批量执行 run_benchmark.sh
model_mode_list=(pwgan) fp_item_list=(fp32) # 满 bs 是 26 bs_item_list=(6) for model_mode in ${model_mode_list[@]}; do for fp_item in ${fp_item_list[@]}; do for bs_item in ${bs_item_list[@]}; do log_name=speech_${model_mode}_bs${bs_item}_${fp_item} echo "index is speed, 1gpus, begin, ${log_name}" run_mode=sp CUDA_VISIBLE_DEVICES=0 bash tests/benchmark/pwgan/run_benchmark.sh ${run_mode} ${bs_item} ${fp_item} 100 ${model_mode} | tee ${log_path}/${log_name}_speed_1gpus 2>&1 sleep 60 echo "index is speed, 8gpus, run_mode is multi_process, begin, ${log_name}" run_mode=mp CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 bash tests/benchmark/pwgan/run_benchmark.sh ${run_mode} ${bs_item} ${fp_item} 100 ${model_mode} | tee ${log_path}/${log_name}_speed_8gpus8p 2>&1 sleep 60 done done done该阶段用三层循环遍历“模型 × 精度 × batch size”组合,对每个组合跑两种形态:
- 单卡形态(sp):
CUDA_VISIBLE_DEVICES=0,训练 100 个迭代,日志写入${LOG_PATH_INDEX_DIR}/speech_pwgan_bs6_fp32_speed_1gpus; - 8 卡多进程形态(mp):
CUDA_VISIBLE_DEVICES=0,1,...,7,8 个进程并行,日志写入..._speed_8gpus8p。
注释“满 bs 是 26”说明 batch_size=6 是保守选取(单条样本下显存上限约可容纳 26),两次压测之间sleep 60用于冷却与 GPU 状态恢复。
run_benchmark.sh:单轮基准的参数与日志解析契约
run_benchmark.sh 是真正发起训练并产出可解析日志的脚本,运行示例为:
CUDA_VISIBLE_DEVICES=0 bash run_benchmark.sh ${run_mode} ${bs_item} ${fp_item} 500 ${model_mode}命令行参数说明
脚本在_set_params函数中解析五个位置参数:
| 参数 | 位置 | 默认值 | 含义 |
|---|---|---|---|
run_mode | 1 | sp | 单卡sp/ 多卡mp |
batch_size | 2 | 8 | 每卡 batch size,会覆盖配置文件中的值 |
fp_item | 3 | fp32 | fp32/fp16,用于日志命名 |
max_iter | 4 | 500 | 训练最大迭代数,可选,用于提前中断训练 |
model_item | 5 | model_item | 模型名,用于拼接日志名 |
run_mode取值非法时脚本会打印choose run_mode(sp or mp)并以退出码 1 结束。
日志解析契约参数
_set_params中还有一组专为下游 benchmark 系统解析日志而设置的变量,可视为该基准对日志格式的“契约”:
base_batch_size=${batch_size} mission_name="语音合成" direction_id="1" ips_unit="sequences/sec" skip_steps=10 # 解析日志,有些模型前几个step耗时长,需要跳过 (必填) keyword="avg_ips:" # 解析日志,筛选出数据所在行的关键字 (必填) index="1" model_name=${model_item}_bs${batch_size}_${fp_item} device=${CUDA_VISIBLE_DEVICES//,/ } arr=(${device}) num_gpu_devices=${#arr[*]} log_file=${run_log_path}/${model_item}_${run_mode}_bs${batch_size}_${fp_item}_${num_gpu_devices}要点有三:
- 性能单位是
sequences/sec,即每秒处理的序列数,而不是 samples/sec 或 samples/s; skip_steps=10用于跳过前若干 step——前几步通常因初始化、显存分配等耗时异常,不参与吞吐统计;keyword="avg_ips:"是解析器在日志行中筛选数据的锚点,这个字符串正是训练器每轮迭代打印的指标名(下文展开)。
多卡时脚本会将CUDA_VISIBLE_DEVICES中的逗号替换为空格并统计出num_gpu_devices,日志文件名为${model_item}_${run_mode}_bs${batch_size}_${fp_item}_${num_gpu_devices},日志目录由环境变量TRAIN_LOG_DIR控制,默认当前目录。
_train 函数:训练命令的拼装
train_cmd="--batch-size=${batch_size}\ --max-iter=${max_iter} --train-metadata=dump/train/norm/metadata.jsonl \ --dev-metadata=dump/dev/norm/metadata.jsonl \ --config=examples/csmsc/voc1/conf/default.yaml \ --output-dir=exp/default \ --run-benchmark=true" case ${run_mode} in sp) train_cmd="python paddlespeech/t2s/exps/gan_vocoder/parallelwave_gan/train.py --ngpu=1 ${train_cmd}" ;; mp) rm -rf ./mylog train_cmd="python paddlespeech/t2s/exps/gan_vocoder/parallelwave_gan/train.py --ngpu=8 ${train_cmd}" log_parse_file="mylog/workerlog.0" ;; esac bash tests/test_tipc/barrier.sh timeout 15m ${train_cmd} > ${log_file} 2>&1从源码结构看,这条命令的每个参数都能在训练入口 train.py 中找到对应解析:
--config、--train-metadata、--dev-metadata、--output-dir、--ngpu是通用训练参数;--batch-size(默认 8)、--max-iter(默认 400000)、--run-benchmark(默认 False)、--profiler_options属于benchmark参数组。
关键在于--run-benchmark=true的作用。train.py 中有一段明确的覆盖逻辑:
# 增加 --batch_size --max_iter 用于 benchmark 调用 if args.run_benchmark: config.batch_size = args.batch_size config.train_max_steps = args.max_iter也就是说,benchmark 模式下命令行参数会强制覆盖default.yaml 中的batch_size(原值 8)与train_max_steps(原值 400000)。这解释了为什么基准可以只训练 100 步:Trainer的停止条件正是stop_trigger=(config.train_max_steps, "iteration"),被--max-iter改写后即变为 100 步,配合timeout 15m兜底防止异常挂死。
训练入口对--ngpu的分发逻辑也印证了两种形态的实现差异:
if args.ngpu > 1: dist.spawn(train_sp, (args, config), nprocs=args.ngpu) else: train_sp(args, config)即 sp 形态直接单进程执行train_sp;mp 形态由paddle.distributed.spawn拉起 8 个进程,world_size > 1时会init_parallel_env()并对生成器/判别器包一层DataParallel,采样器也切换为DistributedBatchSampler。多卡日志取自mylog/workerlog.0(rank 0 worker 日志),脚本末尾会把它复制回标准log_file路径。
训练前还会执行 tests/test_tipc/barrier.sh 做同步,保证多进程压测的起始点对齐。
avg_ips 指标从哪来:训练器日志格式
keyword="avg_ips:"之所以能作为解析锚点,是因为 PaddleSpeech 的通用训练器 trainer.py 在主循环中每轮迭代都会向日志写入一行包含该字段的性能记录:
msg += "avg_samples: {}, ".format( self.updater.batch_size) + "avg_ips: {:.5f} sequences/sec,".format( self.updater.batch_size / avg_batch_cost)其中avg_batch_cost = batch_read_time + batch_time,即“数据读取耗时 + 单 batch 训练耗时”之和,吞吐 = batch 内样本数 / 单批耗时。GPU 环境下该行还会附加max_mem_reserved/max_mem_allocated两个显存峰值指标,便于在压测中观察显存占用是否稳定。因此日志中每一行形如:
iter: 50/100, ..., avg_samples: 6, avg_ips: 12.34567 sequences/sec, max_mem_reserved: xxx MB, max_mem_allocated: xxx MBbenchmark 解析脚本即按skip_steps=10跳过头部、按avg_ips:关键字取列,得到该配置下的 sequences/sec 数据。
被压测的训练任务:default.yaml 关键配置
基准实际压测的是 Parallel WaveGAN 的完整训练(生成器 + 判别器 + 多分辨率 STFT 损失),超参由 examples/csmsc/voc1/conf/default.yaml 定义。文件头部注释说明该配置面向 CSMSC 数据集,约需 12 GB 显存、在 RTX TITAN 上训练完整 40 万步约需 3 天。与基准相关的主要配置段如下:
| 配置段 | 关键项 | 值 | 说明 |
|---|---|---|---|
| 特征提取 | fs/n_fft/n_shift/n_mels | 24000 / 2048 / 300 / 80 | 24 kHz 采样率,12.5 ms hop,80 维 mel |
| 生成器 | layers/stacks/upsample_scales | 30 / 3 / [4,5,3,5] | 残差块数与上采样率,乘积 300 = hop size |
| 判别器 | layers/conv_channels | 10 / 64 | 多层卷积判别器 |
| STFT 损失 | fft_sizes/hop_sizes/win_lengths | [1024,2048,512] 等三组 | 多分辨率 STFT 损失 |
| 数据加载 | batch_size/batch_max_steps/num_workers | 8 / 25500 / 2 | batch_max_steps必须能被n_shift整除 |
| 优化器 | 学习率(G/D) | 1e-4 / 5e-5 | 均配StepDecay(step_size=200000, gamma=0.5)与梯度裁剪(10 / 1) |
| 训练节奏 | discriminator_train_start_steps/train_max_steps/save_interval_steps/eval_interval_steps | 100000 / 400000 / 5000 / 1000 | 判别器延后启动,定期存快照与评估 |
需要强调:基准运行时batch_size与train_max_steps会被命令行覆盖(见前文),但特征维度、网络结构、损失与优化器设置仍然生效——这保证了压测负载与真实 pwgan 训练完全同构,测出的吞吐具有代表性。
结果产出与注意事项
一次完整基准运行后,LOG_PATH_INDEX_DIR(或当前目录)下会产出形如speech_pwgan_bs6_fp32_speed_1gpus与speech_pwgan_bs6_fp32_speed_8gpus8p的训练日志,其中avg_ips: X sequences/sec行即最终性能数据来源。
结合脚本内容,实际操作时还有几个值得注意的点:
- 环境前提:
run_all.sh注释标明基线为 Python 3.7 + paddle 2.1.2 + CUDA 10.1/cuDNN7 的 docker 镜像;mp 形态需要 8 张可见 GPU,CUDA_VISIBLE_DEVICES需给出 8 个卡号; - 外部依赖:脚本末尾
source ${BENCHMARK_ROOT}/scripts/run_model.sh会对符合 benchmark 规范的日志调用analysis.py做性能解析;脚本注释说明如果不联调、只想产出训练 log,可注释掉该行及_run调用,直接放开_train; - 时长控制:
max_iter=100+timeout 15m双重限制单轮时长,skip_steps=10保证统计的稳定性;若修改配置导致单步变慢,需相应评估超时是否足够; - 可复现性:
preprocess.py、normalize.py等预处理产物均落在dump/目录,benchmark 各阶段由stage/stop_stage控制,重跑时可以从任意 stage 开始,避免重复下载与预处理; - 该基准目录与 conformer 基准 同属
tests/benchmark/体系,conformer 面向 ASR 训练吞吐,pwgan 面向 TTS 声码器训练吞吐,两者共用“训练 log + 关键字解析”的取数方式。
小结
tests/benchmark/pwgan/提供了一套结构清晰的 pwgan 声码器训练性能基准:run_all.sh以 stage 方式串起依赖安装、BZNSYP 数据集下载、mel 特征预处理与归一化,再到单卡/8 卡两种形态的批量压测;run_benchmark.sh通过--run-benchmark=true触发 train.py 中的参数覆盖逻辑,使 batch size 与迭代数完全由命令行决定;最终吞吐指标来自 trainer.py 打印的avg_ips(sequences/sec),并经由skip_steps+keyword契约被 benchmark 系统解析。掌握这条“脚本参数 → 训练入口覆盖 → 训练器日志指标”的完整链路,就能在 PaddleSpeech 中稳定复现并解读 Parallel WaveGAN 的训练性能数据。
- 人工智能
- 语音
- 音频
- 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.
相关推荐
PaddleSpeech Conformer 训练性能基准测试实践:AISHELL-1 Benchmark 脚本、运行流程与日志解析
PaddleSpeech Conformer 训练性能基准测试实践:AISHELL 1 Benchmark 脚本、运行流程与日志解析 本文围绕 PaddleSp
人工智能语音音频PaddleSpeech Parallel WaveGAN 声码器模块解析:训练脚本、配置参数与波形合成实战
PaddleSpeech Parallel WaveGAN 声码器模块解析:训练脚本、配置参数与波形合成实战 导读 本文以 PaddleSpeech 仓库中 p
人工智能语音音频PaddleSpeech Parallel WaveGAN 训练更新器(PWGUpdater)源码解析:GAN 声码器的训练与评估全流程
PaddleSpeech Parallel WaveGAN 训练更新器(PWGUpdater)源码解析:GAN 声码器的训练与评估全流程 本篇技术指南以 Pad
人工智能语音音频NLP媒体生成
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考