【信息科学与工程学】【人工智能】计算科学与自动化-第八篇03 Transformer 模型中的数学推导
Transformer模型数学推导全集
一、Transformer核心架构概述
1.1 Transformer整体架构
Transformer模型基于编码器-解码器架构,主要由以下部分组成:
Transformer = 编码器(Encoder) × N + 解码器(Decoder) × N
编码器 = 自注意力(Self-Attention) + 前馈神经网络(FFN) + 残差连接(Residual) + 层归一化(LayerNorm)
解码器 = 掩码自注意力(Masked Self-Attention) + 编码器-解码器注意力(Encoder-Decoder Attention) + 前馈神经网络(FFN) + 残差连接 + 层归一化
二、自注意力机制数学推导
2.1 缩放点积注意力(Scaled Dot-Product Attention)
2.1.1 基本定义
设输入序列为 X = [x_1, x_2, ..., x_n] \in \mathbb{R}^{n \times d_{model}},其中:
-
n:序列长度
-
d_{model}:模型维度
2.1.2 查询(Query)、键(Key)、值(Value)矩阵
通过线性变换得到Q、K、V矩阵:
Q = XW^Q, \quad W^Q \in \mathbb{R}^{d_{model} \times d_k}
K = XW^K, \quad W^K \in \mathbb{R}^{d_{model} \times d_k}
V = XW^V, \quad W^V \in \mathbb{R}^{d_{model} \times d_v}
其中:
-
d_k:键/查询的维度
-
d_v:值的维度
-
通常 d_k = d_v = d_{model}/h,h 为注意力头数
2.1.3 注意力分数计算
步骤1:计算相似度分数
计算查询Q和键K的点积相似度:
\text{Similarity}(Q, K) = QK^T \in \mathbb{R}^{n \times n}
推导:
-
设 q_i = x_iW^Q 为第i个位置的查询向量
-
设 k_j = x_jW^K 为第j个位置的键向量
-
则相似度分数 s_{ij} = q_i \cdot k_j^T
矩阵形式:
S = QK^T
其中 S_{ij} = q_i k_j^T
步骤2:缩放
为了防止点积值过大导致梯度消失,进行缩放:
S_{\text{scaled}} = \frac{QK^T}{\sqrt{d_k}}
数学推导:
假设 q_i 和 k_j 的每个分量是独立同分布的随机变量,均值为0,方差为1,则:
\text{Var}(q_i \cdot k_j^T) = \text{Var}\left(\sum_{l=1}^{d_k} q_{il}k_{jl}\right)
由于 q_{il} 和 k_{jl} 独立:
\text{Var}(q_i \cdot k_j^T) = \sum_{l=1}^{d_k} \text{Var}(q_{il}k_{jl}) = \sum_{l=1}^{d_k} \text{Var}(q_{il})\text{Var}(k_{jl}) = d_k \cdot 1 \cdot 1 = d_k
因此标准差为 \sqrt{d_k},除以 \sqrt{d_k} 可以将方差控制为1,有助于稳定梯度。
步骤3:应用Softmax得到注意力权重
A = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)
其中softmax按行应用:
A_{ij} = \frac{\exp\left(\frac{q_i k_j^T}{\sqrt{d_k}}\right)}{\sum_{l=1}^n \exp\left(\frac{q_i k_l^T}{\sqrt{d_k}}\right)}
步骤4:加权求和得到输出
\text{Attention}(Q, K, V) = AV
具体计算:
\text{output}_i = \sum_{j=1}^n A_{ij} v_j
其中 v_j = x_jW^V 是第j个位置的值向量。
2.1.4 完整公式
缩放点积注意力公式:
\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V
2.2 多头注意力(Multi-Head Attention)
2.2.1 多头注意力定义
多头注意力并行地执行h个注意力头,然后将结果拼接并线性变换:
\text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, ..., \text{head}_h)W^O
其中:
\text{head}_i = \text{Attention}(QW_i^Q, KW_i^K, VW_i^V)
2.2.2 参数维度
-
W_i^Q \in \mathbb{R}^{d_{model} \times d_k}
-
W_i^K \in \mathbb{R}^{d_{model} \times d_k}
-
W_i^V \in \mathbb{R}^{d_{model} \times d_v}
-
W^O \in \mathbb{R}^{h d_v \times d_{model}}
通常设置 d_k = d_v = d_{model}/h
2.2.3 多头注意力推导
步骤1:线性变换为h个头
对每个头 i \in \{1, ..., h\}:
Q_i = QW_i^Q \in \mathbb{R}^{n \times d_k}
K_i = KW_i^K \in \mathbb{R}^{n \times d_k}
V_i = VW_i^V \in \mathbb{R}^{n \times d_v}
步骤2:计算每个头的注意力
\text{head}_i = \text{Attention}(Q_i, K_i, V_i) = \text{softmax}\left(\frac{Q_i K_i^T}{\sqrt{d_k}}\right)V_i
\text{head}_i \in \mathbb{R}^{n \times d_v}
步骤3:拼接所有头
\text{MultiHead}_{\text{concat}} = [\text{head}_1; \text{head}_2; ...; \text{head}_h] \in \mathbb{R}^{n \times (h d_v)}
步骤4:线性变换输出
\text{MultiHead}(Q, K, V) = \text{MultiHead}_{\text{concat}} W^O
其中 W^O \in \mathbb{R}^{(h d_v) \times d_{model}},输出维度为 \mathbb{R}^{n \times d_{model}}
2.2.4 多头注意力的意义
设总计算成本为 C,单头注意力计算成本:
C_{\text{single}} = O(n^2 d_k + n d_k d_v)
多头注意力计算成本(h个头):
C_{\text{multi}} = h \cdot O\left(\left(\frac{n}{h}\right)^2 d_k + \frac{n}{h} d_k d_v\right) = O(n^2 d_k + n d_k d_v)
计算复杂度相同,但可以:
-
并行计算h个头
-
学习不同的表示子空间
-
增强模型表达能力
三、位置编码(Positional Encoding)
3.1 正弦余弦位置编码
由于Transformer没有递归或卷积结构,需要注入位置信息。
3.1.1 位置编码公式
对于位置 pos 和维度 i:
PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{2i/d_{model}}}\right)
PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{2i/d_{model}}}\right)
其中:
-
pos:位置索引(0, 1, 2, ...)
-
i:维度索引(0, 1, ..., d_{model}/2-1)
-
d_{model}:模型维度
3.1.2 矩阵形式
设位置编码矩阵 P \in \mathbb{R}^{n \times d_{model}},其中 n 为最大序列长度。
对于每个位置 pos:
P_{pos} = \left[\sin\left(\frac{pos}{10000^{0/d_{model}}}\right), \cos\left(\frac{pos}{10000^{0/d_{model}}}\right), \sin\left(\frac{pos}{10000^{2/d_{model}}}\right), \cos\left(\frac{pos}{10000^{2/d_{model}}}\right), ...\right]
3.1.3 简化表示
令 \omega_i = \frac{1}{10000^{2i/d_{model}}},则:
PE_{(pos, 2i)} = \sin(pos \cdot \omega_i)
PE_{(pos, 2i+1)} = \cos(pos \cdot \omega_i)
3.1.4 位置编码的性质
性质1:相对位置关系
对于固定偏移 k,PE_{pos+k} 可以表示为 PE_{pos} 的线性函数:
\begin{aligned}
PE_{(pos+k, 2i)} &= \sin((pos+k)\omega_i) \\
&= \sin(pos\omega_i)\cos(k\omega_i) + \cos(pos\omega_i)\sin(k\omega_i) \\
&= PE_{(pos, 2i)} \cos(k\omega_i) + PE_{(pos, 2i+1)} \sin(k\omega_i)
\end{aligned}
\begin{aligned}
PE_{(pos+k, 2i+1)} &= \cos((pos+k)\omega_i) \\
&= \cos(pos\omega_i)\cos(k\omega_i) - \sin(pos\omega_i)\sin(k\omega_i) \\
&= PE_{(pos, 2i+1)} \cos(k\omega_i) - PE_{(pos, 2i)} \sin(k\omega_i)
\end{aligned}
这表明模型可以学习到相对位置信息。
性质2:位置编码与输入相加
输入嵌入与位置编码直接相加:
X' = X + P
其中 X \in \mathbb{R}^{n \times d_{model}} 是词嵌入,P \in \mathbb{R}^{n \times d_{model}} 是位置编码。
四、前馈神经网络(Feed-Forward Network)
4.1 前馈网络结构
每个位置独立地应用相同的两层前馈网络:
\text{FFN}(x) = \text{ReLU}(xW_1 + b_1)W_2 + b_2
其中:
-
x \in \mathbb{R}^{1 \times d_{model}}:单个位置的输入
-
W_1 \in \mathbb{R}^{d_{model} \times d_{ff}},b_1 \in \mathbb{R}^{1 \times d_{ff}}
-
W_2 \in \mathbb{R}^{d_{ff} \times d_{model}},b_2 \in \mathbb{R}^{1 \times d_{model}}
-
d_{ff}:中间维度,通常 d_{ff} = 4d_{model}
4.2 矩阵形式
对于整个序列 X \in \mathbb{R}^{n \times d_{model}}:
\text{FFN}(X) = \text{ReLU}(XW_1 + b_1)W_2 + b_2
其中广播机制会使 b_1 和 b_2 应用到每一行。
4.3 详细推导
步骤1:第一层线性变换
Z_1 = XW_1 + b_1 \in \mathbb{R}^{n \times d_{ff}}
步骤2:ReLU激活函数
A_1 = \text{ReLU}(Z_1) = \max(0, Z_1) \in \mathbb{R}^{n \times d_{ff}}
步骤3:第二层线性变换
\text{FFN}(X) = A_1W_2 + b_2 \in \mathbb{R}^{n \times d_{model}}
五、层归一化(Layer Normalization)
5.1 层归一化公式
对于输入 x \in \mathbb{R}^{d_{model}}(单个位置的向量):
\text{LayerNorm}(x) = \gamma \odot \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}} + \beta
其中:
-
\mu = \frac{1}{d_{model}} \sum_{i=1}^{d_{model}} x_i:均值
-
\sigma^2 = \frac{1}{d_{model}} \sum_{i=1}^{d_{model}} (x_i - \mu)^2:方差
-
\gamma, \beta \in \mathbb{R}^{d_{model}}:可学习的缩放和平移参数
-
\epsilon:小常数(如 10^{-5})防止除零
-
\odot:逐元素相乘
5.2 矩阵形式
对于整个序列 X \in \mathbb{R}^{n \times d_{model}},对每一行(每个位置)独立应用层归一化:
对于第 j 行 X_{j:} \in \mathbb{R}^{1 \times d_{model}}:
\mu_j = \frac{1}{d_{model}} \sum_{i=1}^{d_{model}} X_{ji}
\sigma_j^2 = \frac{1}{d_{model}} \sum_{i=1}^{d_{model}} (X_{ji} - \mu_j)^2
\text{LayerNorm}(X)_{j:} = \gamma \odot \frac{X_{j:} - \mu_j}{\sqrt{\sigma_j^2 + \epsilon}} + \beta
5.3 与批量归一化的区别
| 归一化类型 | 归一化维度 | 适用场景 | 公式 |
|---|---|---|---|
| 批量归一化 | 批量维度 | 卷积网络、大批量 | \mu = \frac{1}{B} \sum_{i=1}^B x_i |
| 层归一化 | 特征维度 | 序列模型、小批量 | \mu = \frac{1}{d} \sum_{i=1}^d x_i |
六、残差连接(Residual Connection)
6.1 残差连接公式
对于子层 F(x),残差连接为:
\text{Output} = \text{LayerNorm}(x + F(x))
或者在某些实现中:
\text{Output} = x + \text{LayerNorm}(F(x))
原始Transformer论文使用前者。
6.2 前向传播推导
设输入为 x,子层函数为 F(可以是自注意力或前馈网络):
-
计算子层输出:y = F(x)
-
残差连接:z = x + y
-
层归一化:\text{Output} = \text{LayerNorm}(z)
6.3 反向传播推导(梯度计算)
设损失函数为 L,需要计算 \frac{\partial L}{\partial x}:
令 z = x + y,其中 y = F(x)
则:
\frac{\partial L}{\partial x} = \frac{\partial L}{\partial \text{Output}} \cdot \frac{\partial \text{Output}}{\partial z} \cdot \frac{\partial z}{\partial x}
其中:
-
\frac{\partial \text{Output}}{\partial z} 来自层归一化的梯度
-
\frac{\partial z}{\partial x} = 1 + \frac{\partial y}{\partial x}
因此梯度可以直接流过残差连接:
\frac{\partial L}{\partial x} = \frac{\partial L}{\partial \text{Output}} \cdot \frac{\partial \text{Output}}{\partial z} \cdot \left(1 + \frac{\partial F(x)}{\partial x}\right)
即使 \frac{\partial F(x)}{\partial x} 很小,梯度也可以通过 "+1" 项回传,缓解梯度消失问题。
七、编码器层完整推导
7.1 编码器单层结构
一个编码器层包含:
-
多头自注意力 + 残差连接 + 层归一化
-
前馈网络 + 残差连接 + 层归一化
7.2 数学公式
设第 l 层编码器的输入为 H^l \in \mathbb{R}^{n \times d_{model}}:
步骤1:多头自注意力子层
H_{\text{attn}}^l = \text{MultiHead}(H^l, H^l, H^l)
H_{\text{attn\_res}}^l = \text{LayerNorm}(H^l + H_{\text{attn}}^l)
步骤2:前馈网络子层
H_{\text{ffn}}^l = \text{FFN}(H_{\text{attn\_res}}^l)
H^{l+1} = \text{LayerNorm}(H_{\text{attn\_res}}^l + H_{\text{ffn}}^l)
输出 H^{l+1} 作为下一层的输入。
7.3 详细推导
自注意力子层:
-
输入:H^l \in \mathbb{R}^{n \times d_{model}}
-
计算查询、键、值:
Q^l = H^l W_Q^l, \quad K^l = H^l W_K^l, \quad V^l = H^l W_V^l -
多头注意力:
\text{head}_i^l = \text{Attention}(Q^l W_{Q,i}^l, K^l W_{K,i}^l, V^l W_{V,i}^l)H_{\text{attn}}^l = \text{Concat}(\text{head}_1^l, ..., \text{head}_h^l) W_O^l -
残差连接和层归一化:
H_{\text{attn\_res}}^l = \text{LayerNorm}(H^l + H_{\text{attn}}^l)
前馈网络子层:
-
输入:H_{\text{attn\_res}}^l \in \mathbb{R}^{n \times d_{model}}
-
第一层线性变换:
Z_1^l = H_{\text{attn\_res}}^l W_1^l + b_1^l -
ReLU激活:
A_1^l = \text{ReLU}(Z_1^l) -
第二层线性变换:
H_{\text{ffn}}^l = A_1^l W_2^l + b_2^l -
残差连接和层归一化:
H^{l+1} = \text{LayerNorm}(H_{\text{attn\_res}}^l + H_{\text{ffn}}^l)
八、解码器层完整推导
8.1 解码器单层结构
一个解码器层包含:
-
掩码多头自注意力 + 残差连接 + 层归一化
-
编码器-解码器注意力 + 残差连接 + 层归一化
-
前馈网络 + 残差连接 + 层归一化
8.2 掩码自注意力
在解码器中,自注意力需要被掩码,以防止当前位置关注到未来的位置。
8.2.1 掩码矩阵
定义掩码矩阵 M \in \mathbb{R}^{n \times n}:
M_{ij} =
\begin{cases}
0, & \text{if } i \geq j \text{ (允许关注当前位置及之前位置)}\\
-\infty, & \text{if } i < j \text{ (屏蔽未来位置)}
\end{cases}
8.2.2 掩码注意力计算
\text{MaskedAttention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}} + M\right)V
由于 softmax(-\infty) = 0,未来位置的注意力权重为0。
8.3 数学公式
设第 l 层解码器的输入为 H_{\text{dec}}^l \in \mathbb{R}^{m \times d_{model}},编码器输出为 H_{\text{enc}} \in \mathbb{R}^{n \times d_{model}},其中 m 是目标序列长度,n 是源序列长度。
步骤1:掩码多头自注意力子层
H_{\text{masked\_attn}}^l = \text{MaskedMultiHead}(H_{\text{dec}}^l, H_{\text{dec}}^l, H_{\text{dec}}^l)
H_{\text{masked\_res}}^l = \text{LayerNorm}(H_{\text{dec}}^l + H_{\text{masked\_attn}}^l)
步骤2:编码器-解码器注意力子层
H_{\text{enc\_dec\_attn}}^l = \text{MultiHead}(H_{\text{masked\_res}}^l, H_{\text{enc}}, H_{\text{enc}})
H_{\text{enc\_dec\_res}}^l = \text{LayerNorm}(H_{\text{masked\_res}}^l + H_{\text{enc\_dec\_attn}}^l)
步骤3:前馈网络子层
H_{\text{ffn}}^l = \text{FFN}(H_{\text{enc\_dec\_res}}^l)
H_{\text{dec}}^{l+1} = \text{LayerNorm}(H_{\text{enc\_dec\_res}}^l + H_{\text{ffn}}^l)
8.4 编码器-解码器注意力详解
在编码器-解码器注意力中:
-
查询(Q)来自解码器:Q = H_{\text{masked\_res}}^l W_Q^l
-
键(K)来自编码器:K = H_{\text{enc}} W_K^l
-
值(V)来自编码器:V = H_{\text{enc}} W_V^l
这使得解码器可以关注编码器的所有位置。
九、位置前馈网络(Position-wise FFN)推导
9.1 位置独立性
位置前馈网络对序列中的每个位置独立应用相同的变换:
对于输入 X \in \mathbb{R}^{n \times d_{model}},输出 Y \in \mathbb{R}^{n \times d_{model}},对于每个位置 i:
Y_i = \text{FFN}(X_i) = \text{ReLU}(X_i W_1 + b_1) W_2 + b_2
其中 X_i \in \mathbb{R}^{1 \times d_{model}} 是第 i 个位置的向量。
9.2 参数共享
所有位置共享相同的参数 W_1, b_1, W_2, b_2,这减少了参数量并增加了泛化能力。
9.3 计算复杂度
设 d_{model} = d,d_{ff} = 4d:
-
第一层:XW_1,计算复杂度 O(n \cdot d \cdot 4d) = O(4nd^2)
-
第二层:A_1W_2,计算复杂度 O(n \cdot 4d \cdot d) = O(4nd^2)
-
总复杂度:O(8nd^2)
十、多头注意力复杂度分析
10.1 计算复杂度推导
设:
-
序列长度:n
-
模型维度:d
-
头数:h
-
每个头的维度:d_k = d_v = d/h
10.1.1 单头注意力复杂度
-
计算 QK^T:O(n \cdot d_k \cdot n) = O(n^2 d_k)
-
计算softmax:O(n^2)
-
乘以V:O(n^2 \cdot d_v) = O(n^2 d_v)
-
总复杂度:O(n^2 d_k + n^2 d_v) = O(n^2 (d_k + d_v))
由于 d_k = d_v = d/h,所以 O(n^2 \cdot 2d/h) = O(2n^2 d/h)
10.1.2 多头注意力复杂度
h个头并行计算,每个头复杂度 O(2n^2 d/h),所以h个头总复杂度 O(h \cdot 2n^2 d/h) = O(2n^2 d)
10.1.3 线性变换复杂度
-
输入到Q、K、V的线性变换:O(n \cdot d \cdot 3d) = O(3nd^2)
-
多头拼接后的输出线性变换:O(n \cdot d \cdot d) = O(nd^2)
-
总线性变换复杂度:O(4nd^2)
10.1.4 总复杂度
多头注意力总复杂度 = 注意力计算复杂度 + 线性变换复杂度
O(2n^2 d + 4nd^2)
10.2 与RNN复杂度比较
RNN的复杂度为 O(n d^2)(每个时间步 O(d^2),共n步)
比较:
-
当 n < d 时,Transformer的 O(n^2 d) 可能小于RNN的 O(n d^2)
-
当 n > d 时,Transformer的 O(n^2 d) 大于RNN的 O(n d^2)
因此Transformer更适合中等长度序列,长序列需要优化(如稀疏注意力)。
十一、位置编码的傅里叶分析
11.1 位置编码的正弦余弦形式
位置编码可以看作频率不同的正弦余弦函数的组合:
PE_{(pos, 2i)} = \sin(\omega_i \cdot pos)
PE_{(pos, 2i+1)} = \cos(\omega_i \cdot pos)
其中 \omega_i = 10000^{-2i/d}
11.2 频率分布
频率 \omega_i 随维度 i 指数衰减:
\omega_i = 10000^{-2i/d} = e^{-\frac{2i}{d} \ln 10000}
因此:
-
低维度(小i):高频(\omega_i 大)
-
高维度(大i):低频(\omega_i 小)
11.3 位置编码的线性性质证明
定理:对于任意偏移 k,PE_{pos+k} 可以表示为 PE_{pos} 的线性函数。
证明:
由三角恒等式:
\sin(\omega_i (pos + k)) = \sin(\omega_i pos) \cos(\omega_i k) + \cos(\omega_i pos) \sin(\omega_i k)
\cos(\omega_i (pos + k)) = \cos(\omega_i pos) \cos(\omega_i k) - \sin(\omega_i pos) \sin(\omega_i k)
写成矩阵形式:
\begin{bmatrix}
PE_{(pos+k, 2i)} \\
PE_{(pos+k, 2i+1)}
\end{bmatrix}
=
\begin{bmatrix}
\cos(\omega_i k) & \sin(\omega_i k) \\
-\sin(\omega_i k) & \cos(\omega_i k)
\end{bmatrix}
\begin{bmatrix}
PE_{(pos, 2i)} \\
PE_{(pos, 2i+1)}
\end{bmatrix}
这是一个旋转矩阵,因此位置编码具有线性性质,模型可以学习相对位置信息。
十二、梯度流分析
12.1 残差连接对梯度的影响
考虑第 l 层到第 l+1 层的变换:
H^{l+1} = \text{LayerNorm}(H^l + F(H^l))
在反向传播时,梯度为:
\frac{\partial H^{l+1}}{\partial H^l} = \frac{\partial \text{LayerNorm}}{\partial (H^l + F(H^l))} \cdot \left(I + \frac{\partial F(H^l)}{\partial H^l}\right)
即使 \frac{\partial F(H^l)}{\partial H^l} 很小,梯度也可以通过单位矩阵 I 回传,缓解梯度消失。
12.2 层归一化对梯度的影响
层归一化的梯度计算:
设 y = \text{LayerNorm}(x),则:
y_i = \gamma_i \hat{x}_i + \beta_i, \quad \hat{x}_i = \frac{x_i - \mu}{\sqrt{\sigma^2 + \epsilon}}
其中:
\mu = \frac{1}{d} \sum_{j=1}^d x_j, \quad \sigma^2 = \frac{1}{d} \sum_{j=1}^d (x_j - \mu)^2
梯度计算:
\frac{\partial y_i}{\partial x_j} = \gamma_i \cdot \frac{\partial \hat{x}_i}{\partial x_j}
\frac{\partial \hat{x}_i}{\partial x_j} = \frac{\delta_{ij} - \frac{1}{d} - \hat{x}_i \cdot \frac{1}{d} \sum_{k=1}^d \hat{x}_k (\delta_{jk} - \frac{1}{d})}{\sqrt{\sigma^2 + \epsilon}}
其中 \delta_{ij} 是Kronecker delta符号。
十三、Transformer训练目标函数
13.1 语言模型目标函数
对于序列 \mathbf{x} = (x_1, x_2, ..., x_T),Transformer解码器的目标是最大化条件概率:
P(x_t | x_1, ..., x_{t-1}) = \text{softmax}(W_o h_t + b_o)
其中 h_t 是解码器在位置 t 的隐藏状态。
13.2 交叉熵损失函数
对于目标序列 \mathbf{y} = (y_1, y_2, ..., y_T),损失函数为:
\mathcal{L} = -\sum_{t=1}^T \log P(y_t | y_1, ..., y_{t-1}, \mathbf{x})
其中 \mathbf{x} 是源序列。
13.3 标签平滑(Label Smoothing)
为了避免过拟合,使用标签平滑:
y_{\text{smooth}} = (1 - \epsilon) y_{\text{one-hot}} + \epsilon / K
其中 K 是词汇表大小,\epsilon 是平滑参数(通常0.1)。
损失函数变为:
\mathcal{L} = -\sum_{t=1}^T \sum_{k=1}^K y_{\text{smooth},t,k} \log P(y_t = k | ...)
十四、注意力权重可视化
14.1 注意力权重矩阵
注意力权重矩阵 A = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right) \in \mathbb{R}^{n \times n} 可以可视化,显示每个位置关注其他位置的程度。
14.2 多头注意力可视化
对于h个头,有h个注意力权重矩阵 A_i \in \mathbb{R}^{n \times n},可以分别可视化,观察不同头关注的不同模式。
十五、Transformer变体数学推导
15.1 稀疏注意力
15.1.1 局部注意力
只关注局部窗口内的位置:
A_{ij} =
\begin{cases}
\text{softmax}\left(\frac{q_i k_j^T}{\sqrt{d_k}}\right), & \text{if } |i-j| \leq w \\
0, & \text{otherwise}
\end{cases}
其中 w 是窗口大小。
复杂度从 O(n^2) 降为 O(nw)。
15.1.2 扩张注意力
每隔 d 个位置关注一次:
关注位置:j = i + k \cdot d,其中 k \in \mathbb{Z}
15.1.3 随机注意力
对每个查询,只关注随机选择的 r 个位置,而不是所有位置。
复杂度从 O(n^2) 降为 O(nr)。
15.2 线性注意力
标准注意力:O = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V
改写为:O_i = \frac{\sum_{j=1}^n \exp\left(\frac{q_i k_j^T}{\sqrt{d_k}}\right) v_j}{\sum_{j=1}^n \exp\left(\frac{q_i k_j^T}{\sqrt{d_k}}\right)}
使用核函数近似:\exp(q_i k_j^T) \approx \phi(q_i)^T \phi(k_j)
则:
O_i \approx \frac{\phi(q_i)^T \sum_{j=1}^n \phi(k_j) v_j^T}{\phi(q_i)^T \sum_{j=1}^n \phi(k_j)}
复杂度从 O(n^2 d) 降为 O(nd^2)。
15.3 相对位置编码
15.3.1 Shaw相对位置编码
在注意力分数中加入相对位置信息:
e_{ij} = \frac{q_i k_j^T + q_i r_{i-j}^T}{\sqrt{d_k}}
其中 r_{i-j} 是相对位置嵌入。
15.3.2 Transformer-XL相对位置编码
A_{i,j}^{\text{rel}} = \frac{q_i k_j^T + q_i R_{i-j}^T u^T + v^T R_{i-j} k_j^T}{\sqrt{d_k}}
其中 R 是正弦相对位置编码,u,v 是可学习参数。
十六、数学性质证明
16.1 注意力机制的线性变换等价性
定理:对于线性变换 W_Q, W_K, W_V,注意力机制满足:
\text{Attention}(QW_Q, KW_K, VW_V) = \text{Attention}(Q, K, V) W_O'
其中 W_O' 是某个线性变换。
证明:
设 Q' = QW_Q, K' = KW_K, V' = VW_V
则:
\begin{aligned}
\text{Attention}(Q', K', V') &= \text{softmax}\left(\frac{Q'K'^T}{\sqrt{d_k}}\right)V' \\
&= \text{softmax}\left(\frac{QW_Q (KW_K)^T}{\sqrt{d_k}}\right)VW_V \\
&= \text{softmax}\left(\frac{Q(W_Q W_K^T) K^T}{\sqrt{d_k}}\right)VW_V
\end{aligned}
而:
\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V
两者不一定相等,除非 W_Q W_K^T = I。但注意力机制对线性变换不是等价的,这是多头注意力的基础。
16.2 多头注意力的表达能力
定理:多头注意力可以表示任何连续序列到序列的函数,只要头数足够多。
证明思路:
-
单个注意力头可以看作加权求和
-
多个头可以学习不同的注意力模式
-
通过适当的权重,可以近似任意连续函数
16.3 位置编码的唯一性
定理:正弦位置编码对于不同的位置产生不同的编码向量。
证明:
假设存在 pos_1 \neq pos_2 使得 PE_{pos_1} = PE_{pos_2}。
则对于所有 i:
\sin(\omega_i pos_1) = \sin(\omega_i pos_2) \quad \text{且} \quad \cos(\omega_i pos_1) = \cos(\omega_i pos_2)
这意味着对于所有 i,\omega_i (pos_1 - pos_2) 是 2\pi 的整数倍。
但由于 \omega_i 是几何级数,这是不可能的。因此 PE_{pos_1} \neq PE_{pos_2}。
十七、优化器和学习率调度
17.1 Adam优化器
Transformer使用Adam优化器,参数更新公式:
\theta_t = \theta_{t-1} - \eta \cdot \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon}
其中:
-
m_t = \beta_1 m_{t-1} + (1-\beta_1) g_t(一阶矩估计)
-
v_t = \beta_2 v_{t-1} + (1-\beta_2) g_t^2(二阶矩估计)
-
\hat{m}_t = m_t / (1-\beta_1^t)(偏差校正)
-
\hat{v}_t = v_t / (1-\beta_2^t)(偏差校正)
17.2 学习率调度
Transformer使用学习率预热(warmup)和逆平方根衰减:
\text{learning\_rate} = d_{\text{model}}^{-0.5} \cdot \min(\text{step\_num}^{-0.5}, \text{step\_num} \cdot \text{warmup\_steps}^{-1.5})
十八、完整Transformer前向传播算法
18.1 编码器前向传播
输入:源序列 X \in \mathbb{R}^{n \times d_{model}}
输出:编码表示 H_{\text{enc}} \in \mathbb{R}^{n \times d_{model}}
算法:
1. 添加位置编码:X = X + PE
2. 对于每个编码器层 l = 1 到 L:
a. 多头自注意力:
Q = H^{l-1} W_Q^l, K = H^{l-1} W_K^l, V = H^{l-1} W_V^l
head_i = Attention(QW_{Q,i}^l, KW_{K,i}^l, VW_{V,i}^l), i=1..h
MultiHead = Concat(head_1, ..., head_h) W_O^l
b. 残差连接和层归一化:
H' = LayerNorm(H^{l-1} + MultiHead)
c. 前馈网络:
FFN = ReLU(H' W_1^l + b_1^l) W_2^l + b_2^l
d. 残差连接和层归一化:
H^l = LayerNorm(H' + FFN)
3. 返回 H^L
18.2 解码器前向传播
输入:目标序列 Y \in \mathbb{R}^{m \times d_{model}},编码器输出 H_{\text{enc}}
输出:解码器输出 H_{\text{dec}} \in \mathbb{R}^{m \times d_{model}}
算法:
1. 添加位置编码:Y = Y + PE
2. 对于每个解码器层 l = 1 到 L:
a. 掩码多头自注意力:
Q = H_dec^{l-1} W_Q^{l,1}, K = H_dec^{l-1} W_K^{l,1}, V = H_dec^{l-1} W_V^{l,1}
计算掩码注意力:A = softmax(QK^T/√d_k + M)V
head_i = Attention(QW_{Q,i}^{l,1}, KW_{K,i}^{l,1}, VW_{V,i}^{l,1}), i=1..h
MaskedMultiHead = Concat(head_1, ..., head_h) W_O^{l,1}
H_masked = LayerNorm(H_dec^{l-1} + MaskedMultiHead)
b. 编码器-解码器注意力:
Q = H_masked W_Q^{l,2}, K = H_enc W_K^{l,2}, V = H_enc W_V^{l,2}
head_i = Attention(QW_{Q,i}^{l,2}, KW_{K,i}^{l,2}, VW_{V,i}^{l,2}), i=1..h
EncDecMultiHead = Concat(head_1, ..., head_h) W_O^{l,2}
H_encdec = LayerNorm(H_masked + EncDecMultiHead)
c. 前馈网络:
FFN = ReLU(H_encdec W_1^l + b_1^l) W_2^l + b_2^l
H_dec^l = LayerNorm(H_encdec + FFN)
3. 返回 H_dec^L
十九、Transformer复杂度总结
| 组件 | 时间复杂度 | 空间复杂度 | 说明 |
|---|---|---|---|
| 自注意力 | O(n^2 d) | O(n^2) | 序列长度的平方 |
| 前馈网络 | O(n d^2) | O(n d) | 模型维度的平方 |
| 层归一化 | O(n d) | O(d) | 线性复杂度 |
| 位置编码 | O(n d) | O(n d) | 预计算或实时计算 |
| 总编码器层 | O(L(n^2 d + n d^2)) | O(L(n^2 + n d)) | L层 |
| 总解码器层 | O(L(m^2 d + m n d + m d^2)) | O(L(m^2 + m n + m d)) | 目标长度m,源长度n |
二十、Transformer数学性质总结
-
置换等变性:自注意力对输入排列是等变的
-
位置敏感性:通过位置编码引入位置信息
-
长程依赖:自注意力可以捕获任意距离的依赖
-
并行计算:所有位置可以并行计算
-
表达能力强:可以近似任意连续序列到序列的函数
二十一、代码实现关键公式
21.1 缩放点积注意力实现
import torch
import torch.nn as nn
import torch.nn.functional as F
def scaled_dot_product_attention(Q, K, V, mask=None):
"""
Q: [batch_size, seq_len_q, d_k]
K: [batch_size, seq_len_k, d_k]
V: [batch_size, seq_len_v, d_v] (通常seq_len_k = seq_len_v)
mask: [batch_size, seq_len_q, seq_len_k]
"""
d_k = Q.size(-1)
# 计算注意力分数
scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(d_k) # [batch_size, seq_len_q, seq_len_k]
# 应用掩码(如果有)
if mask is not None:
scores = scores.masked_fill(mask == 0, -1e9)
# 应用softmax得到注意力权重
attn_weights = F.softmax(scores, dim=-1) # [batch_size, seq_len_q, seq_len_k]
# 加权求和
output = torch.matmul(attn_weights, V) # [batch_size, seq_len_q, d_v]
return output, attn_weights
21.2 多头注意力实现
class MultiHeadAttention(nn.Module):
def __init__(self, d_model, num_heads):
super().__init__()
self.d_model = d_model
self.num_heads = num_heads
self.d_k = d_model // num_heads
self.d_v = d_model // num_heads
# 线性变换矩阵
self.W_Q = nn.Linear(d_model, d_model)
self.W_K = nn.Linear(d_model, d_model)
self.W_V = nn.Linear(d_model, d_model)
self.W_O = nn.Linear(d_model, d_model)
def forward(self, Q, K, V, mask=None):
batch_size = Q.size(0)
# 线性变换
Q = self.W_Q(Q) # [batch_size, seq_len, d_model]
K = self.W_K(K)
V = self.W_V(V)
# 重塑为多头
Q = Q.view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2) # [batch_size, num_heads, seq_len, d_k]
K = K.view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
V = V.view(batch_size, -1, self.num_heads, self.d_v).transpose(1, 2)
# 计算缩放点积注意力
scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(self.d_k) # [batch_size, num_heads, seq_len_q, seq_len_k]
if mask is not None:
mask = mask.unsqueeze(1) # 扩展维度以匹配多头
scores = scores.masked_fill(mask == 0, -1e9)
attn_weights = F.softmax(scores, dim=-1)
context = torch.matmul(attn_weights, V) # [batch_size, num_heads, seq_len_q, d_v]
# 合并多头
context = context.transpose(1, 2).contiguous().view(batch_size, -1, self.d_model) # [batch_size, seq_len_q, d_model]
# 输出线性变换
output = self.W_O(context) # [batch_size, seq_len_q, d_model]
return output, attn_weights
总结
Transformer模型的核心数学推导包括:
-
缩放点积注意力: \text{Attention}(Q,K,V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V
-
多头注意力:并行计算多个注意力头并拼接
-
位置编码:正弦余弦函数编码位置信息
-
前馈网络:两层全连接层加ReLU激活
-
残差连接: x + F(x) 缓解梯度消失
-
层归一化:沿特征维度归一化
Transformer的数学设计使其能够:
-
并行处理序列
-
捕获长程依赖
-
具有强表达能力
-
训练稳定高效
这些数学性质使Transformer成为自然语言处理、计算机视觉等领域的强大基础模型。
Transformer 模型中的权重矩阵
WQ, WK, WV 是其自注意力机制的核心。它们的作用是将输入序列的嵌入表示投影到查询空间、键空间和值空间,从而计算注意力分数。下面是它们的数学方程式和关键细节。
一、核心数学方程式
给定输入序列的矩阵表示 X(其形状通常为 (序列长度, d_model),即 (n, d_model)),通过线性变换得到查询矩阵 Q、键矩阵 K 和值矩阵 V 的方程式如下:
Q=X⋅WQ
K=X⋅WK
V=X⋅WV
其中:
- X:输入矩阵(通常是词嵌入向量与位置编码相加后的结果)。
- WQ,WK,WV:模型可学习的参数矩阵(即权重矩阵),通过训练数据学习得到。
- Q,K,V:分别代表查询矩阵、键矩阵和值矩阵。
二、维度详解
理解这些矩阵的维度非常重要:
- 输入矩阵 X: 维度为
(n, d_model) - 权重矩阵 WQ 和 WK: 维度通常为
(d_model, d_k) - 权重矩阵 WV: 维度通常为
(d_model, d_v) - 输出矩阵 Q 和 K: 维度为
(n, d_k) - 输出矩阵 V: 维度为
(n, d_v)
在多头注意力机制中,通常会将 dmodel 维度平均分配给每个头(head),即 dk=dv=dmodel/h(h 为头的数量)。每个头都有自己独立的 WiQ,WiK,WiV 矩阵,允许模型从不同角度关注信息。
三、权重矩阵的特性与功能
这三个权重矩阵各有其独特的功能和特点,下表总结了它们的核心特性:
| 特性 | 权重矩阵 WQ | 权重矩阵 WK | 权重矩阵 WV |
|---|---|---|---|
| 核心作用 | 将输入投影到查询空间,用于“询问”其他位置的信息 | 将输入投影到键空间,用于被其他位置的查询“匹配” | 将输入投影到值空间,提供实际的内容信息 |
| 数学表示 | Q=X⋅WQ | K=X⋅WK | V=X⋅WV |
| 维度 | (dmodel,dk) | (dmodel,dk) | (dmodel,dv) |
| 是否可学习 | ✅ 是,通过反向传播和梯度下降进行优化 | ✅ 是,通过反向传播和梯度下降进行优化 | ✅ 是,通过反向传播和梯度下降进行优化 |
| 参数共享 | 同一层内所有位置共享相同的 WQ | 同一层内所有位置共享相同的 WK | 同一层内所有位置共享相同的 WV |
| 功能视角 | 学习“当前词想找什么”的映射规则 | 学习“当前词是什么”的映射规则 | 学习“当前词的详细信息是什么”的映射规则 |
四、在注意力机制中的完整计算
这些权重矩阵生成的 Q, K, V 会进一步用于计算缩放点积注意力 (Scaled Dot-Product Attention),其完整公式为:
Attention(Q,K,V)=softmax(dkQKT)V
其中:
- QKT:计算查询和键之间的相似度分数。
- dk:缩放因子,用于控制点积结果的数量级,防止梯度消失。
- softmax:将注意力分数转换为概率分布。
- 最终输出是使用注意力权重对值向量 V 进行加权求和的结果。
五、关键要点
- 可学习参数:WQ, WK, WV 是模型通过训练学习得到的参数,其初始值通常采用 Xavier 或 He 初始化 方法。
- 独立的功能:使用独立的权重矩阵(而非共享参数)是为了让模型能更灵活地学习到输入序列在不同空间(查询、键、值)的表示,从而更精确地计算注意力权重。
- 计算效率:所有这些矩阵运算都可以通过矩阵操作高效完成,并充分利用 GPU 进行并行计算。
Transformer大语言模型训练全过程数学推导
推导Transformer大语言模型在预训练阶段的所有数学过程,包括前向传播、损失计算、反向传播、梯度优化等。
一、模型架构与符号定义
1.1 模型整体架构
输入序列: X = [x₁, x₂, ..., x_T] ∈ ℝ^{T×V} (one-hot编码)
词嵌入: E ∈ ℝ^{V×d_model}
位置编码: P ∈ ℝ^{T×d_model}
模型输出: L ∈ ℝ^{T×V} (logits)
1.2 模型层定义
-
词嵌入层: W_e ∈ ℝ^{V×d_{model}}
-
位置编码: P ∈ ℝ^{T×d_{model}}
-
L个Decoder层
-
输出层: W_o ∈ ℝ^{d_{model}×V} (通常与词嵌入权重绑定)
-
LayerNorm参数: γ, β ∈ ℝ^{d_{model}}
-
注意力参数: W_Q^l, W_K^l, W_V^l ∈ ℝ^{d_{model}×d_{model}}, W_O^l ∈ ℝ^{d_{model}×d_{model}}
-
FFN参数: W_1^l ∈ ℝ^{d_{model}×d_{ff}}, W_2^l ∈ ℝ^{d_{ff}×d_{model}}, b_1^l ∈ ℝ^{d_{ff}}, b_2^l ∈ ℝ^{d_{model}}
二、完整前向传播推导
2.1 输入预处理
步骤1: 词嵌入查找
输入序列 X ∈ ℕ^T (词索引序列) → 转换为one-hot: X_{\text{one-hot}} ∈ ℝ^{T×V}
词嵌入: E = X_{\text{one-hot}} W_e,其中 W_e ∈ ℝ^{V×d_{model}}
数值示例:
-
词汇表大小 V=50000
-
模型维度 d_model=768
-
序列长度 T=1024
-
E ∈ ℝ^{1024×768}
步骤2: 添加位置编码
H^0 = E + P
其中 P 是正弦位置编码:
P_{t,2i} = \sin\left(\frac{t}{10000^{2i/d_{model}}}\right)
P_{t,2i+1} = \cos\left(\frac{t}{10000^{2i/d_{model}}}\right)
数值:H^0 ∈ ℝ^{1024×768}
2.2 第l层Decoder前向传播
2.2.1 掩码自注意力子层
输入: H^{l-1} ∈ ℝ^{T×d_{model}}
步骤1: 线性变换得到Q,K,V
Q^l = H^{l-1} W_Q^l, \quad W_Q^l ∈ ℝ^{d_{model}×d_{model}}
K^l = H^{l-1} W_K^l, \quad W_K^l ∈ ℝ^{d_{model}×d_{model}}
V^l = H^{l-1} W_V^l, \quad W_V^l ∈ ℝ^{d_{model}×d_{model}}
数值: Q^l, K^l, V^l ∈ ℝ^{1024×768}
步骤2: 多头拆分
将 Q^l, K^l, V^l 重塑为多头形式:
-
头数 h=12
-
每个头维度 d_k = d_v = d_{model}/h = 768/12 = 64
Q^{l,h} ∈ ℝ^{1024×12×64}, \quad K^{l,h} ∈ ℝ^{1024×12×64}, \quad V^{l,h} ∈ ℝ^{1024×12×64}
步骤3: 计算缩放点积注意力(带掩码)
对于每个头 h:
\text{Attention}^l_h = \text{softmax}\left(\frac{Q^{l,h} (K^{l,h})^T}{\sqrt{d_k}} + M\right) V^{l,h}
掩码矩阵 M ∈ ℝ^{T×T}:
M_{ij} =
\begin{cases}
0, & i \geq j \ (\text{允许关注当前及之前位置})\\
-\infty, & i < j \ (\text{屏蔽未来位置})
\end{cases}
数值推导:
-
计算 Q^{l,h}(K^{l,h})^T: (1024×64) × (64×1024) → 1024×1024
-
除以 \sqrt{64} = 8
-
加掩码: 上三角设为 -∞
-
Softmax: 每一行和为1
-
乘以 V^{l,h}: (1024×1024) × (1024×64) → 1024×64
步骤4: 多头拼接
将12个头的输出拼接:
\text{MultiHead}^l = \text{Concat}(\text{Attention}^l_1, ..., \text{Attention}^l_{12}) ∈ ℝ^{1024×768}
步骤5: 输出投影
\text{AttnOutput}^l = \text{MultiHead}^l W_O^l, \quad W_O^l ∈ ℝ^{768×768}
步骤6: 残差连接和LayerNorm
Z^l_{\text{attn}} = \text{LayerNorm}(H^{l-1} + \text{AttnOutput}^l)
LayerNorm计算:
\mu = \frac{1}{d_{model}} \sum_{i=1}^{d_{model}} x_i
\sigma^2 = \frac{1}{d_{model}} \sum_{i=1}^{d_{model}} (x_i - \mu)^2
\text{LayerNorm}(x) = \gamma \odot \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}} + \beta
其中 \epsilon = 10^{-5}, \gamma, \beta ∈ ℝ^{768} 是可学习参数。
2.2.2 前馈神经网络子层
输入: Z^l_{\text{attn}} ∈ ℝ^{1024×768}
步骤1: 第一层线性变换
A_1^l = Z^l_{\text{attn}} W_1^l + b_1^l
其中 W_1^l ∈ ℝ^{768×3072} (通常 d_{ff} = 4×d_{model}), b_1^l ∈ ℝ^{3072}
步骤2: 激活函数
A_2^l = \text{ReLU}(A_1^l) = \max(0, A_1^l) ∈ ℝ^{1024×3072}
步骤3: 第二层线性变换
\text{FFNOutput}^l = A_2^l W_2^l + b_2^l
其中 W_2^l ∈ ℝ^{3072×768}, b_2^l ∈ ℝ^{768}
步骤4: 残差连接和LayerNorm
H^l = \text{LayerNorm}(Z^l_{\text{attn}} + \text{FFNOutput}^l) ∈ ℝ^{1024×768}
2.3 输出层
经过L层后得到 H^L ∈ ℝ^{1024×768}
线性变换到词汇表:
L = H^L W_o ∈ ℝ^{1024×50000}
其中 W_o ∈ ℝ^{768×50000}
可选: 权重绑定,即 W_o = W_e^T (词嵌入矩阵的转置)
2.4 损失计算
步骤1: Softmax计算概率
对于位置 t:
P_t = \text{softmax}(L_t) = \frac{\exp(L_t)}{\sum_{j=1}^V \exp(L_{t,j})} ∈ ℝ^{V}
步骤2: 交叉熵损失
目标序列: Y = [y_1, y_2, ..., y_T],其中 y_t 是下一个词的索引
损失函数:
\mathcal{L} = -\frac{1}{T} \sum_{t=1}^{T} \log P_t[y_t]
其中 P_t[y_t] 是 P_t 在第 y_t 个位置的值。
数值示例:
-
如果 y_t = 42 (词索引42)
-
则 \log P_t[42] 是预测词42的对数概率
-
总损失是所有位置的平均负对数似然
三、反向传播(梯度计算)推导
3.1 损失函数的梯度
设 L_t ∈ ℝ^V 是位置t的logits,P_t = \text{softmax}(L_t)
\frac{\partial \mathcal{L}}{\partial L_{t,j}} = P_{t,j} - \delta_{j,y_t}
其中 \delta_{j,y_t} 是Kronecker delta函数:
\delta_{j,y_t} =
\begin{cases}
1, & j = y_t \\
0, & j \neq y_t
\end{cases}
证明:
\mathcal{L} = -\sum_{t=1}^T \log P_t[y_t] = -\sum_{t=1}^T \log \frac{\exp(L_{t,y_t})}{\sum_{k=1}^V \exp(L_{t,k})}
\frac{\partial \mathcal{L}}{\partial L_{t,j}} = -\frac{\partial}{\partial L_{t,j}} \left[ L_{t,y_t} - \log \sum_{k=1}^V \exp(L_{t,k}) \right]
= -\left[ \delta_{j,y_t} - \frac{\exp(L_{t,j})}{\sum_{k=1}^V \exp(L_{t,k})} \right]
= P_{t,j} - \delta_{j,y_t}
梯度矩阵: \frac{\partial \mathcal{L}}{\partial L} ∈ ℝ^{T×V}
3.2 输出层梯度
L = H^L W_o
梯度计算:
\frac{\partial \mathcal{L}}{\partial W_o} = (H^L)^T \frac{\partial \mathcal{L}}{\partial L} ∈ ℝ^{768×50000}
\frac{\partial \mathcal{L}}{\partial H^L} = \frac{\partial \mathcal{L}}{\partial L} W_o^T ∈ ℝ^{1024×768}
3.3 第L层反向传播
3.3.1 LayerNorm梯度
设 x = Z^L_{\text{attn}} + \text{FFNOutput}^L,y = \text{LayerNorm}(x)
y_i = \gamma_i \hat{x}_i + \beta_i, \quad \hat{x}_i = \frac{x_i - \mu}{\sqrt{\sigma^2 + \epsilon}}
\mu = \frac{1}{d} \sum_{k=1}^d x_k, \quad \sigma^2 = \frac{1}{d} \sum_{k=1}^d (x_k - \mu)^2
梯度计算:
\frac{\partial \mathcal{L}}{\partial x_i} = \sum_{j=1}^d \frac{\partial \mathcal{L}}{\partial y_j} \frac{\partial y_j}{\partial x_i}
\frac{\partial y_j}{\partial x_i} = \gamma_j \cdot \frac{\partial \hat{x}_j}{\partial x_i}
\frac{\partial \hat{x}_j}{\partial x_i} = \frac{\delta_{ij} - \frac{1}{d} - \hat{x}_j \cdot \frac{1}{d} \sum_{k=1}^d \hat{x}_k (\delta_{ik} - \frac{1}{d})}{\sqrt{\sigma^2 + \epsilon}}
其中 \delta_{ij} 是Kronecker delta。
简化公式:
设 \hat{x} = \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}},\frac{\partial \mathcal{L}}{\partial \hat{x}} = \frac{\partial \mathcal{L}}{\partial y} \odot \gamma
则:
\frac{\partial \mathcal{L}}{\partial \sigma^2} = \sum_{i=1}^d \frac{\partial \mathcal{L}}{\partial \hat{x}_i} \cdot (x_i - \mu) \cdot \left(-\frac{1}{2}(\sigma^2 + \epsilon)^{-3/2}\right)
\frac{\partial \mathcal{L}}{\partial \mu} = \left(\sum_{i=1}^d \frac{\partial \mathcal{L}}{\partial \hat{x}_i} \cdot \frac{-1}{\sqrt{\sigma^2 + \epsilon}}\right) + \frac{\partial \mathcal{L}}{\partial \sigma^2} \cdot \frac{-2}{d} \sum_{i=1}^d (x_i - \mu)
\frac{\partial \mathcal{L}}{\partial x_i} = \frac{\partial \mathcal{L}}{\partial \hat{x}_i} \cdot \frac{1}{\sqrt{\sigma^2 + \epsilon}} + \frac{\partial \mathcal{L}}{\partial \sigma^2} \cdot \frac{2(x_i - \mu)}{d} + \frac{\partial \mathcal{L}}{\partial \mu} \cdot \frac{1}{d}
参数梯度:
\frac{\partial \mathcal{L}}{\partial \gamma} = \sum_{i=1}^d \frac{\partial \mathcal{L}}{\partial y_i} \odot \hat{x}_i
\frac{\partial \mathcal{L}}{\partial \beta} = \sum_{i=1}^d \frac{\partial \mathcal{L}}{\partial y_i}
3.3.2 FFN子层梯度
输出层梯度:
设 C = Z^L_{\text{attn}} + \text{FFNOutput}^L,\text{FFNOutput}^L = A_2^L W_2^L + b_2^L
\frac{\partial \mathcal{L}}{\partial W_2^L} = (A_2^L)^T \frac{\partial \mathcal{L}}{\partial C} ∈ ℝ^{3072×768}
\frac{\partial \mathcal{L}}{\partial b_2^L} = \sum_{t=1}^T \frac{\partial \mathcal{L}}{\partial C_t} ∈ ℝ^{768}
\frac{\partial \mathcal{L}}{\partial A_2^L} = \frac{\partial \mathcal{L}}{\partial C} (W_2^L)^T ∈ ℝ^{1024×3072}
激活层梯度:
A_2^L = \text{ReLU}(A_1^L)
\frac{\partial \mathcal{L}}{\partial A_1^L} = \frac{\partial \mathcal{L}}{\partial A_2^L} \odot \mathbb{I}(A_1^L > 0)
其中 \mathbb{I}(A_1^L > 0) 是指示函数,大于0的位置为1,否则为0。
第一层梯度:
A_1^L = Z^L_{\text{attn}} W_1^L + b_1^L
\frac{\partial \mathcal{L}}{\partial W_1^L} = (Z^L_{\text{attn}})^T \frac{\partial \mathcal{L}}{\partial A_1^L} ∈ ℝ^{768×3072}
\frac{\partial \mathcal{L}}{\partial b_1^L} = \sum_{t=1}^T \frac{\partial \mathcal{L}}{\partial A_{1,t}^L} ∈ ℝ^{3072}
\frac{\partial \mathcal{L}}{\partial Z^L_{\text{attn}}} = \frac{\partial \mathcal{L}}{\partial A_1^L} (W_1^L)^T + \frac{\partial \mathcal{L}}{\partial C} \ (\text{来自残差连接})
3.3.3 注意力子层梯度
自注意力输出梯度:
设 D = H^{L-1} + \text{AttnOutput}^L,\text{AttnOutput}^L = \text{MultiHead}^L W_O^L
\frac{\partial \mathcal{L}}{\partial W_O^L} = (\text{MultiHead}^L)^T \frac{\partial \mathcal{L}}{\partial D} ∈ ℝ^{768×768}
\frac{\partial \mathcal{L}}{\partial \text{MultiHead}^L} = \frac{\partial \mathcal{L}}{\partial D} (W_O^L)^T ∈ ℝ^{1024×768}
多头注意力梯度:
设多头注意力输出是12个头拼接: \text{MultiHead}^L = [\text{head}_1; ...; \text{head}_{12}]
对每个头 h:
\frac{\partial \mathcal{L}}{\partial \text{head}_h} = \text{slice}\left(\frac{\partial \mathcal{L}}{\partial \text{MultiHead}^L}, h\right) ∈ ℝ^{1024×64}
注意力计算梯度:
设 \text{head}_h = \text{softmax}(S_h) V_h,其中 S_h = \frac{Q_h K_h^T}{\sqrt{d_k}} + M
定义 A_h = \text{softmax}(S_h) ∈ ℝ^{T×T}
步骤1: 对V的梯度
\frac{\partial \mathcal{L}}{\partial V_h} = A_h^T \frac{\partial \mathcal{L}}{\partial \text{head}_h} ∈ ℝ^{1024×64}
步骤2: 对注意力权重A的梯度
\frac{\partial \mathcal{L}}{\partial A_h} = \frac{\partial \mathcal{L}}{\partial \text{head}_h} V_h^T ∈ ℝ^{1024×1024}
步骤3: 对S的梯度
设 A_h = \text{softmax}(S_h),则:
对于 i = 1,...,T, j = 1,...,T:
\frac{\partial \mathcal{L}}{\partial S_{h,ij}} = A_{h,ij} \left( \frac{\partial \mathcal{L}}{\partial A_{h,ij}} - \sum_{k=1}^T A_{h,ik} \frac{\partial \mathcal{L}}{\partial A_{h,ik}} \right)
矩阵形式:
\frac{\partial \mathcal{L}}{\partial S_h} = A_h \odot \left( \frac{\partial \mathcal{L}}{\partial A_h} - \text{row\_sum}\left(A_h \odot \frac{\partial \mathcal{L}}{\partial A_h}\right) \cdot \mathbf{1}^T \right)
其中 \odot 是逐元素相乘,\text{row\_sum} 是行求和。
步骤4: 对Q,K的梯度
由于 S_h = \frac{Q_h K_h^T}{\sqrt{d_k}} + M
\frac{\partial \mathcal{L}}{\partial Q_h} = \frac{1}{\sqrt{d_k}} \frac{\partial \mathcal{L}}{\partial S_h} K_h ∈ ℝ^{1024×64}
\frac{\partial \mathcal{L}}{\partial K_h} = \frac{1}{\sqrt{d_k}} \left(\frac{\partial \mathcal{L}}{\partial S_h}\right)^T Q_h ∈ ℝ^{1024×64}
合并多头:
将12个头的梯度合并:
\frac{\partial \mathcal{L}}{\partial Q} = \text{concat}\left(\frac{\partial \mathcal{L}}{\partial Q_1}, ..., \frac{\partial \mathcal{L}}{\partial Q_{12}}\right) ∈ ℝ^{1024×768}
类似地计算 \frac{\partial \mathcal{L}}{\partial K} 和 \frac{\partial \mathcal{L}}{\partial V}
步骤5: 对投影矩阵的梯度
Q = H^{L-1} W_Q^L, K = H^{L-1} W_K^L, V = H^{L-1} W_V^L
\frac{\partial \mathcal{L}}{\partial W_Q^L} = (H^{L-1})^T \frac{\partial \mathcal{L}}{\partial Q} ∈ ℝ^{768×768}
\frac{\partial \mathcal{L}}{\partial W_K^L} = (H^{L-1})^T \frac{\partial \mathcal{L}}{\partial K} ∈ ℝ^{768×768}
\frac{\partial \mathcal{L}}{\partial W_V^L} = (H^{L-1})^T \frac{\partial \mathcal{L}}{\partial V} ∈ ℝ^{768×768}
\frac{\partial \mathcal{L}}{\partial H^{L-1}} = \frac{\partial \mathcal{L}}{\partial Q} (W_Q^L)^T + \frac{\partial \mathcal{L}}{\partial K} (W_K^L)^T + \frac{\partial \mathcal{L}}{\partial V} (W_V^L)^T + \frac{\partial \mathcal{L}}{\partial D} \ (\text{来自残差连接})
步骤6: 对输入H^{L-1}的梯度
\frac{\partial \mathcal{L}}{\partial H^{L-1}} = \frac{\partial \mathcal{L}}{\partial \text{LayerNorm}_{\text{attn}}} + \frac{\partial \mathcal{L}}{\partial D} \ (\text{来自注意力残差连接})
其中 \frac{\partial \mathcal{L}}{\partial \text{LayerNorm}_{\text{attn}}} 是通过注意力子层的LayerNorm的梯度。
3.4 逐层反向传播
类似地,对每一层 l = L-1, L-2, ..., 1 重复上述过程,计算:
-
LayerNorm的梯度
-
FFN的梯度 (W_1^l, b_1^l, W_2^l, b_2^l)
-
注意力的梯度 (W_Q^l, W_K^l, W_V^l, W_O^l)
-
LayerNorm参数梯度 (\gamma^l, \beta^l)
3.5 输入层梯度
词嵌入梯度:
E = X_{\text{one-hot}} W_e
\frac{\partial \mathcal{L}}{\partial W_e} = X_{\text{one-hot}}^T \frac{\partial \mathcal{L}}{\partial H^0} ∈ ℝ^{V×768}
位置编码梯度:
\frac{\partial \mathcal{L}}{\partial P} = \frac{\partial \mathcal{L}}{\partial H^0}
由于位置编码是固定的正弦编码,通常不更新。如果是可学习的位置编码,则更新。
四、优化器更新(Adam优化器)
4.1 Adam优化器公式
参数: \theta (所有可训练参数)
梯度: g_t = \nabla_\theta \mathcal{L}(\theta_{t-1})
一阶矩估计:
m_t = \beta_1 m_{t-1} + (1-\beta_1) g_t
二阶矩估计:
v_t = \beta_2 v_{t-1} + (1-\beta_2) g_t^2
偏差校正:
\hat{m}_t = \frac{m_t}{1 - \beta_1^t}
\hat{v}_t = \frac{v_t}{1 - \beta_2^t}
参数更新:
\theta_t = \theta_{t-1} - \eta \cdot \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon}
默认参数:
-
\beta_1 = 0.9, \beta_2 = 0.999
-
\epsilon = 10^{-8}
-
\eta: 学习率
4.2 学习率调度
预热(Warmup) + 余弦衰减:
\text{learning\_rate} =
\begin{cases}
\frac{t}{t_{\text{warmup}}} \cdot \eta_{\max}, & t < t_{\text{warmup}} \\
\frac{1}{2} \eta_{\max} \left(1 + \cos\left(\pi \cdot \frac{t - t_{\text{warmup}}}{t_{\text{total}} - t_{\text{warmup}}}\right)\right), & t \geq t_{\text{warmup}}
\end{cases}
或线性衰减:
\text{learning\_rate} = \eta_{\max} \cdot \max\left(0, 1 - \frac{t}{t_{\text{total}}}\right)
4.3 梯度裁剪
g_t \leftarrow g_t \cdot \min\left(1, \frac{\text{clip\_norm}}{\|g_t\|_2}\right)
其中 \|g_t\|_2 是梯度的L2范数,\text{clip\_norm} 是裁剪阈值(如1.0)。
五、训练过程数学公式总结
5.1 前向传播流程
输入: X ∈ ℕ^T (词索引)
1. 词嵌入: E = one_hot(X) W_e ∈ ℝ^{T×d}
2. 加位置编码: H⁰ = E + P
3. 对于 l = 1 到 L:
a. 注意力:
Q = H^{l-1} W_Q^l, K = H^{l-1} W_K^l, V = H^{l-1} W_V^l
A = softmax(QK^T/√d_k + M)V
Attn = Concat(A_1,...,A_h) W_O^l
Z = LayerNorm(H^{l-1} + Attn)
b. FFN:
FFN = ReLU(Z W_1^l + b_1^l) W_2^l + b_2^l
H^l = LayerNorm(Z + FFN)
4. 输出: L = H^L W_o ∈ ℝ^{T×V}
5. 损失: ℒ = -1/T Σ_{t=1}^T log softmax(L_t)[y_t]
5.2 反向传播关键梯度
| 层类型 | 参数 | 梯度公式 | 维度 |
|---|---|---|---|
| 输出层 | W_o | \frac{\partial \mathcal{L}}{\partial W_o} = (H^L)^T \frac{\partial \mathcal{L}}{\partial L} | d×V |
| LayerNorm | \gamma, \beta | \frac{\partial \mathcal{L}}{\partial \gamma} = \sum \frac{\partial \mathcal{L}}{\partial y} \odot \hat{x} | d |
| FFN | W_1^l, b_1^l | \frac{\partial \mathcal{L}}{\partial W_1^l} = (Z^l)^T \frac{\partial \mathcal{L}}{\partial A_1^l} | d×4d |
| FFN | W_2^l, b_2^l | \frac{\partial \mathcal{L}}{\partial W_2^l} = (A_2^l)^T \frac{\partial \mathcal{L}}{\partial C} | 4d×d |
| 注意力 | W_Q^l, W_K^l, W_V^l | \frac{\partial \mathcal{L}}{\partial W_Q^l} = (H^{l-1})^T \frac{\partial \mathcal{L}}{\partial Q} | d×d |
| 注意力 | W_O^l | \frac{\partial \mathcal{L}}{\partial W_O^l} = (\text{MultiHead}^l)^T \frac{\partial \mathcal{L}}{\partial D} | d×d |
| 词嵌入 | W_e | \frac{\partial \mathcal{L}}{\partial W_e} = X^T \frac{\partial \mathcal{L}}{\partial H^0} | V×d |
5.3 计算复杂度分析
前向传播:
-
注意力: O(T^2 d)
-
FFN: O(T d^2)
-
总复杂度: O(L(T^2 d + T d^2))
反向传播:
-
大约是前向传播的2-3倍
-
需要存储中间激活值用于梯度计算
内存消耗:
-
参数: O(L d^2)
-
激活值: O(L T d)
-
梯度: O(L d^2)
-
优化器状态(Adam): O(2L d^2) (m和v)
六、训练超参数与数值稳定性
6.1 权重初始化
Xavier/Glorot初始化:
对于线性层 y = Wx + b:
W \sim \mathcal{U}\left(-\sqrt{\frac{6}{n_{in} + n_{out}}}, \sqrt{\frac{6}{n_{in} + n_{out}}}\right)
Kaiming/He初始化 (适合ReLU):
W \sim \mathcal{N}\left(0, \sqrt{\frac{2}{n_{in}}}\right)
注意力投影初始化:
-
W_Q, W_K, W_V: 通常用较小标准差初始化
-
W_O: Xavier初始化
6.2 数值稳定性技巧
1. 梯度裁剪:
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
2. 权重衰减 (L2正则化):
\mathcal{L}_{\text{total}} = \mathcal{L} + \lambda \sum_i \|W_i\|_2^2
3. 混合精度训练:
-
使用FP16进行前向传播和反向传播
-
使用FP32存储主权重和进行优化器更新
-
损失缩放防止下溢
4. 激活检查点 (Gradient Checkpointing):
-
只存储部分层的激活值
-
在反向传播时重新计算其他激活值
-
时间换空间,减少内存消耗
6.3 损失函数扩展
标签平滑:
目标分布从one-hot变为:
y' = (1-\epsilon) y_{\text{one-hot}} + \epsilon / V
序列级损失:
除了交叉熵,还可加辅助损失:
\mathcal{L}_{\text{total}} = \mathcal{L}_{\text{CE}} + \alpha \mathcal{L}_{\text{aux}}
七、分布式训练数学
7.1 数据并行
梯度平均:
设 K 个GPU,每个GPU的梯度为 g_k,平均梯度:
\bar{g} = \frac{1}{K} \sum_{k=1}^K g_k
同步SGD:
所有GPU计算梯度后同步,然后更新参数。
异步SGD:
GPU独立更新,可能导致梯度过时。
7.2 模型并行
张量并行 (Tensor Parallelism):
将矩阵乘法分块计算。例如 Y = XW,W 被切分到多个GPU。
流水线并行 (Pipeline Parallelism):
将模型层分配到不同GPU,微批次流水线执行。
序列并行 (Sequence Parallelism):
将序列维度分到多个GPU,适合长序列。
7.3 ZeRO优化器 (Zero Redundancy Optimizer)
ZeRO Stage 1: 优化器状态分区
-
每个GPU只存储部分优化器状态
-
减少内存约4倍
ZeRO Stage 2: 梯度分区
-
每个GPU只存储部分梯度
-
减少内存约8倍
ZeRO Stage 3: 参数分区
-
每个GPU只存储部分参数
-
前向/反向传播时广播/收集参数
-
减少内存与GPU数成正比
八、完整训练流程示例
8.1 GPT-3 175B参数训练示例
模型配置:
-
参数: 175B
-
层数: L=96
-
维度: d_model=12288
-
头数: h=96
-
FFN维度: d_ff=4×12288=49152
-
序列长度: T=2048
-
批次大小: 3.2M tokens (512个序列,每个2048)
内存计算:
-
参数: 175B × 2字节(FP16) = 350GB
-
梯度: 175B × 2字节 = 350GB
-
优化器状态(Adam): 175B × 2 × 2字节 = 700GB
-
激活值: ~1TB
-
总计: >2TB → 需要模型并行+数据并行
训练步骤:
1. 初始化: 参数随机初始化,优化器状态清零
2. 数据加载: 加载3.2M tokens
3. 前向传播: 计算损失
4. 反向传播: 计算梯度
5. 优化器更新: Adam更新参数
6. 重复2-5步,直到收敛
训练时间:
-
GPT-3 175B: 使用1024个A100训练约34天
-
总计算量: ~3.14×10²³ FLOPs
8.2 损失曲线分析
损失通常遵循幂律:
\mathcal{L}(N) = \frac{a}{N^b} + c
其中 N 是训练tokens数,a, b, c 是常数。
Chinchilla定律:
最优计算分配:
N_{\text{opt}} = 20 \cdot P_{\text{params}}, \quad D_{\text{opt}} = 40 \cdot P_{\text{params}}
其中 N_{\text{opt}} 是训练tokens数,D_{\text{opt}} 是数据集大小,P_{\text{params}} 是参数数量。
九、数学公式总结表
| 组件 | 前向传播 | 反向传播梯度 | 时间复杂度 | 空间复杂度 |
|---|---|---|---|---|
| 词嵌入 | E = XW_e | \frac{\partial \mathcal{L}}{\partial W_e} = X^T \frac{\partial \mathcal{L}}{\partial E} | O(TVd) | O(Td) |
| 注意力 | A=\text{softmax}(QK^T/√d)V | \frac{\partial \mathcal{L}}{\partial Q}=\frac{1}{√d}\frac{\partial \mathcal{L}}{\partial S}K | O(T^2d) | O(T^2) |
| FFN | \text{FFN}(x)=\text{ReLU}(xW_1)W_2 | \frac{\partial \mathcal{L}}{\partial W_1}=X^T\frac{\partial \mathcal{L}}{\partial A_1} | O(Td^2) | O(Td) |
| LayerNorm | y=\frac{x-\mu}{σ}γ+β | \frac{\partial \mathcal{L}}{\partial x}=\frac{γ}{σ}(I-\frac{1}{d}11^T)(I-\hat{x}\hat{x}^T)\frac{\partial \mathcal{L}}{\partial y} | O(Td) | O(Td) |
| Softmax | p_i=\frac{e^{x_i}}{∑_j e^{x_j}} | \frac{\partial \mathcal{L}}{\partial x_i}=p_i-δ_{i,y} | O(TV) | O(TV) |
| Adam | \theta_t=\theta_{t-1}-η\frac{\hat{m}_t}{√{\hat{v}_t}+ϵ} | m_t=β_1m_{t-1}+(1-β_1)g_t | O(P) | O(P) |
十、实际训练技巧
10.1 学习率调度策略
线性预热 + 余弦衰减:
learning_rate = min(
current_step / warmup_steps * max_lr,
max_lr * 0.5 * (1 + cos(π * (current_step - warmup_steps) / (total_steps - warmup_steps)))
)
OneCycle策略:
先线性增加到最大,再余弦衰减到最小。
10.2 批次大小调整
线性缩放规则:
当批次大小乘以k,学习率也乘以k。
热身阶段:
开始时用小批次,逐渐增加。
10.3 权重衰减
解耦权重衰减 (AdamW):
\theta_t = \theta_{t-1} - η\left(\frac{\hat{m}_t}{√{\hat{v}_t}+ϵ} + λ\theta_{t-1}\right)
10.4 梯度累积
对于大模型,实际批次大小 = 设备数 × 每设备批次大小 × 梯度累积步数
for i in range(gradient_accumulation_steps):
loss = model(batch[i])
loss.backward() # 累积梯度
if (step + 1) % gradient_accumulation_steps == 0:
optimizer.step()
optimizer.zero_grad()
结论
Transformer大语言模型训练是一个复杂的数学过程,涉及:
-
前向传播: 词嵌入 → 位置编码 → L层Transformer → 输出层 → 损失计算
-
反向传播: 从损失反向传播梯度,计算所有参数梯度
-
优化器更新: Adam优化器更新参数
-
分布式训练: 数据并行、模型并行、流水线并行
-
数值稳定性: 混合精度、梯度裁剪、权重衰减
训练过程需要精心调优超参数,管理内存和计算资源,才能成功训练出百亿甚至千亿参数的大模型。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)