Working with Quantized Types(一)
- Quantization Workflows
- Post-training quantization (PTQ)
- Quantization-aware training (QAT)
- Quantization Modes
距离上一篇文章已经过去快一年了,这一年也真够忙的,也够累的,躺平吧又躺不平,赚钱吧又赚不到,先混着吧,考虑到对于部署的人来说,TensorRT的确非常重要,而且自己还有很多不会的地方,所以还是想着把剩下没有滤掉的地方认真搞一下,特别是后面的plugin部分,估计是面试的重点和难点。
这一节我们来学习一下量化的知识。
官方文档说TensorRT支持的量化方法是对称量化,支持有符号int8、FP8、有符号int4、和FP4,量化到反量化也只是一个简单的乘法操作,使用sacle的倒数,再经过clamping、rounding或者casting进行。TensorRT对激活值+权重的量化支持int8、fp8、fp4,但是对于Weight-only的量化,也就是只量化权重的情况只支持int4。
Quantization Workflows
对于网络的量化,有两种方式,分别是PTQ和QAT
Post-training quantization (PTQ)
对网络进行训练后得到尺度因子。TensorRT为PTQ提供了一个称为calibration的工作流程。当网络在代表性输入数据上执行时,它测量每个激活张量内的激活分布,然后使用该分布来估计每个张量的缩放值
Quantization-aware training (QAT)
利用伪量化计算训练过程中的尺度因子,模拟量化和反量化过程。这允许训练过程补偿量化和反量化操作的影响。
可以使用Quantization Toolkit来进行QAT和PTQ,在github仓库里,这部分缺少guide,暂时放过,后面有机会补充。
几种量化算法:
int8:
首先统计出ch通道的最大最小值,然后计算出s,再然后x/s,并且约束范围到[-128, 127]
FP8:
基本一致,只是约束的范围不同而已
int4:
上方的舍入规则:
Round half to even 的规则:
如果舍入的数值的尾数正好是中间值(例如 0.5、5.5 等),则舍入到最近的偶数。
否则,按照常规的舍入规则进行舍入。
Quantization Modes
tensorrt支持三种量化尺度
- 逐张量量化:单个尺度值(标量)用于缩放整个张量。
- 逐通道量化:一个尺度张量沿着给定的轴传播——对于卷积神经网络,这通常是通道轴,就是按照通道方向进行统计
- 块量化:张量沿着单个维度分成固定大小的1维块。为每个块定义一个比例因子
激活值只能使用逐张量量化,权重这几种方法都支持
对于其中的范围,你可以手动设置,需要使用setDynamicRange这个函数来:
tensor->setDynamicRange(min_float, max_float);
剩下的官方文档说了一堆,目前感觉没啥用,就不看了。