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

Support **DictConfig hparam serialization #2519

Merged
merged 4 commits into from Aug 12, 2020
Merged

Support **DictConfig hparam serialization #2519

merged 4 commits into from Aug 12, 2020

Conversation

romesco
Copy link
Contributor

@romesco romesco commented Jul 5, 2020

What does this PR do?

Context: Passing an unpacked DictConfig to __init__() and then calling save_hyperparameters()

Bug: save_hyperparameters() deals with the unpacked DictConfig as a dict which might still contain values of type DictConfig. Upon serialization during saving, this errors out because it is handled with yaml.dump().

Fix: Enables OmegaConf to serialize the object as originally intended by casting back to a DictConfig.

Fixes: #2844

Before submitting

  • Was this discussed/approved via a Github issue? (no need for typos and docs improvements)
  • Did you read the contributor guideline, Pull Request section?
  • Did you make sure your PR does only one thing, instead of bundling different changes together? Otherwise, we ask you to create a separate PR for every change.
  • Did you make sure to update the documentation with your changes?
  • Did you write any new necessary tests?
  • Did you verify new and existing tests pass locally with your changes?
  • If you made a notable change (that affects users), did you update the CHANGELOG?

PR review

Anyone in the community is free to review the PR once the tests have passed.
If we didn't discuss your PR in Github issues there's a high chance it will not be merged.

Did you have fun?

Always.

@pep8speaks
Copy link

pep8speaks commented Jul 5, 2020

Hello @romesco! Thanks for updating this PR.

There are currently no PEP 8 issues detected in this Pull Request. Cheers! 🍻

Comment last updated at 2020-08-11 10:03:26 UTC

@mergify mergify bot requested a review from a team July 5, 2020 23:21
@romesco
Copy link
Contributor Author

romesco commented Jul 5, 2020

Let me update this to actual casting, I was using the OmegaConf API, but this is likely creating a new object which is definitely not memory efficient...

@romesco
Copy link
Contributor Author

romesco commented Jul 6, 2020

For a bit more clarification, this is fixing the case where the LightningModule is defined like the following example:

class LightningTemplateModel(LightningModule):
    def __init__(self,
                 in_features: int = 28 * 28,
                 hidden_dim: int = 1000,
                 out_features: int = 10,
                 drop_prob: float = 0.2,
                 batch_size: int = 2,
                 learning_rate: float = 0.001 * 8,
                 optimizer_name: str = 'adam',
                 data_root: str = './datasets',
                 ds = None,
                 **kwargs
                 ):
        # init superclass
        super().__init__()
        self.save_hyperparameters()

followed by this constructor call:

model = LightningTemplateModel(**cfg.model, **cfg.data)

where cfg is a DictConfig from omegaconf.

I am unpacking the cfg before using it. I have a slight preference for this over passing the DictConfig directly because it respects the default keyword args. If something is missing from the cfg, the default in keyword args fills it in. It seems that the best practices interface for a LightningModule will list out all the arguments with defaults like above as it is way more explicit and easy to use. Although one could define a set of defaults in the DictConfig format, I doubt a majority of users who want to exchange portable models will do that. So far it seems either people include defaults in the add_model_specific_args() or now as a part of the __init__() signature.

With that in mind, I would prefer to unpack, but that leads me to the issue where save_hyperparameters() sees the args as their own items which might be DictConfigs themselves [this happens when OmegaConf creates a heirarchical DictConfig I guess]. That's what this fix addresses. There might be a better way to do this, and I'm open to suggestions from others of course!

@romesco romesco changed the title Support DictConfig hparam serialization Support **DictConfig hparam serialization Jul 6, 2020
@Borda Borda self-assigned this Jul 6, 2020
@omry
Copy link
Contributor

omry commented Jul 6, 2020

I don't understand what is an 'unpacked DictConfig'. What are you actually passing in as hparams?

Looking at the fix, it does not make much sense to me.

@Borda
Copy link
Member

Borda commented Jul 6, 2020

I don't understand what is an 'unpacked DictConfig'. What are you actually passing in as hparams?

like this LightningTemplateModel(**cfg.model, **cfg.data)

Looking at the fix, it does not make much sense to me.

and what you dont like?

@omry
Copy link
Contributor

omry commented Jul 6, 2020

I see, so you a dict that have some DictConfig objects in it?
now it makes more sense.

@williamFalcon williamFalcon changed the title Support **DictConfig hparam serialization [WIP] Support **DictConfig hparam serialization Jul 9, 2020
Copy link
Contributor

@omry omry left a comment

Choose a reason for hiding this comment

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

lgtm

@Borda Borda added the feature Is an improvement or enhancement label Jul 18, 2020
@romesco romesco marked this pull request as ready for review July 19, 2020 21:10
@romesco romesco changed the title [WIP] Support **DictConfig hparam serialization Support **DictConfig hparam serialization Jul 22, 2020
Copy link
Member

@justusschock justusschock left a comment

Choose a reason for hiding this comment

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

almost good, just some minor changes

pytorch_lightning/core/saving.py Outdated Show resolved Hide resolved
pytorch_lightning/core/saving.py Outdated Show resolved Hide resolved
@mergify mergify bot requested a review from a team August 6, 2020 06:09
@Borda Borda added this to the 0.9.0 milestone Aug 6, 2020
@codecov
Copy link

codecov bot commented Aug 7, 2020

Codecov Report

Merging #2519 into master will increase coverage by 1%.
The diff coverage is 100%.

@@           Coverage Diff           @@
##           master   #2519    +/-   ##
=======================================
+ Coverage      89%     90%    +1%     
=======================================
  Files          80      80            
  Lines        7531    7425   -106     
=======================================
- Hits         6738    6709    -29     
+ Misses        793     716    -77     

@romesco
Copy link
Contributor Author

romesco commented Aug 7, 2020

Made all the requested changes. All (non docs) CI tests are passing!

@@ -17,7 +17,7 @@
try:
from omegaconf import OmegaConf
except ImportError:
Container = None
pass
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you want OmegaConf = None here, otherwise you are accessing an uninitialized variable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ah you're right, forgot after removing Container to replace this

@mergify mergify bot requested a review from a team August 7, 2020 13:12
@mergify
Copy link
Contributor

mergify bot commented Aug 7, 2020

This pull request is now in conflict... :(

@Borda Borda changed the title Support **DictConfig hparam serialization [blocked by #2639] Support **DictConfig hparam serialization Aug 7, 2020
@romesco
Copy link
Contributor Author

romesco commented Aug 7, 2020

@Borda is this actually [blocked by #2639]?

if anything, it seems like it's blocking #2639 😅

Either way, enabling this enhancement is IMO much more minor than that PR which definitely still needs more discussion. =]

@Borda Borda changed the title [blocked by #2639] Support **DictConfig hparam serialization Support **DictConfig hparam serialization Aug 7, 2020
@Borda Borda assigned yukw777 and nateraw and unassigned Borda Aug 7, 2020
@Borda Borda added the ready PRs ready to be merged label Aug 11, 2020
@mergify mergify bot requested a review from a team August 11, 2020 10:18
@mergify mergify bot requested a review from a team August 11, 2020 16:28
@williamFalcon williamFalcon merged commit f9d88f8 into Lightning-AI:master Aug 12, 2020
ameliatqy pushed a commit to ameliatqy/pytorch-lightning that referenced this pull request Aug 17, 2020
* change to OmegaConf API

Co-authored-by: Omry Yadan <omry@fb.com>

* Swapped Container for OmegaConf sentinel; Limited ds copying

* Add Namespace check.

* Container removed. Pass local tests.

Co-authored-by: Omry Yadan <omry@fb.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Is an improvement or enhancement ready PRs ready to be merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Tensorboard logger fails to save model OmegaConf hparams
8 participants