TensorRTAPI开发手册

更新时间:2023-05-31 10:25:25 阅读: 评论:0

TensorRTAPI开发⼿册
第⼀章综述
NVIDIA的TensorRT是⼀个基于GPU⾼性能前向运算的C++库。TensorRT导⼊⽹络定义,通过合并tensors与layers,权值转换,选择⾼效中间数据类型,基于层参数与性能评估的选择,来进⾏⽹络优化。
TensorRT提供模型导⼊途径来帮助你对训练好的深度学习模型进⾏表⽰,同于TensorRT的优化与运⾏。这种优化⼯具⾃动进⾏图优化,层融合,并利⽤多样化的⾼度优化的计算核⼼寻找最快的模型实现⽅式。输出可以前向运算时可以运⾏这个⽹络的运⾏库。
TensorRT提供了⼀种基础能⼒,使得⽤户可以在Pascal与VoltaGPU上选择性进⾏快速多精度应⽤。TensorRT⽤gcc4.8进⾏编译。1.1 TensorRTLayers
TensorRT直接⽀持以下类型的层:
Activation
激活层通过逐像素激活函数实现。⽀持的激活类型包括,RELU,tanh与sigmoid.
BatchGemm
批矩阵相乘层实现了批矩阵的乘法运算。在矩阵相乘前矩阵可以进⾏转置。当维度不匹配的时候会进⾏适当的矩阵扩展。
Concatenation
连接层在通道维度上将宽⾼相同的tensors进⾏连接。
Constant
Constant层是⼀个提供本层参数的tensor,使得常量在计算时可以⽅便使⽤。
Convolution
Convolution层计算3D卷积(通道,⾼,宽),可选择是否使⽤偏置。
Deconvolution
Deconvolution层实现了去卷积运算,可选择是否使⽤偏置。
ElementWi
ElementWi层也叫做Eltwi层,实现了逐像素操作。⽀持加法,乘法,最⼤,减法,除法,指数运算。
Flatten
Flatten层在保持batch_size的同时,将输⼊转成⼀个向量。假设第⼀个维度表⽰batch⼤⼩。Flatten只能在全连接层前使⽤。
FullConnected
全连接层实现了矩阵向量积运算,可选择是否使⽤偏置。部门划分
Gather
Gather层实现了聚集操作,将⼀个数据tensor,⼀个索引tensor,⼀个数据tensor axis作为输⼊,利⽤索引index将数据tensor重建索引。当前,只有TensorRT C++API⽀持。
LRN
LRN层实现跨通道局部响应归⼀化。
MartrixMultipy
矩阵乘法层实现了⼀系列的矩阵相乘运算。在乘法运算前可以选择是否将矩阵转置。当维度不匹配的时候会进⾏适当的矩阵扩展。
Padding
Padding层实现了tensors的空间0扩展。Padding可以是不同维度,不对称的,也可以是正的(tensor扩展结果),或者负的(均值结果)。
Plugin
Plugin层允许⽤户实现原⽣TensorRT不⽀持的层。
Pooling
微风席席Pooling层在通道维度实现池化操作。⽀持最⼤池化与均值池化。
Ragged SoftMax
Ragged SoftMax实现了包含不同长度序列tensor的跨通道的Softmax。序列的长度利⽤另外⼀个tenso
r输⼊。
Reduce
Reduce使⽤降维算法实现了tensors降维操作。降维运算⽀持像素相乘,最⼤,最⼩,平均。⽬前只有TensorRT的C++API⽀持这个层。
RNN
这个层在RNNV2层出现后已经弃⽤了,然⽽还是向下兼容。
RNNv2
RNNv2实现了类似递归神经⽹络,GRU,LSTM这样的递归层。当前⽀持RNN,GPU,LSTM。
Scale
Scale层实现了逐tensor,逐通道,逐权重的仿射变换,与或运算,以及常数幂运算。
Shuffle
Shuffle层⽤来实现tensors得重新排序,可以⽤来进⾏reshape或者数据转换。
SoftMax
SoftMax实现了跨通道的softmax。
Squeeze
Squeeze层将tensor中维度为1的shape。
TopK
TopK层在⼀个维度中寻找TopK元素,返回降维的tensor,与⼀个位置索引的tensor。
Unary
Unary⽀持元素级的⼀元操作。⽀持exp,log,sqrt,recip,abs与neg操作。
注:
BatchNormalization可以利⽤TensorRT的Scale层实现。
卷积层进⾏的操作实际上是相关操作。这样主要是考虑通过TensorRT API导⼊权重,⽽不是通过NVCaffe解析库。
1.2 关键概念
确保你对⼀下关键概念熟悉:
⽹络结果定义(Network definition)
⽹络定义有由⼀系列层与tensors集组成。
层(layer)
每个层根据⼀系列输⼊tensors计算输出的tensors。层具有⼀些参数,例如convolution size,stride,filter wights。
Tensor
Tensor既可以是⽹络的输⼊,也可以是输出。Tensors通过数据类型(data-type)来指定精确度,例如16-bit float或者32bit float。Tensors有三个维度,例如通道(channels),宽(weight),⾼(height)。输⼊tensors的维度由应⽤决定,输出的tensor维度由builder推理出来。⽀持的维度是N(P_1,P_2,P_3)CHW格式,其中P_1,P_2等是索引维。Tensors最多可以有
Dims::MAX_DIMENSIONS维度,设为常量8。
Tensors在batch间可见。这样的tensor的batchsize维度(公式中为N)为1,不管⽹络在运⾏的时候batchsize多⼤。所以,当这个tensor是输⼊的时候,他会独⽴于batchsize。适当的时候使⽤的是标准的⼴播(broadcasting)规则。
输⼊tensor是否在batch间⼴播取决于⽹络定义,输出tensor则取决于builder。在确保build过程batch中每个元素数据的前提下,builder 会将⼴播中间与输出tensors。所以batch间⼴播的操作往往会产⽣tensor在batch间⼴播的效果。例如,运算将在⼴播前进⾏,⼴播将推到运算链⾥。如果整个操作链都在没有⼴播的状态下实现,输出的tensor可能作为⼀个batch间⼴播的掩模,意味着是否在batch间⼴播取决于应⽤需求。
在读写batch间⼴播的tensor对应内存的时候,需要有些特别注意的问题。不管在运⾏是⽹络的batchsize是多少,数据都是按照batchsize 等于1排列的。因此,batch间共享的tensors⽐由N个相同数据副本对应N各batch元素的tensors会更加节省内存。
每个层与tensor都有⼀个名字,这些名字在解析或者读取TensorRT⽣成⽇志的时候有⽤。
当使⽤NvCaffeParr时,tensor与layer的名字是根据NVCaffe的prototxt⽂件命名。
数据类型(DataType)
Tensors⽀持的有效数据类型是Kfloat,Khalf,Kint8与Kint32。对于⽹络输⼊来说,需要在设置⽹络输⼊时指定数据类型。其它的tensors 类型可以通过tensor中的tType⽅式实现。输⼊与输出不能是kINT8类型。kINT32表⽰索引值,Kint8表⽰编码成8bit的浮点值。详见SampleINT8-Calibration 与8-bit Inference,取得更多有关8-bit整形的inference性能。
Broadcasting
Broadcasting当两个tensor间维度不匹配时起作⽤。当两个tensor同个索引的维度长度不等,并且其中⼀个tensors维度是1,这时broadcasting⼯作。假设两个tensor,⼀个为(N,1,H,W)⼀个为(1,C,H,W),第⼆个tensor在batch维度broadcastN次,第⼀个tensor在channel维度broadcastC次,得到(N,C,H,W)。不是所有层都⽀持Broadcasting。取得更多NumPy中broadcasting的意义,见Braodcasting。
1.3 TensorRT API’s
周记50字左右
TensorRT API允许开发者导⼊,校验,⽣成与部署优化⽹络。⽹络可以直接通过NVCaffe或者其他⽀持UFF与ONNX格式的框架。也可以通过编程的⽅式,导⼊每层与相关参数与权重。
除了主要的C++接⼝外,TensorRT还带有python接⼝。TensorRT的python接⼝当前⽀持所有功能。接
⼝通过NumPy格式引⼊层权重,通过PyCUDA引⼊输⼊输出数据。还提供了⼀系列公共函数来解决开发过程中可能会遇到的类似解析NVCaffe模型⽂件,从流中解析UFF 模型,从UFF⽂件中读写PLAN⽂件这样的公共问题。这些功能都在tensorrt.utils中实现。
在tensorrt/examples/custom_layers中有python进⾏⽤户⾃实现层的例⼦。
注:
女生最吃香的十大专业
要使⽤户可以在python接⼝中使⽤⾃⼰的C++实现,还需要⼀些额外的依赖项,例如swig>=3.0,libnvinfer-dev。
1.3.1 Python Samples
Python接⼝⽀持之前只有C++接⼝⽀持的所有功能,包括:
NvCaffeParr
NvUffParr(TensorFlow)
NvONNXParr(Open Neural Network Exchange)
⽤于图定义的nvinfer API’s
⽤于建⽴⾼效前向引擎的builder
⽤于执⾏的前向运算引擎
逆作法⽤于注册⾃实现层的接⼝
⽤户可以在{PYTHON_PACKAGE_DIR}/tensorrt/examples中找到python⽰例。
TensorRT包⾃带⼀对⽰例应⽤实现。如果是TensorRT安装到系统中则可以找到。
Table1 应⽤例程位置
想了解更多⽤python将模型导⼊到TensorRT中,请参考NVCaffe Python Workflow,TensorFlow Python Workflow, and Converting A Model From An UnsupportedFramework To TensorRT With The TensorRT Python API。
1.3.2 Python Workflows
Python是⼀种流⾏并且通常再数据科学⾮常⾼效的语⾔并且再许多深度学习框架中都有使⽤。这⾥提
供⼀下⼏种情况的使⽤⽤例
有⼀个ONNX格式的模型,TensorRT包含了ONNX解析器,使得我们可以直接将模型加载到tensorRT中。
有⼀个TensorFlow模型,使⽤者希望使⽤TensorRT调⽤。
将TensorFlow模型转为TensorRT格式
有⼀个NvCaffe模型,希望使⽤TensorRT调⽤。
将NVCaffe模型转为TensorRT格式。
开发者希望将TensorRT引擎作为像⽹站后端这样⼤规模的应⽤。
开发者希望TensorRT调⽤当前UFF不⽀持的训练框架训练的模型或者⾮NVCaffe训练出来的模型。
如需了解以上⽤例的详细步骤,请看NVCaffe Workflow,TensorFlow Workflow, andConverting A Model From An Unsupported Framework To TensorRT With The TensorRTPython API.
2. TensorRT初始化
什么是社会主义核心价值观有两种⽅式初始化TensorRT:
1、创建IBuilder对象去优化⽹络
2、创建IRuntime对象执⾏⼀个被优化的⽹络
这两种⽅式,你都需要先实现⼀个logging interface(⽇志接⼝),TensorRT会通过这个接⼝进⾏报错、警告和消息提⽰
class Logger : public ILogger
{
void log(Severity verity, const char* msg) override
{
//不提⽰INFO信息,只显⽰警告和错误
if (verity != Severity::kINFO)
{
std::cout << msg << std::endl;
}
}
}gLogger;
历史人物故事有哪些注意:你可能会创建很多的IBuilder和IRuntime,但是logger是⼀个单例
1.2 在C++中创建⼀个⽹络定义
使⽤tensorRT的第⼀步就是从你的model中创建⼀个tensorRT的⽹络定义
可以从别的深度学习框架中进⾏导⼊,现在⽀持:
1、Caffe(both BVLC)
2、ONNX
3、UFF(ud for tensorflow)
同样也可以使⽤TensorRT API直接构造模型,但是需要在⽹络层中使⽤少量API定义每⼀层,并且实现⾃⼰导⼊参数机制,来导⼊已经训练完毕的模型参数
在以上的⽅式你必须明确告诉tensorRT哪些张量是输出,因为被确定为输出的张量不会因为采取加速⽽被builder进⾏优化。
输⼊和输出张量都需要进⾏命名(使⽤ITensor::tName())
同时推理的时候,需要为引擎提供输⼊和输出的buff缓存指针
还有对于tensorRT⽹络定义很重要的⼀个⽅⾯,就是包含指向模型权重的指针,它会被builder拷贝到优化引擎⾥
注意:如果⽹络定义是从语法中创建的,解析器占⽤权重的内存,因此解析器在builder运⾏前都不能被删除
1.3 在C++使⽤解析器导⼊⼀个模型
使⽤C++解析器导⼊你需要遵循以下的步骤:
1、创建TensorRT的builder和network
2、为特殊的格式创建TensorRT的解析器
3、使⽤解析器解析导⼊的模型并填充⽹络
注意:builder必须在network之前创建,因为builder是network的⼯⼚;不同的解析器有不同的机制来标记⽹络输出。
1.3.1 导⼊caffe模型
//1、创建builder和network
IBuilder* builder = createInferBuilder(gLogger);
INetworkDefinition* network = builder->createNetwork();
//2、创建caffe的解析器
ICaffeParr* parr = createCaffeParr();
休息用英语怎么说
//3、使⽤解析器导⼊模型
const IBlobNameToTensor* blobNameToTensor = parr->par("deploy_file" ,"modelFile", *network, DataType::kFLOAT);
//4、指定模型的输出
for (auto& s : outputs)
network->markOutput(*blobNameToTensor->find(s.c_str()));
注意:
最后的参数表⽰解析器会⽣成⼀个32位浮点数的⽹络,使⽤DataType::kHALF表⽰会⽣成16位浮点数的模型⽹络(原⽂如下:The final argument instructs the parr to generate a network who weights are 32-bit floats. Using DataType::kHALF would generate a model with 16-bit weights instead)

本文发布于:2023-05-31 10:25:25,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/819655.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:实现   模型   运算   维度   输出
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图