Transformer的工作原理:从RNN瓶颈到注意力机制、智能体与上下文窗口
变压器结构详解:为何RNN发展停滞、标记与嵌入的工作原理、注意力机制、QKV、头单元、位置信息、块结构以及缩放因子与代理。
那些只使用人工智能工具的人无需了解其底层运作机制也能应付自如,但那些想要构建、调试或改进这些系统的人则无法做到。目前所有常用的大型语言模型都基于2017年发表的一篇约15页的论文中所提出的架构,该论文标题为《Attention Is All You Need》。过去十年中,很少有研究论文能像它一样深刻地改变人工智能的发展方向。其背后的理念其实并不像听起来那么复杂,只要按照正确的步骤逐步推导,相关的数学运算也并非难以理解。此后,这些理念随处可见:体现在智能体如何规划任务、上下文学习为何有效、模型为何能在对话过程中切换话题,以及更长的上下文窗口为何如此重要等方面。
下面的路线从传统的顺序处理方式及其停滞的原因讲起,接着介绍文本如何转化为数字,再探讨注意力机制与完整块结构,最后说明该设计是如何发展成如今的语言模型和智能体的。
为何逐词阅读文本会遇到瓶颈
在Transformer出现之前,语言处理主要依靠循环神经网络,通常简称为RNN。其原理很简单:网络逐词处理序列,并向前传递隐藏状态,即对迄今为止所见内容的持续总结。
大致情况是:有人阅读小说时可能只保留一张便签,必须逐页阅读,既不能跳过前面内容,也不能倒回去看。每读完一句,就会把重要内容写在便签上,但由于便签面积有限,能记录的内容很少。到第300页时,第1页的内容几乎全被抹去。同时让朋友阅读第二章也是不可能的,因为必须先完成第一章的便签记录。
这种严格的顺序要求带来了两个独立的缩放问题。
第一个问题是梯度消失。训练过程通过反向传播来调整权重,该过程会追踪每个参数对误差的贡献程度。在处理长序列的RNN中,这一信号必须逐时间步反向传递。等到传递到最早期的时间步时,其强度往往已经衰减到几乎为零,因此网络实际上无法从那些早期的词句中学习到任何信息。
第二种是顺序瓶颈。在处理完位置n-1之前,无法计算出位置n的结果,因为每一步都需要使用之前的隐藏状态。现代GPU专为同时执行大量操作而设计,而RNN几乎无法让它们并行处理任何任务。一份1,000字的文档需要连续进行1,000步处理,其间硬件大多处于空闲状态。
下图对比了两种处理标记的方式:一种是一次处理一个标记,且隐藏状态会逐渐消失;另一种则是同时连接所有成对的标记:
╔══════════════════════════════════════════════════════════════════════════════╗
║ RNN vs TRANSFORMER: HOW TOKENS ARE PROCESSED ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ ║
║ ┌─────────────────────────────────────────────────────────────────────┐ ║
║ │ RNN ── Sequential (slow, forgets early context) │ ║
║ └─────────────────────────────────────────────────────────────────────┘ ║
║ ║
║ "The" "cat" "sat" "on" "the" "mat" ║
║ │ │ │ │ │ │ ║
║ ▼ ▼ ▼ ▼ ▼ ▼ ║
║ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ║
║ │ RNN │──▶│ RNN │─▶│ RNN │▶│ RNN │▶│ RNN │▶│ RNN │ ║
║ │ 1 │ │ 2 │ │ 3 │ │ 4 │ │ 5 │ │ 6 │ ║
║ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ ║
║ h₁ ──▶ h₂ ──▶ h₃ ──▶ h₄ ──▶ h₅ ──▶ h₆ ║
║ ║
║ Step 1 Step 2 Step 3 Step 4 Step 5 Step 6 (must wait!) ║
║ ⚠ "The" signal is diluted through 5 hops by the time we reach "mat" ║
║ ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ ║
║ ┌─────────────────────────────────────────────────────────────────────┐ ║
║ │ TRANSFORMER ── Parallel (fast, every token sees all others) │ ║
║ └─────────────────────────────────────────────────────────────────────┘ ║
║ ║
║ "The" "cat" "sat" "on" "the" "mat" ◀── ALL AT ONCE ║
║ │╲╲ │╲ ╲╲ │╲╲ ╲ │ ╲╲ │ ╲╲ │ ║
║ │ ╲╲ │ ╲ ╲╲ │ ╲╲ ╲ │ ╲╲ │ ╲╲ │ ║
║ ├───╫──┼───╫───┼───╫───┼────╫──┼────╫───┤ ← every token ║
║ │ ╱╱ │ ╱ ╱╱ │ ╱╱ ╱ │ ╱╱ │ ╱╱ │ attends to ║
║ │╱╱ │╱ ╱╱ │╱╱ ╱ │ ╱╱ │ ╱╱ │ every token ║
║ ▼ ▼ ▼ ▼ ▼ ▼ ║
║ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ║
║ │ out │ │ out │ │ out │ │ out │ │ out │ │ out │ ← all computed ║
║ │ 1 │ │ 2 │ │ 3 │ │ 4 │ │ 5 │ │ 6 │ simultaneously ║
║ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ ║
║ ✓ "The" has DIRECT connection to "mat" — no information decay ║
║ ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ LEGEND: ──▶ sequential dependency ╲╱╱ all-pairs attention ║
║ h₁ hidden state ⚠ information bottleneck ║
╚══════════════════════════════════════════════════════════════════════════════╝
门控机制有所帮助,但并未改变问题的本质
1997年,Hochreiter和Schmidhuber提出了长短期记忆网络,通过引入门控机制,能够明确控制每一步该保留什么、舍弃什么以及输出什么。这种机制效果良好,在2010年代之前,它支撑了大多数实际的自然语言处理任务,包括早期的机器翻译、情感分析以及文本生成。
不过这类模型依然属于顺序处理类型,处理长距离依赖关系仍然困难,且并行硬件也未能得到充分利用。长短期记忆网络并非因为对语言建模能力差而失败,而是因为无法实现扩展:不断增加计算资源带来的收益越来越小,要突破这一限制就需要完全不同的计算方式。
从文本到数字
神经网络处理的是数字,而语言由单词构成,因此在引入注意力机制之前必须先进行转换。这一过程包含两个步骤:分词和嵌入。
分词
分词是将字符串转换为从固定词汇表中选取的整数ID序列。首先需要明白的是,这些token并非单词。现代分词器通常使用字节对编码或WordPiece技术将文本拆分成子词片段,其结果如下所示:
"Hello world" → ["Hello", " world"] → [15496, 995]
"unbelievable" → ["un", "believ", "able"] → [256, 9391, 540]
"ChatGPT" → ["Chat", "G", "PT"] → [14126, 38, 2969]
"antidisestablishmentarianism" → ["ant", "idis", "est", "ablish", "ment", "ari", "an", "ism"]
常见词汇会被赋予独立的标记,而罕见词或复合词则会被拆分成更小的部分。这样只需用规模可控的词汇表就能实现良好的覆盖,因为无需为每个可能的单词都创建条目。BERT的词汇量约为30,000,GPT-2为50,257,而近期推出的模型则超过100,000。
一个便于理解的换算方式是:一个标记大约相当于一个单词的四分之三,反过来一个单词则约为1.3个标记。因此,一本包含100,000个单词的小说大约对应133,000个标记,这在考虑上下文窗口限制时非常重要。
嵌入向量
每个词汇表条目对应一行、共 d_model 列的嵌入矩阵可将每个令牌 ID 映射为一个密集向量。查询某个令牌只需选取其对应的行即可。代表“world”含义的令牌 ID 995 对应第 995 行,该行会返回 d_model 个数值,例如 0.24、-0.83、0.17,直至 0.91 等。
这些行是在训练过程中学习得到的,由此会产生一个有用的特性:含义相近的令牌对应的向量在几何上会彼此接近。
Cosine similarity in embedding space:
similarity("cat", "lion") ≈ 0.89 ← very similar
similarity("cat", "moon") ≈ 0.12 ← not similar
similarity("king", "queen") ≈ 0.91 ← very similar
关于“著名的国王减去男人加上女人等于女王”这一例子的注意事项是:这种运算方式源自2013年的Word2Vec模型,而非Transformer模型中的嵌入表示。Transformer模型会与其他所有参数一起共同学习嵌入向量,因此纯粹的向量运算可靠性较低。不过,含义相近的词语会位于向量空间中的相邻区域这一原则仍然是成立的。
处处等宽
在变换器中,一个固定维度 d_model 出现在各个地方:嵌入向量、注意力输出,以及前馈层的输入和输出。这是有意为之的设计。所有组件都读取并写入同一个固定宽度的向量流,即残差流,该流会流经每一层。由于所有组件都在相同大小的向量上操作并将结果重新加回其中,因此各部分能够顺畅地协同工作。这也正是位置信息可以直接添加到词元嵌入向量的原因:两者形状相同,其和可以直接进入向量流中。
因此,第一个模块的输入是词元嵌入加上位置向量。由于二者处于同一空间,相加操作不会增加额外参数,且位置信息会被整合到承载意义的向量中。像BERT这类需要同时处理两个句子的模型,例如在问答系统中处理问题与段落时,会添加一个段嵌入来标记每个词元属于哪一句,第一句对应0,第二句对应1。而GPT风格的模型则不会使用这一机制。
注意力机制:学习关注何处
在2014年左右,从事机器翻译研究的人员发现,即便是LSTM系统也存在缺陷。该模型在开始生成输出之前,会将关于输入句子的所有信息压缩成一个固定大小的向量,这又成了一个新的瓶颈。一个显而易见的问题是:该模型是否能在生成的每一步都回过头去查看整个输入内容。对这个问题的解答就是注意力机制,它改变了序列建模的方式。
两种日常场景能让这一概念更易于理解。
在一场有十场对话同时进行的嘈杂派对上,人在跟随朋友交谈时并不会给每个声音赋予相同的权重。它会提升朋友的声音和来源方向,同时降低其他声音的音量,但并不会完全关闭这些声音。这种权重调整是连续的,而非开关式的。
当被要求从班级照片中找出老师时,人们并不会均匀地扫描每个像素。他们的搜索会直接指向那些能表明是成年人的特征,比如身高与其他人的对比以及面部比例。所寻找的目标决定了目光的走向。
计算注意力将这些直觉转化为四个步骤:首先要有需要寻找的目标,即查询项;其次要有一组可能相关的候选项;然后为每个候选项赋予一个连续的相关性得分;最后根据这些得分对信息进行加权整合。
有一个误解需要尽早澄清:注意力并不意味着模型只关注某一样东西而忽略其他一切。输出结果是一个加权平均值,每个元素都会对其产生影响,只不过有些元素的贡献远大于其他元素。这是一种有层次度的考量,而非二元的聚焦。
最初的、附加式的形式
最初,注意力机制是作为RNN和LSTM模型的附加组件存在的。在每个解码步骤中,模型会:
- 查看编码器的所有隐藏状态;
- 计算当前解码器状态与每个编码器状态之间的相关性得分;
- 通过softmax函数将这些得分转换为权重;
- 以编码器状态的加权之和作为注意力上下文。
关于softmax需要简单说明一下。它可以将任意实数向量转换为概率分布。每个得分会被转化为e的该次方,再除以所有得分对应的e的次方之和。所有输出值均为正数且总和为1,由于指数函数会放大大数值与小数值之间的差距,因此得分最高的项会获得最大的权重比例。
这无疑是一个巨大的进步,因为模型现在可以在每一步访问输入的任意部分。随后,《Attention Is All You Need》一文的作者提出了更大胆的想法:如果去掉循环结构,让注意力机制不再是附加组件,而是成为整个模型的核心呢?
自注意力机制与查询、键、值三要素
2017年那篇论文的核心思想就是自注意力机制。它并非让一个序列去关注另一个序列,而是让同一个序列中的每个标记都去关注该序列中的其他所有标记。正是通过这种方式,变换器能够构建上下文,而要理解这一机制,就需要了解每次注意力计算中都会出现的三个向量:查询、键和值。
视频搜索引擎
在视频网站上输入“如何制作酸面团面包”时,并不会将文本与每个视频的每一帧进行比对。每个视频都带有元数据标签,这些标签起着关键作用:标题、标签、描述关键词。网站会通过这些标签与查询内容进行匹配,从而得出相关性得分,得分最高的视频会被展示出来,以便获取其实际内容。
在注意力机制中有一个重要的变化。最终结果并非单个视频,而是所有视频的加权混合体,每个视频的播放音量与其相关性成正比。最相关的视频会占据主导地位,其他视频的贡献则以较弱的音量叠加在下方。具体的映射关系为:
| YouTube Concept | Attention Concept | Question it Answers |
|----------------|------------------|---------------------|
| Search query | **Query (Q)** | "What am I looking for?" |
| Video metadata/tags | **Key (K)** | "What do I contain?" |
| Actual video content | **Value (V)** | "What should I contribute?" |
为何需要三个独立的向量
为何不直接比较嵌入向量呢?以句子“猫坐在垫子上,因为它累了。”为例,为确定“它”所指的对象,该代词必须关注“猫”。但在原始嵌入空间中,代词与名词之间并无显著相似性。通过将数据拆分为查询项和键项,模型可以学会:即使代词与名词在基础嵌入中的表现毫无相似之处,其查询项也应与可能指代的名词的键项相匹配。这样学到的投影方式能够构建出一个独立于原始嵌入相似性空间的相关性空间。相关性与相似性是不同的概念,而QKV设计使得模型能够同时编码这两种特性。
分四步理解缩放点积注意力机制
第一步是投影。每个标记的嵌入向量会与三个学习得到的矩阵W_Q、W_K和W_V相乘,从而为该标记生成查询向量、键向量和值向量。
第二步是衡量匹配度。问题在于标记a与标记b的匹配程度如何,其答案就是标记a的查询向量与标记b的键向量的点积。较高的点积值意味着标记a应当重点关注标记b。点积会随着向量大小以及键向量的维度d_k而增大,而不仅仅与方向有关,因此下一步需要对它们进行重新缩放。
第三步是缩放与归一化。当d_k较大时,原始点积值会变得很大,导致softmax函数进入梯度极小的区域。在应用softmax之前先将点积值除以d_k的平方根,就可以避免这种情况,这也正是该方法被称为“缩放点积注意力”的原因。最终会得到一组权重alpha_ab。
第四步为聚合操作。标记a的输出是所有标记b的alpha_ab与b的值向量之和。
所有标记都可以作为矩阵一起处理,用一行简洁的公式表示:Attention(Q, K, V) = softmax(QK^T / sqrt(d_k)) V。下图展示了三词短语“the cat sat”的处理过程:
╔══════════════════════════════════════════════════════════════════════════════╗
║ SCALED DOT-PRODUCT ATTENTION ── "the cat sat" ║
╚══════════════════════════════════════════════════════════════════════════════╝
STEP 1: Input embeddings - ALL tokens are stacked into one matrix X
┌─────────────────────────────────────────┐
│ "the"→x₁ "cat"→x₂ "sat"→x₃ │ X ∈ ℝⁿˣᵈ
└──────────────────┬──────────────────────┘
│ the SAME X feeds all three projections
STEP 2: Three separate linear projections (each applied to every token)
┌─────────────┴─────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ W_Q │ │ W_K │ │ W_V │ ← learned weight matrices
└────┬────┘ └────┬────┘ └────┬────┘
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Q rows │ │ K rows │ │ V rows │
│ q₁ │ │ k₁ │ │ v₁ │
│ q₂ │ │ k₂ │ │ v₂ │
│ q₃ │ │ k₃ │ │ v₃ │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
STEP 3: score = QKᵀ, scale by 1/√dₖ, then softmax row-wise
│ │ │
└──────┬──────┘ │
▼ │
┌─────────────────────┐ │
│ softmax(QKᵀ / √dₖ) │ │
│ the cat sat │ │
│ the[.72 .20 .08] │ │ each row
│ cat[.12 .71 .17] │ │ sums to 1.0
│ sat[.09 .28 .63] │ │
└──────────┬──────────┘ │
│ │
STEP 4: multiply weights by Values V (weighted sum)
└──────────┬─────────┘
▼
┌─────────────────┐
│ output for "cat"│ 0.12·v₁ + 0.71·v₂ + 0.17·v₃
└────────┬────────┘ ← rich context-aware vector
│
OUTPUT: contextualized token representations
┌──────────┐ ┌──────────┐ ┌──────────┐
│"the" │ │"cat" │ │"sat" │
│knows it │ │knows it │ │knows │
│precedes │ │sat, and │ │who was │
│"cat" │ │where │ │sitting │
└──────────┘ └──────────┘ └──────────┘
一个实际案例:词库
以“她去银行存钱”为例。在Transformer对“bank”进行编码时,自注意力机制能让该词同时与其它所有词建立关联。权重会集中到“deposit”和“money”上,从而将金融相关的含义融入“bank”的表征中。上下文则有助于消除歧义。
╔══════════════════════════════════════════════════════════════════════════════╗
║ SELF-ATTENTION RESOLVES AMBIGUITY: What does "bank" mean? ║
╚══════════════════════════════════════════════════════════════════════════════╝
Sentence: "I went to the bank to deposit money"
t₁ t₂ t₃ t₄ t₅ t₆ t₇ t₈
ATTENTION WEIGHTS for token "bank" (t₅) attending to all other tokens:
Token │ Weight │ Visualization
──────────┼────────┼───────────────────────────────────────────
"I" │ 0.03 │ ░
"went" │ 0.04 │ ░
"to" │ 0.02 │
"the" │ 0.03 │ ░
"bank" │ 0.08 │ ░░
"to" │ 0.05 │ ░
"deposit" │ 0.38 │ ████████████████████████░░░░░░░░ ← strong!
"money" │ 0.37 │ ████████████████████████░░░░░░░ ← strong!
FULL ATTENTION HEATMAP (rows = query token, columns = key token):
Higher weight → more ░/▒/▓/█
Q\K │ I went to the bank to deposit money
──────────┼──────────────────────────────────────────────
I │ ▓ ░ ░ ░ ░ ░ ░ ░
went │ ░ ▓ ░ ░ ░ ░ ░ ░
bank │ ░ ░ ░ ░ ▒ ░ █ █ ← "bank"→"deposit","money"
deposit │ ░ ░ ░ ░ █ ░ ▓ ▒ ← "deposit"→"bank"
money │ ░ ░ ░ ░ █ ░ ▒ ▓ ← "money"→"bank"
BEFORE attention: "bank" = ambiguous (river bank? financial bank?)
AFTER attention: "bank" ≈ 0.38·v(deposit) + 0.37·v(money) + ...
→ "bank" representation is now strongly financial ✓
The model learned this WITHOUT any explicit disambiguation rules.
该图中的权重仅为便于展示而设定,并非来自真实模型。实际的模式往往更为复杂,目前关于注意力权重与模型“思考”内容之间关系的研究仍在进行中。其实际优势与图示有所不同:对所有标记应用自注意力机制仅需一次矩阵乘法运算,即单次GPU操作。而RNN需要n次顺序运算才能完成的任务,Transformer仅需一次并行运算即可完成,这也是Transformer具备良好扩展性的原因。
多个注意力头,多种视角
一个处理单元一次只能计算一种相关性,那么当多种关系同时存在时该如何处理呢?以“在音乐节上表演的音乐家获得了奖项”为例,要理解这句话就需要同时追踪多条关联关系:“获得”与作为主语和动词的“音乐家”相关,“音乐家”通过定语从句与“表演”相关,“表演”与地点“音乐节”相关,而“奖项”则与作为动词和宾语的“获得”相关。
单个注意力头需要将所有信息压缩到一组权重中。而多注意力头则并行运行h次注意力函数,每次都使用针对查询、键和值各自学习得到的投影。这h个输出结果会被拼接起来,再通过另一个学习得到的矩阵W_O处理,从而转换回模型维度。每个注意力头在较小的子空间中工作,其中d_k等于d_model除以h,因此所有注意力头带来的总计算成本大致相当于一个全宽度注意力头的成本。
想象一份手稿被送到编辑委员会。语法编辑检查句法,风格编辑关注叙事流畅性,事实核查员检验语义一致性,结构编辑则审视整体布局。他们同时独立阅读,并将各自的意见整合成一份审稿报告。多注意力头的工作方式也与此类似。
╔══════════════════════════════════════════════════════════════════════════════╗
║ MULTI-HEAD ATTENTION (3 heads shown) ║
╚══════════════════════════════════════════════════════════════════════════════╝
Input Embedding x ∈ ℝᵈ_model
┌────────────────────────────┐
│ [ x₁ x₂ x₃ ... xₙ ] │
└──────────┬─────────────────┘
│
┌────────────────────┼────────────────────┐
│ │ │
▼ ▼ ▼
╔══════════════╗ ╔══════════════╗ ╔══════════════╗
║ HEAD 1 ║ ║ HEAD 2 ║ ║ HEAD 3 ║
║ "Syntax" ║ ║ "Semantics" ║ ║ "Position" ║
║ ║ ║ ║ ║ ║
║ W_Q¹ W_K¹ ║ ║ W_Q² W_K² ║ ║ W_Q³ W_K³ ║
║ W_V¹ ║ ║ W_V² ║ ║ W_V³ ║
║ ║ ║ ║ ║ ║
║ ┌──────────┐ ║ ║ ┌──────────┐ ║ ║ ┌──────────┐ ║
║ │ Scaled │ ║ ║ │ Scaled │ ║ ║ │ Scaled │ ║
║ │ Dot- │ ║ ║ │ Dot- │ ║ ║ │ Dot- │ ║
║ │ Product │ ║ ║ │ Product │ ║ ║ │ Product │ ║
║ │Attention │ ║ ║ │Attention │ ║ ║ │Attention │ ║
║ └────┬─────┘ ║ ║ └────┬─────┘ ║ ║ └────┬─────┘ ║
║ │ ║ ║ │ ║ ║ │ ║
║ learns: ║ ║ learns: ║ ║ learns: ║
║ subject-verb ║ ║ word meaning ║ ║ nearby-word ║
║ agreement ║ ║ similarity ║ ║ relationships║
╚══════╤═══════╝ ╚══════╤═══════╝ ╚══════╤═══════╝
│ head₁ ∈ ℝⁿˣ⁽ᵈ/ʰ⁾ │ head₂ │ head₃
└───────────────────┼───────────────────┘
▼
┌──────────────────────────────┐
│ CONCATENATE all heads │
│ [head₁ ║ head₂ ║ head₃] │ ∈ ℝⁿˣᵈ_model
└──────────────┬───────────────┘
▼
┌──────────────────────────────┐
│ Final linear projection W_O │ blends info from all heads
└──────────────┬───────────────┘
▼
┌──────────────────────────────┐
│ Multi-Head Attention Output │ ∈ ℝⁿˣᵈ_model (same shape as input)
└──────────────────────────────┘
各模块的实际功能
对经过训练的模型进行分析后,发现其中存在专门化处理的模块。有些模块负责处理句法结构,比如主谓一致以及名词的修饰语。有些模块能够处理较长的距离关系,将代词与其指代对象关联起来。有些模块则关注局部信息,处理相邻的单词及二元词组模式。还有些模块能够记录标记之间的相对距离,另有部分模块则负责识别主题角色,即确定谁对谁做了什么。这些功能并非由人工编程设定,而是通过训练让模型以准确预测为目标,进而自行发现将任务分配给不同专门化模块更为有效。
该观点的一个局限在于:这些分类主要源自对较小模型的可解释性研究。在大型模型中,许多特征头无法被清晰解读,实验表明这类模型即便剪除大量特征头,性能损失也很小。虽然这种架构使得功能专业化成为可能,但并不能保证存在清晰、易于人类理解的分类。
为词汇赋予地址
自注意力机制会将每一对标记相互关联,但这种方式将序列视为无顺序的集合。任意标记a与标记b之间的得分仅取决于内容本身,而与它们的出现顺序或距离无关。语言却高度依赖顺序——“狗咬人”和“人咬狗”虽然包含相同的词汇,但含义截然相反;“不快乐”与“快乐不”也表达完全不同的意义。由于变换器是并行处理所有位置的,它默认不会编码顺序信息,因此必须显式地加入位置信息。这就是位置编码的作用。
试想为城市中的每一栋建筑添加元数据。每栋建筑都需要一个地址,既能确定其具体位置,又能体现相对方位(如402号楼位于404号楼附近),而且无需事先掌握整个城市的规划图。GPS坐标就能很好地实现这一点。而位置编码则是其语言学版本:在每个词的表示形式中加入数学坐标。
正弦波与余弦波
最初的变换器使用正弦函数,每对嵌入维度对应一个频率。对于位置pos和维度索引k,将pos的正弦值与余弦值除以10000的幂次后再根据k进行缩放,从而填充向量。低频的缓慢波动用于表示粗略位置,高频的快速波动则用于表示精确位置,二者结合便能为每个位置生成唯一的特征标识。
╔══════════════════════════════════════════════════════════════════════════╗
║ SINUSOIDAL POSITIONAL ENCODING ║
╚══════════════════════════════════════════════════════════════════════════╝
GRID: exact values for a tiny d_model=8 - positions 0-4, dims 0-7
(frequency denominators are 1, 10, 100, 1000 for dim-pairs 0,1,2,3)
dim→ d=0 d=1 d=2 d=3 d=4 d=5 d=6 d=7
sin cos sin cos sin cos sin cos
pos↓ ──────────────────────────────────────────────────────
pos=0 │ 0.000 1.000 0.000 1.000 0.000 1.000 0.000 1.000 │
pos=1 │ 0.841 0.540 0.100 0.995 0.010 1.000 0.001 1.000 │
pos=2 │ 0.909 -0.416 0.199 0.980 0.020 1.000 0.002 1.000 │
pos=3 │ 0.141 -0.990 0.296 0.955 0.030 1.000 0.003 1.000 │
pos=4 │ -0.757 -0.654 0.389 0.921 0.040 0.999 0.004 1.000 │
↑ fast-changing ↑ medium-changing ↑ very slow
(high frequency) (mid frequency) (low freq)
unique per position gradual shift global structure
WAVE PATTERNS (each row = one dimension across positions):
dim 0 (sin): █ ▇ ▄ ▁ ▂ ▅ ▇ █ ▇ ▄ ▁ ← fast oscillation
dim 2 (sin): █ █ ▇ ▇ ▆ ▅ ▄ ▃ ▂ ▁ ▁ ← medium oscillation
dim 4 (sin): █ █ █ █ █ █ ▇ ▇ ▇ ▇ ▆ ← slow oscillation
dim 6 (sin): █ █ █ █ █ █ █ █ █ █ █ ← very slow oscillation
HOW IT'S USED: Added to the token embedding elementwise
┌─────────────────┐ ┌─────────────────┐ ┌──────────────────┐
│ Token Embedding│ │ Positional Enc. │ │ Final Input x_t │
│ "cat" │ │ position = 2 │ │ │
│ [0.2, 0.8, │ │ [0.9,-0.4, │ │ [1.1, 0.4, │
│ 0.1, 0.5, │ + │ 0.2, 1.0, │ = │ 0.3, 1.5, │
│ 0.9, 0.3] │ │ 0.0, 1.0] │ │ 0.9, 1.3] │
│ (meaning) │ │ (where in seq) │ │ (meaning+position)│
└─────────────────┘ └─────────────────┘ └──────────────────┘
WHY SINUSOIDS?
✓ Each position gets a unique encoding across all dimensions
✓ Distance between nearby positions is consistent and learnable
✓ Can represent any position mathematically (unlike learned embeddings)
✓ Model can attend to relative positions via linear combinations
低维度的振荡速度较快,能够捕捉精细的位置信息,而高维度的变化较慢,主要用于把握整体结构。该向量会被直接加到令牌嵌入中。
固定波形、学习得到的表结构以及旋转
正弦函数方案具有一个有用的数学特性:位置pos+k处的编码是位置pos处编码的线性函数。因此相对偏移量能够以一致的方式表示,从而便于学习位置关系。
BERT所使用的基于位置嵌入的方法,即为每个位置创建一条记录的独立表格,虽然更为简单,但无法推断出训练数据中未出现过的位置,而正弦函数原则上可以表示任意位置。即便如此,正弦函数也无法完全解决长上下文泛化问题。模型在处理远超过训练数据长度的序列时依然存在困难,因为注意力模式本身也需要泛化到未曾见过的距离上。
像Llama这样的模型使用旋转位置嵌入技术,即RoPE。在计算点积之前,查询向量与键向量会根据其位置以相应角度进行旋转。处于不同位置的查询向量与键向量相乘时,这种相对旋转会直接体现位置偏移。将相对位置作为注意力得分的显式输入,而非通过投影矩阵间接推断或学习的结果,有助于处理更长的上下文。
完整架构
现在可以将各组成部分组合起来。该图展示了整个结构采用现代预层归一化形式的样貌:
╔═══════════════════════════════════════════════════════════════════════════════════════╗
║ THE COMPLETE TRANSFORMER ARCHITECTURE (Pre-LayerNorm, modern) ║
╠═══════════════════════════════════════════╦═══════════════════════════════════════════╣
║ ENCODER (×N layers) ║ DECODER (×N layers) ║
╠═══════════════════════════════════════════╬═══════════════════════════════════════════╣
║ ║ ┌───────────────────────────────────────┐ ║
║ ║ │ Linear → Softmax → P(next token) │ ║
║ ║ └───────────────────────────────────────┘ ║
║ ║ ▲ ║
║ ║ ┌───────────────────────────────────────┐ ║
║ ║ │ ⊕ Add (residual) │ ║
║ ║ └───────────────────────────────────────┘ ║
║ ║ ▲ ║
║ ║ ┌───────────────────────────────────────┐ ║
║ ║ │ FFN( LayerNorm(x) ) │ ║
║ ║ └───────────────────────────────────────┘ ║
║ ║ ▲ ║
║ Encoder output → K, V (to decoder) ║ ┌───────────────────────────────────────┐ ║
║ ▲ ║ │ ⊕ Add (residual) │ ║
║ ┌───────────────────────────────────────┐ ║ └───────────────────────────────────────┘ ║
║ │ ⊕ Add (residual) │ ║ ▲ ║
║ └───────────────────────────────────────┘ ║ ┌───────────────────────────────────────┐ ║
║ ▲ ║ │ Cross-Attention │ ║
║ ┌───────────────────────────────────────┐ ║ │ Q ← decoder │ ║
║ │ FFN( LayerNorm(x) ) │ ║ │ K, V ← encoder output │ ║
║ └───────────────────────────────────────┘ ║ └───────────────────────────────────────┘ ║
║ ▲ ║ ▲ ║
║ ┌───────────────────────────────────────┐ ║ ┌───────────────────────────────────────┐ ║
║ │ ⊕ Add (residual) │ ║ │ ⊕ Add (residual) │ ║
║ └───────────────────────────────────────┘ ║ └───────────────────────────────────────┘ ║
║ ▲ ║ ▲ ║
║ ┌───────────────────────────────────────┐ ║ ┌───────────────────────────────────────┐ ║
║ │ Multi-Head Self-Attention │ ║ │ Masked Multi-Head Self-Attention │ ║
║ │ ( on LayerNorm(x), bidirectional ) │ ║ │ ( on LayerNorm(x), causal ) │ ║
║ └───────────────────────────────────────┘ ║ └───────────────────────────────────────┘ ║
║ ▲ ║ ▲ ║
║ ┌───────────────────────────────────────┐ ║ ┌───────────────────────────────────────┐ ║
║ │ Input Embedding + Positional Enc. │ ║ │ Output Embedding + Positional Enc. │ ║
║ └───────────────────────────────────────┘ ║ └───────────────────────────────────────┘ ║
║ ▲ ║ ▲ ║
║ ┌───────────────────────────────────────┐ ║ ┌───────────────────────────────────────┐ ║
║ │ Source: "The cat sat on the mat" │ ║ │ Target (shifted): <BOS> "Le" "chat"… │ ║
║ └───────────────────────────────────────┘ ║ └───────────────────────────────────────┘ ║
╠═══════════════════════════════════════════╩═══════════════════════════════════════════╣
║ Data flows UPWARD (▲). Each sub-layer is a residual branch over a ║
║ LayerNorm-ed input: h = x + SubLayer( LayerNorm(x) ) ║
║ The encoder's output (K, V) flows into the decoder's Cross-Attention. ║
╚═══════════════════════════════════════════════════════════════════════════════════════╝
变换器由两个主要部分组成:编码器和解码器。在原始论文中,每个部分都有6层结构,配备8个注意力头,d_model值为512。
编码器:理解上下文
编码器会读取输入序列,并为每个标记生成具有上下文信息的表示,它关注的不是单词本身的独立含义,而是该单词在特定句子中的意义。编码器采用双向自注意力机制,因此每个标记都可以查看两侧的所有其他标记。正是通过这种方式解决了上文提到的“bank”一词的歧义:模型能够同时看到“deposit”和“money”。
共有六层编码器依次运行,每层都对特征表示进行优化。早期的编码层侧重于词序、词性等语法结构。中间层处理更为复杂的语法结构。而后期的编码层则能捕捉实体类型、事件结构及语用意义等高层次含义。正是这种分层结构使得模型迁移效果如此出色:微调主要作用于后期层,而早期层中通用的语言模式在各种任务中依然有用。
解码器:借助记忆生成内容
解码器以自回归方式逐个生成输出标记。每个新标记的生成都依赖于此前已生成的所有内容以及整个编码后的输入。它由三个子层组成。
第一种是掩码自注意力,也称为因果注意力。解码器只能查看其已生成的标记,这一限制由因果掩码实现。在应用softmax之前,对对角线以上的得分会被设为负无穷大,从而使未来的标记不可见。这样一来,训练过程与推理过程就保持一致了,因为模型必须仅依据过去的上下文来预测每个标记。
╔══════════════════════════════════════════════════════════════════════════╗
║ DECODER SELF-ATTENTION: Causal (Autoregressive) Masking ║
║ "Each token can only attend to itself and tokens before it" ║
╚══════════════════════════════════════════════════════════════════════════╝
Tokens: [The] [cat] [sat] [on] [mat]
t₁ t₂ t₃ t₄ t₅
ATTENTION SCORE MATRIX (row = query, col = key)
KEY → t₁ t₂ t₃ t₄ t₅
QUERY ↓ "The" "cat" "sat" "on" "mat"
──────────────────────────────────────
t₁ "The" │ ✓ ✗ ✗ ✗ ✗
t₂ "cat" │ ✓ ✓ ✗ ✗ ✗
t₃ "sat" │ ✓ ✓ ✓ ✗ ✗
t₄ "on" │ ✓ ✓ ✓ ✓ ✗
t₅ "mat" │ ✓ ✓ ✓ ✓ ✓
✓ = ALLOWED (score kept, participates in softmax)
✗ = MASKED (score → −∞, becomes 0 after softmax)
When generating t₃ "sat":
Raw scores: [ 2.1 3.4 1.8 -∞ -∞ ]
After softmax: [ 0.18 0.68 0.14 0 0 ]
↑
future tokens are invisible
WHY IS MASKING NECESSARY?
┌──────────────────────────────────────────────────────────┐
│ TRAINING: We feed the whole target sequence at once │
│ (teacher-forcing). Without masking, t₃ could "cheat" │
│ by looking at t₄ and t₅ - the answers it should │
│ be predicting. │
│ │
│ INFERENCE: We generate one token at a time anyway, │
│ so future tokens literally don't exist yet. Masking │
│ makes training match inference behavior exactly. │
└──────────────────────────────────────────────────────────┘
第二种是交叉注意力机制,它是编码器与解码器之间的桥梁。查询项来自解码器,代表当前生成的状态,而键和值则来自编码器,代表输入内容。翻译过程就是如此进行的:当解码器生成法语单词“chat”时,它会查询编码器对整句英语的表示,交叉注意力机制会将较大的权重分配给“cat”。
第三种是前馈网络,其作用与编码器中的前馈网络相同,具体内容将在下文介绍。
由相同组件构成的三类结构
编码器-解码器的组合只是使用这些组件的方式之一,不同的任务需要不同的配置:
| Model | Architecture | Training Objective | Best For |
|-------|-------------|-------------------|----------|
| **BERT** | Encoder-only | Masked Language Modeling | Understanding: classification, NER, QA |
| **GPT** | Decoder-only | Next token prediction | Generation: writing, coding, conversation |
| **T5** | Encoder-Decoder | Text-to-text seq-to-seq | Transformation: translation, summarization |
╔══════════════════════════════════════════════════════════════════════════════════════╗
║ BERT vs GPT vs T5: Architecture Families ║
╠══════════════════╦═══════════════════════════╦═════════════════════════════════════╣
║ BERT ║ GPT ║ T5 ║
║ Encoder-Only ║ Decoder-Only ║ Encoder + Decoder ║
╠══════════════════╬═══════════════════════════╬═════════════════════════════════════╣
║ ATTENTION: ║ ATTENTION: ║ ATTENTION: ║
║ t₁ ● ● ● ● ║ t₁ ● ║ Encoder: ● ● ● ● (bidir) ║
║ t₂ ● ● ● ● ║ t₂ ● ● ║ ● ● ● ● ║
║ t₃ ● ● ● ● ║ t₃ ● ● ● ║ Decoder: causal + ║
║ t₄ ● ● ● ● ║ t₄ ● ● ● ● ║ cross-attn to encoder ║
║ (bidirectional) ║ (causal/left-only) ║ ║
╠══════════════════╬═══════════════════════════╬═════════════════════════════════════╣
║ BEST FOR: ║ BEST FOR: ║ BEST FOR: ║
║ ✓ Classification ║ ✓ Text generation ║ ✓ Translation ║
║ ✓ NER / tagging ║ ✓ Completion ║ ✓ Summarization ║
║ ✓ Sentence embeds ║ ✓ Chat / dialogue ║ ✓ Question answering ║
║ ✓ Reading comp. ║ ✓ Code generation ║ ✓ Any seq-to-seq task ║
╠══════════════════╬═══════════════════════════╬═════════════════════════════════════╣
║ EXAMPLES: ║ EXAMPLES: ║ EXAMPLES: ║
║ BERT, RoBERTa ║ GPT-4o, Claude 4, ║ T5, BART, ║
║ DeBERTa ║ Llama 4, Gemini 2.5 ║ mT5, FLAN-T5 ║
╚══════════════════╩═══════════════════════════╩═════════════════════════════════════╝
BERT能够双向读取文本,非常适合理解类任务。GPT在因果掩码机制下从左到右生成文本。T5则保留完整的架构以实现结构化的序列到序列转换。选择哪种模型取决于架构是否适合特定任务,而非哪种模型更优。简而言之,编码器构建双向上下文表示,解码器通过因果掩码与交叉注意力机制进行自回归生成,而该架构的不同组件则分别用于理解、生成和转换任务。
辅助组件
注意力机制和前馈层最受关注,但还有三个部分防止深度Transformer在训练过程中崩溃:前馈网络本身、层归一化以及残差连接。
前馈网络:每个标记的思考时间
每个块中的每个注意力层之后都跟着一个按位置划分的前馈网络。每个标记的向量都会经过相同的双层多层感知机结构,该结构会分别作用于每个位置:先乘以W1,加上偏置,再应用GeLU非线性函数,随后乘以W2并加上另一个偏置。W1将维度从d_model映射到四倍的d_model,而W2则将其再映射回原来的维度。在原始参数设置下,这一维度从512扩大到2048,然后再收缩到512,这样网络就有足够的空间来存储和处理仅靠注意力机制无法捕捉的信息。
“按位置划分”是关键表述,因为该层会独立处理每个标记。注意力机制是标记之间相互交流的机制,而前馈网络则是计算机制,每个标记会据此处理自己收集到的信息。
Geva及其同事(2021年)发现,这些层的行为有点类似于键值存储器,存在一些会对特定语义概念产生反应的神经元。当语言模型“知道”巴黎是法国的首都时,这种关联主要存在于前馈权重中。这可以解释两件事:微调能够更新事实性知识,因为它会调整这些权重;而检索增强生成技术之所以有效,是因为它将相关事实置于上下文窗口中,使得注意力可以直接获取到这些信息。
残差连接
在深度网络中,向反向传播的梯度会在多层结构中逐渐衰减。残差连接,也称为跳过连接,能够很好地解决这一问题:子层的输出等于该子层的计算结果加上其自身的输入。这样一来,该层只需学习变化量即残差,而无需学习完整的映射关系。这为梯度提供了一条直接返回的“高速公路”,可以绕过任何层,这也是现代变换器能够堆叠96层甚至更多层而不会导致训练失败的原因。
层归一化:控制数值尺度
层归一化会将每个标记的激活向量标准化为零均值和单位方差,然后再应用学到的缩放参数γ和偏移参数β。这些统计量来自单个标记的d_model特征:均值是其各分量的简单平均值,而方差则是这些分量到该均值的平均平方距离。为了防止出现除以零的情况,会在平方根内加入一个很小的常数ε,通常为10的负5次方。与批量归一化不同,这种计算是针对每个标记单独进行的,而非在整个批次上操作,因此更适合长度可变的序列。
现代块结构
最初的论文在残差相加之后应用LayerNorm,即所谓的Post-LN。从GPT-2、GPT-3到Llama,以及自2020年左右以来训练的几乎所有现代模型,都采用Pre-LayerNorm,在每个子层之前进行归一化处理。Pre-LN的训练更加稳定,且不需要学习率预热步骤。
随后,每个模块会在归一化后的输入上分别添加注意力分支和前馈分支。第一个中间状态是原始输入加上作用于归一化后输入的注意力机制,第二个状态则是该状态再加上作用于其自身归一化版本的前馈网络。查看任何现代Transformer的代码都会发现,LayerNorm位于注意力机制和前馈步骤之前。将这样的模块重复N次,其中N的值根据模型大小不同可为6、12、24、96或更多,这样就能构成整个Transformer结构。
注意力机制是那个巧妙的想法,而那些辅助组件则是让这一巧妙想法得以实现的工程技术。前馈层负责对每个标记进行计算以存储事实关联,残差路径为梯度提供了贯穿网络深度的通道,Pre-LN则有助于保持激活值的稳定性。正是这些组件的共同作用,使得堆叠数十个模块成为可能。
句子的处理流程
从开始到结束的完整流程为:对文本进行分词、嵌入处理、添加位置编码、进行编码,然后逐个解码标记,最终将其映射到词汇表中。下图展示了“Hello world”这句话的翻译过程:
╔══════════════════════════════════════════════════════════════════════════╗
║ END-TO-END DATA FLOW: "Hello world" → Translation ║
╚══════════════════════════════════════════════════════════════════════════╝
STAGE 1: Tokenization
┌─────────────────────────────────────────────────────────────────┐
│ Raw text: "Hello world" │
│ ↓ Tokenizer (BPE / WordPiece) │
│ Token IDs: [ 7592, 2088 ] ← integers into vocabulary │
└──────────────────────┬──────────────────────────────────────────┘
↓
STAGE 2: Embedding Lookup e_t = E[t] ∈ ℝ^512
┌─────────────────────────────────────────────────────────────────┐
│ 7592 → [0.21, -0.54, 0.88, ...] "Hello" │
│ 2088 → [0.67, 0.12,-0.34, ...] "world" │
└──────────────────────┬──────────────────────────────────────────┘
↓
STAGE 3: Add Positional Encoding x_t = e_t + PE(t)
┌─────────────────────────────────────────────────────────────────┐
│ embedding + PE = input vector carrying BOTH meaning AND order │
└──────────────────────┬──────────────────────────────────────────┘
↓
STAGE 4: Encoder Stack (× N layers)
┌─────────────────────────────────────────────────────────────────┐
│ ╔═══════════════════════════════════╗ │
│ ║ Each Encoder Layer: ║ × 6 │
│ ║ h₁ = x + Attn(LayerNorm(x)) ║ │
│ ║ h₂ = h₁ + FFN(LayerNorm(h₁)) ║ │
│ ╚═══════════════════════════════════╝ │
│ After 6 layers: rich contextual reps - "Hello" knows context │
└──────────────────────┬──────────────────────────────────────────┘
↓ (K, V flow into decoder cross-attention)
STAGE 5: Decoder Stack (generates tokens autoregressively)
┌─────────────────────────────────────────────────────────────────┐
│ Step 1: <BOS> → Decoder → predict "Hola" │
│ Step 2: <BOS> "Hola" → Decoder → predict "mundo" │
│ Step 3: <BOS> "Hola mundo" → Decoder → predict <EOS> │
│ │
│ Each step: ① Masked self-attention on generated tokens │
│ ② Cross-attention: Q←decoder, K,V←encoder │
│ ③ LayerNorm → FFN → residual │
└──────────────────────┬──────────────────────────────────────────┘
↓
STAGE 6: Output Projection & Softmax
┌─────────────────────────────────────────────────────────────────┐
│ hidden state → W_vocab → logits over 50k vocab items │
│ → softmax → probability distribution │
│ → sample or argmax → next token │
└──────────────────────┬──────────────────────────────────────────┘
↓
"Hola mundo" ✓
一篇翻译论文如何演变成语言模型
上述内容涵盖了完整的架构,但机器翻译的设计究竟是如何发展成能够撰写文章、编写代码并解决复杂问题的系统的呢?简短的答案就是规模。
下图展示了从2017年的Transformer模型到近期最先进的模型的发展历程:
YEAR MODEL PARAMS KEY DEVELOPMENT
────────────────────────────────────────────────────────────────────────────────
2017 Transformer 65M "Attention Is All You Need" published
2018 GPT-1 117M First successful generative pre-training
2019 GPT-2 1.5B Improved fluency; staged release
2020 GPT-3 175B Few-shot in-context learning emerges
2022 ChatGPT 175B+ InstructGPT + RLHF = aligned conversational AI
2023 GPT-4 undisclosed Multimodal input + stronger reasoning
2024 GPT-4o undisclosed Natively multimodal, faster & cheaper (May)
2024 o1 undisclosed "Reasoning" model: thinks before answering (Sep)
2025 o3 / o4-mini undisclosed Stronger reasoning, tool use, long-horizon
2025 Claude 4 undisclosed Anthropic: Opus 4 / Sonnet 4 (May)
2025 Gemini 2.5 undisclosed Google: 1M-token context, multimodal
2025 Llama 4 undisclosed Meta: open weights, up to 10M-token context
2026 GPT-5 series undisclosed OpenAI flagship (GPT-5.4 / 5.5); 272K-1M ctx
2026 Gemini 3.x undisclosed Google: frontier reasoning; 1M context
2026 Claude 5 family undisclosed Anthropic: Opus 4.8, Sonnet 5, Fable 5
2026 Grok 4.x undisclosed xAI frontier line (Grok 4.5, Jul 2026)
(Every one is the same core transformer from 2017 — scaled and refined, not replaced)
GPT-1与当今最先进的模型之间,其核心架构几乎没有任何变化。真正发生变化的是以下几点:
- 规模上的提升,即更多的参数、更多数据以及更强的计算能力。
- 对齐机制,通过人类反馈强化学习让模型变得更实用且安全。
- 指令调优,使模型能够遵循指示而非仅仅继续生成文本。
- 推理训练,将大规模强化学习应用于可验证的问题。这正是各类推理模型背后的技术基础,比如OpenAI的o系列,以及Claude、Gemini等模型中常见的扩展思维模式——这类模型在回答问题前会投入额外计算力进行思考。
似乎被激活的能力
随着模型规模的扩大,出现了一些意料之外的现象。某些能力并非逐步提升,而是在达到特定规模时突然跃升。参数量在100亿左右时几乎无法进行多步运算,而达到1000亿参数后则能稳定完成此类运算。除非模型规模足够大且经过相应提示,否则几乎不存在思维链推理能力。在GPT-3级别的模型之上,代码生成能力有了显著提升。这些变化并非预先设定,而是自然出现的。
这些提升的幅度究竟有多大仍存在争议。Schaeffer及其同事在2023年发表的一篇被广泛引用的分析文章《大型语言模型的新兴能力是幻象吗?》指出,某些看似突然的跃进部分源于评估指标本身。像精确匹配准确率那样采用全有或全无的评分方式,会将持续、渐进的进步表现为突然的飞跃,而连续型指标则能展现其背后的稳步进展。虽然大型模型确实具备小型模型无法实现的功能,这一观点在实践中成立,但具体的阈值数值仅应作为粗略参考,而非不可改变的客观规律。
所有GPT风格模型的训练目标都是同一个简单的任务——预测下一个标记。推理、代码生成、多语言理解以及创意写作这些能力从未被直接训练过。只要模型在下一个标记的预测能力上不断进步,并且拥有足够大的规模:即规模庞大、质量高且内容多样的语料库,以及足够大的模型结构来存储必要的模式,这些能力就会随之出现。正因如此,研究人员才会说这个目标看似简单实则不然。目标本身很简单,但模型要出色地完成它所需学习的内容却并不简单。
作为工作记忆的上下文窗口
对模型而言,工作记忆就是上下文窗口:即单次前向传播过程中能够处理的最大token数量。这一数值增长极为迅速——2019年的GPT-2可处理1,024个token,2020年的GPT-3则提升至2,048个。2024年推出的GPT-4o更是达到了128,000个token。到2026年中,这一标准又进一步提升:OpenAI的GPT-5系列默认支持272,000个token,通过API还能处理约100万个token;Anthropic的Claude与Google的Gemini 3也能处理超过100万个token;而Meta开源的Llama 4 Scout则宣称可处理高达1,000万个token,相当于约15,000页内容。每一代模型的这一数值都在持续上升。
更大的上下文窗口非常重要,因为它能够让模型分析整个代码文件而不仅仅是片段内容,维持多轮对话的连贯性,总结整份文档,并在考虑众多中间结果的情况下进行多步骤推理。
不过这里有个问题。在训练阶段,要计算出将每个标记与所有其他标记关联起来的完整注意力矩阵,需要 O(n平方) 的时间和内存。如果上下文长度翻倍,这两者都会变为原来的四倍。在推理阶段,KV缓存虽然能降低每步的计算量,但内存仍会随上下文长度线性增长。这一二次方的训练瓶颈是目前研究的热点。稀疏注意力、Mistral中使用的滑动窗口注意力以及其他高效设计、Flash Attention(内存高效的精确注意力机制)和线性近似方法,都在试图降低这一成本。
构建在基础之上的要素
注意力机制、QKV结构、多个注意力头、位置编码以及编码器-解码器架构都属于基础设施,学习它们的原因就在于所有上层模型都是建立在这些基础之上的。
生成式AI其实就是不断重复的下一词预测
每一个生成式应用本质上都是不断重复运行的同一个循环:
Prompt: "Write a poem about autumn"
↓
Model predicts most likely next token: "The"
↓
Prompt + "The" → predicts: "leaves"
↓
Prompt + "The leaves" → predicts: "fall"
↓
... continues until <end-of-sequence> token predicted
这样看就能解释某些行为的谜团:
- 幻觉现象。模型预测的是可能的词元,而非从数据库中检索事实。如果存在合理但错误的词元,模型就可能会生成它。
- 为何上下文如此重要。在每个生成步骤中都会考虑整个上下文窗口,因此提示词中的内容决定了哪些注意力权重会被计算,进而影响输出结果。
上下文学习:注意力机制用于检索
大型变换器最引人注目的能力之一就是上下文学习,它无需任何微调,就能通过提示中的示例来适应新任务。这一机制与上文所述内容相符。少量示例会位于窗口中的特定位置。当模型处理测试实例时,该实例的查询向量会通过点积与之前所有标记的键向量进行比较,包括示例对中的标记。由于这些示例与测试实例具有相似的结构模式,它们的键向量匹配度很高,因此对应的值会获得较高的权重。注意力机制实际上就是一种检索机制,正因如此,提示的结构通过影响注意力模式,从而改变了输出结果。
智能体:作为推理引擎的变换器
AI智能体是能够自行分解任务、调用工具、根据反馈不断迭代,并通过多步操作实现目标的系统。2023年时,它们还只是研究领域的有趣现象。如今,Claude Code、GitHub Copilot、Cursor和Devin等产品已被开发者们日常使用。每一个成熟的智能体都以变换器作为其核心架构。
╔══════════════════════════════════════════════════════════════════════════════╗
║ THE CONTEXT WINDOW AS AGENT WORKING MEMORY ║
╚══════════════════════════════════════════════════════════════════════════════╝
TIME ──────────────────────────────────────────────────────────────────────▶
┌──────────────┬──────────────┬────────────────┬────────────┬──────────────┐
│ SYSTEM │ USER │ AGENT │ TOOL │ AGENT │
│ PROMPT │ MESSAGE │ THOUGHT │ RESULT │ RESPONSE │
│ │ │ (reasoning) │ │ │
│ "You are a │ "What is │ <think> │ {"temp": │ "The current │
│ weather │ the weather │ I need to │ 22, │ temperature │
│ assistant │ in Paris │ call the │ "unit": │ in Paris │
│ ..." │ today?" │ weather API │ "C", │ is 22°C and │
│ │ │ for Paris... │ "cond": │ cloudy." │
│ │ │ </think> │ "cloudy"} │ │
│ ~200 tokens │ ~15 tokens │ ~80 tokens │ ~40 tokens │ ~25 tokens │
└──────────────┴──────────────┴────────────────┴────────────┴──────────────┘
▲ ▲ ▲ ▲ ▲
└───────────────┴───────────────┴───────────────┴─────────────┘
│
At each generation step:
Full self-attention runs over the
ENTIRE context simultaneously.
Cost: O(n²) in total context length.
WHAT THIS MEANS FOR AGENTS:
✓ Tool results are just tokens - the model attends to them like any text
✓ Reasoning traces are visible - chain-of-thought shapes next generation
✓ Long task history - "memory" without any separate mechanism
⚠ Context fills up - very long loops need summarization/offload
⚠ O(n²) attention cost - longer context = quadratically more compute
KEY INSIGHT: There is no "working memory" separate from the context.
The context window IS the agent's entire cognitive state.
对智能体而言,窗口是一个扁平的、有序的标记缓冲区,每一步生成过程都会遍历整个缓冲区,从而将截至当前的所有信息保留在可达范围内。窗口就是智能体的工作记忆,注意力机制则是它的推理方式,而下一个标记的循环则构成其行动循环。智能体型人工智能并不需要新的架构,关键在于人们意识到:当Transformer的规模足够大时,它已经能够支撑智能体的行为能力。
在实际应用中,2026年开发的智能体很少仅依赖单纯的窗口来处理任务。为完成耗时较长的任务,它们会接入外部内存:临时存储文件、检索层或智能体持续更新的知识库。这并不与前述观点矛盾,因为外部内存只有被读回窗口时才会影响模型。它只是扩展了缓冲区而非替代它,而Transformer对相关上下文的注意力机制依然是思维发生的核心所在。
研究的发展方向
Transformer的性能遵循参数、训练数据及计算资源方面的可预测幂律关系,这为研究人员提供了发展路线图。当前的研究前沿正沿着以下几个方向推进:
- 高效架构,通过闪存注意力、稀疏注意力及线性注意力等方式降低注意力的二次成本。
所有这些技术都基于变换器架构,了解该基础有助于理解这些发展方向。
下表将各个组件汇总在一页中,说明其解决的问题、工作原理及主要特性:
| Component | Problem it Solves | Core Mechanism | Key Properties |
|-----------|------------------|----------------|----------------|
| **Tokenization** | Text is not natively numeric | Subword BPE/WordPiece splitting | Vocabulary ≈ 30k–100k; subwords handle rare terms |
| **Embeddings** | Discrete IDs have no geometry | $\mathbf{e}_t = E[t] \in \mathbb{R}^{d_{\text{model}}}$ | Semantic similarity → geometric proximity |
| **Positional Encoding** | Parallel attention loses token order | sin/cos at different frequencies (or RoPE) | Multi-scale; encodes absolute and relative position |
| **Self-Attention** | Long-range deps, sequential bottleneck | $\text{softmax}(QK^\top/\sqrt{d_k})V$ | $O(n^2)$ but parallel; dynamic contextual reps |
| **Query/Key/Value** | Separating "what I seek" from "what I offer" | Three separate learned linear projections | Relevance ≠ similarity; flexible dependency modeling |
| **Multi-Head Attention** | Single head captures only one relationship type | $h$ parallel heads, concatenated + $W^O$ | Simultaneously captures syntactic, semantic, positional |
| **Encoder** | Understanding input in full bidirectional context | Full self-attention, no masking | Bidirectional; rich contextualized representations |
| **Decoder** | Generating output autoregressively | Causal self-attention + cross-attention | Predicts one token at a time; teacher-forcing in training |
| **Cross-Attention** | Connecting generation to input understanding | Q from decoder, K/V from encoder | Enables encoder→decoder communication |
| **Feed-Forward Network** | Per-token computation + factual storage | $\text{GeLU}(\mathbf{x}W_1)\,W_2$ per token | Position-wise; stores factual associations in weights |
| **Residual Connections** | Vanishing gradients in deep networks | $\mathbf{h} = \text{SubLayer}(\mathbf{x}) + \mathbf{x}$ | Creates gradient highway; enables 100+ layer models |
| **Pre-LayerNorm** | Unstable activations in deep networks | Normalize before each sublayer | Stable training; standard in all modern transformers |
已涵盖的内容及下一步方向
各组成部分的协同方式如下:并行注意力机制比逐步骤处理更高效,能更有效地捕捉远距离依赖关系,这也是Transformer取代序列模型的原因。数据从文本流向标记、嵌入向量、位置编码、注意力机制,再进入前馈层,之后循环往复。自注意力是核心操作,每个标记通过学习得到的Q、K和V投影来关注其他所有标记,即Attention(Q, K, V) = softmax(QK^T / sqrt(d_k)) V。多个注意力头可捕捉不同模式,位置编码用于恢复顺序,而编码器-解码器结构则同时支持理解与生成功能。前馈层用于存储知识,残差连接有助于增加模型深度,预层归一化则能保持训练稳定性。大规模的下一词预测能够产生新的能力,上下文窗口充当智能体的工作记忆,该架构则实现了……
2017年发表的一篇翻译论文推动了当今最先进的系统的发展。
若想更深入理解,分阶段计划效果较好。
前两周:数学基础。观看Andrei Karpathy在YouTube上发布的“神经网络:从零到精通”系列视频,尤其是从头开始构建GPT的那期。然后用NumPy编写一个简单的自注意力层。亲手计算这些概念后,理解会更深刻。
第三周和第四周:相关论文。阅读现已可获取的《注意力就是你所需》(Vaswani等人,2017年),以及BERT论文(Devlin等人,2018年)、GPT-3相关论文《语言模型是少样本学习者》(Brown等人,2020年)和《神经语言模型的缩放定律》(Kaplan等人,2020年)。
第二个月:使用库和API进行实践。 Hugging Face的transformers库让这些模型只需简单配置即可在Python中使用。可以针对分类任务对BERT或Llama、Qwen等小型开源模型进行微调。随后通过Anthropic或OpenAI的Python SDK来使用当前最先进的模型,比如Claude Sonnet 5或GPT-5系列模型。这两种实践方式都能将理论与实际结合,因为无论是开源模型还是最先进的API模型,都遵循相同的变换器原理。
第三个月:深入研究一个领域。可以选择某个智能体框架(LangChain、LlamaIndex),或者亲自使用Claude Code或Cursor来观察真实生产环境中的智能体行为;也可以研究高效变换器技术(Flash Attention、稀疏注意力与线性注意力),或是利用LoRA和PEFT进行大语言模型微调。此时深度学习比广度学习更为重要。
持续关注:及时了解最新研究进展。 arXiv上的cs.CL和cs.LG分类、Hugging Face博客、Anthropic的研究页面以及AI Alignment论坛都是不错的信息来源。该领域发展迅速,但上述基础内容有助于理解新发表的论文。
那篇关于Transformer的论文约有十五页,其中描述的架构简单到足以在下午之内实现。它所带来的变革,以及后续的扩展与优化所进一步引发的改变,都改变了人们对机器能力的认知。