0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

TensorRT的Python API的基本用法和接口解析

星星科技指导员 来源:NVIDIA 作者:Ken He 2022-05-13 15:46 次阅读

本章说明 Python API 的基本用法,假设您从 ONNX 模型开始。onnx_resnet50.py示例更详细地说明了这个用例。

Python API 可以通过tensorrt模块访问:

import tensorrt as trt

4.1. The Build Phase

要创建构建器,您需要首先创建一个记录器。 Python 绑定包括一个简单的记录器实现,它将高于特定严重性的所有消息记录到stdout

logger = trt.Logger(trt.Logger.WARNING)

或者,可以通过从ILogger类派生来定义您自己的记录器实现:

class MyLogger(trt.ILogger):
    def __init__(self):
       trt.ILogger.__init__(self)

    def log(self, severity, msg):
        pass # Your custom logging implementation here

logger = MyLogger()

然后,您可以创建一个构建器:

builder = trt.Builder(logger)

4.1.1. Creating a Network Definition in Python

创建构建器后,优化模型的第一步是创建网络定义:

network = builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH))

为了使用 ONNX 解析器导入模型,需要EXPLICIT_BATCH标志。有关详细信息,请参阅显式与隐式批处理部分。

4.1.2. Importing a Model using the ONNX Parser

现在,需要从 ONNX 表示中填充网络定义。您可以创建一个 ONNX 解析器来填充网络,如下所示:

parser = trt.OnnxParser(network, logger)

然后,读取模型文件并处理任何错误:

success = parser.parse_from_file(model_path)
for idx in range(parser.num_errors):
    print(parser.get_error(idx))

if not success:
    pass # Error handling code here

4.1.3. Building an Engine

下一步是创建一个构建配置,指定 TensorRT 应该如何优化模型:

config = builder.create_builder_config()

这个接口有很多属性,你可以设置这些属性来控制 TensorRT 如何优化网络。一个重要的属性是最大工作空间大小。层实现通常需要一个临时工作空间,并且此参数限制了网络中任何层可以使用的最大大小。如果提供的工作空间不足,TensorRT 可能无法找到层的实现:

config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, 1 << 20) # 1 MiB

指定配置后,可以使用以下命令构建和序列化引擎:

serialized_engine = builder.build_serialized_network(network, config)

将引擎保存到文件以供将来使用可能很有用。你可以这样做:

with open(“sample.engine”, “wb”) as f:
    f.write(serialized_engine)

4.2. Deserializing a Plan

要执行推理,您首先需要使用Runtime接口反序列化引擎。与构建器一样,运行时需要记录器的实例。

runtime = trt.Runtime(logger)

然后,您可以从内存缓冲区反序列化引擎:

engine = runtime.deserialize_cuda_engine(serialized_engine)

如果您需要首先从文件加载引擎,请运行:

with open(“sample.engine”, “rb”) as f:
    serialized_engine = f.read()

4.3. Performing Inference

引擎拥有优化的模型,但要执行推理需要额外的中间激活状态。这是通过IExecutionContext接口完成的:

context = engine.create_execution_context()

一个引擎可以有多个执行上下文,允许一组权重用于多个重叠的推理任务。 (当前的一个例外是使用动态形状时,每个优化配置文件只能有一个执行上下文。)

要执行推理,您必须为输入和输出传递 TensorRT 缓冲区,TensorRT 要求您在 GPU 指针列表中指定。您可以使用为输入和输出张量提供的名称查询引擎,以在数组中找到正确的位置:

input_idx = engine[input_name]
output_idx = engine[output_name]

使用这些索引,为每个输入和输出设置 GPU 缓冲区。多个 Python 包允许您在 GPU 上分配内存,包括但不限于 PyTorch、Polygraphy CUDA 包装器和 PyCUDA。

然后,创建一个 GPU 指针列表。例如,对于 PyTorch CUDA 张量,您可以使用data_ptr()方法访问 GPU 指针;对于 PolygraphyDeviceArray,使用ptr属性:

buffers = [None] * 2 # Assuming 1 input and 1 output
buffers[input_idx] = input_ptr
buffers[output_idx] = output_ptr

填充输入缓冲区后,您可以调用 TensorRT 的execute_async方法以使用 CUDA 流异步启动推理。

首先,创建 CUDA 流。如果您已经有 CUDA 流,则可以使用指向现有流的指针。例如,对于 PyTorch CUDA 流,即torch.cuda.Stream(),您可以使用cuda_stream属性访问指针;对于 Polygraphy CUDA 流,使用ptr属性。 接下来,开始推理:

context.execute_async_v2(buffers, stream_ptr)

通常在内核之前和之后将异步memcpy()排入队列以从 GPU 中移动数据(如果数据尚不存在)。

要确定内核(可能还有memcpy() )何时完成,请使用标准 CUDA 同步机制,例如事件或等待流。例如,对于 Polygraphy,使用:

stream.synchronize()

如果您更喜欢同步推理,请使用execute_v2方法而不是execute_async_v2

关于作者

Ken He 是 NVIDIA 企业级开发者社区经理 & 高级讲师,拥有多年的 GPU 和人工智能开发经验。自 2017 年加入 NVIDIA 开发者社区以来,完成过上百场培训,帮助上万个开发者了解人工智能和 GPU 编程开发。在计算机视觉,高性能计算领域完成过多个独立项目。并且,在机器人无人机领域,有过丰富的研发经验。对于图像识别,目标的检测与跟踪完成过多种解决方案。曾经参与 GPU 版气象模式GRAPES,是其主要研发者。

审核编辑:郭婷

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • gpu
    gpu
    +关注

    关注

    27

    文章

    4413

    浏览量

    126640
  • python
    +关注

    关注

    51

    文章

    4671

    浏览量

    83458
  • CUDA
    +关注

    关注

    0

    文章

    119

    浏览量

    13460
收藏 人收藏

    评论

    相关推荐

    Python存储数据详解

    用的存储方式,Python标准数据库接口Python DB-APIPython DB-API
    发表于 03-29 15:47

    python restful api学习技巧精选2

    python restful api 学习笔记2 快速开始
    发表于 09-16 13:39

    有关Python解析

    搜了很多历年蓝桥杯真题解答,大多都是Java,C++,C这些语言编写的代码解析Python解析的几乎,甚至可以说没有。而当下Python又这么火热,蓝桥杯也出了
    发表于 07-29 08:39

    一张图学会Python3的基本用法

    这不Github上一位大神就把 Python 3 的几乎所有语法重点都整理到了一张图上,对于有编程基础的小伙伴,通过这张图掌握Python的基本用法不成问题。
    的头像 发表于 02-09 09:22 7910次阅读
    一张图学会<b class='flag-5'>Python</b>3的基本<b class='flag-5'>用法</b>

    python代码示例之基于Python的日历api调用代码实例

    本文档的主要内容详细介绍的是python代码示例之基于Python的日历api调用代码实例。
    发表于 09-06 14:25 42次下载
    <b class='flag-5'>python</b>代码示例之基于<b class='flag-5'>Python</b>的日历<b class='flag-5'>api</b>调用代码实例

    API-Shop-OCR-营业执照识别API接口Python调用示例代码说明

    本文档的主要内容详细介绍的是API-Shop-OCR-营业执照识别API接口Python调用示例代码说明
    发表于 01-10 11:48 6次下载
    <b class='flag-5'>API</b>-Shop-OCR-营业执照识别<b class='flag-5'>API</b><b class='flag-5'>接口</b><b class='flag-5'>Python</b>调用示例代码说明

    如何把Tengine Python API移植到Tengine Lite上

    大佬说选择移植Tengine Python API这个任务,一方面是因为他之前做过涉及Python和C++/C交互的开源项目工作,如 MXNet 中DLPack的Python ...
    的头像 发表于 12-15 00:30 385次阅读

    ADM1266 Linux APIPython库简介

    ADM1266 Linux APIPython库简介
    发表于 05-17 10:50 6次下载
    ADM1266 Linux <b class='flag-5'>API</b>和<b class='flag-5'>Python</b>库简介

    将Tengine Python API移植到Tengine Lite

    大佬说选择移植Tengine Python API这个任务,一方面是因为他之前做过涉及Python和C++/C交互的开源项目工作,如 MXNet 中DLPack的Python ...
    发表于 01-26 17:52 2次下载
    将Tengine <b class='flag-5'>Python</b> <b class='flag-5'>API</b>移植到Tengine Lite

    TensorRT的功能与应用分析

      Polygraphy 是一个工具包,旨在帮助在 TensorRT 和其他框架中运行和调试深度学习模型。它包括一个Python API和一个使用此 API 构建的命令行界面 (CLI
    的头像 发表于 05-13 15:37 1458次阅读

    TensorRT的C++接口解析

    CUDA 上下文会在 TensorRT 第一次调用 CUDA 时自动创建,如果在该点之前不存在。通常最好在第一次调用 TensoRT 之前自己创建和配置 CUDA 上下文。 为了说明对象的生命周期,本章中的代码不使用智能指针;但是,建议将它们与 TensorRT
    的头像 发表于 05-13 15:41 1993次阅读

    api接口怎么使用

    本文就从API接口的维度,浅析API的概念以及为什么要了解它 一、API的概念 API,官方定义为应用程序编程
    的头像 发表于 05-24 14:44 975次阅读

    python里item的用法

    item是Python中一个非常重要的概念,它可以用于多种数据结构和算法的实现。在Python中,item通常用于表示一个集合或序列中的一个元素。本文将详细介绍item的用法,并探讨它在列表、字典
    的头像 发表于 11-21 15:09 1532次阅读

    python中text的用法

    可以使用text(字符串)进行各种操作,例如创建、访问、修改、连接、比较和搜索等。下面将详细介绍Python中使用text的各种用法。 创建和访问文本: 在Python中,我们可以使用单引号或双引号
    的头像 发表于 11-23 15:46 1216次阅读

    split在python中的用法

    split在python中的用法 split()是Python中一个非常常用的字符串函数,它能够根据指定的分隔符将一个字符串分割成多个子字符串,并返回一个包含这些子字符串的列表。本文将详细介绍
    的头像 发表于 12-25 15:12 1587次阅读