Example #1
0
    def _is_module_prunable(self, graph: NNCFGraph,
                            node: NNCFNode) -> PruningAnalysisDecision:
        """
        Check whether we should prune module corresponding to provided node
        according to algorithm parameters.

        :param graph: Graph to work with.
        :param node: Node to check.
        :return: Pruning analysis decision.
        """
        stop_propagation_ops = self._stop_propagation_op_metatype.get_all_op_aliases(
        )
        types_to_track = self._prune_operations_types + stop_propagation_ops
        input_non_pruned_nodes = get_first_nodes_of_type(graph, types_to_track)
        node_name = node.node_name

        if not should_consider_scope(node_name, self._ignored_scopes,
                                     self._target_scopes):
            return PruningAnalysisDecision(False,
                                           PruningAnalysisReason.IGNORED_SCOPE)

        if not self._prune_first and node in input_non_pruned_nodes:
            return PruningAnalysisDecision(False,
                                           PruningAnalysisReason.FIRST_CONV)

        if is_grouped_conv(node) and not is_prunable_depthwise_conv(node):
            return PruningAnalysisDecision(False,
                                           PruningAnalysisReason.GROUP_CONV)

        if not self._prune_downsample_convs and is_conv_with_downsampling(
                node):
            return PruningAnalysisDecision(
                False, PruningAnalysisReason.DOWNSAMPLE_CONV)

        return PruningAnalysisDecision(True)
Example #2
0
    def _get_quantizable_weighted_layer_nodes(
            self, nncf_graph: NNCFGraph) -> List[QuantizableWeightedLayerNode]:
        nodes_with_weights = []
        for node in nncf_graph.get_all_nodes():
            metatype = node.metatype
            if metatype in OUTPUT_NOOP_METATYPES:
                continue

            if not (metatype in QUANTIZATION_LAYER_METATYPES
                    and should_consider_scope(
                        node.node_name,
                        ignored_scopes=self.ignored_scopes_per_group[
                            QuantizerGroup.WEIGHTS],
                        target_scopes=None)):
                continue

            assert issubclass(metatype, TFLayerWithWeightsMetatype)
            nodes_with_weights.append(node)
        scope_overrides_dict = self._get_algo_specific_config_section().get(
            'scope_overrides', {})
        weighted_node_and_qconf_lists = assign_qconfig_lists_to_modules(
            nodes_with_weights,
            self.DEFAULT_QCONFIG,
            self.global_quantizer_constraints[QuantizerGroup.WEIGHTS],
            scope_overrides_dict,
            hw_config=self.hw_config)
        return [
            QuantizableWeightedLayerNode(node, qconf_list)
            for node, qconf_list in weighted_node_and_qconf_lists.items()
        ]
Example #3
0
    def get_transformation_layout(self, model: tf.keras.Model) -> TFTransformationLayout:
        converter = TFModelConverterFactory.create(model)
        nncf_graph = converter.convert()
        transformations = TFTransformationLayout()

        processed_shared_layer_names = set()  # type: Set[str]

        for node in nncf_graph.get_all_nodes():
            if node.is_shared():
                target_layer_name, _ = get_original_name_and_instance_idx(node.node_name)
                if target_layer_name in processed_shared_layer_names:
                    continue
                processed_shared_layer_names.add(target_layer_name)

            if not (node.metatype in SPARSITY_LAYER_METATYPES and
                    should_consider_scope(node.node_name, ignored_scopes=self.ignored_scopes)):
                continue

            _, layer_info = converter.get_layer_info_for_node(node.node_name)
            for weight_def in node.metatype.weight_definitions:
                op_name = self._get_rb_sparsity_operation_name(node.node_name,
                                                               weight_def.weight_attr_name)
                self._op_names.append(op_name)

                transformations.register(
                    TFInsertionCommand(
                        target_point=TFLayerWeight(layer_info.layer_name, weight_def.weight_attr_name),
                        callable_object=RBSparsifyingWeight(op_name),
                        priority=TransformationPriority.SPARSIFICATION_PRIORITY
                    ))

        return transformations
Example #4
0
    def get_transformation_layout(
            self, model: tf.keras.Model) -> TFTransformationLayout:
        converter = TFModelConverterFactory.create(model)
        nncf_graph = converter.convert()
        transformations = TFTransformationLayout()

        processed_shared_layer_names = set()  # type: Set[str]

        for node in nncf_graph.get_all_nodes():
            if node.is_shared():
                target_layer_name, _ = get_original_name_and_instance_idx(
                    node.node_name)
                if target_layer_name in processed_shared_layer_names:
                    continue
                processed_shared_layer_names.add(target_layer_name)

            if not should_consider_scope(node.node_name,
                                         ignored_scopes=self.ignored_scopes):
                continue

            if node.metatype in OUTPUT_NOOP_METATYPES:
                continue

            is_custom, layer_info = converter.get_layer_info_for_node(
                node.node_name)
            if node.metatype in SPARSITY_LAYER_METATYPES:
                # Processing a regular weighted node
                for weight_def in node.metatype.weight_definitions:
                    op_name = self._get_sparsity_operation_name(
                        node.node_name, weight_def.weight_attr_name)
                    self._op_names.append(op_name)

                    transformations.register(
                        TFInsertionCommand(target_point=TFLayerWeight(
                            layer_info.layer_name,
                            weight_def.weight_attr_name),
                                           callable_object=BinaryMask(op_name),
                                           priority=TransformationPriority.
                                           SPARSIFICATION_PRIORITY))
            elif node.metatype in WEIGHTABLE_TF_OP_METATYPES:
                assert is_custom
                # Processing a custom layer weighted node
                # Caution: here layer_name will refer to the weight itself, not to the op
                weight_attr_name = node.layer_name
                op_name = self._get_sparsity_operation_name(
                    node.node_name, weight_attr_name)
                self._op_names.append(op_name)

                transformations.register(
                    TFInsertionCommand(
                        target_point=TFLayerWeight(layer_info.layer_name,
                                                   weight_attr_name),
                        callable_object=BinaryMaskWithWeightsBackup(
                            op_name, weight_attr_name),
                        priority=TransformationPriority.SPARSIFICATION_PRIORITY
                    ))

        return transformations
Example #5
0
    def get_init_config_for_scope_and_group(
            self, qid: QuantizerId, group: QuantizerGroup) -> RangeInitConfig:
        matches = []  # type: List[RangeInitConfig]
        for pl_config in self.per_layer_range_init_configs:
            if should_consider_scope(qid, pl_config.ignored_scopes,
                                     pl_config.target_scopes):
                if group == pl_config.target_group or pl_config.target_group is None:
                    matches.append(
                        RangeInitConfig(pl_config.init_type,
                                        pl_config.num_init_samples,
                                        pl_config.init_type_specific_params))
        if len(matches) > 1:
            raise ValueError(
                "Location {} matches more than one per-layer initialization parameter "
                "definition!".format(str(qid)))
        if len(matches) == 1:
            return matches[0]
        if not matches and self.global_init_config is not None:
            return deepcopy(self.global_init_config)

        raise ValueError(
            "Location {} does not match any per-layer initialization parameter "
            "definition!".format(str(qid)))
 def _should_consider_scope(self, node_name: NNCFNodeName) -> bool:
     return should_consider_scope(node_name, self.ignored_scopes,
                                  self.target_scopes)