- 人工智能
- 语音
- 音频
- 深度学习
- NLP
【免费下载链接】espnet
End-to-End Speech Processing Toolkit
本文以 ESPnet 仓库中的 zh_openslr38 配方 README 为核心,系统讲解如何基于开源的 Free ST Chinese Mandarin Corpus(ST-CMDS)语料库,使用 ESPnet2 完成从数据下载、划分、去重到 Conformer 频谱特征基线训练,以及 HuBERT 自监督表示(SSLR)特征训练的完整流程。读完本文,你将能够独立复现两套中文普通话语音识别基线,理解训练/解码配置中每个关键参数的作用,并掌握 CER 评估结果的解读方法。
语料库概览:Free ST Chinese Mandarin Corpus
zh_openslr38 配方使用的语料是Free ST Chinese Mandarin Corpus(ST-CMDS),由 Surfingtech(www.surfing.ai)收集并免费发布,可通过 OpenSLR 平台(编号 38)获取。语料库的规模参数如下:
- 总话语数:102,600 条
- 说话人数:855 人
- 总时长:109.73 小时
这是一个典型的"说话人众多、时长中等"的普通话朗读语料,适合用于验证中文 ASR 系统的通用泛化能力,也是 ESPnet2 官方验证中文单字(char)级识别基线的重要基准之一。
数据划分策略:按说话人 ID 的 90-5-5 划分
语料库中每位说话人恰好有 120 条话语,因此配方采用按说话人 ID 划分而非随机按话语划分,以保证同一说话人的所有话语只出现在一个集合中,避免说话人级别的数据泄漏:
| 数据集 | 说话人数 | 说明 |
|---|---|---|
| train | 769 | 训练集 |
| dev | 43 | 验证集 |
| test | 43 | 测试集 |
划分比例约为 90%-5%-5%。该策略在 local/data_split.py 中实现,并由 local/check_train_test_duplicate.py 做后续校验。
训练数据泄漏处理:重复转录去重
原始数据集的一个特点是:存在转录文本完全相同、但由不同说话人朗读的重复句子。虽然这些重复句子的波形各不相同,不属于传统意义上的直接拷贝,但为了严谨起见,配方仍然从dev 和 test 集合中移除所有在训练集中出现过相同转录的句子,从而彻底消除训练数据泄漏对评测结果的影响。
这一去重逻辑在数据准备阶段执行,具体流程见下文数据准备小节。
环境与复现前提
README 记录的结果复现环境如下:
- Python 版本:
3.9.10(conda-forge 打包) - ESPnet 版本:
espnet 0.10.7a1 - PyTorch 版本:
pytorch 1.10.1
注意:上述版本为原实验结果的环境快照。当前仓库版本可能已升级,实际运行时请以仓库配套的安装文档(如 doc/installation.md)为准,配置路径与命令接口保持兼容。
数据准备流程:从下载到标准 data 目录
数据准备由 local/data.sh 驱动,其核心步骤包括:
- 下载语料:从 OpenSLR 38 资源目录下载
ST-CMDS-20170001_1-OS.tar.gz压缩包。下载目录由 db.sh 中的ST_CMDS变量控制(默认downloads,即自动下载模式)。若希望下载完成后立即删除压缩包以节省磁盘,可传入--remove_archive true选项。 - 解压与切分:调用 local/data_split.py,按说话人 ID 将数据切分为
data/train、data/dev、data/test三个标准 ESPnet data 目录。 - 生成 spk2utt:对每个集合执行
utils/utt2spk_to_spk2utt.pl,从已有的utt2spk生成spk2utt,完成双向说话人-话语映射。 - 去重校验:运行 local/check_train_test_duplicate.py,确保 dev/test 中不存在与训练集转录重复的句子。
- 格式验证:使用
utils/validate_data_dir.sh --no-feats分别校验三个集合的 data 目录格式是否合法(因为此处是原始 wav 特征,故加--no-feats跳过特征文件检查)。
完成以上步骤后,data/{train,dev,test}即为后续asr.sh流水线的标准输入。
基线实验一:频谱特征(Fbank)训练 Conformer
频谱特征基线是 zh_openslr38 配方的主结果,一键复现命令为:
./run.shrun.sh 是配方的入口脚本,它定义了本次实验的核心调度参数,并调用 ESPnet2 通用训练脚本asr.sh:
train_set=train valid_set=dev test_sets="dev test" asr_config=conf/train_asr.yaml inference_config=conf/decode_asr.yaml lm_config=conf/train_lm.yaml use_lm=true use_wordlm=false # speed perturbation related speed_perturb_factors="0.9 1.0 1.1" ./asr.sh \ --lang zh \ --audio_format wav \ --feats_type raw \ --token_type char \ --use_lm ${use_lm} \ --use_word_lm ${use_wordlm} \ --lm_config "${lm_config}" \ --asr_config "${asr_config}" \ --inference_config "${inference_config}" \ --train_set "${train_set}" \ --valid_set "${valid_set}" \ --test_sets "${test_sets}" \ --speed_perturb_factors "${speed_perturb_factors}" \ --asr_speech_fold_length 512 \ --asr_text_fold_length 150 \ --lm_fold_length 150 \ --lm_train_text "data/${train_set}/text" "$@"关键运行参数解读
| 参数 | 取值 | 含义 |
|---|---|---|
--lang zh | zh | 语言标识,影响 tokenization 等环节 |
--audio_format wav | wav | 音频格式为 wav,直接读取原始波形 |
--feats_type raw | raw | 使用原始音频,由前端在线提取特征 |
--token_type char | char | 以中文字符(单字)为建模单元 |
--use_lm true | true | 训练并使用外部语言模型参与解码 |
--use_word_lm false | false | 不使用词级语言模型 |
--speed_perturb_factors | "0.9 1.0 1.1" | 三倍速度扰动数据增强,训练集变为train_sp |
--asr_speech_fold_length | 512 | ASR 语音长度按 512 对齐,便于分桶 |
--asr_text_fold_length | 150 | ASR 文本长度按 150 对齐 |
--lm_fold_length | 150 | LM 文本长度按 150 对齐 |
速度扰动(speed perturbation)是这里最重要的数据增强手段:以 0.9、1.0、1.1 三个倍率对训练语音做变速重采样,将数据量扩为原来的 3 倍,能显著提升模型对语速变化的鲁棒性,也是 ESPnet2 配方中标准的中文 ASR 配置。
声学模型配置:Conformer + Transformer 混合 CTC/Attention
声学模型配置位于 conf/train_asr.yaml,采用 ESPnet2 经典的Conformer 编码器 + Transformer 解码器 + 混合 CTC/Attention架构:
# encoder related encoder: conformer encoder_conf: output_size: 256 # dimension of attention attention_heads: 4 linear_units: 2048 # the number of units of position-wise feed forward num_blocks: 12 # the number of encoder blocks dropout_rate: 0.1 positional_dropout_rate: 0.1 attention_dropout_rate: 0.0 input_layer: conv2d # encoder architecture type normalize_before: true pos_enc_layer_type: rel_pos selfattention_layer_type: rel_selfattn activation_type: swish macaron_style: true use_cnn_module: true cnn_module_kernel: 15 # decoder related 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.0 src_attention_dropout_rate: 0.0 # hybrid CTC/attention model_conf: ctc_weight: 0.3 lsm_weight: 0.1 # label smoothing option length_normalized_loss: false配置要点:
- Conformer 编码器:12 层 Transformer 块,每个块内部同时包含前馈网络(macaron_style 双甜筒结构)和CNN 模块(kernel=15),能同时建模全局上下文与局部细节;使用相对位置编码(rel_pos)与相对自注意力(rel_selfattn),对长语音更友好;激活函数为 swish。
- Transformer 解码器:6 层、4 头注意力、2048 维前馈隐藏单元。
- 混合目标:
ctc_weight: 0.3表示训练损失中 CTC 占 30%、Attention 占 70%,兼顾对齐能力与上下文建模;lsm_weight: 0.1为标签平滑系数,缓解过拟合。
优化与正则配置同样完整:
# minibatch related batch_type: numel batch_bins: 4000000 # optimization related accum_grad: 4 grad_clip: 5 max_epoch: 40 val_scheduler_criterion: - valid - acc best_model_criterion: - valid - acc - max keep_nbest_models: 10 optim: adam optim_conf: lr: 0.0005 scheduler: warmuplr scheduler_conf: warmup_steps: 30000 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- 动态分桶:
batch_type: numel按元素总数动态组批,batch_bins: 4000000控制每个 batch 的规模,长短句混合时更高效。 - 优化策略:Adam(lr=0.0005)+ warmup 学习率调度(30,000 步预热),梯度裁剪 5,
accum_grad: 4等效放大 batch,max_epoch: 40。 - 模型选择:以验证集 acc 为准则保留最好的 10 个模型(
keep_nbest_models: 10)。 - SpecAugment:时间扭曲(窗口 5)、频域掩码(宽度 0-30,2 个掩码)、时域掩码(宽度 0-40,2 个掩码)全部开启,是提升泛化能力的关键。
语言模型配置:Transformer LM
由于use_lm=true,配方同时训练一个中文 Transformer 语言模型,配置见 conf/train_lm.yaml:
lm: transformer lm_conf: pos_enc: null embed_unit: 128 att_unit: 512 head: 8 unit: 2048 layer: 16 dropout_rate: 0.1 # optimization related grad_clip: 5.0 batch_type: numel batch_bins: 2000000 accum_grad: 1 max_epoch: 15 # 15epoch is enougth optim: adam optim_conf: lr: 0.001 scheduler: warmuplr scheduler_conf: warmup_steps: 25000 best_model_criterion: - - valid - loss - min keep_nbest_models: 10 # 10 is good.该 LM 为 16 层 Transformer(嵌入 128、注意力维度 512、8 头、前馈 2048),以验证集 loss 最小化为准则保留 10 个最佳模型,训练 15 个 epoch 即可达到足够效果。LM 训练文本来自data/train/text(即--lm_train_text参数)。
解码配置:Beam Search 参数
推理阶段配置见 conf/decode_asr.yaml:
beam_size: 20 penalty: 0.0 maxlenratio: 0.0 minlenratio: 0.0 ctc_weight: 0.6 lm_weight: 0.3beam_size: 20:束宽 20,在解码质量与速度之间取得平衡。ctc_weight: 0.6:解码时 CTC 得分权重提升到 0.6(高于训练的 0.3),这是 ESPnet2 推荐的"训练轻 CTC、解码重 CTC"策略,能显著抑制 Attention 解码的早停/晚停问题。lm_weight: 0.3:外部语言模型插值权重 0.3,为最终假设注入语言先验。
频谱特征基线 CER 结果
README 记录的两组 CER 结果(模型为valid.acc.ave平均模型,配合 Transformer LM 解码):
| dataset | Snt | Wrd | Corr | Sub | Del | Ins | Err | S.Err |
|---|---|---|---|---|---|---|---|---|
| decode_asr_rnn_lm_lm_train_lm_transformer_zh_char_valid.loss.ave_asr_model_valid.acc.ave/dev | 4322 | 46490 | 91.0 | 8.4 | 0.5 | 0.2 | 9.2 | 51.5 |
| decode_asr_rnn_lm_lm_train_lm_transformer_zh_char_valid.loss.ave_asr_model_valid.acc.ave/test | 4167 | 45803 | 91.1 | 8.5 | 0.5 | 0.2 | 9.1 | 52.2 |
表中各列含义:Snt(句子数)、Wrd(字数)、Corr(正确率)、Sub(替换错误率)、Del(删除错误率)、Ins(插入错误率)、Err(总错误率,即 CER)、S.Err(句子错误率)。dev/test 的 CER 分别为9.2% 和 9.1%,识别正确率均在 91% 以上,可作为该语料库的强参考基线。
基线实验二:HuBERT 自监督特征(SSLR)训练
除频谱特征外,配方还提供了一套HuBERT 自监督学习特征(SSLR)的实验脚本,用于对比自监督预训练表示与传统 Fbank 特征在中文 ASR 上的表现:
./local/run_sslr.sh脚本位于 local/run_sslr.sh,与run.sh的主流程一致,但将声学模型配置切换为 conf/tuning/train_asr_sslr.yaml,并额外指定了以下参数:
--feats_normalize uttmvn \ --nj 1 \ --inference_asr_model valid.acc.best.pth \ --gpu_inference true--feats_normalize uttmvn:对自监督特征采用 utterance-level 均值方差归一化(而非全局 CMVN)。--nj 1:单进程执行,因为 s3prl 前端在特征提取阶段占用较多资源。--inference_asr_model valid.acc.best.pth:解码时选用验证集 acc 最佳的单个模型。--gpu_inference true:推理阶段使用 GPU。
SSLR 配置的核心差异:s3prl 前端 + 线性预编码器
train_asr_sslr.yaml 在基线配置的基础上,用s3prl 自监督前端替换了传统的 Fbank 特征提取,并新增线性预编码器:
frontend: s3prl frontend_conf: frontend_conf: upstream: hubert_large_ll60k # Note: If the upstream is changed, please change the input_size in the preencoder. download_dir: ./hub multilayer_feature: True preencoder: linear preencoder_conf: input_size: 1024 # Note: If the upstream is changed, please change this value accordingly. output_size: 80关键点:
- upstream: hubert_large_ll60k:选用在 60k 小时语音上预训练的 HuBERT-Large 模型作为上游特征提取器,模型权重下载到
./hub目录。 - multilayer_feature: True:融合 HuBERT 多层隐藏状态,获得更丰富的表示。
- preencoder: linear:用单层线性投影将 1024 维的 HuBERT 特征降维到 80 维,再送入 Conformer 编码器。注释明确指出:更换 upstream 时必须同步调整
input_size,这是该配置最容易出错的地方。 - extract_feats_in_collect_stats: false:在统计特征(collect stats)阶段生成哑统计文件而非真正调用前端提取特征,以节省 SSLR 场景下的统计时间。
其余编码器、解码器、优化器与 SpecAugment 配置与基线一致。README 同时说明:由于 HuBERT 特征训练耗时显著增长,该实验仅训练 24 个 epoch(通过max_epoch控制)。
SSLR 实验结果
| dataset | Snt | Wrd | Corr | Sub | Del | Ins | Err | S.Err |
|---|---|---|---|---|---|---|---|---|
| decode_asr_lm_lm_train_lm_zh_char_valid.loss.ave_asr_model_valid.acc.best/dev | 4322 | 46490 | 90.8 | 8.6 | 0.6 | 0.2 | 9.4 | 51.9 |
| decode_asr_lm_lm_train_lm_zh_char_valid.loss.ave_asr_model_valid.acc.best/test | 4167 | 45803 | 90.8 | 8.7 | 0.5 | 0.2 | 9.4 | 54.1 |
两个基线的对比分析
| 对比维度 | 频谱特征(Fbank) | HuBERT SSLR |
|---|---|---|
| 特征来源 | 在线 Fbank 提取 | s3prl 前端 + hubert_large_ll60k |
| 训练 epoch | 40 | 24 |
| 特征维度(预编码后) | 80 | 80(线性投影自 1024 维) |
| dev CER | 9.2% | 9.4% |
| test CER | 9.1% | 9.4% |
在**相同 epoch 预算受限(24 epoch)**的条件下,SSLR 模型并未取得比频谱特征更低的 CER,但差距很小(约 0.2-0.3 个百分点)。README 明确指出:这一结论受限于训练时长,若延长训练 epoch,SSLR 表现有望进一步提升。这说明在数据量约 110 小时的中等规模语料上,传统 Fbank + SpecAugment 依然是一条性价比极高的基线路径;而 HuBERT 特征作为"少标注、强表示"路线的备选方案,其潜力需要在更长训练预算下验证。
总结与实操建议
围绕 zh_openslr38 配方,可以沉淀出以下可复用的实践结论:
- 数据划分严谨性:按说话人划分(90-5-5)+ 训练集转录去重,是保证中文语音识别评测可信度的关键,配方通过 local/data_split.py 与 local/check_train_test_duplicate.py 双脚本保障。
- 标准训练入口:
./run.sh一键完成"数据准备 → 特征 → 训练 → LM → 解码 → 评分"全流程,核心参数集中在脚本头部,便于按需调整(如修改test_sets、speed_perturb_factors)。 - 混合 CTC/Attention 的参数哲学:训练
ctc_weight=0.3、解码ctc_weight=0.6的"轻训练重解码"搭配,配合lm_weight=0.3的外部语言模型插值,是 ESPnet2 中文 ASR 配方中被验证有效的标准组合。 - SSLR 接入路径清晰:只需将
frontend切换为s3prl并配套线性preencoder,即可把任意自监督上游模型接入现有 Conformer 训练管线,切换 upstream 时务必同步修改input_size。 - 结果对标基准:频谱特征基线 test CER 9.1%、SSLR(24 epoch)test CER 9.4%,后续在该语料上的任何改进实验均可与此两组数字直接对比。
如需深入了解asr.sh内部的阶段划分(数据准备、Fbank 提取、速度扰动、CMVN、训练、解码、评分等),可查阅 egs2/TEMPLATE/asr1/asr.sh 及各阶段配套脚本,它与 zh_openslr38 配方共用同一套 ESPnet2 训练框架。
- 人工智能
- 语音
- 音频
- 深度学习
- NLP
【免费下载链接】espnet
End-to-End Speech Processing Toolkit
相关推荐
ESPnet2 IEMOCAP ASR 实战:基于 HuBERT / Conformer 的语音情感识别与情绪标注联合建模
ESPnet2 IEMOCAP ASR 实战:基于 HuBERT / Conformer 的语音情感识别与情绪标注联合建模 导读 本文基于 ESPnet2 端到
人工智能语音音频深度学习NLPESPnet 中文普通话 ASR 实战:在 aidatatang_200zh 上复现 E-Branchformer 与 Conformer 实验
ESPnet 中文普通话 ASR 实战:在 aidatatang_200zh 上复现 E Branchformer 与 Conformer 实验 本指南围绕 E
人工智能语音音频深度学习NLPPaddleSpeech 在 TALCS 中文普通话 ASR 上的 Conformer 与 Chunk Conformer 实验:指标、解码方法与完整复现指南
PaddleSpeech 在 TALCS 中文普通话 ASR 上的 Conformer 与 Chunk Conformer 实验:指标、解码方法与完整复现指南
人工智能语音音频
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考