-
Notifications
You must be signed in to change notification settings - Fork 214
Draft: Java API to use tf.function available on SavedModel. #89
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
Draft: Java API to use tf.function available on SavedModel. #89
Conversation
Python models that contain tf.function is inconvenient to be consumed by Java clients. This proposal provides an API to (a) Invoke a tf.function, given the signature name (b) Retrieve the node name in the graph corresponding to a tf.function
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed (or fixed any issues), please reply here with What to do if you already signed the CLAIndividual signers
Corporate signers
ℹ️ Googlers: Go here for more info. |
Python models that contain tf.function is inconvenient to be consumed by Java clients. This proposal provides an API to (a) Invoke a tf.function, given the signature name (b) Retrieve the node name in the graph corresponding to a tf.function
Hi @Shajan , can you please rebase this PR to merge it in the shared branch created for this story we will working on together instead of master? https://github.com/tensorflow/java/tree/shared-saved-model I think we should merge it back to master only when the whole solution is complete |
@karllessard i tried to rebase and then push the change to tensorflow:shared-saved-model i may not have permission to do so. Instead i made a pull request to the shared-saved-model branch. |
Thanks @Shajan , it's ok I've merged it and sent you an invite to collaborate to this repository, I think after you accept it, I will be able to give you write access to the shared branch |
Thanks @karllessard got the invite. Will wait for you to merge your changes and then add tests. |
* input / output parameters of a <a | ||
* href="https://www.tensorflow.org/api_docs/python/tf/function">tf.function</a> | ||
*/ | ||
public static final class SignatureToNodeName { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Read through this change, and I believe the following API design would be both cleaner and more intuitive to use. Wdyt?
- Update Loader and add
withSignature(String... signatures)
. - Update
Loader.load()
to also constructTfFunctions
corresponding to the specified signatures. SignatureToNodeName
can become private and not exposed to end user, preferrably living insideTfFunction
as private.TfFunction
should not have a reference to thesession
. Let SavedModelBundle manage the session (which it already does).TfFunction
can become a pure data class.- Add
SavedModelBundle.call(String signature, Map<String, Tensor<?>> inputs, Map<String, Tensor<?>> outputs)
toSavedModelBundle
.TfFunction
can become private and not exposed to end user as well.
What do you think about the above proposed API design?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not exposing SignatureToNodeName (3) sounds good
TtFunction not having reference to session (4) is good as well
Regarding (5), it is desirable to have a way to do repeated call to the same function. Having a TfFuction class allows for this. I am also thinking removing runtime check currently done with each call in the Tensor call(Tensor) method and do that once.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your proposal @yzhuang , some thoughts on it:
SignatureToNodeName can become private and not exposed to end user, preferrably living inside TfFunction as private.
Looking at it, getSignatureToNodeName()
can already be private in SavedModelBundle
and SignatureToNodeName
could be restricted at the default-package level. I don't think it should be in TfFunction
though as it maps all signatures while an instance of TfFunction
is only mapped to one of them.
TfFunction should not have a reference to the session. Let SavedModelBundle manage the session (which it already does). TfFunction can become a pure data class.
That would prevent though to just invoke function.call(tensor)
to run the graph, which I personally like. While I understand that data classes have their lot of advantages, I'm not sure there is real gains for having TfFunction
as one of them, especially that Session
instances are thread-safe.
Add SavedModelBundle.call(String signature, Map<String, Tensor> inputs, Map> outputs) to SavedModelBundle. TfFunction can become private and not exposed to end user as well.
Again, I personally like the OO approach of letting users manipulating callable entities instead of having SavedModelBundle
acting as a "service". Is the intention here is just to hide the TfFunction
at the user level? Note that I was planning to reuse the same object to add new signatures to a model when exporting it (but I could also do it just with SavedModelBundle
if we decide to take that direction).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Karl and Shajan,
I have been busy with traveling, and didn't have time to follow up on this thread. Please feel free to take whatever you find helpful from my suggestions, and discard the rest. Thank you for taking time to go through my comments!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @karllessard and @Shajan ,
Sorry for the late reply on your comment—just landed in Hong Kong :)
My suggestion to let SavedModel manage the session is not about thread safety, but about resource ownership. SavedModel currently “owns” the session and is responsible for closing the resource to avoid memory leaks. If we create TFFunction objects holding references to the session, it complicate the resource ownership mental model. For example, we will need to do things such as the below:
- Perform reference counting on the session, and have the last “user” of the session close it. This is user friendly, but introduces complexity and room for bugs. OR
- Continue to let SavedModel own the session, but TFFunction objects need to anticipate that it’s underlying resource (the session) can become defunct at anytime. This can be counterintuitive to users as users likely need to surround their call with a try/catch.
Is the intention here is just to hide the TfFunction at the user level?
My intention was to not have to think about the resource ownership problem, and keep the resource ownership unchanged. The API of having TFFunctions be callable and exposed to users sounds great to me, and we need to think about the above 1 & 2 though. This is not a contrived scenario: we already do model hot swapping at Twitter in our prediction servers, and SavedModels are hot swapped without restarting the JVM.
Thank you Karl and Shajan!
@yzhuang , this SIG is having a community video chat where we will discuss about this topic, among other things. Are you available and interested to join? |
@karllessard missed the meeting today. I see the decision to be
I take it that we go with the current branch (after addressing open comments) and adding unit tests. For unit tests: Here is a proposal
|
Python models that contain tf.function is inconvenient to be consumed by Java clients. This proposal provides an API to (a) Invoke a tf.function, given the signature name (b) Retrieve the node name in the graph corresponding to a tf.function Co-authored-by: Shajan Dasan <[email protected]>
…ow#89) Python models that contain tf.function is inconvenient to be consumed by Java clients. This proposal provides an API to (a) Invoke a tf.function, given the signature name (b) Retrieve the node name in the graph corresponding to a tf.function Co-authored-by: Shajan Dasan <[email protected]>
* Draft: Java API to use tf.function available on SavedModel. (#89) Python models that contain tf.function is inconvenient to be consumed by Java clients. This proposal provides an API to (a) Invoke a tf.function, given the signature name (b) Retrieve the node name in the graph corresponding to a tf.function Co-authored-by: Shajan Dasan <[email protected]> * Change API for creating concrete functions and exporting them to a saved model Co-authored-by: Karl Lessard <[email protected]>
Python models that contain tf.function is inconvenient to be consumed by Java clients. This proposal provides an API to (a) Invoke a tf.function, given the signature name (b) Retrieve the node name in the graph corresponding to a tf.function Co-authored-by: Shajan Dasan <[email protected]> Save models as functions (#103) * Draft: Java API to use tf.function available on SavedModel. (#89) Python models that contain tf.function is inconvenient to be consumed by Java clients. This proposal provides an API to (a) Invoke a tf.function, given the signature name (b) Retrieve the node name in the graph corresponding to a tf.function Co-authored-by: Shajan Dasan <[email protected]> * Change API for creating concrete functions and exporting them to a saved model Co-authored-by: Karl Lessard <[email protected]> Rename signature name to key Print function signature when converting to String Add method that returns the signature of all functions in a saved model Add unit tests for python created SavedModel with tf.function
Python models that contain tf.function is inconvenient to be consumed by Java clients. This proposal provides an API to (a) Invoke a tf.function, given the signature name (b) Retrieve the node name in the graph corresponding to a tf.function Co-authored-by: Shajan Dasan <[email protected]> Save models as functions (#103) * Draft: Java API to use tf.function available on SavedModel. (#89) Python models that contain tf.function is inconvenient to be consumed by Java clients. This proposal provides an API to (a) Invoke a tf.function, given the signature name (b) Retrieve the node name in the graph corresponding to a tf.function Co-authored-by: Shajan Dasan <[email protected]> * Change API for creating concrete functions and exporting them to a saved model Co-authored-by: Karl Lessard <[email protected]> Rename signature name to key Print function signature when converting to String Add method that returns the signature of all functions in a saved model Add unit tests for python created SavedModel with tf.function
* Create, save and load models using functional API Python models that contain tf.function is inconvenient to be consumed by Java clients. This proposal provides an API to (a) Invoke a tf.function, given the signature name (b) Retrieve the node name in the graph corresponding to a tf.function Co-authored-by: Shajan Dasan <[email protected]> Save models as functions (#103) * Draft: Java API to use tf.function available on SavedModel. (#89) Python models that contain tf.function is inconvenient to be consumed by Java clients. This proposal provides an API to (a) Invoke a tf.function, given the signature name (b) Retrieve the node name in the graph corresponding to a tf.function Co-authored-by: Shajan Dasan <[email protected]> * Change API for creating concrete functions and exporting them to a saved model Co-authored-by: Karl Lessard <[email protected]> Rename signature name to key Print function signature when converting to String Add method that returns the signature of all functions in a saved model Add unit tests for python created SavedModel with tf.function * Add validations on signatures and saved models * Convert text file to Python * Add copyright on Python sample Co-authored-by: Shajan Dasan <[email protected]>
Python models that contain tf.function is inconvenient to be consumed by Java clients.
This proposal provides an API to
(a) Invoke a tf.function, given the signature name
(b) Retrieve the node name in the graph corresponding to a tf.function
TBD: Unit tests before this change is ready to merge.