ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

MMS N-best Re-ranking 实战指南:用简单重排序提升野外多语言 LID+ASR 识别准确率

MMS N-best Re-ranking 实战指南:用简单重排序提升野外多语言 LID+ASR 识别准确率 MMS N-best Re-ranking 实战指南用简单重排序提升野外多语言 LIDASR 识别准确率【免费下载链接】fairseqFacebook AI Research Sequence-to-Sequence Toolkit written in Python.项目地址: https://gitcode.com/gh_mirrors/fa/fairseq核心导读本文档基于 examples/mms/lid_rerank/README.md完整讲解 Fairseq 生态中多语言语音识别ASR的 N-best 重排序N-best Re-ranking推理流程。该方案针对先预测语言身份LID、再按语言转写的真实野外in the wild多语言识别场景先为每条语音生成 N-best 语言假设用对应语言的 ASR 模型分别转写再借助语言模型、书面 LID、声学模型等外部特征对候选转写重新打分排序从而显著提升 LID 准确率与转写质量。阅读本文后你将掌握 LIDASR 推理、外部特征提取、特征系数调优、测试集重排序的完整命令行流程并能读懂背后每一条命令对应的源码实现。1. 方法概述N-best 重排序为何有效野外多语言语音往往语言混杂、口音与背景噪声复杂单次 LID 预测极易出错。MMS N-best 重排序的思路非常直接用 N-best 而不是 1-best 来做决策。完整工作流包含四步运行 LIDASR 推理支持 MMS 与 Whisper 两条后端计算外部重排序特征在开发集dev set上调优特征系数将最优系数应用到测试集test set。从源码结构看这一流程对应 examples/mms/lid_rerank 目录下的四个子模块每个子模块对应一个步骤步骤目录核心脚本LIDASR 推理whisper、mmsinfer_lid.py/infer_asr.pyinfer.py等外部特征mala、nllb、mms-zsinfer.pyinfer.pyuromanize.py/falign.py系数调优reranktune_coefficients.py测试集应用rerankrerank.py1.1 为什么重排序能纠正 LID 错误设某条语音实际为英语但 LID 模型把英语排在第 2 位。传统的 1-best 决策会用错误语言如法语去转写结果自然很差。N-best 重排序会保留前 N 个语言假设用 N 种语言各转写一遍再借助语言无关的外部信号如 LLM 对候选文本的困惑度、书面文本 LID 模型、罗马化声学模型的强制对齐分数重新打分。如果英语假设的转写文本在这几个外部特征上得分最高重排序就能把它提升到第 1 位同时纠正 LID 与 ASR 两个环节的错误。这正是论文Improving Multilingual ASR in the Wild Using Simple N-best Re-ranking的核心思想本目录即该论文的官方开源实现。1.2 代码组织与数据格式约定重排序管线各脚本间通过纯文本文件交换数据统一采用每行一条的格式。理解这些约定是跑通流程的关键N-best 相关文件nbest_lid、nbest_asr_hyp每行对应一条 N-best 候选长度是句子数的 N 倍分数文件slid_score、asr_score、wlid_score、lm_score、uasr_score同样逐行对齐第 i 条语句的 N 个候选占据行区间[i*N, i*NN)。例如 tune_coefficients.py 中的断言len(ref_lid) * args.n len(nbest_lid)正是校验这一对齐关系一旦不满足会直接抛错。2. 步骤一LIDASR 推理2.1 数据准备首先准备一个 wav 列表文件每行一个音频路径#/path/to/wav/list /path/to/audio1.wav /path/to/audio2.wav /path/to/audio3.wav工作流假设 LID 与 ASR 的参考标注可用至少开发集要有Whisper 与 MMS 统一使用 3 字母 ISO 语言码MMS 使用的 4017 语言码表可参考其官方文档。2.2 Whisper 后端Whisper 的安装请参考其官方文档。先运行 LID 推理得到 N-best 语言假设与分数python whisper/infer_lid.py --wavs path/to/wav/list --dst path/to/lid/results --model large-v2 --n 10--n 10表示 N-best 列表大小为 10。从 infer_lid.py 源码看该脚本对每个 wav 调用model.detect_language(mel)取概率最高的前 N 个语言然后将(语言, 概率)原始列表写入predictions将语言码经 lid_mapping.txt 映射为 MMS 3 字母码逐行写入nbest_lid将log(概率)逐行写入slid_score。lid_mapping.txt的格式为whisper语言码;MMS语言码如en;eng、zh;cmn共 99 行覆盖主流语言。接着用 top-N 语言假设依次做 ASRpython whisper/infer_asr.py --wavs path/to/wav/list --lids path/to/lid/results/nbest_lid --dst path/to/asr/results --model large-v2infer_asr.py 会把每个 wav 复制 N 份for _ in range(args.n)与nbest_lid逐条配对用whisper.DecodingOptions(beam_size1, languagelang_code)逐条解码并将转写文本逐行写入nbest_asr_hyp长度归一化分数avg_logprob * length逐行写入asr_score。注意该脚本通过--mapping参数将 MMS 语言码反向映射回 Whisper 语言码若未出现在映射表中则直接透传默认映射文件同样为whisper/lid_mapping.txt。2.3 MMS 后端MMS 后端基于 Fairseq 生态需先按 examples/mms/README.md 的说明准备数据与模型LID 模型与对应字典如mms1b_l126.pt与dict.lang.txt。MMS 后端的 wav 列表格式与 Whisper 不同需要用脚本转换python mms/format_wav_list.py --src /path/to/wav/list --dst /path/to/wav/manifest.tsv注意 README 中此命令名为mms/format_wav_list.py仓库中对应实现为 prep_wav_list.py首行写/作为根目录随后每行写wav路径\t采样点数采样点数通过soundfile读取计算。同时 MMS 要求 LID 参考标注放在与 manifest 同名的.lang文件中即/path/to/wav/manifest.lang。随后运行 MMS LID 推理N-best 大小同样设为 10cd path/to/fairseq/dir PYTHONPATH. python3 examples/mms/lid/infer.py path/to/dict/dir --path path/to/model --task audio_classification --infer-manifest path/to/wav/manifest.tsv --output-path path/to/lid/results --top-k 10该命令的核心实现位于 examples/mms/lid/infer.py通过options.get_generation_parser(default_taskaudio_classification)解析参数并追加--top-k默认 3、--infer-manifest、--output-path等自定义参数load_model_ensemble_and_task加载模型与任务用FileAudioDataset读取 manifest并用AddTargetDataset包装.lang标签wrap_target_dataset要求 manifest 与.lang文件行数一致对每个样本计算log_softmax后取topk将(语言码, 概率)列表写入output-path/predictions.txt。之后运行 ASR使用 top-N 语言预测。由于 MMS 使用语言特定参数脚本将推理按语言并行化# 按语言切分数据 python mms/split_by_lang.py --wavs_tsv /path/to/wav/manifest.tsv --lid_preds path/to/lid/resultspredictions.txt --dst path/to/data/split # 生成各语言的 ASR 命令并写入可执行文件 mms/make_parallel_single_runs.py --dump path/to/data/split --model path/to/model --dst path/to/asr/results --fairseq_dir path/to/fairseq/dir run.sh # 逐个语言顺序执行也可自行并行化 . ./run.sh # 将各语言结果合并回原始顺序 python mms/merge_by_run.py --dump path/to/data/split --exp path/to/asr/results三个脚本的职责如下split_by_lang.py读取 manifest 与predictions.txt每行一个 eval 后的[(lang, prob), ...]列表将每个 wav 按 top-k 语言复制展开后按语言分组写入dst/lang/test.tsv与dst/lang/ids.txt记录全局序号以便合并并生成占位的test.ltr/test.wrdmake_parallel_single_runs.py遍历切分出的语言目录为每个语言打印一条python mms/run_single_lang.py ...命令run_single_lang.py真正执行 ASR——调用examples/speech_recognition/new/infer.pyinfer_common配置、viterbi 解码、dataset.gen_subsetlang:test并把结果通过reorder_decode按ids.txt的顺序重排写入hypo.word.reord与asr_score.reord。其内部维护了一个mapping如cmn - cmn-script_simplified、srp - srp-script_latin把部分 3 字母码映射为脚本级语言码。若某语言不被 ASR 模型支持会写入空行并打印提示这属于预期行为merge_by_lang.py汇总各语言的hypo.word.reord与asr_score.reord按ids.txt的全局序号合并回原始顺序输出nbest_asr_hyp与asr_score。值得一提的是README 中的命令名为mms/merge_by_run.py仓库内实际文件名是 merge_by_lang.py使用时注意以仓库文件名为准。至此Whisper 或 MMS 两条后端都会产出统一的中间产物nbest_lid、slid_score、nbest_asr_hyp、asr_score。3. 步骤二计算外部重排序特征重排序的外部信号共四类LLM 语言模型分数、书面 LID 模型分数、U-roman 声学模型强制对齐分数以及调优/应用时使用的ASR 分数与假设长度。前三者按以下方式计算。3.1 MaLA大语言模型特征lm_scoreMaLA 是 500 语言的多语言 LLM用于给 N-best 候选转写打分——语法通顺、语言正确的候选应获得更高概率python mala/infer.py --txt path/to/asr/results/nbest_asr_hyp --dst path/to/lm/results从 mala/infer.py 源码看其实现为加载meta-llama/Llama-2-7b-hf基座模型resize_token_embeddings(260164)后加载MaLA-LM/mala-500的 PEFT 适配器支持--gpu开关决定是否放到 cuda对每条候选文本逐 token 计算log_softmax概率并累加为对数概率逐行写入lm_score。3.2 NLLB书面 LID 模型特征wlid_scoreNLLB 仓库提供了 fastText 训练的书面向 LID 模型用于判断这段文本更像哪种语言python nllb/infer.py --txt path/to/asr/results/nbest_asr_hyp --dst path/to/wlid/results --model path/to/nllb/model从 nllb/infer.py 源码看脚本用fasttext.load_model加载书面 LID 模型对每条候选做model.predict(t, k218)最多取 218 个候选通过fix_code把 NLLB 语言码映射回 MMS 码如arb-ara、zho-cmn内置映射表见源码第 16 行然后在预测列表中查找与输入 LID 一致的语言并输出其log(概率)若目标语言不在预测前 218 位中则输出-1000作为惩罚分数写入wlid_score。注意该脚本还接受一个--lid参数传入nbest_lid用于逐行指定每条候选对应的目标语言。3.3 MMS-ZeroshotU-roman 声学模型特征uasr_scoreMMS-Zeroshot 是通用罗马化U-roman声学模型。整个流程分两步先把 N-best 转写统一转写成罗马拼音再用强制对齐计算音频与文本的匹配度。第一步U-roman 化python mms-zs/uromanize.py --txt path/to/asr/results/nbest_asr_hyp --lid path/to/lid/results/nbest_lid --dst path/to/uasr/results --model path/to/mms-zeroshoturomanize.py 调用模型目录下的uroman/bin/uroman.plperl 脚本配合norm_uroman归一化小写、去除标点、压缩空格逐词转写。对于cer_langs.txt中列出的字素-音素一一对应的语言如cmn、jpn、tha、yue、lao等见 cer_langs.txt按字符级处理char_langTrue否则按词级处理最终写入nbest_asr_hyp_uroman。第二步强制对齐打分python mms-zs/falign.py --uroman_txt path/to/uasr/results/nbest_asr_hyp_uroman --wav path/to/wav/list --dst path/to/uasr/results --model path/to/mms-zeroshotfalign.py 加载Wav2Vec2ForCTC模型与 processor对每条音频计算 CTC log 发射概率outputs.log_softmax随后对每个 N-best 候选的 token 序列调用lib.falign_ext.falign做强制对齐取对齐 alpha 序列末端的最大值作为匹配分数对齐失败如 token 超出词表时回退为log(1e-9)逐行写入uasr_score。该脚本会自动选择 cuda、mps 或 cpu 设备。3.4 依赖与运行环境requirements.txt 列出了全部依赖transformers、peft、protobuf、blobfile、sentencepiece、fasttext、numpy1.26.4、librosa、ninja、editdistance。其中numpy1.26.4的版本上限值得注意是兼容性约束。4. 步骤三调优特征系数重排序的打分公式为候选特征的加权和。系数调优在开发集上进行核心命令python rerank/tune_coefficients.py --slid path/to/lid/results/slid_score --asr path/to/asr/results/asr_score --wlid path/to/wlid/results/wlid_score --lm path/to/lm/results/lm_score --uasr path/to/uasr/results/uasr_score --dst path/to/rerank/results --ref_lid ground-truth/lid --nbest_lid path/to/lid/results/nbest_lid --ref_asr ground-truth/asr --nbest_asr path/to/asr/results/nbest_asr_hyp从 tune_coefficients.py 源码可以拆解出完整的搜索机制输入slid声学 LID 分数、wlid书面 LID 分数、asrASR 分数、lmLLM 分数、uasrU-roman 强制对齐分数外加ref_lid/ref_asr参考标注与nbest_lid/nbest_asr候选脚本会先断言五类分数长度一致特征拼接feats [[s, w, a, l, u, le] ...]其中le是候选转写的长度lengths [len(x) for x in nbest_asr]即打分公式包含 6 个特征s*w_slid w*w_wlid a*w_asr l*w_lm u*w_uasr le*w_len随机采样系数--iters默认 10000次迭代中每次按np.random.rand() * scale采样一组系数各特征有独立缩放范围--slid_scale默认 100、--wlid_scale默认 100、--asr_scale默认 10、--lm_scale默认 10、--uasr_scale默认 10、--len_scale默认 1且长度项系数在[-0.5, 0.5]内采样并行评估--num_jobs默认 64个进程通过multiprocessing.Pool并行执行compute对每组系数在开发集上计算 LID 准确率与 ASR WER词错误率若参考语言属于cer_langs.txt则按字符级计算 CER即 .join(hyp)后按字符切分评估指标compute返回{lid_acc, asr_wer, weights}其中 WER 使用editdistance计算对每条语句在 N 个候选的加权分数中取最大值对应的候选作为重排序输出输出全部结果写入dst/results.allWER 最低的一组系数写入dst/best_coefficients格式为字典的字符串表示含weights键。--exclude参数可传入若干语言码调优时跳过这些语言不参与 LID 准确率与 WER 统计用于验证语言泛化性。5. 步骤四在测试集上应用重排序测试阶段不再搜索系数而是直接使用调优得到的最优系数python rerank/rerank.py --slid path/to/lid/results/slid_score --asr path/to/asr/results/asr_score --wlid path/to/wlid/results/wlid_score --lm path/to/lm/results/lm_score --uasr path/to/uasr/results/uasr_score --dst path/to/rerank/results --ref_lid ground-truth/lid --nbest_lid path/to/lid/results/nbest_lid --ref_asr ground-truth/asr --nbest_asr path/to/asr/results/nbest_asr_hyp --w path/to/rerank/results/best_coefficients关键差异在于--w参数从 rerank.py 源码看weight eval(open(args.w, r).read())[weights]直接读取best_coefficients中的系数列表随后select函数用相同公式对每个 N-best 块计算加权分数并取最大值。执行完毕后重排序结果位于path/to/rerank/results/reranked_1best_lid重排序后的 LID 1-bestpath/to/rerank/results/reranked_1best_asr_hyp重排序后的 ASR 转写 1-best。同时text.result中会记录本次评估的lid_acc与asr_wer。rerank.py还提供--tag参数为输出文件追加后缀如reranked_1best_asr_hyp.tag便于多组系数对比实验--exclude同样可用。6. 完整端到端流程速查将四个步骤串起来一次完整的实验路径如下# ---- 步骤 0准备 ---- # wav 列表每行一个 wav 路径 # ---- 步骤 1LIDASR以 MMS 为例---- python mms/format_wav_list.py --src wav.list --dst manifest.tsv # 实际文件名为 prep_wav_list.py PYTHONPATH. python3 examples/mms/lid/infer.py dict_dir --path lid_model \ --task audio_classification --infer-manifest manifest.tsv --output-path lid_results --top-k 10 python mms/split_by_lang.py --wavs_tsv manifest.tsv --lid_preds lid_results/predictions.txt --dst data/split mms/make_parallel_single_runs.py --dump data/split --model asr_model --dst asr_results --fairseq_dir . run.sh . ./run.sh python mms/merge_by_lang.py --dump data/split --exp asr_results # ---- 步骤 2外部特征 ---- python mala/infer.py --txt asr_results/nbest_asr_hyp --dst lm_results python nllb/infer.py --txt asr_results/nbest_asr_hyp --dst wlid_results --model nllb_lid_model --lid lid_results/nbest_lid python mms-zs/uromanize.py --txt asr_results/nbest_asr_hyp --lid lid_results/nbest_lid --dst uasr_results --model mms_zs python mms-zs/falign.py --uroman_txt uasr_results/nbest_asr_hyp_uroman --wav wav.list --dst uasr_results --model mms_zs # ---- 步骤 3开发集调优 ---- python rerank/tune_coefficients.py --slid lid_results/slid_score --asr asr_results/asr_score \ --wlid wlid_results/wlid_score --lm lm_results/lm_score --uasr uasr_results/uasr_score \ --dst rerank_results --ref_lid dev.lid --nbest_lid lid_results/nbest_lid \ --ref_asr dev.asr --nbest_asr asr_results/nbest_asr_hyp # ---- 步骤 4测试集应用 ---- python rerank/rerank.py --slid lid_results/slid_score --asr asr_results/asr_score \ --wlid wlid_results/wlid_score --lm lm_results/lm_score --uasr uasr_results/uasr_score \ --dst rerank_results --ref_lid test.lid --nbest_lid lid_results/nbest_lid \ --ref_asr test.asr --nbest_asr asr_results/nbest_asr_hyp --w rerank_results/best_coefficients # 输出rerank_results/reranked_1best_lid 与 rerank_results/reranked_1best_asr_hyp7. 实现细节与工程要点7.1 打分公式与系数语义综合 tune_coefficients.py 与 rerank.py候选最终得分可写成score w_slid * slid w_wlid * wlid w_asr * asr w_lm * lm w_uasr * uasr w_len * length各项特征都取对数域如slid与wlid均为 log 概率、lm为 log 累加概率、uasr为 log 对齐 alpha因此加权和等价于对数域的概率融合。len_scale的系数可在[-0.5, 0.5]区间采样允许长度惩罚为负值用于抑制过长的幻觉转写。7.2 多语言文本的 CER/WER 区分cer_langs.txt 列出了无需分词即可按字符计算错误的语言如bod、cmn、dzo、jpn、khm、lao、mya、tha、yue、adx、khg。调优与评估代码中compute/select对属于该列表的语言将假设与参考 .join(...)后按字符切分再计算编辑距离否则按词切分计算 WER。同时uromanize.py也以同一份列表决定是否按字符级做 U-roman 化。7.3 语言码映射管线中存在两处关键映射Whisper ↔ MMSlid_mapping.txtwhisper码;MMS码infer_lid.py正向映射、infer_asr.py反向映射NLLB ↔ MMS内置在 nllb/infer.py 的mapping字典中如arb-ara、zho-cmn、uzn-uzbMMS ASR 脚本级语言码run_single_lang.py 的mapping如cmn-cmn-script_simplified、urd-urd-script_arabic。这三层映射的存在是因为不同模型族Whisper / MMS / NLLB / MaLA使用各自的语言编码体系重排序必须统一到同一套 3 字母码上才能逐行对齐特征。7.4 可复现性与故障排查所有分数文件必须逐行对齐且长度一致脚本通过多重assert强制校验见 tune_coefficients.py报错时优先检查 N-best 展开顺序是否与 wav 顺序一致MMS ASR 按语言并行后必须经过merge_by_lang.py合并否则nbest_asr_hyp的顺序与nbest_lid无法对应合并脚本对重复 ID 会触发pdb断点出现时应检查split_by_lang.py的输出是否有重复若某语言不在 ASR 模型支持范围内run_single_lang.py会写入空行并继续这是预期行为不会中断整体流程falign.py中对齐失败的回退分数log(1e-9)相当于把该候选的 uasr 特征压到极低值属于防御性设计。8. 引用若在研究中使用了本方法请引用article{yan2024wild, title{Improving Multilingual ASR in the Wild Using Simple N-best Re-ranking}, author{Brian Yan, Vineel Pratap, Shinji Watanabe, Michael Auli}, journal{arXiv}, year{2024} }9. 进一步阅读方法论文Improving Multilingual ASR in the Wild Using Simple N-best Re-rankingarXiv:2409.18428本目录实现examples/mms/lid_rerankREADME 与全部脚本MMS LID 推理与模型清单examples/mms/README.md 中的 LID 章节以及 LID 推理脚本 examples/mms/lid/infer.py相关预处理工具examples/mms/data_prep。【免费下载链接】fairseqFacebook AI Research Sequence-to-Sequence Toolkit written in Python.项目地址: https://gitcode.com/gh_mirrors/fa/fairseq创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表