Nvidia TensorRT文档——开发者指南

摘要

该TensorRT 7.2.1开发者指南演示了如何使用C ++和Python API来实现常见的深度学习层。 它显示了如何采用现有深度学习框架构建模型,并通过提供的解析器把该模型构建为TensorRT引擎。 开发者指南还提供了针对常见任务的分步说明,例如创建TensorRT网络定义,调用TensorRT构建器,序列化和反序列化以及如何向引擎提供数据和执行推理; 可以使用C ++或者Python API。

1.什么是TensorRT

NVIDIA®TensorRT™的核心是一个C ++库,可促进对NVIDIA图形处理单元(GPU)的高性能推断。 它旨在与TensorFlow,Caffe,PyTorch,MXNet等训练框架以互补的方式工作。它专门致力于在GPU上快速有效地运行已经训练好的网络,以生成结果(该过程在其他地方有可能被称为评分,检测,回归或推断)。

一些训练框架(例如TensorFlow)已经集成了TensorRT,因此可以将其用于框架内加速推理。 另外,TensorRT可以用作用户应用程序中的库。 它包括用于从Caffe,ONNX或TensorFlow导入现有模型的解析器,以及用于以编程方式构建模型的C ++和Python API。

图1. TensorRT是用于生产部署的高性能神经网络推理优化器和运行时引擎

TensorRT通过组合层和优化核选择来优化网络,以改善延迟,吞吐量,能效和内存消耗。另外,在应用程序指定的情况下,它将使其以较低的精度运行来优化网络,从而进一步提高性能并减少内存需求。

下图显示TensorRT定义为部分高性能推理优化器和部分运行时引擎。 它可以吸收在这些流行框架上训练过的神经网络,优化神经网络计算,生成轻量级运行时引擎(这是您唯一需要部署到生产环境中的东西),然后它将使这些GPU平台上的性能,吞吐量和延迟最大化(???)。

图2. TensorRT是可编程的推理加速器

TensorRT API包括最常见的深度学习层的实现。有关深度学习层的更多信息,请参见TensorRT层。 您还可以使用C ++插件API或Python插件API为当前TensorRT不支持的那些不常用或更具创新性的层提供实现。

1.1.TensorRT的好处

在训练了神经网络之后,TensorRT使网络可以作为运行时进行压缩,优化和部署,而无需框架的开销。

TensorRT根据指定的精度(FP32,FP16或INT8)组合层,优化核选择以及执行规范化和转换为优化的矩阵数学运算,以改善延迟,吞吐量和效率。

对于深度学习推理,有五个用于衡量软件的关键因素:

  • 吞吐量
    给定时间段内的产出量。 每台服务器的吞吐量通常以推断/秒或样本/秒来衡量,对于数据中心的经济高效扩展至关重要。
  • 效率
    每单位功率交付的吞吐量,通常表示为性能/瓦特。效率是经济高效地扩展数据中心的另一个关键因素,因为服务器,服务器机架和整个数据中心必须在固定的功率预算内运行。
  • 延迟
    执行推理的时间,通常以毫秒为单位。低延迟对于提供快速增长的基于实时推理的服务至关重要。
  • 准确性
    训练好的神经网络能够提供正确答案。 对于图像分类算法,关键指标为top-5或top-1。
  • 内存使用情况
    需要保留以在网络上进行推理的主机和设备内存取大小决于所使用的算法。这限制了哪些网络以及网络的哪些组合可以在给定的推理平台上运行。这对于需要多个网络且内存资源有限的系统尤其重要,例如,在智能视频分析和多摄像机,多网络自动驾驶系统中使用的级联多级检测网络。

使用TensorRT的替代方法包括:

  • 使用训练框架本身执行推断。
  • 编写专门设计用于使用低级库和数学运算来执行网络的自定义应用程序。

使用训练框架执行推理很容易,但是与使用TensorRT之类的优化解决方案相比,相同GPU上的性能往往低得多。训练框架倾向于实施强调通用性的通用代码,而当优化它们时,优化往往集中于有效的训练。
通过编写仅用于执行神经网络的自定义应用程序可以获得更高的效率,但是,这可能会非常费力,并且需要大量专业知识才能在现代GPU上达到较高的性能水平。此外,在一个GPU上进行的优化可能无法完全转换为同一系列中的其他GPU,并且每一代GPU都可能引入只能通过编写新代码来利用的新功能。

TensorRT通过结合抽象出特定硬件细节的高级API和优化推理的实现来解决这些问题,以实现高吞吐量,低延迟和低设备内存占用。

1.1.1.谁可以从TensorRT中受益

TensorRT供负责基于新的或现有的深度学习模型构建功能和应用程序或将模型部署到生产环境中的工程师使用。这些部署可能部署在数据中心或云服务器,嵌入式设备,机器人或车辆或将在您的工作站上运行的应用程序软件中。

TensorRT已在各种场景中成功使用,包括:

  • 机器人
    公司出售使用TensorRT来运行各种计算机视觉模型的机器人,以自动引导在动态环境中飞行的无人机系统。
  • 自动驾驶汽车
    TensorRT用于支持NVIDIA Drive产品中的计算机视觉。
  • 科技计算
    TensorRT嵌入了一种流行的计算软件包技术,可实现神经网络模型的高吞吐量执行。
  • 深度学习训练和部署框架
    TensorRT包含在几种流行的深度学习框架中,包括TensorFlow和MXNet。有关TensorFlow和MXNet容器发行说明,请参阅TensorFlow发行说明和MXNet发行说明。
  • 视频分析
    NVIDIA DeepStream产品中使用TensorRT在边缘(具有1-16个摄像机源)和数据中心(可能聚集数百甚至数千个视频源)中为复杂的视频分析解决方案提供支持。
  • 自动语音识别
    TensorRT用于在小型台式/台式设备上支持语音识别。设备上支持有限的词汇表,而云中提供了更大的词汇表语音识别系统。

1.2.TensorRT适合哪里?

通常,用于开发和部署深度学习模型的工作流经历三个阶段。

  • 第一阶段是训练
  • 第二阶段是开发部署解决方案
  • 第三阶段是该解决方案的部署

阶段1:训练

在训练阶段,数据科学家和开发人员将首先说明他们要解决的问题,并确定将使用的精确输入,输出和损失函数。他们还将收集,整理,扩充并可能打标训练,测试和验证数据集。 然后他们将设计网络结构并训练模型。在训练期间,他们将监控学习过程,该过程可能会提供反馈,这将导致他们修改损失函数,获取或增加训练数据。在此过程结束时,他们将验证模型性能并保存经过训练的模型。训练和验证通常使用DGX-1™,Titan或Tesla数据中心GPU进行。

在训练阶段的任何阶段通常都不会使用TensorRT。

阶段2:开发部署解决方案

在第二阶段中,数据科学家和开发人员将从训练好的模型开始,并使用该训练好的模型创建和验证部署解决方案。将这一阶段分解为若干步骤:

  • 考虑一下神经网络在更大的系统中是如何工作的,并设计和实现适当的解决方案。可能包含神经网络的系统范围千差万别。示例包括:
    车辆中的自动驾驶系统
    公共场所或公司校园中的视频安全系统
    消费者设备的语音接口
    工业生产线自动化质量保证系统
    提供产品推荐的在线零售系统
    提供娱乐筛选器的消费者Web服务,用户可以将其应用于上载的图像。

    确定您的优先事项。考虑到您可以实现的不同系统的多样性,在设计和实现部署体系结构时可能需要考虑很多因素:
    您有一个或多个网络?例如,您是否在开发基于单个网络的功能或系统(人脸检测),或者您的系统也不是由不同模型的混合或级联组成,或者可能不是由更广泛的,可以提供收集模型的设施所组成?由最终用户提供?
    您将使用什么设备或计算元素来运行网络? CPU,GPU或其他?如果模型要在GPU上运行,它是单一类型的GPU,还是您需要设计一个可以在各种GPU上运行的应用程序?
    数据如何到达模型?什么是数据管道?数据是来自照相机或传感器,来自一系列文件,还是通过网络连接上传?
    将进行哪些预处理?数据将以什么格式输入?如果是图像,是否需要裁剪,旋转?如果是文本,它是什么字符集?是否允许所有字符作为模型的输入?是否有特殊令牌?
    您将有什么延迟和吞吐量要求?
    您可以将多个请求一起批处理吗?
    您是否需要一个网络的多个实例来实现所需的整体系统吞吐量和延迟?
    您将如何处理网络的输出?
    需要哪些后处理步骤?

    TensorRT提供了一个快速,模块化,紧凑,健壮,可靠的推理引擎,可以支持部署架构内的推理需求。

  • 数据科学家和开发人员定义了推理解决方案的体系结构,从而确定优先级之后,他们便使用TensorRT从保存的网络中构建了推理引擎。有多种方法可以执行此操作,具体取决于所使用的训练框架和网络体系结构。通常,这意味着您需要使用已保存的神经网络,并使用ONNX解析器(请参见图3左侧),Caffe解析器或UFF解析器将其从其保存的格式解析为TensorRT。


    图3. ONNX Workflow V1
  • 解析网络后,请考虑优化选项-批处理大小,工作空间大小,混合精度以及动态形状上的边界,这些选项是在TensorRT构建步骤中选择和指定的,您可以在其中基于网络构建优化的推理引擎。本指南的后续部分提供了详细说明和工作流这一部分的许多示例,将您的模型解析为TensorRT并选择优化参数(请参见图3)。

  • 使用TensorRT创建推理引擎后,您需要验证它是否可以重现训练过程中测得的模型结果。如果选择了FP32或FP16,则它应与结果非常接近。如果您选择了INT8,则在训练过程中获得的准确度与推理准确度之间可能会有很小的差距。

  • 以序列化格式写出推理引擎。 这也称为计划文件。

阶段3:部署解决方案

TensorRT库将被链接到部署应用程序,部署应用程序在需要推断结果时将调用该库。要初始化推理引擎,应用程序将首先将模型从计划文件中反序列化为推理引擎。
TensorRT通常异步使用,因此,当输入数据到达时,程序将使用输入缓冲区和TensorRT将结果放入的缓冲区调用入队函数。

1.3.TensorRT怎样工作?

为了优化推理模型,TensorRT会采用您的网络定义,执行包括平台特定的优化在内的优化,并生成推理引擎。此过程称为构建阶段。构建阶段可能会花费大量时间,尤其是在嵌入式平台上运行时。 因此,典型的应用程序将只构建一次引擎,然后将其序列化为计划文件以供以后使用。
注意:生成的计划文件不能跨平台或TensorRT版本移植。 计划特定于其所构建的确切GPU模型(除了平台和TensorRT版本),并且如果您想在其他GPU上运行它们,则必须将其重新定位到特定的GPU。

构建阶段对层图执行以下优化:

  • 消除输出不被使用的图层
  • 消除等同于无操作的操作
  • 卷积,偏置和ReLU操作的融合
  • 汇总具有足够相似的参数和相同的源张量的操作(例如,GoogleNet v5的初始模块中的1x1卷积)
  • 通过将层输出定向到正确的最终目的地来合并串联图层。

必要时,构建器还可以修改权重的精度。当生成8位整数精度的网络时,它使用称为校准的过程来确定中间激活的动态范围,从而确定适当的用于量化的缩放因子。

此外,构建阶段还会在虚拟数据上运行各层,以从其核目录中选择最快的核,并在适当的情况下执行权重预格式化和内存优化。

有关更多信息,请参见使用混合精度。

1.4.TensorRT提供哪些功能?

TensorRT使开发人员能够导入,校准,生成和部署优化的网络。网络可以直接从Caffe导入,也可以通过UFF或ONNX格式从其他框架导入。也可以通过实例化各个图层并直接设置参数和权重以编程方式创建它们。

用户还可以使用插件接口通过TensorRT运行自定义层。 GraphSurgeon实用程序提供了将TensorFlow节点映射到TensorRT中的自定义层的功能,从而可以使用TensorRT对许多TensorFlow网络进行推理。

TensorRT在所有支持的平台上提供C++实现,并在x86,aarch64和ppc64le上提供Python实现。

TensorRT核心库中的关键接口是:

  • 网络定义接口
    网络定义接口为应用程序提供了指定网络定义的方法。可以指定输入和输出张量,可以添加层,并且有一个用于配置每种支持的层类型的接口。卷积层和循环层等层类型,以及Plugin层类型允许应用程序实现TensorRT本身不支持的功能。 有关网络定义的更多信息,请参见网络定义API。
  • 优化配置文件
    优化配置文件指定对动态维度的约束。有关更多信息,请参考Optimization Profile API和使用动态形状部分。
  • 构建器配置
    构建器配置接口指定用于创建引擎的详细信息。它允许应用程序指定优化配置文件,最大工作空间大小,最小可接受的精度水平,用于自动调整的定时迭代计数以及用于量化网络以8位精度运行的接口。有关更多信息,请参考Builder Config API。
  • 建造器
    构建器接口允许根据网络定义和构建器配置创建优化的引擎。有关更多信息,请参考Builder API。
  • 引擎
    Engine接口允许应用程序执行推理。它支持同步和异步执行,概要分析以及枚举和查询引擎输入和输出的绑定。单引擎可以具有多个执行上下文,从而允许将一组训练好的的参数用于同时执行多个批次。 有关引擎的更多信息,请参见Execution API。

TensorRT提供了用于导入训练好的网络的解析器,以创建网络定义:

  • Caffe解析器
    该解析器可用于解析在BVLC Caffe或NVCaffe 0.16中创建的Caffe网络。它还提供了为自定义层注册插件工厂的功能。有关C ++ Caffe解析器的更多详细信息,请参见NvCaffeParser或Python Caffe解析器。
  • UFF解析器
    该解析器可用于解析UFF格式的网络。它还提供了注册插件工厂并为自定义层传递字段属性的功能。有关C ++ UFF解析器的更多详细信息,请参见NvUffParser或Python UFF解析器。
  • ONNX解析器
    该解析器可用于解析ONNX模型。有关C ++ ONNX解析器的更多详细信息,请参见NvONNXParser或Python ONNX解析器。

注意:此外,可以在GitHub上找到一些TensorRT Caffe和ONNX解析器和插件。

1.5.我如何获得TensorRT?

有关如何安装TensorRT的分步说明,请参阅《TensorRT安装指南》。

1.6.TensorRT弃用政策

弃用是一项预先警告,功能将消失,因此您有时间用其他方法更新代码。 从TensorRT 8.0开始,版本n.x中不推荐使用的功能将在主要版本(n + 2).0中删除。 例如,TensorRT 8.0将省略TensorRT 6.0中不推荐使用的功能,其中一些早在TensorRT 4.0时就已不推荐使用。 TensorRT 9.0将省略TensorRT 7.x中不推荐使用的功能。

2.使用C ++ API

以下各节重点介绍可使用C ++ API执行的NVIDIA®TensorRT™用户目标和任务。 Samples Support Guide中提供了更多详细信息,并在适当的地方链接到下面。

假设您是从训练好的模型开始的。本章将介绍使用TensorRT的以下必要步骤:

  • 从模型中创建TensorRT网络定义
  • 调用TensorRT构建器以从网络创建优化的运行时引擎
  • 序列化和反序列化引擎,以便可以在运行时快速重新创建它
  • 向引擎提供数据以进行推理

C ++ API与Python API

本质上,C ++ API和Python API在满足您的需求方面应该几乎相同。 C ++ API应该用于任何对性能至关重要的场景,以及在安全性很重要的情况下,例如在汽车中。

Python API的主要优点是易于进行数据预处理和后处理,因为您可以使用NumPy和SciPy等各种库。有关Python API的更多信息,请参见 Using The Python API.

2.1.在C ++中实例化TensorRT对象

为了运行推断,请使用接口IExecutionContext。 为了创建IExecutionContext类型的对象,首先创建ICudaEngine类型的对象(引擎)。
通过以下两种方式之一创建引擎:

  • 通过用户模型中的网络定义。在这种情况下,可以选择对引擎进行序列化并保存以供以后使用。
  • 通过从磁盘读取序列化的引擎。与创建网络定义并从中构建引擎相比,这可以节省大量时间。
    创建一个ILogger类型的全局对象。它是TensorRT API的各种方法的必需参数。下面是一个记录器创建的示例:
class Logger : public ILogger           
 {
     void log(Severity severity, const char* msg) override
     {
         // suppress info-level messages
         if (severity != Severity::kINFO)
             std::cout << msg << std::endl;
     }
 } gLogger;

使用TensorRT API独立函数createInferBuilder(gLogger)创建IBuilder类型的对象。有关更多信息,请参见 IBuilder class参考。

使用方法IBuilder :: createNetworkV2创建类型为INetworkDefinition的对象。

使用INetwork定义作为输入来创建可用的解析器之一(Caffe,ONNX或UFF):

  • ONNX: auto parser = nvonnxparser::createParser(*network, gLogger);
  • Caffe: auto parser = nvcaffeparser1::createCaffeParser();
  • UFF: auto parser = nvuffparser::createUffParser();

调用方法IParser :: parse()读取模型文件并填充TensorRT网络。

调用方法IBuilder :: buildEngineWithConfig()创建ICudaEngine类型的对象。

可以选择将引擎序列化并转储到文件中。

创建并使用执行上下文进行推理。

如果保留了序列化引擎并将其保存到文件中,则可以跳过上述大多数步骤。

使用TensorRT API独立函数createInferRuntime(gLogger)创建IRuntime类型的对象。

通过调用方法IRuntime :: deserializeCudaEngine()创建一个引擎。 有关TensorRT运行时的更多信息,请参见参考IRuntime。

对于引擎是直接从网络构建还是从文件反序列化,其余推理是相同的。

即使可以避免创建CUDA上下文(将为您创建默认上下文),也不建议这样做。建议在创建运行时或生成器对象之前创建和配置CUDA上下文。

将使用与创建线程关联的GPU上下文来创建构建器或运行时。尽管将创建默认上下文(如果尚不存在),但建议在创建运行时或生成器对象之前创建和配置CUDA上下文。

2.2.在C ++中创建网络定义

使用TensorRT进行推理的第一步是根据您的模型创建一个TensorRT网络。

最简单的方法是使用TensorRT解析器库导入模型,该库在以下示例中支持序列化的模型:

  • Object Detection With A TensorFlow SSD Network (sampleMNIST),(BVLC and NVCaffe)
  • “Hello World” For TensorRT From ONNX (sampleOnnxMNIST)
  • Import A TensorFlow Model And Run Inference (sampleUffMNIST)(TensorFlow)

另一种选择是直接使用TensorRT API定义模型。这要求您进行少量的API调用,以定义网络图中的每一层,并为模型训练后的参数实现自己的导入机制。

无论哪种情况,您都需要明确告诉TensorRT哪些张量需要作为推理输出。没有标记为输出的张量被认为是瞬态值,可以由构建器优化。输出张量的数量没有限制,但是,将张量标记为输出可能会禁止对该张量进行一些优化。

输入和输出张量也必须给定名称(使用ITensor :: setName())。 在推论时,您将为引擎提供指向输入和输出缓冲区的指针数组。为了确定引擎期望这些指针的顺序,您可以使用张量名称进行查询。

TensorRT网络定义的一个重要方面是它包含指向模型权重的指针,模型权重由构建器复制到优化引擎中。如果网络是通过解析器创建的,则解析器将拥有权重占用的内存,因此,在运行构建器之后,才应删除解析器对象。

2.2.1.使用C ++ API从头开始创建网络定义

除了使用解析器之外,您还可以通过网络定义API将网络直接定义到TensorRT。该场景假设在网络创建过程中主机内存中的每层权重已准备好传递给TensorRT。

  • 关于此任务
    在下面的示例中,我们将创建一个具有输入,卷积,池化,完全连接,激活和SoftMax层的简单网络。 要整体查看代码,请参阅位于GitHub的 Building A Simple MNIST Network Layer By Layer (sampleMNISTAPI)

  • 过程

1.创建构建器和网络:

IBuilder* builder = createInferBuilder(gLogger);
INetworkDefinition* network = builder->createNetworkV2(1U << static_cast(NetworkDefinitionCreationFlag::kEXPLICIT_BATCH));

2.将输入层(包括动态批处理)和输入维添加到网络中。 一个网络可以有多个输入,尽管在此示例中只有一个:

auto data = network->addInput(INPUT_BLOB_NAME, dt, Dims3{-1, 1, INPUT_H, INPUT_W});

3.添加具有隐藏层输入节点,步长和权重的卷积层以进行滤波和偏置。为了从层中检索张量参考,我们可以使用:

auto conv1 = network->addConvolution(*data->getOutput(0), 20, DimsHW{5, 5}, weightMap["conv1filter"], weightMap["conv1bias"]);
conv1->setStride(DimsHW{1, 1});

注意:传递到TensorRT层的权重在主机内存中。

4.添加池化层

auto pool1 = network->addPooling(*conv1->getOutput(0), PoolingType::kMAX, DimsHW{2, 2});
pool1->setStride(DimsHW{2, 2});

5.添加全连接层和激活层

auto ip1 = network->addFullyConnected(*pool1->getOutput(0), 500, weightMap["ip1filter"], weightMap["ip1bias"]);
auto relu1 = network->addActivation(*ip1->getOutput(0), ActivationType::kRELU);

6.添加SoftMax层以计算最终概率并将其设置为输出:

auto prob = network->addSoftMax(*relu1->getOutput(0));
prob->getOutput(0)->setName(OUTPUT_BLOB_NAME);

7.标记输出

network->markOutput(*prob->getOutput(0));

2.2.2.在C ++中使用解析器导入模型

必须在网络之前创建该构建器,因为它是网络的工厂。 不同的解析器具有不同的机制来标记网络输出。

要使用C ++ Parser API导入模型,您将需要执行以下高级步骤:

1.创建TensorRT构建器。

IBuilder* builder = createInferBuilder(gLogger);

有关如何创建记录器的示例,详见Instantiating TensorRT Objects in C++

2.为特定格式创建TensorRT网络和解析器

ONNX

nvinfer1::INetworkDefinition* network = builder->createNetworkV2(1U << static_cast(NetworkDefinitionCreationFlag::kEXPLICIT_BATCH)); 
auto parser = nvonnxparser::createParser(*network, gLogger);

UFF

nvinfer1::INetworkDefinition* network = builder->createNetworkV2(0U);
auto parser = nvuffparser::createUffParser();

Caffe

nvinfer1::INetworkDefinition* network = builder->createNetworkV2(0U);
auto parser = nvcaffeparser1::createCaffeParser();

3.使用解析器解析导入的模型并填充网络。

parser->parse(args);

具体的args取决于使用哪种格式的解析器。 有关更多信息,请参阅TensorRT API.

2.2.3.使用C ++ Parser API导入Caffe模型

以下步骤说明了如何使用C ++ Parser API导入Caffe模型。

  • 关于此任务
    有关更多信息,请参见位于GitHub中的"Hello World" For TensorRT (sampleMNIST)

  • 过程

1.创建构建器和网络:

IBuilder* builder = createInferBuilder(gLogger);
INetworkDefinition* network = builder->createNetworkV2(0U);

2.创建Caffe解析器:

ICaffeParser* parser = createCaffeParser();

3.解析导入的模型

const IBlobNameToTensor* blobNameToTensor = parser->parse("deploy_file" , "modelFile", *network, DataType::kFLOAT);

这将从Caffe模型填充TensorRT网络。最后一个参数指示解析器生成权重为32位浮点数的网络。使用DataType :: kHALF会生成一个具有16位权重的模型。

除了填充网络定义之外,解析器还返回一个字典,该字典将Caffe Blob名称映射到TensorRT张量。与Caffe不同,TensorRT网络定义没有in-place的概念。当Caffe模型使用in-place时,字典中返回的TensorRT张量对应于对该Blob的最后一次写入。例如,如果卷积写入blob,然后是in-place ReLU,则该blob的名称将映射到TensorRT张量,该张量是ReLU的输出。

4.指定网络的输出:

for (auto& s : outputs)
    network->markOutput(*blobNameToTensor->find(s.c_str()));

2.2.4.使用C ++ UFF Parser API导入TensorFlow模型

以下步骤说明了如何使用C ++ Parser API导入TensorFlow模型。

  • 关于此任务
    注意:对于新项目,建议使用TF-TRT集成作为将TensorFlow网络转换为使用TensorRT进行推理的方法。 有关集成说明,请参阅 Accelerating Inference In TF-TRT User Guide。从TensorFlow框架导入需要将TensorFlow模型转换为中间格式UFF(通用框架格式)。有关转换的更多信息,请参见Converting A Frozen Graph To UFF。有关UFF导入的更多信息,请参阅位于GitHub中的 Importing A TensorFlow Model And Running Inference (sampleUffMNIST)。

  • 过程

1.创建构建器和网络

IBuilder* builder = createInferBuilder(gLogger);
INetworkDefinition* network = builder->createNetworkV2(0U);

2.创建UFF解析器:

IUFFParser* parser = createUffParser();

3.向UFF解析器声明网络输入和输出:

parser->registerInput("Input_0", DimsCHW(1, 28, 28), UffInputOrder::kNCHW);
parser->registerOutput("Binary_3");

4.解析导入的模型以填充网络:

parser->parse(uffFile, *network, nvinfer1::DataType::kFLOAT);

2.2.5.使用C ++ Parser API导入ONNX模型

以下步骤说明了如何使用C ++ Parser API导入ONNX模型。

注意:

通常,ONNX Parser的较新版本被设计为向后兼容直至opset7。当更改不向后兼容时,可能会有一些例外。在这种情况下,请将早期的ONNX模型文件转换为更高支持的版本。有关此主题的更多信息,请参见ONNX Model Opset Version Converter。

用户模型也可能是由导出工具生成的,该工具支持比TensorRT随附的ONNX解析器支持的操作集更高的操作集。在这种情况下,请检查发布到GitHub的TensorRT的最新版本 onnx-tensorrt是否支持所需的版本。受支持的版本由onnx_trt_backend.cpp中的BACKEND_OPSET_VERSION变量定义。从GitHub下载并构建最新版本的ONNX TensorRT Parser。构建说明可在以下位置找到:TensorRT backend for ONNX。

  • 关于此任务

有关ONNX导入的更多信息,详见"Hello World" For TensorRT From ONNX (sampleOnnxMNIST)

注意:在TensorRT 7.0中,ONNX解析器仅支持全尺寸模式,这意味着必须使用设置explicitBatch标志来创建网络定义。有关更多信息,请参见Working With Dynamic Shapes。

UFF不支持explicitBatch或动态形状网络。

  • 过程

1.创建构建器和网络。

IBuilder* builder = createInferBuilder(gLogger);
const auto explicitBatch = 1U << static_cast(NetworkDefinitionCreationFlag::kEXPLICIT_BATCH);  
INetworkDefinition* network = builder->createNetworkV2(explicitBatch);

2.创建ONNX解析器。

nvonnxparser::IParser* parser = nvonnxparser::createParser(*network, gLogger);

有关更多信息,请参考NvOnnxParser.h文件。

3.解析模型

parser->parseFromFile(onnx_filename, ILogger::Severity::kWARNING);
    for (int i = 0; i < parser.getNbErrors(); ++i)
    {
        std::cout << parser->getError(i)->desc() << std::endl;
    }

你可能感兴趣的:(Nvidia TensorRT文档——开发者指南)