chore: import upstream snapshot with attribution
cffconvert / validate (push) Has been skipped
License Check / license-check (push) Failing after 2s

This commit is contained in:
wehub-resource-sync
2026-07-13 12:14:16 +08:00
commit 8a852e4b4e
36502 changed files with 9277225 additions and 0 deletions
@@ -0,0 +1,77 @@
load("@xla//third_party/rules_python/python:py_binary.bzl", "py_binary")
load("@xla//third_party/rules_python/python:py_library.bzl", "py_library")
load("//tensorflow:tensorflow.bzl", "py_test")
load("//tensorflow:tensorflow.default.bzl", "pybind_extension")
package(
# copybara:uncomment default_applicable_licenses = ["//tensorflow:LICENSE"],
default_visibility = [
"//visibility:public",
],
licenses = ["notice"],
)
py_binary(
name = "modify_model_interface",
srcs = ["modify_model_interface.py"],
strict_deps = True,
deps = [
":modify_model_interface_constants",
":modify_model_interface_lib",
"@absl_py//absl:app",
"@absl_py//absl/flags",
],
)
py_library(
name = "modify_model_interface_lib",
srcs = ["modify_model_interface_lib.py"],
strict_deps = True,
deps = [
":_pywrap_modify_model_interface",
":modify_model_interface_constants",
"//tensorflow/lite/python:schema_py",
],
)
# Use --config=disable_tf_lite_py when running this test under github.
py_test(
name = "modify_model_interface_lib_test",
srcs = ["modify_model_interface_lib_test.py"],
strict_deps = True,
deps = [
":modify_model_interface_lib",
#internal proto upb dep
"//third_party/py/numpy",
"//tensorflow:tensorflow_py",
"//tensorflow/lite/python:lite",
"//tensorflow/python/framework:test_lib",
"//tensorflow/python/platform:client_testlib",
],
)
py_library(
name = "modify_model_interface_constants",
srcs = ["modify_model_interface_constants.py"],
strict_deps = True,
deps = ["//tensorflow/python/framework:dtypes"],
)
pybind_extension(
name = "_pywrap_modify_model_interface",
srcs = ["modify_model_interface.cc"],
common_lib_packages = [
"litert/python",
"tensorflow/lite/python",
],
enable_stub_generation = True,
pytype_srcs = [
"_pywrap_modify_model_interface.pyi",
],
wrap_py_init = True,
deps = [
"//tensorflow/lite/schema:schema_fbs",
"//tensorflow/lite/tools/optimize:modify_model_interface",
"@pybind11",
],
)
@@ -0,0 +1,16 @@
# Copyright 2023 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
def modify_model_interface(arg0: str, arg1: str, arg2: int, arg3: int) -> int: ...
@@ -0,0 +1,40 @@
/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
// Python wrapper to modify model interface.
#include "tensorflow/lite/tools/optimize/modify_model_interface.h"
#include <string>
#include "pybind11/pybind11.h" // from @pybind11
#include "tensorflow/lite/schema/schema_generated.h"
namespace pybind11 {
PYBIND11_MODULE(_pywrap_modify_model_interface, m) {
// An anonymous function that invokes the C++ function
// after applying transformations to the python function arguments
m.def("modify_model_interface",
[](const std::string& input_file, const std::string& output_file,
const int input_type, const int output_type) -> int {
return tflite::optimize::ModifyModelInterface(
input_file, output_file,
static_cast<tflite::TensorType>(input_type),
static_cast<tflite::TensorType>(output_type));
});
}
} // namespace pybind11
@@ -0,0 +1,54 @@
# Copyright 2020 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
r"""Modify a quantized model's interface from float to integer."""
from absl import app
from absl import flags
from tensorflow.lite.tools.optimize.python import modify_model_interface_constants as mmi_constants
from tensorflow.lite.tools.optimize.python import modify_model_interface_lib as mmi_lib
FLAGS = flags.FLAGS
flags.DEFINE_string('input_tflite_file', None,
'Full path name to the input TFLite file.')
flags.DEFINE_string('output_tflite_file', None,
'Full path name to the output TFLite file.')
flags.DEFINE_enum('input_type', mmi_constants.DEFAULT_STR_TYPE,
mmi_constants.STR_TYPES,
'Modified input integer interface type.')
flags.DEFINE_enum('output_type', mmi_constants.DEFAULT_STR_TYPE,
mmi_constants.STR_TYPES,
'Modified output integer interface type.')
flags.mark_flag_as_required('input_tflite_file')
flags.mark_flag_as_required('output_tflite_file')
def main(_):
input_type = mmi_constants.STR_TO_TFLITE_TYPES[FLAGS.input_type]
output_type = mmi_constants.STR_TO_TFLITE_TYPES[FLAGS.output_type]
mmi_lib.modify_model_interface(FLAGS.input_tflite_file,
FLAGS.output_tflite_file, input_type,
output_type)
print('Successfully modified the model input type from FLOAT to '
'{input_type} and output type from FLOAT to {output_type}.'.format(
input_type=FLAGS.input_type, output_type=FLAGS.output_type))
if __name__ == '__main__':
app.run(main)
@@ -0,0 +1,30 @@
# Copyright 2020 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Constants for modify_model_interface."""
from tensorflow.python.framework import dtypes
STR_TO_TFLITE_TYPES = {
'INT8': dtypes.int8,
'UINT8': dtypes.uint8,
'INT16': dtypes.int16,
}
TFLITE_TO_STR_TYPES = {v: k for k, v in STR_TO_TFLITE_TYPES.items()}
STR_TYPES = STR_TO_TFLITE_TYPES.keys()
TFLITE_TYPES = STR_TO_TFLITE_TYPES.values()
DEFAULT_STR_TYPE = 'INT8'
DEFAULT_TFLITE_TYPE = STR_TO_TFLITE_TYPES[DEFAULT_STR_TYPE]
@@ -0,0 +1,74 @@
# Copyright 2020 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Library to modify a quantized model's interface from float to integer."""
from tensorflow.lite.python import schema_py_generated as schema_fb
from tensorflow.lite.tools.optimize.python import _pywrap_modify_model_interface
from tensorflow.lite.tools.optimize.python import modify_model_interface_constants as mmi_constants
def _parse_type_to_int(dtype, flag):
"""Converts a tflite type to it's integer representation.
Args:
dtype: tf.DType representing the inference type.
flag: str representing the flag name.
Returns:
integer, a tflite TensorType enum value.
Raises:
ValueError: Unsupported tflite type.
"""
# Validate if dtype is supported in tflite and is a valid interface type.
if dtype not in mmi_constants.TFLITE_TYPES:
raise ValueError(
"Unsupported value '{0}' for {1}. Only {2} are supported.".format(
dtype, flag, mmi_constants.TFLITE_TYPES))
dtype_str = mmi_constants.TFLITE_TO_STR_TYPES[dtype]
dtype_int = schema_fb.TensorType.__dict__[dtype_str]
return dtype_int
def modify_model_interface(input_file, output_file, input_type, output_type):
"""Modify a quantized model's interface (input/output) from float to integer.
Args:
input_file: Full path name to the input tflite file.
output_file: Full path name to the output tflite file.
input_type: Final input interface type.
output_type: Final output interface type.
Raises:
RuntimeError: If the modification of the model interface was unsuccessful.
ValueError: If the input_type or output_type is unsupported.
"""
# Map the interface types to integer values
input_type_int = _parse_type_to_int(input_type, 'input_type')
output_type_int = _parse_type_to_int(output_type, 'output_type')
# Invoke the function to modify the model interface
status = _pywrap_modify_model_interface.modify_model_interface(
input_file, output_file, input_type_int, output_type_int)
# Throw an exception if the return status is an error.
if status != 0:
raise RuntimeError(
'Error occurred when trying to modify the model input type from float '
'to {input_type} and output type from float to {output_type}.'.format(
input_type=input_type, output_type=output_type))
@@ -0,0 +1,163 @@
# Copyright 2020 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Tests for modify_model_interface_lib.py."""
import os
import numpy as np
import tensorflow as tf
from tensorflow.lite.python import lite
from tensorflow.lite.tools.optimize.python import modify_model_interface_lib
from tensorflow.python.framework import test_util
from tensorflow.python.platform import test
def build_tflite_model_with_full_integer_quantization(
supported_ops=lite.OpsSet.TFLITE_BUILTINS_INT8):
# Define TF model
input_size = 3
model = tf.keras.Sequential([
tf.keras.layers.InputLayer(input_shape=(input_size,), dtype=tf.float32),
tf.keras.layers.Dense(units=5, activation=tf.nn.relu),
tf.keras.layers.Dense(units=2, activation=tf.nn.softmax)
])
# Convert TF Model to a Quantized TFLite Model
converter = lite.TFLiteConverterV2.from_keras_model(model)
converter.optimizations = [lite.Optimize.DEFAULT]
def representative_dataset_gen():
for i in range(10):
yield [np.array([i] * input_size, dtype=np.float32)]
converter.representative_dataset = representative_dataset_gen
converter.target_spec.supported_ops = [supported_ops]
tflite_model = converter.convert()
return tflite_model
class ModifyModelInterfaceTest(test_util.TensorFlowTestCase):
def testInt8Interface(self):
# 1. SETUP
# Define the temporary directory and files
temp_dir = self.get_temp_dir()
initial_file = os.path.join(temp_dir, 'initial_model.tflite')
final_file = os.path.join(temp_dir, 'final_model.tflite')
# Define initial model
initial_model = build_tflite_model_with_full_integer_quantization()
with open(initial_file, 'wb') as model_file:
model_file.write(initial_model)
# 2. INVOKE
# Invoke the modify_model_interface function
modify_model_interface_lib.modify_model_interface(initial_file, final_file,
tf.int8, tf.int8)
# 3. VALIDATE
# Load TFLite model and allocate tensors.
initial_interpreter = lite.Interpreter(model_path=initial_file)
initial_interpreter.allocate_tensors()
final_interpreter = lite.Interpreter(model_path=final_file)
final_interpreter.allocate_tensors()
# Get input and output types.
initial_input_dtype = initial_interpreter.get_input_details()[0]['dtype']
initial_output_dtype = initial_interpreter.get_output_details()[0]['dtype']
final_input_dtype = final_interpreter.get_input_details()[0]['dtype']
final_output_dtype = final_interpreter.get_output_details()[0]['dtype']
# Validate the model interfaces
self.assertEqual(initial_input_dtype, np.float32)
self.assertEqual(initial_output_dtype, np.float32)
self.assertEqual(final_input_dtype, np.int8)
self.assertEqual(final_output_dtype, np.int8)
def testInt16Interface(self):
# 1. SETUP
# Define the temporary directory and files
temp_dir = self.get_temp_dir()
initial_file = os.path.join(temp_dir, 'initial_model.tflite')
final_file = os.path.join(temp_dir, 'final_model.tflite')
# Define initial model
initial_model = build_tflite_model_with_full_integer_quantization(
supported_ops=lite.OpsSet
.EXPERIMENTAL_TFLITE_BUILTINS_ACTIVATIONS_INT16_WEIGHTS_INT8)
with open(initial_file, 'wb') as model_file:
model_file.write(initial_model)
# 2. INVOKE
# Invoke the modify_model_interface function
modify_model_interface_lib.modify_model_interface(initial_file, final_file,
tf.int16, tf.int16)
# 3. VALIDATE
# Load TFLite model and allocate tensors.
initial_interpreter = lite.Interpreter(model_path=initial_file)
initial_interpreter.allocate_tensors()
final_interpreter = lite.Interpreter(model_path=final_file)
final_interpreter.allocate_tensors()
# Get input and output types.
initial_input_dtype = initial_interpreter.get_input_details()[0]['dtype']
initial_output_dtype = initial_interpreter.get_output_details()[0]['dtype']
final_input_dtype = final_interpreter.get_input_details()[0]['dtype']
final_output_dtype = final_interpreter.get_output_details()[0]['dtype']
# Validate the model interfaces
self.assertEqual(initial_input_dtype, np.float32)
self.assertEqual(initial_output_dtype, np.float32)
self.assertEqual(final_input_dtype, np.int16)
self.assertEqual(final_output_dtype, np.int16)
def testUInt8Interface(self):
# 1. SETUP
# Define the temporary directory and files
temp_dir = self.get_temp_dir()
initial_file = os.path.join(temp_dir, 'initial_model.tflite')
final_file = os.path.join(temp_dir, 'final_model.tflite')
# Define initial model
initial_model = build_tflite_model_with_full_integer_quantization()
with open(initial_file, 'wb') as model_file:
model_file.write(initial_model)
# 2. INVOKE
# Invoke the modify_model_interface function
modify_model_interface_lib.modify_model_interface(initial_file, final_file,
tf.uint8, tf.uint8)
# 3. VALIDATE
# Load TFLite model and allocate tensors.
initial_interpreter = lite.Interpreter(model_path=initial_file)
initial_interpreter.allocate_tensors()
final_interpreter = lite.Interpreter(model_path=final_file)
final_interpreter.allocate_tensors()
# Get input and output types.
initial_input_dtype = initial_interpreter.get_input_details()[0]['dtype']
initial_output_dtype = initial_interpreter.get_output_details()[0]['dtype']
final_input_dtype = final_interpreter.get_input_details()[0]['dtype']
final_output_dtype = final_interpreter.get_output_details()[0]['dtype']
# Validate the model interfaces
self.assertEqual(initial_input_dtype, np.float32)
self.assertEqual(initial_output_dtype, np.float32)
self.assertEqual(final_input_dtype, np.uint8)
self.assertEqual(final_output_dtype, np.uint8)
if __name__ == '__main__':
test.main()