Skip to content

Integrate CGIR workflow (export, perf, eval) into winml-cli - #1426

Merged
Zhenchao Ni (zhenchaoni) merged 3 commits into
mainfrom
private/zhenni/cgir
Sep 18, 2026
Merged

Zhenchao Ni (zhenchaoni) merged 3 commits into
mainfrom
private/zhenni/cgir

Conversation

@zhenchaoni

Copy link
Copy Markdown
Member

Summary

Integrates CGIR export, configuration, build, compilation, performance measurement, and output comparison into WinML CLI.

Three inference workflows are supported:

Workflow Input Runtime / Backend
Offline CGIR Standalone MLIR Windows ML Runtime / CGC
WinMLCG EP ONNX ONNX Runtime / WinMLCG EP
Online CGC compilation ONNX Windows ML Runtime / CGC

Examples below use ResNet50 and the installed preview Runtime/EP packages. --no-sync preserves those packages in the local environment.

Export ONNX and CGIR

# Export Hugging Face model to ONNX
uv run --no-sync winml export -m microsoft/resnet-50 -o temp\demo-cgc\resnet50.onnx --overwrite

# Export Hugging Face model directly to standalone CGIR
uv run --no-sync winml export -m microsoft/resnet-50 -o temp\demo-cgc\resnet50.mlir --target cgir --overwrite

# Alternatively, convert an existing ONNX model to CGIR
uv run --no-sync winml export -m temp\demo-cgc\resnet50.onnx -o temp\demo-cgc\resnet50.mlir --target cgir --overwrite

Performance: Three Inference Workflows

# 1. Standalone MLIR through Windows ML Runtime
uv run --no-sync winml perf -m temp\demo-cgc\resnet50.mlir --runtime winml-runtime --device gpu --output temp\demo-cgc\perf-mlir.json

# 2. ONNX through ONNX Runtime + WinMLCG EP
uv run --no-sync winml perf -m temp\demo-cgc\resnet50.onnx --runtime winml-ort --ep winmlcg --device gpu --output temp\demo-cgc\perf-winmlcg.json

# 3. ONNX through Windows ML Runtime with online CGC compilation
uv run --no-sync winml perf -m temp\demo-cgc\resnet50.onnx --runtime winml-runtime --backend cgc --device gpu --iterations 100 --output temp\demo-cgc\perf-runtime-cgc.json

perf defaults to automatic runtime selection: MLIR selects winml-runtime; ONNX selects winml-ort. Explicit runtime selection remains available. With winml-runtime, ONNX defaults to the CGC backend.

Compare Against the Original ONNX

Use ORT CPU as the reference and compare the outputs from each workflow. These examples use one sample for a quick check; increase --samples for broader coverage.

# MLIR vs original ONNX
uv run --no-sync winml eval --mode compare -m temp\demo-cgc\resnet50.mlir --runtime winml-runtime --device gpu --reference temp\demo-cgc\resnet50.onnx --reference-device cpu --samples 1 --output temp\demo-cgc\compare-mlir.json

# WinMLCG EP vs original ONNX
uv run --no-sync winml eval --mode compare -m temp\demo-cgc\resnet50.onnx --runtime winml-ort --ep winmlcg --device gpu --reference temp\demo-cgc\resnet50.onnx --reference-device cpu --samples 1 --output temp\demo-cgc\compare-winmlcg.json

# Runtime online CGC vs original ONNX
uv run --no-sync winml eval --mode compare -m temp\demo-cgc\resnet50.onnx --runtime winml-runtime --backend cgc --device gpu --reference temp\demo-cgc\resnet50.onnx --reference-device cpu --samples 1 --output temp\demo-cgc\compare-runtime-cgc.json

Compile a WinMLCG EPContext Model

uv run --no-sync winml compile -m temp\demo-cgc\resnet50.onnx --ep winmlcg --device gpu -o temp\demo-cgc\resnet50-winmlcg-ctx.onnx --overwrite

Generate Configs and Build

--backend cgc prepares the model and converts it to CGIR. --ep winmlcg prepares ONNX for the WinMLCG EP without adding CGIR conversion. Use one selector, not both.

# Generate and review a CGC build configuration
uv run --no-sync winml config -m temp\demo-cgc\resnet50.onnx --backend cgc --device gpu -o temp\demo-cgc\config-cgc.json --overwrite

# Build using that configuration
uv run --no-sync winml build -c temp\demo-cgc\config-cgc.json -m temp\demo-cgc\resnet50.onnx -o temp\demo-cgc\build-cgc

# Or auto-generate the configuration and build in one command
uv run --no-sync winml build -m temp\demo-cgc\resnet50.onnx --backend cgc --device gpu -o temp\demo-cgc\build-cgc-auto

# Generate a configuration for WinMLCG EP
uv run --no-sync winml config -m temp\demo-cgc\resnet50.onnx --ep winmlcg --device gpu -o temp\demo-cgc\config-winmlcg.json --overwrite

# Prepare ONNX for WinMLCG EP with an auto-generated configuration
uv run --no-sync winml build -m temp\demo-cgc\resnet50.onnx --ep winmlcg --device gpu -o temp\demo-cgc\build-winmlcg

These configurations apply CGC compatibility rules and default FP16 preparation. Use --no-quant to preserve the existing ONNX precision, and --rebuild to regenerate existing build artifacts. Review output accuracy, particularly when lossy compatibility rules such as cubic-to-linear Resize are applied.

Standalone Compatibility Optimization

Compatibility rules can also be selected individually before export or inference:

uv run --no-sync winml optimize -m temp\demo-cgc\resnet50.onnx -o temp\demo-cgc\resnet50-compatible.onnx --disable-ort-graph-optimization --enable-omit-empty-resize-inputs --enable-tile-repeats-initializer-to-constant --enable-fold-scalar-initializer-casts --enable-resize-tf-half-pixel-for-nn-to-asymmetric

Select a Specific GPU

# List devices and their LUIDs
uv run --no-sync winml sys

# Replace the placeholder with a LUID from winml sys
uv run --no-sync winml perf -m temp\demo-cgc\resnet50.mlir --runtime winml-runtime --device gpu --device-luid "<LUID>"

Runtime CGC fails explicitly if the selected adapter cannot be resolved; it does not silently switch to another GPU.

Squash nine CGC commits from winml-cli-mirror, from ce58e98f391b2bc6a755b888b45f8277a2c9a9be through 49d67c2 (inclusive).

Include CGC build/config integration, compatibility rewrites, adapter selection, Foundry ABI updates, Runtime output requests, documentation, and unit tests.
@zhenchaoni
Zhenchao Ni (zhenchaoni) requested a review from a team as a code owner September 17, 2026 06:35
Comment thread src/winml/modelkit/config/build.py Dismissed
Comment thread src/winml/modelkit/config/precision.py Dismissed
Comment thread src/winml/modelkit/optim/pipes/cgir_rewrite.py Fixed
Comment thread src/winml/modelkit/pattern/cgc/cgc_constant_folding.py Fixed
Comment thread src/winml/modelkit/pattern/cgc/dft_patterns.py Fixed
Comment thread src/winml/modelkit/session/runtime_session.py Fixed
Comment thread tests/unit/export/cgc/test_exporter.py Fixed
Comment thread tests/unit/models/auto/test_auto_onnx.py Fixed
Comment thread tests/unit/optim/pipes/test_pipe_cgir_rewrite.py Fixed
Comment thread tests/unit/session/test_runtime_session.py Fixed

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI follow-ups for the reviewed commit. These comments identify failing checks and test updates; they do not assert a demonstrated production inference regression.

Comment thread src/winml/modelkit/commands/build.py
Comment thread src/winml/modelkit/utils/constants.py
Comment thread tests/unit/commands/test_optimize_cli.py Outdated
Comment thread src/winml/modelkit/pattern/cgc/gridsample_patterns.py

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed this integration in the context of the earlier mirror PR review, including the retained adapter/scalar/error-handling fixes, added CGC constant/DQ/GridSample/Identity rewrites, exporter publication rollback, and Runtime/build/eval routing. No blocking findings identified. All reported PR CI checks pass and git diff --check passed. Seven Foundry-binding tests passed locally in an isolated harness (two missing pytest-timeout configuration warnings). The broader local exporter/runtime test attempts could not collect under that minimal harness because package exports/native dependencies were not available; those attempts are not counted as passing. Native Windows ML/Foundry inference, rewrite numerical suites and the full unit suite were not rerun locally.

@zhenchaoni
Zhenchao Ni (zhenchaoni) merged commit ad64d0a into main Sep 18, 2026
9 checks passed
@zhenchaoni
Zhenchao Ni (zhenchaoni) deleted the private/zhenni/cgir branch September 18, 2026 01:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants