PaddlePaddle / PaddleDetection

Object Detection toolkit based on PaddlePaddle. It supports object detection, instance segmentation, multiple object tracking and real-time multi-person keypoint detection.
Apache License 2.0
12.6k stars 2.86k forks source link

pp-yoloe导出onnx问题[BUG] #5511

Open sdreamforchen opened 2 years ago

sdreamforchen commented 2 years ago

您好。我在转ONNX模型的时候,提示了警告:Due to the operator:multiclass_nms3, the converted ONNX model will only supports input[batch_size] == 1; 我得到的onnx,我查看输入的维数为[-1,3,640,640],下游环境对这个-1不能识别,比较悲催。请问可以在哪设置一下吗

yghstill commented 2 years ago

@sdreamforchen 使用tools/export_model.py导出模型时可在https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.4/configs/ppyoloe/base/ppyoloe_reader.yml#L30 设置[1, 3, 640, 640] 指定固定batch size为1。

sdreamforchen commented 2 years ago

@sdreamforchen 使用tools/export_model.py导出模型时可在https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.4/configs/ppyoloe/base/ppyoloe_reader.yml#L30 设置[1, 3, 640, 640] 指定固定batch size为1。

还是报这个错。查看onnx还是-1,3,640,640

wangxinxin08 commented 2 years ago

您好。我在转ONNX模型的时候,提示了警告:Due to the operator:multiclass_nms3, the converted ONNX model will only supports input[batch_size] == 1; 我得到的onnx,我查看输入的维数为[-1,3,640,640],下游环境对这个-1不能识别,比较悲催。请问可以在哪设置一下吗

这个不是报错,导出时候的警告而已,下游环境报什么错呢?

sdreamforchen commented 2 years ago

您好。我在转ONNX模型的时候,提示了警告:Due to the operator:multiclass_nms3, the converted ONNX model will only supports input[batch_size] == 1; 我得到的onnx,我查看输入的维数为[-1,3,640,640],下游环境对这个-1不能识别,比较悲催。请问可以在哪设置一下吗

这个不是报错,导出时候的警告而已,下游环境报什么错呢?

未通过onnx修改维度时。下游环境报错是:ValueError: negative dimensions are not allowed; 1 我通过直接修改onnx,将维数变为了1,3,640,640。接着onnxsim操作的时候:RuntimeError: The shape of input "image" has dynamic size "[0, 3, 640, 640]", please.............我便在onnxsim指令中加入input-shape,报The model has more than 1 inputs, please....... 2 我将onnx再次放入下游环境,报错为TypeError: 'str' object cannot be interpreted as an integer。这应该是我下游任务把constant操作识别成str了。 3 我理解的是:转成onnx后,net graph头部的image是图像输入,constant是做图像的scale操作(即预处理???),这俩需要维度匹配,然而我只改了image的维度,所以有了1和2的错误。 感谢你们这么及时回复!

wangxinxin08 commented 2 years ago

不要使用onnxsim,直接使用paddle2onnx转出来的onnx模型即可

sdreamforchen commented 2 years ago

第二步是用的paddle2onnx(第一步是转为paddle的module)。这次PP-yoloE的export是将nms加进去了的,那是否预处理也加进去了的?我尝试下修改graph头部的这个constant。

wangxinxin08 commented 2 years ago

预处理一般是不会导出到onnx的

jiangjiajun commented 2 years ago

如何导出固定shape的onnx模型

Paddle2ONNX支持在导出模型时,将模型的输入形状进行改变,或者固定。 具体做法如下

  1. 安装
    git clone https://github.com/PaddlePaddle/Paddle2ONNX.git
    cd Paddle2ONNX
    python setup.py install
  2. 导出模型
    paddle2onnx --model_dir inference_model   \
                       --model_filename model.pdmodel  \
                       --params_filename model.pdiparams \
                       --save_file model.onnx   \
                       --opset_version 11  \
                       --input_shape_dict="{'image': [1,3,640,640], 'scale_factor':[1, 2]}"

    其原理是在加载Paddle模型后,会根据input_shape_dict重新对整个模型各个节点的shape进行计算,从而得到新的输入shape的模型

sdreamforchen commented 2 years ago

非常感谢回复。但是你这个方法先前就试过了。 今天发现architecture文件夹里面没有PP-yoloE的文件。不知道与这个是否有关呢? 下游环境报错是这样的: TypeError: 'str' object cannot be interpreted as an integer [5099] Failed to execute script pegasus import model ERROR ! 此次转换成的onnx,相比其他模型,多了一个 {Constant,输出是constant_113} .这部分未和网路中任何部分产生关系。感觉问题出在这。 PS:eval.py是可以正常跑的。结果正确。 添麻烦了,不好意思

wangxinxin08 commented 2 years ago

参考 @jiangjiajun 的回复导出,然后不要使用onnx2sim,利用这个issue中的示例跑是没问题的https://github.com/PaddlePaddle/PaddleDetection/issues/5544

jimmy133719 commented 2 years ago

@sdreamforchen 您好,我與您使用相同的下游環境,轉換時同樣出現"TypeError: 'str' object cannot be interpreted as an integer"報錯,想請問您是否已經解掉這個問題了?謝謝!

PS: 我有測試過eval.py和#5544中的示例,兩者皆沒問題。

sdreamforchen commented 2 years ago

@sdreamforchen 您好,我與您使用相同的下游環境,轉換時同樣出現"TypeError: 'str' object cannot be interpreted as an integer"報錯,想請問您是否已經解掉這個問題了?謝謝!

PS: 我有測試過eval.py和#5544中的示例,兩者皆沒問題。

您好。并未解决。最近部署感觉问问题的人有点多,百度在优化吧。我先前picoDet部署都没问题,现在有了。感觉这次版本更新改了不少东西。至少先前导出onnx的batchsize都是1,目前是默认的-1. 另外,ppyoloE的onnx在服务器能跑通,但是会报两个警告,一个是constant_113无用,二个是,输出shape不匹配。这两个onnxruntime都可以自动修改,所以服务器能跑通。下游环境,应该编译转换能力没这么强的原因。反正我是没跑通的。

wangxinxin08 commented 2 years ago

@jimmy133719 @sdreamforchen 下游环境是什么?具体如何复现这一问题呢,可以给出一些方式我们可以帮忙定位一下问题

sdreamforchen commented 2 years ago

@jimmy133719 @sdreamforchen 下游环境是什么?具体如何复现这一问题呢,可以给出一些方式我们可以帮忙定位一下问题

Vivante GPU,转换工具是acuity-tools

sdreamforchen commented 2 years ago

@jimmy133719 @sdreamforchen 下游环境是什么?具体如何复现这一问题呢,可以给出一些方式我们可以帮忙定位一下问题

王老师,您好。我对底层环境实在不了解,不知道这个提议合理不?
现在GPU算是百花齐放,各个芯片IP和编译环境不相同,我们这边又是“工业GPU IP+No英伟达”,在性能、软件环境友好和成本方面,有时候选择比较无奈。 我们paddle生成onnx之类的open模型时,能否做到“极简化”呢? 比如onnxruntime提示的两个警告在转换的时候(arm端未测试过),可以自动优化掉。 保证: 1 输入就是[b,3,w,h],b根据需求可设置为1,或者n; 2 模型剩余部分就是conv,bn, act, linear之类的,如果存在在paddledetection上微改的情况,那就由用户自行编写函数或类就行了,这也是用户自己该做的; 3 输出nms可选; 4 模型最终输出时,各层shape、各种参数固定住,成一个没有多余的固定死的模型。 这样我想下游环境不管是啥,转换应该都是适配的。

sdreamforchen commented 2 years ago

@jimmy133719 @sdreamforchen 下游环境是什么?具体如何复现这一问题呢,可以给出一些方式我们可以帮忙定位一下问题

王老师,您好。我对底层环境实在不了解,不知道这个提议合理不?
现在GPU算是百花齐放,各个芯片IP和编译环境不相同,我们这边又是“工业GPU IP+No英伟达”,在性能、软件环境友好和成本方面,有时候选择比较无奈。 我们paddle生成onnx之类的open模型时,能否做到“极简化”呢? 比如onnxruntime提示的两个警告在转换的时候(arm端未测试过),可以自动优化掉。 保证: 1 输入就是[b,3,w,h],b根据需求可设置为1,或者n; 2 模型剩余部分就是conv,bn, act, linear之类的,如果存在在paddledetection上微改的情况,那就由用户自行编写函数或类就行了,这也是用户自己该做的; 3 输出nms可选; 4 模型最终输出时,各层shape、各种参数固定住,成一个没有多余的固定死的模型。 这样我想下游环境不管是啥,转换应该都是适配的。

wangxinxin08 commented 2 years ago

@sdreamforchen 你的建议挺好的,考虑到nms可能下游硬件不支持的问题,所以可以设置成可选的情况,这一部分是可以操作的,你可以先试下在https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.4/ppdet/modeling/heads/ppyoloe_head.py#L377 这一行之后直接return pred_bboxes, pred_scores,然后再使用export_model导出模型,再转换成onnx试下还有没有其他的问题,再反馈,我们会跟据你反馈的问题来分析,设计以及支持这个需求的

sdreamforchen commented 2 years ago

@sdreamforchen 你的建议挺好的,考虑到nms可能下游硬件不支持的问题,所以可以设置成可选的情况,这一部分是可以操作的,你可以先试下在https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.4/ppdet/modeling/heads/ppyoloe_head.py#L377 这一行之后直接return pred_bboxes, pred_scores,然后再使用export_model导出模型,再转换成onnx试下还有没有其他的问题,再反馈,我们会跟据你反馈的问题来分析,设计以及支持这个需求的

问题一直不是nms的问题哈。 是多了这个constant_113(output),多了一个input constant。这个constant编译的时候就会报"str.......的错。 当然 1 我刚也测试了下无nms的情况,问题一样,毕竟报错是input,所以后续应该都没有执行; 2 我们自己也在环境中找问题,看能否实现onnxruntime这种自行判断和优化; 3 另外,对onnx直接删除constant节点,发现还是报错,所以这条路我们否定了,集中精力找环境底层的一些问题(借鉴onnx处理上的一些好方法)。

jimmy133719 commented 2 years ago

问题一直不是nms的问题哈。 是多了这个constant_113(output),多了一个input constant。这个constant编译的时候就会报"str.......的错。 当然 1 我刚也测试了下无nms的情况,问题一样,毕竟报错是input,所以后续应该都没有执行; 2 我们自己也在环境中找问题,看能否实现onnxruntime这种自行判断和优化; 3 另外,对onnx直接删除constant节点,发现还是报错,所以这条路我们否定了,集中精力找环境底层的一些问题(借鉴onnx处理上的一些好方法)。

我測試了無nms的情況,雖然還是有報錯,但原本""TypeError: 'str' object cannot be interpreted as an integer"的問題不再出現,後續matching時才跑出"TypeError: 'NoneType' object is not iterable",我猜這應該是input constant的問題。不知道如果直接把constant節點寫進模型內再轉換成onnx是否可行?看起來這個節點還是必須,如果刪除會報錯應該是蠻合理的。

wangxinxin08 commented 2 years ago

@sdreamforchen 你的建议挺好的,考虑到nms可能下游硬件不支持的问题,所以可以设置成可选的情况,这一部分是可以操作的,你可以先试下在https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.4/ppdet/modeling/heads/ppyoloe_head.py#L377 这一行之后直接return pred_bboxes, pred_scores,然后再使用export_model导出模型,再转换成onnx试下还有没有其他的问题,再反馈,我们会跟据你反馈的问题来分析,设计以及支持这个需求的

问题一直不是nms的问题哈。 是多了这个constant_113(output),多了一个input constant。这个constant编译的时候就会报"str.......的错。 当然 1 我刚也测试了下无nms的情况,问题一样,毕竟报错是input,所以后续应该都没有执行; 2 我们自己也在环境中找问题,看能否实现onnxruntime这种自行判断和优化; 3 另外,对onnx直接删除constant节点,发现还是报错,所以这条路我们否定了,集中精力找环境底层的一些问题(借鉴onnx处理上的一些好方法)。

@sdreamforchen constant的问题我们可以再看下哈,onnx是支持constant的,卷积中的bias是通过add_constant的形式添加的,输入的constant其实和bias类似,这个我们具体再看下是什么原因导致的

sdreamforchen commented 2 years ago

1 去除掉NMS, 2去除掉与scale_factor相关部分(paddle2onnx输入参数中只设置input image的值), 3所有代码都在postprocess里面,注释掉:从scale_y, scale_x =....此行开始到结束,增加return pred_bboxes,pred_scores。