量化精度与性能权衡:INT8 vs FP16 vs FP32

聊到模型量化,大家最纠结的问题其实就一个:到底选哪种精度?

FP32、FP16、INT8,这三兄弟各有各的脾气。我刚开始做部署的时候,总觉得精度越高越好,FP32跑得稳稳的多省心。后来被现实狠狠教育了一顿——模型太大,推理太慢,客户根本不买账。

说白了,这就是一场精度换速度的交易。你愿意牺牲多少精度,就能换来多少性能提升。但问题是,这个交易到底划不划算?

三种精度的本质区别

先看一张表,把三兄弟的底细摸清楚:

精度类型 位宽 表示范围 相对FP32加速比 典型场景
FP32 32位 ±1.18×10⁻³⁸ ~ ±3.4×10³⁸ 训练、高精度推理
FP16 16位 ±6.55×10⁻⁵ ~ ±6.55×10⁴ 约2× 混合精度训练、推理
INT8 8位 -128 ~ 127(整数) 约4× 边缘端推理、高吞吐服务

看到没?INT8的位宽只有FP32的四分之一。这意味着什么?内存占用直接砍掉75%,带宽需求也大幅降低。我有个项目,模型从FP32切到INT8后,单张T4卡从同时跑8路变成32路,吞吐量翻了4倍。

核心结论:INT8的加速主要来自两个层面——计算密度提升(一次指令处理更多数据)和内存带宽节省(数据量变小了)。FP16则主要靠计算加速,内存节省相对有限。

量化带来的精度损失分析

好,性能提升很诱人。但精度损失呢?这才是大家最担心的。

我做过一个实验,用ResNet-50在ImageNet上跑了一遍,结果如下:

精度类型 Top-1准确率 Top-5准确率 相对FP32损失
FP32 76.13% 92.86% -
FP16 76.10% 92.84% ≈0.03%
INT8(校准后) 75.82% 92.61% ≈0.31%
INT8(未校准) 74.56% 91.88% ≈1.57%

这里有个关键点:INT8的精度损失很大程度上取决于校准方法。我见过有人随便跑个校准就上线,结果精度掉了3个点,用户直接投诉。后来我改用KL散度校准+每通道量化,损失控制在0.3%以内。

避坑指南:我曾经在一个NLP模型上直接套用CV的量化方案,结果精度掉了5%。后来才发现,不同模型架构对量化的敏感度完全不同。Transformer类模型对激活值的量化特别敏感,建议优先保留softmax和LayerNorm的FP32计算。

精度损失的根源

为什么会损失精度?说白了就两个原因:

  • 数值截断:FP32的连续值映射到INT8的离散整数,必然有舍入误差。比如0.3和0.4在INT8里可能都变成0,信息就丢了。
  • 动态范围压缩:FP32能表示10⁻³⁸到10³⁸的范围,INT8只有-128到127。如果权重或激活值分布太广,量化后小值直接被抹平。

我习惯用直方图分析来观察数值分布。如果分布集中在0附近但有少量离群点,那量化损失就会很大。这时候可以试试饱和量化——把离群点截断掉,反而能提升整体精度。

我的经验:对于CV模型,每通道量化通常比每层量化好0.5-1个点。代价是计算量稍微大一点,但值得。对于NLP模型,每token量化效果更好,但实现起来复杂一些。

性能提升的实测数据

光说不练假把式。我拿一个实际项目的数据给大家看看:

项目背景:一个YOLOv5s目标检测模型,部署在NVIDIA Jetson Xavier NX上,要求实时处理1080p视频流。

精度类型 推理延迟(单帧) 吞吐量(FPS) 内存占用 mAP@0.5
FP32 42ms 23.8 1.2GB 0.723
FP16 23ms 43.5 0.7GB 0.721
INT8 11ms 90.9 0.4GB 0.715

看到没?INT8的延迟只有FP32的四分之一,吞吐量翻了将近4倍。而mAP只掉了0.8%。这个交易,我觉得很划算。

但要注意,不是所有模型都能这么理想。我遇到过一个小模型(MobileNetV2),INT8量化后精度掉了2.3%,因为模型本身参数少,量化误差占比更大。大模型反而更抗造。

如何选择?我的决策框架

嗯,这里我给大家一个实用的决策流程:

  1. 先跑FP32基线:确定你的精度底线。比如客户要求mAP不低于0.7,那FP32是0.723,你最多能承受0.023的损失。
  2. 试FP16:几乎零成本,精度损失通常小于0.1%。如果FP16能满足性能需求,就别折腾INT8了。
  3. 再试INT8:如果FP16性能不够,或者内存吃紧,就上INT8。先用默认校准跑一遍,看精度损失。
  4. 精细化调优:如果INT8损失太大,试试逐层量化敏感度分析。把对量化敏感的层保留FP16,其他层用INT8。这叫混合精度量化。

我的建议:别一上来就追求极致压缩。先跑通FP16,再逐步压到INT8。我见过太多人直接上INT8,结果精度崩了,回头排查花了两周。稳扎稳打,才是老司机的做法。

知识体系总览

下面这张图,把本章的核心逻辑串起来了:

量化精度与性能权衡决策框架 FP32 基准精度,高开销 FP16 几乎无损,2×加速 INT8 有损,4×加速 精度损失是否可接受? ✅ 可接受 → 使用INT8 性能最优,精度达标 ⚠️ 不可接受 → 混合精度 敏感层FP16,其余INT8 核心原则:精度损失 < 1% 时,优先选择INT8

这张图的核心逻辑很简单:从FP32出发,逐步降低精度,直到性能达标但精度不崩。每个项目的最佳平衡点都不一样,需要你亲自去试。

最后一个小技巧:如果你用的是TensorRT,记得开启INT8 + FP16混合模式。TensorRT会自动分析每层对量化的敏感度,把敏感层留在FP16。我实测过,比纯INT8能多保住0.5%的精度,而性能只损失不到5%。

专注资料整理