Example #1
0
def toco_convert_protos(model_flags_str,
                        toco_flags_str,
                        input_data_str,
                        debug_info_str=None,
                        enable_mlir_converter=False):
    """Convert `input_data_str` according to model and toco parameters.

  Unless you know what you are doing consider using
  the more friendly `tf.compat.v1.lite.toco_convert`.

  Args:
    model_flags_str: Serialized proto describing model properties, see
      `toco/model_flags.proto`.
    toco_flags_str: Serialized proto describing conversion properties, see
      `toco/toco_flags.proto`.
    input_data_str: Input data in serialized form (e.g. a graphdef is common)
    debug_info_str: Serialized `GraphDebugInfo` proto describing logging
      information. (default None)
    enable_mlir_converter: Enables MLIR-based conversion instead of the default
      TOCO conversion. (default False)

  Returns:
    Converted model in serialized form (e.g. a TFLITE model is common).
  Raises:
    ConverterError: When conversion fails in TFLiteConverter, usually due to
      ops not being supported.
    RuntimeError: When conversion fails, an exception is raised with the error
      message embedded.
  """
    # Historically, TOCO conversion failures would trigger a crash, so we would
    # attempt to run the converter out-of-process. The MLIR conversion pipeline
    # surfaces errors instead, and can be safely run in-process.
    if enable_mlir_converter or not _toco_from_proto_bin:
        try:
            model_str = wrap_toco.wrapped_toco_convert(model_flags_str,
                                                       toco_flags_str,
                                                       input_data_str,
                                                       debug_info_str,
                                                       enable_mlir_converter)
            return model_str
        except Exception as e:
            converter_error = ConverterError(str(e))
            for error_data in _metrics_wrapper.get_collected_errors():
                converter_error.append_error(error_data)
            raise converter_error

    return _run_toco_binary(model_flags_str, toco_flags_str, input_data_str,
                            debug_info_str)
Example #2
0
def convert(model_flags_str,
            conversion_flags_str,
            input_data_str,
            debug_info_str=None,
            enable_mlir_converter=True):
    """Converts `input_data_str` to a TFLite model.

  Args:
    model_flags_str: Serialized proto describing model properties, see
      `model_flags.proto`.
    conversion_flags_str: Serialized proto describing conversion properties, see
      `toco/toco_flags.proto`.
    input_data_str: Input data in serialized form (e.g. a graphdef is common, or
      it can be hlo text or proto)
    debug_info_str: Serialized `GraphDebugInfo` proto describing logging
      information. (default None)
    enable_mlir_converter: Enables MLIR-based conversion. (default True)

  Returns:
    Converted model in serialized form (e.g. a TFLITE model is common).
  Raises:
    ConverterError: When conversion fails in TFLiteConverter, usually due to
      ops not being supported.
    RuntimeError: When conversion fails, an exception is raised with the error
      message embedded.
  """
    # Historically, deprecated conversion failures would trigger a crash, so we
    # attempt to run the converter out-of-process. The current MLIR conversion
    # pipeline surfaces errors instead, and can be safely run in-process.
    if enable_mlir_converter or not _deprecated_conversion_binary:
        try:
            model_str = wrap_toco.wrapped_toco_convert(model_flags_str,
                                                       conversion_flags_str,
                                                       input_data_str,
                                                       debug_info_str,
                                                       enable_mlir_converter)
            return model_str
        except Exception as e:
            converter_error = ConverterError(str(e))
            for error_data in _metrics_wrapper.retrieve_collected_errors():
                converter_error.append_error(error_data)
            raise converter_error

    return _run_deprecated_conversion_binary(model_flags_str,
                                             conversion_flags_str,
                                             input_data_str, debug_info_str)
Example #3
0
def _run_toco_binary(model_flags_str,
                     toco_flags_str,
                     input_data_str,
                     debug_info_str=None):
    """Convert `input_data_str` using TOCO converter binary.

  Args:
    model_flags_str: Serialized proto describing model properties, see
      `toco/model_flags.proto`.
    toco_flags_str: Serialized proto describing conversion properties, see
      `toco/toco_flags.proto`.
    input_data_str: Input data in serialized form (e.g. a graphdef is common)
    debug_info_str: Serialized `GraphDebugInfo` proto describing logging
      information. (default None)

  Returns:
    Converted model in serialized form (e.g. a TFLITE model is common).
  Raises:
    ConverterError: When cannot find the toco binary.
    RuntimeError: When conversion fails, an exception is raised with the error
      message embedded.
  """
    if distutils.spawn.find_executable(_toco_from_proto_bin) is None:
        raise ConverterError(
            """Could not find toco_from_protos binary, make sure
your virtualenv bin directory or pip local bin directory is in your path.
In particular, if you have installed TensorFlow with --user, make sure you
add the install directory to your path.

For example:
Linux: export PATH=$PATH:~/.local/bin/
Mac: export PATH=$PATH:~/Library/Python/<version#>/bin

Alternative, use virtualenv.""")
    # Windows and TemporaryFile are not that useful together,
    # since you cannot have two readers/writers. So we have to
    # make the temporaries and close and delete them explicitly.
    toco_filename, model_filename, input_filename, output_filename = (None,
                                                                      None,
                                                                      None,
                                                                      None)
    try:
        # Build all input files
        with _tempfile.NamedTemporaryFile(delete=False) as fp_toco, \
                 _tempfile.NamedTemporaryFile(delete=False) as fp_model, \
                 _tempfile.NamedTemporaryFile(delete=False) as fp_input, \
                 _tempfile.NamedTemporaryFile(delete=False) as fp_debug:
            toco_filename = fp_toco.name
            input_filename = fp_input.name
            model_filename = fp_model.name
            debug_filename = fp_debug.name

            fp_model.write(model_flags_str)
            fp_toco.write(toco_flags_str)
            fp_input.write(six.ensure_binary(input_data_str))
            debug_info_str = debug_info_str if debug_info_str else ""
            # if debug_info_str contains a "string value", then the call to
            # fp_debug.write(debug_info_str) will fail with the following error
            #
            # TypeError: a bytes-like object is required, not 'str'
            #
            # Some of the subtests within the "convert_test" unit-test fail
            # with the error shown above. So watch out for that scenario and
            # convert debug_info_str to bytes where needed
            if not isinstance(debug_info_str, bytes):
                fp_debug.write(debug_info_str.encode("utf-8"))
            else:
                fp_debug.write(debug_info_str)

        # Reserve an output file
        with _tempfile.NamedTemporaryFile(delete=False) as fp:
            output_filename = fp.name

        # Run
        cmd = [
            _toco_from_proto_bin,
            model_filename,
            toco_filename,
            input_filename,
            output_filename,
            "--debug_proto_file={}".format(debug_filename),
        ]
        cmdline = " ".join(cmd)
        is_windows = _platform.system() == "Windows"
        proc = _subprocess.Popen(cmdline,
                                 shell=True,
                                 stdout=_subprocess.PIPE,
                                 stderr=_subprocess.STDOUT,
                                 close_fds=not is_windows)
        stdout, stderr = proc.communicate()
        exitcode = proc.returncode
        if exitcode == 0:
            with open(output_filename, "rb") as fp:
                return fp.read()
        else:
            stdout = _try_convert_to_unicode(stdout)
            stderr = _try_convert_to_unicode(stderr)
            raise ConverterError("See console for info.\n%s\n%s\n" %
                                 (stdout, stderr))
    finally:
        # Must manually cleanup files.
        for filename in [
                toco_filename, input_filename, model_filename, output_filename
        ]:
            try:
                _os.unlink(filename)
            except (OSError, TypeError):
                pass