예제 #1
0
    def test_scheduler_can_do_epoch_step(self, algo, schedule, get_params,
                                         ref_levels):
        model = get_basic_conv_test_model()
        config = get_empty_config()
        config['compression'] = Dict({
            '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

        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

        _, compression_ctrl = create_compressed_model_and_algo_for_test(
            model, config)
        scheduler = compression_ctrl.scheduler

        assert pytest.approx(scheduler.current_sparsity_level) == ref_levels[0]
        for i, ref_level in enumerate(ref_levels[1:]):
            scheduler.epoch_step(i)
            assert pytest.approx(scheduler.current_sparsity_level) == ref_level
예제 #2
0
def test_checkpoint_callback_make_checkpoints(mocker, tmp_path):
    save_freq = 2
    config = get_basic_quantization_config()
    gen_setup_spy = mocker.spy(QuantizationBuilder, '_get_quantizer_setup')

    model, compression_ctrl = create_compressed_model_and_algo_for_test(
        get_basic_conv_test_model(), config, force_no_init=True)
    assert isinstance(compression_ctrl, QuantizationController)

    quantizer_setup = gen_setup_spy.spy_return
    compression_callbacks = create_compression_callbacks(compression_ctrl,
                                                         log_tensorboard=False)
    dataset_len = 8

    dummy_x = tf.random.normal((dataset_len, ) + model.input_shape[1:])
    dummy_y = tf.random.normal((dataset_len, ) + model.output_shape[1:])

    model.compile(loss=tf.losses.CategoricalCrossentropy())

    ckpt_path = tmp_path / 'checkpoint'
    ckpt = tf.train.Checkpoint(
        model=model, compression_state=TFCompressionState(compression_ctrl))
    model.fit(dummy_x,
              dummy_y,
              epochs=5,
              batch_size=2,
              callbacks=[
                  CheckpointManagerCallback(ckpt, str(ckpt_path), save_freq),
                  *compression_callbacks
              ])

    assert sorted(os.listdir(ckpt_path)) == REF_CKPT_DIR[save_freq]

    new_compression_state = load_compression_state(ckpt_path)

    new_model, new_compression_ctrl = create_compressed_model_and_algo_for_test(
        get_basic_conv_test_model(), config, new_compression_state)
    new_model.compile(loss=tf.losses.CategoricalCrossentropy())
    new_ckpt = tf.train.Checkpoint(
        model=new_model,
        compression_state=TFCompressionState(new_compression_ctrl))
    load_checkpoint(new_ckpt, ckpt_path)

    builder = QuantizationBuilder(config)
    builder.load_state(new_compression_state['builder_state'])
    # pylint:disable=protected-access
    new_quantizer_setup = builder._quantizer_setup

    assert _quantization_setup_cmp(quantizer_setup, new_quantizer_setup)
    assert new_compression_ctrl.get_state() == compression_ctrl.get_state()
    assert tf.reduce_all([
        tf.reduce_all(w_new == w)
        for w_new, w in zip(new_model.weights, model.weights)
    ])
예제 #3
0
def test_quantization_preset_with_scope_overrides():
    model = get_basic_two_conv_test_model()
    config = get_basic_quantization_config()
    config['target_device'] = "TRIAL"
    config['compression'] = {
        'algorithm': 'quantization',
        'preset': 'mixed',
        'scope_overrides': {
            'weights': {
                'conv2d': {
                    "mode": "asymmetric",
                }
            }
        }
    }
    compression_model, _ = create_compressed_model_and_algo_for_test(
        model, config, force_no_init=True)

    activation_quantizers, weight_quantizers = get_quantizers(
        compression_model)
    for aq in activation_quantizers:
        assert aq.mode == 'asymmetric'
    for wq in weight_quantizers:
        if wq.name == 'conv2d_kernel_quantizer':
            assert wq.mode == 'asymmetric'
        else:
            assert wq.mode == 'symmetric'
예제 #4
0
def test_can_load_sparse_algo__with_defaults():
    model = get_basic_two_conv_test_model()
    config = get_basic_sparsity_config(sparsity_init=0.1)
    sparse_model, compression_ctrl = create_compressed_model_and_algo_for_test(
        model, config)
    assert isinstance(compression_ctrl, RBSparsityController)
    assert compression_ctrl.scheduler.initial_level == approx(0.1)

    conv_names = [
        layer.name for layer in model.layers
        if isinstance(layer, tf.keras.layers.Conv2D)
    ]
    wrappers = [
        layer for layer in sparse_model.layers
        if isinstance(layer, NNCFWrapper)
    ]
    correct_wrappers = [
        wrapper for wrapper in wrappers if wrapper.name in conv_names
    ]

    assert len(conv_names) == len(wrappers)
    assert len(conv_names) == len(correct_wrappers)

    for wrapper in wrappers:
        op = get_op_by_cls(wrapper, RBSparsifyingWeight)
        mask = wrapper.get_operation_weights(op.name)['mask']
        ref_mask = tf.fill(mask.shape, logit(0.99))

        tf.assert_equal(mask, ref_mask)
예제 #5
0
def test_magnitude_algo_binary_masks_are_applied():
    input_shape = (1, 5, 5, 1)
    model = get_basic_conv_test_model(input_shape=input_shape[1:])
    config = get_empty_config(input_sample_sizes=input_shape)
    config.update(Dict({'compression': {'algorithm': "magnitude_sparsity"}}))
    compressed_model, _ = create_compressed_model_and_algo_for_test(
        model, config)
    conv = compressed_model.layers[1]
    op_name = list(conv.ops_weights.keys())[0]
    conv.ops_weights[op_name] = {'mask': tf.ones_like(conv.weights[0])}
    input_ = tf.ones(input_shape)
    ref_output_1 = -4 * tf.ones((1, 4, 4, 2))
    output_1 = compressed_model(input_)
    tf.assert_equal(output_1, ref_output_1)

    np_mask = conv.ops_weights[op_name]['mask'].numpy()
    np_mask[0, 1, 0, 0] = 0
    np_mask[1, 0, 0, 1] = 0
    conv.ops_weights[op_name] = {'mask': tf.constant(np_mask)}
    ref_output_2 = -3 * tf.ones_like(ref_output_1)
    output_2 = compressed_model(input_)
    tf.assert_equal(output_2, ref_output_2)

    np_mask[0, 1, 0, 1] = 0
    conv.ops_weights[op_name] = {'mask': tf.constant(np_mask)}
    ref_output_3 = ref_output_2.numpy()
    ref_output_3[..., 1] = -2 * np.ones_like(ref_output_1[..., 1])
    ref_output_3 = tf.constant(ref_output_3)
    output_3 = compressed_model(input_)
    tf.assert_equal(output_3, ref_output_3)
예제 #6
0
def test_quantization_configs__disable_overflow_fix_and_resume_from_compression_state(
        tmp_path):
    model = get_basic_conv_test_model()

    config = get_basic_quantization_config()
    config['compression'].update({'overflow_fix': 'disable'})
    compression_model, compression_ctrl = create_compressed_model_and_algo_for_test(
        model, config, force_no_init=True)

    compression_state_to_load = _save_and_load_compression_state(
        compression_ctrl, tmp_path)

    compression_model, compression_ctrl = create_compressed_model_and_algo_for_test(
        model, config, compression_state_to_load)
    assert isinstance(compression_ctrl, QuantizationController)
    check_specs_for_disabled_overflow_fix(compression_model)
예제 #7
0
def test_compression_controller_state():
    from nncf.common.compression import BaseControllerStateNames as CtrlStateNames
    model = get_magnitude_test_model()
    config = get_basic_magnitude_sparsity_config()
    algo_name = config['compression']['algorithm']
    config['compression']['params'] = {'schedule': 'multistep'}
    _, compression_ctrl = create_compressed_model_and_algo_for_test(
        model, config)

    # Test get state
    compression_ctrl.scheduler.current_step = 100
    compression_ctrl.scheduler.current_epoch = 5
    state_content = compression_ctrl.get_state()[algo_name]
    assert state_content[CtrlStateNames.SCHEDULER] == {
        'current_step': 100,
        'current_epoch': 5
    }

    # Test load state
    new_state = {
        algo_name: {
            CtrlStateNames.SCHEDULER: {
                'current_step': 500,
                'current_epoch': 10
            },
            CtrlStateNames.LOSS: {},
            CtrlStateNames.COMPRESSION_STAGE: None,
        }
    }
    compression_ctrl.load_state(new_state)
    assert compression_ctrl.scheduler.current_step == 500
    assert compression_ctrl.scheduler.current_epoch == 10
    assert compression_ctrl.get_state() == new_state
def test_no_compression_algo_not_change_model_params():
    orig_model = get_basic_two_conv_test_model()
    model, _algo = create_compressed_model_and_algo_for_test(
        orig_model, NO_COMPRESSION_NNCF_CONFIG)

    orig_model_weights = orig_model.get_weights()
    model_weights = model.get_weights()
    TFTensorListComparator.check_equal(orig_model_weights, model_weights)
예제 #9
0
def test_quantization_configs__with_defaults():
    model = get_basic_conv_test_model()
    config = get_basic_quantization_config()

    compression_model, compression_ctrl = create_compressed_model_and_algo_for_test(
        model, config, force_no_init=True)

    assert isinstance(compression_ctrl, QuantizationController)
    check_default_qspecs(compression_model)
예제 #10
0
def test_can_create_magnitude_algo__without_levels():
    config = get_basic_magnitude_sparsity_config()
    config['compression']['params'] = {
        'schedule': 'multistep',
        'multistep_steps': [1]
    }
    _, compression_ctrl = create_compressed_model_and_algo_for_test(
        get_mock_model(), config)
    assert compression_ctrl.scheduler.current_sparsity_level == approx(0.1)
예제 #11
0
def test_adaptive_compression_training_loop(max_accuracy_degradation, final_compression_rate,
                                            reference_final_metric, should_raise_runtime_error,
                                            initial_training_phase_epochs=5, patience_epochs=3,
                                            uncompressed_model_accuracy=0.2, steps_per_epoch=20,
                                            img_size=10):
    set_random_seed(42)
    model = get_simple_conv_regression_model(img_size)
    dataset = get_const_target_mock_regression_dataset(img_size=img_size,
                                                       num_samples=steps_per_epoch)
    config = get_basic_magnitude_sparsity_config(input_sample_size=[1, img_size, img_size, 1])

    params = {
        "initial_training_phase_epochs": initial_training_phase_epochs,
        "patience_epochs": patience_epochs,
    }
    params.update(max_accuracy_degradation)
    accuracy_aware_config = {
        "accuracy_aware_training": {
            "mode": "adaptive_compression_level",
            "params": params
        }
    }

    config.update(accuracy_aware_config)

    compress_model, compression_ctrl = create_compressed_model_and_algo_for_test(model, config)
    compression_callbacks = create_compression_callbacks(compression_ctrl, log_tensorboard=False)
    compress_model.add_loss(compression_ctrl.loss)

    def inverse_loss(y_true, y_pred):
        return 1 / (1 + (y_true - y_pred) ** 2)

    compress_model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.01),
                           loss=tf.keras.losses.MeanSquaredError(),
                           metrics=inverse_loss)

    result_dict_to_val_metric_fn = lambda results: results['inverse_loss']

    exec_ctx = pytest.raises(RuntimeError) if should_raise_runtime_error \
        else contextlib.suppress()
    with exec_ctx as execinfo:
        compress_model.accuracy_aware_fit(dataset,
                                          compression_ctrl,
                                          nncf_config=config,
                                          callbacks=compression_callbacks,
                                          initial_epoch=0,
                                          steps_per_epoch=steps_per_epoch,
                                          uncompressed_model_accuracy=uncompressed_model_accuracy,
                                          result_dict_to_val_metric_fn=result_dict_to_val_metric_fn)
        validation_metrics = compress_model.evaluate(dataset, return_dict=True)

        assert result_dict_to_val_metric_fn(validation_metrics) == pytest.approx(reference_final_metric, 1e-4)
        assert compression_ctrl.compression_rate == pytest.approx(final_compression_rate, 1e-3)

    if should_raise_runtime_error:
        assert str(execinfo.value) == 'Cannot produce a compressed model with a ' \
                                      'specified minimal tolerable accuracy'
예제 #12
0
def test_sparse_algo_can_collect_sparse_ops():
    model = get_basic_two_conv_test_model()

    config = get_basic_sparsity_config()
    _, compression_ctrl = create_compressed_model_and_algo_for_test(
        model, config)

    # pylint: disable=protected-access
    assert len(compression_ctrl.loss._target_ops) == 2
예제 #13
0
def test_compression_controller_state():
    from nncf.common.compression import BaseControllerStateNames as CtrlStateNames
    model = get_basic_two_conv_test_model()
    config = get_basic_sparsity_config()
    algo_name = config['compression']['algorithm']
    _, compression_ctrl = create_compressed_model_and_algo_for_test(
        model, config)

    # Test get state
    compression_ctrl.scheduler.current_step = 100
    compression_ctrl.scheduler.current_epoch = 5
    compression_ctrl.set_sparsity_level(0.5)
    compression_ctrl.freeze()
    assert compression_ctrl.get_state() == {
        algo_name: {
            CtrlStateNames.SCHEDULER: {
                'current_step': 100,
                'current_epoch': 5
            },
            CtrlStateNames.LOSS: {
                'target': 0.5,
                'disabled': True,
                'p': 0.05
            },
            CtrlStateNames.COMPRESSION_STAGE: None
        }
    }
    # Test load state
    new_state = {
        CtrlStateNames.SCHEDULER: {
            'current_step': 5000,
            'current_epoch': 10
        },
        CtrlStateNames.LOSS: {
            'target': 0.9,
            'disabled': False,
            'p': 0.5
        },
        CtrlStateNames.COMPRESSION_STAGE: None
    }
    compression_ctrl.load_state({algo_name: new_state})
    assert tf.equal(compression_ctrl.loss.target,
                    tf.constant(new_state[CtrlStateNames.LOSS]['target']))
    assert compression_ctrl.loss.disabled == new_state[
        CtrlStateNames.LOSS]['disabled']
    assert compression_ctrl.loss.p == pytest.approx(
        new_state[CtrlStateNames.LOSS]['p'])

    new_real_state = compression_ctrl.get_state()[algo_name]
    assert new_real_state[CtrlStateNames.SCHEDULER] == new_state[
        CtrlStateNames.SCHEDULER]
    assert new_real_state[CtrlStateNames.LOSS]['target'] == pytest.approx(
        new_state[CtrlStateNames.LOSS]['target'])
    assert new_real_state[CtrlStateNames.LOSS]['disabled'] == new_state[
        CtrlStateNames.LOSS]['disabled']
    assert new_real_state[CtrlStateNames.LOSS]['p'] == pytest.approx(
        new_state[CtrlStateNames.LOSS]['p'])
예제 #14
0
def test_can_set_sparse_layers_to_loss():
    model = get_basic_conv_test_model()
    config = get_basic_sparsity_config()
    _, compression_ctrl = create_compressed_model_and_algo_for_test(
        model, config)
    loss = compression_ctrl.loss
    assert isinstance(loss, SparseLoss)
    # pylint: disable=protected-access
    for op, _ in loss._target_ops:
        assert isinstance(op, RBSparsifyingWeight)
예제 #15
0
def test_can_not_create_magnitude_algo__with_not_matched_steps_and_levels():
    config = get_basic_magnitude_sparsity_config()
    config['compression']['params'] = {
        'schedule': 'multistep',
        'multistep_sparsity_levels': [0.1],
        'multistep_steps': [1, 2]
    }
    with pytest.raises(ValueError):
        _, _ = create_compressed_model_and_algo_for_test(
            get_mock_model(), config)
예제 #16
0
def test_can_choose_scheduler(algo, schedule_type, scheduler_class):
    config = get_empty_config()
    config['compression'] = Dict({
        'algorithm': algo,
        'params': {
            'schedule': schedule_type
        }
    })
    _, compression_ctrl = create_compressed_model_and_algo_for_test(
        get_mock_model(), config)
    assert isinstance(compression_ctrl.scheduler, scheduler_class)
예제 #17
0
def test_magnitude_algo_set_binary_mask_on_forward():
    config = get_basic_magnitude_sparsity_config()
    config['compression']['params'] = {'weight_importance': 'abs'}
    sparse_model, compression_ctrl = create_compressed_model_and_algo_for_test(
        get_magnitude_test_model(), config)
    compression_ctrl.set_sparsity_level(0.3)

    TFTensorListComparator.check_equal(ref_mask_1,
                                       sparse_model.layers[1].weights[-1])
    TFTensorListComparator.check_equal(ref_mask_2,
                                       sparse_model.layers[2].weights[-1])
예제 #18
0
def test_can_not_create_magnitude_algo__with_adaptive_scheduler():
    config = get_empty_config()
    config['compression'] = {
        'algorithm': 'magnitude_sparsity',
        'params': {
            'schedule': 'adaptive'
        }
    }
    with pytest.raises(ValueError):
        _, _ = create_compressed_model_and_algo_for_test(
            get_mock_model(), config)
예제 #19
0
def test_quantization_statistics(test_case):
    _, compression_ctrl = create_compressed_model_and_algo_for_test(test_case.model,
                                                                    test_case.config,
                                                                    force_no_init=True)
    actual = compression_ctrl.statistics().quantization
    expected = test_case.expected

    assert expected.wq_counter.__dict__ == actual.wq_counter.__dict__
    assert expected.aq_counter.__dict__ == actual.aq_counter.__dict__
    assert expected.num_wq_per_bitwidth == actual.num_wq_per_bitwidth
    assert expected.num_aq_per_bitwidth == actual.num_aq_per_bitwidth
    assert expected.ratio_of_enabled_quantizations == actual.ratio_of_enabled_quantizations
예제 #20
0
def test_magnitude_sparse_algo_sets_threshold(weight_importance,
                                              sparsity_level, threshold):
    model = get_magnitude_test_model()
    config = get_basic_magnitude_sparsity_config()
    config['compression']['params'] = {
        'schedule': 'multistep',
        'weight_importance': weight_importance
    }
    _, compression_ctrl = create_compressed_model_and_algo_for_test(
        model, config)
    if sparsity_level:
        compression_ctrl.set_sparsity_level(sparsity_level)
    assert compression_ctrl._threshold == pytest.approx(threshold, 0.01)  # pylint: disable=protected-access
예제 #21
0
def test_early_exit_compression_training_loop(max_accuracy_degradation,
                                              maximal_total_epochs=100, uncompressed_model_accuracy=0.2,
                                              steps_per_epoch=20, img_size=10):
    set_random_seed(42)
    model = get_simple_conv_regression_model(img_size)
    dataset = get_const_target_mock_regression_dataset(img_size=img_size,
                                                       num_samples=steps_per_epoch)

    config = get_basic_quantization_config(img_size)
    params = {
        "maximal_total_epochs": maximal_total_epochs,
    }
    params.update(max_accuracy_degradation)
    accuracy_aware_config = {
        "accuracy_aware_training": {
            "mode": "early_exit",
            "params": params
        }
    }
    config.update(accuracy_aware_config)
    config = register_default_init_args(config, dataset, batch_size=1)
    compress_model, compression_ctrl = create_compressed_model_and_algo_for_test(model, config)
    compression_callbacks = create_compression_callbacks(compression_ctrl, log_tensorboard=False)
    compress_model.add_loss(compression_ctrl.loss)

    def inverse_loss(y_true, y_pred):
        return 1 / (1 + (y_true - y_pred) ** 2)

    compress_model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.01),
                           loss=tf.keras.losses.MeanSquaredError(),
                           metrics=inverse_loss)

    result_dict_to_val_metric_fn = lambda results: results['inverse_loss']

    compress_model.accuracy_aware_fit(dataset,
                                      compression_ctrl,
                                      nncf_config=config,
                                      callbacks=compression_callbacks,
                                      initial_epoch=0,
                                      steps_per_epoch=steps_per_epoch,
                                      uncompressed_model_accuracy=uncompressed_model_accuracy,
                                      result_dict_to_val_metric_fn=result_dict_to_val_metric_fn)
    original_model_accuracy = compress_model.original_model_accuracy
    compressed_model_accuracy = result_dict_to_val_metric_fn(compress_model.evaluate(dataset, return_dict=True))

    if "maximal_absolute_accuracy_degradation" in max_accuracy_degradation:
        assert (original_model_accuracy - compressed_model_accuracy) <= \
               max_accuracy_degradation["maximal_absolute_accuracy_degradation"]
    else:
        assert (original_model_accuracy - compressed_model_accuracy) / original_model_accuracy * 100 <= \
               max_accuracy_degradation["maximal_relative_accuracy_degradation"]
예제 #22
0
def test_sparse_algo_does_not_replace_not_conv_layer():
    x = tf.keras.layers.Input((10, 10, 3))
    y = tf.keras.layers.Conv2D(1, 1)(x)
    y = tf.keras.layers.BatchNormalization()(y)

    model = tf.keras.Model(inputs=x, outputs=y)
    config = get_basic_sparsity_config()
    _, compression_ctrl = create_compressed_model_and_algo_for_test(
        model, config)
    assert isinstance(compression_ctrl, RBSparsityController)
    # pylint: disable=protected-access
    target_ops = compression_ctrl.loss._target_ops
    assert len(target_ops) == 1
    assert isinstance(target_ops[0][0], RBSparsifyingWeight)
예제 #23
0
def get_basic_rb_sparse_model(model_name,
                              local=False,
                              config=CONF,
                              freeze=False):
    model = TEST_MODELS[model_name]()
    if isinstance(config, Path):
        config = NNCFConfig.from_json(config)
    if local:
        config.update({"params": {"sparsity_level_setting_mode": 'local'}})
    compress_model, algo = create_compressed_model_and_algo_for_test(
        model, config, force_no_init=True)
    if freeze:
        algo.freeze()
    return compress_model, algo, config
예제 #24
0
def test_quantization_configs__on_resume_with_compression_state(
        tmp_path, mocker):
    model = get_basic_conv_test_model()
    config = get_basic_quantization_config()
    init_spy = mocker.spy(QuantizationBuilder, 'initialize')
    gen_setup_spy = mocker.spy(QuantizationBuilder, '_get_quantizer_setup')
    dataset = get_dataset_for_test(shape=[4, 4, 1])
    config = register_default_init_args(config, dataset, 10)

    _, compression_ctrl = create_compressed_model_and_algo_for_test(
        model, config)
    assert isinstance(compression_ctrl, QuantizationController)
    init_spy.assert_called()
    gen_setup_spy.assert_called()
    saved_quantizer_setup = gen_setup_spy.spy_return
    check_serialization(saved_quantizer_setup, _quantization_setup_cmp)

    compression_state_to_load = _save_and_load_compression_state(
        compression_ctrl, tmp_path)

    init_spy.reset_mock()
    gen_setup_spy.reset_mock()

    compression_model, compression_ctrl = create_compressed_model_and_algo_for_test(
        model, config, compression_state_to_load)
    assert isinstance(compression_ctrl, QuantizationController)

    init_spy.assert_not_called()
    gen_setup_spy.assert_not_called()
    check_default_qspecs(compression_model)

    builder = QuantizationBuilder(config)
    builder.load_state(compression_state_to_load['builder_state'])
    # pylint:disable=protected-access
    loaded_quantizer_setup = builder._quantizer_setup
    assert _quantization_setup_cmp(loaded_quantizer_setup,
                                   saved_quantizer_setup)
예제 #25
0
def test_eltwise_unified_scales_for_vpu():
    nncf_config = get_basic_quantization_config()
    x_shape = [1, 1, 1, 1]
    y_shape = [1, 1, 1, 1]
    nncf_config["target_device"] = "VPU"

    model = get_eltwise_quantizer_linking_test_model([x_shape, y_shape])
    compressed_model, _ = create_compressed_model_and_algo_for_test(
        model, nncf_config, force_no_init=True)

    non_weight_quantizers = len(collect_fake_quantize_layers(compressed_model))
    assert non_weight_quantizers == 2

    total_quantizations = get_total_quantizations(compressed_model)
    assert total_quantizations == 8
예제 #26
0
def test_quantize_outputs_removal():
    config = get_basic_quantization_config()
    sample_size = [2, 32, 32, 3]
    model = get_quantize_outputs_removal_test_model(sample_size)

    model, _ = create_compressed_model_and_algo_for_test(model,
                                                         config,
                                                         force_no_init=True)
    ref_fake_quantize_layers = ['input/fake_quantize']
    actual_fake_quantize_layers = [
        layer.name for layer in model.layers
        if isinstance(layer, FakeQuantize)
    ]
    assert actual_fake_quantize_layers == ref_fake_quantize_layers
    assert len(actual_fake_quantize_layers) == len(ref_fake_quantize_layers)
예제 #27
0
def test_export_overflow_fix(sf_mode):
    model = get_basic_two_conv_test_model()
    config = get_basic_quantization_config()
    config['compression'].update({'overflow_fix': sf_mode})
    enabled = sf_mode in ['enable', 'first_layer_only']

    compression_model, compression_ctrl = create_compressed_model_and_algo_for_test(
        model, config, force_no_init=True)
    activation_quantizers_be, weight_quantizers_be = get_quantizers(
        compression_model)

    for idx, wq in enumerate(weight_quantizers_be):
        if sf_mode == 'first_layer_only' and idx > 0:
            enabled = False
        ref_weight_qspec = TFQuantizerSpec(mode=QuantizationMode.SYMMETRIC,
                                           num_bits=8,
                                           signedness_to_force=True,
                                           per_channel=True,
                                           narrow_range=not enabled,
                                           half_range=enabled)
        compare_qspecs(ref_weight_qspec, wq)

    ref_activation_qspec = TFQuantizerSpec(mode=QuantizationMode.SYMMETRIC,
                                           num_bits=8,
                                           signedness_to_force=None,
                                           per_channel=False,
                                           narrow_range=False,
                                           half_range=False)
    for wq in activation_quantizers_be:
        compare_qspecs(ref_activation_qspec, wq)

    enabled = sf_mode in ['enable', 'first_layer_only']
    compression_ctrl.export_model('/tmp/test.pb')
    activation_quantizers_ae, weight_quantizers_ae = get_quantizers(
        compression_model)

    for idx, wq in enumerate(weight_quantizers_ae):
        if sf_mode == 'first_layer_only' and idx > 0:
            enabled = False
        ref_weight_qspec = TFQuantizerSpec(mode=QuantizationMode.SYMMETRIC,
                                           num_bits=8,
                                           signedness_to_force=True,
                                           per_channel=True,
                                           narrow_range=not enabled,
                                           half_range=False)
        compare_qspecs(ref_weight_qspec, wq)
    for wq in activation_quantizers_ae:
        compare_qspecs(ref_activation_qspec, wq)
예제 #28
0
def test_scheduler_can_do_epoch_step__with_rb_algo():
    config = NNCFConfig()
    config['input_info'] = [{"sample_size": [1, 4, 4, 1]}]
    config['compression'] = {
        'algorithm': 'rb_sparsity',
        'sparsity_init': 0.2,
        "params": {
            'schedule': 'polynomial',
            'power': 1,
            'sparsity_target_epoch': 2,
            'sparsity_target': 0.6,
            'sparsity_freeze_epoch': 3
        }
    }

    _, compression_ctrl = create_compressed_model_and_algo_for_test(
        get_basic_conv_test_model(), config)
    scheduler = compression_ctrl.scheduler
    loss = compression_ctrl.loss

    assert not loss.disabled

    # pylint: disable=protected-access
    for op, op_weights in loss._target_ops:
        assert op.get_trainable_weight(op_weights)

    scheduler.epoch_step()
    assert pytest.approx(loss.target_sparsity_rate, abs=1e-3) == 0.2
    assert pytest.approx(loss(), abs=1e-3) == 16
    assert not loss.disabled

    scheduler.epoch_step()
    assert pytest.approx(loss.target_sparsity_rate, abs=1e-3) == 0.4
    assert pytest.approx(loss(), abs=1e-3) == 64
    assert not loss.disabled

    scheduler.epoch_step()
    assert pytest.approx(loss.target_sparsity_rate, abs=1e-3) == 0.6
    assert pytest.approx(loss(), abs=1e-3) == 144
    assert not loss.disabled

    scheduler.epoch_step()
    assert loss.disabled
    assert pytest.approx(loss.target_sparsity_rate, abs=1e-3) == 0.6
    assert loss() == 0

    for op, op_weights in loss._target_ops:
        assert not op.get_trainable_weight(op_weights)
예제 #29
0
def test_struct_auxiliary_nodes_nncf_graph():
    model = get_basic_conv_test_model()
    config = get_basic_quantization_config()
    compressed_model, _ = create_compressed_model_and_algo_for_test(
        model, config, force_no_init=True)

    nncf_graph = convert_keras_model_to_nncf_graph(compressed_model)

    input_nodes = nncf_graph.get_input_nodes()
    output_nodes = nncf_graph.get_output_nodes()

    assert len(input_nodes) == 1
    assert len(output_nodes) == 1

    assert input_nodes[0].metatype in INPUT_NOOP_METATYPES
    assert output_nodes[0].metatype in OUTPUT_NOOP_METATYPES
예제 #30
0
def test_unified_scales_with_concat(target_device, model_creator,
                                    ref_aq_module_count, ref_quantizations):
    nncf_config = get_basic_quantization_config()
    x_shape = [1, 4, 1, 1]
    y_shape = [1, 4, 1, 1]
    nncf_config["target_device"] = target_device

    model = model_creator([x_shape, y_shape])
    compressed_model, _ = create_compressed_model_and_algo_for_test(
        model, nncf_config, force_no_init=True)

    non_weight_quantizers = len(collect_fake_quantize_layers(compressed_model))
    assert non_weight_quantizers == ref_aq_module_count

    total_quantizations = get_total_quantizations(compressed_model)
    assert total_quantizations == ref_quantizations