142 lines
2.5 KiB
Markdown
142 lines
2.5 KiB
Markdown
# 第7节:混合精度 + 梯度累积 + 梯度裁剪
|
||
|
||
> 训练流程核心机制笔记
|
||
|
||
---
|
||
|
||
## 📚 本节目录
|
||
|
||
1. [整体训练流程](#1-整体训练流程核心顺序)
|
||
2. [每一步在干什么](#2-每一步在干什么)
|
||
3. [三大核心机制总结](#3-三大核心机制总结)
|
||
4. [一句话总理解](#4-一句话总理解)
|
||
|
||
---
|
||
|
||
## 1. 整体训练流程(核心顺序)
|
||
|
||
```python
|
||
scaler.scale(loss).backward()
|
||
|
||
if step % accumulation_steps == 0:
|
||
scaler.unscale_(optimizer)
|
||
clip_grad_norm_(model.parameters(), max_norm)
|
||
scaler.step(optimizer)
|
||
scaler.update()
|
||
optimizer.zero_grad(set_to_none=True)
|
||
```
|
||
|
||
---
|
||
|
||
## 2. 每一步在干什么
|
||
|
||
### (1) `scaler.scale(loss).backward()`
|
||
|
||
**作用**:AMP 防止 FP16 下溢
|
||
|
||
- loss 先乘一个 scale(放大)
|
||
- backward 计算梯度
|
||
|
||
**目的**:防止 FP16 数值太小 → 梯度变 0
|
||
|
||
---
|
||
|
||
### (2) 梯度累积(accumulation)
|
||
|
||
**每 N 步才更新一次参数**
|
||
|
||
**作用**:
|
||
- 模拟大 batch training
|
||
- 节省显存
|
||
|
||
---
|
||
|
||
### (3) `scaler.unscale_(optimizer)`
|
||
|
||
**作用**:梯度"还原"
|
||
|
||
因为之前 loss 被放大了:`grad = grad × scale`
|
||
|
||
所以这里要把梯度恢复到真实数值(为了梯度裁剪)
|
||
|
||
---
|
||
|
||
### (4) `clip_grad_norm_()`
|
||
|
||
**作用**:防止梯度爆炸
|
||
|
||
**数学本质**:
|
||
|
||
先算整体梯度范数:
|
||
$$\|g\| = \sqrt{\sum_i g_i^2}$$
|
||
|
||
- 如果 `norm ≤ max_norm`:不变
|
||
- 如果 `norm > max_norm`:缩放 → `g := g × max_norm / norm`
|
||
|
||
**直觉**:不改变方向,只限制"更新步子大小"
|
||
|
||
---
|
||
|
||
### (5) `scaler.step(optimizer)`
|
||
|
||
**作用**:真正更新参数
|
||
|
||
- 如果检测到 NaN/Inf → 自动跳过
|
||
- 否则正常 optimizer.step()
|
||
|
||
---
|
||
|
||
### (6) `scaler.update()`
|
||
|
||
**作用**:动态调整 loss scale
|
||
|
||
| 情况 | 动作 |
|
||
|------|------|
|
||
| 出现 NaN/Inf | scale ↓(变小,更保守) |
|
||
| 训练稳定 | scale ↑(变大,提高精度) |
|
||
|
||
**本质**:自动调节 FP16 "放大倍率",保证稳定 + 高效
|
||
|
||
---
|
||
|
||
### (7) `optimizer.zero_grad(set_to_none=True)`
|
||
|
||
**作用**:清空梯度
|
||
|
||
`set_to_none=True` → 更省显存 + 更快
|
||
|
||
---
|
||
|
||
## 3. 三大核心机制总结
|
||
|
||
### AMP(scaler)
|
||
|
||
👉 解决 FP16 数值问题
|
||
|
||
- scale loss(防 underflow)
|
||
- 自动调 scale(防 overflow)
|
||
|
||
### 梯度累积
|
||
|
||
👉 解决显存限制
|
||
|
||
- 多 step 累积梯度
|
||
- 再统一更新
|
||
|
||
### 梯度裁剪
|
||
|
||
👉 解决梯度爆炸
|
||
|
||
- 控制 norm 上限
|
||
- 保持方向不变
|
||
|
||
---
|
||
|
||
## 4. 一句话总理解
|
||
|
||
**这套流程本质是在做三件事**:
|
||
|
||
1. 用 AMP 提速
|
||
2. 用 accumulation 放大 batch
|
||
3. 用 clipping 保稳定
|