fix(export): bind keyword inputs and add OWLv2 recipes#1146
Conversation
Independent reviewer verdict: REQUEST_CHANGESReviewed exact PR head Blocking findings and routing
Independently verified, not blocking
The PR should remain Draft. Re-review from a fresh checkout after both owner-routed fixes land. |
REQUEST_CHANGES mapping responseResolved both blocking findings at unchanged model PR head
Preserved: Draft state, |
Independent reviewer verdict: APPROVEReviewed exact PR head Prior blockers independently closed
Independent revalidation
No remaining reviewer-owned or role-routed blocker was found. APPROVE, while preserving Draft state and the label. |
Summary
This adds CPU fp32/fp16 support for
google/owlv2-base-patch16-finetuned, an open-vocabulary zero-shot object detector, together with a class-wide exporter repair for keyword-generated multi-input models. The shipped Effort/Outcome is L2, and both required CPU tuples reached L2 PASS with semantic-input performance and all-four-output parity against the pinned PyTorch checkpoint.winml evalremains CLI-BLOCKED for both tuples because no zero-shot-object-detection evaluator exists; no task metric is fabricated.Model metadata
What the model does
OWLv2 is an open-vocabulary, text-conditioned object detector. It accepts an image and one or more text queries and returns per-patch query logits, normalized bounding boxes, and text/image embeddings for locating objects not limited to a fixed training label set.
Evidence: Hugging Face model card for
google/owlv2-base-patch16-finetunedpinned atd69b086b07123308a4e198343ab2824e1af7774a; pinnedconfig.jsonwitharchitectures=["Owlv2ForObjectDetection"]andmodel_type="owlv2"; TransformersOwlv2ForObjectDetection.forwardsource.Confidence: verified.
Primary user stories
A user supplies an image and natural-language candidate object labels to obtain scored bounding boxes for zero-shot text-conditioned object localization. Evidence: pinned model-card usage example and intended-use section. Confidence: verified.
A researcher supplies images and previously unseen category descriptions to study open-vocabulary detector robustness, generalization, bias, and constraints. Evidence: pinned model-card intended-use section. Confidence: verified.
Supported tasks
| Task | Support surfaces | Evidence | Confidence |
|---|---|---|---|
| zero-shot-object-detection | checkpoint; Transformers; Optimum ONNX; WinML | Pinned Hub
pipeline_tag; TransformersOwlv2ForObjectDetection; Optimum TasksManager vendor registration forowlv2;winml inspectresolution toOwlV2OnnxConfig| verified || feature-extraction | Transformers; Optimum ONNX | Transformers
Owlv2Model/Owlv2TextModel/Owlv2VisionModel; Optimum TasksManager vendor registration | mapped |Model architecture
Owlv2ForObjectDetectionsource, and the exported ONNX hierarchy (verified).Validation and support evidence
Baseline
Fresh baseline validation used current
maincommit38767add6f91c7b10b6394fae3af6f437e02effdwith WinML0.2.0. Optimum advertisedfeature-extractionandzero-shot-object-detectionboth before and after WinML registration, with no WinML-added task: VENDOR-ONLY.Auto-config resolved
zero-shot-object-detection,AutoModelForZeroShotObjectDetection, andOwlV2OnnxConfig, but emitted/export/input_tensorsas[pixel_values,input_ids,attention_mask].Recipe-free build returned process exit 0 in 122.981 s, but failed the L0 floor: the graph bound
pixel_valuestoINT32 [1,16]andinput_idstoFLOAT [1,3,960,960], oppositeOwlv2ForObjectDetection.forward(input_ids, pixel_values, attention_mask). An exit-zero export was therefore not valid task coverage.Semantic named-input perf failed with exit 1:
Invalid rank for input: pixel_values Got: 4 Expected: 2. Random graph-shaped perf returned p50 3034.894 ms, throughput 0.33 samples/s, and RSS total delta 1426.47 MB, but is invalid task evidence because it follows the swapped graph bindings.Eval was CLI-BLOCKED before data/model execution:
zero-shot-object-detectionwas absent fromTASK_SCHEMASand_EVALUATOR_REGISTRY. The pinned COCO mirror is object-detection data, but a valid evaluator must derive candidate text queries from category names, run grounded post-processing, and score COCO mAP; the fixed-label object-detection evaluator is not semantically interchangeable. The generalized evaluator gap is filed as winml-cli #1147.Baseline Goal floor: L0.
Goal
Effort: L2 — repair the class-of-models keyword-input name binding, add a regression test, and add the two required recipes.
Goal ceiling: L2.
Outcome commitment: L2 for CPU/cpu fp32 and fp16.
Success definition: for both tuples, perform fresh config/build with exact named ONNX structure, run processor-generated semantic image+text perf, and compare all four raw outputs against pinned PyTorch revision
d69b086b07123308a4e198343ab2824e1af7774a.No ceiling change or re-issued charter occurred.
Outcome
Shipped tier: L2.
Highest Goal verdict: L2 PASS.
Coverage: full; both required CPU/cpu precision tuples passed; deferred tuples: none.
Supplementary eval: CLI-BLOCKED for both tuples; no task metric fabricated.
Shipped paths: the shared exporter repair and regression test, plus fp32/fp16 recipes under
examples/recipes/google_owlv2-base-patch16-finetuned/cpu/cpu/.Model findings:
owlv2-004records faithful fp32/fp16 CPU export/perf/parity and the fp16 box-delta caveat;owlv2-005records the zero-shot evaluator gap, why fixed-label evaluation is invalid, and the filed issue winml-cli #1147.Methodology finding:
_meta-084distinguishes recipe ordering defects from generalized keyword-export binding defects and requires recipe-free semantic acceptance while preserving explicit positional export protocols.Lane A provenance: these findings and the corresponding producer/tester/reviewer contract refinements are in source-branch commit
7cdfad2a05fc20d2e7ed96db93e666df20689485. This exact post-merge source-branch commit updatesowlv2-005.feature_gaps_filedto winml-cli #1147. It remains on the source branch because ModelKitArtifacts PR #159 is already merged; no Lane A files are included in this model PR.Per-EP/device/precision results — including perf and eval data
Goal ladder
| Tier | Verdict | Evidence |
|---|---|---|
| L0 | PASS | Both exact CPU/cpu precision tuples were freshly configured, built, and structurally validated. fp32/fp16 build times were 100.8660367 s / 116.974988 s; both expose
input_ids INT32 [1,16],pixel_values FLOAT [1,3,960,960], andattention_mask INT32 [1,16], pluslogits,pred_boxes,text_embeds, andimage_embeds. || L1 | PASS | Both tuples completed 10 warmups and 100 measured processor-generated semantic-input iterations with memory capture. |
| L2 | PASS | Both tuples compared
logits,pred_boxes,text_embeds, andimage_embedsagainst pinned PyTorch on identical semantic inputs. |Performance
| Tier | EP / Device | Precision | Verdict | Mean | p50 | p90 / p95 / p99 | Std | Warmup mean | Throughput | RAM Δ (load + inference) | VRAM local/shared Δ |
|---|---|---|---|---:|---:|---:|---:|---:|---:|---:|---:|
| L1 | CPUExecutionProvider / cpu | fp32 | PASS | 2864.275 ms | 2868.799 ms | 2990.744 / 3090.821 / 4458.42 ms | 227.563 ms | 3129.52 ms | 0.35 samples/s | 1423.95 MB (504.39 + 919.56) | 0.0 / 0.0 MB |
| L1 | CPUExecutionProvider / cpu | fp16 | PASS | 3958.256 ms | 3943.525 ms | 4091.145 / 4127.269 / 4566.801 ms | 94.429 ms | 4021.603 ms | 0.25 samples/s | 3634.66 MB (618.49 + 3016.17) | 0.0 / 0.0 MB |
L2 all-output parity
Parity is against PyTorch checkpoint revision
d69b086b07123308a4e198343ab2824e1af7774aon the same processor-generated inputs, beforepost_process_grounded_object_detection.| Precision | Output | Shape | Cosine similarity | Max abs diff | Mean abs diff | RMSE | Additional task-facing measure |
|---|---|---|---:|---:|---:|---:|---|
| fp32 | logits |
[1,3600,1]| 0.9999999999973036 | 0.0002536773681640625 | 0.00003874407874213324 | 0.00005066664507799361 | sigmoid probability max Δ 1.0459867096952605e-09 || fp32 | pred_boxes |
[1,3600,4]| 0.9999999999978494 | 0.000020384788513183594 | 6.614572420302365e-07 | 1.2354488877881363e-06 | mean raw normalized cxcywh IoU 0.9999946354690188; center L2 4.988567341990188e-07; size L2 1.6024903863345032e-06 || fp32 | text_embeds |
[1,1,512]| 0.9999999999998044 | 1.1920928955078125e-07 | 2.1396012961361066e-08 | 2.7659271996813866e-08 | row cosine min/mean 0.9999999999998042 || fp32 | image_embeds |
[1,60,60,768]| 0.9999999999992097 | 0.00016033649444580078 | 7.003135723185441e-07 | 1.258130226559189e-06 | row cosine min 0.9999999999611946; mean 0.9999999999992424 || fp16 | logits |
[1,3600,1]| 0.9999985234500899 | 0.4004535675048828 | 0.03721526781717936 | 0.047675061767347246 | sigmoid probability max Δ 4.985980597621861e-07 || fp16 | pred_boxes |
[1,3600,4]| 0.9999983128330443 | 0.016967952251434326 | 0.0005751266507690565 | 0.001102209982320831 | mean raw normalized cxcywh IoU 0.9954116316743082; center L2 0.00043634357334799317; size L2 0.0013853381709355733 || fp16 | text_embeds |
[1,1,512]| 0.9999997517780107 | 0.0001614093780517578 | 0.00002433118910527554 | 0.000031142131733688554 | row cosine min/mean 0.9999997517780105 || fp16 | image_embeds |
[1,60,60,768]| 0.99999922301875 | 0.18775832653045654 | 0.0006581207882101428 | 0.0012534093656211827 | row cosine min 0.9999292538054624; mean 0.9999992292296191 |The fp16
pred_boxesmax-absolute delta 0.016967952251434326 fails the strict auxiliary0.005absolute check. L2 remains PASS because all outputs are present and the task-facing box criterion passes: mean raw normalized-box IoU is 0.9954116316743082 against the0.99threshold. This does not claim dataset mAP, query derivation, threshold stability, target-size rescaling, or final detection-list equivalence.Eval
| EP / Device | Precision | Verdict | Dataset | Revision | Subset | Exit | Metric |
|---|---|---|---|---|---|---:|---|
| CPUExecutionProvider / cpu | fp32 | CLI-BLOCKED |
detection-datasets/coco|cf0b22332314a937e9dc8a1957b21725430bb41d| none | 1 | none || CPUExecutionProvider / cpu | fp16 | CLI-BLOCKED |
detection-datasets/coco|cf0b22332314a937e9dc8a1957b21725430bb41d| none | 1 | none |Both tuples returned the same error before dataset/model execution:
Block reason: no zero-shot-object-detection schema or evaluator exists; fixed-label object detection is semantically non-interchangeable. Filed gap: winml-cli #1147.
Delta
Recipe versus fresh auto-config
| Recipe | JSON pointer | Auto-config baseline | Shipped | Reason |
|---|---|---|---|---|
| fp32 |
/export/input_tensors|[pixel_values,input_ids,attention_mask]|[input_ids,pixel_values,attention_mask]| Match the resolvedOwlv2ForObjectDetection.forwardorder and remain independently safe for positional ONNX naming. || fp16 |
/export/input_tensors|[pixel_values,input_ids,attention_mask]|[input_ids,pixel_values,attention_mask]| Same ordering repair. || fp16 |
/quant|null| generatedmode=fp16configuration withfp16_keep_io_types=true| Produce the required exact fp16 CPU candidate while retaining fp32 I/O. |All checkpoint dimensions and loader fields remain checkpoint-derived. The production recipe README is untouched.
General exporter change
HTPExporter._resolve_keyword_input_namesandHTPExporter._convert_model_to_onnxnow derive ONNXinput_namesfor keyword-generated multi-input exports from the inspectedforwardsignature filtered to the configured/generated input set. If inspection is unavailable or incomplete, configured order is preserved without guessing. Models with explicitget_export_args()retain their configured positional protocol; a dedicated regression test covers that behavior.This is consistent with the charter's class-of-models fix. Recipe-free acceptance passed in 106.191 s with exact semantic bindings (
input_ids INT32 [1,16],pixel_values FLOAT [1,3,960,960],attention_mask INT32 [1,16]), so acceptance is not dependent on the model-specific recipe ordering.Analyze summary — component level and op level
ANALYZE-PARTIAL-SUCCESS: public static rule analysis produced all 11 classification rows for each artifact, but the process exited 1 after host OpenVINO plugin registration failed with Error 126 (
onnxruntime_providers_shared.dllmissing). These classifications are static rule analysis, not accelerator runtime execution or fresh accelerator support.Rules provenance: public WinML CLI release v0.2.0,
rules-v0.2.0.zip, containing 1,746 parquet rule files for TensorRT RTX GPU, OpenVINO CPU/GPU/NPU, and QNN GPU/NPU.Component-level summary
| Artifact | Architecture coverage | Mapping | Actionable EP findings |
|---|---|---|---|
| fp32 | 12x causal text Transformer; 12x ViT-B/16 image Transformer; patch/text fusion; class, objectness, and box heads | 1007 mapped, 0 partial, 0 unmapped; confidence
mapped| TensorRT RTX and OpenVINO CPU/GPU/NPU unknown: Cast, Einsum, Sqrt. QNN GPU/NPU partial: Add, Div, Erf, Mul; unknown: Cast, Einsum, Sqrt; none unsupported. || fp16 | same regions | 1012 mapped, 0 partial, 0 unmapped; confidence
mapped| TensorRT RTX and OpenVINO CPU/GPU/NPU unknown: Cast, Einsum, Sqrt. QNN GPU/NPU partial: Add, Div, Erf, Expand, Mul; unknown: Cast, Einsum, Sqrt; none unsupported. |Op-level summary
| Artifact | Graph | Dominant operators | EP roll-up |
|---|---|---|---|
| fp32 | 1007 operators / 27 types | Reshape 235; Add 231; MatMul 199; Transpose 121; Mul 81; LayerNormalization 52; Sigmoid 25; Softmax 24 | TensorRT RTX/OpenVINO/QNN findings as above; no fully-supported EP group established by the rules. |
| fp16 | 1012 operators / 27 types | Reshape 235; Add 231; MatMul 199; Transpose 121; Mul 81; LayerNormalization 52; Sigmoid 25; Softmax 24 | TensorRT RTX/OpenVINO/QNN findings as above; no fully-supported EP group established by the rules. |
Rule-less results for CPUExecutionProvider/CPU, CUDAExecutionProvider/GPU, DmlExecutionProvider/GPU, MIGraphXExecutionProvider/GPU, and VitisAIExecutionProvider/NPU classify all operator types as unknown.
Reproduce commands
The checkpoint and dataset are pinned below. The exact Hub revision is first materialized into
$SNAPSHOTwithhuggingface_hub.snapshot_download; every WinML checkpoint load, processor load, and PyTorch reference then consumes that local snapshot.$INPUTSis a named semantic NPZ generated from a constant 960×960 RGB image and the text querya photo of a cat; this preserves the validation surface used for perf and parity.