- 人工智能
- 语音
- 音频
【免费下载链接】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 语音识别模型的训练性能基准测试(benchmark)文档展开,完整讲解tests/benchmark/conformer/目录下环境准备、单卡/8 卡运行脚本、参数配置与日志产出规范;读者读完后可在标准 GPU 环境中复现 Conformer 的 ips(sent./sec)性能数据,理解--benchmark-batch-size、--benchmark-max-step等参数如何作用于训练器,以及最终 JSON 日志中FINAL_RESULT等字段的生成逻辑。
基准测试目标与文件组织
tests/benchmark/conformer/是 PaddleSpeech 针对 Conformer ASR 模型构建的性能基准测试目录,核心目标是在固定硬件、固定软件环境下,量化模型在单卡与 8 卡两种运行模式下的训练速度,指标单位为ips(sent./sec,每秒处理句子数)。测试数据与模型取自 AISHELL-1 数据集的 ASR 示例(examples/aishell/asr1),从而保证性能数据可在相同条件下复现与横向对比。
根据 README 给出的文件清单,一个完整的 benchmark 目录组织如下:
└── benchmark # 模型名 ├── README.md # 运行文档 ├── analysis.py # log解析脚本,每个框架尽量统一 ├── recoder_mp_bs16_fp32_ngpu1.txt # 单卡数据 ├── recoder_mp_bs16_fp32_ngpu8.txt # 8卡数据 ├── prepare.sh # 竞品PyTorch运行环境搭建 ├── run_benchmark.sh # 运行脚本(包含性能、收敛性) ├── run_analysis_mp.sh # 分析8卡的脚本 ├── run_analysis_sp.sh # 分析单卡的脚本 ├── log │ ├── log_sp.out # 单卡的结果 │ └── log_mp.out # 8卡的结果 └── run.sh # 全量运行脚本当前仓库中该目录实际包含 README、prepare.sh、run.sh 与 run_benchmark.sh 四个文件;README 清单中列出的recoder_*.txt、log/等为运行后产出的结果文件,analysis.py等日志解析脚本则统一采用 PaddlePaddle 官方 benchmark 仓库中的通用版本(run_benchmark.sh 第 73 行通过source ${BENCHMARK_ROOT}/scripts/run_model.sh引入该解析流程),各框架尽量保持解析逻辑统一,以方便跨框架对比。
环境要求:物理环境与 Docker 镜像
基准测试的有效性高度依赖环境的可复现性,文档明确给出了标准测试环境:
物理环境(单机,覆盖单卡与 8 卡两种规模;多机 32 卡方案在文档中标注为 TODO):
| 项目 | 规格 |
|---|---|
| 系统 | Ubuntu 16.04.6 LTS |
| GPU | Tesla V100-SXM2-16GB × 8 |
| CPU | Intel(R) Xeon(R) Gold 6148 CPU @ 2.40GHz × 96 |
| Driver Version | 440.64.00 |
| 内存 | 440 GB |
| CUDA / cuDNN | cuda 10.2 / cuDNN 7 |
Docker 镜像(保证软件栈一致的标准执行环境):
- 镜像版本:
registry.baidubce.com/paddlepaddle/paddle:2.1.0-gpu-cuda10.2-cudnn7 - CUDA 版本:10.2
- cuDNN 版本:7
run.sh 第 2 行进一步注明了可稳定复现性能的执行环境:标准 docker 环境内 py37,paddle=2.1.2, py=37。环境搭建的第一步是按 安装文档 完成 PaddleSpeech 的安装。
第一步:准备环境(prepare.sh)
按 README 指示,环境准备只需一条命令:
bash prepare.sh从 prepare.sh 源码看,该脚本完成了三件事:
- 安装 PaddleSpeech:
cd ../../../ && pip install -e .,以可编辑模式安装当前仓库; - 进入示例目录:
pushd ../../../examples/aishell/asr1,即 AISHELL-1 的 ASR1(Conformer 架构)示例; - 准备数据:
bash run.sh --stage 0 --stop_stage 0,只执行run.sh的第 0 阶段(数据下载、转 manifest 与词表等前置流程),不启动训练。
数据准备完成后,examples/aishell/asr1下会生成训练所需的data/manifest.train、data/manifest.dev、data/manifest.test与data/lang_char/vocab.txt,这些路径正是 conf/conformer.yaml 中train_manifest、dev_manifest、test_manifest、vocab_filepath字段所引用的文件。
第二步:全量运行基准测试(run.sh)
bash run.shrun.sh 是全量运行脚本,其完整逻辑可以拆为四段:
1)环境固定与日志路径。脚本头部先记录CUR_DIR=${PWD}(即PaddleSpeech/tests/benchmark/conformer),日志目录通过环境变量LOG_PATH_INDEX_DIR指定(benchmark 系统会注入该参数),未指定时默认当前目录;随后执行sed -i '/set\ -xe/d' run_benchmark.sh去掉子脚本的严格模式,避免单次失败中断整个矩阵扫描。
2)切换基准训练配置。脚本进入examples/aishell/asr1后source path.sh(path.sh 中定义了MAIN_ROOT、BIN_DIR等关键变量),然后:
mkdir -p conf/benchmark cp conf/conformer.yaml conf/benchmark/conformer.yaml sed -i "s/ accum_grad: 2/ accum_grad: 1/g" conf/benchmark/conformer.yaml即拷贝一份基准专用配置,并把梯度累积accum_grad调小为 1,使 benchmark 只测训练吞吐、不受累积步长影响。需要注意:当前仓库中 conf/conformer.yaml 的accum_grad默认值为 8(第 77 行),sed规则匹配的是accum_grad: 2,因此复现时应以实际配置文件中该字段的真实取值为准确认替换是否生效。
3)性能扫描矩阵。脚本以两层循环遍历精度与 batch size:
fp_item_list=(fp32) # 精度维度,当前仅 fp32 bs_item=(16) # 批大小维度,当前仅 bs16每个组合先后执行两种运行模式,并tee到标准日志文件:
| 运行模式 | 命令要点 | 输出日志 |
|---|---|---|
| 多卡 mp | CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 ... ngpu=8 | ${log_path}/speech_conformer_bs16_fp32_speed_8gpus8p |
| 单卡 sp | CUDA_VISIBLE_DEVICES=0 ... ngpu=1 | ${log_path}/speech_conformer_bs16_fp32_speed_1gpus |
每次任务之间sleep 60,用于冷却与释放显存,保证多次测量之间相互独立。
4)调用 run_benchmark.sh 执行单次任务。两种模式最终都调用同一脚本,参数传递顺序为:${run_mode} ${config_path} ${decode_config_path} ${output} ${seed} ${ngpu} ${profiler_options} ${bs_item} ${fp_item} ${model_item},其中config_path=conf/benchmark/conformer.yaml、decode_config_path=conf/tuning/decode.yaml、output=exp/conformer、seed=0、model_item=conformer。
run_benchmark.sh 参数与执行细节
run_benchmark.sh 是单次 benchmark 任务的核心,其_set_params函数定义了完整的参数表(均可省略、带默认值):
| 位置参数 | 变量名 | 默认值 | 说明 |
|---|---|---|---|
| $1 | run_mode | sp | 单卡 sp / 多卡 mp |
| $2 | config_path | conf/conformer.yaml | 训练配置 |
| $3 | decode_config_path | conf/tuning/decode.yaml | 解码配置 |
| $4 | output | exp/conformer | 实验输出目录 |
| $5 | seed | 0 | 随机种子 |
| $6 | ngpu | 1 | GPU 数量 |
| $7 | profiler_options | None | 非 None 时追加--profiler-options |
| $8 | batch_size | 32 | 基准 batch size |
| $9 | fp_item | fp32 | 精度 |
| $10 | model_item | conformer | 模型名 |
脚本中还有若干与日志解析规范强相关的固定参数,直接决定了后续 analysis 脚本如何提取性能数据:
benchmark_max_step=0 # 0 表示不提前终止 skip_steps=10 # 跳过前10个step(前期step耗时长,会拉低均值) keyword="ips:" # 从训练log中筛选含该关键字的行 index="1" mission_name="语音识别" direction_id="1" ips_unit="sent./sec" # 性能单位文件名与任务名的构造规则为:
model_name=${model_item}_bs${batch_size}_${fp_item} log_file=${run_log_path}/recoder_${model_item}_${run_mode}_bs${batch_size}_${fp_item}_ngpu${ngpu}即 README 文件清单中的recoder_sp_bs16_fp32_ngpu1.txt、recoder_mp_bs16_fp32_ngpu8.txt正是按该规则生成的结果文件。
训练命令的拼装与超时控制:_train函数把参数映射为训练器入参:
train_cmd="--config=${config_path} \ --decode_cfg=${decode_config_path} \ --output=${output} \ --seed=${seed} \ --ngpu=${ngpu} \ --benchmark-batch-size ${batch_size} \ --benchmark-max-step ${benchmark_max_step} "并以timeout 15m限时 15 分钟执行,超时或失败时导出job_fail_flag=1,成功则记SUCCESS——这正是结果 JSON 中JOB_FAIL_FLAG字段的来源。多卡(mp)模式下 Paddle 分布式训练会把各 worker 日志写入mylog/,脚本随后将mylog/workerlog.0(rank 0 worker 的日志)拷贝为最终的recoder_*.txt,保证单卡、多卡两种模式产出同构日志,供统一的解析脚本处理。
最后,脚本source ${BENCHMARK_ROOT}/scripts/run_model.sh:该脚本会对符合 benchmark 规范的日志调用analysis.py完成性能解析;如果只是本地调试、仅想产出训练 log 而不做联调解析,README 注释说明可以把该解析行注掉,但提交时必须打开。
源码级原理:benchmark 参数如何作用于训练器
--benchmark-batch-size与--benchmark-max-step并非 shell 层的"伪参数",而是由 S2T 训练入口原生支持的命令行选项。
参数定义:在 cli.py 中注册:
parser.add_argument('--benchmark-batch-size', ...) # batch size for benchmark. parser.add_argument('--benchmark-max-step', ...) # max iteration for benchmark.batch size 覆写与高频日志:在 trainer.py 的设备初始化阶段:
# profiler and benchmark options if hasattr(self.args, "benchmark_batch_size") and self.args.benchmark_batch_size: with UpdateConfig(self.config): self.config.batch_size = self.args.benchmark_batch_size self.config.log_interval = 1 logger.info(f"Benchmark reset batch-size: {self.args.benchmark_batch_size}")可以看到:--benchmark-batch-size会强制覆盖YAML 配置中的batch_size(这就是run.sh中把扫描值放在 shell 变量里、而不是直接改配置文件的原因);同时log_interval被置为 1,使每个 step 都输出一条日志,为按 step 粒度的吞吐解析提供数据。
max-step 提前终止:trainer.py 中:
if self.args.benchmark_max_step: ... if self.args.benchmark_max_step and self.iteration > self.args.benchmark_max_step: logger.info(f"Reach benchmark-max-step: {self.args.benchmark_max_step}")当指定了--benchmark-max-step(非 0)时,训练到达该 iteration 即停止,方便只测前 N 个 step 的速度;当前 conformer 基准将其设为 0(不提前终止,靠timeout 15m兜底)。
ips 指标的计算:训练主循环里用time.time()记录每个 batch 的处理耗时(trainer.py),并写入观察量observation['ips samples/s'];底层计时由 timer.py 的Timer类(elapsed_time)提供。日志行中的ips:关键字与run_benchmark.sh里的keyword="ips:"精确对应——analysis 脚本正是从含该关键字的日志行中按skip_steps=10跳过头 10 个 step 后统计吞吐,最终换算为sent./sec单位写入结果文件。
结果日志格式与 FINAL_RESULT
benchmark 系统最终把单次任务的元信息与解析出的性能指标合并为一段 JSON(README 给出的真实样例):
{"log_file": "recoder_sp_bs16_fp32_ngpu1.txt", "model_name": "Conformer", "mission_name": "one gpu", "direction_id": 1, "run_mode": "sp", "index": 1, "gpu_num": 1, "FINAL_RESULT": 23.228, "JOB_FAIL_FLAG": 0, "log_with_profiler": null, "profiler_path": null, "UNIT": "sent./sec" }各字段与脚本参数的对应关系:
| 字段 | 含义 | 来源 |
|---|---|---|
log_file | 原始训练日志文件名 | recoder_${model}_${run_mode}_bs${bs}_${fp}_ngpu${ngpu}规则 |
model_name/mission_name | 模型名与任务名 | model_item、mission_name参数 |
run_mode/gpu_num | sp 单卡 / mp 多卡、GPU 数 | run_mode、ngpu参数 |
FINAL_RESULT | 最终性能值(样例为 23.228) | analysis.py 从日志ips:行解析,跳过前 10 步 |
JOB_FAIL_FLAG | 0 成功 / 1 失败 | _train中job_fail_flag的导出 |
UNIT | 性能单位 | ips_unit="sent./sec" |
log_with_profiler/profiler_path | 是否附带 profiler 数据 | profiler_options参数,默认None |
复现注意事项小结
- 环境一致性:性能数据只在 README 声明的 V100×8 / cuda10.2-cudnn7 / paddle 2.1.x、py37 标准 docker 环境下具有可比性;换 GPU 型号、CUDA 版本或 paddle 版本后数据需重新标注。
- 数据前置:先跑
prepare.sh完成examples/aishell/asr1的 stage 0 数据准备,再执行run.sh,否则训练入口会因缺少 manifest 与词表而失败。 - 单次任务时长:
run_benchmark.sh对每次训练设 15 分钟超时(timeout 15m),bs16、fp32 的 Conformer 单卡任务在该窗口内应能产出足量 step;若 15 分钟内 step 数过少,skip_steps=10之后参与统计的样本会不足,影响 FINAL_RESULT 的稳定性。 - mp 日志取 rank 0:多卡结果文件是
mylog/workerlog.0的拷贝,单卡与多卡日志格式同构,可共用同一套analysis.py解析逻辑。 - 解析链路依赖 BENCHMARK_ROOT:本地只想看训练 log 时,可按 run_benchmark.sh 注释将
source run_model.sh与_run行注掉、改为直接调用_train;提交基准结果时必须恢复解析链路。
参考文件
- 基准测试运行文档:tests/benchmark/conformer/README.md
- 环境准备脚本:tests/benchmark/conformer/prepare.sh
- 全量运行脚本:tests/benchmark/conformer/run.sh
- 单次任务执行与解析脚本:tests/benchmark/conformer/run_benchmark.sh
- Conformer 训练配置:examples/aishell/asr1/conf/conformer.yaml
- 示例环境变量:examples/aishell/asr1/path.sh
- benchmark 参数定义:paddlespeech/s2t/training/cli.py
- 训练器 benchmark 逻辑:paddlespeech/s2t/training/trainer.py
- 计时工具:paddlespeech/s2t/training/timer.py
- 安装文档:docs/source/install.md
- 人工智能
- 语音
- 音频
【免费下载链接】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.
相关推荐
PaddleDetection TIPC Benchmark 训练性能测试全指南:从准备到日志解析
PaddleDetection TIPC Benchmark 训练性能测试全指南:从准备到日志解析 导读 :本文聚焦 PaddleDetection 仓库中 T
人工智能深度学习计算机视觉markdown-it 基准测试全解析:Benchmark 脚本、测试样本与性能解读
markdown it 基准测试全解析:Benchmark 脚本、测试样本与性能解读 导读 本文以 docs/benchmark.md https://link
开发工具CLI香山处理器 XSNoCTop:片上网络的 5 个可查证设计决策
香山处理器 XSNoCTop:片上网络的 5 个可查证设计决策 香山处理器(XiangShan)是一个开源 RISC V 高性能核心。当它被放进多核 SoC 时
硬件开发指令集高性能计算
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考