MIT-BEVFusion系列七--量化4 calibrate 标定与敏感层禁用(较重要)

本文详细介绍了如何设置数据并行和评估模式,加速校准计算,特别是针对输入和权重的量化处理,以及如何融合ReLU和稀疏卷积。文章涵盖了从收集统计数据、校准模型到对特定层的量化策略,以及最终的PTQ模型储存和融合操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

该系列文章与qwe一同创作,喜欢的话不妨点个赞。

本文书接上回,替换层、conv与bn融合后,就要开启标定了。

标定这个步骤的结果,就是得到如下图onnx中qdq节点中的scale数值。

在这里插入图片描述

一、设置数据并行和评估模式

在这里插入图片描述

二、加速校准计算

在这里插入图片描述

在这里插入图片描述

这里主要找到所有 _input_quantizer_weight_quantizer,将 _input_quantizer 中的_calibrator._torch_hist 设置为 True,之后在校准时会使用 pytorch 进行直方图计算,如果使用默认值 False 的话,就会使用 numpy 来计算直方图。这里不会对 _weight_quantizer 进行修改,是因为 _weight_quantizer._calibrator 属于 calib.MaxCalibrator这个类。

三、校准模型

在这里插入图片描述

校准模型分为两个部分

  • 收集统计数据
  • 计算绝对最大值
3.1 收集统计数据
  • 收集的功能,封装在函数collect_stats中。
    在这里插入图片描述
3.1.1 禁用量化模式,启用校准模式

在这里插入图片描述

将模型切换到评估模式后,遍历模型中所有的子模块去寻找是否属于TensorQuantizer的子类。其实就是找量化层中的 _input_quantizer_weight_quantizer,如果找到 _input_quantizer_weight_quantizer,就将禁用量化模式(module.disable_quant)启用校准模式(module.enable_calib)

在这里插入图片描述

禁用量化模式就是将量化器中的 _if_quant 设置为 False。

在这里插入图片描述

启用校准模式就是将量化器中的 _if_calib 设置为 True。

在这里插入图片描述

这样在之后的 forward 中,就不会对数据进行量化操作,并且会收集数据用于校准。

3.1.2 收集统计数据
  • 其实就是执行了模型的前向,因为quantizer中的collect开关打开了,前向的过程已经不是输入数据,得到result这么简单了。而是输入数据,每个quantizer都会收集流转到这里的数据的动态范围。
    在这里插入图片描述
_input_quantizer

在这里插入图片描述

  • 通常_input_quantizer 创建时使用per-tensor加histogram的方式。即每个激活的量化器使用直方图的方式收集数据,最终计算出一个scale。

  • 第一次使用模块中的 _input_quantizer 收集数据时,量化器的校准器中并没有存储统计数据,即 _calib_hist_calib_bin_edgesNone,在进行统计数据收集时,直接将统计结果赋值给 _calib_hist,然后为 _calib_bin_edges 设置成一个长度为 2049 的张量,将0到输入数据x.max() 划分为 2049 个值

    • 其含义为 2048 个 bin 的 2049 个边界,即直方图的边界。
  • 这里的 self._num_bins 为 2048 是因为在初始化校准器时,默认设置的数值为 2048,是 tensorrt 默认设置的统计直方图时的 bin 的个数。

在这里插入图片描述

  • 除了第一次收集数据时会从零创建直方图,后续收集数据会更新第一次创建的直方图。
  • 更新直方图的最大值:amax
  • 更新直方图的边界的数值:_calib_bin_edges
  • 更新直方图的 bin 的个数:_num_bins
  • 111行判断当前数据的最大值与上一个统计的直方图的最大值哪个大。
  • 113行在保证bins的width 没有变化的情况下计算出新的bins的数量。114行计算出边界。主要是 116-117 行代码,需要再原始的直方图 bin 的数值上,将前一次与本次的直方图数值进行累加。
  • 如果这个模块中的 _input_quantizer 收集过数据,会先判断当前数据的最大值是否超过直方图的最大范围,超过了的话就会维持之前每个 bin 的区间,去扩充 bin 的数量到可以包容到现在数据的最大值。

在这里插入图片描述

之后会将之前统计的结果与当前统计的结果相加保存到 _calib_hist 中。

_weight_quantizer

在这里插入图片描述

使用模块中的 _weight_quantizer 收集数据时,先根据指定 axis 找出局部最大值。

  • 通常对于2d卷积的权重来说,因为形状通常是[O,I,KH,KW]的,并且采用PER_CHANNEL的方式,所以通常指定axis为0,即最终计算得到O个(输出通道数量个)scale。

在这里插入图片描述

在这里插入图片描述

这个是对于 torch.nn 中一些常用的 module 的 weight 的量化描述器的配置,这里主要会使用针对 Conv2D 和 ConvTranspose2D 的量化描述器,针对 SparseConv 的量化描述器是自定义的,主要区别就是 axis 不同,这里值为4,通常对于SparseConv的权重,这个维度也是输出的维度,在之后统计 amax 时会根据这个 axis 来统计最大值。

在这里插入图片描述

这里就会遍历出了指定 axis 之外的所有维度,找出每个维度的最大值,这样最后就可以将其余维度的最大值保存在指定 axis 中,最后的形状会变成 [1, 1, 1, 1, ori]。

在这里插入图片描述

训练好的模型,权重是固定的。
_cali

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值