diff --git a/model_compression_toolkit/core/__init__.py b/model_compression_toolkit/core/__init__.py index b8f6ee3e9..cb41daafd 100644 --- a/model_compression_toolkit/core/__init__.py +++ b/model_compression_toolkit/core/__init__.py @@ -18,7 +18,7 @@ from model_compression_toolkit.core.common.quantization.debug_config import DebugConfig from model_compression_toolkit.core.common.quantization import quantization_config from model_compression_toolkit.core.common.mixed_precision import mixed_precision_quantization_config -from model_compression_toolkit.core.common.quantization.quantization_config import QuantizationConfig, QuantizationErrorMethod, DEFAULTCONFIG +from model_compression_toolkit.core.common.quantization.quantization_config import QuantizationConfig, QuantizationErrorMethod, DEFAULTCONFIG, CustomOpsetLayers from model_compression_toolkit.core.common.quantization.bit_width_config import BitWidthConfig from model_compression_toolkit.core.common.quantization.core_config import CoreConfig from model_compression_toolkit.core.common.mixed_precision.resource_utilization_tools.resource_utilization import ResourceUtilization diff --git a/model_compression_toolkit/core/common/quantization/quantization_config.py b/model_compression_toolkit/core/common/quantization/quantization_config.py index cf3a39976..f43831723 100644 --- a/model_compression_toolkit/core/common/quantization/quantization_config.py +++ b/model_compression_toolkit/core/common/quantization/quantization_config.py @@ -13,13 +13,30 @@ # limitations under the License. # ============================================================================== -from dataclasses import dataclass, field +from dataclasses import dataclass import math from enum import Enum +from typing import Optional, Dict, NamedTuple, List +from model_compression_toolkit import DefaultDict from model_compression_toolkit.constants import MIN_THRESHOLD +class CustomOpsetLayers(NamedTuple): + """ + This struct defines a set of operators from a specific framework, which will be used to configure a custom operator + set in the TPC. + + Args: + operators: a list of framework operators to map to a certain custom opset name. + attr_mapping: a mapping between an opset name to a mapping between its attributes' general names and names in + the framework. + """ + + operators: List + attr_mapping: Optional[Dict[str, DefaultDict]] = None + + class QuantizationErrorMethod(Enum): """ Method for quantization threshold selection: @@ -86,6 +103,7 @@ class QuantizationConfig: concat_threshold_update: bool = False activation_bias_correction: bool = False activation_bias_correction_threshold: float = 0.0 + custom_tpc_opset_to_layer: Optional[Dict[str, CustomOpsetLayers]] = None # Default quantization configuration the library use. diff --git a/model_compression_toolkit/core/keras/resource_utilization_data_facade.py b/model_compression_toolkit/core/keras/resource_utilization_data_facade.py index 16fde507a..ffc313c37 100644 --- a/model_compression_toolkit/core/keras/resource_utilization_data_facade.py +++ b/model_compression_toolkit/core/keras/resource_utilization_data_facade.py @@ -18,6 +18,7 @@ from model_compression_toolkit.core.common.mixed_precision.resource_utilization_tools.resource_utilization import ResourceUtilization from model_compression_toolkit.logger import Logger from model_compression_toolkit.constants import TENSORFLOW +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel from model_compression_toolkit.target_platform_capabilities.target_platform import TargetPlatformCapabilities from model_compression_toolkit.core.common.mixed_precision.resource_utilization_tools.resource_utilization_data import compute_resource_utilization_data from model_compression_toolkit.verify_packages import FOUND_TF @@ -27,6 +28,8 @@ from model_compression_toolkit.core.keras.default_framework_info import DEFAULT_KERAS_INFO from model_compression_toolkit.core.keras.keras_implementation import KerasImplementation from tensorflow.keras.models import Model + from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras from model_compression_toolkit import get_target_platform_capabilities @@ -36,7 +39,8 @@ def keras_resource_utilization_data(in_model: Model, representative_data_gen: Callable, core_config: CoreConfig = CoreConfig( mixed_precision_config=MixedPrecisionQuantizationConfig()), - target_platform_capabilities: TargetPlatformCapabilities = KERAS_DEFAULT_TPC) -> ResourceUtilization: + target_platform_capabilities: TargetPlatformModel = KERAS_DEFAULT_TPC + ) -> ResourceUtilization: """ Computes resource utilization data that can be used to calculate the desired target resource utilization for mixed-precision quantization. @@ -78,6 +82,12 @@ def keras_resource_utilization_data(in_model: Model, fw_impl = KerasImplementation() + # Attach tpc model to framework + attach2keras = AttachTpcToKeras() + target_platform_capabilities = attach2keras.attach( + target_platform_capabilities, + custom_opset2layer=core_config.quantization_config.custom_tpc_opset_to_layer) + return compute_resource_utilization_data(in_model, representative_data_gen, core_config, diff --git a/model_compression_toolkit/core/pytorch/resource_utilization_data_facade.py b/model_compression_toolkit/core/pytorch/resource_utilization_data_facade.py index 4daa913a2..23c1d2c4c 100644 --- a/model_compression_toolkit/core/pytorch/resource_utilization_data_facade.py +++ b/model_compression_toolkit/core/pytorch/resource_utilization_data_facade.py @@ -17,19 +17,21 @@ from model_compression_toolkit.logger import Logger from model_compression_toolkit.constants import PYTORCH +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel from model_compression_toolkit.target_platform_capabilities.target_platform import TargetPlatformCapabilities from model_compression_toolkit.core.common.mixed_precision.resource_utilization_tools.resource_utilization import ResourceUtilization -from model_compression_toolkit.core.common.framework_info import FrameworkInfo from model_compression_toolkit.core.common.mixed_precision.resource_utilization_tools.resource_utilization_data import compute_resource_utilization_data from model_compression_toolkit.core.common.quantization.core_config import CoreConfig from model_compression_toolkit.core.common.mixed_precision.mixed_precision_quantization_config import MixedPrecisionQuantizationConfig +from model_compression_toolkit.target_platform_capabilities.constants import DEFAULT_TP_MODEL from model_compression_toolkit.verify_packages import FOUND_TORCH if FOUND_TORCH: from model_compression_toolkit.core.pytorch.default_framework_info import DEFAULT_PYTORCH_INFO from model_compression_toolkit.core.pytorch.pytorch_implementation import PytorchImplementation - from model_compression_toolkit.target_platform_capabilities.constants import DEFAULT_TP_MODEL from torch.nn import Module + from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2pytorch import \ + AttachTpcToPytorch from model_compression_toolkit import get_target_platform_capabilities @@ -39,7 +41,7 @@ def pytorch_resource_utilization_data(in_model: Module, representative_data_gen: Callable, core_config: CoreConfig = CoreConfig(), - target_platform_capabilities: TargetPlatformCapabilities = PYTORCH_DEFAULT_TPC + target_platform_capabilities: TargetPlatformModel= PYTORCH_DEFAULT_TPC ) -> ResourceUtilization: """ Computes resource utilization data that can be used to calculate the desired target resource utilization for mixed-precision quantization. @@ -80,6 +82,12 @@ def pytorch_resource_utilization_data(in_model: Module, fw_impl = PytorchImplementation() + # Attach tpc model to framework + attach2pytorch = AttachTpcToPytorch() + target_platform_capabilities = ( + attach2pytorch.attach(target_platform_capabilities, + custom_opset2layer=core_config.quantization_config.custom_tpc_opset_to_layer)) + return compute_resource_utilization_data(in_model, representative_data_gen, core_config, diff --git a/model_compression_toolkit/gptq/keras/quantization_facade.py b/model_compression_toolkit/gptq/keras/quantization_facade.py index 9c723ae8a..7d5ba1f7e 100644 --- a/model_compression_toolkit/gptq/keras/quantization_facade.py +++ b/model_compression_toolkit/gptq/keras/quantization_facade.py @@ -22,6 +22,7 @@ LR_BIAS_DEFAULT, GPTQ_MOMENTUM, REG_DEFAULT_SLA from model_compression_toolkit.logger import Logger from model_compression_toolkit.constants import TENSORFLOW, ACT_HESSIAN_DEFAULT_BATCH_SIZE, GPTQ_HESSIAN_NUM_SAMPLES +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel from model_compression_toolkit.verify_packages import FOUND_TF from model_compression_toolkit.core.common.user_info import UserInformation from model_compression_toolkit.gptq.common.gptq_config import GradientPTQConfig, GPTQHessianScoresConfig, \ @@ -47,6 +48,8 @@ from model_compression_toolkit.exporter.model_wrapper import get_exportable_keras_model from model_compression_toolkit import get_target_platform_capabilities from mct_quantizers.keras.metadata import add_metadata + from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras # As from TF2.9 optimizers package is changed if version.parse(tf.__version__) < version.parse("2.9"): @@ -152,7 +155,7 @@ def keras_gradient_post_training_quantization(in_model: Model, representative_da gptq_representative_data_gen: Callable = None, target_resource_utilization: ResourceUtilization = None, core_config: CoreConfig = CoreConfig(), - target_platform_capabilities: TargetPlatformCapabilities = DEFAULT_KERAS_TPC) -> Tuple[Model, UserInformation]: + target_platform_capabilities: TargetPlatformModel = DEFAULT_KERAS_TPC) -> Tuple[Model, UserInformation]: """ Quantize a trained Keras model using post-training quantization. The model is quantized using a symmetric constraint quantization thresholds (power of two). @@ -237,6 +240,12 @@ def keras_gradient_post_training_quantization(in_model: Model, representative_da fw_impl = GPTQKerasImplemantation() + # Attach tpc model to framework + attach2keras = AttachTpcToKeras() + target_platform_capabilities = attach2keras.attach( + target_platform_capabilities, + custom_opset2layer=core_config.quantization_config.custom_tpc_opset_to_layer) + tg, bit_widths_config, hessian_info_service, scheduling_info = core_runner(in_model=in_model, representative_data_gen=representative_data_gen, core_config=core_config, diff --git a/model_compression_toolkit/gptq/pytorch/quantization_facade.py b/model_compression_toolkit/gptq/pytorch/quantization_facade.py index dbe964ee0..38b09aaa8 100644 --- a/model_compression_toolkit/gptq/pytorch/quantization_facade.py +++ b/model_compression_toolkit/gptq/pytorch/quantization_facade.py @@ -31,6 +31,7 @@ from model_compression_toolkit.gptq.runner import gptq_runner from model_compression_toolkit.logger import Logger from model_compression_toolkit.metadata import create_model_metadata +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel from model_compression_toolkit.target_platform_capabilities.target_platform import TargetPlatformCapabilities from model_compression_toolkit.verify_packages import FOUND_TORCH @@ -47,6 +48,9 @@ from torch.optim import Adam, Optimizer from model_compression_toolkit import get_target_platform_capabilities from mct_quantizers.pytorch.metadata import add_metadata + from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2pytorch import \ + AttachTpcToPytorch + DEFAULT_PYTORCH_TPC = get_target_platform_capabilities(PYTORCH, DEFAULT_TP_MODEL) def get_pytorch_gptq_config(n_epochs: int, @@ -140,7 +144,7 @@ def pytorch_gradient_post_training_quantization(model: Module, core_config: CoreConfig = CoreConfig(), gptq_config: GradientPTQConfig = None, gptq_representative_data_gen: Callable = None, - target_platform_capabilities: TargetPlatformCapabilities = DEFAULT_PYTORCH_TPC): + target_platform_capabilities: TargetPlatformModel = DEFAULT_PYTORCH_TPC): """ Quantize a trained Pytorch module using post-training quantization. By default, the module is quantized using a symmetric constraint quantization thresholds @@ -209,6 +213,11 @@ def pytorch_gradient_post_training_quantization(model: Module, fw_impl = GPTQPytorchImplemantation() + # Attach tpc model to framework + attach2pytorch = AttachTpcToPytorch() + target_platform_capabilities = attach2pytorch.attach(target_platform_capabilities, + core_config.quantization_config.custom_tpc_opset_to_layer) + # ---------------------- # # Core Runner # ---------------------- # diff --git a/model_compression_toolkit/pruning/keras/pruning_facade.py b/model_compression_toolkit/pruning/keras/pruning_facade.py index 817c87567..cd565c4bc 100644 --- a/model_compression_toolkit/pruning/keras/pruning_facade.py +++ b/model_compression_toolkit/pruning/keras/pruning_facade.py @@ -17,12 +17,12 @@ from model_compression_toolkit import get_target_platform_capabilities from model_compression_toolkit.constants import TENSORFLOW +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel from model_compression_toolkit.verify_packages import FOUND_TF from model_compression_toolkit.core.common.mixed_precision.resource_utilization_tools.resource_utilization import ResourceUtilization from model_compression_toolkit.core.common.pruning.pruner import Pruner from model_compression_toolkit.core.common.pruning.pruning_config import PruningConfig from model_compression_toolkit.core.common.pruning.pruning_info import PruningInfo -from model_compression_toolkit.core.common.quantization.bit_width_config import BitWidthConfig from model_compression_toolkit.core.common.quantization.set_node_quantization_config import set_quantization_configuration_to_graph from model_compression_toolkit.core.graph_prep_runner import read_model_to_graph from model_compression_toolkit.logger import Logger @@ -35,6 +35,8 @@ from model_compression_toolkit.core.keras.pruning.pruning_keras_implementation import PruningKerasImplementation from model_compression_toolkit.core.keras.default_framework_info import DEFAULT_KERAS_INFO from tensorflow.keras.models import Model + from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras DEFAULT_KERAS_TPC = get_target_platform_capabilities(TENSORFLOW, DEFAULT_TP_MODEL) @@ -42,7 +44,7 @@ def keras_pruning_experimental(model: Model, target_resource_utilization: ResourceUtilization, representative_data_gen: Callable, pruning_config: PruningConfig = PruningConfig(), - target_platform_capabilities: TargetPlatformCapabilities = DEFAULT_KERAS_TPC) -> Tuple[Model, PruningInfo]: + target_platform_capabilities: TargetPlatformModel = DEFAULT_KERAS_TPC) -> Tuple[Model, PruningInfo]: """ Perform structured pruning on a Keras model to meet a specified target resource utilization. This function prunes the provided model according to the target resource utilization by grouping and pruning @@ -111,6 +113,10 @@ def keras_pruning_experimental(model: Model, # Instantiate the Keras framework implementation. fw_impl = PruningKerasImplementation() + # Attach tpc model to framework + attach2keras = AttachTpcToKeras() + target_platform_capabilities = attach2keras.attach(target_platform_capabilities) + # Convert the original Keras model to an internal graph representation. float_graph = read_model_to_graph(model, representative_data_gen, diff --git a/model_compression_toolkit/pruning/pytorch/pruning_facade.py b/model_compression_toolkit/pruning/pytorch/pruning_facade.py index 2acb99e18..2c1b2d498 100644 --- a/model_compression_toolkit/pruning/pytorch/pruning_facade.py +++ b/model_compression_toolkit/pruning/pytorch/pruning_facade.py @@ -16,12 +16,12 @@ from typing import Callable, Tuple from model_compression_toolkit import get_target_platform_capabilities from model_compression_toolkit.constants import PYTORCH +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel from model_compression_toolkit.verify_packages import FOUND_TORCH from model_compression_toolkit.core.common.mixed_precision.resource_utilization_tools.resource_utilization import ResourceUtilization from model_compression_toolkit.core.common.pruning.pruner import Pruner from model_compression_toolkit.core.common.pruning.pruning_config import PruningConfig from model_compression_toolkit.core.common.pruning.pruning_info import PruningInfo -from model_compression_toolkit.core.common.quantization.bit_width_config import BitWidthConfig from model_compression_toolkit.core.common.quantization.set_node_quantization_config import set_quantization_configuration_to_graph from model_compression_toolkit.core.graph_prep_runner import read_model_to_graph from model_compression_toolkit.logger import Logger @@ -38,6 +38,8 @@ PruningPytorchImplementation from model_compression_toolkit.core.pytorch.default_framework_info import DEFAULT_PYTORCH_INFO from torch.nn import Module + from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2pytorch import \ + AttachTpcToPytorch # Set the default Target Platform Capabilities (TPC) for PyTorch. DEFAULT_PYOTRCH_TPC = get_target_platform_capabilities(PYTORCH, DEFAULT_TP_MODEL) @@ -46,7 +48,7 @@ def pytorch_pruning_experimental(model: Module, target_resource_utilization: ResourceUtilization, representative_data_gen: Callable, pruning_config: PruningConfig = PruningConfig(), - target_platform_capabilities: TargetPlatformCapabilities = DEFAULT_PYOTRCH_TPC) -> \ + target_platform_capabilities: TargetPlatformModel = DEFAULT_PYOTRCH_TPC) -> \ Tuple[Module, PruningInfo]: """ Perform structured pruning on a Pytorch model to meet a specified target resource utilization. @@ -117,6 +119,10 @@ def pytorch_pruning_experimental(model: Module, # Instantiate the Pytorch framework implementation. fw_impl = PruningPytorchImplementation() + # Attach TPC to framework + attach2pytorch = AttachTpcToPytorch() + target_platform_capabilities = attach2pytorch.attach(target_platform_capabilities) + # Convert the original Pytorch model to an internal graph representation. float_graph = read_model_to_graph(model, representative_data_gen, diff --git a/model_compression_toolkit/ptq/keras/quantization_facade.py b/model_compression_toolkit/ptq/keras/quantization_facade.py index 5c0ccb15b..97785fb33 100644 --- a/model_compression_toolkit/ptq/keras/quantization_facade.py +++ b/model_compression_toolkit/ptq/keras/quantization_facade.py @@ -22,6 +22,7 @@ from model_compression_toolkit.core.common.visualization.tensorboard_writer import init_tensorboard_writer from model_compression_toolkit.logger import Logger from model_compression_toolkit.constants import TENSORFLOW +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel from model_compression_toolkit.verify_packages import FOUND_TF from model_compression_toolkit.core.common.mixed_precision.resource_utilization_tools.resource_utilization import ResourceUtilization from model_compression_toolkit.core.common.mixed_precision.mixed_precision_quantization_config import \ @@ -41,6 +42,9 @@ from model_compression_toolkit import get_target_platform_capabilities from mct_quantizers.keras.metadata import add_metadata + from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras + DEFAULT_KERAS_TPC = get_target_platform_capabilities(TENSORFLOW, DEFAULT_TP_MODEL) @@ -48,7 +52,7 @@ def keras_post_training_quantization(in_model: Model, representative_data_gen: Callable, target_resource_utilization: ResourceUtilization = None, core_config: CoreConfig = CoreConfig(), - target_platform_capabilities: TargetPlatformCapabilities = DEFAULT_KERAS_TPC): + target_platform_capabilities: TargetPlatformModel = DEFAULT_KERAS_TPC): """ Quantize a trained Keras model using post-training quantization. The model is quantized using a symmetric constraint quantization thresholds (power of two). @@ -134,6 +138,11 @@ def keras_post_training_quantization(in_model: Model, fw_impl = KerasImplementation() + attach2keras = AttachTpcToKeras() + target_platform_capabilities = attach2keras.attach( + target_platform_capabilities, + custom_opset2layer=core_config.quantization_config.custom_tpc_opset_to_layer) + # Ignore returned hessian service as PTQ does not use it tg, bit_widths_config, _, scheduling_info = core_runner(in_model=in_model, representative_data_gen=representative_data_gen, diff --git a/model_compression_toolkit/ptq/pytorch/quantization_facade.py b/model_compression_toolkit/ptq/pytorch/quantization_facade.py index 147d08f5e..2f71ea619 100644 --- a/model_compression_toolkit/ptq/pytorch/quantization_facade.py +++ b/model_compression_toolkit/ptq/pytorch/quantization_facade.py @@ -19,6 +19,7 @@ from model_compression_toolkit.core.common.visualization.tensorboard_writer import init_tensorboard_writer from model_compression_toolkit.logger import Logger from model_compression_toolkit.constants import PYTORCH +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel from model_compression_toolkit.verify_packages import FOUND_TORCH from model_compression_toolkit.target_platform_capabilities.target_platform import TargetPlatformCapabilities from model_compression_toolkit.core.common.mixed_precision.resource_utilization_tools.resource_utilization import ResourceUtilization @@ -39,6 +40,8 @@ from model_compression_toolkit.exporter.model_wrapper.pytorch.builder.fully_quantized_model_builder import get_exportable_pytorch_model from model_compression_toolkit import get_target_platform_capabilities from mct_quantizers.pytorch.metadata import add_metadata + from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2pytorch import \ + AttachTpcToPytorch DEFAULT_PYTORCH_TPC = get_target_platform_capabilities(PYTORCH, DEFAULT_TP_MODEL) @@ -46,7 +49,7 @@ def pytorch_post_training_quantization(in_module: Module, representative_data_gen: Callable, target_resource_utilization: ResourceUtilization = None, core_config: CoreConfig = CoreConfig(), - target_platform_capabilities: TargetPlatformCapabilities = DEFAULT_PYTORCH_TPC): + target_platform_capabilities: TargetPlatformModel = DEFAULT_PYTORCH_TPC): """ Quantize a trained Pytorch module using post-training quantization. By default, the module is quantized using a symmetric constraint quantization thresholds @@ -107,6 +110,11 @@ def pytorch_post_training_quantization(in_module: Module, fw_impl = PytorchImplementation() + # Attach tpc model to framework + attach2pytorch = AttachTpcToPytorch() + target_platform_capabilities = attach2pytorch.attach(target_platform_capabilities, + core_config.quantization_config.custom_tpc_opset_to_layer) + # Ignore hessian info service as it is not used here yet. tg, bit_widths_config, _, scheduling_info = core_runner(in_model=in_module, representative_data_gen=representative_data_gen, diff --git a/model_compression_toolkit/qat/__init__.py b/model_compression_toolkit/qat/__init__.py index 7a7cbc825..9586bf579 100644 --- a/model_compression_toolkit/qat/__init__.py +++ b/model_compression_toolkit/qat/__init__.py @@ -13,6 +13,9 @@ # limitations under the License. # ============================================================================== from model_compression_toolkit.qat.common.qat_config import QATConfig +from model_compression_toolkit.verify_packages import FOUND_TF, FOUND_TORCH -from model_compression_toolkit.qat.keras.quantization_facade import keras_quantization_aware_training_init_experimental, keras_quantization_aware_training_finalize_experimental -from model_compression_toolkit.qat.pytorch.quantization_facade import pytorch_quantization_aware_training_init_experimental, pytorch_quantization_aware_training_finalize_experimental +if FOUND_TF: + from model_compression_toolkit.qat.keras.quantization_facade import keras_quantization_aware_training_init_experimental, keras_quantization_aware_training_finalize_experimental +if FOUND_TORCH: + from model_compression_toolkit.qat.pytorch.quantization_facade import pytorch_quantization_aware_training_init_experimental, pytorch_quantization_aware_training_finalize_experimental diff --git a/model_compression_toolkit/qat/keras/quantization_facade.py b/model_compression_toolkit/qat/keras/quantization_facade.py index aaa4fc6ea..c3494c44f 100644 --- a/model_compression_toolkit/qat/keras/quantization_facade.py +++ b/model_compression_toolkit/qat/keras/quantization_facade.py @@ -19,6 +19,7 @@ from model_compression_toolkit.core import CoreConfig from model_compression_toolkit.core.common.visualization.tensorboard_writer import init_tensorboard_writer from model_compression_toolkit.logger import Logger +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel from model_compression_toolkit.verify_packages import FOUND_TF from model_compression_toolkit.core.common.mixed_precision.resource_utilization_tools.resource_utilization import ResourceUtilization from model_compression_toolkit.core.common.mixed_precision.mixed_precision_quantization_config import \ @@ -54,6 +55,8 @@ from model_compression_toolkit.qat.keras.quantizer.quantization_builder import quantization_builder, \ get_activation_quantizer_holder from model_compression_toolkit.qat.common.qat_config import QATConfig + from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras DEFAULT_KERAS_TPC = get_target_platform_capabilities(TENSORFLOW, DEFAULT_TP_MODEL) @@ -90,7 +93,7 @@ def keras_quantization_aware_training_init_experimental(in_model: Model, target_resource_utilization: ResourceUtilization = None, core_config: CoreConfig = CoreConfig(), qat_config: QATConfig = QATConfig(), - target_platform_capabilities: TargetPlatformCapabilities = DEFAULT_KERAS_TPC): + target_platform_capabilities: TargetPlatformModel = DEFAULT_KERAS_TPC): """ Prepare a trained Keras model for quantization aware training. First the model quantization is optimized with post-training quantization, then the model layers are wrapped with QuantizeWrappers. The model is @@ -186,6 +189,11 @@ def keras_quantization_aware_training_init_experimental(in_model: Model, fw_impl = KerasImplementation() + attach2keras = AttachTpcToKeras() + target_platform_capabilities = attach2keras.attach( + target_platform_capabilities, + custom_opset2layer=core_config.quantization_config.custom_tpc_opset_to_layer) + # Ignore hessian service since is not used in QAT at the moment tg, bit_widths_config, _, _ = core_runner(in_model=in_model, representative_data_gen=representative_data_gen, diff --git a/model_compression_toolkit/qat/pytorch/quantization_facade.py b/model_compression_toolkit/qat/pytorch/quantization_facade.py index 1d66c5148..7f9d66373 100644 --- a/model_compression_toolkit/qat/pytorch/quantization_facade.py +++ b/model_compression_toolkit/qat/pytorch/quantization_facade.py @@ -17,6 +17,9 @@ from functools import partial from model_compression_toolkit.constants import PYTORCH +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2pytorch import \ + AttachTpcToPytorch from model_compression_toolkit.verify_packages import FOUND_TORCH from model_compression_toolkit.core import CoreConfig @@ -79,7 +82,7 @@ def pytorch_quantization_aware_training_init_experimental(in_model: Module, target_resource_utilization: ResourceUtilization = None, core_config: CoreConfig = CoreConfig(), qat_config: QATConfig = QATConfig(), - target_platform_capabilities: TargetPlatformCapabilities = DEFAULT_PYTORCH_TPC): + target_platform_capabilities: TargetPlatformModel = DEFAULT_PYTORCH_TPC): """ Prepare a trained Pytorch model for quantization aware training. First the model quantization is optimized with post-training quantization, then the model layers are wrapped with QuantizeWrappers. The model is @@ -154,6 +157,11 @@ def pytorch_quantization_aware_training_init_experimental(in_model: Module, tb_w = init_tensorboard_writer(DEFAULT_PYTORCH_INFO) fw_impl = PytorchImplementation() + # Attach tpc model to framework + attach2pytorch = AttachTpcToPytorch() + target_platform_capabilities = attach2pytorch.attach(target_platform_capabilities, + core_config.quantization_config.custom_tpc_opset_to_layer) + # Ignore hessian scores service as we do not use it here tg, bit_widths_config, _, _ = core_runner(in_model=in_model, representative_data_gen=representative_data_gen, diff --git a/model_compression_toolkit/target_platform_capabilities/schema/mct_current_schema.py b/model_compression_toolkit/target_platform_capabilities/schema/mct_current_schema.py index 80bf1ce5e..c751049fe 100644 --- a/model_compression_toolkit/target_platform_capabilities/schema/mct_current_schema.py +++ b/model_compression_toolkit/target_platform_capabilities/schema/mct_current_schema.py @@ -7,6 +7,6 @@ QuantizationConfigOptions = schema.QuantizationConfigOptions OperatorsSetBase = schema.OperatorsSetBase OperatorsSet = schema.OperatorsSet -OperatorSetConcat= schema.OperatorSetConcat +OperatorSetConcat = schema.OperatorSetConcat Fusing = schema.Fusing TargetPlatformModel = schema.TargetPlatformModel diff --git a/model_compression_toolkit/target_platform_capabilities/schema/v1.py b/model_compression_toolkit/target_platform_capabilities/schema/v1.py index 6675471b8..d4df977d9 100644 --- a/model_compression_toolkit/target_platform_capabilities/schema/v1.py +++ b/model_compression_toolkit/target_platform_capabilities/schema/v1.py @@ -13,66 +13,74 @@ # limitations under the License. # ============================================================================== import pprint - from enum import Enum from typing import Dict, Any, Union, Tuple, List, Optional, Literal, Annotated + +from pydantic import BaseModel, Field, root_validator, validator, PositiveInt + from mct_quantizers import QuantizationMethod from model_compression_toolkit.constants import FLOAT_BITWIDTH from model_compression_toolkit.logger import Logger -from pydantic import BaseModel, Field, root_validator, validator, PositiveInt, PrivateAttr - - -class OperatorSetNames(Enum): - OPSET_CONV = "Conv" - OPSET_DEPTHWISE_CONV = "DepthwiseConv2D" - OPSET_CONV_TRANSPOSE = "ConvTranspose" - OPSET_FULLY_CONNECTED = "FullyConnected" - OPSET_CONCATENATE = "Concatenate" - OPSET_STACK = "Stack" - OPSET_UNSTACK = "Unstack" - OPSET_GATHER = "Gather" - OPSET_EXPAND = "Expend" - OPSET_BATCH_NORM = "BatchNorm" - OPSET_RELU = "ReLU" - OPSET_RELU6 = "ReLU6" - OPSET_LEAKY_RELU = "LEAKYReLU" - OPSET_HARD_TANH = "HardTanh" - OPSET_ADD = "Add" - OPSET_SUB = "Sub" - OPSET_MUL = "Mul" - OPSET_DIV = "Div" - OPSET_MIN = "Min" - OPSET_MAX = "Max" - OPSET_PRELU = "PReLU" - OPSET_SWISH = "Swish" - OPSET_SIGMOID = "Sigmoid" - OPSET_TANH = "Tanh" - OPSET_GELU = "Gelu" - OPSET_HARDSIGMOID = "HardSigmoid" - OPSET_HARDSWISH = "HardSwish" - OPSET_FLATTEN = "Flatten" - OPSET_GET_ITEM = "GetItem" - OPSET_RESHAPE = "Reshape" - OPSET_UNSQUEEZE = "Unsqueeze" - OPSET_SQUEEZE = "Squeeze" - OPSET_PERMUTE = "Permute" - OPSET_TRANSPOSE = "Transpose" - OPSET_DROPOUT = "Dropout" - OPSET_SPLIT = "Split" - OPSET_CHUNK = "Chunk" - OPSET_MAXPOOL = "MaxPool" - OPSET_SIZE = "Size" - OPSET_SHAPE = "Shape" - OPSET_EQUAL = "Equal" - OPSET_ARGMAX = "ArgMax" - OPSET_TOPK = "TopK" - OPSET_FAKE_QUANT_WITH_MIN_MAX_VARS = "FakeQuantWithMinMaxVars" - OPSET_COMBINED_NON_MAX_SUPPRESSION = "CombinedNonMaxSuppression" - OPSET_CROPPING2D = "Cropping2D" - OPSET_ZERO_PADDING2d = "ZeroPadding2D" - OPSET_CAST = "Cast" - OPSET_STRIDED_SLICE = "StridedSlice" - OPSET_SSD_POST_PROCESS = "SSDPostProcess" + + +class OperatorSetNames(str, Enum): + CONV = "Conv" + DEPTHWISE_CONV = "DepthwiseConv2D" + CONV_TRANSPOSE = "ConvTranspose" + FULLY_CONNECTED = "FullyConnected" + CONCATENATE = "Concatenate" + STACK = "Stack" + UNSTACK = "Unstack" + GATHER = "Gather" + EXPAND = "Expend" + BATCH_NORM = "BatchNorm" + L2NORM = "L2Norm" + RELU = "ReLU" + RELU6 = "ReLU6" + LEAKY_RELU = "LeakyReLU" + ELU = "Elu" + HARD_TANH = "HardTanh" + ADD = "Add" + SUB = "Sub" + MUL = "Mul" + DIV = "Div" + MIN = "Min" + MAX = "Max" + PRELU = "PReLU" + ADD_BIAS = "AddBias" + SWISH = "Swish" + SIGMOID = "Sigmoid" + SOFTMAX = "Softmax" + LOG_SOFTMAX = "LogSoftmax" + TANH = "Tanh" + GELU = "Gelu" + HARDSIGMOID = "HardSigmoid" + HARDSWISH = "HardSwish" + FLATTEN = "Flatten" + GET_ITEM = "GetItem" + RESHAPE = "Reshape" + UNSQUEEZE = "Unsqueeze" + SQUEEZE = "Squeeze" + PERMUTE = "Permute" + TRANSPOSE = "Transpose" + DROPOUT = "Dropout" + SPLIT_CHUNK = "SplitChunk" + MAXPOOL = "MaxPool" + AVGPOOL = "AvgPool" + SIZE = "Size" + SHAPE = "Shape" + EQUAL = "Equal" + ARGMAX = "ArgMax" + TOPK = "TopK" + FAKE_QUANT = "FakeQuant" + COMBINED_NON_MAX_SUPPRESSION = "CombinedNonMaxSuppression" + ZERO_PADDING2D = "ZeroPadding2D" + CAST = "Cast" + RESIZE = "Resize" + PAD = "Pad" + FOLD = "Fold" + STRIDED_SLICE = "StridedSlice" + SSD_POST_PROCESS = "SSDPostProcess" @classmethod def get_values(cls): diff --git a/model_compression_toolkit/target_platform_capabilities/target_platform/targetplatform2framework/attach2fw.py b/model_compression_toolkit/target_platform_capabilities/target_platform/targetplatform2framework/attach2fw.py index 04afa236e..0c752e517 100644 --- a/model_compression_toolkit/target_platform_capabilities/target_platform/targetplatform2framework/attach2fw.py +++ b/model_compression_toolkit/target_platform_capabilities/target_platform/targetplatform2framework/attach2fw.py @@ -1,12 +1,15 @@ -from typing import Dict, Tuple, List, Any, Optional +from typing import Dict, Optional -from model_compression_toolkit import DefaultDict -from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel +from model_compression_toolkit.logger import Logger +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel, \ + OperatorsSet from model_compression_toolkit.target_platform_capabilities.target_platform import TargetPlatformCapabilities, \ OperationsSetToLayers +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers -class AttachTpModelToFw: + +class AttachTpcToFramework: def __init__(self): self._opset2layer = None @@ -17,7 +20,7 @@ def __init__(self): self._opset2attr_mapping = None # Mapping of operation sets to their corresponding framework-specific layers def attach(self, tpc_model: TargetPlatformModel, - custom_opset2layer: Dict[str, Tuple[List[Any], Optional[Dict[str, DefaultDict]]]] = None + custom_opset2layer: Optional[Dict[str, 'CustomOpsetLayers']] = None ) -> TargetPlatformCapabilities: """ Attaching a TargetPlatformModel which includes a platform capabilities description to specific @@ -35,22 +38,30 @@ def attach(self, tpc_model: TargetPlatformModel, """ tpc = TargetPlatformCapabilities(tpc_model) + custom_opset2layer = custom_opset2layer if custom_opset2layer is not None else {} with tpc: - for opset_name, operators in self._opset2layer.items(): - attr_mapping = self._opset2attr_mapping.get(opset_name) - OperationsSetToLayers(opset_name, operators, attr_mapping=attr_mapping) - - if custom_opset2layer is not None: - for opset_name, operators in custom_opset2layer.items(): - if len(operators) == 1: - OperationsSetToLayers(opset_name, operators[0]) - elif len(operators) == 2: - OperationsSetToLayers(opset_name, operators[0], attr_mapping=operators[1]) + for opset in tpc_model.operator_set: + if isinstance(opset, OperatorsSet): # filter out OperatorsSetConcat + if opset.name in custom_opset2layer: + custom_opset_layers = custom_opset2layer[opset.name] + OperationsSetToLayers(opset.name, + layers=custom_opset_layers.operators, + attr_mapping=custom_opset_layers.attr_mapping) + + elif opset.name in self._opset2layer: + # Note that if the user provided a custom operator set with a name that exists in our + # pre-defined set of operator sets, we prioritize the user's custom opset definition + layers = self._opset2layer[opset.name] + if len(layers) > 0: + # If the framework does not define any matching operators to a given operator set name that + # appears in the TPC, then we just skip it + attr_mapping = self._opset2attr_mapping.get(opset.name) + OperationsSetToLayers(opset.name, layers, attr_mapping=attr_mapping) else: - raise ValueError(f"Custom operator set to layer mapping should include up to 2 elements - " - f"a list of layers to attach to the operator and an optional mapping of " - f"attributes names, but given a mapping contains {len(operators)} elements.") + Logger.critical(f'{opset.name} is defined in TargetPlatformModel, ' + f'but is not defined in the framework set of operators or in the provided ' + f'custom operator sets mapping.') return tpc diff --git a/model_compression_toolkit/target_platform_capabilities/target_platform/targetplatform2framework/attach2keras.py b/model_compression_toolkit/target_platform_capabilities/target_platform/targetplatform2framework/attach2keras.py index f7c8a524c..2f1157868 100644 --- a/model_compression_toolkit/target_platform_capabilities/target_platform/targetplatform2framework/attach2keras.py +++ b/model_compression_toolkit/target_platform_capabilities/target_platform/targetplatform2framework/attach2keras.py @@ -23,12 +23,12 @@ if version.parse(tf.__version__) >= version.parse("2.13"): from keras.src.layers import Conv2D, DepthwiseConv2D, Dense, Reshape, ZeroPadding2D, Dropout, \ - MaxPooling2D, Activation, ReLU, Add, Subtract, Multiply, PReLU, Flatten, Cropping2D, LeakyReLU, Permute, \ - Conv2DTranspose, Identity, Concatenate, BatchNormalization, Minimum, Maximum + MaxPooling2D, AveragePooling2D, Activation, ReLU, Add, Subtract, Multiply, PReLU, Flatten, Cropping2D, LeakyReLU, Permute, \ + Conv2DTranspose, Concatenate, BatchNormalization, Minimum, Maximum, Softmax else: from keras.layers import Conv2D, DepthwiseConv2D, Dense, Reshape, ZeroPadding2D, Dropout, \ - MaxPooling2D, Activation, ReLU, Add, Subtract, Multiply, PReLU, Flatten, Cropping2D, LeakyReLU, Permute, \ - Conv2DTranspose, Concatenate, BatchNormalization, Minimum, Maximum + MaxPooling2D, AveragePooling2D, Activation, ReLU, Add, Subtract, Multiply, PReLU, Flatten, Cropping2D, LeakyReLU, Permute, \ + Conv2DTranspose, Concatenate, BatchNormalization, Minimum, Maximum, Softmax from model_compression_toolkit import DefaultDict from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, BIAS, \ @@ -36,72 +36,93 @@ from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import OperatorSetNames from model_compression_toolkit.target_platform_capabilities.target_platform import LayerFilterParams from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2fw import \ - AttachTpModelToFw + AttachTpcToFramework -class AttachTpModelToKeras(AttachTpModelToFw): +class AttachTpcToKeras(AttachTpcToFramework): def __init__(self): super().__init__() self._opset2layer = { - OperatorSetNames.OPSET_CONV.value: [Conv2D, tf.nn.conv2d], - OperatorSetNames.OPSET_DEPTHWISE_CONV.value: [DepthwiseConv2D, tf.nn.depthwise_conv2d], - OperatorSetNames.OPSET_CONV_TRANSPOSE.value: [Conv2DTranspose, tf.nn.conv2d_transpose], - OperatorSetNames.OPSET_FULLY_CONNECTED.value: [Dense], - OperatorSetNames.OPSET_CONCATENATE.value: [tf.concat, Concatenate], - OperatorSetNames.OPSET_STACK.value: [tf.stack], - OperatorSetNames.OPSET_UNSTACK.value: [tf.unstack], - OperatorSetNames.OPSET_GATHER.value: [tf.gather, tf.compat.v1.gather], - OperatorSetNames.OPSET_EXPAND.value: [], - OperatorSetNames.OPSET_BATCH_NORM.value: [BatchNormalization], - OperatorSetNames.OPSET_RELU.value: [tf.nn.relu, ReLU], - OperatorSetNames.OPSET_RELU6.value: [tf.nn.relu6], - OperatorSetNames.OPSET_LEAKY_RELU.value: [tf.nn.leaky_relu, LeakyReLU], - OperatorSetNames.OPSET_HARD_TANH.value: [LayerFilterParams(Activation, activation="hard_tanh")], - OperatorSetNames.OPSET_ADD.value: [tf.add, Add], - OperatorSetNames.OPSET_SUB.value: [tf.subtract, Subtract], - OperatorSetNames.OPSET_MUL.value: [tf.math.multiply, Multiply], - OperatorSetNames.OPSET_DIV.value: [tf.math.divide, tf.math.truediv], - OperatorSetNames.OPSET_MIN.value: [tf.math.minimum, Minimum], - OperatorSetNames.OPSET_MAX.value: [tf.math.maximum, Maximum], - OperatorSetNames.OPSET_PRELU.value: [PReLU], - OperatorSetNames.OPSET_SWISH.value: [tf.nn.swish, LayerFilterParams(Activation, activation="swish")], - OperatorSetNames.OPSET_SIGMOID.value: [tf.nn.sigmoid, LayerFilterParams(Activation, activation="sigmoid")], - OperatorSetNames.OPSET_TANH.value: [tf.nn.tanh, LayerFilterParams(Activation, activation="tanh")], - OperatorSetNames.OPSET_GELU.value: [tf.nn.gelu, LayerFilterParams(Activation, activation="gelu")], - OperatorSetNames.OPSET_HARDSIGMOID.value: [tf.keras.activations.hard_sigmoid, - LayerFilterParams(Activation, activation="hard_sigmoid")], - OperatorSetNames.OPSET_FLATTEN.value: [Flatten], - OperatorSetNames.OPSET_GET_ITEM.value: [tf.__operators__.getitem], - OperatorSetNames.OPSET_RESHAPE.value: [Reshape, tf.reshape], - OperatorSetNames.OPSET_PERMUTE.value: [Permute], - OperatorSetNames.OPSET_TRANSPOSE.value: [tf.transpose], - OperatorSetNames.OPSET_DROPOUT.value: [Dropout], - OperatorSetNames.OPSET_SPLIT.value: [tf.split], - OperatorSetNames.OPSET_MAXPOOL.value: [MaxPooling2D], - OperatorSetNames.OPSET_SHAPE.value: [tf.shape, tf.compat.v1.shape], - OperatorSetNames.OPSET_EQUAL.value: [tf.math.equal], - OperatorSetNames.OPSET_ARGMAX.value: [tf.math.argmax], - OperatorSetNames.OPSET_TOPK.value: [tf.nn.top_k], - OperatorSetNames.OPSET_FAKE_QUANT_WITH_MIN_MAX_VARS.value: [tf.quantization.fake_quant_with_min_max_vars], - OperatorSetNames.OPSET_COMBINED_NON_MAX_SUPPRESSION.value: [tf.image.combined_non_max_suppression], - OperatorSetNames.OPSET_CROPPING2D.value: [Cropping2D], - OperatorSetNames.OPSET_ZERO_PADDING2d.value: [ZeroPadding2D], - OperatorSetNames.OPSET_CAST.value: [tf.cast], - OperatorSetNames.OPSET_STRIDED_SLICE.value: [tf.strided_slice] + OperatorSetNames.CONV: [Conv2D, tf.nn.conv2d], + OperatorSetNames.DEPTHWISE_CONV: [DepthwiseConv2D, tf.nn.depthwise_conv2d], + OperatorSetNames.CONV_TRANSPOSE: [Conv2DTranspose, tf.nn.conv2d_transpose], + OperatorSetNames.FULLY_CONNECTED: [Dense], + OperatorSetNames.CONCATENATE: [tf.concat, Concatenate], + OperatorSetNames.STACK: [tf.stack], + OperatorSetNames.UNSTACK: [tf.unstack], + OperatorSetNames.GATHER: [tf.gather, tf.compat.v1.gather], + OperatorSetNames.EXPAND: [], + OperatorSetNames.BATCH_NORM: [BatchNormalization, tf.nn.batch_normalization], + OperatorSetNames.RELU: [tf.nn.relu, ReLU, LayerFilterParams(Activation, activation="relu")], + OperatorSetNames.RELU6: [tf.nn.relu6], + OperatorSetNames.LEAKY_RELU: [tf.nn.leaky_relu, LeakyReLU, LayerFilterParams(Activation, activation="leaky_relu")], + OperatorSetNames.HARD_TANH: [LayerFilterParams(Activation, activation="hard_tanh")], + OperatorSetNames.ADD: [tf.add, Add], + OperatorSetNames.SUB: [tf.subtract, Subtract], + OperatorSetNames.MUL: [tf.math.multiply, Multiply], + OperatorSetNames.DIV: [tf.math.divide, tf.math.truediv], + OperatorSetNames.MIN: [tf.math.minimum, Minimum], + OperatorSetNames.MAX: [tf.math.maximum, Maximum], + OperatorSetNames.PRELU: [PReLU], + OperatorSetNames.SWISH: [tf.nn.swish, LayerFilterParams(Activation, activation="swish")], + OperatorSetNames.HARDSWISH: [LayerFilterParams(Activation, activation="hard_swish")], + OperatorSetNames.SIGMOID: [tf.nn.sigmoid, LayerFilterParams(Activation, activation="sigmoid")], + OperatorSetNames.TANH: [tf.nn.tanh, LayerFilterParams(Activation, activation="tanh")], + OperatorSetNames.GELU: [tf.nn.gelu, LayerFilterParams(Activation, activation="gelu")], + OperatorSetNames.HARDSIGMOID: [tf.keras.activations.hard_sigmoid, + LayerFilterParams(Activation, activation="hard_sigmoid")], + OperatorSetNames.FLATTEN: [Flatten], + OperatorSetNames.GET_ITEM: [tf.__operators__.getitem], + OperatorSetNames.RESHAPE: [Reshape, tf.reshape], + OperatorSetNames.PERMUTE: [Permute], + OperatorSetNames.TRANSPOSE: [tf.transpose], + OperatorSetNames.UNSQUEEZE: [tf.expand_dims], + OperatorSetNames.SQUEEZE: [tf.squeeze], + OperatorSetNames.DROPOUT: [Dropout], + OperatorSetNames.SPLIT_CHUNK: [tf.split], + OperatorSetNames.MAXPOOL: [MaxPooling2D, tf.nn.avg_pool2d], + OperatorSetNames.AVGPOOL: [AveragePooling2D], + OperatorSetNames.SIZE: [tf.size], + OperatorSetNames.RESIZE: [tf.image.resize], + OperatorSetNames.PAD: [tf.pad, Cropping2D], + OperatorSetNames.FOLD: [tf.space_to_batch_nd], + OperatorSetNames.SHAPE: [tf.shape, tf.compat.v1.shape], + OperatorSetNames.EQUAL: [tf.math.equal], + OperatorSetNames.ARGMAX: [tf.math.argmax], + OperatorSetNames.TOPK: [tf.nn.top_k], + OperatorSetNames.FAKE_QUANT: [tf.quantization.fake_quant_with_min_max_vars], + OperatorSetNames.COMBINED_NON_MAX_SUPPRESSION: [tf.image.combined_non_max_suppression], + OperatorSetNames.ZERO_PADDING2D: [ZeroPadding2D], + OperatorSetNames.CAST: [tf.cast], + OperatorSetNames.STRIDED_SLICE: [tf.strided_slice], + OperatorSetNames.ELU: [tf.nn.elu, LayerFilterParams(Activation, activation="elu")], + OperatorSetNames.SOFTMAX: [tf.nn.softmax, Softmax, + LayerFilterParams(Activation, activation="softmax")], + OperatorSetNames.LOG_SOFTMAX: [tf.nn.log_softmax], + OperatorSetNames.ADD_BIAS: [tf.nn.bias_add], + OperatorSetNames.L2NORM: [tf.math.l2_normalize], } if FOUND_SONY_CUSTOM_LAYERS: - self._opset2layer[OperatorSetNames.OPSET_POST_PROCESS] = [SSDPostProcess] + self._opset2layer[OperatorSetNames.SSD_POST_PROCESS] = [SSDPostProcess] + else: + # If Custom layers is not installed then we don't want the user to fail, but just ignore custom layers + # in the initialized framework TPC + self._opset2layer[OperatorSetNames.SSD_POST_PROCESS] = [] - self._opset2attr_mapping = {OperatorSetNames.OPSET_CONV.value: { - KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}, - OperatorSetNames.OPSET_DEPTHWISE_CONV.value: { + self._opset2attr_mapping = { + OperatorSetNames.CONV: { + KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), + BIAS_ATTR: DefaultDict(default_value=BIAS)}, + OperatorSetNames.CONV_TRANSPOSE: { + KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), + BIAS_ATTR: DefaultDict(default_value=BIAS)}, + OperatorSetNames.DEPTHWISE_CONV: { KERNEL_ATTR: DefaultDict({ DepthwiseConv2D: KERAS_DEPTHWISE_KERNEL, tf.nn.depthwise_conv2d: KERAS_DEPTHWISE_KERNEL}, default_value=KERAS_KERNEL), BIAS_ATTR: DefaultDict(default_value=BIAS)}, - OperatorSetNames.OPSET_FULLY_CONNECTED.value: { + OperatorSetNames.FULLY_CONNECTED: { KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), BIAS_ATTR: DefaultDict(default_value=BIAS)}} diff --git a/model_compression_toolkit/target_platform_capabilities/target_platform/targetplatform2framework/attach2pytorch.py b/model_compression_toolkit/target_platform_capabilities/target_platform/targetplatform2framework/attach2pytorch.py index e68043596..fe94ea2a4 100644 --- a/model_compression_toolkit/target_platform_capabilities/target_platform/targetplatform2framework/attach2pytorch.py +++ b/model_compression_toolkit/target_platform_capabilities/target_platform/targetplatform2framework/attach2pytorch.py @@ -18,74 +18,89 @@ import torch from torch import add, sub, mul, div, divide, flatten, reshape, split, unsqueeze, dropout, sigmoid, tanh, \ chunk, unbind, topk, gather, equal, transpose, permute, argmax, squeeze, multiply, subtract, minimum, \ - maximum -from torch.nn import Conv2d, Linear, ConvTranspose2d, MaxPool2d, BatchNorm2d -from torch.nn import Dropout, Flatten, Hardtanh -from torch.nn import ReLU, ReLU6, PReLU, SiLU, Sigmoid, Tanh, Hardswish, Hardsigmoid, LeakyReLU, GELU + maximum, softmax, fake_quantize_per_channel_affine +from torch.nn import Conv2d, Linear, ConvTranspose2d, MaxPool2d, BatchNorm2d, Dropout, Flatten, Hardtanh, ReLU, ReLU6, \ + PReLU, SiLU, Sigmoid, Tanh, Hardswish, Hardsigmoid, LeakyReLU, GELU, LogSoftmax, Softmax, ELU, AvgPool2d, ZeroPad2d +from torch.nn.functional import relu, relu6, prelu, silu, hardtanh, hardswish, hardsigmoid, leaky_relu, gelu, fold import torch.nn.functional as F -from torch.nn.functional import relu, relu6, prelu, silu, hardtanh, hardswish, hardsigmoid, leaky_relu, gelu from model_compression_toolkit import DefaultDict from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, PYTORCH_KERNEL, BIAS, \ BIAS_ATTR from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import OperatorSetNames -from model_compression_toolkit.target_platform_capabilities.target_platform import LayerFilterParams +from model_compression_toolkit.target_platform_capabilities.target_platform import LayerFilterParams, Eq from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2fw import \ - AttachTpModelToFw + AttachTpcToFramework -class AttachTpModelToPytorch(AttachTpModelToFw): +class AttachTpcToPytorch(AttachTpcToFramework): def __init__(self): super().__init__() self._opset2layer = { - OperatorSetNames.OPSET_CONV.value: [Conv2d], - OperatorSetNames.OPSET_CONV_TRANSPOSE.value: [ConvTranspose2d], - OperatorSetNames.OPSET_FULLY_CONNECTED.value: [Linear], - OperatorSetNames.OPSET_CONCATENATE.value: [torch.cat, torch.concat, torch.concatenate], - OperatorSetNames.OPSET_STACK.value: [torch.stack], - OperatorSetNames.OPSET_UNSTACK.value: [unbind], - OperatorSetNames.OPSET_GATHER.value: [gather], - OperatorSetNames.OPSET_EXPAND.value: [torch.Tensor.expand], - OperatorSetNames.OPSET_BATCH_NORM.value: [BatchNorm2d], - OperatorSetNames.OPSET_RELU.value: [torch.relu, ReLU, relu], - OperatorSetNames.OPSET_RELU6.value: [ReLU6, relu6], - OperatorSetNames.OPSET_LEAKY_RELU.value: [LeakyReLU, leaky_relu], - OperatorSetNames.OPSET_HARD_TANH.value: [LayerFilterParams(Hardtanh, min_val=0), - LayerFilterParams(hardtanh, min_val=0)], - OperatorSetNames.OPSET_ADD.value: [operator.add, add], - OperatorSetNames.OPSET_SUB.value: [operator.sub, sub, subtract], - OperatorSetNames.OPSET_MUL.value: [operator.mul, mul, multiply], - OperatorSetNames.OPSET_DIV.value: [operator.truediv, div, divide], - OperatorSetNames.OPSET_MIN.value: [minimum], - OperatorSetNames.OPSET_MAX.value: [maximum], - OperatorSetNames.OPSET_PRELU.value: [PReLU, prelu], - OperatorSetNames.OPSET_SWISH.value: [SiLU, silu], - OperatorSetNames.OPSET_SIGMOID.value: [Sigmoid, sigmoid, F.sigmoid], - OperatorSetNames.OPSET_TANH.value: [Tanh, tanh, F.tanh], - OperatorSetNames.OPSET_GELU.value: [GELU, gelu], - OperatorSetNames.OPSET_HARDSIGMOID.value: [Hardsigmoid, hardsigmoid], - OperatorSetNames.OPSET_HARDSWISH.value: [Hardswish, hardswish], - OperatorSetNames.OPSET_FLATTEN.value: [Flatten, flatten], - OperatorSetNames.OPSET_GET_ITEM.value: [operator.getitem], - OperatorSetNames.OPSET_RESHAPE.value: [reshape], - OperatorSetNames.OPSET_UNSQUEEZE.value: [unsqueeze], - OperatorSetNames.OPSET_SQUEEZE.value: [squeeze], - OperatorSetNames.OPSET_PERMUTE.value: [permute], - OperatorSetNames.OPSET_TRANSPOSE.value: [transpose], - OperatorSetNames.OPSET_DROPOUT.value: [Dropout, dropout], - OperatorSetNames.OPSET_SPLIT.value: [split], - OperatorSetNames.OPSET_CHUNK.value: [chunk], - OperatorSetNames.OPSET_MAXPOOL.value: [MaxPool2d], - OperatorSetNames.OPSET_SIZE.value: [torch.Tensor.size], - OperatorSetNames.OPSET_SHAPE.value: [torch.Tensor.shape], - OperatorSetNames.OPSET_EQUAL.value: [equal], - OperatorSetNames.OPSET_ARGMAX.value: [argmax], - OperatorSetNames.OPSET_TOPK.value: [topk], + OperatorSetNames.CONV: [Conv2d], + OperatorSetNames.DEPTHWISE_CONV: [], # no specific operator for depthwise conv in pytorch + OperatorSetNames.CONV_TRANSPOSE: [ConvTranspose2d], + OperatorSetNames.FULLY_CONNECTED: [Linear], + OperatorSetNames.CONCATENATE: [torch.cat, torch.concat, torch.concatenate], + OperatorSetNames.STACK: [torch.stack], + OperatorSetNames.UNSTACK: [unbind], + OperatorSetNames.GATHER: [gather], + OperatorSetNames.EXPAND: [torch.Tensor.expand], + OperatorSetNames.BATCH_NORM: [BatchNorm2d], + OperatorSetNames.RELU: [torch.relu, ReLU, relu], + OperatorSetNames.RELU6: [ReLU6, relu6], + OperatorSetNames.LEAKY_RELU: [LeakyReLU, leaky_relu], + OperatorSetNames.HARD_TANH: [LayerFilterParams(Hardtanh, min_val=0), + LayerFilterParams(hardtanh, min_val=0)], + OperatorSetNames.ADD: [operator.add, add], + OperatorSetNames.SUB: [operator.sub, sub, subtract], + OperatorSetNames.MUL: [operator.mul, mul, multiply], + OperatorSetNames.DIV: [operator.truediv, div, divide], + OperatorSetNames.ADD_BIAS: [], # no specific operator for bias_add in pytorch + OperatorSetNames.MIN: [minimum], + OperatorSetNames.MAX: [maximum], + OperatorSetNames.PRELU: [PReLU, prelu], + OperatorSetNames.SWISH: [SiLU, silu], + OperatorSetNames.SIGMOID: [Sigmoid, sigmoid, F.sigmoid], + OperatorSetNames.TANH: [Tanh, tanh, F.tanh], + OperatorSetNames.GELU: [GELU, gelu], + OperatorSetNames.HARDSIGMOID: [Hardsigmoid, hardsigmoid], + OperatorSetNames.HARDSWISH: [Hardswish, hardswish], + OperatorSetNames.FLATTEN: [Flatten, flatten], + OperatorSetNames.GET_ITEM: [operator.getitem], + OperatorSetNames.RESHAPE: [reshape], + OperatorSetNames.UNSQUEEZE: [unsqueeze], + OperatorSetNames.SQUEEZE: [squeeze], + OperatorSetNames.PERMUTE: [permute], + OperatorSetNames.TRANSPOSE: [transpose], + OperatorSetNames.DROPOUT: [Dropout, dropout], + OperatorSetNames.SPLIT_CHUNK: [split, chunk], + OperatorSetNames.MAXPOOL: [MaxPool2d, F.max_pool2d], + OperatorSetNames.AVGPOOL: [AvgPool2d, F.avg_pool2d], + OperatorSetNames.SIZE: [torch.Tensor.size], + OperatorSetNames.RESIZE: [torch.Tensor.resize], + OperatorSetNames.PAD: [F.pad], + OperatorSetNames.FOLD: [fold], + OperatorSetNames.SHAPE: [torch.Tensor.shape], + OperatorSetNames.EQUAL: [equal], + OperatorSetNames.ARGMAX: [argmax], + OperatorSetNames.TOPK: [topk], + OperatorSetNames.FAKE_QUANT: [fake_quantize_per_channel_affine], + OperatorSetNames.ZERO_PADDING2D: [ZeroPad2d], + OperatorSetNames.CAST: [torch.Tensor.type], + OperatorSetNames.STRIDED_SLICE: [], # no such operator in pytorch, the equivalent is get_item which has a separate operator set + OperatorSetNames.ELU: [ELU, F.elu], + OperatorSetNames.SOFTMAX: [Softmax, softmax, F.softmax], + OperatorSetNames.LOG_SOFTMAX: [LogSoftmax], + OperatorSetNames.L2NORM: [LayerFilterParams(torch.nn.functional.normalize, + Eq('p', 2) | Eq('p', None))], + OperatorSetNames.SSD_POST_PROCESS: [], # no such operator in pytorch + OperatorSetNames.COMBINED_NON_MAX_SUPPRESSION: [] # no such operator in pytorch } pytorch_linear_attr_mapping = {KERNEL_ATTR: DefaultDict(default_value=PYTORCH_KERNEL), BIAS_ATTR: DefaultDict(default_value=BIAS)} - self._opset2attr_mapping = {OperatorSetNames.OPSET_CONV.value: pytorch_linear_attr_mapping, - OperatorSetNames.OPSET_CONV_TRANSPOSE.value: pytorch_linear_attr_mapping, - OperatorSetNames.OPSET_FULLY_CONNECTED.value: pytorch_linear_attr_mapping} + self._opset2attr_mapping = {OperatorSetNames.CONV: pytorch_linear_attr_mapping, + OperatorSetNames.CONV_TRANSPOSE: pytorch_linear_attr_mapping, + OperatorSetNames.FULLY_CONNECTED: pytorch_linear_attr_mapping} diff --git a/model_compression_toolkit/target_platform_capabilities/target_platform/targetplatform2framework/operations_to_layers.py b/model_compression_toolkit/target_platform_capabilities/target_platform/targetplatform2framework/operations_to_layers.py index ad9508d8c..ea09059e2 100644 --- a/model_compression_toolkit/target_platform_capabilities/target_platform/targetplatform2framework/operations_to_layers.py +++ b/model_compression_toolkit/target_platform_capabilities/target_platform/targetplatform2framework/operations_to_layers.py @@ -138,10 +138,8 @@ def validate_op_sets(self): OperationsSetToLayers), f'Operators set should be of type OperationsSetToLayers but it ' \ f'is of type {type(ops2layers)}' - # Assert that opset in the current TargetPlatformCapabilities and has a unique name. - opset_in_model = is_opset_in_model(_current_tpc.get().tp_model, ops2layers.name) - assert opset_in_model, f'{ops2layers.name} is not defined in the target platform model that is associated with the target platform capabilities.' - assert not (ops2layers.name in existing_opset_names), f'OperationsSetToLayers names should be unique, but {ops2layers.name} appears to violate it.' + # Assert that opset has a unique name. + assert ops2layers.name not in existing_opset_names, f'OperationsSetToLayers names should be unique, but {ops2layers.name} appears to violate it.' existing_opset_names.append(ops2layers.name) # Assert that a layer does not appear in more than a single OperatorsSet in the TargetPlatformModel. diff --git a/model_compression_toolkit/target_platform_capabilities/target_platform/targetplatform2framework/target_platform_capabilities.py b/model_compression_toolkit/target_platform_capabilities/target_platform/targetplatform2framework/target_platform_capabilities.py index d29d52e28..43574a83e 100644 --- a/model_compression_toolkit/target_platform_capabilities/target_platform/targetplatform2framework/target_platform_capabilities.py +++ b/model_compression_toolkit/target_platform_capabilities/target_platform/targetplatform2framework/target_platform_capabilities.py @@ -156,7 +156,6 @@ def __exit__(self, exc_type, exc_value, tb): if exc_value is not None: print(exc_value, exc_value.args) raise exc_value - self.raise_warnings() self.layer2qco, self.filterlayer2qco = self._get_config_options_mapping() _current_tpc.reset() self.initialized_done() @@ -226,15 +225,6 @@ def remove_opset_from_not_used_list(self, if opset_to_remove in self.__tp_model_opsets_not_used: self.__tp_model_opsets_not_used.remove(opset_to_remove) - def raise_warnings(self): - """ - - Log warnings regards unused opsets. - - """ - for op in self.__tp_model_opsets_not_used: - Logger.warning(f'{op} is defined in TargetPlatformModel, but is not used in TargetPlatformCapabilities.') - @property def is_simd_padding(self) -> bool: """ diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/get_target_platform_capabilities.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/get_target_platform_capabilities.py index 289d80e40..c0170f954 100644 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/get_target_platform_capabilities.py +++ b/model_compression_toolkit/target_platform_capabilities/tpc_models/get_target_platform_capabilities.py @@ -12,45 +12,63 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== +from model_compression_toolkit.constants import TENSORFLOW, PYTORCH +from model_compression_toolkit.target_platform_capabilities.constants import DEFAULT_TP_MODEL, IMX500_TP_MODEL, \ + TFLITE_TP_MODEL, QNNPACK_TP_MODEL +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel -from model_compression_toolkit.target_platform_capabilities.target_platform import TargetPlatformCapabilities +from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1.tp_model import get_tp_model as get_tp_model_imx500_v1 +from model_compression_toolkit.target_platform_capabilities.tpc_models.tflite_tpc.v1.tp_model import get_tp_model as get_tp_model_tflite_v1 +from model_compression_toolkit.target_platform_capabilities.tpc_models.qnnpack_tpc.v1.tp_model import get_tp_model as get_tp_model_qnnpack_v1 -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.target_platform_capabilities import \ - get_tpc_dict_by_fw as get_imx500_tpc -from model_compression_toolkit.target_platform_capabilities.tpc_models.tflite_tpc.target_platform_capabilities import \ - get_tpc_dict_by_fw as get_tflite_tpc -from model_compression_toolkit.target_platform_capabilities.tpc_models.qnnpack_tpc.target_platform_capabilities import \ - get_tpc_dict_by_fw as get_qnnpack_tpc -from model_compression_toolkit.target_platform_capabilities.constants import DEFAULT_TP_MODEL, IMX500_TP_MODEL, TFLITE_TP_MODEL, QNNPACK_TP_MODEL, LATEST - -tpc_dict = {DEFAULT_TP_MODEL: get_imx500_tpc, - IMX500_TP_MODEL: get_imx500_tpc, - TFLITE_TP_MODEL: get_tflite_tpc, - QNNPACK_TP_MODEL: get_qnnpack_tpc} +# TODO: These methods need to be replaced once modifying the TPC API. def get_target_platform_capabilities(fw_name: str, target_platform_name: str, - target_platform_version: str = None) -> TargetPlatformCapabilities: + target_platform_version: str = None) -> TargetPlatformModel: """ - Get a TargetPlatformCapabilities by the target platform model name and the framework name. - For now, it supports frameworks 'tensorflow' and 'pytorch'. For both of them - the target platform model can be 'default', 'imx500', 'tflite', or 'qnnpack'. + This is a degenerated function that only returns the MCT default TargetPlatformModel object, to comply with the + existing TPC API. Args: fw_name: Framework name of the TargetPlatformCapabilities. target_platform_name: Target platform model name the model will use for inference. target_platform_version: Target platform capabilities version. + Returns: - A TargetPlatformCapabilities object that models the hardware and attaches - a framework information to it. + A default TargetPlatformModel object. """ - assert target_platform_name in tpc_dict, f'Target platform {target_platform_name} is not defined!' - fw_tpc = tpc_dict.get(target_platform_name) - tpc_versions = fw_tpc(fw_name) - if target_platform_version is None: - target_platform_version = LATEST - else: - assert target_platform_version in tpc_versions, (f'TPC version {target_platform_version} is not supported for ' - f'framework {fw_name}.') - return tpc_versions[target_platform_version]() + + assert fw_name in [TENSORFLOW, PYTORCH], f"Unsupported framework {fw_name}." + + if target_platform_name == DEFAULT_TP_MODEL: + return get_tp_model_imx500_v1() + + assert target_platform_version == 'v1' or target_platform_version is None, \ + "The usage of get_target_platform_capabilities API is supported only with the default TPC ('v1')." + + if target_platform_name == IMX500_TP_MODEL: + return get_tp_model_imx500_v1() + elif target_platform_name == TFLITE_TP_MODEL: + return get_tp_model_tflite_v1() + elif target_platform_name == QNNPACK_TP_MODEL: + return get_tp_model_qnnpack_v1() + + raise ValueError(f"Unsupported target platform name {target_platform_name}.") + + +def get_tpc_model(name: str, tp_model: TargetPlatformModel): + """ + This is a utility method that just returns the TargetPlatformModel that it receives, to support existing TPC API. + + Args: + name: the name of the TargetPlatformModel (not used in this function). + tp_model: a TargetPlatformModel to return. + + Returns: + The given TargetPlatformModel object. + + """ + + return tp_model diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/latest/__init__.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/latest/__init__.py index 6073d712c..797491b47 100644 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/latest/__init__.py +++ b/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/latest/__init__.py @@ -16,9 +16,10 @@ from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1.tp_model import get_tp_model, generate_tp_model, \ get_op_quantization_configs if FOUND_TF: - from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1.tpc_keras import get_keras_tpc as get_keras_tpc_latest - from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1.tpc_keras import generate_keras_tpc + from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1.tp_model import get_tp_model as get_keras_tpc_latest + from model_compression_toolkit.target_platform_capabilities.tpc_models.get_target_platform_capabilities import \ + get_tpc_model as generate_keras_tpc if FOUND_TORCH: - from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1.tpc_pytorch import get_pytorch_tpc as \ - get_pytorch_tpc_latest - from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1.tpc_pytorch import generate_pytorch_tpc + from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1.tp_model import get_tp_model as get_pytorch_tpc_latest + from model_compression_toolkit.target_platform_capabilities.tpc_models.get_target_platform_capabilities import \ + get_tpc_model as generate_pytorch_tpc diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/target_platform_capabilities.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/target_platform_capabilities.py deleted file mode 100644 index f08ec5e14..000000000 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/target_platform_capabilities.py +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright 2023 Sony Semiconductor Israel, Inc. All rights reserved. -# -# 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 model_compression_toolkit.logger import Logger - -from model_compression_toolkit.constants import TENSORFLOW, PYTORCH -from model_compression_toolkit.verify_packages import FOUND_TORCH, FOUND_TF -from model_compression_toolkit.target_platform_capabilities.constants import LATEST - - -def get_tpc_dict_by_fw(fw_name): - tpc_models_dict = None - if fw_name == TENSORFLOW: - ############################### - # Build Tensorflow TPC models - ############################### - if FOUND_TF: - from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import \ - get_keras_tpc_latest - from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1.tpc_keras import \ - get_keras_tpc as get_keras_tpc_v1 - from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1_lut.tpc_keras import \ - get_keras_tpc as get_keras_tpc_v1_lut - from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1_pot.tpc_keras import \ - get_keras_tpc as get_keras_tpc_v1_pot - from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v2.tpc_keras import \ - get_keras_tpc as get_keras_tpc_v2 - from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v2_lut.tpc_keras import \ - get_keras_tpc as get_keras_tpc_v2_lut - from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v3.tpc_keras import \ - get_keras_tpc as get_keras_tpc_v3 - from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v3_lut.tpc_keras import \ - get_keras_tpc as get_keras_tpc_v3_lut - from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v4.tpc_keras import \ - get_keras_tpc as get_keras_tpc_v4 - - # Keras: TPC versioning - tpc_models_dict = {'v1': get_keras_tpc_v1, - 'v1_lut': get_keras_tpc_v1_lut, - 'v1_pot': get_keras_tpc_v1_pot, - 'v2': get_keras_tpc_v2, - 'v2_lut': get_keras_tpc_v2_lut, - 'v3': get_keras_tpc_v3, - 'v3_lut': get_keras_tpc_v3_lut, - 'v4': get_keras_tpc_v4, - LATEST: get_keras_tpc_latest} - elif fw_name == PYTORCH: - ############################### - # Build Pytorch TPC models - ############################### - if FOUND_TORCH: - from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import \ - get_pytorch_tpc_latest - from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1.tpc_pytorch import \ - get_pytorch_tpc as get_pytorch_tpc_v1 - from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1_pot.tpc_pytorch import \ - get_pytorch_tpc as get_pytorch_tpc_v1_pot - from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1_lut.tpc_pytorch import \ - get_pytorch_tpc as get_pytorch_tpc_v1_lut - from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v2.tpc_pytorch import \ - get_pytorch_tpc as get_pytorch_tpc_v2 - from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v2_lut.tpc_pytorch import \ - get_pytorch_tpc as get_pytorch_tpc_v2_lut - from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v3.tpc_pytorch import \ - get_pytorch_tpc as get_pytorch_tpc_v3 - from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v3_lut.tpc_pytorch import \ - get_pytorch_tpc as get_pytorch_tpc_v3_lut - from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v4.tpc_pytorch import \ - get_pytorch_tpc as get_pytorch_tpc_v4 - - # Pytorch: TPC versioning - tpc_models_dict = {'v1': get_pytorch_tpc_v1, - 'v1_lut': get_pytorch_tpc_v1_lut, - 'v1_pot': get_pytorch_tpc_v1_pot, - 'v2': get_pytorch_tpc_v2, - 'v2_lut': get_pytorch_tpc_v2_lut, - 'v3': get_pytorch_tpc_v3, - 'v3_lut': get_pytorch_tpc_v3_lut, - 'v4': get_pytorch_tpc_v4, - LATEST: get_pytorch_tpc_latest} - if tpc_models_dict is not None: - return tpc_models_dict - else: - Logger.critical(f'Framework {fw_name} is not supported in imx500 or the relevant packages are not ' - f'installed. Please make sure the relevant packages are installed when using MCT for optimizing' - f' a {fw_name} model. For Tensorflow, please install tensorflow. For PyTorch, please install ' - f'torch.') # pragma: no cover diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1/tp_model.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1/tp_model.py index dd62cf03f..238e5dd93 100644 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1/tp_model.py +++ b/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1/tp_model.py @@ -167,38 +167,70 @@ def generate_tp_model(default_config: OpQuantizationConfig, operator_set = [] fusing_patterns = [] - operator_set.append(schema.OperatorsSet(name="NoQuantization", - qc_options=default_configuration_options.clone_and_edit(enable_activation_quantization=False) - .clone_and_edit_weight_attribute(enable_weights_quantization=False))) + no_quantization_config = (default_configuration_options.clone_and_edit(enable_activation_quantization=False) + .clone_and_edit_weight_attribute(enable_weights_quantization=False)) + + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.STACK, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.UNSTACK, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.DROPOUT, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.FLATTEN, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SPLIT_CHUNK, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.GET_ITEM, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.RESHAPE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.UNSQUEEZE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SIZE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.PERMUTE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.TRANSPOSE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.EQUAL, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.ARGMAX, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.GATHER, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.TOPK, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SQUEEZE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.MAXPOOL, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.PAD, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.ZERO_PADDING2D, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.CAST, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.COMBINED_NON_MAX_SUPPRESSION, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.FAKE_QUANT, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SSD_POST_PROCESS, qc_options=no_quantization_config)) # Define operator sets that use mixed_precision_configuration_options: - conv = schema.OperatorsSet(name="Conv", qc_options=mixed_precision_configuration_options) - fc = schema.OperatorsSet(name="FullyConnected", qc_options=mixed_precision_configuration_options) + conv = schema.OperatorsSet(name=schema.OperatorSetNames.CONV, qc_options=mixed_precision_configuration_options) + conv_transpose = schema.OperatorsSet(name=schema.OperatorSetNames.CONV_TRANSPOSE, qc_options=mixed_precision_configuration_options) + depthwise_conv = schema.OperatorsSet(name=schema.OperatorSetNames.DEPTHWISE_CONV, qc_options=mixed_precision_configuration_options) + fc = schema.OperatorsSet(name=schema.OperatorSetNames.FULLY_CONNECTED, qc_options=mixed_precision_configuration_options) # Define operations sets without quantization configuration # options (useful for creating fusing patterns, for example): - any_relu = schema.OperatorsSet(name="AnyReLU") - add = schema.OperatorsSet(name="Add") - sub = schema.OperatorsSet(name="Sub") - mul = schema.OperatorsSet(name="Mul") - div = schema.OperatorsSet(name="Div") - prelu = schema.OperatorsSet(name="PReLU") - swish = schema.OperatorsSet(name="Swish") - sigmoid = schema.OperatorsSet(name="Sigmoid") - tanh = schema.OperatorsSet(name="Tanh") - - operator_set.extend([conv, fc, any_relu, add, sub, mul, div, prelu, swish, sigmoid, tanh]) + relu = schema.OperatorsSet(name=schema.OperatorSetNames.RELU) + relu6 = schema.OperatorsSet(name=schema.OperatorSetNames.RELU6) + leaky_relu = schema.OperatorsSet(name=schema.OperatorSetNames.LEAKY_RELU) + prelu = schema.OperatorsSet(name=schema.OperatorSetNames.PRELU) + add = schema.OperatorsSet(name=schema.OperatorSetNames.ADD) + sub = schema.OperatorsSet(name=schema.OperatorSetNames.SUB) + mul = schema.OperatorsSet(name=schema.OperatorSetNames.MUL) + div = schema.OperatorsSet(name=schema.OperatorSetNames.DIV) + swish = schema.OperatorsSet(name=schema.OperatorSetNames.SWISH) + hard_swish = schema.OperatorsSet(name=schema.OperatorSetNames.HARDSWISH) + sigmoid = schema.OperatorsSet(name=schema.OperatorSetNames.SIGMOID) + tanh = schema.OperatorsSet(name=schema.OperatorSetNames.TANH) + hard_tanh = schema.OperatorsSet(name=schema.OperatorSetNames.HARD_TANH) + + operator_set.extend([conv, conv_transpose, depthwise_conv, fc, relu, relu6, leaky_relu, add, sub, mul, div, prelu, swish, + hard_swish, sigmoid, tanh, hard_tanh]) + any_relu = schema.OperatorSetConcat(operators_set=[relu, relu6, leaky_relu, hard_tanh]) # Combine multiple operators into a single operator to avoid quantization between # them. To do this we define fusing patterns using the OperatorsSets that were created. # To group multiple sets with regard to fusing, an OperatorSetConcat can be created - activations_after_conv_to_fuse = schema.OperatorSetConcat(operators_set=[any_relu, swish, prelu, sigmoid, tanh]) - activations_after_fc_to_fuse = schema.OperatorSetConcat(operators_set=[any_relu, swish, sigmoid]) + activations_after_conv_to_fuse = schema.OperatorSetConcat(operators_set=[relu, relu6, leaky_relu, hard_tanh, swish, hard_swish, prelu, sigmoid, tanh]) + conv_types = schema.OperatorSetConcat(operators_set=[conv, conv_transpose, depthwise_conv]) + activations_after_fc_to_fuse = schema.OperatorSetConcat(operators_set=[relu, relu6, leaky_relu, hard_tanh, swish, hard_swish, sigmoid]) any_binary = schema.OperatorSetConcat(operators_set=[add, sub, mul, div]) # ------------------- # # Fusions # ------------------- # - fusing_patterns.append(schema.Fusing(operator_groups=(conv, activations_after_conv_to_fuse))) + fusing_patterns.append(schema.Fusing(operator_groups=(conv_types, activations_after_conv_to_fuse))) fusing_patterns.append(schema.Fusing(operator_groups=(fc, activations_after_fc_to_fuse))) fusing_patterns.append(schema.Fusing(operator_groups=(any_binary, any_relu))) diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1/tpc_keras.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1/tpc_keras.py deleted file mode 100644 index 43ca2b4e0..000000000 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1/tpc_keras.py +++ /dev/null @@ -1,129 +0,0 @@ -# Copyright 2023 Sony Semiconductor Israel, Inc. All rights reserved. -# -# 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. -# ============================================================================== -import tensorflow as tf -from packaging import version - -from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel -from model_compression_toolkit.defaultdict import DefaultDict -from model_compression_toolkit.verify_packages import FOUND_SONY_CUSTOM_LAYERS -from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, KERAS_DEPTHWISE_KERNEL, \ - KERAS_KERNEL, BIAS_ATTR, BIAS - -if FOUND_SONY_CUSTOM_LAYERS: - from sony_custom_layers.keras.object_detection.ssd_post_process import SSDPostProcess - -if version.parse(tf.__version__) >= version.parse("2.13"): - from keras.src.layers import Conv2D, DepthwiseConv2D, Dense, Reshape, ZeroPadding2D, Dropout, \ - MaxPooling2D, Activation, ReLU, Add, Subtract, Multiply, PReLU, Flatten, Cropping2D, LeakyReLU, Permute, \ - Conv2DTranspose -else: - from keras.layers import Conv2D, DepthwiseConv2D, Dense, Reshape, ZeroPadding2D, Dropout, \ - MaxPooling2D, Activation, ReLU, Add, Subtract, Multiply, PReLU, Flatten, Cropping2D, LeakyReLU, Permute, \ - Conv2DTranspose - -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1.tp_model import get_tp_model -import model_compression_toolkit as mct -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1 import __version__ as TPC_VERSION - -tp = mct.target_platform - - -def get_keras_tpc() -> tp.TargetPlatformCapabilities: - """ - get a Keras TargetPlatformCapabilities object with default operation sets to layers mapping. - Returns: a Keras TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - imx500_tpc_tp_model = get_tp_model() - return generate_keras_tpc(name='imx500_tpc_keras_tpc', tp_model=imx500_tpc_tp_model) - - -def generate_keras_tpc(name: str, tp_model: TargetPlatformModel): - """ - Generates a TargetPlatformCapabilities object with default operation sets to layers mapping. - - Args: - name: Name of the TargetPlatformCapabilities. - tp_model: TargetPlatformModel object. - - Returns: a TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - - keras_tpc = tp.TargetPlatformCapabilities(tp_model) - - no_quant_list = [Reshape, - tf.reshape, - Permute, - tf.transpose, - Flatten, - Cropping2D, - ZeroPadding2D, - Dropout, - MaxPooling2D, - tf.split, - tf.quantization.fake_quant_with_min_max_vars, - tf.math.argmax, - tf.shape, - tf.math.equal, - tf.gather, - tf.cast, - tf.unstack, - tf.compat.v1.gather, - tf.nn.top_k, - tf.__operators__.getitem, - tf.image.combined_non_max_suppression, - tf.compat.v1.shape] - - if FOUND_SONY_CUSTOM_LAYERS: - no_quant_list.append(SSDPostProcess) - - with keras_tpc: - tp.OperationsSetToLayers("NoQuantization", no_quant_list) - tp.OperationsSetToLayers("Conv", - [Conv2D, - DepthwiseConv2D, - Conv2DTranspose, - tf.nn.conv2d, - tf.nn.depthwise_conv2d, - tf.nn.conv2d_transpose], - # we provide attributes mapping that maps each layer type in the operations set - # that has weights attributes with provided quantization config (in the tp model) to - # its framework-specific attribute name. - # note that a DefaultDict should be provided if not all the layer types in the - # operation set are provided separately in the mapping. - attr_mapping={ - KERNEL_ATTR: DefaultDict({ - DepthwiseConv2D: KERAS_DEPTHWISE_KERNEL, - tf.nn.depthwise_conv2d: KERAS_DEPTHWISE_KERNEL}, default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}) - tp.OperationsSetToLayers("FullyConnected", [Dense], - attr_mapping={KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}) - tp.OperationsSetToLayers("AnyReLU", [tf.nn.relu, - tf.nn.relu6, - tf.nn.leaky_relu, - ReLU, - LeakyReLU, - tp.LayerFilterParams(Activation, activation="relu"), - tp.LayerFilterParams(Activation, activation="leaky_relu")]) - tp.OperationsSetToLayers("Add", [tf.add, Add]) - tp.OperationsSetToLayers("Sub", [tf.subtract, Subtract]) - tp.OperationsSetToLayers("Mul", [tf.math.multiply, Multiply]) - tp.OperationsSetToLayers("Div", [tf.math.divide]) - tp.OperationsSetToLayers("PReLU", [PReLU]) - tp.OperationsSetToLayers("Swish", [tf.nn.swish, tp.LayerFilterParams(Activation, activation="swish")]) - tp.OperationsSetToLayers("Sigmoid", [tf.nn.sigmoid, tp.LayerFilterParams(Activation, activation="sigmoid")]) - tp.OperationsSetToLayers("Tanh", [tf.nn.tanh, tp.LayerFilterParams(Activation, activation="tanh")]) - - return keras_tpc diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1/tpc_pytorch.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1/tpc_pytorch.py deleted file mode 100644 index 345e525a4..000000000 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1/tpc_pytorch.py +++ /dev/null @@ -1,108 +0,0 @@ -# Copyright 2023 Sony Semiconductor Israel, Inc. All rights reserved. -# -# 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. -# ============================================================================== - -import operator - -import torch -from torch import add, sub, mul, div, flatten, reshape, split, unsqueeze, dropout, sigmoid, tanh, chunk, unbind, topk, \ - gather, equal, transpose, permute, argmax, squeeze -from torch.nn import Conv2d, Linear, BatchNorm2d, ConvTranspose2d -from torch.nn import Dropout, Flatten, Hardtanh -from torch.nn import ReLU, ReLU6, PReLU, SiLU, Sigmoid, Tanh, Hardswish, LeakyReLU -from torch.nn.functional import relu, relu6, prelu, silu, hardtanh, hardswish, leaky_relu - -from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel -from model_compression_toolkit.defaultdict import DefaultDict -from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, BIAS_ATTR, PYTORCH_KERNEL, \ - BIAS -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1.tp_model import get_tp_model -import model_compression_toolkit as mct - -tp = mct.target_platform - - -def get_pytorch_tpc() -> tp.TargetPlatformCapabilities: - """ - get a Pytorch TargetPlatformCapabilities object with default operation sets to layers mapping. - Returns: a Pytorch TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - imx500_tpc_tp_model = get_tp_model() - return generate_pytorch_tpc(name='imx500_tpc_pytorch_tpc', tp_model=imx500_tpc_tp_model) - - -def generate_pytorch_tpc(name: str, tp_model: TargetPlatformModel): - """ - Generates a TargetPlatformCapabilities object with default operation sets to layers mapping. - Args: - name: Name of the TargetPlatformModel. - tp_model: TargetPlatformModel object. - Returns: a TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - - pytorch_tpc = tp.TargetPlatformCapabilities(tp_model) - - # we provide attributes mapping that maps each layer type in the operations set - # that has weights attributes with provided quantization config (in the tp model) to - # its framework-specific attribute name. - # note that a DefaultDict should be provided if not all the layer types in the - # operation set are provided separately in the mapping. - pytorch_linear_attr_mapping = {KERNEL_ATTR: DefaultDict(default_value=PYTORCH_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)} - - with pytorch_tpc: - tp.OperationsSetToLayers("NoQuantization", [Dropout, - Flatten, - dropout, - flatten, - split, - operator.getitem, - reshape, - unsqueeze, - BatchNorm2d, - chunk, - unbind, - torch.Tensor.size, - permute, - transpose, - equal, - argmax, - gather, - topk, - squeeze]) - - tp.OperationsSetToLayers("Conv", [Conv2d, ConvTranspose2d], - attr_mapping=pytorch_linear_attr_mapping) - tp.OperationsSetToLayers("FullyConnected", [Linear], - attr_mapping=pytorch_linear_attr_mapping) - tp.OperationsSetToLayers("AnyReLU", [torch.relu, - ReLU, - ReLU6, - LeakyReLU, - relu, - relu6, - leaky_relu, - tp.LayerFilterParams(Hardtanh, min_val=0), - tp.LayerFilterParams(hardtanh, min_val=0)]) - - tp.OperationsSetToLayers("Add", [operator.add, add]) - tp.OperationsSetToLayers("Sub", [operator.sub, sub]) - tp.OperationsSetToLayers("Mul", [operator.mul, mul]) - tp.OperationsSetToLayers("Div", [operator.truediv, div]) - tp.OperationsSetToLayers("PReLU", [PReLU, prelu]) - tp.OperationsSetToLayers("Swish", [SiLU, silu, Hardswish, hardswish]) - tp.OperationsSetToLayers("Sigmoid", [Sigmoid, sigmoid]) - tp.OperationsSetToLayers("Tanh", [Tanh, tanh]) - - return pytorch_tpc diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1_lut/tpc_keras.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1_lut/tpc_keras.py deleted file mode 100644 index 9bf658512..000000000 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1_lut/tpc_keras.py +++ /dev/null @@ -1,130 +0,0 @@ -# Copyright 2023 Sony Semiconductor Israel, Inc. All rights reserved. -# -# 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. -# ============================================================================== -import tensorflow as tf -from packaging import version - -from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel -from model_compression_toolkit.defaultdict import DefaultDict -from model_compression_toolkit.verify_packages import FOUND_SONY_CUSTOM_LAYERS -from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, KERAS_KERNEL, BIAS_ATTR, \ - KERAS_DEPTHWISE_KERNEL, BIAS - -if FOUND_SONY_CUSTOM_LAYERS: - from sony_custom_layers.keras.object_detection.ssd_post_process import SSDPostProcess - -if version.parse(tf.__version__) >= version.parse("2.13"): - from keras.src.layers import Conv2D, DepthwiseConv2D, Dense, Reshape, ZeroPadding2D, Dropout, \ - MaxPooling2D, Activation, ReLU, Add, Subtract, Multiply, PReLU, Flatten, Cropping2D, LeakyReLU, Permute, \ - Conv2DTranspose -else: - from keras.layers import Conv2D, DepthwiseConv2D, Dense, Reshape, ZeroPadding2D, Dropout, \ - MaxPooling2D, Activation, ReLU, Add, Subtract, Multiply, PReLU, Flatten, Cropping2D, LeakyReLU, Permute, \ - Conv2DTranspose - -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1_lut.tp_model import get_tp_model -import model_compression_toolkit as mct -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1_lut import __version__ as TPC_VERSION - -tp = mct.target_platform - - -def get_keras_tpc() -> tp.TargetPlatformCapabilities: - """ - get a Keras TargetPlatformCapabilities object with default operation sets to layers mapping. - Returns: a Keras TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - imx500_tpc_tp_model = get_tp_model() - return generate_keras_tpc(name='imx500_tpc_keras_tpc', tp_model=imx500_tpc_tp_model) - - -def generate_keras_tpc(name: str, tp_model: TargetPlatformModel): - """ - Generates a TargetPlatformCapabilities object with default operation sets to layers mapping. - - Args: - name: Name of the TargetPlatformCapabilities. - tp_model: TargetPlatformModel object. - - Returns: a TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - - keras_tpc = tp.TargetPlatformCapabilities(tp_model) - - no_quant_list = [Reshape, - tf.reshape, - Permute, - tf.transpose, - Flatten, - Cropping2D, - ZeroPadding2D, - Dropout, - MaxPooling2D, - tf.split, - tf.quantization.fake_quant_with_min_max_vars, - tf.math.argmax, - tf.shape, - tf.math.equal, - tf.gather, - tf.cast, - tf.unstack, - tf.compat.v1.gather, - tf.nn.top_k, - tf.__operators__.getitem, - tf.image.combined_non_max_suppression, - tf.compat.v1.shape] - - if FOUND_SONY_CUSTOM_LAYERS: - no_quant_list.append(SSDPostProcess) - - with keras_tpc: - tp.OperationsSetToLayers("NoQuantization", no_quant_list) - - tp.OperationsSetToLayers("Conv", - [Conv2D, - DepthwiseConv2D, - Conv2DTranspose, - tf.nn.conv2d, - tf.nn.depthwise_conv2d, - tf.nn.conv2d_transpose], - # we provide attributes mapping that maps each layer type in the operations set - # that has weights attributes with provided quantization config (in the tp model) to - # its framework-specific attribute name. - # note that a DefaultDict should be provided if not all the layer types in the - # operation set are provided separately in the mapping. - attr_mapping={ - KERNEL_ATTR: DefaultDict({ - DepthwiseConv2D: KERAS_DEPTHWISE_KERNEL, - tf.nn.depthwise_conv2d: KERAS_DEPTHWISE_KERNEL}, default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}) - tp.OperationsSetToLayers("FullyConnected", [Dense], - attr_mapping={KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}) - tp.OperationsSetToLayers("AnyReLU", [tf.nn.relu, - tf.nn.relu6, - tf.nn.leaky_relu, - ReLU, - LeakyReLU, - tp.LayerFilterParams(Activation, activation="relu"), - tp.LayerFilterParams(Activation, activation="leaky_relu")]) - tp.OperationsSetToLayers("Add", [tf.add, Add]) - tp.OperationsSetToLayers("Sub", [tf.subtract, Subtract]) - tp.OperationsSetToLayers("Mul", [tf.math.multiply, Multiply]) - tp.OperationsSetToLayers("Div", [tf.math.divide]) - tp.OperationsSetToLayers("PReLU", [PReLU]) - tp.OperationsSetToLayers("Swish", [tf.nn.swish, tp.LayerFilterParams(Activation, activation="swish")]) - tp.OperationsSetToLayers("Sigmoid", [tf.nn.sigmoid, tp.LayerFilterParams(Activation, activation="sigmoid")]) - tp.OperationsSetToLayers("Tanh", [tf.nn.tanh, tp.LayerFilterParams(Activation, activation="tanh")]) - - return keras_tpc diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1_lut/tpc_pytorch.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1_lut/tpc_pytorch.py deleted file mode 100644 index 9e03c497f..000000000 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1_lut/tpc_pytorch.py +++ /dev/null @@ -1,109 +0,0 @@ -# Copyright 2023 Sony Semiconductor Israel, Inc. All rights reserved. -# -# 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. -# ============================================================================== - -import operator - -import torch -from torch import add, sub, mul, div, flatten, reshape, split, unsqueeze, dropout, sigmoid, tanh, chunk, unbind, topk, \ - gather, equal, transpose, permute, argmax, squeeze -from torch.nn import Conv2d, Linear, BatchNorm2d, ConvTranspose2d -from torch.nn import Dropout, Flatten, Hardtanh -from torch.nn import ReLU, ReLU6, PReLU, SiLU, Sigmoid, Tanh, Hardswish, LeakyReLU -from torch.nn.functional import relu, relu6, prelu, silu, hardtanh, hardswish, leaky_relu - -import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema -from model_compression_toolkit.defaultdict import DefaultDict -from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, PYTORCH_KERNEL, BIAS_ATTR, \ - BIAS -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1_lut.tp_model import get_tp_model -import model_compression_toolkit as mct -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1_lut import __version__ as TPC_VERSION - -tp = mct.target_platform - - -def get_pytorch_tpc() -> tp.TargetPlatformCapabilities: - """ - get a Pytorch TargetPlatformCapabilities object with default operation sets to layers mapping. - Returns: a Pytorch TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - imx500_tpc_tp_model = get_tp_model() - return generate_pytorch_tpc(name='imx500_tpc_pytorch_tpc', tp_model=imx500_tpc_tp_model) - - -def generate_pytorch_tpc(name: str, tp_model: schema.TargetPlatformModel): - """ - Generates a TargetPlatformCapabilities object with default operation sets to layers mapping. - Args: - name: Name of the TargetPlatformModel. - tp_model: TargetPlatformModel object. - Returns: a TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - - pytorch_tpc = tp.TargetPlatformCapabilities(tp_model) - - # we provide attributes mapping that maps each layer type in the operations set - # that has weights attributes with provided quantization config (in the tp model) to - # its framework-specific attribute name. - # note that a DefaultDict should be provided if not all the layer types in the - # operation set are provided separately in the mapping. - pytorch_linear_attr_mapping = {KERNEL_ATTR: DefaultDict(default_value=PYTORCH_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)} - - with pytorch_tpc: - tp.OperationsSetToLayers("NoQuantization", [Dropout, - Flatten, - dropout, - flatten, - split, - operator.getitem, - reshape, - unsqueeze, - BatchNorm2d, - chunk, - unbind, - torch.Tensor.size, - permute, - transpose, - equal, - argmax, - gather, - topk, - squeeze]) - - tp.OperationsSetToLayers("Conv", [Conv2d, ConvTranspose2d], - attr_mapping=pytorch_linear_attr_mapping) - tp.OperationsSetToLayers("FullyConnected", [Linear], - attr_mapping=pytorch_linear_attr_mapping) - tp.OperationsSetToLayers("AnyReLU", [torch.relu, - ReLU, - ReLU6, - LeakyReLU, - relu, - relu6, - leaky_relu, - tp.LayerFilterParams(Hardtanh, min_val=0), - tp.LayerFilterParams(hardtanh, min_val=0)]) - - tp.OperationsSetToLayers("Add", [operator.add, add]) - tp.OperationsSetToLayers("Sub", [operator.sub, sub]) - tp.OperationsSetToLayers("Mul", [operator.mul, mul]) - tp.OperationsSetToLayers("Div", [operator.truediv, div]) - tp.OperationsSetToLayers("PReLU", [PReLU, prelu]) - tp.OperationsSetToLayers("Swish", [SiLU, silu, Hardswish, hardswish]) - tp.OperationsSetToLayers("Sigmoid", [Sigmoid, sigmoid]) - tp.OperationsSetToLayers("Tanh", [Tanh, tanh]) - - return pytorch_tpc diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1_pot/tpc_keras.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1_pot/tpc_keras.py deleted file mode 100644 index 0bca7062f..000000000 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1_pot/tpc_keras.py +++ /dev/null @@ -1,130 +0,0 @@ -# Copyright 2023 Sony Semiconductor Israel, Inc. All rights reserved. -# -# 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. -# ============================================================================== -import tensorflow as tf -from packaging import version - -import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema -from model_compression_toolkit.defaultdict import DefaultDict -from model_compression_toolkit.verify_packages import FOUND_SONY_CUSTOM_LAYERS -from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, KERAS_DEPTHWISE_KERNEL, \ - KERAS_KERNEL, BIAS_ATTR, BIAS - -if FOUND_SONY_CUSTOM_LAYERS: - from sony_custom_layers.keras.object_detection.ssd_post_process import SSDPostProcess - -if version.parse(tf.__version__) >= version.parse("2.13"): - from keras.src.layers import Conv2D, DepthwiseConv2D, Dense, Reshape, ZeroPadding2D, Dropout, \ - MaxPooling2D, Activation, ReLU, Add, Subtract, Multiply, PReLU, Flatten, Cropping2D, LeakyReLU, Permute, \ - Conv2DTranspose -else: - from keras.layers import Conv2D, DepthwiseConv2D, Dense, Reshape, ZeroPadding2D, Dropout, \ - MaxPooling2D, Activation, ReLU, Add, Subtract, Multiply, PReLU, Flatten, Cropping2D, LeakyReLU, Permute, \ - Conv2DTranspose - -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1_pot.tp_model import get_tp_model -import model_compression_toolkit as mct -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1_pot import __version__ as TPC_VERSION - -tp = mct.target_platform - - -def get_keras_tpc() -> tp.TargetPlatformCapabilities: - """ - get a Keras TargetPlatformCapabilities object with default operation sets to layers mapping. - Returns: a Keras TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - imx500_pot_tpc_tp_model = get_tp_model() - return generate_keras_tpc(name='imx500_pot_tpc_keras_tpc', tp_model=imx500_pot_tpc_tp_model) - - -def generate_keras_tpc(name: str, tp_model: schema.TargetPlatformModel): - """ - Generates a TargetPlatformCapabilities object with default operation sets to layers mapping. - - Args: - name: Name of the TargetPlatformCapabilities. - tp_model: TargetPlatformModel object. - - Returns: a TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - - keras_tpc = tp.TargetPlatformCapabilities(tp_model) - - no_quant_list = [Reshape, - tf.reshape, - Permute, - tf.transpose, - Flatten, - Cropping2D, - ZeroPadding2D, - Dropout, - MaxPooling2D, - tf.split, - tf.quantization.fake_quant_with_min_max_vars, - tf.math.argmax, - tf.shape, - tf.math.equal, - tf.gather, - tf.cast, - tf.unstack, - tf.compat.v1.gather, - tf.nn.top_k, - tf.__operators__.getitem, - tf.image.combined_non_max_suppression, - tf.compat.v1.shape] - - if FOUND_SONY_CUSTOM_LAYERS: - no_quant_list.append(SSDPostProcess) - - with keras_tpc: - tp.OperationsSetToLayers("NoQuantization", no_quant_list) - - tp.OperationsSetToLayers("Conv", - [Conv2D, - DepthwiseConv2D, - Conv2DTranspose, - tf.nn.conv2d, - tf.nn.depthwise_conv2d, - tf.nn.conv2d_transpose], - # we provide attributes mapping that maps each layer type in the operations set - # that has weights attributes with provided quantization config (in the tp model) to - # its framework-specific attribute name. - # note that a DefaultDict should be provided if not all the layer types in the - # operation set are provided separately in the mapping. - attr_mapping={ - KERNEL_ATTR: DefaultDict({ - DepthwiseConv2D: KERAS_DEPTHWISE_KERNEL, - tf.nn.depthwise_conv2d: KERAS_DEPTHWISE_KERNEL}, default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}) - tp.OperationsSetToLayers("FullyConnected", [Dense], - attr_mapping={KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}) - tp.OperationsSetToLayers("AnyReLU", [tf.nn.relu, - tf.nn.relu6, - tf.nn.leaky_relu, - ReLU, - LeakyReLU, - tp.LayerFilterParams(Activation, activation="relu"), - tp.LayerFilterParams(Activation, activation="leaky_relu")]) - tp.OperationsSetToLayers("Add", [tf.add, Add]) - tp.OperationsSetToLayers("Sub", [tf.subtract, Subtract]) - tp.OperationsSetToLayers("Mul", [tf.math.multiply, Multiply]) - tp.OperationsSetToLayers("Div", [tf.math.divide]) - tp.OperationsSetToLayers("PReLU", [PReLU]) - tp.OperationsSetToLayers("Swish", [tf.nn.swish, tp.LayerFilterParams(Activation, activation="swish")]) - tp.OperationsSetToLayers("Sigmoid", [tf.nn.sigmoid, tp.LayerFilterParams(Activation, activation="sigmoid")]) - tp.OperationsSetToLayers("Tanh", [tf.nn.tanh, tp.LayerFilterParams(Activation, activation="tanh")]) - - return keras_tpc diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1_pot/tpc_pytorch.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1_pot/tpc_pytorch.py deleted file mode 100644 index 7c5ac0769..000000000 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1_pot/tpc_pytorch.py +++ /dev/null @@ -1,110 +0,0 @@ -# Copyright 2023 Sony Semiconductor Israel, Inc. All rights reserved. -# -# 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. -# ============================================================================== - -import operator - -import torch -from torch import add, sub, mul, div, flatten, reshape, split, unsqueeze, dropout, sigmoid, tanh, chunk, unbind, topk, \ - gather, equal, transpose, permute, argmax, squeeze -from torch.nn import Conv2d, Linear, BatchNorm2d, ConvTranspose2d -from torch.nn import Dropout, Flatten, Hardtanh -from torch.nn import ReLU, ReLU6, PReLU, SiLU, Sigmoid, Tanh, Hardswish, LeakyReLU -from torch.nn.functional import relu, relu6, prelu, silu, hardtanh, hardswish, leaky_relu - -import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema -from model_compression_toolkit.defaultdict import DefaultDict -from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, PYTORCH_KERNEL, BIAS_ATTR, \ - BIAS -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1_pot.tp_model import get_tp_model -import model_compression_toolkit as mct -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v1_pot import ( - __version__ as TPC_VERSION) - -tp = mct.target_platform - - -def get_pytorch_tpc() -> tp.TargetPlatformCapabilities: - """ - get a Pytorch TargetPlatformCapabilities object with default operation sets to layers mapping. - Returns: a Pytorch TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - imx500_pot_tpc_tp_model = get_tp_model() - return generate_pytorch_tpc(name='imx500_pot_tpc_pytorch_tpc', tp_model=imx500_pot_tpc_tp_model) - - -def generate_pytorch_tpc(name: str, tp_model: schema.TargetPlatformModel): - """ - Generates a TargetPlatformCapabilities object with default operation sets to layers mapping. - Args: - name: Name of the TargetPlatformModel. - tp_model: TargetPlatformModel object. - Returns: a TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - - pytorch_tpc = tp.TargetPlatformCapabilities(tp_model) - - # we provide attributes mapping that maps each layer type in the operations set - # that has weights attributes with provided quantization config (in the tp model) to - # its framework-specific attribute name. - # note that a DefaultDict should be provided if not all the layer types in the - # operation set are provided separately in the mapping. - pytorch_linear_attr_mapping = {KERNEL_ATTR: DefaultDict(default_value=PYTORCH_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)} - - with pytorch_tpc: - tp.OperationsSetToLayers("NoQuantization", [Dropout, - Flatten, - dropout, - flatten, - split, - operator.getitem, - reshape, - unsqueeze, - BatchNorm2d, - chunk, - unbind, - torch.Tensor.size, - permute, - transpose, - equal, - argmax, - gather, - topk, - squeeze]) - - tp.OperationsSetToLayers("Conv", [Conv2d, ConvTranspose2d], - attr_mapping=pytorch_linear_attr_mapping) - tp.OperationsSetToLayers("FullyConnected", [Linear], - attr_mapping=pytorch_linear_attr_mapping) - tp.OperationsSetToLayers("AnyReLU", [torch.relu, - ReLU, - ReLU6, - LeakyReLU, - relu, - relu6, - leaky_relu, - tp.LayerFilterParams(Hardtanh, min_val=0), - tp.LayerFilterParams(hardtanh, min_val=0)]) - - tp.OperationsSetToLayers("Add", [operator.add, add]) - tp.OperationsSetToLayers("Sub", [operator.sub, sub]) - tp.OperationsSetToLayers("Mul", [operator.mul, mul]) - tp.OperationsSetToLayers("Div", [operator.truediv, div]) - tp.OperationsSetToLayers("PReLU", [PReLU, prelu]) - tp.OperationsSetToLayers("Swish", [SiLU, silu, Hardswish, hardswish]) - tp.OperationsSetToLayers("Sigmoid", [Sigmoid, sigmoid]) - tp.OperationsSetToLayers("Tanh", [Tanh, tanh]) - - return pytorch_tpc diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v2/tpc_keras.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v2/tpc_keras.py deleted file mode 100644 index b84430911..000000000 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v2/tpc_keras.py +++ /dev/null @@ -1,132 +0,0 @@ -# Copyright 2024 Sony Semiconductor Israel, Inc. All rights reserved. -# -# 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. -# ============================================================================== -import tensorflow as tf -from packaging import version - -import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema -from model_compression_toolkit.defaultdict import DefaultDict -from model_compression_toolkit.verify_packages import FOUND_SONY_CUSTOM_LAYERS -from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, KERAS_DEPTHWISE_KERNEL, \ - KERAS_KERNEL, BIAS_ATTR, BIAS - -if FOUND_SONY_CUSTOM_LAYERS: - from sony_custom_layers.keras.object_detection.ssd_post_process import SSDPostProcess - -if version.parse(tf.__version__) >= version.parse("2.13"): - from keras.src.layers import Conv2D, DepthwiseConv2D, Dense, Reshape, ZeroPadding2D, Dropout, \ - MaxPooling2D, Activation, ReLU, Add, Subtract, Multiply, PReLU, Flatten, Cropping2D, LeakyReLU, Permute, \ - Conv2DTranspose, Identity -else: - from keras.layers import Conv2D, DepthwiseConv2D, Dense, Reshape, ZeroPadding2D, Dropout, \ - MaxPooling2D, Activation, ReLU, Add, Subtract, Multiply, PReLU, Flatten, Cropping2D, LeakyReLU, Permute, \ - Conv2DTranspose, Identity - -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v2.tp_model import get_tp_model -import model_compression_toolkit as mct -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v2 import __version__ as TPC_VERSION - -tp = mct.target_platform - - -def get_keras_tpc() -> tp.TargetPlatformCapabilities: - """ - get a Keras TargetPlatformCapabilities object with default operation sets to layers mapping. - - Returns: a Keras TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - imx500_tpc_tp_model = get_tp_model() - return generate_keras_tpc(name='imx500_tpc_keras_tpc', tp_model=imx500_tpc_tp_model) - - -def generate_keras_tpc(name: str, tp_model: schema.TargetPlatformModel): - """ - Generates a TargetPlatformCapabilities object with default operation sets to layers mapping. - - Args: - name: Name of the TargetPlatformCapabilities. - tp_model: TargetPlatformModel object. - - Returns: a TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - - keras_tpc = tp.TargetPlatformCapabilities(tp_model) - - no_quant_list = [Identity, - tf.identity, - Reshape, - tf.reshape, - Permute, - tf.transpose, - Flatten, - Cropping2D, - ZeroPadding2D, - Dropout, - MaxPooling2D, - tf.split, - tf.quantization.fake_quant_with_min_max_vars, - tf.math.argmax, - tf.shape, - tf.math.equal, - tf.gather, - tf.cast, - tf.unstack, - tf.compat.v1.gather, - tf.nn.top_k, - tf.__operators__.getitem, - tf.image.combined_non_max_suppression, - tf.compat.v1.shape] - - if FOUND_SONY_CUSTOM_LAYERS: - no_quant_list.append(SSDPostProcess) - - with keras_tpc: - tp.OperationsSetToLayers("NoQuantization", no_quant_list) - tp.OperationsSetToLayers("Conv", - [Conv2D, - DepthwiseConv2D, - Conv2DTranspose, - tf.nn.conv2d, - tf.nn.depthwise_conv2d, - tf.nn.conv2d_transpose], - # we provide attributes mapping that maps each layer type in the operations set - # that has weights attributes with provided quantization config (in the tp model) to - # its framework-specific attribute name. - # note that a DefaultDict should be provided if not all the layer types in the - # operation set are provided separately in the mapping. - attr_mapping={ - KERNEL_ATTR: DefaultDict({ - DepthwiseConv2D: KERAS_DEPTHWISE_KERNEL, - tf.nn.depthwise_conv2d: KERAS_DEPTHWISE_KERNEL}, default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}) - tp.OperationsSetToLayers("FullyConnected", [Dense], - attr_mapping={KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}) - tp.OperationsSetToLayers("AnyReLU", [tf.nn.relu, - tf.nn.relu6, - tf.nn.leaky_relu, - ReLU, - LeakyReLU, - tp.LayerFilterParams(Activation, activation="relu"), - tp.LayerFilterParams(Activation, activation="leaky_relu")]) - tp.OperationsSetToLayers("Add", [tf.add, Add]) - tp.OperationsSetToLayers("Sub", [tf.subtract, Subtract]) - tp.OperationsSetToLayers("Mul", [tf.math.multiply, Multiply]) - tp.OperationsSetToLayers("Div", [tf.math.divide, tf.math.truediv]) - tp.OperationsSetToLayers("PReLU", [PReLU]) - tp.OperationsSetToLayers("Swish", [tf.nn.swish, tp.LayerFilterParams(Activation, activation="swish")]) - tp.OperationsSetToLayers("Sigmoid", [tf.nn.sigmoid, tp.LayerFilterParams(Activation, activation="sigmoid")]) - tp.OperationsSetToLayers("Tanh", [tf.nn.tanh, tp.LayerFilterParams(Activation, activation="tanh")]) - - return keras_tpc diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v2/tpc_pytorch.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v2/tpc_pytorch.py deleted file mode 100644 index 471ed4ae0..000000000 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v2/tpc_pytorch.py +++ /dev/null @@ -1,110 +0,0 @@ -# Copyright 2024 Sony Semiconductor Israel, Inc. All rights reserved. -# -# 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. -# ============================================================================== - -import operator - -import torch -from torch import add, sub, mul, div, flatten, reshape, split, unsqueeze, dropout, sigmoid, tanh, chunk, unbind, topk, \ - gather, equal, transpose, permute, argmax, squeeze -from torch.nn import Conv2d, Linear, ConvTranspose2d -from torch.nn import Dropout, Flatten, Hardtanh, Identity -from torch.nn import ReLU, ReLU6, PReLU, SiLU, Sigmoid, Tanh, Hardswish, LeakyReLU -from torch.nn.functional import relu, relu6, prelu, silu, hardtanh, hardswish, leaky_relu - -import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema -from model_compression_toolkit.defaultdict import DefaultDict -from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, BIAS_ATTR, PYTORCH_KERNEL, \ - BIAS -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v2.tp_model import get_tp_model -import model_compression_toolkit as mct -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v2 import __version__ as TPC_VERSION - -tp = mct.target_platform - - -def get_pytorch_tpc() -> tp.TargetPlatformCapabilities: - """ - get a Pytorch TargetPlatformCapabilities object with default operation sets to layers mapping. - - Returns: a Pytorch TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - imx500_tpc_tp_model = get_tp_model() - return generate_pytorch_tpc(name='imx500_tpc_pytorch_tpc', tp_model=imx500_tpc_tp_model) - - -def generate_pytorch_tpc(name: str, tp_model: schema.TargetPlatformModel): - """ - Generates a TargetPlatformCapabilities object with default operation sets to layers mapping. - Args: - name: Name of the TargetPlatformModel. - tp_model: TargetPlatformModel object. - Returns: a TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - - pytorch_tpc = tp.TargetPlatformCapabilities(tp_model) - - # we provide attributes mapping that maps each layer type in the operations set - # that has weights attributes with provided quantization config (in the tp model) to - # its framework-specific attribute name. - # note that a DefaultDict should be provided if not all the layer types in the - # operation set are provided separately in the mapping. - pytorch_linear_attr_mapping = {KERNEL_ATTR: DefaultDict(default_value=PYTORCH_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)} - - with pytorch_tpc: - tp.OperationsSetToLayers("NoQuantization", [Identity, - Dropout, - Flatten, - dropout, - flatten, - split, - operator.getitem, - reshape, - unsqueeze, - chunk, - unbind, - torch.Tensor.size, - permute, - transpose, - equal, - argmax, - gather, - topk, - squeeze]) - - tp.OperationsSetToLayers("Conv", [Conv2d, ConvTranspose2d], - attr_mapping=pytorch_linear_attr_mapping) - tp.OperationsSetToLayers("FullyConnected", [Linear], - attr_mapping=pytorch_linear_attr_mapping) - tp.OperationsSetToLayers("AnyReLU", [torch.relu, - ReLU, - ReLU6, - LeakyReLU, - relu, - relu6, - leaky_relu, - tp.LayerFilterParams(Hardtanh, min_val=0), - tp.LayerFilterParams(hardtanh, min_val=0)]) - - tp.OperationsSetToLayers("Add", [operator.add, add]) - tp.OperationsSetToLayers("Sub", [operator.sub, sub]) - tp.OperationsSetToLayers("Mul", [operator.mul, mul]) - tp.OperationsSetToLayers("Div", [operator.truediv, div]) - tp.OperationsSetToLayers("PReLU", [PReLU, prelu]) - tp.OperationsSetToLayers("Swish", [SiLU, silu, Hardswish, hardswish]) - tp.OperationsSetToLayers("Sigmoid", [Sigmoid, sigmoid]) - tp.OperationsSetToLayers("Tanh", [Tanh, tanh]) - - return pytorch_tpc diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v2_lut/tpc_keras.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v2_lut/tpc_keras.py deleted file mode 100644 index 192464bac..000000000 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v2_lut/tpc_keras.py +++ /dev/null @@ -1,132 +0,0 @@ -# Copyright 2024 Sony Semiconductor Israel, Inc. All rights reserved. -# -# 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. -# ============================================================================== -import tensorflow as tf -from packaging import version - -import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema -from model_compression_toolkit.defaultdict import DefaultDict -from model_compression_toolkit.verify_packages import FOUND_SONY_CUSTOM_LAYERS -from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, KERAS_KERNEL, BIAS_ATTR, \ - KERAS_DEPTHWISE_KERNEL, BIAS - -if FOUND_SONY_CUSTOM_LAYERS: - from sony_custom_layers.keras.object_detection.ssd_post_process import SSDPostProcess - -if version.parse(tf.__version__) >= version.parse("2.13"): - from keras.src.layers import Conv2D, DepthwiseConv2D, Dense, Reshape, ZeroPadding2D, Dropout, \ - MaxPooling2D, Activation, ReLU, Add, Subtract, Multiply, PReLU, Flatten, Cropping2D, LeakyReLU, Permute, \ - Conv2DTranspose, Identity -else: - from keras.layers import Conv2D, DepthwiseConv2D, Dense, Reshape, ZeroPadding2D, Dropout, \ - MaxPooling2D, Activation, ReLU, Add, Subtract, Multiply, PReLU, Flatten, Cropping2D, LeakyReLU, Permute, \ - Conv2DTranspose, Identity - -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v2_lut.tp_model import get_tp_model -import model_compression_toolkit as mct -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v2_lut import __version__ as TPC_VERSION - -tp = mct.target_platform - - -def get_keras_tpc() -> tp.TargetPlatformCapabilities: - """ - get a Keras TargetPlatformCapabilities object with default operation sets to layers mapping. - Returns: a Keras TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - imx500_tpc_tp_model = get_tp_model() - return generate_keras_tpc(name='imx500_tpc_keras_tpc', tp_model=imx500_tpc_tp_model) - - -def generate_keras_tpc(name: str, tp_model: schema.TargetPlatformModel): - """ - Generates a TargetPlatformCapabilities object with default operation sets to layers mapping. - - Args: - name: Name of the TargetPlatformCapabilities. - tp_model: TargetPlatformModel object. - - Returns: a TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - - keras_tpc = tp.TargetPlatformCapabilities(tp_model) - - no_quant_list = [Identity, - tf.identity, - Reshape, - tf.reshape, - Permute, - tf.transpose, - Flatten, - Cropping2D, - ZeroPadding2D, - Dropout, - MaxPooling2D, - tf.split, - tf.quantization.fake_quant_with_min_max_vars, - tf.math.argmax, - tf.shape, - tf.math.equal, - tf.gather, - tf.cast, - tf.unstack, - tf.compat.v1.gather, - tf.nn.top_k, - tf.__operators__.getitem, - tf.image.combined_non_max_suppression, - tf.compat.v1.shape] - - if FOUND_SONY_CUSTOM_LAYERS: - no_quant_list.append(SSDPostProcess) - - with keras_tpc: - tp.OperationsSetToLayers("NoQuantization", no_quant_list) - - tp.OperationsSetToLayers("Conv", - [Conv2D, - DepthwiseConv2D, - Conv2DTranspose, - tf.nn.conv2d, - tf.nn.depthwise_conv2d, - tf.nn.conv2d_transpose], - # we provide attributes mapping that maps each layer type in the operations set - # that has weights attributes with provided quantization config (in the tp model) to - # its framework-specific attribute name. - # note that a DefaultDict should be provided if not all the layer types in the - # operation set are provided separately in the mapping. - attr_mapping={ - KERNEL_ATTR: DefaultDict({ - DepthwiseConv2D: KERAS_DEPTHWISE_KERNEL, - tf.nn.depthwise_conv2d: KERAS_DEPTHWISE_KERNEL}, default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}) - tp.OperationsSetToLayers("FullyConnected", [Dense], - attr_mapping={KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}) - tp.OperationsSetToLayers("AnyReLU", [tf.nn.relu, - tf.nn.relu6, - tf.nn.leaky_relu, - ReLU, - LeakyReLU, - tp.LayerFilterParams(Activation, activation="relu"), - tp.LayerFilterParams(Activation, activation="leaky_relu")]) - tp.OperationsSetToLayers("Add", [tf.add, Add]) - tp.OperationsSetToLayers("Sub", [tf.subtract, Subtract]) - tp.OperationsSetToLayers("Mul", [tf.math.multiply, Multiply]) - tp.OperationsSetToLayers("Div", [tf.math.divide, tf.math.truediv]) - tp.OperationsSetToLayers("PReLU", [PReLU]) - tp.OperationsSetToLayers("Swish", [tf.nn.swish, tp.LayerFilterParams(Activation, activation="swish")]) - tp.OperationsSetToLayers("Sigmoid", [tf.nn.sigmoid, tp.LayerFilterParams(Activation, activation="sigmoid")]) - tp.OperationsSetToLayers("Tanh", [tf.nn.tanh, tp.LayerFilterParams(Activation, activation="tanh")]) - - return keras_tpc diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v2_lut/tpc_pytorch.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v2_lut/tpc_pytorch.py deleted file mode 100644 index 6d05fe910..000000000 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v2_lut/tpc_pytorch.py +++ /dev/null @@ -1,109 +0,0 @@ -# Copyright 2024 Sony Semiconductor Israel, Inc. All rights reserved. -# -# 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. -# ============================================================================== - -import operator - -import torch -from torch import add, sub, mul, div, flatten, reshape, split, unsqueeze, dropout, sigmoid, tanh, chunk, unbind, topk, \ - gather, equal, transpose, permute, argmax, squeeze -from torch.nn import Conv2d, Linear, ConvTranspose2d -from torch.nn import Dropout, Flatten, Hardtanh, Identity -from torch.nn import ReLU, ReLU6, PReLU, SiLU, Sigmoid, Tanh, Hardswish, LeakyReLU -from torch.nn.functional import relu, relu6, prelu, silu, hardtanh, hardswish, leaky_relu - -import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema -from model_compression_toolkit.defaultdict import DefaultDict -from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, PYTORCH_KERNEL, BIAS_ATTR, \ - BIAS -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v2_lut.tp_model import get_tp_model -import model_compression_toolkit as mct -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v2_lut import __version__ as TPC_VERSION - -tp = mct.target_platform - - -def get_pytorch_tpc() -> tp.TargetPlatformCapabilities: - """ - get a Pytorch TargetPlatformCapabilities object with default operation sets to layers mapping. - Returns: a Pytorch TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - imx500_tpc_tp_model = get_tp_model() - return generate_pytorch_tpc(name='imx500_tpc_pytorch_tpc', tp_model=imx500_tpc_tp_model) - - -def generate_pytorch_tpc(name: str, tp_model: schema.TargetPlatformModel): - """ - Generates a TargetPlatformCapabilities object with default operation sets to layers mapping. - Args: - name: Name of the TargetPlatformModel. - tp_model: TargetPlatformModel object. - Returns: a TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - - pytorch_tpc = tp.TargetPlatformCapabilities(tp_model) - - # we provide attributes mapping that maps each layer type in the operations set - # that has weights attributes with provided quantization config (in the tp model) to - # its framework-specific attribute name. - # note that a DefaultDict should be provided if not all the layer types in the - # operation set are provided separately in the mapping. - pytorch_linear_attr_mapping = {KERNEL_ATTR: DefaultDict(default_value=PYTORCH_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)} - - with pytorch_tpc: - tp.OperationsSetToLayers("NoQuantization", [Identity, - Dropout, - Flatten, - dropout, - flatten, - split, - operator.getitem, - reshape, - unsqueeze, - chunk, - unbind, - torch.Tensor.size, - permute, - transpose, - equal, - argmax, - gather, - topk, - squeeze]) - - tp.OperationsSetToLayers("Conv", [Conv2d, ConvTranspose2d], - attr_mapping=pytorch_linear_attr_mapping) - tp.OperationsSetToLayers("FullyConnected", [Linear], - attr_mapping=pytorch_linear_attr_mapping) - tp.OperationsSetToLayers("AnyReLU", [torch.relu, - ReLU, - ReLU6, - LeakyReLU, - relu, - relu6, - leaky_relu, - tp.LayerFilterParams(Hardtanh, min_val=0), - tp.LayerFilterParams(hardtanh, min_val=0)]) - - tp.OperationsSetToLayers("Add", [operator.add, add]) - tp.OperationsSetToLayers("Sub", [operator.sub, sub]) - tp.OperationsSetToLayers("Mul", [operator.mul, mul]) - tp.OperationsSetToLayers("Div", [operator.truediv, div]) - tp.OperationsSetToLayers("PReLU", [PReLU, prelu]) - tp.OperationsSetToLayers("Swish", [SiLU, silu, Hardswish, hardswish]) - tp.OperationsSetToLayers("Sigmoid", [Sigmoid, sigmoid]) - tp.OperationsSetToLayers("Tanh", [Tanh, tanh]) - - return pytorch_tpc diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v3/tpc_keras.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v3/tpc_keras.py deleted file mode 100644 index 27f79c562..000000000 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v3/tpc_keras.py +++ /dev/null @@ -1,135 +0,0 @@ -# Copyright 2024 Sony Semiconductor Israel, Inc. All rights reserved. -# -# 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. -# ============================================================================== -import tensorflow as tf -from packaging import version - -from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel -from model_compression_toolkit.defaultdict import DefaultDict -from model_compression_toolkit.verify_packages import FOUND_SONY_CUSTOM_LAYERS -from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, KERAS_DEPTHWISE_KERNEL, \ - KERAS_KERNEL, BIAS_ATTR, BIAS - -if FOUND_SONY_CUSTOM_LAYERS: - from sony_custom_layers.keras.object_detection.ssd_post_process import SSDPostProcess - -if version.parse(tf.__version__) >= version.parse("2.13"): - from keras.src.layers import Conv2D, DepthwiseConv2D, Dense, Reshape, ZeroPadding2D, Dropout, \ - MaxPooling2D, Activation, ReLU, Add, Subtract, Multiply, PReLU, Flatten, Cropping2D, LeakyReLU, Permute, \ - Conv2DTranspose, Identity, Concatenate -else: - from keras.layers import Conv2D, DepthwiseConv2D, Dense, Reshape, ZeroPadding2D, Dropout, \ - MaxPooling2D, Activation, ReLU, Add, Subtract, Multiply, PReLU, Flatten, Cropping2D, LeakyReLU, Permute, \ - Conv2DTranspose, Identity, Concatenate - -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v3.tp_model import get_tp_model -import model_compression_toolkit as mct -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v3 import __version__ as TPC_VERSION - -tp = mct.target_platform - - -def get_keras_tpc() -> tp.TargetPlatformCapabilities: - """ - get a Keras TargetPlatformCapabilities object with default operation sets to layers mapping. - - Returns: a Keras TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - imx500_tpc_tp_model = get_tp_model() - return generate_keras_tpc(name='imx500_tpc_keras_tpc', tp_model=imx500_tpc_tp_model) - - -def generate_keras_tpc(name: str, tp_model: TargetPlatformModel): - """ - Generates a TargetPlatformCapabilities object with default operation sets to layers mapping. - - Args: - name: Name of the TargetPlatformCapabilities. - tp_model: TargetPlatformModel object. - - Returns: a TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - - keras_tpc = tp.TargetPlatformCapabilities(tp_model) - - no_quant_list = [Identity, - tf.identity, - Reshape, - tf.reshape, - Permute, - tf.transpose, - Flatten, - Cropping2D, - ZeroPadding2D, - Dropout, - MaxPooling2D, - tf.split, - tf.quantization.fake_quant_with_min_max_vars, - tf.math.argmax, - tf.shape, - tf.math.equal, - tf.gather, - tf.cast, - tf.unstack, - tf.compat.v1.gather, - tf.nn.top_k, - tf.__operators__.getitem, - tf.strided_slice, - tf.image.combined_non_max_suppression, - tf.compat.v1.shape] - - if FOUND_SONY_CUSTOM_LAYERS: - no_quant_list.append(SSDPostProcess) - - with keras_tpc: - tp.OperationsSetToLayers("NoQuantization", no_quant_list) - tp.OperationsSetToLayers("Default16BitInout", [tf.stack, - tf.concat, Concatenate]) - tp.OperationsSetToLayers("Conv", - [Conv2D, - DepthwiseConv2D, - Conv2DTranspose, - tf.nn.conv2d, - tf.nn.depthwise_conv2d, - tf.nn.conv2d_transpose], - # we provide attributes mapping that maps each layer type in the operations set - # that has weights attributes with provided quantization config (in the tp model) to - # its framework-specific attribute name. - # note that a DefaultDict should be provided if not all the layer types in the - # operation set are provided separately in the mapping. - attr_mapping={ - KERNEL_ATTR: DefaultDict({ - DepthwiseConv2D: KERAS_DEPTHWISE_KERNEL, - tf.nn.depthwise_conv2d: KERAS_DEPTHWISE_KERNEL}, default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}) - tp.OperationsSetToLayers("FullyConnected", [Dense], - attr_mapping={KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}) - tp.OperationsSetToLayers("AnyReLU", [tf.nn.relu, - tf.nn.relu6, - tf.nn.leaky_relu, - ReLU, - LeakyReLU, - tp.LayerFilterParams(Activation, activation="relu"), - tp.LayerFilterParams(Activation, activation="leaky_relu")]) - tp.OperationsSetToLayers("Add", [tf.add, Add]) - tp.OperationsSetToLayers("Sub", [tf.subtract, Subtract]) - tp.OperationsSetToLayers("Mul", [tf.math.multiply, Multiply]) - tp.OperationsSetToLayers("Div", [tf.math.divide, tf.math.truediv]) - tp.OperationsSetToLayers("PReLU", [PReLU]) - tp.OperationsSetToLayers("Swish", [tf.nn.swish, tp.LayerFilterParams(Activation, activation="swish")]) - tp.OperationsSetToLayers("Sigmoid", [tf.nn.sigmoid, tp.LayerFilterParams(Activation, activation="sigmoid")]) - tp.OperationsSetToLayers("Tanh", [tf.nn.tanh, tp.LayerFilterParams(Activation, activation="tanh")]) - - return keras_tpc diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v3/tpc_pytorch.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v3/tpc_pytorch.py deleted file mode 100644 index 3f52dfe1e..000000000 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v3/tpc_pytorch.py +++ /dev/null @@ -1,113 +0,0 @@ -# Copyright 2024 Sony Semiconductor Israel, Inc. All rights reserved. -# -# 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. -# ============================================================================== - -import operator - -import torch -from torch import add, sub, mul, div, flatten, reshape, split, unsqueeze, dropout, sigmoid, tanh, chunk, unbind, topk, \ - gather, equal, transpose, permute, argmax, squeeze, multiply, subtract -from torch.nn import Conv2d, Linear, ConvTranspose2d, MaxPool2d -from torch.nn import Dropout, Flatten, Hardtanh, Identity -from torch.nn import ReLU, ReLU6, PReLU, SiLU, Sigmoid, Tanh, Hardswish, LeakyReLU -from torch.nn.functional import relu, relu6, prelu, silu, hardtanh, hardswish, leaky_relu - -from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel -from model_compression_toolkit.defaultdict import DefaultDict -from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, BIAS_ATTR, PYTORCH_KERNEL, \ - BIAS -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v3.tp_model import get_tp_model -import model_compression_toolkit as mct -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v3 import __version__ as TPC_VERSION - -tp = mct.target_platform - - -def get_pytorch_tpc() -> tp.TargetPlatformCapabilities: - """ - get a Pytorch TargetPlatformCapabilities object with default operation sets to layers mapping. - - Returns: a Pytorch TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - imx500_tpc_tp_model = get_tp_model() - return generate_pytorch_tpc(name='imx500_tpc_pytorch_tpc', tp_model=imx500_tpc_tp_model) - - -def generate_pytorch_tpc(name: str, tp_model: TargetPlatformModel): - """ - Generates a TargetPlatformCapabilities object with default operation sets to layers mapping. - Args: - name: Name of the TargetPlatformModel. - tp_model: TargetPlatformModel object. - Returns: a TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - - pytorch_tpc = tp.TargetPlatformCapabilities(tp_model) - - # we provide attributes mapping that maps each layer type in the operations set - # that has weights attributes with provided quantization config (in the tp model) to - # its framework-specific attribute name. - # note that a DefaultDict should be provided if not all the layer types in the - # operation set are provided separately in the mapping. - pytorch_linear_attr_mapping = {KERNEL_ATTR: DefaultDict(default_value=PYTORCH_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)} - - with pytorch_tpc: - tp.OperationsSetToLayers("NoQuantization", [Identity, - Dropout, - Flatten, - dropout, - flatten, - split, - operator.getitem, - reshape, - unsqueeze, - chunk, - unbind, - torch.Tensor.size, - permute, - transpose, - equal, - argmax, - gather, - topk, - squeeze, - MaxPool2d]) - tp.OperationsSetToLayers("Default16BitInout", - [torch.stack, torch.cat, torch.concat, torch.concatenate]) - - tp.OperationsSetToLayers("Conv", [Conv2d, ConvTranspose2d], - attr_mapping=pytorch_linear_attr_mapping) - tp.OperationsSetToLayers("FullyConnected", [Linear], - attr_mapping=pytorch_linear_attr_mapping) - tp.OperationsSetToLayers("AnyReLU", [torch.relu, - ReLU, - ReLU6, - LeakyReLU, - relu, - relu6, - leaky_relu, - tp.LayerFilterParams(Hardtanh, min_val=0), - tp.LayerFilterParams(hardtanh, min_val=0)]) - - tp.OperationsSetToLayers("Add", [operator.add, add]) - tp.OperationsSetToLayers("Sub", [operator.sub, sub, subtract]) - tp.OperationsSetToLayers("Mul", [operator.mul, mul, multiply]) - tp.OperationsSetToLayers("Div", [operator.truediv, div]) - tp.OperationsSetToLayers("PReLU", [PReLU, prelu]) - tp.OperationsSetToLayers("Swish", [SiLU, silu, Hardswish, hardswish]) - tp.OperationsSetToLayers("Sigmoid", [Sigmoid, sigmoid]) - tp.OperationsSetToLayers("Tanh", [Tanh, tanh]) - - return pytorch_tpc diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v3_lut/tpc_keras.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v3_lut/tpc_keras.py deleted file mode 100644 index ffd712a8c..000000000 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v3_lut/tpc_keras.py +++ /dev/null @@ -1,132 +0,0 @@ -# Copyright 2024 Sony Semiconductor Israel, Inc. All rights reserved. -# -# 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. -# ============================================================================== -import tensorflow as tf -from packaging import version - -from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel -from model_compression_toolkit.defaultdict import DefaultDict -from model_compression_toolkit.verify_packages import FOUND_SONY_CUSTOM_LAYERS -from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, KERAS_KERNEL, BIAS_ATTR, \ - KERAS_DEPTHWISE_KERNEL, BIAS - -if FOUND_SONY_CUSTOM_LAYERS: - from sony_custom_layers.keras.object_detection.ssd_post_process import SSDPostProcess - -if version.parse(tf.__version__) >= version.parse("2.13"): - from keras.src.layers import Conv2D, DepthwiseConv2D, Dense, Reshape, ZeroPadding2D, Dropout, \ - MaxPooling2D, Activation, ReLU, Add, Subtract, Multiply, PReLU, Flatten, Cropping2D, LeakyReLU, Permute, \ - Conv2DTranspose, Identity -else: - from keras.layers import Conv2D, DepthwiseConv2D, Dense, Reshape, ZeroPadding2D, Dropout, \ - MaxPooling2D, Activation, ReLU, Add, Subtract, Multiply, PReLU, Flatten, Cropping2D, LeakyReLU, Permute, \ - Conv2DTranspose, Identity - -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v3_lut.tp_model import get_tp_model -import model_compression_toolkit as mct -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v3_lut import __version__ as TPC_VERSION - -tp = mct.target_platform - - -def get_keras_tpc() -> tp.TargetPlatformCapabilities: - """ - get a Keras TargetPlatformCapabilities object with default operation sets to layers mapping. - Returns: a Keras TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - imx500_tpc_tp_model = get_tp_model() - return generate_keras_tpc(name='imx500_tpc_keras_tpc', tp_model=imx500_tpc_tp_model) - - -def generate_keras_tpc(name: str, tp_model: TargetPlatformModel): - """ - Generates a TargetPlatformCapabilities object with default operation sets to layers mapping. - - Args: - name: Name of the TargetPlatformCapabilities. - tp_model: TargetPlatformModel object. - - Returns: a TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - - keras_tpc = tp.TargetPlatformCapabilities(tp_model) - - no_quant_list = [Identity, - tf.identity, - Reshape, - tf.reshape, - Permute, - tf.transpose, - Flatten, - Cropping2D, - ZeroPadding2D, - Dropout, - MaxPooling2D, - tf.split, - tf.quantization.fake_quant_with_min_max_vars, - tf.math.argmax, - tf.shape, - tf.math.equal, - tf.gather, - tf.cast, - tf.unstack, - tf.compat.v1.gather, - tf.nn.top_k, - tf.__operators__.getitem, - tf.image.combined_non_max_suppression, - tf.compat.v1.shape] - - if FOUND_SONY_CUSTOM_LAYERS: - no_quant_list.append(SSDPostProcess) - - with keras_tpc: - tp.OperationsSetToLayers("NoQuantization", no_quant_list) - - tp.OperationsSetToLayers("Conv", - [Conv2D, - DepthwiseConv2D, - Conv2DTranspose, - tf.nn.conv2d, - tf.nn.depthwise_conv2d, - tf.nn.conv2d_transpose], - # we provide attributes mapping that maps each layer type in the operations set - # that has weights attributes with provided quantization config (in the tp model) to - # its framework-specific attribute name. - # note that a DefaultDict should be provided if not all the layer types in the - # operation set are provided separately in the mapping. - attr_mapping={ - KERNEL_ATTR: DefaultDict({ - DepthwiseConv2D: KERAS_DEPTHWISE_KERNEL, - tf.nn.depthwise_conv2d: KERAS_DEPTHWISE_KERNEL}, default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}) - tp.OperationsSetToLayers("FullyConnected", [Dense], - attr_mapping={KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}) - tp.OperationsSetToLayers("AnyReLU", [tf.nn.relu, - tf.nn.relu6, - tf.nn.leaky_relu, - ReLU, - LeakyReLU, - tp.LayerFilterParams(Activation, activation="relu"), - tp.LayerFilterParams(Activation, activation="leaky_relu")]) - tp.OperationsSetToLayers("Add", [tf.add, Add]) - tp.OperationsSetToLayers("Sub", [tf.subtract, Subtract]) - tp.OperationsSetToLayers("Mul", [tf.math.multiply, Multiply]) - tp.OperationsSetToLayers("Div", [tf.math.divide, tf.math.truediv]) - tp.OperationsSetToLayers("PReLU", [PReLU]) - tp.OperationsSetToLayers("Swish", [tf.nn.swish, tp.LayerFilterParams(Activation, activation="swish")]) - tp.OperationsSetToLayers("Sigmoid", [tf.nn.sigmoid, tp.LayerFilterParams(Activation, activation="sigmoid")]) - tp.OperationsSetToLayers("Tanh", [tf.nn.tanh, tp.LayerFilterParams(Activation, activation="tanh")]) - - return keras_tpc diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v3_lut/tpc_pytorch.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v3_lut/tpc_pytorch.py deleted file mode 100644 index 458470bea..000000000 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v3_lut/tpc_pytorch.py +++ /dev/null @@ -1,110 +0,0 @@ -# Copyright 2024 Sony Semiconductor Israel, Inc. All rights reserved. -# -# 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. -# ============================================================================== - -import operator - -import torch -from torch import add, sub, mul, div, flatten, reshape, split, unsqueeze, dropout, sigmoid, tanh, chunk, unbind, topk, \ - gather, equal, transpose, permute, argmax, squeeze -from torch.nn import Conv2d, Linear, ConvTranspose2d, MaxPool2d -from torch.nn import Dropout, Flatten, Hardtanh, Identity -from torch.nn import ReLU, ReLU6, PReLU, SiLU, Sigmoid, Tanh, Hardswish, LeakyReLU -from torch.nn.functional import relu, relu6, prelu, silu, hardtanh, hardswish, leaky_relu - -from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel -from model_compression_toolkit.defaultdict import DefaultDict -from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, PYTORCH_KERNEL, BIAS_ATTR, \ - BIAS -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v3_lut.tp_model import get_tp_model -import model_compression_toolkit as mct -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v3_lut import __version__ as TPC_VERSION - -tp = mct.target_platform - - -def get_pytorch_tpc() -> tp.TargetPlatformCapabilities: - """ - get a Pytorch TargetPlatformCapabilities object with default operation sets to layers mapping. - Returns: a Pytorch TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - imx500_tpc_tp_model = get_tp_model() - return generate_pytorch_tpc(name='imx500_tpc_pytorch_tpc', tp_model=imx500_tpc_tp_model) - - -def generate_pytorch_tpc(name: str, tp_model: TargetPlatformModel): - """ - Generates a TargetPlatformCapabilities object with default operation sets to layers mapping. - Args: - name: Name of the TargetPlatformModel. - tp_model: TargetPlatformModel object. - Returns: a TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - - pytorch_tpc = tp.TargetPlatformCapabilities(tp_model) - - # we provide attributes mapping that maps each layer type in the operations set - # that has weights attributes with provided quantization config (in the tp model) to - # its framework-specific attribute name. - # note that a DefaultDict should be provided if not all the layer types in the - # operation set are provided separately in the mapping. - pytorch_linear_attr_mapping = {KERNEL_ATTR: DefaultDict(default_value=PYTORCH_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)} - - with pytorch_tpc: - tp.OperationsSetToLayers("NoQuantization", [Identity, - Dropout, - Flatten, - dropout, - flatten, - split, - operator.getitem, - reshape, - unsqueeze, - chunk, - unbind, - torch.Tensor.size, - permute, - transpose, - equal, - argmax, - gather, - topk, - squeeze, - MaxPool2d]) - - tp.OperationsSetToLayers("Conv", [Conv2d, ConvTranspose2d], - attr_mapping=pytorch_linear_attr_mapping) - tp.OperationsSetToLayers("FullyConnected", [Linear], - attr_mapping=pytorch_linear_attr_mapping) - tp.OperationsSetToLayers("AnyReLU", [torch.relu, - ReLU, - ReLU6, - LeakyReLU, - relu, - relu6, - leaky_relu, - tp.LayerFilterParams(Hardtanh, min_val=0), - tp.LayerFilterParams(hardtanh, min_val=0)]) - - tp.OperationsSetToLayers("Add", [operator.add, add]) - tp.OperationsSetToLayers("Sub", [operator.sub, sub]) - tp.OperationsSetToLayers("Mul", [operator.mul, mul]) - tp.OperationsSetToLayers("Div", [operator.truediv, div]) - tp.OperationsSetToLayers("PReLU", [PReLU, prelu]) - tp.OperationsSetToLayers("Swish", [SiLU, silu, Hardswish, hardswish]) - tp.OperationsSetToLayers("Sigmoid", [Sigmoid, sigmoid]) - tp.OperationsSetToLayers("Tanh", [Tanh, tanh]) - - return pytorch_tpc diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v4/tpc_keras.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v4/tpc_keras.py deleted file mode 100644 index 37d4d9657..000000000 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v4/tpc_keras.py +++ /dev/null @@ -1,140 +0,0 @@ -# Copyright 2024 Sony Semiconductor Israel, Inc. All rights reserved. -# -# 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. -# ============================================================================== -import tensorflow as tf -from packaging import version - -import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema -from model_compression_toolkit.defaultdict import DefaultDict -from model_compression_toolkit.verify_packages import FOUND_SONY_CUSTOM_LAYERS -from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, KERAS_DEPTHWISE_KERNEL, \ - KERAS_KERNEL, BIAS_ATTR, BIAS - -if FOUND_SONY_CUSTOM_LAYERS: - from sony_custom_layers.keras.object_detection.ssd_post_process import SSDPostProcess - -if version.parse(tf.__version__) >= version.parse("2.13"): - from keras.src.layers import Conv2D, DepthwiseConv2D, Dense, Reshape, ZeroPadding2D, Dropout, \ - MaxPooling2D, Activation, ReLU, Add, Subtract, Multiply, PReLU, Flatten, Cropping2D, LeakyReLU, Permute, \ - Conv2DTranspose, Identity, Concatenate, BatchNormalization, Minimum, Maximum -else: - from keras.layers import Conv2D, DepthwiseConv2D, Dense, Reshape, ZeroPadding2D, Dropout, \ - MaxPooling2D, Activation, ReLU, Add, Subtract, Multiply, PReLU, Flatten, Cropping2D, LeakyReLU, Permute, \ - Conv2DTranspose, Identity, Concatenate, BatchNormalization, Minimum, Maximum - -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v4.tp_model import get_tp_model -import model_compression_toolkit as mct -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v4 import __version__ as TPC_VERSION -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v4.tp_model import OPSET_NO_QUANTIZATION, \ - OPSET_QUANTIZATION_PRESERVING, OPSET_DIMENSION_MANIPULATION_OPS_WITH_WEIGHTS, OPSET_DIMENSION_MANIPULATION_OPS, \ - OPSET_MERGE_OPS, OPSET_CONV, OPSET_FULLY_CONNECTED, OPSET_ANY_RELU, OPSET_ADD, OPSET_SUB, OPSET_MUL, OPSET_DIV, \ - OPSET_PRELU, OPSET_SWISH, OPSET_SIGMOID, OPSET_TANH, OPSET_GELU, OPSET_BATCH_NORM, OPSET_MIN_MAX, OPSET_HARDSIGMOID, \ - OPSET_SPLIT_OPS - -tp = mct.target_platform - - -def get_keras_tpc() -> tp.TargetPlatformCapabilities: - """ - get a Keras TargetPlatformCapabilities object with default operation sets to layers mapping. - - Returns: a Keras TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - imx500_tpc_tp_model = get_tp_model() - return generate_keras_tpc(name='imx500_tpc_keras_tpc', tp_model=imx500_tpc_tp_model) - - -def generate_keras_tpc(name: str, tp_model: schema.TargetPlatformModel): - """ - Generates a TargetPlatformCapabilities object with default operation sets to layers mapping. - - Args: - name: Name of the TargetPlatformCapabilities. - tp_model: TargetPlatformModel object. - - Returns: a TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - - keras_tpc = tp.TargetPlatformCapabilities(tp_model) - - no_quant_list = [tf.quantization.fake_quant_with_min_max_vars, - tf.math.argmax, - tf.shape, - tf.math.equal, - tf.nn.top_k, - tf.image.combined_non_max_suppression, - tf.compat.v1.shape] - quantization_preserving = [Cropping2D, - ZeroPadding2D, - Dropout, - MaxPooling2D, - tf.cast] - quantization_preserving_list_16bit_input = [Reshape, - tf.reshape, - Permute, - tf.transpose, - Flatten] - - if FOUND_SONY_CUSTOM_LAYERS: - no_quant_list.append(SSDPostProcess) - - with keras_tpc: - tp.OperationsSetToLayers(OPSET_NO_QUANTIZATION, no_quant_list) - tp.OperationsSetToLayers(OPSET_QUANTIZATION_PRESERVING, quantization_preserving) - tp.OperationsSetToLayers(OPSET_DIMENSION_MANIPULATION_OPS, quantization_preserving_list_16bit_input) - tp.OperationsSetToLayers(OPSET_DIMENSION_MANIPULATION_OPS_WITH_WEIGHTS, [tf.gather, tf.compat.v1.gather]) - tp.OperationsSetToLayers(OPSET_SPLIT_OPS,[tf.unstack, tf.split, tf.strided_slice, tf.__operators__.getitem]) - tp.OperationsSetToLayers(OPSET_MERGE_OPS, [tf.stack, tf.concat, Concatenate]) - tp.OperationsSetToLayers(OPSET_CONV, - [Conv2D, - DepthwiseConv2D, - Conv2DTranspose, - tf.nn.conv2d, - tf.nn.depthwise_conv2d, - tf.nn.conv2d_transpose], - # we provide attributes mapping that maps each layer type in the operations set - # that has weights attributes with provided quantization config (in the tp model) to - # its framework-specific attribute name. - # note that a DefaultDict should be provided if not all the layer types in the - # operation set are provided separately in the mapping. - attr_mapping={ - KERNEL_ATTR: DefaultDict({ - DepthwiseConv2D: KERAS_DEPTHWISE_KERNEL, - tf.nn.depthwise_conv2d: KERAS_DEPTHWISE_KERNEL}, default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}) - tp.OperationsSetToLayers(OPSET_FULLY_CONNECTED, [Dense], - attr_mapping={KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}) - tp.OperationsSetToLayers(OPSET_BATCH_NORM, [BatchNormalization]) - tp.OperationsSetToLayers(OPSET_ANY_RELU, [tf.nn.relu, - tf.nn.relu6, - tf.nn.leaky_relu, - ReLU, - LeakyReLU, - tp.LayerFilterParams(Activation, activation="relu"), - tp.LayerFilterParams(Activation, activation="leaky_relu")]) - tp.OperationsSetToLayers(OPSET_ADD, [tf.add, Add]) - tp.OperationsSetToLayers(OPSET_SUB, [tf.subtract, Subtract]) - tp.OperationsSetToLayers(OPSET_MUL, [tf.math.multiply, Multiply]) - tp.OperationsSetToLayers(OPSET_DIV, [tf.math.divide, tf.math.truediv]) - tp.OperationsSetToLayers(OPSET_MIN_MAX, [tf.math.minimum, tf.math.maximum, Minimum, Maximum]) - tp.OperationsSetToLayers(OPSET_PRELU, [PReLU]) - tp.OperationsSetToLayers(OPSET_SWISH, [tf.nn.swish, tp.LayerFilterParams(Activation, activation="swish")]) - tp.OperationsSetToLayers(OPSET_SIGMOID, [tf.nn.sigmoid, tp.LayerFilterParams(Activation, activation="sigmoid")]) - tp.OperationsSetToLayers(OPSET_TANH, [tf.nn.tanh, tp.LayerFilterParams(Activation, activation="tanh")]) - tp.OperationsSetToLayers(OPSET_GELU, [tf.nn.gelu, tp.LayerFilterParams(Activation, activation="gelu")]) - tp.OperationsSetToLayers(OPSET_HARDSIGMOID, [tf.keras.activations.hard_sigmoid, - tp.LayerFilterParams(Activation, activation="hard_sigmoid")]) - - return keras_tpc diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v4/tpc_pytorch.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v4/tpc_pytorch.py deleted file mode 100644 index aaf62d8a6..000000000 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v4/tpc_pytorch.py +++ /dev/null @@ -1,122 +0,0 @@ -# Copyright 2024 Sony Semiconductor Israel, Inc. All rights reserved. -# -# 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. -# ============================================================================== - -import operator - -import torch -from torch import add, sub, mul, div, divide, flatten, reshape, split, unsqueeze, dropout, sigmoid, tanh, \ - chunk, unbind, topk, gather, equal, transpose, permute, argmax, squeeze, multiply, subtract, minimum, \ - maximum -from torch.nn import Conv2d, Linear, ConvTranspose2d, MaxPool2d, BatchNorm2d -from torch.nn import Dropout, Flatten, Hardtanh -from torch.nn import ReLU, ReLU6, PReLU, SiLU, Sigmoid, Tanh, Hardswish, Hardsigmoid, LeakyReLU, GELU -import torch.nn.functional as F -from torch.nn.functional import relu, relu6, prelu, silu, hardtanh, hardswish, hardsigmoid, leaky_relu, gelu - -import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema -from model_compression_toolkit.defaultdict import DefaultDict -from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, BIAS_ATTR, PYTORCH_KERNEL, \ - BIAS -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v4.tp_model import get_tp_model -import model_compression_toolkit as mct -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v4 import __version__ as TPC_VERSION -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v4.tp_model import OPSET_NO_QUANTIZATION, \ - OPSET_QUANTIZATION_PRESERVING, OPSET_DIMENSION_MANIPULATION_OPS_WITH_WEIGHTS, OPSET_DIMENSION_MANIPULATION_OPS, \ - OPSET_MERGE_OPS, OPSET_CONV, OPSET_FULLY_CONNECTED, OPSET_ANY_RELU, OPSET_ADD, OPSET_SUB, OPSET_MUL, OPSET_DIV, \ - OPSET_PRELU, OPSET_SWISH, OPSET_SIGMOID, OPSET_TANH, OPSET_GELU, OPSET_BATCH_NORM, OPSET_MIN_MAX, OPSET_HARDSIGMOID, \ - OPSET_HARDSWISH, OPSET_SPLIT_OPS - -tp = mct.target_platform - - -def get_pytorch_tpc() -> tp.TargetPlatformCapabilities: - """ - get a Pytorch TargetPlatformCapabilities object with default operation sets to layers mapping. - - Returns: a Pytorch TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - imx500_tpc_tp_model = get_tp_model() - return generate_pytorch_tpc(name='imx500_tpc_pytorch_tpc', tp_model=imx500_tpc_tp_model) - - -def generate_pytorch_tpc(name: str, tp_model: schema.TargetPlatformModel): - """ - Generates a TargetPlatformCapabilities object with default operation sets to layers mapping. - Args: - name: Name of the TargetPlatformModel. - tp_model: TargetPlatformModel object. - Returns: a TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - - pytorch_tpc = tp.TargetPlatformCapabilities(tp_model) - - # we provide attributes mapping that maps each layer type in the operations set - # that has weights attributes with provided quantization config (in the tp model) to - # its framework-specific attribute name. - # note that a DefaultDict should be provided if not all the layer types in the - # operation set are provided separately in the mapping. - pytorch_linear_attr_mapping = {KERNEL_ATTR: DefaultDict(default_value=PYTORCH_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)} - - with pytorch_tpc: - tp.OperationsSetToLayers(OPSET_NO_QUANTIZATION, [torch.Tensor.size, - equal, - argmax, - topk]) - tp.OperationsSetToLayers(OPSET_QUANTIZATION_PRESERVING, [Dropout, - dropout, - MaxPool2d]) - tp.OperationsSetToLayers(OPSET_DIMENSION_MANIPULATION_OPS, [Flatten, - flatten, - operator.getitem, - reshape, - unsqueeze, - squeeze, - permute, - transpose]) - tp.OperationsSetToLayers(OPSET_DIMENSION_MANIPULATION_OPS_WITH_WEIGHTS, [gather, torch.Tensor.expand]) - tp.OperationsSetToLayers(OPSET_SPLIT_OPS,[split, chunk, unbind]) - tp.OperationsSetToLayers(OPSET_MERGE_OPS, - [torch.stack, torch.cat, torch.concat, torch.concatenate]) - - tp.OperationsSetToLayers(OPSET_CONV, [Conv2d, ConvTranspose2d], - attr_mapping=pytorch_linear_attr_mapping) - tp.OperationsSetToLayers(OPSET_FULLY_CONNECTED, [Linear], - attr_mapping=pytorch_linear_attr_mapping) - tp.OperationsSetToLayers(OPSET_BATCH_NORM, [BatchNorm2d]) - tp.OperationsSetToLayers(OPSET_ANY_RELU, [torch.relu, - ReLU, - ReLU6, - LeakyReLU, - relu, - relu6, - leaky_relu, - tp.LayerFilterParams(Hardtanh, min_val=0), - tp.LayerFilterParams(hardtanh, min_val=0)]) - - tp.OperationsSetToLayers(OPSET_ADD, [operator.add, add]) - tp.OperationsSetToLayers(OPSET_SUB, [operator.sub, sub, subtract]) - tp.OperationsSetToLayers(OPSET_MUL, [operator.mul, mul, multiply]) - tp.OperationsSetToLayers(OPSET_DIV, [operator.truediv, div, divide]) - tp.OperationsSetToLayers(OPSET_MIN_MAX, [minimum, maximum]) - tp.OperationsSetToLayers(OPSET_PRELU, [PReLU, prelu]) - tp.OperationsSetToLayers(OPSET_SWISH, [SiLU, silu]) - tp.OperationsSetToLayers(OPSET_SIGMOID, [Sigmoid, sigmoid, F.sigmoid]) - tp.OperationsSetToLayers(OPSET_TANH, [Tanh, tanh, F.tanh]) - tp.OperationsSetToLayers(OPSET_GELU, [GELU, gelu]) - tp.OperationsSetToLayers(OPSET_HARDSIGMOID, [Hardsigmoid, hardsigmoid]) - tp.OperationsSetToLayers(OPSET_HARDSWISH, [Hardswish, hardswish]) - - return pytorch_tpc diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/qnnpack_tpc/latest/__init__.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/qnnpack_tpc/latest/__init__.py index 6cd964f0e..a35f93d7e 100644 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/qnnpack_tpc/latest/__init__.py +++ b/model_compression_toolkit/target_platform_capabilities/tpc_models/qnnpack_tpc/latest/__init__.py @@ -15,8 +15,12 @@ from model_compression_toolkit.verify_packages import FOUND_TORCH, FOUND_TF from model_compression_toolkit.target_platform_capabilities.tpc_models.qnnpack_tpc.v1.tp_model import get_tp_model, generate_tp_model, get_op_quantization_configs if FOUND_TF: - from model_compression_toolkit.target_platform_capabilities.tpc_models.qnnpack_tpc.v1.tpc_keras import get_keras_tpc as get_keras_tpc_latest - from model_compression_toolkit.target_platform_capabilities.tpc_models.qnnpack_tpc.v1.tpc_keras import generate_keras_tpc + from model_compression_toolkit.target_platform_capabilities.tpc_models.qnnpack_tpc.v1.tp_model import get_tp_model as \ + get_keras_tpc_latest + from model_compression_toolkit.target_platform_capabilities.tpc_models.get_target_platform_capabilities import \ + get_tpc_model as generate_keras_tpc, get_tpc_model as generate_keras_tpc if FOUND_TORCH: - from model_compression_toolkit.target_platform_capabilities.tpc_models.qnnpack_tpc.v1.tpc_pytorch import get_pytorch_tpc as get_pytorch_tpc_latest - from model_compression_toolkit.target_platform_capabilities.tpc_models.qnnpack_tpc.v1.tpc_pytorch import generate_pytorch_tpc \ No newline at end of file + from model_compression_toolkit.target_platform_capabilities.tpc_models.qnnpack_tpc.v1.tp_model import get_tp_model as \ + get_pytorch_tpc_latest + from model_compression_toolkit.target_platform_capabilities.tpc_models.get_target_platform_capabilities import \ + get_tpc_model as generate_pytorch_tpc, get_tpc_model as generate_pytorch_tpc diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/qnnpack_tpc/target_platform_capabilities.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/qnnpack_tpc/target_platform_capabilities.py deleted file mode 100644 index ac68c99ce..000000000 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/qnnpack_tpc/target_platform_capabilities.py +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright 2022 Sony Semiconductor Israel, Inc. All rights reserved. -# -# 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 model_compression_toolkit.constants import TENSORFLOW, PYTORCH -from model_compression_toolkit.verify_packages import FOUND_TORCH, FOUND_TF -from model_compression_toolkit.logger import Logger -from model_compression_toolkit.target_platform_capabilities.constants import LATEST - -def get_tpc_dict_by_fw(fw_name): - tpc_models_dict = None - if fw_name == TENSORFLOW: - ############################### - # Build Tensorflow TPC models - ############################### - if FOUND_TF: - from model_compression_toolkit.target_platform_capabilities.tpc_models.qnnpack_tpc.v1.tpc_keras import \ - get_keras_tpc as get_keras_tpc_v1 - from model_compression_toolkit.target_platform_capabilities.tpc_models.qnnpack_tpc.latest import \ - get_keras_tpc_latest - - # Keras: TPC versioning - tpc_models_dict = {'v1': get_keras_tpc_v1, - LATEST: get_keras_tpc_latest} - elif fw_name == PYTORCH: - ############################### - # Build Pytorch TPC models - ############################### - if FOUND_TORCH: - from model_compression_toolkit.target_platform_capabilities.tpc_models.qnnpack_tpc.v1.tpc_pytorch import \ - get_pytorch_tpc as get_pytorch_tpc_v1 - from model_compression_toolkit.target_platform_capabilities.tpc_models.qnnpack_tpc.latest import \ - get_pytorch_tpc_latest - - # Pytorch: TPC versioning - tpc_models_dict = {'v1': get_pytorch_tpc_v1, - LATEST: get_pytorch_tpc_latest} - if tpc_models_dict is not None: - return tpc_models_dict - else: - Logger.critical(f'Framework {fw_name} is not supported in imx500 or the relevant packages are not ' - f'installed. Please make sure the relevant packages are installed when using MCT for optimizing' - f' a {fw_name} model. For Tensorflow, please install tensorflow. For PyTorch, please install ' - f'torch.') # pragma: no cover diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/qnnpack_tpc/v1/tp_model.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/qnnpack_tpc/v1/tp_model.py index 58fd8b9d2..6ac1bc040 100644 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/qnnpack_tpc/v1/tp_model.py +++ b/model_compression_toolkit/target_platform_capabilities/tpc_models/qnnpack_tpc/v1/tp_model.py @@ -148,19 +148,29 @@ def generate_tp_model(default_config: OpQuantizationConfig, operator_set = [] fusing_patterns = [] - conv = schema.OperatorsSet(name="Conv") - batchnorm = schema.OperatorsSet(name="BatchNorm") - relu = schema.OperatorsSet(name="Relu") - linear = schema.OperatorsSet(name="Linear") + conv = schema.OperatorsSet(name=schema.OperatorSetNames.CONV) + conv_depthwise = schema.OperatorsSet(name=schema.OperatorSetNames.DEPTHWISE_CONV) + conv_transpose = schema.OperatorsSet(name=schema.OperatorSetNames.CONV_TRANSPOSE) + batchnorm = schema.OperatorsSet(name=schema.OperatorSetNames.BATCH_NORM) + relu = schema.OperatorsSet(name=schema.OperatorSetNames.RELU) + relu6 = schema.OperatorsSet(name=schema.OperatorSetNames.RELU6) + + hard_tanh = schema.OperatorsSet(name=schema.OperatorSetNames.HARD_TANH) + linear = schema.OperatorsSet(name=schema.OperatorSetNames.FULLY_CONNECTED) + + operator_set.extend([conv, conv_depthwise, conv_transpose, batchnorm, relu, relu6, hard_tanh, linear]) + + conv_opset_concat = schema.OperatorSetConcat(operators_set=[conv, conv_transpose]) + relu_opset_concat = schema.OperatorSetConcat(operators_set=[relu, relu6, hard_tanh]) - operator_set.extend([conv, batchnorm, relu, linear]) # ------------------- # # Fusions # ------------------- # - fusing_patterns.append(schema.Fusing(operator_groups=(conv, batchnorm, relu))) - fusing_patterns.append(schema.Fusing(operator_groups=(conv, batchnorm))) - fusing_patterns.append(schema.Fusing(operator_groups=(conv, relu))) - fusing_patterns.append(schema.Fusing(operator_groups=(linear, relu))) + fusing_patterns.append(schema.Fusing(operator_groups=(conv_opset_concat, batchnorm, relu_opset_concat))) + fusing_patterns.append(schema.Fusing(operator_groups=(conv_opset_concat, batchnorm))) + fusing_patterns.append(schema.Fusing(operator_groups=(conv_opset_concat, relu_opset_concat))) + fusing_patterns.append(schema.Fusing(operator_groups=(linear, relu_opset_concat))) + # Create a TargetPlatformModel and set its default quantization config. # This default configuration will be used for all operations # unless specified otherwise (see OperatorsSet, for example): diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/qnnpack_tpc/v1/tpc_keras.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/qnnpack_tpc/v1/tpc_keras.py deleted file mode 100644 index 73c6dd1f8..000000000 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/qnnpack_tpc/v1/tpc_keras.py +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright 2022 Sony Semiconductor Israel, Inc. All rights reserved. -# -# 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. -# ============================================================================== -import tensorflow as tf - -from packaging import version - -import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema -from model_compression_toolkit.defaultdict import DefaultDict -from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, KERAS_KERNEL, BIAS_ATTR, \ - KERAS_DEPTHWISE_KERNEL, BIAS -from model_compression_toolkit.target_platform_capabilities.tpc_models.qnnpack_tpc.v1 import __version__ as TPC_VERSION - -if version.parse(tf.__version__) >= version.parse("2.13"): - from keras.src.layers import Conv2D, DepthwiseConv2D, Conv2DTranspose, Dense, BatchNormalization, ReLU, Activation -else: - from keras.layers import Conv2D, DepthwiseConv2D, Conv2DTranspose, Dense, BatchNormalization, ReLU, Activation - -from model_compression_toolkit.target_platform_capabilities.tpc_models.qnnpack_tpc.v1.tp_model import get_tp_model -import model_compression_toolkit as mct - -tp = mct.target_platform - - -def get_keras_tpc() -> tp.TargetPlatformCapabilities: - """ - get a Keras TargetPlatformCapabilities object with default operation sets to layers mapping. - Returns: a Keras TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - qnnpack_tp_model = get_tp_model() - return generate_keras_tpc(name='qnnpack_keras', tp_model=qnnpack_tp_model) - - -def generate_keras_tpc(name: str, tp_model: schema.TargetPlatformModel): - """ - Generates a TargetPlatformCapabilities object with default operation sets to layers mapping. - - Args: - name: Name of the TargetPlatformCapabilities. - tp_model: TargetPlatformModel object. - - Returns: a TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - - keras_tpc = tp.TargetPlatformCapabilities(tp_model) - - with keras_tpc: - tp.OperationsSetToLayers("Conv", - [Conv2D, - DepthwiseConv2D, - Conv2DTranspose, - tf.nn.conv2d, - tf.nn.depthwise_conv2d, - tf.nn.conv2d_transpose], - # we provide attributes mapping that maps each layer type in the operations set - # that has weights attributes with provided quantization config (in the tp model) to - # its framework-specific attribute name. - # note that a DefaultDict should be provided if not all the layer types in the - # operation set are provided separately in the mapping. - attr_mapping={ - KERNEL_ATTR: DefaultDict({ - DepthwiseConv2D: KERAS_DEPTHWISE_KERNEL, - tf.nn.depthwise_conv2d: KERAS_DEPTHWISE_KERNEL}, default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}) - - tp.OperationsSetToLayers("Linear", [Dense], - attr_mapping={KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}) - - tp.OperationsSetToLayers("BatchNorm", [BatchNormalization, - tf.nn.batch_normalization]) - - tp.OperationsSetToLayers("Relu", [tf.nn.relu, - tf.nn.relu6, - tp.LayerFilterParams(ReLU, negative_slope=0.0), - tp.LayerFilterParams(Activation, activation="relu")]) - - return keras_tpc diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/qnnpack_tpc/v1/tpc_pytorch.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/qnnpack_tpc/v1/tpc_pytorch.py deleted file mode 100644 index f1a0e39ef..000000000 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/qnnpack_tpc/v1/tpc_pytorch.py +++ /dev/null @@ -1,78 +0,0 @@ -# Copyright 2022 Sony Semiconductor Israel, Inc. All rights reserved. -# -# 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. -# ============================================================================== -import torch -from torch.nn import Conv2d, Linear, BatchNorm2d, ConvTranspose2d, Hardtanh, ReLU, ReLU6 -from torch.nn.functional import relu, relu6, hardtanh - -import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema -from model_compression_toolkit.defaultdict import DefaultDict -from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, PYTORCH_KERNEL, BIAS_ATTR, \ - BIAS -from model_compression_toolkit.target_platform_capabilities.tpc_models.qnnpack_tpc.v1.tp_model import get_tp_model -import model_compression_toolkit as mct -from model_compression_toolkit.target_platform_capabilities.tpc_models.qnnpack_tpc.v1 import __version__ as TPC_VERSION - -tp = mct.target_platform - - -def get_pytorch_tpc() -> tp.TargetPlatformCapabilities: - """ - get a Pytorch TargetPlatformCapabilities object with default operation sets to layers mapping. - Returns: a Pytorch TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - qnnpack_pytorch = get_tp_model() - return generate_pytorch_tpc(name='qnnpack_pytorch', tp_model=qnnpack_pytorch) - - -def generate_pytorch_tpc(name: str, tp_model: schema.TargetPlatformModel): - """ - Generates a TargetPlatformCapabilities object with default operation sets to layers mapping. - Args: - name: Name of the TargetPlatformModel. - tp_model: TargetPlatformModel object. - Returns: a TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - - pytorch_tpc = tp.TargetPlatformCapabilities(tp_model) - - # we provide attributes mapping that maps each layer type in the operations set - # that has weights attributes with provided quantization config (in the tp model) to - # its framework-specific attribute name. - # note that a DefaultDict should be provided if not all the layer types in the - # operation set are provided separately in the mapping. - pytorch_linear_attr_mapping = {KERNEL_ATTR: DefaultDict(default_value=PYTORCH_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)} - - with pytorch_tpc: - tp.OperationsSetToLayers("Conv", [Conv2d, - torch.nn.functional.conv2d, - ConvTranspose2d, - torch.nn.functional.conv_transpose2d], - attr_mapping=pytorch_linear_attr_mapping) - - tp.OperationsSetToLayers("Linear", [Linear], - attr_mapping=pytorch_linear_attr_mapping) - - tp.OperationsSetToLayers("BatchNorm", [BatchNorm2d]) - - tp.OperationsSetToLayers("Relu", [torch.relu, - ReLU, - ReLU6, - relu, - relu6, - tp.LayerFilterParams(Hardtanh, min_val=0), - tp.LayerFilterParams(hardtanh, min_val=0)]) - - return pytorch_tpc diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/tflite_tpc/latest/__init__.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/tflite_tpc/latest/__init__.py index 050d84ec8..6525c6aa6 100644 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/tflite_tpc/latest/__init__.py +++ b/model_compression_toolkit/target_platform_capabilities/tpc_models/tflite_tpc/latest/__init__.py @@ -15,8 +15,11 @@ from model_compression_toolkit.verify_packages import FOUND_TORCH, FOUND_TF from model_compression_toolkit.target_platform_capabilities.tpc_models.tflite_tpc.v1.tp_model import get_tp_model, generate_tp_model, get_op_quantization_configs if FOUND_TF: - from model_compression_toolkit.target_platform_capabilities.tpc_models.tflite_tpc.v1.tpc_keras import get_keras_tpc as get_keras_tpc_latest - from model_compression_toolkit.target_platform_capabilities.tpc_models.tflite_tpc.v1.tpc_keras import generate_keras_tpc + from model_compression_toolkit.target_platform_capabilities.tpc_models.tflite_tpc.v1.tp_model import get_keras_tpc as get_keras_tpc_latest + from model_compression_toolkit.target_platform_capabilities.tpc_models.get_target_platform_capabilities import \ + get_tpc_model as generate_keras_tpc if FOUND_TORCH: - from model_compression_toolkit.target_platform_capabilities.tpc_models.tflite_tpc.v1.tpc_pytorch import get_pytorch_tpc as get_pytorch_tpc_latest - from model_compression_toolkit.target_platform_capabilities.tpc_models.tflite_tpc.v1.tpc_pytorch import generate_pytorch_tpc \ No newline at end of file + from model_compression_toolkit.target_platform_capabilities.tpc_models.tflite_tpc.v1.tp_model import \ + get_tp_model as get_pytorch_tpc_latest + from model_compression_toolkit.target_platform_capabilities.tpc_models.get_target_platform_capabilities import \ + get_tpc_model as generate_pytorch_tpc \ No newline at end of file diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/tflite_tpc/target_platform_capabilities.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/tflite_tpc/target_platform_capabilities.py deleted file mode 100644 index baa35e036..000000000 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/tflite_tpc/target_platform_capabilities.py +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright 2022 Sony Semiconductor Israel, Inc. All rights reserved. -# -# 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 model_compression_toolkit.constants import TENSORFLOW, PYTORCH -from model_compression_toolkit.verify_packages import FOUND_TORCH, FOUND_TF -from model_compression_toolkit.logger import Logger -from model_compression_toolkit.target_platform_capabilities.constants import LATEST - -def get_tpc_dict_by_fw(fw_name): - tpc_models_dict = None - if fw_name == TENSORFLOW: - ############################### - # Build Tensorflow TPC models - ############################### - if FOUND_TF: - from model_compression_toolkit.target_platform_capabilities.tpc_models.tflite_tpc.v1.tpc_keras import \ - get_keras_tpc as get_keras_tpc_v1 - from model_compression_toolkit.target_platform_capabilities.tpc_models.tflite_tpc.latest import \ - get_keras_tpc_latest - - # Keras: TPC versioning - tpc_models_dict = {'v1': get_keras_tpc_v1, - LATEST: get_keras_tpc_latest} - elif fw_name == PYTORCH: - ############################### - # Build Pytorch TPC models - ############################### - if FOUND_TORCH: - from model_compression_toolkit.target_platform_capabilities.tpc_models.tflite_tpc.v1.tpc_pytorch import \ - get_pytorch_tpc as get_pytorch_tpc_v1 - from model_compression_toolkit.target_platform_capabilities.tpc_models.tflite_tpc.latest import \ - get_pytorch_tpc_latest - - # Pytorch: TPC versioning - tpc_models_dict = {'v1': get_pytorch_tpc_v1, - LATEST: get_pytorch_tpc_latest} - if tpc_models_dict is not None: - return tpc_models_dict - else: - Logger.critical(f'Framework {fw_name} is not supported in imx500 or the relevant packages are not ' - f'installed. Please make sure the relevant packages are installed when using MCT for optimizing' - f' a {fw_name} model. For Tensorflow, please install tensorflow. For PyTorch, please install ' - f'torch.') # pragma: no cover diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/tflite_tpc/v1/tp_model.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/tflite_tpc/v1/tp_model.py index 0f2cd571e..965695dc3 100644 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/tflite_tpc/v1/tp_model.py +++ b/model_compression_toolkit/target_platform_capabilities/tpc_models/tflite_tpc/v1/tp_model.py @@ -18,8 +18,7 @@ import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema from model_compression_toolkit.constants import FLOAT_BITWIDTH from model_compression_toolkit.target_platform_capabilities.constants import BIAS_ATTR, KERNEL_ATTR, TFLITE_TP_MODEL -from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel, \ - Signedness, \ +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel, Signedness, \ AttributeQuantizationConfig, OpQuantizationConfig tp = mct.target_platform @@ -137,8 +136,7 @@ def generate_tp_model(default_config: OpQuantizationConfig, # of possible configurations to consider when quantizing a set of operations (in mixed-precision, for example). # If the QuantizationConfigOptions contains only one configuration, # this configuration will be used for the operation quantization: - default_configuration_options = schema.QuantizationConfigOptions( - quantization_configurations=tuple([default_config])) + default_configuration_options = schema.QuantizationConfigOptions(quantization_configurations=tuple([default_config])) # In TFLite, the quantized operator specifications constraint operators quantization # differently. For more details: @@ -146,44 +144,60 @@ def generate_tp_model(default_config: OpQuantizationConfig, operator_set = [] fusing_patterns = [] - operator_set.append(schema.OperatorsSet(name="NoQuantization", - qc_options=default_configuration_options.clone_and_edit( - quantization_preserving=True))) - - fc = schema.OperatorsSet(name="FullyConnected", - qc_options=default_configuration_options.clone_and_edit_weight_attribute( - weights_per_channel_threshold=False)) - - operator_set.append(schema.OperatorsSet(name="L2Normalization", + quant_preserving = default_configuration_options.clone_and_edit(quantization_preserving=True) + + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.UNSTACK, qc_options=quant_preserving)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.TRANSPOSE, qc_options=quant_preserving)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.GATHER, qc_options=quant_preserving)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.RESHAPE, qc_options=quant_preserving)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.MAXPOOL, qc_options=quant_preserving)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.AVGPOOL, qc_options=quant_preserving)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.STRIDED_SLICE, qc_options=quant_preserving)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.CONCATENATE, qc_options=quant_preserving)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.MUL, qc_options=quant_preserving)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.MIN, qc_options=quant_preserving)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.MAX, qc_options=quant_preserving)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.ZERO_PADDING2D, qc_options=quant_preserving)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.RESIZE, qc_options=quant_preserving)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.PAD, qc_options=quant_preserving)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.FOLD, qc_options=quant_preserving)) + + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.L2NORM, qc_options=default_configuration_options.clone_and_edit( fixed_zero_point=0, fixed_scale=1 / 128))) - operator_set.append(schema.OperatorsSet(name="LogSoftmax", + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.LOG_SOFTMAX, qc_options=default_configuration_options.clone_and_edit( fixed_zero_point=127, fixed_scale=16 / 256))) - operator_set.append(schema.OperatorsSet(name="Tanh", - qc_options=default_configuration_options.clone_and_edit( - fixed_zero_point=0, fixed_scale=1 / 128))) - operator_set.append(schema.OperatorsSet(name="Softmax", - qc_options=default_configuration_options.clone_and_edit( - fixed_zero_point=-128, fixed_scale=1 / 256))) - operator_set.append(schema.OperatorsSet(name="Logistic", + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SOFTMAX, qc_options=default_configuration_options.clone_and_edit( fixed_zero_point=-128, fixed_scale=1 / 256))) - conv2d = schema.OperatorsSet(name="Conv2d") - kernel = schema.OperatorSetConcat(operators_set=[conv2d, fc]) + sigmoid = schema.OperatorsSet(name=schema.OperatorSetNames.SIGMOID, + qc_options=default_configuration_options.clone_and_edit_weight_attribute( + weights_per_channel_threshold=False)) + tanh = schema.OperatorsSet(name=schema.OperatorSetNames.TANH, + qc_options=default_configuration_options.clone_and_edit( + fixed_zero_point=-128, fixed_scale=1 / 256)) + fc = schema.OperatorsSet(name=schema.OperatorSetNames.FULLY_CONNECTED, + qc_options=default_configuration_options.clone_and_edit_weight_attribute( + weights_per_channel_threshold=False)) + squeeze = schema.OperatorsSet(name=schema.OperatorSetNames.SQUEEZE, + qc_options=default_configuration_options.clone_and_edit( + quantization_preserving=True)) + + conv2d = schema.OperatorsSet(name=schema.OperatorSetNames.CONV) + relu = schema.OperatorsSet(name=schema.OperatorSetNames.RELU) + relu6 = schema.OperatorsSet(name=schema.OperatorSetNames.RELU6) + elu = schema.OperatorsSet(name=schema.OperatorSetNames.ELU) + batch_norm = schema.OperatorsSet(name=schema.OperatorSetNames.BATCH_NORM) + add = schema.OperatorsSet(name=schema.OperatorSetNames.ADD) + bias_add = schema.OperatorsSet(name=schema.OperatorSetNames.ADD_BIAS) - relu = schema.OperatorsSet(name="Relu") - elu = schema.OperatorsSet(name="Elu") + kernel = schema.OperatorSetConcat(operators_set=[conv2d, fc]) activations_to_fuse = schema.OperatorSetConcat(operators_set=[relu, elu]) - batch_norm = schema.OperatorsSet(name="BatchNorm") - bias_add = schema.OperatorsSet(name="BiasAdd") - add = schema.OperatorsSet(name="Add") - squeeze = schema.OperatorsSet(name="Squeeze", - qc_options=default_configuration_options.clone_and_edit( - quantization_preserving=True)) - operator_set.extend([fc, conv2d, relu, elu, batch_norm, bias_add, add, squeeze]) + operator_set.extend([fc, conv2d, relu, relu6, tanh, sigmoid, batch_norm, add, bias_add, elu, squeeze]) + # ------------------- # # Fusions # ------------------- # diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/tflite_tpc/v1/tpc_keras.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/tflite_tpc/v1/tpc_keras.py deleted file mode 100644 index a5101f819..000000000 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/tflite_tpc/v1/tpc_keras.py +++ /dev/null @@ -1,118 +0,0 @@ -# Copyright 2022 Sony Semiconductor Israel, Inc. All rights reserved. -# -# 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. -# ============================================================================== -import tensorflow as tf -from packaging import version - -import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema -from model_compression_toolkit.defaultdict import DefaultDict -from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, KERAS_KERNEL, BIAS_ATTR, BIAS - -if version.parse(tf.__version__) >= version.parse("2.13"): - from keras.src.layers import Conv2D, Dense, Reshape, ZeroPadding2D, AveragePooling2D, Activation, DepthwiseConv2D, \ - MaxPooling2D, ReLU, Add, Softmax, Concatenate, Multiply, Maximum, Minimum, BatchNormalization -else: - from keras.layers import Conv2D, Dense, Reshape, ZeroPadding2D, AveragePooling2D, Activation, DepthwiseConv2D, \ - MaxPooling2D, ReLU, Add, Softmax, Concatenate, Multiply, Maximum, Minimum, BatchNormalization - -from tensorflow.python.keras.layers.core import SlicingOpLambda -from tensorflow.python.ops.image_ops_impl import ResizeMethod -from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attribute_filter import \ - Eq - -from model_compression_toolkit.target_platform_capabilities.tpc_models.tflite_tpc.v1.tp_model import get_tp_model -import model_compression_toolkit as mct -from model_compression_toolkit.target_platform_capabilities.tpc_models.tflite_tpc.v1 import __version__ as TPC_VERSION - -tp = mct.target_platform - - -def get_keras_tpc() -> tp.TargetPlatformCapabilities: - """ - get a Keras TargetPlatformCapabilities object with default operation sets to layers mapping. - Returns: a Keras TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - tflite_tp_model = get_tp_model() - return generate_keras_tpc(name='tflite_keras', tp_model=tflite_tp_model) - - -def generate_keras_tpc(name: str, tp_model: schema.TargetPlatformModel): - """ - Generates a TargetPlatformCapabilities object with default operation sets to layers mapping. - - Args: - name: Name of the TargetPlatformCapabilities. - tp_model: TargetPlatformModel object. - - Returns: a TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - - keras_tpc = tp.TargetPlatformCapabilities(tp_model) - - with keras_tpc: - tp.OperationsSetToLayers("NoQuantization", [AveragePooling2D, - tf.nn.avg_pool2d, - Concatenate, - tf.concat, - MaxPooling2D, - Multiply, - tf.multiply, - Reshape, - tf.reshape, - tp.LayerFilterParams(tf.image.resize, - method=ResizeMethod.BILINEAR), - tf.nn.space_to_depth, - ZeroPadding2D, - tf.unstack, - tf.gather, - tf.compat.v1.batch_to_space_nd, - tf.space_to_batch_nd, - tf.transpose, - tf.maximum, - Maximum, - tf.minimum, - Minimum, - tf.pad, - tf.slice, - SlicingOpLambda]) - - tp.OperationsSetToLayers("FullyConnected", [Dense], - # we provide attributes mapping that maps each layer type in the operations set - # that has weights attributes with provided quantization config (in the tp model) to - # its framework-specific attribute name. - # note that a DefaultDict should be provided if not all the layer types in the - # operation set are provided separately in the mapping. - attr_mapping={ - KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}) - tp.OperationsSetToLayers("L2Normalization", [tf.math.l2_normalize]) - tp.OperationsSetToLayers("LogSoftmax", [tf.nn.log_softmax]) - tp.OperationsSetToLayers("Tanh", [tf.nn.tanh, tp.LayerFilterParams(Activation, activation="tanh")]) - tp.OperationsSetToLayers("Softmax", [tf.nn.softmax, - Softmax, - tp.LayerFilterParams(Activation, activation="softmax")]) - tp.OperationsSetToLayers("Logistic", [tf.sigmoid, tp.LayerFilterParams(Activation, activation="sigmoid")]) - - tp.OperationsSetToLayers("Conv2d", [Conv2D, DepthwiseConv2D]) - tp.OperationsSetToLayers("Relu", [tf.nn.relu, - tf.nn.relu6, - tp.LayerFilterParams(ReLU, Eq("max_value", None) | Eq("max_value", 6)), - tp.LayerFilterParams(Activation, activation="relu")]) - tp.OperationsSetToLayers("Elu", [tf.nn.elu, tp.LayerFilterParams(Activation, activation="elu")]) - tp.OperationsSetToLayers("BatchNorm", [BatchNormalization, tf.nn.batch_normalization]) - tp.OperationsSetToLayers("Squeeze", [tf.squeeze]) - tp.OperationsSetToLayers("BiasAdd", [tf.nn.bias_add]) - tp.OperationsSetToLayers("Add", [tf.add, Add]) - - return keras_tpc diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/tflite_tpc/v1/tpc_pytorch.py b/model_compression_toolkit/target_platform_capabilities/tpc_models/tflite_tpc/v1/tpc_pytorch.py deleted file mode 100644 index 6af810100..000000000 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/tflite_tpc/v1/tpc_pytorch.py +++ /dev/null @@ -1,100 +0,0 @@ -# Copyright 2022 Sony Semiconductor Israel, Inc. All rights reserved. -# -# 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. -# ============================================================================== -import torch -from torch.nn import AvgPool2d, MaxPool2d -from torch.nn.functional import avg_pool2d, max_pool2d, interpolate - -import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema -from model_compression_toolkit.defaultdict import DefaultDict -from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, PYTORCH_KERNEL, BIAS_ATTR, \ - BIAS -from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attribute_filter import Eq - -from model_compression_toolkit.target_platform_capabilities.tpc_models.tflite_tpc.v1.tp_model import get_tp_model -import model_compression_toolkit as mct -from model_compression_toolkit.target_platform_capabilities.tpc_models.tflite_tpc.v1 import __version__ as TPC_VERSION - -tp = mct.target_platform - - -def get_pytorch_tpc() -> tp.TargetPlatformCapabilities: - """ - get a Pytorch TargetPlatformCapabilities object with default operation sets to layers mapping. - Returns: a Pytorch TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - tflite_tp_model = get_tp_model() - return generate_pytorch_tpc(name='tflite_torch', tp_model=tflite_tp_model) - - -def generate_pytorch_tpc(name: str, tp_model: schema.TargetPlatformModel): - """ - Generates a TargetPlatformCapabilities object with default operation sets to layers mapping. - Args: - name: Name of the TargetPlatformModel. - tp_model: TargetPlatformModel object. - Returns: a TargetPlatformCapabilities object for the given TargetPlatformModel. - """ - - pytorch_tpc = tp.TargetPlatformCapabilities(tp_model) - - with pytorch_tpc: - tp.OperationsSetToLayers("NoQuantization", [AvgPool2d, - avg_pool2d, - torch.cat, - torch.concat, - MaxPool2d, - max_pool2d, - torch.mul, - torch.multiply, - torch.reshape, - tp.LayerFilterParams(interpolate, mode='bilinear'), - torch.nn.ZeroPad2d, - torch.gather, - torch.transpose, - torch.maximum, - torch.max, - torch.minimum, - torch.min, - torch.nn.functional.pad, - torch.select, - torch.unbind]) - - tp.OperationsSetToLayers("FullyConnected", [torch.nn.Linear, torch.nn.functional.linear], - # we provide attributes mapping that maps each layer type in the operations set - # that has weights attributes with provided quantization config (in the tp model) to - # its framework-specific attribute name. - # note that a DefaultDict should be provided if not all the layer types in the - # operation set are provided separately in the mapping. - attr_mapping={KERNEL_ATTR: DefaultDict(default_value=PYTORCH_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}) - tp.OperationsSetToLayers("L2Normalization", - [tp.LayerFilterParams(torch.nn.functional.normalize, Eq('p', 2) | Eq('p', None))]) - tp.OperationsSetToLayers("LogSoftmax", [torch.nn.LogSoftmax]) - tp.OperationsSetToLayers("Tanh", [torch.nn.Tanh, torch.nn.functional.tanh]) - tp.OperationsSetToLayers("Softmax", [torch.nn.Softmax, torch.nn.functional.softmax]) - tp.OperationsSetToLayers("Logistic", [torch.nn.Sigmoid, torch.nn.functional.sigmoid]) - tp.OperationsSetToLayers("Conv2d", [torch.nn.Conv2d, torch.nn.functional.conv2d]) - tp.OperationsSetToLayers("Relu", [torch.relu, - torch.nn.ReLU, - torch.nn.ReLU6, - torch.nn.functional.relu, - torch.nn.functional.relu6, - tp.LayerFilterParams(torch.nn.Hardtanh, min_val=0, max_val=6), - tp.LayerFilterParams(torch.nn.functional.hardtanh, min_val=0, max_val=6)]) - tp.OperationsSetToLayers("Elu", [torch.nn.ELU, torch.nn.functional.elu]) - tp.OperationsSetToLayers("BatchNorm", [torch.nn.BatchNorm2d, torch.nn.functional.batch_norm]) - tp.OperationsSetToLayers("Squeeze", [torch.squeeze]) - - return pytorch_tpc diff --git a/model_compression_toolkit/xquant/keras/keras_report_utils.py b/model_compression_toolkit/xquant/keras/keras_report_utils.py index 6dc617bff..f62401d7e 100644 --- a/model_compression_toolkit/xquant/keras/keras_report_utils.py +++ b/model_compression_toolkit/xquant/keras/keras_report_utils.py @@ -13,11 +13,11 @@ # limitations under the License. # ============================================================================== - +from model_compression_toolkit import get_target_platform_capabilities +from model_compression_toolkit.constants import TENSORFLOW from model_compression_toolkit.core.keras.default_framework_info import DEFAULT_KERAS_INFO from model_compression_toolkit.core.keras.keras_implementation import KerasImplementation from model_compression_toolkit.xquant.common.framework_report_utils import FrameworkReportUtils -from model_compression_toolkit.ptq.keras.quantization_facade import DEFAULT_KERAS_TPC from model_compression_toolkit.xquant.common.model_folding_utils import ModelFoldingUtils from model_compression_toolkit.xquant.common.similarity_calculator import SimilarityCalculator from model_compression_toolkit.xquant.keras.dataset_utils import KerasDatasetUtils @@ -26,6 +26,9 @@ from model_compression_toolkit.xquant.keras.similarity_functions import KerasSimilarityFunctions from model_compression_toolkit.xquant.keras.tensorboard_utils import KerasTensorboardUtils from mct_quantizers.keras.metadata import get_metadata +from model_compression_toolkit.target_platform_capabilities.constants import DEFAULT_TP_MODEL +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras class KerasReportUtils(FrameworkReportUtils): @@ -40,10 +43,15 @@ def __init__(self, report_dir: str): fw_info = DEFAULT_KERAS_INFO fw_impl = KerasImplementation() + # Set the default Target Platform Capabilities (TPC) for Keras. + default_tpc = get_target_platform_capabilities(TENSORFLOW, DEFAULT_TP_MODEL) + attach2pytorch = AttachTpcToKeras() + target_platform_capabilities = attach2pytorch.attach(default_tpc) + dataset_utils = KerasDatasetUtils() model_folding = ModelFoldingUtils(fw_info=fw_info, fw_impl=fw_impl, - fw_default_tpc=DEFAULT_KERAS_TPC) + fw_default_tpc=target_platform_capabilities) similarity_calculator = SimilarityCalculator(dataset_utils=dataset_utils, model_folding=model_folding, diff --git a/model_compression_toolkit/xquant/pytorch/pytorch_report_utils.py b/model_compression_toolkit/xquant/pytorch/pytorch_report_utils.py index 3373ece62..4145d5942 100644 --- a/model_compression_toolkit/xquant/pytorch/pytorch_report_utils.py +++ b/model_compression_toolkit/xquant/pytorch/pytorch_report_utils.py @@ -12,9 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== +from model_compression_toolkit import get_target_platform_capabilities +from model_compression_toolkit.constants import PYTORCH from model_compression_toolkit.core.pytorch.utils import get_working_device +from model_compression_toolkit.target_platform_capabilities.constants import DEFAULT_TP_MODEL +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2pytorch import \ + AttachTpcToPytorch -from model_compression_toolkit.ptq.pytorch.quantization_facade import DEFAULT_PYTORCH_TPC from model_compression_toolkit.xquant.common.framework_report_utils import FrameworkReportUtils from model_compression_toolkit.core.pytorch.default_framework_info import DEFAULT_PYTORCH_INFO from model_compression_toolkit.core.pytorch.pytorch_implementation import PytorchImplementation @@ -37,11 +41,15 @@ def __init__(self, report_dir: str): """ fw_info = DEFAULT_PYTORCH_INFO fw_impl = PytorchImplementation() + # Set the default Target Platform Capabilities (TPC) for PyTorch. + default_tpc = get_target_platform_capabilities(PYTORCH, DEFAULT_TP_MODEL) + attach2pytorch = AttachTpcToPytorch() + target_platform_capabilities = attach2pytorch.attach(default_tpc) dataset_utils = PytorchDatasetUtils() model_folding = ModelFoldingUtils(fw_info=fw_info, fw_impl=fw_impl, - fw_default_tpc=DEFAULT_PYTORCH_TPC) + fw_default_tpc=target_platform_capabilities) similarity_calculator = SimilarityCalculator(dataset_utils=dataset_utils, model_folding=model_folding, diff --git a/tests/common_tests/helpers/generate_test_tp_model.py b/tests/common_tests/helpers/generate_test_tp_model.py index 765f65d0e..c994e6944 100644 --- a/tests/common_tests/helpers/generate_test_tp_model.py +++ b/tests/common_tests/helpers/generate_test_tp_model.py @@ -84,6 +84,11 @@ def generate_mixed_precision_test_tp_model(base_cfg, default_config, mp_bitwidth name=name) +def _op_config_quantize_activation(op_set, default_quantize_activation): + return ((not getattr(op_set, 'qc_options') and default_quantize_activation) or (op_set.qc_options is not None and + op_set.qc_options.base_config.enable_activation_quantization)) + + def generate_tp_model_with_activation_mp(base_cfg, default_config, mp_bitwidth_candidates_list, custom_opsets=[], name="activation_mp_model"): mp_op_cfg_list = [] @@ -106,11 +111,13 @@ def generate_tp_model_with_activation_mp(base_cfg, default_config, mp_bitwidth_c mixed_precision_cfg_list=mp_op_cfg_list, name=name) - mixed_precision_configuration_options = schema.QuantizationConfigOptions(quantization_configurations=tuple(mp_op_cfg_list), - base_config=base_cfg) + mixed_precision_configuration_options = schema.QuantizationConfigOptions( + quantization_configurations=tuple(mp_op_cfg_list), base_config=base_cfg) + # setting only operator that already quantizing activations to mixed precision activation operator_sets_dict = {op_set.name: mixed_precision_configuration_options for op_set in base_tp_model.operator_set - if op_set.name is not "NoQuantization"} + if _op_config_quantize_activation(op_set, base_tp_model.default_qco.base_config.enable_activation_quantization)} + operator_sets_dict["Input"] = mixed_precision_configuration_options for c_ops in custom_opsets: operator_sets_dict[c_ops] = mixed_precision_configuration_options diff --git a/tests/common_tests/helpers/prep_graph_for_func_test.py b/tests/common_tests/helpers/prep_graph_for_func_test.py index 9f4ee4656..5dfca2e06 100644 --- a/tests/common_tests/helpers/prep_graph_for_func_test.py +++ b/tests/common_tests/helpers/prep_graph_for_func_test.py @@ -18,7 +18,6 @@ from model_compression_toolkit.core.common.mixed_precision.bit_width_setter import set_bit_widths from model_compression_toolkit.core.common.mixed_precision.mixed_precision_search_facade import search_bit_width from model_compression_toolkit.core.common.model_collector import ModelCollector -from model_compression_toolkit.core.common.quantization.bit_width_config import BitWidthConfig from model_compression_toolkit.core.common.quantization.quantization_params_generation.qparams_computation import \ calculate_quantization_params from model_compression_toolkit.core.common.visualization.tensorboard_writer import init_tensorboard_writer @@ -38,6 +37,7 @@ def prepare_graph_with_configs(in_model, fw_info, representative_dataset, get_tpc_func, + attach2fw, qc=DEFAULTCONFIG, mixed_precision_enabled=False, running_gptq=False): @@ -49,6 +49,8 @@ def prepare_graph_with_configs(in_model, _tp = generate_tp_model(default_config, base_config, op_cfg_list, "function_test") tpc = get_tpc_func("function_test", _tp) + tpc = attach2fw.attach(tpc, qc.custom_tpc_opset_to_layer) + # Read Model graph = graph_preparation_runner(in_model, representative_data_gen=representative_dataset, @@ -68,6 +70,7 @@ def prepare_graph_with_quantization_parameters(in_model, representative_dataset, get_tpc_func, input_shape, + attach2fw, qc=DEFAULTCONFIG, mixed_precision_enabled=False): @@ -76,6 +79,7 @@ def prepare_graph_with_quantization_parameters(in_model, fw_info, representative_dataset, get_tpc_func, + attach2fw, qc, mixed_precision_enabled) diff --git a/tests/common_tests/helpers/tpcs_for_tests/__init__.py b/tests/common_tests/helpers/tpcs_for_tests/__init__.py new file mode 100644 index 000000000..5397dea24 --- /dev/null +++ b/tests/common_tests/helpers/tpcs_for_tests/__init__.py @@ -0,0 +1,14 @@ +# Copyright 2025 Sony Semiconductor Israel, Inc. All rights reserved. +# +# 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. +# ============================================================================== diff --git a/tests/common_tests/helpers/tpcs_for_tests/v1/__init__.py b/tests/common_tests/helpers/tpcs_for_tests/v1/__init__.py new file mode 100644 index 000000000..4769f5afd --- /dev/null +++ b/tests/common_tests/helpers/tpcs_for_tests/v1/__init__.py @@ -0,0 +1,16 @@ +# Copyright 2023 Sony Semiconductor Israel, Inc. All rights reserved. +# +# 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. +# ============================================================================== + +__version__ = 'v1' diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v2/tp_model.py b/tests/common_tests/helpers/tpcs_for_tests/v1/tp_model.py similarity index 64% rename from model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v2/tp_model.py rename to tests/common_tests/helpers/tpcs_for_tests/v1/tp_model.py index d9f5ad63a..fb9b3ff7d 100644 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v2/tp_model.py +++ b/tests/common_tests/helpers/tpcs_for_tests/v1/tp_model.py @@ -1,4 +1,4 @@ -# Copyright 2024 Sony Semiconductor Israel, Inc. All rights reserved. +# Copyright 2023 Sony Semiconductor Israel, Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,8 +19,7 @@ from model_compression_toolkit.constants import FLOAT_BITWIDTH from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, BIAS_ATTR, WEIGHTS_N_BITS, \ IMX500_TP_MODEL -from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel, \ - Signedness, \ +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel, Signedness, \ AttributeQuantizationConfig, OpQuantizationConfig tp = mct.target_platform @@ -33,7 +32,6 @@ def get_tp_model() -> TargetPlatformModel: NOTE: in order to generate a target platform model with different configurations but with the same Operators Sets (for tests, experiments, etc.), use this method implementation as a test-case, i.e., override the 'get_op_quantization_configs' method and use its output to call 'generate_tp_model' with your configurations. - This version enables metadata by default. Returns: A TargetPlatformModel object. @@ -45,8 +43,7 @@ def get_tp_model() -> TargetPlatformModel: name='imx500_tp_model') -def get_op_quantization_configs() -> \ - Tuple[OpQuantizationConfig, List[OpQuantizationConfig], OpQuantizationConfig]: +def get_op_quantization_configs() -> Tuple[OpQuantizationConfig, List[OpQuantizationConfig], OpQuantizationConfig]: """ Creates a default configuration object for 8-bit quantization, to be used to set a default TargetPlatformModel. In addition, creates a default configuration objects list (with 8, 4 and 2 bit quantization) to be used as @@ -169,54 +166,86 @@ def generate_tp_model(default_config: OpQuantizationConfig, # Otherwise, it will be a configure-less set (used in fusing): operator_set = [] fusing_patterns = [] - # May suit for operations like: Dropout, Reshape, etc. - operator_set.append(schema.OperatorsSet(name="NoQuantization", qc_options=default_configuration_options.clone_and_edit( - enable_activation_quantization=False).clone_and_edit_weight_attribute(enable_weights_quantization=False))) + + no_quantization_config = (default_configuration_options.clone_and_edit(enable_activation_quantization=False) + .clone_and_edit_weight_attribute(enable_weights_quantization=False)) + + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.STACK, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.UNSTACK, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.DROPOUT, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.FLATTEN, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SPLIT_CHUNK, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.GET_ITEM, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.RESHAPE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.UNSQUEEZE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.BATCH_NORM, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SIZE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.PERMUTE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.TRANSPOSE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.EQUAL, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.ARGMAX, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.GATHER, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.TOPK, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SQUEEZE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.MAXPOOL, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.PAD, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.ZERO_PADDING2D, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.CAST, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.COMBINED_NON_MAX_SUPPRESSION, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.FAKE_QUANT, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SSD_POST_PROCESS, qc_options=no_quantization_config)) # Define operator sets that use mixed_precision_configuration_options: - conv = schema.OperatorsSet(name="Conv", qc_options=mixed_precision_configuration_options) - fc = schema.OperatorsSet(name="FullyConnected", qc_options=mixed_precision_configuration_options) + conv = schema.OperatorsSet(name=schema.OperatorSetNames.CONV, qc_options=mixed_precision_configuration_options) + conv_transpose = schema.OperatorsSet(name=schema.OperatorSetNames.CONV_TRANSPOSE, qc_options=mixed_precision_configuration_options) + depthwise_conv = schema.OperatorsSet(name=schema.OperatorSetNames.DEPTHWISE_CONV, qc_options=mixed_precision_configuration_options) + fc = schema.OperatorsSet(name=schema.OperatorSetNames.FULLY_CONNECTED, qc_options=mixed_precision_configuration_options) # Define operations sets without quantization configuration # options (useful for creating fusing patterns, for example): - any_relu = schema.OperatorsSet(name="AnyReLU") - add = schema.OperatorsSet(name="Add") - sub = schema.OperatorsSet(name="Sub") - mul = schema.OperatorsSet(name="Mul") - div = schema.OperatorsSet(name="Div") - prelu = schema.OperatorsSet(name="PReLU") - swish = schema.OperatorsSet(name="Swish") - sigmoid = schema.OperatorsSet(name="Sigmoid") - tanh = schema.OperatorsSet(name="Tanh") - - operator_set.extend([conv, fc, any_relu, add, sub, mul, div, prelu, swish, sigmoid, tanh]) - + relu = schema.OperatorsSet(name=schema.OperatorSetNames.RELU) + relu6 = schema.OperatorsSet(name=schema.OperatorSetNames.RELU6) + leaky_relu = schema.OperatorsSet(name=schema.OperatorSetNames.LEAKY_RELU) + prelu = schema.OperatorsSet(name=schema.OperatorSetNames.PRELU) + add = schema.OperatorsSet(name=schema.OperatorSetNames.ADD) + sub = schema.OperatorsSet(name=schema.OperatorSetNames.SUB) + mul = schema.OperatorsSet(name=schema.OperatorSetNames.MUL) + div = schema.OperatorsSet(name=schema.OperatorSetNames.DIV) + swish = schema.OperatorsSet(name=schema.OperatorSetNames.SWISH) + hard_swish = schema.OperatorsSet(name=schema.OperatorSetNames.HARDSWISH) + sigmoid = schema.OperatorsSet(name=schema.OperatorSetNames.SIGMOID) + tanh = schema.OperatorsSet(name=schema.OperatorSetNames.TANH) + hard_tanh = schema.OperatorsSet(name=schema.OperatorSetNames.HARD_TANH) + + operator_set.extend([conv, conv_transpose, depthwise_conv, fc, relu, relu6, leaky_relu, add, sub, mul, div, prelu, swish, + hard_swish, sigmoid, tanh, hard_tanh]) + any_relu = schema.OperatorSetConcat(operators_set=[relu, relu6, leaky_relu, hard_tanh]) # Combine multiple operators into a single operator to avoid quantization between # them. To do this we define fusing patterns using the OperatorsSets that were created. # To group multiple sets with regard to fusing, an OperatorSetConcat can be created - activations_after_conv_to_fuse = schema.OperatorSetConcat(operators_set=[any_relu, swish, prelu, sigmoid, tanh]) - activations_after_fc_to_fuse = schema.OperatorSetConcat(operators_set=[any_relu, swish, sigmoid]) + activations_after_conv_to_fuse = schema.OperatorSetConcat(operators_set=[relu, relu6, leaky_relu, hard_tanh, swish, hard_swish, prelu, sigmoid, tanh]) + conv_types = schema.OperatorSetConcat(operators_set=[conv, conv_transpose, depthwise_conv]) + activations_after_fc_to_fuse = schema.OperatorSetConcat(operators_set=[relu, relu6, leaky_relu, hard_tanh, swish, hard_swish, sigmoid]) any_binary = schema.OperatorSetConcat(operators_set=[add, sub, mul, div]) # ------------------- # # Fusions # ------------------- # - fusing_patterns.append(schema.Fusing(operator_groups=(conv, activations_after_conv_to_fuse))) + fusing_patterns.append(schema.Fusing(operator_groups=(conv_types, activations_after_conv_to_fuse))) fusing_patterns.append(schema.Fusing(operator_groups=(fc, activations_after_fc_to_fuse))) fusing_patterns.append(schema.Fusing(operator_groups=(any_binary, any_relu))) # Create a TargetPlatformModel and set its default quantization config. # This default configuration will be used for all operations # unless specified otherwise (see OperatorsSet, for example): - generated_tpm = schema.TargetPlatformModel( + generated_tpc = schema.TargetPlatformModel( default_qco=default_configuration_options, - tpc_minor_version=2, + tpc_minor_version=1, tpc_patch_version=0, tpc_platform_type=IMX500_TP_MODEL, operator_set=tuple(operator_set), fusing_patterns=tuple(fusing_patterns), - add_metadata=True, name=name, + add_metadata=False, is_simd_padding=True) - - return generated_tpm + return generated_tpc diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1_lut/__init__.py b/tests/common_tests/helpers/tpcs_for_tests/v1_lut/__init__.py similarity index 100% rename from model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1_lut/__init__.py rename to tests/common_tests/helpers/tpcs_for_tests/v1_lut/__init__.py diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1_lut/tp_model.py b/tests/common_tests/helpers/tpcs_for_tests/v1_lut/tp_model.py similarity index 60% rename from model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1_lut/tp_model.py rename to tests/common_tests/helpers/tpcs_for_tests/v1_lut/tp_model.py index 557bb8a45..14885e841 100644 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1_lut/tp_model.py +++ b/tests/common_tests/helpers/tpcs_for_tests/v1_lut/tp_model.py @@ -151,10 +151,12 @@ def generate_tp_model(default_config: OpQuantizationConfig, # of possible configurations to consider when quantizing a set of operations (in mixed-precision, for example). # If the QuantizationConfigOptions contains only one configuration, # this configuration will be used for the operation quantization: - default_configuration_options = schema.QuantizationConfigOptions(quantization_configurations=tuple([default_config])) + default_configuration_options = schema.QuantizationConfigOptions(quantization_configurations= + tuple([default_config])) # Create Mixed-Precision quantization configuration options from the given list of OpQuantizationConfig objects - mixed_precision_configuration_options = schema.QuantizationConfigOptions(quantization_configurations=tuple(mixed_precision_cfg_list), + mixed_precision_configuration_options = schema.QuantizationConfigOptions(quantization_configurations= + tuple(mixed_precision_cfg_list), base_config=base_config) # Create an OperatorsSet to represent a set of operations. @@ -165,53 +167,118 @@ def generate_tp_model(default_config: OpQuantizationConfig, operator_set = [] fusing_patterns = [] - # May suit for operations like: Dropout, Reshape, etc. - operator_set.append(schema.OperatorsSet(name="NoQuantization", - qc_options=default_configuration_options.clone_and_edit( - enable_activation_quantization=False) - .clone_and_edit_weight_attribute(enable_weights_quantization=False))) + no_quantization_config = (default_configuration_options.clone_and_edit(enable_activation_quantization=False) + .clone_and_edit_weight_attribute(enable_weights_quantization=False)) + + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.STACK, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.UNSTACK, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.DROPOUT, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.FLATTEN, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.SPLIT_CHUNK, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.GET_ITEM, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.RESHAPE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.UNSQUEEZE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.BATCH_NORM, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.SIZE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.PERMUTE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.TRANSPOSE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.EQUAL, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.ARGMAX, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.GATHER, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.TOPK, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.SQUEEZE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.MAXPOOL, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.PAD, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.ZERO_PADDING2D, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.CAST, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.COMBINED_NON_MAX_SUPPRESSION, + qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.FAKE_QUANT, + qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SSD_POST_PROCESS, + qc_options=no_quantization_config)) # Define operator sets that use mixed_precision_configuration_options: - conv = schema.OperatorsSet(name="Conv", qc_options=mixed_precision_configuration_options) - fc = schema.OperatorsSet(name="FullyConnected", qc_options=mixed_precision_configuration_options) + conv = schema.OperatorsSet(name=schema.OperatorSetNames.CONV, + qc_options=mixed_precision_configuration_options) + conv_transpose = schema.OperatorsSet(name=schema.OperatorSetNames.CONV_TRANSPOSE, + qc_options=mixed_precision_configuration_options) + depthwise_conv = schema.OperatorsSet(name=schema.OperatorSetNames.DEPTHWISE_CONV, + qc_options=mixed_precision_configuration_options) + fc = schema.OperatorsSet(name=schema.OperatorSetNames.FULLY_CONNECTED, + qc_options=mixed_precision_configuration_options) # Define operations sets without quantization configuration # options (useful for creating fusing patterns, for example): - any_relu = schema.OperatorsSet(name="AnyReLU") - add = schema.OperatorsSet(name="Add") - sub = schema.OperatorsSet(name="Sub") - mul = schema.OperatorsSet(name="Mul") - div = schema.OperatorsSet(name="Div") - prelu = schema.OperatorsSet(name="PReLU") - swish = schema.OperatorsSet(name="Swish") - sigmoid = schema.OperatorsSet(name="Sigmoid") - tanh = schema.OperatorsSet(name="Tanh") - - operator_set.extend([conv, fc, any_relu, add, sub, mul, div, prelu, swish, sigmoid, tanh]) + relu = schema.OperatorsSet(name=schema.OperatorSetNames.RELU) + relu6 = schema.OperatorsSet(name=schema.OperatorSetNames.RELU6) + leaky_relu = schema.OperatorsSet(name=schema.OperatorSetNames.LEAKY_RELU) + prelu = schema.OperatorsSet(name=schema.OperatorSetNames.PRELU) + add = schema.OperatorsSet(name=schema.OperatorSetNames.ADD) + sub = schema.OperatorsSet(name=schema.OperatorSetNames.SUB) + mul = schema.OperatorsSet(name=schema.OperatorSetNames.MUL) + div = schema.OperatorsSet(name=schema.OperatorSetNames.DIV) + swish = schema.OperatorsSet(name=schema.OperatorSetNames.SWISH) + hard_swish = schema.OperatorsSet(name=schema.OperatorSetNames.HARDSWISH) + sigmoid = schema.OperatorsSet(name=schema.OperatorSetNames.SIGMOID) + tanh = schema.OperatorsSet(name=schema.OperatorSetNames.TANH) + hard_tanh = schema.OperatorsSet(name=schema.OperatorSetNames.HARD_TANH) + + operator_set.extend( + [conv, conv_transpose, depthwise_conv, fc, relu, relu6, leaky_relu, add, sub, mul, div, prelu, swish, + hard_swish, sigmoid, + tanh, hard_tanh]) + any_relu = schema.OperatorSetConcat(operators_set=[relu, relu6, leaky_relu, hard_tanh]) # Combine multiple operators into a single operator to avoid quantization between # them. To do this we define fusing patterns using the OperatorsSets that were created. # To group multiple sets with regard to fusing, an OperatorSetConcat can be created - activations_after_conv_to_fuse = schema.OperatorSetConcat(operators_set=[any_relu, swish, prelu, sigmoid, tanh]) - activations_after_fc_to_fuse = schema.OperatorSetConcat(operators_set=[any_relu, swish, sigmoid]) + activations_after_conv_to_fuse = schema.OperatorSetConcat( + operators_set=[relu, relu6, leaky_relu, hard_tanh, swish, hard_swish, prelu, sigmoid, tanh]) + conv_types = schema.OperatorSetConcat(operators_set=[conv, conv_transpose, depthwise_conv]) + activations_after_fc_to_fuse = schema.OperatorSetConcat( + operators_set=[relu, relu6, leaky_relu, hard_tanh, swish, hard_swish, sigmoid]) any_binary = schema.OperatorSetConcat(operators_set=[add, sub, mul, div]) # ------------------- # # Fusions # ------------------- # - fusing_patterns.append(schema.Fusing(operator_groups=(conv, activations_after_conv_to_fuse))) + fusing_patterns.append(schema.Fusing(operator_groups=(conv_types, activations_after_conv_to_fuse))) fusing_patterns.append(schema.Fusing(operator_groups=(fc, activations_after_fc_to_fuse))) fusing_patterns.append(schema.Fusing(operator_groups=(any_binary, any_relu))) # Create a TargetPlatformModel and set its default quantization config. # This default configuration will be used for all operations # unless specified otherwise (see OperatorsSet, for example): - generated_tpc = schema.TargetPlatformModel( + generated_tpm = schema.TargetPlatformModel( default_qco=default_configuration_options, - tpc_minor_version=1, + tpc_minor_version=2, tpc_patch_version=0, tpc_platform_type=IMX500_TP_MODEL, operator_set=tuple(operator_set), fusing_patterns=tuple(fusing_patterns), - add_metadata=False, - name=name) - return generated_tpc + add_metadata=True, + name=name, + is_simd_padding=True) + + return generated_tpm diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1_pot/__init__.py b/tests/common_tests/helpers/tpcs_for_tests/v1_pot/__init__.py similarity index 100% rename from model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1_pot/__init__.py rename to tests/common_tests/helpers/tpcs_for_tests/v1_pot/__init__.py diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1_pot/tp_model.py b/tests/common_tests/helpers/tpcs_for_tests/v1_pot/tp_model.py similarity index 60% rename from model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1_pot/tp_model.py rename to tests/common_tests/helpers/tpcs_for_tests/v1_pot/tp_model.py index 2669fe92c..c463f0d0f 100644 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v1_pot/tp_model.py +++ b/tests/common_tests/helpers/tpcs_for_tests/v1_pot/tp_model.py @@ -147,10 +147,12 @@ def generate_tp_model(default_config: OpQuantizationConfig, # of possible configurations to consider when quantizing a set of operations (in mixed-precision, for example). # If the QuantizationConfigOptions contains only one configuration, # this configuration will be used for the operation quantization: - default_configuration_options = schema.QuantizationConfigOptions(quantization_configurations=tuple([default_config])) + default_configuration_options = schema.QuantizationConfigOptions(quantization_configurations= + tuple([default_config])) # Create Mixed-Precision quantization configuration options from the given list of OpQuantizationConfig objects - mixed_precision_configuration_options = schema.QuantizationConfigOptions(quantization_configurations=tuple(mixed_precision_cfg_list), + mixed_precision_configuration_options = schema.QuantizationConfigOptions(quantization_configurations= + tuple(mixed_precision_cfg_list), base_config=base_config) # Create an OperatorsSet to represent a set of operations. @@ -161,55 +163,117 @@ def generate_tp_model(default_config: OpQuantizationConfig, operator_set = [] fusing_patterns = [] - # May suit for operations like: Dropout, Reshape, etc. - operator_set.append(schema.OperatorsSet(name="NoQuantization", - qc_options=default_configuration_options.clone_and_edit( - enable_activation_quantization=False) - .clone_and_edit_weight_attribute(enable_weights_quantization=False))) + no_quantization_config = (default_configuration_options.clone_and_edit(enable_activation_quantization=False) + .clone_and_edit_weight_attribute(enable_weights_quantization=False)) + + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.STACK, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.UNSTACK, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.DROPOUT, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.FLATTEN, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.SPLIT_CHUNK, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.GET_ITEM, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.RESHAPE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.UNSQUEEZE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.BATCH_NORM, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.SIZE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.PERMUTE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.TRANSPOSE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.EQUAL, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.ARGMAX, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.GATHER, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.TOPK, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.SQUEEZE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.MAXPOOL, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.PAD, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.ZERO_PADDING2D, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.CAST, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.COMBINED_NON_MAX_SUPPRESSION, + qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.FAKE_QUANT, + qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SSD_POST_PROCESS, + qc_options=no_quantization_config)) # Define operator sets that use mixed_precision_configuration_options: - conv = schema.OperatorsSet(name="Conv", qc_options=mixed_precision_configuration_options) - fc = schema.OperatorsSet(name="FullyConnected", qc_options=mixed_precision_configuration_options) + conv = schema.OperatorsSet(name=schema.OperatorSetNames.CONV, + qc_options=mixed_precision_configuration_options) + conv_transpose = schema.OperatorsSet(name=schema.OperatorSetNames.CONV_TRANSPOSE, + qc_options=mixed_precision_configuration_options) + depthwise_conv = schema.OperatorsSet(name=schema.OperatorSetNames.DEPTHWISE_CONV, + qc_options=mixed_precision_configuration_options) + fc = schema.OperatorsSet(name=schema.OperatorSetNames.FULLY_CONNECTED, + qc_options=mixed_precision_configuration_options) # Define operations sets without quantization configuration # options (useful for creating fusing patterns, for example): - any_relu = schema.OperatorsSet(name="AnyReLU") - add = schema.OperatorsSet(name="Add") - sub = schema.OperatorsSet(name="Sub") - mul = schema.OperatorsSet(name="Mul") - div = schema.OperatorsSet(name="Div") - prelu = schema.OperatorsSet(name="PReLU") - swish = schema.OperatorsSet(name="Swish") - sigmoid = schema.OperatorsSet(name="Sigmoid") - tanh = schema.OperatorsSet(name="Tanh") - - operator_set.extend([conv, fc, any_relu, add, sub, mul, div, prelu, swish, sigmoid, tanh]) - + relu = schema.OperatorsSet(name=schema.OperatorSetNames.RELU) + relu6 = schema.OperatorsSet(name=schema.OperatorSetNames.RELU6) + leaky_relu = schema.OperatorsSet(name=schema.OperatorSetNames.LEAKY_RELU) + prelu = schema.OperatorsSet(name=schema.OperatorSetNames.PRELU) + add = schema.OperatorsSet(name=schema.OperatorSetNames.ADD) + sub = schema.OperatorsSet(name=schema.OperatorSetNames.SUB) + mul = schema.OperatorsSet(name=schema.OperatorSetNames.MUL) + div = schema.OperatorsSet(name=schema.OperatorSetNames.DIV) + swish = schema.OperatorsSet(name=schema.OperatorSetNames.SWISH) + hard_swish = schema.OperatorsSet(name=schema.OperatorSetNames.HARDSWISH) + sigmoid = schema.OperatorsSet(name=schema.OperatorSetNames.SIGMOID) + tanh = schema.OperatorsSet(name=schema.OperatorSetNames.TANH) + hard_tanh = schema.OperatorsSet(name=schema.OperatorSetNames.HARD_TANH) + + operator_set.extend( + [conv, conv_transpose, depthwise_conv, fc, relu, relu6, leaky_relu, add, sub, mul, div, prelu, swish, + hard_swish, sigmoid, + tanh, hard_tanh]) + any_relu = schema.OperatorSetConcat(operators_set=[relu, relu6, leaky_relu, hard_tanh]) # Combine multiple operators into a single operator to avoid quantization between # them. To do this we define fusing patterns using the OperatorsSets that were created. # To group multiple sets with regard to fusing, an OperatorSetConcat can be created - activations_after_conv_to_fuse = schema.OperatorSetConcat(operators_set=[any_relu, swish, prelu, sigmoid, tanh]) - activations_after_fc_to_fuse = schema.OperatorSetConcat(operators_set=[any_relu, swish, sigmoid]) + activations_after_conv_to_fuse = schema.OperatorSetConcat( + operators_set=[relu, relu6, leaky_relu, hard_tanh, swish, hard_swish, prelu, sigmoid, tanh]) + conv_types = schema.OperatorSetConcat(operators_set=[conv, conv_transpose, depthwise_conv]) + activations_after_fc_to_fuse = schema.OperatorSetConcat( + operators_set=[relu, relu6, leaky_relu, hard_tanh, swish, hard_swish, sigmoid]) any_binary = schema.OperatorSetConcat(operators_set=[add, sub, mul, div]) # ------------------- # # Fusions # ------------------- # - fusing_patterns.append(schema.Fusing(operator_groups=(conv, activations_after_conv_to_fuse))) + fusing_patterns.append(schema.Fusing(operator_groups=(conv_types, activations_after_conv_to_fuse))) fusing_patterns.append(schema.Fusing(operator_groups=(fc, activations_after_fc_to_fuse))) fusing_patterns.append(schema.Fusing(operator_groups=(any_binary, any_relu))) # Create a TargetPlatformModel and set its default quantization config. # This default configuration will be used for all operations # unless specified otherwise (see OperatorsSet, for example): - generated_tpc = schema.TargetPlatformModel( + generated_tpm = schema.TargetPlatformModel( default_qco=default_configuration_options, - tpc_minor_version=1, + tpc_minor_version=2, tpc_patch_version=0, tpc_platform_type=IMX500_TP_MODEL, operator_set=tuple(operator_set), fusing_patterns=tuple(fusing_patterns), + add_metadata=True, name=name, - add_metadata=False, is_simd_padding=True) - return generated_tpc + return generated_tpm diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v2/__init__.py b/tests/common_tests/helpers/tpcs_for_tests/v2/__init__.py similarity index 100% rename from model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v2/__init__.py rename to tests/common_tests/helpers/tpcs_for_tests/v2/__init__.py diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v3/tp_model.py b/tests/common_tests/helpers/tpcs_for_tests/v2/tp_model.py similarity index 64% rename from model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v3/tp_model.py rename to tests/common_tests/helpers/tpcs_for_tests/v2/tp_model.py index 4f0512cc3..16c6c2381 100644 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v3/tp_model.py +++ b/tests/common_tests/helpers/tpcs_for_tests/v2/tp_model.py @@ -156,31 +156,12 @@ def generate_tp_model(default_config: OpQuantizationConfig, # of possible configurations to consider when quantizing a set of operations (in mixed-precision, for example). # If the QuantizationConfigOptions contains only one configuration, # this configuration will be used for the operation quantization: - default_configuration_options = schema.QuantizationConfigOptions(quantization_configurations=tuple([default_config])) - - # Create a QuantizationConfigOptions for quantizing constants in functional ops. - # Constant configuration is similar to the default eight bit configuration except for PoT - # quantization method for the constant. - # Since the constants are not named attributes of the layer, we use the default_weight_attr_config to - # define the desired quantization properties for them. - const_config = default_config.clone_and_edit( - default_weight_attr_config=default_config.default_weight_attr_config.clone_and_edit( - enable_weights_quantization=True, weights_per_channel_threshold=True, - weights_quantization_method=tp.QuantizationMethod.POWER_OF_TWO)) - const_configuration_options = schema.QuantizationConfigOptions(quantization_configurations=tuple([const_config])) - - # 16 bits inputs and outputs. Currently, only defined for consts since they are used in operators that - # support 16 bit as input and output. - const_config_input16 = const_config.clone_and_edit( - supported_input_activation_n_bits=(8, 16)) - const_config_input16_output16 = const_config_input16.clone_and_edit( - activation_n_bits=16, signedness=Signedness.SIGNED) - const_configuration_options_inout16 = schema.QuantizationConfigOptions(quantization_configurations=tuple([const_config_input16_output16, - const_config_input16]), - base_config=const_config_input16) + default_configuration_options = schema.QuantizationConfigOptions(quantization_configurations= + tuple([default_config])) # Create Mixed-Precision quantization configuration options from the given list of OpQuantizationConfig objects - mixed_precision_configuration_options = schema.QuantizationConfigOptions(quantization_configurations=tuple(mixed_precision_cfg_list), + mixed_precision_configuration_options = schema.QuantizationConfigOptions(quantization_configurations= + tuple(mixed_precision_cfg_list), base_config=base_config) # Create an OperatorsSet to represent a set of operations. @@ -190,42 +171,78 @@ def generate_tp_model(default_config: OpQuantizationConfig, # Otherwise, it will be a configure-less set (used in fusing): operator_set = [] fusing_patterns = [] - # May suit for operations like: Dropout, Reshape, etc. - operator_set.append(schema.OperatorsSet(name="NoQuantization", - qc_options=default_configuration_options.clone_and_edit( - enable_activation_quantization=False, - supported_input_activation_n_bits=(8, 16)) - .clone_and_edit_weight_attribute(enable_weights_quantization=False))) - operator_set.append(schema.OperatorsSet(name="Default16BitInout", qc_options=const_configuration_options_inout16)) + + no_quantization_config = (default_configuration_options.clone_and_edit(enable_activation_quantization=False) + .clone_and_edit_weight_attribute(enable_weights_quantization=False)) + + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.STACK, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.UNSTACK, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.DROPOUT, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.FLATTEN, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SPLIT_CHUNK, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.GET_ITEM, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.RESHAPE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.UNSQUEEZE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.BATCH_NORM, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SIZE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.PERMUTE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.TRANSPOSE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.EQUAL, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.ARGMAX, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.GATHER, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.TOPK, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SQUEEZE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.MAXPOOL, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.PAD, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.ZERO_PADDING2D, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.CAST, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.COMBINED_NON_MAX_SUPPRESSION, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.FAKE_QUANT, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SSD_POST_PROCESS, qc_options=no_quantization_config)) # Define operator sets that use mixed_precision_configuration_options: - conv = schema.OperatorsSet(name="Conv", qc_options=mixed_precision_configuration_options) - fc = schema.OperatorsSet(name="FullyConnected", qc_options=mixed_precision_configuration_options) + conv = schema.OperatorsSet(name=schema.OperatorSetNames.CONV, + qc_options=mixed_precision_configuration_options) + conv_transpose = schema.OperatorsSet(name=schema.OperatorSetNames.CONV_TRANSPOSE, + qc_options=mixed_precision_configuration_options) + depthwise_conv = schema.OperatorsSet(name=schema.OperatorSetNames.DEPTHWISE_CONV, + qc_options=mixed_precision_configuration_options) + fc = schema.OperatorsSet(name=schema.OperatorSetNames.FULLY_CONNECTED, + qc_options=mixed_precision_configuration_options) # Define operations sets without quantization configuration # options (useful for creating fusing patterns, for example): - any_relu = schema.OperatorsSet(name="AnyReLU") - add = schema.OperatorsSet(name="Add", qc_options=const_configuration_options_inout16) - sub = schema.OperatorsSet(name="Sub", qc_options=const_configuration_options_inout16) - mul = schema.OperatorsSet(name="Mul", qc_options=const_configuration_options_inout16) - div = schema.OperatorsSet(name="Div", qc_options=const_configuration_options) - prelu = schema.OperatorsSet(name="PReLU") - swish = schema.OperatorsSet(name="Swish") - sigmoid = schema.OperatorsSet(name="Sigmoid") - tanh = schema.OperatorsSet(name="Tanh") - - operator_set.extend([conv, fc, any_relu, add, sub, mul, div, prelu, swish, sigmoid, tanh]) + relu = schema.OperatorsSet(name=schema.OperatorSetNames.RELU) + relu6 = schema.OperatorsSet(name=schema.OperatorSetNames.RELU6) + leaky_relu = schema.OperatorsSet(name=schema.OperatorSetNames.LEAKY_RELU) + prelu = schema.OperatorsSet(name=schema.OperatorSetNames.PRELU) + add = schema.OperatorsSet(name=schema.OperatorSetNames.ADD) + sub = schema.OperatorsSet(name=schema.OperatorSetNames.SUB) + mul = schema.OperatorsSet(name=schema.OperatorSetNames.MUL) + div = schema.OperatorsSet(name=schema.OperatorSetNames.DIV) + swish = schema.OperatorsSet(name=schema.OperatorSetNames.SWISH) + hard_swish = schema.OperatorsSet(name=schema.OperatorSetNames.HARDSWISH) + sigmoid = schema.OperatorsSet(name=schema.OperatorSetNames.SIGMOID) + tanh = schema.OperatorsSet(name=schema.OperatorSetNames.TANH) + hard_tanh = schema.OperatorsSet(name=schema.OperatorSetNames.HARD_TANH) + + operator_set.extend( + [conv, conv_transpose, depthwise_conv, fc, relu, relu6, leaky_relu, add, sub, mul, div, prelu, swish, hard_swish, sigmoid, + tanh, hard_tanh]) + any_relu = schema.OperatorSetConcat(operators_set=[relu, relu6, leaky_relu, hard_tanh]) # Combine multiple operators into a single operator to avoid quantization between # them. To do this we define fusing patterns using the OperatorsSets that were created. # To group multiple sets with regard to fusing, an OperatorSetConcat can be created - activations_after_conv_to_fuse = schema.OperatorSetConcat(operators_set=[any_relu, swish, prelu, sigmoid, tanh]) - activations_after_fc_to_fuse = schema.OperatorSetConcat(operators_set=[any_relu, swish, sigmoid]) + activations_after_conv_to_fuse = schema.OperatorSetConcat( + operators_set=[relu, relu6, leaky_relu, hard_tanh, swish, hard_swish, prelu, sigmoid, tanh]) + conv_types = schema.OperatorSetConcat(operators_set=[conv, conv_transpose, depthwise_conv]) + activations_after_fc_to_fuse = schema.OperatorSetConcat(operators_set=[relu, relu6, leaky_relu, hard_tanh, swish, hard_swish, sigmoid]) any_binary = schema.OperatorSetConcat(operators_set=[add, sub, mul, div]) # ------------------- # # Fusions # ------------------- # - fusing_patterns.append(schema.Fusing(operator_groups=(conv, activations_after_conv_to_fuse))) + fusing_patterns.append(schema.Fusing(operator_groups=(conv_types, activations_after_conv_to_fuse))) fusing_patterns.append(schema.Fusing(operator_groups=(fc, activations_after_fc_to_fuse))) fusing_patterns.append(schema.Fusing(operator_groups=(any_binary, any_relu))) @@ -234,7 +251,7 @@ def generate_tp_model(default_config: OpQuantizationConfig, # unless specified otherwise (see OperatorsSet, for example): generated_tpm = schema.TargetPlatformModel( default_qco=default_configuration_options, - tpc_minor_version=3, + tpc_minor_version=2, tpc_patch_version=0, tpc_platform_type=IMX500_TP_MODEL, operator_set=tuple(operator_set), diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v2_lut/__init__.py b/tests/common_tests/helpers/tpcs_for_tests/v2_lut/__init__.py similarity index 100% rename from model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v2_lut/__init__.py rename to tests/common_tests/helpers/tpcs_for_tests/v2_lut/__init__.py diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v2_lut/tp_model.py b/tests/common_tests/helpers/tpcs_for_tests/v2_lut/tp_model.py similarity index 61% rename from model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v2_lut/tp_model.py rename to tests/common_tests/helpers/tpcs_for_tests/v2_lut/tp_model.py index be420bf03..4aa691d46 100644 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v2_lut/tp_model.py +++ b/tests/common_tests/helpers/tpcs_for_tests/v2_lut/tp_model.py @@ -153,10 +153,12 @@ def generate_tp_model(default_config: OpQuantizationConfig, # of possible configurations to consider when quantizing a set of operations (in mixed-precision, for example). # If the QuantizationConfigOptions contains only one configuration, # this configuration will be used for the operation quantization: - default_configuration_options = schema.QuantizationConfigOptions(quantization_configurations=tuple([default_config])) + default_configuration_options = schema.QuantizationConfigOptions(quantization_configurations= + tuple([default_config])) # Create Mixed-Precision quantization configuration options from the given list of OpQuantizationConfig objects - mixed_precision_configuration_options = schema.QuantizationConfigOptions(quantization_configurations=tuple(mixed_precision_cfg_list), + mixed_precision_configuration_options = schema.QuantizationConfigOptions(quantization_configurations= + tuple(mixed_precision_cfg_list), base_config=base_config) # Create an OperatorsSet to represent a set of operations. @@ -166,40 +168,104 @@ def generate_tp_model(default_config: OpQuantizationConfig, # Otherwise, it will be a configure-less set (used in fusing): operator_set = [] fusing_patterns = [] - # May suit for operations like: Dropout, Reshape, etc. - operator_set.append(schema.OperatorsSet(name="NoQuantization", - qc_options=default_configuration_options.clone_and_edit( - enable_activation_quantization=False) - .clone_and_edit_weight_attribute(enable_weights_quantization=False))) + + no_quantization_config = (default_configuration_options.clone_and_edit(enable_activation_quantization=False) + .clone_and_edit_weight_attribute(enable_weights_quantization=False)) + + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.STACK, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.UNSTACK, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.DROPOUT, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.FLATTEN, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.SPLIT_CHUNK, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.GET_ITEM, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.RESHAPE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.UNSQUEEZE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.BATCH_NORM, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.SIZE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.PERMUTE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.TRANSPOSE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.EQUAL, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.ARGMAX, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.GATHER, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.TOPK, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.SQUEEZE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.MAXPOOL, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.PAD, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.ZERO_PADDING2D, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.CAST, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.COMBINED_NON_MAX_SUPPRESSION, + qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.FAKE_QUANT, + qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SSD_POST_PROCESS, + qc_options=no_quantization_config)) # Define operator sets that use mixed_precision_configuration_options: - conv = schema.OperatorsSet(name="Conv", qc_options=mixed_precision_configuration_options) - fc = schema.OperatorsSet(name="FullyConnected", qc_options=mixed_precision_configuration_options) + conv = schema.OperatorsSet(name=schema.OperatorSetNames.CONV, + qc_options=mixed_precision_configuration_options) + conv_transpose = schema.OperatorsSet(name=schema.OperatorSetNames.CONV_TRANSPOSE, + qc_options=mixed_precision_configuration_options) + depthwise_conv = schema.OperatorsSet(name=schema.OperatorSetNames.DEPTHWISE_CONV, + qc_options=mixed_precision_configuration_options) + fc = schema.OperatorsSet(name=schema.OperatorSetNames.FULLY_CONNECTED, + qc_options=mixed_precision_configuration_options) # Define operations sets without quantization configuration # options (useful for creating fusing patterns, for example): - any_relu = schema.OperatorsSet(name="AnyReLU") - add = schema.OperatorsSet(name="Add") - sub = schema.OperatorsSet(name="Sub") - mul = schema.OperatorsSet(name="Mul") - div = schema.OperatorsSet(name="Div") - prelu = schema.OperatorsSet(name="PReLU") - swish = schema.OperatorsSet(name="Swish") - sigmoid = schema.OperatorsSet(name="Sigmoid") - tanh = schema.OperatorsSet(name="Tanh") - - operator_set.extend([conv, fc, any_relu, add, sub, mul, div, prelu, swish, sigmoid, tanh]) + relu = schema.OperatorsSet(name=schema.OperatorSetNames.RELU) + relu6 = schema.OperatorsSet(name=schema.OperatorSetNames.RELU6) + leaky_relu = schema.OperatorsSet(name=schema.OperatorSetNames.LEAKY_RELU) + prelu = schema.OperatorsSet(name=schema.OperatorSetNames.PRELU) + add = schema.OperatorsSet(name=schema.OperatorSetNames.ADD) + sub = schema.OperatorsSet(name=schema.OperatorSetNames.SUB) + mul = schema.OperatorsSet(name=schema.OperatorSetNames.MUL) + div = schema.OperatorsSet(name=schema.OperatorSetNames.DIV) + swish = schema.OperatorsSet(name=schema.OperatorSetNames.SWISH) + hard_swish = schema.OperatorsSet(name=schema.OperatorSetNames.HARDSWISH) + sigmoid = schema.OperatorsSet(name=schema.OperatorSetNames.SIGMOID) + tanh = schema.OperatorsSet(name=schema.OperatorSetNames.TANH) + hard_tanh = schema.OperatorsSet(name=schema.OperatorSetNames.HARD_TANH) + + operator_set.extend( + [conv, conv_transpose, depthwise_conv, fc, relu, relu6, leaky_relu, add, sub, mul, div, prelu, swish, + hard_swish, sigmoid, + tanh, hard_tanh]) + any_relu = schema.OperatorSetConcat(operators_set=[relu, relu6, leaky_relu, hard_tanh]) # Combine multiple operators into a single operator to avoid quantization between # them. To do this we define fusing patterns using the OperatorsSets that were created. # To group multiple sets with regard to fusing, an OperatorSetConcat can be created - activations_after_conv_to_fuse = schema.OperatorSetConcat(operators_set=[any_relu, swish, prelu, sigmoid, tanh]) - activations_after_fc_to_fuse = schema.OperatorSetConcat(operators_set=[any_relu, swish, sigmoid]) + activations_after_conv_to_fuse = schema.OperatorSetConcat( + operators_set=[relu, relu6, leaky_relu, hard_tanh, swish, hard_swish, prelu, sigmoid, tanh]) + conv_types = schema.OperatorSetConcat(operators_set=[conv, conv_transpose, depthwise_conv]) + activations_after_fc_to_fuse = schema.OperatorSetConcat( + operators_set=[relu, relu6, leaky_relu, hard_tanh, swish, hard_swish, sigmoid]) any_binary = schema.OperatorSetConcat(operators_set=[add, sub, mul, div]) # ------------------- # # Fusions # ------------------- # - fusing_patterns.append(schema.Fusing(operator_groups=(conv, activations_after_conv_to_fuse))) + fusing_patterns.append(schema.Fusing(operator_groups=(conv_types, activations_after_conv_to_fuse))) fusing_patterns.append(schema.Fusing(operator_groups=(fc, activations_after_fc_to_fuse))) fusing_patterns.append(schema.Fusing(operator_groups=(any_binary, any_relu))) @@ -214,6 +280,8 @@ def generate_tp_model(default_config: OpQuantizationConfig, operator_set=tuple(operator_set), fusing_patterns=tuple(fusing_patterns), add_metadata=True, - name=name) + name=name, + is_simd_padding=True) + return generated_tpm diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v3/__init__.py b/tests/common_tests/helpers/tpcs_for_tests/v3/__init__.py similarity index 100% rename from model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v3/__init__.py rename to tests/common_tests/helpers/tpcs_for_tests/v3/__init__.py diff --git a/tests/common_tests/helpers/tpcs_for_tests/v3/tp_model.py b/tests/common_tests/helpers/tpcs_for_tests/v3/tp_model.py new file mode 100644 index 000000000..5f2932d98 --- /dev/null +++ b/tests/common_tests/helpers/tpcs_for_tests/v3/tp_model.py @@ -0,0 +1,293 @@ +# Copyright 2024 Sony Semiconductor Israel, Inc. All rights reserved. +# +# 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 typing import List, Tuple + +import model_compression_toolkit as mct +import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema +from model_compression_toolkit.constants import FLOAT_BITWIDTH +from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, BIAS_ATTR, WEIGHTS_N_BITS, \ + IMX500_TP_MODEL +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel, \ + Signedness, \ + AttributeQuantizationConfig, OpQuantizationConfig + +tp = mct.target_platform + + +def get_tp_model() -> TargetPlatformModel: + """ + A method that generates a default target platform model, with base 8-bit quantization configuration and 8, 4, 2 + bits configuration list for mixed-precision quantization. + NOTE: in order to generate a target platform model with different configurations but with the same Operators Sets + (for tests, experiments, etc.), use this method implementation as a test-case, i.e., override the + 'get_op_quantization_configs' method and use its output to call 'generate_tp_model' with your configurations. + This version enables metadata by default. + + Returns: A TargetPlatformModel object. + + """ + base_config, mixed_precision_cfg_list, default_config = get_op_quantization_configs() + return generate_tp_model(default_config=default_config, + base_config=base_config, + mixed_precision_cfg_list=mixed_precision_cfg_list, + name='imx500_tp_model') + + +def get_op_quantization_configs() -> \ + Tuple[OpQuantizationConfig, List[OpQuantizationConfig], OpQuantizationConfig]: + """ + Creates a default configuration object for 8-bit quantization, to be used to set a default TargetPlatformModel. + In addition, creates a default configuration objects list (with 8, 4 and 2 bit quantization) to be used as + default configuration for mixed-precision quantization. + + Returns: An OpQuantizationConfig config object and a list of OpQuantizationConfig objects. + + """ + + # TODO: currently, we don't want to quantize any attribute but the kernel by default, + # to preserve the current behavior of MCT, so quantization is disabled for all other attributes. + # Other quantization parameters are set to what we eventually want to quantize by default + # when we enable multi-attributes quantization - THIS NEED TO BE MODIFIED IN ALL TP MODELS! + + # define a default quantization config for all non-specified weights attributes. + default_weight_attr_config = AttributeQuantizationConfig( + weights_quantization_method=tp.QuantizationMethod.POWER_OF_TWO, + weights_n_bits=8, + weights_per_channel_threshold=False, + enable_weights_quantization=False, + # TODO: this will changed to True once implementing multi-attributes quantization + lut_values_bitwidth=None) + + # define a quantization config to quantize the kernel (for layers where there is a kernel attribute). + kernel_base_config = AttributeQuantizationConfig( + weights_quantization_method=tp.QuantizationMethod.SYMMETRIC, + weights_n_bits=8, + weights_per_channel_threshold=True, + enable_weights_quantization=True, + lut_values_bitwidth=None) + + # define a quantization config to quantize the bias (for layers where there is a bias attribute). + bias_config = AttributeQuantizationConfig( + weights_quantization_method=tp.QuantizationMethod.POWER_OF_TWO, + weights_n_bits=FLOAT_BITWIDTH, + weights_per_channel_threshold=False, + enable_weights_quantization=False, + lut_values_bitwidth=None) + + # Create a quantization config. + # A quantization configuration defines how an operator + # should be quantized on the modeled hardware: + + # We define a default config for operation without kernel attribute. + # This is the default config that should be used for non-linear operations. + eight_bits_default = schema.OpQuantizationConfig( + default_weight_attr_config=default_weight_attr_config, + attr_weights_configs_mapping={}, + activation_quantization_method=tp.QuantizationMethod.POWER_OF_TWO, + activation_n_bits=8, + supported_input_activation_n_bits=8, + enable_activation_quantization=True, + quantization_preserving=False, + fixed_scale=None, + fixed_zero_point=None, + simd_size=32, + signedness=Signedness.AUTO) + + # We define an 8-bit config for linear operations quantization, that include a kernel and bias attributes. + linear_eight_bits = schema.OpQuantizationConfig( + default_weight_attr_config=default_weight_attr_config, + attr_weights_configs_mapping={KERNEL_ATTR: kernel_base_config, BIAS_ATTR: bias_config}, + activation_quantization_method=tp.QuantizationMethod.POWER_OF_TWO, + activation_n_bits=8, + supported_input_activation_n_bits=8, + enable_activation_quantization=True, + quantization_preserving=False, + fixed_scale=None, + fixed_zero_point=None, + simd_size=32, + signedness=Signedness.AUTO) + + # To quantize a model using mixed-precision, create + # a list with more than one OpQuantizationConfig. + # In this example, we quantize some operations' weights + # using 2, 4 or 8 bits, and when using 2 or 4 bits, it's possible + # to quantize the operations' activations using LUT. + four_bits = linear_eight_bits.clone_and_edit(attr_to_edit={KERNEL_ATTR: {WEIGHTS_N_BITS: 4}}, + simd_size=linear_eight_bits.simd_size * 2) + two_bits = linear_eight_bits.clone_and_edit(attr_to_edit={KERNEL_ATTR: {WEIGHTS_N_BITS: 2}}, + simd_size=linear_eight_bits.simd_size * 4) + + mixed_precision_cfg_list = [linear_eight_bits, four_bits, two_bits] + + return linear_eight_bits, mixed_precision_cfg_list, eight_bits_default + + +def generate_tp_model(default_config: OpQuantizationConfig, + base_config: OpQuantizationConfig, + mixed_precision_cfg_list: List[OpQuantizationConfig], + name: str) -> TargetPlatformModel: + """ + Generates TargetPlatformModel with default defined Operators Sets, based on the given base configuration and + mixed-precision configurations options list. + + Args + default_config: A default OpQuantizationConfig to set as the TP model default configuration. + base_config: An OpQuantizationConfig to set as the TargetPlatformModel base configuration for mixed-precision purposes only. + mixed_precision_cfg_list: A list of OpQuantizationConfig to be used as the TP model mixed-precision + quantization configuration options. + name: The name of the TargetPlatformModel. + + Returns: A TargetPlatformModel object. + + """ + # Create a QuantizationConfigOptions, which defines a set + # of possible configurations to consider when quantizing a set of operations (in mixed-precision, for example). + # If the QuantizationConfigOptions contains only one configuration, + # this configuration will be used for the operation quantization: + default_configuration_options = schema.QuantizationConfigOptions(quantization_configurations=tuple([default_config])) + + # Create a QuantizationConfigOptions for quantizing constants in functional ops. + # Constant configuration is similar to the default eight bit configuration except for PoT + # quantization method for the constant. + # Since the constants are not named attributes of the layer, we use the default_weight_attr_config to + # define the desired quantization properties for them. + const_config = default_config.clone_and_edit( + default_weight_attr_config=default_config.default_weight_attr_config.clone_and_edit( + enable_weights_quantization=True, weights_per_channel_threshold=True, + weights_quantization_method=tp.QuantizationMethod.POWER_OF_TWO)) + const_configuration_options = schema.QuantizationConfigOptions(quantization_configurations=tuple([const_config])) + + # 16 bits inputs and outputs. Currently, only defined for consts since they are used in operators that + # support 16 bit as input and output. + const_config_input16 = const_config.clone_and_edit( + supported_input_activation_n_bits=(8, 16)) + const_config_input16_output16 = const_config_input16.clone_and_edit( + activation_n_bits=16, signedness=Signedness.SIGNED) + const_configuration_options_inout16 = schema.QuantizationConfigOptions(quantization_configurations= + tuple([const_config_input16_output16, + const_config_input16]), + base_config=const_config_input16) + + # Create Mixed-Precision quantization configuration options from the given list of OpQuantizationConfig objects + mixed_precision_configuration_options = schema.QuantizationConfigOptions(quantization_configurations= + tuple(mixed_precision_cfg_list), + base_config=base_config) + + # Create an OperatorsSet to represent a set of operations. + # Each OperatorsSet has a unique label. + # If a quantization configuration options is passed, these options will + # be used for operations that will be attached to this set's label. + # Otherwise, it will be a configure-less set (used in fusing): + operator_set = [] + fusing_patterns = [] + # May suit for operations like: Dropout, Reshape, etc. + + no_quantization_config = default_configuration_options.clone_and_edit( + enable_activation_quantization=False, + supported_input_activation_n_bits=(8, 16)).clone_and_edit_weight_attribute(enable_weights_quantization=False) + + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.UNSTACK, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.DROPOUT, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.FLATTEN, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SPLIT_CHUNK, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.GET_ITEM, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.RESHAPE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.UNSQUEEZE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.BATCH_NORM, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SIZE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.PERMUTE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.TRANSPOSE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.EQUAL, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.ARGMAX, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.GATHER, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.TOPK, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SQUEEZE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.MAXPOOL, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.PAD, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.ZERO_PADDING2D, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.CAST, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.COMBINED_NON_MAX_SUPPRESSION, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.FAKE_QUANT, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.STRIDED_SLICE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SSD_POST_PROCESS, qc_options=no_quantization_config)) + + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.STACK, + qc_options=const_configuration_options_inout16)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.CONCATENATE, + qc_options=const_configuration_options_inout16)) + + # Define operator sets that use mixed_precision_configuration_options: + conv = schema.OperatorsSet(name=schema.OperatorSetNames.CONV, + qc_options=mixed_precision_configuration_options) + conv_transpose = schema.OperatorsSet(name=schema.OperatorSetNames.CONV_TRANSPOSE, + qc_options=mixed_precision_configuration_options) + depthwise_conv = schema.OperatorsSet(name=schema.OperatorSetNames.DEPTHWISE_CONV, + qc_options=mixed_precision_configuration_options) + fc = schema.OperatorsSet(name=schema.OperatorSetNames.FULLY_CONNECTED, + qc_options=mixed_precision_configuration_options) + + # Define operations sets without quantization configuration options (useful for creating fusing patterns): + relu = schema.OperatorsSet(name=schema.OperatorSetNames.RELU) + relu6 = schema.OperatorsSet(name=schema.OperatorSetNames.RELU6) + leaky_relu = schema.OperatorsSet(name=schema.OperatorSetNames.LEAKY_RELU) + prelu = schema.OperatorsSet(name=schema.OperatorSetNames.PRELU) + add = schema.OperatorsSet(name=schema.OperatorSetNames.ADD, + qc_options=const_configuration_options_inout16) + sub = schema.OperatorsSet(name=schema.OperatorSetNames.SUB, + qc_options=const_configuration_options_inout16) + mul = schema.OperatorsSet(name=schema.OperatorSetNames.MUL, + qc_options=const_configuration_options_inout16) + div = schema.OperatorsSet(name=schema.OperatorSetNames.DIV, qc_options=const_configuration_options) + swish = schema.OperatorsSet(name=schema.OperatorSetNames.SWISH) + hard_swish = schema.OperatorsSet(name=schema.OperatorSetNames.HARDSWISH) + sigmoid = schema.OperatorsSet(name=schema.OperatorSetNames.SIGMOID) + tanh = schema.OperatorsSet(name=schema.OperatorSetNames.TANH) + hard_tanh = schema.OperatorsSet(name=schema.OperatorSetNames.HARD_TANH) + + operator_set.extend( + [conv, conv_transpose, depthwise_conv, fc, relu, relu6, leaky_relu, add, sub, mul, div, prelu, swish, hard_swish, sigmoid, + tanh, hard_tanh]) + any_relu = schema.OperatorSetConcat(operators_set=[relu, relu6, leaky_relu, hard_tanh]) + + # Combine multiple operators into a single operator to avoid quantization between + # them. To do this, we define fusing patterns using the OperatorsSets that were created. + # To group multiple sets with regard to fusing, an OperatorSetConcat can be created + activations_after_conv_to_fuse = schema.OperatorSetConcat(operators_set=[relu, relu6, leaky_relu, hard_tanh, swish, hard_swish, prelu, sigmoid, tanh]) + conv_types = schema.OperatorSetConcat(operators_set=[conv, conv_transpose, depthwise_conv]) + activations_after_fc_to_fuse = schema.OperatorSetConcat(operators_set=[relu, relu6, leaky_relu, hard_tanh, swish, hard_swish, sigmoid]) + any_binary = schema.OperatorSetConcat(operators_set=[add, sub, mul, div]) + + # ------------------- # + # Fusions + # ------------------- # + fusing_patterns.append(schema.Fusing(operator_groups=(conv_types, activations_after_conv_to_fuse))) + fusing_patterns.append(schema.Fusing(operator_groups=(fc, activations_after_fc_to_fuse))) + fusing_patterns.append(schema.Fusing(operator_groups=(any_binary, any_relu))) + + # Create a TargetPlatformModel and set its default quantization config. + # This default configuration will be used for all operations + # unless specified otherwise (see OperatorsSet, for example): + generated_tpm = schema.TargetPlatformModel( + default_qco=default_configuration_options, + tpc_minor_version=3, + tpc_patch_version=0, + tpc_platform_type=IMX500_TP_MODEL, + operator_set=tuple(operator_set), + fusing_patterns=tuple(fusing_patterns), + add_metadata=True, + name=name, + is_simd_padding=True) + + return generated_tpm diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v3_lut/__init__.py b/tests/common_tests/helpers/tpcs_for_tests/v3_lut/__init__.py similarity index 100% rename from model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v3_lut/__init__.py rename to tests/common_tests/helpers/tpcs_for_tests/v3_lut/__init__.py diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v3_lut/tp_model.py b/tests/common_tests/helpers/tpcs_for_tests/v3_lut/tp_model.py similarity index 58% rename from model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v3_lut/tp_model.py rename to tests/common_tests/helpers/tpcs_for_tests/v3_lut/tp_model.py index 438544c56..c238f6002 100644 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v3_lut/tp_model.py +++ b/tests/common_tests/helpers/tpcs_for_tests/v3_lut/tp_model.py @@ -153,7 +153,8 @@ def generate_tp_model(default_config: OpQuantizationConfig, # of possible configurations to consider when quantizing a set of operations (in mixed-precision, for example). # If the QuantizationConfigOptions contains only one configuration, # this configuration will be used for the operation quantization: - default_configuration_options = schema.QuantizationConfigOptions(quantization_configurations=tuple([default_config])) + default_configuration_options = schema.QuantizationConfigOptions( + quantization_configurations=tuple([default_config])) # Create a QuantizationConfigOptions for quantizing constants in functional ops. # Constant configuration is similar to the default eight bit configuration except for PoT @@ -166,8 +167,20 @@ def generate_tp_model(default_config: OpQuantizationConfig, weights_quantization_method=tp.QuantizationMethod.POWER_OF_TWO)) const_configuration_options = schema.QuantizationConfigOptions(quantization_configurations=tuple([const_config])) + # 16 bits inputs and outputs. Currently, only defined for consts since they are used in operators that + # support 16 bit as input and output. + const_config_input16 = const_config.clone_and_edit( + supported_input_activation_n_bits=(8, 16)) + const_config_input16_output16 = const_config_input16.clone_and_edit( + activation_n_bits=16, signedness=Signedness.SIGNED) + const_configuration_options_inout16 = schema.QuantizationConfigOptions(quantization_configurations= + tuple([const_config_input16_output16, + const_config_input16]), + base_config=const_config_input16) + # Create Mixed-Precision quantization configuration options from the given list of OpQuantizationConfig objects - mixed_precision_configuration_options = schema.QuantizationConfigOptions(quantization_configurations=tuple(mixed_precision_cfg_list), + mixed_precision_configuration_options = schema.QuantizationConfigOptions(quantization_configurations= + tuple(mixed_precision_cfg_list), base_config=base_config) # Create an OperatorsSet to represent a set of operations. @@ -178,39 +191,113 @@ def generate_tp_model(default_config: OpQuantizationConfig, operator_set = [] fusing_patterns = [] # May suit for operations like: Dropout, Reshape, etc. - operator_set.append(schema.OperatorsSet(name="NoQuantization", - qc_options=default_configuration_options.clone_and_edit( - enable_activation_quantization=False) - .clone_and_edit_weight_attribute(enable_weights_quantization=False))) + + no_quantization_config = default_configuration_options.clone_and_edit( + enable_activation_quantization=False, + supported_input_activation_n_bits=(8, 16)).clone_and_edit_weight_attribute(enable_weights_quantization=False) + + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.UNSTACK, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.DROPOUT, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.FLATTEN, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.SPLIT_CHUNK, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.GET_ITEM, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.RESHAPE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.UNSQUEEZE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.BATCH_NORM, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.SIZE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.PERMUTE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.TRANSPOSE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.EQUAL, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.ARGMAX, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.GATHER, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.TOPK, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.SQUEEZE, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.MAXPOOL, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.PAD, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.ZERO_PADDING2D, qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.CAST, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.COMBINED_NON_MAX_SUPPRESSION, + qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.FAKE_QUANT, + qc_options=no_quantization_config)) + operator_set.append( + schema.OperatorsSet(name=schema.OperatorSetNames.STRIDED_SLICE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SSD_POST_PROCESS, + qc_options=no_quantization_config)) + + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.STACK, + qc_options=const_configuration_options_inout16)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.CONCATENATE, + qc_options=const_configuration_options_inout16)) # Define operator sets that use mixed_precision_configuration_options: - conv = schema.OperatorsSet(name="Conv", qc_options=mixed_precision_configuration_options) - fc = schema.OperatorsSet(name="FullyConnected", qc_options=mixed_precision_configuration_options) - - # Define operations sets without quantization configuration - # options (useful for creating fusing patterns, for example): - any_relu = schema.OperatorsSet(name="AnyReLU") - add = schema.OperatorsSet(name="Add", qc_options=const_configuration_options) - sub = schema.OperatorsSet(name="Sub", qc_options=const_configuration_options) - mul = schema.OperatorsSet(name="Mul", qc_options=const_configuration_options) - div = schema.OperatorsSet(name="Div", qc_options=const_configuration_options) - prelu = schema.OperatorsSet(name="PReLU") - swish = schema.OperatorsSet(name="Swish") - sigmoid = schema.OperatorsSet(name="Sigmoid") - tanh = schema.OperatorsSet(name="Tanh") - - operator_set.extend([conv, fc, any_relu, add, sub, mul, div, prelu, swish, sigmoid, tanh]) + conv = schema.OperatorsSet(name=schema.OperatorSetNames.CONV, + qc_options=mixed_precision_configuration_options) + conv_transpose = schema.OperatorsSet(name=schema.OperatorSetNames.CONV_TRANSPOSE, + qc_options=mixed_precision_configuration_options) + depthwise_conv = schema.OperatorsSet(name=schema.OperatorSetNames.DEPTHWISE_CONV, + qc_options=mixed_precision_configuration_options) + fc = schema.OperatorsSet(name=schema.OperatorSetNames.FULLY_CONNECTED, + qc_options=mixed_precision_configuration_options) + + # Define operations sets without quantization configuration options (useful for creating fusing patterns): + relu = schema.OperatorsSet(name=schema.OperatorSetNames.RELU) + relu6 = schema.OperatorsSet(name=schema.OperatorSetNames.RELU6) + leaky_relu = schema.OperatorsSet(name=schema.OperatorSetNames.LEAKY_RELU) + prelu = schema.OperatorsSet(name=schema.OperatorSetNames.PRELU) + add = schema.OperatorsSet(name=schema.OperatorSetNames.ADD, + qc_options=const_configuration_options_inout16) + sub = schema.OperatorsSet(name=schema.OperatorSetNames.SUB, + qc_options=const_configuration_options_inout16) + mul = schema.OperatorsSet(name=schema.OperatorSetNames.MUL, + qc_options=const_configuration_options_inout16) + div = schema.OperatorsSet(name=schema.OperatorSetNames.DIV, qc_options=const_configuration_options) + swish = schema.OperatorsSet(name=schema.OperatorSetNames.SWISH) + hard_swish = schema.OperatorsSet(name=schema.OperatorSetNames.HARDSWISH) + sigmoid = schema.OperatorsSet(name=schema.OperatorSetNames.SIGMOID) + tanh = schema.OperatorsSet(name=schema.OperatorSetNames.TANH) + hard_tanh = schema.OperatorsSet(name=schema.OperatorSetNames.HARD_TANH) + + operator_set.extend( + [conv, conv_transpose, depthwise_conv, fc, relu, relu6, leaky_relu, add, sub, mul, div, prelu, swish, + hard_swish, sigmoid, + tanh, hard_tanh]) + any_relu = schema.OperatorSetConcat(operators_set=[relu, relu6, leaky_relu, hard_tanh]) + # Combine multiple operators into a single operator to avoid quantization between - # them. To do this we define fusing patterns using the OperatorsSets that were created. + # them. To do this, we define fusing patterns using the OperatorsSets that were created. # To group multiple sets with regard to fusing, an OperatorSetConcat can be created - activations_after_conv_to_fuse = schema.OperatorSetConcat(operators_set=[any_relu, swish, prelu, sigmoid, tanh]) - activations_after_fc_to_fuse = schema.OperatorSetConcat(operators_set=[any_relu, swish, sigmoid]) + activations_after_conv_to_fuse = schema.OperatorSetConcat( + operators_set=[relu, relu6, leaky_relu, hard_tanh, swish, hard_swish, prelu, sigmoid, tanh]) + conv_types = schema.OperatorSetConcat(operators_set=[conv, conv_transpose, depthwise_conv]) + activations_after_fc_to_fuse = schema.OperatorSetConcat( + operators_set=[relu, relu6, leaky_relu, hard_tanh, swish, hard_swish, sigmoid]) any_binary = schema.OperatorSetConcat(operators_set=[add, sub, mul, div]) # ------------------- # # Fusions # ------------------- # - fusing_patterns.append(schema.Fusing(operator_groups=(conv, activations_after_conv_to_fuse))) + fusing_patterns.append(schema.Fusing(operator_groups=(conv_types, activations_after_conv_to_fuse))) fusing_patterns.append(schema.Fusing(operator_groups=(fc, activations_after_fc_to_fuse))) fusing_patterns.append(schema.Fusing(operator_groups=(any_binary, any_relu))) @@ -225,6 +312,7 @@ def generate_tp_model(default_config: OpQuantizationConfig, operator_set=tuple(operator_set), fusing_patterns=tuple(fusing_patterns), add_metadata=True, - name=name) + name=name, + is_simd_padding=True) return generated_tpm diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v4/__init__.py b/tests/common_tests/helpers/tpcs_for_tests/v4/__init__.py similarity index 100% rename from model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v4/__init__.py rename to tests/common_tests/helpers/tpcs_for_tests/v4/__init__.py diff --git a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v4/tp_model.py b/tests/common_tests/helpers/tpcs_for_tests/v4/tp_model.py similarity index 64% rename from model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v4/tp_model.py rename to tests/common_tests/helpers/tpcs_for_tests/v4/tp_model.py index 2038e6eba..ec5dc46f3 100644 --- a/model_compression_toolkit/target_platform_capabilities/tpc_models/imx500_tpc/v4/tp_model.py +++ b/tests/common_tests/helpers/tpcs_for_tests/v4/tp_model.py @@ -25,30 +25,6 @@ tp = mct.target_platform -OPSET_NO_QUANTIZATION = "NoQuantization" -OPSET_QUANTIZATION_PRESERVING = "QuantizationPreserving" -OPSET_DIMENSION_MANIPULATION_OPS_WITH_WEIGHTS = "DimensionManipulationOpsWithWeights" -OPSET_DIMENSION_MANIPULATION_OPS = "DimensionManipulationOps" -OPSET_SPLIT_OPS = "SplitOps" -OPSET_MERGE_OPS = "MergeOps" -OPSET_CONV = "Conv" -OPSET_FULLY_CONNECTED = "FullyConnected" -OPSET_BATCH_NORM = "BatchNorm" -OPSET_ANY_RELU = "AnyReLU" -OPSET_ADD = "Add" -OPSET_SUB = "Sub" -OPSET_MUL = "Mul" -OPSET_DIV = "Div" -OPSET_MIN_MAX = "MinMax" -OPSET_PRELU = "PReLU" -OPSET_SWISH = "Swish" -OPSET_SIGMOID = "Sigmoid" -OPSET_TANH = "Tanh" -OPSET_GELU = "Gelu" -OPSET_HARDSIGMOID = "HardSigmoid" -OPSET_HARDSWISH = "HardSwish" - - def get_tp_model() -> TargetPlatformModel: """ A method that generates a default target platform model, with base 8-bit quantization configuration and 8, 4, 2 @@ -187,16 +163,6 @@ def generate_tp_model(default_config: OpQuantizationConfig, signedness=Signedness.SIGNED)]), base_config=default_config_input16) - qpreseving_config = default_config.clone_and_edit(enable_activation_quantization=False, - quantization_preserving=True, - supported_input_activation_n_bits=(8, 16)) - - qpreseving_config_options = schema.QuantizationConfigOptions(quantization_configurations=tuple([qpreseving_config, - qpreseving_config.clone_and_edit( - activation_n_bits=16, - signedness=Signedness.SIGNED)]), - base_config=qpreseving_config) - # Create a QuantizationConfigOptions for quantizing constants in functional ops. # Constant configuration is similar to the default eight bit configuration except for PoT # quantization method for the constant. @@ -214,10 +180,9 @@ def generate_tp_model(default_config: OpQuantizationConfig, supported_input_activation_n_bits=(8, 16)) const_config_input16_output16 = const_config_input16.clone_and_edit( activation_n_bits=16, signedness=Signedness.SIGNED) - const_configuration_options_inout16 = schema.QuantizationConfigOptions( - quantization_configurations=tuple([const_config_input16_output16, - const_config_input16]), - base_config=const_config_input16) + const_configuration_options_inout16 = schema.QuantizationConfigOptions(quantization_configurations=tuple([const_config_input16_output16, + const_config_input16]), + base_config=const_config_input16) const_config_input16_per_tensor = const_config.clone_and_edit( supported_input_activation_n_bits=(8, 16), @@ -242,8 +207,8 @@ def generate_tp_model(default_config: OpQuantizationConfig, for mp_cfg in mixed_precision_cfg_list] # Create Mixed-Precision quantization configuration options from the given list of OpQuantizationConfig objects - mixed_precision_configuration_options = schema.QuantizationConfigOptions(quantization_configurations=tuple( - mixed_precision_cfg_list + mp_cfg_list_16bit), + mixed_precision_configuration_options = schema.QuantizationConfigOptions( + quantization_configurations=tuple(mixed_precision_cfg_list + mp_cfg_list_16bit), base_config=base_config) # Create an OperatorsSet to represent a set of operations. @@ -254,64 +219,94 @@ def generate_tp_model(default_config: OpQuantizationConfig, operator_set = [] fusing_patterns = [] # May suit for operations like: Dropout, Reshape, etc. - operator_set.append(schema.OperatorsSet(name=OPSET_NO_QUANTIZATION, - qc_options=default_configuration_options.clone_and_edit( - enable_activation_quantization=False) - .clone_and_edit_weight_attribute(enable_weights_quantization=False))) - operator_set.append(schema.OperatorsSet(name=OPSET_QUANTIZATION_PRESERVING, - qc_options=default_configuration_options.clone_and_edit( - enable_activation_quantization=False, - quantization_preserving=True) - .clone_and_edit_weight_attribute(enable_weights_quantization=False))) - operator_set.append( - schema.OperatorsSet(name=OPSET_DIMENSION_MANIPULATION_OPS_WITH_WEIGHTS, - qc_options=qpreserving_const_config_options)) - operator_set.append(schema.OperatorsSet(name=OPSET_DIMENSION_MANIPULATION_OPS, - qc_options=default_configuration_options.clone_and_edit( - enable_activation_quantization=False, - quantization_preserving=True, - supported_input_activation_n_bits=(8, 16)) - .clone_and_edit_weight_attribute(enable_weights_quantization=False))) - - operator_set.append(schema.OperatorsSet(name=OPSET_SPLIT_OPS, qc_options=qpreseving_config_options)) - operator_set.append(schema.OperatorsSet(name=OPSET_MERGE_OPS, qc_options=const_configuration_options_inout16_per_tensor)) - - # Define operator sets that use mixed_precision_configuration_options: - conv = schema.OperatorsSet(name=OPSET_CONV, qc_options=mixed_precision_configuration_options) - fc = schema.OperatorsSet(name=OPSET_FULLY_CONNECTED, qc_options=mixed_precision_configuration_options) - - operator_set.append(schema.OperatorsSet(name=OPSET_BATCH_NORM, qc_options=default_config_options_16bit)) - - # Note: Operations sets without quantization configuration are useful for creating fusing patterns - any_relu = schema.OperatorsSet(name=OPSET_ANY_RELU, qc_options=default_config_options_16bit) - add = schema.OperatorsSet(name=OPSET_ADD, qc_options=const_configuration_options_inout16) - sub = schema.OperatorsSet(name=OPSET_SUB, qc_options=const_configuration_options_inout16) - mul = schema.OperatorsSet(name=OPSET_MUL, qc_options=const_configuration_options_inout16) - div = schema.OperatorsSet(name=OPSET_DIV, qc_options=const_configuration_options) - min_max = schema.OperatorsSet(name=OPSET_MIN_MAX, qc_options=const_configuration_options_inout16) - prelu = schema.OperatorsSet(name=OPSET_PRELU, qc_options=default_config_options_16bit) - swish = schema.OperatorsSet(name=OPSET_SWISH, qc_options=default_config_options_16bit) - sigmoid = schema.OperatorsSet(name=OPSET_SIGMOID, qc_options=default_config_options_16bit) - tanh = schema.OperatorsSet(name=OPSET_TANH, qc_options=default_config_options_16bit) - gelu = schema.OperatorsSet(name=OPSET_GELU, qc_options=default_config_options_16bit) - hardsigmoid = schema.OperatorsSet(name=OPSET_HARDSIGMOID, qc_options=default_config_options_16bit) - hardswish = schema.OperatorsSet(name=OPSET_HARDSWISH, qc_options=default_config_options_16bit) + + no_quantization_config = (default_configuration_options.clone_and_edit(enable_activation_quantization=False) + .clone_and_edit_weight_attribute(enable_weights_quantization=False)) + + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SIZE, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.EQUAL, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.ARGMAX, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.TOPK, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.COMBINED_NON_MAX_SUPPRESSION, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.FAKE_QUANT, qc_options=no_quantization_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SSD_POST_PROCESS, qc_options=no_quantization_config)) + + quant_preserving_config = (default_configuration_options.clone_and_edit(enable_activation_quantization=False, + quantization_preserving=True) + .clone_and_edit_weight_attribute(enable_weights_quantization=False)) + + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.UNSTACK, qc_options=quant_preserving_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.DROPOUT, qc_options=quant_preserving_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SPLIT_CHUNK, qc_options=quant_preserving_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.GET_ITEM, qc_options=quant_preserving_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.MAXPOOL, qc_options=quant_preserving_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.PAD, qc_options=quant_preserving_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.ZERO_PADDING2D, qc_options=quant_preserving_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.CAST, qc_options=quant_preserving_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.STRIDED_SLICE, qc_options=quant_preserving_config)) + + dim_manipulation_config = (default_configuration_options.clone_and_edit(enable_activation_quantization=False, + quantization_preserving=True, + supported_input_activation_n_bits=(8, 16)) + .clone_and_edit_weight_attribute(enable_weights_quantization=False)) + + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.FLATTEN, qc_options=dim_manipulation_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.RESHAPE, qc_options=dim_manipulation_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.UNSQUEEZE, qc_options=dim_manipulation_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.SQUEEZE, qc_options=dim_manipulation_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.PERMUTE, qc_options=dim_manipulation_config)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.TRANSPOSE, qc_options=dim_manipulation_config)) + + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.GATHER, qc_options=qpreserving_const_config_options)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.EXPAND, qc_options=qpreserving_const_config_options)) + + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.STACK, qc_options=const_configuration_options_inout16_per_tensor)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.CONCATENATE, qc_options=const_configuration_options_inout16_per_tensor)) + + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.BATCH_NORM, qc_options=default_config_options_16bit)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.MIN, qc_options=default_config_options_16bit)) + operator_set.append(schema.OperatorsSet(name=schema.OperatorSetNames.MAX, qc_options=default_config_options_16bit)) + + conv = schema.OperatorsSet(name=schema.OperatorSetNames.CONV, qc_options=mixed_precision_configuration_options) + conv_transpose = schema.OperatorsSet(name=schema.OperatorSetNames.CONV_TRANSPOSE, qc_options=mixed_precision_configuration_options) + depthwise_conv = schema.OperatorsSet(name=schema.OperatorSetNames.DEPTHWISE_CONV, qc_options=mixed_precision_configuration_options) + fc = schema.OperatorsSet(name=schema.OperatorSetNames.FULLY_CONNECTED, qc_options=mixed_precision_configuration_options) + + relu = schema.OperatorsSet(name=schema.OperatorSetNames.RELU, qc_options=default_config_options_16bit) + relu6 = schema.OperatorsSet(name=schema.OperatorSetNames.RELU6, qc_options=default_config_options_16bit) + leaky_relu = schema.OperatorsSet(name=schema.OperatorSetNames.LEAKY_RELU, qc_options=default_config_options_16bit) + prelu = schema.OperatorsSet(name=schema.OperatorSetNames.PRELU, qc_options=default_config_options_16bit) + add = schema.OperatorsSet(name=schema.OperatorSetNames.ADD, qc_options=const_configuration_options_inout16) + sub = schema.OperatorsSet(name=schema.OperatorSetNames.SUB, qc_options=const_configuration_options_inout16) + mul = schema.OperatorsSet(name=schema.OperatorSetNames.MUL, qc_options=const_configuration_options_inout16) + div = schema.OperatorsSet(name=schema.OperatorSetNames.DIV, qc_options=const_configuration_options) + swish = schema.OperatorsSet(name=schema.OperatorSetNames.SWISH, qc_options=default_config_options_16bit) + hardswish = schema.OperatorsSet(name=schema.OperatorSetNames.HARDSWISH, qc_options=default_config_options_16bit) + sigmoid = schema.OperatorsSet(name=schema.OperatorSetNames.SIGMOID, qc_options=default_config_options_16bit) + hardsigmoid = schema.OperatorsSet(name=schema.OperatorSetNames.HARDSIGMOID, qc_options=default_config_options_16bit) + gelu = schema.OperatorsSet(name=schema.OperatorSetNames.GELU, qc_options=default_config_options_16bit) + tanh = schema.OperatorsSet(name=schema.OperatorSetNames.TANH, qc_options=default_config_options_16bit) + hard_tanh = schema.OperatorsSet(name=schema.OperatorSetNames.HARD_TANH, qc_options=default_config_options_16bit) operator_set.extend( - [conv, fc, any_relu, add, sub, mul, div, prelu, swish, sigmoid, tanh, min_max, gelu, hardsigmoid, hardswish]) + [conv, conv_transpose, depthwise_conv, fc, relu, relu6, leaky_relu, add, sub, mul, div, prelu, swish, hardswish, sigmoid, + tanh, gelu, hardsigmoid, hard_tanh]) + any_relu = schema.OperatorSetConcat(operators_set=[relu, relu6, leaky_relu, hard_tanh]) + # Combine multiple operators into a single operator to avoid quantization between # them. To do this we define fusing patterns using the OperatorsSets that were created. # To group multiple sets with regard to fusing, an OperatorSetConcat can be created - activations_after_conv_to_fuse = schema.OperatorSetConcat(operators_set=[any_relu, swish, prelu, sigmoid, - tanh, gelu, hardswish, hardsigmoid]) - activations_after_fc_to_fuse = schema.OperatorSetConcat(operators_set=[any_relu, swish, sigmoid, tanh, gelu, + activations_after_conv_to_fuse = schema.OperatorSetConcat( + operators_set=[relu, relu6, leaky_relu, hard_tanh, swish, gelu, hardswish, hardsigmoid, prelu, sigmoid, tanh]) + conv_types = schema.OperatorSetConcat(operators_set=[conv, conv_transpose, depthwise_conv]) + activations_after_fc_to_fuse = schema.OperatorSetConcat(operators_set=[relu, relu6, leaky_relu, hard_tanh, swish, sigmoid, tanh, gelu, hardswish, hardsigmoid]) any_binary = schema.OperatorSetConcat(operators_set=[add, sub, mul, div]) # ------------------- # # Fusions # ------------------- # - fusing_patterns.append(schema.Fusing(operator_groups=(conv, activations_after_conv_to_fuse))) + fusing_patterns.append(schema.Fusing(operator_groups=(conv_types, activations_after_conv_to_fuse))) fusing_patterns.append(schema.Fusing(operator_groups=(fc, activations_after_fc_to_fuse))) fusing_patterns.append(schema.Fusing(operator_groups=(any_binary, any_relu))) diff --git a/tests/keras_tests/custom_layers_tests/test_sony_ssd_postprocess_layer.py b/tests/keras_tests/custom_layers_tests/test_sony_ssd_postprocess_layer.py index 44f3e0e63..14c19057b 100644 --- a/tests/keras_tests/custom_layers_tests/test_sony_ssd_postprocess_layer.py +++ b/tests/keras_tests/custom_layers_tests/test_sony_ssd_postprocess_layer.py @@ -20,6 +20,7 @@ import model_compression_toolkit as mct from sony_custom_layers.keras.object_detection.ssd_post_process import SSDPostProcess from mct_quantizers.keras.metadata import MetadataLayer +from tests.common_tests.helpers.tpcs_for_tests.v4.tp_model import get_tp_model keras = tf.keras layers = keras.layers @@ -54,7 +55,9 @@ def test_custom_layer(self): q_model, _ = mct.ptq.keras_post_training_quantization(model, get_rep_dataset(2, (1, 8, 8, 3)), core_config=core_config, - target_resource_utilization=mct.core.ResourceUtilization(weights_memory=6000)) + target_resource_utilization=mct.core.ResourceUtilization(weights_memory=6000), + target_platform_capabilities=get_tp_model() + ) # verify the custom layer is in the quantized model last_model_layer_index = -2 if isinstance(q_model.layers[-1], MetadataLayer) else -1 diff --git a/tests/keras_tests/exporter_tests/tflite_int8/imx500_int8_tp_model.py b/tests/keras_tests/exporter_tests/tflite_int8/imx500_int8_tp_model.py index e40185c5e..46e612bec 100644 --- a/tests/keras_tests/exporter_tests/tflite_int8/imx500_int8_tp_model.py +++ b/tests/keras_tests/exporter_tests/tflite_int8/imx500_int8_tp_model.py @@ -34,6 +34,7 @@ import model_compression_toolkit as mct from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel, OpQuantizationConfig +from tests.common_tests.helpers.tpcs_for_tests.v1.tp_model import generate_tp_model tp = mct.target_platform @@ -62,60 +63,9 @@ def get_op_quantization_configs() -> Tuple[OpQuantizationConfig, List[OpQuantiza return eight_bits, mixed_precision_cfg_list, default_config -def generate_tp_model(default_config: OpQuantizationConfig, - base_config: OpQuantizationConfig, - mixed_precision_cfg_list: List[OpQuantizationConfig], - name: str) -> TargetPlatformModel: - default_configuration_options = schema.QuantizationConfigOptions(quantization_configurations=tuple( - [default_config])) - - mixed_precision_configuration_options = schema.QuantizationConfigOptions(quantization_configurations=tuple(mixed_precision_cfg_list), - base_config=base_config) - - operator_set, fusing_patterns = [], [] - - operator_set.append(schema.OperatorsSet(name="NoQuantization", - qc_options=default_configuration_options - .clone_and_edit(enable_activation_quantization=False) - .clone_and_edit_weight_attribute(enable_weights_quantization=False))) - - conv = schema.OperatorsSet(name="Conv", qc_options=mixed_precision_configuration_options) - fc = schema.OperatorsSet(name="FullyConnected", qc_options=mixed_precision_configuration_options) - - any_relu = schema.OperatorsSet(name="AnyReLU") - add = schema.OperatorsSet(name="Add") - sub = schema.OperatorsSet(name="Sub") - mul = schema.OperatorsSet(name="Mul") - div = schema.OperatorsSet(name="Div") - prelu = schema.OperatorsSet(name="PReLU") - swish = schema.OperatorsSet(name="Swish") - sigmoid = schema.OperatorsSet(name="Sigmoid") - tanh = schema.OperatorsSet(name="Tanh") - - operator_set.extend([conv, fc, any_relu, add, sub, mul, div, prelu, swish, sigmoid, tanh]) - - activations_after_conv_to_fuse = schema.OperatorSetConcat(operators_set=(any_relu, swish, prelu, sigmoid, tanh)) - activations_after_fc_to_fuse = schema.OperatorSetConcat(operators_set=(any_relu, swish, sigmoid)) - any_binary = schema.OperatorSetConcat(operators_set=(add, sub, mul, div)) - - fusing_patterns.append(schema.Fusing(operator_groups=(conv, activations_after_conv_to_fuse))) - fusing_patterns.append(schema.Fusing(operator_groups=(fc, activations_after_fc_to_fuse))) - fusing_patterns.append(schema.Fusing(operator_groups=(any_binary, any_relu))) - - generated_tpc = schema.TargetPlatformModel( - default_qco=default_configuration_options, - tpc_minor_version=None, - tpc_patch_version=None, - tpc_platform_type=None, - operator_set=tuple(operator_set), - fusing_patterns=tuple(fusing_patterns), - add_metadata=False, name=name) - return generated_tpc - - -def get_int8_tpc(edit_weights_params_dict={}, edit_act_params_dict={}) -> tp.TargetPlatformCapabilities: +def get_int8_tpc(edit_weights_params_dict={}, edit_act_params_dict={}) -> tp.TargetPlatformModel: default_tp_model = get_tp_model(edit_weights_params_dict, edit_act_params_dict) - return generate_keras_tpc(name='int8_tpc', tp_model=default_tp_model) + return default_tp_model def generate_keras_tpc(name: str, tp_model: schema.TargetPlatformModel): diff --git a/tests/keras_tests/feature_networks_tests/feature_networks/activation_16bit_test.py b/tests/keras_tests/feature_networks_tests/feature_networks/activation_16bit_test.py index 9db95aa7f..1e9a44c8c 100644 --- a/tests/keras_tests/feature_networks_tests/feature_networks/activation_16bit_test.py +++ b/tests/keras_tests/feature_networks_tests/feature_networks/activation_16bit_test.py @@ -20,6 +20,12 @@ from model_compression_toolkit.core import MixedPrecisionQuantizationConfig from model_compression_toolkit.target_platform_capabilities.constants import IMX500_TP_MODEL from mct_quantizers.keras.activation_quantization_holder import KerasActivationQuantizationHolder +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import OperatorSetNames, \ + QuantizationConfigOptions +from model_compression_toolkit.target_platform_capabilities.schema.schema_functions import \ + get_config_options_by_operators_set +from tests.common_tests.helpers.generate_test_tp_model import generate_custom_test_tp_model +from tests.common_tests.helpers.tpcs_for_tests.v4.tp_model import get_tp_model from tests.keras_tests.feature_networks_tests.base_keras_feature_test import BaseKerasFeatureNetworkTest from tests.keras_tests.utils import get_layers_from_model_by_type @@ -33,13 +39,21 @@ class Activation16BitTest(BaseKerasFeatureNetworkTest): def get_tpc(self): - tpc = mct.get_target_platform_capabilities(TENSORFLOW, IMX500_TP_MODEL, 'v4') - # Force Mul base_config to 16bit only - mul_op_set = get_op_set('Mul', tpc.tp_model.operator_set) - base_config = [l for l in mul_op_set.qc_options.quantization_configurations if l.activation_n_bits == 16][0] - tpc.layer2qco[tf.multiply] = tpc.layer2qco[tf.multiply].copy(update= - {'quantization_configurations': mul_op_set.qc_options.quantization_configurations, - 'base_config': base_config}) + tpc = get_tp_model() + base_cfg_16 = [c for c in get_config_options_by_operators_set(tpc, + OperatorSetNames.MUL).quantization_configurations + if c.activation_n_bits == 16][0].clone_and_edit() + qco_16 = QuantizationConfigOptions(base_config=base_cfg_16, + quantization_configurations=(tpc.default_qco.base_config, + base_cfg_16)) + tpc = generate_custom_test_tp_model( + name="custom_16_bit_tpc", + base_cfg=tpc.default_qco.base_config, + base_tp_model=tpc, + operator_sets_dict={ + OperatorSetNames.MUL: qco_16, + }) + return tpc def create_networks(self): @@ -69,15 +83,26 @@ def compare(self, quantized_model, float_model, input_x=None, quantization_info= class Activation16BitMixedPrecisionTest(Activation16BitTest): def get_tpc(self): - tpc = mct.get_target_platform_capabilities(TENSORFLOW, IMX500_TP_MODEL, 'v3') - mul_op_set = get_op_set('Mul', tpc.tp_model.operator_set) - base_config = [l for l in mul_op_set.qc_options.quantization_configurations if l.activation_n_bits == 16][0] - quantization_configurations = list(tpc.layer2qco[tf.multiply].quantization_configurations) + tpc = get_tp_model() + + mul_qco = get_config_options_by_operators_set(tpc, OperatorSetNames.MUL) + base_cfg_16 = [l for l in mul_qco.quantization_configurations if l.activation_n_bits == 16][0] + quantization_configurations = list(mul_qco.quantization_configurations) quantization_configurations.extend([ - tpc.layer2qco[tf.multiply].base_config.clone_and_edit(activation_n_bits=4), - tpc.layer2qco[tf.multiply].base_config.clone_and_edit(activation_n_bits=2)]) - tpc.layer2qco[tf.multiply] = tpc.layer2qco[tf.multiply].copy( - update={'base_config': base_config, 'quantization_configurations': tuple(quantization_configurations)}) + base_cfg_16.clone_and_edit(activation_n_bits=4), + base_cfg_16.clone_and_edit(activation_n_bits=2)]) + + qco_16 = QuantizationConfigOptions(base_config=base_cfg_16, + quantization_configurations=quantization_configurations) + + tpc = generate_custom_test_tp_model( + name="custom_16_bit_tpc", + base_cfg=tpc.default_qco.base_config, + base_tp_model=tpc, + operator_sets_dict={ + OperatorSetNames.MUL: qco_16, + }) + return tpc def get_resource_utilization(self): diff --git a/tests/keras_tests/feature_networks_tests/feature_networks/bn_attributes_quantization_test.py b/tests/keras_tests/feature_networks_tests/feature_networks/bn_attributes_quantization_test.py index c15ddb199..52b957f2d 100644 --- a/tests/keras_tests/feature_networks_tests/feature_networks/bn_attributes_quantization_test.py +++ b/tests/keras_tests/feature_networks_tests/feature_networks/bn_attributes_quantization_test.py @@ -22,6 +22,7 @@ from model_compression_toolkit.core.keras.constants import GAMMA, BETA from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import Signedness from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, KERAS_KERNEL, BIAS, BIAS_ATTR +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers from tests.common_tests.helpers.generate_test_tp_model import generate_test_attr_configs, \ DEFAULT_WEIGHT_ATTR_CONFIG, KERNEL_BASE_CONFIG, generate_test_op_qc, BIAS_CONFIG from tests.keras_tests.feature_networks_tests.base_keras_feature_test import BaseKerasFeatureNetworkTest @@ -93,23 +94,6 @@ def _generate_bn_quantized_tpm(quantize_linear): return generated_tpm -def _generate_bn_quantized_tpc(tp_model): - tpc = tp.TargetPlatformCapabilities(tp_model) - - with tpc: - tp.OperationsSetToLayers("Conv", [layers.Conv2D], - attr_mapping={ - KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}) - - tp.OperationsSetToLayers("BN", [layers.BatchNormalization], - attr_mapping={ - GAMMA: DefaultDict(default_value=GAMMA), - BETA: DefaultDict(default_value=BETA)}) - - return tpc - - class BNAttributesQuantization(BaseKerasFeatureNetworkTest): def __init__(self, unit_test, quantize_linear, input_shape=(8, 8, 3)): @@ -119,10 +103,14 @@ def __init__(self, unit_test, quantize_linear, input_shape=(8, 8, 3)): def get_tpc(self): tpm = _generate_bn_quantized_tpm(self.quantize_linear) - return _generate_bn_quantized_tpc(tpm) + return tpm def get_quantization_config(self): - return mct.core.QuantizationConfig(weights_bias_correction=True) + return mct.core.QuantizationConfig(weights_bias_correction=True, + custom_tpc_opset_to_layer={ + 'BN': CustomOpsetLayers([layers.BatchNormalization], { + GAMMA: DefaultDict(default_value=GAMMA), + BETA: DefaultDict(default_value=BETA)})}) def create_networks(self): inputs = layers.Input(shape=self.get_input_shapes()[0][1:]) diff --git a/tests/keras_tests/feature_networks_tests/feature_networks/bn_folding_test.py b/tests/keras_tests/feature_networks_tests/feature_networks/bn_folding_test.py index 86ef34ee2..bf51d0bfb 100644 --- a/tests/keras_tests/feature_networks_tests/feature_networks/bn_folding_test.py +++ b/tests/keras_tests/feature_networks_tests/feature_networks/bn_folding_test.py @@ -17,13 +17,10 @@ from abc import ABC from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import generate_keras_tpc -from tests.common_tests.base_feature_test import BaseFeatureNetworkTest import model_compression_toolkit as mct import tensorflow as tf -from tests.common_tests.base_layer_test import LayerTestMode from tests.common_tests.helpers.generate_test_tp_model import generate_test_tp_model -from tests.keras_tests.tpc_keras import get_16bit_tpc from tests.keras_tests.feature_networks_tests.base_keras_feature_test import BaseKerasFeatureNetworkTest import numpy as np from tests.common_tests.helpers.tensors_compare import cosine_similarity, normalized_mse diff --git a/tests/keras_tests/feature_networks_tests/feature_networks/compute_max_cut_test.py b/tests/keras_tests/feature_networks_tests/feature_networks/compute_max_cut_test.py index d6c0ff98e..d256ca67c 100644 --- a/tests/keras_tests/feature_networks_tests/feature_networks/compute_max_cut_test.py +++ b/tests/keras_tests/feature_networks_tests/feature_networks/compute_max_cut_test.py @@ -19,6 +19,7 @@ from mct_quantizers.keras.metadata import get_metadata from model_compression_toolkit.constants import TENSORFLOW from model_compression_toolkit.target_platform_capabilities.constants import IMX500_TP_MODEL +from tests.common_tests.helpers.tpcs_for_tests.v2.tp_model import get_tp_model from tests.keras_tests.feature_networks_tests.base_keras_feature_test import BaseKerasFeatureNetworkTest keras = tf.keras @@ -41,7 +42,7 @@ def create_networks(self): return keras.Model(inputs=inputs, outputs=outputs) def get_tpc(self): - return mct.get_target_platform_capabilities(TENSORFLOW, IMX500_TP_MODEL, "v2") + return get_tp_model() def get_debug_config(self): return mct.core.DebugConfig(simulate_scheduler=True) diff --git a/tests/keras_tests/feature_networks_tests/feature_networks/const_quantization_test.py b/tests/keras_tests/feature_networks_tests/feature_networks/const_quantization_test.py index 1e87d6fe5..128fa0a9d 100644 --- a/tests/keras_tests/feature_networks_tests/feature_networks/const_quantization_test.py +++ b/tests/keras_tests/feature_networks_tests/feature_networks/const_quantization_test.py @@ -19,18 +19,16 @@ import model_compression_toolkit as mct import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema from model_compression_toolkit.core import MixedPrecisionQuantizationConfig -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v4.tp_model import generate_tp_model, \ - get_op_quantization_configs -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v4.tpc_keras import generate_keras_tpc -from tests.common_tests.helpers.generate_test_tp_model import generate_test_attr_configs, DEFAULT_WEIGHT_ATTR_CONFIG, \ - generate_test_tp_model, generate_custom_test_tp_model + +from tests.common_tests.helpers.generate_test_tp_model import generate_custom_test_tp_model +from tests.common_tests.helpers.tpcs_for_tests.v3.tp_model import get_tp_model as get_tp_v3 +from tests.common_tests.helpers.tpcs_for_tests.v4.tp_model import get_tp_model as get_tp_v4 +from tests.common_tests.helpers.tpcs_for_tests.v4.tp_model import generate_tp_model, get_op_quantization_configs from tests.keras_tests.feature_networks_tests.base_keras_feature_test import BaseKerasFeatureNetworkTest from tests.common_tests.helpers.tensors_compare import cosine_similarity from tests.keras_tests.utils import get_layers_from_model_by_type -from mct_quantizers import KerasQuantizationWrapper, QuantizationMethod +from mct_quantizers import KerasQuantizationWrapper -from model_compression_toolkit.constants import TENSORFLOW -from model_compression_toolkit.target_platform_capabilities.constants import IMX500_TP_MODEL keras = tf.keras layers = keras.layers @@ -56,18 +54,19 @@ def create_const_quant_tpc(qmethod): const_merge_configuration_options = schema.QuantizationConfigOptions(quantization_configurations=tuple([const_merge_config])) operator_sets_dict = {} - operator_sets_dict["Add"] = const_configuration_options - operator_sets_dict["Sub"] = const_configuration_options - operator_sets_dict["Mul"] = const_configuration_options - operator_sets_dict["Div"] = const_configuration_options - operator_sets_dict["MergeOps"] = const_merge_configuration_options + operator_sets_dict[schema.OperatorSetNames.ADD] = const_configuration_options + operator_sets_dict[schema.OperatorSetNames.SUB] = const_configuration_options + operator_sets_dict[schema.OperatorSetNames.MUL] = const_configuration_options + operator_sets_dict[schema.OperatorSetNames.DIV] = const_configuration_options + operator_sets_dict[schema.OperatorSetNames.STACK] = const_merge_configuration_options + operator_sets_dict[schema.OperatorSetNames.CONCATENATE] = const_merge_configuration_options tp_model = generate_custom_test_tp_model(name=name, base_cfg=base_cfg, base_tp_model=base_tp_model, operator_sets_dict=operator_sets_dict) - return generate_keras_tpc(name="const_quant_tpc", tp_model=tp_model) + return tp_model class ConstQuantizationTest(BaseKerasFeatureNetworkTest): @@ -152,7 +151,7 @@ def generate_inputs(self): return [1 + np.random.random(in_shape) for in_shape in self.get_input_shapes()] def get_tpc(self): - return mct.get_target_platform_capabilities(TENSORFLOW, IMX500_TP_MODEL, "v3") + return get_tp_v3() def create_networks(self): inputs = layers.Input(shape=self.get_input_shapes()[0][1:]) @@ -178,7 +177,7 @@ def __init__(self, unit_test, input_shape=(32, 32, 16)): super(ConstQuantizationMultiInputTest, self).__init__(unit_test=unit_test, input_shape=input_shape) def get_tpc(self): - return mct.get_target_platform_capabilities(TENSORFLOW, IMX500_TP_MODEL, "v4") + return get_tp_v4() def create_networks(self): as_const = lambda v: np.random.random(v.shape.as_list()).astype(np.float32) diff --git a/tests/keras_tests/feature_networks_tests/feature_networks/lut_quantizer.py b/tests/keras_tests/feature_networks_tests/feature_networks/lut_quantizer.py index b8165ad94..33f9a42bf 100644 --- a/tests/keras_tests/feature_networks_tests/feature_networks/lut_quantizer.py +++ b/tests/keras_tests/feature_networks_tests/feature_networks/lut_quantizer.py @@ -28,7 +28,7 @@ from mct_quantizers.common.constants import THRESHOLD, LUT_VALUES from tests.common_tests.helpers.generate_test_tp_model import generate_test_attr_configs, generate_test_op_qc, \ generate_test_tp_model -from tests.keras_tests.exporter_tests.tflite_int8.imx500_int8_tp_model import generate_keras_tpc +from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import generate_keras_tpc from tests.keras_tests.feature_networks_tests.base_keras_feature_test import BaseKerasFeatureNetworkTest from tests.keras_tests.utils import get_layers_from_model_by_type diff --git a/tests/keras_tests/feature_networks_tests/feature_networks/manual_bit_selection.py b/tests/keras_tests/feature_networks_tests/feature_networks/manual_bit_selection.py index a1ef4f410..eb83f903a 100644 --- a/tests/keras_tests/feature_networks_tests/feature_networks/manual_bit_selection.py +++ b/tests/keras_tests/feature_networks_tests/feature_networks/manual_bit_selection.py @@ -17,10 +17,15 @@ import model_compression_toolkit as mct from mct_quantizers import KerasActivationQuantizationHolder, KerasQuantizationWrapper -from model_compression_toolkit.constants import TENSORFLOW from model_compression_toolkit.core.common.network_editors import NodeNameFilter, NodeTypeFilter -from model_compression_toolkit.target_platform_capabilities.constants import IMX500_TP_MODEL -from tests.common_tests.helpers.generate_test_tp_model import generate_test_op_qc, generate_test_attr_configs +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import OperatorSetNames, \ + QuantizationConfigOptions +from model_compression_toolkit.target_platform_capabilities.schema.schema_functions import \ + get_config_options_by_operators_set +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers +from tests.common_tests.helpers.generate_test_tp_model import generate_test_op_qc, generate_test_attr_configs, \ + generate_custom_test_tp_model +from tests.common_tests.helpers.tpcs_for_tests.v3.tp_model import get_tp_model from tests.keras_tests.feature_networks_tests.base_keras_feature_test import BaseKerasFeatureNetworkTest from tests.keras_tests.tpc_keras import get_tpc_with_activation_mp_keras @@ -88,7 +93,8 @@ def get_tpc(self): def get_mp_core_config(self): qc = mct.core.QuantizationConfig(mct.core.QuantizationErrorMethod.MSE, mct.core.QuantizationErrorMethod.MSE, relu_bound_to_power_of_2=False, weights_bias_correction=True, - input_scaling=False, activation_channel_equalization=False) + input_scaling=False, activation_channel_equalization=False, + custom_tpc_opset_to_layer={'Input': CustomOpsetLayers([layers.InputLayer])}) mpc = mct.core.MixedPrecisionQuantizationConfig(num_of_images=1) core_config = mct.core.CoreConfig(quantization_config=qc, mixed_precision_config=mpc) @@ -130,13 +136,23 @@ class Manual16BitWidthSelectionTest(ManualBitWidthSelectionTest): Uses the manual bit width API in the "get_core_configs" method. """ def get_tpc(self): - tpc = mct.get_target_platform_capabilities(TENSORFLOW, IMX500_TP_MODEL, 'v3') - # Force Mul base_config to 16bit only - mul_op_set = get_op_set('Mul', tpc.tp_model.operator_set) - base_config = [l for l in mul_op_set.qc_options.quantization_configurations if l.activation_n_bits == 16][0] - tpc.layer2qco[tf.multiply] = tpc.layer2qco[tf.multiply].copy( - update={'quantization_configurations': mul_op_set.qc_options.quantization_configurations, - 'base_config': base_config}) + tpc = get_tp_model() + base_cfg_16 = [c for c in get_config_options_by_operators_set(tpc, + OperatorSetNames.MUL).quantization_configurations + if c.activation_n_bits == 16][0].clone_and_edit() + qco_16 = QuantizationConfigOptions(base_config=base_cfg_16, + quantization_configurations=(tpc.default_qco.base_config, + base_cfg_16)) + tpc = generate_custom_test_tp_model( + name="custom_16_bit_tpc", + base_cfg=tpc.default_qco.base_config, + base_tp_model=tpc, + operator_sets_dict={ + OperatorSetNames.MUL: qco_16, + OperatorSetNames.GELU: qco_16, + OperatorSetNames.TANH: qco_16, + }) + return tpc def create_networks(self): @@ -158,15 +174,26 @@ class Manual16BitWidthSelectionMixedPrecisionTest(Manual16BitWidthSelectionTest) Uses the manual bit width API in the "get_core_configs" method. """ def get_tpc(self): - tpc = mct.get_target_platform_capabilities(TENSORFLOW, IMX500_TP_MODEL, 'v3') - mul_op_set = get_op_set('Mul', tpc.tp_model.operator_set) - base_config = [l for l in mul_op_set.qc_options.quantization_configurations if l.activation_n_bits == 16][0] - quantization_configurations = list(tpc.layer2qco[tf.multiply].quantization_configurations) + tpc = get_tp_model() + + mul_qco = get_config_options_by_operators_set(tpc, OperatorSetNames.MUL) + base_cfg_16 = [l for l in mul_qco.quantization_configurations if l.activation_n_bits == 16][0] + quantization_configurations = list(mul_qco.quantization_configurations) quantization_configurations.extend([ - tpc.layer2qco[tf.multiply].base_config.clone_and_edit(activation_n_bits=4), - tpc.layer2qco[tf.multiply].base_config.clone_and_edit(activation_n_bits=2)]) - tpc.layer2qco[tf.multiply] = tpc.layer2qco[tf.multiply].copy( - update={'base_config': base_config, 'quantization_configurations': tuple(quantization_configurations)}) + base_cfg_16.clone_and_edit(activation_n_bits=4), + base_cfg_16.clone_and_edit(activation_n_bits=2)]) + + qco_16 = QuantizationConfigOptions(base_config=base_cfg_16, + quantization_configurations=quantization_configurations) + + tpc = generate_custom_test_tp_model( + name="custom_16_bit_tpc", + base_cfg=tpc.default_qco.base_config, + base_tp_model=tpc, + operator_sets_dict={ + OperatorSetNames.MUL: qco_16, + }) + return tpc def get_resource_utilization(self): diff --git a/tests/keras_tests/feature_networks_tests/feature_networks/metadata_test.py b/tests/keras_tests/feature_networks_tests/feature_networks/metadata_test.py index 4283e3002..4fc584055 100644 --- a/tests/keras_tests/feature_networks_tests/feature_networks/metadata_test.py +++ b/tests/keras_tests/feature_networks_tests/feature_networks/metadata_test.py @@ -17,6 +17,7 @@ import numpy as np import model_compression_toolkit as mct +from tests.common_tests.helpers.tpcs_for_tests.v2.tp_model import get_tp_model from tests.keras_tests.feature_networks_tests.base_keras_feature_test import BaseKerasFeatureNetworkTest from mct_quantizers.keras.metadata import add_metadata, get_metadata @@ -31,7 +32,7 @@ class MetadataTest(BaseKerasFeatureNetworkTest): def get_tpc(self): - return mct.get_target_platform_capabilities(TENSORFLOW, IMX500_TP_MODEL, "v2") + return get_tp_model() def create_networks(self): inputs = layers.Input(shape=self.get_input_shapes()[0][1:]) diff --git a/tests/keras_tests/feature_networks_tests/feature_networks/mixed_precision/requires_mixed_precision_test.py b/tests/keras_tests/feature_networks_tests/feature_networks/mixed_precision/requires_mixed_precision_test.py index 4b3ec493d..a82ddd149 100644 --- a/tests/keras_tests/feature_networks_tests/feature_networks/mixed_precision/requires_mixed_precision_test.py +++ b/tests/keras_tests/feature_networks_tests/feature_networks/mixed_precision/requires_mixed_precision_test.py @@ -14,6 +14,18 @@ # ============================================================================== import numpy as np +import tensorflow as tf + +from packaging import version + +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras + +if version.parse(tf.__version__) >= version.parse("2.13"): + from keras.src.engine.input_layer import InputLayer +else: + from keras.engine.input_layer import InputLayer from model_compression_toolkit.core import ResourceUtilization from model_compression_toolkit.core.common.mixed_precision.resource_utilization_tools.resource_utilization_data import \ @@ -54,10 +66,15 @@ def get_tpc(self): name="") def get_max_resources_for_model(self, model): + tpc = self.get_tpc() + cc = self.get_core_config() + attach2keras = AttachTpcToKeras() + tpc = attach2keras.attach(tpc, cc.quantization_config.custom_tpc_opset_to_layer) + return compute_resource_utilization_data(in_model=model, representative_data_gen=self.representative_data_gen(), - core_config=self.get_core_config(), - tpc=self.get_tpc(), + core_config=cc, + tpc=tpc, fw_info=DEFAULT_KERAS_INFO, fw_impl=KerasImplementation(), transformed_graph=None, @@ -69,7 +86,8 @@ def get_quantization_config(self): relu_bound_to_power_of_2=True, weights_bias_correction=True, input_scaling=False, - activation_channel_equalization=True) + activation_channel_equalization=True, + custom_tpc_opset_to_layer={"Input": CustomOpsetLayers([InputLayer])}) def get_resource_utilization(self): ru_data = self.get_max_resources_for_model(self.create_networks()) diff --git a/tests/keras_tests/feature_networks_tests/feature_networks/mixed_precision_bops_test.py b/tests/keras_tests/feature_networks_tests/feature_networks/mixed_precision_bops_test.py index a63983dbb..ac7933cc8 100644 --- a/tests/keras_tests/feature_networks_tests/feature_networks/mixed_precision_bops_test.py +++ b/tests/keras_tests/feature_networks_tests/feature_networks/mixed_precision_bops_test.py @@ -13,9 +13,11 @@ # limitations under the License. # ============================================================================== -from model_compression_toolkit.core import ResourceUtilization, MixedPrecisionQuantizationConfig +from model_compression_toolkit.core import ResourceUtilization, MixedPrecisionQuantizationConfig, CoreConfig, \ + QuantizationConfig from keras.layers import Conv2D, Conv2DTranspose, DepthwiseConv2D, Dense, BatchNormalization, ReLU, Input, Add +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers from tests.keras_tests.feature_networks_tests.base_keras_feature_test import BaseKerasFeatureNetworkTest from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import get_op_quantization_configs import tensorflow as tf @@ -38,6 +40,10 @@ def __init__(self, unit_test, mixed_precision_candidates_list): self.mixed_precision_candidates_list = mixed_precision_candidates_list + def get_core_config(self): + return CoreConfig(quantization_config=QuantizationConfig( + custom_tpc_opset_to_layer={"Input": CustomOpsetLayers([layers.InputLayer])})) + def get_tpc(self): base_config, _, default_config = get_op_quantization_configs() diff --git a/tests/keras_tests/feature_networks_tests/feature_networks/mixed_precision_tests.py b/tests/keras_tests/feature_networks_tests/feature_networks/mixed_precision_tests.py index 209a76653..9d9f4de4b 100644 --- a/tests/keras_tests/feature_networks_tests/feature_networks/mixed_precision_tests.py +++ b/tests/keras_tests/feature_networks_tests/feature_networks/mixed_precision_tests.py @@ -21,8 +21,10 @@ import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema from mct_quantizers import KerasActivationQuantizationHolder from model_compression_toolkit import DefaultDict +from model_compression_toolkit.core import QuantizationConfig, CoreConfig from model_compression_toolkit.core.keras.constants import SIGMOID, SOFTMAX, BIAS from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, BIAS_ATTR, KERAS_KERNEL +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers from tests.common_tests.helpers.generate_test_tp_model import generate_test_op_qc, generate_test_attr_configs from tests.keras_tests.exporter_tests.tflite_int8.imx500_int8_tp_model import get_op_quantization_configs from tests.keras_tests.feature_networks_tests.base_keras_feature_test import BaseKerasFeatureNetworkTest @@ -52,6 +54,10 @@ def __init__(self, unit_test, activation_layers_idx, num_calibration_iter=1): self.activation_layers_idx = activation_layers_idx + def get_core_config(self): + return CoreConfig(quantization_config=QuantizationConfig( + custom_tpc_opset_to_layer={"Input": CustomOpsetLayers([layers.InputLayer])})) + def get_tpc(self): eight_bits = generate_test_op_qc(**generate_test_attr_configs()) @@ -70,7 +76,8 @@ def get_quantization_config(self): relu_bound_to_power_of_2=False, weights_bias_correction=True, input_scaling=False, - activation_channel_equalization=False) + activation_channel_equalization=False, + custom_tpc_opset_to_layer={"Input": CustomOpsetLayers([layers.InputLayer])}) def get_mixed_precision_config(self): return mct.core.MixedPrecisionQuantizationConfig(num_of_images=1) @@ -549,6 +556,12 @@ def __init__(self, unit_test): def get_resource_utilization(self): return ResourceUtilization(np.inf, 767) + def get_core_config(self): + return CoreConfig(quantization_config=QuantizationConfig( + custom_tpc_opset_to_layer={"Softmax": CustomOpsetLayers([layers.Softmax, tf.nn.softmax, softmax, + tp.LayerFilterParams(layers.Activation, activation=SOFTMAX)]), + "Input": CustomOpsetLayers([layers.InputLayer])})) + def get_tpc(self): eight_bits = generate_test_op_qc(**generate_test_attr_configs()) @@ -557,13 +570,11 @@ def get_tpc(self): default_config = eight_bits.clone_and_edit(attr_weights_configs_mapping={}) - custom_opsets = {"Softmax": [layers.Softmax, tf.nn.softmax, softmax, - tp.LayerFilterParams(layers.Activation, activation=SOFTMAX)]} return get_tpc_with_activation_mp_keras(base_config=eight_bits, default_config=default_config, mp_bitwidth_candidates_list=mixed_precision_candidates_list, name="mixed_precision_activation_test", - custom_opsets=custom_opsets) + custom_opsets={'Softmax': mixed_precision_candidates_list}) def create_networks(self): inputs = layers.Input(shape=self.get_input_shapes()[0][1:]) @@ -587,6 +598,9 @@ def __init__(self, unit_test): def get_resource_utilization(self): return ResourceUtilization(np.inf, 767) + def get_core_config(self): + return CoreConfig(quantization_config=QuantizationConfig( + custom_tpc_opset_to_layer={"Input": CustomOpsetLayers([layers.InputLayer])})) def get_tpc(self): eight_bits = generate_test_op_qc(**generate_test_attr_configs()) @@ -599,7 +613,9 @@ def get_tpc(self): return get_tpc_with_activation_mp_keras(base_config=eight_bits, default_config=default_config, mp_bitwidth_candidates_list=mixed_precision_candidates_list, - name="mixed_precision_activation_test") + name="mixed_precision_activation_test", + custom_opsets={schema.OperatorSetNames.SIGMOID: + mixed_precision_candidates_list}) def create_networks(self): inputs = layers.Input(shape=self.get_input_shapes()[0][1:]) @@ -629,6 +645,13 @@ def create_networks(self): model = keras.Model(inputs=inputs, outputs=outputs) return model + def get_core_config(self): + return CoreConfig(quantization_config=QuantizationConfig( + custom_tpc_opset_to_layer={"Weights": CustomOpsetLayers([layers.Conv2D], + {KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), + BIAS_ATTR: DefaultDict(default_value=BIAS)}), + "Activations":CustomOpsetLayers([layers.ReLU, layers.Add])})) + def get_tpc(self): cfg, mixed_precision_cfg_list, _ = get_op_quantization_configs() @@ -663,22 +686,7 @@ def get_tpc(self): add_metadata=False, name="mp_activation_conf_weights_test") - keras_tpc = tp.TargetPlatformCapabilities(tp_model) - - with keras_tpc: - tp.OperationsSetToLayers( - "Weights", - [layers.Conv2D], - attr_mapping={KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)} - ) - - tp.OperationsSetToLayers( - "Activations", - [layers.ReLU, layers.Add] - ) - - return keras_tpc + return tp_model def get_resource_utilization(self): return ResourceUtilization(np.inf, 5407) diff --git a/tests/keras_tests/feature_networks_tests/feature_networks/network_editor/edit_qc_test.py b/tests/keras_tests/feature_networks_tests/feature_networks/network_editor/edit_qc_test.py index 89bfde7de..fb7408e70 100644 --- a/tests/keras_tests/feature_networks_tests/feature_networks/network_editor/edit_qc_test.py +++ b/tests/keras_tests/feature_networks_tests/feature_networks/network_editor/edit_qc_test.py @@ -34,6 +34,8 @@ from model_compression_toolkit.core.common.substitutions.apply_substitutions import substitute from model_compression_toolkit.core.graph_prep_runner import graph_preparation_runner from model_compression_toolkit.core.keras.constants import KERNEL +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras from tests.keras_tests.feature_networks_tests.base_keras_feature_test import BaseKerasFeatureNetworkTest from model_compression_toolkit.target_platform_capabilities.target_platform import QuantizationMethod @@ -48,6 +50,9 @@ def prepare_graph_for_first_network_editor(in_model, representative_data_gen, co if target_resource_utilization is not None: core_config.mixed_precision_config.set_mixed_precision_enable() + attach2keras = AttachTpcToKeras() + tpc = attach2keras.attach(tpc) + transformed_graph = graph_preparation_runner(in_model, representative_data_gen, core_config.quantization_config, diff --git a/tests/keras_tests/feature_networks_tests/feature_networks/qat/qat_test.py b/tests/keras_tests/feature_networks_tests/feature_networks/qat/qat_test.py index bd73659aa..fd27723ae 100644 --- a/tests/keras_tests/feature_networks_tests/feature_networks/qat/qat_test.py +++ b/tests/keras_tests/feature_networks_tests/feature_networks/qat/qat_test.py @@ -23,6 +23,7 @@ from mct_quantizers.common.base_inferable_quantizer import QuantizerID from mct_quantizers.common.get_all_subclasses import get_all_subclasses from mct_quantizers.keras.quantizers import BaseKerasInferableQuantizer +from model_compression_toolkit.core import QuantizationConfig, CustomOpsetLayers from model_compression_toolkit.qat.keras.quantizer.base_keras_qat_weight_quantizer import \ BaseKerasQATWeightTrainableQuantizer from model_compression_toolkit.trainable_infrastructure import TrainingMethod, KerasTrainableQuantizationWrapper, \ @@ -292,7 +293,9 @@ def __init__(self, unit_test, ru_weights=17919, ru_activation=5407, expected_mp_ def run_test(self, **kwargs): model_float = self.create_networks() - config = mct.core.CoreConfig() + config = mct.core.CoreConfig( + quantization_config=QuantizationConfig(custom_tpc_opset_to_layer={"Input": CustomOpsetLayers([layers.InputLayer])}) + ) qat_ready_model, quantization_info, custom_objects = mct.qat.keras_quantization_aware_training_init_experimental( model_float, self.representative_data_gen_experimental, diff --git a/tests/keras_tests/feature_networks_tests/feature_networks/second_moment_correction_test.py b/tests/keras_tests/feature_networks_tests/feature_networks/second_moment_correction_test.py index d22ee5ee0..86be4a2d8 100644 --- a/tests/keras_tests/feature_networks_tests/feature_networks/second_moment_correction_test.py +++ b/tests/keras_tests/feature_networks_tests/feature_networks/second_moment_correction_test.py @@ -38,6 +38,8 @@ from model_compression_toolkit.target_platform_capabilities.constants import DEFAULT_TP_MODEL from model_compression_toolkit.target_platform_capabilities.target_platform import QuantizationMethod from model_compression_toolkit.target_platform_capabilities.target_platform import TargetPlatformCapabilities +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import generate_keras_tpc from tests.common_tests.helpers.generate_test_tp_model import generate_test_tp_model from tests.keras_tests.feature_networks_tests.base_keras_feature_test import BaseKerasFeatureNetworkTest @@ -281,6 +283,9 @@ def prepare_graph(self, fw_impl = KerasImplementation() + attach2keras = AttachTpcToKeras() + target_platform_capabilities = attach2keras.attach(target_platform_capabilities) + # Ignore initialized hessian service as it is not used here tg, bit_widths_config, _, _ = core_runner(in_model=in_model, representative_data_gen=representative_data_gen, diff --git a/tests/keras_tests/feature_networks_tests/feature_networks/weights_mixed_precision_tests.py b/tests/keras_tests/feature_networks_tests/feature_networks/weights_mixed_precision_tests.py index 3a13d12b3..7854b6f99 100644 --- a/tests/keras_tests/feature_networks_tests/feature_networks/weights_mixed_precision_tests.py +++ b/tests/keras_tests/feature_networks_tests/feature_networks/weights_mixed_precision_tests.py @@ -19,10 +19,12 @@ import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema from mct_quantizers import KerasQuantizationWrapper +from model_compression_toolkit.core import CoreConfig, QuantizationConfig from model_compression_toolkit.core.keras.constants import KERNEL from model_compression_toolkit.defaultdict import DefaultDict from model_compression_toolkit.core.common.mixed_precision.distance_weighting import MpDistanceWeighting from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, KERAS_KERNEL, BIAS_ATTR, BIAS +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import \ get_op_quantization_configs, generate_keras_tpc from tests.common_tests.helpers.generate_test_tp_model import generate_test_op_qc, generate_test_attr_configs @@ -170,6 +172,15 @@ class MixedPrecisionSearchPartWeightsLayersTest(MixedPrecisionBaseTest): def __init__(self, unit_test): super().__init__(unit_test, val_batch_size=2) + def get_core_config(self): + return CoreConfig(quantization_config=QuantizationConfig( + custom_tpc_opset_to_layer={"Weights_fixed": CustomOpsetLayers([layers.Dense], + {KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), + BIAS_ATTR: DefaultDict(default_value=BIAS)}), + "Weights_mp": CustomOpsetLayers([layers.Conv2D], + {KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), + BIAS_ATTR: DefaultDict(default_value=BIAS)})})) + def get_tpc(self): # Building a TPC that gives Conv layers mixed precision candidates and Dense layers a fixed candidate. # Both layers that have weights to quantized, so we want to verify that finalizing the model is successful. @@ -198,24 +209,7 @@ def get_tpc(self): add_metadata=False, name="mp_part_weights_layers_test") - keras_tpc = tp.TargetPlatformCapabilities(tp_model) - - with keras_tpc: - tp.OperationsSetToLayers( - "Weights_fixed", - [layers.Dense], - attr_mapping={KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)} - ) - - tp.OperationsSetToLayers( - "Weights_mp", - [layers.Conv2D], - attr_mapping={KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)} - ) - - return keras_tpc + return tp_model def create_networks(self): inputs = layers.Input(shape=self.get_input_shapes()[0][1:]) @@ -489,6 +483,13 @@ class MixedPrecisionWeightsOnlyConfigurableActivationsTest(MixedPrecisionBaseTes def __init__(self, unit_test): super().__init__(unit_test) + def get_core_config(self): + return CoreConfig(quantization_config=QuantizationConfig( + custom_tpc_opset_to_layer={"Weights": CustomOpsetLayers([layers.Conv2D], + {KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), + BIAS_ATTR: DefaultDict(default_value=BIAS)}), + "Activations": CustomOpsetLayers([layers.ReLU, layers.Add],)})) + def create_networks(self): inputs = layers.Input(shape=self.get_input_shapes()[0][1:]) x = layers.Conv2D(32, 4)(inputs) @@ -531,22 +532,7 @@ def get_tpc(self): add_metadata=False, name="mp_weights_conf_act_test") - keras_tpc = tp.TargetPlatformCapabilities(tp_model) - - with keras_tpc: - tp.OperationsSetToLayers( - "Weights", - [layers.Conv2D], - attr_mapping={KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)} - ) - - tp.OperationsSetToLayers( - "Activations", - [layers.ReLU, layers.Add] - ) - - return keras_tpc + return tp_model def get_resource_utilization(self): return ResourceUtilization(1535) diff --git a/tests/keras_tests/feature_networks_tests/test_features_runner.py b/tests/keras_tests/feature_networks_tests/test_features_runner.py index b59e4096c..00492c1a9 100644 --- a/tests/keras_tests/feature_networks_tests/test_features_runner.py +++ b/tests/keras_tests/feature_networks_tests/test_features_runner.py @@ -864,13 +864,6 @@ def test_metadata(self): def test_keras_tpcs(self): TpcTest(f'{C.IMX500_TP_MODEL}.v1', self).run_test() - TpcTest(f'{C.IMX500_TP_MODEL}.v1_lut', self).run_test() - TpcTest(f'{C.IMX500_TP_MODEL}.v1_pot', self).run_test() - TpcTest(f'{C.IMX500_TP_MODEL}.v2', self).run_test() - TpcTest(f'{C.IMX500_TP_MODEL}.v2_lut', self).run_test() - TpcTest(f'{C.IMX500_TP_MODEL}.v3', self).run_test() - TpcTest(f'{C.IMX500_TP_MODEL}.v3_lut', self).run_test() - TpcTest(f'{C.IMX500_TP_MODEL}.v4', self).run_test() TpcTest(f'{C.TFLITE_TP_MODEL}.v1', self).run_test() TpcTest(f'{C.QNNPACK_TP_MODEL}.v1', self).run_test() diff --git a/tests/keras_tests/function_tests/test_activation_quantization_holder_gptq.py b/tests/keras_tests/function_tests/test_activation_quantization_holder_gptq.py index 316215016..8385b4cf1 100644 --- a/tests/keras_tests/function_tests/test_activation_quantization_holder_gptq.py +++ b/tests/keras_tests/function_tests/test_activation_quantization_holder_gptq.py @@ -11,6 +11,8 @@ from model_compression_toolkit.core.keras.default_framework_info import DEFAULT_KERAS_INFO from model_compression_toolkit.gptq.keras.gptq_keras_implementation import GPTQKerasImplemantation from model_compression_toolkit.gptq.keras.gptq_training import KerasGPTQTrainer +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import generate_keras_tpc from tests.common_tests.helpers.prep_graph_for_func_test import prepare_graph_with_quantization_parameters @@ -77,6 +79,7 @@ def _get_gptq_model(self, input_shape, get_model_fn): representative_dataset, generate_keras_tpc, (1,) + input_shape, + attach2fw=AttachTpcToKeras(), mixed_precision_enabled=False) graph = set_bit_widths(mixed_precision_enable=False, graph=graph) diff --git a/tests/keras_tests/function_tests/test_activation_weights_composition_substitution.py b/tests/keras_tests/function_tests/test_activation_weights_composition_substitution.py index d959d4948..f88f9f271 100644 --- a/tests/keras_tests/function_tests/test_activation_weights_composition_substitution.py +++ b/tests/keras_tests/function_tests/test_activation_weights_composition_substitution.py @@ -20,13 +20,15 @@ from packaging import version import tensorflow as tf -from model_compression_toolkit.core.common.quantization.bit_width_config import BitWidthConfig +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras from tests.common_tests.helpers.generate_test_tp_model import generate_test_op_qc, generate_test_attr_configs if version.parse(tf.__version__) >= version.parse("2.13"): - from keras.src.layers import Conv2D, Conv2DTranspose, DepthwiseConv2D, Dense, BatchNormalization, ReLU, Input, Add + from keras.src.layers import Conv2D, Conv2DTranspose, DepthwiseConv2D, Dense, BatchNormalization, ReLU, Input, Add, InputLayer else: - from keras.layers import Conv2D, Conv2DTranspose, DepthwiseConv2D, Dense, BatchNormalization, ReLU, Input, Add + from keras.layers import Conv2D, Conv2DTranspose, DepthwiseConv2D, Dense, BatchNormalization, ReLU, Input, Add, InputLayer import numpy as np from model_compression_toolkit.core import DEFAULTCONFIG, MixedPrecisionQuantizationConfig @@ -98,7 +100,7 @@ def representative_dataset(): def prepare_graph(in_model, keras_impl, mixed_precision_candidates_list, base_config, default_config): fw_info = DEFAULT_KERAS_INFO - qc = mct.core.QuantizationConfig() + qc = mct.core.QuantizationConfig(custom_tpc_opset_to_layer={"Input": CustomOpsetLayers([InputLayer])}) graph = keras_impl.model_reader(in_model, representative_dataset) # model reading @@ -107,6 +109,9 @@ def prepare_graph(in_model, keras_impl, mixed_precision_candidates_list, base_co mp_bitwidth_candidates_list=mixed_precision_candidates_list, name="activation_weights_composition_test") + attach2keras = AttachTpcToKeras() + tpc = attach2keras.attach(tpc, qc.custom_tpc_opset_to_layer) + graph.set_fw_info(fw_info) graph.set_tpc(tpc) diff --git a/tests/keras_tests/function_tests/test_cfg_candidates_filter.py b/tests/keras_tests/function_tests/test_cfg_candidates_filter.py index c0838b0a8..421ee46ba 100644 --- a/tests/keras_tests/function_tests/test_cfg_candidates_filter.py +++ b/tests/keras_tests/function_tests/test_cfg_candidates_filter.py @@ -15,11 +15,11 @@ import keras import unittest -from tensorflow.keras.layers import Conv2D, ReLU, Input +from tensorflow.keras.layers import Conv2D, ReLU, Input, InputLayer import model_compression_toolkit as mct from model_compression_toolkit.constants import FLOAT_BITWIDTH -from model_compression_toolkit.core.common.quantization.bit_width_config import BitWidthConfig +from model_compression_toolkit.core import CustomOpsetLayers from model_compression_toolkit.core.common.quantization.filter_nodes_candidates import filter_nodes_candidates from model_compression_toolkit.core.common.quantization.set_node_quantization_config import \ set_quantization_configuration_to_graph @@ -27,6 +27,8 @@ from model_compression_toolkit.core.keras.default_framework_info import DEFAULT_KERAS_INFO from model_compression_toolkit.core.keras.keras_implementation import KerasImplementation from model_compression_toolkit.core.common.fusion.layer_fusing import fusion +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras from tests.common_tests.helpers.generate_test_tp_model import generate_test_attr_configs, generate_test_op_qc from tests.keras_tests.tpc_keras import get_tpc_with_activation_mp_keras @@ -48,6 +50,10 @@ def prepare_graph(in_model, base_config, default_config, bitwidth_candidates): fw_info = DEFAULT_KERAS_INFO keras_impl = KerasImplementation() graph = keras_impl.model_reader(in_model, None) # model reading + + attach2keras = AttachTpcToKeras() + tpc = attach2keras.attach(tpc, custom_opset2layer={"Input": CustomOpsetLayers([InputLayer])}) + graph.set_tpc(tpc) graph.set_fw_info(fw_info) graph = set_quantization_configuration_to_graph(graph=graph, diff --git a/tests/keras_tests/function_tests/test_custom_layer.py b/tests/keras_tests/function_tests/test_custom_layer.py index f31101b92..e82e89884 100644 --- a/tests/keras_tests/function_tests/test_custom_layer.py +++ b/tests/keras_tests/function_tests/test_custom_layer.py @@ -19,8 +19,11 @@ import model_compression_toolkit as mct import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema +from model_compression_toolkit.core import CoreConfig, QuantizationConfig from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import Signedness from model_compression_toolkit.target_platform_capabilities.constants import BIAS_ATTR, KERNEL_ATTR +from model_compression_toolkit.target_platform_capabilities.target_platform import LayerFilterParams +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers from tests.common_tests.helpers.generate_test_tp_model import generate_test_attr_configs, DEFAULT_WEIGHT_ATTR_CONFIG, \ KERNEL_BASE_CONFIG, BIAS_CONFIG @@ -88,13 +91,8 @@ def get_tpc(): tpc_patch_version=None, tpc_platform_type=None, add_metadata=False) - tpc = tp.TargetPlatformCapabilities(tp_model) - with tpc: - # No need to quantize Flatten and Dropout layers - tp.OperationsSetToLayers("NoQuantization", [CustomIdentity, - tp.LayerFilterParams(CustomIdentityWithArg, dummy_arg=0), ]) - return tpc + return tp_model class TestCustomLayer(unittest.TestCase): @@ -105,8 +103,14 @@ def test_custom_layer_in_tpc(self): x = CustomIdentityWithArg(0)(x) model = keras.Model(inputs=inputs, outputs=x) + core_cfg = CoreConfig(quantization_config=QuantizationConfig( + custom_tpc_opset_to_layer={"NoQuantization": + CustomOpsetLayers([CustomIdentity, + LayerFilterParams(CustomIdentityWithArg, dummy_arg=0)])})) + q_model, _ = mct.ptq.keras_post_training_quantization(model, lambda: [np.random.randn(1, 3, 3, 3)], + core_config=core_cfg, target_platform_capabilities=get_tpc()) # verify the custom layer is in the quantized model diff --git a/tests/keras_tests/function_tests/test_hessian_info_calculator.py b/tests/keras_tests/function_tests/test_hessian_info_calculator.py index 6ab6a58fb..ff07cb44d 100644 --- a/tests/keras_tests/function_tests/test_hessian_info_calculator.py +++ b/tests/keras_tests/function_tests/test_hessian_info_calculator.py @@ -28,6 +28,8 @@ from model_compression_toolkit.core.keras.data_util import data_gen_to_dataloader from model_compression_toolkit.core.keras.default_framework_info import DEFAULT_KERAS_INFO from model_compression_toolkit.core.keras.keras_implementation import KerasImplementation +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import generate_keras_tpc from tests.common_tests.helpers.prep_graph_for_func_test import prepare_graph_with_configs @@ -111,7 +113,8 @@ def _setup(self, layer, input_shape=(1, 16, 16, 3)): keras_impl, DEFAULT_KERAS_INFO, _repr_dataset, - generate_keras_tpc) + generate_keras_tpc, + attach2fw=AttachTpcToKeras()) return graph, _repr_dataset, keras_impl @@ -232,7 +235,8 @@ def test_reused_layer(self): keras_impl, DEFAULT_KERAS_INFO, _repr_dataset, - generate_keras_tpc) + generate_keras_tpc, + attach2fw=AttachTpcToKeras()) sorted_graph_nodes = graph.get_topo_sorted_nodes() @@ -275,7 +279,8 @@ def _test_advanced_graph(self, float_model, _repr_dataset): keras_impl, DEFAULT_KERAS_INFO, _repr_dataset, - generate_keras_tpc) + generate_keras_tpc, + attach2fw=AttachTpcToKeras()) sorted_graph_nodes = graph.get_topo_sorted_nodes() @@ -408,7 +413,8 @@ def test_reused_layer(self): keras_impl, DEFAULT_KERAS_INFO, _repr_dataset, - generate_keras_tpc) + generate_keras_tpc, + attach2fw=AttachTpcToKeras()) sorted_graph_nodes = graph.get_topo_sorted_nodes() @@ -453,7 +459,8 @@ def _test_advanced_graph(self, float_model, _repr_dataset): keras_impl, DEFAULT_KERAS_INFO, _repr_dataset, - generate_keras_tpc) + generate_keras_tpc, + attach2fw=AttachTpcToKeras()) sorted_graph_nodes = graph.get_topo_sorted_nodes() diff --git a/tests/keras_tests/function_tests/test_hessian_service.py b/tests/keras_tests/function_tests/test_hessian_service.py index 2acc85200..a651674e5 100644 --- a/tests/keras_tests/function_tests/test_hessian_service.py +++ b/tests/keras_tests/function_tests/test_hessian_service.py @@ -25,6 +25,8 @@ from model_compression_toolkit.core.keras.data_util import data_gen_to_dataloader from model_compression_toolkit.core.keras.default_framework_info import DEFAULT_KERAS_INFO from model_compression_toolkit.core.keras.keras_implementation import KerasImplementation +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import generate_keras_tpc from tests.common_tests.helpers.prep_graph_for_func_test import prepare_graph_with_configs @@ -72,7 +74,8 @@ def setUp(self): self.keras_impl, DEFAULT_KERAS_INFO, get_representative_dataset_fn(), - generate_keras_tpc) + generate_keras_tpc, + attach2fw=AttachTpcToKeras()) self.hessian_service = HessianInfoService(graph=self.graph, fw_impl=self.keras_impl) @@ -162,7 +165,8 @@ def test_fetch_multiple_nodes(self): self.keras_impl, DEFAULT_KERAS_INFO, get_representative_dataset_fn(), - generate_keras_tpc) + generate_keras_tpc, + attach2fw=AttachTpcToKeras()) self.hessian_service = HessianInfoService(graph=self.graph, fw_impl=self.keras_impl) diff --git a/tests/keras_tests/function_tests/test_hmse_error_method.py b/tests/keras_tests/function_tests/test_hmse_error_method.py index 82d895d8a..39558f643 100644 --- a/tests/keras_tests/function_tests/test_hmse_error_method.py +++ b/tests/keras_tests/function_tests/test_hmse_error_method.py @@ -31,6 +31,9 @@ from model_compression_toolkit.core.keras.constants import KERNEL, GAMMA from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, BIAS_ATTR, KERAS_KERNEL, BIAS from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import AttributeQuantizationConfig +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import generate_keras_tpc from model_compression_toolkit.core.keras.default_framework_info import DEFAULT_KERAS_INFO from model_compression_toolkit.core.keras.keras_implementation import KerasImplementation @@ -69,14 +72,22 @@ def get_tpc(quant_method, per_channel): tp = generate_test_tp_model(edit_params_dict={ 'weights_quantization_method': quant_method, 'weights_per_channel_threshold': per_channel}) - tpc = generate_keras_tpc(name="hmse_params_selection_test", tp_model=tp) - return tpc + return tp class TestParamSelectionWithHMSE(unittest.TestCase): def _setup_with_args(self, quant_method, per_channel, running_gptq=True, tpc_fn=get_tpc, model_gen_fn=model_gen): - self.qc = QuantizationConfig(weights_error_method=mct.core.QuantizationErrorMethod.HMSE) + self.qc = QuantizationConfig(weights_error_method=mct.core.QuantizationErrorMethod.HMSE, + custom_tpc_opset_to_layer={ + "Linear": CustomOpsetLayers([layers.Conv2D, layers.Dense], + {KERNEL_ATTR: DefaultDict( + default_value=KERAS_KERNEL), + BIAS_ATTR: DefaultDict( + default_value=BIAS)}), + "BN": CustomOpsetLayers([layers.BatchNormalization], + {GAMMA: DefaultDict(default_value=GAMMA)})}) + self.float_model = model_gen_fn() self.keras_impl = KerasImplementation() self.fw_info = DEFAULT_KERAS_INFO @@ -87,7 +98,8 @@ def _setup_with_args(self, quant_method, per_channel, running_gptq=True, tpc_fn= representative_dataset, lambda name, _tp: tpc_fn(quant_method, per_channel), qc=self.qc, - running_gptq=running_gptq + running_gptq=running_gptq, + attach2fw=AttachTpcToKeras() # to enable HMSE in params calculation if needed ) @@ -182,27 +194,12 @@ def _generate_bn_quantization_tpc(quant_method, per_channel): tpc_minor_version=None, tpc_patch_version=None, tpc_platform_type=None, - operator_set=tuple([schema.OperatorsSet(name="Linear", qc_options=conv_qco), - schema.OperatorsSet(name="BN", qc_options=bn_qco)]), + operator_set=tuple( + [schema.OperatorsSet(name="Linear", qc_options=conv_qco), + schema.OperatorsSet(name="BN", qc_options=bn_qco)]), add_metadata=False) - tpc = tp.TargetPlatformCapabilities(tp_model) - - with tpc: - tp.OperationsSetToLayers( - "Linear", - [layers.Conv2D, layers.Dense], - attr_mapping={KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)} - ) - - tp.OperationsSetToLayers( - "BN", - [layers.BatchNormalization], - attr_mapping={GAMMA: DefaultDict(default_value=GAMMA)} - ) - - return tpc + return tp_model self._setup_with_args(quant_method=mct.target_platform.QuantizationMethod.SYMMETRIC, per_channel=True, tpc_fn=_generate_bn_quantization_tpc, model_gen_fn=no_bn_fusion_model_gen) diff --git a/tests/keras_tests/function_tests/test_layer_fusing.py b/tests/keras_tests/function_tests/test_layer_fusing.py index 1a2713a08..730f78115 100644 --- a/tests/keras_tests/function_tests/test_layer_fusing.py +++ b/tests/keras_tests/function_tests/test_layer_fusing.py @@ -3,13 +3,13 @@ import tensorflow as tf import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema -from model_compression_toolkit.core import DEFAULTCONFIG +from model_compression_toolkit.core import DEFAULTCONFIG, QuantizationConfig from model_compression_toolkit.core.common.fusion.layer_fusing import fusion -from model_compression_toolkit.core.common.quantization.set_node_quantization_config import \ - set_quantization_configuration_to_graph -from model_compression_toolkit.core.common.substitutions.apply_substitutions import substitute from model_compression_toolkit.core.keras.default_framework_info import DEFAULT_KERAS_INFO from model_compression_toolkit.core.keras.keras_implementation import KerasImplementation +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import \ get_op_quantization_configs import model_compression_toolkit as mct @@ -107,14 +107,7 @@ def get_tpc_1(): generated_tp = generate_base_tpc(operator_set, fusing_patterns) - keras_tpc = tp.TargetPlatformCapabilities(generated_tp) - with keras_tpc: - tp.OperationsSetToLayers("Conv", [Conv2D]) - tp.OperationsSetToLayers("AnyReLU", [tf.nn.relu, - tp.LayerFilterParams(ReLU, negative_slope=0.0), - tp.LayerFilterParams(Activation, activation="relu")]) - return keras_tpc - + return generated_tp def get_tpc_2(): base_config, mixed_precision_cfg_list, default_config = get_op_quantization_configs() @@ -132,17 +125,7 @@ def get_tpc_2(): generated_tp = generate_base_tpc(operator_set, fusing_patterns) - keras_tpc = tp.TargetPlatformCapabilities(generated_tp) - with keras_tpc: - tp.OperationsSetToLayers("Conv", [Conv2D, DepthwiseConv2D]) - tp.OperationsSetToLayers("AnyReLU", [tf.nn.relu, - tp.LayerFilterParams(ReLU, negative_slope=0.0), - tp.LayerFilterParams(Activation, activation="relu")]) - tp.OperationsSetToLayers("Swish", [tf.nn.swish, tp.LayerFilterParams(Activation, activation="swish")]) - tp.OperationsSetToLayers("Sigmoid", [tf.nn.sigmoid, tp.LayerFilterParams(Activation, activation="sigmoid")]) - tp.OperationsSetToLayers("Tanh", [tf.nn.tanh, tp.LayerFilterParams(Activation, activation="tanh")]) - return keras_tpc - + return generated_tp def get_tpc_3(): base_config, mixed_precision_cfg_list, default_config = get_op_quantization_configs() @@ -156,13 +139,7 @@ def get_tpc_3(): generated_tp = generate_base_tpc(operator_set, fusing_patterns) - keras_tpc = tp.TargetPlatformCapabilities(generated_tp) - with keras_tpc: - tp.OperationsSetToLayers("Conv", [Conv2D]) - tp.OperationsSetToLayers("AnyReLU", [tf.nn.relu, - tp.LayerFilterParams(ReLU, negative_slope=0.0), - tp.LayerFilterParams(Activation, activation="relu")]) - return keras_tpc + return generated_tp def get_tpc_4(): @@ -184,17 +161,7 @@ def get_tpc_4(): generated_tp = generate_base_tpc(operator_set, fusing_patterns) - keras_tpc = tp.TargetPlatformCapabilities(generated_tp) - with keras_tpc: - tp.OperationsSetToLayers("Conv", [Conv2D]) - tp.OperationsSetToLayers("FullyConnected", [Dense]) - tp.OperationsSetToLayers("AnyReLU", [tf.nn.relu, - tp.LayerFilterParams(ReLU, negative_slope=0.0), - tp.LayerFilterParams(Activation, activation="relu")]) - tp.OperationsSetToLayers("Add", [tf.add, Add]) - tp.OperationsSetToLayers("Swish", [tf.nn.swish, tp.LayerFilterParams(Activation, activation="swish")]) - - return keras_tpc + return generated_tp def get_type(fusion): @@ -216,8 +183,14 @@ def test_layer_fusing_1(self): expected_fusions = [[Conv2D, Activation]] model = create_network_1(INPUT_SHAPE) + qc = QuantizationConfig(custom_tpc_opset_to_layer={"Conv": CustomOpsetLayers([Conv2D]), + "AnyReLU": CustomOpsetLayers([tf.nn.relu, + tp.LayerFilterParams(ReLU, negative_slope=0.0), + tp.LayerFilterParams(Activation, activation="relu")])}) + fusion_graph = prepare_graph_with_configs(model, KerasImplementation(), DEFAULT_KERAS_INFO, - representative_dataset, lambda name, _tp: get_tpc_1()) + representative_dataset, lambda name, _tp: get_tpc_1(), + attach2fw=AttachTpcToKeras(), qc=qc) self._compare(fusion_graph.fused_nodes, expected_fusions) @@ -225,8 +198,21 @@ def test_layer_fusing_2(self): expected_fusions = [[Conv2D, Activation], [Conv2D, ReLU], [Conv2D, tf.nn.sigmoid], [Conv2D, Activation]] model = create_network_2(INPUT_SHAPE) + qc = QuantizationConfig(custom_tpc_opset_to_layer={"Conv": CustomOpsetLayers([Conv2D]), + "AnyReLU": CustomOpsetLayers([tf.nn.relu, + tp.LayerFilterParams(ReLU, negative_slope=0.0), + tp.LayerFilterParams(Activation, + activation="relu")]), + "Swish": CustomOpsetLayers([tf.nn.swish, tp.LayerFilterParams(Activation, + activation="swish")]), + "Sigmoid": CustomOpsetLayers([tf.nn.sigmoid, tp.LayerFilterParams(Activation, + activation="sigmoid")]), + "Tanh": CustomOpsetLayers([tf.nn.tanh, tp.LayerFilterParams(Activation, + activation="tanh")])}) + fusion_graph = prepare_graph_with_configs(model, KerasImplementation(), DEFAULT_KERAS_INFO, - representative_dataset, lambda name, _tp: get_tpc_2()) + representative_dataset, lambda name, _tp: get_tpc_2(), + attach2fw=AttachTpcToKeras(), qc=qc) self._compare(fusion_graph.fused_nodes, expected_fusions) @@ -234,8 +220,15 @@ def test_layer_fusing_3(self): expected_fusions = [[Conv2D, Activation]] model = create_network_3(INPUT_SHAPE) + qc = QuantizationConfig(custom_tpc_opset_to_layer={"Conv": CustomOpsetLayers([Conv2D]), + "AnyReLU": CustomOpsetLayers([tf.nn.relu, + tp.LayerFilterParams(ReLU, negative_slope=0.0), + tp.LayerFilterParams(Activation, + activation="relu")])}) + fusion_graph = prepare_graph_with_configs(model, KerasImplementation(), DEFAULT_KERAS_INFO, - representative_dataset, lambda name, _tp: get_tpc_3()) + representative_dataset, lambda name, _tp: get_tpc_3(), + attach2fw=AttachTpcToKeras(), qc=qc) self._compare(fusion_graph.fused_nodes, expected_fusions) @@ -244,7 +237,19 @@ def test_layer_fusing_4(self): [Conv2D, ReLU, Add], [Dense, tf.nn.silu], [Dense, Activation]] model = create_network_4(INPUT_SHAPE) + qc = QuantizationConfig(custom_tpc_opset_to_layer={ + "Conv": CustomOpsetLayers([Conv2D]), + "FullyConnected": CustomOpsetLayers([Dense]), + "AnyReLU": CustomOpsetLayers([tf.nn.relu, + tp.LayerFilterParams(ReLU, negative_slope=0.0), + tp.LayerFilterParams(Activation, + activation="relu")]), + "Add": CustomOpsetLayers([tf.add, Add]), + "Swish": CustomOpsetLayers([tf.nn.swish, tp.LayerFilterParams(Activation, activation="swish")]), + }) + fusion_graph = prepare_graph_with_configs(model, KerasImplementation(), DEFAULT_KERAS_INFO, - representative_dataset, lambda name, _tp: get_tpc_4()) + representative_dataset, lambda name, _tp: get_tpc_4(), + attach2fw=AttachTpcToKeras(), qc=qc) self._compare(fusion_graph.fused_nodes, expected_fusions) diff --git a/tests/keras_tests/function_tests/test_quant_config_filtering.py b/tests/keras_tests/function_tests/test_quant_config_filtering.py index 9a85527d3..281009a4c 100644 --- a/tests/keras_tests/function_tests/test_quant_config_filtering.py +++ b/tests/keras_tests/function_tests/test_quant_config_filtering.py @@ -13,13 +13,20 @@ # limitations under the License. # ============================================================================== import unittest -import model_compression_toolkit as mct -from model_compression_toolkit.constants import THRESHOLD, TENSORFLOW -from model_compression_toolkit.target_platform_capabilities.constants import IMX500_TP_MODEL from model_compression_toolkit.core.common.graph.functional_node import FunctionalNode from model_compression_toolkit.core.keras.constants import FUNCTION import tensorflow as tf + +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import OperatorSetNames, \ + QuantizationConfigOptions +from model_compression_toolkit.target_platform_capabilities.schema.schema_functions import \ + get_config_options_by_operators_set +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras +from tests.common_tests.helpers.generate_test_tp_model import generate_custom_test_tp_model +from tests.common_tests.helpers.tpcs_for_tests.v3.tp_model import get_tp_model + if tf.__version__ >= "2.13": from keras.src.layers import TFOpLambda else: @@ -33,13 +40,23 @@ class TestKerasQuantConfigFiltering(unittest.TestCase): @staticmethod def get_tpc_default_16bit(): - tpc = mct.get_target_platform_capabilities(TENSORFLOW, IMX500_TP_MODEL, 'v3') - # Force Mul base_config to 16bit only - mul_op_set = get_op_set('Mul', tpc.tp_model.operator_set) - base_config = [l for l in mul_op_set.qc_options.quantization_configurations if l.activation_n_bits == 16][0] - tpc.layer2qco[tf.multiply] = tpc.layer2qco[tf.multiply].copy( - update={'quantization_configurations': mul_op_set.qc_options.quantization_configurations, - 'base_config': base_config}) + tpc = get_tp_model() + base_cfg_16 = [c for c in get_config_options_by_operators_set(tpc, + OperatorSetNames.MUL).quantization_configurations + if c.activation_n_bits == 16][0].clone_and_edit() + qco_16 = QuantizationConfigOptions(base_config=base_cfg_16, + quantization_configurations=(tpc.default_qco.base_config, + base_cfg_16)) + tpc = generate_custom_test_tp_model( + name="custom_16_bit_tpc", + base_cfg=tpc.default_qco.base_config, + base_tp_model=tpc, + operator_sets_dict={ + OperatorSetNames.MUL: qco_16, + OperatorSetNames.GELU: qco_16, + OperatorSetNames.TANH: qco_16, + }) + return tpc def test_config_filtering(self): @@ -54,6 +71,8 @@ def test_config_filtering(self): [], {}, functional_op=tf.divide) tpc = self.get_tpc_default_16bit() + tpc = AttachTpcToKeras().attach(tpc) + node_qc_options = node.get_qco(tpc) self.assertTrue(node_qc_options.base_config.activation_n_bits == 16, "base_config should start with 16 bits.") diff --git a/tests/keras_tests/function_tests/test_resource_utilization_data.py b/tests/keras_tests/function_tests/test_resource_utilization_data.py index d94878aca..cd8b4d49e 100644 --- a/tests/keras_tests/function_tests/test_resource_utilization_data.py +++ b/tests/keras_tests/function_tests/test_resource_utilization_data.py @@ -20,13 +20,13 @@ import numpy as np import keras import unittest -from tensorflow.keras.layers import Conv2D, BatchNormalization, ReLU, Input, SeparableConv2D +from tensorflow.keras.layers import Conv2D, BatchNormalization, ReLU, Input, SeparableConv2D, InputLayer -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import \ - get_op_quantization_configs +from model_compression_toolkit.core import QuantizationConfig from model_compression_toolkit.core.keras.constants import DEPTHWISE_KERNEL, KERNEL from model_compression_toolkit.core.keras.graph_substitutions.substitutions.separableconv_decomposition import \ POINTWISE_KERNEL +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers from tests.common_tests.helpers.generate_test_tp_model import generate_test_op_qc, generate_test_attr_configs from tests.keras_tests.tpc_keras import get_tpc_with_activation_mp_keras @@ -95,7 +95,9 @@ def prep_test(model, mp_bitwidth_candidates_list, random_datagen): ru_data = mct.core.keras_resource_utilization_data(in_model=model, representative_data_gen=random_datagen, - core_config=mct.core.CoreConfig(), + core_config=mct.core.CoreConfig( + quantization_config=QuantizationConfig( + custom_tpc_opset_to_layer={"Input": CustomOpsetLayers([InputLayer])})), target_platform_capabilities=tpc) return ru_data diff --git a/tests/keras_tests/function_tests/test_sensitivity_eval_non_suppoerted_output.py b/tests/keras_tests/function_tests/test_sensitivity_eval_non_suppoerted_output.py index 8f3dbc7df..7eebd5687 100644 --- a/tests/keras_tests/function_tests/test_sensitivity_eval_non_suppoerted_output.py +++ b/tests/keras_tests/function_tests/test_sensitivity_eval_non_suppoerted_output.py @@ -20,6 +20,8 @@ from model_compression_toolkit.core import MixedPrecisionQuantizationConfig from model_compression_toolkit.core.keras.default_framework_info import DEFAULT_KERAS_INFO from model_compression_toolkit.core.keras.keras_implementation import KerasImplementation +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import generate_keras_tpc from tests.common_tests.helpers.prep_graph_for_func_test import prepare_graph_with_quantization_parameters import model_compression_toolkit.core.common.hessian as hess @@ -82,6 +84,7 @@ def verify_test_for_model(self, model): DEFAULT_KERAS_INFO, representative_dataset, generate_keras_tpc, + attach2fw=AttachTpcToKeras(), input_shape=(1, 8, 8, 3), mixed_precision_enabled=True) diff --git a/tests/keras_tests/function_tests/test_sensitivity_metric_interest_points.py b/tests/keras_tests/function_tests/test_sensitivity_metric_interest_points.py index 52267cf37..5feb09f2a 100644 --- a/tests/keras_tests/function_tests/test_sensitivity_metric_interest_points.py +++ b/tests/keras_tests/function_tests/test_sensitivity_metric_interest_points.py @@ -18,16 +18,17 @@ from keras.applications.densenet import DenseNet121 from keras.applications.mobilenet_v2 import MobileNetV2 -from packaging import version - -from model_compression_toolkit.core.common.quantization.bit_width_config import BitWidthConfig -from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR - -if version.parse(tf.__version__) >= version.parse("2.13"): +if tf.__version__ >= "2.13": + from keras.src.engine.input_layer import InputLayer from keras.src.layers.core import TFOpLambda else: + from keras.engine.input_layer import InputLayer from keras.layers.core import TFOpLambda +from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras + from model_compression_toolkit.constants import AXIS from model_compression_toolkit.core.common.mixed_precision.distance_weighting import MpDistanceWeighting from model_compression_toolkit.core.common.mixed_precision.mixed_precision_quantization_config import \ @@ -66,6 +67,8 @@ def dummy_representative_dataset(): c.activation_n_bits) for c in mixed_precision_cfg_list], name="sem_test") + tpc = AttachTpcToKeras().attach(tpc, custom_opset2layer={"Input": ([InputLayer],)}) + graph.set_tpc(tpc) graph = set_quantization_configuration_to_graph(graph=graph, quant_config=DEFAULTCONFIG, diff --git a/tests/keras_tests/function_tests/test_set_layer_to_bitwidth.py b/tests/keras_tests/function_tests/test_set_layer_to_bitwidth.py index 0e33b7853..c612163cc 100644 --- a/tests/keras_tests/function_tests/test_set_layer_to_bitwidth.py +++ b/tests/keras_tests/function_tests/test_set_layer_to_bitwidth.py @@ -14,11 +14,23 @@ # ============================================================================== import unittest import keras +import tensorflow as tf import numpy as np from keras import Input from keras.layers import Conv2D + +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers + +if tf.__version__ >= "2.13": + from keras.src.engine.input_layer import InputLayer +else: + from keras.engine.input_layer import InputLayer + from mct_quantizers import KerasActivationQuantizationHolder +from model_compression_toolkit.core import QuantizationConfig +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras from model_compression_toolkit.trainable_infrastructure import KerasTrainableQuantizationWrapper from model_compression_toolkit.core.common.mixed_precision.set_layer_to_bitwidth import set_layer_to_bitwidth @@ -44,13 +56,16 @@ def representative_dataset(): yield [np.random.randn(1, 8, 8, 3).astype(np.float32)] -def test_setup(get_tpc_fn): +def setup_test(get_tpc_fn): model = base_model((8, 8, 3)) - graph = prepare_graph_with_quantization_parameters(model, KerasImplementation(), DEFAULT_KERAS_INFO, + graph = prepare_graph_with_quantization_parameters(model, KerasImplementation(), DEFAULT_KERAS_INFO, representative_dataset, get_tpc_fn, input_shape=(1, 8, 8, 3), + attach2fw=AttachTpcToKeras(), + qc=QuantizationConfig( + custom_tpc_opset_to_layer={"Input": CustomOpsetLayers([InputLayer])}), mixed_precision_enabled=True) layer = model.layers[1] @@ -71,7 +86,7 @@ def test_set_layer_to_bitwidth_weights(self): # In this test we need a dedicated TPC so we just override the TPC generator function that needed to be passed # to the tests preparation helper method - layer, node = test_setup(get_tpc_fn=lambda x, y: tpc) + layer, node = setup_test(get_tpc_fn=lambda x, y: tpc) wrapper_layer = \ KerasTrainableQuantizationWrapper(layer, @@ -106,7 +121,7 @@ def test_set_layer_to_bitwidth_activation(self): # In this test we need a dedicated TPC so we just override the TPC generator function that needed to be passed # to the tests preparation helper method - layer, node = test_setup(get_tpc_fn=lambda x, y: tpc) + layer, node = setup_test(get_tpc_fn=lambda x, y: tpc) holder_layer = \ KerasActivationQuantizationHolder(ConfigurableActivationQuantizer( diff --git a/tests/keras_tests/function_tests/test_symmetric_threshold_selection_weights.py b/tests/keras_tests/function_tests/test_symmetric_threshold_selection_weights.py index c0dc8324b..cb3108d23 100644 --- a/tests/keras_tests/function_tests/test_symmetric_threshold_selection_weights.py +++ b/tests/keras_tests/function_tests/test_symmetric_threshold_selection_weights.py @@ -22,6 +22,8 @@ from model_compression_toolkit.core import QuantizationConfig, QuantizationErrorMethod from model_compression_toolkit.constants import THRESHOLD from model_compression_toolkit.core.keras.constants import KERNEL +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import generate_keras_tpc from model_compression_toolkit.core.keras.default_framework_info import DEFAULT_KERAS_INFO from model_compression_toolkit.core.keras.keras_implementation import KerasImplementation @@ -102,7 +104,8 @@ def run_test_for_threshold_method(self, threshold_method, per_channel=True): graph = prepare_graph_with_quantization_parameters(in_model, KerasImplementation(), DEFAULT_KERAS_INFO, representative_dataset, lambda name, _tp: get_tpc(per_channel), - qc=qc, input_shape=(1, 16, 16, 4)) + qc=qc, input_shape=(1, 16, 16, 4), + attach2fw=AttachTpcToKeras(), ) nodes_list = list(graph.nodes) conv1_threshold = nodes_list[0].candidates_quantization_cfg[0].weights_quantization_cfg.get_attr_config(KERNEL).weights_quantization_params[THRESHOLD] diff --git a/tests/keras_tests/function_tests/test_uniform_range_selection_weights.py b/tests/keras_tests/function_tests/test_uniform_range_selection_weights.py index a487ae2b5..91a584ccb 100644 --- a/tests/keras_tests/function_tests/test_uniform_range_selection_weights.py +++ b/tests/keras_tests/function_tests/test_uniform_range_selection_weights.py @@ -22,6 +22,8 @@ from model_compression_toolkit.core import QuantizationConfig, QuantizationErrorMethod from model_compression_toolkit.constants import RANGE_MIN, RANGE_MAX from model_compression_toolkit.core.keras.constants import KERNEL +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import generate_keras_tpc from model_compression_toolkit.core.keras.default_framework_info import DEFAULT_KERAS_INFO from model_compression_toolkit.core.keras.keras_implementation import KerasImplementation @@ -101,7 +103,8 @@ def run_test_for_threshold_method(self, threshold_method, per_channel=True): graph = prepare_graph_with_quantization_parameters(in_model, KerasImplementation(), DEFAULT_KERAS_INFO, representative_dataset, lambda name, _tp: get_tpc(per_channel), - qc=qc, input_shape=(1, 16, 16, 4)) + qc=qc, input_shape=(1, 16, 16, 4), + attach2fw=AttachTpcToKeras(), ) nodes_list = list(graph.nodes) conv1_min = nodes_list[0].candidates_quantization_cfg[0].weights_quantization_cfg.get_attr_config(KERNEL).weights_quantization_params[RANGE_MIN].flatten() diff --git a/tests/keras_tests/function_tests/test_weights_activation_split_substitution.py b/tests/keras_tests/function_tests/test_weights_activation_split_substitution.py index 93fa0b881..e3f6020cb 100644 --- a/tests/keras_tests/function_tests/test_weights_activation_split_substitution.py +++ b/tests/keras_tests/function_tests/test_weights_activation_split_substitution.py @@ -13,14 +13,22 @@ # limitations under the License. # ============================================================================== import copy - +import tensorflow as tf import keras import unittest -from keras.layers import Conv2D, Conv2DTranspose, DepthwiseConv2D, Dense, BatchNormalization, ReLU, Input +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers + +if tf.__version__ >= "2.13": + from keras.src.layers import Conv2D, Conv2DTranspose, DepthwiseConv2D, Dense, BatchNormalization, ReLU, Input + from keras.src.engine.input_layer import InputLayer +else: + from keras.layers import Conv2D, Conv2DTranspose, DepthwiseConv2D, Dense, BatchNormalization, ReLU, Input + from keras.engine.input_layer import InputLayer + import numpy as np -from model_compression_toolkit.core import DEFAULTCONFIG, MixedPrecisionQuantizationConfig +from model_compression_toolkit.core import QuantizationConfig from model_compression_toolkit.core.common.graph.virtual_activation_weights_node import VirtualSplitActivationNode, \ VirtualSplitWeightsNode from model_compression_toolkit.core.keras.default_framework_info import DEFAULT_KERAS_INFO @@ -28,6 +36,8 @@ WeightsActivationSplit from model_compression_toolkit.core.keras.keras_implementation import KerasImplementation from model_compression_toolkit.core.common.substitutions.apply_substitutions import substitute +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import get_op_quantization_configs import model_compression_toolkit as mct @@ -75,11 +85,12 @@ def get_tpc(mixed_precision_candidates_list): name="weights_activation_split_test") -def test_setup(in_model, keras_impl, mixed_precision_candidates_list): - qc = DEFAULTCONFIG +def setup_test(in_model, keras_impl, mixed_precision_candidates_list): graph = prepare_graph_with_configs(in_model, keras_impl, DEFAULT_KERAS_INFO, representative_dataset, - lambda name, _tp: get_tpc(mixed_precision_candidates_list), qc=qc, - mixed_precision_enabled=True) + lambda name, _tp: get_tpc(mixed_precision_candidates_list), + mixed_precision_enabled=True, + attach2fw=AttachTpcToKeras(), + qc=QuantizationConfig(custom_tpc_opset_to_layer={"Input": CustomOpsetLayers([InputLayer])})) # Split graph substitution split_graph = substitute(copy.deepcopy(graph), [WeightsActivationSplit()]) @@ -120,7 +131,7 @@ def test_single_conv_net_split(self): in_model = single_conv_model() keras_impl = KerasImplementation() - graph, split_graph = test_setup(in_model, keras_impl, mixed_precision_candidates_list=_get_base_mp_nbits_candidates()) + graph, split_graph = setup_test(in_model, keras_impl, mixed_precision_candidates_list=_get_base_mp_nbits_candidates()) # num_activation_candidates here is 1 because the split Conv has ReLU after it - thenbecause of fusion, the # Conv layer doesn't have activation quantization candidates self._verify_single_conv_test(graph, split_graph, num_weights_candidates=3, num_activation_candidates=1) @@ -129,14 +140,14 @@ def test_single_conv_net_weights_only_split(self): in_model = single_conv_model() keras_impl = KerasImplementation() - graph, split_graph = test_setup(in_model, keras_impl, mixed_precision_candidates_list=[(8, 8), (4, 8), (2, 8)]) + graph, split_graph = setup_test(in_model, keras_impl, mixed_precision_candidates_list=[(8, 8), (4, 8), (2, 8)]) self._verify_single_conv_test(graph, split_graph, num_weights_candidates=3, num_activation_candidates=1) def test_single_conv_net_activation_only_split(self): in_model = single_conv_model() keras_impl = KerasImplementation() - graph, split_graph = test_setup(in_model, keras_impl, mixed_precision_candidates_list=[(8, 8), (8, 4), (8, 2)]) + graph, split_graph = setup_test(in_model, keras_impl, mixed_precision_candidates_list=[(8, 8), (8, 4), (8, 2)]) # num_activation_candidates here is 1 because the split Conv has ReLU after it - thenbecause of fusion, the # Conv layer doesn't have activation quantization candidates self._verify_single_conv_test(graph, split_graph, num_weights_candidates=1, num_activation_candidates=1) @@ -145,7 +156,7 @@ def test_all_weights_layers_split(self): in_model = multiple_weights_nodes_model() keras_impl = KerasImplementation() - graph, split_graph = test_setup(in_model, keras_impl, mixed_precision_candidates_list=_get_base_mp_nbits_candidates()) + graph, split_graph = setup_test(in_model, keras_impl, mixed_precision_candidates_list=_get_base_mp_nbits_candidates()) weights_node_types = [Conv2D, Conv2DTranspose, DepthwiseConv2D, Dense] original_weights_nodes = [n for n in graph.get_topo_sorted_nodes() if any([n.is_match_type(_type) for _type in weights_node_types])] @@ -170,4 +181,4 @@ def test_non_composite_candidates_config(self): keras_impl = KerasImplementation() with self.assertRaises(Exception): - test_setup(in_model, keras_impl, mixed_precision_candidates_list=[(8, 2), (2, 4), (4, 8)]) + setup_test(in_model, keras_impl, mixed_precision_candidates_list=[(8, 2), (2, 4), (4, 8)]) diff --git a/tests/keras_tests/non_parallel_tests/test_keras_tp_model.py b/tests/keras_tests/non_parallel_tests/test_keras_tp_model.py index 23a57c13a..3b8b387c2 100644 --- a/tests/keras_tests/non_parallel_tests/test_keras_tp_model.py +++ b/tests/keras_tests/non_parallel_tests/test_keras_tp_model.py @@ -225,21 +225,22 @@ def test_qco_by_keras_layer(self): self.assertEqual(tanh_qco, sevenbit_qco) self.assertEqual(relu_qco, default_qco) - def test_opset_not_in_tp(self): - default_qco = schema.QuantizationConfigOptions(quantization_configurations=tuple([TEST_QC])) - hm = schema.TargetPlatformModel(default_qco=default_qco, - tpc_minor_version=None, - tpc_patch_version=None, - tpc_platform_type=None, - operator_set=tuple([schema.OperatorsSet(name="opA")]), - add_metadata=False) - hm_keras = tp.TargetPlatformCapabilities(hm) - with self.assertRaises(Exception) as e: - with hm_keras: - tp.OperationsSetToLayers("conv", [Conv2D]) - self.assertEqual( - 'conv is not defined in the target platform model that is associated with the target platform capabilities.', - str(e.exception)) + # TODO: need to test as part of attach to fw tests + # def test_opset_not_in_tp(self): + # default_qco = schema.QuantizationConfigOptions(quantization_configurations=tuple([TEST_QC])) + # hm = schema.TargetPlatformModel(default_qco=default_qco, + # tpc_minor_version=None, + # tpc_patch_version=None, + # tpc_platform_type=None, + # operator_set=tuple([schema.OperatorsSet(name="opA")]), + # add_metadata=False) + # hm_keras = tp.TargetPlatformCapabilities(hm) + # with self.assertRaises(Exception) as e: + # with hm_keras: + # tp.OperationsSetToLayers("conv", [Conv2D]) + # self.assertEqual( + # 'conv is not defined in the target platform model that is associated with the target platform capabilities.', + # str(e.exception)) def test_keras_fusing_patterns(self): default_qco = schema.QuantizationConfigOptions(quantization_configurations=tuple([TEST_QC])) @@ -322,37 +323,16 @@ def rep_data(): def test_get_keras_supported_version(self): tpc = mct.get_target_platform_capabilities(TENSORFLOW, DEFAULT_TP_MODEL) # Latest - self.assertTrue(tpc.tp_model.tpc_minor_version == 1) - - tpc = mct.get_target_platform_capabilities(TENSORFLOW, DEFAULT_TP_MODEL, 'v1_pot') - self.assertTrue(tpc.tp_model.tpc_minor_version == 1) - tpc = mct.get_target_platform_capabilities(TENSORFLOW, DEFAULT_TP_MODEL, 'v1_lut') - self.assertTrue(tpc.tp_model.tpc_minor_version == 1) - tpc = mct.get_target_platform_capabilities(TENSORFLOW, DEFAULT_TP_MODEL, 'v1') - self.assertTrue(tpc.tp_model.tpc_minor_version == 1) - tpc = mct.get_target_platform_capabilities(TENSORFLOW, DEFAULT_TP_MODEL, 'v2_lut') - self.assertTrue(tpc.tp_model.tpc_minor_version == 2) - tpc = mct.get_target_platform_capabilities(TENSORFLOW, DEFAULT_TP_MODEL, 'v2') - self.assertTrue(tpc.tp_model.tpc_minor_version == 2) + self.assertTrue(tpc.tpc_minor_version == 1) tpc = mct.get_target_platform_capabilities(TENSORFLOW, IMX500_TP_MODEL, "v1") - self.assertTrue(tpc.tp_model.tpc_minor_version == 1) - tpc = mct.get_target_platform_capabilities(TENSORFLOW, IMX500_TP_MODEL, "v2") - self.assertTrue(tpc.tp_model.tpc_minor_version == 2) - - tpc = mct.get_target_platform_capabilities(TENSORFLOW, IMX500_TP_MODEL, "v1_lut") - self.assertTrue(tpc.tp_model.tpc_minor_version == 1) - tpc = mct.get_target_platform_capabilities(TENSORFLOW, IMX500_TP_MODEL, "v2_lut") - self.assertTrue(tpc.tp_model.tpc_minor_version == 2) - - tpc = mct.get_target_platform_capabilities(TENSORFLOW, IMX500_TP_MODEL, "v1_pot") - self.assertTrue(tpc.tp_model.tpc_minor_version == 1) + self.assertTrue(tpc.tpc_minor_version == 1) tpc = mct.get_target_platform_capabilities(TENSORFLOW, TFLITE_TP_MODEL, "v1") - self.assertTrue(tpc.tp_model.tpc_minor_version == 1) + self.assertTrue(tpc.tpc_minor_version == 1) tpc = mct.get_target_platform_capabilities(TENSORFLOW, QNNPACK_TP_MODEL, "v1") - self.assertTrue(tpc.tp_model.tpc_minor_version == 1) + self.assertTrue(tpc.tpc_minor_version == 1) def test_get_keras_not_supported_platform(self): with self.assertRaises(Exception) as e: @@ -366,5 +346,5 @@ def test_get_keras_not_supported_fw(self): def test_get_keras_not_supported_version(self): with self.assertRaises(Exception) as e: - mct.get_target_platform_capabilities(TENSORFLOW, DEFAULT_TP_MODEL, "v0") + mct.get_target_platform_capabilities(TENSORFLOW, IMX500_TP_MODEL, "v0") self.assertTrue(e.exception) diff --git a/tests/keras_tests/non_parallel_tests/test_lp_search_bitwidth.py b/tests/keras_tests/non_parallel_tests/test_lp_search_bitwidth.py index 4c1bdcc73..85c41581c 100644 --- a/tests/keras_tests/non_parallel_tests/test_lp_search_bitwidth.py +++ b/tests/keras_tests/non_parallel_tests/test_lp_search_bitwidth.py @@ -39,6 +39,8 @@ from model_compression_toolkit.core.keras.default_framework_info import DEFAULT_KERAS_INFO from model_compression_toolkit.core.keras.keras_implementation import KerasImplementation from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import \ get_op_quantization_configs from tests.keras_tests.tpc_keras import get_weights_only_mp_tpc_keras @@ -230,6 +232,9 @@ def dummy_representative_dataset(): return None graph = keras_impl.model_reader(in_model, dummy_representative_dataset) # model reading + + tpc = AttachTpcToKeras().attach(tpc) + graph.set_fw_info(fw_info) graph.set_tpc(tpc) graph = set_quantization_configuration_to_graph(graph=graph, diff --git a/tests/keras_tests/non_parallel_tests/test_tensorboard_writer.py b/tests/keras_tests/non_parallel_tests/test_tensorboard_writer.py index 05ce87a87..987d6f5b6 100644 --- a/tests/keras_tests/non_parallel_tests/test_tensorboard_writer.py +++ b/tests/keras_tests/non_parallel_tests/test_tensorboard_writer.py @@ -25,12 +25,16 @@ import model_compression_toolkit as mct from model_compression_toolkit.constants import TENSORFLOW +from model_compression_toolkit.core import QuantizationConfig from model_compression_toolkit.core.common.visualization.final_config_visualizer import \ ActivationFinalBitwidthConfigVisualizer from model_compression_toolkit.target_platform_capabilities.constants import DEFAULT_TP_MODEL from model_compression_toolkit.core.keras.default_framework_info import DEFAULT_KERAS_INFO from model_compression_toolkit.core.keras.keras_implementation import KerasImplementation from model_compression_toolkit.logger import Logger +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import generate_keras_tpc from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import get_op_quantization_configs from tests.common_tests.helpers.generate_test_tp_model import generate_tp_model_with_activation_mp @@ -132,7 +136,7 @@ def tensorboard_initial_graph_num_of_nodes(self, num_event_files, event_to_test) nodes_in_graph = len(g.node) self.assertTrue(nodes_in_graph == nodes_in_model) - def plot_tensor_sizes(self): + def plot_tensor_sizes(self, core_config): model = SingleOutputNet() base_config, _, default_config = get_op_quantization_configs() tpc_model = generate_tp_model_with_activation_mp( @@ -142,6 +146,7 @@ def plot_tensor_sizes(self): (4, 8), (4, 4), (4, 2), (2, 8), (2, 4), (2, 2)]) tpc = generate_keras_tpc(name='mp_keras_tpc', tp_model=tpc_model) + tpc =AttachTpcToKeras().attach(tpc, core_config.quantization_config.custom_tpc_opset_to_layer) # Hessian service assumes core should be initialized. This test does not do it, so we disable the use of hessians in MP cfg = mct.core.DEFAULTCONFIG @@ -193,7 +198,11 @@ def rep_data(): mp_qc = mct.core.MixedPrecisionQuantizationConfig(num_of_images=1, use_hessian_based_scores=False) core_config = mct.core.CoreConfig(mixed_precision_config=mp_qc, + quantization_config= + QuantizationConfig(custom_tpc_opset_to_layer= + {"Input": CustomOpsetLayers([layers.InputLayer])}), debug_config=mct.core.DebugConfig(analyze_similarity=True)) + quantized_model, _ = mct.ptq.keras_post_training_quantization(self.model, rep_data, target_resource_utilization=mct.core.ResourceUtilization( @@ -217,7 +226,7 @@ def rep_data(): target_platform_capabilities=self.get_tpc()) # Test tensor size plotting - self.plot_tensor_sizes() + self.plot_tensor_sizes(core_config) # Disable Logger Logger.LOG_PATH = None diff --git a/tests/keras_tests/pruning_tests/test_memory_calculator.py b/tests/keras_tests/pruning_tests/test_memory_calculator.py index 88240c47c..2047c34f8 100644 --- a/tests/keras_tests/pruning_tests/test_memory_calculator.py +++ b/tests/keras_tests/pruning_tests/test_memory_calculator.py @@ -24,6 +24,9 @@ import keras +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2keras import \ + AttachTpcToKeras + layers = keras.layers import numpy as np @@ -50,6 +53,8 @@ def test_conv_layer(self): fw_impl = PruningKerasImplementation() tpc = mct.get_target_platform_capabilities('tensorflow', 'imx500') + tpc = AttachTpcToKeras().attach(tpc) + # Convert the original Keras model to an internal graph representation. float_graph = read_model_to_graph(model, self.representative_dataset, diff --git a/tests/keras_tests/tpc_keras.py b/tests/keras_tests/tpc_keras.py index 0ec5df058..08055fe35 100644 --- a/tests/keras_tests/tpc_keras.py +++ b/tests/keras_tests/tpc_keras.py @@ -80,7 +80,7 @@ def get_weights_only_mp_tpc_keras(base_config, default_config, mp_bitwidth_candi mp_tp_model = generate_mixed_precision_test_tp_model(base_cfg=base_config, default_config=default_config, mp_bitwidth_candidates_list=mp_bitwidth_candidates_list) - return generate_keras_tpc(name=name, tp_model=mp_tp_model) + return mp_tp_model def get_tpc_with_activation_mp_keras(base_config, default_config, mp_bitwidth_candidates_list, name, custom_opsets={}): @@ -89,24 +89,4 @@ def get_tpc_with_activation_mp_keras(base_config, default_config, mp_bitwidth_ca mp_bitwidth_candidates_list=mp_bitwidth_candidates_list, custom_opsets=list(custom_opsets.keys())) - op_sets_to_layer_add = { - "Input": [InputLayer], - } - - op_sets_to_layer_add.update(custom_opsets) - - # we assume a standard tp model with standard operator sets names, - # otherwise - need to generate the tpc per test and not with this generic function - attr_mapping = {'Conv': { - KERNEL_ATTR: DefaultDict({ - DepthwiseConv2D: KERAS_DEPTHWISE_KERNEL, - tf.nn.depthwise_conv2d: KERAS_DEPTHWISE_KERNEL}, default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}, - 'FullyConnected': {KERNEL_ATTR: DefaultDict(default_value=KERAS_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}} - - return generate_test_tpc(name=name, - tp_model=mp_tp_model, - base_tpc=generate_keras_tpc(name=f"base_{name}", tp_model=mp_tp_model), - op_sets_to_layer_add=op_sets_to_layer_add, - attr_mapping=attr_mapping) + return mp_tp_model diff --git a/tests/keras_tests/xquant_tests/test_xquant_end2end.py b/tests/keras_tests/xquant_tests/test_xquant_end2end.py index 0cccc4923..b62fe7c86 100644 --- a/tests/keras_tests/xquant_tests/test_xquant_end2end.py +++ b/tests/keras_tests/xquant_tests/test_xquant_end2end.py @@ -42,6 +42,7 @@ INTERMEDIATE_SIMILARITY_METRICS_VAL, XQUANT_REPR, XQUANT_VAL, CUT_MEMORY_ELEMENTS, CUT_TOTAL_SIZE from model_compression_toolkit.xquant.keras.facade_xquant_report import xquant_report_keras_experimental +from tests.common_tests.helpers.tpcs_for_tests.v2.tp_model import get_tp_model def random_data_gen(shape=(8, 8, 3), use_labels=False, num_inputs=1, batch_size=2, num_iter=2): @@ -74,7 +75,7 @@ def get_core_config(self): return mct.core.CoreConfig(debug_config=mct.core.DebugConfig(simulate_scheduler=True)) def get_tpc(self): - return mct.get_target_platform_capabilities(TENSORFLOW, IMX500_TP_MODEL, "v2") + return get_tp_model() def get_model_to_test(self): inputs = keras.layers.Input(shape=self.get_input_shape()) diff --git a/tests/pytorch_tests/exporter_tests/test_exporting_qat_models.py b/tests/pytorch_tests/exporter_tests/test_exporting_qat_models.py index bee9c7cfd..59b2671f8 100644 --- a/tests/pytorch_tests/exporter_tests/test_exporting_qat_models.py +++ b/tests/pytorch_tests/exporter_tests/test_exporting_qat_models.py @@ -21,7 +21,6 @@ from torchvision.models.mobilenetv2 import mobilenet_v2 import model_compression_toolkit as mct -from model_compression_toolkit.verify_packages import FOUND_ONNXRUNTIME, FOUND_ONNX from model_compression_toolkit.core.pytorch.pytorch_device_config import get_working_device from model_compression_toolkit.core.pytorch.utils import to_torch_tensor from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import \ diff --git a/tests/pytorch_tests/function_tests/layer_fusing_test.py b/tests/pytorch_tests/function_tests/layer_fusing_test.py index 390373f8d..0ab6db09e 100644 --- a/tests/pytorch_tests/function_tests/layer_fusing_test.py +++ b/tests/pytorch_tests/function_tests/layer_fusing_test.py @@ -18,9 +18,13 @@ from torch.nn.functional import relu, relu6 import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema +from model_compression_toolkit.core import QuantizationConfig from model_compression_toolkit.target_platform_capabilities.target_platform import LayerFilterParams from model_compression_toolkit.core.pytorch.default_framework_info import DEFAULT_PYTORCH_INFO from model_compression_toolkit.core.pytorch.pytorch_implementation import PytorchImplementation +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2pytorch import \ + AttachTpcToPytorch from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import \ get_op_quantization_configs from tests.common_tests.helpers.prep_graph_for_func_test import prepare_graph_with_configs @@ -60,6 +64,7 @@ class LayerFusingTest1(BaseLayerFusingTest): def __init__(self, unit_test): super().__init__(unit_test) self.expected_fusions = [[nn.Conv2d, nn.ReLU]] + self.attach2fw = AttachTpcToPytorch() def get_tpc(self): base_config, mixed_precision_cfg_list, default_config = get_op_quantization_configs() @@ -67,7 +72,7 @@ def get_tpc(self): mixed_precision_configuration_options = schema.QuantizationConfigOptions(quantization_configurations=tuple(mixed_precision_cfg_list), base_config=base_config) conv = schema.OperatorsSet(name="Conv", qc_options=mixed_precision_configuration_options) - any_relu = schema.OperatorsSet(name="AnyReLU") + any_relu = schema.OperatorsSet(name="ReLU") operator_set = [conv, any_relu] # Define fusions fusing_patterns = [schema.Fusing(operator_groups=(conv, any_relu))] @@ -79,19 +84,14 @@ def get_tpc(self): fusing_patterns=tuple(fusing_patterns), name='layer_fusing_test') - - pytorch_tpc = tp.TargetPlatformCapabilities(generated_tp) - with pytorch_tpc: - tp.OperationsSetToLayers("Conv", [nn.Conv2d]) - tp.OperationsSetToLayers("AnyReLU", [torch.relu, - nn.ReLU]) - return pytorch_tpc + return generated_tp def run_test(self, seed=0): model_float = self.LayerFusingNetTest() graph = prepare_graph_with_configs(model_float, PytorchImplementation(), DEFAULT_PYTORCH_INFO, - self.representative_data_gen, lambda name, _tp: self.get_tpc()) + self.representative_data_gen, lambda name, _tp: self.get_tpc(), + attach2fw=self.attach2fw) self._compare(graph.fused_nodes) @@ -132,17 +132,16 @@ def get_tpc(self): fusing_patterns=tuple(fusing_patterns), name='layer_fusing_test') - pytorch_tpc = tp.TargetPlatformCapabilities(generated_tp) - with pytorch_tpc: - tp.OperationsSetToLayers("Conv", [Conv2d]) - tp.OperationsSetToLayers("AnyAct", - [ReLU, relu6, relu, SiLU, Sigmoid, LayerFilterParams(Hardtanh, min_val=0)]) - return pytorch_tpc + return generated_tp def run_test(self, seed=0): model_float = self.LayerFusingNetTest() graph = prepare_graph_with_configs(model_float, PytorchImplementation(), DEFAULT_PYTORCH_INFO, - self.representative_data_gen, lambda name, _tp: self.get_tpc()) + self.representative_data_gen, lambda name, _tp: self.get_tpc(), + attach2fw=AttachTpcToPytorch(), + qc=QuantizationConfig( + custom_tpc_opset_to_layer={"AnyAct": CustomOpsetLayers([ReLU, relu6, relu, SiLU, Sigmoid, + LayerFilterParams(Hardtanh, min_val=0)])})) self._compare(graph.fused_nodes) @@ -194,16 +193,15 @@ def get_tpc(self): operator_set=tuple(operator_set), fusing_patterns=tuple(fusing_patterns), name='layer_fusing_test') - pytorch_tpc = tp.TargetPlatformCapabilities(generated_tp) - with pytorch_tpc: - tp.OperationsSetToLayers("Conv", [Conv2d]) - tp.OperationsSetToLayers("AnyAct", [ReLU, relu6, relu]) - return pytorch_tpc + return generated_tp def run_test(self, seed=0): model_float = self.LayerFusingNetTest() graph = prepare_graph_with_configs(model_float, PytorchImplementation(), DEFAULT_PYTORCH_INFO, - self.representative_data_gen, lambda name, _tp: self.get_tpc()) + self.representative_data_gen, lambda name, _tp: self.get_tpc(), + attach2fw=AttachTpcToPytorch(), + qc=QuantizationConfig( + custom_tpc_opset_to_layer={"AnyAct": CustomOpsetLayers([ReLU, relu6, relu])})) self._compare(graph.fused_nodes) @@ -244,13 +242,13 @@ def get_tpc(self): mixed_precision_configuration_options = schema.QuantizationConfigOptions(quantization_configurations=tuple(mixed_precision_cfg_list), base_config=base_config) default_configuration_options = schema.QuantizationConfigOptions(quantization_configurations=tuple([default_config])) - conv = schema.OperatorsSet(name="Conv", qc_options=mixed_precision_configuration_options) - fc = schema.OperatorsSet(name="FullyConnected", qc_options=mixed_precision_configuration_options) - any_relu = schema.OperatorsSet(name="AnyReLU") - add = schema.OperatorsSet(name="Add") - swish = schema.OperatorsSet(name="Swish") - operator_set = [conv, fc, any_relu, add, swish] - activations_to_fuse = schema.OperatorSetConcat(operators_set=[any_relu, swish]) + conv = schema.OperatorsSet(name=schema.OperatorSetNames.CONV, qc_options=mixed_precision_configuration_options) + fc = schema.OperatorsSet(name=schema.OperatorSetNames.FULLY_CONNECTED, qc_options=mixed_precision_configuration_options) + relu = schema.OperatorsSet(name=schema.OperatorSetNames.RELU) + add = schema.OperatorsSet(name=schema.OperatorSetNames.ADD) + swish = schema.OperatorsSet(name=schema.OperatorSetNames.SWISH) + operator_set = [conv, fc, relu, add, swish] + activations_to_fuse = schema.OperatorSetConcat(operators_set=[relu, swish]) # Define fusions fusing_patterns = [schema.Fusing(operator_groups=(conv, activations_to_fuse)), schema.Fusing(operator_groups=(conv, add, activations_to_fuse)), @@ -265,19 +263,13 @@ def get_tpc(self): fusing_patterns=tuple(fusing_patterns), name='layer_fusing_test') - pytorch_tpc = tp.TargetPlatformCapabilities(generated_tp) - with pytorch_tpc: - tp.OperationsSetToLayers("Conv", [Conv2d]) - tp.OperationsSetToLayers("FullyConnected", [Linear]) - tp.OperationsSetToLayers("AnyReLU", [ReLU]) - tp.OperationsSetToLayers("Add", [torch.add]) - tp.OperationsSetToLayers("Swish", [SiLU]) - return pytorch_tpc + return generated_tp def run_test(self, seed=0): model_float = self.LayerFusingNetTest() graph = prepare_graph_with_configs(model_float, PytorchImplementation(), DEFAULT_PYTORCH_INFO, - self.representative_data_gen, lambda name, _tp: self.get_tpc()) + self.representative_data_gen, lambda name, _tp: self.get_tpc(), + attach2fw=AttachTpcToPytorch()) self._compare(graph.fused_nodes) diff --git a/tests/pytorch_tests/function_tests/resource_utilization_data_test.py b/tests/pytorch_tests/function_tests/resource_utilization_data_test.py index ef4339b91..6eefe763d 100644 --- a/tests/pytorch_tests/function_tests/resource_utilization_data_test.py +++ b/tests/pytorch_tests/function_tests/resource_utilization_data_test.py @@ -19,6 +19,9 @@ import torch from torch.nn import Conv2d, BatchNorm2d, ReLU +from model_compression_toolkit.core import QuantizationConfig +from model_compression_toolkit.core.pytorch.reader.node_holders import DummyPlaceHolder +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import \ get_op_quantization_configs from model_compression_toolkit.core.pytorch.constants import KERNEL @@ -115,7 +118,10 @@ def prep_test(model, mp_bitwidth_candidates_list, random_datagen): ru_data = mct.core.pytorch_resource_utilization_data(in_model=model, representative_data_gen=random_datagen, - core_config=mct.core.CoreConfig(), + core_config=mct.core.CoreConfig( + quantization_config=QuantizationConfig( + custom_tpc_opset_to_layer={ + "Input": CustomOpsetLayers([DummyPlaceHolder])})), target_platform_capabilities=tpc_dict['ru_data_test']) return ru_data diff --git a/tests/pytorch_tests/function_tests/set_layer_to_bitwidth_test.py b/tests/pytorch_tests/function_tests/set_layer_to_bitwidth_test.py index cbafbadcb..1cef3c0ef 100644 --- a/tests/pytorch_tests/function_tests/set_layer_to_bitwidth_test.py +++ b/tests/pytorch_tests/function_tests/set_layer_to_bitwidth_test.py @@ -25,6 +25,8 @@ from model_compression_toolkit.core.pytorch.mixed_precision.configurable_weights_quantizer import \ ConfigurableWeightsQuantizer from model_compression_toolkit.core.pytorch.pytorch_implementation import PytorchImplementation +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2pytorch import \ + AttachTpcToPytorch from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import get_op_quantization_configs from tests.common_tests.helpers.generate_test_tp_model import generate_mixed_precision_test_tp_model from tests.common_tests.helpers.prep_graph_for_func_test import prepare_graph_with_quantization_parameters @@ -44,12 +46,13 @@ def forward(self, inp): return x -def test_setup(representative_data_gen, get_tpc_fn): +def setup_test(representative_data_gen, get_tpc_fn): model = base_model() graph = prepare_graph_with_quantization_parameters(model, PytorchImplementation(), DEFAULT_PYTORCH_INFO, representative_data_gen, get_tpc_fn, input_shape=(1, 3, 8, 8), - mixed_precision_enabled=True) + mixed_precision_enabled=True, + attach2fw=AttachTpcToPytorch()) layer = list(model.children())[0] node = graph.get_topo_sorted_nodes()[1] @@ -82,7 +85,7 @@ def run_test(self, seed=0, **kwargs): # In this test we need a dedicated TPC so we just override the TPC generator function that needed to be passed # to the tests preparation helper method - node, layer = test_setup(self.representative_data_gen, get_tpc_fn=lambda x, y: tpc) + node, layer = setup_test(self.representative_data_gen, get_tpc_fn=lambda x, y: tpc) wrapper_layer = PytorchQuantizationWrapper(layer, weights_quantizers={KERNEL: @@ -132,7 +135,7 @@ def run_test(self, seed=0, **kwargs): # In this test we need a dedicated TPC so we just override the TPC generator function that needed to be passed # to the tests preparation helper method - node, layer = test_setup(self.representative_data_gen, get_tpc_fn=lambda x, y: tpc) + node, layer = setup_test(self.representative_data_gen, get_tpc_fn=lambda x, y: tpc) holder_layer = \ PytorchActivationQuantizationHolder(ConfigurableActivationQuantizer( diff --git a/tests/pytorch_tests/function_tests/test_activation_quantization_holder_gptq.py b/tests/pytorch_tests/function_tests/test_activation_quantization_holder_gptq.py index a475f2921..fae9b7f91 100644 --- a/tests/pytorch_tests/function_tests/test_activation_quantization_holder_gptq.py +++ b/tests/pytorch_tests/function_tests/test_activation_quantization_holder_gptq.py @@ -14,6 +14,8 @@ from model_compression_toolkit.gptq.pytorch.gptq_training import PytorchGPTQTrainer from model_compression_toolkit.gptq.common.gradual_activation_quantization import \ GradualActivationQuantizerWrapper +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2pytorch import \ + AttachTpcToPytorch from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import generate_pytorch_tpc from model_compression_toolkit.trainable_infrastructure import TrainingMethod from model_compression_toolkit.trainable_infrastructure.common.base_trainable_quantizer import VariableGroup @@ -151,7 +153,8 @@ def _get_gptq_model(self, input_shape, in_model, gptq_cfg=None): generate_pytorch_tpc, [1] + input_shape, mixed_precision_enabled=False, - qc=qc) + qc=qc, + attach2fw=AttachTpcToPytorch()) graph = set_bit_widths(mixed_precision_enable=False, graph=graph) gptq_cfg = gptq_cfg or mct.gptq.get_pytorch_gptq_config(1, use_hessian_based_weights=False, diff --git a/tests/pytorch_tests/function_tests/test_hessian_info_calculator.py b/tests/pytorch_tests/function_tests/test_hessian_info_calculator.py index 9ec14e347..f7b383422 100644 --- a/tests/pytorch_tests/function_tests/test_hessian_info_calculator.py +++ b/tests/pytorch_tests/function_tests/test_hessian_info_calculator.py @@ -23,6 +23,8 @@ from model_compression_toolkit.core.pytorch.default_framework_info import DEFAULT_PYTORCH_INFO from model_compression_toolkit.core.pytorch.pytorch_implementation import PytorchImplementation +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2pytorch import \ + AttachTpcToPytorch from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import generate_pytorch_tpc from tests.common_tests.helpers.prep_graph_for_func_test import prepare_graph_with_configs from tests.pytorch_tests.model_tests.base_pytorch_test import BasePytorchTest @@ -221,7 +223,8 @@ def _setup(self): model_float = self.model() pytorch_impl = PytorchImplementation() graph = prepare_graph_with_configs(model_float, PytorchImplementation(), DEFAULT_PYTORCH_INFO, - self.representative_data_gen, generate_pytorch_tpc) + self.representative_data_gen, generate_pytorch_tpc, + attach2fw=AttachTpcToPytorch()) return graph, pytorch_impl diff --git a/tests/pytorch_tests/function_tests/test_hessian_service.py b/tests/pytorch_tests/function_tests/test_hessian_service.py index 9bc13130d..244b7d88a 100644 --- a/tests/pytorch_tests/function_tests/test_hessian_service.py +++ b/tests/pytorch_tests/function_tests/test_hessian_service.py @@ -23,6 +23,8 @@ from model_compression_toolkit.core.pytorch.data_util import data_gen_to_dataloader from model_compression_toolkit.core.pytorch.default_framework_info import DEFAULT_PYTORCH_INFO from model_compression_toolkit.core.pytorch.pytorch_implementation import PytorchImplementation +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2pytorch import \ + AttachTpcToPytorch from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import generate_pytorch_tpc from tests.common_tests.helpers.prep_graph_for_func_test import prepare_graph_with_configs from tests.pytorch_tests.model_tests.base_pytorch_test import BasePytorchTest @@ -76,6 +78,7 @@ def __init__(self, unit_test, model, compute_hessian=True, run_verification=True self.pytorch_impl = PytorchImplementation() self.run_verification = run_verification self.compute_hessian = compute_hessian + self.attach2fw = AttachTpcToPytorch() def verify_hessian(self): self.unit_test.assertEqual(len(self.hessian), self.num_nodes, f"Expecting returned Hessian list to include " @@ -115,7 +118,8 @@ def run_test(self, seed=0): self.pytorch_impl, DEFAULT_PYTORCH_INFO, representative_dataset, - generate_pytorch_tpc) + generate_pytorch_tpc, + attach2fw=self.attach2fw) dataloader = data_gen_to_dataloader(representative_dataset, batch_size=1) self.request = HessianScoresRequest(mode=HessianMode.ACTIVATION, granularity=HessianScoresGranularity.PER_TENSOR, @@ -138,7 +142,8 @@ def run_test(self, seed=0): self.pytorch_impl, DEFAULT_PYTORCH_INFO, representative_dataset, - generate_pytorch_tpc) + generate_pytorch_tpc, + attach2fw=self.attach2fw) self.request = HessianScoresRequest(mode=HessianMode.WEIGHTS, granularity=HessianScoresGranularity.PER_OUTPUT_CHANNEL, @@ -161,7 +166,8 @@ def run_test(self, seed=0): self.pytorch_impl, DEFAULT_PYTORCH_INFO, representative_dataset, - generate_pytorch_tpc) + generate_pytorch_tpc, + attach2fw=self.attach2fw) data_loader = data_gen_to_dataloader(representative_dataset, batch_size=2) self.request = HessianScoresRequest(mode=HessianMode.ACTIVATION, granularity=HessianScoresGranularity.PER_TENSOR, @@ -188,7 +194,8 @@ def run_test(self, seed=0): self.pytorch_impl, DEFAULT_PYTORCH_INFO, representative_dataset, - generate_pytorch_tpc) + generate_pytorch_tpc, + attach2fw=self.attach2fw) data_loader = data_gen_to_dataloader(representative_dataset, batch_size=1) self.request = HessianScoresRequest(mode=HessianMode.ACTIVATION, @@ -217,7 +224,8 @@ def run_test(self, seed=0): self.pytorch_impl, DEFAULT_PYTORCH_INFO, representative_dataset, - generate_pytorch_tpc) + generate_pytorch_tpc, + attach2fw=self.attach2fw) data_loader = data_gen_to_dataloader(representative_dataset, batch_size=3) self.request = HessianScoresRequest(mode=HessianMode.ACTIVATION, @@ -243,7 +251,8 @@ def run_test(self, seed=0): self.pytorch_impl, DEFAULT_PYTORCH_INFO, representative_dataset, - generate_pytorch_tpc) + generate_pytorch_tpc, + attach2fw=AttachTpcToPytorch()) data_loader = data_gen_to_dataloader(representative_dataset, batch_size=1) self.request = HessianScoresRequest(mode=HessianMode.ACTIVATION, granularity=HessianScoresGranularity.PER_TENSOR, @@ -266,7 +275,8 @@ def run_test(self, seed=0): self.pytorch_impl, DEFAULT_PYTORCH_INFO, representative_dataset, - generate_pytorch_tpc) + generate_pytorch_tpc, + attach2fw=self.attach2fw) nodes = list(self.graph.get_topo_sorted_nodes()) data_loader = data_gen_to_dataloader(representative_dataset, batch_size=1) @@ -290,7 +300,8 @@ def run_test(self, seed=0): self.pytorch_impl, DEFAULT_PYTORCH_INFO, representative_dataset, - generate_pytorch_tpc) + generate_pytorch_tpc, + attach2fw=self.attach2fw) target_node = list(self.graph.get_topo_sorted_nodes())[0] data_loader = data_gen_to_dataloader(representative_dataset, batch_size=1) diff --git a/tests/pytorch_tests/function_tests/test_pytorch_tp_model.py b/tests/pytorch_tests/function_tests/test_pytorch_tp_model.py index fb693e9d4..5169ae46a 100644 --- a/tests/pytorch_tests/function_tests/test_pytorch_tp_model.py +++ b/tests/pytorch_tests/function_tests/test_pytorch_tp_model.py @@ -219,21 +219,22 @@ def test_filter_layer_attached_to_multiple_opsets(self): tp.OperationsSetToLayers('opsetB', [LayerFilterParams(torch.nn.Softmax, dim=2)]) self.assertEqual('Found layer Softmax(dim=2) in more than one OperatorsSet', str(e.exception)) - def test_opset_not_in_tp(self): - default_qco = schema.QuantizationConfigOptions(quantization_configurations=tuple([TEST_QC])) - hm = schema.TargetPlatformModel(default_qco=default_qco, - tpc_minor_version=None, - tpc_patch_version=None, - tpc_platform_type=None, - operator_set=tuple([schema.OperatorsSet(name="opA")]), - add_metadata=False) - hm_pytorch = tp.TargetPlatformCapabilities(hm) - with self.assertRaises(Exception) as e: - with hm_pytorch: - tp.OperationsSetToLayers("conv", [torch.nn.Conv2d]) - self.assertEqual( - 'conv is not defined in the target platform model that is associated with the target platform capabilities.', - str(e.exception)) + # TODO: need to test as part of attach to fw tests + # def test_opset_not_in_tp(self): + # default_qco = schema.QuantizationConfigOptions(quantization_configurations=tuple([TEST_QC])) + # hm = schema.TargetPlatformModel(default_qco=default_qco, + # tpc_minor_version=None, + # tpc_patch_version=None, + # tpc_platform_type=None, + # operator_set=tuple([schema.OperatorsSet(name="opA")]), + # add_metadata=False) + # hm_pytorch = tp.TargetPlatformCapabilities(hm) + # with self.assertRaises(Exception) as e: + # with hm_pytorch: + # tp.OperationsSetToLayers("conv", [torch.nn.Conv2d]) + # self.assertEqual( + # 'conv is not defined in the target platform model that is associated with the target platform capabilities.', + # str(e.exception)) def test_pytorch_fusing_patterns(self): default_qco = schema.QuantizationConfigOptions(quantization_configurations=tuple( @@ -298,23 +299,16 @@ def rep_data(): def test_get_pytorch_supported_version(self): tpc = mct.get_target_platform_capabilities(PYTORCH, DEFAULT_TP_MODEL) # Latest - self.assertTrue(tpc.tp_model.tpc_minor_version == 1) - - tpc = mct.get_target_platform_capabilities(PYTORCH, DEFAULT_TP_MODEL, 'v1') - self.assertTrue(tpc.tp_model.tpc_minor_version == 1) - tpc = mct.get_target_platform_capabilities(PYTORCH, DEFAULT_TP_MODEL, 'v2') - self.assertTrue(tpc.tp_model.tpc_minor_version == 2) + self.assertTrue(tpc.tpc_minor_version == 1) tpc = mct.get_target_platform_capabilities(PYTORCH, IMX500_TP_MODEL, "v1") - self.assertTrue(tpc.tp_model.tpc_minor_version == 1) - tpc = mct.get_target_platform_capabilities(PYTORCH, IMX500_TP_MODEL, "v2") - self.assertTrue(tpc.tp_model.tpc_minor_version == 2) + self.assertTrue(tpc.tpc_minor_version == 1) tpc = mct.get_target_platform_capabilities(PYTORCH, TFLITE_TP_MODEL, "v1") - self.assertTrue(tpc.tp_model.tpc_minor_version == 1) + self.assertTrue(tpc.tpc_minor_version == 1) tpc = mct.get_target_platform_capabilities(PYTORCH, QNNPACK_TP_MODEL, "v1") - self.assertTrue(tpc.tp_model.tpc_minor_version == 1) + self.assertTrue(tpc.tpc_minor_version == 1) def test_get_pytorch_not_supported_platform(self): with self.assertRaises(Exception) as e: @@ -328,7 +322,7 @@ def test_get_pytorch_not_supported_fw(self): def test_get_pytorch_not_supported_version(self): with self.assertRaises(Exception) as e: - mct.get_target_platform_capabilities(PYTORCH, DEFAULT_TP_MODEL, "v0") + mct.get_target_platform_capabilities(PYTORCH, IMX500_TP_MODEL, "v0") self.assertTrue(e.exception) diff --git a/tests/pytorch_tests/function_tests/test_quant_config_filtering.py b/tests/pytorch_tests/function_tests/test_quant_config_filtering.py index fc344f38f..870b4818e 100644 --- a/tests/pytorch_tests/function_tests/test_quant_config_filtering.py +++ b/tests/pytorch_tests/function_tests/test_quant_config_filtering.py @@ -13,14 +13,19 @@ # limitations under the License. # ============================================================================== import unittest -import model_compression_toolkit as mct -from model_compression_toolkit.constants import PYTORCH -from model_compression_toolkit.target_platform_capabilities.constants import IMX500_TP_MODEL from model_compression_toolkit.core.common.graph.functional_node import FunctionalNode from model_compression_toolkit.core.keras.constants import FUNCTION import torch +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import OperatorSetNames, \ + QuantizationConfigOptions +from model_compression_toolkit.target_platform_capabilities.schema.schema_functions import \ + get_config_options_by_operators_set +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2pytorch import \ + AttachTpcToPytorch +from tests.common_tests.helpers.generate_test_tp_model import generate_custom_test_tp_model +from tests.common_tests.helpers.tpcs_for_tests.v3.tp_model import get_tp_model get_op_set = lambda x, x_list: [op_set for op_set in x_list if op_set.name == x][0] @@ -29,13 +34,23 @@ class TestTorchQuantConfigFiltering(unittest.TestCase): @staticmethod def get_tpc_default_16bit(): - tpc = mct.get_target_platform_capabilities(PYTORCH, IMX500_TP_MODEL, 'v3') - # Force Mul base_config to 16bit only - mul_op_set = get_op_set('Mul', tpc.tp_model.operator_set) - base_config = [l for l in mul_op_set.qc_options.quantization_configurations if l.activation_n_bits == 16][0] - tpc.layer2qco[torch.multiply] = tpc.layer2qco[torch.multiply].copy( - update={'quantization_configurations': mul_op_set.qc_options.quantization_configurations, - 'base_config': base_config}) + tpc = get_tp_model() + base_cfg_16 = [c for c in get_config_options_by_operators_set(tpc, + OperatorSetNames.MUL).quantization_configurations + if c.activation_n_bits == 16][0].clone_and_edit() + qco_16 = QuantizationConfigOptions(base_config=base_cfg_16, + quantization_configurations=(tpc.default_qco.base_config, + base_cfg_16)) + tpc = generate_custom_test_tp_model( + name="custom_16_bit_tpc", + base_cfg=tpc.default_qco.base_config, + base_tp_model=tpc, + operator_sets_dict={ + OperatorSetNames.MUL: qco_16, + OperatorSetNames.GELU: qco_16, + OperatorSetNames.TANH: qco_16, + }) + return tpc def test_config_filtering(self): @@ -50,6 +65,8 @@ def test_config_filtering(self): [], {}, functional_op=torch.div) tpc = self.get_tpc_default_16bit() + tpc = AttachTpcToPytorch().attach(tpc) + node_qc_options = node.get_qco(tpc) self.assertTrue(node_qc_options.base_config.activation_n_bits == 16, "base_config should start with 16 bits.") diff --git a/tests/pytorch_tests/function_tests/test_sensitivity_eval_non_supported_output.py b/tests/pytorch_tests/function_tests/test_sensitivity_eval_non_supported_output.py index 8889c3832..a9b4724e1 100644 --- a/tests/pytorch_tests/function_tests/test_sensitivity_eval_non_supported_output.py +++ b/tests/pytorch_tests/function_tests/test_sensitivity_eval_non_supported_output.py @@ -20,6 +20,8 @@ from model_compression_toolkit.core.common.hessian import HessianInfoService from model_compression_toolkit.core.pytorch.default_framework_info import DEFAULT_PYTORCH_INFO from model_compression_toolkit.core.pytorch.pytorch_implementation import PytorchImplementation +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2pytorch import \ + AttachTpcToPytorch from tests.common_tests.helpers.prep_graph_for_func_test import prepare_graph_with_quantization_parameters from tests.pytorch_tests.model_tests.base_pytorch_test import BasePytorchTest from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import generate_pytorch_tpc @@ -65,7 +67,8 @@ def verify_test_for_model(self, model): self.representative_data_gen, generate_pytorch_tpc, input_shape=(1, 3, 16, 16), - mixed_precision_enabled=True) + mixed_precision_enabled=True, + attach2fw=AttachTpcToPytorch()) hessian_info_service = HessianInfoService(graph=graph, fw_impl=pytorch_impl) se = pytorch_impl.get_sensitivity_evaluator(graph, diff --git a/tests/pytorch_tests/model_tests/base_pytorch_test.py b/tests/pytorch_tests/model_tests/base_pytorch_test.py index b7cc402f5..a06d67a57 100644 --- a/tests/pytorch_tests/model_tests/base_pytorch_test.py +++ b/tests/pytorch_tests/model_tests/base_pytorch_test.py @@ -15,13 +15,13 @@ import random from torch.fx import symbolic_trace -from model_compression_toolkit.target_platform_capabilities.target_platform import TargetPlatformCapabilities -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import generate_pytorch_tpc from model_compression_toolkit.core.pytorch.utils import set_model, to_torch_tensor, \ torch_tensor_to_numpy import model_compression_toolkit as mct import torch import numpy as np + +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel from tests.common_tests.base_feature_test import BaseFeatureNetworkTest from tests.common_tests.helpers.generate_test_tp_model import generate_test_tp_model @@ -44,24 +44,21 @@ def __init__(self, def get_tpc(self): return { - 'no_quantization': generate_pytorch_tpc(name="no_quant_pytorch_test", - tp_model=generate_test_tp_model({'weights_n_bits': 32, - 'activation_n_bits': 32, - 'enable_weights_quantization': False, - 'enable_activation_quantization': False - })), - 'all_32bit': generate_pytorch_tpc(name="32_quant_pytorch_test", - tp_model=generate_test_tp_model({'weights_n_bits': 32, - 'activation_n_bits': 32, - 'enable_weights_quantization': True, - 'enable_activation_quantization': True - })), - 'all_4bit': generate_pytorch_tpc(name="4_quant_pytorch_test", - tp_model=generate_test_tp_model({'weights_n_bits': 4, - 'activation_n_bits': 4, - 'enable_weights_quantization': True, - 'enable_activation_quantization': True - })), + 'no_quantization': generate_test_tp_model({'weights_n_bits': 32, + 'activation_n_bits': 32, + 'enable_weights_quantization': False, + 'enable_activation_quantization': False + }), + 'all_32bit': generate_test_tp_model({'weights_n_bits': 32, + 'activation_n_bits': 32, + 'enable_weights_quantization': True, + 'enable_activation_quantization': True + }), + 'all_4bit': generate_test_tp_model({'weights_n_bits': 4, + 'activation_n_bits': 4, + 'enable_weights_quantization': True, + 'enable_activation_quantization': True + }), } def get_core_configs(self): @@ -139,7 +136,7 @@ def representative_data_gen_experimental(): "mapping the test model name to a TPC object." for model_name in tpc_dict.keys(): tpc = tpc_dict[model_name] - assert isinstance(tpc, TargetPlatformCapabilities) + assert isinstance(tpc, TargetPlatformModel) core_config = core_config_dict.get(model_name) assert core_config is not None, f"Model name {model_name} does not exists in the test's " \ diff --git a/tests/pytorch_tests/model_tests/feature_models/activation_16bit_test.py b/tests/pytorch_tests/model_tests/feature_models/activation_16bit_test.py index 44eec1fc3..3ab11b38a 100644 --- a/tests/pytorch_tests/model_tests/feature_models/activation_16bit_test.py +++ b/tests/pytorch_tests/model_tests/feature_models/activation_16bit_test.py @@ -19,15 +19,16 @@ from model_compression_toolkit.constants import PYTORCH from model_compression_toolkit.core import MixedPrecisionQuantizationConfig from model_compression_toolkit.target_platform_capabilities.constants import IMX500_TP_MODEL -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.v4.tp_model import \ - OPSET_MUL, OPSET_GELU, OPSET_TANH +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import OperatorSetNames, \ + QuantizationConfigOptions +from model_compression_toolkit.target_platform_capabilities.schema.schema_functions import \ + get_config_options_by_operators_set +from tests.common_tests.helpers.generate_test_tp_model import generate_custom_test_tp_model +from tests.common_tests.helpers.tpcs_for_tests.v4.tp_model import get_tp_model from model_compression_toolkit.core.pytorch.utils import get_working_device from tests.pytorch_tests.model_tests.base_pytorch_feature_test import BasePytorchFeatureNetworkTest -get_op_set = lambda x, x_list: [op_set for op_set in x_list if op_set.name == x][0] - - class Activation16BitNet(torch.nn.Module): def __init__(self, use_concat=True, enable_head=True): @@ -81,21 +82,25 @@ def forward(self, x): return x -def set_16bit_as_default(tpc, required_op_set, required_ops_list): - for op in required_ops_list: - base_config = [l for l in tpc.layer2qco[op].quantization_configurations if l.activation_n_bits == 16][0] - tpc.layer2qco[op] = tpc.layer2qco[op].copy( - update={'quantization_configurations': tpc.layer2qco[op].quantization_configurations, - 'base_config': base_config}) - - class Activation16BitTest(BasePytorchFeatureNetworkTest): def get_tpc(self): - tpc = mct.get_target_platform_capabilities(PYTORCH, IMX500_TP_MODEL, 'v4') - set_16bit_as_default(tpc, OPSET_MUL, [torch.mul, mul]) - set_16bit_as_default(tpc, OPSET_GELU, [torch.nn.GELU, torch.nn.functional.gelu]) - set_16bit_as_default(tpc, OPSET_TANH, [torch.nn.Tanh, torch.nn.functional.tanh, torch.tanh]) + tpc = get_tp_model() + base_cfg_16 = [c for c in get_config_options_by_operators_set(tpc, OperatorSetNames.MUL).quantization_configurations + if c.activation_n_bits == 16][0].clone_and_edit() + qco_16 = QuantizationConfigOptions(base_config=base_cfg_16, + quantization_configurations=(tpc.default_qco.base_config, + base_cfg_16)) + tpc = generate_custom_test_tp_model( + name="custom_16_bit_tpc", + base_cfg=tpc.default_qco.base_config, + base_tp_model=tpc, + operator_sets_dict={ + OperatorSetNames.MUL: qco_16, + OperatorSetNames.GELU: qco_16, + OperatorSetNames.TANH: qco_16, + }) + return tpc def create_networks(self): @@ -124,17 +129,26 @@ def compare(self, quantized_model, float_model, input_x=None, quantization_info= class Activation16BitMixedPrecisionTest(Activation16BitTest): def get_tpc(self): - tpc = mct.get_target_platform_capabilities(PYTORCH, IMX500_TP_MODEL, 'v4') - mul_op_set = get_op_set('Mul', tpc.tp_model.operator_set) - base_config = [l for l in mul_op_set.qc_options.quantization_configurations if l.activation_n_bits == 16][0] - quantization_configurations = list(mul_op_set.qc_options.quantization_configurations) + tpc = get_tp_model() + + mul_qco = get_config_options_by_operators_set(tpc, OperatorSetNames.MUL) + base_cfg_16 = [l for l in mul_qco.quantization_configurations if l.activation_n_bits == 16][0] + quantization_configurations = list(mul_qco.quantization_configurations) quantization_configurations.extend([ - tpc.layer2qco[torch.mul].base_config.clone_and_edit(activation_n_bits=4), - tpc.layer2qco[torch.mul].base_config.clone_and_edit(activation_n_bits=2)]) - tpc.layer2qco[torch.mul] = tpc.layer2qco[torch.mul].copy( - update={'base_config': base_config, 'quantization_configurations': tuple(quantization_configurations)}) - tpc.layer2qco[mul] = tpc.layer2qco[mul].copy( - update={'base_config': base_config, 'quantization_configurations': tuple(quantization_configurations)}) + base_cfg_16.clone_and_edit(activation_n_bits=4), + base_cfg_16.clone_and_edit(activation_n_bits=2)]) + + qco_16 = QuantizationConfigOptions(base_config=base_cfg_16, + quantization_configurations=quantization_configurations) + + tpc = generate_custom_test_tp_model( + name="custom_16_bit_tpc", + base_cfg=tpc.default_qco.base_config, + base_tp_model=tpc, + operator_sets_dict={ + OperatorSetNames.MUL: qco_16, + }) + return tpc def get_resource_utilization(self): diff --git a/tests/pytorch_tests/model_tests/feature_models/bn_attributes_quantization_test.py b/tests/pytorch_tests/model_tests/feature_models/bn_attributes_quantization_test.py index 111643ea6..ca1c09f3e 100644 --- a/tests/pytorch_tests/model_tests/feature_models/bn_attributes_quantization_test.py +++ b/tests/pytorch_tests/model_tests/feature_models/bn_attributes_quantization_test.py @@ -19,9 +19,11 @@ import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema from mct_quantizers import QuantizationMethod, PytorchQuantizationWrapper from model_compression_toolkit import DefaultDict +from model_compression_toolkit.core import CoreConfig, QuantizationConfig from model_compression_toolkit.core.pytorch.constants import GAMMA, BETA from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, PYTORCH_KERNEL, BIAS, \ BIAS_ATTR +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers from tests.common_tests.helpers.generate_test_tp_model import generate_test_attr_configs, \ DEFAULT_WEIGHT_ATTR_CONFIG, KERNEL_BASE_CONFIG, generate_test_op_qc, BIAS_CONFIG from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import Signedness @@ -92,23 +94,6 @@ def _generate_bn_quantized_tpm(quantize_linear): return generated_tpm -def _generate_bn_quantized_tpc(tp_model): - tpc = tp.TargetPlatformCapabilities(tp_model) - - with tpc: - tp.OperationsSetToLayers("Conv", [nn.Conv2d], - attr_mapping={ - KERNEL_ATTR: DefaultDict(default_value=PYTORCH_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}) - - tp.OperationsSetToLayers("BN", [nn.BatchNorm2d], - attr_mapping={ - GAMMA: DefaultDict(default_value=GAMMA), - BETA: DefaultDict(default_value=BETA)}) - - return tpc - - class BNAttributesQuantization(BasePytorchTest): def __init__(self, unit_test, quantize_linear): @@ -119,10 +104,18 @@ def __init__(self, unit_test, quantize_linear): def get_tpc(self): tpm = _generate_bn_quantized_tpm(self.quantize_linear) - return {self.test_name: _generate_bn_quantized_tpc(tpm)} + return {self.test_name: tpm} def get_core_configs(self): - return {self.test_name: mct.core.CoreConfig()} + return {self.test_name: CoreConfig( + quantization_config=QuantizationConfig( + custom_tpc_opset_to_layer={ + "Conv": CustomOpsetLayers([nn.Conv2d], + {KERNEL_ATTR: DefaultDict(default_value=PYTORCH_KERNEL), + BIAS_ATTR: DefaultDict(default_value=BIAS)}), + "BN": CustomOpsetLayers([nn.BatchNorm2d], {GAMMA: DefaultDict(default_value=GAMMA), + BETA: DefaultDict(default_value=BETA)}) + }))} def create_feature_network(self, input_shape): class BNAttributesNet(nn.Module): diff --git a/tests/pytorch_tests/model_tests/feature_models/compute_max_cut_test.py b/tests/pytorch_tests/model_tests/feature_models/compute_max_cut_test.py index 9d9ab1efa..a648ff95b 100644 --- a/tests/pytorch_tests/model_tests/feature_models/compute_max_cut_test.py +++ b/tests/pytorch_tests/model_tests/feature_models/compute_max_cut_test.py @@ -15,6 +15,7 @@ import torch.nn as nn import model_compression_toolkit as mct +from tests.common_tests.helpers.tpcs_for_tests.v2.tp_model import get_tp_model from tests.pytorch_tests.model_tests.base_pytorch_feature_test import BasePytorchFeatureNetworkTest from model_compression_toolkit.target_platform_capabilities.constants import IMX500_TP_MODEL from model_compression_toolkit.constants import PYTORCH @@ -42,9 +43,7 @@ def forward(self, x): class ComputeMaxCutTest(BasePytorchFeatureNetworkTest): def get_tpc(self): - return mct.get_target_platform_capabilities(PYTORCH, - IMX500_TP_MODEL, - "v2") + return get_tp_model() def create_networks(self): return MaxCutModel() diff --git a/tests/pytorch_tests/model_tests/feature_models/const_quantization_test.py b/tests/pytorch_tests/model_tests/feature_models/const_quantization_test.py index 13c7fb878..cda176144 100644 --- a/tests/pytorch_tests/model_tests/feature_models/const_quantization_test.py +++ b/tests/pytorch_tests/model_tests/feature_models/const_quantization_test.py @@ -19,14 +19,15 @@ import model_compression_toolkit as mct import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import Signedness -from model_compression_toolkit.core import MixedPrecisionQuantizationConfig +from model_compression_toolkit.core import MixedPrecisionQuantizationConfig, CoreConfig, QuantizationConfig from model_compression_toolkit.core.pytorch.utils import to_torch_tensor, torch_tensor_to_numpy, set_model +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers +from tests.common_tests.helpers.tpcs_for_tests.v4.tp_model import get_tp_model as get_tp_v4 +from tests.common_tests.helpers.tpcs_for_tests.v3.tp_model import get_tp_model as get_tp_v3 from tests.pytorch_tests.model_tests.base_pytorch_feature_test import BasePytorchFeatureNetworkTest from tests.common_tests.helpers.tensors_compare import cosine_similarity from tests.pytorch_tests.utils import get_layers_from_model_by_type from tests.common_tests.helpers.generate_test_tp_model import generate_test_attr_configs, DEFAULT_WEIGHT_ATTR_CONFIG -from model_compression_toolkit.target_platform_capabilities.constants import IMX500_TP_MODEL -from model_compression_toolkit.constants import PYTORCH from mct_quantizers import PytorchQuantizationWrapper tp = mct.target_platform @@ -64,7 +65,7 @@ def generate_inputs(self): return [np.random.random(in_shape) + 1 for in_shape in self.get_input_shapes()] def get_tpc(self): - return mct.get_target_platform_capabilities(PYTORCH, IMX500_TP_MODEL, "v3") + return get_tp_v3() def create_networks(self): if self.input_reverse_order: @@ -121,7 +122,7 @@ def generate_inputs(self): return [np.random.random(in_shape) + 1 for in_shape in self.get_input_shapes()] def get_tpc(self): - return mct.get_target_platform_capabilities(PYTORCH, IMX500_TP_MODEL, "v3") + return get_tp_v3() def get_mixed_precision_config(self): return MixedPrecisionQuantizationConfig() @@ -180,7 +181,7 @@ def generate_inputs(self): return [np.random.randint(-128, 127, size=in_shape) for in_shape in self.get_input_shapes()] def get_tpc(self): - return mct.get_target_platform_capabilities(PYTORCH, IMX500_TP_MODEL, "v4") + return get_tp_v4() def create_networks(self): return MultiInputConstQuantizationNet() @@ -225,6 +226,10 @@ def __init__(self, unit_test): def generate_inputs(self): return [np.random.randint(-128, 127, size=in_shape).astype(np.float32) for in_shape in self.get_input_shapes()] + def get_core_config(self): + return CoreConfig(quantization_config=QuantizationConfig(custom_tpc_opset_to_layer= + {"WeightQuant": CustomOpsetLayers([torch.Tensor.expand, torch.cat])})) + def get_tpc(self): tp = mct.target_platform attr_cfg = generate_test_attr_configs() @@ -257,11 +262,7 @@ def get_tpc(self): operator_set=tuple([schema.OperatorsSet(name="WeightQuant", qc_options=const_configuration_options)]), add_metadata=False) - tpc = tp.TargetPlatformCapabilities(tp_model) - with tpc: - tp.OperationsSetToLayers("WeightQuant", [torch.Tensor.expand, torch.cat]) - - return tpc + return tp_model def create_networks(self): return ExpandConstQuantizationNet(self.val_batch_size) diff --git a/tests/pytorch_tests/model_tests/feature_models/dynamic_size_inputs_test.py b/tests/pytorch_tests/model_tests/feature_models/dynamic_size_inputs_test.py index c5a392013..d1c9d3046 100644 --- a/tests/pytorch_tests/model_tests/feature_models/dynamic_size_inputs_test.py +++ b/tests/pytorch_tests/model_tests/feature_models/dynamic_size_inputs_test.py @@ -18,9 +18,7 @@ import torch import model_compression_toolkit as mct -from model_compression_toolkit.core import MixedPrecisionQuantizationConfig -from model_compression_toolkit.target_platform_capabilities.target_platform import TargetPlatformCapabilities -from model_compression_toolkit.core.pytorch.default_framework_info import DEFAULT_PYTORCH_INFO +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel from tests.pytorch_tests.model_tests.base_pytorch_test import BasePytorchTest """ @@ -111,7 +109,8 @@ def representative_data_gen_experimental(): "mapping the test model name to a TPC object." for model_name in tpc_dict.keys(): tpc = tpc_dict[model_name] - assert isinstance(tpc, TargetPlatformCapabilities) + + assert isinstance(tpc, TargetPlatformModel) core_config = core_config_dict.get(model_name) assert core_config is not None, f"Model name {model_name} does not exists in the test's " \ diff --git a/tests/pytorch_tests/model_tests/feature_models/manual_bit_selection.py b/tests/pytorch_tests/model_tests/feature_models/manual_bit_selection.py index 57f83f80f..5d012769c 100644 --- a/tests/pytorch_tests/model_tests/feature_models/manual_bit_selection.py +++ b/tests/pytorch_tests/model_tests/feature_models/manual_bit_selection.py @@ -12,15 +12,21 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== -from operator import mul import inspect -from model_compression_toolkit.constants import PYTORCH -from model_compression_toolkit.target_platform_capabilities.constants import IMX500_TP_MODEL +from model_compression_toolkit.core.pytorch.reader.node_holders import DummyPlaceHolder from mct_quantizers import PytorchActivationQuantizationHolder import model_compression_toolkit as mct import torch + +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import OperatorSetNames, \ + QuantizationConfigOptions +from model_compression_toolkit.target_platform_capabilities.schema.schema_functions import \ + get_config_options_by_operators_set +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers +from tests.common_tests.helpers.generate_test_tp_model import generate_custom_test_tp_model +from tests.common_tests.helpers.tpcs_for_tests.v3.tp_model import get_tp_model from tests.pytorch_tests.model_tests.feature_models.mixed_precision_activation_test import \ MixedPrecisionActivationBaseTest from tests.pytorch_tests.utils import get_layer_type_from_activation_quantizer @@ -81,7 +87,8 @@ def create_feature_network(self, input_shape): def get_mp_core_config(): qc = mct.core.QuantizationConfig(mct.core.QuantizationErrorMethod.MSE, mct.core.QuantizationErrorMethod.MSE, relu_bound_to_power_of_2=False, weights_bias_correction=True, - input_scaling=False, activation_channel_equalization=False) + input_scaling=False, activation_channel_equalization=False, + custom_tpc_opset_to_layer={"Input": CustomOpsetLayers([DummyPlaceHolder])}) mpc = mct.core.MixedPrecisionQuantizationConfig(num_of_images=1) core_config = mct.core.CoreConfig(quantization_config=qc, mixed_precision_config=mpc) @@ -91,7 +98,7 @@ def get_core_configs(self): # Configures the core settings including manual bit width adjustments. core_config = self.get_mp_core_config() core_config.bit_width_config.set_manual_activation_bit_width(self.filters, self.bit_widths) - return {"mixed_precision_activation_model": core_config} + return {"manual_bit_selection": core_config} class ManualBitWidthByLayerTypeTest(BaseManualBitWidthSelectionTest): @@ -118,6 +125,10 @@ def __init__(self, unit_test, filters, bit_widths): super().__init__(unit_test) + def get_tpc(self): + tpc_dict = super().get_tpc() + return {"manual_bit_selection": v for _, v in tpc_dict.items()} + def compare(self, quantized_models, float_model, input_x=None, quantization_info=None): # in the compare we need bit_widths to be a list bit_widths = [self.bit_widths] if not isinstance(self.bit_widths, list) else self.bit_widths @@ -163,6 +174,10 @@ def __init__(self, unit_test, filters, bit_widths): super().__init__(unit_test) + def get_tpc(self): + tpc_dict = super().get_tpc() + return {"manual_bit_selection": v for _, v in tpc_dict.items()} + def compare(self, quantized_models, float_model, input_x=None, quantization_info=None): # in the compare we need bit_widths to be a list bit_widths = [self.bit_widths] if not isinstance(self.bit_widths, list) else self.bit_widths @@ -185,16 +200,24 @@ def compare(self, quantized_models, float_model, input_x=None, quantization_info class Manual16BitTest(ManualBitWidthByLayerNameTest): def get_tpc(self): - tpc = mct.get_target_platform_capabilities(PYTORCH, IMX500_TP_MODEL, 'v3') - mul_op_set = get_op_set('Mul', tpc.tp_model.operator_set) - base_config = [l for l in mul_op_set.qc_options.quantization_configurations if l.activation_n_bits == 16][0] - tpc.layer2qco[torch.mul] = tpc.layer2qco[torch.mul].copy( - update={'quantization_configurations': mul_op_set.qc_options.quantization_configurations, - 'base_config': base_config}) - tpc.layer2qco[mul] = tpc.layer2qco[mul].copy( - update={'quantization_configurations': mul_op_set.qc_options.quantization_configurations, - 'base_config': base_config}) - return {'mixed_precision_activation_model': tpc} + tpc = get_tp_model() + + mul_qco = get_config_options_by_operators_set(tpc, OperatorSetNames.MUL) + base_cfg_16 = [l for l in mul_qco.quantization_configurations if l.activation_n_bits == 16][0] + quantization_configurations = list(mul_qco.quantization_configurations) + + qco_16 = QuantizationConfigOptions(base_config=base_cfg_16, + quantization_configurations=quantization_configurations) + + tpc = generate_custom_test_tp_model( + name="custom_16_bit_tpc", + base_cfg=tpc.default_qco.base_config, + base_tp_model=tpc, + operator_sets_dict={ + OperatorSetNames.MUL: qco_16, + }) + + return {'manual_bit_selection': tpc} def create_feature_network(self, input_shape): return Activation16BitNet() @@ -203,18 +226,27 @@ def create_feature_network(self, input_shape): class Manual16BitTestMixedPrecisionTest(ManualBitWidthByLayerNameTest): def get_tpc(self): - tpc = mct.get_target_platform_capabilities(PYTORCH, IMX500_TP_MODEL, 'v3') - mul_op_set = get_op_set('Mul', tpc.tp_model.operator_set) - base_config = [l for l in mul_op_set.qc_options.quantization_configurations if l.activation_n_bits == 16][0] - quantization_configurations = list(mul_op_set.qc_options.quantization_configurations) - quantization_configurations.extend( - [mul_op_set.qc_options.base_config.clone_and_edit(activation_n_bits=4), - mul_op_set.qc_options.base_config.clone_and_edit(activation_n_bits=2)]) - tpc.layer2qco[torch.mul] = tpc.layer2qco[torch.mul].copy( - update={'base_config': base_config, 'quantization_configurations': tuple(quantization_configurations)}) - tpc.layer2qco[mul] = tpc.layer2qco[mul].copy( - update={'base_config': base_config, 'quantization_configurations': tuple(quantization_configurations)}) - return {'mixed_precision_activation_model': tpc} + tpc = get_tp_model() + + mul_qco = get_config_options_by_operators_set(tpc, OperatorSetNames.MUL) + base_cfg_16 = [l for l in mul_qco.quantization_configurations if l.activation_n_bits == 16][0] + quantization_configurations = list(mul_qco.quantization_configurations) + quantization_configurations.extend([ + base_cfg_16.clone_and_edit(activation_n_bits=4), + base_cfg_16.clone_and_edit(activation_n_bits=2)]) + + qco_16 = QuantizationConfigOptions(base_config=base_cfg_16, + quantization_configurations=quantization_configurations) + + tpc = generate_custom_test_tp_model( + name="custom_16_bit_tpc", + base_cfg=tpc.default_qco.base_config, + base_tp_model=tpc, + operator_sets_dict={ + OperatorSetNames.MUL: qco_16, + }) + + return {'manual_bit_selection': tpc} def get_resource_utilization(self): return mct.core.ResourceUtilization(activation_memory=15000) diff --git a/tests/pytorch_tests/model_tests/feature_models/metadata_test.py b/tests/pytorch_tests/model_tests/feature_models/metadata_test.py index 16137b93a..4ee1937ff 100644 --- a/tests/pytorch_tests/model_tests/feature_models/metadata_test.py +++ b/tests/pytorch_tests/model_tests/feature_models/metadata_test.py @@ -18,6 +18,7 @@ import numpy as np import model_compression_toolkit as mct from model_compression_toolkit.core.pytorch.utils import to_torch_tensor, torch_tensor_to_numpy, set_model +from tests.common_tests.helpers.tpcs_for_tests.v2.tp_model import get_tp_model from tests.pytorch_tests.model_tests.base_pytorch_feature_test import BasePytorchFeatureNetworkTest from tests.common_tests.helpers.tensors_compare import cosine_similarity from model_compression_toolkit.target_platform_capabilities.constants import IMX500_TP_MODEL @@ -42,7 +43,7 @@ def forward(self, x): class MetadataTest(BasePytorchFeatureNetworkTest): def get_tpc(self): - return mct.get_target_platform_capabilities(PYTORCH, IMX500_TP_MODEL, "v2") + return get_tp_model() def create_networks(self): return DummyNet() diff --git a/tests/pytorch_tests/model_tests/feature_models/mixed_precision_activation_test.py b/tests/pytorch_tests/model_tests/feature_models/mixed_precision_activation_test.py index 1d0576fad..337f7dd8b 100644 --- a/tests/pytorch_tests/model_tests/feature_models/mixed_precision_activation_test.py +++ b/tests/pytorch_tests/model_tests/feature_models/mixed_precision_activation_test.py @@ -18,13 +18,16 @@ from torch.nn import Softmax, Sigmoid from model_compression_toolkit import DefaultDict -from model_compression_toolkit.core import MixedPrecisionQuantizationConfig, ResourceUtilization +from model_compression_toolkit.core import MixedPrecisionQuantizationConfig, ResourceUtilization, CoreConfig, \ + QuantizationConfig from model_compression_toolkit.core.common.user_info import UserInformation +from model_compression_toolkit.core.pytorch.reader.node_holders import DummyPlaceHolder from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, BIAS_ATTR, PYTORCH_KERNEL, \ BIAS from model_compression_toolkit.target_platform_capabilities.target_platform import TargetPlatformCapabilities, OperationsSetToLayers from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel, OperatorsSet, \ QuantizationConfigOptions +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import get_op_quantization_configs from tests.common_tests.helpers.generate_test_tp_model import generate_tp_model_with_activation_mp from tests.pytorch_tests.model_tests.base_pytorch_test import BasePytorchTest @@ -55,7 +58,8 @@ def get_tpc(self): def get_core_configs(self): qc = mct.core.QuantizationConfig(mct.core.QuantizationErrorMethod.MSE, mct.core.QuantizationErrorMethod.MSE, relu_bound_to_power_of_2=False, weights_bias_correction=True, - input_scaling=False, activation_channel_equalization=False) + input_scaling=False, activation_channel_equalization=False, + custom_tpc_opset_to_layer={"Input": CustomOpsetLayers([DummyPlaceHolder])}) mpc = mct.core.MixedPrecisionQuantizationConfig(num_of_images=1) return {"mixed_precision_activation_model": mct.core.CoreConfig(quantization_config=qc, mixed_precision_config=mpc)} @@ -136,6 +140,11 @@ def __init__(self, unit_test): def get_resource_utilization(self): return ResourceUtilization(np.inf, 431) + def get_core_configs(self): + return {"mixed_precision_activation_model": CoreConfig(quantization_config=QuantizationConfig( + custom_tpc_opset_to_layer={'Concat': CustomOpsetLayers([torch.concat]), + "Input": CustomOpsetLayers([DummyPlaceHolder])}))} + def get_tpc(self): base_config, _, default_config = get_op_quantization_configs() return get_mp_activation_pytorch_tpc_dict( @@ -145,8 +154,7 @@ def get_tpc(self): mp_bitwidth_candidates_list=[(8, 8), (8, 4), (8, 2), (4, 8), (4, 4), (4, 2), (2, 8), (2, 4), (2, 2)], - custom_opsets=['Concat']), - custom_opsets_to_layer={'Concat': [torch.concat]}, + custom_opsets=['Concat']), test_name='mixed_precision_activation_model', tpc_name='mixed_precision_activation_pytorch_test') @@ -250,9 +258,13 @@ def __init__(self, unit_test): def get_resource_utilization(self): return ResourceUtilization(np.inf, 3071) + def get_core_configs(self): + return {"mixed_precision_activation_model": CoreConfig(quantization_config=QuantizationConfig( + custom_tpc_opset_to_layer={'Softmax': CustomOpsetLayers([softmax, Softmax]), + "Input": CustomOpsetLayers([DummyPlaceHolder])}))} + def get_tpc(self): base_config, _, default_config = get_op_quantization_configs() - custom_opsets_to_layer = {'Softmax': [softmax, Softmax]} mp_list = [(8, 8), (8, 4), (8, 2), (4, 8), (4, 4), (4, 2), (2, 8), (2, 4), (2, 2)] @@ -264,7 +276,6 @@ def get_tpc(self): custom_opsets=['Softmax']) return get_mp_activation_pytorch_tpc_dict(tpc_model=tp_model, - custom_opsets_to_layer=custom_opsets_to_layer, test_name='mixed_precision_activation_model', tpc_name='mixed_precision_distance_fn_test') @@ -280,6 +291,15 @@ def __init__(self, unit_test): super().__init__(unit_test) self.expected_config = [1, 1] + def get_core_configs(self): + return {"mixed_precision_activation_model": CoreConfig(quantization_config=QuantizationConfig( + custom_tpc_opset_to_layer={"Weights": CustomOpsetLayers([torch.nn.Conv2d], + {KERNEL_ATTR: DefaultDict( + default_value=PYTORCH_KERNEL), + BIAS_ATTR: DefaultDict(default_value=BIAS)}), + "Activations": CustomOpsetLayers([torch.nn.ReLU, torch.add])} + ))} + def get_tpc(self): cfg, mixed_precision_cfg_list, _ = get_op_quantization_configs() @@ -315,22 +335,7 @@ def get_tpc(self): add_metadata=False, name="mp_activation_conf_weights_test") - torch_tpc = TargetPlatformCapabilities(tp_model) - - with torch_tpc: - OperationsSetToLayers( - "Weights", - [torch.nn.Conv2d], - attr_mapping={KERNEL_ATTR: DefaultDict(default_value=PYTORCH_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)} - ) - - OperationsSetToLayers( - "Activations", - [torch.nn.ReLU, torch.add] - ) - - return {'mixed_precision_activation_model': torch_tpc} + return {'mixed_precision_activation_model': tp_model} def create_feature_network(self, input_shape): return MixedPrecisionActivationTestNet(input_shape) diff --git a/tests/pytorch_tests/model_tests/feature_models/mixed_precision_bops_test.py b/tests/pytorch_tests/model_tests/feature_models/mixed_precision_bops_test.py index dfd585cdd..7016a84fd 100644 --- a/tests/pytorch_tests/model_tests/feature_models/mixed_precision_bops_test.py +++ b/tests/pytorch_tests/model_tests/feature_models/mixed_precision_bops_test.py @@ -14,6 +14,8 @@ # ============================================================================== import torch.nn from model_compression_toolkit.core import MixedPrecisionQuantizationConfig, ResourceUtilization, MixedPrecisionQuantizationConfig +from model_compression_toolkit.core.pytorch.reader.node_holders import DummyPlaceHolder +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers from tests.pytorch_tests.model_tests.base_pytorch_test import BasePytorchTest from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import get_op_quantization_configs @@ -116,7 +118,8 @@ def get_tpc(self): def get_core_configs(self): qc = mct.core.QuantizationConfig(mct.core.QuantizationErrorMethod.MSE, mct.core.QuantizationErrorMethod.MSE, relu_bound_to_power_of_2=False, weights_bias_correction=True, - input_scaling=False, activation_channel_equalization=False) + input_scaling=False, activation_channel_equalization=False, + custom_tpc_opset_to_layer={"Input": CustomOpsetLayers([DummyPlaceHolder])}) mpc = MixedPrecisionQuantizationConfig(num_of_images=1) return {"mixed_precision_bops_model": mct.core.CoreConfig(quantization_config=qc, mixed_precision_config=mpc)} diff --git a/tests/pytorch_tests/model_tests/feature_models/mixed_precision_weights_test.py b/tests/pytorch_tests/model_tests/feature_models/mixed_precision_weights_test.py index 4560e6614..1fa5fa58e 100644 --- a/tests/pytorch_tests/model_tests/feature_models/mixed_precision_weights_test.py +++ b/tests/pytorch_tests/model_tests/feature_models/mixed_precision_weights_test.py @@ -18,7 +18,7 @@ import model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema as schema from model_compression_toolkit.defaultdict import DefaultDict -from model_compression_toolkit.core import ResourceUtilization +from model_compression_toolkit.core import ResourceUtilization, CoreConfig, QuantizationConfig from model_compression_toolkit.core.common.mixed_precision.distance_weighting import MpDistanceWeighting from model_compression_toolkit.core.common.user_info import UserInformation from model_compression_toolkit.core.pytorch.constants import BIAS @@ -27,6 +27,7 @@ OperationsSetToLayers from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel, OperatorsSet, \ QuantizationConfigOptions +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import get_tp_model, \ get_op_quantization_configs from tests.common_tests.helpers.generate_test_tp_model import generate_mixed_precision_test_tp_model @@ -133,6 +134,16 @@ class MixedPrecisionSearchPartWeightsLayers(MixedPrecisionBaseTest): def __init__(self, unit_test): super().__init__(unit_test) + def get_core_configs(self): + return {"mixed_precision_model": CoreConfig(quantization_config=QuantizationConfig( + custom_tpc_opset_to_layer={"Weights_mp": CustomOpsetLayers([torch.nn.Conv2d], + {KERNEL_ATTR: DefaultDict(default_value=PYTORCH_KERNEL), + BIAS_ATTR: DefaultDict(default_value=BIAS)}), + "Weights_fixed": CustomOpsetLayers([torch.nn.Linear], + {KERNEL_ATTR: DefaultDict(default_value=PYTORCH_KERNEL), + BIAS_ATTR: DefaultDict(default_value=BIAS)})} + ))} + def get_tpc(self): # Building a TPC that gives Conv layers mixed precision candidates and Dense layers a fixed candidate. # Both layers that have weights to quantized, so we want to verify that finalizing the model is successful. @@ -160,25 +171,7 @@ def get_tpc(self): schema.OperatorsSet(name="Weights_fixed", qc_options=weight_fixed_cfg)]), name="mp_part_weights_layers_test") - - pytorch_tpc = tp.TargetPlatformCapabilities(tp_model) - - with pytorch_tpc: - tp.OperationsSetToLayers( - "Weights_fixed", - [torch.nn.Linear], - attr_mapping={KERNEL_ATTR: DefaultDict(default_value=PYTORCH_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)} - ) - - tp.OperationsSetToLayers( - "Weights_mp", - [torch.nn.Conv2d], - attr_mapping={KERNEL_ATTR: DefaultDict(default_value=PYTORCH_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)} - ) - - return {'mixed_precision_model': pytorch_tpc} + return {'mixed_precision_model': tp_model} def create_feature_network(self, input_shape): class ConvLinearModel(torch.nn.Module): @@ -294,6 +287,14 @@ def __init__(self, unit_test): super().__init__(unit_test) self.expected_config = [1] + def get_core_configs(self): + return {"mixed_precision_model": CoreConfig(quantization_config=QuantizationConfig( + custom_tpc_opset_to_layer={"Weights": CustomOpsetLayers([torch.nn.Conv2d], + {KERNEL_ATTR: DefaultDict(default_value=PYTORCH_KERNEL), + BIAS_ATTR: DefaultDict(default_value=BIAS)}), + "Activations": CustomOpsetLayers([torch.nn.ReLU, torch.add])} + ))} + def get_tpc(self): cfg, mixed_precision_cfg_list, _ = get_op_quantization_configs() @@ -328,22 +329,7 @@ def get_tpc(self): OperatorsSet(name="Weights", qc_options=weight_mixed_cfg)]), name="mp_weights_conf_act_test") - torch_tpc = TargetPlatformCapabilities(tp_model) - - with torch_tpc: - OperationsSetToLayers( - "Weights", - [torch.nn.Conv2d], - attr_mapping={KERNEL_ATTR: DefaultDict(default_value=PYTORCH_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)} - ) - - OperationsSetToLayers( - "Activations", - [torch.nn.ReLU, torch.add] - ) - - return {'mixed_precision_model': torch_tpc} + return {'mixed_precision_model': tp_model} def create_feature_network(self, input_shape): return MixedPrecisionWeightsTestNet(input_shape) diff --git a/tests/pytorch_tests/model_tests/feature_models/multi_head_attention_test.py b/tests/pytorch_tests/model_tests/feature_models/multi_head_attention_test.py index 3cb4d34af..503d6751a 100644 --- a/tests/pytorch_tests/model_tests/feature_models/multi_head_attention_test.py +++ b/tests/pytorch_tests/model_tests/feature_models/multi_head_attention_test.py @@ -19,6 +19,7 @@ import torch.nn as nn import model_compression_toolkit as mct +from model_compression_toolkit.target_platform_capabilities.schema.mct_current_schema import TargetPlatformModel from model_compression_toolkit.target_platform_capabilities.target_platform import TargetPlatformCapabilities from model_compression_toolkit.core.pytorch.default_framework_info import DEFAULT_PYTORCH_INFO from tests.pytorch_tests.model_tests.base_pytorch_test import BasePytorchTest @@ -104,7 +105,7 @@ def representative_data_gen(): assert isinstance(tpc_dict, dict), "Pytorch tests get_tpc should return a dictionary " \ "mapping the test model name to a TPC object." for model_name, tpc in tpc_dict.items(): - assert isinstance(tpc, TargetPlatformCapabilities) + assert isinstance(tpc, TargetPlatformModel) assert model_name in core_configs_dict core_config = core_configs_dict[model_name] diff --git a/tests/pytorch_tests/model_tests/feature_models/qat_test.py b/tests/pytorch_tests/model_tests/feature_models/qat_test.py index 75def1874..1d68ad95e 100644 --- a/tests/pytorch_tests/model_tests/feature_models/qat_test.py +++ b/tests/pytorch_tests/model_tests/feature_models/qat_test.py @@ -27,10 +27,13 @@ from mct_quantizers.common.base_inferable_quantizer import QuantizerID from mct_quantizers.common.get_all_subclasses import get_all_subclasses from mct_quantizers.pytorch.quantizers import BasePyTorchInferableQuantizer +from model_compression_toolkit.core import CoreConfig, QuantizationConfig from model_compression_toolkit.core.pytorch.pytorch_device_config import get_working_device +from model_compression_toolkit.core.pytorch.reader.node_holders import DummyPlaceHolder from model_compression_toolkit.core.pytorch.utils import to_torch_tensor from model_compression_toolkit.qat.pytorch.quantizer.base_pytorch_qat_weight_quantizer import \ BasePytorchQATWeightTrainableQuantizer +from model_compression_toolkit.core.common.quantization.quantization_config import CustomOpsetLayers from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import generate_pytorch_tpc, \ get_op_quantization_configs from model_compression_toolkit.trainable_infrastructure import TrainingMethod @@ -133,7 +136,6 @@ def run_test(self): self.representative_data_gen_experimental, target_platform_capabilities=_tpc) - qat_ready_model, quantization_info = mct.qat.pytorch_quantization_aware_training_init_experimental(model_float, self.representative_data_gen_experimental, qat_config=_qat_config, @@ -270,7 +272,9 @@ def get_tpc(self): def run_test(self): self._gen_fixed_input() model_float = self.create_networks() - config = mct.core.CoreConfig(mct.core.QuantizationConfig(shift_negative_activation_correction=False)) + config = mct.core.CoreConfig(mct.core.QuantizationConfig(shift_negative_activation_correction=False, + custom_tpc_opset_to_layer={ + "Input": CustomOpsetLayers([DummyPlaceHolder])})) ru = mct.core.ResourceUtilization(57, 47) # inf memory qat_ready_model, quantization_info = mct.qat.pytorch_quantization_aware_training_init_experimental(model_float, self.representative_data_gen_experimental, @@ -314,7 +318,9 @@ def get_tpc(self): def run_test(self): self._gen_fixed_input() model_float = self.create_networks() - config = mct.core.CoreConfig(mct.core.QuantizationConfig(shift_negative_activation_correction=False)) + config = mct.core.CoreConfig(mct.core.QuantizationConfig(shift_negative_activation_correction=False, + custom_tpc_opset_to_layer={ + "Input": CustomOpsetLayers([DummyPlaceHolder])})) ru = mct.core.ResourceUtilization(weights_memory=50, activation_memory=40) qat_ready_model, quantization_info = mct.qat.pytorch_quantization_aware_training_init_experimental(model_float, self.representative_data_gen_experimental, diff --git a/tests/pytorch_tests/model_tests/feature_models/second_moment_correction_test.py b/tests/pytorch_tests/model_tests/feature_models/second_moment_correction_test.py index d39f9ec8e..f3c01b8d7 100644 --- a/tests/pytorch_tests/model_tests/feature_models/second_moment_correction_test.py +++ b/tests/pytorch_tests/model_tests/feature_models/second_moment_correction_test.py @@ -34,6 +34,8 @@ pytorch_apply_second_moment_correction from model_compression_toolkit.core.pytorch.utils import to_torch_tensor, set_model from model_compression_toolkit.core.runner import core_runner +from model_compression_toolkit.target_platform_capabilities.target_platform.targetplatform2framework.attach2pytorch import \ + AttachTpcToPytorch from tests.common_tests.helpers.generate_test_tp_model import generate_test_tp_model from tests.pytorch_tests.model_tests.base_pytorch_test import BasePytorchTest from tests.pytorch_tests.tpc_pytorch import get_pytorch_test_tpc_dict @@ -312,6 +314,10 @@ def representative_data_gen(): for model_name, core_config in core_config_dict.items(): tpc = tpc_dict[model_name] + + attach2pytorch = AttachTpcToPytorch() + tpc = attach2pytorch.attach(tpc) + tg, graph_after_second_moment_correction = self.prepare_graph(model_float, representative_data_gen, core_config=core_config, diff --git a/tests/pytorch_tests/model_tests/test_feature_models_runner.py b/tests/pytorch_tests/model_tests/test_feature_models_runner.py index 9ffa87edd..53e7cfd97 100644 --- a/tests/pytorch_tests/model_tests/test_feature_models_runner.py +++ b/tests/pytorch_tests/model_tests/test_feature_models_runner.py @@ -592,10 +592,10 @@ def test_mixed_precision_activation_4bit_functional(self): MixedPrecisionActivationSearch4BitFunctional(self).run_test() def test_mixed_precision_multiple_inputs(self): - """ - This test checks the activation Mixed Precision search with multiple inputs to model. - """ - MixedPrecisionActivationMultipleInputs(self).run_test() + """ + This test checks the activation Mixed Precision search with multiple inputs to model. + """ + MixedPrecisionActivationMultipleInputs(self).run_test() def test_mixed_precision_bops_utilization(self): """ @@ -613,11 +613,11 @@ def test_mixed_precision_bops_utilization(self): MixedPrecisionBopsMultipleOutEdgesTest(self).run_test() def test_mixed_precision_distance_functions(self): - """ - This test checks the Mixed Precision search with layers that use different distance functions during - the computation. - """ - MixedPrecisionDistanceFunctions(self).run_test() + """ + This test checks the Mixed Precision search with layers that use different distance functions during + the computation. + """ + MixedPrecisionDistanceFunctions(self).run_test() def test_mha_layer_test(self): """ @@ -764,13 +764,6 @@ def test_metadata(self): def test_torch_tpcs(self): TpcTest(f'{C.IMX500_TP_MODEL}.v1', self).run_test() - TpcTest(f'{C.IMX500_TP_MODEL}.v1_lut', self).run_test() - TpcTest(f'{C.IMX500_TP_MODEL}.v1_pot', self).run_test() - TpcTest(f'{C.IMX500_TP_MODEL}.v2', self).run_test() - TpcTest(f'{C.IMX500_TP_MODEL}.v2_lut', self).run_test() - TpcTest(f'{C.IMX500_TP_MODEL}.v3', self).run_test() - TpcTest(f'{C.IMX500_TP_MODEL}.v3_lut', self).run_test() - TpcTest(f'{C.IMX500_TP_MODEL}.v4', self).run_test() TpcTest(f'{C.TFLITE_TP_MODEL}.v1', self).run_test() TpcTest(f'{C.QNNPACK_TP_MODEL}.v1', self).run_test() diff --git a/tests/pytorch_tests/tpc_pytorch.py b/tests/pytorch_tests/tpc_pytorch.py index b7c3bc5d6..055a1cffe 100644 --- a/tests/pytorch_tests/tpc_pytorch.py +++ b/tests/pytorch_tests/tpc_pytorch.py @@ -14,21 +14,14 @@ # ============================================================================== import model_compression_toolkit as mct -from model_compression_toolkit.defaultdict import DefaultDict -from model_compression_toolkit.core.pytorch.constants import BIAS -from model_compression_toolkit.target_platform_capabilities.constants import KERNEL_ATTR, BIAS_ATTR, PYTORCH_KERNEL - -from model_compression_toolkit.target_platform_capabilities.tpc_models.imx500_tpc.latest import generate_pytorch_tpc -from model_compression_toolkit.core.pytorch.reader.node_holders import DummyPlaceHolder -from tests.common_tests.helpers.generate_test_tp_model import generate_test_tpc, generate_test_tp_model +from tests.common_tests.helpers.generate_test_tp_model import generate_test_tp_model tp = mct.target_platform def get_pytorch_test_tpc_dict(tp_model, test_name, ftp_name): return { - test_name: generate_pytorch_tpc(name=ftp_name, - tp_model=tp_model), + test_name: tp_model } def get_activation_quantization_disabled_pytorch_tpc(name): @@ -40,25 +33,6 @@ def get_weights_quantization_disabled_pytorch_tpc(name): return get_pytorch_test_tpc_dict(tp, name, name) -def get_mp_activation_pytorch_tpc_dict(tpc_model, test_name, tpc_name, custom_opsets_to_layer={}): - op_sets_to_layer_add = { - "Input": [DummyPlaceHolder], - } - - op_sets_to_layer_add.update(custom_opsets_to_layer) - - # we assume a standard tp model with standard operator sets names, - # otherwise - need to generate the tpc per test and not with this generic function - attr_mapping = {'Conv': {KERNEL_ATTR: DefaultDict(default_value=PYTORCH_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}, - 'FullyConnected': {KERNEL_ATTR: DefaultDict(default_value=PYTORCH_KERNEL), - BIAS_ATTR: DefaultDict(default_value=BIAS)}} - - return { - test_name: generate_test_tpc(name=tpc_name, - tp_model=tpc_model, - base_tpc=generate_pytorch_tpc(name=f"base_{tpc_name}", - tp_model=tpc_model), - op_sets_to_layer_add=op_sets_to_layer_add, - attr_mapping=attr_mapping), - } +def get_mp_activation_pytorch_tpc_dict(tpc_model, test_name, tpc_name): + # This is a legacy helper function that is kept for maintaining tests usability + return {test_name: tpc_model} \ No newline at end of file diff --git a/tests/pytorch_tests/xquant_tests/test_xquant_end2end.py b/tests/pytorch_tests/xquant_tests/test_xquant_end2end.py index 4712df8c8..e9f8f01d8 100644 --- a/tests/pytorch_tests/xquant_tests/test_xquant_end2end.py +++ b/tests/pytorch_tests/xquant_tests/test_xquant_end2end.py @@ -41,6 +41,8 @@ from model_compression_toolkit.xquant.common.constants import OUTPUT_SIMILARITY_METRICS_REPR, \ OUTPUT_SIMILARITY_METRICS_VAL, INTERMEDIATE_SIMILARITY_METRICS_REPR, INTERMEDIATE_SIMILARITY_METRICS_VAL, \ XQUANT_REPR, XQUANT_VAL, CUT_MEMORY_ELEMENTS, CUT_TOTAL_SIZE +from tests.common_tests.helpers.tpcs_for_tests.v2.tp_model import get_tp_model + def random_data_gen(shape=(3, 8, 8), use_labels=False, num_inputs=1, batch_size=2, num_iter=2): if use_labels: @@ -71,7 +73,7 @@ def get_core_config(self): return mct.core.CoreConfig(debug_config=mct.core.DebugConfig(simulate_scheduler=True)) def get_tpc(self): - return mct.get_target_platform_capabilities(PYTORCH, IMX500_TP_MODEL, "v2") + return get_tp_model() def get_model_to_test(self): class BaseModelTest(torch.nn.Module):