快速入门指南#
本 TensorRT 快速入门指南是希望试用 TensorRT SDK 的开发人员的起点;具体来说,它演示了如何快速构建一个应用程序,以在 TensorRT 引擎上运行推理。
简介#
NVIDIA TensorRT 是一个 SDK,用于优化训练过的深度学习模型,以实现高性能推理。TensorRT 包含一个深度学习推理优化器和一个用于执行的运行时。
在您使用您选择的框架训练了深度学习模型之后,TensorRT 使您能够以更高的吞吐量和更低的延迟运行它。

本节介绍 TensorRT 中可用的基本安装、转换和运行时选项,以及它们最适用的场景。
以下是每个章节的快速摘要
Installing TensorRT - 我们提供了多种简单的 TensorRT 安装方法。
The TensorRT Ecosystem - 我们描述了一个简单的流程图,展示不同类型的转换和部署工作流程,并讨论它们的优点和缺点。
Example Deployment Using ONNX - 本章 بررسی(检查,examine)转换和部署模型的基本步骤。它介绍了本指南其余部分中使用的概念,并引导您完成为优化推理执行而必须做出的决策。
ONNX Conversion and Deployment - 我们提供了来自 PyTorch 的 ONNX 导出的广泛概述,以及指向提供更多详细信息的 Jupyter Notebook 的指针。
Using the TensorRT Runtime API - 本节提供了关于使用 TensorRT C++ 和 Python API 进行图像语义分割的教程。
对于允许您快速部署模型的更高级别应用程序,请参阅 NVIDIA Triton Inference Server 快速入门。
安装 TensorRT#
有几种 TensorRT 的安装方法。本节介绍使用以下方式的最常见选项:
容器,
Debian 文件,或
独立的
pip
wheel 文件。
有关安装 TensorRT 的其他方法,请参阅安装指南。
对于已经熟悉 TensorRT 并希望快速运行其应用程序、正在使用 NVIDIA CUDA 容器或希望设置自动化的高级用户,请按照网络存储库安装说明进行操作(请参阅使用 NVIDIA 机器学习网络存储库进行 Debian 安装)。
容器安装#
本节介绍 NVIDIA 定期发布和维护的定制虚拟机镜像 (VMI)。NVIDIA NGC 认证的公有云平台用户可以通过浏览 NGC 网站 并识别可用于在其 VMI 上运行的可用 NGC 容器和标签来访问特定的设置说明。
在每个主要的云提供商上,NVIDIA 都发布了定制的 GPU 优化 VMI,并定期更新操作系统和驱动程序。这些 VMI 针对最新一代 NVIDIA GPU 的性能进行了优化。使用这些 VMI 在具有 B200、H100、A100、L40S 或 T4 GPU 的云托管虚拟机实例上部署 NGC 托管的容器、模型和资源,可确保深度学习、机器学习和 HPC 工作负载的最佳性能。
要在公有云上部署 TensorRT 容器,请按照与您的 NGC 认证的公有云平台 相关的步骤进行操作。
Debian 安装#
请参阅 Debian 安装 说明。
Python 包索引安装#
请参阅 Python 包索引安装 说明。
TensorRT 生态系统#
TensorRT 是一个大型且灵活的项目。它可以处理各种转换和部署工作流程,哪种工作流程最适合您将取决于您的具体用例和问题设置。
TensorRT 提供了多种部署选项,但所有工作流程都涉及将您的模型转换为优化的表示形式,TensorRT 将其称为引擎。为您的模型构建 TensorRT 工作流程包括选择正确的部署选项和用于引擎创建的正确参数组合。
基本 TensorRT 工作流程#
您必须遵循五个基本步骤来转换和部署您的模型
导出模型
选择精度
转换模型
部署模型
在完整的端到端工作流程的上下文中理解这些步骤是最容易的:在Example Deployment Using ONNX 中,我们将介绍一个简单的框架无关的部署工作流程,以使用 ONNX 转换和 TensorRT 的独立运行时将训练好的 ResNet-50 模型转换为 TensorRT 并进行部署。
转换和部署选项#
TensorRT 生态系统分为两个部分
您可以遵循各种路径将其模型转换为优化的 TensorRT 引擎。
用户在部署其优化的 TensorRT 引擎时可以使用 TensorRT 定位的各种运行时。
转换#
使用 TensorRT 转换模型有四个主要选项
使用 Torch-TensorRT
从
.onnx
文件自动 ONNX 转换使用基于 GUI 的工具 Nsight Deep Learning Designer
使用 TensorRT API 手动构建网络(在 C++ 或 Python 中)
PyTorch 集成 (Torch-TensorRT) 提供了模型转换和用于转换 PyTorch 模型的高级运行时 API。在 TensorRT 不支持特定运算符的情况下,它可以回退到 PyTorch 实现。有关支持的运算符的更多信息,请参阅 ONNX Operator Support。
用于自动模型转换和部署的更高效选项是使用 ONNX 进行转换。ONNX 是一种框架无关的选项,适用于 TensorFlow、PyTorch 和更多框架中的模型。TensorRT 支持使用 TensorRT API 或 trtexec
从 ONNX 文件进行自动转换,我们将在本节中使用 trtexec。ONNX 转换是全有或全无的,这意味着模型中的所有操作都必须受 TensorRT 支持(或者您必须为不支持的操作提供自定义插件)。ONNX 转换生成一个单一的 TensorRT 引擎,与 Torch-TensorRT 相比,开销更小。
除了 trtexec
之外,Nsight Deep Learning Designer 还可以将 ONNX 文件转换为 TensorRT 引擎。基于 GUI 的工具提供模型可视化和编辑、推理性能分析以及轻松将 ONNX 模型转换为 TensorRT 引擎。Nsight Deep Learning Designer 会根据需要自动下载 TensorRT 位(包括 CUDA 和 cuBlas),而无需单独安装 TensorRT。
您可以使用 TensorRT 网络定义 API 手动构建 TensorRT 引擎,以获得最佳性能和自定义性。这涉及在 TensorRT 中逐个操作地构建与目标模型相同的网络,仅使用 TensorRT 操作。创建 TensorRT 网络后,您将仅从框架中导出模型的权重,并将它们加载到 TensorRT 网络中。对于这种方法,有关使用 TensorRT 的网络定义 API 构建模型的更多信息可以在这里找到:
部署#
使用 TensorRT 部署模型有三种选项
在 PyTorch 中部署
使用独立的 TensorRT 运行时 API
使用 NVIDIA Triton 推理服务器
您对部署的选择将决定转换模型所需的步骤。
当使用 Torch-TensorRT 时,最常见的部署选项是简单地在 PyTorch 中部署。Torch-TensorRT 转换会生成一个 PyTorch 图,其中插入了 TensorRT 操作。您可以像使用 Python 运行任何其他 PyTorch 模型一样运行 Torch-TensorRT 模型。
TensorRT 运行时 API 允许最低的开销和最细粒度的控制。但是,TensorRT 本身不支持的运算符必须作为插件实现(预先编写的插件库可在 GitHub: TensorRT plugin 上找到)。使用运行时 API 进行部署的最常见路径是使用框架的 ONNX 导出,我们将在下一节中介绍。
最后,NVIDIA Triton 推理服务器是开源推理服务软件,使团队能够从任何框架(TensorFlow、TensorRT、PyTorch、ONNX Runtime 或自定义框架)、从本地存储或 Google Cloud Platform 或 AWS S3 在任何基于 GPU 或 CPU 的基础设施(云、数据中心或边缘)上部署训练好的 AI 模型。它是一个灵活的项目,具有几个独特的功能,例如异构模型的并发模型执行和同一模型的多个副本(多个模型副本可以进一步减少延迟)、负载平衡和模型分析。如果您必须通过 HTTP 提供模型服务(例如在云推理解决方案中),这是一个不错的选择。您可以找到 NVIDIA Triton 推理服务器主页 和 文档。
选择正确的工作流程#
选择如何转换和部署模型时,两个最重要的因素是
您选择的框架
您首选的 TensorRT 运行时目标
有关可用运行时选项的更多信息,请参阅本指南中包含的关于 Understanding TensorRT Runtimes 的 Jupyter Notebook。
使用 ONNX 的示例部署#
ONNX 是一种框架无关的模型格式,可以从大多数主要框架(包括 TensorFlow 和 PyTorch)导出。TensorRT 提供了一个库,用于通过 ONNX-TRT 解析器 将 ONNX 直接转换为 TensorRT 引擎。
本节将介绍将来自 ONNX 模型动物园的预训练 ResNet-50 模型转换为 TensorRT 引擎的五个步骤。从视觉上看,这是我们将遵循的过程
在您了解 TensorRT 工作流程的基本步骤之后,您可以深入研究更深入的 Jupyter Notebook(请参阅以下主题),以了解如何使用 Torch-TensorRT 或 ONNX 使用 TensorRT。使用 PyTorch 框架,您可以按照入门 Jupyter Notebook Running this Guide 进行操作,其中更详细地介绍了这些工作流程步骤。
导出模型#
TensorRT 转换的主要自动路径需要不同的模型格式才能成功转换模型:ONNX 路径要求模型以 ONNX 格式保存。
在此示例中,我们使用 ONNX,因此我们需要一个 ONNX 模型。我们将使用 ResNet-50,这是一个可用于各种目的的基本骨干视觉模型。我们将使用 ONNX 模型动物园中包含的预训练 ResNet-50 ONNX 模型执行分类。
使用 wget 从 ONNX 模型动物园下载预训练的 ResNet-50 模型并解压它。
wget https://download.onnxruntime.ai/onnx/models/resnet50.tar.gz tar xzf resnet50.tar.gz
这会将预训练的 ResNet-50 .onnx
文件解压到路径 resnet50/model.onnx
。
在Exporting To ONNX From PyTorch 中,您可以看到我们如何导出将在此相同部署工作流程中使用的 ONNX 模型。
选择精度#
推理通常比训练需要更低的数值精度。在一定程度上,较低的精度可以为您提供更快的计算速度和更低的内存消耗,而不会牺牲任何有意义的准确性。TensorRT 支持 FP32、FP16、FP8、BF16、FP8、INT64、INT32、INT8 和 INT4 精度。
TensorRT 有两种类型的系统
弱类型允许 TensorRT 的优化器自由地降低精度以提高性能。
强类型要求 TensorRT 根据输入类型静态推断网络中每个张量的类型,然后严格遵守这些类型。如果您在导出之前已经降低了精度并希望 TensorRT 符合要求,这将非常有用。
有关更多信息,请参阅Strong Typing vs Weak Typing。
本节演示了弱类型网络的使用。
FP32 是大多数框架的默认训练精度,因此我们将从此处开始使用它进行推理。
import numpy as np PRECISION = np.float32
我们设置 TensorRT 引擎在运行时应使用的精度,我们将在下一节中进行设置。
转换模型#
ONNX 转换路径是自动 TensorRT 转换的最通用和性能最高的路径之一。它适用于 TensorFlow、PyTorch 和许多其他框架。
有几个工具可以帮助您将模型从 ONNX 转换为 TensorRT 引擎。一种常见的方法是使用 trtexec
- 一个包含在 TensorRT 中的命令行工具,它可以执行多种操作,包括将 ONNX 模型转换为 TensorRT 引擎并对其进行分析。
我们可以按如下方式运行此转换
trtexec --onnx=resnet50/model.onnx --saveEngine=resnet_engine_intro.engine
这会将我们的 resnet50/model.onnx
转换为名为 resnet_engine_intro.engine
的 TensorRT 引擎。
注意
要告诉
trtexec
在哪里找到我们的 ONNX 模型,请运行以下命令--onnx=resnet50/model.onnx要告诉
trtexec
在哪里保存我们优化的 TensorRT 引擎,请运行以下命令--saveEngine=resnet_engine_intro.engine
对于喜欢基于 GUI 工具的简易性的开发人员,Nsight Deep Learning Designer 使您能够轻松地将 ONNX 模型转换为 TensorRT 引擎文件。trtexec
的大多数命令行参数在 Nsight Deep Learning Designer 的 GUI 上也可用。
部署模型#
成功创建 TensorRT 引擎后,我们必须决定如何使用 TensorRT 运行它。
有两种类型的 TensorRT 运行时:具有 C++ 和 Python 绑定的独立运行时以及与 PyTorch 的原生集成。本节将使用一个简化的包装器 (ONNXClassifierWrapper
),它调用独立运行时。我们将生成一批随机化的“虚拟”数据,并使用我们的 ONNXClassifierWrapper
对该批次运行推理。有关 TensorRT 运行时的更多信息,请参阅 Understanding TensorRT Runtimes Jupyter Notebook。
设置
ONNXClassifierWrapper
(使用我们在选择精度中确定的精度)。from onnx_helper import ONNXClassifierWrapper trt_model = ONNXClassifierWrapper("resnet_engine.trt", target_dtype = PRECISION)
生成虚拟批次。
input_shape = (1, 3, 224, 224) dummy_input_batch = np.zeros(input_shape , dtype = PRECISION)
将一批数据馈送到我们的引擎并获取我们的预测。
predictions = trt_model.predict(dummy_input_batch)
请注意,包装器在运行第一批次时加载并初始化引擎,因此此批次通常需要一段时间。有关批处理的更多信息,请参阅Batching 部分。
有关 TensorRT API 的更多信息,请参阅 NVIDIA TensorRT API 文档。有关 ONNXClassifierWrapper
的更多信息,请参阅 GitHub 上 onnx_helper.py 的实现。
ONNX 转换和部署#
ONNX 交换格式提供了一种从许多框架(包括 PyTorch、TensorFlow 和 TensorFlow 2)导出模型以与 TensorRT 运行时一起使用的方法。使用 ONNX 导入模型要求模型中的运算符受 ONNX 支持,并且您需要提供 TensorRT 不支持的任何运算符的插件实现。(TensorRT 的插件库可以在 GitHub: plugin 上找到)。
使用 ONNX 导出#
可以使用 PyTorch export 从 PyTorch 模型轻松生成 ONNX 模型。
Using PyTorch with TensorRT through the ONNX notebook 展示了如何从 PyTorch ResNet-50 模型生成 ONNX 模型,使用 trtexec
将这些 ONNX 模型转换为 TensorRT 引擎,以及在推理时使用 TensorRT 运行时将输入馈送到 TensorRT 引擎。
从 PyTorch 导出到 ONNX#
将 PyTorch 模型转换为 TensorRT 的一种方法是将 PyTorch 模型导出到 ONNX,然后将其转换为 TensorRT 引擎。有关更多详细信息,请参阅 Using PyTorch with TensorRT through ONNX。该 Notebook 将引导您完成此路径,从以下导出步骤开始
从
torchvision
导入 ResNet-50 模型。这将加载一个带有预训练权重的 ResNet-50 副本。import torchvision.models as models resnet50 = models.resnet50(pretrained=True, progress=False).eval() )
从 PyTorch 保存 ONNX 文件。
注意
我们需要一批数据才能从 PyTorch 保存我们的 ONNX 文件。我们将使用虚拟批次。
import torch BATCH_SIZE = 32 dummy_input=torch.randn(BATCH_SIZE, 3, 224, 224)
保存 ONNX 文件。
import torch.onnx torch.onnx.export(resnet50, dummy_input, "resnet50_pytorch.onnx", verbose=False) )
将 ONNX 转换为 TensorRT 引擎#
将 ONNX 文件转换为 TensorRT 引擎有三种主要方法
使用
trtexec
使用 TensorRT API
在本节中,我们将重点介绍使用 trtexec
。要使用 trtexec
将上述 ONNX 模型之一转换为 TensorRT 引擎,我们可以按如下方式运行此转换
trtexec --onnx=resnet50_pytorch.onnx --saveEngine=resnet_engine_pytorch.trt
这会将我们的 resnet50_onnx_model.onnx
转换为名为 resnet_engine.trt
的 TensorRT 引擎。
将 TensorRT 引擎部署到 Python 运行时 API#
有几种运行时可用于 TensorRT 的目标。当性能很重要时,TensorRT API 是运行 ONNX 模型的好方法。以下部分将使用 TensorRT 运行时 API 在 C++ 和 Python 中部署更复杂的 ONNX 模型。
在 Notebook Using PyTorch through ONNX 中,您可以看到如何在 Jupyter 中使用 Python 运行时 API 部署上述模型。另一个简单的选项是使用 ONNXClassifierWrapper
,如Deploy the Model 中所示。
使用 TensorRT 运行时 API#
模型转换和部署的最有效且可自定义的选项之一是 TensorRT API,它具有 C++ 和 Python 绑定。
TensorRT 包括一个具有 C++ 和 Python 绑定的独立运行时。它通常比 Torch-TRT 集成更高效且更可自定义,并且在 PyTorch 中运行。C++ API 的开销较低,但 Python API 与 Python 数据加载器和 NumPy 和 SciPy 等库配合良好,并且更易于用于原型设计、调试和测试。
以下教程说明了如何使用 TensorRT C++ 和 Python API 对图像进行语义分割。对于此任务,使用了具有 ResNet-101 骨干的全卷积模型。该模型接受任意大小的图像并生成每像素预测。
本教程包含以下步骤
设置:启动测试容器并从导出到 ONNX 并使用
trtexec
转换的 PyTorch 模型生成 TensorRT 引擎。C++ 运行时 API:使用引擎和 TensorRT 的 C++ API 运行推理。
Python 运行时 API:使用引擎和 TensorRT 的 Python API 运行推理。
设置测试容器并构建 TensorRT 引擎#
从 TensorRT 开源软件存储库 下载此快速入门教程的源代码。
$ git clone https://github.com/NVIDIA/TensorRT.git $ cd TensorRT/quickstart
将预训练的 FCN-ResNet-101 模型转换为 ONNX。
在这里,我们使用教程中包含的导出脚本来生成 ONNX 模型并将其保存到
fcn-resnet101.onnx
。有关 ONNX 转换的详细信息,请参阅ONNX Conversion and Deployment。该脚本还生成了一个大小为 1282x1026 的测试图像,并将其保存到input.ppm
。启动 NVIDIA PyTorch 容器以运行导出脚本。
$ docker run --rm -it --gpus all -p 8888:8888 -v `pwd`:/workspace -w /workspace/SemanticSegmentation nvcr.io/nvidia/pytorch:20.12-py3 bash
运行导出脚本以将预训练模型转换为 ONNX。
$ python3 export.py
注意
FCN-ResNet-101 有一个维度为
[batch, 3, height, width]
的输入和一个维度为[batch, 21, height, weight]
的输出,其中包含与 21 个类别标签的预测相对应的未归一化概率。将模型导出到 ONNX 时,我们在输出端附加一个 argmax 层,以生成最高概率的每像素类别标签。使用 trtexec 工具从 ONNX 构建 TensorRT 引擎。
trtexec
可以从 ONNX 模型生成 TensorRT 引擎,然后可以使用 TensorRT 运行时 API 部署该引擎。它利用 TensorRT ONNX 解析器 将 ONNX 模型加载到 TensorRT 网络图中,并利用TensorRT Builder API 生成优化的引擎。构建引擎可能很耗时,通常离线执行。
trtexec --onnx=fcn-resnet101.onnx --saveEngine=fcn-resnet101.engine --optShapes=input:1x3x1026x1282
成功执行应生成一个引擎文件,以及在命令输出中类似于
Successful
的内容。trtexec
可以使用 Commonly Used Command-line Flags 中描述的配置选项构建 TensorRT 引擎。
在 C++ 中运行引擎#
在测试容器中编译并运行 C++ 分割教程。
$ make $ ./bin/segmentation_tutorial
以下步骤展示了如何使用Deserializing A Plan 进行推理。
从文件反序列化 TensorRT 引擎。文件内容被读取到缓冲区并在内存中反序列化。
std::vector<char> engineData(fsize); engineFile.read(engineData.data(), fsize); std::unique_ptr<nvinfer1::IRuntime> mRuntime{nvinfer1::createInferRuntime(sample::gLogger.getTRTLogger())}; std::unique_ptr<nvinfer1::ICudaEngine> mEngine(runtime->deserializeCudaEngine(engineData.data(), fsize));
TensorRT 执行上下文封装了执行状态,例如用于在推理期间保持中间激活张量的持久设备内存。
由于分割模型是在启用动态形状的情况下构建的,因此必须为推理执行指定输入的形状。可以查询网络输出形状以确定输出缓冲区的相应维度。
char const* input_name = "input"; assert(mEngine->getTensorDataType(input_name) == nvinfer1::DataType::kFLOAT); auto input_dims = nvinfer1::Dims4{1, /* channels */ 3, height, width}; context->setInputShape(input_name, input_dims); auto input_size = util::getMemorySize(input_dims, sizeof(float)); char const* output_name = "output"; assert(mEngine->getTensorDataType(output_name) == nvinfer1::DataType::kINT64); auto output_dims = context->getTensorShape(output_name); auto output_size = util::getMemorySize(output_dims, sizeof(int64_t));
为了准备推理,为所有输入和输出分配 CUDA 设备内存,处理图像数据并将其复制到输入内存中,并生成引擎绑定的列表。
对于语义分割,输入图像数据通过拟合到 [0, 1] 范围内进行处理,并使用均值 [0.485, 0.456, 0.406] 和标准差 [0.229, 0.224, 0.225] 进行归一化。有关
torchvision
模型 GitHub: models 的输入预处理要求,请参阅 GitHub: models。此操作由实用程序类RGBImageReader
抽象化。void* input_mem{nullptr}; cudaMalloc(&input_mem, input_size); void* output_mem{nullptr}; cudaMalloc(&output_mem, output_size); const std::vector<float> mean{0.485f, 0.456f, 0.406f}; const std::vector<float> stddev{0.229f, 0.224f, 0.225f}; auto input_image{util::RGBImageReader(input_filename, input_dims, mean, stddev)}; input_image.read(); cudaStream_t stream; auto input_buffer = input_image.process(); cudaMemcpyAsync(input_mem, input_buffer.get(), input_size, cudaMemcpyHostToDevice, stream);
推理执行使用上下文的
executeV2
或enqueueV3
方法启动。执行后,我们将结果复制到主机缓冲区并释放所有设备内存分配。context->setTensorAddress(input_name, input_mem); context->setTensorAddress(output_name, output_mem); bool status = context->enqueueV3(stream); auto output_buffer = std::unique_ptr<int64_t>{new int64_t[output_size]}; cudaMemcpyAsync(output_buffer.get(), output_mem, output_size, cudaMemcpyDeviceToHost, stream); cudaStreamSynchronize(stream); cudaFree(input_mem); cudaFree(output_mem);
每像素类别预测的伪彩色图被写入
output.ppm
以可视化结果。实用程序类ArgmaxImageWriter
抽象化了这一点。const int num_classes{21}; const std::vector<int> palette{ (0x1 << 25) - 1, (0x1 << 15) - 1, (0x1 << 21) - 1}; auto output_image{util::ArgmaxImageWriter(output_filename, output_dims, palette, num_classes)}; int64_t* output_ptr = output_buffer.get(); std::vector<int32_t> output_buffer_casted(output_size); for (size_t i = 0; i < output_size; ++i) { output_buffer_casted[i] = static_cast<int32_t>(output_ptr[i]); } output_image.process(output_buffer_casted.get()); output_image.write();
对于测试图像,预期输出如下
在 Python 中运行引擎#
安装所需的 Python 包。
$ pip install pycuda
启动 Jupyter 并使用提供的令牌使用 http://<host-ip-address>:8888 浏览器登录。
$ jupyter notebook --port=8888 --no-browser --ip=0.0.0.0 --allow-root
打开 tutorial-runtime.ipynb notebook 并按照其步骤操作。
TensorRT Python 运行时 API 直接映射到Running An Engine In C++ 中描述的 C++ API。