今天是程序员节,当然是以程序员的方式来度过节日。 很早就听说TensorRT可以加速模型推理,但一直没时间去进行实践,今天就来把这个陈年旧坑填补一下。
在实践之前有必要了解一下相关知识。
TensorRT是可以在NVIDIA各种GPU硬件平台下运行的一个C++推理框架。我们利用Pytorch、TF或者其他框架训练好的模型,可以转化为TensorRT的格式,然后利用TensorRT推理引擎去运行我们这个模型,从而提升这个模型在英伟达GPU上运行的速度[1]。
TensorRT支持几乎所有主流深度学习框架,将python框架转换成C++的TensorRT,从而可以加速推理。
具体而言,TensorRT主要做了以下几点来加快推理速度[1]:
当然,TensorRT主要缺点是与特定GPU绑定[1],在不同型号上转换出来的模型不能通用(这一点笔者暂未去从实践证实)
TensorRT官方在其仓库提供了三个开源工具,之后有需要可以使用。
三个工具大致用途[1]:
下面来进行实践上手。
这是我的电脑环境:
TensortRT非常依赖CUDA版本,在安装之前,需要先查看本机安装好的CUDA版本,查看方式有多种,第一种方式可以通过NVIDIA 控制面板查看;第二种方式可以通过在控制台输入nvcc -V
进行查看。
首先需要到Nvidia官网去下载对应Cuda版本的TensorRT安装包。
我这里下载的是红框选中的这一个,这个版本支持CUDA11.0-11.7
下载好后,将压缩包进行解压缩,然后到Anaconda环境中,以此进入到以下几个文件夹,安装这几个whl文件
cd TensorRT-8.4.3.1\python
pip install tensorrt-8.4.3.1-cp38-none-win_amd64.whl
cd TensorRT-8.4.3.1\graphsurgeon
pip install graphsurgeon-0.4.6-py2.py3-none-any.whl
cd TensorRT-8.4.3.1\onnx_graphsurgeon
pip install onnx_graphsurgeon-0.3.12-py2.py3-none-any.whl
cd TensorRT-8.4.3.1\uff
pip install uff-0.6.9-py2.py3-none-any.whl
然后需要移动安装包里的一些文件:
TensorRT-8.4.3.1\include
中头文件拷贝到C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.6\include
TensorRT-8.4.3.1\lib
中所有lib文件拷贝到C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.6\lib\x64
TensorRT-8.4.3.1\lib
中所有dll文件拷贝到C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.6\bin
注:这里的v11.6根据自己的Cuda版本号即可
之后,需要手动将C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.6\bin
路径添加到用户Path环境变量中
然后进行验证:
python
import tensorrt
print(tensorrt.__version__)
在import
时发生报错,
FileNotFoundError: Could not find: nvinfer.dll. Is it on your PATH?
此时只需要将缺少的文件找到,然后添加到上面的bin
目录下即可,我这里是在安装的torch中lib文件下找到的部分文件,缺什么移什么即可。
如无报错,再次验证,可以输出tensorrt版本:
下面运行安装包里面的一个sample.py文件,以确保tensorrt能够正常工作。
进入到下图所示的路径,运行sample.py
,如果正常输出,则代表tensorrt安装成功。
如果提示没装pycuda,还需要再安装一下
pip install pycuda
下面内容有点乱,是我实验时的草稿,明天再起来整理。
python export.py --weights yolov5s.pt --data data/coco128.yaml --include engine --device 0 --half
ONNX: export failure 0.4s: Exporting the operator silu to ONNX opset version 12 is not supported.
pytorch的激活函数源码位置:X:\anaconda3\envs\python3.7\Lib\sitepackages\torch\nn\modules\activation.py(此处结合自己的anaconda实际安装位置来更改)。
class SiLU(Module):
__constants__ = ['inplace']
inplace: bool
def __init__(self, inplace: bool = False):
super(SiLU, self).__init__()
self.inplace = inplace
def forward(self, input: Tensor) -> Tensor:
# ------------------------------------- #
# 把F.silu替换掉,修改后如下
return input * torch.sigmoid(input)
#原来的代码
return F.silu(input, inplace=self.inplace)
导出花费时间
Export complete (404.2s) 半精度
不是半精度 Export complete (99.5s)
80多秒
实验
修改detect
if __name__ == "__main__":
begin_time = time.time()
opt = parse_opt()
main(opt)
end_time = time.time()
print("程序花费时间{}秒".format(end_time-begin_time))
执行
python detect.py --weights yolov5s.pt
程序花费时间8.395954370498657秒
半精度
python detect.py --weights yolov5s.engine
程序花费时间4.830101728439331秒
全精度
程序花费时间5.456318378448486秒
计算一下速度提升35%
pt all 128 929 0.719 0.625 0.714 0.475
半精度 all 128 929 0.682 0.64 0.708 0.47
全精度 all 128 929 0.677 0.659 0.711 0.472
检测视频
正常检测 程序花费时间20.880696058273315秒
转换成tensorrt 程序花费时间16.03518009185791秒
转成onnx推理 程序花费时间25.689934253692627秒
[1]TensorRT详细入门指北:https://blog.csdn.net/IAMoldpan/article/details/117908232 [2]https://blog.csdn.net/weixin_43917589/article/details/122578198 [3]https://blog.csdn.net/qq_44523137/article/details/123178290?spm=1001.2014.3001.5502