Ejemplo n.º 1
0
 def wrapped(*args, **kwargs):
     func(*args, **kwargs)
     if len(args) > 0:
         target_ninja_file_path = args[0]
     else:
         target_ninja_file_path = kwargs['path']
     with safe_open(Path(target_ninja_file_path),
                    'r') as ninja_build_file:
         ninja_file_contents = ninja_build_file.read()
     with safe_open(Path(target_ninja_file_path),
                    'w') as ninja_build_file:
         ninja_build_file.write(
             re.sub(
                 r'--generate-dependencies-with-compile --dependency-output \$out\.d',
                 '', ninja_file_contents))
Ejemplo n.º 2
0
    def _dump_episode(self, episodic_info_tuple: Tuple,
                      bit_stats_df: pd.DataFrame, env: 'QuantizationEnv',
                      agent: 'DDPG'):
        if self._dump_autoq_data:
            episode, final_reward, _, accuracy, model_ratio, bop_ratio, _, _, _ = episodic_info_tuple

            current_bitwidth_per_scope = self.get_bitwidth_per_scope(
                env.qctrl.get_quantizer_setup_for_current_state())

            current_episode_nncfcfg = deepcopy(self._init_args.config)
            current_episode_nncfcfg['compression']['initializer']['precision'] = \
                {"bitwidth_per_scope": current_bitwidth_per_scope}

            # Save nncf compression cfg
            episode_cfgfile = '{0}/{1:03d}_nncfcfg.json'.format(
                str(self._init_args.config['episodic_nncfcfg']), episode)

            with safe_open(Path(episode_cfgfile), "w") as outfile:
                json.dump(current_episode_nncfcfg,
                          outfile,
                          indent=4,
                          sort_keys=False)

            self.policy_dict[episode] = env.master_df['action'].astype('int')
            pd.DataFrame(self.policy_dict.values(),
                         index=self.policy_dict.keys()).T.sort_index(
                             axis=1,
                             ascending=False).to_csv(osp.join(
                                 self.dump_dir, "policy_per_episode.csv"),
                                                     index_label="nodestr")

            # log current episode policy and feedback as text
            info_tuple = (episode, final_reward, accuracy, model_ratio,
                          bop_ratio)
            current_strategy_string = self._generate_tensorboard_logging_string(
                bit_stats_df, env.master_df, info_tuple, env.skip_constraint)

            if env.performant_bw is True:
                list_of_dump_dict = []
                for i, _ in enumerate(env.groups_of_adjacent_quantizers):
                    list_of_dump_dict.append(env.master_df.loc[
                        env.adjq_groupwise_df_lut_keys[i],
                        ["action", "action_aligned"]].to_dict())
                current_strategy_string += "\t\n\t# Precision(s) per Group of Adjacent Quantizers\n\t" \
                                            + json.dumps(list_of_dump_dict, indent=4).replace("\n","\n\t") + "\n\n"

            self.tb_writer.add_text('AutoQ/current_policy',
                                    current_strategy_string, episode)

            # visualization over episode
            if self.tb_writer is not None:
                self._add_to_tensorboard(self.tb_writer, episodic_info_tuple)

            if episode % int((self._iter_number + 10) / 10) == 0:
                agent.save_model(self.dump_dir)
Ejemplo n.º 3
0
    def _dump_adjacent_quantizer_group_alignment(self):
        list_of_dump_dict = []
        for i, _ in enumerate(self.groups_of_adjacent_quantizers):
            list_of_dump_dict.append(
                self.master_df.loc[self.adjq_groupwise_df_lut_keys[i],
                                   ["action", "action_aligned"]].to_dict())

        os.makedirs(self.dump_dir / 'bw_alignment', exist_ok=True)
        with safe_open(
                self.dump_dir /
                'bw_alignment/{0:03d}_bw_alignment.json'.format(self._n_eval),
                "w") as DUMP_FH:
            json.dump(list_of_dump_dict, DUMP_FH, indent=4)
Ejemplo n.º 4
0
def create_sample_config(args, parser) -> SampleConfig:
    sample_config = SampleConfig.from_json(args.config)
    sample_config.update_from_args(args, parser)

    file_path = Path(args.config).resolve()
    with safe_open(file_path) as f:
        loaded_json = json.load(f)

    if sample_config.get("target_device") is not None:
        target_device = sample_config.pop("target_device")
        loaded_json["target_device"] = target_device

    nncf_config = NNCFConfig.from_dict(loaded_json)
    sample_config.nncf_config = nncf_config
    return sample_config
Ejemplo n.º 5
0
    def _dump_groups_of_adjacent_quantizers(self):
        adj_quantizer_groups = []

        for i, _ in enumerate(self.groups_of_adjacent_quantizers):
            group_members = []
            for _, aq in enumerate(self.groups_of_adjacent_quantizers[i].
                                   activation_quantizers):
                group_members.append(
                    self.master_df.index[self.master_df.qid == str(aq[0])][0])
            for _, wq in enumerate(
                    self.groups_of_adjacent_quantizers[i].weight_quantizers):
                group_members.append(
                    self.master_df.index[self.master_df.qid == str(wq[0])][0])
            adj_quantizer_groups.append(natsorted(group_members))

        with safe_open(
                self.dump_dir / "{}_groups_of_adjacent_quantizers.json".format(
                    self.model_name), "w") as DUMP_FH:
            json.dump(natsorted(adj_quantizer_groups), DUMP_FH, indent=4)
Ejemplo n.º 6
0
    def apply_init(self) -> SingleConfigQuantizerSetup:
        if not self._weight_quantizations_by_execution_order:
            return self._algo.get_quantizer_setup_for_current_state()

        original_device = next(self._model.parameters()).device
        self._model.to(self._init_device)

        traces_per_layer = self._calc_traces(self._criterion_fn,
                                             self._criterion,
                                             self._iter_number,
                                             self._tolerance)
        if not traces_per_layer:
            raise RuntimeError('Failed to calculate hessian traces!')

        traces_order = traces_per_layer.traces_order
        weight_qconfig_sequences_in_trace_order, covering_qconfig_sequences = \
            self.get_qconfig_sequences_constrained_by_traces_order(traces_order)

        weight_quantizer_ids_in_execution_order = list(
            self._weight_quantizations_by_execution_order.keys())

        if not weight_qconfig_sequences_in_trace_order:
            warnings.warn(
                'All bitwidths configurations are incompatible with HW Config!',
                RuntimeWarning)
            return None

        weight_qconfig_sequences_in_trace_order = \
            self._filter_qconfig_sequences_by_excessive_bitwidth(weight_qconfig_sequences_in_trace_order)

        if self._bitwidth_assignment_mode == BitwidthAssignmentMode.STRICT:
            weight_qconfig_sequences_in_trace_order = \
                self._filter_qconfig_sequences_by_grouped_weight_quantizers(weight_qconfig_sequences_in_trace_order,
                                                                            weight_quantizer_ids_in_execution_order,
                                                                            self._groups_of_adjacent_quantizers,
                                                                            traces_order)
        if not weight_qconfig_sequences_in_trace_order:
            warnings.warn(
                'No bitwidths configurations are left after removing inconsistent groups of weight quantizers'
                ' with adjacent activation quantizers!', RuntimeWarning)
            return self._algo.get_quantizer_setup_for_current_state()

        compression_ratio_per_qconfig = self.get_compression_ratio_per_qconfig_sequence(
            weight_qconfig_sequences_in_trace_order, traces_order)
        min_ratio = min(compression_ratio_per_qconfig)
        max_ratio = max(compression_ratio_per_qconfig)
        if not min_ratio <= self._compression_ratio <= max_ratio:
            raise AttributeError(
                'Invalid compression ratio={}. Should be within range [{:.3f}, {:.3f}]'
                .format(self._compression_ratio, min_ratio, max_ratio))

        perturbations, weight_observers = self.calc_quantization_noise(
            covering_qconfig_sequences, traces_order)

        metric_per_qconfig_sequence = self.calc_hawq_metric_per_qconfig_sequence(
            weight_qconfig_sequences_in_trace_order, perturbations,
            traces_per_layer, self._init_device)

        qconfig_sequence_index = self.choose_qconfig_sequence(
            metric_per_qconfig_sequence, compression_ratio_per_qconfig,
            self._compression_ratio)
        chosen_qconfig_sequence_in_traces_order = weight_qconfig_sequences_in_trace_order[
            qconfig_sequence_index]
        chosen_qconfig_sequence_in_execution_order = traces_order.get_execution_order_configs(
            chosen_qconfig_sequence_in_traces_order)
        bitwidth_sequence = [
            qconfig.num_bits
            for qconfig in chosen_qconfig_sequence_in_execution_order
        ]
        nncf_logger.info(
            'Chosen HAWQ bitwidth sequence with ratio={:.2f}, bitwidth per weightable layer={}'
            .format(compression_ratio_per_qconfig[qconfig_sequence_index],
                    bitwidth_sequence))
        nncf_logger.debug(
            'Order of the weightable layers in the HAWQ bitwidth sequence (in descending order of average'
            ' Hessian traces) ={}'.format(traces_order))

        final_quantizer_setup = self.get_quantizer_setup_for_qconfig_sequence(
            chosen_qconfig_sequence_in_traces_order, traces_order)
        if is_debug() or self._dump_hawq_data:
            hawq_debugger = HAWQDebugger(
                weight_qconfig_sequences_in_trace_order, perturbations,
                weight_observers, traces_per_layer, self._bitwidths)
            hawq_debugger.dump_metric_MB(metric_per_qconfig_sequence)
            hawq_debugger.dump_metric_flops(metric_per_qconfig_sequence,
                                            compression_ratio_per_qconfig,
                                            qconfig_sequence_index)
            hawq_debugger.dump_avg_traces()
            hawq_debugger.dump_density_of_quantization_noise()
            hawq_debugger.dump_perturbations_ratio()
            new_ctrl, new_model = self._algo.apply_new_quantizer_setup(
                final_quantizer_setup)
            groups_of_adjacent_quantizers = new_ctrl.groups_of_adjacent_quantizers
            hawq_debugger.dump_bitwidth_graph(new_ctrl, new_model,
                                              groups_of_adjacent_quantizers)
        bitwidth_per_scope = self.get_bitwidth_per_scope(final_quantizer_setup)
        str_bw = [
            str(element)
            for element in self.get_bitwidth_per_scope(final_quantizer_setup)
        ]
        nncf_logger.info('\n'.join(
            ['\n\"bitwidth_per_scope\": [', ',\n'.join(str_bw), ']']))
        from nncf.common.utils.debug import DEBUG_LOG_DIR
        Path(DEBUG_LOG_DIR).mkdir(parents=True, exist_ok=True)
        with safe_open(Path(DEBUG_LOG_DIR) / 'bitwidth_per_scope.json',
                       "w") as outfile:
            json.dump({'bitwidth_per_scope': bitwidth_per_scope},
                      outfile,
                      indent=4,
                      sort_keys=False)
        self._model.to(original_device)
        return final_quantizer_setup
Ejemplo n.º 7
0
 def from_json(cls, path) -> 'NNCFConfig':
     file_path = Path(path).resolve()
     with safe_open(file_path) as f:
         loaded_json = json.load(f)
     return cls.from_dict(loaded_json)
Ejemplo n.º 8
0
 def from_json(cls, path):
     file_path = Path(path).resolve()
     with safe_open(file_path) as f:
         json_config = json.load(f, object_pairs_hook=OrderedDict)
         return cls.from_dict(json_config)