From bd0c9fdec3b20b009e00de53429c12f8b2200adb Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Fri, 9 Jan 2026 07:53:36 -0800 Subject: [PATCH 1/2] Added UINT4 support --- python/tflite_micro/numpy_utils.cc | 3 +++ tensorflow/compiler/mlir/lite/core/c/tflite_types.h | 1 + tensorflow/compiler/mlir/lite/schema/schema.fbs | 1 + tensorflow/lite/core/api/flatbuffer_conversions.cc | 3 +++ tensorflow/lite/core/c/common.cc | 2 ++ tensorflow/lite/micro/tools/layer_by_layer.cc | 3 +++ .../lite/micro/tools/layer_by_layer_schema.fbs | 1 + .../micro/tools/layer_by_layer_schema_generated.h | 13 ++++++++----- tensorflow/lite/schema/schema_generated.h | 13 ++++++++----- 9 files changed, 30 insertions(+), 10 deletions(-) diff --git a/python/tflite_micro/numpy_utils.cc b/python/tflite_micro/numpy_utils.cc index fb728a18a1e..718fdf8ae19 100644 --- a/python/tflite_micro/numpy_utils.cc +++ b/python/tflite_micro/numpy_utils.cc @@ -55,6 +55,9 @@ int TfLiteTypeToPyArrayType(TfLiteType tf_lite_type) { return NPY_INT16; case kTfLiteUInt8: return NPY_UINT8; + case kTfLiteUInt4: + // TODO(b/246806634): NPY_UINT4 currently doesn't exist + return NPY_BYTE; case kTfLiteInt4: // TODO(b/246806634): NPY_INT4 currently doesn't exist return NPY_BYTE; diff --git a/tensorflow/compiler/mlir/lite/core/c/tflite_types.h b/tensorflow/compiler/mlir/lite/core/c/tflite_types.h index f09923dda5f..c14cb5d2e81 100644 --- a/tensorflow/compiler/mlir/lite/core/c/tflite_types.h +++ b/tensorflow/compiler/mlir/lite/core/c/tflite_types.h @@ -65,6 +65,7 @@ typedef enum { kTfLiteInt4 = 18, kTfLiteBFloat16 = 19, kTfLiteInt2 = 20, + kTfLiteUInt4 = 21, } TfLiteType; // LINT.ThenChange(//tensorflow/lite/profiling/proto/model_runtime_info.proto:EdgeDataType) diff --git a/tensorflow/compiler/mlir/lite/schema/schema.fbs b/tensorflow/compiler/mlir/lite/schema/schema.fbs index 1d5d6b1c95e..76d92df99f9 100644 --- a/tensorflow/compiler/mlir/lite/schema/schema.fbs +++ b/tensorflow/compiler/mlir/lite/schema/schema.fbs @@ -62,6 +62,7 @@ enum TensorType : byte { INT4 = 17, BFLOAT16 = 18, INT2 = 19, + UINT4 = 20, } // Custom quantization parameters for experimenting with new quantization diff --git a/tensorflow/lite/core/api/flatbuffer_conversions.cc b/tensorflow/lite/core/api/flatbuffer_conversions.cc index 76d03a7fd89..a0c190641b5 100644 --- a/tensorflow/lite/core/api/flatbuffer_conversions.cc +++ b/tensorflow/lite/core/api/flatbuffer_conversions.cc @@ -1098,6 +1098,9 @@ TfLiteStatus ConvertTensorType(TensorType tensor_type, TfLiteType* type, case TensorType_INT2: *type = kTfLiteInt2; return kTfLiteOk; + case TensorType_UINT4: + *type = kTfLiteUInt4; + return kTfLiteOk; default: *type = kTfLiteNoType; TF_LITE_REPORT_ERROR(error_reporter, diff --git a/tensorflow/lite/core/c/common.cc b/tensorflow/lite/core/c/common.cc index 5d483bdf977..6d247309ec5 100644 --- a/tensorflow/lite/core/c/common.cc +++ b/tensorflow/lite/core/c/common.cc @@ -511,6 +511,8 @@ const char* TfLiteTypeGetName(TfLiteType type) { return "INT4"; case kTfLiteInt2: return "INT2"; + case kTfLiteUInt4: + return "UINT4"; } return "Unknown type"; } diff --git a/tensorflow/lite/micro/tools/layer_by_layer.cc b/tensorflow/lite/micro/tools/layer_by_layer.cc index b72517523fa..26e690ed04c 100644 --- a/tensorflow/lite/micro/tools/layer_by_layer.cc +++ b/tensorflow/lite/micro/tools/layer_by_layer.cc @@ -117,6 +117,9 @@ TfLiteStatus ConvertTensorType(TfLiteType type, TensorTypes& tensor_type) { case kTfLiteVariant: tensor_type = TensorTypes_VARIANT; return kTfLiteOk; + case kTfLiteUInt4: + tensor_type = TensorTypes_UINT4; + return kTfLiteOk; case kTfLiteInt4: tensor_type = TensorTypes_INT4; return kTfLiteOk; diff --git a/tensorflow/lite/micro/tools/layer_by_layer_schema.fbs b/tensorflow/lite/micro/tools/layer_by_layer_schema.fbs index b788399a839..21cdcc00fd6 100644 --- a/tensorflow/lite/micro/tools/layer_by_layer_schema.fbs +++ b/tensorflow/lite/micro/tools/layer_by_layer_schema.fbs @@ -36,6 +36,7 @@ enum TensorTypes : byte { INT4 = 17, BFLOAT16 = 18, INT2 = 19, + UINT4 = 20, } table TensorData { diff --git a/tensorflow/lite/micro/tools/layer_by_layer_schema_generated.h b/tensorflow/lite/micro/tools/layer_by_layer_schema_generated.h index 25f101bc183..90f644db577 100644 --- a/tensorflow/lite/micro/tools/layer_by_layer_schema_generated.h +++ b/tensorflow/lite/micro/tools/layer_by_layer_schema_generated.h @@ -60,11 +60,12 @@ enum TensorTypes : int8_t { TensorTypes_INT4 = 17, TensorTypes_BFLOAT16 = 18, TensorTypes_INT2 = 19, + TensorTypes_UINT4 = 20, TensorTypes_MIN = TensorTypes_FLOAT32, - TensorTypes_MAX = TensorTypes_INT2 + TensorTypes_MAX = TensorTypes_UINT4 }; -inline const TensorTypes (&EnumValuesTensorTypes())[20] { +inline const TensorTypes (&EnumValuesTensorTypes())[21] { static const TensorTypes values[] = { TensorTypes_FLOAT32, TensorTypes_FLOAT16, @@ -85,13 +86,14 @@ inline const TensorTypes (&EnumValuesTensorTypes())[20] { TensorTypes_UINT16, TensorTypes_INT4, TensorTypes_BFLOAT16, - TensorTypes_INT2 + TensorTypes_INT2, + TensorTypes_UINT4 }; return values; } inline const char * const *EnumNamesTensorTypes() { - static const char * const names[21] = { + static const char * const names[22] = { "FLOAT32", "FLOAT16", "INT32", @@ -112,13 +114,14 @@ inline const char * const *EnumNamesTensorTypes() { "INT4", "BFLOAT16", "INT2", + "UINT4", nullptr }; return names; } inline const char *EnumNameTensorTypes(TensorTypes e) { - if (::flatbuffers::IsOutRange(e, TensorTypes_FLOAT32, TensorTypes_INT2)) return ""; + if (::flatbuffers::IsOutRange(e, TensorTypes_FLOAT32, TensorTypes_UINT4)) return ""; const size_t index = static_cast(e); return EnumNamesTensorTypes()[index]; } diff --git a/tensorflow/lite/schema/schema_generated.h b/tensorflow/lite/schema/schema_generated.h index 67c8279d83d..7d62dc7bd47 100755 --- a/tensorflow/lite/schema/schema_generated.h +++ b/tensorflow/lite/schema/schema_generated.h @@ -712,11 +712,12 @@ enum TensorType : int8_t { TensorType_INT4 = 17, TensorType_BFLOAT16 = 18, TensorType_INT2 = 19, + TensorType_UINT4 = 20, TensorType_MIN = TensorType_FLOAT32, - TensorType_MAX = TensorType_INT2 + TensorType_MAX = TensorType_UINT4 }; -inline const TensorType (&EnumValuesTensorType())[20] { +inline const TensorType (&EnumValuesTensorType())[21] { static const TensorType values[] = { TensorType_FLOAT32, TensorType_FLOAT16, @@ -737,13 +738,14 @@ inline const TensorType (&EnumValuesTensorType())[20] { TensorType_UINT16, TensorType_INT4, TensorType_BFLOAT16, - TensorType_INT2 + TensorType_INT2, + TensorType_UINT4 }; return values; } inline const char * const *EnumNamesTensorType() { - static const char * const names[21] = { + static const char * const names[22] = { "FLOAT32", "FLOAT16", "INT32", @@ -764,13 +766,14 @@ inline const char * const *EnumNamesTensorType() { "INT4", "BFLOAT16", "INT2", + "INT4", nullptr }; return names; } inline const char *EnumNameTensorType(TensorType e) { - if (::flatbuffers::IsOutRange(e, TensorType_FLOAT32, TensorType_INT2)) return ""; + if (::flatbuffers::IsOutRange(e, TensorType_FLOAT32, TensorType_UINT4)) return ""; const size_t index = static_cast(e); return EnumNamesTensorType()[index]; } From 9adb606a9f6a3f3622a38946202530f9a2894090 Mon Sep 17 00:00:00 2001 From: TFLM-bot Date: Wed, 14 Jan 2026 14:04:59 +0000 Subject: [PATCH 2/2] Sync from upstream TF. --- tensorflow/lite/python/schema_py_generated.py | 1 + tensorflow/lite/schema/schema_generated.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tensorflow/lite/python/schema_py_generated.py b/tensorflow/lite/python/schema_py_generated.py index 03cca34f037..cd76b46ac4c 100755 --- a/tensorflow/lite/python/schema_py_generated.py +++ b/tensorflow/lite/python/schema_py_generated.py @@ -28,6 +28,7 @@ class TensorType(object): INT4 = 17 BFLOAT16 = 18 INT2 = 19 + UINT4 = 20 class QuantizationDetails(object): diff --git a/tensorflow/lite/schema/schema_generated.h b/tensorflow/lite/schema/schema_generated.h index 7d62dc7bd47..041a0338faa 100755 --- a/tensorflow/lite/schema/schema_generated.h +++ b/tensorflow/lite/schema/schema_generated.h @@ -766,7 +766,7 @@ inline const char * const *EnumNamesTensorType() { "INT4", "BFLOAT16", "INT2", - "INT4", + "UINT4", nullptr }; return names;