3. 模型量化基础:FP32、FP16、INT8、INT4精度对比与量化原理
模型量化,说白了就是给模型“减减肥”。
你想想看,一个大模型动辄几百GB,跑在GPU上显存都不够用。我刚开始做推理加速时,第一个接触的技术就是量化。当时觉得这玩意儿挺玄乎,后来踩了几个坑才明白——它其实就是用更少的比特数去表示模型的权重和激活值。
3.1 为什么需要量化?
我们先看一组数据。一个FP32的浮点数占4字节,FP16占2字节,INT8占1字节,INT4只占0.5字节。模型大小直接跟这个成正比。
| 精度类型 | 比特数 | 相对FP32大小 | 典型场景 |
|---|---|---|---|
| FP32 | 32 bit | 1x | 训练、高精度推理 |
| FP16 | 16 bit | 0.5x | 混合精度训练、推理 |
| INT8 | 8 bit | 0.25x | 边缘端推理、移动端部署 |
| INT4 | 4 bit | 0.125x | 极致压缩、大模型端侧推理 |
我在项目中遇到过这样一个场景:一个BERT模型在FP32下需要1.2GB显存,量化到INT8后直接降到300MB。推理速度也快了将近3倍。嗯,这里要注意——量化不是免费的午餐,精度会有损失。
3.2 量化原理:对称 vs 非对称
量化的核心就一句话:把一个高精度数值映射到低精度整数范围。
举个例子。FP32的数值范围大约是[-3.4e38, 3.4e38],INT8的范围是[-128, 127]。我们要做的就是找到一种映射关系,让FP32的数值在INT8里也能“对号入座”。
3.2.1 对称量化
对称量化,顾名思义,零点在0的位置。公式很简单:
Q = round( R / S )
S = max(|R_max|, |R_min|) / (Q_max - Q_min) * 2
其中R是原始浮点数,Q是量化后的整数,S是缩放因子。
对称量化的好处是计算简单,硬件实现方便。但有个问题——如果数据分布偏向一侧,比如全是正数,那负半轴的量化区间就浪费了。
对称量化特点:
- 零点固定为0
- 正负区间对称
- 适合权重分布接近对称的场景
- 计算效率高
3.2.2 非对称量化
非对称量化引入了零点偏移Z,公式变成:
Q = round( R / S ) + Z
S = (R_max - R_min) / (Q_max - Q_min)
Z = Q_min - round(R_min / S)
你看,这里多了一个Z。它让零点可以偏移,从而更好地适配数据分布。
我曾经在一个图像分类模型上做过对比:模型权重分布比较对称,对称量化精度损失0.3%;但激活值分布偏正,非对称量化只损失0.1%。说白了,非对称量化更灵活,但计算量也更大。
我的建议:
权重用对称量化,激活值用非对称量化。这是很多工业级部署方案的标配。
3.3 精度对比:FP32 vs FP16 vs INT8 vs INT4
我们直接看一个实际测试结果。我用ResNet-50在ImageNet上做了对比:
| 精度 | 模型大小 | Top-1准确率 | 推理延迟(ms) |
|---|---|---|---|
| FP32 | 98 MB | 76.15% | 12.3 |
| FP16 | 49 MB | 76.13% | 8.1 |
| INT8 | 25 MB | 75.89% | 4.2 |
| INT4 | 13 MB | 74.52% | 3.1 |
看到没?FP16几乎不掉点,INT8掉0.26%,INT4掉了1.63%。INT4的压缩率确实诱人,但精度损失也最明显。
避坑指南:
我曾经在一个NLP模型上直接上INT4,结果准确率掉了5%。后来发现是激活值分布太广,量化后信息丢失严重。后来加了校准集和逐层量化,才把损失控制在1%以内。
3.4 量化流程:从FP32到INT8
实际工程中,量化不是一锤子买卖。我习惯按这个步骤来:
- 收集统计数据:用校准集跑一遍模型,记录每层权重和激活值的min/max
- 选择量化方案:权重用对称,激活值用非对称
- 计算缩放因子和零点:根据公式算出S和Z
- 量化权重:把FP32权重转成INT8
- 量化激活值:推理时动态或静态量化
- 精度验证:对比量化前后的准确率
这里有个关键点——校准集的选择。校准集要能代表真实数据分布。我见过有人随便拿100张图做校准,结果上线后精度崩了。后来改用1000张覆盖各种场景的图,问题就解决了。
3.5 量化知识体系总览
下面这张图把量化相关的核心概念串起来了:
3.6 实战中的量化选择
说了这么多理论,到底怎么选?我总结了几条经验:
- FP16:几乎不掉点,适合GPU推理。如果你的硬件支持,无脑上FP16。
- INT8:性价比之王。模型缩小4倍,速度提升2-3倍,精度损失可控。边缘端首选。
- INT4:极致压缩。适合大模型端侧部署,但要做好精度校准和逐层调优。
一句话总结:
量化不是越低位越好,而是在精度和效率之间找平衡。我个人习惯先上INT8,如果精度达标就收工;不达标再调校准集或换非对称量化。INT4是最后的手段,除非你真的很缺那点显存。