tinyvision / DAMO-YOLO

DAMO-YOLO: a fast and accurate object detection method with some new techs, including NAS backbones, efficient RepGFPN, ZeroHead, AlignedOTA, and distillation enhancement.
Apache License 2.0
3.75k stars 470 forks source link

Make DAMO-YOLO work with dynamic_axes #93

Closed ahmedtalbi closed 1 year ago

ahmedtalbi commented 1 year ago

Search before asking

Description

The idea is to make DAMO-YOLO work with dynamic axes, like other models, i.e. YOLOv5. This will allow to have a different input shapes and batch size.

I tried to do it myself but with no success. It seems the converter is not able to convert the latest Mul operation here is a snippet from Netron. the rest of the network seems to be converted correctly.

image

I added the dynamic_axes as argument to torch.onnx._export() as follows

torch.onnx._export( model, dummy_input, onnx_name, input_names=[args.input], output_names=['num_dets', 'det_boxes', 'det_scores', 'det_classes'] if args.end2end else [args.output], dynamic_axes={ 'images': [0, 2, 3], # shape(1,3,640,640) 'output': [0, 1], 'bbox_preds': [0, 1], } if args.dynamic else None, opset_version=args.opset, ) would be thankful for any help.

Use case

No response

Additional

No response

Are you willing to submit a PR?

HYLcool commented 1 year ago

Hi, @ahmedtalbi

Thanks for your suggestion! That's really a good one. We will add this feature in the following updates.

If you need to convert DAMO-YOLO to ONNX models in a hurry, you can add a new parameter dynamic_axes to the export function here: https://github.com/tinyvision/DAMO-YOLO/blob/b12c2647e614ec3446108ffd3690dba519f7b5db/tools/converter.py#L231-L239 For example, for non-end2end conversion of DAMO-YOLO-S, the new parameter is like the below:

dynamic_axes = {
    args.input: {0: 'batch_size'},
    args.output: {0: 'batch_size'},
    '848': {0: 'batch_size'},
},
Here in this dictionary, the 3rd item (which is also the 2nd output) is actually the bbox prediction of DAMO-YOLO, which doesn't have a specific tensor name and is numbered by onnx for now. Therefore, for different models, we list the corresponding number names here: Model name of the 2nd output
DAMO-YOLO-N '1452'
DAMO-YOLO-T '806'
DAMO-YOLO-S '848'
DAMO-YOLO-M '1171'

You can replace the key of the 3rd item with the corresponding name when converting different models.

On the other hand, if you need to convert end2end models to ONNX models, you also need to modify the output keys of dynamic axes to ['num_dets', 'det_boxes', 'det_scores', 'det_classes'].

BTW, we would be very grateful if you would like to submit a PR. And you can contact us anytime if you have further issues.

ahmedtalbi commented 1 year ago

Hello @HYLcool Sorry for my late reply. Unfortunately, I am still getting the same error. After converting the weights, including your code changes, I still get the same error:

onnxruntime.capi.onnxruntime_pybind11_state.RuntimeException: [ONNXRuntimeError] : 6 : RUNTIME_EXCEPTION : Non-zero status code returned while running Mul node. Name:'Mul_540' Status Message: /Users/runner/work/1/s/onnxruntime/core/providers/cpu/math/element_wise_ops.h:505 void onnxruntime::BroadcastIterator::Append(ptrdiff_t, ptrdiff_t) axis == 1 || axis == largest was false. Attempting to broadcast an axis by a dimension other than 1. 2100 by 8400

as far as I can see the issue is not with the input shape but with the second output. I suspect that the corresponding layer is having issues with dynamic computing. maybe you could try it yourself and let me know?

Note: the batch is dynamic, increasing the batch size does not cause any error, the error only happens when the resolution is changed

P.s.: If it does not work for you, could you open the issue again 🙏🏽