欢迎光临
我们一直在努力

Transformer 深度解剖——把“变形金刚“拆成零件给你看1.2

如果你把 Transformer 比作一辆法拉利,那这一章就是把它拆到只剩螺丝钉,然后一颗一颗告诉你:“这颗螺丝是干嘛的,拧紧了会怎样,拧松了又会怎样。”

系好安全带,我们要动刀了。


2.1 Self-Attention:一场精心策划的"相亲大会"

先忘掉公式,听个故事

想象你走进一个有 100 人的派对。你想知道"谁跟我关系最近"。怎么办?

你掏出三样东西:

  • 名片(Query,Q):上面写着"我是谁,我想找什么"
  • 胸牌(Key,K):上面写着"我是谁,我能提供什么"
  • 礼物(Value,V):真正要传递的内容

你拿着自己的名片,跟每个人的胸牌碰一碰,算个"匹配度"。匹配度高的人,你就多拿点他的礼物;匹配度低的,意思意思就行。

最后你手里捧着一堆礼物,按匹配度加权混合——恭喜你,这就是 Self-Attention。

现在上公式(别跑!)

Attention(Q,K,V)=softmax(QKTdk)V\\text{Attention}(Q, K, V) = \\text{softmax}\\left(\\frac{QK^T}{\\sqrt{d_k}}\\right)VAttention(Q,K,V)=softmax(dkQKT)V

逐个拆解:

① QK^T——“名片碰胸牌”

Q 的形状是 [n,dk][n, d_k][n,dk],K 的形状也是 [n,dk][n, d_k][n,dk]。做矩阵乘法 QKTQK^TQKT,得到 [n,n][n, n][n,n] 的矩阵——每行每列代表"第 i 个人对第 j 个人的关注度"。

② 除以 √d_k——“防止音量炸麦”

dkd_kdk 是向量维度。维度越高,点积的数值越大。如果不除,softmax 的输入会变成一堆巨大的数,梯度直接"躺平"(趋近于零)。除以 dk\\sqrt{d_k}dk 相当于给音量旋钮拧到合理位置。

题库原话:sqrt(d) 的作用是防止内积值过大导致梯度消失。

③ Softmax——“把分数变成概率”

把一行的分数变成加起来等于 1 的概率分布。谁分高,谁权重就大。

④ 乘以 V——“按权重收礼物”

最终输出是每个位置的 Value 的加权和。

一句话总结

Self-Attention 的本质:让序列中的每个词,都能"看到"其他所有词,并决定该关注谁、关注多少。

批注:Transformer模型的核心机制是自注意力机制,能够直接建模任意距离的词元之间的交互关系。


2.2 Multi-Head Attention:一个人看不过来的,让八个人一起看

为什么一个头不够?

一个 Self-Attention 头,就像一个人同时当导演、摄影师、灯光师、剪辑师——忙不过来,视角单一。

Multi-Head 的做法:把 d 维空间切成 h 份,每份独立做注意力,最后拼起来。

MultiHead(Q,K,V)=Concat(head1,…,headh)WO\\text{MultiHead}(Q,K,V) = \\text{Concat}(\\text{head}_1, \\dots, \\text{head}_h) W^OMultiHead(Q,K,V)=Concat(head1,,headh)WO

其中每个 headi=Attention(QWiQ,KWiK,VWiV)\\text{head}_i = \\text{Attention}(QW_i^Q, KW_i^K, VW_i^V)headi=Attention(QWiQ,KWiK,VWiV)

通俗比喻

把一部电影同时用 8 个机位拍:

  • 机位 1 专拍主角表情(语法关系)
  • 机位 2 专拍背景(语义上下文)
  • 机位 3 专拍道具(指代关系)
  • ……

最后剪辑师(WOW^OWO)把 8 个画面合成一部完整电影。

批注:多头注意力通过并行多个独立的注意力头,分别学习输入序列在不同子空间的特征表示,从而增强模型捕捉复杂语义的能力。

为什么不是"头越多越好"?

头太多 → 每个子空间维度太小 → 学不到有意义的模式。通常 8~128 个头,取决于模型规模。


2.3 位置编码三剑客:给词排座位

问题:Attention 是个"脸盲"

Self-Attention 只看"谁跟谁像",完全不管顺序。"狗咬人"和"人咬狗"在它眼里一模一样——这可不行。

所以我们需要位置编码,告诉模型:“这个词坐第几排第几座。”

第一代:正弦位置编码(绝对位置)

PE(pos,2i)=sin⁡(pos/100002i/d)PE_{(pos, 2i)} = \\sin(pos / 10000^{2i/d})PE(pos,2i)=sin(pos/100002i/d)
PE(pos,2i+1)=cos⁡(pos/100002i/d)PE_{(pos, 2i+1)} = \\cos(pos / 10000^{2i/d})PE(pos,2i+1)=cos(pos/100002i/d)

比喻:给每个座位刻一个固定编号。第 1 号座永远是 1 号,第 100 号座永远是 100 号。

  • ✅ 简单,不需要学习
  • ❌ 只能表达绝对位置,"第 5 个词和第 3 个词隔了 2 个位置"这种相对关系表达不好
  • ❌ 训练时没见过的位置,推理时外推能力差

第二代:RoPE 旋转位置编码(相对位置)

批注:旋转位置编码通过复数域旋转矩阵对词向量进行空间变换,将相对位置关系融入注意力计算。

比喻:不刻座位号了,而是让每个人原地转一个角度。第 1 个词转 1°,第 2 个词转 2°,第 100 个词转 100°。

两个词做点积时,角度差自然体现了相对距离。就像两个时钟指针,你关心的不是各自指几点,而是它们之间的夹角。

  • ✅ 天然编码相对位置
  • ✅ 有长期衰减特性,适合长序列
  • ✅ 外推能力比正弦编码强
  • 代表用户:LLaMA、Qwen、DeepSeek

第三代:ALiBi(线性偏置)

比喻:不转了,直接在注意力分数上减一个跟距离成正比的惩罚。距离越远,扣分越多。

scoreij=qi⋅kj−m⋅∣i−j∣\\text{score}_{ij} = q_i \\cdot k_j – m \\cdot |i – j|scoreij=qikjmij

  • ✅ 极其简单,不需要额外参数
  • ✅ 天然鼓励关注近处
  • ❌ 对非常长的依赖关系可能过于"短视"

三剑客对比表

方法类型核心操作外推性代表模型
正弦 绝对 sin/cos 加到词向量 一般 原始 Transformer
RoPE 相对 旋转矩阵乘 Q/K LLaMA, Qwen
ALiBi 相对 线性惩罚加到分数 中等 BLOOM

批注:旋转位置编码(RoPE)被广泛用于建模长序列数据,因其具有良好的性能和长期衰减特性。


2.4 Layer Normalization:给每个神经元"调音"

为什么需要归一化?

训练深层网络时,每层的输入分布会不断漂移(Internal Covariate Shift)。就像乐队演出,吉他手突然把音量拧到最大,鼓手被盖住了,整个乐队乱套。

LayerNorm 就是那个调音师:把每层的输入拉回到均值 0、方差 1 的"标准音量"。

LayerNorm(x)=x−μσ2+ϵ⋅γ+β\\text{LayerNorm}(x) = \\frac{x – \\mu}{\\sqrt{\\sigma^2 + \\epsilon}} \\cdot \\gamma + \\betaLayerNorm(x)=σ2+ϵxμγ+β

Post-LN vs Pre-LN:调音师站哪儿?

Post-LN(原始 Transformer):

输入 → Attention → 残差相加 → LayerNorm → FFN → 残差相加 → LayerNorm

调音师站在残差连接之后。问题:深层网络训练不稳定,需要 warmup。

Pre-LN(GPT-2 之后主流):

输入 → LayerNorm → Attention → 残差相加 → LayerNorm → FFN → 残差相加

调音师站在子层之前。训练更稳定,但深层性能可能略弱。

批注:原始Transformer在残差连接前和FFN后均应用LayerNorm(Pre-LN结构)。

RMSNorm:调音师的精简版

LLaMA 用的方案。去掉"减均值"步骤,只做缩放:

RMSNorm(x)=xRMS(x)⋅γ\\text{RMSNorm}(x) = \\frac{x}{\\text{RMS}(x)} \\cdot \\gammaRMSNorm(x)=RMS(x)xγ

少算一个均值,速度快 10%~15%,效果差不多。

DeepNorm:给深层网络加"保险丝"

微软提出的方案,在残差连接上加一个缩放系数 α\\alphaα,让 1000 层网络也能稳定训练。


2.5 激活函数:神经网络里的"门卫"

没有激活函数会怎样?

全是线性变换,100 层网络等价于 1 层。门卫全放假了,谁来都不拦,那还要大楼干嘛?

ReLU:最朴素的门卫

f(x)=max⁡(0,x)f(x) = \\max(0, x)f(x)=max(0,x)

  • 正数?放行。负数?滚。
  • ✅ 计算快,求导简单
  • ❌ 负区间梯度为 0 → “神经元死亡”(一旦输出负值,永远醒不过来)

批注:ReLU在正数区域内的梯度为1,可以保证梯度在传递过程中不会消失。

GeLU:温柔版门卫

f(x)=x⋅Φ(x)f(x) = x \\cdot \\Phi(x)f(x)=xΦ(x)

不是硬邦邦地"负数全拒",而是用概率平滑过渡。Bert、GPT 系列都用它。

SwiGLU / GeGLU:当前顶流

LLaMA、Qwen 等新一代模型的标配。核心思想:把 FFN 拆成两个门控分支,一个走 Swish/GeLU 激活,另一个当"门"控制信息流量。

SwiGLU(x)=(Swish(xW1)⊙(xW3))W2\\text{SwiGLU}(x) = (\\text{Swish}(xW_1) \\odot (xW_3)) W_2SwiGLU(x)=(Swish(xW1)(xW3))W2

比喻:以前厨房只有一个厨师做菜。现在一个厨师做菜,另一个厨师决定"这道菜上不上、上多少"。精细控制,效果更好。


2.6 FFN 隐藏维度演进:厨房越扩越大,又缩回去了

FFN(前馈网络)是 Transformer 里的"厨房"——注意力层负责"看菜单",FFN 负责"炒菜"。

经典配置:4d

原始 Transformer:输入维度 d=512,FFN 隐藏层 4d=2048。

比喻:厨房面积是餐厅的 4 倍。够用了。

大模型时代:8d → 3d

  • GPT-3 用 4d
  • PaLM 用 4d 但加了 SwiGLU,等效约 8d/3 ≈ 2.67d(因为 SwiGLU 多一个矩阵)

最新趋势:2.7d

LLaMA 的做法:用 SwiGLU,隐藏维度设为 8d3\\frac{8d}{3}38d(约 2.67d),但因为 SwiGLU 有 3 个权重矩阵,总参数量跟 4d 的普通 FFN 差不多。

翻译成人话:厨房没变大,但换了更高效的灶台,炒出更多菜。


2.7 残差连接:给梯度修一条"高速公路"

问题:信号传着传着就没了

100 层网络,梯度每层乘一个小数,传到第 1 层时已经接近 0。这叫梯度消失。

批注:ResNet通过残差连接构建H(x)=F(x)+x的恒等映射,确保深层网络至少能保留浅层特征。

解决方案:修一条直通的"电梯"

H(x)=F(x)+xH(x) = F(x) + xH(x)=F(x)+x

  • F(x)F(x)F(x):走楼梯(经过卷积/注意力等变换)
  • xxx:坐电梯(原封不动传过去)

反向传播时:

∂H∂x=∂F∂x+1\\frac{\\partial H}{\\partial x} = \\frac{\\partial F}{\\partial x} + 1xH=xF+1

那个 “+1” 就是电梯——不管楼梯多难走,梯度至少有一条直通路径。

批注:反向传播时,残差连接使得梯度可通过 ∂H/∂x = ∂F/∂x + 1 路径直接传递,避免连续卷积层的导数连乘导致梯度消失。

在 Transformer 中的位置

每个子层(Attention、FFN)后面都跟一个残差连接:

x → [Sub-Layer] → + x → LayerNorm → 输出

没有这条"电梯",Transformer 堆到 12 层以上基本就训不动了。


2.8 长上下文优化:从"只能看一页"到"看完整本书"

痛点:O(n²) 的诅咒

标准 Self-Attention 的计算量和显存都是 O(n2)O(n^2)O(n2)。序列长度从 512 涨到 128K,计算量涨了 62500 倍。

这就像你每读一个新字,都要把之前所有字重新看一遍——书越厚,越读越慢。

第一代:稀疏注意力(Longformer / BigBird)

思路:别每个词都看所有词了,只看附近的 + 几个关键的。

  • Longformer:滑动窗口(局部)+ 全局 token
  • BigBird:局部 + 全局 + 随机连接

比喻:以前每页都要跟其他所有页握手。现在只跟前后 3 页握手,再跟目录页和附录页握个手。

复杂度:O(n2)O(n^2)O(n2)O(n)O(n)O(n)

第二代:Flash Attention(1/2/3)

思路:不改变数学公式,而是优化 GPU 内存访问模式。

传统实现:把 n×nn \\times nn×n 的注意力矩阵完整写进 GPU 显存(HBM),再读出来算 softmax。来回搬运数据是瓶颈。

Flash Attention:把计算拆成小块,在 GPU 的 SRAM(超快缓存)里完成,从不把完整的 n×n 矩阵写进 HBM。

  • Flash Attention 1(2022):速度提升 2~4 倍
  • Flash Attention 2(2023):优化并行,再快 2 倍
  • Flash Attention 3(2024):利用 H100 的异步特性,接近硬件理论峰值

比喻:以前做菜要把所有食材从仓库搬到厨房,做完再搬回去。现在直接在仓库门口支个灶,现拿现炒,省了搬运时间。

第三代:Paged Attention(vLLM)

批注:PagedAttention借鉴了操作系统虚拟内存分页管理思想,将显存划分为固定大小的块(Page),通过分页表记录KV缓存的物理地址映射关系,有效解决显存碎片化问题。

问题:推理时,KV Cache 需要为每个序列预分配连续显存。序列长短不一 → 显存碎片化 → 利用率不到 60%。

解决:学操作系统的虚拟内存分页。

  • 把 KV Cache 切成固定大小的"页"(如 16 个 token 一页)
  • 用"页表"记录逻辑地址 → 物理地址的映射
  • 不同序列可以共享相同的页(比如系统提示词)

效果:显存利用率从 <60% 提升到 >90%,吞吐量提升 14~24 倍。

比喻:以前图书馆给每个读者预留一整排连续书架,有人只看 3 本书也占一排。现在把书拆成标准大小的"书箱",按需分配,不同读者还能共享同一箱参考书。

长上下文技术演进总结

阶段技术核心思想复杂度
1.0 Longformer/BigBird 稀疏化注意力模式 O(n)
2.0 Flash Attention 优化硬件内存访问 O(n²) 但常数极小
3.0 Paged Attention 分页管理 KV Cache 解决显存碎片

批注:KV缓存通过存储注意力机制中的键值对,避免重复计算历史token的注意力,从而加速推理。


本章小结:一张图看懂 Transformer 一层

输入 x

├─→ LayerNorm (RMSNorm)
│ │
│ ▼
│ Multi-Head Self-Attention (带 RoPE)
│ │
│ ▼
└──→ (+) ← 残差连接(电梯)


LayerNorm


FFN (SwiGLU, 隐藏维度 ≈ 8d/3)


(+) ← 残差连接(电梯)


输出 → 送入下一层

堆 N 层(12 / 32 / 80 / 128……),加上 Embedding 和输出头,就是一个完整的 Transformer。


下一章预告:第 3 章我们将进入"炼丹房"——预训练、指令微调、RLHF、LoRA……看看一个大模型是怎么从"白纸"变成"全能选手"的。剧透:LoRA 就是给法拉利换个尾翼,而不是重新造一辆车。


本章完。如果你读到这里还没晕,恭喜你,你已经比 80% 的"AI 从业者"更懂 Transformer 了。 🎉

赞(0)
未经允许不得转载:171主机测评 » Transformer 深度解剖——把“变形金刚“拆成零件给你看1.2
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址