Skip to content

Commit

Permalink
TFLite failures resulted from TF latest version upgrade resolved (apa…
Browse files Browse the repository at this point in the history
…che#6774)

* TFLite failures resulted from TF latest version upgrade resolved

* [1] Review comments handled
  • Loading branch information
ANSHUMAN TRIPATHY authored and Trevor Morris committed Dec 2, 2020
1 parent 6e1681e commit 8afd2de
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 59 deletions.
6 changes: 3 additions & 3 deletions docker/install/ubuntu_install_tflite.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,22 @@ pip3 install flatbuffers
# Build the TFLite static library, necessary for building with TFLite ON.
# The library is built at:
# tensorflow/tensorflow/lite/tools/make/gen/*/lib/libtensorflow-lite.a.
git clone https://github.com/tensorflow/tensorflow --branch=r2.1
git clone https://github.com/tensorflow/tensorflow --branch=r2.3
./tensorflow/tensorflow/lite/tools/make/download_dependencies.sh
./tensorflow/tensorflow/lite/tools/make/build_lib.sh

# Setup tflite from schema
mkdir tflite
cd tflite
wget -q https://raw.githubusercontent.com/tensorflow/tensorflow/r2.1/tensorflow/lite/schema/schema.fbs
wget -q https://raw.githubusercontent.com/tensorflow/tensorflow/r2.3/tensorflow/lite/schema/schema.fbs
flatc --python schema.fbs

cat <<EOM >setup.py
import setuptools
setuptools.setup(
name="tflite",
version="2.1.0",
version="2.3.1",
author="google",
author_email="google@google.com",
description="TFLite",
Expand Down
15 changes: 14 additions & 1 deletion python/tvm/relay/frontend/tflite.py
Original file line number Diff line number Diff line change
Expand Up @@ -2770,7 +2770,7 @@ def convert_transpose_conv(self, op):
raise ImportError("The tflite package must be installed")

input_tensors = self.get_input_tensors(op)
assert len(input_tensors) == 3, "input tensors length should be 3"
assert len(input_tensors) >= 3, "input tensors length should be >= 3"

# Input (data) Tensor. NHWC layout
input_tensor = input_tensors[2]
Expand Down Expand Up @@ -2843,6 +2843,19 @@ def convert_transpose_conv(self, op):
out_dtype=output_tensor_type_str,
)

# if we have bias
if len(input_tensors) == 4:
bias_tensor = input_tensors[3]
bias_tensor_type = bias_tensor.tensor.Type()
# bias tensor type should be INT32 (quantization) or FLOAT32
assert bias_tensor_type in (TensorType.INT32, TensorType.FLOAT32)
bias_tensor_type_str = self.get_tensor_type_str(bias_tensor_type)
bias_expr = self.exp_tab.new_const(
self.get_tensor_value(bias_tensor), dtype=bias_tensor_type_str
)
channel_axis = 3
out = _op.nn.bias_add(out, bias_expr, axis=channel_axis)

return out

def convert_quantize(self, op):
Expand Down
115 changes: 60 additions & 55 deletions tests/python/frontend/tflite/test_forward.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,20 @@ def vmobj_to_list(o):
raise RuntimeError("Unknown object type: %s" % type(o))


def _quantize_keras_model(keras_model, representative_data_gen):
def _quantize_keras_model(
keras_model, representative_data_gen, is_float_input=False, is_float_output=False
):
"""Utility function to quantize a Keras model using TFLite converter."""
converter = interpreter_wrapper.TFLiteConverter.from_keras_model(keras_model)
converter.optimizations = [tf.lite.Optimize.OPTIMIZE_FOR_SIZE]
converter.representative_dataset = representative_data_gen
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
converter.inference_input_type = tf.uint8
converter.inference_output_type = tf.uint8
# NOTE: If representative dataset is provided, and inference input type is not set,
# then converter will self add quant & dequant Op accordingly.
if not is_float_input:
converter.inference_input_type = tf.uint8
if not is_float_output:
converter.inference_output_type = tf.uint8
return converter.convert()


Expand Down Expand Up @@ -973,6 +979,7 @@ def _test_convolution(
[out],
quantized=quantized,
input_range=input_range,
experimental_new_converter=True,
)
else:
# Quantized the inputs and feed them to the convolution
Expand Down Expand Up @@ -1000,6 +1007,7 @@ def _test_convolution(
[out],
quantized=quantized,
input_range=input_range,
experimental_new_converter=True,
)
else:
data_array = np.reshape(data_array, tensor_in_sizes).astype("float32")
Expand Down Expand Up @@ -1078,18 +1086,18 @@ def test_forward_convolution():
)

# TFLite2 quantized convolution testing
if package_version.parse(tf.VERSION) >= package_version.parse("2.1.0"):
_test_tflite2_quantized_convolution(
[1, 8, 8, 176], [1, 1, 176, 32], [1, 1], [1, 1], "SAME", "NHWC"
if package_version.parse(tf.VERSION) >= package_version.parse("2.3.0"):
_test_convolution(
[1, 8, 8, 176], [1, 1, 176, 32], [1, 1], [1, 1], "SAME", "NHWC", quantized=True
)
_test_tflite2_quantized_convolution(
[1, 17, 17, 12], [3, 3, 12, 32], [1, 1], [2, 2], "VALID", "NHWC"
_test_convolution(
[1, 17, 17, 12], [3, 3, 12, 32], [1, 1], [2, 2], "VALID", "NHWC", quantized=True
)
_test_tflite2_quantized_convolution(
[1, 17, 17, 19], [3, 3, 19, 19], [1, 1], [2, 2], "VALID", "NHWC"
_test_convolution(
[1, 17, 17, 19], [3, 3, 19, 19], [1, 1], [2, 2], "VALID", "NHWC", quantized=True
)
_test_tflite2_quantized_convolution(
[1, 17, 17, 124], [1, 1, 124, 19], [1, 1], [1, 1], "SAME", "NHWC"
_test_convolution(
[1, 17, 17, 124], [1, 1, 124, 19], [1, 1], [1, 1], "SAME", "NHWC", quantized=True
)

# Disable as tests are flaky - https://github.com/apache/incubator-tvm/issues/6064
Expand Down Expand Up @@ -2280,7 +2288,7 @@ def representative_data_gen():
for i in range(1):
yield [data]

tflite_model_quant = _quantize_keras_model(keras_model, representative_data_gen)
tflite_model_quant = _quantize_keras_model(keras_model, representative_data_gen, True, True)

tflite_output = run_tflite_graph(tflite_model_quant, data)
tvm_output = run_tvm_graph(tflite_model_quant, data, input_name)
Expand All @@ -2307,7 +2315,7 @@ def representative_data_gen():
for i in range(1):
yield [data]

tflite_model_quant = _quantize_keras_model(keras_model, representative_data_gen)
tflite_model_quant = _quantize_keras_model(keras_model, representative_data_gen, True, True)

tflite_output = run_tflite_graph(tflite_model_quant, data)
tvm_output = run_tvm_graph(tflite_model_quant, data, input_name)
Expand Down Expand Up @@ -2548,14 +2556,17 @@ def test_forward_padv2():
np.array([2], dtype=np.float32),
]
)
_test_padv2(
[
np.arange(0, 256, dtype=np.uint8).reshape((1, 256)),
np.array([[1, 1], [2, 2]], dtype=np.int32),
np.array([2], dtype=np.uint8),
],
quantized=True,
)
# NOTE: In versions > 2.1.0, there is a bug in Tensorflow package for this scenario.
# Hence, it is disabled temporarily for TF version > 2.1.0 .
if package_version.parse(tf.VERSION) <= package_version.parse("2.1.0"):
_test_padv2(
[
np.arange(0, 256, dtype=np.uint8).reshape((1, 256)),
np.array([[1, 1], [2, 2]], dtype=np.int32),
np.array([2], dtype=np.float32),
],
quantized=True,
)

# Constant Values input can be scalar
_test_padv2(
Expand All @@ -2565,14 +2576,17 @@ def test_forward_padv2():
np.float32(2),
]
)
_test_padv2(
[
np.arange(0, 256, dtype=np.uint8).reshape((1, 256)),
np.array([[1, 1], [2, 2]], dtype=np.int32),
np.uint8(10),
],
quantized=True,
)
# NOTE: In versions > 2.1.0, there is a bug in Tensorflow package for this scenario.
# Hence, it is disabled temporarily for TF versions > 2.1.0.
if package_version.parse(tf.VERSION) <= package_version.parse("2.1.0"):
_test_padv2(
[
np.arange(0, 256, dtype=np.uint8).reshape((1, 256)),
np.array([[1, 1], [2, 2]], dtype=np.int32),
np.uint8(10),
],
quantized=True,
)


#######################################################################
Expand Down Expand Up @@ -2870,37 +2884,28 @@ def test_forward_tanh():
def _test_relu(data, quantized=False):
""" One iteration of ReLU """

if quantized:
if package_version.parse(tf.VERSION) < package_version.parse("2.1.0"):
pytest.skip("Testcase requires tflite version >= 2.1.0")
data_in = tf.keras.layers.Input(shape=data.shape[1:])
relu = tf.keras.layers.ReLU()(data_in)
keras_model = tf.keras.models.Model(inputs=data_in, outputs=relu)
input_name = data_in.name.split(":")[0]

# To create quantized values with dynamic range of activations, needs representative dataset
def representative_data_gen():
for i in range(1):
yield [data]

tflite_model_quant = _quantize_keras_model(keras_model, representative_data_gen)

tflite_output = run_tflite_graph(tflite_model_quant, data)
tvm_output = run_tvm_graph(tflite_model_quant, data, input_name)
tvm.testing.assert_allclose(
np.squeeze(tvm_output[0]), np.squeeze(tflite_output[0]), rtol=1e-5, atol=1e-5
)
else:
with tf.Graph().as_default():
in_data = array_ops.placeholder(shape=data.shape, dtype=data.dtype)
with tf.Graph().as_default():
in_data = array_ops.placeholder(shape=data.shape, dtype="float32", name="in_0")

if quantized:
inq_data = tf.quantization.fake_quant_with_min_max_args(
in_data, min=-10, max=10, name="inq_0"
)
input_range = {"inq_0": (-10, 10)}
out = nn_ops.relu(inq_data)
out = tf.quantization.fake_quant_with_min_max_args(out, min=0, max=6, name="out")
compare_tflite_with_tvm(
data, "inq_0:0", [inq_data], [out], quantized=True, input_range=input_range
)
else:
out = nn_ops.relu(in_data)
compare_tflite_with_tvm(data, "Placeholder:0", [in_data], [out])
compare_tflite_with_tvm(data, "in_0:0", [in_data], [out])


def test_forward_relu():
""" ReLU """
_test_relu(np.arange(6.0, dtype=np.float32).reshape((1, 6)))
_test_relu(np.arange(6.0, dtype=np.float32).reshape((1, 6)), quantized=True)
_test_relu(np.random.uniform(0, 255, (3, 6)).astype(np.uint8), quantized=True)


#######################################################################
Expand Down

0 comments on commit 8afd2de

Please sign in to comment.