Skip to content

feat(config): add dynamic export controls to config command#1106

Open
xieofxie wants to merge 8 commits into
mainfrom
hualxie/dynamic_config
Open

feat(config): add dynamic export controls to config command#1106
xieofxie wants to merge 8 commits into
mainfrom
hualxie/dynamic_config

Conversation

@xieofxie

Copy link
Copy Markdown
Contributor

Summary

Adds the dynamic export controls (--input-specs, --export-config, --dynamic-axes) to winml config, bringing it to parity with winml build / winml perf / winml export. This is a follow-up to #1083, which introduced these controls for build/perf and the shared cli_utils option/loader helpers.

What changed

  • commands/config.py
    • Adds the three shared options (input_specs_option, export_config_option, dynamic_axes_option) and their params.
    • Loads a sparse override mapping via cli_utils.load_export_overrides (validates early, doesn't clobber auto-detected fields).
    • New _merge_export_overrides helper applies them via the shared merge_export_overrides, so --input-specs patches the auto-resolved input_tensors by name (unlisted inputs and their dtype/value_range preserved) and symbolic dims re-derive dynamic axes through WinMLExportConfig.__post_init__.
    • Wired into the single-config, --module list, and composite-pipeline paths.
    • Rejected for pre-exported ONNX inputs and for configs with export=null (clear UsageError).
    • Shows the provided files in the console summary; adds docstring examples.
  • docs/commands/config.md: three new flag rows, an example, and a pitfall note.
  • tests/unit/commands/test_config_cli.py: TestConfigExportControls — help visibility, override forwarding/parsing, no-op when absent, and ONNX rejection.

Verification

  • ruff check + ruff format clean.
  • tests/unit/commands/test_config_cli.py (55) and test_config_composite_resolution.py + test_config_value_priority.py (63) pass.
  • Doc flag-alignment check passes.

Mirror build/perf by adding --input-specs, --export-config, and
--dynamic-axes to `winml config`. Overrides are applied via the shared
merge_export_overrides helper so --input-specs patches auto-resolved
input tensors by name (preserving unlisted inputs and their
dtype/value_range) and symbolic dims re-derive dynamic axes. Wired into
the single, --module list, and composite-pipeline paths; rejected for
pre-exported ONNX inputs and configs with export=null.

Docs and config CLI tests updated.
@xieofxie xieofxie requested a review from a team as a code owner July 14, 2026 05:15

@DingmaomaoBJTU DingmaomaoBJTU left a comment

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.

A few notes on the new export controls — mainly the composite-pipeline fan-out and test coverage. Otherwise nice work bringing this to parity with build/perf.

Comment thread src/winml/modelkit/commands/config.py Outdated
Comment thread tests/unit/commands/test_config_cli.py Outdated
Comment thread src/winml/modelkit/commands/config.py Outdated
Hualiang Xie added 3 commits July 15, 2026 16:03
- Reject --input-specs/--export-config/--dynamic-axes for composite
  (multi-component) models instead of fanning the same overrides across
  sub-components with distinct inputs, which could append bogus inputs.
- Move the pre-exported-ONNX rejection ahead of loading/validating the
  override JSON so the error names the ONNX input (not a downstream
  "Invalid export configuration") and skips needless file I/O.
- Replace mock-based tests with integration coverage that lets
  merge_export_overrides run and asserts on to_dict(): by-name patching,
  unlisted-input preservation, symbolic-dim -> dynamic_axes derivation,
  export=null rejection, the --module list path, composite rejection, and
  ONNX rejection ordering.
- Document the composite rejection in config.md.

@DingmaomaoBJTU DingmaomaoBJTU left a comment

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 the export-controls addition to winml config. Overall this is clean and mirrors winml build faithfully — the shared merge_export_overrides / _patch_input_tensors by-name patching, the export=null guard, and the up-front ONNX rejection (with its ordering test) are all solid, and the integration-style tests that let merge_export_overrides actually run are a nice improvement over pure mocks. No correctness bugs found. A few non-blocking notes below: two minor UX/consistency points and one trivial nit.

Comment thread src/winml/modelkit/commands/config.py Outdated
Comment thread src/winml/modelkit/commands/config.py Outdated
Comment thread src/winml/modelkit/commands/config.py Outdated
…ejection

Address PR #1106 review comments:

- --module now rejects --input-specs/--export-config/--dynamic-axes up
  front instead of fanning them onto every submodule config (would append
  bogus inputs on submodules with different input names).
- Reject the ONNX / --module / composite paths on raw flag presence before
  loading the override JSON, so the path-specific error wins over a
  downstream "Invalid export configuration" (mirrors the ONNX guard).
- Move load_export_overrides below composite resolution; the single HF
  config path is now the only consumer.
- Simplify Path(input_specs).name to input_specs.name (already Path|None).
- Docs + tests updated: --module rejection, composite-precedes-JSON test.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

@DingmaomaoBJTU DingmaomaoBJTU left a comment

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.

Thanks for the follow-up — this cleanly resolves all three earlier notes: --module and composite now both reject on raw flag presence before load_export_overrides, so the path-specific error wins over Invalid export configuration; load_export_overrides is scoped to the single-HF path (verified export_overrides is still defined before _merge_export_overrides on that branch); the Path(...).name nit is gone; and the docs read accurately. One new issue from the test refactor — see inline.

Comment thread tests/unit/commands/test_config_cli.py
Hualiang Xie and others added 2 commits July 16, 2026 16:00
The previous refactor fused two tests: the export=null assertion body was
left orphaned at the tail of test_composite_rejection_precedes_json_validation,
so test_merge_export_overrides_rejects_export_null no longer existed as a
discrete test. Split it back into its own method.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…hang

build calls resolve_composite_components before dispatching, which resolves
the model config from HuggingFace Hub (AutoConfig.from_pretrained) over the
network. The build CLI plumbing tests only mocked _run_single_build, so this
detection call stayed live: repeated metadata requests get throttled and
huggingface_hub's retry backoff sleeps, making a later unrelated test appear
to hang mid-run.

Add an autouse fixture that defaults resolve_composite_components to None
(non-composite), matching the existing mock_task_model_compatibility_validator
pattern that keeps these tests off HF resolution paths. Composite-specific
tests already override it with their own patch, which nests inside and wins.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

@DingmaomaoBJTU DingmaomaoBJTU left a comment

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.

Approving. All review feedback is addressed:

  • --input-specs/--export-config/--dynamic-axes are rejected up front (on raw flag presence, before loading the JSON) for the ONNX, --module, and composite paths, so the path-specific error wins over a downstream Invalid export configuration; load_export_overrides is scoped to the single-HF path and _merge_export_overrides still applies there.
  • ae412b3c splits the accidentally-fused test back out — test_merge_export_overrides_rejects_export_null is a discrete method again and the composite test ends cleanly.
  • d7aeaa8a (build-test autouse stub for resolve_composite_components) is a sound, well-targeted flake fix that matches the existing autouse pattern; composite-specific tests still override it.

Docs read accurately. Nice work. (Note: I reviewed by reading the diff/branch; the suite couldn't be run on my ARM64 host, so a green CI run is worth a final glance before merge.)

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.

2 participants