L05: Attention and Transformers

Week 3 · Tue Jan 20 2026 08:00:00 GMT+0800 (中国标准时间)

进度: 0/22 (0%)
下载 PDF
/ 0
100%
正在加载 PDF...

L05: Attention and Transformers

Slides

中英交替版(推荐)

L05 双语 (PDF)

英文原版

L05 EN (PDF)

中文翻译版

L05 ZH (PDF)

核心知识点

1. RNN 的梯度消失/爆炸问题回顾

Slide 1 Slide 2 Slide 3 Slide 4 Slide 5 Slide 6 Slide 7 Slide 8 Slide 9 Slide 10 Slide 11 Slide 12 Slide 13
  • 梯度消失:J(t)h(1)\frac{\partial J^{(t)}}{\partial h^{(1)}} 涉及多次矩阵连乘,小特征值导致梯度趋零
  • 后果:远距离依赖的梯度信号丢失,模型只能学到近距离关系
  • 梯度爆炸:特征值 > 1 时梯度指数增长
    • 解决方案:Gradient Clippingg^thresholdg^g^\hat{g} \leftarrow \frac{\text{threshold}}{\|\hat{g}\|} \hat{g}
  • 根本问题:RNN 很难跨多个时间步保留信息
  • 解决思路:LSTM(记忆单元 + 门控),更根本的是注意力机制残差连接

📐 梯度连乘:完整推导

变量定义

  • h(t)h^{(t)} = 时间步 tt 的隐状态
  • WhW_h = 隐状态到隐状态的权重矩阵
  • σ\sigma = 激活函数(如 tanh)
  • z(j)=Whh(j1)+Wxx(j)z^{(j)} = W_h h^{(j-1)} + W_x x^{(j)} = 前激活值

推导过程

第 1 步:从损失 J(t)J^{(t)}h(k)h^{(k)} 的梯度,需要经过链式法则逐步回传:

J(t)h(k)=J(t)h(t)h(t)h(k)\frac{\partial J^{(t)}}{\partial h^{(k)}} = \frac{\partial J^{(t)}}{\partial h^{(t)}} \cdot \frac{\partial h^{(t)}}{\partial h^{(k)}}

第 2 步:将 h(t)h(k)\frac{\partial h^{(t)}}{\partial h^{(k)}} 展开为连乘积(每一步用链式法则):

h(t)h(k)=j=k+1th(j)h(j1)\frac{\partial h^{(t)}}{\partial h^{(k)}} = \prod_{j=k+1}^{t} \frac{\partial h^{(j)}}{\partial h^{(j-1)}}

第 3 步:计算单步 Jacobian,由 h(j)=σ(Whh(j1)+Wxx(j))h^{(j)} = \sigma(W_h h^{(j-1)} + W_x x^{(j)}) 得:

h(j)h(j1)=WhTdiag ⁣(σ(z(j)))\frac{\partial h^{(j)}}{\partial h^{(j-1)}} = W_h^T \cdot \text{diag}\!\left(\sigma'(z^{(j)})\right)

第 4 步:代入连乘积,得完整梯度公式:

h(t)h(k)=j=k+1tWhTdiag ⁣(σ(z(j)))\frac{\partial h^{(t)}}{\partial h^{(k)}} = \prod_{j=k+1}^{t} W_h^T \cdot \text{diag}\!\left(\sigma'(z^{(j)})\right)

第 5 步:奇异值分析,设 WhW_h 的最大奇异值为 λ1\lambda_1σ\sigma'[0,1][0,1] 有界:

  • λ1<1\lambda_1 < 1:乘积随 tkt - k 指数趋零 → 梯度消失

  • λ1>1\lambda_1 > 1:乘积随 tkt - k 指数爆炸 → 梯度爆炸

Gradient Clipping 算法

g^{thresholdg^g^若 g^>thresholdg^否则\hat{g} \leftarrow \begin{cases} \dfrac{\text{threshold}}{\|\hat{g}\|} \hat{g} & \text{若 } \|\hat{g}\| > \text{threshold} \\ \hat{g} & \text{否则} \end{cases}

直觉:将梯度向量缩放到固定长度以内,保持方向不变,只压缩幅度。

📚 已收录至 拓展阅读知识库

🔢 数值计算示例

设定:标量情形,WhW_h 为标量,σ=1\sigma' = 1(线性激活),t=10t=10k=0k=0

场景WhW_h梯度幅度 =Wh10= W_h^{10}
梯度消失0.50.50.5100.0010.5^{10} \approx 0.001
正常传播1.01.01.010=1.0001.0^{10} = 1.000
梯度爆炸2.02.0210=10242^{10} = 1024

计算(消失示例):

  1. 每步 × 0.50.510.50.251 \to 0.5 \to 0.25 \to \cdots
  2. 10 步后:0.510=2100.000980.5^{10} = 2^{-10} \approx 0.00098
  3. 若学习率为 0.01,实际更新量 9.8×106\approx 9.8 \times 10^{-6},几乎为零

Clipping 示例:若 g^=[3,4]\hat{g} = [3, 4]g^=5\|\hat{g}\| = 5),threshold = 1:

g^clipped=15[3,4]=[0.6,0.8]\hat{g}_\text{clipped} = \frac{1}{5} [3, 4] = [0.6, 0.8]

💡 为什么这样做?

想象一根绳子传递力——每次传递都衰减一半,10 步之后力气几乎为零(梯度消失)。反过来,每次加倍,10 步后力气大到绳子断掉(梯度爆炸)。

Gradient Clipping 就像给绳子加一个限力器:无论力有多大,传出去的力不超过设定值。它只解决爆炸,不解决消失。

RNN 梯度问题的根本解法:

  • LSTM/GRU:加法路径(cell state)让梯度可以”直通”多步
  • Residual connections:加法路径同理
  • Attention:彻底绕过顺序传递,直接建立任意两步的连接

⚠️ 常见误区

  1. 误区:Gradient Clipping 能防止梯度消失 → 正确:Clipping 只防止爆炸(缩小幅度),对消失问题无效;消失需要 LSTM 或注意力机制
  2. 误区:LSTM 完全解决了梯度消失 → 正确:LSTM 缓解但不消除,超长距离(>1000 步)依然困难
  3. 误区:梯度消失只影响最远的时间步 → 正确:每一步都会受到影响,只是距离越远越严重

2. 机器翻译与 Seq2Seq

Slide 14 Slide 15 Slide 16 Slide 17 Slide 18 Slide 19 Slide 20
  • NMT 的突破:2014 年首篇 seq2seq 论文 \to 2016 年 Google Translate 全面转向 NMT
  • Encoder-Decoder 模型:
    • Encoder RNN:编码源句子为一个上下文向量
    • Decoder RNN:条件语言模型,生成目标句子
  • 条件语言模型:P(yx)=tP(yty1,,yt1,x)P(y|x) = \prod_t P(y_t | y_1, \ldots, y_{t-1}, x)
  • 端到端训练:Encoder + Decoder 作为整体系统,反向传播一步到位
  • 瓶颈问题:整个源句信息被压缩到单一上下文向量

📐 条件语言模型:完整推导

变量定义

  • x=(x1,,xm)x = (x_1, \ldots, x_m) = 源句子(长度 mm
  • y=(y1,,yT)y = (y_1, \ldots, y_T) = 目标句子(长度 TT
  • cc = 上下文向量(encoder 最终隐状态)
  • s(t)s^{(t)} = decoder 在时间步 tt 的隐状态

推导过程

第 1 步:目标是对 P(yx)P(y|x) 建模,用概率链式法则分解联合概率:

P(yx)=P(y1,y2,,yTx)=t=1TP(yty1,,yt1,x)P(y|x) = P(y_1, y_2, \ldots, y_T | x) = \prod_{t=1}^{T} P(y_t | y_1, \ldots, y_{t-1}, x)

第 2 步:Encoder 将 xx 压缩为固定向量 cc(Encoder RNN 最后一步隐状态):

c=henc(m)=fenc(x1,,xm)c = h^{(m)}_\text{enc} = f_\text{enc}(x_1, \ldots, x_m)

第 3 步:Decoder 在每一步利用 cc 和之前生成的词:

s(t)=fdec(s(t1),yt1,c)s^{(t)} = f_\text{dec}(s^{(t-1)}, y_{t-1}, c)

P(yty<t,x)=softmax(Wos(t))[yt-index]P(y_t | y_{<t}, x) = \text{softmax}(W_o s^{(t)}) \big[y_t\text{-index}\big]

第 4 步:训练目标——最大化对数似然(对训练集上每个 (x,y)(x, y) 对求和):

L=(x,y)DlogP(yx)=(x,y)Dt=1TlogP(yty<t,x)\mathcal{L} = \sum_{(x,y) \in \mathcal{D}} \log P(y|x) = \sum_{(x,y) \in \mathcal{D}} \sum_{t=1}^{T} \log P(y_t | y_{<t}, x)

第 5 步:推断时用贪心解码或 Beam Search 寻找最高概率序列:

y^=argmaxyP(yx)\hat{y} = \arg\max_{y} P(y|x)

📚 已收录至 拓展阅读知识库

🔢 数值计算示例

设定:源句 “Ich liebe NLP”(3 词),目标句 “I love NLP”(3 词),词表大小 V=5V=5

联合概率分解

P("I love NLP""Ich liebe NLP")=P(I<start>,x)P(loveI,x)P(NLPI love,x)P(\text{"I love NLP"} | \text{"Ich liebe NLP"}) = P(\text{I}|\text{<start>}, x) \cdot P(\text{love}|\text{I}, x) \cdot P(\text{NLP}|\text{I love}, x)

假设各步概率

时间步生成词条件概率
t=1t=1”I"P(y1=I<start>,x)=0.7P(y_1=\text{I} \| \text{<start>}, x) = 0.7
t=2t=2"love"P(y2=loveI,x)=0.6P(y_2=\text{love} \| \text{I}, x) = 0.6
t=3t=3"NLP”P(y3=NLPI love,x)=0.8P(y_3=\text{NLP} \| \text{I love}, x) = 0.8

联合概率

P(yx)=0.7×0.6×0.8=0.336P(y|x) = 0.7 \times 0.6 \times 0.8 = 0.336

对数似然

logP(yx)=log0.7+log0.6+log0.80.357+(0.511)+(0.223)=1.091\log P(y|x) = \log 0.7 + \log 0.6 + \log 0.8 \approx -0.357 + (-0.511) + (-0.223) = -1.091

💡 为什么这样做?

Seq2Seq 本质上是”条件版语言模型”——普通语言模型问的是”这句话自然不自然”,Seq2Seq 问的是”给定源句子,什么是最好的翻译”。

Encoder 相当于一个”理解员”,把源句子的所有信息提炼成一份摘要(上下文向量 cc)。Decoder 相当于”写作员”,拿着这份摘要一个词一个词地翻译出来。

瓶颈在哪:摘要只有固定大小(比如 512 维向量),但源句子可以有 100 个词甚至 1000 个词。就像让你用一句话概括整本书——越长的书,信息损失越多。这就是注意力机制要解决的问题。

⚠️ 常见误区

  1. 误区:Seq2Seq 的 encoder 和 decoder 必须是同一种 RNN → 正确:可以是不同架构(甚至不同维度),只要上下文向量维度匹配即可
  2. 误区:条件概率链式分解是 Seq2Seq 特有的 → 正确:这是所有自回归模型的通用分解,GPT 也用同样公式(只是没有条件 xx
  3. 误区:瓶颈问题可以用更大的上下文向量解决 → 正确:固定大小的向量无法随序列长度线性扩展,根本解法是注意力(直接访问所有 encoder 隐状态)

3. 从 RNN 到注意力(Attention)

Slide 21 Slide 22 Slide 23 Slide 24 Slide 25 Slide 26 Slide 27 Slide 28 Slide 29 Slide 30 Slide 31 Slide 32 Slide 33 Slide 34 Slide 35 Slide 36 Slide 37 Slide 38 Slide 39
  • 注意力机制的动机:解决 seq2seq 的信息瓶颈
  • 核心思想:在每个解码步,允许 decoder 直接”看到”所有 encoder 隐状态
  • 注意力计算步骤:
    • (1) 计算注意力分数:ei=sThie_i = s^T h_i(decoder 隐状态 ss 与 encoder 隐状态 hih_i 的点积)
    • (2) 归一化:α=softmax(e)Rn\alpha = \text{softmax}(e) \in \mathbb{R}^n(注意力权重/分布)
    • (3) 加权求和:a=iαihia = \sum_i \alpha_i h_i(注意力输出/上下文向量)
  • 注意力变体:
    • 点积注意力:ei=sThie_i = s^T h_i
    • 缩放点积注意力:ei=sThidke_i = \frac{s^T h_i}{\sqrt{d_k}}
    • 加性注意力:ei=vTtanh(W1hi+W2s)e_i = v^T \tanh(W_1 h_i + W_2 s)

📐 三步注意力计算:完整推导

变量定义

  • stRds_t \in \mathbb{R}^d = decoder 在时间步 tt 的隐状态(Query)
  • hiRdh_i \in \mathbb{R}^d = encoder 第 ii 个位置的隐状态(Key/Value)
  • H=[h1,,hn]Rd×nH = [h_1, \ldots, h_n] \in \mathbb{R}^{d \times n} = 所有 encoder 隐状态
  • eiRe_i \in \mathbb{R} = 第 ii 个位置的注意力分数(标量)
  • αRn\alpha \in \mathbb{R}^n = 注意力权重向量(概率分布)
  • atRda_t \in \mathbb{R}^d = 注意力输出(加权上下文向量)

推导过程

第 1 步:计算注意力分数(三种等价变体)

点积注意力(Luong et al., 2015):

ei=stThie_i = s_t^T h_i

缩放点积注意力(Vaswani et al., 2017):

ei=stThide_i = \frac{s_t^T h_i}{\sqrt{d}}

缩放原因:stThis_t^T h_i 的期望方差为 dd(若 st,his_t, h_i 各分量 i.i.d. 均值0方差1),d\sqrt{d} 缩放将方差归一化为1。

加性注意力(Bahdanau et al., 2015):

ei=vTtanh(W1hi+W2st),vRda,W1,W2Rda×de_i = v^T \tanh(W_1 h_i + W_2 s_t), \quad v \in \mathbb{R}^{d_a}, W_1, W_2 \in \mathbb{R}^{d_a \times d}

参数 v,W1,W2v, W_1, W_2 通过反向传播学习,表达能力更强但参数更多。

第 2 步:Softmax 归一化

nn 个原始分数归一化为概率分布:

αi=exp(ei)j=1nexp(ej),αRn,i=1nαi=1,αi0\alpha_i = \frac{\exp(e_i)}{\sum_{j=1}^{n} \exp(e_j)}, \quad \alpha \in \mathbb{R}^n, \quad \sum_{i=1}^{n} \alpha_i = 1, \quad \alpha_i \geq 0

矩阵形式:α=softmax(e)\alpha = \text{softmax}(e)

第 3 步:加权求和得上下文向量

at=i=1nαihi=HαRda_t = \sum_{i=1}^{n} \alpha_i h_i = H \alpha \in \mathbb{R}^d

最终将 ata_tsts_t 拼接,送入输出层:s~t=tanh(Wc[at;st])\tilde{s}_t = \tanh(W_c [a_t; s_t]),用于预测 yty_t

📚 已收录至 拓展阅读知识库

🔢 数值计算示例

设定d=2d=2,encoder 3 个位置,decoder 当前隐状态 s=[0.8,0.2]s = [0.8, 0.2]

变量
h1h_1[1.0,0.0][1.0, 0.0]
h2h_2[0.0,1.0][0.0, 1.0]
h3h_3[0.5,0.5][0.5, 0.5]
ss[0.8,0.2][0.8, 0.2]

计算(点积注意力):

  1. 注意力分数:

    • e1=sTh1=0.8×1.0+0.2×0.0=0.8e_1 = s^T h_1 = 0.8 \times 1.0 + 0.2 \times 0.0 = 0.8
    • e2=sTh2=0.8×0.0+0.2×1.0=0.2e_2 = s^T h_2 = 0.8 \times 0.0 + 0.2 \times 1.0 = 0.2
    • e3=sTh3=0.8×0.5+0.2×0.5=0.5e_3 = s^T h_3 = 0.8 \times 0.5 + 0.2 \times 0.5 = 0.5
  2. Softmax(e=[0.8,0.2,0.5]e = [0.8, 0.2, 0.5]):

    • exp(e)=[2.226,1.221,1.649]\exp(e) = [2.226, 1.221, 1.649]=5.096\sum = 5.096
    • α=[0.437,0.239,0.324]\alpha = [0.437, 0.239, 0.324]
  3. 加权求和:

a=0.437×[1,0]+0.239×[0,1]+0.324×[0.5,0.5]=[0.599,0.401]a = 0.437 \times [1,0] + 0.239 \times [0,1] + 0.324 \times [0.5, 0.5] = [0.599, 0.401]

结论:decoder 最关注 h1h_1(43.7%),因为 ss 在第一维较大,与 h1h_1 对齐。

💡 为什么这样做?

注意力 = 软搜索(soft search)

传统信息检索是硬搜索:输入查询词,精确匹配,返回结果。注意力是软版本:给每个 encoder 位置分配”相关性权重”,用加权平均把所有位置的信息混合起来。

为什么用加权平均而不是”找最相关的那个”?因为翻译一个词往往对应源句多个词的组合,权重让模型学会”分配注意力”而不是强制选一个。

三种分数变体的权衡:

  • 点积:最简单,无额外参数
  • 缩放点积:高维时更稳定(防止 softmax 饱和)
  • 加性:最灵活,有额外参数捕捉更复杂的对应关系

⚠️ 常见误区

  1. 误区:注意力权重 α\alpha 是独热(one-hot)的,每次只关注一个位置 → 正确α\alpha 是连续概率分布,多个位置可以同时被关注(这正是”软”的含义)
  2. 误区:只有一种注意力分数计算方式 → 正确:点积/缩放点积/加性等都是合法选项,没有绝对的”最好”;Transformer 用缩放点积,BERT 之前的 NMT 常用加性
  3. 误区:注意力向量 ata_t 直接就是输出 → 正确ata_t 通常需要与 sts_t 拼接后再经过线性层才能预测 yty_t

4. 自注意力(Self-Attention)

Slide 40 Slide 41 Slide 42 Slide 43 Slide 44 Slide 45 Slide 46 Slide 47 Slide 48 Slide 49 Slide 50 Slide 51 Slide 52
  • 关键创新:注意力不仅用于 encoder-decoder 之间,序列内部也可以互相注意
  • Query-Key-Value 框架:
    • 每个位置 ii 生成三个向量:qi=WQxiq_i = W^Q x_iki=WKxik_i = W^K x_ivi=WVxiv_i = W^V x_i
    • 注意力分数:eij=qiTkje_{ij} = q_i^T k_j
    • 输出:outputi=jαijvj\text{output}_i = \sum_j \alpha_{ij} v_j
  • 矩阵形式:
    • Attention(Q,K,V)=softmax(QKTdk)V\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right) V
  • 缩放因子 dk\sqrt{d_k} 的作用:防止点积值过大导致 softmax 梯度过小
  • 优点:
    • 每个位置可以直接关注任何其他位置(O(1)O(1) 的路径长度 vs RNN 的 O(n)O(n)
    • 全部位置可以并行计算(vs RNN 的顺序计算)
  • 缺点:计算复杂度 O(n2d)O(n^2 d),对长序列代价高

📐 Attention(Q, K, V):完整推导

变量定义

  • XRn×dmodelX \in \mathbb{R}^{n \times d_\text{model}} = 输入矩阵(序列长度 nn,每个位置 dmodeld_\text{model} 维)
  • WQRdmodel×dkW^Q \in \mathbb{R}^{d_\text{model} \times d_k} = Query 投影矩阵
  • WKRdmodel×dkW^K \in \mathbb{R}^{d_\text{model} \times d_k} = Key 投影矩阵
  • WVRdmodel×dvW^V \in \mathbb{R}^{d_\text{model} \times d_v} = Value 投影矩阵
  • Q=XWQRn×dkQ = X W^Q \in \mathbb{R}^{n \times d_k}K=XWKRn×dkK = X W^K \in \mathbb{R}^{n \times d_k}V=XWVRn×dvV = X W^V \in \mathbb{R}^{n \times d_v}

推导过程

第 1 步:线性投影

每个输入向量 xiRdmodelx_i \in \mathbb{R}^{d_\text{model}} 通过三个独立线性变换得到 Q/K/V:

qi=xiWQ,ki=xiWK,vi=xiWVq_i = x_i W^Q, \quad k_i = x_i W^K, \quad v_i = x_i W^V

矩阵形式同时处理所有位置:Q=XWQQ = XW^QK=XWKK = XW^KV=XWVV = XW^V

第 2 步:计算相似度矩阵

计算所有 Query 与所有 Key 的点积,得到 n×nn \times n 注意力分数矩阵:

E=QKTRn×n,Eij=qiTkjE = QK^T \in \mathbb{R}^{n \times n}, \quad E_{ij} = q_i^T k_j

EijE_{ij} 表示位置 ii 对位置 jj 的原始注意力分数。

第 3 步:缩放(关键步骤)

为什么需要除以 dk\sqrt{d_k}

qi,kjq_i, k_j 的各分量 i.i.d.,均值 0,方差 1,则:

Var(qiTkj)=Var ⁣(l=1dkqilkjl)=l=1dkVar(qil)Var(kjl)=dk\text{Var}(q_i^T k_j) = \text{Var}\!\left(\sum_{l=1}^{d_k} q_{il} k_{jl}\right) = \sum_{l=1}^{d_k} \text{Var}(q_{il}) \cdot \text{Var}(k_{jl}) = d_k

所以 qiTkjq_i^T k_j 的标准差为 dk\sqrt{d_k}。不缩放时,dkd_k 较大(如 64)的分数会使 softmax 饱和在接近独热分布的区域,梯度近乎为零。缩放后方差归一化为 1:

E~=QKTdk\tilde{E} = \frac{QK^T}{\sqrt{d_k}}

第 4 步:Softmax 按行归一化

A=softmax ⁣(QKTdk)Rn×nA = \text{softmax}\!\left(\frac{QK^T}{\sqrt{d_k}}\right) \in \mathbb{R}^{n \times n}

按行归一化:Aij=exp(E~ij)l=1nexp(E~il)A_{ij} = \dfrac{\exp(\tilde{E}_{ij})}{\sum_{l=1}^{n} \exp(\tilde{E}_{il})},每行之和为 1。

AijA_{ij} 是位置 ii 分配给位置 jj 的注意力权重。

第 5 步:加权求和 Value 得输出

O=AVRn×dv,Oi=j=1nAijvjO = AV \in \mathbb{R}^{n \times d_v}, \quad O_i = \sum_{j=1}^{n} A_{ij} v_j

位置 ii 的输出是所有位置 Value 向量按注意力权重的加权平均。

完整公式

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

形状追踪(务必熟练):

矩阵形状说明
QQ(n×dk)(n \times d_k)
KTK^T(dk×n)(d_k \times n)
QKTQK^T(n×n)(n \times n)注意力矩阵,与序列长度平方成正比
A=softmax()A = \text{softmax}(\cdot)(n×n)(n \times n)行归一化概率矩阵
VV(n×dv)(n \times d_v)
O=AVO = AV(n×dv)(n \times d_v)最终输出

计算复杂度

  • QKTQK^T(n×dk)(dk×n)O(n2dk)(n \times d_k) \cdot (d_k \times n) \Rightarrow O(n^2 d_k)
  • AVAV(n×n)(n×dv)O(n2dv)(n \times n) \cdot (n \times d_v) \Rightarrow O(n^2 d_v)
  • 总:O(n2d)O(n^2 d)n2n^2 是瓶颈)

📚 已收录至 拓展阅读知识库

🔢 数值计算示例

设定n=3n=3dmodel=4d_\text{model}=4dk=dv=2d_k=d_v=2

输入矩阵 XX

X=[101001011100]X = \begin{bmatrix} 1 & 0 & 1 & 0 \\ 0 & 1 & 0 & 1 \\ 1 & 1 & 0 & 0 \end{bmatrix}

投影矩阵(为简化取前两维):

WQ=WK=WV=[10010000]W^Q = W^K = W^V = \begin{bmatrix} 1 & 0 \\ 0 & 1 \\ 0 & 0 \\ 0 & 0 \end{bmatrix}

第 1 步:计算 Q,K,V=XWQ, K, V = XW(取输入前两维):

Q=K=V=[100111]Q = K = V = \begin{bmatrix} 1 & 0 \\ 0 & 1 \\ 1 & 1 \end{bmatrix}

第 2 步:计算 E=QKTE = QK^T

E=[100111][101011]=[101011112]E = \begin{bmatrix} 1&0\\0&1\\1&1 \end{bmatrix} \begin{bmatrix} 1&0&1\\0&1&1 \end{bmatrix} = \begin{bmatrix} 1&0&1\\0&1&1\\1&1&2 \end{bmatrix}

第 3 步:缩放 E~=E/2E/1.414\tilde{E} = E / \sqrt{2} \approx E / 1.414

E~[0.70700.70700.7070.7070.7070.7071.414]\tilde{E} \approx \begin{bmatrix} 0.707 & 0 & 0.707 \\ 0 & 0.707 & 0.707 \\ 0.707 & 0.707 & 1.414 \end{bmatrix}

第 4 步:按行 softmax(取第 3 行为例,[0.707,0.707,1.414][0.707, 0.707, 1.414]):

  • exp([0.707,0.707,1.414])=[2.028,2.028,4.113]\exp([0.707, 0.707, 1.414]) = [2.028, 2.028, 4.113]=8.169\sum = 8.169
  • A3[0.248,0.248,0.503]A_3 \approx [0.248, 0.248, 0.503](第 3 个词最关注自身)

第 5 步O=AVO = AV(第 3 行输出):

O3=0.248×[1,0]+0.248×[0,1]+0.503×[1,1][0.751,0.751]O_3 = 0.248 \times [1,0] + 0.248 \times [0,1] + 0.503 \times [1,1] \approx [0.751, 0.751]

结论:词 3(“1,1” 特征)主要关注自身(50.3%),并均等关注词 1 和词 2。

💡 为什么这样做?

自注意力 = “让序列中每个词问问自己与其他所有词的关系”

  • Queryqiq_i):“我在找什么类型的信息?”
  • Keykjk_j):“我能提供什么类型的信息?”
  • Valuevjv_j):“我实际携带的内容是什么?”

qiTkjq_i^T k_j 衡量”位置 ii 的信息需求”与”位置 jj 的信息供给”的匹配程度。匹配越高,注意力越大,从 vjv_j 取的信息越多。

类比搜索引擎:Query 是搜索词,Key 是页面关键词,Value 是页面内容。注意力分数决定哪些页面排前,输出是加权后的搜索结果。

与 encoder-decoder 注意力的区别:自注意力的 Q、K、V 都来自同一序列(“自”的含义),而 encoder-decoder 注意力的 Q 来自 decoder,K/V 来自 encoder。

⚠️ 常见误区

  1. 误区:自注意力天然知道位置信息 → 正确:自注意力完全没有位置概念——“I love you” 和 “you love I” 的自注意力输出完全相同(排列不变性)。这就是为什么需要额外注入位置编码

  2. 误区1/dk1/\sqrt{d_k} 可以省略 → 正确dkd_k 越大,qTkq^Tk 的方差越大,softmax 越接近独热,梯度越接近零。Vaswani et al. 实验表明:去掉缩放后 dk=64d_k=64 时模型性能显著下降。

  3. 误区QKTQK^T 的形状是 (dk×dk)(d_k \times d_k)正确QKTQK^T 的形状是 (n×n)(n \times n)(序列长度的平方),不是 (dk×dk)(d_k \times d_k)。这是长序列计算代价高的根本原因。

  4. 误区WQ,WK,WVW^Q, W^K, W^V 是方阵(dmodel×dmodeld_\text{model} \times d_\text{model})→ 正确:它们的输出维度 dkd_k 可以与 dmodeld_\text{model} 不同(多头注意力中通常 dk=dmodel/hd_k = d_\text{model} / h)。

5. 多头注意力(Multi-Head Attention)

Slide 53 Slide 54 Slide 55 Slide 56 Slide 57 Slide 58
  • 动机:不同的”头”可以关注不同类型的信息(句法、语义、位置等)
  • MultiHead(Q,K,V)=Concat(head1,,headh)WO\text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, \ldots, \text{head}_h) W^O
  • headi=Attention(QWiQ,KWiK,VWiV)\text{head}_i = \text{Attention}(Q W_i^Q, K W_i^K, V W_i^V)
  • 每个头的维度 dk=dmodel/hd_k = d_{model} / h,总计算量与单头相近

📐 Multi-Head Attention:完整推导

变量定义

  • hh = 注意力头数(Transformer base 中 h=8h=8
  • dmodeld_\text{model} = 模型维度(Transformer base 中 dmodel=512d_\text{model}=512
  • dk=dv=dmodel/hd_k = d_v = d_\text{model} / h = 每个头的维度(base 中 dk=64d_k=64
  • WiQRdmodel×dkW_i^Q \in \mathbb{R}^{d_\text{model} \times d_k}WiKRdmodel×dkW_i^K \in \mathbb{R}^{d_\text{model} \times d_k}WiVRdmodel×dvW_i^V \in \mathbb{R}^{d_\text{model} \times d_v} = 第 ii 个头的投影矩阵
  • WORhdv×dmodelW^O \in \mathbb{R}^{h d_v \times d_\text{model}} = 输出投影矩阵

推导过程

第 1 步:每个头独立计算注意力

ii 个头将输入投影到低维子空间后计算注意力:

headi=Attention(QWiQ,  KWiK,  VWiV)Rn×dv\text{head}_i = \text{Attention}(Q W_i^Q,\; K W_i^K,\; V W_i^V) \in \mathbb{R}^{n \times d_v}

每个头有自己独立的 WiQ,WiK,WiVW_i^Q, W_i^K, W_i^V——这是关键,让每个头可以”专注”不同方面。

第 2 步:拼接所有头的输出

沿最后维度拼接 hh 个头的输出:

Concat(head1,,headh)Rn×(hdv)=Rn×dmodel\text{Concat}(\text{head}_1, \ldots, \text{head}_h) \in \mathbb{R}^{n \times (h \cdot d_v)} = \mathbb{R}^{n \times d_\text{model}}

(因为 hdv=h(dmodel/h)=dmodelh \cdot d_v = h \cdot (d_\text{model}/h) = d_\text{model}

第 3 步:输出投影

WOW^O 将拼接结果投影回 dmodeld_\text{model} 维,融合来自不同头的信息:

MultiHead(Q,K,V)=Concat(head1,,headh)WORn×dmodel\text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, \ldots, \text{head}_h) W^O \in \mathbb{R}^{n \times d_\text{model}}

参数量分析(每个 MultiHead 层):

  • hh 个头的 WiQW_i^Qh×dmodel×dk=dmodel2h \times d_\text{model} \times d_k = d_\text{model}^2(因为 hdk=dmodelh \cdot d_k = d_\text{model}
  • 同理 WiKW_i^KWiVW_i^V:各 dmodel2d_\text{model}^2
  • WOW^Ohdv×dmodel=dmodel2h d_v \times d_\text{model} = d_\text{model}^2
  • 总参数量4dmodel24 d_\text{model}^2(与单头完全相同!)

计算量分析hh 个头,每个头维度 dk=dmodel/hd_k = d_\text{model}/h,计算量 h×O(n2dk)=O(n2dmodel)\approx h \times O(n^2 d_k) = O(n^2 d_\text{model})(与单头相同量级)。

📚 已收录至 拓展阅读知识库

🔢 数值计算示例

设定dmodel=8d_\text{model}=8h=2h=2n=3n=3dk=dv=4d_k=d_v=4

参数
dmodeld_\text{model}8
hh(头数)2
dk=dvd_k = d_v8/2=48/2 = 4
每个 WiQW_i^Q 形状(8×4)(8 \times 4)
WOW^O 形状(8×8)(8 \times 8)

Head 1 投影到前 4 维方向 → 假设捕捉句法关系(如主谓一致):

  • QW1QQW_1^Q:形状 (3×4)(3 \times 4),注意力输出 head1_1(3×4)(3 \times 4)

Head 2 投影到后 4 维方向 → 假设捕捉语义关系(如共指):

  • QW2QQW_2^Q:形状 (3×4)(3 \times 4),注意力输出 head2_2(3×4)(3 \times 4)

拼接Concat(head1,head2)\text{Concat}(\text{head}_1, \text{head}_2)(3×8)(3 \times 8)

输出投影:乘以 WO(8×8)W^O (8 \times 8),最终输出 (3×8)(3 \times 8)

参数量验证

  • 2个头的 WQW^Q2×8×4=64=822 \times 8 \times 4 = 64 = 8^2
  • 同理 WK,WVW^K, W^V:各 64
  • WOW^O8×8=648 \times 8 = 64
  • 总:64×4=256=4×8264 \times 4 = 256 = 4 \times 8^2 ✓(与单头参数量相同)

💡 为什么这样做?

多头注意力 = 多个视角同时观察

单头注意力只能学到一种”什么和什么相关”的模式。多头允许模型同时问不同的问题:

  • Head 1:“这个词的主语是谁?“(句法依存)
  • Head 2:“这个代词指代什么?“(共指消解)
  • Head 3:“这个动词的宾语是什么?“(论元结构)

每个头在 dkd_k 维的子空间内独立运算,互不干扰。最后用 WOW^O 把所有头的发现”融合”成一个综合判断。

为什么不用 hh 个独立的全维度注意力?计算量会变成 hh 倍,而多头通过降维保持总计算量不变,兼顾效率和表达力。

⚠️ 常见误区

  1. 误区:多头注意力的计算量是单头的 hh 倍 → 正确:每个头维度是 dmodel/hd_\text{model}/h,总计算量 h×O(n2dmodel/h)=O(n2dmodel)\approx h \times O(n^2 \cdot d_\text{model}/h) = O(n^2 d_\text{model}),与单头相同量级

  2. 误区:最后的 WOW^O 只是”接口变换”,可以省略 → 正确WOW^O 是关键的信息融合矩阵,它让模型学习如何组合来自不同头的信息;省略后不同头的信息只是简单拼接,无法有效交互

  3. 误区:每个头一定学到了不同的语言学特征 → 正确:这是直觉上的解释,实践中头的分工不总是那么清晰;某些头可能学到相似的模式,也有研究显示许多头可以被剪枝

6. Transformer 架构(Vaswani et al., 2017)

Slide 59 Slide 60 Slide 61 Slide 62 Slide 63 Slide 64
  • “Attention Is All You Need” — 完全去除 RNN,只用注意力
  • Transformer Decoder(GPT 类)
    • 每个 Block:Masked Multi-Head Self-Attention \to Add & Norm \to FFN \to Add & Norm
    • Masked:防止位置 ii 看到未来位置 j>ij > i(因果掩码)
  • Transformer Encoder(BERT 类)
    • 与 Decoder 相同结构,但去掉 masking(双向上下文)
  • Transformer Encoder-Decoder(T5 类)
    • Encoder:双向注意力处理源序列
    • Decoder:因果掩码自注意力 + 交叉注意力(Cross-Attention)
      • Keys/Values 来自 Encoder 输出,Queries 来自 Decoder
  • 关键组件:
    • 位置编码(Positional Encoding):自注意力本身没有位置概念,需要显式注入
      • 正弦位置编码:PE(pos,2i)=sin(pos/100002i/d)PE_{(pos, 2i)} = \sin(pos / 10000^{2i/d})
      • 可学习位置嵌入(learned positional embeddings)
      • RoPE(Rotary Position Embedding,Su et al., 2021)
      • DeRoPE(Xiong et al., 2026)
    • 残差连接(Residual Connections)output=x+SubLayer(x)\text{output} = x + \text{SubLayer}(x)
    • 层归一化(Layer Normalization)
    • 前馈网络(FFN)FFN(x)=W2ReLU(W1x+b1)+b2\text{FFN}(x) = W_2 \cdot \text{ReLU}(W_1 x + b_1) + b_2

📐 Transformer 核心组件:完整推导

一、正弦位置编码

变量定义

  • pospos = 序列中位置(0,1,,n10, 1, \ldots, n-1
  • ii = 编码向量的维度索引(0,1,,dmodel/210, 1, \ldots, d_\text{model}/2 - 1
  • dmodeld_\text{model} = 模型维度

公式

PE(pos,2i)=sin ⁣(pos100002i/dmodel),PE(pos,2i+1)=cos ⁣(pos100002i/dmodel)PE_{(pos,\, 2i)} = \sin\!\left(\frac{pos}{10000^{2i/d_\text{model}}}\right), \quad PE_{(pos,\, 2i+1)} = \cos\!\left(\frac{pos}{10000^{2i/d_\text{model}}}\right)

为什么用正弦/余弦?三个关键性质

性质 1:每个位置有唯一编码——不同 pospos 的编码向量两两不同。

性质 2:可以用线性变换表示相对位置偏移。用三角恒等式展开:

sin(A+B)=sinAcosB+cosAsinB\sin(A + B) = \sin A \cos B + \cos A \sin B

cos(A+B)=cosAcosBsinAsinB\cos(A + B) = \cos A \cos B - \sin A \sin B

ωi=1/100002i/dmodel\omega_i = 1/10000^{2i/d_\text{model}},则 PEpos+kPE_{pos+k} 可由 PEposPE_{pos} 线性表示:

[PE(pos+k,2i)PE(pos+k,2i+1)]=[cos(kωi)sin(kωi)sin(kωi)cos(kωi)][PE(pos,2i)PE(pos,2i+1)]\begin{bmatrix} PE_{(pos+k, 2i)} \\ PE_{(pos+k, 2i+1)} \end{bmatrix} = \begin{bmatrix} \cos(k\omega_i) & \sin(k\omega_i) \\ -\sin(k\omega_i) & \cos(k\omega_i) \end{bmatrix} \begin{bmatrix} PE_{(pos, 2i)} \\ PE_{(pos, 2i+1)} \end{bmatrix}

旋转矩阵只依赖偏移 kk,不依赖绝对位置 pospos——这意味着模型可以学习”相对偏移为 kk 的词之间的关系”,而不受绝对位置影响。

性质 3:低频分量(大 ii,小 ωi\omega_i)变化慢,捕捉长距离结构;高频分量(小 ii,大 ωi\omega_i)变化快,捕捉局部精细位置。

二、前馈网络(FFN)

FFN(x)=W2ReLU(W1x+b1)+b2\text{FFN}(x) = W_2 \cdot \text{ReLU}(W_1 x + b_1) + b_2

  • W1Rdff×dmodelW_1 \in \mathbb{R}^{d_{ff} \times d_\text{model}}W2Rdmodel×dffW_2 \in \mathbb{R}^{d_\text{model} \times d_{ff}}dff=4dmodeld_{ff} = 4 d_\text{model}(先扩展 4 倍再压缩)
  • 作用:在注意力聚合信息后,对每个位置独立做非线性变换
  • 参数量:2×dmodel×dff=8dmodel22 \times d_\text{model} \times d_{ff} = 8 d_\text{model}^2(约占 Transformer 总参数 2/3)

三、残差连接 + Layer Normalization(Post-LN)

output=LayerNorm(x+SubLayer(x))\text{output} = \text{LayerNorm}(x + \text{SubLayer}(x))

残差连接的梯度传播:设 y=x+f(x)y = x + f(x),则:

Lx=Lyyx=Ly(1+fx)\frac{\partial \mathcal{L}}{\partial x} = \frac{\partial \mathcal{L}}{\partial y} \cdot \frac{\partial y}{\partial x} = \frac{\partial \mathcal{L}}{\partial y}\left(1 + \frac{\partial f}{\partial x}\right)

梯度中有 “+1” 项,即使 f/x\partial f/\partial x 很小(子层几乎不学习),梯度仍然能通过 “+1” 路径直接传到更早的层,避免梯度消失。

Layer Normalization

LayerNorm(x)=xμσ+ϵγ+β\text{LayerNorm}(x) = \frac{x - \mu}{\sigma + \epsilon} \cdot \gamma + \beta

其中 μ,σ\mu, \sigma 是在特征维度上计算的(不同于 BatchNorm 在 batch 维度上计算)。

Pre-LN vs Post-LN

  • Post-LN(原始 Transformer):LayerNorm(x+SubLayer(x))\text{LayerNorm}(x + \text{SubLayer}(x))
  • Pre-LN(现代 LLM 标准):x+SubLayer(LayerNorm(x))x + \text{SubLayer}(\text{LayerNorm}(x))
  • Pre-LN 训练更稳定(梯度直接通过残差路径流动,不经过 LayerNorm),现代 LLM(GPT-2 之后)几乎全部采用 Pre-LN。

📚 已收录至 拓展阅读知识库

🔢 数值计算示例

位置编码计算dmodel=4d_\text{model}=4,计算位置 pos=0pos=0pos=1pos=1 的编码向量

ωi=1/100002i/4\omega_i = 1/10000^{2i/4}

  • i=0i=0ω0=1/100000=1.000\omega_0 = 1/10000^0 = 1.000
  • i=1i=1ω1=1/100000.5=0.01\omega_1 = 1/10000^{0.5} = 0.01
posposPE(pos,0)=sin(posω0)PE_{(pos,0)}=\sin(pos \cdot \omega_0)PE(pos,1)=cos(posω0)PE_{(pos,1)}=\cos(pos \cdot \omega_0)PE(pos,2)=sin(posω1)PE_{(pos,2)}=\sin(pos \cdot \omega_1)PE(pos,3)=cos(posω1)PE_{(pos,3)}=\cos(pos \cdot \omega_1)
0sin(0)=0\sin(0)=0cos(0)=1\cos(0)=1sin(0)=0\sin(0)=0cos(0)=1\cos(0)=1
1sin(1)0.841\sin(1)\approx 0.841cos(1)0.540\cos(1)\approx 0.540sin(0.01)0.01\sin(0.01)\approx 0.01cos(0.01)1.000\cos(0.01)\approx 1.000
2sin(2)0.909\sin(2)\approx 0.909cos(2)0.416\cos(2)\approx -0.416sin(0.02)0.02\sin(0.02)\approx 0.02cos(0.02)1.000\cos(0.02)\approx 1.000

观察

  • 高频维度(i=0i=0):相邻位置差异大(00.8410 \to 0.841),分辨局部位置
  • 低频维度(i=1i=1):pos=1pos=1pos=2pos=2 几乎相同(0.010.020.01 \approx 0.02),变化极慢

FFN 数值示例dmodel=4d_\text{model}=4dff=16d_{ff}=16,输入 x=[1,0,0,0]x=[1,0,0,0]

  1. h=W1x+b1h = W_1 x + b_1:形状 (16,)(16,),经 ReLU 后大多数为 0(稀疏激活)
  2. output=W2ReLU(h)+b2\text{output} = W_2 \text{ReLU}(h) + b_2:形状 (4,)(4,),恢复为 dmodeld_\text{model}

💡 为什么这样做?

位置编码:自注意力对输入排列不变——打乱词序后输出只是对应打乱,不改变内容。正弦编码像给每个词贴上”座位号”,让模型感知”我在第 3 位,你在第 7 位,我们相差 4 步”。

残差连接:想象学习”恒等变换”有多难——网络要学会让输出等于输入。有了残差连接,子层只需要学习”要修改的增量”(残差),默认行为是”什么都不改”(直接传递 xx)。这大大降低了训练难度。

FFN 的角色:注意力负责”收集信息”(从其他位置聚合),FFN 负责”处理信息”(对收集到的信息做非线性变换)。研究表明 FFN 像”知识存储”——很多事实性知识(如”法国的首都是巴黎”)存储在 FFN 的权重中。

LayerNorm 的角色:稳定训练,防止层间激活值的均值和方差飘移。BatchNorm 对 batch 归一化在序列模型中不适用(序列长度不固定),LayerNorm 对特征维度归一化更自然。

⚠️ 常见误区

  1. 误区:位置编码是拼接到词嵌入上的 → 正确:是加法input=embedding+PE\text{input} = \text{embedding} + PE),维度不变

  2. 误区:Pre-LN 和 Post-LN 性能相同 → 正确:Post-LN 原始论文用,但需要精细学习率调度;Pre-LN 更稳定,现代 LLM(GPT-2, LLaMA 等)全部用 Pre-LN;深层网络 Pre-LN 明显优于 Post-LN

  3. 误区:Decoder 的掩码是随机 dropout → 正确:Decoder 的 Masked Self-Attention 用因果掩码(causal mask),即严格的下三角矩阵:位置 ii 只能看到 jij \leq i 的位置,保证自回归生成时不看到”未来”

  4. 误区:FFN 的 dffd_{ff} 必须是 4dmodel4 d_\text{model}正确4×4 \times 是 Vaswani et al. 的选择,后来的模型有不同比例(如 LLaMA 3 用 8/3dmodel8/3 \cdot d_\text{model},结合 SwiGLU 激活)

7. Transformer 的优势与待改进

Slide 65 Slide 66 Slide 67 Slide 68 Slide 69 Slide 70
  • 优势:MT 上 SOTA(WMT 2014 EN-DE 28.4 BLEU),文档生成也显著提升
  • 待改进
    • 自注意力的二次计算复杂度 O(n2)O(n^2):长序列(n50000n \ge 50000)仍是挑战
    • 位置表示:绝对位置 vs 相对位置 vs 旋转位置嵌入
    • 实践中,大型 Transformer LM 几乎都沿用标准二次注意力(更便宜的替代方案在规模化后效果不佳)

推荐阅读

关联概念

个人笔记