From fa0fb0d4f66ffb8ec3df287a51287e9acf20a776 Mon Sep 17 00:00:00 2001 From: Jian Li Date: Thu, 14 Nov 2019 14:16:04 -0800 Subject: [PATCH] Add utility functions for integration. This supports the calibration case that the model is initialized multiple times. (1) quatization_wrapper is the external interface to help calibration and quantization. The interface is string and bool so the dependencies are minimal. It has two functions: - CreateCalibrationModel copies a model to a new location and adds intermediate tensors if any of the op need that. - CreateQuantizedModel quantizes a model in place. (2) quatization wrapper_utils is the helper function for quatization_wrapper - added function to load model - added function to write model PiperOrigin-RevId: 280510873 Change-Id: I58891d6e8d6d3b485242f321466ac91ce2fdffda --- tensorflow/lite/tools/optimize/BUILD | 26 +++++++--- .../tools/optimize/quantization_wrapper.cc | 52 +++++++++++++++++++ .../tools/optimize/quantization_wrapper.h | 39 ++++++++++++++ ...nsors.cc => quantization_wrapper_utils.cc} | 26 +++++++++- ...tensors.h => quantization_wrapper_utils.h} | 15 ++++-- ....cc => quantization_wrapper_utils_test.cc} | 2 +- 6 files changed, 148 insertions(+), 12 deletions(-) create mode 100644 tensorflow/lite/tools/optimize/quantization_wrapper.cc create mode 100644 tensorflow/lite/tools/optimize/quantization_wrapper.h rename tensorflow/lite/tools/optimize/{add_intermediate_tensors.cc => quantization_wrapper_utils.cc} (80%) rename tensorflow/lite/tools/optimize/{add_intermediate_tensors.h => quantization_wrapper_utils.h} (69%) rename tensorflow/lite/tools/optimize/{add_intermediate_tensors_test.cc => quantization_wrapper_utils_test.cc} (98%) diff --git a/tensorflow/lite/tools/optimize/BUILD b/tensorflow/lite/tools/optimize/BUILD index 1f57c5c9d80..5548567c2c7 100644 --- a/tensorflow/lite/tools/optimize/BUILD +++ b/tensorflow/lite/tools/optimize/BUILD @@ -13,9 +13,9 @@ exports_files(glob([ ])) cc_library( - name = "add_intermediate_tensors", - srcs = ["add_intermediate_tensors.cc"], - hdrs = ["add_intermediate_tensors.h"], + name = "quantization_wrapper_utils", + srcs = ["quantization_wrapper_utils.cc"], + hdrs = ["quantization_wrapper_utils.h"], deps = [ ":operator_property", "//tensorflow/lite:framework", @@ -26,14 +26,14 @@ cc_library( ) tf_cc_test( - name = "add_intermediate_tensors_test", - srcs = ["add_intermediate_tensors_test.cc"], + name = "quantization_wrapper_utils_test", + srcs = ["quantization_wrapper_utils_test.cc"], tags = [ "tflite_not_portable_android", "tflite_not_portable_ios", ], deps = [ - ":add_intermediate_tensors", + ":quantization_wrapper_utils", "//tensorflow/lite:framework", "//tensorflow/lite/schema:schema_fbs", "@com_google_absl//absl/memory", @@ -42,6 +42,20 @@ tf_cc_test( ], ) +cc_library( + name = "quantization_wrapper", + srcs = ["quantization_wrapper.cc"], + hdrs = ["quantization_wrapper.h"], + deps = [ + ":quantization_wrapper_utils", + "//tensorflow/lite:framework", + "//tensorflow/lite/core/api", + "//tensorflow/lite/schema:schema_fbs", + "//tensorflow/lite/tools/optimize:quantize_model", + "@flatbuffers", + ], +) + cc_library( name = "quantization_utils", srcs = ["quantization_utils.cc"], diff --git a/tensorflow/lite/tools/optimize/quantization_wrapper.cc b/tensorflow/lite/tools/optimize/quantization_wrapper.cc new file mode 100644 index 00000000000..bd3331da6bf --- /dev/null +++ b/tensorflow/lite/tools/optimize/quantization_wrapper.cc @@ -0,0 +1,52 @@ +/* Copyright 2019 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. +==============================================================================*/ +#include "tensorflow/lite/tools/optimize/quantization_wrapper.h" + +#include "tensorflow/lite/tools/optimize/quantization_wrapper_utils.h" +#include "tensorflow/lite/tools/optimize/quantize_model.h" + +namespace tflite { +namespace optimize { + +bool CreateModelForCalibration(const std::string& input_path, + const std::string& output_path) { + ModelT model; + if (LoadModel(input_path, &model) != kTfLiteOk) { + return false; + } + flatbuffers::FlatBufferBuilder builder; + if (AddIntemediateTensorsToFusedOp(&builder, &model) != kTfLiteOk) { + return false; + } + return WriteFile(output_path, builder.GetBufferPointer(), builder.GetSize()); +} + +bool CreateQuantizedModel(const std::string& path) { + ModelT model; + if (LoadModel(path, &model) != kTfLiteOk) { + return false; + } + flatbuffers::FlatBufferBuilder builder; + tflite::StderrReporter error_reporter; + if (tflite::optimize::QuantizeModel( + &builder, &model, tflite::TensorType_FLOAT32, + tflite::TensorType_FLOAT32, &error_reporter) != kTfLiteOk) { + return false; + } + return WriteFile(path, builder.GetBufferPointer(), builder.GetSize()); +} + +} // namespace optimize +} // namespace tflite diff --git a/tensorflow/lite/tools/optimize/quantization_wrapper.h b/tensorflow/lite/tools/optimize/quantization_wrapper.h new file mode 100644 index 00000000000..125bad3e257 --- /dev/null +++ b/tensorflow/lite/tools/optimize/quantization_wrapper.h @@ -0,0 +1,39 @@ +/* Copyright 2019 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. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_TOOLS_OPTIMIZE_QUANTIZATION_WRAPPER_H_ +#define TENSORFLOW_LITE_TOOLS_OPTIMIZE_QUANTIZATION_WRAPPER_H_ + +#include + +namespace tflite { +namespace optimize { + +// Makes an copy of the model at input_path and writes it to output_path, adding +// tensors to the model needed for calibration. +// Returns true if it is successful. +// Example: a/b/c.tflite becomes a/b/c.calibrated.tflite and has +// intermediate tensors added according to operator properties. +bool CreateModelForCalibration(const std::string& input_path, + const std::string& output_path); + +// Quantize a model in place. This function is only to be called after calling +// CreateModelForCalibration and running calibration over data. +// Returns true if it is successful. +bool CreateQuantizedModel(const std::string& path); + +} // namespace optimize +} // namespace tflite + +#endif // TENSORFLOW_LITE_TOOLS_OPTIMIZE_QUANTIZATION_WRAPPER_H_ diff --git a/tensorflow/lite/tools/optimize/add_intermediate_tensors.cc b/tensorflow/lite/tools/optimize/quantization_wrapper_utils.cc similarity index 80% rename from tensorflow/lite/tools/optimize/add_intermediate_tensors.cc rename to tensorflow/lite/tools/optimize/quantization_wrapper_utils.cc index ddf906401d9..b8ed852d14b 100644 --- a/tensorflow/lite/tools/optimize/add_intermediate_tensors.cc +++ b/tensorflow/lite/tools/optimize/quantization_wrapper_utils.cc @@ -12,10 +12,12 @@ 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. ==============================================================================*/ -#include "tensorflow/lite/tools/optimize/add_intermediate_tensors.h" +#include "tensorflow/lite/tools/optimize/quantization_wrapper_utils.h" +#include #include +#include "tensorflow/lite/schema/schema_generated.h" #include "tensorflow/lite/tools/optimize/operator_property.h" namespace tflite { @@ -51,6 +53,19 @@ bool IntermediateTensorExists(ModelT* model) { } } // namespace +TfLiteStatus LoadModel(const string& path, ModelT* model) { + auto input_model = FlatBufferModel::BuildFromFile(path.c_str()); + if (!input_model) { + return kTfLiteError; + } + auto readonly_model = input_model->GetModel(); + if (!readonly_model) { + return kTfLiteError; + } + readonly_model->UnPackTo(model); + return kTfLiteOk; +} + TfLiteStatus AddIntemediateTensorsToFusedOp( flatbuffers::FlatBufferBuilder* builder, ModelT* model) { // Return early if the model already has intermediate tensors. @@ -90,5 +105,14 @@ TfLiteStatus AddIntemediateTensorsToFusedOp( return kTfLiteOk; } +bool WriteFile(const std::string& out_file, const uint8_t* bytes, + size_t num_bytes) { + std::fstream stream(out_file, std::ios::binary | std::ios::out); + for (size_t i = 0; i < num_bytes; i++) { + stream << bytes[i]; + } + return (!stream.bad() && !stream.fail()); +} + } // namespace optimize } // namespace tflite diff --git a/tensorflow/lite/tools/optimize/add_intermediate_tensors.h b/tensorflow/lite/tools/optimize/quantization_wrapper_utils.h similarity index 69% rename from tensorflow/lite/tools/optimize/add_intermediate_tensors.h rename to tensorflow/lite/tools/optimize/quantization_wrapper_utils.h index 6786b88723c..744b0dfc0ac 100644 --- a/tensorflow/lite/tools/optimize/add_intermediate_tensors.h +++ b/tensorflow/lite/tools/optimize/quantization_wrapper_utils.h @@ -12,8 +12,8 @@ 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. ==============================================================================*/ -#ifndef TENSORFLOW_LITE_TOOLS_OPTIMIZE_ADD_INTERMEDIATE_TENSORS_H_ -#define TENSORFLOW_LITE_TOOLS_OPTIMIZE_ADD_INTERMEDIATE_TENSORS_H_ +#ifndef TENSORFLOW_LITE_TOOLS_OPTIMIZE_QUANTIZATION_WRAPPER_UTILS_H_ +#define TENSORFLOW_LITE_TOOLS_OPTIMIZE_QUANTIZATION_WRAPPER_UTILS_H_ #include "tensorflow/lite/core/api/error_reporter.h" #include "tensorflow/lite/model.h" @@ -22,13 +22,20 @@ limitations under the License. namespace tflite { namespace optimize { +// Load a tflite model from path. +TfLiteStatus LoadModel(const string& path, ModelT* model); + // Going through the model and add intermediates tensors if the ops have any. // Returns early if the model has already intermediate tensors. This is to // support cases where a model is initialized multiple times. TfLiteStatus AddIntemediateTensorsToFusedOp( - flatbuffers::FlatBufferBuilder* builder, ModelT* input_model); + flatbuffers::FlatBufferBuilder* builder, ModelT* model); + +// Write model to a given location. +bool WriteFile(const std::string& out_file, const uint8_t* bytes, + size_t num_bytes); } // namespace optimize } // namespace tflite -#endif // TENSORFLOW_LITE_TOOLS_OPTIMIZE_ADD_INTERMEDIATE_TENSORS_H_ +#endif // TENSORFLOW_LITE_TOOLS_OPTIMIZE_QUANTIZATION_WRAPPER_UTILS_H_ diff --git a/tensorflow/lite/tools/optimize/add_intermediate_tensors_test.cc b/tensorflow/lite/tools/optimize/quantization_wrapper_utils_test.cc similarity index 98% rename from tensorflow/lite/tools/optimize/add_intermediate_tensors_test.cc rename to tensorflow/lite/tools/optimize/quantization_wrapper_utils_test.cc index 76d476712e3..704a71106a8 100644 --- a/tensorflow/lite/tools/optimize/add_intermediate_tensors_test.cc +++ b/tensorflow/lite/tools/optimize/quantization_wrapper_utils_test.cc @@ -12,7 +12,7 @@ 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. ==============================================================================*/ -#include "tensorflow/lite/tools/optimize/add_intermediate_tensors.h" +#include "tensorflow/lite/tools/optimize/quantization_wrapper_utils.h" #include #include