让 Transformer 像计算机一样精确执行确定性程序

译者:Carl Cui 通常我们训练 Transformer 是希望它们内部出现有用的模式识别回路,但是如果我们已经知道了路径呢?如果我们不是从数据中学习权重,而是分析性地构建它们,使模型直接执行计算图呢? 以上其实是我一个周末项目背后的想法。 我不把 Transformer 看作一个必须通过优化来发现算法的系统,而是把它当作一台可编程的机器: 调度序列(schedule)规定了每一步应该计算哪些中间量; 隐藏维度(Hidden dimensions)被分配给各个变量,就像微型计算机中的寄存器一样; 注意力头(Attention heads)通过布线(设置权重)来执行查找和路由; 前馈网络(Feed-forward network)用来实现局部门控计算; 残差更新(Residual updates)将下一时刻的机器状态写回流中(token 的残差流)。 结果就是一个普通的 Transformer 在执行一个确定性的程序。 图 1:执行程序的 Transformer。残差流存储当前机器状态 (x,y,z);嵌入之后,状态包含输入 x=B;注意力块执行查找步骤 y=lookup[x]=5,并通过残差加法将该结果写回状态中;然后 FFN 执行局部计算 z=y+1=6;最后,输出头读取更新后的状态,并输出结果。 在这种观点下,残差流(residual stream)是工作内存,每一层成为一个机器步骤。有的值被读取,有的被转换,有的被传递,有的则在其槽位可以安全复用时被覆写。Transformer 开始变得像一个由注意力、线性投影(linear projections)和门控块(gating blocks)构建而成的小型编译计算机。 这一切都不需要训练。如果你已经有了一个计算图,以及一张关于每个中间变量应该存在于哪一步的调度表(schedule),那么你就可以直接构造出模型的权重。这样一来,Transformer 就变成了一个执行引擎(execution engine),它的行为由设计决定,而不是由梯度下降(gradient descent)决定。 有一点会让这件事变得有意义:它为外部工具调用提供了一种替代方案。我们不再需要迫使模型在需要进行精确计算时离开自身的执行循环,而是可以设想给模型一个内部确定性模式。在一种模式下,模型表现得像一个灵活的语言系统:生成、抽象、推理;在另一种模式下,它则更像一台编译好的机器:更新状态、遵循固定的计算图、可靠地执行精确步骤。这与标准的“LLM + 工具”模式完全不同。它表明至少某些形式的精确计算,可以存在于模型内部,而不是外部。 一个有用的对比是 Percepta 最近关于在 Transformer 内部执行程序的工作。他们的方案将一个通用的执行机制,实际上是一个解释器,编译进了模型权重,同时将具体的程序在推理时作为提示词的一部分提供。而我这里的设定则更狭窄、更专门化。我并非在权重中放入一个解释器,而是将目标程序本身编译进了权重。换句话说,他们的模型更像一个为提供的程序而设的通用执行器,而这个模型则更像一个为固定计算图打造的专用编译机器。这使得它的通用性较差,但也更简单、更透明,便于理解确定性计算是如何被直接嵌入到标准 Transformer 模块中的。 在本文的剩余部分,我将通过一个小例子来具体说明上面的思路。我们会从一个简单的程序出发,将其变量分配到隐藏状态的各个槽位中,然后逐步展示:如何通过解析设计来“布线”注意力层、前馈层和残差更新,从而让一个标准的 Transformer 一步一步地执行这个程序。 1. 编译到 Transformer 中的示例程序 与其停留在比喻的层面,不如亲眼看看一个非常小的程序是如何运行的。下这是我在本文其余部分将使用的示例程序: lookup = { "A": 2, "B": 5, "C": 9, } x = input y = lookup[x] z = y + 1 output z 这个程序故意很小,但它包含我们需要的三个要素: ...

April 30, 2026 · 3 min · Sean Moran