- 人工智能
- 语音
- 音频
- 深度学习
- NLP
【免费下载链接】espnet
End-to-End Speech Processing Toolkit
本篇技术指南基于 ESPnet 2 开源语音处理工具包中的 Kathbath 语音识别配方(egs2/kathbath/asr1),系统讲解如何利用 E-Branchformer 编码器 + Transformer 解码器架构,在 12 种印度语言上完成从数据下载、格式转换、BPE 分词、模型训练到 WER/CER 评测的完整流程。读者读完本文后,将掌握该配方的全部关键参数含义、可复现的 WER/CER 结果基线,以及如何将预训练模型迁移到自己的推理场景。
数据集与任务背景:Kathbath 与 IndicSUPERB
Kathbath 是 IndicSUPERB 基准推出的多语种语音数据集,覆盖12 种印度语言:乌尔都语(urdu)、泰卢固语(telugu)、卡纳达语(kannada)、马拉雅拉姆语(malayalam)、孟加拉语(bengali)、奥里亚语(odia)、古吉拉特语(gujarati)、印地语(hindi)、泰米尔语(tamil)、旁遮普语(punjabi)、梵语(sanskrit)和马拉地语(marathi)。
该数据集具有两大设计特点,对 ASR 鲁棒性研究非常有价值:
- 干净与噪声双版本:数据分为
kb_data_clean_m4a(干净语音)与kb_data_noisy_m4a(噪声语音)两部分; - 说话人 known/unknown 双测试集:测试阶段包含
test(总集)、test_known(已知说话人)、test_noisy(噪声)、test_known_noisy(已知说话人 + 噪声)四类评测划分。
在 egs2/kathbath/asr1/local/data.sh 中可以看到全部数据源的下载入口被定义为train_data_url、valid_data_url、clean_test_known_data_url、clean_test_unknown_data_url、noisy_test_known_data_url、noisy_test_unknown_data_url以及干净/噪声两份转录文件transcript_clean_url、transcript_noisy_url,托管在公共对象存储服务上,配方会在 stage 1 自动执行wget+tar完成下载与解包。
配方结构速览
该配方目录是标准的 ESPnet2 recipe 布局,核心文件如下:
| 文件 | 作用 |
|---|---|
| run.sh | 配方入口,定义语言、数据集划分与训练/解码参数 |
| asr.sh | 通用 ASR 流程脚本,按 stage 串联数据准备、分词、训练、解码、评测 |
| local/data.sh | Kathbath 专属的数据下载与 Kaldi 风格数据目录构建脚本 |
| conf/train_asr.yaml | 模型结构(E-Branchformer + Transformer)与训练超参配置 |
| conf/decode_asr.yaml | 解码(beam search + CTC 联合)配置 |
| db.sh | 数据集根路径配置,其中KATHBATH=downloads表示可自动下载 |
| cmd.sh | 并行执行后端选择(local/sge/slurm 等) |
| path.sh | 环境变量与工具链路径加载 |
环境与硬件基线
原 README 记录了本次基线实验的完整运行环境(egs2/kathbath/asr1/README.md):
| 项目 | 值 |
|---|---|
| 实验日期 | Thu Jul 27 01:21:08 IST 2023 |
| Python | 3.8.10 (GCC 9.4.0) |
| ESPnet 版本 | espnet 202304 |
| PyTorch | 1.10.1+cu113 |
| Git hash | 4c8aeda5de44f08d3617cdfc7aeb30bdf3d53d72 |
| GPU | 单张 NVIDIA GeForce RTX 3090 24GB |
| 模型参数量 | 35M |
| 模型文件大小 | 140.03 MB |
| 训练耗时 | 16349 ~ 34072 秒(约 4.5 ~ 9.5 小时) |
值得注意:训练配置 conf/train_asr.yaml 首行注释写的是"A40 (48 GB) x 1 GPUs",而 README 记录为 3090 24GB,两者存在出入;从 README 的实测记录看,最终基线是在单张 24GB 显存的 3090 上完成的,这也说明该 35M 参数模型对显存要求并不苛刻。
端到端复现:从数据下载到模型训练
第 1 步:配置数据根目录
在 db.sh 中,KATHBATH=downloads表示数据由配方自动下载到本地downloads目录;若你的数据已手动放置在其他路径,将该项改为对应绝对路径即可。local/data.sh 会检查KATHBATH是否为空,为空则报错退出,因此这一步是必须的。
第 2 步:下载与数据准备(stage 1–2)
local/data.sh 承担两个 stage:
- stage 1(数据下载):依次下载噪声测试集、噪声转录、干净测试集、训练集、验证集与干净转录,解包后写入
download_done标记文件;若标记已存在则跳过。 - stage 2(数据准备):遍历
kb_data_clean_m4a与kb_data_noisy_m4a下每种语言、每个划分目录,核心操作包括:- 使用
ffmpeg将.m4a统一转为16kHz 单声道.wav; - 生成 Kaldi 风格数据目录(
wav.scp、utt2spk、text、spk2utt); - 对文本做清洗,将不间断空格
\xC2\xA0替换为普通空格; - 调用
utils/fix_data_dir.sh校验数据目录一致性。
- 使用
其中噪声数据中valid_noisy划分会被跳过(见if [ "$splitname" == "valid_noisy" ]分支),因为噪声版本不提供独立验证集。最终得到data/<lang>/train、data/<lang>/valid、data/<lang>/test、data/<lang>/test_known、data/<lang>/test_noisy、data/<lang>/test_known_noisy等目录。
第 3 步:训练入口 run.sh
run.sh 默认以lang="urdu"运行(即单语言训练,每个语言一个独立实验),并将所有参数透传给通用训练脚本 asr.sh:
lang="urdu" train_set="$lang"/"train" valid_set="$lang"/"valid" test_sets="$lang/test $lang/test_known $lang/test_noisy $lang/test_known_noisy" asr_config=conf/train_asr.yaml inference_config=conf/decode_asr.yaml ./asr.sh \ --lang $lang \ --ngpu 1 \ --stage 1 \ --nj 32 \ --inference_nj 32 \ --token_type "bpe" \ --nbpe 500 \ --max_wav_duration 30 \ --feats_type raw \ --use_lm false \ --asr_config "${asr_config}" \ --inference_config "${inference_config}" \ --train_set "${train_set}" \ --valid_set "${valid_set}" \ --test_sets "${test_sets}" "$@"关键参数含义如下:
| 参数 | 值 | 说明 |
|---|---|---|
--lang | urdu | 当前训练语言,可切换为 telugu/kannada 等其余 11 种 |
--ngpu | 1 | 单卡训练 |
--nj/--inference_nj | 32 | 特征提取与解码阶段的并行 job 数 |
--token_type | bpe | 词元类型;孟加拉语、古吉拉特语使用char,其余语言用bpe |
--nbpe | 500 | BPE 词表大小(梵语为 200,见结果表中的实验名) |
--max_wav_duration | 30 | 最长音频时长(秒),超出会被过滤;asr.sh 默认值为 20,此处被覆盖为 30 |
--feats_type | raw | 直接使用原始波形,由前端在线计算 Fbank 特征 |
--use_lm | false | 不训练语言模型,解码仅依赖模型内部 |
--train_set/--valid_set/--test_sets | 上述划分 | 训练、验证与 4 个测试集 |
运行./run.sh时,asr.sh 会按 stage 依次执行:数据准备 → 统计量计算与 CMVN → BPE 词表训练 → 特征 dump → 训练 → 解码 → 打分。由于--use_lm false,流程会跳过 LM 训练阶段。
第 4 步:解码与评估
解码配置见 conf/decode_asr.yaml:
beam_size: 20 ctc_weight: 0.3 lm_weight: 0.0 maxlenratio: 0.0 minlenratio: 0.0 penalty: 0.0即使用beam size 20的集束搜索,以ctc_weight: 0.3将 CTC 路径与注意力解码路径联合评分(lm_weight: 0.0对应不加载外部 LM),maxlenratio/minlenratio均为 0(由模型自动推断输出长度),无长度惩罚。评测环节由 asr.sh 内部调用score_sclite.sh生成 WER,字符级语言则额外产出 CER。
模型配置深度解析:train_asr.yaml
完整训练配置见 conf/train_asr.yaml,下面分层解析。
E-Branchformer 编码器
encoder: e_branchformer encoder_conf: output_size: 256 attention_heads: 4 attention_layer_type: rel_selfattn pos_enc_layer_type: rel_pos rel_pos_type: latest cgmlp_linear_units: 1024 cgmlp_conv_kernel: 31 use_linear_after_conv: false gate_activation: identity num_blocks: 12 dropout_rate: 0.1 positional_dropout_rate: 0.1 attention_dropout_rate: 0.1 input_layer: conv2d layer_drop_rate: 0.0 linear_units: 1024 positionwise_layer_type: linear use_ffn: true macaron_ffn: true merge_conv_kernel: 31E-Branchformer 是 Branchformer 的增强版(参考论文:Kwangyoun Kim et al.,"E-Branchformer: Branchformer with Enhanced merging for speech recognition," SLT 2022),其核心思想是双分支并行:一个分支使用自注意力捕捉全局依赖,另一个分支使用**卷积门控 MLP(ConvolutionalGatingMLP,CGMLP)**捕捉局部依赖,最后通过一个带深度可分离卷积的merge 模块将两个分支的输出增强式融合。在 ESPnet 中的实现位于 espnet2/asr/encoder/e_branchformer_encoder.py:EBranchformerEncoderLayer同时持有attn(注意力分支)、cgmlp(卷积门控分支)与可选的feed_forward/feed_forward_macaron(FFN 与 Macaron-FFN 分支),并通过merge_conv_kernel控制融合卷积核大小(见__init__参数merge_conv_kernel: int = 3)。该文件还提供了面向 CTC 的 e_branchformer_ctc_encoder.py 变体。
本配方对 E-Branchformer 的关键设定:
output_size: 256:模型维度(hidden size),配合attention_heads: 4(每头 64 维);attention_layer_type: rel_selfattn+pos_enc_layer_type: rel_pos+rel_pos_type: latest:使用相对位置自注意力(RelPositionMultiHeadedAttention),对长序列与噪声场景更友好;cgmlp_linear_units: 1024+cgmlp_conv_kernel: 31:CGMLP 分支的线性单元数与卷积核大小,大卷积核(31)提供更宽的局部感受野;use_ffn: true+macaron_ffn: true:同时启用 FFN 与 Macaron-FFN 分支,属于 Branchformer 家族的"三/四分支"增强配置;num_blocks: 12:12 个编码器层;input_layer: conv2d:Conv2d 子采样将 80 维 Fbank 输入降采样 4 倍,缩短序列长度;- 各类 dropout 统一为
0.1,layer_drop_rate: 0.0(不使用随机层丢弃)。
Transformer 解码器
decoder: transformer decoder_conf: attention_heads: 4 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.06 层 Transformer 解码器,linear_units: 2048的 FFN 隐藏层,4 头注意力,dropout 均为 0.1。
模型级损失与特征前端
model_conf: ctc_weight: 0.3 lsm_weight: 0.1 length_normalized_loss: false frontend_conf: n_fft: 512 win_length: 400 hop_length: 160ctc_weight: 0.3:训练时 CTC 与注意力损失的混合权重(与解码端ctc_weight: 0.3一致);lsm_weight: 0.1:标签平滑(label smoothing)强度;- 前端为短时傅里叶变换:
n_fft: 512、win_length: 400(25ms 窗)、hop_length: 160(10ms 帧移),对应 16kHz 采样率。
训练策略
seed: 2022 num_workers: 4 batch_type: numel batch_bins: 10000000 accum_grad: 4 max_epoch: 70 patience: none init: none best_model_criterion: - - valid - acc - max keep_nbest_models: 10 use_amp: true optim: adam optim_conf: lr: 0.002 weight_decay: 0.000001 scheduler: warmuplr scheduler_conf: warmup_steps: 15000 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 - 27 num_freq_mask: 2 apply_time_mask: true time_mask_width_ratio_range: - 0. - 0.05 num_time_mask: 5训练侧要点:
- 动态批大小:
batch_type: numel按元素数量(token 总数)动态组 batch,batch_bins: 10000000为上限,配合accum_grad: 4梯度累积; - 训练轮数与选优:
max_epoch: 70,best_model_criterion以验证集准确率(acc)最大化为标准,keep_nbest_models: 10保留 10 个最优检查点; - 优化器与调度:Adam(lr=0.002,weight_decay=1e-6)+ warmuplr 预热调度(15000 步预热);
- SpecAugment 数据增强:启用时间弯曲(窗口 5、bicubic 插值)、频率掩蔽(每次最多 2 个,宽度 0–27)与时间掩蔽(每次最多 5 个,宽度为序列长度的 0–5%),对噪声鲁棒性贡献明显;
- 混合精度:
use_amp: true开启自动混合精度训练,这也是单卡 3090 上数小时即可收敛的原因之一。
实验结果:12 种语言的 WER 与 CER
以下是 README 记录的基线结果(评测集含干净/噪声 × known/unknown 组合),WER如下:
| lang | exp | test | test_known | test_known_noisy | test_noisy |
|---|---|---|---|---|---|
| urdu | asr_train_asr_raw_urdu_bpe500 | 14.8 | 13.1 | 15.8 | 21.1 |
| telugu | asr_train_asr_raw_telugu_bpe500 | 25.1 | 21.2 | 23.9 | 28.4 |
| kannada | asr_train_asr_raw_kannada_bpe500 | 19.2 | 17.9 | 18.7 | 27.4 |
| malayalam | asr_train_asr_raw_malayalam_bpe500 | 39.2 | 30.0 | 31.3 | 43.1 |
| bengali | asr_train_asr_raw_bengali_char | 17.2 | 13.2 | 16.2 | 21.8 |
| odia | asr_train_asr_raw_odia_bpe500 | 23.6 | 16.7 | 19.9 | 27.5 |
| gujarati | asr_train_asr_raw_gujarati_char | 19.3 | 15.1 | 18.4 | 27.2 |
| hindi | asr_train_asr_raw_hindi_bpe500 | 12.5 | 10.1 | 12.6 | 14.3 |
| tamil | asr_train_asr_raw_tamil_bpe500 | 23.3 | 20.1 | 24.3 | 24.2 |
| punjabi | asr_train_asr_raw_punjabi_bpe500 | 15.9 | 14.3 | 14.2 | 24.9 |
| sanskrit | asr_train_asr_raw_sanskrit_bpe200 | 40.3 | 27.7 | 39.3 | 49.8 |
| marathi | asr_train_asr_raw_marathi_bpe500 | 16.6 | 15.1 | 16.7 | 19.7 |
CER如下:
| lang | exp | test | test_known | test_known_noisy | test_noisy |
|---|---|---|---|---|---|
| urdu | asr_train_asr_raw_urdu_bpe500 | 4.8 | 3.7 | 4.7 | 7.7 |
| telugu | asr_train_asr_raw_telugu_bpe500 | 5.0 | 3.7 | 4.6 | 7.3 |
| kannada | asr_train_asr_raw_kannada_bpe500 | 4.0 | 3.3 | 3.9 | 7.1 |
| malayalam | asr_train_asr_raw_malayalam_bpe500 | 7.8 | 5.4 | 6.2 | 9.4 |
| bengali | asr_train_asr_raw_bengali_char | 3.9 | 2.6 | 3.7 | 5.6 |
| odia | asr_train_asr_raw_odia_bpe500 | 6.0 | 3.3 | 4.4 | 8.1 |
| gujarati | asr_train_asr_raw_gujarati_char | 5.2 | 3.5 | 4.9 | 9.1 |
| hindi | asr_train_asr_raw_hindi_bpe500 | 4.2 | 3.1 | 4.3 | 5.4 |
| tamil | asr_train_asr_raw_tamil_bpe500 | 4.3 | 3.3 | 4.9 | 4.7 |
| punjabi | asr_train_asr_raw_punjabi_bpe500 | 5.2 | 3.8 | 4.5 | 9.4 |
| sanskrit | asr_train_asr_raw_sanskrit_bpe200 | 10.1 | 5.6 | 9.8 | 14.6 |
| marathi | asr_train_asr_raw_marathi_bpe500 | 4.1 | 3.8 | 4.3 | 5.2 |
对结果的两点观察(基于上表可确认的事实):
- 语言间难度差异显著:印地语(hindi)表现最好(test WER 12.5 / CER 4.2),而马拉雅拉姆语(malayalam)与梵语(sanskrit)难度最高(test WER 接近 40%),与数据量与书写系统复杂度相关;
- 噪声是主要挑战:几乎所有语言的
test_noisy都是最差划分(如 urdu 从 14.8 升至 21.1,sanskrit 从 40.3 升至 49.8),说明在未见噪声场景下仍存在明显性能回落;而test_known(已知说话人)普遍优于test,反映出说话人泛化同样影响指标。
另外注意实验命名细节:绝大多数语言使用bpe500(BPE 词表 500),孟加拉语与古吉拉特语使用char(字符级分词),梵语在 WER/CER 表中记为bpe200。分词方式与语言文字特性直接相关。
预训练模型
README 同时提供了每种语言对应的预训练模型发布记录(作者账号viks66,发布在 Hugging Face Hub),模型名与 WER/CER 表中的实验名一一对应,可直接检索,例如:
| lang | 预训练模型标识 |
|---|---|
| urdu | asr_train_asr_raw_urdu_bpe500 |
| telugu | asr_train_asr_raw_telugu_bpe500 |
| kannada | asr_train_asr_raw_kannada_bpe500 |
| malayalam | asr_train_asr_raw_malayalam_bpe500 |
| bengali | asr_train_asr_raw_bengali_char |
| odia | asr_train_asr_raw_odia_bpe500 |
| gujarati | asr_train_asr_raw_gujarati_char |
| hindi | asr_train_asr_raw_hindi_bpe500 |
| tamil | asr_train_asr_raw_tamil_bpe500 |
| punjabi | asr_train_asr_raw_punjabi_bpe500 |
| sanskrit | asr_train_asr_raw_sanskrit_bpe500(WER/CER 表为 bpe200,请以 Hub 实际为准) |
| marathi | asr_train_asr_raw_marathi_bpe500 |
获取预训练模型后,可通过 ESPnet2 的标准推理流程(espnet2.bin.asr_inference)加载model.pth与配套config.yaml完成单句解码,无需重新训练。若需自行复现,直接按上文步骤在对应语言上运行./run.sh --lang <语言>即可,单卡 3090 数小时内可完成全部训练与评估。
复现与调参建议
- 数据与磁盘:Kathbath 含干净/噪声两版完整音频,下载量较大,请确保
KATHBATH目录所在磁盘空间充足;local/data.sh中的download_done与dataprep_done标记可保证断点续跑不重复处理。 - 并行度:
--nj 32适合多核机器;资源紧张时可降低nj/inference_nj,仅影响预处理与解码速度。 - 分词选择:对孟加拉语、古吉拉特语等,原配方选择字符级(
--token_type char),如需 BPE 可参照其他语言的bpe500配置自行切换。 - 训练成本:README 记录的 16349~34072 秒训练时长是在开启
use_amp与accum_grad: 4前提下的实测值;若显存更大(如 A40 48GB,见配置注释),可增大batch_bins或减少梯度累积步数来缩短墙钟时间。 - 噪声鲁棒性:若目标场景噪声严重,可考虑引入更多 SpecAugment 掩蔽强度(如增大
num_time_mask),或参考 egs2/kathbath/asr1 中噪声数据增强相关脚本进一步扩展训练集。
- 人工智能
- 语音
- 音频
- 深度学习
- NLP
【免费下载链接】espnet
End-to-End Speech Processing Toolkit
相关推荐
快速上手postcss-scss:5分钟实现SCSS代码的PostCSS转换
快速上手postcss scss:5分钟实现SCSS代码的PostCSS转换 postcss scss是一个强大的SCSS解析器,专为PostCSS打造,它能让
人工智能语音音频深度学习NLPESPnet Fisher CallHome Spanish 语音识别实战:E-Branchformer 与 Conformer 配置、训练与评测全解
ESPnet Fisher CallHome Spanish 语音识别实战:E Branchformer 与 Conformer 配置、训练与评测全解 本篇技术
人工智能语音音频深度学习NLPAphasiaBank 英语失语症语音识别与失语检测:ESPnet E-Branchformer/WavLM 配方全解
AphasiaBank 英语失语症语音识别与失语检测:ESPnet E Branchformer/WavLM 配方全解 AphasiaBank 是一个面向失语症
人工智能语音音频深度学习NLP
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考