数值精度基础:浮点数与定点数的表示与区别
做模型量化,第一个绕不开的问题就是:这些数字到底是怎么存的?
FP32、FP16、BF16、INT8、INT4……光看名字就够晕的。但说白了,它们只是用不同位宽去表示一个数值。位宽越少,能表示的范围和精度就越有限——这就是量化的代价,也是量化的核心。
我个人习惯把数值精度分成两大类:浮点数和定点数。浮点数适合训练,定点数适合推理。为什么?往下看。
浮点数:FP32 / FP16 / BF16
浮点数的结构,我猜你大概知道:符号位 + 指数位 + 尾数位。但不同格式怎么切分,差别很大。
| 格式 | 总位宽 | 符号位 | 指数位 | 尾数位 | 最大正数 | 最小正数 |
|---|---|---|---|---|---|---|
| FP32 | 32 | 1 | 8 | 23 | ~3.4e38 | ~1.4e-45 |
| FP16 | 16 | 1 | 5 | 10 | 65504 | ~6.0e-8 |
| BF16 | 16 | 1 | 8 | 7 | ~3.4e38 | ~1.2e-38 |
FP32 是标准单精度,训练时最常用。FP16 也叫半精度,指数位只有 5 位,范围窄了很多。BF16 是 Google 搞出来的,保留了 FP32 的 8 位指数,只砍尾数——所以它范围跟 FP32 一样大,但精度低。
关键点:BF16 的指数位和 FP32 一样,所以从 FP32 转 BF16 基本不会溢出。这在训练中非常友好。我在项目中遇到过用 FP16 训练时梯度直接炸掉的情况,换成 BF16 就稳了。
定点数:INT8 / INT4
定点数就简单多了:符号位 + 整数位,没有指数。INT8 用 8 位表示,INT4 用 4 位。范围很直观:
- INT8:有符号 -128 ~ 127,无符号 0 ~ 255
- INT4:有符号 -8 ~ 7,无符号 0 ~ 15
你想想看,一个 INT4 只能表示 16 个值。要把一个 FP32 的权重塞进 16 个格子,信息损失有多大?这就是量化要解决的核心矛盾。
注意:INT4 虽然省显存,但精度损失非常明显。我曾经在某个 NLP 模型上试过 INT4 量化,推理速度是快了,但 BLEU 掉了 3 个点——业务方直接打回。所以 INT4 一般只用在极端场景,比如手机端或边缘设备。
浮点数 vs 定点数:核心区别
我习惯用一张表来对比:
| 维度 | 浮点数 | 定点数 |
|---|---|---|
| 表示范围 | 大(指数可调) | 小(固定位宽) |
| 精度分布 | 不均匀(靠近 0 更密) | 均匀(等间隔) |
| 硬件计算 | 慢(需要指数对齐) | 快(直接整数运算) |
| 典型用途 | 训练、梯度更新 | 推理、部署 |
浮点数为什么适合训练?因为梯度值经常很小,比如 1e-6 这种。FP32 能表示,INT8 直接归零。定点数为什么适合推理?因为推理时权重和激活值可以缩放到一个固定范围,用整数算更快。
我的经验:做量化时,先搞清楚你的模型里数值分布是什么样的。如果大部分值集中在 0 附近,用 INT8 量化效果通常不错。如果分布很散,就得考虑 per-channel 量化或者更复杂的方案。
知识体系结构图
下面这张图帮你理清本章的核心逻辑:
为什么量化要用定点数?
原因其实就两个:快和省。
- 快:整数运算在 CPU/GPU/NPU 上都有专用指令,比浮点运算快 2-4 倍。我实测过一个 MobileNet,INT8 推理比 FP32 快了 3.2 倍。
- 省:INT8 只占 1/4 的存储,INT4 只占 1/8。模型从 500MB 缩到 125MB,加载时间、内存占用都大幅下降。
但代价也很明显:精度损失。你想想看,一个 FP32 的权重可能是 0.123456,INT8 只能表示到 0.12 或者 0.13,小数点后第三位以后全丢了。如果模型对精度敏感,量化后效果会明显变差。
避坑指南:我曾经在某个图像分类模型上做 INT8 量化,Top-1 准确率从 76.3% 掉到 74.1%。后来发现是激活值的分布太宽,量化步长太大。改用 per-tensor 的对称量化后,准确率回到了 75.8%。所以量化不是简单的“转格式”,得根据数据分布选策略。
浮点数转定点数:量化本质
量化的数学本质很简单:
Q = round(R / S) + Z
其中:
- R:原始浮点数
- Q:量化后的整数
- S:缩放因子(步长)
- Z:零点偏移
反量化就是逆过程:
R = (Q - Z) * S
说白了,就是用更少的比特去近似原来的数值。S 越小,精度越高,但能表示的范围越小。S 越大,范围越大,但精度越差。这就是量化的精度-范围权衡。
我的建议:刚开始做量化时,先用 INT8 对称量化(Z=0)试试。对称量化实现简单,硬件支持也好。如果精度不够,再考虑非对称量化或者 per-channel 量化。别一上来就上 INT4,除非你真的很缺显存。
本章小结
数值精度是量化的地基。FP32 是标准,FP16/BF16 是训练时的折中,INT8/INT4 是推理时的利器。理解它们的表示方式和区别,你才能知道量化到底损失了什么、换来了什么。