关键词:tensorrt, int8
简介: int8推理需要在计算能力大于6.1的显卡上。INT8引擎从32位网络定义构建,类似于32位和16位引擎,但有更多的配置步骤。特别地,构建器和网络必须配置为使用INT8, INT8要求按张量动态范围。INT8校验器可以确定如何最好地将权值和激活表示为8位整数,并相应地设置每个张量的动态范围。或者,您可以自定义每个张量的动态范围;这在sampleINT8API中有涉及。
1. 整体流程
- 定义好模型网络
- 设置好校准器(就是一些验证样本)
- 设置好builder,设置能用int8模式
- 构建好模型
- 测试/保存模型
定义网络模型
为INT8执行定义网络与为其他精度定义网络完全相同。权重应该作为FP32值导入,构建器将校准网络,以找到适当的量化因子,将网络的精度降低到INT8。可以采用导入的方式,导入caffe,onnx的模型
设置校准器
在为INT8构建网络时,校准是一个额外的步骤。应用程序必须提供TensorRT样本输入,换句话说,校准数据。然后,TensorRT将在FP32中执行推断,并收集有关中间激活层的统计数据,它将使用这些统计数据构建更低精度的INT8引擎。
必须使用在运行时使用的具有代表性的图像进行校准。因为样本是基于Caffe的,所以Caffe在运行网络之前执行的任何图像预处理(如缩放、裁剪或均值减法)都将在Caffe中完成,并作为一组文件捕获。示例使用一个实用程序类(MNISTBatchStream)来读取这些文件,并为校准创建适当的输入。
校准用的样本需要保证:预处理一样
注意: 校准数据必须代表运行时提供给TensorRT的输入数据;例如,对于图像分类网络,它不应该仅仅由类别的一小部分图像组成。对于ImageNet网络,大约500张校准图像就足够了。
tensorrt 提供了4种校准器可供继承(具体差别还未知):
- IInt8EntropyCalibrator
- IInt8EntropyCalibrator2
- IInt8MinMaxCalibrator
- IInt8LegacyCalibrator
继承一个校准器之后,需要重写getBatchSize()
and getBatch()
两个函数,第一个函数返回校准时的batch大小,后一个函数返回一个batch的数据
在校准开始时,builder调用’ getBatchSize() ‘方法来获取校准集的批大小。然后重复调用’ getBatch() '方法来从应用程序获取批大小,直到该方法返回false。每个校准批次必须包括指定批次大小的图像数量。(这部分是隐藏的,tensorrt的builder自动调的)
设置builder
进行一些常规设置:
-
Set minimum and average number of timing iterations.
config->setAvgTimingIterations(1);
config->setMinTimingIterations(1);
-
Set maximum workspace size.
config->setMaxWorkspaceSize(1_GiB);
-
Set allowed builder precision to INT8 in addition to FP32. Default builder precision is FP32.
config->setFlag(BuilderFlag::kINT8);
-
Set maximum batch size.
builder->setMaxBatchSize(mParams.batchSize);
-
Pass the calibrator object (calibrator) to the builder.
config->setInt8Calibrator(calibrator.get());
构建模型
像float32模型一样构建模型:
mEngine = std::shared_ptr<nvinfer1::ICudaEngine>(
builder->buildEngineWithConfig(*network, *config), samplesCommon::InferDeleter());
测试/保存模型
后续就是保存模型,或者像float32模型一样写推理脚本,推理测试。
int8/float16对比测试
模型 | tensorrt engine size/MB | 显存占用 | 输入尺寸 | 耗时/ms |
---|---|---|---|---|
hrnetw18(int8) | 13.4 | 1710 | 640*480 | 4.437 |
hrnetw18(f16) | 17.1 | 1514 | 640*480 | 4.725 |
hrnetw18(f32) | 29.0 | 1619 | 640*480 | 10.0 |
其他
- tensorrt是提供了python api的,所有的int8量化都可以在python中实现,可以优选python毕竟预处理方便一些
- int8量化较float16类型的推理速度提升有限