TensorRT:1.基本概念和环境准备

折腾了很多C++部署的方案,最终还是需要回到速度这个问题上来,目前能进行模型加速的,就只有TensorRT了,刚好它也是C++接口,能满足我的需求。

1.什么是TensorRT

听起来,TensorRT和TensorFlow、PyTorch和Caffe等深度学习框架很像,实际差别很大。我们常用的深度学习模型更多的注重于模型的设计训练,而TensorRT并不关心如何训练我们的深度学习模型
,它只负责模型的推理(inference)过程,只考虑如何将已训练好的模型进行高效快速的推理,协助于部署应用。

官网地址:
https://developer.nvidia.com/tensorrt

参看官方的图:
TensorRT:1.基本概念和环境准备_第1张图片
注意:
TensorRT是NVIDIA推出的,是为它自家GPU服务的,所以并不支持在CPU和其他GPU上使用。

2.TensorRT为什么能让模型加速?

采用TenorRT对模型进行推理部署,会比模型原生框架跑得快,它是怎么做多的呢?
我们看下官方的说法,有几个方面优化:

  • 去除输出没有被使用的层
  • 去除那些相当于没用的操作
  • 将卷积、偏置和ReLU操作融合在一起
  • 聚合那些相似的操作
  • 融合了残差层

巴拉巴拉说了一堆,综合来看,实际发挥作用最大的就两个:

  • 第一个是算子融合(网络层合并)。TensorRT通过对层间的横向或纵向合并(合并后的结构称为CBR,意指 convolution,
    bias, and ReLU layers are fused to form a single
    layer),使得层的数量大大减少。因此整个模型结构会更小,更快,更高效。
    横向合并可以把卷积、偏置和激活层合并成一个CBR结构,只占用一个CUDA核。
    纵向合并可以把结构相同,但是权值不同的层合并成一个更宽的层,也只占用一个CUDA核心。

  • 第二个是降低模型精度。大部分深度学习框架在训练神经网络时网络中的张量(Tensor)都是32位浮点数的精度(Full 32-bit
    precision,FP32),一旦网络训练完成,在部署推理的过程中由于不需要反向传播,完全可以适当降低数据精度,比如降为FP16或INT8的精度。更低的数据精度将会使得内存占用和延迟更低,模型体积更小。
    当然,低精度带来速度提升的同时,必然会带来准确度的损失,在模型部署时可根据需要来权衡。大多数情况下,我们使用FP16推理是足够了的。

那么这些已训练好的模型,如何使用,TensorRT提供了三个Parser用于模型的导入:

  • Caffe Parser: 支持Caffe框架模型的导入 UFF
  • Parser:通用框架格式(UFF)是描述DNN的执行图的数据格式
  • ONNX Parser:通用模型交换格式(ONNX)是一种开放式的文件格式

通过将模型保存为以上三个Parser可以解析的格式,基本上就可以将市面上绝大多数模型导入到TensorRT中了。各种框架间模型的转换,需要的仅仅是模型的定义及权值。

3.TensorRT如何执行推理?

一个模型从导入到执行,会经过下面三个阶段:

  • Network Definition:这一阶段在TensorRT中定义网络模型,可以使用TensorRT提供的Parser导入已有模型进行定义,也可以使用TensorRT中提供的网络层来编程定义(这一步应该也需要准备好相关的权值)
  • Builder:前面提到过,TensorRT会对模型进行优化,这一步就是配置各项优化参数,并能生成可执行Inference的Engine
  • Engine:Engine可理解为一个Builder的实例,是我们导入的模型经过Builder的配置所生成的一个优化过的Inference执行器,所有的Inference可直接调用Engine来执行

4.TenorRT环境配置
使用TensorRT的前提是,你要有GPU,并且安装好Cuda和CuDNN这些基础环境,这个就不赘述了。直接在NVIDIA网站就可以下载安装。

TenorRT库下载:
https://developer.nvidia.com/nvidia-tensorrt-download
TensorRT:1.基本概念和环境准备_第2张图片
注意需要先登录才能看到下载链接。

目前最新的是8.0版本,我下载的是windows下的7.0,下载下来解压就行了。
TensorRT:1.基本概念和环境准备_第3张图片
里面的Sample很重要,仔细过一遍基本流程就清楚了,很多工具类也可以拿出来自己用。

5. TensorRT C++ API文档

重要的类介绍
(1)ILogger
这是一个必须但不是很重要的类,它用于记录一些日志信息。
在编程时,我们需要声明一个全局的ILogger对象gLogger,TensorRT中很多方法都需要它作为参数这个类,直接从samples/common里面拷贝过来用就行了。

(2)IBuilder
IBuilder类应该算是最重要的一个类,在使用时,首先要使用TensorRT的全局方法createInferBuilder()来创建一个IBuilder类指针,然后由该指针调用IBuilder类方法创建Network和Engine类的指针。

(3)INetworkDefinition
INetworkDefinition类即为网络定义,可通过IBuilder类方法createNetwork()返回其指针。

(4)ICudaEngine
ICudaEngine类即为Engine,可通过IBuilder类方法buildCudaEngine()/buildEngineWithConfig()返回其指针。有两种生成方式,可通过导入模型生成Engine和通过反序列化来加载Engine。

(5)IParser
IParser类对应着前文所述的三种不同的解释器,可根据需要来使用。
IParser类方法parse()用于解析并加载模型及参数到TensorRT网络中(INetworkDefinition类)

(6)IExecutionContext
Engine的运行需要一个运行时环境,createExecutionContext()方法为相应的ICudaEngine生成一个IExecutionContext类型的运行环境。

6. 其他参考资料

官方文档:
TensorRT安装指南,介绍各个操作系统下环境的安装
TensorRT开发者指南,介绍了TensorRT中的一些原理和概念
TensorRT实例教程,一些TensorRT中的具体例子,很详细,覆盖的也很广
TensorRT支持ops,介绍了TensorRT对不同模型所支持的相关操作

官方快速入门实例
“Hello World” For TensorRT

你可能感兴趣的:(人工智能,深度学习,TensorRT,GPU加速,模型部署)