def get_basic_sparsity_config(model_size=4, input_sample_size=None, sparsity_init=0.02, sparsity_target=0.5, sparsity_steps=2, sparsity_training_steps=3): if input_sample_size is None: input_sample_size = [1, 1, 4, 4] config = NNCFConfig() config.update({ "model": "basic_sparse_conv", "model_size": model_size, "input_info": { "sample_size": input_sample_size, }, "compression": { "algorithm": "rb_sparsity", "params": { "schedule": "polynomial", "sparsity_init": sparsity_init, "sparsity_target": sparsity_target, "sparsity_steps": sparsity_steps, "sparsity_training_steps": sparsity_training_steps }, } }) return config
def get_basic_pruning_config(input_sample_size=None) -> NNCFConfig: if input_sample_size is None: input_sample_size = [1, 1, 4, 4] config = NNCFConfig() config.update({ "model": "pruning_conv_model", "input_info": { "sample_size": input_sample_size, }, "compression": { "params": {} } }) return config
def get_basic_sparsity_plus_quantization_config(input_sample_size=None): if input_sample_size is None: input_sample_size = [1, 1, 4, 4] config = NNCFConfig() config.update({ "input_info": { "sample_size": input_sample_size, }, "compression": [{ "algorithm": "rb_sparsity", }, { "algorithm": "quantization" }] }) return config
def get_basic_magnitude_sparsity_config(input_sample_size=None): if input_sample_size is None: input_sample_size = [1, 1, 4, 4] config = NNCFConfig() config.update({ "model": "basic_sparse_conv", "input_info": { "sample_size": input_sample_size, }, "compression": { "algorithm": "magnitude_sparsity", "params": {} } }) return config
def get_empty_config(model_size=4, input_sample_sizes: Union[Tuple[List[int]], List[int]] = None): if input_sample_sizes is None: input_sample_sizes = [1, 1, 4, 4] def _create_input_info(): if isinstance(input_sample_sizes, tuple): return [{"sample_size": sizes} for sizes in input_sample_sizes] return [{"sample_size": input_sample_sizes}] config = NNCFConfig() config.update({ "model": "basic_sparse_conv", "model_size": model_size, "input_info": _create_input_info() }) return config
def get_basic_quantization_config(model_size=4): config = NNCFConfig() config.update({ "model": "basic_quant_conv", "model_size": model_size, "input_info": { "sample_size": [1, 1, model_size, model_size], }, "compression": { "algorithm": "quantization", "initializer": { "range": { "num_init_steps": 0 } } } }) return config
def test_get_default_weight_decay(algo, ref_weight_decay): config = NNCFConfig() config.update({"compression": {"algorithm": algo}}) assert ref_weight_decay == get_default_weight_decay(config)
def test_init_ranges_are_set(quantization_mode: str, per_channel: bool, range_init_type_vs_ref_vals: Tuple[str, float, float, float]): class SyntheticDataset(torch.utils.data.Dataset): def __init__(self): super().__init__() self._length = 1 def __getitem__(self, idx): if idx >= self._length: raise StopIteration test_input_sample = torch.zeros([3, 100, 100]) for i in range(0, 100): for j in range(0, 100): test_input_sample[0][i][j] = i * 100 + j test_input_sample[1] = test_input_sample[0] test_input_sample[2] = test_input_sample[0] return test_input_sample, test_input_sample def __len__(self): return self._length data_loader = torch.utils.data.DataLoader(SyntheticDataset(), batch_size=1, drop_last=True) range_init_type = range_init_type_vs_ref_vals[0] config_with_init = NNCFConfig() config_with_init.update({ "input_info": { "sample_size": [1, 3, 100, 100] }, "target_device": "TRIAL", "compression": { "algorithm": "quantization", "activations": { "mode": quantization_mode, "per_channel": per_channel }, "weights": { "mode": quantization_mode, "per_channel": per_channel }, "initializer": { "range": { "num_init_samples": 1, "type": range_init_type } } } }) if range_init_type == "percentile": config_with_init["compression"]["initializer"]["range"]["params"] = { "min_percentile": 32.10, "max_percentile": 67.89 } # Activations init check id_model = SingleConv2dIdentityModel() config_with_init.register_extra_structs( [QuantizationRangeInitArgs(wrap_dataloader_for_init(data_loader))]) register_bn_adaptation_init_args(config_with_init) _, compression_ctrl = create_compressed_model_and_algo_for_test( id_model, config_with_init) act_quantizer_info = next( iter(compression_ctrl.non_weight_quantizers.values())) ref_scale = range_init_type_vs_ref_vals[1] ref_input_low = range_init_type_vs_ref_vals[2] ref_input_high = range_init_type_vs_ref_vals[3] def check_scales(quantizer: BaseQuantizer, per_channel: bool): # Absolute tolerance is 1.0 due to percentile value interpolation if quantization_mode == 'symmetric': assert torch.allclose(quantizer.scale, torch.ones_like(quantizer.scale) * ref_scale, atol=1.0) if per_channel: assert quantizer.scale.numel() == 3 else: assert quantizer.scale.numel() == 1 else: assert torch.allclose(quantizer.input_low, torch.ones_like(quantizer.input_low) * ref_input_low, atol=1.0) assert torch.allclose(quantizer.input_range, torch.ones_like(quantizer.input_low) * ref_input_high, atol=1.0) if per_channel: assert quantizer.input_low.numel() == 3 assert quantizer.input_range.numel() == 3 else: assert quantizer.input_low.numel() == 1 assert quantizer.input_range.numel() == 1 check_scales(act_quantizer_info.quantizer_module_ref, per_channel) # Weight init check synth_weight_model = SingleConv2dSyntheticWeightModel() _, compression_ctrl = create_compressed_model_and_algo_for_test( synth_weight_model, config_with_init) weight_quantizer_info = next( iter(compression_ctrl.weight_quantizers.values())) check_scales(weight_quantizer_info.quantizer_module_ref, per_channel)
def test_percentile_init(quantization_mode): class SyntheticDataset(torch.utils.data.Dataset): def __init__(self): self._length = 1 def __getitem__(self, idx): if idx >= self._length: raise StopIteration test_input_sample = torch.zeros([1, 100, 100]) for i in range(0, 100): for j in range(0, 100): test_input_sample[0][i][j] = i * 100 + j return test_input_sample, test_input_sample def __len__(self): return self._length data_loader = torch.utils.data.DataLoader(SyntheticDataset(), batch_size=1) config_with_init = NNCFConfig() config_with_init.update({ "input_info": { "sample_size": [1, 1, 100, 100] }, "compression": { "algorithm": "quantization", "activations": { "mode": quantization_mode, }, "weights": { "mode": quantization_mode, }, "initializer": { "range": { "num_init_steps": 1, "type": "percentile", "min_percentile": 32.10, "max_percentile": 67.89 } } } }) # Activations init check id_model = SingleConv2dIdentityModel() config_with_init.register_extra_structs( [QuantizationRangeInitArgs(data_loader)]) _, compression_ctrl = create_compressed_model_and_algo_for_test( id_model, config_with_init) act_quantizer = next(iter(compression_ctrl.non_weight_quantizers.values())) def assert_range(quantizer: BaseQuantizer): # Absolute tolerance is 1.0 due to percentile value interpolation if quantization_mode == 'symmetric': assert quantizer.scale.item() == approx(6789, abs=1.0) else: assert quantizer.input_low.item() == approx(3210, abs=1.0) assert quantizer.input_range.item() == approx(3578, abs=1.0) assert_range(act_quantizer) # Weight init check synth_weight_model = SingleConv2dSyntheticWeightModel() _, compression_ctrl = create_compressed_model_and_algo_for_test( synth_weight_model, config_with_init) weight_quantizer = next( iter(compression_ctrl.non_weight_quantizers.values())) assert_range(weight_quantizer)