def get_fq_nodes_stats_algo(model, preset, bits, is_weights, clipping_value=None): test_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), './data/reference_scale/test_data') config = _get_pytorch_accuracy_checker_config(test_dir) compression_config = Dict( { 'name': 'MinMaxQuantization', 'stat_subset_size': 1, 'preset': preset, 'target_device': 'CPU', 'activations': { 'bits': bits, 'range_estimator': { 'max': { 'clipping_value': clipping_value } } }, 'weights': { 'bits': bits, 'mode': 'symmetric' if preset == 'performance' else 'asymmetric' } }) engine = ACEngine(config) compression_config.subset_indices = [0] algo = COMPRESSION_ALGORITHMS.get('MinMaxQuantization')(compression_config, engine) model = load_model(model.model_params) stats_collector = StatisticsCollector(engine) algo.register_statistics(model, stats_collector) stats_collector.compute_statistics(model) model = algo.run(model) out = {} for fq in mu.get_nodes_by_type(model, ['FakeQuantize']): fq_inputs = get_node_inputs(fq) if is_weights and fq_inputs[0].type == 'Const': min_weights = np.reshape(fq_inputs[1].value, (fq_inputs[1].value.shape[0])) max_weights = np.reshape(fq_inputs[2].value, (fq_inputs[2].value.shape[0])) out[fq.name] = {'low_level': min_weights, 'high_level': max_weights} elif not is_weights and fq_inputs[0].type != 'Const': if not fq_inputs[1].value.shape: out[fq.name] = {'low_level': fq_inputs[1].value, 'high_level': fq_inputs[2].value} else: min_act = np.reshape(fq_inputs[1].value, (fq_inputs[1].value.shape[1])) max_act = np.reshape(fq_inputs[2].value, (fq_inputs[2].value.shape[1])) out[fq.name] = {'low_level': min_act, 'high_level': max_act} return out
def test_statistics_collector_subsets(tmp_path, models, model_name, model_framework): with open(PATHS2DATASETS_CONFIG.as_posix()) as f: data_source = Dict(json.load(f))['ImageNet2012'].pop('source_dir') engine_config = Dict({ 'type': 'simplified', 'data_source': '{}/{}'.format(data_source, 'ILSVRC2012_val*'), 'device': 'CPU' }) minmax_config = Dict({ 'target_device': 'CPU', 'preset': 'performance', 'stat_subset_size': 1, 'ignored': [] }) bias_correction_config = Dict({ 'target_device': 'CPU', 'preset': 'performance', 'stat_subset_size': 2 }) model = models.get(model_name, model_framework, tmp_path) model = load_model(model.model_params) data_loader = create_data_loader(engine_config, model) engine = create_engine(engine_config, data_loader=data_loader, metric=None) collector = StatisticsCollector(engine) min_max_algo = MinMaxQuantization(minmax_config, engine) min_max_algo.register_statistics(model, collector) bias_correction_algo = BiasCorrection(bias_correction_config, engine) bias_correction_algo.register_statistics(model, collector) collector.compute_statistics(model) out = { 'MinMaxQuantization': collector.get_statistics_for_algorithm('MinMaxQuantization'), 'BiasCorrection': collector.get_statistics_for_algorithm('BiasCorrection') } refs_file = Path( __file__).parent / 'data/test_cases_refs/statistics_data.txt' with open(refs_file.as_posix()) as file: refs = json.loads(json.load(file)) eps = 1e-3 for algo_name, algo_val in out.items(): for node_name, node_val in algo_val.items(): for stats_name, stats_val in node_val.items(): if stats_name == 'batch_mean_param_in': continue ref_stats_vals = refs[algo_name][node_name][stats_name] for ref_vals, vals in zip(ref_stats_vals, stats_val): assert np.max(np.abs(np.array(ref_vals) - vals)) < eps
def create_(tmp_path, models, model_name, model_framework, quantization_mode, algo, preset, granularity, type_max, type_min ): with open(PATHS2DATASETS_CONFIG.as_posix()) as f: data_source = Dict(json.load(f))['ImageNet2012'].pop('source_dir') engine_config = Dict({'type': 'simplified', 'data_source': '{}/{}'.format(data_source, 'ILSVRC2012_val*'), 'device': 'CPU'}) model = models.get(model_name, model_framework, tmp_path) model = load_model(model.model_params) data_loader = create_data_loader(engine_config, model) engine = create_engine(engine_config, data_loader=data_loader, metric=None) collector = StatisticsCollector(engine) algo_config = get_algo_config(quantization_mode, algo, preset, granularity, type_max, type_min) return model, engine, collector, algo_config
def test_statistics_collector_subsets(tmp_path, models, model_name, model_framework): with open(PATHS2DATASETS_CONFIG.as_posix()) as f: data_source = Dict(json.load(f))['ImageNet2012'].pop('source_dir') engine_config = Dict({ 'type': 'simplified', 'data_source': '{}/{}'.format(data_source, 'ILSVRC2012_val*'), 'device': 'CPU' }) minmax_config = Dict({ 'target_device': 'CPU', 'preset': 'performance', 'stat_subset_size': 1, 'ignored': [] }) bias_correction_config = Dict({ 'target_device': 'CPU', 'preset': 'performance', 'stat_subset_size': 2 }) model = models.get(model_name, model_framework, tmp_path) model = load_model(model.model_params) data_loader = create_data_loader(engine_config, model) engine = create_engine(engine_config, data_loader=data_loader, metric=None) collector = StatisticsCollector(engine) min_max_algo = MinMaxQuantization(minmax_config, engine) min_max_algo.register_statistics(model, collector) bias_correction_algo = BiasCorrection(bias_correction_config, engine) bias_correction_algo.register_statistics(model, collector) collector.compute_statistics(model) out = { 'MinMaxQuantization': collector.get_statistics_for_algorithm('MinMaxQuantization'), 'BiasCorrection': collector.get_statistics_for_algorithm('BiasCorrection') } refs_file = Path( __file__ ).parent / 'data/test_cases_refs' / f'{model_name}_statistics_data.json' local_path = os.path.join( tmp_path, '{}_{}.json'.format(model_name, 'statistics_data')) local_file = open(local_path, 'w') with open(refs_file.as_posix()) as file: refs = json.load(file) eps = 1e-3 local_out = {} for algo_name, algo_val in out.items(): local_out[algo_name] = {} for node_name, node_val in algo_val.items(): if isinstance(node_name, tuple): name = f'{node_name[0]}.{node_name[1]}' else: name = node_name local_out[algo_name][name] = {} for stats_name, stats_val in node_val.items(): local_out[algo_name][name][stats_name] = [ np.array(v).tolist() for v in stats_val ] json.dump(local_out, local_file) for algo_name, algo_val in out.items(): for node_name, node_val in algo_val.items(): for stats_name, stats_val in node_val.items(): if stats_name in ['batch_mean_param_in', 'shape']: continue if isinstance(node_name, tuple): node_name = f'{node_name[0]}.{node_name[1]}' ref_stats_vals = refs[algo_name][node_name][stats_name] for ref_vals, vals in zip(ref_stats_vals, stats_val): assert np.max(np.abs(np.array(ref_vals) - vals)) < eps
def test_fake_quantize_configurations(tmp_path, models, model_name, model_framework, algo_mode): test_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), './data/reference_scale/test_data') config = _get_pytorch_accuracy_checker_config(test_dir) \ if model_framework == 'pytorch' else _get_tf_accuracy_checker_config(test_dir) if algo_mode == 'symmetric': activations_mode, weights_mode, level_low = 'symmetric', 'symmetric', -127 elif algo_mode == 'asymmetric': activations_mode, weights_mode, level_low = 'asymmetric', 'asymmetric', -128 else: activations_mode, weights_mode, level_low = 'asymmetric', 'symmetric', -127 compression_config = Dict({ 'name': 'MinMaxQuantization', 'stat_subset_size': 1, 'preset': 'performance', 'target_device': 'CPU', 'activations': { 'bits': 8, 'mode': activations_mode }, 'weights': { 'bits': 8, 'mode': weights_mode, 'granularity': 'perchannel', 'level_low': level_low, 'level_high': 127 } }) def _make_list(x): if isinstance(x, np.ndarray): x = x.tolist() if isinstance(x, list): return x return [x] engine = ACEngine(config) compression_config.subset_indices = [0] algo = COMPRESSION_ALGORITHMS.get('MinMaxQuantization')(compression_config, engine) model = models.get(model_name, model_framework, tmp_path) model = load_model(model.model_params) stats_collector = StatisticsCollector(engine) algo.register_statistics(model, stats_collector) stats_collector.compute_statistics(model) model = algo.run(model) refs_path = os.path.join(REFERENCES_DIR, '{}_{}.json'.format(model_name, algo_mode)) local_path = os.path.join(tmp_path, '{}.json'.format(model_name)) ref_exists = os.path.isfile(refs_path) refs = load_refs(refs_path) if ref_exists else {} ref_file = None if ref_exists else open(refs_path, 'w') local_file = open(local_path, 'w') model_values = {} eps = 1e-3 fq_list = mu.get_nodes_by_type(model, ['FakeQuantize']) for fq in sorted(fq_list, key=lambda item: item.name): min_levels, max_levels = tuple( [get_node_value(node) for node in get_node_inputs(fq)[1:3]]) fq_name = fq.name if get_node_input(fq, 0).type == 'Const': min_levels = min_levels.reshape(min_levels.shape[0]) max_levels = max_levels.reshape(max_levels.shape[0]) else: if not min_levels.shape and not max_levels.shape: pass else: min_levels = min_levels.reshape(min_levels.shape[1]) max_levels = max_levels.reshape(max_levels.shape[1]) min_levels = _make_list(min_levels) max_levels = _make_list(max_levels) model_values[fq_name] = {'max': max_levels, 'min': min_levels} if not ref_exists: json.dump(model_values, ref_file) return json.dump(model_values, local_file) for ref_name in refs: refs_min_levels = _make_list(refs[ref_name]['min']) refs_max_levels = _make_list(refs[ref_name]['max']) min_levels = model_values[ref_name]['min'] max_levels = model_values[ref_name]['max'] for min_level, max_level, ref_min, ref_max in zip( min_levels, max_levels, refs_min_levels, refs_max_levels): assert abs(min_level - ref_min) < eps assert abs(max_level - ref_max) < eps