1. TensorRT简要介绍
TensorRT(NVIDIA TensorRT)是 NVIDIA 开发的一个用于深度学习推理的高性能推理引擎。它可以针对 NVIDIA GPU 进行高效的深度学习推理加速,提供了许多优化技术,使得推理速度更快,并且可以在生产环境中部署。
下面是 TensorRT 的一些主要特点和功能:
高性能推理:TensorRT 使用了许多优化技术,包括网络剪枝、量化、层融合、内存优化等,以提高推理速度和效率。这使得 TensorRT 能够在现代 NVIDIA GPU 上实现高性能的深度学习推理。
多平台支持:TensorRT 提供了多个版本,可以在各种 NVIDIA GPU 上运行,并且支持多种操作系统,包括 Linux 和 Windows。它还提供了 Python API 和 C++ API,以满足不同开发环境和需求。
灵活的部署选项:TensorRT 提供了多种部署选项,可以满足不同的部署需求。它可以作为独立的推理引擎使用,也可以与其他深度学习框架集成,例如 TensorFlow、PyTorch 等。
支持常见的深度学习模型:TensorRT 支持常见的深度学习模型,包括卷积神经网络(CNN)、循环神经网络(RNN)、长短期记忆网络(LSTM)等。它还支持各种网络层,如卷积层、池化层、全连接层等。
优化技术:TensorRT 提供了多种优化技术,包括网络剪枝、权重量化、层融合、内存优化等。这些优化技术可以显著提高推理速度,并降低内存消耗。
2. PyTorch到TensorRT
PyTorch已经成为最流行的训练框架之一。
那么如何将PyTorch训练所得到的权重文件部署到TensorRT中呢?
一般情况下有两种方式可以实现。
一种是通过将PyTorch训练的权重转换成为ONNX格式,然后通过TensorRT的OnnxParser推理,或者经过trtexec转换成为tensorrt的engine,然后跨平台推理。
另一种方式是使用INetworkDefinition自行构建网络,生成tensorrt的engine,然后进行推理。
前一种方式较为简洁,后一种方式较为复杂,需要对网络非常了解,对网络构建非常明晰。
本序列课程将基于INetworkDefinition进行网络构建,讲解基于TensorRT的神经网络推理。
3. 初始构建
首先需要明确一点,TensorRT是基于NCHW的Tensor模式。
TensorRT的网络推理分为两个部分,首先是构建引擎,然后才可以使用引擎进行推理。
当然也可以分成一部分,但是为了节省推理时间,我们通常会将构建的因为那个文件序列化,保存在本地,之后在每次推理的时候,反序列化、加载引擎,进行推理。
初始构建的时候,需要先构建一个INetworkDefinition的对象,并且构建输入数据,参考如下。
INetworkDefinition *network = builder->createNetworkV2(1U);ITensor *data = network->addInput(mInputBlobName, dt, mInputDims);
其中,
mInputBlobName是一个字符串,标识输入Tensor节点的名字。
dt是一个DataType类型的变量,顾名思义,它用来标识输入Tensor的类型。
mInputDims是一个Dims类型的数据,用来表示输入Tensor的Dimension信息。
通过以上两行代码,我们看到了构建了一个空的网络。
4. 添加一个简单的卷积层
前面我们已经知道了如何构建一个空“网络”,那么我们接着添加一个卷积层,组成一个只有一层卷积的卷积神经网络。
IConvolutionLayer *conv1 = network->addConvolutionNd(input, outch, DimsHW{ksize, ksize}, weightMap[lname + ".conv.weight"], emptywts);assert(conv1);conv1->setName((lname+".conv").data());conv1->setStrideNd(DimsHW{s, s});conv1->setPaddingNd(DimsHW{p, p});conv1->setNbGroups(g);
以上演示了在“网络”中添加卷积层。但这样我们比较繁琐,我们最好能够将卷积层进行封装。
ILayer *convBlock(INetworkDefinition *network, std::map<std::string, Weights> &weightMap, ITensor &input, int outch, int ksize, int s, int g, std::string lname, bool act){Weights emptywts{DataType::kFLOAT, nullptr, 0};int p = ksize / 3;IConvolutionLayer *conv1 = network->addConvolutionNd(input, outch, DimsHW{ksize, ksize}, weightMap[lname + ".conv.weight"], emptywts);assert(conv1);conv1->setName((lname+".conv").data());conv1->setStrideNd(DimsHW{s, s});conv1->setPaddingNd(DimsHW{p, p});conv1->setNbGroups(g);IScaleLayer *bn1 = addBatchNorm2d(network, weightMap, *conv1->getOutput(0), lname + ".bn", 1e-3);bn1->setName((lname+".bn").data());if(!act){return bn1;}// silu = x * sigmoidauto sig = network->addActivation(*bn1->getOutput(0), ActivationType::kSIGMOID);assert(sig);auto ew = network->addElementWise(*bn1->getOutput(0), *sig->getOutput(0), ElementWiseOperation::kPROD);assert(ew);return ew;}
OK,今天主要是作为TensorRT教程的开端,并构建一个简单的,只有一层卷积的神经网络。后续我们将继续深入探索。