目录

Windows下TensorRT-yolov5-使用总结

原文

一、简介

Yolov5是基于开源的python学习库Pytorch来做的,如果想要在C++环境下来运行yolov5做目标检测,那么就需要转换成新的框架,其中就包括libtorch、tensorRT

二、环境

系统:Windows10

Yolov5:python3.8 + pytorch1.7.0 + cuda11.1 + cudnn11.1 + opencv4.2【默认yolov5运行环境已经安装好了,可参考:windows下Pytorch安装教程

Libtorch:vs2017 + libtorch-1.7.0-cuda11.0-release + opencv3.4.7

tensorRT:vs2017 + TensorRT-7.2.3.4 + opencv3.4.7 + cmake3.16.4 + dirent

三、libtorch

1、部署

首先说一下使用libtorch,github上能够找到一些用libtorch版的yolov5,附上我使用的程序链接https://github.com/yasenh/libtorch-yolov5 ;真实使用时,需要根据自己的需求去修改程序(注意:配置环境可能也是个头疼的问题)。

具体使用步骤及总结,参考:

libTorch环境配置及使用

yolov5-libtorch使用总结

2、存在问题

使用官方模型yolov5s模型,检测每帧(分辨率1920*1080)的耗时较长:127ms。

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223151052735.png

这个检测耗时比pytorch版的yolov5慢了10倍多,pytorch版的yolov5检测每帧耗时11ms左右。

四、tensorRT

1、安装部署vs2017 + opencv3.4.7 + cmake3.16.4 + dirent

这些环境在网上有很多教程,这里就不再多介绍了。

这里说一下dirent,在github官方地址https://github.com/tronkko/dirent 下载下来,解压后备用。

2、安装部署TensorRT

(1)从官网下载tensorRT

官网地址:https://developer.nvidia.com/nvidia-tensorrt-download 会需要先登陆才能下载。

注意:下载与cuda版本一致的tensorRT,这里我下载的包名是

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223151101302.png

(2)解压部署tensorRT

解压后把tensorRT添加到环境变量Path中:E:\3rd-Part\TensorRT-7.2.3.4\lib

(3)安装graphsurgeon和uff

在如下的两个目录中找到graphsurgeon和uff

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223151106680.png

通过anaconda prompt安装它们,安装指令是:

pip install graphsurgeon-0.4.5-py2.py3-none-any.whl

pip install uff-0.6.9-py2.py3-none-any.whl

(4)将TensorRT-7.2.3.4\include目录中所有的文件,拷贝到cuda的include目录中,我的:

C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\include

(5)将TensorRT-7.2.3.4\lib目录中所有的文件,拷贝到cuda的lib/64目录中,我的:

C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\lib\x64

(6)将TensorRT-7.2.3.4\lib目录中所有的文件,拷贝到cuda的bin目录中,我的:

C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\bin

(7)使用vs2017打开tensorRT的测试示例TensorRT-7.2.3.4\samples\sampleMNIST

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223150942948.png

示例项目中的环境配置,都是已经配置好的,也会自动识别系统环境变量中的cuda环境;直接右击项目生成即可。

(8)通过anaconda prompt进入TensorRT-7.2.3.4\data\mnist目录,运行download_pgms.py文件,下载测试数据(我测试过很多次,都失败了,我已经下载好了一份,点击下载);下载指令如下:

python download_pgms.py

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223150943009.png

(9)运行sampleMNIST项目,如果看到如下画面,说明tensorRT安装部署成功:

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223151124066.png

(10)参考链接:

https://www.freesion.com/article/7394364554/

https://blog.csdn.net/lishiyu93/article/details/115526772?spm=1001.2014.3001.5501

3、下载相同版本的yolov5程序和tensorRT程序

一定要下载相同版本的yolov5程序和tensorRT程序。这里用的是yolov5 2.0和tensorRT 2.0。

Git下载指令:

git clone -b v3.0 https://github.com/ultralytics/yolov5.git

git clone -b yolov5-v3.0 https://github.com/wang-xinyu/tensorrtx.git

如果不想通过git来下载,可以直接去github官网下载:

Yolov5的github地址:https://github.com/ultralytics/yolov5

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223151131154.png

tensorRT程序的github地址:https://github.com/wang-xinyu/tensorrtx 【注:感谢wang-xinyu】

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223150943991.png

4、.pt模型转换为.wts模型

(1)将tensorrtx/yolov5目录中的gen_wts.py拷贝到yolov5目录下;

(2)修改gen_wts.py文件,如下图,在这个文件中默认了.pt模型的路径,以及yolov5模型的类型(yolov5s类型),可根据需要,自行修改;

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223150944107.png

(3)通过anaconda prompt进入yolov5目录,执行“python gen_wts.py”,即可生成.wts文件。

(4)注意:每个版本的tensorRT中gen_wts.py程序可能会不同,比如tensorRT 4.0的gen_wts.py程序如下:

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223150944281.png

要想生成yolov5s.wts文件,只需执行“python gen_wts.py yolov5s.pt”即可。

5、编译tensorRT程序中yolov5的vs工程

(1)修改tensorrtx\yolov5\CMakeLists.txt文件

注:我这有一些已经编译成功的CMakeLists.txt文件,可以直接使用;点击下载

官方给的是基于linux系统的配置,这里需要修改一下:

  • #1:工程名称
  • #2:opencv路径
  • #3:tensorRT路径
  • #4:dirent路径
  • #5:工程包含目录
  • #6:tensorRT包含目录
  • #7:dirent包含目录
  • #8:opencv包含目录
  • #9:tensorRT库目录
  • #10:添加工程文件
  • #11:添加tensorRT附加依赖项
  • #12:opencv库目录
  • #13:cuda附加依赖项

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223151156587.png

这里参考博文:https://blog.csdn.net/lishiyu93/article/details/115861265

这篇博文中介绍这块的时候,添加了很多项【可根据需要自选添加】:

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223151219496.png

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223151207485.png

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223151358942.png

(2)用cmake编译工程

在tensorrtx\yolov5中创建目录build,用于存放编译生成的工程文件。先点击Configure,在点击Generate,生成成功即可。

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223150945136.png

(3)编译工程

打开tensorrtx\yolov5\build目录下生成的vs工程,右击工程重新生成即可

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_18,color_FFFFFF,t_70,g_se,x_16-20220223151346304.png

6、运行tensorRT中yolov5

注:我这里有一个已经编译好的项目示例,点击下载

(1)将生成的yolov5s.wts(或者自定义的.wts模型)文件拷贝到tensorrtx\yolov5目录;

(2)修改类别数参数

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223150945603.png

默认CLASS_NUM是80,coco数据集中的类别总数,如果用的是yolov5官方的模型,那这里就不需要修改了。如果.wts模型文件是自定义的模型文件【注意:自定义的模型必须是在对应yolov5版本(这里是yolov5 2.0版本)中训练得到的】,可将CLASS_NUM设置成自己模型中的类别总数。

(3)右击项目属性 -> 配置属性 -> 调试 -> 命令参数中输入生成.engine文件的指令:

-s yolov5s.wts yolov5s.engine s

运行项目,即可生成yolov5s.engine。注意:生成.engine文件的时间较长,需要耐心等待;

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223151331748.png

其中 -s表示将.wts文件成功.engine文件;

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223150945753.png

注意图中的engine_name,初始化的参数STR2(NET)宏定义,默认是s,可自行根据模型类型修改;

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223151322104.png

engine_name名称默认是yolov5s.engine,可根据需要自定义修改。

创建engine文件的方法共四个,分别是s模型、m模型、l模型、x模型。

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223150946300.png

以s模型为例:

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223150946395.png

函数中默认了.wts的名称和路径。如果是自己训练的模型,就自己修改成自己模型的名称。

(4)右击项目属性 -> 配置属性 -> 调试 -> 命令参数中输入运行检测的指令:

-d yolov5s.engine ./images

此指令的意思是:利用yolov5s.engine检测./images目录中所有的图像;

检测结果如下:

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223151311698.png

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223150947135.png

(5)如果同时使用多个模型检测时,可以创建全局的类别数量参数g_nCLASS_NUM,而CLASS_NUM在检测时就作废不用了(但是还会用于“创建.engine文件”)。【注意:新版本中,CLASS_NUM只用于wts转换为engine文件,而不用于检测,就是说检测时不依赖任何类别数量参数】

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223151304454.png

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223151255754.png

注意:模型检测时都需要修改g_nCLASS_NUM为模型的类别数量;检测时,需要在对应.engine文件加载之前设置g_nCLASS_NUM。

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223151250013.png

(6)参考博文

https://blog.csdn.net/lishiyu93/article/details/115861265

https://blog.csdn.net/weixin_41552975/article/details/114398669

7、问题汇总

(1).wts生成.engine文件时,当CLASS_NUM参数值与.wts模型的类别数不相同时,会出现如下错误:

“Assertion failed: engine != nullptr”

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223150947836.png

(2)当生成.pt模型的yolov5版本 与 tensorRT程序版本不一致,会出现如下问题:

“Parameter check failed at: Network.cpp::nvinfer1::Network::addScale::484, condition: shift.count > 0 ? (shift.values != nullptr) : (shift.values == nullptr)”

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223151242795.png

8、注意事项

(1)在不同的硬件环境下,引擎文件(.engine)需要重新生成才能使用,wts文件是可以通用的。

举例说明:

我在显卡RTX3070的主机中生成的引擎文件(.engine),放在相同环境下(cuda版本、tensorRT版本、opencv版本等等)的显卡RTX1060的主机上运行,就会出现如下错误:

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6auY56WleGlhbmc=,size_20,color_FFFFFF,t_70,g_se,x_16-20220223150948062.png

在显卡RTX1060的主机上用wts文件重新生成引擎文件(.engine),再次调用引擎文件检测,即可正常。