news 2026/9/26 0:34:47

ESPnet 音素级 ASR 实战指南:基于 LibriTTS 与 E-Branchformer 的 IPA+标点转写系统

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ESPnet 音素级 ASR 实战指南:基于 LibriTTS 与 E-Branchformer 的 IPA+标点转写系统
  • 人工智能
  • 语音
  • 音频
  • 深度学习
  • NLP

【免费下载链接】espnet

End-to-End Speech Processing Toolkit

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

导读

本文围绕 ESPnet 仓库中 egs2/libritts/asr1 这一音素级 ASR(Automatic Speech Recognition)实验配方展开,讲解如何基于 LibriTTS 语料构建一个输出为 IPA(国际音标)音素序列并保留标点的识别系统。该系统的核心设计目标是产出"可直接作为基于音素的 TTS(Phone-based TTS)输入端"的转写结果,从而将文本(grapheme)到音素(phoneme)的转换负担从 TTS 前端迁移到 ASR 后端。读完本文,你将掌握:音素化数据准备流程、espeak_ng_english_us_vits这一 g2p(grapheme-to-phoneme)方案的底层实现原理、E-Branchformer 训练配置的完整参数含义,以及该系统的 WER/CER/TER 量化表现。

一、系统目标:为什么需要"音素+标点"的 ASR 输出

该配方在 egs2/libritts/asr1/README.md 中开宗明义:本系统的目的是产生适合作为基于音素 TTS 直接输入的输出。这与常规的字素级(grapheme)ASR 有本质区别:

  • 常规 ASR 输出自然语言文本(单词、字词),供人阅读或作为语音识别评测基准;
  • 本配方输出音素序列(IPA 符号)与标点,语义上等价于"语音 → 音素转写",可直接喂给音素级 TTS 前端,避免 TTS 端再做一轮 g2p 转换。

从数据流角度看,这正是把 TTS 流水线中的 g2p 环节前置到 ASR 中联合解决:ASR 学习"声学特征 → 音素串(含标点)"的映射,而音素串本身就是 TTS 可直接消费的中间表示。因此该模型可视为语音转写(speech-to-phoneme transcription)专用系统,其评测指标(WER/CER/TER)也全部基于音素序列计算。

二、实验环境与依赖

原文档记录了该配方的实测环境(详见 egs2/libritts/asr1/README.md):

项目版本
Python3.10.8(GCC 11.3.1)
ESPnetespnet 202308
PyTorch2.0.1+cu118
训练硬件A6000(48 GB)× 2 GPU

需要特别说明:由于本配方依赖 eSpeak NG 进行音素化,必须安装相应的 g2p 依赖。从源码看,espeak_ng_english_us_vits走的是phonemizer库的espeak后端(见下文源码解析小节),因此复现前需要确保环境中安装了phonemizer及其 espeak-ng 后端。

三、数据处理:从 LibriTTS 到"音素化"训练集

3.1 数据下载与目录组织

数据准备脚本为 local/data.sh,它通过 db.sh 读取LIBRITTS环境变量指定的数据根目录,并从www.openslr.org/resources/60下载 LibriTTS 的七个子集:

  • dev-clean、dev-other、test-clean、test-other
  • train-clean-100、train-clean-360、train-other-500

下载完成后在$db_root/LibriTTS/.complete打上标记以避免重复下载。随后:

  1. stage 0:对每个子集调用 local/data_prep.sh 生成 Kaldi 风格数据目录(wav.scp、text、utt2spk、spk2gender、spk2utt),再用utils/fix_data_dir.sh修复,最后调用local/phonemize_dir.py做音素化;
  2. stage 1:用utils/combine_data.sh合并数据——dev由dev-clean+dev-other合并,train-960由三个训练子集合并(合计约 960 小时)。

local/data_prep.sh 沿用了 LibriTTS 的标准做法:以"reader_chapter"作为说话人粒度(utt2spk按章节划分,便于按章节计算 CMVN),转写文本取自每个 wav 对应的.normalized.txt文件。

3.2 音素化核心脚本:phonemize_dir.py

音素化由 local/phonemize_dir.py 完成,其逻辑非常简洁清晰:

from espnet2.text.phoneme_tokenizer import PhonemeTokenizer tokenizer = PhonemeTokenizer("espeak_ng_english_us_vits") with ( open(f"{idir}/text", encoding="utf-8") as itext, open(f"{idir}/text.phn", "w", encoding="utf-8") as otext, ): for line in itext: utt, text = line.strip("\n").split(" ", maxsplit=1) tokens = tokenizer.text2tokens(text) text_phn = "".join(tokens).replace("<space>", " ") otext.write(f"{utt} {text_phn}\n") os.replace(f"{idir}/text", f"{idir}/text.orig") os.replace(f"{idir}/text.phn", f"{idir}/text")

要点拆解:

  • 使用PhonemeTokenizer("espeak_ng_english_us_vits")将每句英文文本转为音素 token 序列;
  • token 序列用"".join()拼回字符串,再统一把<space>占位符替换为真实空格,从而把词边界还原为空格分隔;
  • 处理完成后原文本备份为text.orig,音素文本正式覆盖text,因此训练集、验证集、测试集的text文件都是音素序列,ASR 模型学到的是"声学特征 → 音素+标点"的映射。

3.3 底层 g2p:espeak_ng_english_us_vits 的实现

PhonemeTokenizer定义于 espnet2/text/phoneme_tokenizer.py,espeak_ng_english_us_vits分支位于该文件约 L598-L610:

elif g2p_type == "espeak_ng_english_us_vits": # VITS official implementation-like processing # Reference: https://github.com/jaywalnut310/vits self.g2p = Phonemizer( language="en-us", backend="espeak", with_stress=True, preserve_punctuation=True, strip=True, word_separator=" ", phone_separator="", split_by_single_token=True, )

从源码结构看,该 g2p 方案的关键参数决定了音素化结果的质量:

  • backend="espeak":调用phonemizer库的 eSpeak NG 后端(Phonemizer类是对 bootphon/phonemizer 的封装,见 espnet2/text/phoneme_tokenizer.py L384-L437,内部通过phonemizer.backend.BACKENDS[backend]实例化);
  • language="en-us":使用美式英语发音规则;
  • with_stress=True:保留重音符号——IPA 音素中的主/次重音(如 ˈ 与 ˌ)对 TTS 韵律至关重要;
  • preserve_punctuation=True:保留标点——这正是"IPA + 标点"系统中标点来源,标点会被当作独立 token 输出;
  • word_separator=" "、phone_separator=""、split_by_single_token=True:采用 VITS 官方实现类似的处理方式——词边界用空格分隔、音素间不加分隔符、按单 token 拆分(拆分时Phonemizer.__call__会把空格替换为<space>占位符,再由phonemize_dir.py统一还原)。

此外,espnet2/text/phoneme_tokenizer.py 的g2p_choices列表(L25-L56 附近)还提供了g2p_en、pyopenjtalk(日语)、pypinyin_g2p(中文)、g2pk(韩语)、espeak_ng_*(多语种)等众多方案,本配方选用的espeak_ng_english_us_vits正是为英文音素级 TTS 量身定制的一档。

四、训练配置详解

4.1 入口脚本 run.sh

训练入口为 run.sh,通过./asr.sh以参数方式注入全部超参数:

train_set="train-960" valid_set="dev" test_sets="test-clean test-other dev-clean dev-other" asr_config=conf/train_asr.yaml inference_config=conf/decode_asr.yaml ./asr.sh \ --lang en \ --ngpu 2 \ --nbpe 100 \ --max_wav_duration 30 \ --speed_perturb_factors "0.9 1.0 1.1" \ --audio_format "flac.ark" \ --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}" \ --lm_train_text "data/${train_set}/text" \ --bpe_train_text "data/${train_set}/text" "$@"

参数语义如下:

参数取值作用
--lang enen目标语言为英语
--ngpu 22双 GPU 分布式训练
--nbpe 100100BPE 词表大小 100——由于输出是音素序列,词表天然很小,100 个 BPE 单元足够覆盖音素+标点组合
--max_wav_duration 3030(秒)过滤超过 30 秒的长音频
--speed_perturb_factors"0.9 1.0 1.1"三倍速扰动(0.9×/1.0×/1.1×)做数据增强
--audio_format "flac.ark"flac.ark音频以 FLAC 编码的 ark 格式存储
--feats_type rawraw不预提取特征,直接在训练中计算前端特征
--use_lm falsefalse不使用外部语言模型(音素序列无需 LM 建模)
--asr_configconf/train_asr.yaml训练配置
--inference_configconf/decode_asr.yaml解码配置
--bpe_train_textdata/train-960/text在音素化后的训练文本上训练 BPE 模型

值得注意的是run.sh末尾的"$@"允许命令行追加参数覆盖默认值,这与 ESPnet 所有配方的习惯一致(如覆盖--asr_config指向 conf/tuning/train_asr_e_branchformer.yaml)。

4.2 模型结构:E-Branchformer 编码器 + Transformer 解码器

训练配置 conf/tuning/train_asr_e_branchformer.yaml(与 conf/train_asr.yaml 内容一致)定义了完整的模型与训练方案:

编码器(E-Branchformer)——约 1.41 亿参数中的主体:

encoder: e_branchformer encoder_conf: output_size: 512 attention_heads: 8 attention_layer_type: rel_selfattn pos_enc_layer_type: rel_pos rel_pos_type: latest cgmlp_linear_units: 3072 cgmlp_conv_kernel: 31 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 layer_drop_rate: 0.1 linear_units: 1024 positionwise_layer_type: linear macaron_ffn: true use_ffn: true merge_conv_kernel: 31

关键参数解读:

  • num_blocks: 17、output_size: 512、attention_heads: 8:17 层、512 维、8 头注意力;
  • attention_layer_type: rel_selfattn+pos_enc_layer_type: rel_pos+rel_pos_type: latest:使用相对位置编码的 self-attention;
  • cgmlp_linear_units: 3072、cgmlp_conv_kernel: 31、merge_conv_kernel: 31:E-Branchformer 特有的卷积门控 MLP(Convolution-augmented gMLP)分支配置;
  • macaron_ffn: true、use_ffn: true:启用 Macaron 结构与 FFN 分支;
  • input_layer: conv2d:输入为 Conv2D 下采样(配合下方frontend_conf的 512 点 FFT);
  • layer_drop_rate: 0.1:层级丢弃正则化。

解码器(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

训练损失与优化:

model_conf: ctc_weight: 0.6 lsm_weight: 0.1 length_normalized_loss: false frontend_conf: n_fft: 512 hop_length: 160
  • ctc_weight: 0.6:CTC 与 attention 的混合训练权重(CTC 占 0.6);
  • lsm_weight: 0.1:标签平滑系数 0.1;
  • frontend_conf:在线提取 512 点 FFT、hop 160 的滤波器组特征(对应 16 kHz 采样率下 10 ms 帧移)。

训练调度:

batch_type: numel batch_bins: 10000000 accum_grad: 8 max_epoch: 70 patience: none init: none best_model_criterion: - - valid - acc - max keep_nbest_models: 10 use_amp: true unused_parameters: true optim: adam optim_conf: lr: 0.005 weight_decay: 0.000001 scheduler: warmuplr scheduler_conf: warmup_steps: 40000 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, 0.05] num_time_mask: 10
  • batch_type: numel+batch_bins: 10000000:按元素数(numel)动态批大小,单 batch 不超过 1000 万元素;
  • accum_grad: 8:梯度累积 8 步等效放大批大小;
  • max_epoch: 70:最多训练 70 个 epoch(原注释显示在 A6000 × 2 上每 epoch 约 90 分钟);
  • best_model_criterion:按验证集 accuracy 最大化选择最优模型,保留 10 个 n-best;
  • use_amp: true:启用自动混合精度;
  • 优化器 Adam(lr 0.005)+ WarmupLR(40000 步预热);
  • SpecAugment 时间/频率掩蔽增强:频率掩蔽宽度 0-27、共 2 个;时间掩蔽宽度比例为 0-0.05、共 10 个。

4.3 模型规模

该配方训练出的模型参数量为141.39M(约 1.41 亿),实验目录名为exp/asr_train_asr_raw_en_bpe100_sp,其中:

  • raw:raw 特征(在线前端);
  • en_bpe100:英语、BPE 词表 100;
  • sp:speed perturbation(三倍速扰动)。

五、解码配置

解码配置见 conf/decode_asr.yaml:

beam_size: 15 ctc_weight: 0.2 lm_weight: 0.0 maxlenratio: 0.0 minlenratio: 0.0 penalty: 0.0
  • beam_size: 15:beam 搜索宽度 15;
  • ctc_weight: 0.2:解码时 CTC 与 attention 得分的加权比例(与训练权重 0.6 不同,解码阶段更依赖 attention);
  • lm_weight: 0.0:不集成语言模型(与--use_lm false对应);
  • maxlenratio/minlenratio: 0.0:不限制输出长度比例;
  • penalty: 0.0:无长度惩罚。

最终用于评测的模型为decode_asr_asr_model_valid.acc.ave,即验证集 accuracy 最优模型的平均权重(average checkpoints)。

六、评测结果:WER / CER / TER

音素序列的评测标准覆盖三种错误率:WER(词错率,按空格分隔的"音素词"计)、CER(字符错误率,按音素符号计)、TER(token 错误率,按词表 token 计)。以下数据均来自原文档 egs2/libritts/asr1/README.md,评测模型为decode_asr_asr_model_valid.acc.ave。

6.1 WER(词错误率)

datasetSntWrdCorrSubDelInsErrS.Err
dev-clean57369587291.78.00.40.89.167.0
dev-other46136957788.510.90.61.212.774.2
test-clean48378707891.48.20.40.89.470.4
test-other51207254187.012.20.81.114.177.1

6.2 CER(字符错误率)

datasetSntWrdCorrSubDelInsErrS.Err
dev-clean573657071098.40.80.90.62.267.1
dev-other461341478197.21.61.21.03.874.2
test-clean483753064798.50.70.80.62.270.5
test-other512042946396.71.71.61.04.377.1

6.3 TER(Token 错误率)

datasetSntWrdCorrSubDelInsErrS.Err
dev-clean573643354897.61.41.00.63.067.1
dev-other461331655096.12.51.41.05.074.2
test-clean483740403197.71.40.90.72.970.5
test-other512032724895.42.81.81.15.777.1

结果解读:

  • CER(2.2%~4.3%)远低于 WER(9.1%~14.1%),说明错误主要集中于个别音素符号的替换,整体音素序列质量很高;
  • *-clean与*-other的差距(clean vs 噪声/重口音)符合 LibriTTS 的难度梯度设定;
  • S.Err(句子错误率)约 67%~77%,意味着约三分之一的句子中存在至少一个音素错误——对音素级 TTS 前端而言,剩余的错误可通过 TTS 的容错性(音素序列已包含重音和标点信息)部分消化。

该模型对应预训练权重发布在 Hugging Face 的espnet/akreal_libritts_asr_phn模型仓库中,可直接加载用于推理或微调(可通过 ESPnet 标准模型下载机制espnet_model_zoo/pretrained拉取)。

七、从源码看该配方的可复用性

7.1 g2p 方案可替换

espnet2/text/phoneme_tokenizer.py 的g2p_choices列出全部可用 g2p 类型。若想迁移到其他语言,只需把 local/phonemize_dir.py 中的PhonemeTokenizer("espeak_ng_english_us_vits")替换为espeak_ng_german、espeak_ng_french、espeak_ng_spanish等(多语言 eSpeak NG 后端),或替换为g2pk(韩语)、pyopenjtalk(日语)、pypinyin_g2p(中文)等专用方案,即可构造"任意语言 → 音素级 ASR"的配方。

7.2 与 TTS 配方的衔接

该配方的输出格式(空格分隔的 IPA 音素串、含标点与重音)与 ESPnet 的 TTS 音素输入约定一致。TTS 侧可通过PhonemeTokenizer完成同样的文本→音素转换(见 espnet2/text/build_tokenizer.py L76-L77 对PhonemeTokenizer的构建逻辑),实现"ASR 输出的音素串 → TTS 输入"的无缝对接。这正是 egs2/libritts 同时提供 asr1(音素 ASR)与 tts1 等配方的深层关联所在。

八、复现步骤速览

  1. 准备数据:在 db.sh 中填写LIBRITTS数据根目录,运行./run.sh --stage -1 --stop_stage 1完成下载、Kaldi 数据目录生成与音素化;
  2. 训练:./run.sh --stage 2 --stop_stage 4(按asr.sh默认阶段划分,依次为特征/BPE 准备、训练),或直接./run.sh走完全流程;训练默认使用 conf/train_asr.yaml,如需复现文档中的 E-Branchformer 配置可追加--asr_config conf/tuning/train_asr_e_branchformer.yaml;
  3. 解码与评分:解码阶段生成decode_asr_*目录,使用 ESPnet 标准show_asr_result.sh汇总 WER/CER/TER 结果(脚本见 egs2/libritts/asr1/scripts/utils/show_asr_result.sh);
  4. 加载预训练模型:通过模型名espnet/akreal_libritts_asr_phn从模型库拉取权重,直接对任意英文音频做 IPA+标点转写。

小结

本配方是"音素级语音处理"思路的完整落地:数据侧用 eSpeak NG(espeak_ng_english_us_vits,保留重音与标点、VITS 兼容格式)把 LibriTTS 文本音素化;模型侧用 17 层 E-Branchformer + 6 层 Transformer(CTC 0.6 + 标签平滑 0.1 + SpecAugment)在 960 小时音素监督下训练 1.41 亿参数模型;评测侧以 WER/CER/TER 三重视角确认了音素序列的高保真度(CER 最低 2.2%)。该输出可作为音素级 TTS 的直接前端输入,也可推广到任意语言的音素转写任务。

  • 人工智能
  • 语音
  • 音频
  • 深度学习
  • NLP

【免费下载链接】espnet

End-to-End Speech Processing Toolkit

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

相关推荐

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/26 0:28:44

SEQ上报20 Subscriber Absent:VoLTE用户静默掉线的信令黑洞排查指南

简介&#xff1a;本资源为一份5G网络优化实战案例文档&#xff0c;面向从事5G核心网与IMS信令分析的网优工程师及运维人员&#xff0c;聚焦SEQ上报「20 Subscriber Absent」这一典型拆线原因值的定位与排查。文档围绕IMS未注册、用户缺席等异常场景&#xff0c;梳理了从终端能力…

作者头像 李华
网站建设 2026/9/26 0:28:21

磊能防腐的技术实力强吗

顺应行业发展趋势&#xff0c;锚定防腐领域时代使命东北作为我国传统工业基地&#xff0c;承载着数十年的工业发展积淀&#xff0c;大量工业设施、金属构件长期服役在复杂户外环境中&#xff0c;既要承受工业介质的持续侵蚀&#xff0c;也要应对东北地域独特的严寒、冻融、大温…

作者头像 李华
网站建设 2026/9/26 0:26:43

GEO实操指南:企业内容如何进入AI搜索信源池

一、搜索引擎的技术演进的四个常见问题传统搜索引擎的排序逻辑依赖关键词密度与外链权重&#xff0c;企业只要围绕几个核心词做优化就能获得曝光。但随着豆包、文心一言、通义千问、DeepSeek等对话式AI成为用户获取信息的新入口&#xff0c;这套逻辑正在失效。好客搜公司在服务…

作者头像 李华
网站建设 2026/9/26 0:10:34

LibreChat自部署指南:聚合多模型与数据自主权的开源AI对话平台

LibreChat 这个项目&#xff0c;我从早期版本开始就在用&#xff0c;一路跟进到现在。它本质上是一个开源的、可以自部署的 AI 对话平台&#xff0c;界面和交互逻辑都贴近 ChatGPT 的习惯&#xff0c;但背后能接入的模型远不止 GPT 系列。OpenAI、Anthropic、Google Gemini&…

作者头像 李华