postprocess_hotwords: non-Chinese hotword maps to an empty pinyin key and force-replaces every latin/digit span (ratio("","")=100)

未关闭 适合新手
#3,796 3 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
76/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
python

调研方向

从 funasr/utils/postprocess_hotwords.py 开始,重点查看 _to_pinyin_key、_apply_fuzzy 和 PostprocessHotwordMatcher.__init__。使用提供的纯 Python 示例复现问题,然后检查 matcher 现有的测试,确认其覆盖空 pinyin 键和混合文字系统的 pinyin 键。完成标准是:非中文 hotword 不再替换无关的拉丁字母或数字片段,同时有效的中文同音匹配仍能正常工作。

由索引模型根据 Issue 内容生成。

描述

环境
  • funasr 1.4.16(PyPI),paraformer-zh + fsmn-vad + ct-punc
  • 已安装 pypinyin / rapidfuzz(postprocess 模糊匹配依赖)
现象

postprocess_hotwords 传入含拉丁/数字的热词时,转写文本里的英文与数字片段会被整段替换成热词。一个 "AI" 热词会把识别结果刷成满屏 AIAI,数字也被吞掉。

最小复现(纯 Python,不需要模型与音频):

from funasr.utils.postprocess_hotwords import build_postprocess_hotword_matcher

m = build_postprocess_hotword_matcher(["AI"])
out, matches = m.apply_text("用AI做产品,2024年做AI的公司有很多。")
print(out)
# 实际输出: 用AIAI做产品AIAI年做AIAI的公司有很多。
# 期望输出: 原文不变(或仅做同音纠正)

生产环境实测(paraformer-zh 转写 1 小时中文播客,热词 "AI"):转写稿里出现大量 AIAIAIAIAI 连发、2024 等数字被替换成热词。

根因分析

funasr/utils/postprocess_hotwords.py 中:

  1. _to_pinyin_key 用 lazy_pinyin(..., errors="ignore") 构造拼音键,该配置会丢弃所有非中文字符。纯拉丁热词(如 "AI")的拼音键是空串 ""。
  2. _apply_fuzzy 对滑窗 segment 计算 fuzz.ratio(segment_py, target_py),而 rapidfuzz.fuzz.ratio("", "") == 100.0。于是任何拼音键同样为空的滑窗(纯英文/数字窗口)都得满分,超过默认阈值 0.85,被无条件替换成热词。
  3. 连带影响:"A"、"I" 等相邻单字符窗口也各自满分且互不重叠,双双命中后 "AI" 变成 "AIAI";数字窗口 "20"、"24" 同样被替换。
  4. 混合热词(如 "C端")拼音键只剩 "duan",每个同音中文段都会被粘上拉丁:这个端口 → 这个C端口。
  5. 反直觉的是,这类热词本来的目标收益永远无法命中:ratio("ai", "") == 0,期望中的「爱 → AI」同音纠正一次也不会发生。即该路径对非中文热词只有破坏、没有收益。
建议修复

PostprocessHotwordMatcher.__init__ 构造 _length_buckets 时跳过拼音键为空(或与原词长度严重不符)的目标,例如:

for target in self.fuzzy_targets:
    target_py = _to_pinyin_key(target)
    if not target_py:      # 纯拉丁/数字热词:模糊匹配无意义且误伤满分
        continue
    ...

(更严格的话可要求 target_py 覆盖原词的全部非中文字符长度,避免混合词残键误配。)

用户侧临时规避

只把全中文词条传给 postprocess_hotwords;含英文/数字的术语交给其他纠正路径。

主要语言
Python
星标
20.9k
派生
2.1k
平均合并
1 天 3 小时
30 天内合并 PR
46

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

modelscope/FunASR 的其他 Issue

查看 modelscope/FunASR 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。