1. ONNX的简介
Open Neural Network Exchange(ONNX,开放神经网络交换)格式,是一个用于表示深度学习模型的标准,可使模型在不同框架之间进行转移(一般用于中间部署阶段)。
目前官方支持加载ONNX模型并进行推理的深度学习框架有: Caffe2,PyTorch,MXNet,ML.NET,TensorRT 和 Microsoft CNTK,并且 TensorFlow 也非官方的支持ONNX。
使用tensorrt的一般步骤
主要先是构建(bulid),之后是部署(development)
Build:该阶段主要完成模型转换(从caffe或TensorFlow到TensorRT),如下图所示,在模型转换时会完成前述优化过程中的层间融合,精度校准。这一步的输出是一个针对特定GPU平台和网络模型的优化过的TensorRT模型,这个TensorRT模型可以序列化存储到磁盘或内存中。存储到磁盘中的文件称之为 planfile。
Deploy:该阶段主要完成推理过程,如下图所示。将上一个步骤中的plan文件首先反序列化,并创建一个 runtime engine,然后就可以输入数据(比如测试集或数据集之外的图片),然后输出分类向量结果或检测结果。
以onnx模型为例检测介绍,主要分为3步,如下图所示,第一步是导入模型,这包括从磁盘上保存的文件加载模型,并将其从原始框架转换为TensorRT网络。ONNX是表示深度学习模型的标准,使它们能够在框架之间传输(Caffe2、Chainer、CNTK、paddle、PyTorch和MXNet都支持ONNX格式)。接下来,基于输入模型、目标GPU平台和指定的其他配置参数,构建一个优化的TensorRT引擎。最后一步是向TensorRT引擎提供输入数据以执行推理。
需要用的tensorrt的组件如下:
- ONNX解析器:以ONNX格式的经过训练的模型作为输入,并用TensorRT填充网络对象
- Builder:在TensorRT中获取一个网络并生成一个为目标平台优化的引擎
- Engine:获取输入数据,执行推理并发出推理输出
- Logger:与生成器和引擎关联的对象,用于在生成和推断阶段捕获错误、警告和其他信息
构架引擎步骤三部曲
创建bulider
,
通过builder创建一个空的TensorRT网络(Net)network()
构建一个onnx的解析器parser
。
with trt.Builder(TRT_LOGGER) as builder, \ builder.create_network() as network,\ trt.OnnxParser(network, TRT_LOGGER) as parser:
builder介绍
builder功能之一是搜索cuda内核目录,找到最快的cuda以求获得最快的实现,因此有必要使用相同的GPU进行构建(相同的操作,算子进行融合,减少IO操作),engine就是在此基础上运行的,builder还可以控制网络以什么精度运行(FP32,FP16,INT8),还有两个特别重要的属性是最大批处理大小和最大工作空间大小。
builder.max_workspace_size = 1<< 30 builder.max_batch_size = max_batch_size
它的作用是给出模型中任一层能使用的内存上限。运行时,每一层需要多少内存系统分配多少,并不是每次都分 1 GB,但不会超过 1 GB。 就是 2^30 bytes 即 1 GB。
默认使用FP32加速,即只是图优化等操作,不进行量化或降精度。设置FP16和int9_mode十分简单,一行代码即可:
builder.fp16_mode = fp16_mode # Default: False builder.int8_mode = int8_mode # Default: False
判断是否有parse model文件(onnx)
if not os.path.exists(onnx_file_path): quit('ONNX file {} not found'.format(onnx_file_path)) print('Loading ONNX file from path {}...'.format(onnx_file_path))
正常输出为
Loading ONNX file from path ./model.onnx... • 1
开始onnx的文件解析
with open(onnx_file_path, 'rb') as model: print('Beginning ONNX file parsing') parser.parse(model.read()) #for each_line in model: #可以打印出来观看及鞥 #print(each_line)
对注释部分的打印结果描述是:
Beginning ONNX file parsing b'\x08\x04\x12\x07pytorch\x1a\x031.2:\xdc\xcb\x06\n' b'\x8a\x01\n' b'\x05input\n' b'\rlayer1.weight\n' b'\x0blayer1.bias\x12\x017"\x04Conv*\x12\n' b'\tdilations@\x01@\x01\xa0\x01\x07*\x0c\n' b'\x05group\x18\x01\xa0\x01\x02*\x15\n' b'\x0ckernel_shape@\x03@\x03\xa0\x01\x07*\x11\n' b'\x04pads@\x00@\x00@\x00@\x00\xa0\x01\x07*\x10\n' b'\x07strides@\x01@\x01\xa0\x01\x07\n' b'\x0c\n' b'\x017\x12\x018"\x04Relu\n' b'K\n' b'\x018\x12\x019"\x07MaxPool*\x15\n' b'\x0ckernel_shape@\x03@\x03\xa0\x01\x07*\x11\n' b'\x04pads@\x00@\x00@\x00@\x00\xa0\x01\x07*\x10\n' b'\x07strides@\x01@\x01\xa0\x01\x07\n' b'\x87\x01\n' ......................后面还有很多......................结束
已经完成onnx文件解析,
print('Completed parsing of ONNX file') print('Building an engine from file {}; this may take a while...'.format(onnx_file_path))
输出结果
Completed parsing of ONNX file Building an engine from file ./model.onnx; this may take a while...