混合精度训练在训练过程中混合使用FP16和FP32精度,用FP16加速计算和节省显存,用FP32保持关键精度。你将学到精度转换策略、损失缩放防止梯度下溢和框架支持。适用于在大GPU上训练大模型、显存不足需要优化的工程师。

岗位关联

想象一座永不歇业的快递分拣仓库。每件包裹都要贴一张记录重量的标签,标签越精细,字就越小、印得越慢、占的纸也越大。管理员原先统一用最精细的蜡印标签(FP32)给所有包裹贴单,结果仓库爆满、分拣员累得抬不起手。后来一种速写贴纸(FP16)出现了:只有一半纸,唰唰两笔就能贴好,分拣速度快了一倍。但它有个致命缺陷——特别轻的小包裹会被记成“0 克”直接丢失。聪明的管理员定下新规矩:流水线上的包裹用速写贴纸快速流转,办公室里的正式账本永远用蜡印精记;再给轻到记不出来的包裹发一张“放大券”,过完秤再撤走。这套“双标签+放大券”的制度,就是混合精度训练。 混合精度是 AI 训练场景的“涡轮增压+压缩行李”:显存占用减半、训练速度提升 1.5~3 倍。无论你是训练大模型的工程师,还是卡在显存红线的调优者,这都是必须掌握的看家技能。

目录
  1. 可视化演示
  2. 精度基础概念:两种标签的容量差
  3. 混合精度策略:账本用蜡印,流水用速写
  4. 损失缩放机制:给微小梯度发“放大券”
  5. 显存优化效果:一半的纸,双倍的货
  6. 训练加速原理:流水线的三重提速
  7. 框架实现实践:现成的智能分拣系统
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

展示FP16与FP32混合精度训练的显存节省与速度提升,以及损失缩放如何防止梯度下溢。

本节配有交互动效(进入视口后自动加载,约 3KB)。

混合精度精度对比 FP32全精度:显存占用大,计算慢但精度高 FP16半精度:显存省一半,速度快但易溢出 混合精度:FP32存权重副本,FP16做前向反向 显存减少约50%,速度提升约2x 混合精度兼顾速度与精度。

精度基础概念:两种标签的容量差

仓库管理员最头疼的是标签纸的选择。蜡印标签(FP32)32 位记录,印刷清晰、能写很大的数字,可又重又贵;速写贴纸(FP16)16 位,轻便省纸,但最大只能记到 65504,小数位也粗。普通货物无所谓,可一遇到贵重的精密零件,速写贴纸就会写错数字。

在深度学习里,每个参数、每份梯度都是这样一张“数字标签”。FP32 用 32 个比特(bit)表示一个数:1 位符号、8 位指数、23 位尾数;FP16 只有 16 个比特:1 位符号、5 位指数、10 位尾数。比特少了一半,能表示的范围和精度也同步缩水。

FP16 能表示的最大有限值是 65504,最小规格化正数约 6.1×10⁻⁵;而 FP32 的最大值约 3.4×10³⁸,最小规格化正数约 1.2×10⁻³⁸。对大部分激活值和梯度来说,FP16 的量程够用,但训练中权重更新幅度极其微小,这正是需要特殊手段保护的地方。这张速写贴纸虽然轻快,但并非万能。

明白了两种标签的差异,管理员的第一反应是“全用速写贴纸不就行了?”——不行,因为正式账本要长期保存,容不得半点误差。这正是混合精度不叫“全半精度”的原因:两个精度要像蜡印标签和速写贴纸一样各司其职。

value=(−1)s×2e−15×(1+m210)\displaystyle \text{value} = (-1)^s \times 2^{e-15} \times \left(1 + \frac{m}{2^{10}}\right)
这是 FP16 的“出厂说明书”:符号位定正负,指数位定量级,尾数位定精度,三部分缺一不可。
  1. 符号位 s1 个比特,s=0 表示正数,s=1 表示负数,决定数值的方向。
    s∈{0,1}\displaystyle s \in \{0, 1\}
  2. 指数位 e5 位二进制,范围 0~31,减去偏置 15 后表示 2 的幂次,直接决定数值量级。
    e∈[0,31],2e−15∈[2−14,215]\displaystyle e \in [0, 31], \quad 2^{e-15} \in [2^{-14}, 2^{15}]
  3. 尾数位 m10 位二进制,范围 0~1023,表示小数点后的精细刻度,决定相对精度。
    m∈[0,1023]\displaystyle m \in [0, 1023]
  4. 组合成数三部分相乘得到最终值,可见 FP16 指数和尾数都短,量程与精度双降。
    value=(−1)s×2e−15×(1+m210)\displaystyle \text{value} = (-1)^s \times 2^{e-15} \times \left(1 + \frac{m}{2^{10}}\right)

混合精度策略:账本用蜡印,流水用速写

管理员最终定下规矩:办公室保险柜里的正式账本(权重主副本)永远用蜡印标签,一丝不苟;仓库里流转的包裹单(前向/反向计算产生的激活值和梯度)全用速写贴纸,追求速度。每隔一段时间,把速写单据汇总转成蜡印,更新一次正式账本。

混合精度训练的核心正是“一份权重,两个精度”。训练过程维护一份 FP32 的“主副本”权重,它记录模型最准确的参数;而每次迭代的前向传播和反向传播计算,则在 FP16 下完成,充分利用硬件加速能力。

具体流程是:先把 FP32 主副本转成 FP16 副本用于前向和反向;得到 FP16 梯度后,将它转回 FP32;最后用 FP32 梯度更新 FP32 主副本。转回这一步是精度守卫的关键——更新必须发生在精确空间,否则误差会随着训练步数不断累积,像账本上密密麻麻的小数点错误一样越记越偏。

这套“账本+流水单”的制度,让仓库在速度和账目准确之间找到平衡:流水单快进快出,账本始终精确。同理,混合精度训练里 FP16 负责冲锋陷阵,FP32 负责守住精度的底线,二者缺一不可。

Wt+1=Wt−η⋅FP32⁡(gtFP16)\displaystyle W_{t+1} = W_t - \eta \cdot \operatorname{FP32}\left(g_t^{\text{FP16}}\right)
每一次迭代都遵守“计算用半精度、更新用全精度”,就像只有汇总正式账本时才动用蜡印。
  1. 主副本权重 W_t模型参数在 FP32 下保存,作为所有更新落账的“正式账本”。
    Wt∈Rd(FP32 主副本)\displaystyle W_t \in \mathbb{R}^{d} \quad (\text{FP32 主副本})
  2. FP16 梯度反向传播在 FP16 计算图中产出梯度,数值以半精度暂存。
    gtFP16=FP16⁡(∂L∂W)\displaystyle g_t^{\text{FP16}} = \operatorname{FP16}\left(\frac{\partial L}{\partial W}\right)
  3. 转回 FP32 更新梯度先转回 32 位,再按学习率更新主权重。
    Wt+1=Wt−η⋅FP32⁡(gtFP16)\displaystyle W_{t+1} = W_t - \eta \cdot \operatorname{FP32}\left(g_t^{\text{FP16}}\right)

损失缩放机制:给微小梯度发“放大券”

新制度运行一周后,管理员核对账本时发现:一批特别轻的小包裹(重量小于 0.000061 克)在流水单上全被记成了“0 克”。速写贴纸的格子太小,写不下这么小的数字,只能四舍五入成零。这些“消失的重量”,正是模型里那些微小的梯度。

梯度是模型学习的“修正信号”,很多训练后期或深层网络的梯度值远小于 6.1×10⁻⁵,一旦转成 FP16 就会下溢(underflow)成 0,权重永远得不到更新。解决办法很朴素:在放大镜下称重——把损失值整体乘以一个大的缩放因子 S,再反向传播,梯度也就放大了 S 倍,远离下溢区。

损失缩放分为静态和动态两种。静态缩放固定 S(如 1024 或 65536),简单但需要人工调;动态缩放更聪明:每次反向传播后检查梯度是否上溢(出现 inf 或 NaN),有则把 S 减半,连续若干步无上溢则把 S 加倍。这样 S 会自适应地停在“刚好安全”的位置,像管理员根据天气随时调整放大券的倍率。

放大券在过秤后会被收回,货物的真实重量分毫不差。同理,动态缩放因子会在训练中自动调节“券的倍率”:上溢了就把券印小点,安全了就逐渐放大,保证每一份微小梯度都不被流水线吞掉。

L∗=L×S,g=1S⋅∂L∗∂W\displaystyle L^{\ast} = L \times S, \qquad g = \frac{1}{S} \cdot \frac{\partial L^{\ast}}{\partial W}
放大损失只是手段,还原梯度才是目的——缩放前后数学上完全等价,只是让中间过程的数字不再小到丢失。
  1. 放大损失前向计算出损失 L 后,立即乘上缩放因子 S。
    L∗=L×S\displaystyle L^{\ast} = L \times S
  2. 梯度同倍放大根据链式法则,反向传播得到的梯度天然也放大了 S 倍。
    ∂L∗∂W=S⋅∂L∂W\displaystyle \frac{\partial L^{\ast}}{\partial W} = S \cdot \frac{\partial L}{\partial W}
  3. 更新前还原真正更新权重前,把梯度除以 S,恢复真实大小。
    g=1S⋅∂L∗∂W\displaystyle g = \frac{1}{S} \cdot \frac{\partial L^{\ast}}{\partial W}

显存优化效果:一半的纸,双倍的货

换用速写贴纸后,货架管理员惊喜地发现:同样面积的货架,现在能放两倍的包裹。以前一摞蜡印标签占据的厚度,换成一摞速写贴纸后薄了一半——这就是“省出来的货架空间”。

训练大模型时,显存中真正的大头往往不是权重本身,而是前向计算中缓存的激活值,以及反向传播产生的梯度。这两类数据用 FP16 存储后,每个数字从 4 字节降到 2 字节,显存占用直接对半。

以 ResNet-50 这类视觉模型为例,激活值缓存可以占训练峰值显存的 50% 以上;对 Transformer 大模型,激活值同样是最主要的增长项。激活值和梯度改用 FP16 后,权重主副本与优化器状态仍保留 FP32,但这两者只占总显存的小头。综合下来,混合精度通常能省下 30%~50% 的显存,相当于白送半个 GPU。

管理员用省下的货架接了更大的订单——原本一箱货的容量现在能装两箱。对工程师来说,“更大的订单”就是更大的 batch、更高的分辨率、更深的模型,显存的红线被混合精度悄悄抬高了一大截。

Msaved=12Mgrad+12Mact\displaystyle M_{\text{saved}} = \frac{1}{2} M_{\text{grad}} + \frac{1}{2} M_{\text{act}}
省下的显存可以兑换成更大的 batch size,或直接训练更大的模型——这是混合精度最直观的收益。
  1. 梯度显存减半梯度不再以 FP32 保存,而是以 FP16 暂存。
    MgradFP16=12MgradFP32\displaystyle M_{\text{grad}}^{\text{FP16}} = \frac{1}{2} M_{\text{grad}}^{\text{FP32}}
  2. 激活缓存减半前向传播的中间结果同样以 FP16 缓存。
    MactFP16=12MactFP32\displaystyle M_{\text{act}}^{\text{FP16}} = \frac{1}{2} M_{\text{act}}^{\text{FP32}}
  3. 总节省公式二者节省之和,就是省出来的显存空间。
    Msaved=12Mgrad+12Mact\displaystyle M_{\text{saved}} = \frac{1}{2} M_{\text{grad}} + \frac{1}{2} M_{\text{act}}

训练加速原理:流水线的三重提速

速写贴纸不仅省纸,还让分拣员的手速翻倍;包裹变小后,传送带一次能运更多;连每天往分店发货的卡车都轻了一半。仓库的吞吐量,就这样被一张小小的贴纸全面拉起来了。

训练速度的提升来自三个层面。第一,现代 GPU 内置 Tensor Core 专门加速 FP16 矩阵运算,计算吞吐量是 FP32 的 2~8 倍;第二,显存搬运的字节数减半,内存带宽瓶颈得到缓解;第三,分布式训练中所有卡同步梯度的 All-Reduce 通信量减半,通信等待大幅缩短。

一次迭代的总时间可近似拆成计算、访存、通信三部分。FP16 让三部分分别提速:计算因 Tensor Core 提升 k 倍,访存和通信各提升约 2 倍。综合来看,端到端训练速度通常能提升 1.5~3 倍,且模型精度几乎不变——这正是它“双赢”的底气。

三重提速叠加,仓库从“勉强运转”变成“游刃有余”。混合精度训练既没有偷工减料(主副本保住精度),又让每一环都更轻快——这正是它被称为“双赢方案”的原因。

Tmixed≈Tcomputek+Tmemory2+Tcomm2\displaystyle T_{\text{mixed}} \approx \frac{T_{\text{compute}}}{k} + \frac{T_{\text{memory}}}{2} + \frac{T_{\text{comm}}}{2}
k 是 Tensor Core 对 FP16 计算的加速倍数(2~8),实际加速取决于算子里“计算 vs 访存”的比例。
  1. 计算时间缩短矩阵乘等算子由 Tensor Core 接管,耗时除以 k。
    TcomputeFP16=TcomputeFP32k,k∈[2,8]\displaystyle T_{\text{compute}}^{\text{FP16}} = \frac{T_{\text{compute}}^{\text{FP32}}}{k}, \quad k \in [2, 8]
  2. 访存时间减半数据宽度减半,搬运同样多数据只需一半时间。
    TmemoryFP16=TmemoryFP322\displaystyle T_{\text{memory}}^{\text{FP16}} = \frac{T_{\text{memory}}^{\text{FP32}}}{2}
  3. 通信时间减半梯度同步传输的字节数减半。
    TcommFP16=TcommFP322\displaystyle T_{\text{comm}}^{\text{FP16}} = \frac{T_{\text{comm}}^{\text{FP32}}}{2}

框架实现实践:现成的智能分拣系统

管理员不用手工设计放大券和双标签制度——市面上已有成熟的“智能分拣系统”,也就是各大深度学习框架内置的自动混合精度(AMP)模块。买来装上,规则自动运行,省心又可靠。

PyTorch 从 1.6 起原生支持混合精度,核心是两个组件:autocast 负责精度自动切换,GradScaler 负责损失缩放。前者像自动贴标签机,识别哪些算子适合 FP16,哪些必须留在 FP32(如 Softmax、LayerNorm);后者像自动发券机,动态管理缩放因子。

使用 AMP 只需在训练循环里做三处修改:用 with autocast(): 包裹前向和损失计算;用 scaler.scale(loss).backward() 替代 loss.backward();用 scaler.step(optimizer) 和 scaler.update() 替代 optimizer.step()。此外,NVIDIA 的 apex 库提供 O0~O3 四档优化级别,DeepSpeed、HuggingFace Trainer 也都内置了 AMP,开箱即用。

有了智能分拣系统,仓库管理员只需坐在中控室看仪表盘。同样,工程师只需写几行 AMP 代码,便能坐享显存减半、速度翻倍,还能在分布式训练中无缝使用——这就是工具化带给混合精度训练的最后一公里。

Wt+1=Wt−η⋅FP32⁡(1S⋅∂(S⋅LFP16)∂W)\displaystyle W_{t+1} = W_t - \eta \cdot \operatorname{FP32}\left(\frac{1}{S} \cdot \frac{\partial (S \cdot L_{\text{FP16}})}{\partial W}\right)
这一长串公式就是 AMP 每个 step 做的事:FP16 计算、缩放反向、还原梯度、FP32 更新。
  1. autocast 前向在 autocast 上下文中,损失在 FP16 下算出。
    LFP16=L(FP16(x;W))\displaystyle L_{\text{FP16}} = \mathcal{L}(\text{FP16}(x; W))
  2. 缩放反向GradScaler 把损失乘以 S 再反向传播。
    ∂(S⋅LFP16)∂W=S⋅∂LFP16∂W\displaystyle \frac{\partial (S \cdot L_{\text{FP16}})}{\partial W} = S \cdot \frac{\partial L_{\text{FP16}}}{\partial W}
  3. 还原并更新scaler.step 内部还原梯度、转 FP32,更新主权重。
    Wt+1=Wt−η⋅FP32⁡(1S⋅∂(S⋅LFP16)∂W)\displaystyle W_{t+1} = W_t - \eta \cdot \operatorname{FP32}\left(\frac{1}{S} \cdot \frac{\partial (S \cdot L_{\text{FP16}})}{\partial W}\right)

AI 应用场景

大语言模型训练:显存红线下的扩军

阶段:模型训练(预训练 / 微调)

解决的问题:训练 7B/13B 参数的大语言模型时,单卡显存装不下 batch size 1 的样本;传统 FP32 训练不仅显存爆表,速度也只有混合精度的 1/2~1/3。AMP 自动把激活值和梯度放进 FP16,让有限的 A100/H100 显存塞进更大 batch,同时 Tensor Core 把训练速度拉满。

具体案例:某团队用 8 张 A100 微调 13B 参数的 ChatGLM 模型。开启 PyTorch AMP 后,峰值显存从 72GB 降到 46GB,batch size 从 8 提到 14,训练每千步耗时减少 42%,模型在评测集上的指标几乎不变。

视觉模型训练:更高分辨率、更大批次

阶段:训练前资源规划 / 训练中调优

解决的问题:目标检测和语义分割模型常因显存限制被迫降低输入分辨率,导致精度上不去。混合精度省出的显存让 4K 输入或 2 倍 batch 成为可能,在自动驾驶、医疗影像等场景直接带来精度收益。

具体案例:某自动驾驶团队训练 YOLOv8 检测模型,原先以 1280×1280 输入训练 batch 只能到 16;打开 AMP 后 batch 涨到 32,训练速度提升 1.8 倍,在夜间小目标样本上的 mAP 提升 1.2 个百分点。

分布式多卡训练:通信减半的省钱之道

阶段:分布式训练

解决的问题:多卡训练中每步都要做梯度 All-Reduce,梯度的字节数直接决定通信耗时。混合精度把梯度以 FP16 传输,通信量减半;配合梯度压缩,从 4 卡扩展到 32 卡时的扩展效率显著提升。

具体案例:某推荐系统团队用 DeepSpeed 在多机多卡上训练 CTR 模型,开启 AMP 后梯度通信量从 2.4GB 降到 1.2GB,同步训练吞吐提升 1.6 倍,机时费用降低约 40%。

Python 演示

python36 行
import torchimport torch.nn as nnfrom torch.cuda.amp import autocast, GradScaler torch.manual_seed(42)device = "cuda" if torch.cuda.is_available() else "cpu"  class Net(nn.Module):    def __init__(self):        super().__init__()        self.fc = nn.Linear(64, 10)     def forward(self, x):        return self.fc(x)  model = Net().to(device)opt = torch.optim.SGD(model.parameters(), lr=0.01)scaler = GradScaler() # 合成数据X = torch.randn(256, 64, device=device)y = torch.randint(0, 10, (256,), device=device) model.train()for step in range(50):    opt.zero_grad()    with autocast():        pred = model(X)        loss = nn.functional.cross_entropy(pred, y)    scaler.scale(loss).backward()    scaler.step(opt)    scaler.update()    if step % 10 == 0:        print(f"step {step}: loss = {loss.item():.4f}")
目的:演示 PyTorch 原生 AMP 的完整训练循环——autocast 自动切换精度,GradScaler 自动完成损失缩放与梯度还原。
  1. scaler = GradScaler()初始化动态损失缩放器,相当于给仓库装上“自动发券机”
  2. with autocast():自动分拣算子:卷积/矩阵乘走 FP16,LayerNorm/Softmax 留给 FP32
  3. scaler.scale(loss).backward()损失先乘缩放因子再反向,防止小梯度下溢
  4. scaler.step(opt)若梯度无上溢则还原并更新权重;有上溢则跳过本轮更新
  5. scaler.update()根据本轮是否溢出动态调整缩放因子(有溢出一半,安全则加倍)

常见误区

误区把混合精度理解为把所有参数、所有计算都换成 FP16,以为这样就最快,结果模型损失震荡甚至发散。

正解混合精度的精髓恰恰在于“混合”:计算用 FP16,但权重主副本和优化器状态保留 FP32。全程 FP16 会让权重更新的误差不断累积,最终破坏训练收敛。就像仓库里不能把正式账本也换成速写贴纸一样,关键资产必须留在精确空间。

为何常见:因为“混合精度”名字里的“混合”二字容易让人忽略,而 FP16 的加速和显存优势太显眼,初学者容易贪图极致速度。

误区放大损失再反向传播,梯度被改大了,模型训练出来的效果应该和 FP32 不同吧?

正解缩放前后在数学上是完全等价的。损失乘 S,梯度也乘 S,更新前再除以 S,等价于中间经历了放大-还原的往返。缩放只是为躲避 FP16 的下溢区,并不会改变真实的梯度值和训练轨迹。真正需要警惕的是缩放因子太大导致上溢,这是动态缩放要解决的问题。

为何常见:人直觉上认为“乘倍数就会改结果”,忽略了还原步骤的存在,也低估了 FP16 表示范围的狭窄。

误区FP16 最大才 65504,比 FP32 小太多,训练中数值动不动就会“爆表”上溢。

正解实际训练里更常见、更隐蔽的敌人是下溢。FP16 的最小规格化正数是 6.1×10⁻⁵,比它小的梯度直接变 0,模型悄悄停止学习。上溢多发生在损失缩放因子设得过大时,动态缩放正是靠检测上溢来规避它。两者一个在暗处、一个在明处,下溢的危害往往更大。

为何常见:人对数量级差异的直觉建立在“最大值”上,容易忽略“最小正数”同样受限;而且上溢会直接报 NaN,下溢却无声无息。

误区买了 A100 显卡,代码里什么都不改,训练就自动变快。

正解Tensor Core 需要算子用 FP16 张量调用才会启动,还需要框架层的编译支持。手动把 model.half() 丢进去而不配合 autocast 和 GradScaler,往往会出现精度崩坏或某些层报错。正确姿势是用 PyTorch AMP 或 apex 等成熟封装,让框架自动决定哪些算子走 FP16、哪些留 FP32。

为何常见:硬件宣传把 Tensor Core 讲得神乎其神,人们误以为它是“魔法开关”,而忽略了软件栈才是把算力兑现的最后一环。

面试题

Q1. FP16 中的"16"指的是什么?

单选题 · easy

  • A.16 个字节
  • B.16 个比特← 正确答案
  • C.16 个数值
  • D.16 层网络

答案:B。FP16 是半精度浮点数,用 16 个比特(bit)存储一个数,相当于 2 个字节。其余选项都与精度定义无关。就像速写贴纸的“小”说的是纸张面积(比特数),而不是贴纸的厚度或张数。

Q2. FP32 浮点数中,符号位占多少比特?

单选题 · easy

  • A.1 个比特← 正确答案
  • B.5 个比特
  • C.8 个比特
  • D.23 个比特

答案:A。FP32 的 32 位拆分为 1 位符号、8 位指数、23 位尾数;FP16 则是 1 位符号、5 位指数、10 位尾数。符号位永远只有 1 位,决定正负号。这个拆分就像标签先写“正/负”,再写大小和刻度。

Q3. FP16 能表示的最大有限值大约是多少?

单选题 · easy

  • A.约 3.4e38
  • B.约 6.5e4← 正确答案
  • C.约 2.1e9
  • D.约 1.2e-7

答案:B。FP16 最大值为 65504,约 6.5×10⁴;FP32 最大约 3.4×10³⁸。指数位从 8 位降到 5 位,量程骤减。可以理解为速写贴纸的最大字号有限,太重的货物会写不下。

Q4. 混合精度训练中,“权重主副本”应以什么精度保存?

单选题 · mid

  • A.FP16
  • B.INT8
  • C.FP32← 正确答案
  • D.BF16

答案:C。主副本必须用 FP32 保存,保证权重更新在精确空间进行,避免误差累积。FP16 只承担计算过程,就像速写贴纸负责流水记录,正式账本必须用蜡印精记。

Q5. 损失缩放机制主要解决什么问题?

单选题 · mid

  • A.梯度上溢爆炸
  • B.梯度下溢为零← 正确答案
  • C.损失函数震荡
  • D.学习率衰减

答案:B。FP16 最小规格化正数约 6.1e-5,比它小的梯度会变成 0,模型停止学习。损失缩放把损失乘大后再反向,梯度同步放大远离下溢区。上溢是动态缩放要检测的副作用,而不是主攻问题。

Q6. 关于 FP16 的表示结构,以下哪项描述正确?

单选题 · hard

  • A.符号位 8 位,指数位 5 位
  • B.指数位 5 位,尾数位 10 位← 正确答案
  • C.尾数位 23 位,符号位 1 位
  • D.指数位 10 位,尾数位 5 位

答案:B。FP16 是 1 位符号 + 5 位指数 + 10 位尾数;FP32 是 1 位符号 + 8 位指数 + 23 位尾数。指数位决定量程,尾数位决定精度;FP16 两项都被砍掉,所以量程和精度双双缩水。

Q7. 混合精度训练能带来哪些收益?(多选)

多选题 · mid

  • A.显存占用降低← 正确答案
  • B.训练速度提升← 正确答案
  • C.模型精度提升
  • D.通信开销降低← 正确答案

答案:ABD。混合精度让显存减半、速度提升 1.5~3 倍、分布式通信量减半,但模型精度通常“几乎不变”而不是“提升”。精度提升往往来自省出的显存换更大的 batch,而非混合精度本身。

Q8. 动态损失缩放中,检测到梯度上溢(inf/NaN)时应如何处理?

单选题 · mid

  • A.将缩放因子加倍
  • B.将缩放因子减半← 正确答案
  • C.立即停止训练
  • D.将损失归零

答案:B。检测到上溢说明缩放因子太大,应减半以回到安全区间;连续若干步无上溢才加倍。动态缩放就像管理员调整放大券倍率,溢出就调小、安全就调大,始终保持“刚好吃得下”。

Q9. 关于 PyTorch AMP 的 GradScaler,以下说法正确的有?(多选)

多选题 · hard

  • A.自动维护缩放因子← 正确答案
  • B.反向前放大损失← 正确答案
  • C.更新前还原梯度← 正确答案
  • D.将权重转成 FP16

答案:ABC。GradScaler 做了三件事:动态调缩放因子、scale(loss) 放大后反向、step 内部还原梯度更新权重。权重转换为 FP16 是由 autocast 完成的,且主副本权重始终留在 FP32。

Q10. FP16 的最小规格化正数约为多少?

单选题 · extreme

  • A.约 6.1e-5← 正确答案
  • B.约 1.2e-38
  • C.约 1.4e-45
  • D.约 5.9e-8

答案:A。FP16 的最小规格化正数为 2⁻¹⁴ ≈ 6.1e-5,比它小的梯度直接下溢为 0。FP32 最小约 1.2e-38,FP16 的量程下探非常有限,这正是需要损失缩放的根本原因。