跳转到内容

输入关键词开始搜索

    资料摘要:personal chatgpt 07 — fp16 与自动混合精度训练(amp)显著提升 batch size

    视频摘要更新 2026-08-02置信度 high待阅读原始来源 ↗#深度#大模型#课程#personal-chatgpt

    本讲由真实视频转录与作者 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 和训练中断输出当作当前源码的有效性能证明。

    课程模型由两层卷积和两层最大池化组成,再接全连接层:

    Conv2d → ReLU → MaxPool2d → Conv2d → ReLU → MaxPool2d → Flatten → Linear → Linear

    卷积输出尺寸公式:

    Hout=Hin+2pd(k1)1s+1H_{out}=\left\lfloor\frac{H_{in}+2p-d(k-1)-1}{s}+1\right\rfloor

    课程用 kernel size 3、padding 1、stride 1 演示空间尺寸保持不变;MaxPool2d 再把边长减半。

    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() 中。
    with torch.cuda.amp.autocast():
    output = model(data)
    loss = criterion(output, target)

    课程解释 autocast 会根据算子选择合适 dtype:可安全降低精度的运算走 FP16,高风险运算保留较高精度。它不是把模型中每个数都永久转换成 FP16。

    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 对极小梯度表示不足的问题。

    课程普通 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 不能混在一起解释。

    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:

    L=sL,L=sLL' = sL, \qquad \nabla L' = s\nabla L

    在更新权重前再按 scale 还原梯度;动态 scaler 还会检查 Inf/NaN 并调整 s

    • 00:00:介绍混合精度训练、CNN shape 与 AMP 对比。
    • 01:11:AMP 的 autocastGradScaler
    • 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:31scale → backward → step → update
    • 11:31:视频总结 AMP 可增大 batch;notebook 保存执行本身未完成。
    • 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 校正。
    • 依赖第 5 讲:FP16 的窄动态范围解释为什么需要 loss scaling。
    • 补充第 3 讲:第 3 讲只把 fp16=True 交给 Trainer,本讲展开底层训练循环。
    • 对比第 8 讲:AMP 主要用于训练计算的动态 dtype;LLM.int8 则把矩阵乘拆成 INT8 regular path 与 16-bit outlier path。
    1. autocastGradScaler 分别解决什么问题?
    2. 为什么 scaler.scale(loss).backward() 后不能直接调用普通 optimizer.step()
    3. AMP 是否意味着所有参数、激活和运算都固定使用 FP16?
    4. 为什么本讲保存的 8/64 通道 model summary 不能验证当前 5120/10240 通道源码?
    5. 从课程的 128→256 batch 设置,能否推出 AMP 在所有模型上都能把 batch 翻倍?为什么?
    • 滴答清单抓取时学习状态:已完成
    • 视频正文采用自动语音识别;关键术语已用标题、notebook 与源码校正,无法确认的口语细节不扩写。
    • notebook 未执行的 CUDA、权重下载、训练或外部 API 单元,不表述为已复现实验。