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

add legacy load utility #9166

Merged
merged 64 commits into from
Sep 23, 2021
Merged

add legacy load utility #9166

merged 64 commits into from
Sep 23, 2021

Conversation

awaelchli
Copy link
Contributor

@awaelchli awaelchli commented Aug 27, 2021

What does this PR do?

Splits changes off #8558

Adds a context manager to handle legacy checkpoints that have pickled attributes in the content that was removed from lightning in new versions. The currently known ones are:

  • pytorch_lightning.utilities.argparse_utils (renamed, slated for removal)
  • pytorch_lightning.utilities.argparse._gpus_arg_default (dead code)

We can remove these dead code pieces and instead dynamically patch modules to re-route the imports.
The following works:

    with pl_legacy_patch():
        # this would normally result in ImportError
        from pytorch_lightning.utilities.argparse import _gpus_arg_default

Does your PR introduce any breaking changes? If yes, please list them.

Before submitting

  • Was this discussed/approved via a GitHub issue? (not for typos and docs)
  • 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?
  • Did you make sure to update the documentation with your changes? (if necessary)
  • Did you write any new necessary tests? (not for typos and docs)
  • Did you verify new and existing tests pass locally with your changes?
  • Did you update the CHANGELOG? (not for typos, docs, test updates, or internal minor changes/refactorings)

PR review

Anyone in the community is free to review the PR once the tests have passed.
Before you start reviewing make sure you have read Review guidelines. In short, see the following bullet-list:

  • Is this pull request ready for review? (if not, please submit in draft mode)
  • Check that all items from Before submitting are resolved
  • Make sure the title is self-explanatory and the description concisely explains the PR
  • Add labels and milestones (and optionally projects) to the PR so it can be classified

Did you have fun?

I made sure I had fun coding 🙃

@mergify mergify bot added ready PRs ready to be merged has conflicts and removed has conflicts labels Aug 30, 2021
@awaelchli
Copy link
Contributor Author

awaelchli commented Sep 1, 2021

shall include such case to testing of legacy checkpoints?

@Borda sorry I missed your question.
Are you suggesting to add a 1.2.8 legacy checkpoint to https://pl-public-data.s3.amazonaws.com/legacy/checkpoints.zip ?

Of course, I made sure that the legacy patch works with the old checkpoints. Below is the code I used to verify it.
I can provide the checkpoint file and we can make a test for it but seems a bit overkill imo.

Since we know what the legacy format was, the unit tests that I added should suffice.

import torch
from argparse import ArgumentParser
from torch.utils.data import Dataset

from pytorch_lightning import LightningModule, Trainer


class RandomDataset(Dataset):
    def __init__(self, size, length):
        self.len = length
        self.data = torch.randn(length, size)

    def __getitem__(self, index):
        return self.data[index]

    def __len__(self):
        return self.len


class BoringModel(LightningModule):
    def __init__(self, **kwargs):
        super().__init__()
        self.save_hyperparameters(kwargs)
        self.layer = torch.nn.Linear(32, 2)

    def forward(self, x):
        return self.layer(x)

    def loss(self, batch, prediction):
        # An arbitrary loss to have a loss that updates the model weights during `Trainer.fit` calls
        return torch.nn.functional.mse_loss(prediction, torch.ones_like(prediction))

    def step(self, x):
        x = self.layer(x)
        out = torch.nn.functional.mse_loss(x, torch.ones_like(x))
        return out

    def training_step(self, batch, batch_idx):
        output = self.layer(batch)
        loss = self.loss(batch, output)
        return {"loss": loss}

    def training_step_end(self, training_step_outputs):
        return training_step_outputs

    def training_epoch_end(self, outputs) -> None:
        torch.stack([x["loss"] for x in outputs]).mean()

    def configure_optimizers(self):
        optimizer = torch.optim.SGD(self.layer.parameters(), lr=0.1)
        lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=1)
        return [optimizer], [lr_scheduler]


def run_1_2_7():
    # RUN WITH LIGHTNING 1.2.7

    # fake data
    train_data = torch.utils.data.DataLoader(RandomDataset(32, 64))

    # model
    parser = ArgumentParser()
    parser = Trainer.add_argparse_args(parser)
    args = parser.parse_args()
    trainer = Trainer.from_argparse_args(args, default_root_dir="legacy_logs1.2.7", max_steps=1)
    model = BoringModel(**vars(args))
    trainer.fit(model, train_data)
    print(trainer.checkpoint_callback.best_model_path)


def run_master():
    # RUN WITH LIGHTNING 1.2.7
    from pytorch_lightning.utilities.migration import pl_legacy_patch

    with pl_legacy_patch():  # without this, pickle error!
        # can unpickle!
        x = torch.load("legacy_logs1.2.7/lightning_logs/version_2/checkpoints/epoch=0-step=0.ckpt")
        assert callable(x["hyper_parameters"]["gpus"])


if __name__ == "__main__":
    run_master()

@awaelchli awaelchli mentioned this pull request Sep 9, 2021
@stale stale bot added the won't fix This will not be worked on label Sep 16, 2021
@awaelchli awaelchli added this to the v1.5 milestone Sep 16, 2021
@stale stale bot removed the won't fix This will not be worked on label Sep 16, 2021
Copy link
Member

@Borda Borda left a comment

Choose a reason for hiding this comment

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

great solution and pattern for future similar changes!
@awaelchli mind resolve conflicts? 🐰

@Lightning-AI Lightning-AI deleted a comment from stale bot Sep 23, 2021
@mergify mergify bot removed the has conflicts label Sep 23, 2021
@awaelchli awaelchli enabled auto-merge (squash) September 23, 2021 08:48
@awaelchli awaelchli merged commit 87b11fb into master Sep 23, 2021
@awaelchli awaelchli deleted the feature/callback-state/legacy branch September 23, 2021 09:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
checkpointing Related to checkpointing 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.

4 participants