From ca4b20bd949d0434e6558ae5a9bdd6747e86dec4 Mon Sep 17 00:00:00 2001 From: rohitgr7 Date: Sat, 16 Jan 2021 01:34:23 +0530 Subject: [PATCH 1/7] fix and update tests --- .../callbacks/model_checkpoint.py | 4 +- pytorch_lightning/core/hooks.py | 4 +- pytorch_lightning/loggers/mlflow.py | 6 +- pytorch_lightning/trainer/properties.py | 16 +-- tests/trainer/properties/log_dir.py | 126 ++++++++++-------- 5 files changed, 83 insertions(+), 73 deletions(-) diff --git a/pytorch_lightning/callbacks/model_checkpoint.py b/pytorch_lightning/callbacks/model_checkpoint.py index e5c960b3c002b..5a4eba2dc996f 100644 --- a/pytorch_lightning/callbacks/model_checkpoint.py +++ b/pytorch_lightning/callbacks/model_checkpoint.py @@ -193,7 +193,7 @@ def on_pretrain_routine_start(self, trainer, pl_module): """ When pretrain routine starts we build the ckpt dir on the fly """ - self.__resolve_ckpt_dir(trainer, pl_module) + self.__resolve_ckpt_dir(trainer) self.save_function = trainer.save_checkpoint def on_validation_end(self, trainer, pl_module): @@ -447,7 +447,7 @@ def format_checkpoint_name( ckpt_name = f"{filename}{self.FILE_EXTENSION}" return os.path.join(self.dirpath, ckpt_name) if self.dirpath else ckpt_name - def __resolve_ckpt_dir(self, trainer, pl_module): + def __resolve_ckpt_dir(self, trainer): """ Determines model checkpoint save directory at runtime. References attributes from the trainer's logger to determine where to save checkpoints. diff --git a/pytorch_lightning/core/hooks.py b/pytorch_lightning/core/hooks.py index a87ebbeb47199..a1890fc39980a 100644 --- a/pytorch_lightning/core/hooks.py +++ b/pytorch_lightning/core/hooks.py @@ -283,8 +283,8 @@ def on_after_backward(self) -> None: def on_after_backward(self): # example to inspect gradient information in tensorboard if self.trainer.global_step % 25 == 0: # don't make the tf file huge - params = self.state_dict() - for k, v in params.items(): + params = self.named_parameters() + for k, v in params: self.logger.experiment.add_histogram( tag=k, values=v.grad, global_step=self.trainer.global_step ) diff --git a/pytorch_lightning/loggers/mlflow.py b/pytorch_lightning/loggers/mlflow.py index 4987d050c925d..fa7dec6b63b0f 100644 --- a/pytorch_lightning/loggers/mlflow.py +++ b/pytorch_lightning/loggers/mlflow.py @@ -21,11 +21,9 @@ from time import time from typing import Any, Dict, Optional, Union - from pytorch_lightning import _logger as log from pytorch_lightning.loggers.base import LightningLoggerBase, rank_zero_experiment -from pytorch_lightning.utilities import rank_zero_only, rank_zero_warn, _module_available - +from pytorch_lightning.utilities import _module_available, rank_zero_only, rank_zero_warn LOCAL_FILE_URI_PREFIX = "file:" @@ -190,7 +188,7 @@ def save_dir(self) -> Optional[str]: Return: Local path to the root experiment directory if the tracking uri is local. - Otherwhise returns `None`. + Otherwhise returns ``None``. """ if self._tracking_uri.startswith(LOCAL_FILE_URI_PREFIX): return self._tracking_uri.lstrip(LOCAL_FILE_URI_PREFIX) diff --git a/pytorch_lightning/trainer/properties.py b/pytorch_lightning/trainer/properties.py index 3fa2af79e5530..7aa0e7371c2ad 100644 --- a/pytorch_lightning/trainer/properties.py +++ b/pytorch_lightning/trainer/properties.py @@ -11,10 +11,10 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -from abc import ABC -from argparse import ArgumentParser, Namespace import inspect import os +from abc import ABC +from argparse import ArgumentParser, Namespace from typing import cast, List, Optional, Type, TypeVar, Union from pytorch_lightning.accelerators.accelerator import Accelerator @@ -63,16 +63,10 @@ class TrainerProperties(ABC): @property def log_dir(self): - if self.checkpoint_callback is not None: - dirpath = self.checkpoint_callback.dirpath - dirpath = os.path.split(dirpath)[0] - elif self.logger is not None: - if isinstance(self.logger, TensorBoardLogger): - dirpath = self.logger.log_dir - else: - dirpath = self.logger.save_dir + if self.logger is None: + dirpath = self.default_root_dir else: - dirpath = self._default_root_dir + dirpath = getattr(self.logger, 'log_dir' if isinstance(self.logger, TensorBoardLogger) else 'save_dir') if self.accelerator_backend is not None: dirpath = self.accelerator_backend.broadcast(dirpath) diff --git a/tests/trainer/properties/log_dir.py b/tests/trainer/properties/log_dir.py index 021bb04a7c917..f59cb358a253a 100644 --- a/tests/trainer/properties/log_dir.py +++ b/tests/trainer/properties/log_dir.py @@ -12,114 +12,132 @@ # See the License for the specific language governing permissions and # limitations under the License. import os -import torch + import pytest -from tests.base.boring_model import BoringModel, RandomDataset +import torch + from pytorch_lightning import Trainer +from pytorch_lightning.callbacks import ModelCheckpoint +from pytorch_lightning.loggers import TensorBoardLogger from pytorch_lightning.utilities import APEX_AVAILABLE from pytorch_lightning.utilities.exceptions import MisconfigurationException +from tests.base.boring_model import BoringModel, RandomDataset + + +class TestModel(BoringModel): + def __init__(self, expected_log_dir): + super().__init__() + self.expected_log_dir = expected_log_dir + + def training_step(self, *args, **kwargs): + assert self.trainer.log_dir == self.expected_log_dir + return super().training_step(*args, **kwargs) def test_logdir(tmpdir): """ Tests that the path is correct when checkpoint and loggers are used """ - class TestModel(BoringModel): - def training_step(self, batch, batch_idx): - output = self.layer(batch) - loss = self.loss(batch, output) + expected = os.path.join(tmpdir, 'lightning_logs', 'version_0') - expected = os.path.join(self.trainer.default_root_dir, 'lightning_logs', 'version_0') - assert self.trainer.log_dir == expected - return {"loss": loss} + model = TestModel(expected) - model = TestModel() - - limit_train_batches = 2 trainer = Trainer( default_root_dir=tmpdir, - limit_train_batches=limit_train_batches, - limit_val_batches=2, - max_epochs=1, + max_steps=2, ) + assert trainer.log_dir == expected trainer.fit(model) + assert trainer.log_dir == expected def test_logdir_no_checkpoint_cb(tmpdir): """ Tests that the path is correct with no checkpoint """ - class TestModel(BoringModel): - def training_step(self, batch, batch_idx): - output = self.layer(batch) - loss = self.loss(batch, output) - expected = os.path.join(self.trainer.default_root_dir, 'lightning_logs', 'version_0') - assert self.trainer.log_dir == expected - return {"loss": loss} - - model = TestModel() + expected = os.path.join(tmpdir, 'lightning_logs', 'version_0') + model = TestModel(expected) - limit_train_batches = 2 trainer = Trainer( default_root_dir=tmpdir, - limit_train_batches=limit_train_batches, - limit_val_batches=2, - max_epochs=1, + max_steps=2, checkpoint_callback=False ) + assert trainer.log_dir == expected trainer.fit(model) + assert trainer.log_dir == expected def test_logdir_no_logger(tmpdir): """ Tests that the path is correct even when there is no logger """ - class TestModel(BoringModel): - def training_step(self, batch, batch_idx): - output = self.layer(batch) - loss = self.loss(batch, output) - expected = os.path.join(self.trainer.default_root_dir) - assert self.trainer.log_dir == expected - return {"loss": loss} + expected = os.path.join(tmpdir) + model = TestModel(expected) - model = TestModel() - - limit_train_batches = 2 trainer = Trainer( default_root_dir=tmpdir, - limit_train_batches=limit_train_batches, - limit_val_batches=2, - max_epochs=1, + max_steps=2, logger=False, ) + assert trainer.log_dir == expected trainer.fit(model) + assert trainer.log_dir == expected def test_logdir_no_logger_no_checkpoint(tmpdir): """ Tests that the path is correct even when there is no logger """ - class TestModel(BoringModel): - def training_step(self, batch, batch_idx): - output = self.layer(batch) - loss = self.loss(batch, output) - expected = os.path.join(self.trainer.default_root_dir) - assert self.trainer.log_dir == expected - return {"loss": loss} - - model = TestModel() + expected = os.path.join(tmpdir) + model = TestModel(expected) - limit_train_batches = 2 trainer = Trainer( default_root_dir=tmpdir, - limit_train_batches=limit_train_batches, - limit_val_batches=2, - max_epochs=1, + max_steps=2, logger=False, checkpoint_callback=False ) + assert trainer.log_dir == expected + trainer.fit(model) + assert trainer.log_dir == expected + + +def test_logdir_custom_callback(tmpdir): + """ + Tests that the path is correct even when there is a custom callback + """ + expected = os.path.join(tmpdir, 'lightning_logs', 'version_0') + model = TestModel(expected) + + trainer = Trainer( + default_root_dir=tmpdir, + max_steps=2, + checkpoint_callback=ModelCheckpoint(dirpath=os.path.join(tmpdir, 'ckpts')) + ) + + assert trainer.log_dir == expected + trainer.fit(model) + assert trainer.log_dir == expected + + +def test_logdir_custom_logger(tmpdir): + """ + Tests that the path is correct even when there is a custom logger + """ + expected = os.path.join(tmpdir, 'custom_logs', 'version_0') + model = TestModel(expected) + + trainer = Trainer( + default_root_dir=tmpdir, + max_steps=2, + logger=TensorBoardLogger(save_dir=tmpdir, name='custom_logs') + ) + + assert trainer.log_dir == expected trainer.fit(model) + assert trainer.log_dir == expected From df1723689415cf0420a2968ab66b19a0ff18619a Mon Sep 17 00:00:00 2001 From: rohitgr7 Date: Sat, 16 Jan 2021 02:00:07 +0530 Subject: [PATCH 2/7] update with ModelCheckpoint --- tests/trainer/properties/log_dir.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/trainer/properties/log_dir.py b/tests/trainer/properties/log_dir.py index f59cb358a253a..2bc5c06955b69 100644 --- a/tests/trainer/properties/log_dir.py +++ b/tests/trainer/properties/log_dir.py @@ -45,6 +45,7 @@ def test_logdir(tmpdir): trainer = Trainer( default_root_dir=tmpdir, max_steps=2, + callbacks=[ModelCheckpoint(dirpath=tmpdir)], ) assert trainer.log_dir == expected @@ -81,6 +82,7 @@ def test_logdir_no_logger(tmpdir): default_root_dir=tmpdir, max_steps=2, logger=False, + callbacks=[ModelCheckpoint(dirpath=tmpdir)], ) assert trainer.log_dir == expected @@ -117,7 +119,7 @@ def test_logdir_custom_callback(tmpdir): trainer = Trainer( default_root_dir=tmpdir, max_steps=2, - checkpoint_callback=ModelCheckpoint(dirpath=os.path.join(tmpdir, 'ckpts')) + callbacks=[ModelCheckpoint(dirpath=os.path.join(tmpdir, 'ckpts'))], ) assert trainer.log_dir == expected @@ -135,6 +137,7 @@ def test_logdir_custom_logger(tmpdir): trainer = Trainer( default_root_dir=tmpdir, max_steps=2, + callbacks=[ModelCheckpoint(dirpath=tmpdir)], logger=TensorBoardLogger(save_dir=tmpdir, name='custom_logs') ) From 80187ff8f1a868c34568e48fb93dd60c0c0c6c9e Mon Sep 17 00:00:00 2001 From: rohitgr7 Date: Sat, 16 Jan 2021 02:29:45 +0530 Subject: [PATCH 3/7] chlog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3c2a33469f3b..f998f40780ac1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - Fixed `reinit_scheduler_properties` with correct optimizer ([#5519](https://github.com/PyTorchLightning/pytorch-lightning/pull/5519)) +- Fixed `log_dir` property ([#5537](https://github.com/PyTorchLightning/pytorch-lightning/pull/5537)) + + ## [1.1.4] - 2021-01-12 ### Added From ca248cd3930156d39de6dce7dc61f3bd9fbe96c4 Mon Sep 17 00:00:00 2001 From: rohitgr7 Date: Sun, 17 Jan 2021 02:24:57 +0530 Subject: [PATCH 4/7] wip wandb fix --- pytorch_lightning/loggers/wandb.py | 15 ++++++++++++--- tests/loggers/test_wandb.py | 8 +++++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/pytorch_lightning/loggers/wandb.py b/pytorch_lightning/loggers/wandb.py index f92c44ab27b7f..407c2d1c10d7e 100644 --- a/pytorch_lightning/loggers/wandb.py +++ b/pytorch_lightning/loggers/wandb.py @@ -23,7 +23,8 @@ import torch.nn as nn from pytorch_lightning.loggers.base import LightningLoggerBase, rank_zero_experiment -from pytorch_lightning.utilities import rank_zero_only, _module_available +from pytorch_lightning.utilities import _module_available, rank_zero_only +from pytorch_lightning.utilities.exceptions import MisconfigurationException from pytorch_lightning.utilities.warning_utils import WarningCache _WANDB_AVAILABLE = _module_available("wandb") @@ -98,6 +99,13 @@ def __init__( if wandb is None: raise ImportError('You want to use `wandb` logger which is not installed yet,' # pragma: no-cover ' install it with `pip install wandb`.') + + if offline and log_model: + raise MisconfigurationException( + f'log_model={log_model} and offline={offline} is an invalid configuration' + ' since model checkpoints cannot be uploaded in offline mode.' + ) + super().__init__() self._name = name self._save_dir = save_dir @@ -141,11 +149,12 @@ def experiment(self) -> Run: self._experiment = wandb.init( name=self._name, dir=self._save_dir, project=self._project, anonymous=self._anonymous, id=self._id, resume='allow', **self._kwargs) if wandb.run is None else wandb.run + # offset logging step when resuming a run self._step_offset = self._experiment.step + # save checkpoints in wandb dir to upload on W&B servers - if self._log_model: - self._save_dir = self._experiment.dir + self._save_dir = self._experiment.dir return self._experiment def watch(self, model: nn.Module, log: str = 'gradients', log_freq: int = 100): diff --git a/tests/loggers/test_wandb.py b/tests/loggers/test_wandb.py index a44b19ca39270..9b011849d7a60 100644 --- a/tests/loggers/test_wandb.py +++ b/tests/loggers/test_wandb.py @@ -13,13 +13,13 @@ # limitations under the License. import os import pickle -from unittest import mock -from argparse import ArgumentParser import types +from argparse import ArgumentParser +from unittest import mock from pytorch_lightning import Trainer from pytorch_lightning.loggers import WandbLogger -from tests.base import EvalModelTemplate, BoringModel +from tests.base import BoringModel, EvalModelTemplate def get_warnings(recwarn): @@ -152,6 +152,8 @@ def test_wandb_logger_dirs_creation(wandb, tmpdir): assert trainer.checkpoint_callback.dirpath == str(tmpdir / 'project' / version / 'checkpoints') assert set(os.listdir(trainer.checkpoint_callback.dirpath)) == {'epoch=0-step=9.ckpt'} + assert trainer.log_dir == logger.save_dir + assert 'output.log' in os.listdir(trainer.log_dir) def test_wandb_sanitize_callable_params(tmpdir): From 4167fff8ab21f600ab9c3a9fa65c98735be2f911 Mon Sep 17 00:00:00 2001 From: rohitgr7 Date: Sun, 17 Jan 2021 03:16:20 +0530 Subject: [PATCH 5/7] all fixed --- pytorch_lightning/loggers/mlflow.py | 2 +- pytorch_lightning/loggers/wandb.py | 3 ++- tests/loggers/test_comet.py | 21 ++++----------------- tests/loggers/test_mlflow.py | 5 +++-- tests/loggers/test_neptune.py | 4 +++- tests/loggers/test_tensorboard.py | 4 +++- tests/loggers/test_wandb.py | 16 ++++++++++++++-- 7 files changed, 30 insertions(+), 25 deletions(-) diff --git a/pytorch_lightning/loggers/mlflow.py b/pytorch_lightning/loggers/mlflow.py index fa7dec6b63b0f..929f070deb865 100644 --- a/pytorch_lightning/loggers/mlflow.py +++ b/pytorch_lightning/loggers/mlflow.py @@ -188,7 +188,7 @@ def save_dir(self) -> Optional[str]: Return: Local path to the root experiment directory if the tracking uri is local. - Otherwhise returns ``None``. + Otherwhise returns `None`. """ if self._tracking_uri.startswith(LOCAL_FILE_URI_PREFIX): return self._tracking_uri.lstrip(LOCAL_FILE_URI_PREFIX) diff --git a/pytorch_lightning/loggers/wandb.py b/pytorch_lightning/loggers/wandb.py index 407c2d1c10d7e..34121c3652509 100644 --- a/pytorch_lightning/loggers/wandb.py +++ b/pytorch_lightning/loggers/wandb.py @@ -154,7 +154,8 @@ def experiment(self) -> Run: self._step_offset = self._experiment.step # save checkpoints in wandb dir to upload on W&B servers - self._save_dir = self._experiment.dir + if self._save_dir is None: + self._save_dir = self._experiment.dir return self._experiment def watch(self, model: nn.Module, log: str = 'gradients', log_freq: int = 100): diff --git a/tests/loggers/test_comet.py b/tests/loggers/test_comet.py index fc61829645b6e..b272f98c8925d 100644 --- a/tests/loggers/test_comet.py +++ b/tests/loggers/test_comet.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. import os -from unittest.mock import patch, DEFAULT +from unittest.mock import DEFAULT, patch import pytest @@ -74,7 +74,7 @@ def test_comet_logger_online(comet): @patch('pytorch_lightning.loggers.comet.comet_ml') def test_comet_logger_no_api_key_given(comet): """ Test that CometLogger fails to initialize if both api key and save_dir are missing. """ - with pytest.raises(MisconfigurationException): + with pytest.raises(MisconfigurationException, match='requires either api_key or save_dir'): comet.config.get_api_key.return_value = None CometLogger(workspace='dummy-test', project_name='general') @@ -89,13 +89,10 @@ def test_comet_logger_experiment_name(comet): # Test api_key given with patch('pytorch_lightning.loggers.comet.CometExperiment') as comet_experiment: logger = CometLogger(api_key=api_key, experiment_name=experiment_name,) - assert logger._experiment is None _ = logger.experiment - comet_experiment.assert_called_once_with(api_key=api_key, project_name=None) - comet_experiment().set_name.assert_called_once_with(experiment_name) @@ -118,13 +115,10 @@ def save_os_environ(*args, **kwargs): with patch.dict(os.environ, {"COMET_EXPERIMENT_KEY": experiment_key}): with patch('pytorch_lightning.loggers.comet.CometExperiment', side_effect=save_os_environ) as comet_experiment: logger = CometLogger(api_key=api_key) - assert logger.version == experiment_key - assert logger._experiment is None _ = logger.experiment - comet_experiment.assert_called_once_with(api_key=api_key, project_name=None) assert instantation_environ["COMET_EXPERIMENT_KEY"] == experiment_key @@ -156,10 +150,12 @@ def test_comet_logger_dirs_creation(comet, comet_experiment, tmpdir, monkeypatch model = EvalModelTemplate() trainer = Trainer(default_root_dir=tmpdir, logger=logger, max_epochs=1, limit_val_batches=3) + assert trainer.log_dir == logger.save_dir trainer.fit(model) assert trainer.checkpoint_callback.dirpath == (tmpdir / 'test' / "1" / 'checkpoints') assert set(os.listdir(trainer.checkpoint_callback.dirpath)) == {'epoch=0-step=9.ckpt'} + assert trainer.log_dir == logger.save_dir @patch('pytorch_lightning.loggers.comet.comet_ml') @@ -170,11 +166,8 @@ def test_comet_name_default(comet): with patch('pytorch_lightning.loggers.comet.CometExperiment'): logger = CometLogger(api_key=api_key) - assert logger._experiment is None - assert logger.name == "comet-default" - assert logger._experiment is None @@ -187,11 +180,8 @@ def test_comet_name_project_name(comet): with patch('pytorch_lightning.loggers.comet.CometExperiment'): logger = CometLogger(api_key=api_key, project_name=project_name) - assert logger._experiment is None - assert logger.name == project_name - assert logger._experiment is None @@ -205,14 +195,11 @@ def test_comet_version_without_experiment(comet): with patch('pytorch_lightning.loggers.comet.CometExperiment'): logger = CometLogger(api_key=api_key, experiment_name=experiment_name) - assert logger._experiment is None first_version = logger.version assert first_version is not None - assert logger.version == first_version - assert logger._experiment is None _ = logger.experiment diff --git a/tests/loggers/test_mlflow.py b/tests/loggers/test_mlflow.py index c6072afbb69e2..c0f99220ed00b 100644 --- a/tests/loggers/test_mlflow.py +++ b/tests/loggers/test_mlflow.py @@ -13,11 +13,10 @@ # limitations under the License. import importlib.util import os - from unittest import mock from unittest.mock import MagicMock -import pytest +import pytest from pytorch_lightning import Trainer from pytorch_lightning.loggers import _MLFLOW_AVAILABLE, MLFlowLogger @@ -113,9 +112,11 @@ def test_mlflow_log_dir(client, mlflow, tmpdir): limit_train_batches=1, limit_val_batches=3, ) + assert trainer.log_dir == logger.save_dir trainer.fit(model) assert trainer.checkpoint_callback.dirpath == (tmpdir / "exp-id" / "run-id" / 'checkpoints') assert set(os.listdir(trainer.checkpoint_callback.dirpath)) == {'epoch=0-step=0.ckpt'} + assert trainer.log_dir == logger.save_dir def test_mlflow_logger_dirs_creation(tmpdir): diff --git a/tests/loggers/test_neptune.py b/tests/loggers/test_neptune.py index a6b91be4b0fbf..1580ac6e9784c 100644 --- a/tests/loggers/test_neptune.py +++ b/tests/loggers/test_neptune.py @@ -11,7 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -from unittest.mock import patch, MagicMock +from unittest.mock import MagicMock, patch import torch @@ -112,7 +112,9 @@ def _run_training(logger): limit_train_batches=0.05, logger=logger, ) + assert trainer.log_dir is None trainer.fit(model) + assert trainer.log_dir is None return logger logger_close_after_fit = _run_training(NeptuneLogger(offline_mode=True)) diff --git a/tests/loggers/test_tensorboard.py b/tests/loggers/test_tensorboard.py index 148ad550e74c7..3195279cf9896 100644 --- a/tests/loggers/test_tensorboard.py +++ b/tests/loggers/test_tensorboard.py @@ -35,9 +35,11 @@ def test_tensorboard_hparams_reload(tmpdir): model = EvalModelTemplate() trainer = Trainer(max_epochs=1, default_root_dir=tmpdir) + assert trainer.log_dir == trainer.logger.log_dir trainer.fit(model) - folder_path = trainer.logger.log_dir + assert trainer.log_dir == trainer.logger.log_dir + folder_path = trainer.log_dir # make sure yaml is there with open(os.path.join(folder_path, "hparams.yaml")) as file: diff --git a/tests/loggers/test_wandb.py b/tests/loggers/test_wandb.py index 9b011849d7a60..c297633e9a516 100644 --- a/tests/loggers/test_wandb.py +++ b/tests/loggers/test_wandb.py @@ -17,8 +17,11 @@ from argparse import ArgumentParser from unittest import mock +import pytest + from pytorch_lightning import Trainer from pytorch_lightning.loggers import WandbLogger +from pytorch_lightning.utilities.exceptions import MisconfigurationException from tests.base import BoringModel, EvalModelTemplate @@ -94,6 +97,7 @@ class Experiment: """ """ id = 'the_id' step = 0 + dir = 'wandb' def project_name(self): return 'the_project_name' @@ -109,6 +113,7 @@ def project_name(self): ) # Access the experiment to ensure it's created assert trainer.logger.experiment, 'missing experiment' + assert trainer.log_dir == logger.save_dir pkl_bytes = pickle.dumps(trainer) trainer2 = pickle.loads(pkl_bytes) @@ -147,13 +152,13 @@ def test_wandb_logger_dirs_creation(wandb, tmpdir): version = logger.version model = EvalModelTemplate() - trainer = Trainer(default_root_dir=tmpdir, logger=logger, max_epochs=1, limit_val_batches=3) + trainer = Trainer(default_root_dir=tmpdir, logger=logger, max_epochs=1, limit_val_batches=3, log_every_n_steps=1) + assert trainer.log_dir == logger.save_dir trainer.fit(model) assert trainer.checkpoint_callback.dirpath == str(tmpdir / 'project' / version / 'checkpoints') assert set(os.listdir(trainer.checkpoint_callback.dirpath)) == {'epoch=0-step=9.ckpt'} assert trainer.log_dir == logger.save_dir - assert 'output.log' in os.listdir(trainer.log_dir) def test_wandb_sanitize_callable_params(tmpdir): @@ -184,3 +189,10 @@ def wrapper_something(): assert params["something"] == "something" assert params["wrapper_something"] == "wrapper_something" assert params["wrapper_something_wo_name"] == "" + + +@mock.patch('pytorch_lightning.loggers.wandb.wandb') +def test_wandb_logger_offline_log_model(wandb, tmpdir): + """ Test that log_model=True raises an error in offline mode """ + with pytest.raises(MisconfigurationException, match='checkpoints cannot be uploaded in offline mode'): + logger = WandbLogger(save_dir=str(tmpdir), offline=True, log_model=True) From 9f817d4191111ba5040b847ea313a80596270f94 Mon Sep 17 00:00:00 2001 From: Jirka Borovec Date: Fri, 29 Jan 2021 15:33:10 +0100 Subject: [PATCH 6/7] hint Co-authored-by: chaton --- pytorch_lightning/loggers/wandb.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pytorch_lightning/loggers/wandb.py b/pytorch_lightning/loggers/wandb.py index 34121c3652509..0c3222851e13b 100644 --- a/pytorch_lightning/loggers/wandb.py +++ b/pytorch_lightning/loggers/wandb.py @@ -102,8 +102,9 @@ def __init__( if offline and log_model: raise MisconfigurationException( - f'log_model={log_model} and offline={offline} is an invalid configuration' - ' since model checkpoints cannot be uploaded in offline mode.' + f'Providing log_model={log_model} and offline={offline} is an invalid configuration' + ' since model checkpoints cannot be uploaded in offline mode.\n' + 'Hint: Set `offline=False` to log your model.' ) super().__init__() From 81b82c92c2563014af63cd9a00bf75a904faefc7 Mon Sep 17 00:00:00 2001 From: rohitgr7 Date: Tue, 2 Feb 2021 22:17:21 +0530 Subject: [PATCH 7/7] rev --- pytorch_lightning/core/hooks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pytorch_lightning/core/hooks.py b/pytorch_lightning/core/hooks.py index a1890fc39980a..a87ebbeb47199 100644 --- a/pytorch_lightning/core/hooks.py +++ b/pytorch_lightning/core/hooks.py @@ -283,8 +283,8 @@ def on_after_backward(self) -> None: def on_after_backward(self): # example to inspect gradient information in tensorboard if self.trainer.global_step % 25 == 0: # don't make the tf file huge - params = self.named_parameters() - for k, v in params: + params = self.state_dict() + for k, v in params.items(): self.logger.experiment.add_histogram( tag=k, values=v.grad, global_step=self.trainer.global_step )