BLOG
技术拆解 036|Nesformer:把 NES 塞进 Qwen 权重
技术拆解:热点发布 × 技术判断 × 实用建议。
背景/现象
2026 年 10 月 30 日,GitHub 上出现了一款叫 Nesformer 的项目。它的自我介绍非常直白:「An NES CPU compiled into the weights of a stock Qwen3.5 model.」也就是说,作者没有训练一个游戏 AI,也没有写传统模拟器,而是把一台任天堂 Entertainment System 的 CPU 编译进了 Qwen3.5 的权重里。整个模型不做微调,所有参数都由编译器直接算出。
这件事很快引起了技术圈的关注,因为它把「大模型权重能不能当成一台计算机」这个问题推到了极端。过去我们习惯把 LLM 看作聊天工具,把权重看作一堆训练出来的统计规律。Nesformer 的做法相当于宣布:权重不只是语言的统计容器,也可以直接编码一台完整的游戏机 CPU。
它的上游是 Divyansh Agrawal 的 Qwenputer。后者已经把 CHIP-8 和 RISC-V CPU 编译进 Qwen3.5-4B,证明这种思路可行。Nesformer 把对象换成了更复杂的 NES,也就是 80 年代红遍全球的红白机美版主机。从 CHIP-8 到 RISC-V 再到 NES,复杂度在逐级提升,概念验证的意义也越来越明显。
NES 本身的硬件并不复杂:一颗 1.79 MHz 的 Ricoh 2A03 处理器(兼容 MOS 6502)、2 KB 内存、PPU 负责图像输出、APU 负责声音。但要把这样一套系统塞进 LLM 权重,仍然需要在 CPU 指令集、内存寻址、I/O 映射之间做出完整映射。作者 dbreunig 选择 NES,既是因为它有经典游戏可以演示,也是因为它足够复杂,能够真正考验「权重即计算机」这一命题的边界。
这个项目在 Hacker News 上以 Show HN 形式发布后,迅速收获了大量讨论。有人惊叹于它的创意,也有人质疑它的实用价值。但不管立场如何,大多数人都同意:它至少在工程层面把一件听起来像科幻的事做成了可运行的代码。
技术原理/架构
Nesformer 的核心思路是把 CPU、RAM、ROM 全部映射进大模型的状态里。它选择的基础模型是 Qwen3.5-4B,实际结构做了大幅裁剪:只保留 7 层 Gated DeltaNet,再加 1 层全零 attention 层以满足 HuggingFace 的 cache 要求。总参数量 466.6M bf16,但非零参数只有 9.3M,压缩后 weights zip 仅 3.3 MB。
关键的 trick 在于 Gated DeltaNet 的状态矩阵。作者把状态矩阵的每一行都当作一个可寻址内存单元,设置 gate=1 保证不衰减,write strength=1 保证完全覆盖,再用 one-hot key 精确定位。于是每一次写入都能精确覆盖某一行,模拟出 CPU 寄存器、RAM 和 ROM 的行为。
具体来说,模型权重里编码了 NES 6502 CPU 的全部 151 条官方 opcode、所有寻址模式、标志位、堆栈,以及 BRK/NMI 入口。2 KB 工作 RAM、32 KB PRG-ROM(存两份,一份取指令,一份读数据)、256 字节 OAM DMA 都被塞进模型里。渲染层面的 PPU、控制器输入、APU 寄存器写入和 vblank NMI 注入,则由外部 host.py 负责。
换句话说,Nesformer 把「运行 NES 游戏」这件事拆成两部分:模型内部负责 CPU 执行和内存状态更新,模型外部负责把 token 流翻译成屏幕像素和用户输入。这种分工让权重真正承担起了计算任务,而 host 只负责把结果可视化。
相比传统模拟器用循环解释 opcode,Nesformer 的做法是把整个 CPU 状态机展开成矩阵乘法。每一步前向传播对应一个 CPU 周期,token 的流动对应数据在寄存器和内存之间的搬运。DeltaNet 的 recurrent 状态天然适合表达「上一次状态 + 当前输入 → 下一次状态」这种离散时间系统,这也是为什么它能把 CPU 编译进去而不是训练出来的原因。
词表规模也值得一提:263,808 个 token。这么大的词表不是为了语言多样性,而是把 CPU 地址、数据总线、控制信号都编码成了离散的 token。输入一个 token,模型就能根据当前状态和指令做出下一步状态更新。这种设计让模型的前向传播过程与 CPU 时钟周期形成了一一对应关系。
关键数据/案例
性能方面,Nesformer 离实用还很远。它的速度大约比真实 NES 慢 150 到 290 倍。用 numba 编译最快的前向路径、配合跳零块优化,单核大约能跑到 1,650 tokens/秒;而走 stock transformers 路径只能到 10 tokens/秒。真实 NES 要满帧运行需要约 700,000 tokens/秒,差距一目了然。
验证数据方面,作者验证了几款 NROM mapper 0 游戏,包括 Super Mario Bros. 和 Donkey Kong。更严格的一致性测试显示,Thwaite 600 帧用了 1,916,527 tokens、模拟时间 10.0 秒,其中 300 帧与常规 6502 模拟器逐帧一致;Doug Fraker Full Game 420 帧用了 2,645,885 tokens,同样逐帧一致;nestest 一致性套件在 4,586 tokens 后达到了 HALT 状态。这些数据说明模型在逻辑层面确实复现了 6502 CPU 的行为。
不过这些数据全部来自 README,我没有本地复测,运行帧率也会受硬件和 numba 版本影响。读者如果真想复现,需要先下载约 1GB 解压后的 bf16 权重,并用 shasum 校验 weights/SHA256SUMS。构建环境要求 Python 3.11 以上,外加 numpy、scipy、numba 和 pillow,运行命令是 python -m nesformer run ROM,支持 --frames、--buttons 和 --show 等可选参数。
从压缩率角度看,Nesformer 的参数分布也很有趣。466.6M bf16 参数中只有 9.3M 非零,稀疏率超过 98%。压缩后整个权重包只有 3.3 MB,比很多 NES ROM 本身还小。这说明编译生成的权重可以用极少的有效信息表达复杂的确定性计算,至少在理论层面挑战了「参数越大越好」的固有印象。
影响/意义
Nesformer 最大的意义在于它把「权重即计算机」这个隐喻变成了可运行的工程事实。过去人们讨论 LLM 能否做算术、能不能运行程序,大多停留在 prompt 层面。Nesformer 证明,只要架构设计得当,大模型的状态空间可以直接编码通用计算和存储结构,而且不需要任何训练,全部由编译器生成。
这件事对模型架构研究有两层启发。第一,它验证了 Gated DeltaNet 状态矩阵的可编程性。只要控制好 gate、write strength 和 key 的分布,就能把状态行变成可寻址内存。第二,它提示了一种新的压缩思路:466.6M 的 bf16 参数里只有 9.3M 非零,压缩后仅 3.3 MB,说明稀疏化和编译式生成可能比端到端训练更适合某些特定任务。
从更宏观的视角看,Nesformer 和 Qwenputer 一起,把「在 LLM 权重里跑虚拟机」这个话题推向了更高复杂度。CHIP-8 和 RISC-V 更像教学演示,NES 则涉及 CPU、内存、I/O、渲染协调,是一个更完整的系统。未来类似的思路可能会被用来在模型里嵌入更复杂的确定性计算模块。
这个项目还模糊了「模型」和「程序」的边界。传统软件工程里,程序和内存是分开的;Nesformer 把它们合并进了同一组权重。如果这个方向继续发展,未来可能出现这样的应用:一个 LLM 权重里同时封装了语言理解、推理能力和固定的业务规则引擎,部署时只需要一个文件。
对于端侧部署而言,这种高度稀疏的编译权重也很有吸引力。如果未来的手机或 IoT 设备需要运行一个确定性很强的协议栈或状态机,把它编译进模型权重可能比单独维护一个运行时更加轻便。当然,这还需要在推理效率和可维护性之间找到平衡。
争议/风险
首先是性能瓶颈。150 到 290 倍慢于真实 NES,意味着它目前只能作为概念验证,距离实际游玩体验还很远。即使未来通过量化、编译优化或专用硬件加速,要把 token 吞吐率从千级提升到真实主机的十万级以上,仍然需要数量级的提升。
其次是可维护性和扩展性。把 CPU 编译进权重,意味着任何 bug 修复或功能扩展都要重新跑编译器,而不是像传统模拟器那样改几行代码。对于 mapper 更复杂的游戏,比如 MMC3、MMC5,权重规模可能会大幅膨胀,当前方案能否扩展还是未知数。
第三是评估口径的局限。仓库 README 中所有性能数字和一致性测试都是作者自己跑的,目前没有独立第三方复现。再加上它只能跑 mapper 0 的游戏,覆盖面有限。读者在引用这些数字时需要加上「作者自称」的限定。
最后还有一个更深层的问题:把通用计算硬塞进 LLM 权重,是否真的能带来工程优势?如果单纯为了兼容性,传统模拟器显然更快、更易调试。Nesformer 的价值更多在于探索边界,而不是取代现有方案。
另外,这种把确定性计算编译进神经网络权重的方法也引发了关于可解释性的担忧。传统模拟器的每一行代码都对应明确的硬件行为,而权重中的计算是高度分布式的。一旦系统出现错误,定位和修复都会比传统软件困难得多。
结论/展望
Nesformer 是一次高纯度的技术展示。它没有训练任何权重,而是把一台 NES 的 CPU 编译进了 Qwen3.5 的 7 层 Gated DeltaNet 里,用稀疏参数复现了 6502 CPU、RAM、ROM 和 OAM 的行为。它能跑 Super Mario Bros. 和 Donkey Kong,但速度比真实主机慢两个数量级。
短期来看,这个项目会吸引模型架构、编译器和复古游戏模拟三个方向的关注。它提供了一个可复现的基准,让研究者能直接测试「状态矩阵即内存」的上限。中期来看,如果这类编译方法能够扩展到更复杂的 mapper 和更高效的推理路径,或许能在端侧设备上实现一个模型权重同时承载多种确定性功能的场景。长期来看,它提醒我们:大模型的权重空间远比聊天、摘要、推理更广阔,它可以被编程成任意计算结构,只要我们能找到合适的编译方法。
未来一个有趣的研究方向是「混合权重」:语言理解和推理部分仍用传统训练得到,而确定性规则、协议解析、状态机等模块用编译方式嵌入。这样既能保留神经网络的柔性,又能获得可验证的确定性行为。Nesformer 已经证明这条路走得通,接下来就看能不能把它从玩具项目推向真正的工程应用。另一个待解问题是编译器的通用性:它现在针对 NES 做了大量手工映射,能否抽象成更通用的「将任意有限状态机编译进权重」的工具链,将决定这个方向的最终价值。
这个项目采用 MIT 许可证,代码和构建说明都已公开。如果你对这种「权重即计算机」的玩法感兴趣,可以直接 clone 仓库,按照 README 的步骤跑一遍。即使跑不动全速游戏,只看它如何用 9.3M 非零参数复现一台 NES,也足够值得琢磨。
署名永亮