tensorflow-onnx
tensorflow-onnx copied to clipboard
Add masked LSTM support
Masking is a intra-layer behavior in TF LSTM [1] but is not a intra-op behavior in ONNX LSTM [2]. When converted to ONNX, masked TF LSTM layer is converted to Loop op. This over-complicates the ONNX model, and has a negative impact on inference performance in ORT without leveraging LSTM optimizations. (issue #1871)
This commit adds support to convert masked LSTM correctly, under the important assumption that input must be post-padded - which is the most common use case. The "masking" info is conveyed to ONNX LSTM op as sequence_lens which is dynamically computed by summing the number of non-skip timesteps per batch per-LSTM. This behavior is implemented with reference to keras2onnx PR#386 [3]. Additional logic is added for backward LSTM so that the input sequence is reversed correctly given sequence_lens.
Note that if mask-enabled, and LSTM input is pre- or randomly padded, the converted ONNX model will behave incorrectly for inference. Unless ONNX add new attribute e.g. mask_enabled to RNN ops, converter alone may not be able to handle generic masking while keeping the RNN ops, since masking alters intra-op behavior. With such limitation, I'd like to share this PR for further comment and suggestion.
[1] https://www.tensorflow.org/guide/keras/masking_and_padding#masking [2] https://github.com/onnx/onnx/blob/main/docs/Operators.md#LSTM [3] https://github.com/onnx/keras-onnx/pull/386
Details:
Forward LSTM
Here's an minimal example with an embedded LSTM (mask_zeros=True):
-
H5 model:

-
tf2onnx-converted ONNX model, before proposed change:

-
tf2onnx-converted ONNX model, after proposed change:

Reverse LSTM
- Need to alter
tf.raw_op.ReverseV2->ReverseSequencebehavior to reverse LSTM input correctly:
Sorry will address the test failures on TF-2.9 soon.
Hello, Is there any progress with this issue?
Hi, Is there any update? Will the proposed code work if pulled?