def test_hawq_behaviour__if_method_returns_none(mocker, method_name, expected_behavior): config = HAWQConfigBuilder().with_sample_size([1, 1, 4, 4]).build() config['compression']['initializer']['range']['num_init_samples'] = 0 config['quantizer_setup_type'] = 'pattern_based' model = BasicConvTestModel() mock_train_loader = mocker.stub() mock_train_loader.batch_size = 1 config.register_extra_structs([ QuantizationPrecisionInitArgs(criterion_fn=mocker.stub(), criterion=mocker.stub(), data_loader=mock_train_loader, device='cuda') ]) mocker.patch( 'nncf.quantization.algo.QuantizationController.run_batchnorm_adaptation' ) mocked_calc_traces = mocker.patch( 'nncf.quantization.precision_init.hawq_init.HAWQPrecisionInitializer._calc_traces' ) stub = mocker.stub() stub.traces_order = TracesOrder([0]) mocked_calc_traces.return_value = stub mocked_method = mocker.patch( 'nncf.quantization.precision_init.hawq_init.HAWQPrecisionInitializer.' + method_name) mocked_method.return_value = None with expected_behavior: create_compressed_model_and_algo_for_test(model, config)
def test_can_restore_binary_mask_on_magnitude_algo_resume(): config = get_empty_config() config['compression'] = { "algorithm": "magnitude_sparsity", "params": { "weight_importance": "abs", "schedule": "multistep", "multistep_sparsity_levels": [0.3, 0.5] } } sparse_model, _ = create_compressed_model_and_algo_for_test( MagnitudeTestModel(), config) with torch.no_grad(): sparse_model(torch.ones([1, 1, 10, 10])) config = get_empty_config() config["compression"] = {"algorithm": "const_sparsity"} const_sparse_model, _ = create_compressed_model_and_algo_for_test( MagnitudeTestModel(), config) load_state(const_sparse_model, sparse_model.state_dict()) op = const_sparse_model.conv1.pre_ops['0'] check_equal(ref_mask_1, op.operand.binary_mask) op = const_sparse_model.conv2.pre_ops['0'] check_equal(ref_mask_2, op.operand.binary_mask)
def test_load_state_interoperability(_algos, _model_wrapper, is_resume): config_save = get_empty_config() config_save['compression'] = [{ 'algorithm': algo } for algo in _algos['save_algos']] compressed_model_save, _ = create_compressed_model_and_algo_for_test( BasicConvTestModel(), config_save) model_save = _model_wrapper['save_model'](compressed_model_save) saved_model_state = model_save.state_dict() ref_num_loaded = len(saved_model_state) config_resume = get_empty_config() config_resume['compression'] = [{ 'algorithm': algo } for algo in _algos['load_algos']] compressed_model_resume, _ = create_compressed_model_and_algo_for_test( BasicConvTestModel(), config_resume) model_resume = _model_wrapper['resume_model'](compressed_model_resume) if not is_resume or (is_resume and _algos['is_resume_ok']): act_num_loaded = load_state(model_resume, saved_model_state, is_resume) if ('magnitude_sparsity' in _algos['load_algos'] or 'const_sparsity' in _algos['load_algos']) \ and 'rb_sparsity' in _algos['save_algos']: # no need to load _mask and _uniform ref_num_loaded -= 2 assert act_num_loaded == ref_num_loaded else: with pytest.raises(RuntimeError): load_state(model_resume, saved_model_state, is_resume)
def test_logarithm_scale_parameter(logarithm_scale_setting_1, logarithm_scale_setting_2, quantization_type): for logarithm_scales in [[False, True], [True, False]]: for symmetric in [False, True]: model0, _ = create_compressed_model_and_algo_for_test( TwoConvTestModel(), get_config_for_logarithm_scale( logarithm_scale=logarithm_scale_setting_1, quantization_type=quantization_type)) model1, _ = create_compressed_model_and_algo_for_test( TwoConvTestModel(), get_config_for_logarithm_scale( logarithm_scale=logarithm_scale_setting_2, quantization_type=quantization_type)) sd0 = model0.state_dict() model1.load_state_dict(sd0) sd1 = model1.state_dict() for k, v0 in sd0.items(): v1 = sd1[k] diff = (v1 - v0).abs().sum().item() / v1.numel() assert diff < 1e-6, "symmetric {} logarithm_scales {} param {} is corrupted mean({}-{})={}".format( symmetric, logarithm_scales, k, v0, v1, diff)
def test_range_init_is_called(config_cutter, range_init_call_count, precision_init_call_count, bn_adaptation_call_count, mocker): config = HAWQConfigBuilder().build() config['compression']['initializer'].update( {'batchnorm_adaptation': { 'num_bn_adaptation_steps': 5 }}) config['input_info'] = {"sample_size": [1, 1, 4, 4]} model = BasicConvTestModel() config = register_default_init_args(config, mocker.stub(), mocker.stub()) range_init_spy = mocker.patch( 'nncf.quantization.algo.QuantizationController._do_range_init') precision_init_spy = mocker.patch( 'nncf.quantization.precision_init.hawq_init.HAWQPrecisionInitializer.apply_init' ) bn_adaptation_spy = mocker.patch( 'nncf.initialization.DataLoaderBNAdaptationRunner.run') config_cutter(config['compression']) create_compressed_model_and_algo_for_test(model, config) assert range_init_spy.call_count == range_init_call_count assert precision_init_spy.call_count == precision_init_call_count assert bn_adaptation_spy.call_count == bn_adaptation_call_count
def test_both_targets_assert(): config = get_basic_pruning_config() config['compression']['algorithm'] = 'filter_pruning' config['compression']['params']['pruning_target'] = 0.3 config['compression']['params']['pruning_flops_target'] = 0.5 model = PruningTestModel() with pytest.raises(ValueError): create_compressed_model_and_algo_for_test(model, config)
def test_hawq_hw_vpu_config_e2e(_seed, dataset_dir, tmp_path): config = HAWQConfigBuilder().for_vpu().with_ratio(1.01).build() model = MobileNetV2(num_classes=10) criterion = nn.CrossEntropyLoss() if not dataset_dir: dataset_dir = str(tmp_path) train_loader, _ = create_test_dataloaders(config, dataset_dir) config = register_default_init_args(config, train_loader, criterion) create_compressed_model_and_algo_for_test(model, config)
def test_hawq_raises_error_if_method_returns_none(mocker, method_name): config = create_hawq_test_config() model = MockModel() config = register_default_init_args(config, mocker.stub(), mocker.stub()) mocker.patch('nncf.quantization.algo.QuantizationController._do_range_init') mocker.patch('nncf.quantization.init_precision.HAWQPrecisionInitializer._calc_traces') mocked_trace = mocker.patch('nncf.quantization.init_precision.HAWQPrecisionInitializer.' + method_name) mocked_trace.return_value = None with pytest.raises(RuntimeError): create_compressed_model_and_algo_for_test(model, config)
def test_hawq_behaviour__if_method_returns_none(mocker, method_name, expected_behavior): config = HAWQConfigBuilder().build() config['quantizer_setup_type'] = 'pattern_based' model = MockModel() config = register_default_init_args(config, mocker.stub(), mocker.stub()) mocker.patch('nncf.quantization.algo.QuantizationController._do_range_init') mocker.patch('nncf.quantization.precision_init.hawq_init.HAWQPrecisionInitializer._calc_traces') mocked_trace = mocker.patch('nncf.quantization.precision_init.hawq_init.HAWQPrecisionInitializer.' + method_name) mocked_trace.return_value = None with expected_behavior: create_compressed_model_and_algo_for_test(model, config)
def test_context_independence(model_name, model_builder, input_size, _case_config): config = get_basic_quantization_config(_case_config.quant_type, input_sample_sizes=input_size[0]) compressed_models = [ create_compressed_model_and_algo_for_test(model_builder[0](), config)[0], create_compressed_model_and_algo_for_test(model_builder[1](), config)[0] ] for i, compressed_model in enumerate(compressed_models): check_model_graph(compressed_model, model_name[i], _case_config.graph_dir)
def test_staged_quantization_saves_enabled_quantizers_in_state_dict(tmp_path): config = get_quantization_config_without_range_init() config["compression"]["params"] = { "activations_quant_start_epoch": 2, "weights_quant_start_epoch": 1 } model_save, ctrl_save = create_compressed_model_and_algo_for_test(BasicConvTestModel(), config) ctrl_save.scheduler.epoch_step() _, ctrl_load = create_compressed_model_and_algo_for_test(BasicConvTestModel(), config, resuming_state_dict=model_save.state_dict()) for quantizer_info in ctrl_load.non_weight_quantizers.values(): assert not quantizer_info.quantizer_module_ref.is_enabled_quantization() for quantizer in ctrl_load.weight_quantizers.values(): assert quantizer.is_enabled_quantization()
def test_export_stacked_bi_lstm(tmp_path): p = LSTMTestSizes(3, 3, 3, 3) config = get_empty_config( input_sample_sizes=[1, p.hidden_size, p.input_size]) config['compression'] = {'algorithm': 'quantization'} # TODO: batch_first=True fails with building graph: ambiguous call to mul or sigmoid test_rnn = NNCF_RNN('LSTM', input_size=p.input_size, hidden_size=p.hidden_size, num_layers=2, bidirectional=True, batch_first=False) model, algo = create_compressed_model_and_algo_for_test(test_rnn, config) test_path = str(tmp_path.joinpath('test.onnx')) algo.export_model(test_path) assert os.path.exists(test_path) onnx_num = 0 model = onnx.load(test_path) # pylint: disable=no-member for node in model.graph.node: if node.op_type == 'FakeQuantize': onnx_num += 1 assert onnx_num == 50
def activation_quantizers_dumping_worker(current_gpu, config, tmp_path): model = resnet50(pretrained=False) quant_model, _ = create_compressed_model_and_algo_for_test(model, config) path = get_path_to_keys(tmp_path, current_gpu) print(path) with open(path, 'w') as f: f.writelines("%s\n" % key for key in quant_model.activation_quantizers.keys())
def test_flops(config_creator, ref_values): class ConvLinear(nn.Module): def __init__(self): super().__init__() self.conv1 = create_conv(1, 1, 2, -1, -2) self.fc = nn.Linear(3, 6) def forward(self, x): return self.fc(self.conv1(x)) config = config_creator() model, compression_ctrl = create_compressed_model_and_algo_for_test( ConvLinear(), config) quantizers = compression_ctrl.weight_quantizers handler = WeightQuantizersHandler(model, quantizers, HardwareQuantizationConstraints()) flops_counter = CompressionRatioCalculator(model, handler) assert flops_counter.ratio_for_bits_configuration([4, 8]) == ref_values[0] assert flops_counter.ratio_for_bits_configuration([8, 4]) == ref_values[1] assert flops_counter.ratio_limits([4, 8]) == ref_values[2] assert flops_counter.ratio_limits([2, 4, 8]) == ref_values[3] constraints = HardwareQuantizationConstraints() constraints.add(list(quantizers)[0], {8}) assert flops_counter.ratio_limits([2, 8], constraints) == ref_values[4]
def test_baseline_scheduler(): """ Test baseline scheduler parameters and changes of params during epochs. """ config = get_pruning_baseline_config() config['compression']['algorithm'] = 'filter_pruning' model = PruningTestModel() _, compression_ctrl = create_compressed_model_and_algo_for_test( model, config) scheduler = compression_ctrl.scheduler # Check default params assert isinstance(scheduler, BaselinePruningScheduler) assert pytest.approx(scheduler.pruning_target) == 0.5 assert pytest.approx(scheduler.initial_pruning) == 0.0 assert scheduler.num_init_steps == 1 # Check pruning params before epoch 0 scheduler.epoch_step() assert pytest.approx(scheduler.current_pruning_level) == 0.0 assert pytest.approx(compression_ctrl.pruning_rate) == 0.0 assert scheduler.current_epoch == 0 assert compression_ctrl.frozen is False # Check pruning params after epoch 0 scheduler.epoch_step() assert pytest.approx(scheduler.current_pruning_level) == 0.5 assert pytest.approx(compression_ctrl.pruning_rate) == 0.5 assert scheduler.current_epoch == 1 assert compression_ctrl.frozen is True
def test_scheduler_can_do_epoch_step(self, algo, schedule, get_params, ref_levels): model = BasicConvTestModel() config = get_empty_config() config['compression'] = { 'algorithm': algo, "sparsity_init": 0.2, "params": { **get_params(), "schedule": schedule } } _, compression_ctrl = create_compressed_model_and_algo_for_test( model, config) scheduler = compression_ctrl.scheduler scheduler.epoch_step() assert pytest.approx(scheduler.current_sparsity_level) == ref_levels[0] for ref_level in ref_levels[1:]: scheduler.epoch_step() assert pytest.approx(scheduler.current_sparsity_level) == ref_level for m in compression_ctrl.sparsified_module_info: if hasattr(m.operand, "frozen"): assert m.operand.frozen
def test_number_of_calling_fq_for_lstm(self): p = LSTMTestSizes(1, 1, 1, 5) num_layers = 2 bidirectional = True num_directions = 2 if bidirectional else 1 bias = True batch_first = False config = get_empty_config( input_sample_sizes=[p.seq_length, p.batch, p.input_size]) config['compression'] = { 'algorithm': 'quantization', 'quantize_inputs': True } test_data = TestLSTMCell.generate_lstm_data(p, num_layers, num_directions, bias=bias, batch_first=batch_first) test_rnn = NNCF_RNN('LSTM', input_size=p.input_size, hidden_size=p.hidden_size, num_layers=num_layers, bidirectional=bidirectional, bias=bias, batch_first=batch_first) TestLSTM.set_ref_lstm_weights(test_data, test_rnn, num_layers, num_directions, bias) test_hidden = TestLSTM.get_test_lstm_hidden(test_data) model, algo = create_compressed_model_and_algo_for_test( test_rnn, config) class Counter: def __init__(self): self.count = 0 def next(self): self.count += 1 def hook(model, input_, counter): counter.next() counters = {} counter_for_input_quantizer = None for name, quantizer in algo.all_quantizations.items(): counter = Counter() quantizer.register_forward_pre_hook(partial(hook, counter=counter)) if str(name) == '/nncf_model_input_0|OUTPUT': counter_for_input_quantizer = counter continue counters[name] = counter _ = model(test_data.x, test_hidden) assert model.get_graph().get_nodes_count( ) == 112 # NB: may always fail in debug due to superfluous 'cat' nodes assert len(counters) + 1 == 55 # 8 WQ + 46 AQ + 1 input AQ for counter in counters.values(): assert counter.count == p.seq_length assert counter_for_input_quantizer.count == 1
def test_hawq_precision_init(_seed, dataset_dir, tmp_path, mocker, config_creator: Callable, filename_suffix: str, avg_traces_creator: Callable): batch_size = 10 config = config_creator(batch_size) model = MobileNetV2(num_classes=10) model.eval() criterion = nn.CrossEntropyLoss().cuda() if not dataset_dir: dataset_dir = str(tmp_path) train_loader, _ = create_test_dataloaders(config.get("model_size"), dataset_dir, batch_size) config = register_default_init_args(config, criterion, train_loader) mocked_trace = mocker.patch('nncf.quantization.hessian_trace.HessianTraceEstimator.get_average_traces') mocked_trace.return_value = avg_traces_creator(model, 'cuda') from torchvision.models.mobilenet import model_urls load_state(model, model_zoo.load_url(model_urls['mobilenet_v2'])) model, algo_ctrl = create_compressed_model_and_algo_for_test(model, config) model = model.cuda() all_quantizers_per_full_scope = HAWQDebugger.get_all_quantizers_per_full_scope(model) quantizer_switcher = QuantizersSwitcher(list(all_quantizers_per_full_scope.values())) # graph may not contain some quantizers (e.g. in staged scenario) quantizer_switcher.enable_quantizers() model.rebuild_graph() graph = HAWQDebugger.get_bitwidth_graph(algo_ctrl, model, all_quantizers_per_full_scope) path_to_dot = 'mobilenet_v2_mixed_bitwidth_graph_{}.dot'.format(filename_suffix) check_graph(graph, path_to_dot, os.path.join('quantized', 'hawq'), sort_dot_graph=False)
def test_staged_scheduler_with_empty_quantization(): config = get_squeezenet_quantization_config() config['compression'].update({ 'params': { "activations_quant_start_epoch": 1, "weights_quant_start_epoch": 2, } }) model = squeezenet1_1_custom(num_classes=10, pretrained=False, dropout=0) model, algo = create_compressed_model_and_algo_for_test(model, config) scheduler = algo.scheduler for module in algo.all_quantizations.values(): assert not module.is_enabled_quantization() scheduler.epoch_step() for module in algo.all_quantizations.values(): if module.is_weights: assert not module.is_enabled_quantization() else: assert module.is_enabled_quantization() scheduler.epoch_step() for module in algo.all_quantizations.values(): assert module.is_enabled_quantization()
def test_sparse_algo_can_collect_sparse_layers(): model = TwoConvTestModel() config = get_basic_sparsity_config() _, compression_ctrl = create_compressed_model_and_algo_for_test(model, config) assert len(compression_ctrl.sparsified_module_info) == 2
def test_input_info_specification_from_config(mocker, input_info_test_struct): stub_fn = mocker.stub() mock_model = MockModel(stub_fn) config = get_basic_quantization_config("symmetric") input_info_config_entry = input_info_test_struct[0] target_argument_info = input_info_test_struct[ 1] # type: List[ModelInputInfo] config["input_info"] = input_info_config_entry _, _ = create_compressed_model_and_algo_for_test(mock_model, config) forward_call_args = stub_fn.call_args[0] forward_call_kwargs = stub_fn.call_args[1] ref_args_info = list( filter(lambda x: x.keyword is None, target_argument_info)) ref_kw_vs_arg_info = { x.keyword: x for x in target_argument_info if x.keyword is not None } def check_arg(arg: torch.Tensor, ref_arg_info: ModelInputInfo): assert list(arg.shape) == ref_arg_info.shape assert arg.dtype == ref_arg_info.type assert len(forward_call_args) == len(ref_args_info) assert len(forward_call_kwargs) == len(ref_kw_vs_arg_info) assert set(forward_call_kwargs.keys()) == set(ref_kw_vs_arg_info.keys()) for idx, arg in enumerate(forward_call_args): check_arg(arg, ref_args_info[idx]) for keyword, arg in forward_call_kwargs.items(): check_arg(arg, ref_kw_vs_arg_info[keyword])
def test_create_rb_algo_with_per_layer_loss(): config = get_empty_config() config['compression'] = {'algorithm': 'rb_sparsity', "params": {"sparsity_level_setting_mode": 'local'}} _, compression_ctrl = create_compressed_model_and_algo_for_test(MockModel(), config) # pylint: disable=protected-access assert isinstance(compression_ctrl._loss, SparseLossForPerLayerSparsity)
def test_hawq_precision_init(_seed, dataset_dir, tmp_path, mocker, params): config = params.config_builder.build() model = params.model_creator().cuda() criterion = nn.CrossEntropyLoss().cuda() if not dataset_dir: dataset_dir = str(tmp_path) train_loader, _ = create_test_dataloaders(config, dataset_dir) config = register_default_init_args(config, train_loader, criterion) mocked_trace = mocker.patch( 'nncf.quantization.hessian_trace.HessianTraceEstimator.get_average_traces', autospec=True) pregen_traces_for_all_layers = params.avg_traces_creator(model, 'cuda') # There may be less traces required to be calculated during HAWQ than there are weightable layers. def side_effect_fn(self, max_iter=500, tolerance=1e-5): #pylint:disable=protected-access return pregen_traces_for_all_layers[:len(self._parameter_handler. parameters)] mocked_trace.side_effect = side_effect_fn model, algo_ctrl = create_compressed_model_and_algo_for_test(model, config) path_to_dot = '{}_{}.dot'.format(params.model_creator.__name__, params.config_builder.filename_suffix()) graph_dir = os.path.join('quantized', 'hawq') check_bitwidth_graph(algo_ctrl, model, path_to_dot, graph_dir)
def test_magnitude_algo_binary_masks_are_applied(): model = BasicConvTestModel() config = get_empty_config() config['compression'] = {'algorithm': "magnitude_sparsity"} compressed_model, compression_ctrl = create_compressed_model_and_algo_for_test( model, config) minfo_list = compression_ctrl.sparsified_module_info # type: List[SparseModuleInfo] minfo = minfo_list[0] # type: SparseModuleInfo minfo.operand.binary_mask = torch.ones_like(minfo.module.weight) # 1x1x2x2 input_ = torch.ones(size=(1, 1, 5, 5)) ref_output_1 = -4 * torch.ones(size=(2, 4, 4)) output_1 = compressed_model(input_) assert torch.all(torch.eq(output_1, ref_output_1)) minfo.operand.binary_mask[0][0][0][1] = 0 minfo.operand.binary_mask[1][0][1][0] = 0 ref_output_2 = -3 * torch.ones_like(ref_output_1) output_2 = compressed_model(input_) assert torch.all(torch.eq(output_2, ref_output_2)) minfo.operand.binary_mask[1][0][0][1] = 0 ref_output_3 = ref_output_2.clone() ref_output_3[1] = -2 * torch.ones_like(ref_output_1[1]) output_3 = compressed_model(input_) assert torch.all(torch.eq(output_3, ref_output_3))
def test_quantization_configs__with_precisions_list(): model = ModelForTest() config = get_quantization_config_without_range_init() config['compression']['initializer'].update({ "precision": { "bitwidth_per_scope": [[2, 'ModelForTest/NNCFConv2d[conv1]'], [4, 'ModelForTest/NNCFConv2d[conv2]']] } }) config['compression']["activations"] = {"bits": 6} config['quantizer_setup_type'] = 'pattern_based' model, compression_ctrl = create_compressed_model_and_algo_for_test( model, config) ref_bits = [('ModelForTest/NNCFConv2d[conv1]module_weight', 2), ('ModelForTest/NNCFConv2d[conv2]module_weight', 4), ('ModelForTest/NNCFConv2d[conv2]/conv2d_0|OUTPUT', 6), ('ModelForTest/NNCFConv2d[conv1]/conv2d_0|OUTPUT', 6), ('/nncf_model_input_0|OUTPUT', 6)] for key, quantizer in compression_ctrl.all_quantizations.items(): expected_bit = [ ref_bit for (name, ref_bit) in ref_bits if name == str(key) ][0] assert quantizer.num_bits == expected_bit, 'Unexpected number of bits for {}'.format( key) ref_rows = [['2', '20', '0', '20'], ['4', '20', '0', '20'], ['6', '0', '60', '60']] table = compression_ctrl.non_stable_metric_collectors[0].get_bits_stat() # pylint: disable=protected-access assert table._rows == ref_rows
def test_can_create_magnitude_sparse_algo__with_defaults(): model = MagnitudeTestModel() config = get_basic_magnitude_sparsity_config() config['compression']['params'] = \ {'schedule': 'multistep'} sparse_model, compression_ctrl = create_compressed_model_and_algo_for_test( deepcopy(model), config) assert isinstance(compression_ctrl, MagnitudeSparsityController) assert compression_ctrl.scheduler.current_sparsity_level == approx(0.1) assert len(list(sparse_model.modules())) == 12 _, sparse_model_conv = check_correct_nncf_modules_replacement( model, sparse_model) i = 0 stats = compression_ctrl.statistics() assert stats["sparsity_threshold"] == approx(0.24, 0.1) assert isinstance(compression_ctrl.weight_importance, type(normed_magnitude)) for sparse_module in sparse_model_conv.values(): store = [] ref_mask = torch.ones_like( sparse_module.weight) if i == 0 else ref_mask_2 i += 1 for op in sparse_module.pre_ops.values(): if isinstance(op, UpdateWeight) and isinstance( op.operand, BinaryMask): assert torch.allclose(op.operand.binary_mask, ref_mask) assert op.__class__.__name__ not in store store.append(op.__class__.__name__)
def test_magnitude_scheduler_can_do_epoch_step__with_norm(): _ = MagnitudeTestModel() config = get_multistep_normed_abs_config() _, compression_ctrl = create_compressed_model_and_algo_for_test( MagnitudeTestModel(), config) scheduler = compression_ctrl.scheduler assert isinstance(scheduler, MultiStepSparsityScheduler) assert compression_ctrl.scheduler.current_sparsity_level == pytest.approx( 0.1) assert compression_ctrl.statistics( )["sparsity_threshold"] == pytest.approx(0.219, 0.01) assert scheduler.prev_ind == 0 scheduler.epoch_step() assert compression_ctrl.scheduler.current_sparsity_level == pytest.approx( 0.5) assert compression_ctrl.statistics( )["sparsity_threshold"] == pytest.approx(0.243, 0.01) assert scheduler.prev_ind == 1 scheduler.epoch_step() assert compression_ctrl.scheduler.current_sparsity_level == pytest.approx( 0.5) assert compression_ctrl.statistics( )["sparsity_threshold"] == pytest.approx(0.243, 0.01) assert scheduler.prev_ind == 1 scheduler.epoch_step() assert compression_ctrl.scheduler.current_sparsity_level == pytest.approx( 0.9) assert compression_ctrl.statistics( )["sparsity_threshold"] == pytest.approx(0.371, 0.01) assert scheduler.prev_ind == 2
def test_can_not_set_sparsity_more_than_one_for_magnitude_sparse_algo(): config = get_basic_magnitude_sparsity_config() _, compression_ctrl = create_compressed_model_and_algo_for_test( MagnitudeTestModel(), config) with pytest.raises(AttributeError): compression_ctrl.set_sparsity_level(1) compression_ctrl.set_sparsity_level(1.2)
def test_ordinary_load(algo, _model_wrapper, is_resume): config = get_empty_config() if algo: config['compression'] = {'algorithm': algo} compressed_model_save, _ = create_compressed_model_and_algo_for_test( BasicConvTestModel(), config) model_save = _model_wrapper['save_model'](compressed_model_save) compressed_model_resume, _ = create_compressed_model_and_algo_for_test( BasicConvTestModel(), config) model_resume = _model_wrapper['resume_model'](compressed_model_resume) num_loaded = load_state(model_resume, model_save.state_dict(), is_resume) assert num_loaded == len(model_save.state_dict())
def test_can_load_quant_algo__with_defaults(): model = BasicConvTestModel() config = get_quantization_config_without_range_init() compression_algo_builder_list = create_compression_algorithm_builders(config) assert len(compression_algo_builder_list) == 1 assert isinstance(compression_algo_builder_list[0], QuantizationBuilder) quant_model, _ = create_compressed_model_and_algo_for_test(deepcopy(model), config) model_conv = get_all_modules_by_type(model, 'Conv2d') quant_model_conv = get_all_modules_by_type(quant_model.get_nncf_wrapped_model(), 'NNCFConv2d') assert len(model_conv) == len(quant_model_conv) for module_scope, _ in model_conv.items(): quant_scope = deepcopy(module_scope) # type: Scope quant_scope.pop() quant_scope.push(ScopeElement('NNCFConv2d', 'conv')) assert quant_scope in quant_model_conv.keys() store = [] for op in quant_model_conv[quant_scope].pre_ops.values(): if isinstance(op, (UpdateInputs, UpdateWeight)) and isinstance(op.operand, SymmetricQuantizer): assert op.__class__.__name__ not in store store.append(op.__class__.__name__) assert UpdateWeight.__name__ in store