技术8/25/2026·约 5 分钟

更多词,反而更差

我们拿自己词库和一个五倍大的词库做了基准对比。大的那个分更低:top-1 42.36% 对我们的 47.71%,内存 86 MiB 对 18。真正有意思的是我们拿这个结果去做了什么。

那套专门为了被反驳而建的基准

我们的输入引擎出厂时带着一本词库、一个静态语言模型和一个长尾专家模型。在这些东西靠近任何一台设备之前,我们先建了一套评测:一份固定的留出用例,统计 top-1、top-3、top-5 和 MRR,延迟量的是整条拼音增量输入序列而不是单键。

建它的目的不是为宣传页产出一个数字,而是让取舍变得可读,包括那些我们预期会输的取舍。所以第一次正式运行,拿我们的出厂数据和我们能合法评测到的最大词库——一个大五倍的开源词库——在同样的用例和同样的评分配置下对比。

词库词条Top-1MRRp95常驻内存
更大的开源词库1,866,63442.36%0.49226.58 ms86.3 MiB
我们的352,36447.71%0.55668.04 ms17.9 MiB

五倍的词条,排序更差——在每一个精度指标上都是。而且常驻内存接近五倍。它唯一的优势是延迟,而那个优势在我们这边是靠一个更小、更有针对性的模型换来的,不是靠更大的词库。

这套基准让它得以说出的那句话,是我们在没有这张表之前不会相信的:

更多词条不会自动让排序更好。

这不是在宣称我们的数据有多好。这是在宣称这个问题的形状:词库是一组候选的生成器,而它每多加一条词条,同时也是你原本想赢的那个位置上多一个竞争者。规模不是覆盖,覆盖也不是精度。

那次什么都没变的实验才是有用的那次

把神经模型从 float 量化成 packed int10 与 int8,本来是要把它变小。评测量到的正是它该给出的东西:

Top-1Top-3Top-5MRRp95
量化前31.67%43.10%48.11%0.37755.94 ms
量化后31.67%43.10%48.11%0.37756.03 ms

完全相同。每一个精度数字都没动,MRR 没动,延迟在噪声内。

把它当成「量化是免费的」来汇报很容易。诚实的读法更窄、也更有用:量化在这个模型、这个工作负载上是免费的,而这个结论只有在你真的去量、而不是假设的时候才配说出来。换一个模型、换一种架构、换一个对长尾敏感的任务,同一个操作完全可能改变数字。是那次测量授权了那句话,而它不授权任何更宽泛的推论。

我们发布了量化后的模型。这部分很容易。真正有价值的产出是知道了自己被允许说哪一句话。

一个无法自我晋升的模型

这套系统里最刻意的一部分,是那个说不的部分。

我们当前的模型不是一个候选。不是因为它失败了,也不是因为谁忘了——它的 manifest 把这些写成字段:

production_ready = false
promotion_eligible = false
use_policy = research-only
blind_data_used = false

九条具名的 readiness 阻塞项仍然开着,包括 frozen 盲测从未执行、某个对话语料来源是 research-only、以及某本词库的许可证来源未经验证。训练数据量目标已经达成,而文档明确写着这不构成晋升理由——量不是证据。

而这套机制是结构性的,不是靠文化:

报告无法宣布自己合格。 晋升不是训练运行自己设的字段,而是晋升阶段给出的判决。一份声称自己合格的报告,不是一份你该晋升的报告。

签名由别人来做。 晋升路径把分离签名监督器构建成一个独立产物并显式依赖它,好让 OpenSSH 签名校验无法静默回退到一个没构建的、或者不相干的辅助工具。说「这个好」的,不是产出候选的那个东西。

最终 bundle 会与一份固定清单逐项比对。 最后的生产构建器把自己的可执行清单与受信候选报告逐条比较。任何实际可执行制品的漂移都会拒绝晋升——包括通过手改本地 manifest 声称已就绪的那种漂移。

这每一条都是某个下午六点、赶着发布的人可能会想走的捷径。设计假定他们会走,于是把机会拿掉,而不是请求他们别走。

缺失的测量不是通过

内存那道门是这种纪律最锋利的例子,而它其实与模型无关。

发布档位硬性要求峰值常驻内存与峰值内存 footprint都不超过 10 MiB。在 macOS 上系统工具同时给出两者;在 Linux 上只给常驻内存,于是 footprint 不可用。

策略并不对这两种情况取平均。在 Linux 上跑完一次完整且全部通过的四臂消融,产出的报告仍然被标为 rejected——不是被弱化,不是被加注,不是被「有条件通过」。文档把理由写得很直白:Linux 可以完成这次运行并产出可审计的报告,而这份报告仍然不能被晋升,因为做那个决定所需要的证据从来没有被采集。晋升应当在对的目标平台上补齐。

同一条规则还出现在一个更小的位置:footprint 被测到时,它必须严格大于 0,因为一个报出来的 0 与一次没发生的测量无法区分。

这是一个有真实代价的设计选择——在 Linux 上被验证过的一次真实改进,在有人到 macOS 上重跑一遍之前就是不能晋升。我们刻意接受了这个代价。一份写着「我需要而没量的那个指标」的报告,比一份悄悄换用手上那个指标的报告值钱,因为替换对每一个下游读者都是不可见的,而且和一个「通过」无法区分。

盲测集拒绝声称的东西

最后一块,因为它是同一条原则用在数据集上。

对于一个不会被晋升的模型,它的评测集被保管协议托管着,而它产出的证明书在自己的字段里声明尚未被确立的东西:盲集没有被证明未开封,语义泄漏没有被证明不存在。它直白地说所用的哈希不是防篡改的,因为能重写语料的人也能重写描述它的 manifest。

与此同时,能查的闸门确实在查,而且很严:盲集的最低规模、固定的候选深度、最小的领域与交互覆盖,以及防止一个套件靠只测简单用例蒙混过关的逐格下限。在某个平台上,导出步骤 fail closed——轨迹不带 selector 就无法被释放,而那些 selector 本身就会泄漏设计。

这一切背后的模式是同一个,它也是我们能把上面任何一条写下来的原因:

报告你测到的,报告你测不到的,并且绝不让第二类被悄悄变成第一类。

一套只产出好看数字的基准是广告。我们的这套产出了一张我们更小的数据赢了的表、一个只授权了一句话的量化结果,以及一个不管门禁怎么落都不会自我晋升的模型。

小结

把评测建成一个可以被反驳的东西。在你「需要」它之前就写好它的理由是:这样一来,一个你不喜欢的结果仍然是一个你必须发布的结果。我们这套显示五倍的数据分更低——这不是一个让人高兴的发现,也正是这套基准值得写的全部理由。

区分「这个改动是免费的」和「这个改动在这里是免费的」。量化前后指标逐位相同,只授权一句关于一个模型、一个工作负载的话。没有那次测量,你要么跳过这个优化,要么夸大它——而两者都比把它发出去更糟。

让做判断的那个东西,没法被被判断的那个东西说服。我们能想到的每一条捷径都由结构而不是政策回答:合格与否是别处给出的判决,签名来自单独构建的监督器,最终 bundle 与固定清单做 diff,手改的 manifest 在最后一步失败。信任是一种结构材料。

并且拒绝把缺席转成成功。如果工具量不到那个决定所依赖的东西,那个决定就不该被做出——报告如实说明然后就停在那里。这不方便,而这正是所有说「是」的报告能被相信的原因。

文中提到的产品

继续阅读