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

include_optimizer parameter introduced to push_to_hub_keras() #616

Merged
merged 21 commits into from
Feb 2, 2022

Conversation

merveenoyan
Copy link
Contributor

@merveenoyan merveenoyan commented Jan 21, 2022

This PR addresses the discussion we had in #598.
I did a quick and dirty implementation and haven't tested yet so it's a WIP, I want to hear the review first.

For context: this parameter prevents models with custom optimizers (like the ones built with tfa) to be serialized and is by default set to True so I set it to False and made it an optional parameter.

cc: @osanseviero

Copy link
Member

@gante gante left a comment

Choose a reason for hiding this comment

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

Should solve the issue 👍

@@ -50,7 +52,7 @@ def save_pretrained_keras(
with open(path, "w") as f:
json.dump(config, f)

tf.keras.models.save_model(model, save_directory)
tf.keras.models.save_model(model, save_directory, include_optimizer)
Copy link
Member

Choose a reason for hiding this comment

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

The third argument of save_model is overwrite (doc), so we'll have to specify the keyword argument for include_optimizer

@osanseviero
Copy link
Contributor

Thanks for this PR!

Suggestion for future: before sending PRs for review, it's always good idea to test it at least locally since you might realize it does not work for X reason (wrong argument, weird TF bug, etc).

Anyways, overall looks good 👍 feel free to open the PR for official review once you've tested it and added some automated test as well

@ariG23498
Copy link
Contributor

Hey folks,

My two cents on this would be to use a **model_save_kwargs instead of include_optimizer. This would help us in using all the parameters of the tf.keras.models.save_model API with minimal changes.

WDYT?

@merveenoyan
Copy link
Contributor Author

@osanseviero @ariG23498's suggestion is neat. I don't know which choice to pick because we'll set it to False by default to handle the custom optimizers (like the ones that tfa offers) user has to set it to True if they want to push a model with one of the default optimizers. Maybe take include_optimizer only and take the rest with something like **model_save_kwargs?

@osanseviero
Copy link
Contributor

Yes, @merveenoyan. I think that sounds like a right approach and consistent with what we do in transformers and other places (setting include_optimizer to false and then other save args through **model_save_kwargs**)

@merveenoyan merveenoyan removed the request for review from osanseviero January 27, 2022 11:09
@merveenoyan
Copy link
Contributor Author

merveenoyan commented Jan 27, 2022

I tested this in multiple ways, first one was directly pushing it by include_optimizer = True which was successful.

Second one was adding save_traces = False (this is one of the **model_save_kwargs) which didn't push the custom layers (and given that I didn't implement get_config it failed to load, which is expected already). This is normally set as True by TensorFlow. Pushing is just fine but from_pretrained_keras() doesn't work (again, expected, up to user to set it to something different than default).
Ekran Resmi 2022-01-27 13 42 35
Ekran Resmi 2022-01-27 13 44 05

I also didn't include optimizer and saved the traces, then when loading I was asked to compile manually.
Ekran Resmi 2022-01-27 13 53 03

I wonder if the UX is good enough at this point, I think it's just fine (so I need someone to criticize this well) @ariG23498 @osanseviero
I'll only do style related formatting now.

merveenoyan and others added 2 commits January 27, 2022 15:09
Co-authored-by: Omar Sanseviero <osanseviero@users.noreply.github.com>
@ariG23498
Copy link
Contributor

@merveenoyan I think this works! Thanks for the great work 😄

Copy link
Member

@gante gante left a comment

Choose a reason for hiding this comment

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

LGTM

@merveenoyan
Copy link
Contributor Author

I'm writing automated tests at the moment, I will not merge yet. 🤓

@merveenoyan merveenoyan marked this pull request as ready for review January 28, 2022 15:25
@merveenoyan
Copy link
Contributor Author

@osanseviero last week I've removed the pytest assertions from the two new test cases (they weren't going to be raised so). Should I merge?

Copy link
Contributor

@osanseviero osanseviero left a comment

Choose a reason for hiding this comment

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

Thanks a lot for this PR! Overall looks good, but I think the tests could improve a bit 😄

src/huggingface_hub/keras_mixin.py Outdated Show resolved Hide resolved
include_optimizer (:obj:`bool`, `optional`):
Whether or not to include optimizer during serialization.
model_save_kwargs(:obj:`dict`, `optional`):
Arguments other than default arguments that can be passed to tf.keras.models.save_model().
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here :)

tests/test_keras_integration.py Outdated Show resolved Hide resolved
self.assertIn("saved_model.pb", files)
self.assertIn("keras_metadata.pb", files)
self.assertEqual(len(files), 4)

Copy link
Contributor

Choose a reason for hiding this comment

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

A second test that shows that the optimizer is not there by default would be a good idea

tests/test_keras_integration.py Outdated Show resolved Hide resolved
tests/test_keras_integration.py Show resolved Hide resolved
@osanseviero
Copy link
Contributor

Feel free to pin the black version 😄

@merveenoyan
Copy link
Contributor Author

merveenoyan commented Feb 1, 2022

AFTER FIGHTING BLACK FOR HOURS @osanseviero

Copy link
Contributor

@osanseviero osanseviero left a comment

Choose a reason for hiding this comment

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

Thanks a lot for this PR! I left a couple of improvement ideas but looks almost ready to merge! 🚀 🚀

Comment on lines 191 to 192
model = from_pretrained_keras(f"{WORKING_REPO_DIR}/{REPO_NAME}")
self.assertIsNone(model.optimizer)
Copy link
Contributor

Choose a reason for hiding this comment

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

I would suggest to avoid testing this as well in the same test. Maybe let's have a test which is
test_save_pretrained_does_not_save_optimizer_state_by_default which has this

tests/test_keras_integration.py Outdated Show resolved Hide resolved
tests/test_keras_integration.py Outdated Show resolved Hide resolved
tests/test_keras_integration.py Outdated Show resolved Hide resolved
tests/test_keras_integration.py Outdated Show resolved Hide resolved
tests/test_keras_integration.py Outdated Show resolved Hide resolved
tests/test_keras_integration.py Show resolved Hide resolved
tests/test_keras_integration.py Outdated Show resolved Hide resolved
@merveenoyan
Copy link
Contributor Author

@osanseviero on my local (checked black version) the quality test passes but here it fails. Any guesses?

@merveenoyan merveenoyan merged commit 97ed9b9 into main Feb 2, 2022
@merveenoyan merveenoyan deleted the keras_mixin_fix branch February 2, 2022 10:29
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.

4 participants