量化是将模型参数的存储类型从高精度存储降到低精度存储,从而达到减小模型体积大小、加快模型推理速度的效果。
FP32量化
这个直接使用yolov5的export导出32位存储的 engine格式模型即可
代码语言:javascript复制python export.py --weights runs/train/exp4/weights/best.pt --include onnx engine --device 0
可以看到32位浮点型模型的onnx大小为7.1MB,engine大小为9.5MB。
然后我们用32位的engine模型进行推理
代码语言:javascript复制python detect.py --weights runs/train/exp4/weights/FP32.engine --source ikunData/images
其每张照片的推理速度为4.9ms,比我们用原模型推理的速度要快上一倍(9.5ms)。
32位engine模型的检测效果如下图所示。
FP16量化
代码语言:javascript复制python export.py --weights runs/train/exp4/weights/best.pt --include onnx engine --half --device 0
从32位浮点型转为16位浮点型的onnx模型大小减小了一半,从7.1MB减小到了3.6MB,其engine模型大小从9.5MB减小到了6.1MB,模型压缩效果模型。
再看看16位的模型加速效果
代码语言:javascript复制python detect.py --weights runs/train/exp4/weights/FP16.engine --source ikunData/images
此时的模型已经从32位的4.9ms推理速度提高到了2.3ms,加速效果明显。
与之同时,16位模型的检测效果却与32位的效果基本一样,在模型体积减小,推理速度加快的情况下,能够达到检测效果基本一样,说明16位量化效果十分成功。
INT8量化
我们还可以进一步量化,我们可以将模型量化为int8位存储,但是由于yolov5自带的export的int8导出效果好像并不好,因此int8量化要复杂一下。
我们首先拿到onnx格式的模型,这个我们在FP32量化的时候已经拿到了,在网上搜罗了一番,勉强可以找到一个将onnx转换为int8存储的engine的代码,但是由于这个代码有点年份了,使用到的TensorRT的版本老了,新的TensorRT已经不支持一些属性。
于是,经过一晚上加一下午代码的愉悦修改
具体请看【yolov5】onnx的INT8量化engine-CSDN博客
终于把代码给改对了,最后拿到的模型大小只有4MB。
但是int8的推理速度和FP16的差不多。
Int8目标检测的效果也要差上一些,从图中可以看到有些鸡没有被检测到,可见改用int8存储后的模型精度要差上一些。