dtype

浮点数

计算机里的浮点数由三部分组成:符号位 (Sign) + 指数位 (Exponent) + 尾数位/精度位 (Mantissa/Fraction)

  • 符号位:决定正负。
  • 指数位:决定数值的范围(能表示多大的数,多小的数)。
  • 尾数位:决定数值的精度(小数点后能精确到几位)。

各个数据类型的数值位含义:

格式总位数符号位 (Sign)指数位 (Exponent) [范围]尾数位 (Mantissa) [精度]
FP32 (标准)321823
FP16 (传统)1615 (范围窄)10 (精度尚可)
BF16 (新贵)1618 (范围同FP32)7 (精度低)
  • FP16 说:“我想要保留多一点细节(精度),所以我牺牲了指数位。”
  • BF16 说:“我不想管溢出的问题,我要和 FP32 一样的范围,所以我牺牲了细节(精度)。”

深入理解 FP16 (IEEE 754 Half-Precision)

特点:精细但“腿短”

  • 优势:它的精度相对较高(有10位尾数)。在处理需要细微差别的计算(如某些图像处理任务或早期深度学习模型)时,数值更准确。
  • 致命弱点范围太小
    • 它的指数位只有 5 位,最大只能表示约 $65504$。
    • 在深度学习训练中,梯度的变化范围非常大。如果不小心,数值很容易变成 NaN (溢出) 或 0 (下溢)。
  • 补救措施:为了用 FP16 训练,必须使用一种叫 “混合精度训练 (Mixed Precision) + Loss Scaling” 的技术。你需要人为地把数值放大(Scaling),防止它因为太小变成0,算完后再缩回去。这增加了软件开发的复杂性。

深入理解 BF16 (Brain Floating Point)

特点:粗糙但“腿长”

  • 起源:Google Brain 团队为了 TPU 设计的格式(所以叫 Brain Float)。
  • 核心逻辑:它是直接把 32 位的 FP32 截断成 16 位。它保留了 FP32 完整的 8 位指数,直接砍掉了后面的尾数。
  • 优势
    1. 范围宽:它能表示的数值范围和 FP32 一模一样。你几乎不需要担心数值溢出(Overflow)或下溢。
    2. 易于转换:从 FP32 转 BF16 不需要复杂的数学运算,直接扔掉后 16 位就行,硬件实现非常简单且快。
    3. 训练稳定:在训练大模型(如 Transformer/LLM)时,无需复杂的 Loss Scaling 技巧,开箱即用。
  • 弱点精度低。它的有效数字位数较少。但令人惊讶的是,深度神经网络(尤其是大模型)对精度的容忍度很高,它们更像是一种统计模型,一点点噪音(低精度)通常不会影响最终效果,甚至有时能起正则化作用。

支持情况

硬件支持

  • 早期的 GPU(如 NVIDIA Pascal/Volta V100)主要支持 FP16。
  • 现代 GPU(如 NVIDIA Ampere A100, Hopper H100, RTX 30/40系列)和 TPU 都原生支持 BF16。