本讲主线
这节课围绕一个核心问题展开:如何精确估算训练成本。主要分为三块:
- 内存占用
- FLOPs 估算
- 模型与训练配置
这和 Lecture 1 提到的“效率优先”直接相关。
例题:70B 模型训练时长
问题:使用 1024 张 H100,在 15T tokens 上训练一个 70B 模型,需要多久?
根据 Transformer 常用训练量估算公式($6 \times$ 参数量 $\times$ token 数):
$$ \text{总 FLOPs} = 6 \times 70 \times 10^9 \times 15 \times 10^{12} = 6.3 \times 10^{24}\,\text{FLOPs} $$单卡 H100(BF16)理论性能约为 $2 \times 10^{15}$ FLOPs/s。若考虑大模型训练实际效率约为 30%,则单卡有效 FLOPs/s 为:
$$ 0.3 \times 2 \times 10^{15} = 6 \times 10^{14}\,\text{FLOPs/s} $$总时长:
$$ \text{总时间} = \frac{\text{总 FLOPs}}{\text{每秒有效 FLOPs} \times \text{GPU 数量}} = \frac{6.3 \times 10^{24}}{6 \times 10^{14} \times 1024} $$约等于 119 天。
内存与数值精度
PyTorch 使用 tensor 存储参数、梯度、优化器状态、输入数据和激活值。
float32:单精度,32 bit(4 byte)。float16:半精度,省内存但 dynamic range 较小,容易下溢,训练稳定性受影响。bfloat16:内存占用与float16相同,但 dynamic range 接近float32,在训练中更稳。- H100 支持两种 FP8:
E4M3与E5M2。
当前主流是混合精度训练:例如前向用 {bfloat16, fp8},而梯度和主参数以 float32 维护,从而平衡稳定性与效率。NVIDIA Transformer Engine 也在推动 FP8 在线性层中的应用。
FLOPs 估算
FLOPs 有两种常见语义:
- Floating Point Operations Per Second(性能指标)
- Floating Point Operations(计算总量)
假设线性层将 $d$ 维向量映射到 $k$ 维输出,batch 中有 $n$ 个样本。前向总计算量近似:
$$ \text{flops} = 2 \times n \times d \times k $$其中乘以2是因为每个乘法操作通常伴随着一个加法操作。
反向传播中,参数梯度与激活梯度都会引入额外矩阵运算,因此总量通常近似为前向的 3 倍,即:
$$ \text{flops} = 6 \times n \times d \times k $$模型部分
这一部分偏基础实践,主要围绕两层线性模型展开:参数量计算、模型搭建、数据加载、优化器设置与训练循环。原课内容较基础,这里不展开细记。