From 7fcef07e9ff78efc665b96690ef5cbb13410990e Mon Sep 17 00:00:00 2001 From: Nikita Malinin Date: Tue, 24 Oct 2023 11:09:49 +0200 Subject: [PATCH 1/3] Added ov_version parameter to the env tests (#2209) ### Changes - Added `ov_version` variable for the pytest in `test_examples`; - Added `ov_version` variable for the pytest in the `test_install_*`; ### Reason for changes - More flexible tests ### Related tickets - 122860 ### Tests - Updated --- tests/cross_fw/examples/conftest.py | 8 ++++++++ tests/cross_fw/examples/test_examples.py | 16 +++++++++++++++- tests/cross_fw/install/conftest.py | 8 ++++++++ tests/cross_fw/install/test_install.py | 5 +++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/tests/cross_fw/examples/conftest.py b/tests/cross_fw/examples/conftest.py index cbf665402d8..6cac9c21a3e 100644 --- a/tests/cross_fw/examples/conftest.py +++ b/tests/cross_fw/examples/conftest.py @@ -28,6 +28,9 @@ def pytest_addoption(parser): default=False, help="If the parameter is set then the performance metrics will be tested as well", ) + parser.addoption( + "--ov_version_override", default=None, help="Parameter to set OpenVINO into the env with the version from PyPI" + ) @pytest.fixture(scope="module") @@ -38,3 +41,8 @@ def backends_list(request): @pytest.fixture(scope="module") def is_check_performance(request): return request.config.getoption("--check_performance") + + +@pytest.fixture(scope="module") +def ov_version_override(request): + return request.config.getoption("--ov_version_override") diff --git a/tests/cross_fw/examples/test_examples.py b/tests/cross_fw/examples/test_examples.py index fc3c0d8f815..8f98961da15 100644 --- a/tests/cross_fw/examples/test_examples.py +++ b/tests/cross_fw/examples/test_examples.py @@ -11,6 +11,8 @@ import os import subprocess +from pathlib import Path +from typing import Any, Dict, List import pytest @@ -42,7 +44,14 @@ def example_test_cases(): @pytest.mark.parametrize("example_name, example_params", example_test_cases()) -def test_examples(tmp_path, example_name, example_params, backends_list, is_check_performance): +def test_examples( + tmp_path: Path, + example_name: str, + example_params: Dict[str, Any], + backends_list: List[str], + is_check_performance: bool, + ov_version_override: str, +): backend = example_params["backend"] skip_if_backend_not_selected(backend, backends_list) venv_path = create_venv_with_nncf(tmp_path, "pip_e_local", "venv", set([backend])) @@ -52,6 +61,11 @@ def test_examples(tmp_path, example_name, example_params, backends_list, is_chec run_cmd_line = f"{pip_with_venv} install -r {requirements}" subprocess.run(run_cmd_line, check=True, shell=True) + if ov_version_override is not None: + pip_with_venv = get_pip_executable_with_venv(venv_path) + ov_version_cmd_line = f"{pip_with_venv} install {ov_version_override}" + subprocess.run(ov_version_cmd_line, check=True, shell=True) + env = os.environ.copy() env["PYTHONPATH"] = str(PROJECT_ROOT) # need this to be able to import from tests.* in run_example.py diff --git a/tests/cross_fw/install/conftest.py b/tests/cross_fw/install/conftest.py index 5b5142b3acb..179c2fff682 100644 --- a/tests/cross_fw/install/conftest.py +++ b/tests/cross_fw/install/conftest.py @@ -29,6 +29,9 @@ def pytest_addoption(parser): nargs="+", default=["all"], ) + parser.addoption( + "--ov_version_override", default=None, help="Parameter to set OpenVINO into the env with the version from PyPI" + ) @pytest.fixture(scope="module") @@ -39,3 +42,8 @@ def backend_clopt(request): @pytest.fixture(scope="module") def host_configuration_clopt(request): return request.config.getoption("--host-configuration") + + +@pytest.fixture(scope="module") +def ov_version_override(request): + return request.config.getoption("--ov_version_override") diff --git a/tests/cross_fw/install/test_install.py b/tests/cross_fw/install/test_install.py index c7953d2c6f5..bcd015c55ba 100644 --- a/tests/cross_fw/install/test_install.py +++ b/tests/cross_fw/install/test_install.py @@ -107,11 +107,16 @@ def test_install( package_type: str, backend_clopt: List[str], host_configuration_clopt: str, + ov_version_override: str, ): skip_if_backend_not_selected(backend, backend_clopt) if "pypi" in package_type: pytest.xfail("Disabled until NNCF is exposed in a release") venv_path = create_venv_with_nncf(tmp_path, package_type, venv_type, extra_reqs={backend}) + if ov_version_override is not None: + pip_with_venv = get_pip_executable_with_venv(venv_path) + ov_version_cmd_line = f"{pip_with_venv} install {ov_version_override}" + subprocess.run(ov_version_cmd_line, check=True, shell=True) run_install_checks(venv_path, tmp_path, package_type, backend=backend, install_type=host_configuration_clopt) @staticmethod From 5e0837ae3584628c9a6ee8774af50cfc1617a23f Mon Sep 17 00:00:00 2001 From: Vasily Shamporov Date: Tue, 24 Oct 2023 12:52:00 +0200 Subject: [PATCH 2/3] Do not test common code in backend-specific test targets (#2212) ### Changes As stated in the title ### Reason for changes Common code has an own target now which is run using GH actions, no reason to run these tests additionally in the backend-specific targets. ### Related tickets TBA ### Tests Existing precommit scope --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 58d2121d6d3..8b4c079780e 100644 --- a/Makefile +++ b/Makefile @@ -99,7 +99,7 @@ install-tensorflow-dev: install-tensorflow-test install-pre-commit install-pylin pip install -r examples/post_training_quantization/tensorflow/mobilenet_v2/requirements.txt test-tensorflow: - pytest ${COVERAGE_ARGS} tests/common tests/tensorflow \ + pytest ${COVERAGE_ARGS} tests/tensorflow \ --junitxml ${JUNITXML_PATH} \ $(DATA_ARG) @@ -128,7 +128,7 @@ install-torch-dev: install-torch-test install-pre-commit install-pylint pip install -r examples/post_training_quantization/torch/ssd300_vgg16/requirements.txt test-torch: - pytest ${COVERAGE_ARGS} tests/common tests/torch -m "not weekly and not nightly" --junitxml ${JUNITXML_PATH} $(DATA_ARG) + pytest ${COVERAGE_ARGS} tests/torch -m "not weekly and not nightly" --junitxml ${JUNITXML_PATH} $(DATA_ARG) test-torch-nightly: pytest ${COVERAGE_ARGS} tests/torch -m nightly --junitxml ${JUNITXML_PATH} $(DATA_ARG) From 8c10eea90819d06b735f5535b9179cf07a0e2dc2 Mon Sep 17 00:00:00 2001 From: Andrey Churkin Date: Wed, 25 Oct 2023 07:13:31 +0100 Subject: [PATCH 3/3] Enable SmoothQuant only for OV backend (#2208) ### Changes Run the SmoothQuant and ChannelAlignment algorithms only for the OpenVINO backend. ### Reason for changes Only the OpenVINO backend supports SmoothQuant and ChannelAlignment algorithms. ### Related tickets N/A ### Tests N/A --- nncf/quantization/algorithms/algorithm.py | 8 ++++---- .../algorithms/bias_correction/algorithm.py | 5 ++--- .../algorithms/bias_correction/backend.py | 2 -- .../bias_correction/onnx_backend.py | 3 --- .../bias_correction/openvino_backend.py | 3 --- .../algorithms/channel_alignment/algorithm.py | 7 +++---- .../algorithms/channel_alignment/backend.py | 2 -- .../channel_alignment/openvino_backend.py | 3 --- .../fast_bias_correction/algorithm.py | 5 ++--- .../fast_bias_correction/backend.py | 2 -- .../fast_bias_correction/onnx_backend.py | 3 --- .../fast_bias_correction/openvino_backend.py | 3 --- .../fast_bias_correction/torch_backend.py | 3 --- .../algorithms/min_max/algorithm.py | 5 ++--- .../algorithms/min_max/backend.py | 2 -- .../algorithms/min_max/onnx_backend.py | 3 --- .../algorithms/min_max/openvino_backend.py | 3 --- .../algorithms/min_max/torch_backend.py | 3 --- nncf/quantization/algorithms/pipeline.py | 19 ++++++++++++++++++- .../algorithms/post_training/algorithm.py | 10 +++++++--- .../algorithms/smooth_quant/algorithm.py | 5 ++--- .../algorithms/smooth_quant/backend.py | 2 -- .../smooth_quant/openvino_backend.py | 3 --- .../weight_compression/algorithm.py | 7 +++---- .../algorithms/weight_compression/backend.py | 2 -- .../weight_compression/openvino_backend.py | 3 --- 26 files changed, 43 insertions(+), 73 deletions(-) diff --git a/nncf/quantization/algorithms/algorithm.py b/nncf/quantization/algorithms/algorithm.py index 432f8024491..b2bca79a31e 100644 --- a/nncf/quantization/algorithms/algorithm.py +++ b/nncf/quantization/algorithms/algorithm.py @@ -11,7 +11,7 @@ from abc import ABC from abc import abstractmethod -from typing import Dict, Optional, TypeVar +from typing import List, Optional, TypeVar from nncf import Dataset from nncf.common.graph.graph import NNCFGraph @@ -28,11 +28,11 @@ class Algorithm(ABC): @property @abstractmethod - def available_backends(self) -> Dict[str, BackendType]: + def available_backends(self) -> List[BackendType]: """ - Returns dictionary of the available backends for the algorithm. + Returns list of the available backends for the algorithm. - :return: Dict of backends supported by the algorithm. + :return: List of backends supported by the algorithm. """ @abstractmethod diff --git a/nncf/quantization/algorithms/bias_correction/algorithm.py b/nncf/quantization/algorithms/bias_correction/algorithm.py index 614dc241349..76f4222c9bf 100644 --- a/nncf/quantization/algorithms/bias_correction/algorithm.py +++ b/nncf/quantization/algorithms/bias_correction/algorithm.py @@ -32,7 +32,6 @@ from nncf.common.utils.backend import copy_model from nncf.common.utils.backend import get_backend from nncf.quantization.algorithms.algorithm import Algorithm -from nncf.quantization.algorithms.bias_correction.backend import ALGO_BACKENDS TModel = TypeVar("TModel") @@ -104,8 +103,8 @@ def __init__( raise RuntimeError("BiasCorrection algorithm does not support apply_for_all_nodes=True yet") @property - def available_backends(self) -> Dict[str, BackendType]: - return ALGO_BACKENDS.registry_dict + def available_backends(self) -> List[BackendType]: + return [BackendType.ONNX, BackendType.OPENVINO] def _set_backend_entity(self, model: TModel) -> None: """ diff --git a/nncf/quantization/algorithms/bias_correction/backend.py b/nncf/quantization/algorithms/bias_correction/backend.py index ea490f5fae1..08eb9d433c8 100644 --- a/nncf/quantization/algorithms/bias_correction/backend.py +++ b/nncf/quantization/algorithms/bias_correction/backend.py @@ -22,11 +22,9 @@ from nncf.common.graph.transformations.commands import TransformationCommand from nncf.common.tensor import NNCFTensor from nncf.common.tensor_statistics.collectors import TensorStatisticCollectorBase -from nncf.common.utils.registry import Registry TModel = TypeVar("TModel") OutputType = TypeVar("OutputType") -ALGO_BACKENDS = Registry("algo_backends") # pylint:disable=too-many-public-methods diff --git a/nncf/quantization/algorithms/bias_correction/onnx_backend.py b/nncf/quantization/algorithms/bias_correction/onnx_backend.py index d7f34936bfd..498f33d0aba 100644 --- a/nncf/quantization/algorithms/bias_correction/onnx_backend.py +++ b/nncf/quantization/algorithms/bias_correction/onnx_backend.py @@ -17,7 +17,6 @@ from nncf.common.graph import NNCFGraph from nncf.common.graph import NNCFNode from nncf.common.graph.transformations.commands import TargetType -from nncf.common.utils.backend import BackendType from nncf.onnx.graph.model_utils import remove_fq_from_inputs from nncf.onnx.graph.node_utils import get_bias_value from nncf.onnx.graph.node_utils import is_any_weight_quantized @@ -33,12 +32,10 @@ from nncf.onnx.statistics.collectors import ONNXNNCFCollectorTensorProcessor from nncf.onnx.statistics.collectors import ONNXRawStatisticCollector from nncf.onnx.tensor import ONNXNNCFTensor -from nncf.quantization.algorithms.bias_correction.backend import ALGO_BACKENDS from nncf.quantization.algorithms.bias_correction.backend import BiasCorrectionAlgoBackend # pylint:disable=too-many-public-methods -@ALGO_BACKENDS.register(BackendType.ONNX) class ONNXBiasCorrectionAlgoBackend(BiasCorrectionAlgoBackend): @property def tensor_processor(self) -> ONNXNNCFCollectorTensorProcessor: diff --git a/nncf/quantization/algorithms/bias_correction/openvino_backend.py b/nncf/quantization/algorithms/bias_correction/openvino_backend.py index 7af72dec173..1af3bb9d4cf 100644 --- a/nncf/quantization/algorithms/bias_correction/openvino_backend.py +++ b/nncf/quantization/algorithms/bias_correction/openvino_backend.py @@ -17,7 +17,6 @@ from nncf.common.graph import NNCFGraph from nncf.common.graph import NNCFNode from nncf.common.graph.transformations.commands import TargetType -from nncf.common.utils.backend import BackendType from nncf.experimental.common.tensor_statistics.collectors import TensorCollector from nncf.openvino.graph.metatypes.groups import FAKE_QUANTIZE_OPERATIONS from nncf.openvino.graph.model_utils import insert_null_biases @@ -33,12 +32,10 @@ from nncf.openvino.statistics.collectors import get_mean_statistic_collector from nncf.openvino.statistics.collectors import get_raw_stat_collector from nncf.openvino.tensor import OVNNCFTensor -from nncf.quantization.algorithms.bias_correction.backend import ALGO_BACKENDS from nncf.quantization.algorithms.bias_correction.backend import BiasCorrectionAlgoBackend # pylint:disable=too-many-public-methods -@ALGO_BACKENDS.register(BackendType.OPENVINO) class OVBiasCorrectionAlgoBackend(BiasCorrectionAlgoBackend): @property def tensor_processor(self) -> OVNNCFCollectorTensorProcessor: diff --git a/nncf/quantization/algorithms/channel_alignment/algorithm.py b/nncf/quantization/algorithms/channel_alignment/algorithm.py index f163ec3468c..20ff497e258 100644 --- a/nncf/quantization/algorithms/channel_alignment/algorithm.py +++ b/nncf/quantization/algorithms/channel_alignment/algorithm.py @@ -9,7 +9,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Dict, List, Optional, Tuple, TypeVar +from typing import List, Optional, Tuple, TypeVar import numpy as np @@ -28,7 +28,6 @@ from nncf.common.utils.backend import BackendType from nncf.common.utils.backend import get_backend from nncf.quantization.algorithms.algorithm import Algorithm -from nncf.quantization.algorithms.channel_alignment.backend import ALGO_BACKENDS from nncf.quantization.algorithms.channel_alignment.backend import ChannelAlignmentAlgoBackend from nncf.quantization.algorithms.channel_alignment.backend import LayoutDescriptor @@ -75,8 +74,8 @@ def __init__( self._algorithm_key = f"CA_{hash(self)}" @property - def available_backends(self) -> Dict[str, BackendType]: - return ALGO_BACKENDS.registry_dict + def available_backends(self) -> List[BackendType]: + return [BackendType.OPENVINO] def _set_backend_entity(self, model: TModel) -> None: """ diff --git a/nncf/quantization/algorithms/channel_alignment/backend.py b/nncf/quantization/algorithms/channel_alignment/backend.py index f78f2db08a6..c41a779f0bf 100644 --- a/nncf/quantization/algorithms/channel_alignment/backend.py +++ b/nncf/quantization/algorithms/channel_alignment/backend.py @@ -21,10 +21,8 @@ from nncf.common.graph.transformations.commands import TargetPoint from nncf.common.graph.transformations.commands import TargetType from nncf.common.tensor_statistics.collectors import TensorStatisticCollectorBase -from nncf.common.utils.registry import Registry TModel = TypeVar("TModel") -ALGO_BACKENDS = Registry("algo_backends") @dataclass diff --git a/nncf/quantization/algorithms/channel_alignment/openvino_backend.py b/nncf/quantization/algorithms/channel_alignment/openvino_backend.py index 1a3667be9c5..77716d51969 100644 --- a/nncf/quantization/algorithms/channel_alignment/openvino_backend.py +++ b/nncf/quantization/algorithms/channel_alignment/openvino_backend.py @@ -19,7 +19,6 @@ from nncf.common.graph.layer_attributes import ConvolutionLayerAttributes from nncf.common.graph.transformations.commands import TargetType from nncf.common.tensor_statistics.collectors import TensorStatisticCollectorBase -from nncf.common.utils.backend import BackendType from nncf.experimental.common.tensor_statistics.collectors import MedianAggregator from nncf.experimental.common.tensor_statistics.collectors import TensorCollector from nncf.openvino.graph.layer_attributes import OVLayerAttributes @@ -37,12 +36,10 @@ from nncf.openvino.statistics.collectors import OVNNCFCollectorTensorProcessor from nncf.openvino.statistics.collectors import OVQuantileReducer from nncf.openvino.statistics.statistics import OVMinMaxTensorStatistic -from nncf.quantization.algorithms.channel_alignment.backend import ALGO_BACKENDS from nncf.quantization.algorithms.channel_alignment.backend import ChannelAlignmentAlgoBackend from nncf.quantization.algorithms.channel_alignment.backend import LayoutDescriptor -@ALGO_BACKENDS.register(BackendType.OPENVINO) class OVChannelAlignmentAlgoBackend(ChannelAlignmentAlgoBackend): @staticmethod def target_point(target_type: TargetType, target_node_name: str, port_id: int) -> OVTargetPoint: diff --git a/nncf/quantization/algorithms/fast_bias_correction/algorithm.py b/nncf/quantization/algorithms/fast_bias_correction/algorithm.py index 919f56848c8..821f7475d81 100644 --- a/nncf/quantization/algorithms/fast_bias_correction/algorithm.py +++ b/nncf/quantization/algorithms/fast_bias_correction/algorithm.py @@ -30,7 +30,6 @@ from nncf.experimental.tensor import Tensor from nncf.experimental.tensor import functions as fns from nncf.quantization.algorithms.algorithm import Algorithm -from nncf.quantization.algorithms.fast_bias_correction.backend import ALGO_BACKENDS TModel = TypeVar("TModel") TTensor = TypeVar("TTensor") @@ -92,8 +91,8 @@ def __init__( raise RuntimeError("FastBiasCorrection algorithm does not support apply_for_all_nodes=True yet") @property - def available_backends(self) -> Dict[str, BackendType]: - return ALGO_BACKENDS.registry_dict + def available_backends(self) -> List[BackendType]: + return [BackendType.ONNX, BackendType.OPENVINO, BackendType.TORCH] def _set_backend_entity(self, model: TModel) -> None: """ diff --git a/nncf/quantization/algorithms/fast_bias_correction/backend.py b/nncf/quantization/algorithms/fast_bias_correction/backend.py index a9d2ef0ab74..057c012f868 100644 --- a/nncf/quantization/algorithms/fast_bias_correction/backend.py +++ b/nncf/quantization/algorithms/fast_bias_correction/backend.py @@ -21,13 +21,11 @@ from nncf.common.graph.transformations.commands import TargetType from nncf.common.graph.transformations.commands import TransformationCommand from nncf.common.tensor_statistics.collectors import TensorStatisticCollectorBase -from nncf.common.utils.registry import Registry from nncf.experimental.tensor import Tensor TModel = TypeVar("TModel") TTensor = TypeVar("TTensor") OutputType = TypeVar("OutputType") -ALGO_BACKENDS = Registry("algo_backends") class FastBiasCorrectionAlgoBackend(ABC): diff --git a/nncf/quantization/algorithms/fast_bias_correction/onnx_backend.py b/nncf/quantization/algorithms/fast_bias_correction/onnx_backend.py index d0646f6aeb2..1ae51fcbfe7 100644 --- a/nncf/quantization/algorithms/fast_bias_correction/onnx_backend.py +++ b/nncf/quantization/algorithms/fast_bias_correction/onnx_backend.py @@ -17,7 +17,6 @@ from nncf.common.graph import NNCFGraph from nncf.common.graph import NNCFNode from nncf.common.graph.transformations.commands import TargetType -from nncf.common.utils.backend import BackendType from nncf.experimental.tensor import Tensor from nncf.onnx.graph.node_utils import get_bias_value from nncf.onnx.graph.node_utils import is_any_weight_quantized @@ -28,11 +27,9 @@ from nncf.onnx.graph.transformations.commands import ONNXNullBiasInsertionCommand from nncf.onnx.graph.transformations.commands import ONNXTargetPoint from nncf.onnx.statistics.collectors import ONNXMeanStatisticCollector -from nncf.quantization.algorithms.fast_bias_correction.backend import ALGO_BACKENDS from nncf.quantization.algorithms.fast_bias_correction.backend import FastBiasCorrectionAlgoBackend -@ALGO_BACKENDS.register(BackendType.ONNX) class ONNXFastBiasCorrectionAlgoBackend(FastBiasCorrectionAlgoBackend): @property def types_to_insert_bias(self): diff --git a/nncf/quantization/algorithms/fast_bias_correction/openvino_backend.py b/nncf/quantization/algorithms/fast_bias_correction/openvino_backend.py index d2744da5864..ba8d18d1733 100644 --- a/nncf/quantization/algorithms/fast_bias_correction/openvino_backend.py +++ b/nncf/quantization/algorithms/fast_bias_correction/openvino_backend.py @@ -17,7 +17,6 @@ from nncf.common.graph import NNCFGraph from nncf.common.graph import NNCFNode from nncf.common.graph.transformations.commands import TargetType -from nncf.common.utils.backend import BackendType from nncf.experimental.common.tensor_statistics.collectors import TensorCollector from nncf.experimental.tensor import Tensor from nncf.openvino.graph.metatypes.groups import FAKE_QUANTIZE_OPERATIONS @@ -28,11 +27,9 @@ from nncf.openvino.graph.transformations.commands import OVModelExtractionCommand from nncf.openvino.graph.transformations.commands import OVTargetPoint from nncf.openvino.statistics.collectors import get_mean_statistic_collector -from nncf.quantization.algorithms.fast_bias_correction.backend import ALGO_BACKENDS from nncf.quantization.algorithms.fast_bias_correction.backend import FastBiasCorrectionAlgoBackend -@ALGO_BACKENDS.register(BackendType.OPENVINO) class OVFastBiasCorrectionAlgoBackend(FastBiasCorrectionAlgoBackend): @staticmethod def target_point(target_type: TargetType, target_node_name: str, port_id: int) -> OVTargetPoint: diff --git a/nncf/quantization/algorithms/fast_bias_correction/torch_backend.py b/nncf/quantization/algorithms/fast_bias_correction/torch_backend.py index 193be8994d9..fea39ff068a 100644 --- a/nncf/quantization/algorithms/fast_bias_correction/torch_backend.py +++ b/nncf/quantization/algorithms/fast_bias_correction/torch_backend.py @@ -18,10 +18,8 @@ from nncf.common.graph import NNCFNode from nncf.common.graph.definitions import NNCFGraphNodeType from nncf.common.graph.transformations.commands import TargetType -from nncf.common.utils.backend import BackendType from nncf.experimental.common.tensor_statistics.collectors import TensorCollector from nncf.experimental.tensor import Tensor -from nncf.quantization.algorithms.fast_bias_correction.backend import ALGO_BACKENDS from nncf.quantization.algorithms.fast_bias_correction.backend import FastBiasCorrectionAlgoBackend from nncf.torch.graph.transformations.command_creation import create_bias_correction_command from nncf.torch.graph.transformations.commands import PTBiasCorrectionCommand @@ -35,7 +33,6 @@ from nncf.torch.tensor_statistics.collectors import get_mean_statistic_collector -@ALGO_BACKENDS.register(BackendType.TORCH) class PTFastBiasCorrectionAlgoBackend(FastBiasCorrectionAlgoBackend): TARGET_TYPE_TO_PT_INS_TYPE_MAP = { TargetType.PRE_LAYER_OPERATION: TargetType.OPERATOR_PRE_HOOK, diff --git a/nncf/quantization/algorithms/min_max/algorithm.py b/nncf/quantization/algorithms/min_max/algorithm.py index ddaa6755cd4..55301f212d7 100644 --- a/nncf/quantization/algorithms/min_max/algorithm.py +++ b/nncf/quantization/algorithms/min_max/algorithm.py @@ -51,7 +51,6 @@ from nncf.quantization.advanced_parameters import QuantizationParameters from nncf.quantization.advanced_parameters import changes_asdict from nncf.quantization.algorithms.algorithm import Algorithm -from nncf.quantization.algorithms.min_max.backend import ALGO_BACKENDS from nncf.quantization.fake_quantize import calculate_quantizer_parameters from nncf.quantization.fake_quantize import get_quantizer_narrow_range from nncf.quantization.passes import transform_to_inference_graph @@ -177,8 +176,8 @@ def _reset_cache(self): self._unified_scale_groups = [] @property - def available_backends(self) -> Dict[str, BackendType]: - return ALGO_BACKENDS.registry_dict + def available_backends(self) -> List[BackendType]: + return [BackendType.ONNX, BackendType.OPENVINO, BackendType.TORCH] def _get_quantizer_constraints( self, group: QuantizerGroup, preset: QuantizationPreset, quantization_params: Optional[QuantizationParameters] diff --git a/nncf/quantization/algorithms/min_max/backend.py b/nncf/quantization/algorithms/min_max/backend.py index 0764885a945..733fe3fe736 100644 --- a/nncf/quantization/algorithms/min_max/backend.py +++ b/nncf/quantization/algorithms/min_max/backend.py @@ -23,14 +23,12 @@ from nncf.common.quantization.structs import QuantizerConfig from nncf.common.tensor_statistics.collectors import TensorStatisticCollectorBase from nncf.common.tensor_statistics.statistics import MinMaxTensorStatistic -from nncf.common.utils.registry import Registry from nncf.parameters import ModelType from nncf.parameters import TargetDevice from nncf.quantization.fake_quantize import FakeQuantizeParameters from nncf.quantization.range_estimator import RangeEstimatorParameters TModel = TypeVar("TModel") -ALGO_BACKENDS = Registry("algo_backends") # pylint:disable=too-many-public-methods diff --git a/nncf/quantization/algorithms/min_max/onnx_backend.py b/nncf/quantization/algorithms/min_max/onnx_backend.py index e202252bf59..a549418b05c 100644 --- a/nncf/quantization/algorithms/min_max/onnx_backend.py +++ b/nncf/quantization/algorithms/min_max/onnx_backend.py @@ -20,7 +20,6 @@ from nncf.common.hardware.config import HWConfig from nncf.common.quantization.structs import QuantizationMode from nncf.common.quantization.structs import QuantizerConfig -from nncf.common.utils.backend import BackendType from nncf.onnx.graph.metatypes import onnx_metatypes as om from nncf.onnx.graph.metatypes.groups import MATMUL_METATYPES from nncf.onnx.graph.node_utils import get_input_edges_mapping @@ -39,14 +38,12 @@ from nncf.parameters import TargetDevice from nncf.quantization.advanced_parameters import AggregatorType from nncf.quantization.advanced_parameters import StatisticsType -from nncf.quantization.algorithms.min_max.backend import ALGO_BACKENDS from nncf.quantization.algorithms.min_max.backend import MinMaxAlgoBackend from nncf.quantization.fake_quantize import FakeQuantizeParameters from nncf.quantization.range_estimator import RangeEstimatorParameters # pylint:disable=too-many-public-methods -@ALGO_BACKENDS.register(BackendType.ONNX) class ONNXMinMaxAlgoBackend(MinMaxAlgoBackend): @property def mat_mul_metatypes(self) -> List[OperatorMetatype]: diff --git a/nncf/quantization/algorithms/min_max/openvino_backend.py b/nncf/quantization/algorithms/min_max/openvino_backend.py index 103969142c2..c2010910f56 100644 --- a/nncf/quantization/algorithms/min_max/openvino_backend.py +++ b/nncf/quantization/algorithms/min_max/openvino_backend.py @@ -21,7 +21,6 @@ from nncf.common.quantization.structs import QuantizationMode from nncf.common.quantization.structs import QuantizerConfig from nncf.common.tensor_statistics.collectors import ReductionAxes -from nncf.common.utils.backend import BackendType from nncf.experimental.common.tensor_statistics.collectors import AGGREGATORS_MAP from nncf.experimental.common.tensor_statistics.collectors import TensorCollector from nncf.openvino.graph.layer_attributes import OVLayerAttributes @@ -40,13 +39,11 @@ from nncf.parameters import TargetDevice from nncf.quantization.advanced_parameters import RangeEstimatorParameters from nncf.quantization.advanced_parameters import StatisticsType -from nncf.quantization.algorithms.min_max.backend import ALGO_BACKENDS from nncf.quantization.algorithms.min_max.backend import MinMaxAlgoBackend from nncf.quantization.fake_quantize import FakeQuantizeParameters # pylint:disable=too-many-public-methods -@ALGO_BACKENDS.register(BackendType.OPENVINO) class OVMinMaxAlgoBackend(MinMaxAlgoBackend): @property def mat_mul_metatypes(self) -> List[OperatorMetatype]: diff --git a/nncf/quantization/algorithms/min_max/torch_backend.py b/nncf/quantization/algorithms/min_max/torch_backend.py index cae2c4fa6c2..cecbb79862b 100644 --- a/nncf/quantization/algorithms/min_max/torch_backend.py +++ b/nncf/quantization/algorithms/min_max/torch_backend.py @@ -23,13 +23,11 @@ from nncf.common.hardware.config import HWConfig from nncf.common.quantization.structs import QuantizationMode from nncf.common.quantization.structs import QuantizerConfig -from nncf.common.utils.backend import BackendType from nncf.experimental.common.tensor_statistics.collectors import AGGREGATORS_MAP from nncf.experimental.common.tensor_statistics.collectors import TensorCollector from nncf.parameters import ModelType from nncf.parameters import TargetDevice from nncf.quantization.advanced_parameters import StatisticsType -from nncf.quantization.algorithms.min_max.backend import ALGO_BACKENDS from nncf.quantization.algorithms.min_max.backend import MinMaxAlgoBackend from nncf.quantization.fake_quantize import FakeQuantizeParameters from nncf.quantization.range_estimator import RangeEstimatorParameters @@ -50,7 +48,6 @@ # pylint:disable=too-many-public-methods -@ALGO_BACKENDS.register(BackendType.TORCH) class PTMinMaxAlgoBackend(MinMaxAlgoBackend): TARGET_TYPE_TO_PT_INS_TYPE_MAP = { TargetType.PRE_LAYER_OPERATION: TargetType.OPERATOR_PRE_HOOK, diff --git a/nncf/quantization/algorithms/pipeline.py b/nncf/quantization/algorithms/pipeline.py index 951bd436e2b..1b5db8a8614 100644 --- a/nncf/quantization/algorithms/pipeline.py +++ b/nncf/quantization/algorithms/pipeline.py @@ -14,7 +14,10 @@ from nncf.common.factory import NNCFGraphFactory from nncf.common.factory import StatisticsAggregatorFactory from nncf.common.graph.graph import NNCFGraph +from nncf.common.logging import nncf_logger from nncf.common.tensor_statistics.statistic_point import StatisticPointsContainer +from nncf.common.utils.backend import BackendType +from nncf.common.utils.backend import get_backend from nncf.data.dataset import Dataset from nncf.quantization.algorithms.algorithm import Algorithm @@ -109,6 +112,7 @@ def run_step( current_graph = graph pipeline_step = self.pipeline_steps[step_index] + pipeline_step = self._remove_unsupported_algorithms(pipeline_step, get_backend(current_model)) for algorithm in pipeline_step[:-1]: current_model = algorithm.apply(current_model, current_graph, step_statistics) current_graph = NNCFGraphFactory.create(current_model) @@ -174,9 +178,22 @@ def get_statistic_points_for_step( :return: Statistics that should be collected to execute `step_index`-th pipeline step. """ container = StatisticPointsContainer() - for algorithm in self.pipeline_steps[step_index]: + pipeline_step = self.pipeline_steps[step_index] + pipeline_step = self._remove_unsupported_algorithms(pipeline_step, get_backend(model)) + for algorithm in pipeline_step: for statistic_points in algorithm.get_statistic_points(model, graph).values(): for statistic_point in statistic_points: container.add_statistic_point(statistic_point) return container + + @staticmethod + def _remove_unsupported_algorithms(pipeline_step: PipelineStep, backend: BackendType) -> PipelineStep: + step = [] + for algorithm in pipeline_step: + if backend not in algorithm.available_backends: + nncf_logger.debug(f"{backend.name} does not support {algorithm.__class__.__name__} algorithm yet.") + continue + step.append(algorithm) + + return step diff --git a/nncf/quantization/algorithms/post_training/algorithm.py b/nncf/quantization/algorithms/post_training/algorithm.py index 5c9a0e7777e..e4993f07b1f 100644 --- a/nncf/quantization/algorithms/post_training/algorithm.py +++ b/nncf/quantization/algorithms/post_training/algorithm.py @@ -9,7 +9,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Callable, Dict, Optional, TypeVar +import itertools +from typing import Callable, List, Optional, TypeVar from nncf import Dataset from nncf.common.graph.graph import NNCFGraph @@ -71,8 +72,11 @@ def __init__( ) @property - def available_backends(self) -> Dict[str, BackendType]: - return + def available_backends(self) -> List[BackendType]: + backends = set(BackendType) + for algorithm in itertools.chain.from_iterable(self._pipeline.pipeline_steps): + backends = backends.intersection(algorithm.available_backends) + return list(backends) def get_statistic_points(self, model: TModel, graph: NNCFGraph) -> StatisticPointsContainer: return self._pipeline.get_statistic_points_for_step(0, model, graph) diff --git a/nncf/quantization/algorithms/smooth_quant/algorithm.py b/nncf/quantization/algorithms/smooth_quant/algorithm.py index 780a462d280..8add3315384 100644 --- a/nncf/quantization/algorithms/smooth_quant/algorithm.py +++ b/nncf/quantization/algorithms/smooth_quant/algorithm.py @@ -37,7 +37,6 @@ from nncf.common.utils.backend import BackendType from nncf.common.utils.backend import get_backend from nncf.quantization.algorithms.algorithm import Algorithm -from nncf.quantization.algorithms.smooth_quant.backend import ALGO_BACKENDS TModel = TypeVar("TModel") TTensor = TypeVar("TTensor") @@ -75,8 +74,8 @@ def __init__(self, subset_size: int = 300, inplace_statistics: bool = True, alph self._cached_multiply_names = Counter() @property - def available_backends(self) -> Dict[str, BackendType]: - return ALGO_BACKENDS.registry_dict + def available_backends(self) -> List[BackendType]: + return [BackendType.OPENVINO] def _set_backend_entity(self, model: TModel) -> None: """ diff --git a/nncf/quantization/algorithms/smooth_quant/backend.py b/nncf/quantization/algorithms/smooth_quant/backend.py index e0ccfc955df..9df70d788b5 100644 --- a/nncf/quantization/algorithms/smooth_quant/backend.py +++ b/nncf/quantization/algorithms/smooth_quant/backend.py @@ -19,12 +19,10 @@ from nncf.common.graph.transformations.commands import TargetPoint from nncf.common.graph.transformations.commands import TargetType from nncf.common.graph.transformations.commands import TransformationCommand -from nncf.common.utils.registry import Registry from nncf.experimental.common.tensor_statistics.collectors import TensorCollector TModel = TypeVar("TModel") TTensor = TypeVar("TTensor") -ALGO_BACKENDS = Registry("algo_backends") class SmoothQuantAlgoBackend(ABC): diff --git a/nncf/quantization/algorithms/smooth_quant/openvino_backend.py b/nncf/quantization/algorithms/smooth_quant/openvino_backend.py index 12005168428..2fe24398c52 100644 --- a/nncf/quantization/algorithms/smooth_quant/openvino_backend.py +++ b/nncf/quantization/algorithms/smooth_quant/openvino_backend.py @@ -18,7 +18,6 @@ from nncf.common.graph import NNCFNode from nncf.common.graph.operator_metatypes import OperatorMetatype from nncf.common.graph.transformations.commands import TargetType -from nncf.common.utils.backend import BackendType from nncf.experimental.common.tensor_statistics.collectors import MaxAggregator from nncf.experimental.common.tensor_statistics.collectors import TensorCollector from nncf.openvino.graph.metatypes.openvino_metatypes import OVMatMulMetatype @@ -30,11 +29,9 @@ from nncf.openvino.graph.transformations.commands import OVWeightUpdateCommand from nncf.openvino.statistics.collectors import OVAbsMaxReducer from nncf.openvino.statistics.collectors import OVNNCFCollectorTensorProcessor -from nncf.quantization.algorithms.smooth_quant.backend import ALGO_BACKENDS from nncf.quantization.algorithms.smooth_quant.backend import SmoothQuantAlgoBackend -@ALGO_BACKENDS.register(BackendType.OPENVINO) class OVSmoothQuantAlgoBackend(SmoothQuantAlgoBackend): @property def weighted_metatypes(self) -> List[OperatorMetatype]: diff --git a/nncf/quantization/algorithms/weight_compression/algorithm.py b/nncf/quantization/algorithms/weight_compression/algorithm.py index 1c12cb78791..72693ab59c2 100644 --- a/nncf/quantization/algorithms/weight_compression/algorithm.py +++ b/nncf/quantization/algorithms/weight_compression/algorithm.py @@ -19,7 +19,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Dict, List, Optional, TypeVar +from typing import List, Optional, TypeVar from nncf import Dataset from nncf.common.graph.graph import NNCFGraph @@ -30,7 +30,6 @@ from nncf.common.utils.backend import get_backend from nncf.parameters import CompressWeightsMode from nncf.quantization.algorithms.algorithm import Algorithm -from nncf.quantization.algorithms.weight_compression.backend import ALGO_BACKENDS from nncf.scopes import IgnoredScope from nncf.scopes import get_ignored_node_names_from_ignored_scope @@ -75,8 +74,8 @@ def __init__( self._algorithm_key = f"CW_{hash(self)}" @property - def available_backends(self) -> Dict[str, BackendType]: - return ALGO_BACKENDS.registry_dict + def available_backends(self) -> List[BackendType]: + return [BackendType.OPENVINO] def _set_backend_entity(self, model: TModel) -> None: """ diff --git a/nncf/quantization/algorithms/weight_compression/backend.py b/nncf/quantization/algorithms/weight_compression/backend.py index ca07ed299ac..5bc64a2eac0 100644 --- a/nncf/quantization/algorithms/weight_compression/backend.py +++ b/nncf/quantization/algorithms/weight_compression/backend.py @@ -15,12 +15,10 @@ from nncf.common.graph import NNCFNode from nncf.common.graph.operator_metatypes import OperatorMetatype -from nncf.common.utils.registry import Registry from nncf.parameters import CompressWeightsMode from nncf.scopes import IgnoredScope TModel = TypeVar("TModel") -ALGO_BACKENDS = Registry("algo_backends") class WeightCompressionAlgoBackend(ABC): diff --git a/nncf/quantization/algorithms/weight_compression/openvino_backend.py b/nncf/quantization/algorithms/weight_compression/openvino_backend.py index fcbd67fd6ae..18090ca86c2 100644 --- a/nncf/quantization/algorithms/weight_compression/openvino_backend.py +++ b/nncf/quantization/algorithms/weight_compression/openvino_backend.py @@ -19,7 +19,6 @@ from nncf.common.graph import NNCFNode from nncf.common.graph.operator_metatypes import OperatorMetatype from nncf.common.logging import nncf_logger -from nncf.common.utils.backend import BackendType from nncf.common.utils.helpers import create_table from nncf.openvino.graph.metatypes.openvino_metatypes import OVEmbeddingMetatype from nncf.openvino.graph.metatypes.openvino_metatypes import OVMatMulMetatype @@ -27,13 +26,11 @@ from nncf.openvino.graph.node_utils import get_const_value from nncf.openvino.graph.node_utils import get_weight_channel_axes from nncf.parameters import CompressWeightsMode -from nncf.quantization.algorithms.weight_compression.backend import ALGO_BACKENDS from nncf.quantization.algorithms.weight_compression.backend import WeightCompressionAlgoBackend from nncf.quantization.fake_quantize import calculate_scale_zero_point from nncf.scopes import IgnoredScope -@ALGO_BACKENDS.register(BackendType.OPENVINO) class OVWeightCompressionAlgoBackend(WeightCompressionAlgoBackend): @property def weighted_metatypes(self) -> List[OperatorMetatype]: