Nathan Barry 提出了一个脑洞实验:能不能让 gzip 当语言模型?不要神经网络、不要训练参数,就用你操作系统里那个现成的压缩器——拿语料喂进它的滑动窗口,给个正常提示词,让它在"怎么压最省"的驱动下继续往下生成。结果真的能出字符,虽然远谈不上通顺,但它确实"知道"语料里的一些东西,比作者预期的多得多。
理论根基是那篇《Language Modeling is Compression》讲的压缩-预测等价:每个预测模型本质上是压缩器,而所有压缩算法本质上都是预测模型。信息论的核心——一个符号编码需要的比特数等于 -log2(p),p 是模型给它的概率——意味着任何压缩器内部都藏着一个概率模型,不管有没有人把它写出来。
gzipt --corpus data/tinyshakespeare.txt --prompt $'MENENIUS:\n' --length 200
MENENIUS:
'Though all at once canq
MARCIUS:
Pray now, nocamest thou to a morsel .
LARTIUS:
Hence, and
I' the end admire, where G
again; and after it ag .
gzip 用的是 DEFLATE,它压缩下几个字节的方式是在 32 KiB 的滑动窗口里找最近的匹配。如果生成的续写呼应了窗口里的文本,DEFLATE 就会用便宜的回指编码而不是逐个字节,于是压得极小。这就给出一个打分方法:想判断某段候选续写好不好,就看 len(gzip(上下文+候选)),压得越小说明越"被预测"。把语料塞进窗口当"先验",像语料的续写就压得小,不像的就压得大。
但真正生成没那么简单。最朴素的"选压得最省的下一个字节"会翻车,因为 gzip 只给整数的字节长度——加上一个字节经常根本不影响压缩长度,一堆候选并列,信号被量化噪声淹没了。作者的解法是往前看一段整的再做决定:gzipt 跑的是束搜索,每一步尝试语料中出现过的每个字节,把所有候选按压缩长度打分并剪枝,保留最省的那一束,推进一个 horizon 后再提交。
有个细节特别关键:得分时只有生成的最近一小段尾字节留在上下文里。因为 DEFLATE 对近处的匹配编码得更便宜,如果让 gzip 看到全部历史,它最容易滑进逐字复读——不停拷贝自己刚生成的内容。限制成像窗口那样只留尾部,才逼着它去"接话"而非"复读"。
整件事就是一个纯标准库 Python 文件(只用 zlib),代码在 GitHub 上。论文里也试过这条路但效果差,作者认为束搜索把生成质量显著拉高了一截。这个实验的启示不是"gzip 能干翻大模型"——它显然不能——而是把"压缩即预测"从理论变成能玩的东西:最朴素的压缩器,配上一行束搜索,就能自己"写"出有语感的文本。对理解压缩和预测为什么是一体两面,这比任何抽象论述都直观。
来源: