UNeedCryDear/yolov8-opencv-onnxruntime-cpp

这是一个性能请教的问题,无关代码bug

Opened this issue · 3 comments

大佬们好,我是一个刚开始学习ort的新手,我有一个问题
在所有onnx的头文件中都有个_batchSize 属性,我发现这个初始化的_batch_size属性会极大的影响性能,下面以yolov8_pose_onnx为例
我在一次程序运行中测试了1,2,4,16,32,64,128不同批次下的推理性能,即我修改了OnnxBatchDetect函数,在进入OnnxBatchDetect函数后我主动修改_batchSize 为srcImgs的size,然后仅测试_OrtSession->Run的运行时间,我发现默认设置的_batchSize值总是性能最优的(平均下来单帧推理时间最短)
即如果我在yolov8_pose_onnx.h中设置_batchSize=1,那么测试后就发现批次为1的性能最好(远远好于其他批次);
如果我在yolov8_pose_onnx.h中设置_batchSize=64,那么测试后就发现批次为64的性能最好(也是远远好于其他批次);

这是为什么呢?

  1. 确认下你导出的onnx模型是否为dynamic的,使用https://netron.app 可以打开onnx文件,看下输出这边是具体的数字还是bs,3,h,w这种变量。该参数只对dynamic模型起作用,如果你本身导出的是静态的模型,这个参数不会起作用。
  2. 关于你说的这个batch size的问题,这个跟你的资源利用相关,牵扯到硬件相关,这个每个人都不一样。简单一句话概括就是木桶理论,在batch设置到木桶最短板的极限的时候,这个时候是性能利用最高的地方。另外,也不是说一定会最佳,假设来说一批次图片一共20张,你设置batch size为16,那个剩下的4张需要额外补齐12张到16才可以推理,这就意味着平白耗时,这种还不如batch 为4,然后跑5轮对资源的利用合算。其他的情况类似。

1.我的onnx模型是动态的,input的tensor格式为[batch,3,height,width]
2.我是加载一张图片,然后将其复制为对应批次的数量,[1,2,4,8,16,32,64,128],我预测的性能图像应该是呈现一个抛物线,就是在某一个批次会呈现出最佳推理性能,但是我发现设置不同的初始化_batchsize值,这个最佳性能会波动,我初始化为1,则是1最优,初始化2则是2为最优......初始化为16则是16最优.....,总之就是初始化哪个批次值,哪个批次值是最优的,我感觉这是很奇怪的
3.我没有填充空图像,因为我是直接调用onnxBatchDetect函数来测试不同图像的,在进入函数后就设置_batchSize=srcImgs.size(); _inputTensorShape[0] = _batchSize;

我的环境是ubuntu20,ort 1.16.3 gpu

事实上,_batchSize这个参数在读取模型的时候就已经确认好了,所以你在检测的阶段去修改这个参数意义不大了