A White Paper on Neural Network Deployment
  • ❤️‍🔥A White Paper on Neural Network Deployment
    • ❤️‍🔥A White Paper on Neural Network Deployment
    • 🤠CUDA
      • 🤑CPU|GPU程序执行流程
      • 🤗QiuckLearnFromPicture
      • 🤒GPU编程模型
      • 🫣线程束和线程束分化|Warp
      • 🤭Reduction|并行规约
      • 🤔全局内存(Global Memory)访问模式
      • 🫢Share Memory|共享内存|Bank Conflicts
      • 😷CUDA流和事件
      • 🫡Nsight system和Nsight compute
      • 🤫Grid-Stride Loops
    • 😄ONNX
      • 😉ONNX中的各类Proto
      • 🤔onnx->torch
      • 🥳0x00自定义算子
      • 😕0x01自定义算子
      • 🥴ONNX 模型的修改与调试
      • 😆ONNX中的一些概念
      • 😍用python操作ONNX
      • 🥹ONNX中的广播机制
      • 🤣外部数据
      • 🥰ONNX Model hub
      • 😘ONNX IR(Intermediate Representation)
      • 🥳ONNX后端
      • 🥸概述
    • 🐶TensorRT
      • 🐱TensorRT快速入门指南
      • 🐭文档简介
      • 🐹TensorRT的功能
      • 🐰TensorRT的C++接口解析
      • 🦊TensorRT的Python接口解析
      • 🐻TensorRT如何工作
      • 🐼trtexec的使用
      • 🐻‍❄️实战:解析onnx模型保存为engine文件|from scratch
      • 🐨实战:加载engine文件并执行推理|from scratch
      • 🐯手撕TensoRT源码|0x00
    • 🫶模型量化和剪枝
      • 🖕IEEE754标准
      • 🫰浮点运算产生的误差
      • 🤲映射和偏移
      • 🫴quantization from scratch|python
      • 👏动态量化范围
      • 🤝量化粒度
      • 👍校准
      • 👊Post-Training Quantization
      • ✊Quantization-Aware Training
      • 🤞pytorch-quantization使用文档
      • ✌️Polygraphy-Cheatsheet
    • 🤺杂文不杂
      • 😾Roofline_model
      • 🤖模型部署的几大误区
      • 😽手算Ampere架构各个精度的Throughout
      • 😻Tensor Core VS CUDA Core
      • 😺PNNX计算图结构剖析
      • 🎃融合BN和Conv层
      • 👾深度神经网络编译器原理简介
      • 👽在WSL2上安装CUDA_cuDNN_TensorRT
    • 🍀CPP
      • 🪵lamda表达式|C++11
      • 🌴智能指针|C++11
      • 🌲右值引用|移动语义|完美转发|C++11
      • 🫑emplace_back 减少内存拷贝和移动|C++11
      • 🥬多线程|互斥锁|条件变量|C++11
      • 🥒异步操作|C++11
      • 🍆原子变量|CAS操作|内存顺序|C++11
      • 🍏对象生存期和资源管理|RAII设计思想
      • 🍎Pimpl设计模式|编译防火墙
      • 🌶️std::variant|C++17
      • 🫛std::any|C++17
    • 🩷部署实战
      • ❤️yolov8Multitask
      • 💚yolov5
      • 🧡pointpillars
      • 💛centerpoint
      • 🩵deepstream
      • 💜BEVfusion
      • 💙BEVLane
      • 🖤Occupancy
    • ☯️重点参考书籍
Powered by GitBook
On this page
  • The Build Phase
  • Creating a Network Definition in Python
  • Importing a Model using the ONNX Parser
  • Building an Engine
  • Deserializing a Plan
  • Performing Inference

Was this helpful?

Edit on GitHub
  1. A White Paper on Neural Network Deployment
  2. TensorRT

TensorRT的Python接口解析

PreviousTensorRT的C++接口解析NextTensorRT如何工作

Last updated 12 months ago

Was this helpful?

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

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

import tensorrt as trt

The Build Phase

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

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

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

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)

由于创建引擎是一个离线过程,因此可能需要花费大量时间。请参阅 部分,了解如何使builder运行得更快。

Creating a Network Definition in Python

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

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

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

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)

注意:序列化引擎不能跨平台移植。除平台外,引擎还与所构建的 GPU 型号相关。

Deserializing a Plan

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

runtime = trt.Runtime(logger)

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

engine = runtime.deserialize_cuda_engine(serialized_engine)

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

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

Performing Inference

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

context = engine.create_execution_context()

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

要执行推理,必须为输入和输出指定缓冲区::

context.set_tensor_address(name, ptr)

有几个 Python 软件包允许在 GPU 上分配内存,包括但不限于官方的 CUDA Python 、PyTorch、cuPy 和 Numba。

填充输入缓冲区后,可以调用 TensorRT 的 execute_async_v3 方法,开始使用 CUDA 流进行推理。网络是否以异步方式执行取决于网络的结构和特性。例如,数据的维度、DLA 使用、循环和同步插件等都可能导致同步行为。

首先,创建 CUDA 数据流。如果已经有一个 CUDA 流,则可以使用指向现有流的指针。例如,对于 PyTorch CUDA 流(即 torch.cuda.Stream()),可以使用 cuda_stream 属性访问指针;对于 Polygraphy CUDA 流,可以使用 ptr 属性;也可以通过调用 cudaStreamCreate() 直接使用 CUDA Python 绑定创建流。接下来,开始推理:

context.execute_async_v3(buffers, stream_ptr)

在内核之前和之后启动异步传输(cudaMemcpyAsync())是很常见的做法,以便从 GPU 转移数据。

要确定推理(和异步传输)何时完成,可使用标准的 CUDA 同步机制,如事件或在流上等待。例如,对于 PyTorch CUDA 流或 Polygraphy CUDA 流,可发出 stream.synchronize()。对于使用 CUDA Python 创建的流,请执行 cudaStreamSynchronize(stream)。

要使用 ONNX 导入模型,必须使用 EXPLICIT_BATCH 标志。有关详细信息,请参阅 部分。

❤️‍🔥
🐶
🦊
onnx_resnet50.py
"优化生成器性能 "
"显式批处理与隐式批处理 "