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, "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
def test_magnitude_scheduler_can_do_epoch_step__with_norm(): config = get_multistep_normed_abs_config() model = get_magnitude_test_model(config['input_info']['sample_size'][1:]) _, compression_ctrl = create_compressed_model_and_algo_for_test( model, config) scheduler = compression_ctrl.scheduler assert isinstance(scheduler, MultiStepSparsityScheduler) assert pytest.approx(compression_ctrl.sparsity_level) == 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.statistics( )['sparsity_threshold'] == pytest.approx(0.219, 0.01) assert scheduler.prev_ind == 0 scheduler.epoch_step() assert compression_ctrl.sparsity_level == 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.sparsity_level == 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.sparsity_level == 0.9 assert compression_ctrl.statistics( )['sparsity_threshold'] == pytest.approx(0.371, 0.01) assert scheduler.prev_ind == 2
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) assert isinstance(compression_ctrl, QuantizationController) activation_quantizers, weight_quantizers = get_quantizers( compression_model) for layer in compression_model.layers: if isinstance(layer, NNCFWrapper): for ops in layer.weights_attr_ops.values(): for op in ops.values(): if isinstance(op, Quantizer): weight_quantizers.append(op) ref_weight_qconfig = QuantizerConfig(mode=QuantizationMode.SYMMETRIC, num_bits=8, signed=None, per_channel=False, narrow_range=True) for wq in weight_quantizers: compare_qconfigs(ref_weight_qconfig, wq) ref_activation_qconfig = QuantizerConfig(mode=QuantizationMode.SYMMETRIC, num_bits=8, signed=None, per_channel=False, narrow_range=False) for wq in activation_quantizers: compare_qconfigs(ref_activation_qconfig, wq)
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] = 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].numpy() np_mask[0, 1, 0, 0] = 0 np_mask[1, 0, 0, 1] = 0 conv.ops_weights[op_name] = 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] = 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)
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) check_equal(ref_mask_1, sparse_model.layers[1].weights[-1]) check_equal(ref_mask_2, sparse_model.layers[2].weights[-1])
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.sparsity_level == approx(0.1)
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(AttributeError): _, _ = create_compressed_model_and_algo_for_test( get_mock_model(), config)
def test_sparsity_network(self, desc: ModelDesc, _sparsity_case_config): model = desc.model_builder( input_shape=tuple(desc.input_sample_sizes[1:])) config = get_basic_magnitude_sparsity_config(desc.input_sample_sizes) config['compression']['params'] = {'schedule': 'multistep'} compressed_model, _ = create_compressed_model_and_algo_for_test( model, config) check_model_graph(compressed_model, desc.pb_filename, _sparsity_case_config.graph_dir)
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)
def test_quantize_outputs(desc: ModelDesc, _quantization_case_config): model = desc.model_builder(input_shape=tuple(desc.input_sample_sizes[1:])) config = get_basic_quantization_config( _quantization_case_config.qconfig, input_sample_sizes=desc.input_sample_sizes) config['compression']['quantize_outputs'] = True compressed_model, _ = create_compressed_model_and_algo_for_test( model, config) check_model_graph(compressed_model, desc.pb_filename, _quantization_case_config.graph_dir)
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)
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) 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)
def test_can_create_sparse_scheduler__with_defaults(self, algo): config = get_empty_config() config['compression'] = Dict({ 'algorithm': algo, "params": { "schedule": 'polynomial' } }) _, compression_ctrl = create_compressed_model_and_algo_for_test( get_mock_model(), config) scheduler = compression_ctrl.scheduler assert scheduler.initial_sparsity == 0 assert scheduler.sparsity_target == 0.5 assert scheduler.sparsity_target_epoch == 90 assert scheduler.sparsity_freeze_epoch == 100
def test_magnitude_scheduler_can_do_epoch_step__with_last(): config = get_multistep_normed_abs_config() model = get_magnitude_test_model(config['input_info']['sample_size'][1:]) _, compression_ctrl = create_compressed_model_and_algo_for_test( model, config) scheduler = compression_ctrl.scheduler scheduler.epoch_step(3) assert scheduler.prev_ind == 2 assert compression_ctrl.sparsity_level == 0.9 assert compression_ctrl.statistics( )['sparsity_threshold'] == pytest.approx(0.371, 0.01) scheduler.epoch_step() assert scheduler.prev_ind == 2 assert compression_ctrl.sparsity_level == 0.9 assert compression_ctrl.statistics( )['sparsity_threshold'] == pytest.approx(0.371, 0.01)
def test_quantize_inputs(): config = get_basic_quantization_config() input_shapes = [[2, 32, 32, 3] for i in range(5)] model = get_quantize_inputs_test_model(input_shapes) model, _ = create_compressed_model_and_algo_for_test(model, config) ref_fake_quantize_layers_for_inputs = { 'rescaling/fake_quantize', 'input_2/fake_quantize', 'input_3/fake_quantize', 'input_4/fake_quantize', 'input_5/fake_quantize' } ref_fake_quantize_layers = 17 actual_fake_quantize_layers = { layer.name for layer in model.layers if isinstance(layer, FakeQuantize) } assert ref_fake_quantize_layers_for_inputs.issubset( actual_fake_quantize_layers) assert len(actual_fake_quantize_layers) == ref_fake_quantize_layers
def test_quantization_configs__custom(): model = get_basic_conv_test_model() config = get_basic_quantization_config() config['compression'].update({ "weights": { "mode": "asymmetric", "per_channel": True, "bits": 4 }, "activations": { "mode": "asymmetric", "bits": 4, "signed": True, }, }) compression_model, compression_ctrl = create_compressed_model_and_algo_for_test( model, config) assert isinstance(compression_ctrl, QuantizationController) activation_quantizers, weight_quantizers = get_quantizers( compression_model) ref_weight_qconfig = QuantizerConfig(mode=QuantizationMode.ASYMMETRIC, num_bits=4, signed=None, per_channel=True, narrow_range=True) for wq in weight_quantizers: compare_qconfigs(ref_weight_qconfig, wq) ref_activation_qconfig = QuantizerConfig(mode=QuantizationMode.ASYMMETRIC, num_bits=4, signed=True, per_channel=False, narrow_range=False) for wq in activation_quantizers: compare_qconfigs(ref_activation_qconfig, wq)
def test_ignored_scopes(): config = get_basic_quantization_config(32) config['compression']['ignored_scopes'] = ['conv1', '{re}.*conv2.*'] config['compression'][WEIGHTS]['ignored_scopes'] = ['{re}.*conv3/c[23]'] config['compression'][ACTIVATIONS]['ignored_scopes'] = ['{re}.*c3'] model = tf.keras.Sequential([ layers.Conv2D(3, 3, name='conv1', input_shape=config['input_info']['sample_size'][1:]), layers.Conv2D(3, 3, name='conv2'), layers.Conv2D(3, 3, name='conv2/c1'), layers.Conv2D(3, 3, name='some_scope/conv2/c1'), layers.Conv2D(3, 3, name='some_scope/conv3/c2'), layers.Conv2D(3, 3, name='some_scope/conv3/c3'), layers.Conv2D(3, 3, name='c3_1'), layers.Conv2D(3, 3, name='end') ]) compressed_model, _ = create_compressed_model_and_algo_for_test( model, config) ref_fake_quantize_names = [ 'conv1_input/fake_quantize', 'some_scope/conv3/c2/fake_quantize', 'c3_1/fake_quantize' ] ref_nncf_wrapper_names = ['nncf_wrapper_c3_1', 'nncf_wrapper_end'] fake_quantize_names = [ layer.name for layer in compressed_model.layers if isinstance(layer, FakeQuantize) ] nncf_wrapper_names = [ layer.name for layer in compressed_model.layers if isinstance(layer, NNCFWrapper) ] assert fake_quantize_names == ref_fake_quantize_names assert nncf_wrapper_names == ref_nncf_wrapper_names
def test_magnitude_scheduler_can_do_epoch_step__with_multistep(): config = get_empty_config() config["compression"] = Dict({ "algorithm": "magnitude_sparsity", "params": { "schedule": "multistep", 'multistep_steps': [1] } }) model = get_magnitude_test_model( config['input_info'][0]['sample_size'][1:]) _, compression_ctrl = create_compressed_model_and_algo_for_test( model, config) scheduler = compression_ctrl.scheduler assert isinstance(scheduler, MultiStepSparsityScheduler) assert pytest.approx(compression_ctrl.sparsity_level) == 0.1 assert scheduler.sparsity_levels == [0.1, 0.5] scheduler.epoch_step() assert pytest.approx(compression_ctrl.sparsity_level) == 0.1 scheduler.epoch_step() assert compression_ctrl.sparsity_level == 0.5 scheduler.epoch_step() assert compression_ctrl.sparsity_level == 0.5
def test_can_create_magnitude_sparse_algo__with_defaults(): model = get_magnitude_test_model() config = get_basic_magnitude_sparsity_config() config['compression']['params'] = \ {'schedule': 'multistep'} sparse_model, compression_ctrl = create_compressed_model_and_algo_for_test( model, config) assert isinstance(compression_ctrl, MagnitudeSparsityController) assert compression_ctrl.sparsity_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.layer.name in conv_names ] assert len(conv_names) == len(wrappers) assert len(conv_names) == len(correct_wrappers) assert compression_ctrl.threshold == approx(0.24, 0.1) assert isinstance(compression_ctrl.weight_importance, type(normed_magnitude)) for i, wrapper in enumerate(wrappers): ref_mask = tf.ones_like(wrapper.weights[-1]) if i == 0 else ref_mask_2 mask = list(wrapper.ops_weights.values())[0] op = list(wrapper.weights_attr_ops['kernel'].values())[0] tf.assert_equal(mask, ref_mask) assert isinstance(op, BinaryMask)