🐱TensorRT快速入门指南
TensorRT 生态系统
TensorRT 是一个庞大而灵活的项目。它可以处理各种转换和部署工作流程,哪种工作流程最合适取决于具体用例。
TensorRT 基本工作流程
转换和部署选项
TensorRT 生态系统分为两个部分:
用户可通过各种途径将其模型转换为已经优化好的 TensorRT 引擎。
用户在部署已经优化后的 TensorRT 引擎时,可将 TensorRT 作为推理 runtime。
使用 TensorRT 转换模型有三个主要选项:
使用 TF-TRT
自动从ONNX文件中完成转换
使用 TensorRT API(C++ 或 Python 语言)手动构建网络
对于 TensorFlow 模型的转换,TensorFlow 集成(TF-TRT)提供了模型转换和高级runtime API,并能在 TensorRT 不支持特定算子时返回到 TensorFlow 中去实现运行。
使用 ONNX 进行转换是一种性能更高的模型部署方式。TensorRT 支持使用 TensorRT API 或trtexec从 ONNX 文件中进行自动转换。使用ONNX 转换意味着模型中的所有操作都必须有 TensorRT 的实现(或者必须为不支持的操作提供自定义插件)。ONNX 转换的结果是一个单一的 TensorRT 引擎,比使用 TF-TRT 的开销更少。
为了尽可能提高性能和可定制性,还可以使用 TensorRT 网络定义 API 手动构建 TensorRT 引擎。用 TensorRT 创建网络,只需导出模型的权重,然后将权重加载到网络中即可。
部署
使用 TensorRT 部署模型有三种选择:
在 TensorFlow 中部署
使用独立的 TensorRT runtime API
使用英伟达 Triton 推理服务器
TF-TRT 转换模型的结果是一个插入了 TensorRT 操作的 TensorFlow 图。这意味着您可以像使用其他 TensorFlow 模型一样使用 Python 来运行 TF-TRT 模型。
TensorRT runtime API 可以实现最低的开销和最精细的控制,但 TensorRT 本身不支持的算子必须以插件形式实现(此处提供了一个预编写插件库)。
最后,英伟达™ Triton推理服务器是一款开源推理服务软件,可帮助团队在任何基于GPU或CPU的基础设施(云、数据中心或边缘)上部署来自任何框架(TensorFlow、TensorRT、PyTorch、ONNX Runtime或自定义框架)、本地存储或谷歌云平台或AWS S3的人工智能模型。它是一个灵活的项目,具有一些独特的功能,例如异构模型和同一模型多个副本的并发执行(多个模型副本可进一步减少延迟)以及负载平衡和模型分析。 如果必须通过 HTTP 协议提供模型,例如在云推理解决方案中,它是一个不错的选择。可以在这里找到英伟达™ Triton 推理服务器主页,在这里找到相关文档。
选择正确的工作流程
在选择如何转换和部署模型时,有两个最重要的因素:
模型所选用的框架。
TensorRT runtime。
下面的流程图涵盖了本指南中涉及的不同工作流程。该流程图将帮助您根据这两个因素选择合适的路径。
使用 ONNX 的部署示例
在本节中,我们将以部署预训练的 ONNX 模型为背景,介绍 TensorRT 转换的五个基本步骤。
在本例中,我们将使用 ONNX 格式转换一个预训练的 ResNet-50 模型;ONNX 是一种与框架无关的模型格式,可从大多数主流框架(包括 TensorFlow 和 PyTorch)导出。有关 ONNX 格式的更多信息,请点击此处。
导出模型
TensorRT 根据文件类型不同提供了两种不同的文件转换方式:
TF-TRT 使用 TensorFlow 保存好的模型文件。
ONNXparser 要求模型保存在 ONNX 中。
在本例中,我们使用的是 ONNX 模型文件。
使用wget从 ONNX model zoo 下载预训练的 ResNet-50 模型并解压缩
这将解压缩一个预训练的 ResNet-50.onnx文件到resnet50/model.onnx 路径下。
batchsize的选择
batchsize会对模型的优化将产生很大影响。一般来说,在推理时,当我们想优先考虑延迟时,我们会选择较小的batchsize,而当我们想优先考虑吞吐量时,我们会选择较大的batchsize。较大的batchsize需要更长的处理时间,但可以减少每个样本的平均处理时间。
如果在运行前不知道需要多大的batchsize,TensorRT 可以动态处理batchsize大小。也就是说,固定的batchsize会让 TensorRT 进行额外的优化(a fixed batch size allows TensorRT to make additional optimizations.)。在本示例中,我们使用的固定batchsize为 64。
精度的选择
推理所需的数字精度通常低于训练所需的精度。较低的精度可以加快计算速度,降低内存消耗,而不会牺牲任何精度。TensorRT 支持 TF32、FP32、FP16 和 INT8 精度。FP32 是大多数框架的默认训练精度,因此我们将首先使用 FP32 进行推理
我们将在下一节中设置 TensorRT 引擎在运行时所使用的精度。
转换模型
ONNX 转换为 TensorRT 引擎是最通用、性能最好的方式之一。它适用于 TensorFlow、PyTorch 和许多其他框架。
有几种工具可以帮助你将 ONNX 模型转换为 TensorRT 引擎。一种常见的方法是使用trtexec,它是 TensorRT 附带的一个命令行工具,可以将 ONNX 模型转换为 TensorRT 引擎并对其进行剖析。
我们可以按以下方式运行转换
这将把resnet50/model.onnx转换为名为resnet_engine.trt 的 TensorRT 引擎。注意:
要告诉trtexec在哪里找到我们的 ONNX 模型
要告诉trtexec保存优化后的 TensorRT 引擎的位置
部署模型
成功创建 TensorRT 引擎后,我们如何使用 TensorRT 运行它。
TensorRT runtime有两种类型:一种是与 C++ 和 Python 绑定的独立runtime,另一种与 TensorFlow 集成的 API。在本节中,我们将生成一批随机的 "假 "数据,并使用ONNXClassifierWrapper这个类在该批数据上进行推理。
设置ONNXClassifierWrapper
设置模型的输入
向引擎输入一批数据,然后得到预测结果。
请注意,在运行第一个batch之前,ONNXClassifierWrapper不会加载和初始化引擎,因此第一个batch处理通常需要比较长的一段时间。
使用 TensorRT runtime API
在模型转换和部署方面,使用 TensorRT runtime API是性能最好、最可定制的选择之一,该程序接口有 C++ 和 Python 版本。
TensorRT 包含一个带有 C++ 和 Python 绑定的独立runtime API,与使用 TF-TRT 集成相比,其性能和可定制性通常更高。C++ API 的开销较低,但 Python API 与 Python 数据加载器以及 NumPy 和 SciPy 等库配合良好,更易于用于原型设计、调试和测试。
下面的教程说明了如何使用 TensorRT C++ 和 Python API 对图像进行语义分割。该任务使用了一个以 ResNet-101 为骨干的全卷积模型。该模型可接受任意大小的图像,并为每个像素生成相应的预测结果。
本教程包括以下步骤:
导出ONNX模型,并使用trtexec生成TensorRT引擎
使用TensorRT C++ API进行运行时的推理
使用TensorRT Python API进行运行时的推理
导出ONNX模型,并使用trtexec生成TensorRT引擎
从TensorRT 开源软件仓库下载快速入门教程的源代码。
将预先训练好的 FCN-ResNet-101模型转换为 ONNX。以下是相关的测试图片
a. 启动容器。
b.运行导出脚本,将预训练模型转换为 ONNX。
注: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 生成器API(Builder API)生成优化引擎。构建引擎非常耗时,通常需要离线运行。
执行成功后生成一个引擎文件。
–buildOnly : 跳过推理性能测量(默认是禁用)
可选择使用trtexec 生成随机值验证生成的引擎。
其中,--shapes为用于推理的输入大小。
如果成功,您应该会看到类似下面的内容
用 C++ 运行引擎
在容器中编译并运行
以下步骤展示了如何进行反序列化(Plan)然后推理。
从文件反序列化 TensorRT 引擎。文件内容被读入缓冲区,并在内存中进行反序列化。
TensorRT 执行上下文包含了一些执行状态(例如在推理过程中所需要的激活层的张量值),由于建立分割模型时启用了动态batchsize,因此必须指定输入的维度才能执行推理。可以通过查询网络输出维度来确定输出缓冲区的相应大小。
注意:网络 I/O 的绑定索引可按名称查询。
在准备推理时,会为所有输入和输出数据分配 CUDA 设备内存,image data is processed and copied into input memory, and a list of engine bindings is generated.
对于语义分割,输入图像数据的处理方法是拟合到[0, 1]范围内,并使用均值 [0.485, 0.456, 0.406]和标准差[0.229, 0.224, 0.225] 进行归一化。请参阅此处 torchvision模型的预处理要求。该操作由类RGBImageReader 抽象出来。
推理执行是通过上下文的executeV2或enqueueV2方法启动的。执行完成后,我们会将结果拷贝回主机缓冲区,并释放所有设备内存分配。
对预测结果进行可视化
测试图像的预期输出如下:
在 Python 中运行引擎
安装所需的 Python 包
启动 Jupyter
打开tutorial-runtime.ipynb笔记本并按其步骤操作。
TensorRT Python runtime API 与 C++ runtime API一一映射。
Last updated