使用tensorRT动态shape进行cnn推理,下面是与非动态推理的代码区别
一、网络构建时区别
1. 模型定义时,输入维度给定为-1
nvinfer1::ITensor* input = network->addInput("image", nvinfer1::DataType::kFLOAT, nvinfer1::Dims4(-1, num_input, -1, -1));
注:
- 若onnx文件,则onnx文件打开后应该看到动态或-1
- 模型中若存在reshape类操作,reshape参数必须随动态进行计算(大部分时候这有问题)
- 除非全卷积网络,大部分时候只需要为batch_size维度设置为动态,其他维度避免设置动态
2.配置profile
- create:
builder->createOptimizationProfile()
// 如果模型有多个输入,则必须多个profile
auto profile = builder->createOptimizationProfile();
- set:
setDimensions()
设置kMIN
,kOPT
,kMAX
的一系列输入尺寸范围
// 配置最小允许1 x 1 x 3 x 3
profile->setDimensions(input->getName(), nvinfer1::OptProfileSelector::kMIN, nvinfer1::Dims4(1, num_input, 3, 3));
// 最优配置
profile->setDimensions(input->getName(), nvinfer1::OptProfileSelector::kOPT, nvinfer1::Dims4(1, num_input, 3, 3));
// 配置最大允许10 x 1 x 5 x 5
// if networkDims.d[i] != -1, then minDims.d[i] == optDims.d[i] == maxDims.d[i] == networkDims.d[i]
profile->setDimensions(input->getName(), nvinfer1::OptProfileSelector::kMAX, nvinfer1::Dims4(maxBatchSize, num_input, 5, 5));
- add:
config->addOptimizationProfile(profile);
添加profile到网络配置中
config->addOptimizationProfile(profile);
二、推理阶段
明确当前推理时,使用的数据输入大小
execution_context->setBindingDimensions(0, nvinfer1::Dims4(ib, 1, ih, iw));
// 0为bindingIndex,上一节定义float* bindings[] = {input_data_device, output_data_device};故0为输入