<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Transformer on 楠楠自瑜</title>
    <link>https://cnutshell.net/tags/transformer/</link>
    <description>Recent content in Transformer on 楠楠自瑜</description>
    <generator>Hugo -- 0.157.0</generator>
    <language>zh-cn</language>
    <lastBuildDate>Thu, 30 Apr 2026 21:01:58 +0800</lastBuildDate>
    <atom:link href="https://cnutshell.net/tags/transformer/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>让 Transformer 像计算机一样精确执行确定性程序</title>
      <link>https://cnutshell.net/llm/deterministic-in-transformer/</link>
      <pubDate>Thu, 30 Apr 2026 21:01:58 +0800</pubDate>
      <guid>https://cnutshell.net/llm/deterministic-in-transformer/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;译者：Carl Cui&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;通常我们训练 Transformer 是希望它们内部出现有用的模式识别回路，但是如果我们已经知道了路径呢？如果我们不是从数据中学习权重，而是分析性地构建它们，使模型直接执行计算图呢？&lt;/p&gt;
&lt;p&gt;以上其实是我一个周末项目背后的想法。&lt;/p&gt;
&lt;p&gt;我不把 Transformer 看作一个必须通过优化来发现算法的系统，而是把它当作一台可编程的机器：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;调度序列（schedule）规定了每一步应该计算哪些中间量；&lt;/li&gt;
&lt;li&gt;隐藏维度（Hidden dimensions）被分配给各个变量，就像微型计算机中的寄存器一样；&lt;/li&gt;
&lt;li&gt;注意力头（Attention heads）通过布线（设置权重）来执行查找和路由；&lt;/li&gt;
&lt;li&gt;前馈网络（Feed-forward network）用来实现局部门控计算；&lt;/li&gt;
&lt;li&gt;残差更新（Residual updates）将下一时刻的机器状态写回流中（token 的残差流）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;结果就是一个普通的 Transformer 在执行一个确定性的程序。&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;1*Mwb3Js9fEqGgyxFTcs 6AA&#34; loading=&#34;lazy&#34; src=&#34;https://cdn.jsdelivr.net/gh/cuiguoke/blogger-assets/images/20260430210241405.png&#34;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;图 1：执行程序的 Transformer。残差流存储当前机器状态 &lt;code&gt;(x,y,z)&lt;/code&gt;；嵌入之后，状态包含输入 &lt;code&gt;x=B&lt;/code&gt;；注意力块执行查找步骤 &lt;code&gt;y=lookup[x]=5&lt;/code&gt;，并通过残差加法将该结果写回状态中；然后 FFN 执行局部计算 &lt;code&gt;z=y+1=6&lt;/code&gt;；最后，输出头读取更新后的状态，并输出结果。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在这种观点下，残差流（residual stream）是工作内存，每一层成为一个机器步骤。有的值被读取，有的被转换，有的被传递，有的则在其槽位可以安全复用时被覆写。Transformer 开始变得像一个由注意力、线性投影（linear projections）和门控块（gating blocks）构建而成的小型编译计算机。&lt;/p&gt;
&lt;p&gt;这一切都不需要训练。如果你已经有了一个计算图，以及一张关于每个中间变量应该存在于哪一步的调度表（schedule），那么你就可以直接构造出模型的权重。这样一来，Transformer 就变成了一个执行引擎（execution engine），它的行为由设计决定，而不是由梯度下降（gradient descent）决定。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;有一点会让这件事变得有意义：它为外部工具调用提供了一种替代方案。我们不再需要迫使模型在需要进行精确计算时离开自身的执行循环，而是可以设想给模型一个内部确定性模式。在一种模式下，模型表现得像一个灵活的语言系统：生成、抽象、推理；在另一种模式下，它则更像一台编译好的机器：更新状态、遵循固定的计算图、可靠地执行精确步骤。这与标准的“LLM + 工具”模式完全不同。它表明至少某些形式的精确计算，可以存在于模型内部，而不是外部。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;一个有用的对比是 &lt;a href=&#34;https://www.percepta.ai/blog/constructing-llm-computer&#34;&gt;Percepta 最近关于在 Transformer 内部执行程序的工作&lt;/a&gt;。他们的方案将一个通用的执行机制，实际上是一个解释器，编译进了模型权重，同时将具体的程序在推理时作为提示词的一部分提供。而我这里的设定则更狭窄、更专门化。我并非在权重中放入一个解释器，而是将目标程序本身编译进了权重。换句话说，他们的模型更像一个为提供的程序而设的通用执行器，而这个模型则更像一个为固定计算图打造的专用编译机器。这使得它的通用性较差，但也更简单、更透明，便于理解确定性计算是如何被直接嵌入到标准 Transformer 模块中的。&lt;/p&gt;
&lt;p&gt;在本文的剩余部分，我将通过一个小例子来具体说明上面的思路。我们会从一个简单的程序出发，将其变量分配到隐藏状态的各个槽位中，然后逐步展示：如何通过解析设计来“布线”注意力层、前馈层和残差更新，从而让一个标准的 Transformer 一步一步地执行这个程序。&lt;/p&gt;
&lt;h2 id=&#34;1-编译到-transformer-中的示例程序&#34;&gt;1. 编译到 Transformer 中的示例程序&lt;/h2&gt;
&lt;p&gt;与其停留在比喻的层面，不如亲眼看看一个非常小的程序是如何运行的。下这是我在本文其余部分将使用的示例程序：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lookup &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;A&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;B&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;C&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;9&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;x &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; input
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;y &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; lookup&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;x&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;z &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; y + &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;output z
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这个程序故意很小，但它包含我们需要的三个要素：&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
