浮点数用「符号 + 指数 + 尾数」三段式在有限位宽内表示实数:指数定范围,尾数定精度。FP16/BF16/TF32 的全部差异都源于位宽分配的取舍,而梯度下溢、GradScaler、混合精度选型这些训练侧问题,根因都在这张位分配表里。

IEEE 754 三段式结构

值公式:

  • 符号位 S:1 bit
  • 指数位 E:以 bias 偏移编码正负指数,FP32/FP16/BF16 的 bias 分别为 127/15/127
  • 尾数位 M:只存小数部分——首位是隐含前导 1(正规数恒可写成 ,这个 1 不必存),FP16 的 10 bit 尾数因此有 11 bit 有效位

指数以 2 为底是硬件决定的选择:乘 等价于小数点移位,走线切换即可、近乎零成本;若底为 10, 含因子 5,缩放必须走完整乘法器,延迟、面积、功耗全面上涨。IEEE 754-2008 确实定义了 decimal32/64/128 供金融场景——0.1 这类十进制小数在二进制浮点下无法精确表示,会计不容累积舍入误差——但无 GPU 原生加速,科学计算与深度学习全不用它。

三种格式的边界

格式S/E/Mbias最小正规数最大正规数最小次正规数
FP321/8/23127
FP161/5/101565504
BF161/8/7127

BF16 是对 FP32 的直接截尾(指数位与 bias 原封不动,尾数 23→7),因此范围与 FP32 完全一致、只牺牲精度;FP16 则是全新分配,5 bit 指数换来 10 bit 尾数,范围骤减。

正规数、次正规数与溢出

  • 正规数(normal):指数非全 0 非全 1,带隐含 1,是格式的主力区间
  • 次正规数(subnormal/denormal):指数全 0 时隐含位变 0,能表示更接近 0 的数,但有效位随数值缩小而减少,GPU 上还常走慢速路径或被 flush-to-zero 直接归零
  • 下溢(underflow):小于最小次正规数 → 0
  • 上溢(overflow):超过最大正规数 → inf

训练梯度的典型量级是 。FP16 正规区间下限 ,梯度一转 FP16 就落入次正规区甚至归零:

torch.tensor([1e-7]).half()   # 1.19e-07,舍到次正规格点,有效位寥寥
torch.tensor([5e-8]).half()   # 5.96e-08,被钳到最小次正规,再小即归零

这就是 FP16 训练必须配 GradScaler(放大 loss 把梯度推回正规区间)、而 BF16 免疫下溢(正规区间下限 )的全部原因。训练侧的工程取舍——autocast 分流、scaler 链路、TF32——见 torch.cuda 与混合精度;BF16 的产业背景见 bfloat16。