0 背景
见《AI视频行为分析系统项目复盘——技术篇1》
1 tensorRT 介绍
NVIDIA®TensorRT™是一个深度学习平台,用于模型推理加速(仅支持NVIDIA自家GPU,CPU加速一般使用OpenVINO)。
1.1 tensorRT 诞生意义
深度学习计算量相对普通程序还是挺大的,目前CV落地还不是很普及其中一个点就是对硬件要求较高。其次,算法的计算速度直接影响产品的成本和体验,谁能在硬件成本限制下支撑起算法精度,谁就有产品竞争力。
工程上,GPU上的模型推理,业界主流使用TensorRT去加速,一方面极大提高推理速度(主要目的),另一方面减少显存等等。
1.2 tensorRT 原理
TensorRT主要做了两件事:
- TensorRT支持INT8和FP16的计算。模型训练通常使用float32或16,TRT推理时可以选择不用这么高精度。
- TensorRT对网络结构进行了重构,把一些能够合并的运算合并在了一起,针对GPU的特性做了优化。
总的来说优化方向就是:
- 数据计算角度。(降低权重参数的表示精度、整理某些网络结构)
- 数据传输角度。(整理零碎数据一起传输,减少传输次数)
- 数据访问内存角度。(减少数据访存次数、减少内存占用、提高重复使用效率)
问题1:为什么DL模型训练时不直接用INT8去训练呢?
回答:梯度对精度敏感,模型收敛要求权重的修正量很小很小。
问题2:为什么从FP32转int8,推理精度损失不大呢?
回答:训练好的模型一般具有较强鲁棒性,对噪声(输入噪声、权重噪声等)有一定的容忍度。
2 tensorRT 真实情况下的效果
关于tensorRT到底能加速多少,除了与加速原理相关(如某些网络模块加速幅度更快),这个一般好像还得看运气,实际上挺多因素有影响。
参考1:速度提升1倍——『深度应用』YoloV5 RTX2080Ti TensorRT与PyTorch速度对比
参考2:SSD单帧推理,4倍速度提升。批量推理,9倍速度提升。https://bella722.github.io/post/f524ef1f.html
参考3:
3 tensorRT实现的几种方案
3.1 方案1:基于TensorFlow内置的TensorRT
自TensorFlow 1.7后,TensorFlow已经集成TensorRT了(Google和NVIDIA的合作)。
- GitHub官网:tensorflow/tensorrt
- 官方文档:https://docs.nvidia.com/deeplearning/frameworks/tf-trt-user-guide/index.html
TF-TRT的优缺点:
优点:
1. API易于使用;
2. 无需担心插件。
缺点:
1. 需要将整个TensorFlow库存储在平台中(这对部署环境不利)
2. 需要在运行时将TensorFlow加载到内存中
3. 通常比纯TensorRT引擎运行慢
流程DEMO
(此部分引用自:https://github.com/SimonWang00/TRT-Tensorflow2)
- 简介:在tensorflow2.0上使用tensorrt6加速
- 工作流程:
运行环境准备
- OS:Ubuntu18.0.4 LST
- python:3.6.5
- tensorflow:2.1.0
- tensorrt:6.0.1
- GPU:只支持GPU
执行步骤
- 安装Nvidia深度学习驱动,Cudnn和Cuda驱动:此部分从略。
- 下载安装TensorRT 6.0
保存模型
- save_models形式
转换成tensorrt图
from tensorflow.python.compiler.tensorrt import trt_convert as trt
params=trt.DEFAULT_TRT_CONVERSION_PARAMS
params._replace(precision_mode=trt.TrtPrecisionMode.FP32)
converter = trt.TrtGraphConverterV2(input_saved_model_dir='tf_savedmodel',conversion_params=params)
converter.convert()#完成转换,但是此时没有进行优化,优化在执行推理时完成
converter.save('trt_savedmodel')
优化并推理
import tensorflow as tf
from tensorflow.python.compiler.tensorrt import trt_convert as trt
from tensorflow.keras.datasets import mnist
import time
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_test = x_test.astype('float32')
x_test = x_test.reshape(10000, 784)
x_test /= 255
saved_model_loaded = tf.saved_model.load(
"trt_savedmodel", tags=[trt.tag_constants.SERVING])#读取模型
graph_func = saved_model_loaded.signatures[
trt.signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY]#获取推理函数,也可以使用saved_model_loaded.signatures['serving_default']
frozen_func = trt.convert_to_constants.convert_variables_to_constants_v2(
graph_func)#将模型中的变量变成常量,这一步可以省略,直接调用graph_func也行
t=time.time()
output = frozen_func(tf.constant(x_test))[0].numpy()
print(time.time()-t)
print((output.argmax(-1)==y_test).mean())
3.2 方案2:基于TensorRT自身语法
一般将其他框架模型转成ONNX格式,然后使用TensorRT自身语法去加载并推理ONNX模型。
此方案一个比较好的参考资料:wang-xinyu/tensorrtx (几十个主流算法的tensorRT实现)
C++环境下的tensorRT(yoloV5)全过程DEMO
备注1:以下流程主要参考自wang-xinyu/tensorrtx ,相关细节为自己实践中修改或补全。
备注2:不要下载太新版本的CUDA和tensorRT,很有可能遇到问题无法解决。(网站上的issues中有很多人遇到环境不适配问题且没有解决方案)
备注3:Ubuntu中切换系统默认CUDA的方法见:《AI视频行为分析系统项目复盘——技术篇1》CUDA安装部分。
1. Install CUDA(10.0版)
改用axel下载CUDA包(wget需要翻墙,一般连不上官网),
(axel下载CUDA包,例如:axel -n 50 https://developer.download.nvidia.cn/compute/cuda/11.1.0/local_installers/cuda-repo-ubuntu1804-11-1-local_11.1.0-455.23.05-1_amd64.deb)
命令依次如下:
- 去官网下载cuda-repo-ubuntu1804-10-0-local-10.0.130-410.48_1.0-1_amd64.deb(10.0版本没有显示具体下载网址,所以无法使用axel下载)
- sudo dpkg -i cuda-repo-ubuntu1804-10-0-local-10.0.130-410.48_1.0-1_amd64.deb
- sudo apt-key add /var/cuda-repo-10-0-local-10.0.130-410.48/7fa2af80.pub
- sudo apt-get update
- (可选:apt-cache show cuda #查询本机有哪几个CUDA版本包,并显示他们的详细信息)
- sudo apt-get install cuda=10.0.130-1
备注:如果电脑之前已经安装了高版本CUDA,那么安装cuda时,就需要指定本次CUDA的具体版本号,wang-xinyu/tensorrtx上并没有说明这点。
2. Install TensorRT(7.0.0版)
Go to nvidia-tensorrt-7x-download. You might need login,下载后执行如下命令:
- sudo dpkg -i nv-tensorrt-repo-ubuntu1804-cuda10.0-trt7.0.0.11-ga-20191216_1-1_amd64.deb
- sudo apt update
- sudo apt install tensorrt
3. Install OpenCV
这一步好像Ubuntu默认装了3.2版,不需要安装。
4. Check your installation
如果以下3个命令,终端中都有信息回复,则表示安装成功。
- dpkg -l | grep cuda
- dpkg -l | grep nvinfer
- dpkg -l | grep opencv
5.yolo5s项目准备
下载yolo5官网V5版工程,下载yolo5s.pt预训练模型,将yolov5s.pt模型转为yolov5.wts格式。命令如下:
- git clone -b v5.0 https://github.com/ultralytics/yolov5.git
- git clone https://github.com/wang-xinyu/tensorrtx.git
- // download https://github.com/ultralytics/yolov5/releases/download/v5.0/yolov5s.pt
- cp {tensorrtx}/yolov5/gen_wts.py {ultralytics}/yolov5
- cd {ultralytics}/yolov5
- python gen_wts.py yolov5s.pt
6.build tensorrtx/yolov5 and run
cd {tensorrtx}/yolov5/
// update CLASS_NUM in yololayer.h if your model is trained on custom dataset
mkdir build
cd build
cp {ultralytics}/yolov5/yolov5s.wts {tensorrtx}/yolov5/build
cmake ..
make
sudo ./yolov5 -s [.wts] [.engine] [s/m/l/x/s6/m6/l6/x6 or c/c6 gd gw] // serialize model to plan file
sudo ./yolov5 -d [.engine] [image folder] // deserialize and run inference, the images in [image folder] will be processed.
// For example yolov5s
sudo ./yolov5 -s yolov5s.wts yolov5s.engine s
sudo ./yolov5 -d yolov5s.engine ../samples
// For example Custom model with depth_multiple=0.17, width_multiple=0.25 in yolov5.yaml
sudo ./yolov5 -s yolov5_custom.wts yolov5.engine c 0.17 0.25
sudo ./yolov5 -d yolov5.engine ../samples
7.check the images generated, as follows. _zidane.jpg and _bus.jpg
4 tensorRT技术未来趋势预估
待续