# 6.3 正则化策略：防止过拟合的多重手段

尽管大语言模型通常训练在海量数据上（过拟合风险较低），适当的正则化仍然对训练稳定性和泛化性能至关重要。

## 6.3.1 Dropout

**Dropout** 在训练时随机将一定比例的神经元输出置零。原始 Transformer 在以下位置应用 Dropout（率 $$P\_{\text{drop}} = 0.1$$）：

* 自注意力的权重（注意力 Dropout）
* 每个子层的输出（残差 Dropout）
* 词嵌入与位置编码相加后

Dropout 的工作原理是**防止神经元之间的共适应**——当某些神经元随时可能被关闭时，模型被迫学习更鲁棒的、分布式的特征表示，而非依赖特定的少数神经元。

值得注意的是，现代超大规模语言模型（如 GPT-3、Llama 3）通常**不使用 Dropout**。这是因为在极大规模数据上训练时，模型远未过拟合，Dropout 反而可能减慢收敛。

## 6.3.2 梯度裁剪与梯度爆炸防止

**梯度爆炸问题**：在深度网络中，梯度通过链式法则逐层反向传播。如果某层的雅可比矩阵特征值大于 1，梯度就会指数级放大。在极端情况下，梯度可能溢出为 NaN 或 Inf，完全破坏模型参数。这在长序列或深层网络中特别容易发生。

**梯度裁剪**（Gradient Clipping）是最直接的防护手段。常见的实现是按范数裁剪（L2 Clipping）：

$$\text{如果} |g| > \text{max\_norm}，\text{则} g \leftarrow g \cdot \frac{\text{max\_norm}}{|g|}$$

这确保了梯度的 L2 范数永不超过阈值，同时保留梯度的方向。在 PyTorch 中，这通过 `torch.nn.utils.clip_grad_norm_()` 实现。

常用的裁剪阈值为 1.0。在极端梯度（如遇到异常值或长序列的边界效应）出现时，梯度裁剪能防止单个批次完全摧毁训练过程。

**梯度裁剪对 Transformer 特别重要**的原因包括：

1. **注意力矩阵的尖锐性**：当 Softmax 的输入值变化剧烈时（如某些位置的值非常大），其导数可能接近零或变化剧烈，导致梯度波动
2. **长序列的累积效应**：长序列意味着梯度反向传播的路径更长，放大风险更高
3. **位置编码的相互作用**：位置编码与注意力权重的交互有时会产生数值不稳定

**梯度消失问题**虽然在现代 Transformer 中不如梯度爆炸严重（得益于残差连接和层归一化），但在极其深的模型中仍可能出现。梯度消失时，某些参数的梯度接近零，导致这些参数几乎停止更新。相比梯度爆炸的灾难性，梯度消失的危害是隐性的——模型可能能够训练，但某些早期层学习效率极低。

## 6.3.3 权重衰减

**权重衰减**（Weight Decay）在每次参数更新时对参数施加微小的收缩：

$$\theta \leftarrow (1 - \eta \lambda) \theta - \eta \nabla\_\theta \mathcal{L}$$

它倾向于使权重保持较小的值，防止模型过度依赖少数大权重特征。在与 AdamW 配合使用时，权重衰减通常设为 0.01\~0.1。

## 6.3.4 梯度累积

**梯度累积**（Gradient Accumulation）是在显存有限时扩大有效批次大小的重要技术。其基本思想是：不在每个小批次后更新参数，而是累积多个小批次的梯度后统一更新。

假设我们想要训练有效批次大小为 256，但 GPU 显存只能容纳 64 的批次，那么可以执行 4 个梯度累积步骤：

```python
accumulation_steps = 4
for i in range(accumulation_steps):
    batch = get_batch(size=64)
    loss = model(batch)
    (loss / accumulation_steps).backward()  # 梯度累积到各参数的 param.grad

optimizer.step()            # 每4个小批次后才更新一次参数
optimizer.zero_grad()
```

这里假设 `loss` 已经是每个小批次内按样本平均的标量；除以 `accumulation_steps` 后，累积梯度的尺度才与一次性使用有效批次大小 256 相匹配。对于语言模型等按 token 计算损失的任务，如果序列长度或 padding 数量不同，更稳妥的做法是对累积窗口内所有 non-padding token 的交叉熵求和，再除以该窗口的 non-padding token 总数，而不是简单平均多个小批次的 mean loss。

**梯度累积的关键性质**：

1. **等价于更大批次**：累积 N 个梯度后的参数更新等价于直接在大小为 N\*batch\_size 的批次上进行一步 SGD（在梯度噪声的相关性方面有所不同）
2. **有效批次 vs. 物理批次**：有效批次大小（梯度累积前的最终参数更新使用的样本总数）与物理批次大小（GPU 一次加载的样本数）分离，提高了训练的灵活性
3. **对学习率的影响**：学习率通常按有效批次大小调整。批次越大，学习率通常应该越大（根据批次大小的平方根法则）

**在大规模训练中的应用**：现代 LLM 训练几乎总是使用梯度累积，因为：

* 有效批次大小（通常为百万级词元数）与物理批次大小（通常数百到数千）需要在显存约束下达成
* 梯度累积允许在分布式训练中保持一致的有效批次大小，而不同节点可以使用不同的物理批次大小
* 梯度累积与梯度裁剪配合时，需要注意裁剪应在累积完所有梯度后进行，而非在每个物理批次后进行

## 6.3.5 训练稳定性的实践建议

大规模 Transformer 训练中的稳定性问题是一个持续的工程挑战。常见的实践包括：

* **损失尖峰（Loss Spike）处理**：训练过程中偶尔出现的损失突然飙升，常见原因包括：
  * 梯度爆炸：通过梯度裁剪缓解
  * 学习率过大：降低学习率或检查学习率调度
  * 数据异常：过滤训练数据中的极端值
  * 可恢复性：从最近的检查点回滚，或跳过该批次（需谨慎，可能掩盖潜在问题）
* **参数初始化**：合理的初始化（如 Xavier、Kaiming 初始化）确保各层激活值与梯度处于合理范围。对于 Transformer，多数实现采用较小的初始化标准差（如 $$\mathcal{N}(0,,0.02^2)$$）；更关键的是 **GPT-2／Megatron 的残差缩放**——把每个子层中直接写入残差流的输出投影（注意力的 $$W\_O$$、FFN 的 $$W\_2$$）额外乘以 $$1/\sqrt{2L}$$（$$L$$ 为层数；GPT-2 原文记为 $$1/\sqrt{N}$$，$$N$$ 即残差子层总数 $$2L$$）。动机与 §3.5 的残差流一脉相承：每个子层输出都累加进同一条残差流，若不缩放，$$2L$$ 次累加会让激活方差随深度近似线性增长，在训练起点就把信号推入饱和区；乘以 $$1/\sqrt{2L}$$ 恰好抵消这种增长，使上百层的深网在初始化时仍保持稳定的激活尺度——这正是“残差让梯度流过百层”（§3.5）在前向方向上的对偶保障
* **监控训练指标**：定期记录：
  * 梯度的范数（检测梯度爆炸/消失）
  * 权重的平均大小和方差
  * 激活值的统计量
  * 学习率的当前值


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://yeasy.gitbook.io/llm_internals/di-er-bu-fen-xun-lian-pian/06_training_techniques/6.3_regularization.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
