不训练,编译:在语言模型的权重里装一台 CPU
给大模型出 40 道大数乘法,不许用工具,要求每一步精确。原版 Qwen3.5(40 亿参数)对 22 道。装上一台 CPU 之后,对 39 道。接真 Python 的,对 40 道。
给大模型出 40 道大数乘法,不许用工具,要求每一步精确。原版 Qwen3.5(40 亿参数)对 22 道。装上一台 CPU 之后,对 39 道。接真 Python 的,对 40 道。
那台 CPU 不在模型外面。它在模型的权重里。
10 月下旬,开发者 Divyansh Agrawal 开源了 Qwenputer:在 Qwen3.5 的 40 亿参数前面另加 11 层,这 11 层合起来是一颗 32 位 RISC-V CPU。11 层一步都没训练——每个权重都是编译器算出来直接填进去的,千问原来的权重一个没动。加载的时候用的还是千问自己的标准模型类,不是一个新架构。
千问自带的零件
CPU 需要两样东西:能精确存数的内存,和能精确算数的电路。千问碰巧两样都有,只是从来没人这么用过。
内存用的是 Gated DeltaNet 的状态矩阵。千问 3.5 的线性注意力层里有一个持续运行的状态,delta 规则本来的职责是「记住新的、冲淡旧的」。Qwenputer 把门和写入强度都设成 1、键只对准一行——这时状态的行为变了:写入一行就是精确覆写一行,一点不遗忘,一点不串行。每一行成了一个内存单元。模型负责记忆的那个矩阵,被当成了内存用。
电路用的是前馈层。编译器把 CPU 的每条指令翻译成查表和加法的组合,前馈层的权重就是那张查找表。
Qwen 怎么「调用」这台 CPU?借它自己训练过的工具调用格式。模型照常写出一个 calc 工具调用块,就像它平时调用任何工具一样——只是外部什么都没有真的执行,计算发生在权重里。生成的时候,一个外挂驱动把 CPU 固件装进 DeltaNet 状态、把 CPU「启动」到起始位置,然后 CPU 的执行痕迹(trace tokens)在千问自己的层之前就被消化掉了,不会污染千问的文本行为。基准测下来,千问的文本分布和原版只差 KL 6e-4,噪声地板是 5e-4——装了台计算机,聊天的手感没变。
照方抓药
这个办法不挑规模。照同样的办法编一颗 8 位小 CPU,放进 4 层的小网络(8362 个非零权重),1000 个随机程序、116 万多条指令和参考解释器逐个对上。有个彩蛋:只把寄存器那张表的门从 1 改成 0.999——每个周期遗忘千分之一——13 × 11 就算成 132。精确和出错之间,隔着 0.001。
作者的 11 层也单独跑了:123456789 × 987654321 生成 1111 个 token,一段 C 语言的 CRC-32 程序生成 6283 个 token,都和参考机器逐条一致,结果和 Python 算的一样。作者自己的回放更狠:23 万个输出位置对着参考机器逐个核,零失配。
代价
慢。L4 显卡上一次计算器调用半秒到一秒,这还是用了作者的加速程序(Triton 版每秒 3200 个执行 token,融合版 5500)。大。模型文件从 9.3 GB 涨到 18.8 GB(README 自己给的数是合并后 14.65 GB,多出来的权重几乎全是零,所以下载体积和原版差不多——胀的部分是稀疏的)。还要一个开机驱动,没有它 CPU 起不来。
Hacker News 上吵的是什么
10 月 29 日,Qwenputer 上了 Hacker News 首页,697 分,145 条评论。技术上最较真的是用户 gcr:他先夸了「Really cool work」,然后指出「不靠外部运行环境」的说法要打个折扣——固件的加载、CPU 启动到起始状态、要跑的程序的编译装载,这三件事仍然由一个自定义的主机运行时完成;CPU 运行期间,也是这个运行时手动跳过千问自己的层,保证只有 CPU 层在跑。他希望作者对这些限制更坦率些。
作者在 10 月 20 日的动作可以看成一种回应:修了一个固件 bug(每次调用开始时没把大数寄存器清零,连续调用会继承脏寄存器),同时从 README 的 RISC-V 一节删掉了「从没打印过错误结果」这句声明——CHIP-8 老版本那一节里还留着,删的只是新版的。
模仿者已经进场
10 月 30 日,Drew Breunig 开源了 nesformer:用同一套编译思路,把红白机的 6502 处理器、2 KB 内存和一张卡带的程序 ROM 一起编进了原版 Qwen3.5 的权重,一天 196 个 star。社区里跑得更远的已经出现:有人把 Doom 的 E1M1 第一关地图在权重里的 RISC-V 上跑了起来,还有人往 RV32IMA 机器的方向推,目标是在里面跑 Linux。
回头看这件事的位置。之前的叙事是模型在吃掉外部脚手架——工具、检索、编排,一层层被卷进模型自己的能力里。Qwenputer 是这条路上最狠的一步:连 CPU 都被吃进去了。但 gcr 那条评论刚好说明了另一半——加载固件的、启动 CPU 的、跳层的,还是模型外面那个运行时。它没有消失,只是改名叫 driver。
至于精确和遗忘的距离:0.001。门设成 1,权重里的 CPU 一个比特都不会错;改成 0.999,13 乘 11 就写成 132。
*Qwenputer:github.com/divagr18/qwenputer(326 star);模型:huggingface.co/divagr1925/Qwen3.5-4B-Qwenputer;nesformer:github.com/dbreunig/nesformer。文中基准数字出自仓库 README(DeepMind mul_big,贪心解码 40 题),实测数据来自本号复现与作者回放。*