☰
ESPnet2 中文普通话 ASR 实战:基于 zh_openslr38 语料库的 Conformer 与 HuBERT SSLR 基线复现指南
2026/9/26 8:15:41 网站建设 项目流程
  • 人工智能
  • 语音
  • 音频
  • 深度学习
  • NLP

【免费下载链接】espnet

End-to-End Speech Processing Toolkit

项目地址:https://gitcode.com/gh_mirrors/es/espnet
点击查看免费下载

本文以 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 划分而非随机按话语划分,以保证同一说话人的所有话语只出现在一个集合中,避免说话人级别的数据泄漏:

数据集说话人数说明
train769训练集
dev43验证集
test43测试集

划分比例约为 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 驱动,其核心步骤包括:

  1. 下载语料:从 OpenSLR 38 资源目录下载ST-CMDS-20170001_1-OS.tar.gz压缩包。下载目录由 db.sh 中的ST_CMDS变量控制(默认downloads,即自动下载模式)。若希望下载完成后立即删除压缩包以节省磁盘,可传入--remove_archive true选项。
  2. 解压与切分:调用 local/data_split.py,按说话人 ID 将数据切分为data/train、data/dev、data/test三个标准 ESPnet data 目录。
  3. 生成 spk2utt:对每个集合执行utils/utt2spk_to_spk2utt.pl,从已有的utt2spk生成spk2utt,完成双向说话人-话语映射。
  4. 去重校验:运行 local/check_train_test_duplicate.py,确保 dev/test 中不存在与训练集转录重复的句子。
  5. 格式验证:使用utils/validate_data_dir.sh --no-feats分别校验三个集合的 data 目录格式是否合法(因为此处是原始 wav 特征,故加--no-feats跳过特征文件检查)。

完成以上步骤后,data/{train,dev,test}即为后续asr.sh流水线的标准输入。

基线实验一:频谱特征(Fbank)训练 Conformer

频谱特征基线是 zh_openslr38 配方的主结果,一键复现命令为:

./run.sh

run.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 zhzh语言标识,影响 tokenization 等环节
--audio_format wavwav音频格式为 wav,直接读取原始波形
--feats_type rawraw使用原始音频,由前端在线提取特征
--token_type charchar以中文字符(单字)为建模单元
--use_lm truetrue训练并使用外部语言模型参与解码
--use_word_lm falsefalse不使用词级语言模型
--speed_perturb_factors"0.9 1.0 1.1"三倍速度扰动数据增强,训练集变为train_sp
--asr_speech_fold_length512ASR 语音长度按 512 对齐,便于分桶
--asr_text_fold_length150ASR 文本长度按 150 对齐
--lm_fold_length150LM 文本长度按 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.3
  • beam_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 解码):

datasetSntWrdCorrSubDelInsErrS.Err
decode_asr_rnn_lm_lm_train_lm_transformer_zh_char_valid.loss.ave_asr_model_valid.acc.ave/dev43224649091.08.40.50.29.251.5
decode_asr_rnn_lm_lm_train_lm_transformer_zh_char_valid.loss.ave_asr_model_valid.acc.ave/test41674580391.18.50.50.29.152.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 实验结果

datasetSntWrdCorrSubDelInsErrS.Err
decode_asr_lm_lm_train_lm_zh_char_valid.loss.ave_asr_model_valid.acc.best/dev43224649090.88.60.60.29.451.9
decode_asr_lm_lm_train_lm_zh_char_valid.loss.ave_asr_model_valid.acc.best/test41674580390.88.70.50.29.454.1

两个基线的对比分析

对比维度频谱特征(Fbank)HuBERT SSLR
特征来源在线 Fbank 提取s3prl 前端 + hubert_large_ll60k
训练 epoch4024
特征维度(预编码后)8080(线性投影自 1024 维)
dev CER9.2%9.4%
test CER9.1%9.4%

在**相同 epoch 预算受限(24 epoch)**的条件下,SSLR 模型并未取得比频谱特征更低的 CER,但差距很小(约 0.2-0.3 个百分点)。README 明确指出:这一结论受限于训练时长,若延长训练 epoch,SSLR 表现有望进一步提升。这说明在数据量约 110 小时的中等规模语料上,传统 Fbank + SpecAugment 依然是一条性价比极高的基线路径;而 HuBERT 特征作为"少标注、强表示"路线的备选方案,其潜力需要在更长训练预算下验证。

总结与实操建议

围绕 zh_openslr38 配方,可以沉淀出以下可复用的实践结论:

  1. 数据划分严谨性:按说话人划分(90-5-5)+ 训练集转录去重,是保证中文语音识别评测可信度的关键,配方通过 local/data_split.py 与 local/check_train_test_duplicate.py 双脚本保障。
  2. 标准训练入口:./run.sh一键完成"数据准备 → 特征 → 训练 → LM → 解码 → 评分"全流程,核心参数集中在脚本头部,便于按需调整(如修改test_sets、speed_perturb_factors)。
  3. 混合 CTC/Attention 的参数哲学:训练ctc_weight=0.3、解码ctc_weight=0.6的"轻训练重解码"搭配,配合lm_weight=0.3的外部语言模型插值,是 ESPnet2 中文 ASR 配方中被验证有效的标准组合。
  4. SSLR 接入路径清晰:只需将frontend切换为s3prl并配套线性preencoder,即可把任意自监督上游模型接入现有 Conformer 训练管线,切换 upstream 时务必同步修改input_size。
  5. 结果对标基准:频谱特征基线 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

项目地址:https://gitcode.com/gh_mirrors/es/espnet
点击查看免费下载

相关推荐

上一篇:Shiki 双主题实战:如何一套代码优雅实现 Light/Dark 暗色模式切换
下一篇:Switch游戏安装革命:Awoo Installer如何让你3分钟搞定一切?

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询