Example #1
0
    def apply(self, model, layer_quantize_map, quantize_registry, mode):
        """Implement vitis 8-bit transforms.

    Currently this means the following.
      1. Pull activations into layers, and apply fuse activations. (TODO)
      2. Modify range in incoming layers for Concat. (TODO)
      3. Fuse Conv2D/DepthwiseConv2D + BN into single layer.

    Args:
      model: Keras model to be quantized.
      layer_quantize_map: Map with keys as layer names, and values as dicts
        containing custom `QuantizeConfig`s which may have been passed with
        layers.
      quantize_registry: QuantizeRegistry object containing the quantize configs
        for each layer.
      mode: String object indicating the mode of the quantized model.

    Returns:
      (Transformed Keras model to better match TensorFlow Lite backend, updated
      layer quantize map.)
    """

        transforms = [
            vitis_8bit_quantize_transforms.InputLayerQuantize(
                quantize_registry.get_input_quantizer(), mode),
            vitis_8bit_quantize_transforms.ConvActivationQuantize(),
            vitis_8bit_quantize_transforms.AddActivationQuantize(),
        ]
        return model_transformer.ModelTransformer(
            model, transforms, set(layer_quantize_map.keys()),
            layer_quantize_map).transform()
Example #2
0
    def apply(self, model, layer_quantize_map, remove_dropout, fold_conv_bn,
              fold_bn, replace_relu6, include_cle, cle_steps):
        """Implement vitis 8-bit transforms.

    All the transforms should not break the float model structure, and
    the output of the transformed model should be consistant with the float 
    model.
    """

        transforms = []
        if remove_dropout:
            transforms.append(vitis_optimize_transforms.RemoveDropout())

        if fold_conv_bn:
            transforms.append(vitis_optimize_transforms.Conv2DBatchNormFold())

        if fold_bn:
            transforms.append(vitis_optimize_transforms.BatchNormFold())

        if replace_relu6:
            transforms.append(vitis_optimize_transforms.ReplaceReLU6WithReLU())

        transformed_model, layer_quantize_map = model_transformer.ModelTransformer(
            model, transforms, None, layer_quantize_map).transform()

        # Cross Layer Equalization
        if include_cle:
            cle_transforms = [
                vitis_optimize_transforms.ConvConvCLE(),
                vitis_optimize_transforms.ConvActConvCLE(),
            ]
            progbar = keras.utils.Progbar(cle_steps)
            print('[INFO] Start CrossLayerEqualization...')
            for i in range(cle_steps):
                progbar.update(i + 1)
                tmp_model, tmp_layer_quantize_map = transformed_model, layer_quantize_map
                transformed_model, layer_quantize_map = model_transformer.ModelTransformer(
                    tmp_model, cle_transforms, None,
                    tmp_layer_quantize_map).transform()
            print('[INFO] CrossLayerEqualization Done.')
        return transformed_model, layer_quantize_map
def _apply_availables(model, configs, available_transforms, candidate_layers,
                      layer_metadata):
  transforms = []
  for key in available_transforms:
    if configs.get(key):
      new_trans = available_transforms.get(key)
      if isinstance(new_trans, list):
        transforms.extend(new_trans)
      else:
        transforms.append(new_trans)

  transformed_model, layer_metadata = model_transformer.ModelTransformer(
      model, transforms, candidate_layers,
      layer_metadata).recursive_transform()
  return transformed_model, layer_metadata
Example #4
0
def convert_quantize_strategy(model, conversion='tqt_to_pof2s'):
    allowed_conversions = ['tqt_to_pof2s']
    if not conversion in allowed_conversions:
        logger.error(
            'Invalid conversion {}, allowed conversions are: {}.'.format(
                conversion, allowed_conversions))

    if conversion == 'tqt_to_pof2s':
        transforms = [
            vitis_tqt_refine_transforms.ConvertTQTToPof2SQuantizeStrategy()
        ]
        transformed_model, _ = model_transformer.ModelTransformer(
            model, transforms, None, None).recursive_transform()
        return transformed_model

    return model
  def apply(self, model, candidate_layers, layer_metadata):
    """Implement vitis 8-bit optimize transforms to make it more quantize-friendly.

    All the transforms should not break the float model structure, and
    the output of the transformed model should be consistant with the float 
    model.
    """
    configs = self.get_configs()

    available_transforms = collections.OrderedDict({
        'remove_dropout':
            vitis_optimize_transforms.RemoveDropout(),
        'separate_conv_act':
            vitis_optimize_transforms.SeparateConvAct(),
        'convert_relu6_to_relu':
            vitis_optimize_transforms.ConvertReLU6ToReLU(),
        'convert_tf_op_to_keras':
            vitis_optimize_transforms.ConvertTFOpToKeras(),
    })

    transformed_model, layer_metadata = _apply_availables(
        model, configs, available_transforms, candidate_layers, layer_metadata)

    # Train with bn is conflict with fold bn params
    model = transformed_model
    if configs['train_with_bn']:
      transforms = [
          vitis_optimize_transforms.FakeConvBNFold(),
      ]
      transformed_model, _ = model_transformer.ModelTransformer(
          model, transforms, None, None).recursive_transform()
    else:
      available_transforms = {
          'fold_conv_bn': vitis_optimize_transforms.ConvBNFold(),
          'convert_bn_to_dwconv': vitis_optimize_transforms.ConvertBNToDWConv(),
      }
      transformed_model, layer_metadata = _apply_availables(
          model, configs, available_transforms, candidate_layers,
          layer_metadata)

    # Cross Layer Equalization
    if configs['include_cle']:
      cle_to_relu6 = configs['cle_to_relu6']
      cle_balance_method = configs['cle_balance_method']
      cle_weight_threshold = configs['cle_weight_threshold']
      cle_transforms = [
          vitis_equalization_transforms.ConvConvCLE(cle_to_relu6,
                                                    cle_balance_method,
                                                    cle_weight_threshold),
          vitis_equalization_transforms.ConvActConvCLE(cle_to_relu6,
                                                       cle_balance_method,
                                                       cle_weight_threshold),
          vitis_equalization_transforms.ConvReLUConvCLE(cle_to_relu6,
                                                        cle_balance_method,
                                                        cle_weight_threshold),
          vitis_equalization_transforms.ConvReLUPadConvCLE(
              cle_to_relu6, cle_balance_method, cle_weight_threshold)
      ]

      cle_steps = configs['cle_steps']
      progbar = keras.utils.Progbar(cle_steps)
      logger.info('Start CrossLayerEqualization...')
      for i in range(cle_steps):
        progbar.update(i + 1)
        tmp_model = transformed_model
        transformed_model, layer_metadata = model_transformer.ModelTransformer(
            tmp_model, cle_transforms, candidate_layers,
            layer_metadata).recursive_transform()
      logger.info('CrossLayerEqualization Done.')

    if logger.debug_enabled():
      model_utils.save_model(transformed_model, 'optimized_model.h5',
                             './debug/')
    return transformed_model, layer_metadata
  def apply(self, model, candidate_layers, layer_metadata, quantize_registry,
            mode):
    """Implement vitis 8-bit quantize transforms.

    Args:
      model: Keras model to be quantized.
      quantize_registry: QuantizeRegistry object containing the quantize configs
        for each layer.
      mode: String object indicating the mode of the quantized model.

    Returns:
      (Quantized Keras model.)
    """
    configs = self.get_configs()

    available_pre_annotate_transforms = collections.OrderedDict({})

    pre_annotated_model, layer_metadata = _apply_availables(
        model, configs, available_pre_annotate_transforms, candidate_layers,
        layer_metadata)

    if logger.debug_enabled():
      model_utils.save_model(pre_annotated_model, 'pre_annotated_model.h5',
                             './debug/')

    available_annotate_transforms = collections.OrderedDict({
        'no_quant_in_conv_bn_act':
            vitis_fs_quantize_transforms.NoQuantInConvBNAct(),
        'no_quant_in_conv_act':
            vitis_fs_quantize_transforms.NoQuantInConvAct(
                pre_annotated_model, quantize_registry),
        'no_quant_in_add_act':
            vitis_fs_quantize_transforms.NoQuantInAddAct(
                pre_annotated_model, quantize_registry),
    })
    annotated_model, layer_metadata = _apply_availables(
        pre_annotated_model, configs, available_annotate_transforms,
        candidate_layers, layer_metadata)

    if logger.debug_enabled():
      model_utils.save_model(annotated_model, 'annotated_model.h5', './debug/')

    freeze_bn_delay = configs['freeze_bn_delay']
    if freeze_bn_delay < 0:
      freeze_bn_delay = None
    quantize_transforms = [
        vitis_fs_quantize_transforms.InputLayerQuantize(quantize_registry,
                                                        mode),
        vitis_fs_quantize_transforms.ConvBNQuantize(quantize_registry, mode,
                                                    freeze_bn_delay),
        vitis_fs_quantize_transforms.LayersQuantize(annotated_model,
                                                    quantize_registry, mode),
    ]
    quantized_model, layer_metadata = model_transformer.ModelTransformer(
        annotated_model, quantize_transforms, candidate_layers,
        layer_metadata).recursive_transform()

    input_quantize_transforms = [
        vitis_fs_quantize_transforms.LayersInputQuantize(
            quantized_model, quantize_registry, mode)
    ]
    quantized_model, layer_metadata = model_transformer.ModelTransformer(
        quantized_model, input_quantize_transforms, candidate_layers,
        layer_metadata).recursive_transform()
    return quantized_model, layer_metadata
    def apply(self, quantized_model, candidate_layers, layer_metadata,
              optimized_model, dataset, batch_size, steps, add_shape_info,
              input_shape):
        """Implement vitis 8-bit float scale refine transforms.

    Args:
      qunantized_model: the quantized model to be refined.
      optimized_model: the optimized float model used in fast finetune to generate fake label.
      dataset: the dataset used in fast finetune.
      batch_size: the batch size of dataset used in fast finetune.
      steps: the steps of dataste used in fast finetune.
      add_shape_info: bool, whether to add shape information to the refined model. Must be set True
        for models with custom layers.
      input_shape: the shape of the model inputs, if not set, the default shape in the model inputs
        will be used.

    Returns:
      (Refined quantized model.)
    """
        refined_model = quantized_model
        configs = self.get_configs()

        # Convert TQTQuantizer to Pof2SQuantizer
        if configs['convert_to_pof2s_quantize_strategy']:
            logger.info("Start Converting To Pof2S Quantize Strategy...")
            transforms = [
                vitis_tqt_refine_transforms.ConvertTQTToPof2SQuantizeStrategy(
                )
            ]
            refined_model, _ = model_transformer.ModelTransformer(
                refined_model, transforms, None, None).recursive_transform()
            logger.info("Converting To Pof2S Quantize Strategy Done.")

            # Adjust quantize positions only when convert_to_pof2s_quantize_strategy is True
            logger.info("Start Quantize Position Ajustment...")
            adjust_vs = configs['adjust_dpu_sigmoid']
            adjust_sc = configs['adjust_dpu_shift_cut']
            adjust_sb = configs['adjust_dpu_shift_bias']
            adjust_sr = configs['adjust_dpu_shift_read']
            quantize_info = model_utils.get_quantize_info(refined_model)
            adjusted_quantize_info = vitis_pof2s_refine_transforms.adjust_quantize_info(
                refined_model, quantize_info, adjust_vs, adjust_sc, adjust_sb,
                adjust_sr)
            model_utils.set_quantize_info(refined_model,
                                          adjusted_quantize_info)
            logger.info("Quantize Position Ajustment Done.")

        # Fast finetune
        include_fast_ft = configs['include_fast_ft']
        fast_ft_epochs = configs['fast_ft_epochs']
        if include_fast_ft:
            logger.info("Start Fast Finetuning...")
            vitis_fast_finetune.fast_finetune(refined_model, optimized_model,
                                              dataset, batch_size, steps,
                                              fast_ft_epochs)
            logger.info("Fast Finetuning Done.")

        #  # Bias correction
        #  include_bias_corr = configs['quantize_pipeline_config'][
        #      'include_bias_corr']
        #  if include_bias_corr:
        #    logger.info("Start Bias Correction...")
        #    vitis_bias_correction.bias_correction(self._qcbev_model,
        #                                          self._optimized_model,
        #                                          calib_dataset, calib_batch_size,
        #                                          calib_steps)
        #    logger.info("Bias Correction Done.")

        if add_shape_info:
            logger.info("Start Getting Shape Information...")
            shape_info = model_utils.get_shape(model=refined_model,
                                               calib_dataset=dataset,
                                               input_shape=input_shape)
            if logger.debug_enabled():
                model_utils.save_shape_info(shape_info, './debug/')
                model_utils.save_model(refined_model,
                                       'calibrated_model_add_shape.h5',
                                       './debug/')
            logger.info("Getting Shape Information Done.")

        return refined_model, layer_metadata
    def apply(self, model, candidate_layers, layer_metadata, quantize_registry,
              mode):
        """Implement vitis 8-bit quantize transforms.

    Args:
      model: Keras model to be quantized.
      quantize_registry: QuantizeRegistry object containing the quantize configs
        for each layer.
      mode: String object indicating the mode of the quantized model.

    Returns:
      (Quantized Keras model.)
    """
        configs = self.get_configs()

        available_pre_annotate_transforms = collections.OrderedDict({
            'convert_sigmoid_to_hard_sigmoid': [
                vitis_pof2s_quantize_transforms.ConvertConvSigmoid(),
                vitis_pof2s_quantize_transforms.ConvertActivationSigmoid(),
                vitis_pof2s_quantize_transforms.ConvertConvSwish(),
                vitis_pof2s_quantize_transforms.ConvertActivationSwish(),
            ],
            'convert_hard_sigmoid_to_dpu_version': [
                vitis_pof2s_quantize_transforms.ConvertHardSigmoidToDpuVersion(
                ),
            ],
            'convert_average_pooling2d_to_dpu_version': [
                vitis_pof2s_quantize_transforms.
                ConvertAveragePooling2DToDpuVersion(),
                vitis_pof2s_quantize_transforms.
                ConvertGlobalAveragePooling2DToDpuVersion(),
            ],
            'convert_leaky_relu_to_dpu_version': [
                vitis_pof2s_quantize_transforms.ConvertLeakyReLUToDpuVersion(),
            ],
        })

        pre_annotated_model, layer_metadata = _apply_availables(
            model, configs, available_pre_annotate_transforms,
            candidate_layers, layer_metadata)

        if logger.debug_enabled():
            model_utils.save_model(pre_annotated_model,
                                   'pre_annotated_model.h5', './debug/')

        annotate_transforms = [
            vitis_pof2s_quantize_transforms.AnnotateConvBNAct(),
            vitis_pof2s_quantize_transforms.AnnotateConvAct(
                pre_annotated_model, quantize_registry),
            vitis_pof2s_quantize_transforms.AnnotateAddAct(
                pre_annotated_model, quantize_registry),
            vitis_pof2s_quantize_transforms.AnnotatePoolAct(
                pre_annotated_model, quantize_registry),
        ]
        annotated_model, layer_metadata = model_transformer.ModelTransformer(
            pre_annotated_model, annotate_transforms, candidate_layers,
            layer_metadata).recursive_transform()

        if logger.debug_enabled():
            model_utils.save_model(annotated_model, 'annotated_model.h5',
                                   './debug/')

        quantize_transforms = [
            vitis_pof2s_quantize_transforms.InputLayerQuantize(
                quantize_registry, mode),
            vitis_pof2s_quantize_transforms.ConvBNQuantize(
                quantize_registry, mode, configs['freeze_bn_delay']),
            vitis_pof2s_quantize_transforms.LayersQuantize(
                annotated_model, quantize_registry, mode),
            vitis_pof2s_quantize_transforms.LayersInputQuantize(
                quantize_registry, mode),
            vitis_pof2s_quantize_transforms.CustomLayerWrapper(
                quantize_registry),
        ]
        quantized_model, layer_metadata = model_transformer.ModelTransformer(
            annotated_model, quantize_transforms, candidate_layers,
            layer_metadata).recursive_transform()
        return quantized_model, layer_metadata
Example #9
0
def replace_hard_sigmoid(model):
    transforms = [vitis_pof2s_quantize_transforms.ReplaceHardSigmoid()]
    transformed_model, _ = model_transformer.ModelTransformer(
        model, transforms, None, None).recursive_transform()
    return transformed_model
Example #10
0
def conv_bn_quantize_fold(model):
    transforms = [vitis_pof2s_quantize_transforms.ConvBNQuantizeFold()]
    transformed_model, _ = model_transformer.ModelTransformer(
        model, transforms, None, None).recursive_transform()
    return transformed_model
Example #11
0
def real_conv_bn_fold(model):
    transforms = [vitis_optimize_transforms.RealConvBNFold()]
    transformed_model, _ = model_transformer.ModelTransformer(
        model, transforms, None, None).recursive_transform()
    return transformed_model
Example #12
0
def separate_conv_act(model):
    transforms = [vitis_optimize_transforms.SeparateConvAct()]
    transformed_model, _ = model_transformer.ModelTransformer(
        model, transforms, None, None).recursive_transform()
    return transformed_model
Example #13
0
def remove_layer(model, class_name, name='.*'):
    """Remove given layer from the model."""
    transforms = [vitis_optimize_transforms.RemoveLayer(class_name, name)]
    transformed_model, _ = model_transformer.ModelTransformer(
        model, transforms, None, None).recursive_transform()
    return transformed_model