从TensorRT看INT8量化原理

从TensorRT看INT8量化原理 - nanmi - 博客园从TensorRT看INT8量化原理 - nanmi - 博客园

 

  • 简单的将一个tensor 中的 -|max| 和 |max| FP32 value 映射为 -127 和 127 ,中间值按照线性关系进行映射。
  • 称这种映射关系为不饱和的(No saturation ),对称的。

  • 这种做法不是将 ±|max| 映射为 ±127,而是存在一个 阈值 |T| ,将 ±|T| 映射为±127,显然这里 |T|<|max|。
  • 超出 阈值 ±|T| 外的直接映射为阈值 ±127。比如上图中的三个红色点,直接映射为-127。
  • 称这种映射关系为饱和的(Saturate ),不对称的。
  • 只要 阈值 选取得当,就能将分布散乱的较大的激活值舍弃掉,也就有可能使精度损失不至于降低太多;

        网络的前向计算涉及到两部分数值:权值和激活值(weights 和activation,二者要做乘法运算),Szymon Migacz 也提到他们曾经做过实验,说对weights 做saturation (饱和量化)没有什么变化,因此 对于weights的int8量化就使用的是不饱和的方式;而对activation做saturation就有比较显著的性能提升,因此对activation使用的是饱和的量化方式。

        那现在的问题是 如何确定|T|?我们来思考一下,现在有一个FP32的tensor,FP32肯定是能够表达这个tensor的最佳分布。现在我们要用一个不同的分布(INT8)来表达这个tensor,这个 INT8 分布不是一个最佳的分布。饱和的INT8分布由于阈值 |T|的取值会有很多种情况(128−|max|

        既然如此,我们就需要一个衡量指标来衡量不同的 INT8 分布与原来的FP3F2分布之间的差异程度。这个衡量指标就是 相对熵(relative entropy),又称为KL散度Kullback–Leibler divergence,简称KLD);

KL散度 = 交叉熵 - 信息熵

其中,交叉熵公式如下:

信息熵公式如下:

那么,具体如何得到阈值T呢?

        这里的做法是 从验证集 选取一个子集作为校准集(Calibration Dataset ),校准集应该具有代表性,多样性,最好是验证集的一个子集,不应该只是分类类别的一小部分。激活值分布就是从校准集中得到的。

  • 首先在 校准集上 进行 FP32 inference 推理;
  • 对于网络的每一层(遍历):
    • 收集这一层的激活值,并做 直方图(histograms ),分成几个组别(bins)(官方给的一个说明使用的是2048组),分组是为了下面遍历 |T| 时,减少遍历次数;
    • 对于不同的 阈值 |T| 进行遍历,因为这里 |T|的取值肯定在 第128-2047 组之间,所以就选取每组的中间值作为 T 进行遍历;
      • 选取使得 KL_divergence(ref_distr, quant_distr) 取得最小值的 |T|。
  • 返回一系列 |T|值,每一层都有一个 |T|。创建 CalibrationTable 。

上面解释一下:假设 最后 使得 KL散度最小的|T|值是第200组的中间值,那么就把原来 第 0-200组的 数值线性映射到 0-128之间,超出范围的直接映射到128

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值