Files
yenharvey a41d1cf82a feat: 接入含章·通变与知微模型
接入含章·通变的拼音解码、整句重排与词图兜底生成,扩展 macOS、Windows 和 Linux 的模型加载路径。模型文件按正式标识归档,保留旧用户目录回退,并同步数据打包、评测记录和用户文档。
2026-09-29 12:02:00 +08:00

7.7 KiB
Raw Permalink Blame History

模型假设与验证尺子

输入法里「模型可能能做的事」不止整句重排一件。每一件在动手之前都要先回答:用什么指标算成功、指标从哪些数据算、 现在的基线是多少。基线算不出来的假设不立项。这份文件记每个假设的尺子;输入日志(input-log.jsonl)按这里的需要定格式, 回放评测(qingjian-cli --replay)按这里的指标出报告。

原则

  • 日志记的是情境、给的、做的、事后反馈四件事,不是某个模型的特征。字段与模型无关,任何排序 / 预测 / 纠正类假设都能回放验证。
  • 漏记的补不回来,多记的代价很低:情境数据只要隐私成本接近零就记。
  • 不记应用里的光标前文(含用户没通过青简打的内容)、逐键时间戳、Secure Input 期间的任何东西。
  • 每个假设先写指标与基线,再改代码;改完在同一份冻结日志上比(日志是活的,两次复制的不一样)。
  • 日志验不了的(延迟、UI 感受、反事实「当时给了 X 会不会选」)只能自己用;反事实只在 X 恰好出现在用户最终文本时近似。

日志格式 v1

一行一条 JSON,t 是本机时间戳,event 是事件名;读端跳过不认识的事件与字段,以后加字段不升版本。

事件 何时 字段
session 输入法启动、日志开关打开时 v 格式版本、version 输入法版本、platform、model 本地整句模型开没开、scheme 双拼方案
commit 每次上屏 原有:id scope keys pinyin corrected text source index top(一页 9 条)scheme english;新增:rescored 候选顺序经过神经重排、app 应用标识、pages 翻了几页、ms 首键到上屏的毫秒
retract 上屏后整个退格删掉、同段拼音改选了别的 of text chosen
retype 组句里退格重打,最终键串与第一次退格前不同;或上屏后删掉重打了不同的键 before after of(对应的上屏 id)
passthrough 组句外直打的标点 / 回车 / 空格,攒到下一次上屏或边界时写 text
prediction 云端联想结果到达并展示 scope words sentence
break 上文链断开(切应用、失焦、清空) app 新应用标识

假设与尺子

假设 指标 用哪些字段 基线
整句重排(已做) 词 / 整句首选命中 commit 的 top index 2026-09-12 冻结日志 12886 条可评:词 86.9% / 整句 90.2% / 英文 82.9%(原样上屏也回放进学习之后;之前的 72.5% 是回放没学个人英文词);短语层进词库后 87.3% / 88.2% / 82.5%(整句掉的多半是旧引擎没有短语时用户只能选前缀的偏差,见 docs/notes/phrase-layer.md);领域词 48 条进词库后 87.6% / 88.4% / 82.5%(docs/notes/domain-words.md)
排序常数(个人 n-gram 插值 λ / K / 封顶 / D,敲错四类代价 / 折扣上限 / 整段纠错代价) 同上,--tune 名=值 扫网格 同上 2026-09-12 扫过一轮:全在平台区,见 docs/notes/constant-sweep.md
个人微调(LoRA) 按天留出的首选命中 commit 文本流 + passthrough + break 同上,待按天切
敲错纠正 对 retype 的召回、对正常输入的误纠率 retype、commit.corrected 待攒(事件新加)
本地联想替代云端 预测的下一词 = 用户接着打的词;云端被接受的比例 prediction + 紧接的 commit.source 待攒
中英混输判定 判成英文 vs 用户原样上屏 commit.source == raw 且键像英文词 可从现有日志算
候选质量的隐式信号 翻页数、组句耗时与命中率的相关性 commit.pages commit.ms 待攒
按应用风格 分应用的首选命中 commit.app 待攒
长句切分 / 简拼展开 切分与最终文本的对齐 commit.pinyin commit.text 可从现有日志算
神经重排的净效果 rescored 为真 / 假两组的首选命中 commit.rescored 待攒
神经 P2C(带噪拼音直接生成汉字) 整句首选 + 一次重解码的耗时,两者都要过 commit 的 keys pinyin corrected text(天然就是「带噪拼音 → 正确文本」的监督对) 整句首选 41.6%(冻结集 8322 句,当前带重排的成绩,不是裸基线 37.6%);延迟见下节与 docs/notes/p2c-latency-spike.md

神经 P2C 的延迟门槛(2026-09-20 量过)

这个假设与别的不同:准确率赢了但延迟不达标,一样不立项。把词库召回换成模型生成之后, 候选的存在本身就依赖模型,而拼音前缀每敲一键就变、整句要重解码一次,所以延迟是第一道门槛而不是最后一道。

crates/qingjian-neural/examples/p2c_bench.rs 在 M1 本机拿现有字级模型当代理量过一轮(完整表格与偏差说明见 docs/notes/p2c-latency-spike.md)。延迟只能在目标设备上量,租的卡量不了:用户跑的是 mac 的 Metal 与 Windows 的 CPU。

项 门槛 代理模型(full-small 23M)
一次整句重解码(Metal,前文 64,beam 4,8 字) < 100 ms 68 ms ✔
同上,CPU < 150 ms 141 ms(勉强)
每键增量(前文 64 字,推进 1 个 token) < 10 ms Metal 2.1 / CPU 6.7 ✔
模型加载 < 500 ms 66 ms ✔

已知结论:拼音前缀可缓存、成本可忽略;瓶颈是解码的前向(占 Metal 66% / CPU 95%),把 top-k 搬上 GPU 也只省掉 Metal 那 28%。因此 P2C 当同步主候选不成立(beam 8 / 16 字 Metal 218 ms、CPU 416 ms,追不上 5 到 8 键每秒的手速), 可行的位置是现有的停键异步槽位,词库继续出同步候选。

P2C 值得试的理由是它能做三件当前架构做不到的事:未登录词按字生成、纠错进模型本身、 句中英文(现在 english_tail.rs 只支持句末尾段,见「中英混输判定」那一行)。三件在离线前提下都没有别的解法。

已知的尺子偏差

  • 日志里「选了」的整句多半是当时按空格接受的基线自己的输出:模型对、日志错的例子不少(输入狂 → 输入框)。 整句质量以冻结评测集 data/eval/sentences.tsv 为准(见 docs/notes/neural-rescoring.md),回放只看词级与个人学习。
  • 2026-09-12 以前的日志有一半是空的 raw 行(壳每次回车 / 失焦都调一次 take_raw),读端要跳过 keys 与 text 都空的行。
  • 回放里原样上屏(raw)也要走一遍 take_raw:个人英文词(gist)与「这个串不纠」都是从那里学的,跳过它英文首选低 10 个点(72.5% → 82.9%), 那不是排序的问题,是尺子没学。2026-09-12 起回放这么做。
  • 整句「不在候选」328 条的构成(2026-09-12):16 条是 青简(词库没有的专名,个人词该学但回放从零起);294 条与现在首选同长、只是同音换字 (184 条差一字、112 条差两字:我之前 → 我只前、行的 → 型的、新写的 → 新鞋的),这一类靠上下文分,归神经重排与个人 n-gram, 其中不少「选了」本身就是当时按空格接受的错句(是按、所有哟偶、你先准备以下);18 条长度不同,是切分 / 简拼尾巴(准备以 ← zhunbeiyix)。
  • 词级没命中 1208 条里 742 条是 5 键以上、当时从词候选里选的短语(导航栏 / 候选框 / 我绷不住了 / 对齐),多半是词库缺词而不是排序; 最常重复的键是 ba(45 条,吧 / 把 看上下文)与 wode(34 条,词库缺 我的)。调常数救不了这两类,要补词库与靠上下文模型。