快速入门使用tensorRT进行推理

本文介绍了如何使用PyTorch构建一个简单的模型,并将其转换为ONNX格式,然后利用TensorRT进行编译和压测,关注了动态shape设置、模型优化、吞吐量、延迟等关键性能指标。
摘要由CSDN通过智能技术生成

参数解释

--onnx     # 指定ONNX model
# build option
# eg: input0:1x3x256x256,input1:1x3x128x128
--minShapes    # 模型输入的最小shape, 可动态
--optShapes    # 模型输入的推荐hape, 可动态
--maxShapes    # 模型输入的最大shape, 可动态

--inputIOFormats=spec    # 以什么样的格式获取值, 默认fp32
--outputIOFormats=spec    # 以什么样的格式输出值, 默认fp32

# build options
--memPoolSize=poolspec    # 分配的最大的内存容量
# eg: --memPoolSize=workspace:1024.5,dlaSRAM:256 单位M
--profillingVerbosity=mode  # 打印消息的详细程度
# eg: --mode ::=layer_names_only|detailed|none(default=layer_names_only)
# 只打印ops name, 详细(会打印ops参数), none(不打印)

--fp16  # 默认default 是否对模型执行fp16加速
--int8  # 默认default 是否对模型执行int8量化
--calib=<file>  # 当执行int8量化时用来标定参数的文件, 如果给的是带QDQ节点的model, 则不用给。如果给的不是QDQ model且没给定calib文件,默认会把dynamic range设置为4, 这时model量化会产生很大误差

--best    # 默认disabled, 是否开启全精度方案来达到最优性能FP32+FP16+INT8 使用三种方案同时运行, 然后选最快的
--saveEngine=<file>  # 保存序列化的engine
--loadEngine=<file>  # 加载engine进行反序列化, infer时用到
# === Build Options ===
--tacticSources=tactics  # 默认所有库都允许使用
# 某些平台使用某些库可能会报错, 且各种lib有各自缺点
# 通过 加上(+), 去掉(-) 指定什么包能用, 什么包不能用: +lib -lib
# eg: --taticSources=-CUDNN,+CUBLAS

# ==== inference Options ====  推理的时候指定
--shapes=spec    # 给推理设置输入tenosr形状(支持动态)
# eg: --shapes=input0:1x3x256x256,input1:1x3x128x128
--loadInputs=spec    # 从文件中加载输入, tensor文件
# eg: --loadInputs=input0:input0.binary,input1:input1.binary
--iterations=N    # 推理至少 运行几次 (默认10次)
--warmUp=N    # 默认200ms, 设置多少毫秒用来热启动, 可以缩减误差
--duration=N    # 默认3s, 运行inference所消耗的最少时间
--sleepTime=N    # 默认0s, inference从开始到计算延迟多少s
--idleTime=N    # 默认0s, 两次infer间隔多少s
--streams=N    # 默认1, 使用多个流来运行推理, 多线程下可能会得到加速
--separateProfileRun    # 默认False, 是否在infer时将profiler和benchmark分开, 做benchmark时设置为True
--buildOnly  # 默认False, 是否只做编译不做执行

# =====Reporting Options=======
--verbose  # 默认false, 将日志级别设置为详细
--dumpOutput    # 默认false, 打印最后一次推理的输出
--dumpProfile   # 默认false, 打印 每一层的配置信息
--dumpLayerInfo    # 默认false, 打印每一层的层信息
--exportOutput=<file>    # 默认false, 导出最后一层的输出到json文件中
--exportProfile=<file>    # 默认false, 导出每一层的配置到json文件中
--exportLayerInfo=<file>    # 默认false, 导出每一层的信息到json文件中
# eg: --exportLayerInfo=layer.json --profilingVerbosity=detailed

# ========System Options==========
--device=N    # 默认0, 指定cuda device
--useDLACore=N    # 默认None, 指定DLA core, 可以在Jetson设备上指定
--allowGPUFallback  # 默认disabled, 当DLA被指定时, 允许GPU返回不受支持的层
--plugins    # 加载插件库(.so)
# eg: --plugins=xxx.so --plugins=aaa.so --plugins=www.so

模型的编译和运行压测

1.写一个静态的onnx

1.基本的模型导出和编译

import torch
import torch.nn as nn
import torch.onnx as onnx
import torch.nn.functional as F

class Model(nn.Module):
    def __init__(self):
        super().__init__()
        # x -> 1x1x3x3      conv(x) -> 1x3x3x3
        self.conv = nn.Conv2d(1, 3, kernel_size=3, padding=1, stride=1)
        self.fc   = nn.Linear(in_features=27, out_features=2)
    
    def forward(self, x):
        x = self.conv(x)
        x = F.relu(x)
        x = x.view(-1, 27)
        x = self.fc(x)
        return x

if __name__ == "__main__":
    torch.manual_seed(7)
    dummy = torch.randn(1, 1, 3, 3)
    model = Model().eval()
    
    with torch.no_grad():
        y = model(dummy)
        print(f"y = {y}")
    
    onnx.export(
        model, dummy, "static.onnx", 
        opset_version=14, 
        input_names=['x'],
        output_names=['y'],
        verbose=True
    )

2.让模型持续运行,并进行压测

模型的导出和加载
# 模型的转换和优化阶段,目的是将模型转换为TensorRT可以高效执行的格式
# 包含模型的优化、编译、推理、保存,并将模型转换为TensorRT可以高效执行的格式保存
trtexec --onnx=static.onnx --saveEngine=static.engine
# trtexec --onnx=static.onnx --saveEngine=static.engine --allowGPUFallback --useCudaGraph --useSpinWait

# 模型的加载和推理阶段,通过加载优化好的引擎文件来实现快速的模型推理
# 加载已经转换和优化好的TensorRT引擎文件,直接进行推理计算,无需再次进行模型转换和优化。
trtexec --loadEngine=static.engine


吞吐量和平均延迟是大多数应用场景下最重要的性能指标,它们直接反映了模型处理能力和响应速度。GPU计算时间、排队时间和设备到主机延迟也是在特定场景下需要重点关注的指标,尤其是在计算密集和数据密集型的应用中。
trtexec的输出结果提供了模型性能的综合概述。下面是一些关键指标的分析:

  • Throughput: 模型的吞吐量为35188.9查询每秒(qps),这表示模型每秒能够处理的查询数。高吞吐量意味着模型能够快速处理大量数据。
  • Latency: 延迟指标显示了处理单个查询所需的时间。最小延迟是0.0144043毫秒,最大延迟是0.0686035毫秒,平均延迟是0.0180023毫秒。中位数延迟是0.0170898毫秒,而90%、95%和99%的百分位数延迟分别是0.0213318毫秒、0.0220947毫秒和0.0266113毫秒。这些低延迟值表明模型响应非常迅速。
  • Enqueue Time: 排队时间指的是将任务提交到GPU执行的时间。最小值是0.0065918毫秒,最大值是0.0490723毫秒。平均值是0.0111992毫秒,这意味着任务进入GPU执行队列的速度非常快。
  • H2D Latency (Host to Device): 从主机(CPU)传输数据到设备(GPU)的延迟。这个延迟很低,平均值仅为0.00419833毫秒,表明数据从CPU到GPU的传输非常高效。
  • GPU Compute Time: GPU计算时间是执行任务实际花费在GPU上的时间。平均计算时间为0.00979553毫秒,这表明GPU能够快速完成计算任务。
  • D2H Latency (Device to Host): 从设备(GPU)传输数据回主机(CPU)的延迟。平均值是0.0040085毫秒,再次证明了数据传输的高效性。
  • Total Host Walltime: 总主机时间是3.00006秒,这是执行测试所需的总时间。
  • Total GPU Compute Time: 总GPU计算时间是1.0341秒,表示所有任务在GPU上的累积计算时间。

警告分析:

  • 第一个警告指出吞吐量可能受到排队时间的限制,建议使用–useCudaGraph选项来提高吞吐量。
  • 第二个警告指出GPU计算时间不稳定,可能需要锁定GPU的时钟频率或使用–useSpinWait来改善性能稳定性。
模型的压力测试
trtexec --loadEngine=static.engine --duration=1000

# 可以使用下面两个命令之一查看显卡内存占用率
watch -n 0.1 nvidia-smi
nvitop

在这里插入图片描述

2.写一个动态的onnx

1.基本的模型导出

batch_size 在 ONNX 中会经常设置为动态的, 然后在使用 tensorRT 推理时可以动态指定

import torch
import torch.nn as nn
import torch.onnx as onnx
import torch.nn.functional as F

class Model(nn.Module):
    def __init__(self):
        super().__init__()
        # x -> 1x1x3x3      conv(x) -> 1x3x3x3
        self.conv = nn.Conv2d(1, 3, kernel_size=3, padding=1, stride=1)
        self.fc   = nn.Linear(in_features=27, out_features=2)
    
    def forward(self, x):
        x = self.conv(x)
        x = F.relu(x)
        x = x.view(-1, 27)
        x = self.fc(x)
        return x

if __name__ == "__main__":
    torch.manual_seed(7)
    dummy = torch.randn(1, 1, 3, 3)
    model = Model().eval()
    
    with torch.no_grad():
        y = model(dummy)
        print(f"y = {y}")
    
    onnx.export(
        model, dummy, "dynamic.onnx", 
        opset_version=14, 
        input_names=['x'],
        output_names=['y'],
        verbose=True,
        dynamic_axes={'x': {0: 'batch_size'}, 'y': {0: 'batch_size'}},
    )

2.编译模型,设置动态shape参数

trtexec --onnx=dynamic.onnx --minShapes=x:1x1x3x3 --optShapes=x:50x1x3x3 --maxShapes=x:100x1x3x3 --saveEngine=dynamic.engine

trtexec --loadEngine=dynamic.engine --shapes=x:50x1x3x3

下面看不同batch_size, trt engine的推理时间

batch_size = 16 时, throughout = 35247 qps, meida latency = 0.0158691 ms

batch_size = 64时, througphout = 32613.9 qps,media latency = 0.017334 ms
随着batch_size的增大,系统吞吐量会下降,平均延迟有所增大

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值