Repository: ultralytics/yolov5

Issue:
DetectMultiBackend() default `stride=32`
<!--
Thank you for submitting a YOLOv5 🚀 Pull Request! We want to make contributing to YOLOv5 as easy and transparent as possible. A few tips to get you started:

- Search existing YOLOv5 [PRs](https://github.com/ultralytics/yolov5/pull) to see if a similar PR already exists.
- Link this PR to a YOLOv5 [issue](https://github.com/ultralytics/yolov5/issues) to help us understand what bug fix or feature is being implemented.
- Provide before and after profiling/inference/training results to help us quantify the improvement your PR provides (if applicable).

Please see our ✅ [Contributing Guide](https://github.com/ultralytics/yolov5/blob/master/CONTRIBUTING.md) for more details.
-->


## 🛠️ PR Summary

<sub>Made with ❤️ by [Ultralytics Actions](https://github.com/ultralytics/actions)<sub>

### 🌟 Summary
Optimization of default stride setting for YOLOv5 models.

### 📊 Key Changes
- Changed the default stride value from 64 to 32 in the model initialization.

### 🎯 Purpose & Impact
- 🎯 **Purpose:** This change likely aims to improve the default configuration for better compatibility or performance.
- 💡 **Impact:** Users might experience improved detection accuracy or speed due to the more optimal stride setting. This could be especially beneficial for real-time applications.


Discussion:
hello, when i try to use engine model, it has some wrong. i set my imgsz 224， the multipule of 32, but the common.py set it as 64 automatically and result to wrong. i think may be the default stride should be 32, when the n/s/m/l/x stride is the multiple of 32.
![b66849f0c6a2f256b1a33ca72c5899a](https://user-images.githubusercontent.com/50093021/162345780-52ff5f52-9438-444e-9aed-e3ecd87d8e20.png)

@rglkt some model formats (like PyTorch) can access attached metadata (like stride) to dynamically select the minimum viable stride, while other formats (like ONNX) do not have any metadata and thus lack stride information, in which case stride 64 is assumed since it is valid for both P5 models (minimum stride 32) and P6 models (minimum stride 64).

The only alternative here is to run an image and compare the input to the output to empirically attempt a stride determination at inference time, which would add delay on DetectMultiBackend init. I'll think this over a bit and see what we can do here.

Resolving patch:
diff --git a/export.py b/export.py
--- a/export.py
+++ b/export.py
@@ -140,7 +140,13 @@ def export_onnx(model, im, file, opset, train, dynamic, simplify, prefix=colorst
         # Checks
         model_onnx = onnx.load(f)  # load onnx model
         onnx.checker.check_model(model_onnx)  # check onnx model
-        # LOGGER.info(onnx.helper.printable_graph(model_onnx.graph))  # print
+
+        # Metadata
+        d = {'stride': int(max(model.stride)), 'names': model.names}
+        for k, v in d.items():
+            meta = model_onnx.metadata_props.add()
+            meta.key, meta.value = k, str(v)
+        onnx.save(model_onnx, f)
 
         # Simplify
         if simplify:
diff --git a/models/common.py b/models/common.py
--- a/models/common.py
+++ b/models/common.py
@@ -328,6 +328,9 @@ def __init__(self, weights='yolov5s.pt', device=torch.device('cpu'), dnn=False,
             import onnxruntime
             providers = ['CUDAExecutionProvider', 'CPUExecutionProvider'] if cuda else ['CPUExecutionProvider']
             session = onnxruntime.InferenceSession(w, providers=providers)
+            meta = session.get_modelmeta().custom_metadata_map  # metadata
+            if 'stride' in meta:
+                stride, names = int(meta['stride']), eval(meta['names'])
         elif xml:  # OpenVINO
             LOGGER.info(f'Loading {w} for OpenVINO inference...')
             check_requirements(('openvino-dev',))  # requires openvino-dev: https://pypi.org/project/openvino-dev/


Test patch: