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

[refactor] Extend WandbLogger to log config variables, entity and kwargs #1129

Closed
wants to merge 9 commits into from

Conversation

ayulockin
Copy link
Contributor

@ayulockin ayulockin commented Oct 20, 2021

  1. I was going through the WandbLogger class that was recently added to this library. Since MMF is a config-first framework, it would be great to log the config file to keep track of what's going in the model training/evaluation process.

    The effect of this small change can be seen through the before and after screenshots. One can compare one experiment from another by comparing the config.

    Before:
    image

    After:
    image

  2. I have also added another argument to pass entity to wandb.init. Explicit mention of this will help users who are using a W&B Teams account.

  3. Extra arguments to the wandb.init() can be passed via the config file.

  4. Ability to log learning rate over time.

PS: I am learning about this library and will be using it for personal work. Since I am also affiliated with Weights and Biases, I will be creating some PRs to add functionalities to the logger that might be useful for everyone. :)

…rgs (#1)

ability to log config file, initialize wandb with kwargs and pass entity argument for teams account.
@facebook-github-bot facebook-github-bot added the CLA Signed Do not delete this pull request or issue due to inactivity. label Oct 20, 2021
Copy link
Contributor

@ebsmothers ebsmothers 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 contributing to MMF. The changes look good overall. One small request: can you also update the docs to improve the visibility of the change?

@ayulockin
Copy link
Contributor Author

Hey @ebsmothers, I cleaned the code a bit more and updated the docs. Would love your feedback.

Copy link
Contributor

@ebsmothers ebsmothers 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 updating the diff. I've left a couple suggestions on how we can better handle init_kwargs, please let me know if anything is unclear :)

Comment on lines 431 to 440
self._wandb_init = dict(
entity=entity, name=name, project=project, dir=save_dir, config=config
)

init_kwargs = dict(
itertools.islice(
config.training.wandb.items(), 4, len(config.training.wandb)
)
)
self._wandb_init.update(**init_kwargs)
Copy link
Contributor

Choose a reason for hiding this comment

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

Actually I think the previous version was better, since now we are assuming a specific ordering in the WandB training config (i.e. that the keys corresponding to init_kwargs will come last, which in general will not be true).

Suggested change
self._wandb_init = dict(
entity=entity, name=name, project=project, dir=save_dir, config=config
)
init_kwargs = dict(
itertools.islice(
config.training.wandb.items(), 4, len(config.training.wandb)
)
)
self._wandb_init.update(**init_kwargs)
self._wandb_init = dict(**init_kwargs)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This makes sense. Yes removing this assumption is better.

@@ -58,11 +58,12 @@ def __init__(self, config, trainer):
if env_wandb_logdir:
log_dir = env_wandb_logdir

wandb_projectname = config.training.wandb.wandb_projectname
wandb_runname = config.training.wandb.wandb_runname

self.wandb_logger = WandbLogger(
Copy link
Contributor

Choose a reason for hiding this comment

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

Here you can just pass in wandb init_kwargs straightaway from config.training.wandb (without explicitly declaring entity, project, ... fields). Just unpack config.training.wandb and pass it all in at once, similar to what's done with lightning_params_dict here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for sharing the code snippet. I will make this change and commit.


Raises:
ImportError: If wandb package is not installed.
"""

def __init__(
self,
entity: Optional[str] = None,
Copy link
Contributor

Choose a reason for hiding this comment

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

Here you can just keep **init_kwargs and remove all the other parameters. This way it will be more flexible, and users can still find all the relevant fields enumerated in the docs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will it be okay if we can at least keep the current set of parameters and add **init_kwargs? Explicit mention of some of the arguments will be useful for the users in my opinion, especially, entity since anyone willing to log to a team account needs this and project to pass in the name of the project.

As per your suggestion, we can achieve wandb.init() just by passing **init_kwargs. It's just a matter of explicit vs implicit mention of a few important args.

@ayulockin
Copy link
Contributor Author

ayulockin commented Oct 26, 2021

I have made the changes as per your suggestions. I just explicitly defined entity and project arguments in the WandbLogger. All other arguments are parsed using omegaconf the way it's used here but added this in the WandbLogger itself so that in future I can keep extending the same.

I have also updated the docs to reflect the same.

@facebook-github-bot
Copy link
Contributor

@ebsmothers has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@ayulockin
Copy link
Contributor Author

ayulockin commented Nov 1, 2021

Hey @ebsmothers is there any update on this PR? Would love to know if I need to make any changes. :)

@facebook-github-bot
Copy link
Contributor

@ayulockin has updated the pull request. You must reimport the pull request before landing.

@ebsmothers
Copy link
Contributor

Hi @ayulockin sorry for the delay and thanks for your patience. After a bit more consideration I decided we do not need to use open_dict for this case. To save you the trouble, I went ahead and updated the PR myself (with one other minor change). Thanks :)

@facebook-github-bot
Copy link
Contributor

@ebsmothers has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

mmf/utils/logger.py Outdated Show resolved Hide resolved
@facebook-github-bot
Copy link
Contributor

@ayulockin has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@ebsmothers has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@ayulockin has updated the pull request. You must reimport the pull request before landing.

@ayulockin
Copy link
Contributor Author

Hey @ebsmothers, the change to deepcopy(config.training.wandb) threw an error: "DictConfig has no attribute pop" when wandb_kwargs.pop("enabled") was called so changed the type to dict.

@facebook-github-bot
Copy link
Contributor

@ebsmothers has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

facebook-github-bot pushed a commit that referenced this pull request Nov 23, 2021
Summary:
🚀 I have extended the `WandbLogger` with the ability to log the `current.pt` checkpoint as W&B Artifacts. Note that this PR is based on top of this [PR](#1129).

### What is W&B Artifacts?

> W&B Artifacts was designed to make it effortless to version your datasets and models, regardless of whether you want to store your files with us or whether you already have a bucket you want us to track. Once you've tracked your dataset or model files, W&B will automatically log each and every modification, giving you a complete and auditable history of changes to your files.

Through this PR, W&B Artifacts can help save and organize machine learning models throughout a project's lifecycle. More details in the documentation [here](https://docs.wandb.ai/guides/artifacts/model-versioning).

### Modification

This PR adds a `log_model_checkpoint` method to the `WandbLogger` class in the `utils/logger.py` file. This method is called in the `utils/checkpoint.py` file.

### Usage

To use this, in the `config/defaults.yaml` do, `training.wandb.enabled=true` and `training.wandb.log_checkpoint=true`.

### Result

The screenshot shows the `current.pt` checkpoints saved at intervals defined by `training.checkpoint_interval`. You can check out the logged artifacts page [here](https://wandb.ai/ayut/mmf/artifacts/model/run_ey9xextf_model/0dc64164acbdc300fd01/api).

![image](https://user-images.githubusercontent.com/31141479/139390462-d5c8445e-5c20-4fdd-85d0-51ef64846bf0.png)

### Superpowers

With this small addition, now one can easily track different versions of the model, download a checkpoint of interest by using the API in the API tab, easily share the checkpoints with teammates, etc.

### Requests

This is a draft PR as there are a few more things that can be improved here.

* Is there a better way to access the path to the `current.pt` checkpoint? Rather is the modification made to `utils/checkpoint.py` an acceptable way of approaching this?

* While logging a file as W&B artifacts we can also provide metadata associated with that file. In this case, we can add current iteration, training metrics, etc. as the metadata. Would love to get suggestions about the different data points that I should log as metadata alongside the checkpoints.

* How to determine if a checkpoint is the best one? If a checkpoint is best I can add `best` as an alias for that checkpoint's artifact.

Pull Request resolved: #1137

Test Plan:
Imported from GitHub, without a `Test Plan:` line.

**Static Docs Preview: mmf**
|[Full Site](https://our.intern.facebook.com/intern/staticdocs/eph/D32402090/V6/mmf/)|

|**Modified Pages**|
|[docs/notes/logger](https://our.intern.facebook.com/intern/staticdocs/eph/D32402090/V6/mmf/docs/notes/logger/)|

Reviewed By: apsdehal

Differential Revision: D32402090

Pulled By: ebsmothers

fbshipit-source-id: 94b881ec55c4197301331d571bc926521e2feecc
@ayulockin
Copy link
Contributor Author

Closing this PR in favor of #1137.

@ayulockin ayulockin closed this Nov 24, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed Do not delete this pull request or issue due to inactivity.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants