TensorRT7 Onnx模型动态多batch问题解决

升级到Tensort7, ONNX模型创建网络和预测都需要用V2版本。需要动态的使用batch_size需要做一些额外的操作。

创建模型

    const auto explicitBatch = 1U << static_cast<uint32_t>(NetworkDefinitionCreationFlag::kEXPLICIT_BATCH);
    INetworkDefinition *network = builder->createNetworkV2(explicitBatch); // 创建TensorRT网络

预测模型

context_->enqueueV2(buffer_queue_.data(), stream_, nullptr);

这个遇到几个问题,用v1版本的创建和预测onnx模型会报必须指定explicitBatch。也就是说Tensort7解析解析了4维的第一维度。

换成V2的创建方式可以解决,但是可看到enqueueV2没有了batchsize这个参数。假设我们的onnx模型是10个batch,当只用到1个batch,我们填充数据用1个batch,预测的时候也按10个batch去infer。这样预测时间也是10个,达不到TensoRT7以前可以设定最大bathsize,实际按照小于max_bathsize的个数的运行。

为了解决这个问题,我们需要用到Tensor引入的动态Reshape的特性,这里我们解决第一维bathsize的问题。

首先onnx模型导出的时候第一维度需要用一个占位符号,而不是具体维度。下面是pytorch导出onnx模型代码片段

    input_names = ['input']
    output_names = ['output']
    #model  input_tensor  根据实际情况设置
    torch.onnx.export(model, input_tensor, 'example.onnx',
    export_params=True, verbose=False, input_names = input_names,
    output_names=output_names, opset_version=10,dynamic_axes={"input":{0:"batch_size"},
                                    "output":{0:"batch_size"}})

创建的时候需要创建优化配置类对象。根据输入尺寸设置为动态

    IBuilderConfig *builder_config = builder->createBuilderConfig();

    IOptimizationProfile *profile = builder->createOptimizationProfile();

    ITensor *input = network->getInput(0);

    Dims dims = input->getDimensions();

    profile->setDimensions(input->getName(),
                           OptProfileSelector::kMIN, Dims4{1, dims.d[1], dims.d[2], dims.d[3]});
    //max_batch_size_根据自己模型实际情况设置
    profile->setDimensions(input->getName(),
                           OptProfileSelector::kOPT, Dims4{max_batch_size_, dims.d[1], dims.d[2], dims.d[3]});
    profile->setDimensions(input->getName(),
                           OptProfileSelector::kMAX, Dims4{max_batch_size_, dims.d[1], dims.d[2], dims.d[3]});
    builder_config->addOptimizationProfile(profile);
    //创建cuda_engine 用带withconfig去创建
    ICudaEngine *engine = builder->buildEngineWithConfig(*network, *builder_config);

预测之前需要绑定维度

    //对应参数是batchsize  channel height width   这里只有batchsize是浮动的,其他三个就是网络的输出尺寸
    Dims4 input_dims{batch_size_, input_tensor_.channel(), input_tensor_.height(), input_tensor_.width()};
    context_->setBindingDimensions(0, input_dims);
    context_->enqueueV2(buffer_queue_.data(), stream_, nullptr);

注意初始化内部变量时候inputdim.d[0]由于是占位符号,值变成-1,这里用设置最大max_batch_size。输出维度信息也一样。

Dims inputdim = engine_->getBindingDimensions(b); // C*H*W
input_shape_.Reshape(max_batch_size_, inputdim.d[1], inputdim.d[2], inputdim.d[3]); // [batch_size, C, H, W]
  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
TensorRT是NVIDIA深度学习推理库,可以用于加速神经网络模型的推理,包括 ONNX 模型。下面是使用 TensorRT 加速 ONNX 模型的一些步骤: 1. 安装 TensorRT:可以从 NVIDIA 官网下载并安装 TensorRT 的相应版本。 2. 将 ONNX 模型换为 TensorRT 引擎:使用 TensorRTONNX Parser 将 ONNX 模型换为 TensorRT 引擎。这可以通过以下代码实现: ```python import tensorrt as trt import onnx # Load the ONNX model as a graph and prepare the TensorRT inference engine onnx_model = onnx.load('model.onnx') onnx.checker.check_model(onnx_model) trt_engine = trt.utils.\ onnx_to_trt_engine(onnx_model, max_batch_size=1, max_workspace_size=1 << 28, precision_mode="FP16", minimum_segment_size=2) ``` 3. 创建 TensorRT 推理引擎:创建 TensorRT 推理引擎实例,并为其分配输入和输出张量的内存。这可以通过以下代码实现: ```python # Create a TensorRT inference engine trt_logger = trt.Logger(trt.Logger.WARNING) trt_runtime = trt.Runtime(trt_logger) trt_context = trt_engine.create_execution_context() # Allocate memory for inputs and outputs input_shape = trt_engine.get_binding_shape(0) output_shape = trt_engine.get_binding_shape(1) input_size = trt.volume(input_shape) * trt_engine.max_batch_size * np.dtype(np.float32).itemsize output_size = trt.volume(output_shape) * trt_engine.max_batch_size * np.dtype(np.float32).itemsize # Allocate device memory d_input = cuda.mem_alloc(input_size) d_output = cuda.mem_alloc(output_size) ``` 4. 执行推理:将输入数据复制到设备内存,执行推理,然后将输出数据从设备内存复制回主机内存。这可以通过以下代码实现: ```python # Copy input data to device memory cuda.memcpy_htod(d_input, input_data) # Execute the inference trt_context.execute_v2(bindings=[int(d_input), int(d_output)]) # Copy output data from device memory output_data = np.empty(output_shape, dtype=np.float32) cuda.memcpy_dtoh(output_data, d_output) ``` 这些步骤可以帮助你使用 TensorRT 加速 ONNX 模型的推理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值