下面,我们将跳出“注意力机制就像人类注意力”这种高层隐喻,直接将视角下切到张量、算子、反向传播与内存总线上。

1. 词嵌入(Word Embedding)的极度细节
数学本质:Look-up Table 的物理实现
在代码层面,Embedding 并非是一个复杂的“网络层”,而是一个参数矩阵
当输入一个离散的 Token ID序列(如
在数学上,这等价于将一个 One-hot 向量
物理意义:它将互相正交的高维稀疏空间(One-hot)投影到了一个稠密的、具有内积度量意义的低维连续几何空间中。在这个连续空间里,向量的方向和模长编码了语义和语法关系。
训练机制与 的神秘缩放
Embedding 矩阵
为什么要乘以
- 通常 Embedding 矩阵在初始化时采用标准正态分布(或均匀分布),其激活值的方差近似为 1,但权重的绝对数值较小。
- PE 是通过
和 生成的,其数值稳定分布在 [-1, 1] 之间。
如果不进行缩放,随着
共享机制:Weight Tying 策略
在工业级模型中,底层的输入 Embedding 矩阵
- 数学意义:输出层计算的是上下文向量
与候选词向量的内积(相似度)。共享权重意味着“将词编码为特征”和“从特征解码回词”是在完全相同的语义度量空间中进行的。 - 工程好处:参数量骤降。对于词表
的配置,节省了约 50MB 的显存。同时,这也作为一种极强的正则化手段,防止了模型在大量低频词上过拟合。
2. 参数矩阵的构造与训练( )
参数初始化:Xavier/Glorot 的工程考量
在代码实现中,
为什么? 在未经训练的深度线性网络中,方差会随着层数呈指数级放大或缩小。Xavier 初始化通过绑定输入维度(fan_in)和输出维度(fan_out),使得前向传播时的激活值方差和反向传播时的梯度方差在每一层保持恒定:
这防止了初始状态下 Softmax 极速陷入饱和区。
多头并行的代码级映射( 与 )
在工业实践中,绝对不会用
- 输入 X 形状:
- 单一矩阵乘法:计算
,结果形状仍为 。 - 多头切分(Reshape & Transpose):将张量 Reshape 为
,然后进行维度转置(Transpose/Permute)为 。
此时,多头(
梯度流向与 Bias 选择
- 梯度流(链式法则):前向 Loss 标量通过 Softmax 的雅可比矩阵回传,变成注意力矩阵
上的梯度矩阵。随后梯度分支:一路通过 传向 ,另一路通过 传向 。由于 , 。最终所有梯度汇聚回张量 ,再沿残差路径直达 Embedding 层。 - Bias 项考量:在 BERT 时代,Linear 层普遍带有 Bias。但在现代 LLM(如 LLaMA, GPT-3 的部分实现)中,
通常直接干掉 Bias。原因是:1) Bias 在极高维度的内积空间中对模型表达能力的提升微乎其微;2) 去除 Bias 可以提升算子融合(Kernel Fusion)的效率,减少显存读写带宽。
3. 训练全流程的数值稳定性(工程核心)
LayerNorm 的工程实现与
在张量层面,LayerNorm 并非在 Batch 或 Seq 维度计算,而是严格在特征维度
Pre-LN vs Post-LN 的架构之争
| 特性 | Post-LN (原版 Transformer) | Pre-LN (现代 LLM,如 GPT/LLaMA) |
|---|---|---|
| 公式 | ||
| 恒等路径 | 被 LN 打断 | 完美的 |
| 梯度流动 | 顶部梯度向底层传递时被 LN 缩放,容易引起深层梯度弥散/爆炸。 | 梯度可以无损穿透至第一层。 |
| Warmup依赖 | 极度依赖,缺少 Warmup 必炸。 | 相对鲁棒,收敛更平稳。 |
Scaled Dot-Product 的数学必要性(方差推导)
假设
在计算点积
- 均值:
- 方差:
因此,点积总和的方差为:
工程灾难:当
解法:除以
4. 损失函数与收敛策略
Label Smoothing 细节
通过软化真实标签分布,缓解模型在特定词上的过度自信:
(例如
置信度影响:这使得推理时输出的 Logits 差异变得平滑,模型不会为了追求 1.0 的概率而产生极其极端的 Logit 峰值,从而使得 Beam Search 等解码算法的评分更具有泛化意义。
Teacher Forcing 与 Masking 的矩阵魔法
在工程上,为了避免像 RNN 那样串行循环,我们将整个目标序列右移(Shift Right)后一并输入 Decoder,依赖掩码(Mask)实现绝对的时间隔离。
合并掩码机制:
- Padding Mask:形状为
,值为布尔型(True 代表有效,False 代表 Pad)。 - Sequence (Look-ahead) Mask:形状为
的下三角矩阵(主对角线及以下为 True)。
张量操作:将两者做逻辑与(Logical AND),得到
接着生成掩码偏置矩阵:通过 torch.where 或类似函数,将 True 映射为 0.0,将 False 映射为一个极小的负数(如
在此矩阵中,未来的信息由于加上了
5. 优化器与学习率工程
Adam 优化器参数配置
在 Transformer 训练中,由于参数更新的极端不稳定性,标准配置通常为:
:控制动量(一阶矩)。 :控制 RMSprop(二阶矩)。在处理稀疏梯度和剧烈波动时,稍微调低 (如 0.98)有时能防止二阶矩历史信息阻碍快速步进,但大多数实现使用 0.999。
Learning Rate Warmup 的不可替代性
为何先升再降? 在训练初期,模型参数是随机初始化的,输出层 Logits 方差极大。由于 Adam 使用历史梯度的平方(二阶矩)来归一化更新步长,在最初几个 Step 内,二阶矩非常小且不稳定。如果此时给予巨大的学习率,会导致参数更新的步长越界(Overshoot),直接摧毁精心初始化的参数分布。
如果没有 Warmup 会怎样? 由于残差连接的存在和方差积累,底层 Attention 层的输出会产生巨大的突变,导致 Softmax 急剧收敛到单个 Token 上,产生**“注意力坍缩(Attention Collapse)”**。梯度立刻消失,网络表现为 Loss 挂在一个极大值,永远不下降。Warmup 给出了一个缓冲期,让 Adam 的一二阶统计量收集到足够多的稳定数据后,再全速推进。
🛠️ 工业避坑指南(Top 3 致命陷阱)
-
半精度(FP16)Mask 数值溢出: 在 FP32 中,Mask 的无效值填入
是合理的;但在混合精度(AMP)或纯 FP16 中,FP16 的能表示的最小负数下界约是 -65504。如果强行写入 ,张量会变成 -Inf 甚至 NaN,反向传播第一步直接全网 NaN。 解法:在代码中必须根据 dtype 动态获取: mask_val = torch.finfo(q.dtype).min。 -
忽略 Adam 优化器的
精度灾难: 在混合精度训练中,如果分母(二阶矩均方根)加上极小值 时, 的默认值(如 )超出了 FP16 的精度范围(FP16的最小值阈值通常在 量级)。这会导致除以零。 解法:在用 FP16 训练 Transformer 时,需手动将 Adam 的 eps 参数调整为 。 -
Weight Decay (L2 正则化) 误伤 LayerNorm 参数: 将所有模型参数无脑送入带 Weight Decay 的 Optimizer 中。LayerNorm 中的
和 参数,以及所有 Linear 层的 Bias 项,其本身维度极低且作用是保证仿射变换的平移和缩放能力。如果对其施加 Weight Decay,会限制归一化层的表达力,严重阻碍收敛。 解法:在构建优化器组时,必须使用脚本分离出所有的 LayerNorm.weight、LayerNorm.bias、*.bias等一维张量,对它们应用weight_decay = 0.0。