From d8ba5f3dae87c083a6b971ad13088b0ede105d73 Mon Sep 17 00:00:00 2001 From: stanbiryukov Date: Fri, 22 Apr 2022 18:19:57 -0500 Subject: [PATCH 1/4] remove deprecated test_tube logger --- .gitignore | 3 - docs/source/api_references.rst | 1 - .../source/common/evaluation_intermediate.rst | 2 +- pyproject.toml | 1 - pytorch_lightning/loggers/test_tube.py | 251 ------------------ requirements/loggers.txt | 1 - tests/deprecated_api/test_remove_1-7.py | 8 +- 7 files changed, 2 insertions(+), 265 deletions(-) delete mode 100644 pytorch_lightning/loggers/test_tube.py diff --git a/.gitignore b/.gitignore index 923c2a1829c22..e9bcc4cfd385f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,9 +7,6 @@ pip-wheel-metadata/ lightning_logs/ .vscode/ -# Test-tube -test_tube_*/ - # Documentations docs/source/api docs/source/*.md diff --git a/docs/source/api_references.rst b/docs/source/api_references.rst index 239e5085eddab..17ed5b6dc5a81 100644 --- a/docs/source/api_references.rst +++ b/docs/source/api_references.rst @@ -93,7 +93,6 @@ loggers mlflow neptune tensorboard - test_tube wandb loops diff --git a/docs/source/common/evaluation_intermediate.rst b/docs/source/common/evaluation_intermediate.rst index 7c0ca00029937..d452938f1f797 100644 --- a/docs/source/common/evaluation_intermediate.rst +++ b/docs/source/common/evaluation_intermediate.rst @@ -82,7 +82,7 @@ To run the test set on a pre-trained model, use this method. model = MyLightningModule.load_from_checkpoint( checkpoint_path="/path/to/pytorch_checkpoint.ckpt", - hparams_file="/path/to/test_tube/experiment/version/hparams.yaml", + hparams_file="/path/to/experiment/version/hparams.yaml", map_location=None, ) diff --git a/pyproject.toml b/pyproject.toml index e978317b01500..bace2601b36a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,7 +61,6 @@ module = [ "pytorch_lightning.loggers.mlflow", "pytorch_lightning.loggers.neptune", "pytorch_lightning.loggers.tensorboard", - "pytorch_lightning.loggers.test_tube", "pytorch_lightning.loggers.wandb", "pytorch_lightning.loops.epoch.training_epoch_loop", "pytorch_lightning.strategies.ddp", diff --git a/pytorch_lightning/loggers/test_tube.py b/pytorch_lightning/loggers/test_tube.py deleted file mode 100644 index b456cc5220da3..0000000000000 --- a/pytorch_lightning/loggers/test_tube.py +++ /dev/null @@ -1,251 +0,0 @@ -# Copyright The PyTorch Lightning team. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -""" -Test Tube Logger ----------------- -""" -from argparse import Namespace -from typing import Any, Dict, Optional, Union - -import pytorch_lightning as pl -from pytorch_lightning.loggers.logger import Logger, rank_zero_experiment -from pytorch_lightning.utilities import _module_available -from pytorch_lightning.utilities.logger import _add_prefix, _convert_params, _flatten_dict -from pytorch_lightning.utilities.rank_zero import rank_zero_deprecation, rank_zero_only, rank_zero_warn - -_TESTTUBE_AVAILABLE = _module_available("test_tube") - -if _TESTTUBE_AVAILABLE: - from test_tube import Experiment -else: - Experiment = None - - -class TestTubeLogger(Logger): - r""" - Log to local file system in `TensorBoard `_ format - but using a nicer folder structure (see `full docs `_). - - Warning: - The test-tube package is no longer maintained and PyTorch Lightning will remove the :class:´TestTubeLogger´ - in v1.7.0. - - Install it with pip: - - .. code-block:: bash - - pip install test_tube - - .. code-block:: python - - from pytorch_lightning import Trainer - from pytorch_lightning.loggers import TestTubeLogger - - logger = TestTubeLogger("tt_logs", name="my_exp_name") - trainer = Trainer(logger=logger) - - Use the logger anywhere in your :class:`~pytorch_lightning.core.lightning.LightningModule` as follows: - - .. code-block:: python - - from pytorch_lightning import LightningModule - - - class LitModel(LightningModule): - def training_step(self, batch, batch_idx): - # example - self.logger.experiment.whatever_method_summary_writer_supports(...) - - def any_lightning_module_function_or_hook(self): - self.logger.experiment.add_histogram(...) - - Args: - save_dir: Save directory - name: Experiment name. Defaults to ``'default'``. - description: A short snippet about this experiment - debug: If ``True``, it doesn't log anything. - version: Experiment version. If version is not specified the logger inspects the save - directory for existing versions, then automatically assigns the next available version. - create_git_tag: If ``True`` creates a git tag to save the code used in this experiment. - log_graph: Adds the computational graph to tensorboard. This requires that - the user has defined the `self.example_input_array` attribute in their - model. - prefix: A string to put at the beginning of metric keys. - - Raises: - ModuleNotFoundError: - If required TestTube package is not installed on the device. - """ - - __test__ = False - LOGGER_JOIN_CHAR = "-" - - def __init__( - self, - save_dir: str, - name: str = "default", - description: Optional[str] = None, - debug: bool = False, - version: Optional[int] = None, - create_git_tag: bool = False, - log_graph: bool = False, - prefix: str = "", - ): - rank_zero_deprecation( - "The TestTubeLogger is deprecated since v1.5 and will be removed in v1.7. We recommend switching to the" - " `pytorch_lightning.loggers.TensorBoardLogger` as an alternative." - ) - if Experiment is None: - raise ModuleNotFoundError( - "You want to use `test_tube` logger which is not installed yet," - " install it with `pip install test-tube`." - ) - super().__init__() - self._save_dir = save_dir - self._name = name - self.description = description - self.debug = debug - self._version = version - self.create_git_tag = create_git_tag - self._log_graph = log_graph - self._prefix = prefix - self._experiment = None - - @property - @rank_zero_experiment - def experiment(self) -> Experiment: - r""" - - Actual TestTube object. To use TestTube features in your - :class:`~pytorch_lightning.core.lightning.LightningModule` do the following. - - Example:: - - self.logger.experiment.some_test_tube_function() - - """ - if self._experiment is not None: - return self._experiment - - self._experiment = Experiment( - save_dir=self.save_dir, - name=self._name, - debug=self.debug, - version=self.version, - description=self.description, - create_git_tag=self.create_git_tag, - rank=rank_zero_only.rank, - ) - return self._experiment - - @rank_zero_only - def log_hyperparams(self, params: Union[Dict[str, Any], Namespace]) -> None: - # TODO: HACK figure out where this is being set to true - self.experiment.debug = self.debug - params = _convert_params(params) - params = _flatten_dict(params) - self.experiment.argparse(Namespace(**params)) - - @rank_zero_only - def log_metrics(self, metrics: Dict[str, float], step: Optional[int] = None) -> None: - # TODO: HACK figure out where this is being set to true - metrics = _add_prefix(metrics, self._prefix, self.LOGGER_JOIN_CHAR) - self.experiment.debug = self.debug - self.experiment.log(metrics, global_step=step) - - @rank_zero_only - def log_graph(self, model: "pl.LightningModule", input_array=None): - if self._log_graph: - if input_array is None: - input_array = model.example_input_array - - if input_array is not None: - self.experiment.add_graph(model, model._apply_batch_transfer_handler(input_array)) - else: - rank_zero_warn( - "Could not log computational graph since neither the" - " `model.example_input_array` attribute is set nor" - " `input_array` was given", - ) - - @rank_zero_only - def save(self) -> None: - super().save() - # TODO: HACK figure out where this is being set to true - self.experiment.debug = self.debug - self.experiment.save() - - @rank_zero_only - def finalize(self, status: str) -> None: - super().finalize(status) - # TODO: HACK figure out where this is being set to true - self.experiment.debug = self.debug - self.save() - self.close() - - @rank_zero_only - def close(self) -> None: - super().save() - # TODO: HACK figure out where this is being set to true - self.experiment.debug = self.debug - if not self.debug: - exp = self.experiment - exp.close() - - @property - def save_dir(self) -> Optional[str]: - """Gets the save directory. - - Returns: - The path to the save directory. - """ - return self._save_dir - - @property - def name(self) -> str: - """Gets the experiment name. - - Returns: - The experiment name if the experiment exists, else the name specified in the constructor. - """ - if self._experiment is None: - return self._name - - return self.experiment.name - - @property - def version(self) -> int: - """Gets the experiment version. - - Returns: - The experiment version if the experiment exists, else the next version. - """ - if self._experiment is None: - return self._version - - return self.experiment.version - - # Test tube experiments are not pickleable, so we need to override a few - # methods to get DDP working. See - # https://docs.python.org/3/library/pickle.html#handling-stateful-objects - # for more info. - def __getstate__(self) -> Dict[Any, Any]: - state = self.__dict__.copy() - state["_experiment"] = self.experiment.get_meta_copy() - return state - - def __setstate__(self, state: Dict[Any, Any]): - self._experiment = state["_experiment"].get_non_ddp_exp() - del state["_experiment"] - self.__dict__.update(state) diff --git a/requirements/loggers.txt b/requirements/loggers.txt index 6e09559dcc822..3b02aac28f6c0 100644 --- a/requirements/loggers.txt +++ b/requirements/loggers.txt @@ -2,5 +2,4 @@ neptune-client>=0.10.0 comet-ml>=3.1.12 mlflow>=1.0.0 -test_tube>=0.7.5 wandb>=0.8.21 diff --git a/tests/deprecated_api/test_remove_1-7.py b/tests/deprecated_api/test_remove_1-7.py index c93aa78660a5a..270cd7ecd9769 100644 --- a/tests/deprecated_api/test_remove_1-7.py +++ b/tests/deprecated_api/test_remove_1-7.py @@ -22,7 +22,7 @@ from pytorch_lightning import Callback, Trainer from pytorch_lightning.callbacks.lr_monitor import LearningRateMonitor -from pytorch_lightning.loggers import LoggerCollection, TestTubeLogger +from pytorch_lightning.loggers import LoggerCollection from pytorch_lightning.overrides.distributed import IndexBatchSamplerWrapper from pytorch_lightning.plugins.environments import ( KubeflowEnvironment, @@ -84,12 +84,6 @@ def _run(model, task="fit"): _run(model, "predict") -@mock.patch("pytorch_lightning.loggers.test_tube.Experiment") -def test_v1_7_0_test_tube_logger(_, tmpdir): - with pytest.deprecated_call(match="The TestTubeLogger is deprecated since v1.5 and will be removed in v1.7"): - _ = TestTubeLogger(tmpdir) - - def test_v1_7_0_on_interrupt(tmpdir): class HandleInterruptCallback(Callback): def on_keyboard_interrupt(self, trainer, pl_module): From 3d7d69708887da643885400876b0c5d1d14ff133 Mon Sep 17 00:00:00 2001 From: stanbiryukov Date: Fri, 22 Apr 2022 22:29:42 -0500 Subject: [PATCH 2/4] remove testube from logger __init__ --- pytorch_lightning/loggers/__init__.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pytorch_lightning/loggers/__init__.py b/pytorch_lightning/loggers/__init__.py index 4fd24587b293d..43a9a59059f32 100644 --- a/pytorch_lightning/loggers/__init__.py +++ b/pytorch_lightning/loggers/__init__.py @@ -25,7 +25,6 @@ from pytorch_lightning.loggers.comet import _COMET_AVAILABLE, CometLogger # noqa: F401 from pytorch_lightning.loggers.mlflow import _MLFLOW_AVAILABLE, MLFlowLogger # noqa: F401 from pytorch_lightning.loggers.neptune import _NEPTUNE_AVAILABLE, NeptuneLogger # noqa: F401 -from pytorch_lightning.loggers.test_tube import _TESTTUBE_AVAILABLE, TestTubeLogger # noqa: F401 from pytorch_lightning.loggers.wandb import WandbLogger # noqa: F401 from pytorch_lightning.utilities.imports import _WANDB_AVAILABLE @@ -40,8 +39,5 @@ if _NEPTUNE_AVAILABLE: __all__.append("NeptuneLogger") -if _TESTTUBE_AVAILABLE: - __all__.append("TestTubeLogger") - if _WANDB_AVAILABLE: __all__.append("WandbLogger") From 3aeb67553033b7b796c359815a2f7f35d260b5f0 Mon Sep 17 00:00:00 2001 From: stanbiryukov Date: Fri, 22 Apr 2022 22:29:42 -0500 Subject: [PATCH 3/4] remove relevant testtube tests --- pytorch_lightning/loggers/__init__.py | 4 ---- tests/loggers/test_all.py | 30 +++------------------------ 2 files changed, 3 insertions(+), 31 deletions(-) diff --git a/pytorch_lightning/loggers/__init__.py b/pytorch_lightning/loggers/__init__.py index 4fd24587b293d..43a9a59059f32 100644 --- a/pytorch_lightning/loggers/__init__.py +++ b/pytorch_lightning/loggers/__init__.py @@ -25,7 +25,6 @@ from pytorch_lightning.loggers.comet import _COMET_AVAILABLE, CometLogger # noqa: F401 from pytorch_lightning.loggers.mlflow import _MLFLOW_AVAILABLE, MLFlowLogger # noqa: F401 from pytorch_lightning.loggers.neptune import _NEPTUNE_AVAILABLE, NeptuneLogger # noqa: F401 -from pytorch_lightning.loggers.test_tube import _TESTTUBE_AVAILABLE, TestTubeLogger # noqa: F401 from pytorch_lightning.loggers.wandb import WandbLogger # noqa: F401 from pytorch_lightning.utilities.imports import _WANDB_AVAILABLE @@ -40,8 +39,5 @@ if _NEPTUNE_AVAILABLE: __all__.append("NeptuneLogger") -if _TESTTUBE_AVAILABLE: - __all__.append("TestTubeLogger") - if _WANDB_AVAILABLE: __all__.append("WandbLogger") diff --git a/tests/loggers/test_all.py b/tests/loggers/test_all.py index 2fae9ed102b7c..d72bb8cc51ae4 100644 --- a/tests/loggers/test_all.py +++ b/tests/loggers/test_all.py @@ -29,7 +29,6 @@ MLFlowLogger, NeptuneLogger, TensorBoardLogger, - TestTubeLogger, WandbLogger, ) from pytorch_lightning.loggers.logger import DummyExperiment @@ -45,7 +44,6 @@ mock.patch("pytorch_lightning.loggers.mlflow.mlflow"), mock.patch("pytorch_lightning.loggers.mlflow.MlflowClient"), mock.patch("pytorch_lightning.loggers.neptune.neptune", new_callable=create_neptune_mock), - mock.patch("pytorch_lightning.loggers.test_tube.Experiment"), mock.patch("pytorch_lightning.loggers.wandb.wandb"), ) ALL_LOGGER_CLASSES = ( @@ -54,10 +52,8 @@ MLFlowLogger, NeptuneLogger, TensorBoardLogger, - TestTubeLogger, WandbLogger, ) -ALL_LOGGER_CLASSES_WO_TTUBE = tuple(filter(lambda cls: cls is not TestTubeLogger, ALL_LOGGER_CLASSES)) ALL_LOGGER_CLASSES_WO_NEPTUNE = tuple(filter(lambda cls: cls is not NeptuneLogger, ALL_LOGGER_CLASSES)) ALL_LOGGER_CLASSES_WO_NEPTUNE_WANDB = tuple(filter(lambda cls: cls is not WandbLogger, ALL_LOGGER_CLASSES_WO_NEPTUNE)) @@ -82,7 +78,7 @@ def _instantiate_logger(logger_class, save_dir, **override_kwargs): return logger -@pytest.mark.parametrize("logger_class", ALL_LOGGER_CLASSES_WO_TTUBE) +@pytest.mark.parametrize("logger_class", ALL_LOGGER_CLASSES) def test_loggers_fit_test_all(tmpdir, monkeypatch, logger_class): """Verify that basic functionality of all loggers.""" with contextlib.ExitStack() as stack: @@ -128,10 +124,6 @@ def log_metrics(self, metrics, step): logger.experiment.id = "foo" logger.experiment.project_name = "bar" - if logger_class == TestTubeLogger: - logger.experiment.version = "foo" - logger.experiment.name = "bar" - if logger_class == MLFlowLogger: logger = mock_mlflow_run_creation(logger, experiment_id="foo", run_id="bar") @@ -232,11 +224,7 @@ def test_loggers_pickle_all(tmpdir, monkeypatch, logger_class): """ _patch_comet_atexit(monkeypatch) try: - if logger_class is TestTubeLogger: - with pytest.deprecated_call(match="TestTubeLogger is deprecated since v1.5"): - _test_loggers_pickle(tmpdir, monkeypatch, logger_class) - else: - _test_loggers_pickle(tmpdir, monkeypatch, logger_class) + _test_loggers_pickle(tmpdir, monkeypatch, logger_class) except (ImportError, ModuleNotFoundError): pytest.xfail(f"pickle test requires {logger_class.__class__} dependencies to be installed.") @@ -316,11 +304,7 @@ def test_logger_created_on_rank_zero_only(tmpdir, monkeypatch, logger_class): """Test that loggers get replaced by dummy loggers on global rank > 0.""" _patch_comet_atexit(monkeypatch) try: - if logger_class is TestTubeLogger: - with pytest.deprecated_call(match="TestTubeLogger is deprecated since v1.5"): - _test_logger_created_on_rank_zero_only(tmpdir, logger_class) - else: - _test_logger_created_on_rank_zero_only(tmpdir, logger_class) + _test_logger_created_on_rank_zero_only(tmpdir, logger_class) except (ImportError, ModuleNotFoundError): pytest.xfail(f"multi-process test requires {logger_class.__class__} dependencies to be installed.") @@ -378,14 +362,6 @@ def test_logger_with_prefix_all(tmpdir, monkeypatch): logger.log_metrics({"test": 1.0}, step=0) logger.experiment.add_scalar.assert_called_once_with("tmp-test", 1.0, 0) - # TestTube - with mock.patch("pytorch_lightning.loggers.test_tube.Experiment"), pytest.deprecated_call( - match="TestTubeLogger is deprecated since v1.5" - ): - logger = _instantiate_logger(TestTubeLogger, save_dir=tmpdir, prefix=prefix) - logger.log_metrics({"test": 1.0}, step=0) - logger.experiment.log.assert_called_once_with({"tmp-test": 1.0}, global_step=0) - # WandB with mock.patch("pytorch_lightning.loggers.wandb.wandb") as wandb: logger = _instantiate_logger(WandbLogger, save_dir=tmpdir, prefix=prefix) From 5a207f9b61dc6c3d454c073e6da68ec4825a2133 Mon Sep 17 00:00:00 2001 From: stanbiryukov Date: Sat, 23 Apr 2022 12:43:05 -0500 Subject: [PATCH 4/4] update CHANGELOG with removal of deprecated `TestTubeLogger` --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 768735f97553a..1ab5b277b637a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -70,6 +70,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Removed +- Removed the deprecated `TestTubeLogger` ([#12859](https://github.com/PyTorchLightning/pytorch-lightning/pull/12859)) + + - Removed the deprecated `pytorch_lightning.core.memory.LayerSummary` and `pytorch_lightning.core.memory.ModelSummary` ([#12593](https://github.com/PyTorchLightning/pytorch-lightning/pull/12593))