拓冰建站拓冰建站
首页 / 资讯中心 / 正文

PaddleSpeech ASR 识别解码模块 paddlespeech.s2t.decoders.recog 源码深度解析

PaddleSpeech ASR 识别解码模块 paddlespeech.s2t.decoders.recog 源码深度解析【免费下载链接】PaddleSpeechEasy-to-use Speech Toolkit including Self-Supervised Learning model, SOTA/Streaming ASR with punctuation, Streaming TTS with text frontend, Speaker Verification System, End-to-End Speech Translation and Keyword Spotting. Won NAACL2022 Best Demo Award.项目地址: https://gitcode.com/gh_mirrors/pa/PaddleSpeech本文围绕 docs/source/api/paddlespeech.s2t.decoders.recog.rst 所索引的paddlespeech.s2t.decoders.recog模块展开深入剖析 PaddleSpeech 中基于 Scorer 体系的 Beam Search 识别Recognition / Decoding后端从命令行参数体系、recog_v2主流程、Scorer 接口与权重融合机制到 N-best 结果输出与真实示例脚本的完整调用链。读完本文你将能够独立理解并调优 PaddleSpeech 的 ASR 离线解码流程掌握--ctc-weight、--lm-weight、--beam-size、--maxlenratio等核心参数的实际作用并知道如何基于 ScorerInterface 接入自定义语言模型或 n-gram 模型参与解码。一、模块定位V2 解码后端的核心实现在 PaddleSpeech 的源码树中paddlespeech.s2t.decoders目录集中存放了端到端语音识别E2E ASR的解码器相关代码paddlespeech/s2t/decoders/ ├── recog.py # 本文核心recog_v2 解码主流程 ├── recog_bin.py # 命令行参数解析与入口 main() ├── utils.py # end_detect / parse_hypothesis / add_results_to_json ├── beam_search/ │ ├── beam_search.py # BeamSearch 类paddle.nn.Layer与便捷函数 │ └── batch_beam_search.py # BatchBeamSearch批式实现占位 ├── scorers/ │ ├── scorer_interface.py # ScorerInterface / BatchScorerInterface / PartialScorerInterface │ ├── ctc.py # CTCPrefixScorerCTC 前缀打分器 │ ├── ctc_prefix_score.py │ ├── length_bonus.py # LengthBonus长度奖励 │ └── ngram.py # NgramFullScorer / NgramPartScorer └── ctcdecoder/ # 基于 SWIG 的 C CTC 解码封装recog.py模块的文档字符串recog.py明确说明了其定位V2 backend forasr_recog.pyusingdecoders.beam_search.BeamSearch即它是v2版解码 API 的后端实现面向任何实现了ScorerInterface的自定义模型包括 RNNLM、ngram 等外部打分器。该实现参考并修改自 ESPnetApache 2.0 许可代码风格与接口设计一脉相承。从整个项目的调用链看recog.py处于解码流程的最底层引擎位置示例脚本 recog.sh └── ${BIN_DIR}/recog.pypaddlespeech/s2t/exps/u2_kaldi/bin/recog.py └── paddlespeech.s2t.decoders.recog_bin.main() [命令行参数解析] └── paddlespeech.s2t.decoders.recog.recog_v2(args) [解码主流程] ├── load_trained_model() / load_trained_lm() [模型加载] ├── BeamSearch / BatchBeamSearch [搜索内核] └── add_results_to_json() [结果格式化]入口文件 recog.py 只有寥寥数行它把sys.argv直接交给recog_bin.main()随后main()根据--api参数分派到recog_v2recog_bin.py。二、命令行参数体系一次看全解码选项recog_bin.py中的get_parser()recog_bin.py基于configargparse构建因此所有参数既可以在命令行传入也可以通过 YAML 配置文件传入--config指定。参数按功能可分为以下几组2.1 通用与模型参数参数默认值说明--model-nameu2_kaldi模型名可选deepspeech2、u2、u2_kaldi、u2_st--config/--config2/--config3—配置文件路径后者依次覆盖前者--ngpu0GPU 数量当前只支持 0 或 1多卡会直接报错退出--dtypefloat32计算精度可选float16/float32/float64注意 float16 不支持 CPU--debugmode/--seed/--verbose1/1/2调试、随机种子与日志级别--batchsize1束搜索批大小0表示禁用批处理多语句批解码未实现--apiv2目前唯一支持的解码 API 版本--recog-json—输入识别数据jsonlines 格式必填--result-label—输出结果标签文件jsonlines必填--model/--model-conf—模型参数文件与模型配置文件--num-spkrs/--num-encs1/1说话人数量与编码器数量仅支持 1/12.2 搜索Beam Search参数参数默认值说明--nbest1输出 N-best 假设条数--beam-size1束宽--penalty0.0插入惩罚insection penalty作用于 length_bonus 打分器--maxlenratio0.0最大输出长度 maxlenratio × 输入长度0.0时启用 end-detect 自动终止0时取其绝对值作为固定最大长度--minlenratio0.0最小输出长度 minlenratio × 输入长度--ctc-weight0.0CTC 与 attention 联合解码时 CTC 部分的权重--ctc-window-margin0CTC 窗口加速GPU 上0表示禁用--search-typedefaultTransducer 解码实现default/nsc/tsd/alsd/maes--nstep/--prefix-alpha/--max-sym-exp/--u-max/--expansion-gamma/--expansion-beta1/2/2/400/2.3/2各类 Transducer 搜索算法的专用超参--score-normTrue是否按长度归一化最终假设分数--softmax-temperature1.0softmax 温度惩罚项2.3 外部语言模型参数参数默认值说明--rnnlm/--rnnlm-confNone字符级 RNNLM 模型文件与配置--word-rnnlm/--word-rnnlm-conf/--word-dictNone词级 RNNLM当前 v2 API 未实现指定会报错--lm-weight0.1RNNLM 在联合打分中的权重--ngram-modelNonen-gram 语言模型文件--ngram-weight0.1n-gram 权重--ngram-scorerpartfull对所有假设打分更慢或part只对 topK 假设打分更快2.4 流式与量化参数流式--streaming-modewindow/segment、--streaming-window、--streaming-min-blank-dur、--streaming-onset-margin、--streaming-offset-margin——注意recog_v2目前对--streaming-mode直接抛出NotImplementedErrorrecog.py流式识别需走其他路径。Mask CTC非自回归--maskctc-n-iterations默认10、--maskctc-probability-threshold默认0.999。量化--quantize-config、--quantize-dtype默认qint8、--quantize-asr-model、--quantize-lm-model。main()中的合法性校验值得一提recog_bin.py--dtype float16且ngpu0时直接报错ngpu1会以The program only supports ngpu1.退出--rnnlm与--word-rnnlm同时指定会报错提示二选一--num-spkrs 2说话人分离识别与--num-encs 1多编码器在 v2 API 下均不支持。三、recog_v2 解码主流程逐步解析recog_v2(args)recog.py是解码的核心函数。它自上而下完成以下环节3.1 前置校验与模型加载函数开头先对不支持的场景做防御性检查recog.pyif args.batchsize 1: raise NotImplementedError(multi-utt batch decoding is not implemented) if args.streaming_mode is not None: raise NotImplementedError(streaming mode is not implemented) if args.word_rnnlm: raise NotImplementedError(word LM is not implemented)随后调用load_trained_model(args)recog.py加载训练好的模型confs get_config(args.model_conf) # 用 yacs CfgNode 加载模型配置 class_obj dynamic_import_tester(args.model_name) # 动态导入对应 Tester 类 exp class_obj(confs, args) with exp.eval(): exp.setup() exp.restore() # 恢复 checkpoint char_list exp.args.char_list # 字符表token 列表 model exp.model其中get_config使用yacs.config.CfgNode读取 YAML 配置dynamic_import_tester则根据--model-name动态解析并导入对应的训练/测试器类。load_trained_lm(args)recog.py类似地加载 RNNLM从--rnnlm-conf中读取model_module与model参数构造 LM 实例再用paddle.load(args.rnnlm)装载权重。3.2 输入数据准备模型加载后构造LoadInputsAndTargets来自 reader.py用于读取与预处理音频特征load_inputs_and_targets LoadInputsAndTargets( modeasr, load_outputFalse, # 识别阶段不需要标注 sort_in_input_lengthFalse, preprocess_confconfs.preprocess_config if args.preprocess_conf is None else args.preprocess_conf, preprocess_args{train: False})3.3 Scorer 组装与权重配置这是整个模块最具特色的部分解码器attention decoder、CTC、LM、ngram、长度奖励被统一抽象为Scorer并按权重加权融合scorers model.scorers() # 模型自带 decoder 与 CTC 打分器 scorers[lm] lm scorers[ngram] ngram scorers[length_bonus] LengthBonus(len(char_list)) weights dict( decoder1.0 - args.ctc_weight, # attention decoder 权重与 ctc 互补 ctcargs.ctc_weight, # 联合解码的 CTC 权重 lmargs.lm_weight, # RNNLM 权重 ngramargs.ngram_weight, # n-gram 权重 length_bonusargs.penalty, # 长度惩罚权重 )这里以--ctc-weight为例当ctc_weight0.4时attention decoder 权重为0.6CTC 为0.4两者之和恒为 1体现了典型的Hybrid CTC/Attention 联合打分思路参考 decoders/README.md 中列出的 CTC Prefix Score Join CTC/ATT One-passing Decoding 相关文献。若--ctc-weight1.0则pre_beam_score_key被置为None搜索完全退化为纯 CTC 打分。3.4 构造 BeamSearch 并执行搜索beam_search BeamSearch( beam_sizeargs.beam_size, vocab_sizelen(char_list), weightsweights, scorersscorers, sosmodel.sos, eosmodel.eos, token_listchar_list, pre_beam_score_keyNone if args.ctc_weight 1.0 else full)随后根据打分器类型决定是否启用批式实现recog.py当batchsize 1且所有 full scorer 都实现了BatchScorerInterface时将beam_search.__class__动态替换为BatchBeamSearch否则回退到非批式实现并打印警告日志。需要说明的是仓库中的 batch_beam_search.py 目前仅是一个空占位类class BatchBeamSearch(): pass实际批式打分逻辑在BatchScorerInterface的默认实现中通过 for 循环逐条调用score完成见下文接口分析。设备与精度设置后recog.py进入逐条解码循环with paddle.no_grad(): with jsonlines.open(args.result_label, w) as f: for idx, name in enumerate(js.keys(), 1): batch [(name, js[name])] feat load_inputs_and_targets(batch)[0][0] enc model.encode(paddle.to_tensor(feat).to(dtype)) # 编码器前向 nbest_hyps beam_search( xenc, maxlenratioargs.maxlenratio, minlenratioargs.minlenratio) nbest_hyps [ h.asdict() for h in nbest_hyps[:min(len(nbest_hyps), args.nbest)] ] new_js[name] add_results_to_json(js[name], nbest_hyps, char_list)输入 JSON 文件--recog-json按utt作为 key 组织成字典recog.py每条语句独立完成特征提取 → 编码器前向 → 束搜索 → 结果写回的完整闭环日志中会打印feat与eout的 shape 便于排查问题。四、Scorer 接口与 BeamSearch 搜索内核4.1 四类打分器接口scorer_interface.py 定义了完整的打分器抽象体系ScorerInterfacescorer_interface.py基础接口核心方法是score(y, state, x)对词表内全部 token打分并返回新状态另有init_state初始化状态、select_state按索引裁剪状态、final_score对eos的最终打分默认 0.0。BatchScorerInterface批式版本batch_score(ys, states, xs)其默认实现退化为 for 循环逐条score并给出warnings.warn提示未并行化。PartialScorerInterfacescorer_interface.py部分打分器只对预剪枝后的 token 子集打分score_partial(y, next_tokens, state, x)返回形状为(len(next_tokens),)的分数。典型的实现是 CTC 前缀打分器CTCPrefixScorer对每个时刻只扩展 topK 候选避免对全词表做昂贵的前缀合并计算。BatchPartialScorerInterface批式 部分打分的组合接口。LengthBonuslength_bonus.py是一个简单而有用的 scorer它对词表内每个 token 都返回常量 1.0乘上权重penalty后每扩展一个 token 就给假设增加固定分数从而缓解束搜索天然偏好短句的问题对应论文中的插入惩罚。4.2 BeamSearch 的搜索循环BeamSearch继承自paddle.nn.Layerbeam_search.py构造时按是否实现PartialScorerInterface将打分器划分为full_scorers与part_scorers并把paddle.nn.Layer类型的打分器注册进nn_dict以便整体to(device, dtype)递归迁移。核心搜索过程在forward()beam_search.py与search()beam_search.py中长度边界maxlenratio 0时以编码器输出帧数为最大长度并配合 end-detect 自动终止maxlenratio 0时取绝对值为固定最大长度否则maxlen max(1, int(maxlenratio * T))。单步扩展对每条 running hypothesis先对所有 full scorer 打分并加权求和得到weighted_scores若启用 pre-beamdo_pre_beam先按pre_beam_score_key对应的分数做topk(pre_beam_size)剪枝再对剪枝后的 token 子集调用部分打分器最后加上历史分数。束剪枝beam()方法从加权分数中取 topK选出本轮扩展的 token。终止处理post_process()在最后一轮强制追加eos对已结束的假设调用各 scorer 的final_score累加最终分数后移入ended_hyps。空结果回退若没有任何假设到达eos会递归调用自身并逐步减小minlenratio每次减 0.1下限 0.0并打印提示there is no N-best results, perform recognition again with smaller minlenratio.beam_search.py。end_detect实现在 utils.py其算法对应 Watanabe 等人论文Hybrid CTC/Attention Architecture for End-to-End Speech Recognition中 Eq. (50)若连续 M 步内与当前最佳已结束假设同长度的最佳假设分数差都小于阈值D_end则认为搜索已收敛提前终止解码。五、N-best 结果输出与格式化解码完成后add_results_to_jsonutils.py负责把 N-best 假设合并回原始 JSON保留utt2spk字段对每条假设调用parse_hypothesisutils.py解析出rec_text、rec_token、rec_tokenid与score——其中tokenid去掉开头的sostext由字符拼接并把space还原为空格拷贝 ground-truth 的output信息追加[n]后缀标记第 n 条假设1-best 时在日志中打印groundtruth:与prediction:供人工核对。最终recog_v2向--result-label文件写入每条的规范化结果recog.pyf.write({ utt: name, refs: [ref], # 参考文本 hyps: [rec_text], # 识别文本去除 ▁ 与 eos hyps_tokenid: [rec_tokenid], })注意这里对 BPE/SPM 类词元做了后处理rec_text中的▁空格标记被替换为空格eos被删除并 strip。六、实战示例脚本中的完整调用方式6.1 基于recog.pyV2 API的离线解码examples/librispeech/asr2/local/recog.sh 展示了 V2 API 的典型用法使用 CPU 解码ngpu0--batchsize 0禁用批处理${decode_cmd} JOB1:${nj} ${decode_dir}/log/decode.JOB.log \ python3 -u ${BIN_DIR}/recog.py \ --api v2 \ --config ${decode_config} \ --ngpu ${ngpu} \ --batchsize 0 \ --checkpoint_path ${ckpt_prefix} \ --dict-path ${dict} \ --recog-json ${feat_recog_dir}/split${nj}/JOB/manifest.${rtask} \ --result-label ${decode_dir}/data.JOB.json \ --model-conf ${config_path} \ --model ${ckpt_prefix}.pdparams \ --rnnlm-conf ${rnnlm_config_path} \ --rnnlm ${lmexpdir}/${lang_model}其配套解码配置 examples/librispeech/asr2/conf/decode/decode.yaml 给出了推荐取值batchsize: 0 # 0 表示禁用 batch 解码 beam-size: 60 # 束宽 ctc-weight: 0.4 # CTC 权重attention decoder 权重自动为 0.6 lm-weight: 0.6 # RNNLM 权重 maxlenratio: 0.0 # 0 表示启用 end-detect 自动确定最大长度 minlenratio: 0.0 penalty: 0.0 # 长度惩罚解码完成后脚本调用score_sclite.sh进行 sclite 评分验证解码质量。6.2 与 U2 模型内解码方法的关系需要区分两套解码体系recog.py的 V2 后端面向 U2Kaldi 等通过ASRInterfacescorers()暴露解码器与 CTC 打分器的模型搜索完全由BeamSearch内核驱动支持 LM / ngram 融合。U2 模型内建的decode()方法u2.py则提供四种更轻量的解码策略由配置decoding_method选择attention纯 attention beam search对应recognize()u2.py、ctc_greedy_search、ctc_prefix_beam_search、attention_rescoring先 CTC 前缀搜索出 nbest再用 attention decoder 重打分u2.py。其中ctc_prefix_beam_search与attention_rescoring只支持batch_size 1与 V2 后端一致。对应的解码配置示例见 examples/aishell/asr1/conf/tuning/decode.yamlbeam_size: 10 decode_batch_size: 128 error_rate_type: cer decoding_method: attention # attention, ctc_greedy_search, ctc_prefix_beam_search, attention_rescoring ctc_weight: 0.5 # ctc weight for attention rescoring decode mode. decoding_chunk_size: -1 # 0: 全量 chunk 解码0: 固定 chunk0: 训练专用解码禁用 num_decoding_left_chunks: -1 simulate_streaming: False6.3 DeepSpeech2 的 CTC 束搜索路径另一条常用路径是 DeepSpeech2 的 CTC 解码它不经过recog.py的 Scorer 体系而是直接使用 ctcdecoder/swig_wrapper.py 中封装的 C 解码器ctc_greedy_decoding/ctc_beam_search_decoding/ctc_beam_search_decoding_batch并通过Scorer(alpha, beta, model_path, vocabulary)接入外部语言模型。其配置见 examples/aishell/asr0/conf/tuning/decode.yamldecode_batch_size: 128 error_rate_type: cer decoding_method: ctc_beam_search lang_model_path: data/lm/zh_giga.no_cna_cmn.prune01244.klm alpha: 2.2 # 语言模型权重 beta: 4.3 # 词数权重 beam_size: 500 cutoff_prob: 0.99 # 概率截断阈值 cutoff_top_n: 40 # top-N 候选数 num_proc_bsearch: 10 # 并行进程数七、使用注意事项与限制结合源码实现使用paddlespeech.s2t.decoders.recog时需注意以下边界均为当前仓库代码确认的行为仅支持单条解码batchsize 1抛NotImplementedErrorCTC 前缀搜索与 attention rescoring 在模型内也断言batch_size 1。不支持流式与词级 LM--streaming-mode、--word-rnnlm在recog_v2中均直接抛NotImplementedError。只支持单 GPUngpu 1报错退出float16只可在 GPU 上使用。多说话人 / 多编码器不支持--num-spkrs 2与--num-encs 1在 v2 API 下分别以asr_mix not supported和NotImplementedError拒绝。参数来源灵活由于使用configargparse所有解码参数均可放入 YAML如beam-size、ctc-weight、lm-weight也可在命令行直接覆盖。八、小结paddlespeech.s2t.decoders.recog是 PaddleSpeech 中一套设计干净、可扩展的 ASR 解码后端通过ScorerInterface把 attention decoder、CTC、RNNLM、n-gram 与长度奖励统一为可加权融合的打分器由BeamSearch内核完成端到端的 N-best 搜索并配套完整的命令行参数体系与结果格式化输出。理解这一模块是掌握 PaddleSpeech 离线 ASR 推理、接入自定义语言模型以及调优解码效果束宽、CTC/LM 权重、长度惩罚、长短句边界的起点。更底层的解码器资料与引用文献可继续查看 decoders/README.md。【免费下载链接】PaddleSpeechEasy-to-use Speech Toolkit including Self-Supervised Learning model, SOTA/Streaming ASR with punctuation, Streaming TTS with text frontend, Speaker Verification System, End-to-End Speech Translation and Keyword Spotting. Won NAACL2022 Best Demo Award.项目地址: https://gitcode.com/gh_mirrors/pa/PaddleSpeech创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门