From 3660e1f8ee162edafba1585ce2cb04fc5ea3986c Mon Sep 17 00:00:00 2001 From: Shiyi Zheng Date: Mon, 13 Jul 2026 12:58:33 +0800 Subject: [PATCH 1/5] Add google/owlv2-base-patch16 zero-shot-object-detection fp16 recipe --- ...ero-shot-object-detection_fp16_config.json | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 examples/recipes/google_owlv2-base-patch16/zero-shot-object-detection_fp16_config.json diff --git a/examples/recipes/google_owlv2-base-patch16/zero-shot-object-detection_fp16_config.json b/examples/recipes/google_owlv2-base-patch16/zero-shot-object-detection_fp16_config.json new file mode 100644 index 000000000..be97d3f8c --- /dev/null +++ b/examples/recipes/google_owlv2-base-patch16/zero-shot-object-detection_fp16_config.json @@ -0,0 +1,76 @@ +{ + "export": { + "opset_version": 17, + "batch_size": 1, + "export_params": true, + "do_constant_folding": true, + "verbose": false, + "dynamo": false, + "enable_hierarchy_tags": true, + "clean_onnx": false, + "hierarchy_tag_format": "full", + "input_tensors": [ + { + "name": "pixel_values", + "dtype": "float32", + "shape": [ + 1, + 3, + 960, + 960 + ], + "value_range": [ + 0, + 1 + ] + }, + { + "name": "input_ids", + "dtype": "int32", + "shape": [ + 1, + 16 + ], + "value_range": [ + 0, + 49408 + ] + }, + { + "name": "attention_mask", + "dtype": "int32", + "shape": [ + 1, + 16 + ], + "value_range": [ + 0, + 2 + ] + } + ], + "output_tensors": [ + { + "name": "logits" + }, + { + "name": "pred_boxes" + }, + { + "name": "text_embeds" + }, + { + "name": "image_embeds" + } + ] + }, + "optim": { + "clamp_constant_values": true + }, + "quant": null, + "loader": { + "task": "zero-shot-object-detection", + "model_class": "AutoModelForZeroShotObjectDetection", + "model_type": "owlv2" + } +} From 062e153a3e35926b80449d0379295c3f3075b2b2 Mon Sep 17 00:00:00 2001 From: Shiyi Zheng Date: Mon, 13 Jul 2026 13:46:06 +0800 Subject: [PATCH 2/5] recipe(owlv2-base-patch16): nest under cpu/cpu/ per tested-EP layout (_meta-058) --- .../{ => cpu/cpu}/zero-shot-object-detection_fp16_config.json | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/recipes/google_owlv2-base-patch16/{ => cpu/cpu}/zero-shot-object-detection_fp16_config.json (100%) diff --git a/examples/recipes/google_owlv2-base-patch16/zero-shot-object-detection_fp16_config.json b/examples/recipes/google_owlv2-base-patch16/cpu/cpu/zero-shot-object-detection_fp16_config.json similarity index 100% rename from examples/recipes/google_owlv2-base-patch16/zero-shot-object-detection_fp16_config.json rename to examples/recipes/google_owlv2-base-patch16/cpu/cpu/zero-shot-object-detection_fp16_config.json From df5aee3deaaa4ab687c1a34f1e4a6cbf4cd1d36d Mon Sep 17 00:00:00 2001 From: Shiyi Zheng Date: Wed, 15 Jul 2026 14:02:31 +0800 Subject: [PATCH 3/5] fix(owlv2 recipe): order input_tensors to match forward() signature --- ...ero-shot-object-detection_fp16_config.json | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/recipes/google_owlv2-base-patch16/cpu/cpu/zero-shot-object-detection_fp16_config.json b/examples/recipes/google_owlv2-base-patch16/cpu/cpu/zero-shot-object-detection_fp16_config.json index be97d3f8c..e0387c5a4 100644 --- a/examples/recipes/google_owlv2-base-patch16/cpu/cpu/zero-shot-object-detection_fp16_config.json +++ b/examples/recipes/google_owlv2-base-patch16/cpu/cpu/zero-shot-object-detection_fp16_config.json @@ -11,29 +11,29 @@ "hierarchy_tag_format": "full", "input_tensors": [ { - "name": "pixel_values", - "dtype": "float32", + "name": "input_ids", + "dtype": "int32", "shape": [ 1, - 3, - 960, - 960 + 16 ], "value_range": [ 0, - 1 + 49408 ] }, { - "name": "input_ids", - "dtype": "int32", + "name": "pixel_values", + "dtype": "float32", "shape": [ 1, - 16 + 3, + 960, + 960 ], "value_range": [ 0, - 49408 + 1 ] }, { From 72cd79ef27acf5845683d2e43d32df7bfb68af33 Mon Sep 17 00:00:00 2001 From: "Shiyi Zheng (from Dev Box)" Date: Thu, 16 Jul 2026 11:17:24 +0800 Subject: [PATCH 4/5] fix(export): bind ONNX input names by forward signature --- src/winml/modelkit/export/htp/exporter.py | 19 ++++++++++++++++++- tests/unit/export/test_pytorch_export.py | 19 ++++++++++++------- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/winml/modelkit/export/htp/exporter.py b/src/winml/modelkit/export/htp/exporter.py index c61a162d3..99c839e1c 100644 --- a/src/winml/modelkit/export/htp/exporter.py +++ b/src/winml/modelkit/export/htp/exporter.py @@ -20,6 +20,7 @@ from __future__ import annotations import contextlib +import inspect import logging import sys import time @@ -445,9 +446,25 @@ def _convert_model_to_onnx( output_path = str(Path(output_path).resolve()) Path(output_path).parent.mkdir(parents=True, exist_ok=True) - # Input names from config, fallback to inputs dict keys + # Input names from config, fallback to inputs dict keys. input_names = export_config.get_input_names() or list(inputs.keys()) + if not hasattr(model, "get_export_args"): + # torch.onnx.export binds kwargs by name when invoking forward(), but + # applies input_names positionally to the resulting graph inputs in + # forward-signature order. Keep kwargs for safe invocation and align + # the ONNX names independently so recipe order cannot swap bindings. + try: + parameters = inspect.signature(model.forward).parameters + forward_input_names = [name for name in parameters if name in input_names] + if len(forward_input_names) == len(input_names): + input_names = forward_input_names + except (TypeError, ValueError): + logger.debug( + "Could not inspect %s.forward; preserving configured input order.", + type(model).__name__, + ) + # Output names: infer from traced hierarchy, validate against config traced_outputs = self._hierarchy_builder.get_outputs() if self._hierarchy_builder else None inferred_names = infer_output_names(traced_outputs) if traced_outputs is not None else [] diff --git a/tests/unit/export/test_pytorch_export.py b/tests/unit/export/test_pytorch_export.py index 5b6aeae26..31018c88f 100644 --- a/tests/unit/export/test_pytorch_export.py +++ b/tests/unit/export/test_pytorch_export.py @@ -350,12 +350,12 @@ def test_normalize_false_skips_normalization(self, tmp_path) -> None: assert not _all_value_info_have_shape(onnx_model) def test_mismatched_input_order_exports_successfully(self, tmp_path) -> None: - """Export succeeds when InputTensorSpec order differs from forward() param order. + """ONNX names bind correctly when specs differ from forward() param order. Regression test for CLIP bug: OnnxConfig listed pixel_values before input_ids, - but CLIPModel.forward() expected input_ids first. With positional args this - caused 'not enough values to unpack (expected 4, got 2)'. The fix uses - kwargs= in torch.onnx.export so name-based binding makes order irrelevant. + but CLIPModel.forward() expected input_ids first. kwargs make model invocation + order-independent, while input_names must separately follow forward order + because torch.onnx.export applies those names positionally to graph inputs. """ model = MismatchedInputOrderModel() @@ -374,9 +374,14 @@ def test_mismatched_input_order_exports_successfully(self, tmp_path) -> None: onnx_model = onnx.load(str(tmp_path / "model.onnx")) onnx.checker.check_model(onnx_model) - input_names = {i.name for i in onnx_model.graph.input} - assert "pixel_values" in input_names - assert "text_input" in input_names + input_shapes = { + tensor.name: tuple(dim.dim_value for dim in tensor.type.tensor_type.shape.dim) + for tensor in onnx_model.graph.input + } + assert input_shapes == { + "text_input": (1, 16), + "pixel_values": (1, 3, 8, 8), + } class TestStaleExternalDataCleanup: From 920a3047862e3147db31f9a687cc7f0eceae5406 Mon Sep 17 00:00:00 2001 From: "Shiyi Zheng (from Dev Box)" Date: Thu, 16 Jul 2026 11:18:13 +0800 Subject: [PATCH 5/5] fix(owlv2 recipe): label verified precision as fp32 --- ..._config.json => zero-shot-object-detection_fp32_config.json} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename examples/recipes/google_owlv2-base-patch16/cpu/cpu/{zero-shot-object-detection_fp16_config.json => zero-shot-object-detection_fp32_config.json} (99%) diff --git a/examples/recipes/google_owlv2-base-patch16/cpu/cpu/zero-shot-object-detection_fp16_config.json b/examples/recipes/google_owlv2-base-patch16/cpu/cpu/zero-shot-object-detection_fp32_config.json similarity index 99% rename from examples/recipes/google_owlv2-base-patch16/cpu/cpu/zero-shot-object-detection_fp16_config.json rename to examples/recipes/google_owlv2-base-patch16/cpu/cpu/zero-shot-object-detection_fp32_config.json index e0387c5a4..fcd8f5868 100644 --- a/examples/recipes/google_owlv2-base-patch16/cpu/cpu/zero-shot-object-detection_fp16_config.json +++ b/examples/recipes/google_owlv2-base-patch16/cpu/cpu/zero-shot-object-detection_fp32_config.json @@ -73,4 +73,4 @@ "model_class": "AutoModelForZeroShotObjectDetection", "model_type": "owlv2" } -} +} \ No newline at end of file