TensorRT Analysis Report分析报告

TensorRT Analysis Report

一.介绍

TensorRT是一个高性能的深度学习推理(Inference)优化器,可以为深度学习应用提供低延迟、高吞吐率的部署推理。TensorRT可用于对超大规模数据中心、嵌入式平台或自动驾驶平台进行推理加速。TensorRT现已能支持Tensorflow、Caffe、Mxnet、Pytorch等几乎所有的深度学习框架,将TensorRT和NVIDIA的GPU结合起来,能在几乎所有的框架中进行快速和高效的部署推理。

TensorRT 是一个C++库,从 TensorRT 3 开始提供C++ API和Python API,主要用来针对 NVIDIA GPU进行高性能推理(Inference)加速。现在最新版TensorRT是4.0版本。

TensorRT 之前称为GIE。
TensorRT Analysis Report分析报告

关于推理(Inference):
TensorRT Analysis Report分析报告

在推理过程中,基于 TensorRT 的应用程序的执行速度可比 CPU 平台的速度快 40 倍。借助 TensorRT,可以优化在所有主要框架中训练的神经网络模型,精确校正低精度,并最终将模型部署到超大规模数据中心、嵌入式或汽车产品平台中。

TensorRT以 NVIDIA 的并行编程模型CUDA 为基础构建而成,可帮助利用 CUDA-X 中的库、开发工具和技术,针对人工智能、自主机器、高性能计算和图形优化所有深度学习框架中的推理。

TensorRT 针对多种深度学习推理应用的生产部署提供INT8和 FP16 优化,例如视频流式传输、语音识别、推荐和自然语言处理。推理精度降低后可显著减少应用延迟,这恰巧满足了许多实时服务、自动和嵌入式应用的要求。

TensorRT项目立项的时候名字叫做GPU Inference Engine(简称GIE),Tensor表示数据流动以张量的形式。

张量可以理解为更加复杂的高维数组。
TensorRT Analysis Report分析报告

纬度的就叫Tensor,Matrix其实是二维的Tensor。

在TensoRT中,所有的数据都被组成最高四维的数组,如果对应到CNN中其实就是{N, C, H, W},N表示batch size,即多少张图片或者多少个推断(Inference)的实例;C表示channel数目;H和W表示图像或feature maps的高度和宽度。TR表示的是Runtime。

下图是NVDIA针对深度学习平台的一系列完整的解决方案。分为训练和部署两部分,训练部分首先也是最重要的是构建网络结构,准备数据集,使用各种框架进行训练,训练要包含validation和test的过程,最后对于训练好的模型要在实际业务中进行使用。
TensorRT Analysis Report分析报告

训练(Training)这个阶段如果模型比较慢,可以用更大的集群、更多的机器,做更大的数据并行甚至是模型并行来训练它,重要的是成本的投入。

部署端不只是成本的问题,如果方法不得当,即使使用目前最先进的GPU,也无法满足推断(Inference)的实时性要求。因为模型如果做得不好,没有做优化,可能需要二三百毫秒才能做完一次推断(Inference),再加上来回的网络传输,用户可能一秒后才能得到结果。

二. 为什么TensorRT能让模型加速?
TensorRT Analysis Report分析报告

TensorRT优化训练好的神经网络模型以产生可部署的运行时推理引擎

从图上可以看到,TensorRT主要做了下面几件事,来提升模型的运行速度。
TensorRT Analysis Report分析报告

或张量融合(Layer & Tensor Fusion)

如下图左侧是GoogLeNetInception模块的计算图。这个结构中有很多层,在部署模型推理时,这每一层的运算操作都是由GPU完成的,但实际上是GPU通过启动不同的CUDA(Compute unified device architecture)核心来完成计算的,CUDA核心计算张量的速度是很快的,但是往往大量的时间是浪费在CUDA核心的启动和对每一层输入/输出张量的读写操作上面,这造成了内存带宽的瓶颈和GPU资源的浪费。TensorRT通过对层间的横向或纵向合并(合并后的结构称为CBR,意指 convolution, bias, and ReLU layers are fused to form a single layer),使得层的数量大大减少。横向合并可以把卷积、偏置和**层合并成一个CBR结构,只占用一个CUDA核心。纵向合并可以把结构相同,但是权值不同的层合并成一个更宽的层,也只占用一个CUDA核心。合并之后的计算图(图4右侧)的层次更少了,占用的CUDA核心数也少了,因此整个模型结构会更小,更快,更高效。
TensorRT Analysis Report分析报告

  1. 数据精度校准(Weight &Activation Precision Calibration)

大部分深度学习框架在训练神经网络时网络中的张量(Tensor)都是32位浮点数的精度(Full
32-bit precision,FP32),一旦网络训练完成,在部署推理的过程中由于不需要反向传播,完全可以适当降低数据精度,比如降为FP16或INT8的精度。更低的数据精度将会使得内存占用和延迟更低,模型体积更小。

TensorRT支持FP16和INT8的计算。我们知道深度学习在训练的时候一般是应用32位或者16位数据,TensorRT在推理的时候可以降低模型参数的位宽来进行低精度推理,以达到加速推断的目的。

如下表为不同精度的动态范围:
TensorRT Analysis Report分析报告

INT8只有256个不同的数值,使用INT8来表示 FP32精度的数值,肯定会丢失信息,造成性能下降。不过TensorRT会提供完全自动化的校准(Calibration )过程,会以最好的匹配性能将FP32精度的数据降低为INT8精度,最小化性能损失。关于校准过程,后面会专门做一个探究。

  1. Kernel Auto-Tuning

网络模型在推理计算时,调用GPU的CUDA核进行计算。TensorRT可以针对不同的算法,不同的网络模型,不同的GPU平台,进行 CUDA核的调整,以保证当前模型在特定平台上以最优性能计算。

TensorRT will pick the implementation
from a library of kernels that delivers the best performance for the target
GPU, input data size, filter size, tensor layout, batch size and other
parameters.

  1. Dynamic Tensor Memory

在每个tensor的使用期间,TensorRT会为其指定显存,避免显存重复申请,减少内存占用和提高重复使用效率。

  1. Multi-Stream Execution

Scalable
design to process multiple input streams in parallel,这个应该就是GPU底层的优化了。然后Concat层是可以去掉的,因为TensorRT完全可以实现直接接到需要的地方。

TensorRT对于网络结构进行重构,把一些能够合并的运算合并在了一起,针对GPU的

特性做了优化。在GPU上跑的函数叫Kernel,TensorRT是存在Kernel的调用的。在绝大部分框架中,比如一个卷积层、一个偏置层和一个reload层,这三层是需要调用三次cuDNN对应的API,但实际上这三层的实现完全是可以合并到一起的,TensorRT会对一些可以合并网络进行合并;目前的网络一方面越来越深,另一方面越来越宽,可能并行做若干个相同大小的卷积,这些卷积计算其实也是可以合并到一起来做的。

  1. 不同的硬件,如P4卡还是V100卡,甚至是嵌入式设备的卡,TensorRT都会做优化,得到优化后的engine。

可以从每个深度学习框架中将已训练模型导入到
TensorRT。应用优化后,TensorRT 选择平台特定的内核,在数据中心、Jetson 嵌入式平台以及 NVIDIA DRIVE 自动驾驶平台上更大限度提升 Tesla GPU 的性能。

借助 TensorRT,开发者可专注于创建新颖的 AI 支持应用,无需费力调节性能来部署推理工作。

作为Inference(推理)端的SDK的工具,TensorRT是可编程的处理加速器,主要是用来部署神经网络到Inference端之前,对于网络进行优化加速,来提高程序的吞吐量以及降低延迟。TensorRT理论上可以支持所有主流的深度学习框架,目前最新的版本是3.0版,可以支持Caffe 模型的直接导入,还有就是Tensorflow模型转换为UFF格式后的导入。对于其他的framework,需要用户手动的去调用一些API进行模型和参数的导入,而且在TensorRT 3.0里面还加入了对Python接口的支持,原来我们是只支持C++的,目前加入了Python,这样使得导入网络模型可以变得更加容易一些。

TensorRT的部署流程可以分成两部分。

首先是向TensorRT 导入训练好的网络模型、参数,输入一组测试集数据,这个数据集不用太大。在TensorRT 启动之后,会根据我们刚才所说的几大优化方式依次对网络模型进行优化,对于规模不大的网络,这个过程可能需要耗费几分钟的时间。在执行完成之后,它会输出一个优化策略,如上图所示的Plan。这时我们可以选择将这个优化策略以序列化的方式导出到磁盘文件进行存储,这样,这个策略文件就可以被复制以及移植到不同的设备端来使用。

接下来就可以拿着这个优化策略文件连通TensorRT
的引擎,一起部署到线上服务端。

ONNX(Open Neural Network Exchange )是微软和Facebook携手开发的开放式神经网络交换工具,也就是说不管用什么框架训练,只要转换为ONNX模型,就可以放在其他框架上面去inference。这是一种统一的神经网络模型定义和保存方式,上面提到的除了Tensorflow之外的其他框架官方应该都对ONNX做了支持,而ONNX自己开发了对Tensorflow的支持。从深度学习框架方面来说,这是各大厂商对抗谷歌Tensorflow垄断地位的一种有效方式;从研究人员和开发者方面来说,这可以使开发者轻易地在不同机器学习工具之间进行转换,并为项目选择最好的组合方式,加快从研究到生产的速度。
TensorRT Analysis Report分析报告
TensorRT 和 Tensorflow 已紧密集成,因此可以同时尽享 Tensorflow的灵活性和 TensorRT 的超强优化性能。
TensorRT Analysis Report分析报告

MATLAB 已通过 GPU 编码器实现与 TensorRT 的集成,这能协助工程师和科学家在使用 MATLAB 时为 Jetson、DRIVE
和 Tesla 平台自动生成高性能推理引擎。
TensorRT Analysis Report分析报告

TensorRT提供了一个 ONNX 解析器,因此可以轻松地从框架(例如 Caffe 2、Chainer、Microsoft Cognitive Toolkit、MxNet 和PyTorch)中将 ONNX 模型导入到 TensorRT。

TensorRT 还与 ONNX Runtime 集成,助以 ONNX 格式轻松实现机器学习模型的高性能推理。

Figure 1. TensorRT is a high-performance neural network
inference optimizer and runtime engine for production deployment.
TensorRT Analysis Report分析报告
TensorRT Analysis Report分析报告

Figure 2. TensorRT
is a programmable inference accelerator.
TensorRT Analysis Report分析报告

由以上两张图可以很清楚的看出,训练(training)和
推理(inference)的区别:

· 训练(training)包含了前向传播和后向传播两个阶段,针对的是训练集。训练时通过误差反向传播来不断修改网络权值(weights)。

· 推理(inference)只包含前向传播一个阶段,针对的是除了训练集之外的新数据。可以是测试集,但不完全是,更多的是整个数据集之外的数据。其实就是针对新数据进行预测,预测时,速度是一个很重要的因素。

训练时为了加快速度,会使用多GPU分布式训练。

部署推理时,为了降低成本,往往使用单个GPU机器甚至嵌入式平台(比如 NVIDIA Jetson)进行部署,部署端也要有与训练时相同的深度学习环境,如caffe,Tensorflow等。

由于训练的网络模型可能会很大(比如,inception,resnet等),参数很多,而且部署端的机器性能存在差异,就会导致推理速度慢,延迟高。这对于那些高实时性的应用场合是致命的,比如自动驾驶要求实时目标检测,目标追踪等。

为了提高部署推理的速度,出现了很多轻量级神经网络,比如squeezenet,mobilenet,shufflenet等。基本做法都是基于现有的经典模型提出一种新的模型结构,然后用这些改造过的模型重新训练,再重新部署。

而TensorRT 则是对训练好的模型进行优化。
TensorRT就只是 推理优化器。当你的网络训练完之后,可以将训练模型文件直接丢进TensorRT中,而不再需要依赖深度学习框架(Caffe,Tensorflow等),如下:
TensorRT Analysis Report分析报告

TensorRT是一个只有前向传播的深度学习框架,这个框架可以将 Caffe,Tensorflow的网络模型解析,然后与TensorRT中对应的层进行一一映射,把其它框架的模型统一全部转换到TensorRT中,然后在TensorRT中可以针对NVIDIA自家GPU实施优化策略,并进行部署加速。
TensorRT Analysis Report分析报告

Functions Name

Contents

Caffe/Tensorflow

TensorRT可以直接解析他们的网络模型

Tensorflow/MATLAB

Tensorflow和MATLAB已经将TensorRT集成到框架中

caffe2,pytorch,mxnet,chainer,CNTK

首先要将模型转为ONNX 的通用深度学习模型,然后对ONNX模型做解析。

ONNX(Open Neural Network Exchange )

微软和Facebook携手开发的开放式神经网络交换工具,也就是说不管用什么框架训练,只要转换为ONNX模型,就可以放在其他框架上面去inference。

Tenseflow

ONNX单独开发了对Tensorflow的支持。

Netwok Definition API

给那些使用自定义的深度学习框架训练模型的人提供的TensorRT接口。
比如 YOLO 作者使用的darknet要转TensorRT估计得使用这个API,不过一般网上有很多使用其他框架训练的YOLO,这就可以使用对应的caffe/Tensorflow/onnx API了。

ONNX网络中有自定义的Layer,如何处理?

TensorRT中有一个 Plugin 层,这个层提供了 API 可以由用户自己定义TensorRT不支持的层。 如下图所示:
TensorRT Analysis Report分析报告

基本上比较经典的层,如,卷积,反卷积,全连接,RNN,softmax等,在TensorRT中都是有对应的实现方式的,TensorRT是可以直接解析的。

由于现在深度学习技术发展日新月异,各种不同结构的自定义层(比如:STN)层出不穷,所以TensorRT是不可能全部支持当前存在的所有层的。那对于这些自定义的层该怎么办?

目前TensorRT4.0几乎可以支持所有常用的深度学习框架,对于caffe和Tensorflow来说,TensorRT可以直接解析他们的网络模型;对于caffe2,pytorch,mxnet,chainer,CNTK等框架则是首先要将模型转为 ONNX 的通用深度学习模型,然后对ONNX模型做解析。而Tensorflow和MATLAB已经将TensorRT集成到框架中去了。

ONNX(Open Neural Network Exchange )是微软和Facebook携手开发的开放式神经网络交换工具,也就是说不管用什么框架训练,只要转换为ONNX模型,就可以放在其他框架上面去inference。这是一种统一的神经网络模型定义和保存方式,上面提到的除了Tensorflow之外的其他框架官方应该都对ONNX做了支持,而ONNX自己开发了对Tensorflow的支持。从深度学习框架方面来说,这是各大厂商对抗谷歌Tensorflow垄断地位的一种有效方式;从研究人员和开发者方面来说,这可以使开发者轻易地在不同机器学习工具之间进行转换,并为项目选择最好的组合方式,加快从研究到生产的速度。

ONNX / Tensorflow/ Custom deep-learning frame模型的工作方式:

Netwok Definition API 是自定义的深度学习框架训练模型的人提供的TensorRT接口。

比如 YOLO 使用的darknet要转TensorRT使用这个API,不过一般网上有很多使用其他框架训练的YOLO,这就可以使用对应的caffe/Tensorflow/onnx API了。

TensorRT支持的层有:

·
Activation: ReLU, tanh and sigmoid

·
Concatenation: Link together multiple tensors across the channel dimension.

· Convolution: 3D,2D

· Deconvolution

· Fully-connected: with or without bias

· ElementWise: sum, product or max of two tensors

· Pooling: max and average

· Padding

· Flatten

· LRN: cross-channel only

· SoftMax: cross-channel only

· RNN: RNN, GRU, and LSTM

· Scale: Affine transformation and/or exponentiation by constant values

· Shuffle: Reshuffling of tensors , reshape or transpose data

· Squeeze: Removes dimensions of size 1 from the shape of a tensor

· Unary: Supported operations are exp, log, sqrt, recip, abs and neg

· Plugin: integrate custom layer implementations that TensorRT does not natively support.