目录
Windows平台上使用tensorRT部署yolov5
前言:
GitHub:stu-yzZ/yolov5infer (github.com)
基于tensorrt部署的文章可以参考这个专栏,包括C++和python两种,总的来说搞清楚了也就不是很复杂了。专栏连接:http://t.csdnimg.cn/RQgEp
自己在网上摸索了很久的基于windows平台的tensorRT部署的问题,终于跑通了,我在找资料的过程中没有找到从思路和细节上都具备的文档,我个人觉得思路最重要,我是很多份拼凑出的思路,顺着思路(有时候会错)一点一点解决问题才得出的结果,所有我打算写这份文档,更加侧重整体逻辑思路,技术细节我理解只要解决思路正确,肯定很多人踩过坑,找一找肯定有的,当然我也会提到。
图片来源:Quick Start Guide :: NVIDIA Deep Learning TensorRT Documentation
环境:
我是在windows环境下部署的。Win10+3070ti。硬件cuda是11.7。应该和codna环境中的cuda没有关系,但是需要注意一点,有可能硬件设备上没有安装cudnn,虽然codna环境中有,这个细节注意下,我配置vs2019的适合遇到了(网上好多都写了用vs2019配置的,可能是基于c++部署会用到),不过暂时看来vs2019还没用到(我暂时只针对python进行部署)。
1.为什么要部署?
为了一些使用场景,比如智能机器人,自动驾驶等,在终端设备上,要在低功耗低消耗情况下实现高性能,所以要部署。并不是所有的环境都像实验室一样有4090给咱们跑,sad。
2.那为什么部署可以解决这个问题?(基于tensorRT)
模型部署到 GPU 上使用的是nVidia专门开发的深度学习推理加速库。这些库专门为 GPU 优化,通过量化、融合层次和其他优化技术提高推理速度。具体有以下:
- 并行性和流水线: GPU
- 允许并行处理,因此你可以通过同时处理多个输入来提高推理速度。还可以使用流水线技术,确保 GPU 在处理一个输入时已经开始处理下一个输入。
- 硬件特定优化: 针对具体 GPU 架构的优化也是可能的。例如,CUDA 编程可以用于在 NVIDIA GPU 上实现更高级的优化。
而使用模型权重和网络推理使用的框架内置函数,(Pytorch中的forword)。
这两种区别会导致天壤地别的推理速度,我自己看了我设备上跑的模型,有如下的对比。
方式 | 推理时间/单张 | GPU内存 | 设备 | 显卡 |
权重和网络 | 2s | 2.7G | 21款拯救者windows10 | 3070ti/8G |
tensorRT部署 | 2ms | 1.7G |
可以看出推理速度上差了100倍左右。优势明显。
3.怎么部署(只讨论tensorRT)
3.0部署的流程
部署这个过程涉及到至少三个环节,首先将模型和权重转换成onnx,然后将onnx转换成适合tensorRT推理的engine,也就是trt格式文件。然后将trt文件通过python或者C++部署到硬件设备上。顺便提一嘴也可以使用onnruntime部署,但这种部署不纯粹,没有把硬件层面的加速体现出来。
我们可以使用任意一种深度学习框架来定义网络结构,并通过训练确定网络中的参数。之后,模型的结构和权重会被转换成一种只描述网络结构的中间表示即ONNX,一些针对网络结构的优化会在中间表示上进行。最后,用面向硬件的高性能编程框架(如 CUDA,OpenCL)编写,能高效执行深度学习网络中算子的推理引擎会把中间表示转换成特定的文件格式,并在对应硬件平台上高效运行模型。
接下来依次介绍每个过程和步骤。
3.1怎么得到模型和权重
我理解如果学习到部署这一步的程序的话基本对模型和权重的基础知识都有了,这一步就不详细介绍了。可以使用不同的框架搭建网络并训练,得到权重文件和网络模型就可以进行下一步了。
3.2 怎么获取ONNX
3.2.1 ONNX是什么
ONNX文件主要由模型参数和结构转换而来。
ONNX (Open Neural Network Exchange)是 Facebook 和微软在2017年共同发布的,用于标准描述计算图的一种格式。目前,在数家机构的共同维护下,ONNX 已经对接了多种深度学习框架和多种推理引擎。因此,ONNX 被当成了深度学习框架到推理引擎的桥梁,就像编译器的中间语言一样。由于各框架兼容性不一,我们通常只用 ONNX 表示更容易部署的静态图。
3.2.2怎么将权重pt文件转换为onnx?
Pytorch自带可以将网络和权重转换为onnx的函数:torch.onnx.export。PyTorch 提供了一种叫做追踪(trace)的模型转换方法:给定一组输入,再实际执行一遍模型,即把这组输入对应的计算图记录下来,保存为 ONNX 格式。export 函数用的就是追踪导出方法,需要给任意一组输入,让模型跑起来。
转换函数:
x = torch.randn(1, 3, 256, 256)
with torch.no_grad():
torch.onnx.export(
model, #需要转换的模型,如yolov5
x, #任意一组和输入shape相同的tensor
"yolov5.onnx", #导出的ONNX的文件名
opset_version=11, # ONNX 算子集的版本
input_names=['input'],
output_names=['output'])
执行代码可以得到yolov5.onnx文件,我们可以用下面代码检测该文件是否正确。
import onnx
onnx_model = onnx.load("yolov5.onnx")
try:
onnx.checker.check_model(onnx_model)
except Exception:
print("Model incorrect")
else:
print("Model correct")
onnx文件可以通过Netron这个网站可视化,下面这个是我保存的yolov5s的onnx图片,太长了我只截取了三段。
到这里我们拿到了onnx文件,后面的操作只和yolov5.onnx文件有关了,权重和模型暂时就没用了。下一步开始trt文件的转换。
3.3怎么样将onnx转rtr文件
3.3.1两种转换的方式
Onnx转tensorRT的过程之前也困扰了我很久。很简单,将 ONNX 文件转换为 TensorRT 引擎有两种主要方法,第一种是通过安装的windows平台上tensorRT安装包下的trtexec.exe转换,另一种是通过tensorRT的C++或者python的API转换:
我们暂时只介绍使用trtexec.exe转换的方式。
3.3.2为什么要安装tensorRT
这一步骤中我们的输入是yolov5.onnx文件,我们想要的输出是一个rtr格式engine文件(yolov5.trt)。我们该怎么得到输出呢?这就要安装tensorRT了。
3.3.3安装tensorRT
平台是windows。安装tensorRT很简单,但是需要注意的是版本的匹配问题,查看自己的硬件驱动的cuda版本(注意硬件驱动cuda版本和conda环境中的cuda不相干,硬件驱动的cuda可以向下兼容conda环境中的cuda版本,比如我硬件驱动cuda是11.7,但是我的conda环境中的cuda是11.3),注意是硬件驱动的cuda版本。通过终端输入nvidia-smi命令即可查询。如下所示:
通过这一步我们知道了我们硬件的cuda是什么版本,然后可以安装匹配的tensorRT了。
3.3.3.1下载tensorRT
下载链接在此:NVIDIA TensorRT 8.x Download | NVIDIA Developer,但是需要注册,如果没有注册的话自己注册一下,进入之后页面如下:
GA和EA有什么区别?GA稳定版,EA early access测试版。
我们展开8.5GA版本如下图,根据自己情况选择,可以看到有windows平台的压缩包,并且有适配cuda11.7的版本(这个版本适配范围较广,好评)
3.3.3.2进行安装
安装步骤:
1. 解压到你自己的路径
这一步不做介绍,后面我提到的路径需要参考自己路径。
2. 添加环境变量
E:\TensorRT_8.5\TensorRT-8.5.3.1\lib
3. 将bin和include文件移动到cuda安装目录下
注意别搞混了:
TensorRT-8.5.2.2\lib下的lib文件拷贝到CUDA路径下的lib/64路径下
TensorRT-8.5.2.2\lib下的dll文件拷贝到CUDA路径下的bin路径下
提示:cuda路径参考:我的路径:C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.3\
TensorRT-8.5.2.2\lib下的lib文件拷贝到CUDA路径下的lib/64路径下
TensorRT-8.5.2.2\lib下的dll文件拷贝到CUDA路径下的bin路径下
提示:cuda路径参考:我的路径:C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.3\
4. 安装tensorrt依赖
安装E:\TensorRT_8.5\TensorRT-8.5.3.1\python路径下的tensorrt库文件,注意自己的python版本选择合适的版本安装。
安装方法:anaconda终端打开切换到自己的conda环境,切换路径,conda 切换和linux切换不同,先切换盘符cd E ,然后cd 整个路径。然后执行pip install xxxxx进行安装。
3.3.3.3测试是否安装成功
在conda环境中先进入python,然后如下操作:
import tensorrt
print(tensorrt.__version__)#会输出你的tensorrt版本。
至此,tensorRT安装成功。接下来就开始执行onnx to engine的操作。
3.3.3.4开始转换onnx to engine
提前准备好yolov5.onnx文件,放在该目录下。
输入:yolov5.onnx
输出:yolov5.trt文件
操作命令:trtexec --onnx=yolov5s.onnx --saveEngine=yolov5s_engine.trt
1. anaconda终端切换到trtexec.exe路径下
路径在这里:E:\TensorRT_8.5\TensorRT-8.5.3.1\bin进入之后可以看到如下所示,
2. 使用命令转换
anaconda的终端进入到该目录下,yolov5.onnx放在该路径下(其他路径就改变在输入时写好onnx的路径)
输入:
trtexec --onnx=yolov5s.onnx --saveEngine=yolov5s_engine.trt
即可
3. 转换过程
4. 输出
可以看到目录中多了yolov5.trt文件。
至此使用自带的trtexec.exe文件将onnx转换为trt完成,进入到推理环节。
Note:由于每台设备的参数不同,而onnx转trt的过程是与设备参数高度匹配的,所以绝大多数情况下,trt文件必须得从自己要推理的设备上生成。没法复用。
3.4engine文件进行推理
推理过程有两种方式c++或者python。我们暂时只介绍使用python的推理过程。
Talk is cheap,show me the code。上代码:stu-yzZ/yolov5infer (github.com)
这个地方我基于这位大佬的code做了修改,调用笔记本摄像头直接获取图片进行推理,并输出为视频,做到了实时检测。Ps:代码里fps计算不确定是否正确,但infer time是计算出来的。
个人感觉考虑你问题整体思路是很重要的,有了思路就知道在某一步应该解决什么问题,更加高效定位到自己的问题,相信我们遇到的问题已经有很多前辈遇到过了,我们只需要找个适合自己的那个“瓢”,然后照着画自己的葫芦就好,在画葫芦的过程中理论+实践两方面理解。所以我觉得思路非常重要。我在做部署的过程中很多时间花在了找思路上面,网上有很多技术解决文档,但可能都是技术细节,这样会陷入“局部极值”,所以我写这篇博文记录一下思路有了整体思路指导,就可以在遇到问题时快速定位问题,解决问题。写的不对的地方大家多多探讨共同学习。
Reference:
Win10—YOLOv5实战+TensorRT部署+VS2019编译(小白教程~易懂易上手)---超详细_vs tensort yolo-CSDN博客
TensorRT转换时的静态模式与动态模式 - 大师兄啊哈 - 博客园 (cnblogs.com)
较为详细的记录总结TensorRT的python接口的使用,环境配置,模型转换和静态动态模型推理_pycuda 调用tensorrt-CSDN博客
模型部署入门教程(七):TensorRT 模型构建与推理 - 知乎 (zhihu.com)