From 5d33f6c3651b3eb4c6b10a650b2da2b418d6a7ed Mon Sep 17 00:00:00 2001 From: Shiyi Zheng Date: Mon, 13 Jul 2026 12:18:53 +0800 Subject: [PATCH 1/2] Add vitpose-plus-huge recipe and fix FP16 2GB protobuf limit Add keypoint-detection fp16 recipe for usyd-community/vitpose-plus-huge. The ViT-Huge fp32 export is ~3.4 GB, and ORT's convert_float_to_float16 runs shape inference by default, which serializes the proto and exceeds protobuf's 2 GB message limit (EncodeError). convert_to_fp16 now auto-detects large models (>=90% of 2 GB via ByteSize with a raise-fallback) and passes disable_shape_infer=True, unblocking all >2 GB models. Validated CPU-only: genuine fp16 (FLOAT16=948, FLOAT32=0), build 661.9s, perf P50 746.49ms. --- .../keypoint-detection_fp16_config.json | 61 +++++++++++++++++++ src/winml/modelkit/quant/fp16.py | 23 +++++++ 2 files changed, 84 insertions(+) create mode 100644 examples/recipes/usyd-community_vitpose-plus-huge/keypoint-detection_fp16_config.json diff --git a/examples/recipes/usyd-community_vitpose-plus-huge/keypoint-detection_fp16_config.json b/examples/recipes/usyd-community_vitpose-plus-huge/keypoint-detection_fp16_config.json new file mode 100644 index 000000000..7713b8e7d --- /dev/null +++ b/examples/recipes/usyd-community_vitpose-plus-huge/keypoint-detection_fp16_config.json @@ -0,0 +1,61 @@ +{ + "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, + 256, + 192 + ], + "value_range": [ + 0, + 1 + ] + } + ], + "output_tensors": [ + { + "name": "heatmaps" + } + ] + }, + "optim": {}, + "quant": null, + "compile": null, + "loader": { + "task": "keypoint-detection", + "model_class": "VitPoseForPoseEstimation", + "model_type": "vitpose" + }, + "eval": { + "task": "keypoint-detection", + "dataset": { + "path": "~/.cache/winml/datasets/coco_keypoints_val2017", + "build_script": "scripts/build_coco_keypoints.py", + "split": "validation", + "samples": 100, + "shuffle": true, + "seed": 42, + "columns_mapping": { + "input_column": "image", + "annotation_column": "objects", + "keypoints_key": "keypoints", + "bbox_key": "bbox", + "area_key": "area", + "box_format": "xywh" + } + } + } +} diff --git a/src/winml/modelkit/quant/fp16.py b/src/winml/modelkit/quant/fp16.py index b3a6fe3a3..e35a3e35c 100644 --- a/src/winml/modelkit/quant/fp16.py +++ b/src/winml/modelkit/quant/fp16.py @@ -64,10 +64,33 @@ def convert_to_fp16( if op_block_list: logger.info(" Keeping ops in FP32: %s", op_block_list) + # ORT's converter runs ONNX shape inference by default, which serializes the + # model to a single protobuf message. That serialization fails for models + # whose in-memory proto exceeds protobuf's hard 2 GB message limit + # (google.protobuf.message.EncodeError: Failed to serialize proto), e.g. + # ViT-Huge backbones. Disable shape inference for such models — the FP16 + # cast itself does not require inferred shapes. + protobuf_limit = 2 * 1024**3 + shape_infer_margin = int(protobuf_limit * 0.9) # stay safely under 2 GB + try: + # ByteSize() itself raises once the proto exceeds the 2 GB limit; that + # is already a definitive "too large" signal. + approx_size = model.ByteSize() + except Exception: + approx_size = protobuf_limit + disable_shape_infer = approx_size >= shape_infer_margin + if disable_shape_infer: + logger.info( + " Model is large (~%.2f GB); disabling shape inference during FP16 " + "conversion to avoid the 2 GB protobuf serialization limit.", + approx_size / 1024**3, + ) + converted: ModelProto = convert_float_to_float16( model, keep_io_types=keep_io_types, op_block_list=op_block_list, + disable_shape_infer=disable_shape_infer, ) # ORT's converter appends Cast nodes at the end of the node list (for From 0a301e9ad2eb92d30f46580e03205fa9a9b0ea0b Mon Sep 17 00:00:00 2001 From: Shiyi Zheng Date: Mon, 13 Jul 2026 13:47:30 +0800 Subject: [PATCH 2/2] recipe(vitpose-plus-huge): nest under cpu/cpu/ per tested-EP layout (_meta-058) --- .../{ => cpu/cpu}/keypoint-detection_fp16_config.json | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/recipes/usyd-community_vitpose-plus-huge/{ => cpu/cpu}/keypoint-detection_fp16_config.json (100%) diff --git a/examples/recipes/usyd-community_vitpose-plus-huge/keypoint-detection_fp16_config.json b/examples/recipes/usyd-community_vitpose-plus-huge/cpu/cpu/keypoint-detection_fp16_config.json similarity index 100% rename from examples/recipes/usyd-community_vitpose-plus-huge/keypoint-detection_fp16_config.json rename to examples/recipes/usyd-community_vitpose-plus-huge/cpu/cpu/keypoint-detection_fp16_config.json