Skip to content

recipe(vitpose-base-simple): add CPU keypoint detection configs#1195

Draft
fuliucansheng wants to merge 1 commit into
mainfrom
fuliucansheng/add-nielsr-vitpose-base-simple-recipe
Draft

recipe(vitpose-base-simple): add CPU keypoint detection configs#1195
fuliucansheng wants to merge 1 commit into
mainfrom
fuliucansheng/add-nielsr-vitpose-base-simple-recipe

Conversation

@fuliucansheng

Copy link
Copy Markdown
Contributor

Summary

Adds CPU recipe coverage for nielsr/vitpose-base-simple, a ViTPose keypoint-detection checkpoint. This is an L0 recipe-only contribution: current main resolves the model family but recipe-free winml config / winml build fail with empty exporter I/O, and this PR supplies the verified CPU fp32/fp16 recipe inputs and outputs.

Model metadata

What the model does: nielsr/vitpose-base-simple predicts human-pose keypoint heatmaps from an input image crop. WinML exports it as keypoint-detection with VitPoseForPoseEstimation.

Primary user stories:

Story Confidence
A user supplies a pose-cropped RGB image to obtain 17 keypoint heatmaps for human pose estimation. verified from checkpoint config, image processor metadata, and model architecture

Supported tasks:

Task Surface Confidence
keypoint-detection Transformers / Optimum ONNX / WinML export surface verified

Model architecture:

VitPoseForPoseEstimation
└── VitPoseBackbone
    ├── Patch embeddings (image 256x192, patch 16x16, channels 3, hidden 768)
    └── Encoder stack x12
        ├── self-attention (12 heads)
        └── MLP + GELU + residual/layernorm
└── Pose head -> heatmaps [B, 17, 64, 48]

Source/confidence: pinned checkpoint config resolves model_type: vitpose, architectures: [ViTPoseForPoseEstimation], image size [256, 192], patch size [16, 16], and backbone hidden size 768 with 12 layers and 12 attention heads.

Validation and support evidence

Baseline

Baseline was run from current origin/main at ace130f20e36df44ebf7de6cf0356235c8ee79fd with winml, version 0.2.0.

Probe Result
winml inspect PARTIAL: loader VitPoseForPoseEstimation, exporter VitPoseOnnxConfig, WinML class WinMLModelForGenericTask; task keypoint-detection; exporter input/output tensors are empty.
Optimum coverage VENDOR-ONLY for vitpose: vendor ONNX tasks include keypoint-detection; WinML adds no extra task override.
Recipe-free config FAIL: winml config -m nielsr/vitpose-base-simple -p fp32 --ep cpu --device cpu exits with Unexpected error: list index out of range.
Recipe-free build FAIL: winml build -m nielsr/vitpose-base-simple ... exits with Build failed: list index out of range.
L3 task metric HOST-BLOCKED: winml eval supports keypoint-detection, but the default local COCO keypoints dataset ~/.cache/winml/datasets/coco_keypoints_val2017 is absent on this host.

The checked-in recipe is seeded from existing same-family VitPose recipes and the checkpoint config: pixel_values [1,3,256,192] to heatmaps.

Goal

Effort: L0. Goal ceiling: L2. Outcome: L0 recipe-only.

Success means the checked-in CPU fp32/fp16 recipes repair the recipe-free build failure, produce structurally valid ONNX artifacts, run winml perf on CPU, and match the PyTorch reference heatmaps numerically with the same image tensor. L3 is blocked by missing local COCO keypoint data.

Outcome

Highest verified goal: L2 PASS on CPU for both fp32 and fp16. Coverage is full for the targeted EP set (cpu/cpu/fp32, cpu/cpu/fp16); no accelerator tuples are claimed.

Shipped recipes:

Recipe
examples/recipes/nielsr_vitpose-base-simple/cpu/cpu/keypoint-detection_fp32_config.json
examples/recipes/nielsr_vitpose-base-simple/cpu/cpu/keypoint-detection_fp16_config.json

Methodology friction observed: none. Model finding: this VitPose checkpoint needs explicit recipe I/O because current auto-config exposes empty tensors and fails with list index out of range.

Per-EP/device/precision results

Tier EP / Device Precision Verdict Evidence
L0 build CPUExecutionProvider / cpu fp32 PASS Recipe build complete in 33.2s; optimized model is loadable with input pixel_values [1,3,256,192] float32, output heatmaps [1,17,64,48], 419 nodes, FLOAT initializers, and 327.7 MB external data.
L0 build CPUExecutionProvider / cpu fp16 PASS Recipe build complete in 29.9s with --precision fp16; fp16 stage complete in 4.1s; optimized model is loadable with 421 nodes, FLOAT16 initializers present, and 163.9 MB external data.
L1 perf CPUExecutionProvider / cpu fp32 PASS Avg 34.97 ms, p50 34.07 ms, throughput 28.60 samples/sec, RAM total +389.6 MB.
L1 perf CPUExecutionProvider / cpu fp16 PASS Avg 33.18 ms, p50 33.90 ms, throughput 30.14 samples/sec, RAM total +395.5 MB; perf reports model precision fp16.
L2 compare CPUExecutionProvider / cpu fp32 PASS PyTorch vs ONNX heatmaps on the same deterministic image tensor: cosine 1.0, max absolute diff 2.952292561531067e-07.
L2 compare CPUExecutionProvider / cpu fp16 PASS PyTorch vs ONNX heatmaps on the same deterministic image tensor: cosine 0.9999979734420776, max absolute diff 0.00021735578775405884.
L3 eval CPUExecutionProvider / cpu fp32 HOST-BLOCKED winml eval -m ... --task keypoint-detection --samples 1 fails because default dataset ~/.cache/winml/datasets/coco_keypoints_val2017 is not present.
L3 eval CPUExecutionProvider / cpu fp16 HOST-BLOCKED Same missing-dataset blocker as fp32; no task metric is reported.

Delta

The recipe is not comparable to winml config output because winml config fails before writing a usable config. Relative to the failing auto path, the shipped recipes provide the missing I/O contract:

Field Shipped value Reason
export.input_tensors pixel_values float32 [1,3,256,192], range [0,1] Required by VitPoseForPoseEstimation.forward and the checkpoint image size.
export.output_tensors heatmaps Required output for keypoint detection; validated as [1,17,64,48].
loader task keypoint-detection, class VitPoseForPoseEstimation, type vitpose Matches current loader resolution and existing VitPose recipes.

The fp32 recipe uses quant: null; the fp16 recipe carries the fp16 quantization block and is built with --precision fp16. No source code or tests are changed, and examples/recipes/README.md is untouched.

Reducibility: this PR follows the existing VitPose recipe pattern and ships only exact CPU tuples verified here. The current auto-config failure is documented as a baseline gap; this model PR does not add a class-wide source fix.

Analyze summary

Static rule analysis completed with partial-success exit semantics: QNN/OpenVINO rows were complete, while VitisAI has no rule data and is all-unknown. This is compatibility analysis, not runtime execution.

Component-level summary

Artifact Architecture coverage Mapping Actionable EP findings
fp32 patch embeddings; 12x encoder attention/MLP; pose heatmap head 536 exported nodes tagged during HTP export; 419 optimized ONNX ops analyzed QNN NPU partial: GELU-related Div, Erf, Add, Mul; unknown Resize. OpenVINO NPU: unknown Resize. VitisAI: no rule data.
fp16 patch embeddings; 12x encoder attention/MLP; pose heatmap head 536 exported nodes tagged during HTP export; 421 optimized ONNX ops analyzed QNN NPU partial: GELU-related Div, Erf, Add, Mul; unknown Resize. OpenVINO NPU: unknown Resize. VitisAI: no rule data.

Op-level summary

Artifact Graph Dominant ops EP roll-up
fp32 419 ops / 12 types Add 110; MatMul 96; Reshape 50; Transpose 50; Mul 48; LayerNormalization 25; Softmax 12; Div 12 QNN: 406 supported, 12 partial, 0 unsupported, 1 unknown. OpenVINO: 418 supported, 0 partial, 0 unsupported, 1 unknown. VitisAI: 419 unknown.
fp16 421 ops / 13 types Add 110; MatMul 96; Reshape 50; Transpose 50; Mul 48; LayerNormalization 25; Softmax 12; Div 12 QNN: 408 supported, 12 partial, 0 unsupported, 1 unknown. OpenVINO: 420 supported, 0 partial, 0 unsupported, 1 unknown. VitisAI: 421 unknown.

Reproduce commands

$MODEL = "nielsr/vitpose-base-simple"
$OUT = "temp/repro_nielsr_vitpose_base_simple"

uv run winml inspect -m $MODEL --format json
uv run winml config -m $MODEL -p fp32 --ep cpu --device cpu -o "$OUT/config_fp32.json"
uv run winml build -m $MODEL -o "$OUT/baseline" --ep cpu --device cpu --no-analyze --no-compile --rebuild
uv run winml build -c examples/recipes/nielsr_vitpose-base-simple/cpu/cpu/keypoint-detection_fp32_config.json -m $MODEL -o "$OUT/fp32" --ep cpu --device cpu --no-analyze --no-compile --rebuild
uv run winml build -c examples/recipes/nielsr_vitpose-base-simple/cpu/cpu/keypoint-detection_fp16_config.json -m $MODEL -o "$OUT/fp16" --ep cpu --device cpu --precision fp16 --no-analyze --no-compile --rebuild
uv run winml perf -m "$OUT/fp32/model.onnx" --ep cpu --device cpu --iterations 5 --warmup 1
uv run winml perf -m "$OUT/fp16/model.onnx" --ep cpu --device cpu --iterations 5 --warmup 1
uv run winml eval --schema --task keypoint-detection
uv run winml eval -m "$OUT/fp32/model.onnx" --model-id $MODEL --task keypoint-detection --ep cpu --device cpu --samples 1
uv run winml analyze --model "$OUT/fp32/model.onnx" --ep all --output "$OUT/fp32/analyze_all.json"
uv run winml analyze --model "$OUT/fp16/model.onnx" --ep all --output "$OUT/fp16/analyze_all.json"

@fuliucansheng fuliucansheng added the model-scale-by-skill Model support PR created or maintained by the adding-model-support skill label Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

model-scale-by-skill Model support PR created or maintained by the adding-model-support skill

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant