minimind/learning/day03/02_deep_dive.md

106 lines
2.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Day 3 Deep Dive: Pretrain 训练循环
## 深挖问题 1:训练循环每一步发生了什么?
代码位置:`trainer/train_pretrain.py::train_epoch`
流程:
```text
for input_ids, labels in loader:
move to device
update lr
autocast forward
loss = res.loss + res.aux_loss
loss /= accumulation_steps
backward
if accumulation boundary:
unscale
grad clip
optimizer step
scaler update
zero grad
log
save
```
你要能解释每一行为什么存在。
## 深挖问题 2:学习率怎么变?
代码位置:`trainer/trainer_utils.py::get_lr`
```python
return lr * (0.1 + 0.45 * (1 + cos(pi * current_step / total_steps)))
```
含义:
- 初始接近 `lr`。
- 最终接近 `0.1 * lr`。
- 中间 cosine 平滑下降。
工业注意:
- 这个实现没有 warmup。
- 小模型和小数据通常能跑,但大规模训练一般会加 warmup。
- 如果 early loss 抖动严重,可以考虑降低 lr 或加 warmup。
## 深挖问题 3:checkpoint 保存了什么?
代码位置:`trainer/trainer_utils.py::lm_checkpoint`
保存两类文件:
- `out/pretrain_768.pth`:主要用于推理/下游训练。
- `checkpoints/pretrain_768_resume.pth`:用于断点续训。
resume checkpoint 包含:
- model
- optimizer
- epoch
- step
- world_size
- wandb id
- scaler 等额外状态
为什么 optimizer 也要保存?
因为 AdamW 有动量状态。如果只恢复模型权重,优化器状态丢失,训练动态会突然改变。
## 深挖问题 4:MoE aux_loss 为什么加在 pretrain loss 上?
如果 `use_moe=1`,模型输出 `aux_loss`。训练总 loss:
```python
loss = res.loss + res.aux_loss
```
这表示主目标仍是 next-token prediction,但额外鼓励 expert 负载均衡。
## 今日实验
1. 先跑 200 step smoke test:
```bash
cd trainer
python train_pretrain.py --epochs 1 --save_interval 200 --log_interval 20
```
2. 中断训练。
3. 恢复:
```bash
python train_pretrain.py --epochs 2 --from_resume 1
```
4. 检查日志是否显示跳过 step。
## 复盘问题
- 为什么 `loss / accumulation_steps` 后再 backward?
- 为什么 `scaler.unscale_` 后再 clip grad?
- 为什么保存权重前切 `model.eval()`,保存后再 `model.train()`?