ESPnet 在 GigaSpeech 大规模英文语音识别上的 E-Branchformer 与 Conformer 实战指南
ESPnet 在 GigaSpeech 大规模英文语音识别上的 E-Branchformer 与 Conformer 实战指南
本篇技术指南以 ESPnet 开源语音处理工具包的 GigaSpeech ASR1 配方(egs2/gigaspeech/asr1/README.md)为骨架,系统讲解如何在 10000 小时级大规模英文语料 GigaSpeech 上训练端到端语音识别模型:涵盖数据准备与官方评分流程、两套经过充分调优的模型方案(E-Branchformer 与 Conformer)、完整可复现的训练配置与推理参数,并结合 E-Branchformer 编码器源码 剖析其架构原理。读完本文,你将掌握 GigaSpeech 配方的完整使用流程,能够直接复现 dev/test 集上的词错误率(WER)结果,并理解其中每个关键配置项的含义。
1. 配方概览:从数据准备到官方评分的一站式方案
GigaSpeech 是面向大规模监督式语音识别研究的开源英文语料库,其 ASR1 配方遵循 ESPnet 的 egs2 标准流程组织:训练、验证、测试集合分别命名为 train、dev、test,其中训练集使用 GigaSpeech 官方划分中规模最大的 train_xl 子集(约 10000 小时)。
该配方在数据准备与评测环节采用了与 GigaSpeech 官方仓库深度协同的设计:
- 数据准备:在 stage 1,local/data.sh 会
git cloneGigaSpeech 官方仓库(https://github.com/SpeechColab/GigaSpeech.git),利用其提供的toolkits/kaldi/gigaspeech_data_prep.sh标准脚本完成音频与标注的整理,并输出为 Kaldi 格式数据目录; - 评分:推理完成后,local/score.sh 调用官方仓库中的
GigaSpeech/utils/gigaspeech_scoring.py对ref.trn与hyp.trn进行评分。README 中特别强调:为保证跨工具包(toolkit)对比的公平性,这里报告的结果全部由官方评分脚本生成。
1.1 数据准备的三个关键阶段
local/data.sh 中的流程分为 stage 1–3:
| Stage | 作用 | 关键操作 |
|---|---|---|
| 1 | 校验并克隆官方仓库 | 检查 $GIGASPEECH/audio 目录与 GigaSpeech.json 是否存在,随后 git clone 官方仓库到本地 GigaSpeech/ 目录 |
| 2 | 生成 Kaldi 格式数据目录 | 在 GigaSpeech/ 内执行 ./toolkits/kaldi/gigaspeech_data_prep.sh --train-subset XL ${GIGASPEECH} ${abs_data_dir},随后把 gigaspeech_train_xl、gigaspeech_dev、gigaspeech_test 重命名为 train、dev、test |
| 3 | 修复数据目录 | 对三个子集执行 utils/fix_data_dir.sh,并删除 reco2dur 文件(注释说明该文件会导致后续 asr.sh 的 stage 4 报错) |
在运行任何阶段之前,需要先在 db.sh 中填写 GIGASPEECH= 变量为本地数据路径。该文件集中维护了所有语料的路径映射(downloads 表示配方可自动下载;GigaSpeech 体积庞大,需要手动下载后填写实际路径)。
2. 两套官方基线模型与评测结果
README 记录了两种编码器架构在 GigaSpeech 上的完整基线:E-Branchformer(较新)与 Conformer(较旧)。两套模型的环境快照与评测结果必须严格按原文档完整保留,它们是复现时校验环境与结果的基准。
2.1 E-Branchformer 基线
训练环境快照(原文档原文记录):
| 项 | 值 |
|---|---|
| date | Sat Jan 21 17:54:14 EST 2023 |
| python version | 3.9.15 (main, Nov 24 2022, 14:31:59) [GCC 11.2.0] |
| espnet version | espnet 202211 |
| pytorch version | pytorch 1.12.1 |
| Git hash | 197dc412eab82e9bab008f00fbcb922c824d8cf2(提交于 Sat Jan 21 13:59:20 2023 -0500) |
模型标识:asr_train_asr_e_branchformer_e17_size512_mlp3072_linear1024_layerdrop
- ASR 配置:conf/tuning/train_asr_e_branchformer_e17_size512_mlp3072_linear1024_layerdrop.yaml
- 预训练模型权重由
pyf98/gigaspeech_e_branchformer发布(原文档给出的外部模型链接,读者可自行前往对应模型托管平台获取)
WER 评测结果(由 GigaSpeech 官方评分脚本生成):
| dataset | Snt | Wrd | Corr | Sub | Del | Ins | Err | S.Err |
|---|---|---|---|---|---|---|---|---|
| decode_asr_asr_model_valid.acc.ave/dev | 5715 | 127790 | 92.2 | 5.7 | 2.0 | 2.8 | 10.6 | 69.9 |
| decode_asr_asr_model_valid.acc.ave/test | 19930 | 390744 | 91.5 | 6.4 | 2.1 | 2.0 | 10.5 | 63.3 |
表中各列含义:Snt 为句子数,Wrd 为词数,Corr/Sub/Del/Ins 分别为正确率、替换、删除、插入错误率(%),Err 为最终 WER(%),S.Err 为句子错误率(%)。解码模型为 valid.acc.ave(验证集准确率最高的平均模型)。
2.2 Conformer 基线
训练环境快照(原文档原文记录):
| 项 | 值 |
|---|---|
| date | Tue Mar 23 10:03:49 EDT 2021 |
| python version | 3.8.5 (default, Sep 4 2020, 07:30:14) [GCC 7.3.0] |
| espnet version | espnet 0.9.8 |
| pytorch version | pytorch 1.7.1 |
| Git hash | dcb5bdb2ffa34a9f44255c0b073759c5b9b3f86e(提交于 Sat Mar 13 10:16:16 2021 -0500) |
模型标识:asr_train_asr_raw_en_bpe5000(模型权重发布于 Zenodo 记录 4630406,原文档给出的外部链接)
WER 评测结果:
| dataset | Snt | Wrd | Corr | Sub | Del | Ins | Err | S.Err |
|---|---|---|---|---|---|---|---|---|
| decode_asr_asr_model_valid.acc.ave/dev | 5715 | 127790 | 92.0 | 6.0 | 2.1 | 2.9 | 10.9 | 70.9 |
| decode_asr_asr_model_valid.acc.ave/test | 19930 | 390744 | 91.2 | 6.7 | 2.1 | 2.0 | 10.8 | 64.2 |
结论要点:在相同的官方评分口径下,E-Branchformer 在 dev 集上 WER 从 10.9% 降至 10.6%,在 test 集上从 10.8% 降至 10.5%,词错误率全面优于 Conformer 基线,验证了其合并模块(merge module)对全局与局部上下文信息融合的有效性。
3. 核心训练配置深度解析
3.1 E-Branchformer 完整配置
asr_train_asr_e_branchformer_e17_size512_mlp3072_linear1024_layerdrop 使用的配置与默认配置 conf/train_asr_e_branchformer.yaml 完全一致,文件头部注释记录了训练背景:使用 5 张 A5000(24GB)GPU 训练约 8 天,编码器配置基于 egs2/librispeech/asr1 的 E-Branchformer 调优配置 演进而来。
训练调度与批处理
batch_type: numel # 按元素数量动态批处理
batch_bins: 35000000 # 每个 batch 的元素数上限(约 3500 万)
accum_grad: 4 # 梯度累积 4 步
max_epoch: 30 # 最多 30 个 epoch
patience: none # 不依赖早停
init: none # 不使用额外初始化
best_model_criterion:
- - valid
- acc # 以验证集 acc 为准
- max
keep_nbest_models: 10 # 保留 10 个最优模型(用于 valid.acc.ave 平均)
num_workers: 4 # DataLoader 工作进程数
unused_parameters: true # 允许 DDP 存在未使用的参数
numel 批处理模式按“参数元素总数”动态确定 batch 大小,能够在大规模、句长分布差异明显的语料(如 GigaSpeech)上显著提高 GPU 利用率;accum_grad: 4 等效于在不扩大单卡 batch 的前提下把有效 batch 扩大 4 倍。
E-Branchformer 编码器
encoder: e_branchformer
encoder_conf:
output_size: 512 # 模型维度(size)
attention_heads: 8 # 自注意力头数
attention_layer_type: rel_selfattn # 相对位置自注意力
pos_enc_layer_type: rel_pos # 相对位置编码
rel_pos_type: latest # 使用最新版相对位置实现
cgmlp_linear_units: 3072 # CGMLP 前馈宽度
cgmlp_conv_kernel: 31 # CGMLP 深度可分离卷积核
use_linear_after_conv: false
gate_activation: identity # 门控激活函数
num_blocks: 17 # 编码器层数
dropout_rate: 0.1
positional_dropout_rate: 0.1
attention_dropout_rate: 0.1
input_layer: conv2d # conv2d 下采样输入层
layer_drop_rate: 0.1 # 层丢弃(LayerDrop)比率
linear_units: 1024 # 辅助 FFN 中间维度
positionwise_layer_type: linear
macaron_ffn: true # 启用马卡龙 FFN
use_ffn: true # 每个块额外使用 FFN
merge_conv_kernel: 31 # 合并模块深度可分离卷积核
Transformer 解码器
decoder: transformer
decoder_conf:
attention_heads: 8
linear_units: 2048
num_blocks: 6
dropout_rate: 0.1
positional_dropout_rate: 0.1
self_attention_dropout_rate: 0.1
src_attention_dropout_rate: 0.1
layer_drop_rate: 0.2 # 解码器同样启用 LayerDrop
模型、优化器与数据增强
ctc_conf:
ignore_nan_grad: true
model_conf:
ctc_weight: 0.3 # CTC 与注意力联合训练,CTC 权重 0.3
lsm_weight: 0.1 # 标签平滑 0.1
length_normalized_loss: false
optim: adam
optim_conf:
lr: 0.0015
scheduler: warmuplr
scheduler_conf:
warmup_steps: 25000
frontend_conf:
n_fft: 512 # 与 fbank.conf 一致的 FFT 点数
hop_length: 256 # 帧移(对应 10ms @16kHz)
specaug: specaug
specaug_conf:
apply_time_warp: true # 时间扭曲
time_warp_window: 5
time_warp_mode: bicubic
apply_freq_mask: true # 频率掩蔽
freq_mask_width_range: [0, 30]
num_freq_mask: 2
apply_time_mask: true # 时间掩蔽
time_mask_width_range: [0, 40]
num_time_mask: 2
解码器保留了 layer_drop_rate: 0.2 的正则策略,编码器侧则依赖 17 层深模型 + LayerDrop + SpecAugment 的组合来抑制大规模数据下的过拟合;ctc_weight: 0.3 表示混合 CTC/注意力训练,兼顾对齐鲁棒性与注意力解码精度。
3.2 Conformer 调优配置对照
Conformer 基线对应的调优配置为 conf/tuning/train_asr_conformer6_n_fft512_hop_length256.yaml,与 E-Branchformer 配置在训练调度(numel/35000000、accum_grad: 4、warmuplr、ctc_weight: 0.3、lsm_weight: 0.1)及 SpecAugment 参数上保持一致,差异集中在编码器结构:
encoder: conformer
encoder_conf:
output_size: 512
attention_heads: 8
linear_units: 2048 # FFN 中间维度 2048
num_blocks: 12 # 12 层
dropout_rate: 0.1
positional_dropout_rate: 0.1
attention_dropout_rate: 0.1
input_layer: conv2d
normalize_before: true
macaron_style: true # 马卡龙式 FFN
pos_enc_layer_type: "rel_pos"
selfattention_layer_type: "rel_selfattn"
activation_type: "swish"
use_cnn_module: true # 使用 CNN 模块
cnn_module_kernel: 31
对比可见:Conformer 用 12 层 linear_units=2048 的堆叠;而 E-Branchformer 用 17 层、cgmlp_linear_units=3072、linear_units=1024 的双分支 + 合并结构,层数更深但单层参数更精简,最终以更低的 WER 胜出。
4. 训练与推理实操流程
4.1 一键训练入口 run.sh
train_set="train"
valid_set="dev"
test_sets="dev test"
asr_config=conf/train_asr_e_branchformer.yaml
lm_config=conf/train_lm.yaml
inference_config=conf/decode_asr.yaml
speed_perturb_factors="" # 不启用变速扰动
./asr.sh \
--audio_format flac.ark \
--lang en \
--ngpu 5 \
--nj 64 \
--gpu_inference true \
--inference_nj 5 \
--use_lm false \
--nbpe 5000 \
--max_wav_duration 30 \
--speed_perturb_factors "${speed_perturb_factors}" \
--asr_config "${asr_config}" \
--lm_config "${lm_config}" \
--inference_config "${inference_config}" \
--train_set "${train_set}" \
--valid_set "${valid_set}" \
--test_sets "${test_sets}" \
--bpe_train_text "data/${train_set}/text" \
--local_score_opts "--inference_config ${inference_config} --use_lm false" "$@"
各参数要点:
--audio_format flac.ark:GigaSpeech 音频以 FLAC 归档格式提供,配方按flac.ark读取;--nbpe 5000:使用 5000 词元的 SentencePiece 子词模型,训练文本来自data/train/text;--ngpu 5/--nj 64:5 卡 DDP 训练、64 个并行任务做特征提取等预处理;--gpu_inference true/--inference_nj 5:推理阶段在 GPU 上并行执行;--use_lm false:该基线直接使用联合训练模型解码而不外挂语言模型(conf/train_lm.yaml 中仍提供了 LSTM LM 配置,rnn_type: lstm、nlayers: 2、unit: 2024,需要时可开启);--max_wav_duration 30:丢弃时长超过 30 秒的超长音频,避免训练时 OOM。
4.2 推理(解码)配置 conf/decode_asr.yaml
beam_size: 20 # 束搜索宽度
ctc_weight: 0.2 # 解码时 CTC 权重(低于训练的 0.3)
lm_weight: 0.0 # 无 LM 参与
penalty: 0.0 # 长度惩罚
maxlenratio: 0.0
minlenratio: 0.0
解码阶段将 CTC 权重调整为 0.2,是联合 CTC/注意力模型常用的“训练侧重注意力、解码放宽 CTC”策略;在关闭 LM 的配置下,lm_weight: 0.0 保证打分仅来自 ASR 模型自身。最终解码结果目录形如 exp/asr_train_asr_e_branchformer_.../decode_asr_asr_model_valid.acc.ave/{dev,test},随后由 local/score.sh 调用 gigaspeech_scoring.py 对 cer、wer、ter 三种指标输出 score_* 目录,其中 WER 即 README 表格所报告的数字。
5. 源码级原理:E-Branchformer 编码器
E-Branchformer 是 Branchformer 的改进版本(论文:E-Branchformer: Branchformer with Enhanced merging for speech recognition, SLT 2022),其核心实现位于 espnet2/asr/encoder/e_branchformer_encoder.py。
从源码结构看,编码器逐层构建 EBranchformerEncoderLayer,每个块内部并行运行两条分支:
- 全局分支:标准/高效自注意力(配置中为
rel_selfattn相对位置自注意力,对应源码引入的RelPositionMultiHeadedAttention等实现); - 局部分支:卷积门控 MLP(CGMLP),由 espnet2/asr/layers/cgmlp.py 中的
ConvolutionalGatingMLP提供,cgmlp_conv_kernel: 31控制其中深度可分离卷积的核宽,负责捕获局部上下文; - 合并模块(merge module):两分支输出经拼接后用带
merge_conv_kernel: 31的深度可分离卷积融合,这是 E-Branchformer 相对 Branchformer 的关键增强——通过可学习的卷积合并取代简单的加权求和,使全局与局部信息得到更充分的交互。
配置中 macaron_ffn: true 与 use_ffn: true 对应源码中在马卡龙位置与块尾部各保留一个 FFN 模块(feed_forward_macaron 与 feed_forward 参数),构成类似 Conformer 的马卡龙残差结构;layer_drop_rate: 0.1 则对应训练时随机跳过部分块的正则机制。此外,espnet2/asr/encoder/e_branchformer_ctc_encoder.py 还提供了面向 CTC 分支的 E-Branchformer 编码器变体,可供需要额外 CTC 建模的定制场景参考。配置中 rel_pos_type: latest 表明采用相对位置编码的最新实现路径(源码同时维护 LegacyRelPositionalEncoding 以兼容旧配方)。
6. 复现建议与注意事项
- 环境对齐:README 给出的两套环境快照(E-Branchformer:espnet 202211 + pytorch 1.12.1 + python 3.9.15;Conformer:espnet 0.9.8 + pytorch 1.7.1 + python 3.8.5)是复现结果的前提;使用更新版本时,结果可能存在合理波动;
- 数据路径:先在 db.sh 中正确设置
GIGASPEECH,并确保audio目录与GigaSpeech.json结构完整,否则 stage 1 会直接报错退出; - 硬件需求:E-Branchformer 基线按 5×A5000(24GB)训练约 8 天设计,若显存或卡数不足,可优先调整
batch_bins、accum_grad与max_wav_duration; - 评测口径:务必使用 GigaSpeech 官方评分脚本(
gigaspeech_scoring.py)生成结果,与论文及其他工具包对比时才能保证公平一致; - 解码阶段:保持
ctc_weight: 0.2与beam_size: 20的组合即可复现 README 中的 WER 数字;若希望进一步提升,可尝试开启 conf/train_lm.yaml 中的 LSTM LM 并调整lm_weight。
7. 延伸阅读
- 配方全部脚本与配置:查看 egs2/gigaspeech/asr1 目录下的
run.sh、asr.sh、cmd.sh、path.sh及conf/目录; - ESPnet2 通用训练入口:espnet2/tasks/asr.py 与
espnet2/asr/模块下的编码器、解码器、CTC 实现; - E-Branchformer 编码器源码:espnet2/asr/encoder/e_branchformer_encoder.py、espnet2/asr/layers/cgmlp.py;
- 模型权重下载与本地推理:可参照配方输出目录结构(
exp/与dump/)及 tools/README.md 中的环境配置说明自行组织。