Transformer 架构速览:从 Self-Attention 到 GPT

它为什么会取代 RNN/CNN,Self-Attention 在做什么,整块网络是怎么一路走到 GPT 这类大模型上的。

在自然语言建模上,传统做法主要是 RNN/LSTM、1D-CNN 这两类:

  • RNN/LSTM 擅长“按时间一步步读”,可以记住前面的信息,但:
    • 序列太长时,梯度传播困难,长依赖容易衰减;
    • 无法很好地并行训练,一次只能处理一个时间步。
  • 1D-CNN 可以并行一些,但卷积核的感受野有限,想覆盖长距离依赖就要堆很多层。

Transformer 做的事情,就是直接把“按顺序一格格读”的束缚拆掉,用 Self-Attention 一步看全局。

它的几个关键点:

  • 完全基于注意力(Attention),没有循环结构;
  • 同一层里,所有位置可以并行计算,训练速度大幅提升;
  • 注意力可以直接“跳跃式”连接远距离 token,更容易建模长依赖。

先用一个直觉版的说法:

  • 对于序列里的每个 token,它要“问自己一个问题”:当前我在理解什么?需要关注谁?
  • Query(Q):这个 token 提出的“问题”。
  • Key(K):其它 token 的“标签 / 特征”。
  • Value(V):其它 token 提供的“具体信息”。

Self-Attention 的核心公式是:

$$ \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^\top}{\sqrt{d_k}}\right)V $$

可以按步骤理解:

  1. 相似度计算:$QK^\top$ 得到每个 token 对其它 token 的“关注分数”。
  2. 缩放 & 归一化:除以 $\sqrt{d_k}$ 再过一遍 $\text{softmax}$,让分数既稳定又能当权重用。
  3. 加权求和:用这些权重对 V 做加权求和,得到新的表示。

结果就是:每个位置的表示,不再只是自己那一个向量,而是“看了整句之后重新编码”的向量。

如果只有一个头,整个注意力层只能在一个子空间里学习“谁该看谁”。
Multi-Head 的做法是:

  • 把输入向量先投影到多个子空间,每个子空间各自做一套 Q/K/V 和 Attention;
  • 最后把所有头的结果拼接起来,再线性投影回原始维度。

这样做的好处是:
不同的头可以学习到不同的模式 —— 有的强调句法关系,有的关注语义,有的偏位置特征等。

Self-Attention 本身对输入顺序是不敏感的:
如果你把序列整体打乱,它依然可以算出一堆注意力分数,但这显然不符合“语言是有顺序的”这一事实。

为了解决这个问题,Transformer 在输入 token 向量时,会额外加上一个 位置向量

1输入向量 = token embedding + position embedding

常见的做法有两类:

  • 正弦位置编码(Sinusoidal)
    • 用不同频率的正弦、余弦函数生成一个固定的向量序列;
    • 好处是:位置关系在数学上“连续”,模型在较长序列外推时更自然。
  • 可学习的位置编码(Learned Positional Embedding)
    • 把每个位置当成一个“可学习的 embedding”;
    • 好处是灵活、简单,但外推到比训练时更长的序列会稍微麻烦一些。

在后来的模型里,又出现了 RoPE(旋转位置编码)、ALiBi 等方案,本质上都是在解决一个问题:
怎么在注意力里优雅地编码“谁在前、谁在后、谁离谁更近”。

以最常见的 Encoder/Decoder Block 为例,可以把一层 Block 里发生的事拆成几步:

  1. 输入向量(token embedding + 位置编码)进入多头自注意力层
  2. Attention 输出和原输入做一次 残差连接 + LayerNorm
  3. 结果再进一个 前馈网络(Feed-Forward Network, FFN),通常是两层 MLP(中间维度放大,再压回去);
  4. FFN 输出和它的输入再做一次 残差连接 + LayerNorm

如果只看一层,可以简化理解为:

  • Self-Attention:让每个位置“看一眼全局”
  • FFN:在位置上逐点做非线性变换,相当于“再加工一下信息”
  • 残差 + LayerNorm:保证梯度流动顺畅、训练更稳定

堆叠很多层这样的 Block,再配合输入/输出头部(embedding、分类/生成头),就是整套 Transformer 网络。

最初的 Transformer(机器翻译场景)是 Encoder-Decoder 结构:

  • Encoder:读入源语言句子,输出一串上下文表示;
  • Decoder:在看着 Encoder 输出的同时,自回归地生成目标语言。

后来几个主流方向做了不同的裁剪:

  • BERT 一类(Encoder-only)
    • 只保留 Encoder 部分,做双向编码,用来做分类、匹配、抽取等任务;
    • 训练目标通常是 Masked Language Modeling(挖空再预测)。
  • GPT 一类(Decoder-only)
    • 只保留 Decoder,自回归地预测“下一个 token”;
    • 通过因果 Mask(Causal Mask)保证当前位置只能看到“自己左边”的 token。

对使用者来说,最重要的差别是:

  • Encoder-only 更适合做“理解类”任务(给你一句话/一段文本,输出一个整体表示或标签);
  • Decoder-only 更适合做“生成类”任务(续写、对话、代码补全等)。

在 GPT 这类模型里,训练和推理都遵循一个简单原则:
当前位置的预测只能依赖它左边已经看到的 token。

在 Attention 的实现里,这通过一个 上三角 Mask 矩阵 来完成:

  • 对于位置 $i$,只允许它看到 $0 \dots i$ 的位置,把 $i$ 右上方的注意力权重全部屏蔽(设为 $-\infty$ 再过 softmax)。
  • 这样一来,无论是训练时的并行计算,还是推理时的逐步生成,都不会“偷看未来”。

自回归生成过程可以简单理解为:

  1. 给模型一个初始 prompt,生成第一个新 token;
  2. 把这个新 token 拼回输入,再生成下一个;
  3. 如此循环,直到生成结束标记或达到长度上限。
  • Self-Attention:用全局视角重写每个 token 的表示,是 Transformer 的核心算子;
  • Multi-Head:在多个子空间并行建模不同关系,让注意力有“多种视角”;
  • 位置编码:修复 Self-Attention 对顺序不敏感的问题,让模型真正理解“前后关系”;
  • 残差 + LayerNorm + FFN:保证训练稳定,并对信息做进一步的非线性变换;
  • Encoder-only / Decoder-only:决定了模型更偏“理解”还是“生成”,GPT 就是典型的 Decoder-only 自回归架构。

有了这一整块的骨架,后面无论是看论文里的各种改造,还是理解大模型推理/微调时发生了什么,都会轻松很多。