Ejemplo n.º 1
0
 def _convertSavedModel(self,
                        saved_model_dir,
                        input_arrays=None,
                        input_shapes=None,
                        output_arrays=None,
                        tag_set=None,
                        signature_key=None):
     if tag_set is None:
         tag_set = set([tag_constants.SERVING])
     if signature_key is None:
         signature_key = signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY
     graph_def, in_tensors, out_tensors = convert_saved_model.freeze_saved_model(
         saved_model_dir=saved_model_dir,
         input_arrays=input_arrays,
         input_shapes=input_shapes,
         output_arrays=output_arrays,
         tag_set=tag_set,
         signature_key=signature_key)
     return graph_def, in_tensors, out_tensors
 def _convertSavedModel(self,
                        saved_model_dir,
                        input_arrays=None,
                        input_shapes=None,
                        output_arrays=None,
                        tag_set=None,
                        signature_key=None):
   if tag_set is None:
     tag_set = set([tag_constants.SERVING])
   if signature_key is None:
     signature_key = signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY
   graph_def, in_tensors, out_tensors = convert_saved_model.freeze_saved_model(
       saved_model_dir=saved_model_dir,
       input_arrays=input_arrays,
       input_shapes=input_shapes,
       output_arrays=output_arrays,
       tag_set=tag_set,
       signature_key=signature_key)
   return graph_def, in_tensors, out_tensors
Ejemplo n.º 3
0
def mlir_convert(
    options,
    saved_model_dir,
    input_tensors,
    output_tensors,  # pylint: disable=unused-argument
    **kwargs):
  """Convert a saved model into a tflite model with MLIR-based conversion.

  Args:
    options: A lite.testing.generate_examples_lib.Options instance.
    saved_model_dir: Path to the saved model.
    input_tensors: List of input tensor tuples `(name, shape, type)`.
    output_tensors: List of output tensors (names).
    **kwargs: Extra parameters.

  Returns:
    output tflite model, log_txt from conversion
    or None, log_txt if it did not convert properly.
  """
  test_params = kwargs.get("test_params", {})
  # TODO(b/146025965): Rename ExtraTocoOptions to ExtraConvertOptions or
  #                    something else.
  extra_toco_options = kwargs.get("extra_toco_options",
                                  zip_test_utils.ExtraTocoOptions())
  tflite_model = None
  log = ""

  with tempfile.NamedTemporaryFile() as graphdef_file:
    signature_key = signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY
    converter = tf.lite.TFLiteConverter.from_saved_model(
        saved_model_dir, [signature_key])
    if extra_toco_options.convert_from_graphdef:
      saved_model_tags = set([tag_constants.SERVING])
      input_arrays = [x[0] for x in input_tensors]
      input_shapes = zip_test_utils.get_input_shapes_map(input_tensors)
      result = freeze_saved_model(saved_model_dir, input_arrays, input_shapes,
                                  output_tensors, saved_model_tags,
                                  signature_key)
      graph_def = result[0]
      graphdef_file.write(graph_def.SerializeToString())
      graphdef_file.flush()
      converter = tf.compat.v1.lite.TFLiteConverter.from_frozen_graph(
          graphdef_file.name, input_arrays, output_tensors, input_shapes)

    converter.allow_custom_ops = extra_toco_options.allow_custom_ops
    converter.experimental_new_quantizer = options.mlir_quantizer

    if options.run_with_flex:
      converter.supported_ops = set(
          [tf.lite.OpsSet.TFLITE_BUILTINS, tf.lite.OpsSet.SELECT_TF_OPS])

    if test_params.get("dynamic_range_quantize", False):
      converter.optimizations = [tf.lite.Optimize.DEFAULT]

    if test_params.get("fully_quantize", False):
      converter.optimizations = [tf.lite.Optimize.DEFAULT]

      # Read the input range for the representative dataset from parameters.
      min_value, max_value = test_params.get("input_range", (-1, 1))

      def representative_dataset(input_tensors):
        calibration_inputs = {}
        for name, shape, dtype in input_tensors:
          if shape:
            dims = [1 if dim.value is None else dim.value for dim in shape.dims]
            calibration_inputs[name] = np.random.uniform(
                min_value, max_value, tuple(dims)).astype(dtype.as_numpy_dtype)
        return calibration_inputs

      def representative_dataset_gen():
        for _ in range(100):
          yield representative_dataset(input_tensors)

      if test_params.get("quant_16x8", False):
        converter.target_spec.supported_ops = [
            tf.lite.OpsSet
            .EXPERIMENTAL_TFLITE_BUILTINS_ACTIVATIONS_INT16_WEIGHTS_INT8
        ]
      else:
        converter.target_spec.supported_ops = [
            tf.lite.OpsSet.TFLITE_BUILTINS_INT8
        ]

      converter.representative_dataset = representative_dataset_gen
      if extra_toco_options.inference_input_type:
        converter.inference_input_type = (
            extra_toco_options.inference_input_type)

      if extra_toco_options.inference_output_type:
        converter.inference_output_type = (
            extra_toco_options.inference_output_type)

    try:
      tflite_model = converter.convert()
      if options.expected_ops_in_converted_model:
        ops_list = tflite_test_util.get_ops_list(tflite_model)
        for expected_op in options.expected_ops_in_converted_model:
          if expected_op not in ops_list:
            # Force the test to fail.
            tflite_model = None
            raise ValueError(
                "{} op not found in the converted model".format(expected_op))
    except Exception as e:  # pylint: disable=broad-except
      log = str(e)

  return tflite_model, log
Ejemplo n.º 4
0
def toco_convert(options, saved_model_dir, input_tensors, output_tensors,
                 **kwargs):
    """Convert a saved model into a tflite model.

  NOTE: this currently shells out to the toco binary, but we would like
  convert to Python API tooling in the future.

  Args:
    options: An Options instance.
    saved_model_dir: Path to the saved model.
    input_tensors: List of input tensor tuples `(name, shape, type)`.
    output_tensors: List of output tensors (names).
    **kwargs: Extra options to be passed.

  Returns:
    output tflite model, log_txt from conversion
    or None, log_txt if it did not convert properly.
  """
    extra_toco_options = kwargs.get("extra_toco_options",
                                    zip_test_utils.ExtraTocoOptions())
    test_params = kwargs.get("test_params", {})
    input_arrays = [x[0] for x in input_tensors]
    input_shapes = zip_test_utils.get_input_shapes_map(input_tensors)
    data_types = [zip_test_utils.TF_TYPE_INFO[x[2]][1] for x in input_tensors]

    fully_quantize = test_params.get("fully_quantize", False)
    dynamic_range_quantize = test_params.get("dynamic_range_quantize", False)

    if dynamic_range_quantize or fully_quantize:
        converter = tf.lite.TFLiteConverter.from_saved_model(
            saved_model_dir, input_arrays, input_shapes, output_tensors)
        converter.experimental_new_quantizer = options.mlir_quantizer
        converter.optimizations = [tf.lite.Optimize.DEFAULT]

        if fully_quantize:
            # Read the input range for the representative dataset from parameters.
            min_value, max_value = test_params.get("input_range", (-1, 1))

            def representative_dataset(input_tensors):
                calibration_inputs = []
                for _, shape, dtype in input_tensors:
                    if shape:
                        dims = [dim.value for dim in shape.dims]
                        calibration_inputs.append(
                            np.random.uniform(min_value, max_value,
                                              tuple(dims)).astype(
                                                  dtype.as_numpy_dtype))
                return calibration_inputs

            def representative_dataset_gen():
                for _ in range(100):
                    yield representative_dataset(input_tensors)

            if test_params.get("quant_16x8", False):
                converter.target_spec.supported_ops = [
                    tf.lite.OpsSet.
                    EXPERIMENTAL_TFLITE_BUILTINS_ACTIVATIONS_INT16_WEIGHTS_INT8
                ]
            else:
                converter.target_spec.supported_ops = [
                    tf.lite.OpsSet.TFLITE_BUILTINS_INT8
                ]

            converter.representative_dataset = representative_dataset_gen
            if extra_toco_options.inference_input_type:
                converter.inference_input_type = (
                    extra_toco_options.inference_input_type)
            if extra_toco_options.inference_output_type:
                converter.inference_output_type = (
                    extra_toco_options.inference_output_type)
            else:
                if test_params.get("quant_16x8", False):
                    converter.inference_output_type = tf.int16
                else:
                    converter.inference_output_type = tf.int8

        try:
            tflite_model = converter.convert()
            return tflite_model, ""
        except Exception as e:
            log = "{0}\n{1}".format(str(e), traceback.format_exc())
            return None, log

    else:
        opts = toco_options(data_types=data_types,
                            input_arrays=input_arrays,
                            shapes=[x[1] for x in input_tensors],
                            output_arrays=output_tensors,
                            extra_toco_options=extra_toco_options)

        # Convert saved model to GraphDef.
        saved_model_tags = set([tf.saved_model.tag_constants.SERVING])
        signature_keys = signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY
        graph_def, _, _, _ = freeze_saved_model(saved_model_dir, input_arrays,
                                                input_shapes, output_tensors,
                                                saved_model_tags,
                                                signature_keys)
        # Convert ophint ops if presented.
        graph_def = tf.compat.v1.lite.experimental.convert_op_hints_to_stubs(
            graph_def=graph_def)
        graph_def_str = graph_def.SerializeToString()

        with tempfile.NamedTemporaryFile() as graphdef_file, \
             tempfile.NamedTemporaryFile() as output_file, \
             tempfile.NamedTemporaryFile("w+") as stdout_file:
            graphdef_file.write(graph_def_str)
            graphdef_file.flush()

            if options.run_with_flex:
                opts += " --enable_select_tf_ops --force_select_tf_ops"
            cmd = ("%s --input_file=%s --output_file=%s %s > %s 2>&1" %
                   (options.toco, graphdef_file.name, output_file.name, opts,
                    stdout_file.name))
            exit_code = os.system(cmd)
            log = (cmd + "exited with code %d" % exit_code +
                   "\n------------------\n" + stdout_file.read())
            return (None if exit_code != 0 else output_file.read()), log