量化校准
根据所需的量化参数可以分为:权重量化和权重激活量化。
- 权重量化 :仅对网络中的权重执行量化,由于网络权重一般保存下来的,因此提前根据权重便可以计算出相应的量化参数S和Z,而不需要额外的校准数据集。一般来说,推理过程中,权重值的数量远小于激活值,仅对权重执行量化加速效果一般。
- 权重激活量化:不仅对网络中的权重进行量化,还对激活值(神经网络层的输出)进行量化。由于激活值的范围通常不容易提前获得,因此需要在网络推理过程中进行计算或者根据模型大致的预测。因此引入了量化校准步骤。
TensorRT进行PTQ量化
TnesorRT进行量化操作时,主要针对权重激活量化所需的量化校准步骤进行介绍。tensorRT中的calibrator类一共存在五种,分别为nvinfer1::IInt8EntropyCalibrator2、nvinfer1::IInt8MinMaxCalibrator、nvinfer1::IInt8EntropyCalibrator、 nvinfer1::IInt8LegacyCalibrator、 nvinfer1::IInt8Calibrator。
nvinfer1::IInt8EntropyCalibrator2:是tensorRT 7.0引入的接口,实现基于熵的INT8量化校准器。(默认情况下优先使用它)
nvinfer1::IInt8MinMaxCalibrator:实现基于最大值最小值的INT8量化校准器。
nvinfer1::IInt8EntropyCalibrator:是tensorRT 7.0之前的接口,实现基于熵的INT8量化校准器。(目前已被弃用)
nvinfer1::IInt8LegacyCalibrator:是tensorRT 6.x之前的接口。(目前已被弃用),IInt8MinMaxCalibrator和IInt8EntropyCalibrator可以完全取代它。
nvinfer1::IInt8Calibrator:是 IInt8LegacyCalibrator 的基类,用于向后兼容。如果要实现自定义的 INT8 量化校准器,可以选择从该基类派生,并实现所需的校准逻辑。
因此优先使用IInt8EntropyCalibrator2接口
使用tensorRT进行量化时,首先需要创建一个自定义calibrator类,该类继承上述几种接口。并且实现其虚函数。
class Int8EntropyCalibrator : public nvinfer1::IInt8MinMaxCalibrator
{
// class Int8EntropyCalibrator: public nvinfer1::IInt8EntropyCalibrator {
public:
Int8EntropyCalibrator(CalibratorParams ¶ms);
~Int8EntropyCalibrator(){};
int getBatchSize() const noexcept override { return params_.batch_size; };
bool getBatch(void *bin