bootgpt 发布:512 字节引导扇区运行 int8 语言模型

原标题:Show HN: A language model that lives in a boot sector
78AI 研判分

开发者推出 bootgpt,一个能在无操作系统、无 C 运行时的 16 位实模式下运行的微型语言模型。该模型仅占 11.5 KB(int8 量化),由手写汇编加载并执行,能生成模拟的 Linux 启动日志。这一实验展示了在极端受限硬件环境下部署神经网络的可行性与工程技巧。

报道正文

本文目录3 个章节

bootgpt

一个能启动你 PC 的神经网络。

MBR(主引导记录)是 512 字节的手写汇编代码。它从随后的 23 个扇区加载一个 11.5 KB 的 int8 模型,并在 386 处理器的 16 位实模式下运行它。没有操作系统,没有 C 运行时库,什么都没有。机器醒来后“梦”出了一段 Linux 启动日志:时间戳、PCI BARs、以及为从未存在的硬件生成的 ACPI 事件。

demo

构建线程:https://x.com/krlntn/status/2116514628457185757

在仅有 8 个字符上下文和一个隐藏层的情况下,大致能得到如下质量:

文本
[  2.283888] pci 0000:01:01.4: [1b36:0a35] ryndrde c4128 6422 Vveine
[  1.953886] pci 0000:01:1f.2: reg 0x10: [mem 0x7e4515e5-0x2d766c27] usbbore: reg
[  0.206596] Command line: BOOT_IMAGE=/vmlinu -5.5.2-1-generic gcc version 13.3.0, GNU ld ...
[  1.815765] ACPI: PCI Interrupt Link [LNKA: v/s.xos212
[  1.883084] NET: Registered protocol family 16

运行方法

文本
brew install nasm qemu
python3 -m venv .venv && .venv/bin/pip install numpy
./build.sh
./run.sh

disk.img 是一个标准的启动镜像。如果你有支持 BIOS 的设备,可以将其 dd 写入 USB 闪存盘并直接启动。它只读取属于自己的扇区。

组件说明

corpus_gen.py 生成 3 MB 的伪造 dmesg 数据。每次启动会话使用一个内核版本和一个磁盘标识,因为真实的启动日志具有重复性,而这种重复性正是让微型模型看起来合理的关键。

train.py 负责训练模型(字符嵌入、单个隐藏层、softmax),并将所有内容量化为带有 2 的幂次方缩放因子的 int8 格式,以便引导扇区仅通过 imul 和单次 idiv 指令即可完成整个前向传播过程。该脚本还模拟了汇编代码将执行的确切整数运算(包括 LCG 采样器),因此 Python 输出与引导扇区输出可以进行逐字符比对。它们完全一致。

boot.asm 包含整个运行时逻辑:使用 int 13h 加载权重,使用 int 10h 打印输出,通过 cdq/idiv 实现软截断激活函数,以及利用定时器种子噪声进行 argmax 采样。任何按键操作都会重启机器。

record.py 通过监视器套接字从无头 QEMU 中录制演示 GIF。无需打开窗口界面。

引导扇区仅包含代码。字符串、权重和词汇表都存放在数据扇区中,这是将推理逻辑加上 BIOS 底层接口塞进 510 字节的唯一办法。

先前工作

引导扇区(boot sector)这一领域历史悠久且成就斐然。Oscar Toledo 在其中塞进了一个完整的 国际象棋程序、一个 操作系统,甚至还有一个 BASIC 解释器;其他人则实现了 C 编译器。所有这些全部压缩在 512 字节之内。他关于引导扇区游戏的著作值得一读。

最接近的同类项目是 sectorllm,它仅用约 1.2 KB 的真实模式汇编代码,就能从引导过程中启动一个真正的 Llama2 Transformer 模型(包含 5 层结构、注意力机制等完整组件),运行的是 Karpathy 的 stories260K 模型。sectorlisp-nn 则在引导期间于 Lisp 解释器上运行一个经 TensorFlow 训练的网络。此外,还有一些 UEFI 应用程序可以直接在现代硬件上引导进入 llama 类模型。

而 bootgpt 走向了另一个极端:整个推理引擎完全容纳在 510 字节的 MBR(主引导记录)本身之中,权重和字符串数据存放在随后的扇区中。该模型并非通用的故事生成器,而是一个微小的字符级神经网络,专门针对单一任务进行训练——即“幻觉”出它所唤醒的那台机器的启动日志。


作者发帖说明(HN):

所有灵感均源自引导扇区的演示场景(demo scene),在那里人们曾在 512 字节内编写国际象棋和 BASIC 游戏,甚至包括 C 编译器。我好奇的是,如果用神经网络代替传统程序能做什么?为非存在的硬件生成启动日志是一件非常有趣的事情。

整个推理引擎仅占 510 字节的 MBR 空间,权重、词表和字符串数据位于 MBR 之后的扇区中。这个小型字符级神经网络是在由机器生成的 dmesg 日志上进行训练的,因此这台机器能够无限地生成 Linux 启动消息。

train.py 执行的整数运算与 asm 代码完全一致,因此生成的输出在字符级别上与 QEMU 产生的输出完全相同。差异分析揭示了一个我最喜欢的 bug。开头的字符与模拟器生成的结果匹配,但随后输出出现了分歧。我通过 QEMU 的调试端口获取了隐藏层,并将神经元的值与模拟器的值逐个神经元进行比较。只有第一个神经元的值是正确的。激活过程涉及 idiv 指令,而 idiv 会将余数存储在 edx 寄存器中。指向偏置(bias)表的指针原本存储在 edx 中,这导致第一个神经元的偏置计算正确,而后续神经元则使用了垃圾数据。现在,偏置的地址是根据循环计数器确定的,从而无需让任何指针在除法操作后存活。另一个 bug 是我在进行首次运行之前,仅通过查看代码就发现的:BIOS 打印例程会将 bx 清零,但 bx 中包含的是……