这是一篇纯技术文章
海思芯片介绍
这边文章是写给需要在海思平台上部署目标检测模型的算法研究人员,前提条件是按照海思的官方文档跑通了目标检测的demo ,才能看懂本篇文章。
海思芯片在最近回归了,最近也因为业务需要、国产替代的背景等,需要将算法从rknn平台迁移到海思平台。初步验证yolov8n320*192的单类检测模型在RK3568上的推理速度在12ms,海思HI3516DV300上只需要1.9ms,速度提升的不止一点半点。而且海思平台还给yolo模型的后处理提供了rpn的硬化层(将后处理放在模型,包含nms、阈值过滤、clip_box等),拿来模型的推理结果就可以直接用,不用自己再写后处理,减少了CPU资源占用的同时还提升了速度。
如何生成带RPN层的yolov8模型
在海思提供的samples目录,按照README_yolov8.md进行操作即可
在这里插入图片描述
官方提供的patch补丁是基于yolov8官方模型的,在实际使用的时候也有很多不合理的地方需要修改,主要修改的如下所示(屏蔽掉的就是patch补丁的代码):
这里需要将imgW和imgH设置为自己输入图像的大小,其它参数可以不用动。
修改后,重新导出onnx模型即可
可以看出,导出的模型已经有了filter、sort、nms等自定义后处理层
海思模型量化的精度问题
测试512*288大小且带适用rpn层进行后处理的yolov8n在海思3516dv300芯片上的速度和精度测试
模型 | 板端速度 | AP |
---|---|---|
onnx | - | 44.3 |
hi3516 16bit | 5.7ms | 43.7 |
hi3516 8bit | 3.4ms | 39.1 |
观察上表可以发现,16bit量化的模型AP比较接近onnx模型的AP,但是int8量化的模型指标掉了5个点,说明8bit量化的模型存在问题。考虑到边缘计算设备较低的计算资源,我们当然是希望采用速度更快、NPU资源占用更少的int8量化,所以需要排查int8量化存在的问题。
8bit量化精度问题排查
- 排查rpn层的问题。
这一步直接去掉rpn层,模型是一个输出,模型结构有yolov8官方导出的模型结构一样,然后自己写nms等后处理,发现精度还是下降了5个点,说明不是rpn层的问题。 - 排查锚框计算层的问题
参考CSDN文章,只导出了yolov8 head部分的卷积计算部分。
再对模型进行8bit量化,测得的AP值与16bit量化非常接近,那精度下降问题很明显出现在后面的dfl、anchor、dist2bbox、self.strides中的一个或者几个层里面。
yolov8官方模型在导出onnx时只有一个输出,但是我发现通常将yolo模型部署在移动端的框架上的时候,如ncnn、rknn时,大部分的教程都是推荐去掉后处理,得到三个检测头分支的,每个分支包含分类cls和检测框reg两个头,共六个检测头,再自己去写dfl、锚框、乘以strides恢复到输入图像大小等后处理操作。网上也有大佬在测试的时候发现了这个问题链接1、链接2。和很少有文章去解释为什么要去掉后处理导出6个分支,明明一个分支更加简洁,这个问题我通过查阅大量的文献得出的结论是yolo模型的头部很难被量化 。
精度下降的问题很明显出现在如下所示画红框的部分,接下来继续排查。
- 排查strides计算的问题
从后往前排查,首先就排查strides的问题,这一步操作* self.strides
是将8、16、32倍下采样的检测框恢复到输入图像的大小,strides本身是一个很长的数组,里面是一长串的8、16、32,感兴趣的可以去打印这个数组看看。
我们首先找到这一步操作在onnx上对应的位置:
对比8bit量化参数和16bit的量化参数(在《ATC工具使用指南.pdf》的2.3节,--output目录下会生成一个calibration_param.txt的文件,这个文件就是量化参数)
直接用16bit量化参数将8bit的"Mul_270"这个OP的量化参数替换。再使用--gfpq_param_file指定选用修改后的8bit量化参数文件进行量化,最后测试精度。发现这样做的AP来到了43.0,只比16bit量化降低了0.7,而且没有增加8bit模型的推理速度,还是3.4ms。
接下来又尝试了将其他算子用16bit的量化参数进行替代,AP有涨有跌,长得也不多所以这里不再展示。最终我工程中应用的模型就是只将"Mul_270"这个乘以strides的OP用16bit的量化参数进行替换。
最终得到的AP指标如下表所示:
模型 | 板端速度 | AP |
---|---|---|
onnx | - | 44.3 |
hi3516 16bit | 5.7ms | 43.7 |
hi3516 8bit | 3.4ms | 39.1 |
hi3516 8bit+strides层16bit量化 | 3.4ms | 43.0 |
结语
在国产化替代的大背景下,相信海思的应用和开发会越来越多,希望我的这一篇文章能对大家带来一点的帮助,也希望大家指出我的不足或者在我的基础上继续发扬光大!
有问题请留言或者私信,我看到了都会回复。