【tensorrt】——trtexec动态batch支持与batch推理耗时评测

tensorrt, batch

1. trtexec编译

trtexec地址
参考官方的说明,进行项目编译

2. 模型转换

  1. pytorch->onnx的时候,需要在动态尺寸上定义好,例如:
dynamic_axes = {
    'input': {0: 'batch_size'},  # 
}

torch.onnx.export(model,  # model being run
                  x,  # model input (or a tuple for multiple inputs)
                  'save.onnx',
                  export_params=True,
                  opset_version=11,  # the ONNX version to export the model to
                  do_constant_folding=True,
                  input_names=['input'],  # the model's input names
                  dynamic_axes=dynamic_axes)

这里就是定义batch的数值为动态的。

导出成onnx后,可以看一下输入的shape:batch_size×3×480×640
在这里插入图片描述

  1. trtexec模型转换
    直接可以用以下命令进行模型转换
./trtexec --onnx=xxx.onnx --saveEngine=xxx.trt --workspace=1024 --minShapes=inputx:1x3x480x640 --optShapes=inputx:16x3x480x640 --maxShapes=inputx:32x3x480x640 --fp16

说明:

  • onnx: 输入的onnx模型
  • saveEngine:转换好后保存的tensorrt engine
  • workspace:使用的gpu内存,有时候不够,需要手动增大点
  • minShapes:动态尺寸时的最小尺寸,格式为NCHW,需要给定输入node的名字
  • optShapes:推理测试的尺寸,trtexec会执行推理测试,该shape就是测试时的输入shape
  • maxShapes:动态尺寸时的最大尺寸,这里只有batch是动态的,其他维度都是写死的
  • fp16:float16推理

3. batch推理耗时评测

  1. 推理命令
    由上一节的介绍,动态batch推理时,通过改变optShapes的参数就可以实现不同batch的推理。例如:
# batch = 1
./trtexec --onnx=xxx.onnx --saveEngine=xxx.trt --workspace=1024 --minShapes=inputx:1x3x480x640 --optShapes=inputx:1x3x480x640 --maxShapes=inputx:32x3x480x640 --fp16

# batch = 2
./trtexec --onnx=xxx.onnx --saveEngine=xxx.trt --workspace=1024 --minShapes=inputx:1x3x480x640 --optShapes=inputx:2x3x480x640 --maxShapes=inputx:32x3x480x640 --fp16

# batch = 4
./trtexec --onnx=xxx.onnx --saveEngine=xxx.trt --workspace=1024 --minShapes=inputx:1x3x480x640 --optShapes=inputx:4x3x480x640 --maxShapes=inputx:32x3x480x640 --fp16

# batch = 8
./trtexec --onnx=xxx.onnx --saveEngine=xxx.trt --workspace=1024 --minShapes=inputx:1x3x480x640 --optShapes=inputx:8x3x480x640 --maxShapes=inputx:32x3x480x640 --fp16

  1. 耗时情况
    trtexec会打印出很多时间,这里需要对每个时间的含义进行解释,然后大家各取所需,进行评测。总的打印如下:
[09/06/2021-13:50:34] [I] Average on 10 runs - GPU latency: 2.74553 ms - Host latency: 3.74192 ms (end to end 4.93066 ms, enqueue 0.624805 ms)  # 跑了10次,GPU latency: GPU计算耗时, Host latency:GPU输入+计算+输出耗时,end to end:GPU端到端的耗时,eventout - eventin,enqueue:CPU异步耗时
[09/06/2021-13:50:34] [I] Host Latency
[09/06/2021-13:50:34] [I] min: 3.65332 ms (end to end 3.67603 ms)
[09/06/2021-13:50:34] [I] max: 5.95093 ms (end to end 6.88892 ms)
[09/06/2021-13:50:34] [I] mean: 3.71375 ms (end to end 5.30082 ms)
[09/06/2021-13:50:34] [I] median: 3.70032 ms (end to end 5.32935 ms)
[09/06/2021-13:50:34] [I] percentile: 4.10571 ms at 99% (end to end 6.11792 ms at 99%)
[09/06/2021-13:50:34] [I] throughput: 356.786 qps
[09/06/2021-13:50:34] [I] walltime: 3.00741 s
[09/06/2021-13:50:34] [I] Enqueue Time
[09/06/2021-13:50:34] [I] min: 0.248474 ms
[09/06/2021-13:50:34] [I] max: 2.12134 ms
[09/06/2021-13:50:34] [I] median: 0.273987 ms
[09/06/2021-13:50:34] [I] GPU Compute
[09/06/2021-13:50:34] [I] min: 2.69702 ms
[09/06/2021-13:50:34] [I] max: 4.99219 ms
[09/06/2021-13:50:34] [I] mean: 2.73299 ms
[09/06/2021-13:50:34] [I] median: 2.71875 ms
[09/06/2021-13:50:34] [I] percentile: 3.10791 ms at 99%
[09/06/2021-13:50:34] [I] total compute time: 2.93249 s
  • Host Latency gpu: 输入+计算+输出 三部分的耗时
  • Enqueue Time:CPU异步的时间(该时间不具有参考意义,因为GPU的计算可能还没有完成
  • GPU Compute:GPU计算的耗时
    综上,去了Enqueue Time时间都是有意义的

这里附上个人的测试。

设备模型modelbatchgpu 计算耗时/ms
3080pcddrnet23_ocrfp1611.70512
3080pcddrnet23_ocrfp1622.70069
3080pcddrnet23_ocrfp1644.78706
3080pcddrnet23_ocrfp1689.03271
3080pcddrnet23_ocrfp161616.1414

可以看到tensorrt的batch推理有线性增长的问题

### 测试环境配置 为了对比模型在Python中的原始推理时间以及经过TensorRT优化后的性能表现,测试应当在一个稳定的环境中进行。确保安装了必要的库和工具版本一致。 ### 原始PyTorch模型推理时间测量 对于未优化前的模型,在执行预测操作之前加载预训练好的模型并设置为评估模式: ```python import torch from torchvision import models import time device = 'cuda' if torch.cuda.is_available() else 'cpu' model = models.resnet50(pretrained=True).to(device) model.eval() dummy_input = torch.randn(1, 3, 224, 224, device=device) start_time = time.time() with torch.no_grad(): _ = model(dummy_input) end_time = time.time() print(f"Inference Time without Optimization: {end_time - start_time:.4f}s") ``` 这段代码展示了如何计算一次推断所需的时间[^1]。 ### 使用TensorRT优化模型 通过转换成ONNX格式再导入到TensorRT中实现加速效果。这里假设已经完成了从PyTorch到ONNX再到TensorRT的过程。 ```python import tensorrt as trt import pycuda.driver as cuda import numpy as np import pycuda.autoinit TRT_LOGGER = trt.Logger(trt.LogLevel.WARNING) runtime = trt.Runtime(TRT_LOGGER) with open("resnet50.trt", "rb") as f: engine = runtime.deserialize_cuda_engine(f.read()) context = engine.create_execution_context() input_data = np.random.rand(1, 3, 224, 224).astype(np.float32) output = np.empty([1, 1000], dtype=np.float32) d_input = cuda.mem_alloc(1 * input_data.nbytes) d_output = cuda.mem_alloc(1 * output.nbytes) bindings = [int(d_input), int(d_output)] stream = cuda.Stream() def predict(batch): # result gets copied into output global output # Transfer input data to device cuda.memcpy_htod_async(d_input, batch, stream) # Execute model context.execute_async_v2(bindings=bindings, stream_handle=stream.handle) # Transfer predictions back cuda.memcpy_dtoh_async(output, d_output, stream) # Syncronize threads stream.synchronize() start_time = time.time() predict(input_data) end_time = time.time() print(f"Inference Time with TensorRT Optimization: {end_time - start_time:.4f}s") ``` 上述脚本实现了基于TensorRT引擎的快速推理过程,并记录下了所花费的实际时间
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值