惯例先放资源
1.官方的tensorrt文档
2.tensorrt官方主页
3.tensorrt支持的操作
模型加速越来越成为深度学习工程中的刚需了,最近的CVPR和ICLR会议中,模型的压缩和剪枝是受到的关注越来越多。
毕竟所有的算法想要产生经济效益一定要考虑落地的情况,可能我们看很多论文提出的方法或者说github公布的代码大多关注精度及python环境下的FPS,但在实际的工程用在考虑精度的同时,速度也是十分重要的,且更多的公司越来越青睐python 训练,C++重写推理并利用tensorrt库进行加速。
拿自动驾驶举例来说,如果使用一个经典的深度学习模型,单帧图像的推理速度很容易就跑到200ms的延时
,那么这意味着,在实际驾驶过程中,你的车一秒钟只能看到5张图像
,这限制了我们对环境的感知情况,这是很危险的一件事。
再比如来说,同样功能的app,一个每次打开需要响应500ms的,和一个每次打开只需要响应100ms的,用户用脚投票也会淘汰掉500ms的app。
所以,对于实时响应比较高的任务,模型的加速时很有必要的一件事情了。
可以把TensorRT看做一个“深度学习框架”,不同于常用的TensorFlow、PyTorch和Caffe等深度学习框架,TensorRT的目的不是如何训练我们的深度学习模型,而是考虑如何将那些使用其他框架训练好的模型进行高效快速的Inference。
官方的这张图可以很明确的说明TensorRT的作用:用于模型训练完之后的部署阶段,以进行高效低延时的Inference:
在工程实践中,一般还是用python + tensorflow/pytorch 等工具对数据预处理与进行训练,训练完成后得到权重文件,利用c++ 与 tensorrt重写模型推理部分,生成特定的tensorrt推理引擎,通常想对于python的推理速度会快大约5-20倍左右。
需要注意的是,tensorrt不支持cpu的加速,如果需要cpu部署加速可以尝试libtorch(torch官方的加速工具)
这里会有疑问:直接使用TensorFlow和PyTorch等模型进行部署不可以吗?
这当然是可以的,只是TensorRT是一个专用的Inference工具,使用它进行部署会使模型运行更高效。
有时制约计算速度的并不仅仅是计算量,而是网络对于内存的读写花费太大,TensorRT中将多个层的操作合并为同一个层,这样就可以一定程度的减少kernel launches和内存读写。例如conv和relu等操作一次做完。另外,对于多分支合并的情况,TensorRT完全可以实现直接接到需要的地方,不用专门做concat的操作,所以这一层也可以取消掉。
如上图左边为InceptionBlock,通过以下步骤优化得到上图右边的计算图:首先合并conv、bias、relu为一个CBR
;接下来合并三个相连的1×1的CBR为一个大的1×1的CBR
;最后取消concat层
,直接连接到下一层的nextinput。另外还可以做并发(Concurrency)
,不同并的分支是相互独立的路径,本质上是不相关的,可以在GPU上通过并发来做,来达到的优化的目标。
训练时由于梯度等对于计算精度要求较高,但是inference阶段可以利用精度较低的数据类型加速运算,降低模型的大小。
在GPU上跑的函数叫Kernel,TensorRT是存在Kernel的调用的。TensorRT针对不同的超参数有一些Kernel层面的优化,比如会根据卷积核的大小、输入大小等超参数确定使用哪种算法进行卷积运算。
TensorRT经过优化减少内存开销,提高内存的reuse。
对于同一输入的多个分支可以进行并行运算,还可以根据不同batchsize优化。
总结一下
TensorRT对一个模型主要进行了以下几点优化:
除了上述对模型整体的优化外,在TensorRT中还可以直接设置权值的精度,如可以进行INT8
或FP16
精度的运算,默认是FP32
精度。当然,低精度带来速度提升的同时,必然会带来准确度的损失,在模型部署时可根据需要来权衡。
通过其他框架训练好的模型,如何导入到TensorRT中使用?
TensorRT支持TensorFlow、PyTorch,MXNet和Caffe等主流框架模型的导入,支持方式是通过一些通用的模型交换格式作为中间媒介。
TensorRT中有三个Parser用于模型的导入:
通用模型交换格式(ONNX)
是一种开放式的文件格式,用于存储训练好的模型作者自己一般使用pytorch,一般都是将.pt/.pth文件转换成.onnx或者.wts格式文件,然后导入至tensorrt
需要清楚的是,各种框架间模型的转换,需要的仅仅是模型的定义及权值
。
通过将模型保存为以上三个Parser(trt解析器)可以解析的格式,则基本上就可以将模型导入到TensorRT中。
事实上,一个模型从导入到执行,会经过下面三个阶段:
通过上面的分析可以有这样的理解:一个导入的模型可根据不同的Builder配置来生成不同的Engine来执行Inference。
一个模型从导入到生成Engine是需要花费一些时间的,因此TensorRT提供了Engine的序列化和反序列化操作,一旦我们确定了一个Engine,可以对其进行序列化操作,下次执行Inference时直接反序列化该Engine即可。
1.trt官方文档
2.《一》TensorRT之基本概念
3.tensorrt轻松部署高性能dnn推理_深度学习模型inference优化之tensorrt(TRT)