使用Tensorrt对YOLOv5目标检测的代码进行加速

1. 前言

  • 最近在使用YOLOv5做apex的辅助,训练代码现在是写完了,在训练场中把禁止的假人还行,但是对于移动的目标,总是出现丢帧、追不上的问题。测了一下FPS,发现我的RTX2060上面的FPS只有3到5,这基本上相当于PPT的水平,自己的硬件一时半会没办法升级,但自己真的想把这个APEX的辅助给做完,所以只好通过代码加速的方法来曲线救国。从网上查到Tensorrt对于代码的加速效果非常好,所以下面开始动手尝试。
  • 先放一张目前辅助的识别效果
  • (先透漏一下,使用TensorRT对YOLOv5进行加速之后,FPS可以达到100以上,Amazing 吧~)

2. 官网

3. 安装依赖

3.1. 安装OpenCV

3.1.1. 安装

提取安装包内容
这个安装和普通软件的安装没有区别,直接点开EXE安装包,一直下一步就可以完成了
选择安装位置


  • 正在安装

  • 安装完成后会在安装目录下生成build和source两个文件夹,我们将来需要使用的文件主要放在build文件夹中

3.1.2. 添加环境变量

添加如下的环境变量

D:\Program\OpenCV\build\x64\vc16\bin
D:\Program\OpenCV\build\x64\vc16\lib
D:\Program\OpenCV\build\include
D:\Program\OpenCV\build\include\opencv2

之后重启电脑

3.1.3. 查看版本

在命令行下输入下面代码opencv_version,就可以查看到OpenCV的版本了

3.2. 安装TensorRT

3.2.1. 下载

首先到英伟达的tensorRT的官网上下载适合Windows平台的版本

3.2.2. 安装

这个TensorRT本质上是一组lib库和一组.h文件

复制文件

  • 将TensorRT/lib下面所有的lib复制到cuda v11.1/lib/x64目录下,
  • 将TensorRT/include下的所有.h文件复制到cuda/v11.1/include目录下

3.2.3. 添加环境变量

将TensorRT/lib的路径填入到path环境变量中

  • 这样TensorRT就算安装完成了

4. 下载项目

5. 生成WTS模型

  • 将仓库中的gen_wts.py和下载好的yolov5s.pt权重文件拷贝到yolov5 6.0的目录下
  • 运行下面的命令进行模型的转换
  • python gen_wts.py -w yolov5s.pt -o yolov5s.wts
  • 其中w参数为输入pt模型路径,-o参数为输出wts模型的路径。
  • 运行完成后,会在当前目录下生成一个yolov5s.wts的权重模型,这个模型就是用于之后转换为tensorrt的专用序列化模型

6. cmake

6.1. 生成Makefile

  • 在当前仓库下新建一个build文件夹

  • 打开Cmake,源文件选择本仓库目录,build选择刚新建的build目录

  • 修改configure

    选择自己需用的Visual Studio版本,以及编译平台,之后点击finish

  • 一段时间之后就可以完成了

6.1.1. 配置CMakeLists.txt

6.1.1.1. 修改编译依赖的路径

打开CMakeLists.txt,修改OpenCV、TensorRT、dirent.h的目录,其中dirent.h在本仓库的include中,需要注意的,这些路径都必须使用绝对路径,用\来分割路径。

6.1.1.2. 修改算力

具体数值参考
CUDA GPU | NVIDIA Developer
developer.nvidia.com/zh cn/cuda gpus#compute
进行设定
我这里RTX 2060的算力是75

所以修改arch=compute_75;code=sm_75

7. 编译

7.1. 修改源代码

  • 使用Visual Studio打开项目build文件夹中的sln文件

    搜索yololayer.h文件对其进行修改
  • 修改文件中的这些参数为自己的模型类别数、输入大小,
  • 如果使用的是官方预训练权重,那么不用修改。但如果是自己训练的模型不修改的话,之后是会报错的
static constexpr int CLASS_NUM = 80;
static constexpr int INPUT_H = 640;  // yolov5's input height and width must be divisible by 32.
static constexpr int INPUT_W = 640;

7.2. 生成exe

  • 将界面上方的debug改为Release,然后点击菜单栏处的生成-重新生成yolov5

编译成功


可以看到build/release文件夹下已经生成了对应的exe文件了

7.3. 生成engine

  • 将最开始生成的yolov5s.wts模型复制到exe所在的文件夹中,在这个目录中打开cmd输入
 yolov5 -s yolov5s.wts yolov5s.engine s

  • 我们这边使用的是s模型,最后则输入s,同理若为m模型,最后一个参数则需要改成m

  • 此时,程序会将wts转换为engine序列化模型,需要的时间比较久,千万不要因为等不及而关掉页面,那样就前功尽弃了,具体时间跟你的CPU性能有关系,总体说来大约需要等待30到40分钟,时间很久就不用一直在这等着了,可以先去干点其他事情,或者看一部电影

  • 我的电脑编译完成花了三十多分钟


  • 生成engine完成后,会在文件夹下出现yolov5s.engine的模型,

8. 推理

8.1. exe推理

  • 将仓库中的pictures文件夹复制到EXE文件夹项,尝试预测是否正确,输入
yolov5 -d yolov5s.engine ./pictures

  • 里面一共有两张图片,每一张的推理时间仅为4毫秒,也就是250FPS,这个速度可以说相当快了
  • 而且推理效果也是非常棒

8.2. Python 调用dll推理

  • 刚才将模型部署为C++之后,可以预测文件夹内的图片,但也仅仅局限于此,对于程序中的调用是没有办法做到的,而我们在做很多图像处理任务时候,其实是用的Python语言,因此,我们还应该进一步将模型部署到Python上面。

点击项目属性-

  • 将目标文件扩展名和配置类型由exe改为dll

    修改之后

  • 之后对项目进行重新生成

  • 生成完成后,会在文件夹下出现yolov5.dll的文件

  • 设置自己调用的dll路径以及需要预测的图像路径,这里需要注意的是, Detector类中model_path参数需要传入bytes类型的路径,b''表示将字符串转换为bytes类型 ,如果不加b’'的话,会导致TypeError: expected bytes, str found的错误。

 det = Detector(model_path=b"./yolov5s.engine",dll_path="./yolov5.dll")  # b'' is needed
img = cv2.imread("./pictures/zidane.jpg")

  • 将仓库根目录中的python_trt.py复制到dll文件所在的文件夹下
  • 运行代码,如果不报错的话,就会显示下面的检测结果,over,just enjoy it!

8.3. 性能测试

  • 最后我们来测试一下这个TensorRT的性能

  • 检测单张图片,加上读取图片的时间,一张图像也仅需要0.015s,也就是15毫秒,速度是真的快

  • 检测100张图片,仅需要1.65秒,

  • 这之前的速度还包括了读取数据的时间。如果把这部分时间去掉,速度又快了很多,真的是可以做到10毫秒之内就检测一张图片

  • 100张图片也仅需要0.58s,持续运行的话,FPS应该是170左右,也就是说在RTX2060Ti上面,这个速度真的是快到没朋友了~~~

  • 我觉得接下来我的Apex辅助应该可以做到实时检测了

9. 报错

  • Error in configuration process,project files may be invalid

  • CMake Error at CMakeLists.txt:3 (project):

  • Failed to run MSBuild command:

  • MSBuild.exe

  • 查看下面的报错信息,确定一下到底是哪个文件找不到

  • 添加 MSBuild.exe 的环境变量

D:\Program\VisualStudio2022\MSBuild\Current\Bin\amd64

之后重启电脑

  • 安装window SDK
    这个靠谱

  • No CUDA toolset found.

描述

Error in configuration process, project files may be invalid

CUDA_SDK_ROOT_DIR-NOTFOUND

  • Windows CMake编译错误:No CUDA toolset found解决方法_no cuda toolset found._Zirong.的博客-CSDN博客

  • 可能是自己安装cuda的时候没有勾上这个 CUDA toolset 吧,再重新安装一次就好了


    之后重启电脑

  • 如果依然报错的话,执行下面的步骤:

  • 将C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\extras\visual_studio_integration**MSBuildExtensions 里面的四个文件*手动复制到D:\Program\VisualStudio2022\MSBuild\Microsoft\VC\v170*BuildCustomizations

    大约20秒之后就可以成功了

  • 其他尝试过但是没用的策略
    使用旧版本的cmake

  • c - CUDA 在 Windows 上编译问题,Cmake 错误 : No CUDA toolset found - IT工具网

  • 3.17.1

  • 和版本没有关系,如果配置正确的话,高版本cmake也可以正常编译

  • 手动指定CUDA_SDK_ROOT_DIR
    将cuda卸载之后再重新安装
    使用Ubuntu来进行这个编译
    使用Visual Studio重新安装和cmake所有相关的文件

  • 由于找不到 cudnn64_8.dll,无法继续执行代码。重新安装程序可能会解决此问题。

  • 这个报错应该是下载的cudnn文件解压错的位置,重新安装 就好了

  • TensorRT was linked against cuBLAS/cuBLAS LT 11.3.0 but loaded cuBLAS/cuBLAS LT 11.2.1

  • 这个是警告,而非报错,最终可能会编译好,但是精度会受影响

  • 所以按照人家的要求,完完全全老老实实地选择对应的版本,cuda11.3,cuDNN 8.1.0

  • 修改正确cudnn之后少了一个报错

  • 再修改cuda为11.3 之后所有错误都没了


    一段时间之后也可以编译好了

  • CUDA lazy loading is not enabled. Enabling it can significantly reduce device memory usage. See CUDA_MODULE_LOADING in https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.htmlenv-vars

  • 换一个版本的TensorRT就好了

  • FileNotFoundError: Could not find module ‘E:\Documents\Desktop\Yolov5_Tensorrt_Win10-master\build\Release\yolov5.dll’ (or one of its dependencies). Try using the full path with constructor syntax.

使用绝对路径

并没有解决

  • Python版本太高,使用低版本的Python3.7就好了
    一般使用python3.7一下的版本不会报错,python3.8会报错,报错的原因是python3.8对其进行了安全性检查,
    具体原理可以查看看这篇博客 iyn.me/i/post 40.html

  • Python 3.8 变更了 Windows 下动态链接库 (DLL) 的加载规则。

  • 新的规则提高了安全性,默认情况下仅能从可信的位置(Trusted Locations)加载 DLL 依赖,一定程度上避免诸如 DLL 劫持之类的安全风险。

  • 可信的位置包括:

  • DLL 所在的路径(加载 DLL 时提供 DLL 的完整路径或部分路径,文件存在则该路径即可信)。

  • 使用 add_dll_directory() 添加的路径。

  • (系统可信位置)

  • OSError: [WinError -529697949] Windows Error 0xe06d7363

  • github.com/Monday Leo/Yolov5 Tensorrt Win10/issues/8

版本不兼容所致

需要保证编译过程中所用的Python版本和和最终推理使用的Python版本是同一个,否则可能会出现这个错误

  • 编译完成后,为什么build文件夹下没有sln文件
  • 因为只运行了configure,而没有运行generate

    generate之后就有了sln文件了
  • 仔细看一下运行过程,应该是有报错的
    Performing Test CMAKE_HAVE_LIBC_PTHREAD Failed

  • Visual Studio没有生成dll文件

  • 缺少必要的依赖库或者头文件

  • 有可能是上一步生成的sln文件本身就有问题

  • OSError: exception: access violation reading 0x0000000000000000

  • Win10 TensorRT-**8.4.3.1 **+ CUDA 11.7 + cudnn8.6.0.163

版本不匹配

  • 重新生成一次解决方案也许就好了
    很玄学,但的确就是这样
    2023.05.31-13:27:56
    啥也没动,突然之间就好了

10. 参考资料

本案例使用到的各种资源

猜你喜欢

转载自blog.csdn.net/u014723479/article/details/130967449