Skip to content

[TorchAO] [OVQuantizer] Update Torch AO Dependency and Refactor Executorch Tests#3842

Open
anzr299 wants to merge 59 commits intoopenvinotoolkit:developfrom
anzr299:an/executorch_tests
Open

[TorchAO] [OVQuantizer] Update Torch AO Dependency and Refactor Executorch Tests#3842
anzr299 wants to merge 59 commits intoopenvinotoolkit:developfrom
anzr299:an/executorch_tests

Conversation

@anzr299
Copy link
Collaborator

@anzr299 anzr299 commented Jan 15, 2026

Changes

Include tests for executorch, OVQuantizer
Remove OVQuantizer from NNCF
Move the tests in appropriate directory

Reason for changes

Migrate from torch.ao -> torchao

Notable differences in torch.ao and torchao implementation which affect test references:

  1. Constant folding in torch.ao produced the new constant with the name _frozen_param{index}. In the new torchao implementation it keeps the same name as the node being replaced with.
  2. The old deprecated XNNPACK Quantizer was being used before which is now changed to point to the new XNNPACKQuantizer implementation in https://github.com/pytorch/executorch/tree/main/backends/xnnpack/quantizer which now explicitly quantizes the conv_transpose2D operator and its weights.

Reference graphs changed due to above:

  1. tests/executorch/data/ao_export_quantization_OpenVINOQuantizer/mobilenet_v3_small.dot
  2. tests/executorch/data/ao_export_quantization_OpenVINOQuantizer/resnet18.dot
  3. tests/executorch/data/ao_export_quantization_OpenVINOQuantizer/swin_v2_t.dot
  4. tests/executorch/data/ao_export_quantization_OpenVINOQuantizer/synthetic_transformer.dot
  5. tests/executorch/data/ao_export_quantization_OpenVINOQuantizer/unet.dot
  6. tests/executorch/data/ao_export_quantization_OpenVINOQuantizer/vit_b_16.dot
  7. tests/executorch/data/ao_export_quantization_OpenVINOQuantizer/yolo11n_sdpa_block.dot
  8. tests/executorch/data/XNNPACKQuantizer/unet.dot (Due to difference Number 2)
  9. tests/executorch/data/XNNPACKQuantizer/unet_ref_qconfig.json ((Due to difference Number 2))

Related tickets

CVS-176783

Tests

PTQ Conformance - PTQ-789 - Pass
Examples - https://github.com/openvinotoolkit/nncf/actions/runs/21204888584 - Pass
WC conformance - https://github.com/openvinotoolkit/nncf/actions/runs/21204893707 - Pass

pytest tests/executorch results:
image
All tests in tests/executorch pass

@anzr299 anzr299 requested a review from a team as a code owner January 15, 2026 15:33
@anzr299 anzr299 marked this pull request as draft January 15, 2026 16:44
@github-actions github-actions bot added the API Public API-impacting changes label Jan 15, 2026
@github-actions github-actions bot added NNCF PT Pull requests that updates NNCF PyTorch NNCF PTQ Pull requests that updates NNCF PTQ labels Jan 15, 2026
@anzr299 anzr299 marked this pull request as ready for review January 20, 2026 14:41
from nncf.quantization.range_estimator import RangeEstimatorParameters


def _is_openvino_quantizer_instance(obj) -> bool:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks like WA for mistakes in https://github.com/pytorch/executorch/blame/main/backends/openvino/quantizer/quantizer.py

It's really bad import tree.
Need some time...

Copy link
Collaborator

Choose a reason for hiding this comment

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

There is a dependency and ownership issue around the quantization entry point that needs clarification.

Currently:

  • quantize_pt2e depends on OpenVINOQuantizer (from executorch).
  • quantize_model (also in executorch) depends on quantize_pt2e.
  • OpenVINOQuantizer and quantize_model are defined in the same file.

As a result, the effective call chain looks like this: executorch → nncf → executorch

This creates a circular dependency and makes it unclear what the intended public entry point is for OpenVINO PT2E quantization. Since everything lives in a single executorch file, it’s not obvious:

  • which function users are expected to call directly
  • which layer “owns” the quantization workflow (executorch or NNCF).

So my current suggest to dont block this PR:

  1. Create ticket on it, add TODO here.
  2. Refactor openvino backend files in executorch
  3. Finalize quantize_pt2e

@daniil-lyakhov
@MaximProshin

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Created a ticket - CVS-179719

"""
try:
from executorch.backends.openvino.quantizer.quantizer import OpenVINOQuantizer
except ModuleNotFoundError as err:
Copy link
Collaborator

Choose a reason for hiding this comment

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

But _is_openvino_quantizer_instance function is useless.
In case to avoid circular import just move import inside a function.

And it's not safely check cause raise error. For optional dependencies it's should looks like

    try:
        from executorch.backends.openvino.quantizer.quantizer import OpenVINOQuantizer
        return isinstance(obj, OpenVINOQuantizer)
    except ImportError:
        return False

And better use ImportError for checks like this, because for old version of executorch will raised ImportError.
ModuleNotFoundError is subclass of ImportError.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

oh okay, I will change it

pytest-xdist==3.5.0
pytest-forked==1.6.0
pytest-split==0.9.0
ipython==8.37.0 No newline at end of file
Copy link
Collaborator

Choose a reason for hiding this comment

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

ipython is not requared.
Use fastprogress==1.0.5 as it in constraints.txt #3815

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ah Alright, Done

@@ -0,0 +1,1038 @@
strict digraph {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Differ from old tests/torch/data/fx/OpenVINOQuantizer/mobilenet_v3_small.dot
Is it expected? What has changed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It was a bug, it is changed ot be the same now

@AlexanderDokuchaev
Copy link
Collaborator

@anzr299 What version of executorch is required to run tests?

@anzr299
Copy link
Collaborator Author

anzr299 commented Jan 20, 2026

@anzr299 What version of executorch is required to run tests?

Executorch 1.0.1 for PTQ tests.
For Weights compression it will have to be installed from develop of executorch

@@ -1,5 +1,6 @@
tensorboard==2.13.0
torch==2.9.0
torchao==0.14.0
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why torch example require torchao?
It's not use anything from it.
torchao and executorch should not be required dependency for TORCH backend

Copy link
Collaborator Author

@anzr299 anzr299 Jan 21, 2026

Choose a reason for hiding this comment

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

It was importing torchao in src/nncf/torch/quantization/strip.py. Earlier this was torch.ao so it was hidden

https://github.com/openvinotoolkit/nncf/actions/runs/21142246987/job/60798968378

Perhaps I can make it lazy import inside the convert_to_torch_fakequantizer function

optimum-onnx==0.1.0
optimum==2.1.0
scikit-learn>=1.2.2,<=1.5.0
scikit-learn>=1.2.2,<=1.7.1
Copy link
Collaborator

Choose a reason for hiding this comment

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

Set strict version of used package (get version from test job)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

preset = quantizer_kwargs.pop("preset", None)
model_type = quantizer_kwargs.pop("model_type", None)

# This logic is copied and inverted from OVQuantizer code
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why is it here?
Please use model_scope.py to setup compression arguments without any hidden behavior.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

from nncf.quantization.range_estimator import RangeEstimatorParameters


def _is_openvino_quantizer_instance(obj) -> bool:
Copy link
Collaborator

Choose a reason for hiding this comment

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

There is a dependency and ownership issue around the quantization entry point that needs clarification.

Currently:

  • quantize_pt2e depends on OpenVINOQuantizer (from executorch).
  • quantize_model (also in executorch) depends on quantize_pt2e.
  • OpenVINOQuantizer and quantize_model are defined in the same file.

As a result, the effective call chain looks like this: executorch → nncf → executorch

This creates a circular dependency and makes it unclear what the intended public entry point is for OpenVINO PT2E quantization. Since everything lives in a single executorch file, it’s not obvious:

  • which function users are expected to call directly
  • which layer “owns” the quantization workflow (executorch or NNCF).

So my current suggest to dont block this PR:

  1. Create ticket on it, add TODO here.
  2. Refactor openvino backend files in executorch
  3. Finalize quantize_pt2e

@daniil-lyakhov
@MaximProshin

@MaximProshin
Copy link
Collaborator

MaximProshin commented Jan 23, 2026

Agreed to merge it after the CF to mitigate any risks with a new dependency. @anzr299 @AlexanderDokuchaev

# Pytorch
torch==2.9.0
torchvision==0.24.0
torchao==0.14.0
Copy link
Collaborator

Choose a reason for hiding this comment

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

Aamir, as we discussed it with Alexander Suslov, the main idea was to get rid of torch.ao and do not use any external dependencies (like torchao)
The task is to remove torch.ao imports and replace them with code in the nncf codebase, no external dependencies

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

API Public API-impacting changes NNCF PT Pull requests that updates NNCF PyTorch NNCF PTQ Pull requests that updates NNCF PTQ

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

Comments