Exemple #1
0
import torch.nn as nn
from nncf.common.utils.registry import Registry


COMPRESSION_MODULES = Registry('compression modules')


class ProxyModule:
    def __init__(self, module):
        self._module = module

    def __getattr__(self, name):
        return getattr(self._module, name)


class _NNCFModuleMixin:
    """Default class for modules that will be optimized by NNCF.

        Attributes:
            op_func_name    Name of corresponding torch function.
            target_weight_dim_for_compression   Target dimension of weights that will be compressed in some algorithms.
            ignored_algorithms   List of algorithms that will skip the module.
        """

    op_func_name = ""
    target_weight_dim_for_compression = 0
    ignored_algorithms = []

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        _NNCFModuleMixin.add_mixin_fields(self)
Exemple #2
0
import numpy as np
from scipy.interpolate import interp1d

from nncf.api.compression import CompressionAlgorithmController
from nncf.common.composite_compression import CompositeCompressionAlgorithmController
from nncf.common.utils.logger import logger as nncf_logger
from nncf.common.utils.registry import Registry
from nncf.config.config import NNCFConfig
from nncf.config.extractors import extract_accuracy_aware_training_params
from nncf.common.accuracy_aware_training.runner import TrainingRunner
from nncf.common.accuracy_aware_training.runner import TrainingRunnerCreator
from nncf.common.accuracy_aware_training.runner import EarlyExitTrainingRunnerCreator
from nncf.common.accuracy_aware_training.runner import AdaptiveCompressionLevelTrainingRunnerCreator

ModelType = TypeVar('ModelType')
ADAPTIVE_COMPRESSION_CONTROLLERS = Registry('adaptive_compression_controllers')


class TrainingLoop(ABC):
    """
    The training loop object is instantiated by the user, the training process
    is launched via the `run` method.
    """
    @abstractmethod
    def run(self,
            model: ModelType,
            train_epoch_fn,
            validate_fn,
            configure_optimizers_fn=None,
            dump_checkpoint_fn=None,
            tensorboard_writer=None,
Exemple #3
0
"""
 Copyright (c) 2020 Intel Corporation
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
      http://www.apache.org/licenses/LICENSE-2.0
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 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 nncf.common.utils.registry import Registry

NNCF_CUSTOM_OBJECTS = Registry('NNCF Custom Objects')
NNCF_QUANTIZATION_OPERATONS = Registry('NNCF Quantization Operations')


def get_nncf_custom_objects():
    return NNCF_CUSTOM_OBJECTS.registry_dict
from nncf.torch.graph.transformations.layout import PTTransformationLayout
from nncf.torch.nncf_network import NNCFNetwork

from nncf.api.compression import CompressionStage
from nncf.api.compression import CompressionScheduler
from nncf.torch.compression_method_api import PTCompressionAlgorithmBuilder
from nncf.torch.compression_method_api import PTCompressionAlgorithmController

from nncf.torch.compression_method_api import PTCompressionLoss
from nncf.common.compression import NO_COMPRESSION_ALGORITHM_NAME
from nncf.common.schedulers import StubCompressionScheduler
from nncf.common.utils.registry import Registry
from nncf.common.statistics import NNCFStatistics

PT_COMPRESSION_ALGORITHMS = Registry('compression algorithm',
                                     add_name_as_attr=True)


class ZeroCompressionLoss(PTCompressionLoss):
    def __init__(self, device: str):
        super().__init__()
        self._device = device

    def calculate(self) -> torch.Tensor:
        return torch.zeros([], device=self._device)


@PT_COMPRESSION_ALGORITHMS.register(NO_COMPRESSION_ALGORITHM_NAME)
class NoCompressionAlgorithmBuilder(PTCompressionAlgorithmBuilder):
    def _get_transformation_layout(
            self, target_model: NNCFNetwork) -> PTTransformationLayout:
Exemple #5
0
 You may obtain a copy of the License at
      http://www.apache.org/licenses/LICENSE-2.0
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 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 bisect import bisect_right
import numpy as np

from beta.nncf.api.compression import CompressionScheduler
from nncf.common.utils.registry import Registry

SPARSITY_SCHEDULERS = Registry("sparsity_schedulers")


class SparsityScheduler(CompressionScheduler):
    def __init__(self, sparsity_algo, params: dict = None):
        super().__init__()
        if params is None:
            self._params = dict()
        else:
            self._params = params

        self.algo = sparsity_algo
        self.initial_sparsity = self._params.get('sparsity_init', 0)
        self.sparsity_target = self._params.get('sparsity_target', 0.5)
        self.sparsity_target_epoch = self._params.get('sparsity_target_epoch',
                                                      90)
Exemple #6
0
 limitations under the License.
"""

import sys
from argparse import ArgumentParser
from collections import OrderedDict

import torch

from nncf.common.utils.registry import Registry

INCEPTION_NAME = 'inception'
RESNET_NAME = 'resnet'
MOBILENET_NAME = 'mobilenet'

KEYS_REPLACERS = Registry("keys_replacers")


@KEYS_REPLACERS.register(INCEPTION_NAME)
def inception_replacer(k):
    if 'RELU' in k:
        return k.replace('335', '0')
    return k


@KEYS_REPLACERS.register(MOBILENET_NAME)
def mobilenet_replacer(k):
    keywords = ['hardtanh', 'batch_norm', '__add__']
    if any(x in k for x in keywords):
        return k.replace('63', '0').replace('62', '0').replace('111', '0')
    return k
Exemple #7
0
 limitations under the License.
"""

import torch
import torch.nn as nn

from nncf.dynamic_graph.patch_pytorch import register_operator
from nncf.layer_utils import COMPRESSION_MODULES
from nncf.common.utils.registry import Registry
from nncf.utils import get_per_channel_scale_shape
from nncf.binarization.binarize_functions import XNORBinarizeFn, DOREFABinarizeFn
from nncf.binarization.binarize_functions import ActivationBinarizationScaleThresholdFn

from nncf.nncf_logger import logger as nncf_logger

BINARIZATION_MODULES = Registry('binarization_modules')


class BinarizationMode:
    XNOR = "xnor"
    DOREFA = "dorefa"


class BaseBinarizer(nn.Module):
    def __init__(self, enabled=False):
        super().__init__()
        self.register_buffer('enabled', torch.IntTensor([0]))
        if enabled:
            self.enable()

    def forward(self, x):
Exemple #8
0
NNCF_GENERAL_CONV_MODULES_DICT = dict(NNCF_CONV_MODULES_DICT)
NNCF_GENERAL_CONV_MODULES_DICT.update(NNCF_DECONV_MODULES_DICT)

NNCF_LINEAR_MODULES_DICT = {NNCFLinear: nn.Linear}

NNCF_PRUNING_MODULES_DICT = {
    NNCFConv1d: nn.Conv1d,
    NNCFConv2d: nn.Conv2d,
    NNCFConv3d: nn.Conv3d,
    NNCFConvTranspose2d: nn.ConvTranspose2d,
    NNCFConvTranspose3d: nn.ConvTranspose3d,
}
NNCF_PRUNING_MODULES_MAP = {k.__name__: v.__name__ for k, v in NNCF_CONV_MODULES_DICT.items()}
NNCF_PRUNING_MODULES = list(NNCF_CONV_MODULES_MAP.keys())

UNWRAPPED_USER_MODULES = Registry('user_modules')
NNCF_WRAPPED_USER_MODULES_DICT = {}


def register_module(*quantizable_field_names: str, ignored_algorithms: list = None):
    # quantizable_field_names will work for `weight` attributes only. Should later extend to registering
    # customly named attributes if it becomes necessary
    def wrap(cls):
        UNWRAPPED_USER_MODULES.registry_dict[cls.__name__] = cls
        nncf_wrapped_module_class_name = 'NNCFUser{}'.format(cls.__name__)
        NNCF_WRAPPED_USER_MODULES_DICT[cls] = type(nncf_wrapped_module_class_name, (_NNCFModuleMixin, cls), {})
        get_base_attributes_fn = lambda self: GenericWeightedLayerAttributes(self.weight.requires_grad,
                                                                             self.weight.shape)
        setattr(NNCF_WRAPPED_USER_MODULES_DICT[cls], "get_weight_shape", get_base_attributes_fn)
        if ignored_algorithms:
            setattr(NNCF_WRAPPED_USER_MODULES_DICT[cls], "ignored_algorithms", ignored_algorithms)
Exemple #9
0
from torch import distributed

from nncf.torch.checkpoint_loading import OPTIONAL_PARAMETERS_REGISTRY
from nncf.common.utils.debug import is_debug
from nncf.torch.functions import clamp
from nncf.common.utils.logger import logger as nncf_logger
from nncf.common.quantization.structs import QuantizationMode, QuantizerConfig, QuantizerSpec
from nncf.common.quantization.quantizers import calculate_symmetric_level_ranges
from nncf.common.quantization.quantizers import calculate_asymmetric_level_ranges
from nncf.torch.quantization.quantize_functions import symmetric_quantize, asymmetric_quantize, \
    ExportQuantizeToFakeQuantize, get_scale_zp_from_input_low_input_high, ExportQuantizeToONNXQuantDequant, TuneRange
from nncf.torch.layer_utils import COMPRESSION_MODULES, CompressionParameter
from nncf.common.utils.registry import Registry
from nncf.torch.utils import get_flat_tensor_contents_string, no_jit_trace, is_tracing_state

QUANTIZATION_MODULES = Registry('quantization_modules')
INITIALIZABLE_MODULES = Registry('initializable_modules')


class QuantizerExportMode(Enum):
    FAKE_QUANTIZE = "fake_quantize"
    ONNX_QUANTIZE_DEQUANTIZE_PAIRS = "quantize_dequantize"

    @staticmethod
    def from_str(config_value: str) -> 'HWConfigType':
        if config_value == QuantizerExportMode.FAKE_QUANTIZE.value:
            return QuantizerExportMode.FAKE_QUANTIZE
        if config_value == QuantizerExportMode.ONNX_QUANTIZE_DEQUANTIZE_PAIRS.value:
            return QuantizerExportMode.ONNX_QUANTIZE_DEQUANTIZE_PAIRS
        raise RuntimeError("Unknown quantizer ONNX export mode string")
Exemple #10
0
      http://www.apache.org/licenses/LICENSE-2.0
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 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 typing import Optional
import numpy as np
import scipy.optimize

from nncf.common.utils.registry import Registry
from nncf.common.schedulers import ExponentialDecaySchedule, BaseCompressionScheduler

PRUNING_SCHEDULERS = Registry('pruning_schedulers')


class PruningScheduler(BaseCompressionScheduler):
    """
    This is the class from which all pruning schedulers inherit.

    A pruning scheduler is an object which specifies the pruning
    level at each training epoch. It involves a scheduling algorithm,
    defined in the `_calculate_pruning_level()` method and a state
    (some parameters required for current pruning level calculation)
    defined in the `__init__()` method.

    :param initial_level: Pruning level which already has been
        applied to the model. It is the level at which the schedule begins.
    :param target_level: Pruning level at which the schedule ends.
 You may obtain a copy of the License at
      http://www.apache.org/licenses/LICENSE-2.0
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 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 beta.nncf.api.compression import CompressionAlgorithmBuilder
from beta.nncf.api.compression import CompressionAlgorithmController
from beta.nncf.tensorflow.graph.transformations.layout import TransformationLayout
from beta.nncf.utils.logger import logger
from nncf.common.utils.registry import Registry

TF_COMPRESSION_ALGORITHMS = Registry('compression algorithm')


@TF_COMPRESSION_ALGORITHMS.register('NoCompressionAlgorithm')
class NoCompressionAlgorithmBuilder(CompressionAlgorithmBuilder):
    def get_transformation_layout(self, _):
        return TransformationLayout()


class NoCompressionAlgorithmController(CompressionAlgorithmController):
    pass


def get_compression_algorithm_builder(config):
    algorithm_key = config.get('algorithm', 'NoCompressionAlgorithm')
    logger.info('Creating compression algorithm: {}'.format(algorithm_key))
        return wrap

    def get_operator_metatype_by_op_name(
            self, op_name: str) -> Type[OperatorMetatype]:
        """
        Returns the operator metatype by operator name.

        :param op_name: The operator name.
        :return: The operator metatype.
        """
        if op_name not in self._op_name_to_op_meta_dict:
            return UnknownMetatype
        return self._op_name_to_op_meta_dict[op_name]


NOOP_METATYPES = Registry('noop_metatypes')
INPUT_NOOP_METATYPES = Registry('input_noop_metatypes')
OUTPUT_NOOP_METATYPES = Registry('output_noop_metatypes')


class UnknownMetatype(OperatorMetatype):
    """
    UnknownMetatype is mapped to operations in NNCFGraph, which are unknown for algorithms,
    typically these are the operations that haven't been discovered before.
    Algorithms should avoid processing graph nodes with this metatype.
    """
    name = "unknown"

    @classmethod
    def get_all_aliases(cls) -> List[str]:
        return [cls.name]
Exemple #13
0
import enum
import torch

from abc import ABC, abstractmethod
from nncf.common.utils.registry import Registry

EXTENSIONS = Registry('extensions')


class ExtensionsType(enum.Enum):
    CPU = 0
    CUDA = 1


class ExtensionLoader(ABC):
    @staticmethod
    @abstractmethod
    def extension_type():
        pass

    @staticmethod
    @abstractmethod
    def load():
        pass


def _force_build_extensions(ext_type: ExtensionsType):
    for class_type in EXTENSIONS.registry_dict.values():
        if class_type.extension_type() != ext_type:
            continue
        class_type.load()
Exemple #14
0
      http://www.apache.org/licenses/LICENSE-2.0
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 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.
"""
import logging

from nncf.common.utils.registry import Registry
from nncf.common.schedulers import BaseCompressionScheduler
from nncf.api.compression import CompressionStage

logger = logging.getLogger(__name__)

QUANTIZATION_SCHEDULERS = Registry("quantization_schedulers")


@QUANTIZATION_SCHEDULERS.register("staged")
class StagedQuantizationScheduler(BaseCompressionScheduler):
    def __init__(self,
                 quantization_ctrl: 'QuantizationController',
                 params=None):
        super().__init__()
        if params is None:
            params = {}
        self.algo = quantization_ctrl
        self.activations_quant_start_epoch = params.get(
            'activations_quant_start_epoch', 1)
        self.weights_quant_start_epoch = params.get(
            'weights_quant_start_epoch', 1)