Skip to content
Merged
3 changes: 2 additions & 1 deletion src/nncf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@
from nncf.quantization.advanced_parameters import AdvancedSmoothQuantParameters as AdvancedSmoothQuantParameters
from nncf.quantization.advanced_parameters import GroupSizeFallbackMode as GroupSizeFallbackMode
from nncf.quantization.advanced_parameters import OverflowFix as OverflowFix
from nncf.scopes import IgnoredScope as IgnoredScope
from nncf.scopes import IgnoredScope as IgnoredScope # Deprecated alias for nncf.Scope
from nncf.scopes import Scope as Scope
from nncf.scopes import Subgraph as Subgraph
from nncf.version import __version__ as __version__

Expand Down
76 changes: 0 additions & 76 deletions src/nncf/common/scopes.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,8 @@
import re
from typing import Iterable

import nncf
from nncf.common.graph import NNCFGraph
from nncf.common.graph import NNCFNode
from nncf.common.graph import NNCFNodeName
from nncf.common.logging import nncf_logger
from nncf.common.quantization.structs import QuantizerId
from nncf.scopes import IgnoredScope
from nncf.scopes import convert_ignored_scope_to_list


def matches_any(tested_str: str, strs_to_match_to: Iterable[str] | str | None) -> bool:
Expand Down Expand Up @@ -70,73 +64,3 @@ def should_consider_scope(
return (target_scopes is None or matches_any(string_id, target_scopes)) and not matches_any(
string_id, ignored_scopes
)


def get_not_matched_scopes(scope: list[str] | str | IgnoredScope | None, nodes: list[NNCFNode]) -> list[str]:
"""
Return list of scope that do not match node list.

:param scope: List of ignored/target scope or instance of IgnoredScope.
:param graph: The model graph.

:return : List of not matched scopes.
"""
if scope is None:
return []

if isinstance(scope, str):
patterns = [scope]
elif isinstance(scope, IgnoredScope):
patterns = convert_ignored_scope_to_list(scope)
else:
patterns = list(scope)

if not patterns:
return []

matched_patterns = set()
for node in nodes:
for pattern in patterns:
if matches_any(node.node_name, pattern):
matched_patterns.add(pattern)
return list(set(patterns) - matched_patterns)


def check_scopes_in_graph(
graph: NNCFGraph,
ignored_scopes: IgnoredScope | list[str],
target_scopes: list[str] | None = None,
validate_scopes: bool = True,
) -> None:
"""
Raise RuntimeError in case if ignored/target scope names do not match model graph.

:param graph: The model graph.
:param ignored_scopes: The instance of IgnoredScope or a list of strings specifying a denylist
for the serializable_id.
:param target_scopes: A list of strings specifying an allowlist for the serializable_id.
:param validate_scopes: If set to True, then a RuntimeError will be raised if the names of the
ignored/target scopes do not match the names of the scopes in the model graph.
"""
node_list = graph.get_all_nodes()
not_matched_ignored_scopes = get_not_matched_scopes(ignored_scopes, node_list)
not_matched_target_scopes = get_not_matched_scopes(target_scopes, node_list)

if not_matched_ignored_scopes or not_matched_target_scopes:
err_message = (
"No match has been found among the model operations for the following ignored/target scope definitions:\n"
)
if not_matched_ignored_scopes:
err_message += f" - ignored_scope: {not_matched_ignored_scopes}\n"
if not_matched_target_scopes:
err_message += f" - target_scope: {not_matched_target_scopes}\n"

err_message += (
"Refer to the original_graph.dot to discover the operations "
"in the model currently visible to NNCF and specify the ignored/target "
"scopes in terms of the names there."
)

if validate_scopes:
raise nncf.ValidationError(err_message)
nncf_logger.info(err_message)
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
from nncf.experimental.torch.sparsify_activations.target_scope import TargetScope
from nncf.experimental.torch.sparsify_activations.target_scope import get_target_node_names_from_target_scope
from nncf.scopes import IgnoredScope
from nncf.scopes import get_ignored_node_names_from_ignored_scope
from nncf.scopes import Scope
from nncf.scopes import get_node_names_from_scope
from nncf.torch.model_creation import is_wrapped_model
from nncf.torch.model_creation import wrap_model

Expand Down Expand Up @@ -181,9 +182,7 @@ def _get_target_sparsity_by_node(self, graph: NNCFGraph) -> dict[NNCFNode, float
:return: A dictionary with nodes and the corresponding target sparsity level.
"""
supported_metatypes = self._backend_entity.supported_metatypes
ignored_names = get_ignored_node_names_from_ignored_scope(
self._ignored_scope, graph, strict=self._ignored_scope.validate
)
ignored_names = get_node_names_from_scope(self._ignored_scope, graph, strict=self._ignored_scope.validate)
target_sparsity_by_node = {}
for scope, target_sparsity in self._target_sparsity_by_scope.items():
target_names = get_target_node_names_from_target_scope(scope, graph, strict=scope.validate)
Expand Down Expand Up @@ -245,7 +244,7 @@ def sparsify_activations(
raise ValueError(msg)

if ignored_scope is None:
ignored_scope = IgnoredScope()
ignored_scope = Scope()

backend = get_backend(model)
if backend == BackendType.TORCH and not is_wrapped_model(model):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@

import nncf
from nncf.common.graph.graph import NNCFGraph
from nncf.scopes import IgnoredScope
from nncf.scopes import get_difference_ignored_scope
from nncf.scopes import get_matched_ignored_scope_info
from nncf.scopes import Scope
from nncf.scopes import get_difference_scope
from nncf.scopes import get_matched_scope_info


@dataclass
class TargetScope(IgnoredScope):
class TargetScope(Scope):
r"""
Specifies the target portions in a model graph.

Expand Down Expand Up @@ -84,7 +84,7 @@ def get_target_node_names_from_target_scope(
:param strict: Whether target_scope must match at least one node or not.
:return: NNCF node names from the given graph matched by target scope.
"""
matched_target_scope, matches = get_matched_ignored_scope_info(target_scope, [nncf_graph])
matched_target_scope, matches = get_matched_scope_info(target_scope, [nncf_graph])
if strict:
_check_target_scope_strictly_matched(target_scope, matched_target_scope)
return set().union(*matches.values())
Expand All @@ -97,7 +97,7 @@ def _check_target_scope_strictly_matched(target_scope: TargetScope, matched_targ
:param target_scope: The given target scope.
:param matched_target_scope: The actual target scope matched in a graph.
"""
unmatched_scope = get_difference_ignored_scope(target_scope, matched_target_scope)
unmatched_scope = get_difference_scope(target_scope, matched_target_scope)
error_messages = []
for match_type in ("names", "types", "patterns", "subgraphs"):
unmatched_rules = getattr(unmatched_scope, match_type)
Expand Down
7 changes: 4 additions & 3 deletions src/nncf/openvino/quantization/quantize_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@
from nncf.quantization.statistics_caching import cache_weight_compression_statistics
from nncf.quantization.statistics_caching import register_statistics_for_algorithm
from nncf.scopes import IgnoredScope
from nncf.scopes import validate_ignored_scope
from nncf.scopes import Scope
Comment thread
andrey-churkin marked this conversation as resolved.
Resolved
from nncf.scopes import validate_scope

TTensor = TypeVar("TTensor")

Expand Down Expand Up @@ -96,8 +97,8 @@ def _extract_all_subgraphs(model: ov.Model, current_id: str) -> None:
main_model_graph_id = "main_model_graph"
_extract_all_subgraphs(model, main_model_graph_id)
if ignored_scope and ignored_scope.validate:
validate_ignored_scope(ignored_scope, graphs.values())
ignored_scope = IgnoredScope(
validate_scope(ignored_scope, graphs.values())
ignored_scope = Scope(
ignored_scope.names, ignored_scope.patterns, ignored_scope.types, ignored_scope.subgraphs, validate=False
)
quantization_algorithm = PostTrainingQuantization(
Expand Down
8 changes: 4 additions & 4 deletions src/nncf/openvino/rt_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@

import nncf
from nncf.common.logging import nncf_logger
from nncf.scopes import IgnoredScope
from nncf.scopes import Scope


def exclude_empty_fields(value: dict[str, Any]) -> dict[str, Any]:
"""
Remove keys where value is empty and key is `validate`

:param value: IgnoredScope instance, based on the quantization parameters
:param value: Scope instance, based on the quantization parameters
"""
value.pop("validate")
keys = list(value.keys())
Expand All @@ -47,8 +47,8 @@ def dump_parameters(
try:
path = path if path else []
for key, value in parameters.items():
# Special condition for composed fields like IgnoredScope
if isinstance(value, IgnoredScope):
# Special condition for composed fields like Scope
if isinstance(value, Scope):
value = exclude_empty_fields(asdict(value))
if bool(value):
dump_parameters(model, value, algo_name, [key])
Expand Down
7 changes: 4 additions & 3 deletions src/nncf/quantization/algorithms/min_max/algorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@
from nncf.quantization.range_estimator import RangeEstimatorParametersSet
from nncf.quantization.range_estimator import StatisticsType
from nncf.scopes import IgnoredScope
from nncf.scopes import get_ignored_node_names_from_ignored_scope
from nncf.scopes import Scope
from nncf.scopes import get_node_names_from_scope

TModel = TypeVar("TModel")

Expand Down Expand Up @@ -206,7 +207,7 @@ def __init__(
self._activations_range_estimator_params = activations_range_estimator_params
self._weights_range_estimator_params = weights_range_estimator_params
self._preset = preset
self._ignored_scope = IgnoredScope() if ignored_scope is None else ignored_scope
self._ignored_scope = Scope() if ignored_scope is None else ignored_scope
self.quantizer_propagation_rule = quantizer_propagation_rule

# validate input parameter types
Expand Down Expand Up @@ -613,7 +614,7 @@ def _get_ignored_names(
:param ignored_patterns: Ignored patterns.
:return: Ignored node names and ignore reason for quantization.
"""
user_ignored_names = get_ignored_node_names_from_ignored_scope(
user_ignored_names = get_node_names_from_scope(
self._ignored_scope, nncf_graph, strict=self._ignored_scope.validate
)
autogenerated_ignored_names = get_node_names_matching_graph_pattern(inference_nncf_graph, ignored_patterns)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@
from nncf.quantization.algorithms.weight_compression.weight_lowering import WeightCompressionConfig
from nncf.quantization.algorithms.weight_compression.weight_lowering import get_reduction_channel_size
from nncf.scopes import IgnoredScope
from nncf.scopes import get_ignored_node_names_from_ignored_scope
from nncf.scopes import Scope
from nncf.scopes import get_node_names_from_scope
from nncf.tensor import Tensor
from nncf.tensor import functions as fns
from nncf.tensor.definitions import TensorDataType
Expand Down Expand Up @@ -122,7 +123,7 @@ def get_weight_compression_configuration(
"scale_estimation": scale_estimation or False,
"gptq": gptq or False,
"lora_correction": lora_correction or False,
"ignored_scope": ignored_scope or IgnoredScope(),
"ignored_scope": ignored_scope or Scope(),
"sensitivity_metric": (
(
SensitivityMetric.WEIGHT_QUANTIZATION_ERROR
Expand Down Expand Up @@ -506,9 +507,7 @@ def get_ignored_node_names(self, nncf_graph: NNCFGraph) -> set[str]:
:param nncf_graph: The NNCF graph to analyze.
:return: A set of node names to be ignored during weight compression.
"""
ignored_names = get_ignored_node_names_from_ignored_scope(
self._ignored_scope, nncf_graph, strict=self._ignored_scope.validate
)
ignored_names = get_node_names_from_scope(self._ignored_scope, nncf_graph, strict=self._ignored_scope.validate)

autogenerated_ignored_names = get_node_names_matching_graph_pattern(
nncf_graph, self._backend_entity.get_ignored_patterns()
Expand Down Expand Up @@ -858,7 +857,7 @@ def _get_ignored_scope_weight_statistics(self, model: TModel, graph: NNCFGraph)
:param graph: Model graph.
:return: A list of weight sizes for the ignored nodes.
"""
ignored_names = get_ignored_node_names_from_ignored_scope(self._ignored_scope, graph, strict=False)
ignored_names = get_node_names_from_scope(self._ignored_scope, graph, strict=False)
weighted_metatypes = (
self._backend_entity.matmul_metatypes
+ self._backend_entity.embedding_metatypes
Expand Down
Loading
Loading