Skip to content

Commit a27a5db

Browse files
NXP backend: Fix bug with reused Linear bias. (#23112)
### Summary Sometimes, the bias of multiple `Linear` nodes can be shared, so all occurrences have the same quantization parameters. But as the bias's scale is determined by the scale of the input and weight, an error is introduced. This commit assigns each bias the correct scale during conversion to Neutron IR. By doing so, 7 LSTM harness tests are enabled, leaving only 3 failing ones (2 timeouts and 1 accuracy issue. Fixing them is not a priority as proper LSTM support is planned for the future). ### Test plan `pytest -c /dev/nul backends/test /suite/operators/test_lstm.py -m backend_nxp` cc @robert-kalmar @JakeStevens @digantdesai @rascani
1 parent 53c79ed commit a27a5db

2 files changed

Lines changed: 22 additions & 10 deletions

File tree

‎backends/nxp/backend/ir/converter/node_converters/ops_converters/addmm_converter.py‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# This source code is licensed under the BSD-style license found in the
44
# LICENSE file in the root directory of this source tree.
55

6+
import numpy as np
67
import torch
78

89
from executorch.backends.nxp.backend.edge_helper import (
@@ -15,6 +16,7 @@
1516
CustomDelegationOptions,
1617
NodeConverter,
1718
)
19+
from executorch.backends.nxp.backend.ir.tflite_generator import tflite_model
1820
from executorch.backends.nxp.backend.ir.tflite_generator.builtin_options import (
1921
fully_connected_options,
2022
)
@@ -138,4 +140,21 @@ def convert(self, node: Node):
138140
# be present in the output model if the weights are static.)
139141
ops.add_pre(self.builder.create_transpose_operator_before(t_op, 1, [1, 0]))
140142

143+
# Neutron IR requires the bias scale to be the product of the input and weight scale. During quantization the
144+
# bias may have been shared across ops, so its annotated scale can be incorrect.
145+
# Recompute the bias scale now that the tensor is unique per op.
146+
if (
147+
bias.quantization is not None
148+
and x.quantization is not None
149+
and w.quantization is not None
150+
):
151+
expected_scale = np.array(x.quantization.scale.vector) * np.array(
152+
w.quantization.scale.vector
153+
)
154+
if not np.allclose(bias.quantization.scale.vector, expected_scale):
155+
bias.quantization = tflite_model.Quantization(
156+
scale=tflite_model.Scale(list(expected_scale)),
157+
zero_point=tflite_model.ZeroPoint([0] * len(expected_scale)),
158+
)
159+
141160
self.builder.append_operators(ops.flatten())

‎backends/test/suite/flows/nxp.py‎

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,9 @@
3131
# Tests known to fail on Neutron due to known bugs. Marked as xfail
3232
# (strict=True) so that an unexpected pass is also reported.
3333
_NEUTRON_XFAILS = [
34-
"test_lstm_batch_first_false",
35-
"test_lstm_return_hidden_states",
36-
"test_lstm_batch_sizes",
37-
"test_lstm_seq_lengths",
38-
"test_lstm_bidirectional",
39-
"test_lstm_with_dropout",
40-
"test_lstm_dtype",
41-
"test_lstm_with_initial_states",
42-
"test_lstm_feature_sizes",
43-
"test_lstm_num_layers",
34+
"test_lstm_return_hidden_states", # Accuracy error.
35+
"test_lstm_seq_lengths", # Timeout.
36+
"test_lstm_num_layers", # Timeout.
4437
]
4538

4639

0 commit comments

Comments
 (0)