def _binarize_weights_and_module_inputs(self, target_model: NNCFNetwork) -> List[InsertionCommand]: device = next(target_model.parameters()).device modules = target_model.get_nncf_modules() insertion_commands = [] for scope, module in modules.items(): scope_str = str(scope) if not self._should_consider_scope(scope_str): nncf_logger.info("Ignored adding binarizers in scope: {}".format(scope_str)) continue if isinstance(module, torch.nn.modules.Conv2d): nncf_logger.info("Adding Weight binarizer in scope: {}".format(scope_str)) op_weights = UpdateWeight( self.__create_binarize_module() ).to(device) nncf_logger.info("Adding Activation binarizer in scope: {}".format(scope_str)) op_inputs = UpdateInputs(ActivationBinarizationScaleThreshold(module.weight.shape)).to(device) insertion_commands.append(InsertionCommand( InsertionPoint( InputAgnosticOperationExecutionContext("", scope, 0), InsertionType.NNCF_MODULE_PRE_OP), op_weights, OperationPriority.QUANTIZATION_PRIORITY)) insertion_commands.append(InsertionCommand( InsertionPoint( InputAgnosticOperationExecutionContext("", scope, 0), InsertionType.NNCF_MODULE_PRE_OP), op_inputs, OperationPriority.QUANTIZATION_PRIORITY)) return insertion_commands
def _sparsify_weights(self, target_model: NNCFNetwork) -> List[InsertionCommand]: device = next(target_model.parameters()).device sparsified_modules = target_model.get_nncf_modules_by_module_names( self.compressed_nncf_module_names) insertion_commands = [] for module_scope, module in sparsified_modules.items(): scope_str = str(module_scope) if not self._should_consider_scope(scope_str): nncf_logger.info( "Ignored adding Weight Sparsifier in scope: {}".format( scope_str)) continue nncf_logger.info( "Adding Weight Sparsifier in scope: {}".format(scope_str)) operation = self.create_weight_sparsifying_operation(module) hook = UpdateWeight(operation).to(device) insertion_commands.append( InsertionCommand( InsertionPoint(InsertionType.NNCF_MODULE_PRE_OP, module_scope=module_scope), hook, OperationPriority.SPARSIFICATION_PRIORITY)) self._sparsified_module_info.append( SparseModuleInfo(scope_str, module, hook.operand)) return insertion_commands
def __init__(self, layer, frozen, size=1): super().__init__() self.size = size self.layer = layer if frozen is None: sparsifier = RBSparsifyingWeight(size=size) else: sparsifier = RBSparsifyingWeight(frozen=frozen, size=size) self.op_key = self.layer.register_pre_forward_operation(UpdateWeight(sparsifier))
def _apply_to(self, target_model: NNCFNetwork) -> List[InsertionCommand]: # Will it really suffice to use a single collector for all threads? After all, each of the threads # receives its own data, and should we use a thread-local collector, there would have to be a # separate thread reduction step involved. Still, is there a better option here than to rely on GIL? retval = [] # type: List[InsertionCommand] for op, collector in self._observation_points_vs_collectors.items(): hook_obj = collector.register_input is_weights = op.insertion_point.insertion_type in [ InsertionType.NNCF_MODULE_PRE_OP, InsertionType.NNCF_MODULE_POST_OP ] if is_weights: hook_obj = UpdateWeight(hook_obj) command = InsertionCommand( op.insertion_point, hook_obj, OperationPriority.FP32_TENSOR_STATISTICS_OBSERVATION) retval.append(command) return retval
def _prune_weights(self, target_model: NNCFNetwork): grops_of_modules_to_prune = self._create_pruning_groups(target_model) device = next(target_model.parameters()).device insertion_commands = [] self.pruned_module_groups_info = Clusterization('module_scope') for i, group in enumerate(grops_of_modules_to_prune.get_all_clusters()): group_minfos = [] for node in group.nodes: module_scope, module = node.module_scope, node.module # Check that we need to prune weights in this op assert self._is_pruned_module(module) module_scope_str = str(module_scope) nncf_logger.info("Adding Weight Pruner in scope: {}".format(module_scope_str)) operation = self.create_weight_pruning_operation(module) hook = UpdateWeight(operation).to(device) insertion_commands.append( InsertionCommand( InsertionPoint(InsertionType.NNCF_MODULE_PRE_OP, module_scope=module_scope), hook, OperationPriority.PRUNING_PRIORITY ) ) related_modules = {} if self.prune_batch_norms: bn_module, bn_scope = get_bn_for_module_scope(target_model, module_scope) related_modules[PrunedModuleInfo.BN_MODULE_NAME] = BatchNormInfo(module_scope, bn_module, bn_scope) minfo = PrunedModuleInfo(module_scope, module, hook.operand, related_modules, node.id) group_minfos.append(minfo) cluster = NodesCluster(i, group_minfos, [n.id for n in group.nodes]) self.pruned_module_groups_info.add_cluster(cluster) return insertion_commands
def _prune_weights(self, target_model: NNCFNetwork): device = next(target_model.parameters()).device modules_to_prune = target_model.get_nncf_modules() insertion_commands = [] bn_for_depthwise = {} input_non_pruned_modules = get_first_pruned_modules( target_model, self.get_types_of_pruned_modules() + ['linear']) output_non_pruned_modules = get_last_pruned_modules( target_model, self.get_types_of_pruned_modules() + ['linear']) for module_scope, module in modules_to_prune.items(): # Check that we need to prune weights in this op if not self._is_pruned_module(module): continue module_scope_str = str(module_scope) if self.ignore_frozen_layers and not module.weight.requires_grad: nncf_logger.info( "Ignored adding Weight Pruner in scope: {} because" " the layer appears to be frozen (requires_grad=False)". format(module_scope_str)) continue if not self._should_consider_scope(module_scope_str): nncf_logger.info( "Ignored adding Weight Pruner in scope: {}".format( module_scope_str)) continue if not self.prune_first and module in input_non_pruned_modules: nncf_logger.info( "Ignored adding Weight Pruner in scope: {} because" " this scope is one of the first convolutions".format( module_scope_str)) continue if not self.prune_last and module in output_non_pruned_modules: nncf_logger.info( "Ignored adding Weight Pruner in scope: {} because" " this scope is one of the last convolutions".format( module_scope_str)) continue if is_grouped_conv(module): if is_depthwise_conv(module): previous_conv = get_previous_conv(target_model, module, module_scope) if previous_conv: depthwise_bn = get_bn_for_module_scope( target_model, module_scope) bn_for_depthwise[str(previous_conv.op_exec_context. scope_in_model)] = depthwise_bn nncf_logger.info( "Ignored adding Weight Pruner in scope: {} because" " this scope is grouped convolution".format( module_scope_str)) continue if not self.prune_downsample_convs and is_conv_with_downsampling( module): nncf_logger.info( "Ignored adding Weight Pruner in scope: {} because" " this scope is convolution with downsample".format( module_scope_str)) continue nncf_logger.info( "Adding Weight Pruner in scope: {}".format(module_scope_str)) operation = self.create_weight_pruning_operation(module) hook = UpdateWeight(operation).to(device) insertion_commands.append( InsertionCommand( InsertionPoint( InputAgnosticOperationExecutionContext( "", module_scope, 0), InsertionType.NNCF_MODULE_PRE_OP), hook, OperationPriority.PRUNING_PRIORITY)) related_modules = {} if self.prune_batch_norms: related_modules[ PrunedModuleInfo.BN_MODULE_NAME] = get_bn_for_module_scope( target_model, module_scope) self._pruned_module_info.append( PrunedModuleInfo(module_scope_str, module, hook.operand, related_modules)) if self.prune_batch_norms: self.update_minfo_with_depthwise_bn(bn_for_depthwise) return insertion_commands
def __init__(self, layer): super().__init__() self.layer = layer sparsifier = BinaryMask(layer.weight.size()) self.op_key = self.layer.register_pre_forward_operation( UpdateWeight(sparsifier))
def _prune_weights(self, target_model: NNCFNetwork): device = next(target_model.parameters()).device modules_to_prune = target_model.get_nncf_modules() insertion_commands = [] input_non_pruned_modules = get_first_pruned_modules( target_model, self.get_types_of_pruned_modules() + ['linear']) output_non_pruned_modules = get_last_pruned_modules( target_model, self.get_types_of_pruned_modules() + ['linear']) for module_scope, module in modules_to_prune.items(): # Check that we need to prune weights in this op if not self._is_pruned_module(module): continue module_scope_str = str(module_scope) if not self._should_consider_scope(module_scope_str): nncf_logger.info( "Ignored adding Weight Pruner in scope: {}".format( module_scope_str)) continue if not self.prune_first and module in input_non_pruned_modules: nncf_logger.info( "Ignored adding Weight Pruner in scope: {} because" " this scope is one of the first convolutions".format( module_scope_str)) continue if not self.prune_last and module in output_non_pruned_modules: nncf_logger.info( "Ignored adding Weight Pruner in scope: {} because" " this scope is one of the last convolutions".format( module_scope_str)) continue if not self.prune_downsample_convs and is_conv_with_downsampling( module): nncf_logger.info( "Ignored adding Weight Pruner in scope: {} because" " this scope is convolution with downsample".format( module_scope_str)) continue nncf_logger.info( "Adding Weight Pruner in scope: {}".format(module_scope_str)) operation = self.create_weight_pruning_operation(module) hook = UpdateWeight(operation).to(device) insertion_commands.append( InsertionCommand( InsertionPoint( InputAgnosticOperationExecutionContext( "", module_scope, 0), InsertionType.NNCF_MODULE_PRE_OP), hook, OperationPriority.PRUNING_PRIORITY)) related_modules = {} if self.prune_batch_norms: related_modules['bn_module'] = get_bn_for_module_scope( target_model, module_scope) self._pruned_module_info.append( PrunedModuleInfo(module_scope_str, module, hook.operand, related_modules)) return insertion_commands
def __init__(self, layer): super().__init__() self.layer = layer pruning_op = FilterPruningBlock(layer.weight.size(0)) self.op_key = self.layer.register_pre_forward_operation( UpdateWeight(pruning_op))