ONNX 介绍及TensorRT部署

ONNX简介

Open Neural Network Exchange(ONNX,开放神经网络交换)格式,是一个用于表示深度学习模型的标准,可以使模型在不一样框架之间进行转移。html

 

python

ONNX是一种针对机器学习所设计的开放式的文件格式,用于存储训练好的模型。它使得不一样的人工智能框架(如Pytorch, MXNet)能够采用相同格式存储模型数据并交互。 ONNX的规范及代码主要由微软,亚马逊 ,Facebook 和 IBM 等公司共同开发,以开放源代码的方式托管在Github上。目前官方支持加载ONNX模型并进行推理的深度学习框架有: Caffe2, PyTorch, MXNet,ML.NET,TensorRT 和 Microsoft CNTK,而且 TensorFlow 也非官方的支持ONNX。---维基百科linux



咱们可能会在某一任务中将Pytorch或者TensorFlow模型转化为ONNX模型(ONNX模型通常用于中间部署阶段),而后再拿转化后的ONNX模型进而转化为咱们使用不一样框架部署须要的类型。

算法

典型的几个线路:性能优化

Pytorch -> ONNX -> TensorRT网络

Pytorch -> ONNX -> TVM数据结构

TF – onnx – ncnn框架

等等,ONNX至关于一个翻译的做用,这也是为何ONNX叫作Open Neural Network Exchange。机器学习

 

Pytorch模型定义和模型权重暂时不支持打包在一块儿,这在推理时候须要先用模型定义代码构建模型,再加载模型权重,比较麻烦。借助于onnx格式转换能够把模型打包一块儿,在ONNX Runtime中运行推理,ONNX Runtime 是针对 ONNX 模型的以性能为中心的引擎,可大大提高模型的性能。另外,onnx模型支持在不一样框架之间转换,也支持tensorRT加速分布式

 

举例

 

假如咱们利用Pytorch训练好一个模型,而后咱们将其保存为.pt文件:

好比就叫作model.pt,这个咱们应该很熟悉吧,二进制的模型权重文件,咱们能够读取这个文件,至关于预加载了权重信息。

ONNX呢,利用Pytorch咱们能够将model.pt转化为model.onnx格式的权重,在这里onnx充当一个后缀名称,model.onnx就表明ONNX格式的权重文件,这个权重文件不只包含了权重值,也包含了神经网络的网络流动信息以及每一层网络的输入输出信息和一些其余的辅助信息。

简单拿netron这个工具来可视化(读取ONNX文件)一下:

 

 


 

如图,ONNX中的一些信息都被可视化展现了出来,例如文件格式ONNX v3,该文件的导出方pytorch 0.4等等,这些信息都保存在ONNX格式的文件中。


 

假设一个场景:如今某组织由于主要开发用TensorFlow为基础的框架,如今有一个深度算法,须要将其部署在移动设备上,以观测变现。传统地咱们须要用caffe2从新将模型写好,而后再训练参数;试想下这将是一个多么耗时耗力的过程。

此时,ONNX便应运而生,Caffe2,PyTorch,Microsoft Cognitive Toolkit,Apache MXNet等主流框架都对ONNX有着不一样程度的支持。这就便于了咱们的算法及模型在不一样的框架之间的迁移。


 

ONNX

开放式神经网络交换(ONNX)是迈向开放式生态系统的第一步,它使AI开发人员可以随着项目的发展选择合适的工具。 ONNX为AI模型提供开源格式。 它定义了可扩展的计算图模型,以及内置运算符和标准数据类型的定义。 最初的ONNX专一于推理(评估)所需的功能。 ONNX解释计算图的可移植,它使用graph的序列化格式。 它不必定是框架选择在内部使用和操做计算的形式。 例如,若是在优化过程当中操做更有效,则实现能够在存储器中以不一样方式表示模型。

ONNX是一个开放式规范,由如下组件组成:

可扩展计算图模型的定义
标准数据类型的定义
内置运算符的定义


 

Protobuf

ONNX既然是一个文件格式,那么咱们就须要一些规则去读取它,或者写入它,ONNX采用的是protobuf这个序列化数据结构协议去存储神经网络权重信息。

Protobuf是个什么东西,若是你们使用过caffe或者caffe2,那么想必可能对Protobuf比较熟悉,由于caffe的模型采用的存储数据结构协议也是Protobuf。

这里简单介绍一些protobuf吧,Protobuf是一种平台无关、语言无关、可扩展且轻便高效的序列化数据结构的协议,能够用于网络通讯和数据存储。咱们能够经过protobuf本身设计一种数据结构的协议,而后使用各类语言去读取或者写入,一般咱们采用的语言就是C++。

关于这个有一篇文章比较好地对此进行了介绍:https://www.ibm.com/developerworks/cn/linux/l-cn-gpb/index.html这里就不进行详细的介绍了。

 

为何要用onnx

如今你们都喜欢用pytorch训练模型,而pytorch训练的模型转成pth,用C++推理也很难达到真正的加速效果,由于本质上最耗时的网络前向推理部分并无太多的加速。而且采用libtorch C++推理pytorch并非一件简单的事情,除非你的模型能够被trace。

在这种状况之下,引入onnx更合理,从目前整个DL生态来看,onnx具备如下好处:

  • 它的模型格式比基于layer的老一代框架更加细粒度;

  • 它拥有统一化的定义,而且基于任何框架均可以推理他;

  • 它能够实现不一样框架之间的互相转化。

咱们今天要作的事情,就是在上面的onnx模型的基础上,采用TensorRT来进行推理。先作一个简单的速度对比:

框架

语言

耗时(s)

fps

Pytorch

python

0.012+0.022

29

ONNXRuntime

python

0.008+0.022

34

TensorRT

C++

0.004+0.001

250



 

真正落地的算法部署,毫无疑问,假如你的targetGPU,采用ONNX+TensorRT应该是目前最成熟、最优化的方案。假如你的target是一些嵌入式芯片,那么采用MNN也是能够经过onnx轻松实现CPU嵌入式端快速推理的。

既然ONNX和TensorRT这么好,为何都不用呢?为何都还在用Python写难看的推理的代码呢?缘由也很简单:

  • 入门太难,C++通常人玩不来;

  • 既要懂模型的每一层输入输出,又要懂TensorRT的API,至少要很熟悉。

 

TensorRT

通常的深度学习项目,训练时为了加快速度,会使用多GPU分布式训练。但在部署推理时,为了下降成本,每每使用单个GPU机器甚至嵌入式平台(好比 NVIDIA Jetson)进行部署,部署端也要有与训练时相同的深度学习环境,如caffe,TensorFlow等。因为训练的网络模型可能会很大(好比,inception,resnet等),参数不少,并且部署端的机器性能存在差别,就会致使推理速度慢,延迟高。这对于那些高实时性的应用场合是致命的,好比自动驾驶要求实时目标检测,目标追踪等。因此为了提升部署推理的速度,出现了不少轻量级神经网络,好比squeezenet,mobilenet,shufflenet等。基本作法都是基于现有的经典模型提出一种新的模型结构,而后用这些改造过的模型从新训练,再从新部署。

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。

深度学习

  • 训练
  • 部署

 

训练(training)和 推理(inference)的区别:

  • 训练(training)包含了前向传播和后向传播两个阶段,针对的是训练集。训练时经过偏差反向传播来不断修改网络权值(weights)。
  • 推理(inference)只包含前向传播一个阶段,针对的是除了训练集以外的新数据。能够是测试集,但不彻底是,更多的是整个数据集以外的数据。其实就是针对新数据进行预测,预测时,速度是一个很重要的因素。

日常自学深度学习的时候关注的更可能是训练的部分,即获得一个模型.而实际工做很大一块的工做内容集中于如何将模型部署到具体的芯片上.你本身写的模型效果是很难优于成熟的知名的模型的.
以无人驾驶为例,拍摄到图片后,芯片上的加载的模型要可以识别出图片里是什么.对自动驾驶这种场景而言,对实时性地要求是很是高的.试想,从图片输入到模型,到模型识别出图片中前方有我的花了1分钟,你正以100km/h行驶,后果天然是灾难性的.
这就引出了推理引擎.model里的信息其实就是一些权重矩阵信息而已.输入图片数据后,进行一大堆的矩阵运算,获得最终图片的分类.推理引擎干的事情就是优化矩阵运算,缩短运算时间.

 

而tensorRT 则是对训练好的模型进行优化。 tensorRT就只是推理优化器。当你的网络训练完以后,能够将训练模型文件直接丢进tensorRT中,而再也不须要依赖深度学习框架(Caffe,TensorFlow等),以下:

能够认为tensorRT是一个只有前向传播的深度学习框架,这个框架能够将 Caffe,TensorFlow的网络模型解析,而后与tensorRT中对应的层进行一一映射,把其余框架的模型统一所有 转换到tensorRT中,而后在tensorRT中能够针对NVIDIA自家GPU实施优化策略,并进行部署加速。

TensorRT的核心就是一个深度学习的高性能C++的推理库, 基本适配主流的训练框架,如Tensorflow, Caffe, Pytorch, MXNet。

若是想了解更多关于tensorrt的介绍,可参考官网介绍

详细介绍参见这里

 

安装流程:

1.系统环境:cuda10.2 + cudnn7.6.5 ,Nvidia驱动安装版本为440.33,具体参见这里

2.须要的cuDNN的版本,须要时自行下载

3.TensorRT安装及配置步骤:

tar -zxvf TensorRT-7.0.0.11.Ubuntu-16.04.x86_64-gnu.cuda-10.2.cudnn7.6.tar.gz 
 
#解压获得TensorRT-7.0.0.11的文件夹,将里边的lib绝对路径添加到环境变量中
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/gavin/mysoft/TensorRT-7.0.0.11/lib
 
#安装TensorRT
cd TensorRT-7.0.0.11/python
#if python2
sudo pip2 install tensorrt-5.1.5.0-py2.py3-none-any.whl
#if python3
sudo pip3 install tensorrt-7.0.0.11-cp35-none-linux_x86_64.whl
 
#安装UFF
cd TensorRT-7.0.0.11/uff
#if python2
sudo pip2 install uff-0.6.5-py2.py3-none-any.whl
#if python3
sudo pip3 install uff-0.6.5-py2.py3-none-any.whl
 
#安装graphsurgeon
cd TensorRT-7.0.0.11/graphsurgeon
#if python2
sudo pip2 install graphsurgeon-0.4.1-py2.py3-none-any.whl
#if python3
sudo pip3 install graphsurgeon-0.4.1-py2.py3-none-any.whl

我的配置部分截图

 

测试:

python
import tensorflow
import tensorrt
import uff

不报错就对了。

 

下载相应版本的cuDNN

cuda卸载:

到CUDA9.0的目录下,找到卸载的文件

/usr/local/cuda-9.0/bin

sudo /usr/local/cuda-9.0/bin/uninstall_cuda_9.0.pl

这个过程须要一分钟左右,

sudo rm -rf /usr/local/cuda-9.0/

 

卸载cuDNN

打开终端,输入

sudo rm -rf /usr/local/cuda/lib64/libcudnn

sudo rm -rf /usr/local/cuda/include/cudnn.h

 

 

关系

  • onnx能够认为是一个文件协议(表示机器学习模型的开放标准), 许多框架(包括 TensorFlow、PyTorch、SciKit-Learn、Keras、Chainer、MXNet 和 MATLAB)中的模型均可以导出或转换为标准 ONNX 格式。 模型采用 ONNX 格式后,可在各类平台和设备上运行。能够支持不一样平台的CPU,GPU推理
  • tensortRT 是一个推理优化器,是一个C++库

目前pytorch比较成熟的方式:①trace 模型,而后 libtorch 前向 ② pytorch模型转到onnx模型,而后使用tensorrt部署;第二种部署方式更加有效率

 

TensorRT 为何能让模型加速跑?

模型加速愈来愈成为深度学习工程中的刚需了,最近的CVPR和ICLR会议中,模型的压缩和剪枝是受到的关注愈来愈多。毕竟工程上,算法工程师的深度学习模型是要在嵌入式平台跑起来,投入应用的。在模型的推理(inference)过程当中,计算速度是很重要的。好比自动驾驶,若是使用一个经典的深度学习模型,很容易就跑到200毫秒的延时,那么这意味着,在实际驾驶过程当中,你的车一秒钟只能看到5张图像,这固然是很危险的一件事。因此,对于实时响应比较高的任务,模型的加速时颇有必要的一件事情了。

若是你使用英伟达的产品,好比PX2,那么在平台上部署模型投入应用,不少时候就须要用到专门的模型加速工具 —— TensorRT。

TensorRT下的模型是在作什么?

TensorRT只负责模型的推理(inference)过程,通常不用TensorRT来训练模型的哈。

TensorRT能加速模型吗?

能!根据官方文档,使用TensorRT,在CPU或者GPU模式下其可提供10X乃至100X的加速。本人的实际经验中,TensorRT提供了20X的加速。

TensorRT为何能提高模型的运行速度?

TensorRT是英伟达针对自家平台作的加速包,TensorRT主要作了这么两件事情,来提高模型的运行速度。

  1. TensorRT支持INT8和FP16的计算。深度学习网络在训练时,一般使用 32 位或 16 位数据。TensorRT则在网络的推理时选用不了这么高的精度,达到加速推断的目的。
  2. TensorRT对于网络结构进行了重构,把一些可以合并的运算合并在了一块儿,针对GPU的特性作了优化。如今大多数深度学习框架是没有针对GPU作过性能优化的,而英伟达,GPU的生产者和搬运工,天然就推出了针对本身GPU的加速工具TensorRT。一个深度学习模型,在没有优化的状况下,好比一个卷积层、一个偏置层和一个reload层,这三层是须要调用三次cuDNN对应的API,但实际上这三层的实现彻底是能够合并到一块儿的,TensorRT会对一些能够合并网络进行合并。咱们经过一个典型的inception block来看一看这样的合并运算。

 

参考文献:

1.TensorRT安装及使用

2.tensorRT 7.0安装配置

相关文章
相关标签/搜索