资料摘要:personal chatgpt 07 — fp16 与自动混合精度训练(amp)显著提升 batch size
本讲由真实视频转录与作者 notebook/代码交叉整理。原始层:🔒 带时间戳视频转录;课程总览:personal chatgpt — LLMs 实践系列。
本讲用 MNIST CNN 对比普通 FP32 训练与 CUDA Automatic Mixed Precision(AMP)。AMP 的基本做法是在 autocast 区域自动为不同算子选择较低或较高精度,并用 GradScaler 放大 loss,避免 FP16 梯度因数值过小而 underflow;完成反向传播后再由 scaler 执行 optimizer step 和动态调整缩放因子。
课程还用更大 batch size 说明低精度可能节省激活显存,但 notebook 存在严重 source/output drift,不能把保存的 summary 和训练中断输出当作当前源码的有效性能证明。
1. CNN 与 shape 计算
Section titled “1. CNN 与 shape 计算”课程模型由两层卷积和两层最大池化组成,再接全连接层:
Conv2d → ReLU → MaxPool2d → Conv2d → ReLU → MaxPool2d → Flatten → Linear → Linear卷积输出尺寸公式:
课程用 kernel size 3、padding 1、stride 1 演示空间尺寸保持不变;MaxPool2d 再把边长减半。
2. 普通 FP32 训练循环
Section titled “2. 普通 FP32 训练循环”optimizer.zero_grad()output = model(data)loss = criterion(output, target)loss.backward()optimizer.step()- MNIST 通过
torchvision.datasets.MNIST加载; - 普通分支 batch size 为 128;
- 优化器是 Adam,损失是 CrossEntropyLoss;
- 验证阶段放在
torch.no_grad()中。
3. AMP 的两部分
Section titled “3. AMP 的两部分”autocast
Section titled “autocast”with torch.cuda.amp.autocast(): output = model(data) loss = criterion(output, target)课程解释 autocast 会根据算子选择合适 dtype:可安全降低精度的运算走 FP16,高风险运算保留较高精度。它不是把模型中每个数都永久转换成 FP16。
GradScaler
Section titled “GradScaler”scaler = torch.cuda.amp.GradScaler()scaler.scale(loss).backward()scaler.step(optimizer)scaler.update()scale(loss):把 loss 放大,反向传播得到更大的梯度数值;step(optimizer):在内部完成必要的 unscale/有限值检查后再更新;update():根据溢出情况动态调整 scale。
课程把这称为 loss scaling,用于缓解 FP16 对极小梯度表示不足的问题。
4. batch size 与显存
Section titled “4. batch size 与显存”课程普通 FP32 分支使用 batch size 128,AMP 分支使用 256,并口头称 128 是其当时机器上普通训练的最大 batch。这只能说明特定模型、特定实现、特定 GPU 下的观察:
- AMP 可能减少某些激活/中间张量显存;
- batch size 变大仍会增加激活显存;
- 参数、梯度、优化器状态不一定全部变成 FP16;
- 能扩大多少 batch 需要实测,不能从 128→256 推导通用倍数。
5. 当前 notebook 的 source/output drift
Section titled “5. 当前 notebook 的 source/output drift”材料审计发现:
- 当前源码把卷积通道写成 5120/10240;
- 保存的
torchsummary输出却是 8/64 通道、约 2,011,946 参数; - 当前源码静态估算约 476,938,250 参数,仅 FP32 权重约 1.78 GiB;
- AMP cell 保存结果是约 9 个 batch 后
KeyboardInterrupt; - 没有完成 epoch、准确率或稳定显存对比证据。
因此,保存输出显然来自旧版小网络;当前 source 和历史 output 不能混在一起解释。
公式 / 代码
Section titled “公式 / 代码”AMP 训练的最小顺序:
scaler = torch.cuda.amp.GradScaler()
optimizer.zero_grad()with torch.cuda.amp.autocast(): output = model(data) loss = criterion(output, target)
scaler.scale(loss).backward()scaler.step(optimizer)scaler.update()概念性的 loss scaling:
在更新权重前再按 scale 还原梯度;动态 scaler 还会检查 Inf/NaN 并调整 s。
00:00:介绍混合精度训练、CNN shape 与 AMP 对比。01:11:AMP 的autocast和GradScaler。02:01:为制造显存压力而扩大卷积通道。03:01:卷积/池化输出 shape 的计算。07:02:MNIST 数据、DataLoader 和 CUDA 设备。08:00:普通 FP32 forward/backward/optimizer step。09:36:讲者环境中 FP32 batch 128、AMP batch 256 的设置。10:00:创建 scaler,在 autocast 中前向与计算 loss。10:31:scale → backward → step → update。11:31:视频总结 AMP 可增大 batch;notebook 保存执行本身未完成。
运行边界与可复现性
Section titled “运行边界与可复现性”- AMP 部分硬编码
torch.cuda.amp,不是 Apple MPS 的原样运行路径。 - 当前巨大 CNN 在 CPU/MPS 上也不适合直接照搬;应先恢复与全连接输入匹配的小通道网络。
- notebook 保存的唯一 AMP 终止是
KeyboardInterrupt,没有完成训练证据。 - 当前 source 与保存 summary/输出不一致,属于陈旧输出;任何参数量、耗时、显存或准确率结论都应重新运行确认。
- 课程“128 是最大 batch”只适用于讲者当时的 CUDA 环境。
- ASR 把 AMP、autocast、loss scaling、GradScaler、underflow 等识别为近音词;本稿按 notebook/PyTorch API 校正。
与前后讲关系
Section titled “与前后讲关系”- 依赖第 5 讲:FP16 的窄动态范围解释为什么需要 loss scaling。
- 补充第 3 讲:第 3 讲只把
fp16=True交给 Trainer,本讲展开底层训练循环。 - 对比第 8 讲:AMP 主要用于训练计算的动态 dtype;LLM.int8 则把矩阵乘拆成 INT8 regular path 与 16-bit outlier path。
autocast与GradScaler分别解决什么问题?- 为什么
scaler.scale(loss).backward()后不能直接调用普通optimizer.step()? - AMP 是否意味着所有参数、激活和运算都固定使用 FP16?
- 为什么本讲保存的 8/64 通道 model summary 不能验证当前 5120/10240 通道源码?
- 从课程的 128→256 batch 设置,能否推出 AMP 在所有模型上都能把 batch 翻倍?为什么?
- 视频:fp16 与自动混合精度训练(amp)显著提升 batch size
- 转录:🔒 personal chatgpt 07 视频转录
- 课件 / 代码:🔒 07_fp16_mixed_precision_training.ipynb
- 滴答清单抓取时学习状态:已完成。
- 视频正文采用自动语音识别;关键术语已用标题、notebook 与源码校正,无法确认的口语细节不扩写。
- notebook 未执行的 CUDA、权重下载、训练或外部 API 单元,不表述为已复现实验。