Tensorrt学习笔记--Tensorrt的基本知识

TensorRT流程简介和支持Parser

可以分三个步骤,即模型的解析(Parser),Engine优化和执行(Execution)。
模型解析后,engine会进行优化,具;得到优化好的engine可以序列化到内存(buffer)或文件(file),读的时候需要反序列化,将其变成engine以供使用;然后在执行的时候创建context,主要是分配预先的资源,engine加context就可以做推断(Inference)。

tensorrt支持三种Parser,分别是
Caffe Parser
This parser can be used to parse a Caffe network created in BVLC Caffe or NVCaffe 0.16. It also provides the ability to register a plugin factory for custom layers.
UFF Parser
This parser can be used to parse a network in UFF format. It also provides the ability to register a plugin factory and pass field attributes for custom layers.
ONNX Parser
This parser can be used to parse an ONNX model.

下面是使用tensorrt的一般流程,分为使用C++和Python两个不同的操作方式,这里展示的是C++的流程

2.2 Creating A Network Definition In C++

Importing A TensorFlow Model Using The C++ UFF Parser API

  • 首先将tensorflow模型转成uff格式, convert the TensorFlow model into intermediate format UF
  • Create the builder and network:
IBuilder* builder = createInferBuilder(gLogger);
INetworkDefinition* network = builder->createNetwork();
  • Create the UFF parser:
IUFFParser* parser = createUffParser();
  • Declare the network inputs and outputs to the UFF parser:
parser->registerInput("Input_0", DimsCHW(1, 28, 28), UffInputOrder::kNCHW);
parser->registerOutput("Binary_3")
  • Parse the imported model to populate the network:
 parser->parse(uffFile, *network, nvinfer1::DataType::kFLOAT);

2.3. Building An Engine In C++

Build the engine using the builder object

builder->setMaxBatchSize(maxBatchSize);
IBuilderConfig * config = builder->createBuilderConfig();
config->setMaxWorkspaceSize(1 << 20);
ICudaEngine* engine = builder->buildEngineWithConfig(*network, *config);

Dispense with the network, builder, and parser if using one

parser->destroy();
network->destroy();
config->destroy();
builder->destroy();

2.4. Serializing A Model In C++

It is not absolutely necessary to serialize and deserialize a model before using it for inference – if desirable, the engine object can be used for inference directly.

Run the builder as a prior offline step and then serialize:

IHostMemory *serializedModel = engine->serialize();
// store model to disk
// <>
serializedModel->destroy();

Create a runtime object to deserialize:

IRuntime* runtime = createInferRuntime(gLogger);
ICudaEngine* engine = runtime->deserializeCudaEngine(modelData, modelSize, nullptr);

TensorRT的优化内容

总结下来主要有这么几点:

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

第二,比如在concat这一层,比如说这边计算出来一个1×3×24×24,另一边计算出来1×5×24×24,concat到一起,变成一个1×8×24×24的矩阵,这个叫concat这层这其实是完全没有必要的,因为TensorRT完全可以实现直接接到需要的地方,不用专门做concat的操作,所以这一层也可以取消掉。

第三,Kernel可以根据不同的batch size 大小和问题的复杂程度,去选择最合适的算法,TensorRT预先写了很多GPU实现,有一个自动选择的过程。

第四,不同的batch size会做tuning。

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

Tensort中的INT8推断

对于INT8 推断(Inference),需要生成一个校准表来量化模型。接下来主要关注INT8推断(Inference)的几个方面,即:如何生成校准表,如何使用校准表,和INT8推断(Inference)实例。

1) 如何生成校准表?

校准表的生成需要输入有代表性的数据集, 对于分类任务TensorRT建议输入五百张到一千张有代表性的图片,最好每个类都要包括。生成校准表分为两步:第一步是将输入的数据集转换成batch文件;第二步是将转换好的batch文件喂到TensorRT中来生成基于数据集的校准表,可以去统计每一层的情况

2) 如何使用校准表?

3)INT8推断(Inference)实例

未完待续

https://docs.nvidia.com/deeplearning/sdk/tensorrt-developer-guide/index.html#serial_model_c

你可能感兴趣的:(模型压缩与加速,计算机视觉,深度学习,深度学习)