recipe(swin2sr): add QNN NPU configs - #1396
Qiong Wu (qiowu) (DingmaomaoBJTU) wants to merge 1 commit into
Conversation
Independent reviewer verdict: APPROVE
Scope and evidenceThe diff is one commit containing exactly three canonical LF recipe JSON files under
All three use Tuple disposition
Coverage is correctly reported as Quality and residual riskThe frozen license/Ruff/mypy and five-partition results total 8,607 passed with zero failures. Reuse is valid because source, workflow, test, and Residuals are explicit: W8A8 has low fixed-input quality; FP16 is absent after exhausted native HTP failures; image-to-image Eval has no task metric; analyzer results are static; and proposed methodology findings Orchestrator follow-up is required only to record terminal APPROVE, perform the separately owned promotion-handoff update, and disposition the Lane A proposals. Keep this PR in DRAFT. |
Summary
Adds QNN/NPU recipes for
caidas/swin2SR-classical-sr-x2-64, a 2x image-super-resolution checkpoint, in FP32, W8A8, and W8A16. This is an L0★ effort with an L0 recipe-only outcome; the three shipped tuples reached L2 PASS for fixed-input performance and tensor parity. The required FP16 tuple is terminalEXHAUSTED-FAILat L0, so coverage isrequired-tuples-contain-exhausted-failures, neither full nor partial. W8A8 completed L2 but has explicitly low numerical quality.Model metadata
What the model does
This Swin2SR checkpoint accepts a 64 x 64 RGB image tensor and reconstructs an RGB image at twice the spatial resolution (128 x 128) for image super-resolution.
caidas/swin2SR-classical-sr-x2-64model card and config (image_size=64,num_channels=3,upscale=2,upsampler=pixelshuffle); recipe-free ONNX I/Opixel_values[1,3,64,64] -> reconstruction[1,3,128,128].verified.Primary user stories
Swin2SRForImageSuperResolution.forwardreturnsImageSuperResolutionOutput.reconstruction.verified.Supported tasks
image-to-imageacross the checkpoint, Transformers, Optimum ONNX, and WinML support surfaces.Swin2SRForImageSuperResolution; Optimum 2.1.0 registersswin2sr/image-to-image; WinML inspect resolvesimage-to-image,AutoModelForImageToImage, andSwin2srOnnxConfig.verified.Model architecture
The concrete task model normalizes and embeds the image, runs six residual Swin Transformer stages with six shifted-window layers per stage at width 180, restores the spatial feature map through a residual body convolution, and applies a pixel-shuffle x2 reconstruction head.
Swin2SRForImageSuperResolutionandPixelShuffleUpsamplersource (verified). The recipe-free export reported 884 modules, 278 traced modules, and 12.1M parameters, with encoder and pixel-shuffle scopes present in ONNX.Validation and support evidence
Baseline
maincommit169a6f0122d1e1dd7d60c9605b5f19add26a209b, WinML 0.3.0, model revisioncee1c923c6a37361c6e5650b65dcf4be821e5d52.pixel_valuesfloat32[1,3,64,64]toreconstructionfloat32[1,3,128,128].959.390/957.538/1020.707 ms, throughput1.04 samples/s.winml eval --schema --task image-to-imageexited 2 becauseimage-to-imageis not registered; no task metric was produced.AutoModelForImageToImage,image-to-image, QNN/NPU, and static uint8-weight/uint16-activation quantization. The contribution freezes measured choices instead of leaving autoconf active.VENDOR-ONLY; Optimum already registeredswin2srforfeature-extractionandimage-to-image, and WinML added no task registration.Goal
L0★.L2, unchanged. Success required every QNN/NPU precision to build recipe-only with exact effective semantics, run fixed-input QNN performance, and complete fixed-input PyTorch parity.L0recipe-only; no source implementation, evaluator implementation, or optimizer work belongs to this contribution.Outcome
The shipped outcome is L0 with three exact-tuple recipes:
qnn/npu/fp32,qnn/npu/w8a8, andqnn/npu/w8a16. Each reached L0/L1/L2 PASS. The reachable requiredqnn/npu/fp16tuple is terminalEXHAUSTED-FAIL, with no candidate shipped and no deferred tuple; therefore the exact coverage classification isrequired-tuples-contain-exhausted-failures, neither full nor partial.No source code, tests, dependencies, lockfiles, or
examples/recipes/README.mdchanged. Model knowledge was captured only in run-local evidence and is not committed in this model PR. Methodology friction was observed; the proposed Lane A follow-up remains separate and no skill commit or skill PR is claimed here.Repository gates passed: license insertion check, Ruff, mypy across 442 source files, and five non-hardware pytest partitions. Aggregate pytest results were 8,607 passed, 77 skipped, 2 xfailed, 1 deselected, and no failures. The Node-reached partition passed with Node 20.20.0 while the workflow pins Node 22; this is not a Node 22 claim.
Per-EP/device/precision results
Performance used 20 warmups and 30 measured iterations per candidate.
W8A8 is not a high-quality result: its L2 command completed, but the low cosine and high NRMSE above are retained without upgrade or softening. These are single fixed-input tensor comparisons, not task-level image-quality measurements.
W8A16 also reproduced the separately sealed A1/B1/B2/A2 paired result:
17.975235769464405%gain with bootstrap 95% CI[17.889904562599636%, 18.04282472170429%]. That paired result used 20 warmups and 100 measured iterations per session; it is distinct from the fresh 30-iteration performance row above.FP16 exhausted two real attempts. Both completed FLOAT16 conversion and then crashed during native QNN HTP compilation with exit
-1073741819 (0xC0000005). The recipe-owned attempt usedauto=false,quant.mode=fp16, FP32 public I/O, and the complete QNN provider options, but produced no Build complete marker, finalmodel.onnx, wrapper, or EPContext. The failed candidate is absent; switching from QNN HTP/NPU to QNN GPU or adding shared runtime capability would change scope.Functional smoke Eval
All four tuples are
CLI-BLOCKED:winml eval --schema --task image-to-imageexits 2 because WinML 0.3.0 has no image-to-image evaluator registration. The missing capability includes a paired low/high-resolution dataset adapter, Swin2SR prediction decoder, and super-resolution task metric. No dataset was processed and no task metric, representative accuracy, or benchmark-quality image claim is made.Delta
The final diff contains exactly these checked-in recipes:
examples/recipes/caidas_swin2SR-classical-sr-x2-64/qnn/npu/image-to-image_fp32_config.jsonexamples/recipes/caidas_swin2SR-classical-sr-x2-64/qnn/npu/image-to-image_w8a8_config.jsonexamples/recipes/caidas_swin2SR-classical-sr-x2-64/qnn/npu/image-to-image_w8a16_config.jsonAll three recipes change
/autofrom the schema defaulttruetofalse; change/optimfrom{}to{"gelu_fusion":true,"highdimRTR_lowdimRTR":true,"matmul_add_fusion":false}; add/compile/provider_options/htp_performance_mode="burst"; and add/compile/provider_options/htp_graph_finalization_optimization_mode="3". Effective QNN options aredevice_type=NPU,htp_performance_mode=burst, and finalization mode3. Canonical line-ending normalization does not change runtime configuration semantics: the committed recipes materialize to the tested effective configs./quant: static uint8-weight/uint16-activation object ->null/quant/activation_type:uint16->uint8;/quant/model_id: planner-local source ->caidas/swin2SR-classical-sr-x2-64;/quant/seed:null->42/quant/model_id: planner-local source ->caidas/swin2SR-classical-sr-x2-64;/quant/seed:null->42The failed FP16 candidate was removed. This remains consistent with the L0★ per-model recipe resolution; recipe-free acceptance is not required. There are no code changes, and the production recipe README remains untouched.
Analyze summary - component and op levels
All four static scans are
ANALYZE-PARTIAL-SUCCESS: each all-EP command exited 1, but each emitted all 12 requested EP/device rows with complete classification arrays. This is static compatibility analysis, not runtime execution or provider-attributed hotspot evidence; runtime claims come only from the independent build, performance, and parity results above.Component-level summary
Slice; unsupported: noneExpand; OpenVINO/NPU partial:Slice; unsupported: noneMatMulQDQ; unsupported: nonePartial-node counts are subsets of mapped nodes and are not added to mapped plus unmapped totals. The remaining 73, 73, 37, and 37 optimizer-generated nodes are explicitly unmapped because their mapped neighbors disagree or provide no unique component owner.
Op-level summary
Slice; unsupported: noneExpand; OpenVINO/NPU partial:Slice; unsupported: noneMatMulQDQ; unsupported: noneCUDA/GPU, MIGraphX/GPU, TensorRT/GPU, DML/GPU, CPU/CPU, and VitisAI/NPU are rule-less groups in these static results. Their operator classifications are unknown, not unsupported. Static operator frequency and partial-node counts are not runtime hotspots.
Reproduce commands
These are the tester-normalized public commands. Resolve the durable model ID at the pinned revision to a local snapshot, and provide an equivalent fixed performance input NPZ.