【实战】基于 TensorRT 加速 YOLO 系列以及其他加速算法实战与对比
[深度学习]TensorRT 为什么能让模型跑快快
模型加速越来越成为深度学习工程中的刚需了,最近的 CVPR 和 ICLR 会议中,模型的压缩和剪枝是受到的关注越来越多。毕竟工程上,算法工程师的深度学习模型是要在嵌入式平台跑起来,投入应用的。在模型的推理(inference)过程中,计算速度是很重要的。比如自动驾驶,如果使用一个经典的深度学习模型,很容易就跑到 200 毫秒的延时,那么这意味着,在实际驾驶过程中,你的车一秒钟只能看到 5 张图像,这当然是很危险的一件事。所以,对于实时响应比较高的任务,模型的加速时很有必要的一件事情了。
如果你使用英伟达的产品,比如 PX2,那么在平台上部署模型投入应用,很多时候就需要用到专门的模型加速工具 —— TensorRT。
TensorRT 下的模型是在做什么?
TensorRT 只负责模型的推理(inference)过程,一般不用 TensorRT 来训练模型的哈。
TensorRT 能加速模型吗?
能!根据官方文档,使用 TensorRT,在 CPU 或者 GPU 模式下其可提供 10X 乃至 100X 的加速。本人的实际经验中,TensorRT 提供了 20X 的加速。
TensorRT 为什么能提升模型的运行速度?
TensorRT 是英伟达针对自家平台做的加速包,TensorRT 主要做了这么两件事情,来提升模型的运行速度。
TensorRT 支持 INT8 和 FP16 的计算。深度学习网络在训练时,通常使用 32 位或 16 位数据。TensorRT 则在网络的推理时选用不这么高的精度,达到加速推断的目的。
TensorRT 对于网络结构进行了重构,把一些能够合并的运算合并在了一起,针对 GPU 的特性做了优化。现在大多数深度学习框架是没有针对 GPU 做过性能优化的,而英伟达,GPU 的生产者和搬运工,自然就推出了针对自己 GPU 的加速工具 TensorRT。一个深度学习模型,在没有优化的情况下,比如一个卷积层、一个偏置层和一个 reload 层,这三层是需要调用三次 cuDNN 对应的 API,但实际上这三层的实现完全是可以合并到一起的,TensorRT 会对一些可以合并网络进行合并。我们通过一个典型的 inception block 来看一看这样的合并运算。
在没有经过优化的时候,inception block 是图 1 中的样子,一个既有深度,又有宽度,还有 concat 操作的结构。
图 1
首先,对于网络结构的垂直整合,即将目前主流神经网络的 conv、BN、Relu 三个层融合为了一个层,所谓 CBR,合并后就成了图 2 中的结构。
图 2
然后,TensorRT 还可以对网络做水平组合,水平组合是指将输入为相同张量和执行相同操作的层融合一起,比如图 3, 就将三个相连的 1×1 的 CBR 为一个大的 1×1 的 CBR。
图 3
最后,对于 concat 层,将 contact 层的输入直接送入下面的操作中,不用单独进行 concat 后在输入计算,相当于减少了一次传输吞吐。
图 4
所以啊,如果你使用的是英伟达家的产品,TensorRT 还是很推荐的呢!
今天尝试了使用 TensorRT 做 YOLO 的加速,先概述我这边实现的速度和精度对比:
精度上对比:
可以看到,精度上使用 TensorRT 精度不掉,反而略微上升了一些些(具体情况未知,还在摸索)
TensorRT 速度上的对比:
另外值得注意的是,我使用的 TensorRT 的作者介绍说:YOLOV5 s 小模型原本已经很快了,使用 python 版的 tensorRT 加速反而慢了一些,使用 cpp 版快了 3 倍,如果是使用 YOLOV5 X 的大模型,加速效果会更明显。
下面开始手把手教学,先大致说说思路:
1:配置 cuda cudnn 和 TensorRT ,先配置适合你的电脑的 cuda cudnn,以及到 Nvidia 官网下载适合你 cuda 和 cudnn 呃 tensorRT 版本,
2:再分别下载 tensorRT 源码;YOlov5 源码,以及 YOLOv5 模型
3:编译 tensorRT-v5 生成 engine
4:测试模型
官方的介绍是 Ubuntu16.04 / cuda10.0 / cudnn7.6.5 / tensorrt7.0.0 / opencv3.3 的配置:
Install CUDA 安装 cuda,cudnn
Go to cuda-10.0-download. Choose Linux -> x86_64 -> Ubuntu -> 16.04 -> deb(local) and download the .deb package.
Then follow the installation instructions.
sudo dpkg -i cuda-repo-ubuntu1604-10-0-local-10.0.130-410.481.0-1amd64.deb
sudo apt-key add /var/cuda-repo-<version>/7fa2af80.pub
sudo apt-get update
sudo apt-get install cuda
Install TensorRT 安装 tensorRT
Go to nvidia-tensorrt-7x-download. You might need login.
Choose TensorRT 7.0 and TensorRT 7.0.0.11 for Ubuntu 1604 and CUDA 10.0 DEB local repo packages
Install with following commands, after apt install tensorrt, it will automatically install cudnn, nvinfer, nvinfer-plugin, etc.
sudo dpkg -i nv-tensorrt-repo-ubuntu1604-cuda10.0-trt7.0.0.11-ga-201912161-1amd64.deb
sudo apt update
sudo apt install tensorrt
Install OpenCV 安装 opencv
sudo add-apt-repository ppa:timsc/opencv-3.3
sudo apt-get update
sudo apt install libopencv-dev
Check your installation
dpkg -l | grep cuda
dpkg -l | grep nvinfer
dpkg -l | grep opencv
Run tensorrtx
It is recommanded to go through the getting started guide, lenet5 as a demo. first.
But if you are proficient in tensorrt, please check the readme of the model you want directly.
我的配置是 cuda 10.1 cudnn 7 ,用同样的方式配置好自己的版本,下载了 tensorRT 6.0.1 的 deb 包,并且安装了。
然后将 TensorRT/yolov5/CMakeLists.txt 修改一下刚刚安装的 TensorRT 的 include 和 lib,如图:
generate yolov5s.wts from pytorch with yolov5s.pt, or download .wts from model zoo
git clone https://github.com/wang-xinyu/tensorrtx.git
git clone https://github.com/ultralytics/yolov5.git
// download its weights 'yolov5s.pt'
// copy tensorrtx/yolov5/gen_wts.py into ultralytics/yolov5
// ensure the file name is yolov5s.pt and yolov5s.wts in gen_wts.py
// go to ultralytics/yolov5
python gen_wts.py
// a file 'yolov5s.wts' will be generated.
接下来可以编译生成 yolov5s.engine 了:
build tensorrtx/yolov5 and run
// put yolov5s.wts into tensorrtx/yolov5
// go to tensorrtx/yolov5
// ensure the macro NET in yolov5.cpp is s
mkdir build
cd build
cmake ..
make
sudo ./yolov5 -s // serialize model to plan file i.e. 'yolov5s.engine'
sudo ./yolov5 -d ../samples // deserialize plan file and run inference, the images in samples will be processed.
check the images generated, as follows. zidane.jpg and bus.jpg
optional, load and run the tensorrt model in python
// install python-tensorrt, pycuda, etc.
// ensure the yolov5s.engine and libmyplugins.so have been built
python yolov5_trt.py
其中:sudo ./yolov5 -d …/samples 命令中…/samples 就是你测试图片的文件夹路径,我们可以自己修改路径来推理。然后
就可以推理了。如果有什么报错的话,可以通过公众号咨询我~
另外 tensroRT 默认使用的是固定尺寸(默认尺寸),而 pytorch 版的使用的是等比例缩放到 640X 640 所以如果要做消融对比的实验,建议同一个 size 做对比,我文章开头部分的对比图片,是将 pytorch 版的 img-size 改成了 608 来推理,所以速度会快一些。对比下来实际上使用 cpp 版 yolov5s 速度还是快了很多,大家可以尝试使用 yolov5x 来加速尝试一下。如果你想改 tensorRT 为 640x640 ,那么可以修改 yololayer.h 中的 20 行左右 inputH,inputW = 608 为 640。但是我没有实际测试~
另外对于训练自己的数据集,使用 tensorRT 加速,需要修改一下一些地方:
将 yolov5.cpp 中的第七行:改成 #define USE_FP16 改成自己的 FP32 正常我们的模型训练出来是 FP32 的。
我建议还是使用 yolov5_trt 来做推理,main 函数中修改一下类别,等等。
另外,使用 Openvino 加速
cpu(i5 )下原 yolov5s 下 640X 640 是 380ms 每帧,使用 Openvino 是 300ms 以下,gpu 我没测试,应该也是稍微快一些,大家可以根据我另一篇文章测试一下~
另外,CV 调包侠自己做了个目标检测中必备地一个工具~ 使用我的工具,可以方便快捷地做数据标注!哦不,你什么也不用干,工具来标注~ 可以让你一分钟就获取大量数据,并且获取 xml 标注文件,获取 labels 归一化标签,直接可以使用 yolo 训练,关注公众号,星标一下,过几天开源出来~
评论