模型量化一直是模型部署阶段一个重要的过程。从学术上看,很多通用模型在常规8bit量化下的指标已经刷爆了,我们之前介绍过一个模型量化的综述性的系列,其中的论文在8bit下的结果大部分看起来都游刃有余,因此越来越多的论文都已经迈入到4bit阶段,考虑int4在通用模型上的量化。面对不可避免的精度下降,一般会使用类似brecq、LSQ这样的权重或量化参数的调整方案。在工业上,尽管大部分模型在int8量化下基本可以保证精度,但是还会有很多对精度要求高,或者权重激活分布特殊的模型,它们在int8量化后都会掉点严重。
综上,目前在工业上的状态是int8勉强可用,甚至某些情况下还需要借助fp16等更高比特的配置,基本就更不会考虑了int4了。那么有没有一种方案的效果能介于int8和fp16之间,而且还不需要堆很多trick呢,这就很容易让人联想到fp8这种方案。
和fp32不同,fp8并没有IEEE标准的指数位和小数位的分配方式。FP8这种数制对描述钟形分布有着天然的优势,并且深度学习中的大部分模型中的数据分布都是钟形分布,只是可能平坦度有区别。因此一些方法对模型尝试5M2E(5个小数位/2个指数位/1个符号位)、4M3E等方案,然后采用效果最好的方式。不管怎么样,FP8量化的热度已经明显增加,很多芯片例如NVIDIA的H100已经支持了FP8这种数制,并且一些厂商例如特斯拉已经将FP8应用到了实际业务中。最近翻论文的时候又发现有大厂分别在axriv上投稿了两篇新鲜的FP8论文,分别是
高通:FP8 Quantization: The Power of the Exponent
NVIDIA&ARM&INTEL:FP8 FORMATS FOR DEEP LEARNING
两篇都对FP8量化做了详细的介绍,这次我们就先一起解读一下第一篇高通对FP8量化的理解。这篇文章由于是刚刚放出来的初版,文章里某些细节可能有一些错误,但它的内容很丰富。我们主要分三个方面介绍:FP8初识、FP8实现、FP8效果。
1. FP8初识
在认识FP8之前,我们首先回顾一下浮点数的表示方式
在了解了FP8的表示机制后,我们先来看一下这种数制对于数据的量化效果,如下图
左边这幅图中表示数据在不同的量化配置下的量化影响,这里拿两种FP8数制和int8数制进行了比较,明显可以看出对于接近0附近的x,fp8要比int8的量化误差更小,并且小数位更多的4M3E的FP8比3M4E的量化误差更小;中间的图纵轴换成了概率密度函数加权的量化误差,结论和左图一样(各种量化误差的计算方式可以在论文附录里找到推导);最右边的图很重要,它比较了在FP8中,bias(上述公式中的b)的选择的影响。蓝色的柱子表示标准的bias选择方式,也就是,这种方式在5M2E的数制下直接崩掉了,因为对于它可表示的范围太小了;绿色的柱子表示整数bias,但是具体是怎么计算的论文里没有说,我推测是标准的bias值乘以一个scale factor后取整得到的,而这个scale factor的求解方式我们在下一节讲到;橙色的柱子可以看出量化误差是最小的,它是由标准的bias乘以scale factor后得到的浮点值,可能这里大家第一次看会有点疑问,bias还能取浮点值?其实只要只有p和m必须是整数,当bias是浮点值时,x可以被更精确的用2的浮点次幂来表示。
上面这三张图表示了不同的量化配置对不同的分布的影响,左边两张图是对于一些理想分布的量化误差,包括标准分布、均匀分布和两种学生分布;最右边是对Resnet18的一个层的真实分布的量化误差,因此论文中对resnet18给出的量化配置建议就是M5E2(这里的bias用的什么不确定)。
2. FP8实现
在了解了上一节FP8对刻画不同分布的优越性之后,我们要对模型使用FP8这种量化方式就需要得到它的量化参数,类似INT8的量化参数scale,从而才能在软件上模拟FP8量化的精度。FP8我们需要求得的量化参数有两个:bias和m,有了它们p也就能推导出来,从而在硬件上可以配置FP8的实现方式。
其中,c是当前数制的最大值,因此量化后的结果需要按其值做裁剪。而p的裁剪根据公式3可知只需要一个下限,由于论文里规定了当p=0时表示浮点数1,因此其下限时是1-b-m。
PTQ的方式比较直接,就是网格搜索。对于m考虑1,2,3,4,5,6这些值,对于 c,找到输入的最大绝对值 σ,并在 0.1σ 和 1.2σ 之间的 111 个均匀间隔的值上运行网格搜索。然后我们记录最小化 MSE 的 m 和 c 的值作为FP8量化器的参数。论文也提到了训练得到的参数和线性搜索参数也比较接近。
3. FP8效果
论文中还对不同的模型运用不用的8bit量化进行了丰富的实验,首先是几个常见的通用模型的量化结果。下表是PTQ的方式的量化结果,对于Fixed bias这一列,表示的是bias用固定的标准值,然后选用了3种指数位和尾数位的分配方式;Flex bias是指bias是可以通过scale调整的,而指数位和尾数位的分配方式也是手动选择了3种;Flexible表示量化参数完全灵活,包括m和bias的选取,也就是我们在第二节的公式里要求的目标。
根据结果我们可以得到几个结论:
- 只有当指数位偏移bias进行调整时,FP8的效果才比INT8好。
- 手动选取指数位和尾数位的分配方式和灵活选择差别不大,毕竟m的搜索空间本来就很小。论文里说可能是因为他们使用的局部贪心搜索方法找不到全局最优的设置。
- 具有大激活异常值的网络(ViT、Bert、SalsaNext 和 HRNet)对于具有更多指数位的格式显示出更好的结果,因为它们有更大的动态范围。
下表是比较了QAT和PTQ方式的量化结果。从中我们看到 QAT 可以提高 FP8 量化模型的性能。与仅学习权重相比,学习最大值 c 和指数位数 m 提高了 ResNet18 和 MobileNetV2的结果,但会稍微损害 BERT 的性能,尽管差异很小。总体来说,QAT 减少了不同格式之间的精度差距,因为网络的权重可以适应不同配置的量化器。
另外,论文没有明确表示实验中的FP8量化是用的per tensor还是per channel,但附录里提到,如果使用per channel量化,每个channel会有一个自己的clip最大值c,但尾数位数m还是整个tensor共享一个。
这篇文章先介绍到这,有些细节可能我理解的也不是很深,还是推荐大家可以阅读一下原论文。之后有时间的时候会再介绍一下NVIDIA&ARM&INTEL的那篇FP8论文,欢迎关注。
The End
作者:液态黑洞
编辑丨GiantPandaCV
来源:GiantPandaCV
推荐阅读
- 如何使用“LoRa”的方式加载ONNX模型:StableDiffusion相关模型 的C++推理
- TransformerEngine代码走读
- 60行代码加速20倍 NEON实现深度学习OD任务后处理绘框
- BitsFusion 权重量化方法,使 UNet 模型体积减少一半,所有评估中超过了全精度模型 !
欢迎大家点赞留言,更多Arm技术文章动态请关注极术社区嵌入式AI专栏欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。