跳转到内容

输入关键词开始搜索

    低精度浮点格式(FP16 与 BF16)

    概念更新 2026-08-02置信度 high#概念#基础#长青#数值计算#训练

    FP16 与 BF16 都用 16 bit 存数,但 FP16 把更多位给尾数、BF16 把更多位给指数;前者相对精细,后者动态范围更接近 FP32。

    格式 符号位 指数位 尾数位 指数 bias 主要特征
    FP32 1 8 23 127 范围与精度都较高
    FP16 1 5 10 15 尾数较多,但容易上溢/下溢
    BF16 1 8 7 127 动态范围接近 FP32,但有效精度较低

    规格化数可写为:

    (1)s×(1.m)2×2ebias.(-1)^s\times(1.m)_2\times 2^{e-\mathrm{bias}}.

    指数全 0 时包含零与 subnormal;指数全 1 时表示无穷或 NaN。subnormal 用更少有效位换取靠近 0 的渐进下溢区间。

    • FP16 的 10 位尾数使局部数值刻画比 BF16 更细,但 5 位指数限制动态范围。
    • BF16 保留 FP32 的 8 位指数,较不容易因大梯度溢出;代价是只有 7 位尾数。
    • 低精度节省权重、激活和带宽,不代表每个算子都应强制用同一种 dtype。

    为什么训练时不能只做 dtype 转换

    Section titled “为什么训练时不能只做 dtype 转换”

    训练包含前向、反向、梯度归约和参数更新。FP16 中很小的梯度可能下溢为 0,很大的中间值可能变成 inf。实际训练通常配合 自动混合精度(AMP):适合的算子用低精度,敏感计算保留更高精度,并在 FP16 场景用 loss scaling 放大梯度。

    BF16 因范围接近 FP32,通常不依赖同样程度的动态 loss scaling;但它的尾数更短,并不保证所有任务都比 FP16 更准确。

    第 5 讲 notebook 通过位级拆解与 Python/NumPy 实验观察:

    • 符号、指数、尾数如何还原数值;
    • normal、subnormal、inf 与 NaN;
    • FP16/BF16 在“大范围”和“细精度”上的不同;
    • 低精度算术中的舍入、上溢和下溢。

    第 7 讲把这些数值性质连接到 AMP 训练;第 8 讲进一步进入 int8 线性层量化。三者是相邻但不同的问题。

    • BF16 比 FP16“位数更多”:总位数相同,只是指数/尾数分配不同。
    • 低精度一定让模型更快:还取决于硬件内核、数据搬运和算子支持。
    • 把模型 .half() 就等于 AMP:全模型 FP16 与按算子选择精度的 AMP 不相同。
    • 精度格式决定最终质量:训练配方、缩放、优化器状态和硬件实现同样关键。