最近工作中要对YOLOV5模型进行GPU加速,尝试过Tensorrt及Torch版本部署。下面做一下阶段总结,后期有新发现会持续更新。
1.Tensorrt方法:
GPU版本加速首先想到的肯定是TRT了,也尝试github上YOLOV5版本的TRT方法在原本作者的基础上自己也做了优化并提升了速度,主要是原作者模型的前后处理对于大batchsize优化并不是很好以及在GPU中的内存拷贝方法有部分冗余。毕竟代码是基于python版本的Torch上的,所以我也做了torch结合tensorrt一起。
代码如下,Torch结合TensorRT方法,这样可以减少内存的拷贝。当然从cpu到cuda过程是必不可少的,我用的cv2所以self.inputs肯定是要从cpu中转移过来的,这一步拷贝时间消耗是必不可少的。
self.inputs = torch.zeros_like(self.demo_in)
self.out = torch.zeros_like(self.demo_out)
context.execute_async(batch_size=self.batch_size,
bindings=[self.inputs.data_ptr(), self.out.data_ptr()],
stream_handle=stream.handle)
stream.synchronize()
但是不知道什么原因TRT版本不管F16还是F32我测试下来精度和torch版本还是有很大差距最终放弃了TRT版本。
注(2021.7.27):
问题找到了,原作者batchNorm方法eps数值0.001太大了改成0.00001即可,精度和torch完全一样。
2.Torch版本:
实际上Torch版本的加速如果你是1 batchsize那么加速还是要看网络模型的加速,但是我项目中batchsize较大,所以时间消耗基本都是在preprocess和postprocess上,这是加速preprocess和postprocess的意义远远大于加速模型本身。
主要加速思路是:
1.减少内存拷贝过程(CPU到GPU,GPU到CPU),这个很重要!
2.采用多线程拷贝同时拷贝,这个主要用在preprocess加载图片和归一化上
3.尽可能都在GPU中完成指令操作少用CPU指令操作,这个主要是在postprocess
4.能在batch的维度上一起处理的就不要用for循环一个个处理(例如:置信度过滤),这个是在postprocess