Transformer架构初步
从 RNN 爬到 Transformer 山顶
第一次听到 Transformer 的时候,我脑子里闪过三个画面:
- 物理书里的“变压器”
- 变形金刚
- 导师嘴里那句:“现在大部分大模型都是这个架构……”
然后我去翻论文《Attention is All You Need》,翻开第一眼:
公式一堆、结构图一堆,我当场关掉 PDF,默默记住一个结论:
这个东西以后肯定逃不过,但今天先不学。
直到后面真的要用到它,我才开始系统地啃。下面的内容可以看作是我这个初学者把 Transformer 从“听过名字”到“勉强理解”的过程整理。
一、先说结论:Transformer 到底干了件什么事?
如果只能用一句话来概括 Transformer,我现在会这样说:
以前我们处理一句话,是按时间步从左到右递推;
Transformer 改成了:整句一起看,通过自注意力让每个位置和所有位置建立联系。
更具体一点:
- RNN:依次处理每一步依赖前一步的隐状态$(h_{t-1})$;
- Transformer:把整段序列表示成矩阵,一次性送进若干层自注意力和前馈网络中,在每一层里,任意两个位置都可以直接交互信息。
它的两个核心优势:
- 计算上不再严格串行,可以很好地并行;
- 任意距离的依赖都可以通过注意力直接建模,长依赖不再需要“层层传递”。
剩下的公式、结构设计,基本都是围绕这两点展开的工程实现细节。
二、以前的我们都是怎么处理“序列”的?
在遇到 Transformer 之前,主流的序列建模方法是 RNN / LSTM / GRU。
典型形式是:
每个时间步的隐状态依赖当前输入和上一个隐状态。从直觉来看,这非常符合“按顺序处理”的想法。
问题也很典型:
- 序列一长,早期的信息要一层层往后传,容易衰减(梯度消失/信息稀释);
- 每一步要等前一步算完,并行度有限;
- 想把模型做大、把序列拉长,训练成本会明显上升。
简单说,RNN 系列的结构在“表达序列依赖”和“与现代硬件的计算模式”之间,存在一个天然的矛盾。
Transformer 的思路就是把这个矛盾拆开:顺序感不靠递推来体现,而交给其他机制(位置编码),序列关系不靠链式传递,而用注意力做全局建模。
三、Self-Attention:一句话里的词怎么“互相看”?
3.1 一个具体例子
来看一句中文:
“昨天我在公园看到一个人,他牵着一只看起来像猫的狗。”
在理解这句话时:
- 看到“他”,大多数人会自然地把它和前面的“一个人”对应起来;
- 看到“像猫的狗”,会把“像猫”和“狗”关联,而不是“公园像猫”。
也就是说,人类在理解语句时,并不是只盯着当前位置,而是会参考整句中其他相关的位置。
Self-Attention 做的事情就是:
让模型在计算每个位置的表示时,可以访问整个序列,根据“相关性”来决定该从哪些位置获取信息。
3.2 Q / K / V 到底在干什么?
一开始看到 Q/K/V 我也一头雾水,后来把它们简单地整理成三个角色:
- Q(Query):查询向量,表示当前这个位置“想要什么信息”;
- K(Key):键向量,表示序列中每个位置可以被“匹配”的特征;
- V(Value):值向量,是真正要被加权聚合的信息。
自注意力的计算形式是:
$[
\text{Attention}(Q,K,V)
= \text{softmax}\left(\frac{QK^\top}{\sqrt{d_k}}\right)V
]$
逐步理解一下:
- 对序列每个位置 $(i)$,利用线性变换得到它的 $(Q_i, K_i, V_i)$;
- 对于位置 $(i)$,计算它的$ (Q_i)$ 与所有位置 $(j)$ 的 $(K_j) $的点积,得到一串相关性分数;
- 对这些分数做 $softmax$,得到一组权重$ ( \alpha_{ij} )$;
- 用这组权重对所有 $(V_j)$ 做加权求和,得到位置$ (i) $的新的表示。
Self-Attention = 每个位置用自己的 Q,去匹配全序列的 K,得到权重后对全序列的 V 做加权求和。
相比 RNN 这种“链式传递”,Self-Attention 允许任意位置之间直接发生交互。
四、多头注意力:为什么要搞那么多“头”?
多头注意力(Multi-Head Attention)刚听上去有点吓人,其实做的事情非常机械:
- 把输入向量先通过线性变换,分成 (h) 份不同的子空间(head);
- 每个 head 在自己的子空间里独立完成一遍 Self-Attention;
- 把所有 head 的输出在最后一个维度拼接起来,再经过一次线性变换。
形式上是:
$[
\text{head}_i = \text{Attention}(QW_i^Q, KW_i^K, VW_i^V)
]$
$[
\text{MultiHead}(Q,K,V) = \text{Concat}(\text{head}_1,\dots,\text{head}_h)W^O
]$
直观含义:
- 不同的 head 在不同的子空间中建模“相关性”,可以捕捉到不同类型的模式(比如局部关系、长距离关系、语法结构等);
- 多个 head 并行计算,不会增加时间复杂度量级,只是扩大了宽度。
所以,可以简化地记住:
多头注意力 = 多个自注意力并联,在不同子空间里建模,再合并。
五、顺序去哪了?——位置编码出场
上面说的 Self-Attention 有一个明显问题:
它本身对序列的顺序不敏感,只关心向量值,而不关心“第几个位置”。
如果不给模型额外的位置信息,“我 在 昨天 公园”和“公园 昨天 在 我”在它眼里只是向量排列的变化。
解决方法就是位置编码(Positional Encoding):
在送入 Transformer 之前,为每个位置添加一个专门的“位置向量”。
常见做法有两类:
- 固定位置编码(正弦/余弦)
论文中的做法是用不同频率的正弦、余弦函数生成位置向量,例如:
这样做的一个好处是:不同位置之间的“差值”在空间中有一定结构,且可以泛化到训练长度以外的序列。
可学习位置编码 / 旋转位置编码(RoPE)等
- 可学习位置编码:把位置当成一种特殊的 embedding,训练时一并更新;
- RoPE 等:通过在注意力计算中引入位置相关的旋转结构,更适合长序列。
从初学者角度,先记住一句话就够:
Transformer 自己不带顺序感,顺序信息是通过位置编码显式加进去的。
六、一个标准 Transformer Block 长什么样?
把前面的这些组件组合起来,一个标准的 Transformer 编码层大致包含:
- 多头自注意力(Multi-Head Self-Attention)
- 前馈网络(Feed Forward Network, FFN)
- 残差连接(Residual Connection)
- LayerNorm(层归一化)
简化结构:
1 | 输入 x |
稍微展开一下:
- 多头自注意力:输入序列经过 Q/K/V 投影和 attention 计算,得到新的序列表示;
- 残差 + LayerNorm:把 attention 输出与原输入相加,再做归一化,缓解梯度问题;
- FFN:位置独立的前馈网络,一般是两层全连接,中间带激活(如 GELU),维度通常放大 4 倍再压回去;
- 残差 + LayerNorm:再叠加一次,形成一层完整的 Block。
多层这样的 Block 堆叠,就构成了我们常说的 Transformer Encoder/Decoder 主体结构。
七、Encoder / Decoder / GPT
原始论文里的 Transformer 是为机器翻译设计的,因此有 Encoder 和 Decoder 两部分:
- Encoder:多层 Transformer Block,输入为源语言序列,输出为一系列上下文表示;
Decoder:同样是多层 Block,但每一层包含:
- 对已经生成的目标序列做 Masked Self-Attention;
- 对 Encoder 输出和当前目标序列做 Encoder-Decoder Attention。
整体流程大致是:
1 | 输入序列 → [多层 Encoder] → 中间表示 → [多层 Decoder] → 输出序列 |
后来,在具体任务中出现了几种简化/变体:
只用 Encoder(例如 BERT)
- 擅长“理解型”任务:分类、匹配、抽取、检索等。
只用 Decoder(例如 GPT 系列)
- 使用 Masked Self-Attention,从左到右自回归预测下一个 token;
- 擅长“生成型”任务:对话、续写、代码生成等。
Encoder + Decoder
- 仍然主要用于翻译、摘要这类“输入一句话 / 文档,输出一句话 / 文档”的 Seq2Seq 任务。
作为初学者,我给自己定的目标是:
先把 Self-Attention、多头、位置编码、Transformer Block 这几件事搞清楚,
然后能大概说清:
- BERT 用的是 Encoder;
- GPT 用的是 Decoder,自回归预测下一个 token。
做到这一点,就已经从“只听过名字”走出了好几步。
八、为什么大家都在用 Transformer?(一点点宏观视角)
从一个新手的角度回头看,Transformer 成为主流架构,大致有这几点原因:
计算模式和硬件高度匹配
- 主体运算是矩阵乘法和点积,可以很好地利用 GPU/TPU 的并行能力;
- 不需要严格按时间步串行,训练长序列和大模型都更高效。
表达能力强
- 自注意力允许任意两个位置直接交互,而不是依赖链式传递;
- 多头 + 多层堆叠,可以学习复杂的语言结构、依赖模式。
形式统一,适配多模态
- 文本天然是 token 序列;
- 图像可以被切成 patch,当成“视觉 token”(比如 ViT);
- 声音、视频等也可以编码成序列,再喂给 Transformer。
从学习者视角看,最大的收益是:
理解一套结构,可以看懂一大批模型的整体框架。
小结:Transformer 神坛
最后简单收个尾。
对我这种初学者来说,现在对 Transformer 的认识大概是:
- 它的确是这一批模型的基础架构,值得花时间;
- 但它并不是玄学,而是一套很符合现代硬件和大规模数据场景的工程设计;
- 不需要一口气啃到各种长序列技巧、KV Cache、MoE 才算入门。
我现在给自己的要求只有这几条:
- 知道 为什么会出现 Attention/Transformer;
- 能解释清楚 Self-Attention + 多头 + 位置编码 在做什么;
- 能画出一个 Transformer Block 的大致结构;
- 大概知道 BERT / GPT 和原始 Transformer 之间的关系。
做到这一步,再回头看那篇论文标题 Attention is All You Need,感觉就不再只是一个“标题党”,而是能从工程和建模的角度理解它在说什么。
