You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tvm.apache.org by lu...@apache.org on 2023/10/16 19:45:36 UTC
[tvm] branch main updated: [microNPU][ETHOSU] Fix rounding mode in requantize operation (#15929)
This is an automated email from the ASF dual-hosted git repository.
lukhut pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm.git
The following commit(s) were added to refs/heads/main by this push:
new 0276c5a0d8 [microNPU][ETHOSU] Fix rounding mode in requantize operation (#15929)
0276c5a0d8 is described below
commit 0276c5a0d81021489663d08b3afbab6f0ed6ab8e
Author: Aleksei-grovety <11...@users.noreply.github.com>
AuthorDate: Mon Oct 16 23:45:28 2023 +0400
[microNPU][ETHOSU] Fix rounding mode in requantize operation (#15929)
Before the fix, TFL rounding was used in the requantize operation and this led to a discrepancy in the results in some cases
---
python/tvm/relay/backend/contrib/ethosu/legalize.py | 1 +
python/tvm/relay/backend/contrib/ethosu/op/identity.py | 18 ++++++++++++++++--
python/tvm/relay/backend/contrib/ethosu/te/identity.py | 8 +++++++-
.../tvm/relay/backend/contrib/ethosu/tir/identity.py | 2 +-
src/relay/op/contrib/ethosu/identity.cc | 3 ++-
src/relay/op/contrib/ethosu/op_attrs.h | 8 ++++++++
.../cascader/test_ethosu_identity_matcher.py | 1 +
tests/python/contrib/test_ethosu/test_codegen.py | 1 +
8 files changed, 37 insertions(+), 5 deletions(-)
diff --git a/python/tvm/relay/backend/contrib/ethosu/legalize.py b/python/tvm/relay/backend/contrib/ethosu/legalize.py
index 242d3c2d0c..2806ef8a46 100644
--- a/python/tvm/relay/backend/contrib/ethosu/legalize.py
+++ b/python/tvm/relay/backend/contrib/ethosu/legalize.py
@@ -1216,6 +1216,7 @@ class RequantizeRewriter(DFPatternCallback):
ifm_zero_point=int(params.ifm.q_params.zero_point),
ofm_scale=float(params.ofm.q_params.scale_f32),
ofm_zero_point=int(params.ofm.q_params.zero_point),
+ rounding_mode="NATURAL",
)
diff --git a/python/tvm/relay/backend/contrib/ethosu/op/identity.py b/python/tvm/relay/backend/contrib/ethosu/op/identity.py
index f070144ba2..d91de971db 100644
--- a/python/tvm/relay/backend/contrib/ethosu/op/identity.py
+++ b/python/tvm/relay/backend/contrib/ethosu/op/identity.py
@@ -36,8 +36,16 @@ def create_ethosu_identity_compute(attrs, args, out_type):
ofm_scale = attrs.ofm_scale
ofm_zero_point = attrs.ofm_zero_point
activation = attrs.activation
+ rounding_mode = attrs.rounding_mode
op = identity_compute(
- ifm, lut, ifm_scale, ifm_zero_point, ofm_scale, ofm_zero_point, activation
+ ifm,
+ lut,
+ ifm_scale,
+ ifm_zero_point,
+ ofm_scale,
+ ofm_zero_point,
+ activation,
+ rounding_mode,
)
return [op]
@@ -61,6 +69,7 @@ def ethosu_identity(
ofm_scale: float = 1,
ofm_zero_point: int = 0,
activation: str = "NONE",
+ rounding_mode: str = "TFL",
) -> tvm.relay.Call:
"""The Identity operator that runs on the NPU.
@@ -87,6 +96,11 @@ def ethosu_identity(
"TANH" - tanh activation function.
"SIGMOID" - sigmoid activation function.
"LUT" - use a look-up table to perform the activation function.
+ rounding_mode : str, optional
+ The rounding mode to apply to the Output Feature Map tensor.
+ "TFL" - Tensorflow Lite rounding scheme.
+ "TRUNCATE" - Truncate towards zero.
+ "NATURAL" - Round to nearest value, with x.5 rounded up towards +infinity.
Returns
-------
@@ -94,5 +108,5 @@ def ethosu_identity(
A call to the ethosu_identity op.
"""
return _make.ethosu_identity(
- ifm, lut, ifm_scale, ifm_zero_point, ofm_scale, ofm_zero_point, activation
+ ifm, lut, ifm_scale, ifm_zero_point, ofm_scale, ofm_zero_point, activation, rounding_mode
)
diff --git a/python/tvm/relay/backend/contrib/ethosu/te/identity.py b/python/tvm/relay/backend/contrib/ethosu/te/identity.py
index d2ffcee085..7f9bcebf70 100644
--- a/python/tvm/relay/backend/contrib/ethosu/te/identity.py
+++ b/python/tvm/relay/backend/contrib/ethosu/te/identity.py
@@ -31,6 +31,7 @@ def identity_compute(
ofm_scale: float,
ofm_zero_point: int,
activation: str,
+ rounding_mode: str,
) -> te.Tensor:
"""A compute operator for the NPU identity operator.
@@ -54,6 +55,11 @@ def identity_compute(
"TANH" - tanh activation function.
"SIGMOID" - sigmoid activation function.
"LUT" - use a look-up table to perform the activation function.
+ rounding_mode : str
+ The rounding mode to apply to the Output Feature Map tensor.
+ "TFL" - Tensorflow Lite rounding scheme.
+ "TRUNCATE" - Truncate towards zero.
+ "NATURAL" - Round to nearest value, with x.5 rounded up towards +infinity.
Returns
-------
@@ -61,7 +67,7 @@ def identity_compute(
The Output Feature Map tensor.
"""
dmaed_ifm = read_compute(ifm, ifm_zero_point, ifm_scale)
- id_attrs = {"op": "ethosu_identity", "activation": activation}
+ id_attrs = {"op": "ethosu_identity", "activation": activation, "rounding_mode": rounding_mode}
has_lut = activation in ("TANH", "LUT", "SIGMOID")
diff --git a/python/tvm/relay/backend/contrib/ethosu/tir/identity.py b/python/tvm/relay/backend/contrib/ethosu/tir/identity.py
index 43ae52b3ba..9610c8dd3c 100644
--- a/python/tvm/relay/backend/contrib/ethosu/tir/identity.py
+++ b/python/tvm/relay/backend/contrib/ethosu/tir/identity.py
@@ -166,7 +166,7 @@ def get_identity_params(
padding=SerialPadding(0, 0, 0, 0),
activation=serial_activation,
upscale="NONE",
- rounding_mode="TFL",
+ rounding_mode=attrs["rounding_mode"],
block_config=SerialBlockConfig(0, 0, 0),
),
output_pointer,
diff --git a/src/relay/op/contrib/ethosu/identity.cc b/src/relay/op/contrib/ethosu/identity.cc
index 9b00978d43..f808e8c219 100644
--- a/src/relay/op/contrib/ethosu/identity.cc
+++ b/src/relay/op/contrib/ethosu/identity.cc
@@ -63,13 +63,14 @@ bool EthosuIdentityRel(const Array<Type>& types, int num_inputs, const Attrs& at
}
Expr MakeEthosuIdentity(Expr ifm, Expr lut, double ifm_scale, int ifm_zero_point, double ofm_scale,
- int ofm_zero_point, String activation) {
+ int ofm_zero_point, String activation, String rounding_mode) {
auto attrs = make_object<EthosuIdentityAttrs>();
attrs->ifm_scale = ifm_scale;
attrs->ifm_zero_point = ifm_zero_point;
attrs->ofm_scale = ofm_scale;
attrs->ofm_zero_point = ofm_zero_point;
attrs->activation = std::move(activation);
+ attrs->rounding_mode = std::move(rounding_mode);
static const Op& op = Op::Get("contrib.ethosu.identity");
return Call(op, {ifm, lut}, Attrs(attrs), {});
}
diff --git a/src/relay/op/contrib/ethosu/op_attrs.h b/src/relay/op/contrib/ethosu/op_attrs.h
index 74e7fe856e..868d9d6ad4 100644
--- a/src/relay/op/contrib/ethosu/op_attrs.h
+++ b/src/relay/op/contrib/ethosu/op_attrs.h
@@ -319,6 +319,7 @@ struct EthosuIdentityAttrs : public tvm::AttrsNode<EthosuIdentityAttrs> {
double ofm_scale;
int ofm_zero_point;
String activation;
+ String rounding_mode;
TVM_DECLARE_ATTRS(EthosuIdentityAttrs, "relay.attrs.EthosuIdentityAttrs") {
TVM_ATTR_FIELD(ifm_scale).describe("The quantization scale for the Input Feature Map tensor.");
@@ -335,6 +336,13 @@ struct EthosuIdentityAttrs : public tvm::AttrsNode<EthosuIdentityAttrs> {
"'SIGMOID' - sigmoid activation function. "
"'LUT' - use a look-up table to perform the activation function.")
.set_default("NONE");
+ TVM_ATTR_FIELD(rounding_mode)
+ .describe(
+ "The rounding mode to apply to the Output Feature Map tensor. "
+ "'TFL' - Tensorflow Lite rounding scheme. "
+ "'TRUNCATE' - Truncate towards zero."
+ "'NATURAL' - Round to nearest value, with x.5 rounded up towards +infinity.")
+ .set_default("TFL");
}
};
diff --git a/tests/python/contrib/test_ethosu/cascader/test_ethosu_identity_matcher.py b/tests/python/contrib/test_ethosu/cascader/test_ethosu_identity_matcher.py
index 4bdccfced3..11d76ab2b8 100644
--- a/tests/python/contrib/test_ethosu/cascader/test_ethosu_identity_matcher.py
+++ b/tests/python/contrib/test_ethosu/cascader/test_ethosu_identity_matcher.py
@@ -39,6 +39,7 @@ def test_ethosu_identity_matcher():
ofm_scale=1,
ofm_zero_point=0,
activation="NONE",
+ rounding_mode="TFL",
)
length = len(ifm.shape)
diff --git a/tests/python/contrib/test_ethosu/test_codegen.py b/tests/python/contrib/test_ethosu/test_codegen.py
index fde2e28434..66809a775f 100644
--- a/tests/python/contrib/test_ethosu/test_codegen.py
+++ b/tests/python/contrib/test_ethosu/test_codegen.py
@@ -1233,6 +1233,7 @@ def test_tflite_split(accel_type, ifm_shape, num_or_size_splits, axis):
[
[(1, 8, 8, 3), 1.0, 0, 1.0, 0],
[(1, 20, 30, 3), 1.345, 34, 0.32, -23],
+ [(1, 1, 4, 8), 0.0078125, 0, 0.00997, -30],
],
)
def test_ethosu_requantize(accel_type, ifm_shape, ifm_scale, ifm_zp, ofm_scale, ofm_zp):