Transformer 架构速览:从 Self-Attention 到 GPT
它为什么会取代 RNN/CNN,Self-Attention 在做什么,整块网络是怎么一路走到 GPT 这类大模型上的。
从 RNN/CNN 到 Transformer:为什么要换一套架构?
在自然语言建模上,传统做法主要是 RNN/LSTM、1D-CNN 这两类:
- RNN/LSTM 擅长“按时间一步步读”,可以记住前面的信息,但:
- 序列太长时,梯度传播困难,长依赖容易衰减;
- 无法很好地并行训练,一次只能处理一个时间步。
- 1D-CNN 可以并行一些,但卷积核的感受野有限,想覆盖长距离依赖就要堆很多层。
Transformer 做的事情,就是直接把“按顺序一格格读”的束缚拆掉,用 Self-Attention 一步看全局。
它的几个关键点:
- 完全基于注意力(Attention),没有循环结构;
- 同一层里,所有位置可以并行计算,训练速度大幅提升;
- 注意力可以直接“跳跃式”连接远距离 token,更容易建模长依赖。
Self-Attention:Q/K/V 在干什么?
先用一个直觉版的说法:
- 对于序列里的每个 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 $$可以按步骤理解:
- 相似度计算:$QK^\top$ 得到每个 token 对其它 token 的“关注分数”。
- 缩放 & 归一化:除以 $\sqrt{d_k}$ 再过一遍 $\text{softmax}$,让分数既稳定又能当权重用。
- 加权求和:用这些权重对 V 做加权求和,得到新的表示。
结果就是:每个位置的表示,不再只是自己那一个向量,而是“看了整句之后重新编码”的向量。
Multi-Head Attention:为什么要多头?
如果只有一个头,整个注意力层只能在一个子空间里学习“谁该看谁”。
Multi-Head 的做法是:
- 把输入向量先投影到多个子空间,每个子空间各自做一套 Q/K/V 和 Attention;
- 最后把所有头的结果拼接起来,再线性投影回原始维度。
这样做的好处是:
不同的头可以学习到不同的模式 —— 有的强调句法关系,有的关注语义,有的偏位置特征等。
位置编码:让模型知道“顺序”
Self-Attention 本身对输入顺序是不敏感的:
如果你把序列整体打乱,它依然可以算出一堆注意力分数,但这显然不符合“语言是有顺序的”这一事实。
为了解决这个问题,Transformer 在输入 token 向量时,会额外加上一个 位置向量:
1输入向量 = token embedding + position embedding
常见的做法有两类:
- 正弦位置编码(Sinusoidal):
- 用不同频率的正弦、余弦函数生成一个固定的向量序列;
- 好处是:位置关系在数学上“连续”,模型在较长序列外推时更自然。
- 可学习的位置编码(Learned Positional Embedding):
- 把每个位置当成一个“可学习的 embedding”;
- 好处是灵活、简单,但外推到比训练时更长的序列会稍微麻烦一些。
在后来的模型里,又出现了 RoPE(旋转位置编码)、ALiBi 等方案,本质上都是在解决一个问题:
怎么在注意力里优雅地编码“谁在前、谁在后、谁离谁更近”。
一个标准 Transformer Block 里发生了什么?
以最常见的 Encoder/Decoder Block 为例,可以把一层 Block 里发生的事拆成几步:
- 输入向量(token embedding + 位置编码)进入多头自注意力层;
- Attention 输出和原输入做一次 残差连接 + LayerNorm;
- 结果再进一个 前馈网络(Feed-Forward Network, FFN),通常是两层 MLP(中间维度放大,再压回去);
- FFN 输出和它的输入再做一次 残差连接 + LayerNorm。
如果只看一层,可以简化理解为:
- Self-Attention:让每个位置“看一眼全局”;
- FFN:在位置上逐点做非线性变换,相当于“再加工一下信息”;
- 残差 + LayerNorm:保证梯度流动顺畅、训练更稳定。
堆叠很多层这样的 Block,再配合输入/输出头部(embedding、分类/生成头),就是整套 Transformer 网络。
从 Encoder-Decoder 到 GPT:结构上的差异
最初的 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 更适合做“生成类”任务(续写、对话、代码补全等)。
因果 Mask 与自回归生成
在 GPT 这类模型里,训练和推理都遵循一个简单原则:
当前位置的预测只能依赖它左边已经看到的 token。
在 Attention 的实现里,这通过一个 上三角 Mask 矩阵 来完成:
- 对于位置 $i$,只允许它看到 $0 \dots i$ 的位置,把 $i$ 右上方的注意力权重全部屏蔽(设为 $-\infty$ 再过 softmax)。
- 这样一来,无论是训练时的并行计算,还是推理时的逐步生成,都不会“偷看未来”。
自回归生成过程可以简单理解为:
- 给模型一个初始 prompt,生成第一个新 token;
- 把这个新 token 拼回输入,再生成下一个;
- 如此循环,直到生成结束标记或达到长度上限。
总结一下这版架构的几个关键词
- Self-Attention:用全局视角重写每个 token 的表示,是 Transformer 的核心算子;
- Multi-Head:在多个子空间并行建模不同关系,让注意力有“多种视角”;
- 位置编码:修复 Self-Attention 对顺序不敏感的问题,让模型真正理解“前后关系”;
- 残差 + LayerNorm + FFN:保证训练稳定,并对信息做进一步的非线性变换;
- Encoder-only / Decoder-only:决定了模型更偏“理解”还是“生成”,GPT 就是典型的 Decoder-only 自回归架构。
有了这一整块的骨架,后面无论是看论文里的各种改造,还是理解大模型推理/微调时发生了什么,都会轻松很多。