Skip to content

Commit

Permalink
Init commit
Browse files Browse the repository at this point in the history
  • Loading branch information
daniil-lyakhov committed Jun 21, 2023
1 parent 0a263dc commit 66f55fd
Show file tree
Hide file tree
Showing 26 changed files with 793 additions and 106 deletions.
63 changes: 15 additions & 48 deletions nncf/common/graph/layer_attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from abc import ABC
from abc import abstractmethod
from dataclasses import dataclass
from enum import Enum
from typing import Any, List, Tuple, Union
from typing import Any, Dict, List, Tuple, TypeVar, Union


class Dtype(Enum):
Expand All @@ -26,6 +27,9 @@ class BaseLayerAttributes(ABC):
of modules/layers.
"""

def __eq__(self, __o: object) -> bool:
return isinstance(__o, self.__class__) and self.__dict__ == __o.__dict__


class MultipleInputLayerAttributes(BaseLayerAttributes):
def __init__(self, axis: int):
Expand All @@ -35,9 +39,6 @@ def __init__(self, axis: int):
"""
self.axis = axis

def __eq__(self, other: Any):
return isinstance(other, MultipleInputLayerAttributes) and self.axis == other.axis


class MultipleOutputLayerAttributes(BaseLayerAttributes):
def __init__(self, chunks: Union[int, List], axis: int):
Expand All @@ -49,11 +50,6 @@ def __init__(self, chunks: Union[int, List], axis: int):
self.chunks = chunks
self.axis = axis

def __eq__(self, other: Any):
return (
isinstance(other, MultipleOutputLayerAttributes) and self.chunks == other.chunks and self.axis == other.axis
)


class WeightedLayerAttributes(BaseLayerAttributes):
def __init__(self, weight_requires_grad: bool, dtype: Dtype = Dtype.FLOAT):
Expand All @@ -66,9 +62,6 @@ def __init__(self, weight_requires_grad: bool, dtype: Dtype = Dtype.FLOAT):
self.weight_requires_grad = weight_requires_grad
self.dtype = dtype

def __eq__(self, other: Any):
return isinstance(other, WeightedLayerAttributes) and self.weight_requires_grad == other.weight_requires_grad

@abstractmethod
def get_weight_shape(self) -> List[int]:
pass
Expand Down Expand Up @@ -107,6 +100,14 @@ def get_target_dim_for_compression(self) -> int:
return 0


WeightID = TypeVar("WeightID")


class MultipleWeightsLayerAttributes(BaseLayerAttributes):
def __init__(self, weights_attributes: Dict[WeightID, GenericWeightedLayerAttributes]):
self.weights_attributes = weights_attributes


class LinearLayerAttributes(WeightedLayerAttributes):
def __init__(self, weight_requires_grad: bool, in_features: int, out_features: int, bias: bool = True):
"""
Expand Down Expand Up @@ -140,6 +141,7 @@ def __init__(
out_channels: int,
kernel_size: Tuple[int, ...],
stride: Tuple[int, ...],
dilations: Tuple[int, ...],
groups: int,
transpose: bool,
padding_values: Tuple[int, ...],
Expand All @@ -161,22 +163,11 @@ def __init__(
self.out_channels = out_channels
self.kernel_size = kernel_size
self.stride = stride
self.dilations = dilations
self.groups = groups
self.transpose = transpose
self.padding_values = padding_values

def __eq__(self, other: Any):
return (
isinstance(other, ConvolutionLayerAttributes)
and super().__eq__(other)
and self.in_channels == other.in_channels
and self.out_channels == other.out_channels
and self.kernel_size == other.kernel_size
and self.stride == other.stride
and self.groups == other.groups
and self.transpose == other.transpose
)

def get_weight_shape(self) -> List[int]:
if not self.transpose:
return [self.out_channels, self.in_channels // self.groups, *self.kernel_size]
Expand All @@ -202,14 +193,6 @@ def __init__(self, weight_requires_grad: bool, num_channels: int, num_groups: in
self.num_channels = num_channels
self.num_groups = num_groups

def __eq__(self, other: Any):
return (
isinstance(other, GroupNormLayerAttributes)
and super().__eq__(other)
and self.num_channels == other.num_channels
and self.num_groups == other.num_groups
)

def get_weight_shape(self) -> List[int]:
return [self.num_channels]

Expand Down Expand Up @@ -238,14 +221,6 @@ class TransposeLayerAttributes(BaseLayerAttributes):
dim0: int
dim1: int

def __eq__(self, other: Any) -> bool:
return (
isinstance(other, TransposeLayerAttributes)
and super().__eq__(other)
and self.dim0 == other.dim0
and self.dim1 == other.dim1
)


@dataclass
class PermuteLayerAttributes(BaseLayerAttributes):
Expand All @@ -255,14 +230,6 @@ class PermuteLayerAttributes(BaseLayerAttributes):

permutation: List[int]

def __eq__(self, other: Any) -> bool:
return (
isinstance(other, PermuteLayerAttributes)
and super().__eq__(other)
and len(self.permutation) == len(other.permutation)
and (l == r for l, r in zip(self.permutation, other.permutation))
)


@dataclass
class GetItemLayerAttributes(BaseLayerAttributes):
Expand Down
3 changes: 3 additions & 0 deletions nncf/common/tensor_statistics/aggregator.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ def collect_statistics(self, model: TModel) -> None:
model_with_outputs = model_transformer.transform(transformation_layout)
engine = EngineFactory.create(model_with_outputs)

if not self.statistic_points:
return

for input_data in tqdm(
islice(self.dataset.get_inference_data(), self.stat_subset_size),
total=self.stat_subset_size,
Expand Down
4 changes: 2 additions & 2 deletions nncf/experimental/common/tensor_statistics/collectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,11 +442,11 @@ class QuantileReducerBase(TensorReducerBase):
def __init__(
self,
reduction_shape: Optional[ReductionShape] = None,
quantile: Optional[Union[float, List[float]]] = None,
quantile: Union[float, List[float]] = (0.01, 0.99),
inplace: bool = False,
):
super().__init__(reduction_shape, False)
self._quantile = [0.01, 0.99] if quantile is None else quantile
self._quantile = quantile

def __eq__(self, __o: object) -> bool:
return super().__eq__(__o) and self._quantile == __o._quantile
Expand Down
76 changes: 76 additions & 0 deletions nncf/openvino/graph/layer_attributes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
from dataclasses import dataclass
from typing import Any, Dict, List, Tuple, TypeVar

from nncf.common.graph.layer_attributes import BaseLayerAttributes
from nncf.common.graph.layer_attributes import ConvolutionLayerAttributes
from nncf.common.graph.layer_attributes import Dtype
from nncf.common.graph.layer_attributes import GenericWeightedLayerAttributes
from nncf.common.graph.layer_attributes import MultipleWeightsLayerAttributes
from nncf.common.graph.layer_attributes import WeightedLayerAttributes
from nncf.openvino.graph.metatypes.openvino_metatypes import OVConvolutionMetatype
from nncf.openvino.graph.metatypes.openvino_metatypes import OVDepthwiseConvolutionMetatype
from nncf.openvino.graph.metatypes.openvino_metatypes import OVGroupConvolutionMetatype


class OVConstantLayerAttributesContainer(BaseLayerAttributes):
"""
This class stores mapping weights port indices to constant name and shape.
"""

def __init__(self, const_attrs: Dict[int, Any], common_layer_attrs: Dict[int, BaseLayerAttributes]):
"""
:param const_attrs: Map of weights port ID to corresponding const attributes.
"""
self.const_attrs = const_attrs
self.common_layer_attrs = common_layer_attrs

def get_const_port_ids(self) -> List[int]:
"""
Returns indices of input ports corresponding to the constant nodes.
:returns: List of input port indices with constants.
"""
return list(self.const_attrs.keys())


def get_weighted_layer_attributes(ov_node, ov_metatype, constant_attributes: Dict[str, Any]):
retval = {}
for port_id, attrs in constant_attributes.items():
if ov_metatype in [OVConvolutionMetatype, OVDepthwiseConvolutionMetatype, OVGroupConvolutionMetatype]:
node_attrs = ov_node.get_attributes()
kwargs = {
"weight_requires_grad": False,
"stride": tuple(node_attrs["strides"]),
"dilations": node_attrs["dilations"],
"transpose": attrs.get("transpose", False),
# TODO: Unify pad attribute
"padding_values": tuple(node_attrs["pads_begin"] + node_attrs["pads_end"]),
}

const_shape = attrs["shape"]
if ov_metatype == OVConvolutionMetatype:
kwargs.update(
{
"in_channels": const_shape[1],
"out_channels": const_shape[0],
"kernel_size": tuple(const_shape[2:]),
"groups": 1,
}
)
else:
kwargs.update(
{
"in_channels": const_shape[2],
"out_channels": const_shape[1],
"kernel_size": tuple(const_shape[3:]),
"groups": const_shape[0],
}
)

common_layer_attr = ConvolutionLayerAttributes(**kwargs)
else:
common_layer_attr = GenericWeightedLayerAttributes(
weight_requires_grad=False, weight_shape=attrs.get("shape", None)
)
retval[port_id] = common_layer_attr
return retval
40 changes: 15 additions & 25 deletions nncf/openvino/graph/nncf_graph_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,31 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from collections import UserDict
from collections import deque
from typing import Dict, List, Type
from dataclasses import dataclass
from typing import Any, Dict, List, Tuple, Type

import openvino.runtime as ov

from nncf.common.graph import BaseLayerAttributes
from nncf.common.graph import NNCFGraph
from nncf.common.graph.layer_attributes import BaseLayerAttributes
from nncf.common.graph.layer_attributes import ConvolutionLayerAttributes
from nncf.common.graph.layer_attributes import Dtype
from nncf.common.graph.layer_attributes import MultipleWeightsLayerAttributes
from nncf.common.graph.layer_attributes import WeightedLayerAttributes
from nncf.common.graph.operator_metatypes import OperatorMetatype
from nncf.common.graph.operator_metatypes import UnknownMetatype
from nncf.openvino.graph.layer_attributes import OVConstantLayerAttributesContainer
from nncf.openvino.graph.layer_attributes import get_weighted_layer_attributes
from nncf.openvino.graph.metatypes.openvino_metatypes import METATYPES_WITH_CONST_PORT_ID
from nncf.openvino.graph.metatypes.openvino_metatypes import OV_OPERATOR_METATYPES
from nncf.openvino.graph.metatypes.openvino_metatypes import OVConstantMetatype
from nncf.openvino.graph.metatypes.openvino_metatypes import OVConvolutionBackpropDataMetatype
from nncf.openvino.graph.metatypes.openvino_metatypes import OVConvolutionMetatype
from nncf.openvino.graph.metatypes.openvino_metatypes import OVDepthwiseConvolutionMetatype
from nncf.openvino.graph.metatypes.openvino_metatypes import OVGroupConvolutionBackpropDataMetatype
from nncf.openvino.graph.metatypes.openvino_metatypes import OVGroupConvolutionMetatype
from nncf.openvino.graph.metatypes.openvino_metatypes import OVGRUSequenceMetatype
from nncf.openvino.graph.metatypes.openvino_metatypes import OVLSTMSequenceMetatype
from nncf.openvino.graph.metatypes.openvino_metatypes import OVMatMulMetatype
Expand Down Expand Up @@ -191,32 +201,12 @@ def create_nncf_graph(model: ov.Model) -> NNCFGraph:

if const_attrs:
nncf_node = nncf_graph.get_node_by_name(node_name)
nncf_node.layer_attributes = OVConstantLayerAttributes(const_attrs)

common_layer_attrs = get_weighted_layer_attributes(node, metatype, const_attrs)
nncf_node.layer_attributes = OVConstantLayerAttributesContainer(const_attrs, common_layer_attrs)
GraphConverter._add_edges_to_nncf_graph(model, nncf_graph)
return nncf_graph


class OVConstantLayerAttributes(BaseLayerAttributes):
"""
This class stores mapping weights port indices to constant name and shape.
"""

def __init__(self, const_attrs: Dict[int, Dict]):
"""
:param const_attrs: Map of weights port ID to corresponding const attributes.
"""
self.const_attrs = const_attrs

def get_const_port_ids(self) -> List[int]:
"""
Returns indices of input ports corresponding to the constant nodes.
:returns: List of input port indices with constants.
"""
return list(self.const_attrs.keys())


def get_operation_const_op(operation: ov.Node, const_port_id: int) -> ov.Node:
"""
Returns constant node of given operation placed on given const port id.
Expand Down Expand Up @@ -247,6 +237,6 @@ def get_operation_const_op(operation: ov.Node, const_port_id: int) -> ov.Node:
queue.append(curr_node.input_value(0).get_node())

if constant_node is None:
raise RuntimeError("Constant node was expected but could not find it.")
raise RuntimeError("Constant node was expected but could not be found.")

return constant_node
4 changes: 2 additions & 2 deletions nncf/openvino/graph/node_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@

from nncf.common.graph.graph import NNCFGraph
from nncf.common.graph.graph import NNCFNode
from nncf.openvino.graph.layer_attributes import OVConstantLayerAttributesContainer
from nncf.openvino.graph.metatypes.openvino_metatypes import GENERAL_WEIGHT_LAYER_METATYPES
from nncf.openvino.graph.metatypes.openvino_metatypes import OPERATIONS_WITH_BIAS_METATYPES
from nncf.openvino.graph.metatypes.openvino_metatypes import OVAddMetatype
from nncf.openvino.graph.metatypes.openvino_metatypes import OVConstantMetatype
from nncf.openvino.graph.metatypes.openvino_metatypes import OVConvertMetatype
from nncf.openvino.graph.metatypes.openvino_metatypes import OVMatMulMetatype
from nncf.openvino.graph.nncf_graph_builder import OVConstantLayerAttributes

InplaceInsertionFnType = Callable[[ov.Node, int], ov.Node]

Expand Down Expand Up @@ -323,7 +323,7 @@ def get_weight_channel_axes(node: NNCFNode, weights_port_id: int) -> List[int]:

channel_axes = node.metatype.const_channel_axis
if node.metatype == OVMatMulMetatype:
assert isinstance(node.layer_attributes, OVConstantLayerAttributes)
assert isinstance(node.layer_attributes, OVConstantLayerAttributesContainer)
assert len(channel_axes) == 1
assert channel_axes[0] in [-1, -2]
const_attrs = node.layer_attributes.const_attrs[weights_port_id]
Expand Down
1 change: 1 addition & 0 deletions nncf/openvino/quantization/quantize_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ def quantize_impl(
"""
Implementation of the `quantize()` method for the OpenVINO backend.
"""
# subset_size = 1
if should_use_pot(advanced_parameters):
from nncf.openvino.pot.quantization.quantize_model import quantize_impl as pot_quantize_impl

Expand Down
1 change: 1 addition & 0 deletions nncf/quantization/advanced_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ class AdvancedQuantizationParameters:
overflow_fix: OverflowFix = OverflowFix.FIRST_LAYER
quantize_outputs: bool = False
inplace_statistics: bool = True
disable_channel_alignment: bool = False
disable_bias_correction: bool = False

# Advanced Quantization parameters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

from nncf.common.graph import NNCFGraph
from nncf.common.graph import NNCFNode
from nncf.openvino.graph.layer_attributes import OVConstantLayerAttributesContainer
from nncf.openvino.graph.metatypes.common import CONSTANT_OPERATIONS
from nncf.openvino.graph.metatypes.common import FAKE_QUANTIZE_OPERATIONS
from nncf.openvino.graph.metatypes.common import QUANTIZABLE_OPERATIONS
Expand All @@ -24,7 +25,6 @@
from nncf.openvino.graph.metatypes.openvino_metatypes import GENERAL_WEIGHT_LAYER_METATYPES
from nncf.openvino.graph.metatypes.openvino_metatypes import OVConcatMetatype
from nncf.openvino.graph.metatypes.openvino_metatypes import OVOpMetatype
from nncf.openvino.graph.nncf_graph_builder import OVConstantLayerAttributes
from nncf.openvino.graph.node_utils import get_bias_value
from nncf.openvino.graph.node_utils import get_weight_value
from nncf.openvino.graph.node_utils import is_node_with_bias
Expand Down Expand Up @@ -67,7 +67,7 @@ def is_node_with_bias(node: NNCFNode, nncf_graph: NNCFGraph) -> bool:
@staticmethod
def is_node_with_weight(node: NNCFNode) -> bool:
return node.metatype in GENERAL_WEIGHT_LAYER_METATYPES and isinstance(
node.layer_attributes, OVConstantLayerAttributes
node.layer_attributes, OVConstantLayerAttributesContainer
)

@staticmethod
Expand Down
1 change: 1 addition & 0 deletions nncf/quantization/algorithms/algorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

from abc import ABC
from abc import abstractmethod
from abc import abstractproperty
from typing import Dict, Optional, TypeVar

from nncf import Dataset
Expand Down
Loading

0 comments on commit 66f55fd

Please sign in to comment.