Files
Lu Fan(SonnyCalcr) 8a524aa498 feat(engine): 全拼纠错扩展到多字/漏字,贵档读法按整句分领衔 (#623)
* feat(engine): 合法输入纠错扩展到多字、漏字,纠错读音按原始区间消耗字母

jiuzheeyang 切成 jiu'zhe'e'yang 全合法,多打的 e 原本纠不回「就这样」;多字纠错的
读音又与原始字母不等长,buuhui 选「不会」后会剩下一个 i。

- legal_input_correction_cuts(原 legal_input_transposition_cuts)认换位、多字、漏字
  三类静态表读法,不认邻键与生成式空间;末尾音节按漏字读出的(nia -> nian)视为
  还没打完,跳过;k-best 先取 9 条再过滤,长句里纠正不被别处的读法挤掉
- 改变字母数的纠正代价 3.0(换位 2.0);字面切分本身是真词时不认改变字母数的读法,
  少一个音节的句子在语言模型里天然分高(邪恶 -> 些、答案 -> 但)
- 新增 correction_cut_for_reading / corrected_reading_raw_length:选词按纠错切分
  记录的原始区间消耗字母,预编辑也按它分隔(jiu'zhee'yang)
- AutocorrectCut 恢复 has_generated,供合法输入路径排除生成式读法

* fix(engine): 被裁掉的合法输入纠错读法不再误标原读法的候选

合法输入上的纠错读法登记进了全局纠错标记表,即使裁决时被丢掉也照样参与按读音字母
的标记匹配:xiee 按多一个 e 读成 xie 被丢掉后,邪恶后面的前缀单字 写/些/血 读音
也是 xie,全被标成纠错。

改为不登记,只在 arbitrate_legal_corrections 里给真正用上的那条纠错读法的整读音
候选打标,标记随结果进缓存。

* feat(engine): 结构性贵档纠错读法可按整句分领衔

shiideya 的换位读法 shi + ide->die(权重 10,是爹呀)比多字读法 shii->shi(权重 12,
是的呀)便宜一档。#592 只在同档内做上下文消解,贵档读法一律排在最后,「是的呀」
连首页都进不了。

- 上下文消解把前 2 条贵档读法也解码,不要求词库有整词;总分 = 路径分 - 手误代价,
  代价按纠错表权重换算(权重 x 0.2:换位 2.0、漏字 2.2、多字 2.4)
- 只收由结构性手误(换位、漏字、多字)构成的贵档读法:邻键只比漏字贵 0.4 分,
  常用词的语言模型优势会把 zhowei 的「周围」挤成「作为」
- AutocorrectCutSegment 记录每段的纠正权重,用来区分纠正类型
- 预编辑跟随领衔读法分隔也覆盖切不成合法音节的输入(shii'de'ya)
- eval_quanpin_autocorrect 新增 --word-lattice,量产品默认开词格时的排序

评测(--word-lattice,300 样本,seed 42)各档 R@1/R@3 不低于改动前:mixed R@1
79.7/76.7/78.3/70.3 -> 82.3/81.7/81.3/78.0,insertion 83.3/74.7/72.7/52.0 ->
91.3/89.3/90.0/83.7,deletion 持平或上升,ambiguous 持平。

* fix(engine): 纠错上下文消解在任一整句来源开启时生效

上下文消解只认 word_lattice 开关。只开万象重排、不显示 Trigram 整句时(词格在内部
照样解码),整段被跳过,shiideya 退回静态排序,「是爹呀」又领衔。

- 新增 SentenceAssociationOptions::any_sentence_source,门控改看它;全关时仍是纯
  静态排序,#592 的「关联关闭 = 静态路径」不变
- 贵档胜者没有整词也没有整句行时(重排模型未载入),由它的最长前缀词领衔,不让
  主切的行顶回首位
2026-10-05 01:41:37 +08:00

52 lines
4.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# engine/tests
本目录产出两个独立二进制,都通过 `add_subdirectory` 链接 `engine/CMakeLists.txt` 的正式引擎库 `MetasequoiaIme::Engine`(不另抄源文件清单,编译选项与出货构建一致),互不依赖:
| 目标 | main | 用途 |
|---|---|---|
| `imetest` | `src/test_pinyin.cpp` | 引擎测试:全拼/双拼会话、退格、词典增删与查询时序;注册源只有 `test_pinyin.cpp`,CI 不执行,仅作本地跑测试的入口 |
| `eval_quanpin_autocorrect` | `src/eval_quanpin_autocorrect.cpp` | 全拼纠错离线评测:采样真实 msime.db 注错,测召回(R@1/R@3)、读音还原与温态延迟 |
## 构建
```powershell
cmake --preset default
cmake --build build --config Release --target <imetest | eval_quanpin_autocorrect>
```
两个目标共用同一份引擎库,只多编各自的 main。日常改代码跑 `imetest` 即可,按需单独构建评测目标。
## eval_quanpin_autocorrect:离线评测工具
这是**评测工具,不是测试**,永远进不了 CI:
- 依赖真实的 `msime.db`(用 `--db` 指定)和 `server/assets/tables` 资源目录(在仓库根目录运行,或 `--resource` 指定)。
- 不挂测试框架、不进断言,产出的是 markdown/CSV 报告,供人工对照基线。
- 存在的理由:纠错阈值、门逻辑(gate)或错误类型改动后,需要用同一把尺子复测。固定种子保证逐档样本一致,数字与历史基线可比。基线口径是「改动后各档不得低于基线值」的零回归门禁。
注错的变体生成规则(交换/邻键/漏字/多字、QWERTY 邻键表、长度与合法音节过滤)与 `server/scripts/generate_quanpin_autocorrect.py` **必须逐键一致**——两侧漂移会让注错模型脱离纠错表的假设空间,基线失去可比性。改任一侧时在同一个提交里同步另一侧。
`--seeds-file <路径>` 是独立数据入口:每行 `typo<TAB>期望key[<TAB>期望词]`(`#` 注释、空行跳过,期望词缺省时取该 key 的最高权重词),产出独立的 Seed suite 报告节与 `seeds` 聚合 CSV 行。它**豁免于上述逐键一致契约**——种子表度量的正是契约外与用户反馈直接相关的场景(误报/漏报样例固化)。
资源目录要求:引擎加载 `sc.lm`(词格)与 `sentence-model-*.safetensors`(神经重排),而 `server/assets/tables` 只有 `dict_pinyin.dat`、`helpcode.txt`、`user_dict.dat`——模型文件不入库。本机没有把模型放进 tables 时,用安装数据目录拼一个隔离资源目录(只读模型拷贝 + `msime.db` 副本),`--db` 与 `--resource` 都指过去;直接指安装目录也可以,但评测进程会以读写方式打开 `--db`,拷贝副本更干净。
沙箱环境下子进程可能被拒绝在 `%TEMP%` 下新建目录(表现为 `create_directories: Access is denied.` 后直接退出),把 `TEMP`/`TMP` 环境变量指到仓库内的已存在目录再跑即可。
历史基线与采集笔记在归档任务目录:`.trellis/tasks/archive/2026-09/09-12-quanpin-autocorrect-patent/eval/`(阶段 0 基线)与 `09-13-quanpin-insertion-autocorrect/eval/`(insertion 上线前后对照)。
### 运行
```powershell
# 仓库根目录执行;--model 可选 mixed|deletion|ambiguous|insertion|outside
# outside = 表外形状注错(非相邻替换/远键插入),度量生成式纠错空间的覆盖增益,
# 与静态表形状构造性不相交——该档 R@1 在无生成空间的代码上恒为 0。
./engine/tests/build/bin/Release/eval_quanpin_autocorrect.exe `
--db <msime.db 路径> `
--samples 300 --seed 42 --model mixed `
--csv eval-mixed.csv > eval-mixed.md
```
产品默认开着词格整句联想,纠错的上下文消解(同档消解、结构性贵档读法按整句分领衔)只在词格开启时生效。要量产品实际的排序,加 `--word-lattice`,并让 `--resource` 指向带 `sc.lm` 的目录;不加时测到的是纯静态排序,与历史基线口径一致。
参数细节与报告分节说明见 `src/eval_quanpin_autocorrect.cpp` 文件头注释。