1. 混合精度推理概述
各位同学,咱们今天聊聊混合精度推理。说实话,这个概念在端侧芯片上越来越重要了。我最早接触它是在一个智能音箱的项目里,当时芯片的算力捉襟见肘,模型跑起来卡得不行。后来用了混合精度,效果立竿见影。
什么是混合精度推理
混合精度推理,说白了就是让模型在推理时,不同层用不同精度的数据格式。比如卷积层用FP16,全连接层用INT8,甚至某些层用INT4。你想想看,这就像做菜——大火爆炒用猛火,小火慢炖用文火,各取所长。
我习惯把混合精度理解成「精度分级管理」。模型里有些层对精度敏感,比如Batch Normalization层,那就用高精度;有些层对精度不敏感,比如某些激活函数后的计算,那就用低精度。这样既保证了模型精度,又提升了推理速度。
核心思想:用最合适的精度,做最合适的事。
为什么需要混合精度推理
原因其实很直接——端侧芯片的资源太有限了。我做过一个统计,在某个AIoT芯片上,纯FP32推理的功耗是FP16的3倍多,但精度只差了0.1%。你说这值不值?
具体来说,有三大驱动力:
- 算力瓶颈:端侧芯片的算力通常只有几TOPS到几十TOPS。FP32的计算单元占面积大,能放的核数有限。换成FP16或INT8,同样面积能塞进更多计算单元。
- 带宽瓶颈:模型参数和中间结果需要频繁读写内存。FP32的数据量是FP16的两倍,是INT8的四倍。带宽就那么宽,数据量减半,速度自然翻倍。
- 功耗限制:端侧设备靠电池供电。低精度计算不仅快,还省电。我在一个智能摄像头项目里,用INT8推理比FP32省了40%的电量。
我的经验:别一上来就全盘用低精度。先跑一遍精度敏感度分析,看看哪些层可以降精度。我曾经有个模型,降了80%的层到INT8,精度只掉了0.3%。
FP16/INT8/INT4等精度格式介绍
这些格式各有各的脾气。我给大家梳理一下:
| 格式 | 位宽 | 动态范围 | 精度 | 典型场景 |
|---|---|---|---|---|
| FP32 | 32位 | ~10^38 | 高 | 训练、精度敏感层 |
| FP16 | 16位 | ~10^5 | 中高 | 推理、梯度计算 |
| INT8 | 8位 | [-128, 127] | 中 | 推理主力 |
| INT4 | 4位 | [-8, 7] | 低 | 极端压缩场景 |
FP16:这是最常用的混合精度格式。它的动态范围够大,不容易溢出。我记得第一次用FP16跑ResNet-50,精度和FP32几乎一样,但速度提升了1.8倍。嗯,这里要注意——FP16的梯度容易下溢,所以训练时一般用混合精度训练,推理倒还好。
INT8:这是端侧推理的「主力军」。INT8的计算单元比FP16小一半,比FP32小四分之三。但INT8的问题是动态范围窄,需要做量化校准。我建议用校准数据集跑一遍,找到每层的最佳缩放因子。
INT4:这个就比较激进了。INT4的压缩比高,但精度损失也大。我一般只在模型压缩到极限时才用,比如某些轻量级模型的后几层。曾经有个项目,用INT4把模型从2MB压到0.5MB,精度掉了2%,但客户能接受。
避坑指南:我曾经在某个芯片上直接用INT4跑MobileNet,结果精度掉了5%以上。后来发现是激活值分布太广,INT4根本装不下。解决办法是先做激活值裁剪,再量化。
端侧芯片的算力与带宽瓶颈
这个问题我感触很深。端侧芯片不像服务器GPU,它要兼顾成本、功耗和面积。我画了一张图,帮大家理解这个瓶颈:
从这张图能看出来,端侧芯片的算力和带宽是相互制约的。算力再高,带宽不够,数据喂不进去,计算单元只能干等。反过来,带宽再宽,算力不够,数据堆在缓存里也处理不完。
我举个例子。某个芯片的算力是4TOPS,带宽是20GB/s。跑一个FP32的模型,每帧需要处理100M个参数。算一下:
- 算力需求:100M × 4字节 = 400MB/帧
- 带宽限制:20GB/s ÷ 400MB = 50帧/秒
- 实际帧率:受带宽限制,最多50fps
如果换成INT8,每帧数据量变成100MB。带宽限制变成200fps。但算力呢?INT8的计算单元通常比FP32多4倍,所以算力瓶颈也松了。这就是混合精度的价值所在。
我的建议:选芯片时,别只看算力峰值。要算「有效算力」——带宽能喂饱的算力才是真算力。我见过不少项目,芯片标称10TOPS,实际跑起来连2TOPS都用不满,就是因为带宽不够。
好了,这一章就讲到这里。混合精度推理的核心就是「用精度换效率」。后面我们会深入讲量化方法、校准技巧,还有各种芯片上的实战经验。
本章要点:
- 混合精度推理 = 不同层用不同精度
- 三大驱动力:算力、带宽、功耗
- FP16适合精度敏感层,INT8是主力,INT4用于极端压缩
- 端侧芯片的算力和带宽相互制约,混合精度是破局关键