跳到主要内容
那 0.03 个 bit 才是真东西

那 0.03 个 bit 才是真东西

嘴替
嘴替

· 阅读约 4 分钟

速评:讲 Unix spell 怎么把词典塞进 64kB 那篇文章,一年多前发的,这两天我又翻出来读了一遍。转的人配的评论基本是"前人真巧"。

巧不是重点。

McIlroy 最早那版紧凑结构用的是 Bloom filter,文章里说当时论文里叫叠加编码方案,大概是最早的实用部署之一,实现还是 Ritchie 给的。位表固定 400,000 位,11 个哈希函数,25,000 个词,假阳性率配到 1/2000,他们判定"低到这个程度就不必再回去查完整词典"。整套参数是按 25,000 手工配平的。

然后词典涨到 30,000。位表不够用,方案推倒。

这段我看了两遍。它不是"当年硬件差所以工程师很努力"的故事,它是关于常数的故事——**任何按"现在数据大概就这么大"配平的紧凑结构,保质期不由设计水平决定,由数据的增长速度决定。**25,000 到 30,000,涨了两成,崩了。不是设计得差,是设计得太好,好到精确踩在当前规模上。精确踩在当前规模上,就是这么个下场。

后面那段才真正值得看。他们不存完整哈希表,只存哈希码:30,000 约等于 2^15,能容忍 1/2^12 的碰撞,所以 27 位。27 乘 2^15 位超预算,得压。文章把理论下限算出来了,每词 13.57 位。然后排序、存相邻差值、发现差值服从几何分布、翻出 Golomb 1965 年那篇编码论文,最后压到 13.60。

差 0.03 位。

我第一反应是这数字太漂亮了,漂亮得像事后凑的。第二反应是——他们是先算出 13.57 这个天花板,再动手逼近它的。这个顺序,今天的工程里基本绝迹。

今天做系统的顺序是先算预算:多少张卡、多少 token、多少钱、多长时间,预算花完为止。没人问"这个任务在信息论上的下限是多少",问了也没用,反正卡已经买了。约束从"物理不允许"变成了"财务不允许",而财务约束有个特点——它可以商量。可以再融一轮,可以再续一年云合同,可以写个 PPT 把预算要回来。64kB 没得商量,多一位就装不下。

那 0.03 位不是炫技炫出来的,是没得选。

补一句,免得我把话说太满:他们也没死磕极限。最后为了查询速度,差值表切成 M 个 bin,每词多花 log2 M 位的指针,总存储从 13.60 涨到约 14 位,文章的原话是"仍在内存预算内"。极限算出来是给决策用的,不是拿来供着的——知道天花板在哪,才能判断为速度花掉那 0.4 位值不值。今天的问题在于不少人连天花板在哪都不知道就在花钱买速度,然后管这叫工程取舍。取舍的前提是你知道自己在舍掉什么。

Golomb 那篇是 1965 年的,McIlroy 用它解决的是十几年后的问题。工具箱从来不是新的,能不能翻到,看你知不知道自己在找什么。

也别把这代人浪漫化。词缀剥离那部分是拿准确率换空间:misrepresented 一路归到 present,规则省下的每一位都对应着一批会漏掉的拼写错误。文章说他们当时判定"可以接受"。可以接受这四个字底下埋着多少漏网错词,没人统计,也没法统计。

约束逼出来的东西不全是优雅,一多半是妥协,而且是当事人心里清楚、嘴上说不出口的那种妥协。今天买大内存的代价记在账单上,当年省内存的代价记在漏报率上。账没有消失,只换了币种。谁也别笑谁。

还有个细节:初版 spell 是 Steve Johnson 1975 年一个下午写的原型,Bentley 说的,又慢又不准,但被采用了,McIlroy 才动手重写。原型一下午、重写不知道多久——这节奏今天也成立,区别是今天的原型叫 MVP,一下午写完直接挂上线给几千万人用,然后没有"重写"这一步,只有下一版。

现在聊 context window 上限,思路是再买卡;聊推理成本,思路是再签一份长约。没人去算这个任务压到极限是多少位。1970 年代有人证明过算这个有用,到今天还是没人问。

这里立个 flag:接下来十二个月,会有一个跑得挺顺的基础设施因为某个"我们假设规模大概就这样"的常数崩一次,然后有人写一篇复盘。

崩在哪一层我不敢猜。但那个复盘的标题,我大概能猜到。