Repository navigation
Add standalone OpenVINO EPContext compilation support - #2732
Xiaoyu Z (xiaoyu-work) wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Workflow initialization can reject OpenVINO before compilation, and device matching and failed-output cleanup need correction.
3 open findings
What changed in this PR
Adds standalone OpenVINO EPContext compilation to Olive’s existing context-generation pass, without model packaging.
Changes:
- Adds OpenVINO AOT/JIT compilation, device filtering, and virtual targets.
- Validates generated context artifacts while preserving QNN behavior.
- Documents configuration and adds focused tests.
| File | Description |
|---|---|
| test/passes/onnx/test_context_binary.py | Tests OpenVINO options, registration ownership, and output validation. |
| olive/passes/onnx/context_binary.py | Adds OpenVINO compilation and explicit provider dispatch. |
| olive/olive_config.json | Declares OpenVINO and CPU/GPU/NPU support. |
| docs/source/reference/pass.rst | Documents standalone compilation and limitations. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Preetha Veeramalai (@preetha-intel).. Can you please review. |
|
This EpctxBinaryGenerator is limited to the single model run for a single run where its not linked to CompositeModelHandler which helps in creating the production level ModelPackage. Both are updated in the original parent PR-2717 |
Mayuresh Varerkar (MayureshV1)
left a comment
There was a problem hiding this comment.
Thanks Xiaoyu Z (@xiaoyu-work) for extracting this. Single-device OpenVINO compilation looks solid: it honours embed_context/disable_cpu_fallback, rejects weight_sharing, parses booleans and enums properly, and cleans up after failed runs.
Before we go further, could you clarify the intent with respect to #2717? Is the plan for #2732 to replace the EPContextBinaryGenerator changes in #2717, with those changes then dropped from #2717? If so, #2732 would need to merge first and #2717 would be rebased to contain only ORTModelPackage. We're fine with that order; we just want to agree on it so the two PRs don't keep conflicting in context_binary.py.
A few questions on scope:
-
Multi-device compilation isn't covered yet.
ORTModelPackagein #2717 consumes a composite model produced by compiling one source model for several devices in one run (target_devices): one component per device, each in its own<device_id>folder, with component names equal to the device IDs (these become variant names). It also relies on these model attributes:source_model_path(where the shared weights come from),device_idper component, andno_flatten. #2732 is single-device and rejects composite input. Do you plan to add this to #2732, or should it come in a follow-up PR on top of it before #2717 is rebased? -
Weightless compilation by default. The docs in #2732 say weightless compilation isn't enabled by default. For packaging, weightless is the main use case: each device variant references one shared copy of the weights instead of duplicating them. Should the pass keep weightless opt-in (users set
ep.enable_weightless) and document it as the recommended setting for model packages, or turn it on by default when compiling for packaging? Either is fine with us; we'd just like it to be explicit. Note that ORT only defines theep.enable_weightlesskey from 1.30; earlier releases defineep.enable_weightless_ep_context_nodes, so the docs should say which ORT version the recommended setting applies to. -
Per-device binary naming (
set_ep_context_binary_information). #2717 usesModelCompiler.set_ep_context_binary_informationto control the folder and name of each device's binary. The underlying C API has been available since ORT 1.23, but the Python binding is only being added in microsoft/onnxruntime#33640 (not merged yet, expected in ORT 1.32). Is this something you'd want in this pass? If so, it would need to be optional (used only when the binding is available).
Inline comments below.
| and ep_device.device.type == device_type | ||
| and cls._ep_device_matches(ep_device, ep_device_filters or {}) | ||
| ] | ||
| if len(selected) != 1: |
There was a problem hiding this comment.
When the plugin is registered both by maybe_register_ep_libraries and under ovep_registration.virtual, a physical and a virtual NPU can report the same device_id (e.g. B03E on PTL), so {"device_id": "B03E"} matches two devices. Could selection prefer the entry with npu_platform metadata when a device_id filter matches more than one, or document that npu_platform is required in this case?
| "optimum-intel>=1.26.0", | ||
| "onnxruntime-openvino" | ||
| "onnxruntime-openvino", | ||
| "onnxruntime-ep-openvino" |
There was a problem hiding this comment.
Is installing onnxruntime-openvino and onnxruntime-ep-openvino together intended? Both provide OpenVINOExecutionProvider, and onnxruntime-openvino is now deprecated. Our preference is to pull in and use onnxruntime + onnxruntime-ep-openvino instead.
| raise ValueError("model_compiler_options are only supported with compile_flow='aot'.") | ||
| compiler_kwargs = {} | ||
| if compile_flow == "aot": | ||
| if not hasattr(ort, "ModelCompiler"): |
There was a problem hiding this comment.
Could we add a minimum ORT version check for the plugin-EP path, so older ORT fails with a clear message instead of an AttributeError? The OpenVINO plugin supports ORT 1.23.0+ (the plugin EP registration, get_ep_devices/add_provider_for_devices and the compile API used here are all in 1.23), so >= 1.23.0 looks like the right floor.


Describe your changes
Extract the OpenVINO plugin EP context-compilation support from #2717 into a standalone change to
EPContextBinaryGenerator. This PR intentionally excludesOpenVINOModelPackage, package manifests, shared assets, and multi-device package assembly._run_qnnand_run_openvino; preserve QNN's existing session-based compilation, composite/weight-sharing behavior, metadata, and optional GenAI config updates.ModelCompiler, and JIT viaInferenceSession.embed_context,disable_cpu_fallback, and typed logging options. Parse JSON boolean/compiler enum values correctly and avoid redundant AOT session entries already controlled by the compile API.Review fixes
0xprefix, leading zeros, and integer IDs.Validation
& .\.venv\Scripts\python.exe -m pytest test\passes\onnx\test_context_binary.py test\common\test_ort_inference.py test\systems\test_local.py -q— passed: 72 tests; 4 QNN hardware tests skipped because QNNExecutionProvider is unavailable.lintrunner olive\common\ort_inference.py olive\passes\onnx\context_binary.py test\common\test_ort_inference.py test\passes\onnx\test_context_binary.py docs\source\reference\pass.rst— passed, including PYLINT.device_id: 0x00B03E.Release note:
EPContextBinaryGeneratornow supports standalone OpenVINO plugin EP compilation through ORT's AOT/JIT APIs, including automatic Windows LocalSystem plugin discovery, virtual target selection, embedded/external context data, and clean retries after failed compilation.Checklist before requesting a review
lintrunner -a(Optional) Issue link
Extracted compilation support from #2717; the original packaging PR remains separate.