Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TFLite] Add option to overwrite OperatorConverter class in relay.frontend.from_tflite #9256

Merged
merged 2 commits into from Oct 14, 2021

Conversation

PhilippvK
Copy link
Contributor

Motivation

Having an ability to overwrite the mapping from TFLite Operators to TVM Relay Operators via downstream python scripts is desirable to:

  • Add support for unsupported builtin or even custom operators by adding a hand-written convert function
  • Enable a possibility to overwrite existing convert functions for supported operators by alternative implementations (useful for currently unsupported edge cases)

Changes

  • Add optional argument op_converter to tvm.relay.frontend.from_tflite function, defaulting to relay.frontend.tflite.OperatorConverter
  • Add allow_custom_ops flag to OperatorConverter, which allows to manually add convert function for CUSTOM opertator types

Tests

I also came up with a test case added to tvm/python/frontend/tflite/test_forward.py.

@areusch
Copy link
Contributor

areusch commented Oct 14, 2021

@PhilippvK can you retrigger the CI?

@jwfromm @masahi are you able to help review this PR?

@masahi
Copy link
Member

masahi commented Oct 14, 2021

Yeah PyTorch frontend also has something similar

custom_convert_map : Dictionary of str to Relay op
A custom op conversion map in the same format as _convert_map above
. I think it is a useful feature.

@masahi masahi self-assigned this Oct 14, 2021
@PhilippvK
Copy link
Contributor Author

@masahi I first tried to follow the same approach as in the PyTorch frontend, just passing a dict to overwrite the convert map. However in the TFLite frontend, the convert_* functions are instance methods of the OperatorConverter class, so I decided to accept an op_converter defined by the user which will most likely be inherited from the original one.

This allows to overwrite the mapping from TFLite Operators to TVM Relay Operators from external python scripts. This has the following advantages:
- Adding support for unsupported builtin or even custom operators by adding a hand-written convert function
- Enables overwriting of existing convert functions for supported operators by alternative implementations (useful for currently unsupported edge cases)

Example Usage:

```
class CustomOperatorConverter(relay.frontend.tflite.OperatorConverter):

    def __init__(self, model, subgraph, exp_tab):
        super(CustomOperatorConverter, self).__init__(model, subgraph, exp_tab)
        convert_map_overwrite = {"SUB": self.convert_sub_custom}
        self.convert_map.update(convert_map_overwrite)

    def convert_sub_custom(self, op):
        ...
...
relay_mod = relay.frontend.from_tflite(
    tflite_model, shape_dict=shape_dict, dtype_dict=dtype_dict, op_converter=CustomOperatorConverter
)
```

[TFLite] Make sure that even DETECTION_POSTPROCESS op can be overwritten

This is desirable, because the current implementation of this CUSTOM op is incompatible with MicroTVM targets
…rontend

Kept the test as simple as possible by only comparing 2 different
implementations of a SUB TFLite operator:

1. Original: c = a - b
2. Dummy: c = a + (-b)

Comparison with TFLite reference output is not necessary because tis is
already covered by other test cases. Instead comparisons of the two TVM
models are used.
@PhilippvK PhilippvK force-pushed the tflite-frontend-overwrite-converter branch from 10f51a6 to b354b58 Compare October 14, 2021 11:02
@masahi masahi merged commit f4db899 into apache:main Oct 14, 2021
@masahi
Copy link
Member

masahi commented Oct 14, 2021

Thanks @PhilippvK

ylc pushed a commit to ylc/tvm that referenced this pull request Jan 7, 2022
…ntend.from_tflite (apache#9256)

* [TFLite] Relay Frontend: Add option to overwrite OperatorConverter class

This allows to overwrite the mapping from TFLite Operators to TVM Relay Operators from external python scripts. This has the following advantages:
- Adding support for unsupported builtin or even custom operators by adding a hand-written convert function
- Enables overwriting of existing convert functions for supported operators by alternative implementations (useful for currently unsupported edge cases)

Example Usage:

```
class CustomOperatorConverter(relay.frontend.tflite.OperatorConverter):

    def __init__(self, model, subgraph, exp_tab):
        super(CustomOperatorConverter, self).__init__(model, subgraph, exp_tab)
        convert_map_overwrite = {"SUB": self.convert_sub_custom}
        self.convert_map.update(convert_map_overwrite)

    def convert_sub_custom(self, op):
        ...
...
relay_mod = relay.frontend.from_tflite(
    tflite_model, shape_dict=shape_dict, dtype_dict=dtype_dict, op_converter=CustomOperatorConverter
)
```

[TFLite] Make sure that even DETECTION_POSTPROCESS op can be overwritten

This is desirable, because the current implementation of this CUSTOM op is incompatible with MicroTVM targets

* Tests: added test case for overwriting op_converter in TFLite relay frontend

Kept the test as simple as possible by only comparing 2 different
implementations of a SUB TFLite operator:

1. Original: c = a - b
2. Dummy: c = a + (-b)

Comparison with TFLite reference output is not necessary because tis is
already covered by other test cases. Instead comparisons of the two TVM
models are used.
ylc pushed a commit to ylc/tvm that referenced this pull request Jan 13, 2022
…ntend.from_tflite (apache#9256)

* [TFLite] Relay Frontend: Add option to overwrite OperatorConverter class

This allows to overwrite the mapping from TFLite Operators to TVM Relay Operators from external python scripts. This has the following advantages:
- Adding support for unsupported builtin or even custom operators by adding a hand-written convert function
- Enables overwriting of existing convert functions for supported operators by alternative implementations (useful for currently unsupported edge cases)

Example Usage:

```
class CustomOperatorConverter(relay.frontend.tflite.OperatorConverter):

    def __init__(self, model, subgraph, exp_tab):
        super(CustomOperatorConverter, self).__init__(model, subgraph, exp_tab)
        convert_map_overwrite = {"SUB": self.convert_sub_custom}
        self.convert_map.update(convert_map_overwrite)

    def convert_sub_custom(self, op):
        ...
...
relay_mod = relay.frontend.from_tflite(
    tflite_model, shape_dict=shape_dict, dtype_dict=dtype_dict, op_converter=CustomOperatorConverter
)
```

[TFLite] Make sure that even DETECTION_POSTPROCESS op can be overwritten

This is desirable, because the current implementation of this CUSTOM op is incompatible with MicroTVM targets

* Tests: added test case for overwriting op_converter in TFLite relay frontend

Kept the test as simple as possible by only comparing 2 different
implementations of a SUB TFLite operator:

1. Original: c = a - b
2. Dummy: c = a + (-b)

Comparison with TFLite reference output is not necessary because tis is
already covered by other test cases. Instead comparisons of the two TVM
models are used.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants