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

[POC][OV] Support OpenVINO as Keras 3 backend #19727

Open
wants to merge 19 commits into
base: master
Choose a base branch
from

Conversation

rkazants
Copy link

@rkazants rkazants commented May 17, 2024

Details: Support OpenVINO as Keras 3 backend. This is inference-only backend. In order to switch on this, define environment variable as follows: os.environ["KERAS_BACKEND"] = "openvino" or use set_backend.

Here is an example how it works:
Install OpenVINO pip install openvino -U

import os
os.environ["KERAS_BACKEND"] = "openvino"
import numpy as np
import keras

# build a simple network
x1 = keras.Input(shape=(2,), dtype='float32')
x2 = keras.Input(shape=(2,), dtype='float32')
add = keras.layers.Add()([x1, x2])
sigmoid = keras.activations.sigmoid(add)
model = keras.Model(inputs={'x1': x1, 'x2': x2}, outputs={'sigmoid': sigmoid})
model.summary()

# infer using OpenVINO
out = model.predict({'x1': np.array([[1.0, 2.0]], dtype=np.float32),
                     'x2': np.array([[3.0, 4.0]], dtype=np.float32)})
print('openvino out = ', out)

Copy link

google-cla bot commented May 17, 2024

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

Copy link
Member

@fchollet fchollet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR!

keras/src/ops/function.py Outdated Show resolved Hide resolved
@@ -289,6 +291,9 @@ def __init__(
self._convert_input_args = True
# Whether to allow non-tensors as positional arguments in `call()`.
self._allow_non_tensor_positional_args = False
if backend.backend() == "openvino":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be backend-specific.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @fchollet, please advice how to avoid this code. Keras common requires it to be of KerasTensor type during calling op-by-op. How to relax this check and allow to pass ov type object into ops wrappers?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All you need is for backend.is_tensor(x) to return True for the types you consider to be tensors.

Copy link
Author

@rkazants rkazants Oct 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fchollet, I redefined it for my backend but openvino.runtime.Output does not have dtype attribute and exception is raised here: https://github.com/keras-team/keras/blob/master/keras/src/dtype_policies/dtype_policy.py#L200
We retrieve dtype using method get_element_type. I think backend.standardize_dtype should accept x instead of x.dtype.
How do you think I can solve this exception? Thanks for your help in advance.

keras/src/backend/openvino/linalg.py Outdated Show resolved Hide resolved
@codecov-commenter
Copy link

codecov-commenter commented May 20, 2024

Codecov Report

Attention: Patch coverage is 0.36101% with 552 lines in your changes missing coverage. Please review.

Project coverage is 78.03%. Comparing base (d85036c) to head (facde41).
Report is 10 commits behind head on master.

Files with missing lines Patch % Lines
keras/src/backend/openvino/numpy.py 0.00% 178 Missing ⚠️
keras/src/backend/openvino/core.py 0.00% 114 Missing ⚠️
keras/src/backend/openvino/trainer.py 0.00% 114 Missing ⚠️
keras/src/backend/openvino/nn.py 0.00% 52 Missing ⚠️
keras/src/backend/openvino/__init__.py 0.00% 22 Missing ⚠️
keras/src/backend/openvino/math.py 0.00% 18 Missing ⚠️
keras/src/backend/openvino/random.py 0.00% 14 Missing ⚠️
keras/src/backend/openvino/linalg.py 0.00% 12 Missing ⚠️
keras/src/backend/openvino/rnn.py 0.00% 7 Missing ⚠️
keras/src/backend/exports.py 0.00% 4 Missing ⚠️
... and 6 more
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #19727      +/-   ##
==========================================
- Coverage   78.91%   78.03%   -0.88%     
==========================================
  Files         510      522      +12     
  Lines       48590    49460     +870     
  Branches     8960     9059      +99     
==========================================
+ Hits        38344    38596     +252     
- Misses       8391     9000     +609     
- Partials     1855     1864       +9     
Flag Coverage Δ
keras 77.89% <0.36%> (-0.88%) ⬇️
keras-jax 61.65% <0.18%> (-0.73%) ⬇️
keras-numpy 56.86% <0.36%> (-0.70%) ⬇️
keras-tensorflow 62.92% <0.18%> (-0.81%) ⬇️
keras-torch 61.64% <0.18%> (-0.79%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@gbaned
Copy link
Collaborator

gbaned commented Jun 14, 2024

Hi @rkazants Can you please resolve the conflicts? Thank you!

@rkazants
Copy link
Author

Hi @rkazants Can you please resolve the conflicts? Thank you!

I am working on this PR. I am trying to resolve comments.

Best regards,
Roman

@gbaned
Copy link
Collaborator

gbaned commented Jul 12, 2024

Hi @rkazants Any update on this PR? Please. Thank you!

Copy link

This PR is stale because it has been open for 14 days with no activity. It will be closed if no further activity occurs. Thank you.

@github-actions github-actions bot added the stale label Jul 27, 2024
@rkazants
Copy link
Author

I am just back from vacation. I plan to continue from the next week.

Copy link

This PR is stale because it has been open for 14 days with no activity. It will be closed if no further activity occurs. Thank you.

@gbaned
Copy link
Collaborator

gbaned commented Sep 9, 2024

Hi @rkazants Any update on this PR? Please. Thank you!

@rkazants
Copy link
Author

rkazants commented Sep 9, 2024

Hi @rkazants Any update on this PR? Please. Thank you!

Hi @gbaned, please anticipate the update early this week. Sorry for the delay.

Thanks,
Roman

Signed-off-by: Kazantsev, Roman <[email protected]>
Signed-off-by: Kazantsev, Roman <[email protected]>
Signed-off-by: Kazantsev, Roman <[email protected]>
Signed-off-by: Kazantsev, Roman <[email protected]>
Signed-off-by: Kazantsev, Roman <[email protected]>
@rkazants
Copy link
Author

@fchollet, please review. all other comments are addressed.

Signed-off-by: Kazantsev, Roman <[email protected]>
@rkazants
Copy link
Author

rkazants commented Sep 25, 2024

@fchollet,
Also, I would suggest separate integration tests for openvino backend. I want to have test suite for each keras operation where it creates one layer model and test inference results. As reference, we can use numpy backend's results, for example. This way we will add more op coverage support step-by-step and validate new functionality. How do you think?

Thanks,
Roman

Signed-off-by: Kazantsev, Roman <[email protected]>
Signed-off-by: Kazantsev, Roman <[email protected]>
Signed-off-by: Kazantsev, Roman <[email protected]>
Signed-off-by: Kazantsev, Roman <[email protected]>
Signed-off-by: Kazantsev, Roman <[email protected]>
@rkazants
Copy link
Author

Hi @fchollet, look forward to receive your review:)
I am ready to address your comments asap these days.

Thanks in advance,
Roman

@rkazants
Copy link
Author

@fchollet, kindly reminder about review.

Thank you,
Roman

@rkazants
Copy link
Author

Hi @fchollet, any update? Please inform me if any concerns.

Thanks,
Roman

@rkazants
Copy link
Author

rkazants commented Oct 2, 2024

Hi @fchollet, @gbaned,

Could you please take a look? Let me know if any minimal scope of supported ops are required for this PR. I will add it here.

Thanks,
Roman

Copy link
Member

@fchollet fchollet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, only seeing this now. It looks better! It seems the set of ops currently implemented is quite small, however. What kinds of end-to-end workflows are currently working? What level of op coverage do you think you can achieve?

@@ -289,6 +291,9 @@ def __init__(
self._convert_input_args = True
# Whether to allow non-tensors as positional arguments in `call()`.
self._allow_non_tensor_positional_args = False
if backend.backend() == "openvino":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All you need is for backend.is_tensor(x) to return True for the types you consider to be tensors.

@rkazants
Copy link
Author

rkazants commented Oct 3, 2024

Sorry, only seeing this now. It looks better! It seems the set of ops currently implemented is quite small, however. What kinds of end-to-end workflows are currently working? What level of op coverage do you think you can achieve?

Hi @fchollet, currently we support predict method only for inference. evaluate is not supported because it requires to support loss function and run it on the same backend. That is not convenient to do with our backend because eager execution is absent.

In future, from my quick glance we will be able to cover solid number of operations because OpenVINO opset is quite well developed and support a lot of TF, PyTorch, ONNX models from different hubs (TF, ONNX, HF, PyTorch, etc,) for inference and we permanently develop it to cover TF, PyTorch, ONNX opsets. You can find all OV operations here: https://docs.openvino.ai/2024/documentation/openvino-ir-format/operation-sets/operation-specs.html

Let me know what amount of operations I should cover in this PR to get it merged. So we will have the base OpenVINO support here and continue ops coverage support in future PRs. For the base OpenVINO support, I propose to support operations required by BERT model without preprocessor from Keras Hub, for example, and demonstrate that it works. Example below. Will it be sufficient for merge?

import os
os.environ["KERAS_BACKEND"] = "openvino"

import keras_nlp

features = {
    "token_ids": np.ones(shape=(2, 12), dtype="int32"),
    "segment_ids": np.array([[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0]] * 2),
    "padding_mask": np.array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0]] * 2),
}

# Load a BERT model.
classifier = keras_nlp.models.BertClassifier.from_preset(
    "bert_base_en_uncased", 
    num_classes=2,
    preprocessor=None
)

classifier.predict(features)

In the description of this PR, I demonstrated very simple model inference. Please check.

@fchollet
Copy link
Member

fchollet commented Oct 4, 2024

Let me know what amount of operations I should cover in this PR to get it merged. So we will have the base OpenVINO support here and continue ops coverage support in future PRs. For the base OpenVINO support, I propose to support operations required by BERT model without preprocessor from Keras Hub, for example, and demonstrate that it works. Example below. Will it be sufficient for merge?

We will have to run only a very similar subset of unit tests on CI for OpenVINO since we cannot skip every test that isn't passing (too many). So we would have to create basically an OpenVINO-specific integration test that checks precisely the end-to-end workflows that are intended to be supported.

Are you going to add support for CV workflows? I would recommend also having support for conv/pooling ops.

@rkazants
Copy link
Author

rkazants commented Oct 4, 2024

We will have to run only a very similar subset of unit tests on CI for OpenVINO since we cannot skip every test that isn't passing (too many). So we would have to create basically an OpenVINO-specific integration test that checks precisely the end-to-end workflows that are intended to be supported.

Are you going to add support for CV workflows? I would recommend also having support for conv/pooling ops.

Yes, I will add separate integration tests for OpenVINO to cover currently supported ops. For this PR, let me enable MobileNetV3 from KerasCV that will require to support conv/pooling operations.

Summarizing it, my to-do list for this PR looks as follows:

  1. Enable BertClassifier model from KerasNLP
  2. Enable MobileNet model from KerasCV
  3. Add integration tests for OpenVINO to cover supported ops

@fchollet, will it be fine and sufficient for this PR merge?

Thanks a lot,
Roman

@fchollet
Copy link
Member

fchollet commented Oct 4, 2024

@fchollet, will it be fine and sufficient for this PR merge?

Yes, that sounds good to me!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Assigned Reviewer
Development

Successfully merging this pull request may close these issues.

5 participants