nncf/torch/pruning/filter_pruning/algo.py
def _set_binary_masks_for_pruned_modules_globally_by_flops_target(self,
                                                                      target_flops_pruning_level: float) -> None:
        """
        Sorting all prunable filters in the network by importance and pruning the amount of the
        least important filters sufficient to achieve the target pruning level by flops.
        Filters are pruned one-by-one and the corresponding flops value is checked.

        :param target_flops_pruning_level: target proportion of flops removed from the model
        :return:
        """
        target_flops = self.full_flops * (1 - target_flops_pruning_level)

        # 1. Initialize masks
        for minfo in self.pruned_module_groups_info.get_all_nodes():
            new_mask = torch.ones(get_filters_num(minfo.module)).to(
                minfo.module.weight.device)
            self.set_mask(minfo, new_mask)

        # 2. Calculate filter importances for all prunable groups
        filter_importances = []
        cluster_indexes = []
        filter_indexes = []

        for cluster in self.pruned_module_groups_info.get_all_clusters():
            filters_num = torch.tensor([get_filters_num(minfo.module) for minfo in cluster.elements])
            assert torch.all(filters_num == filters_num[0])
            device = cluster.elements[0].module.weight.device

            cumulative_filters_importance = torch.zeros(filters_num[0]).to(device)
            # Calculate cumulative importance for all filters in this group
            for minfo in cluster.elements:
                weight = minfo.module.weight
                if self.normalize_weights:
                    weight = self.weights_normalizer(weight)
                filters_importance = self.filter_importance(weight,
                                                            minfo.module.target_weight_dim_for_compression)
                scaled_importance = self.ranking_coeffs[minfo.node_name][0] * filters_importance + \
                                    self.ranking_coeffs[minfo.node_name][1]
                cumulative_filters_importance += scaled_importance

            filter_importances.append(cumulative_filters_importance)
            cluster_indexes.append(cluster.id * torch.ones_like(cumulative_filters_importance))
            filter_indexes.append(torch.arange(len(cumulative_filters_importance)))

        importances = torch.cat(filter_importances)
        cluster_indexes = torch.cat(cluster_indexes)
        filter_indexes = torch.cat(filter_indexes)

        # 3. Sort all filter groups by importances and prune the least important filters
        # until target flops pruning level is achieved
        sorted_importances = sorted(zip(importances, cluster_indexes, filter_indexes), key=lambda x: x[0])
        cur_num = 0
        tmp_in_channels = self._modules_in_channels.copy()
        tmp_out_channels = self._modules_out_channels.copy()
        tmp_pruning_quotas = self.pruning_quotas.copy()

        while cur_num < len(sorted_importances):
            cluster_idx = int(sorted_importances[cur_num][1])
            filter_idx = int(sorted_importances[cur_num][2])

            if tmp_pruning_quotas[cluster_idx] > 0:
                tmp_pruning_quotas[cluster_idx] -= 1
            else:
                cur_num += 1
                continue

            cluster = self.pruned_module_groups_info.get_cluster_by_id(cluster_idx)
            for node in cluster.elements:
                tmp_out_channels[node.node_name] -= 1
                if node.is_depthwise:
                    tmp_in_channels[node.node_name] -= 1

                node.operand.binary_filter_pruning_mask[filter_idx] = 0

            # Prune in channels in all next nodes
            next_nodes = self.next_nodes[cluster.id]
            for node_id in next_nodes:
                tmp_in_channels[node_id] -= 1

            flops, params_num = count_flops_and_weights(self._model.get_original_graph(),
                                                        self._modules_in_shapes,
                                                        self._modules_out_shapes,
                                                        input_channels=tmp_in_channels,
                                                        output_channels=tmp_out_channels,
                                                        conv_op_metatypes=GENERAL_CONV_LAYER_METATYPES,
                                                        linear_op_metatypes=LINEAR_LAYER_METATYPES)
            if flops < target_flops:
                self.current_flops = flops
                self.current_params_num = params_num
                return
            cur_num += 1
        raise RuntimeError("Can't prune model to asked flops pruning level")

        Sorting all prunable filters in the network by importance and pruning the amount of the
        least important filters sufficient to achieve the target pruning level by flops.
        Filters are pruned one-by-one and the corresponding flops value is checked.

        :param target_flops_pruning_level: target proportion of flops removed from the model
        :return:
        
Sorting all prunable filters in the network by importance and pruning the amount of the
least important filters sufficient to achieve the target pruning level by flops.
Filters are pruned one-by-one and the corresponding flops value is checked.
Sorting all prunable filters in the network by importance and pruning the amount of the least important filters sufficient to achieve the target pruning level by flops . Filters are pruned one - by - one and the corresponding flops value is checked .
def _set_binary_masks_for_pruned_modules_globally_by_flops_target(self,
                                                                      target_flops_pruning_level: float) -> None:
        target_flops = self.full_flops * (1 - target_flops_pruning_level)
        for minfo in self.pruned_module_groups_info.get_all_nodes():
            new_mask = torch.ones(get_filters_num(minfo.module)).to(
                minfo.module.weight.device)
            self.set_mask(minfo, new_mask)
        filter_importances = []
        cluster_indexes = []
        filter_indexes = []
        for cluster in self.pruned_module_groups_info.get_all_clusters():
            filters_num = torch.tensor([get_filters_num(minfo.module) for minfo in cluster.elements])
            assert torch.all(filters_num == filters_num[0])
            device = cluster.elements[0].module.weight.device
            cumulative_filters_importance = torch.zeros(filters_num[0]).to(device)
            for minfo in cluster.elements:
                weight = minfo.module.weight
                if self.normalize_weights:
                    weight = self.weights_normalizer(weight)
                filters_importance = self.filter_importance(weight,
                                                            minfo.module.target_weight_dim_for_compression)
                scaled_importance = self.ranking_coeffs[minfo.node_name][0] * filters_importance + \
                                    self.ranking_coeffs[minfo.node_name][1]
                cumulative_filters_importance += scaled_importance
            filter_importances.append(cumulative_filters_importance)
            cluster_indexes.append(cluster.id * torch.ones_like(cumulative_filters_importance))
            filter_indexes.append(torch.arange(len(cumulative_filters_importance)))
        importances = torch.cat(filter_importances)
        cluster_indexes = torch.cat(cluster_indexes)
        filter_indexes = torch.cat(filter_indexes)
        sorted_importances = sorted(zip(importances, cluster_indexes, filter_indexes), key=lambda x: x[0])
        cur_num = 0
        tmp_in_channels = self._modules_in_channels.copy()
        tmp_out_channels = self._modules_out_channels.copy()
        tmp_pruning_quotas = self.pruning_quotas.copy()
        while cur_num < len(sorted_importances):
            cluster_idx = int(sorted_importances[cur_num][1])
            filter_idx = int(sorted_importances[cur_num][2])
            if tmp_pruning_quotas[cluster_idx] > 0:
                tmp_pruning_quotas[cluster_idx] -= 1
            else:
                cur_num += 1
                continue
            cluster = self.pruned_module_groups_info.get_cluster_by_id(cluster_idx)
            for node in cluster.elements:
                tmp_out_channels[node.node_name] -= 1
                if node.is_depthwise:
                    tmp_in_channels[node.node_name] -= 1
                node.operand.binary_filter_pruning_mask[filter_idx] = 0
            next_nodes = self.next_nodes[cluster.id]
            for node_id in next_nodes:
                tmp_in_channels[node_id] -= 1
            flops, params_num = count_flops_and_weights(self._model.get_original_graph(),
                                                        self._modules_in_shapes,
                                                        self._modules_out_shapes,
                                                        input_channels=tmp_in_channels,
                                                        output_channels=tmp_out_channels,
                                                        conv_op_metatypes=GENERAL_CONV_LAYER_METATYPES,
                                                        linear_op_metatypes=LINEAR_LAYER_METATYPES)
            if flops < target_flops:
                self.current_flops = flops
                self.current_params_num = params_num
                return
            cur_num += 1
        raise RuntimeError("Can't prune model to asked flops pruning level")
def _set_binary_masks_for_pruned_modules_globally_by_flops_target ( self , target_flops_pruning_level : float ) -> None : target_flops = self . full_flops * ( 1 - target_flops_pruning_level ) for minfo in self . pruned_module_groups_info . get_all_nodes ( ) : new_mask = torch . ones ( get_filters_num ( minfo . module ) ) . to ( minfo . module . weight . device ) self . set_mask ( minfo , new_mask ) filter_importances = [ ] cluster_indexes = [ ] filter_indexes = [ ] for cluster in self . pruned_module_groups_info . get_all_clusters ( ) : filters_num = torch . tensor ( [ get_filters_num ( minfo . module ) for minfo in cluster . elements ] ) assert torch . all ( filters_num == filters_num [ 0 ] ) device = cluster . elements [ 0 ] . module . weight . device cumulative_filters_importance = torch . zeros ( filters_num [ 0 ] ) . to ( device ) for minfo in cluster . elements : weight = minfo . module . weight if self . normalize_weights : weight = self . weights_normalizer ( weight ) filters_importance = self . filter_importance ( weight , minfo . module . target_weight_dim_for_compression ) scaled_importance = self . ranking_coeffs [ minfo . node_name ] [ 0 ] * filters_importance + self . ranking_coeffs [ minfo . node_name ] [ 1 ] cumulative_filters_importance += scaled_importance filter_importances . append ( cumulative_filters_importance ) cluster_indexes . append ( cluster . id * torch . ones_like ( cumulative_filters_importance ) ) filter_indexes . append ( torch . arange ( len ( cumulative_filters_importance ) ) ) importances = torch . cat ( filter_importances ) cluster_indexes = torch . cat ( cluster_indexes ) filter_indexes = torch . cat ( filter_indexes ) sorted_importances = sorted ( zip ( importances , cluster_indexes , filter_indexes ) , key = lambda x : x [ 0 ] ) cur_num = 0 tmp_in_channels = self . _modules_in_channels . copy ( ) tmp_out_channels = self . _modules_out_channels . copy ( ) tmp_pruning_quotas = self . pruning_quotas . copy ( ) while cur_num < len ( sorted_importances ) : cluster_idx = int ( sorted_importances [ cur_num ] [ 1 ] ) filter_idx = int ( sorted_importances [ cur_num ] [ 2 ] ) if tmp_pruning_quotas [ cluster_idx ] > 0 : tmp_pruning_quotas [ cluster_idx ] -= 1 else : cur_num += 1 continue cluster = self . pruned_module_groups_info . get_cluster_by_id ( cluster_idx ) for node in cluster . elements : tmp_out_channels [ node . node_name ] -= 1 if node . is_depthwise : tmp_in_channels [ node . node_name ] -= 1 node . operand . binary_filter_pruning_mask [ filter_idx ] = 0 next_nodes = self . next_nodes [ cluster . id ] for node_id in next_nodes : tmp_in_channels [ node_id ] -= 1 flops , params_num = count_flops_and_weights ( self . _model . get_original_graph ( ) , self . _modules_in_shapes , self . _modules_out_shapes , input_channels = tmp_in_channels , output_channels = tmp_out_channels , conv_op_metatypes = GENERAL_CONV_LAYER_METATYPES , linear_op_metatypes = LINEAR_LAYER_METATYPES ) if flops < target_flops : self . current_flops = flops self . current_params_num = params_num return cur_num += 1 raise RuntimeError ( "Can't prune model to asked flops pruning level" )
Sorting all prunable filters in the network by importance and pruning the amount of the
least important filters sufficient to achieve the target pruning level by flops.
Sorting all prunable filters in the network by importance and pruning the amount of the least important filters sufficient to achieve the target pruning level by flops .
"""
        Sorting all prunable filters in the network by importance and pruning the amount of the
        least important filters sufficient to achieve the target pruning level by flops.
        Filters are pruned one-by-one and the corresponding flops value is checked.

        :param target_flops_pruning_level: target proportion of flops removed from the model
        :return:
        """ # 1. Initialize masks # 2. Calculate filter importances for all prunable groups # Calculate cumulative importance for all filters in this group # 3. Sort all filter groups by importances and prune the least important filters # until target flops pruning level is achieved # Prune in channels in all next nodes
None
self
target_flops_pruning_level
float
target proportion of flops removed from the model
target proportion of flops removed from the model