Mocking loggers (part 2, neptune) (#3617)

* mock neptune base tests

* neptune doctest

* remove extra

* mock loggers

* typo

* mock import

* neptune not compatible with multigpu

* add back experiment
This commit is contained in:
Adrian Wälchli 2020-10-05 03:20:06 +02:00 committed by GitHub
parent 2bca89a752
commit e0f8505394
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 56 additions and 50 deletions

View File

@ -22,11 +22,9 @@ from typing import Any, Dict, Iterable, List, Optional, Union
try:
import neptune
from neptune.experiments import Experiment
_NEPTUNE_AVAILABLE = True
except ImportError: # pragma: no-cover
neptune = None
Experiment = None
_NEPTUNE_AVAILABLE = False
import torch
from torch import is_tensor
@ -50,52 +48,57 @@ class NeptuneLogger(LightningLoggerBase):
**ONLINE MODE**
Example:
>>> from pytorch_lightning import Trainer
>>> from pytorch_lightning.loggers import NeptuneLogger
>>> # arguments made to NeptuneLogger are passed on to the neptune.experiments.Experiment class
>>> # We are using an api_key for the anonymous user "neptuner" but you can use your own.
>>> neptune_logger = NeptuneLogger(
... api_key='ANONYMOUS',
... project_name='shared/pytorch-lightning-integration',
... experiment_name='default', # Optional,
... params={'max_epochs': 10}, # Optional,
... tags=['pytorch-lightning', 'mlp'] # Optional,
... )
>>> trainer = Trainer(max_epochs=10, logger=neptune_logger)
.. code-block:: python
from pytorch_lightning import Trainer
from pytorch_lightning.loggers import NeptuneLogger
# arguments made to NeptuneLogger are passed on to the neptune.experiments.Experiment class
# We are using an api_key for the anonymous user "neptuner" but you can use your own.
neptune_logger = NeptuneLogger(
api_key='ANONYMOUS',
project_name='shared/pytorch-lightning-integration',
experiment_name='default', # Optional,
params={'max_epochs': 10}, # Optional,
tags=['pytorch-lightning', 'mlp'] # Optional,
)
trainer = Trainer(max_epochs=10, logger=neptune_logger)
**OFFLINE MODE**
Example:
>>> from pytorch_lightning.loggers import NeptuneLogger
>>> # arguments made to NeptuneLogger are passed on to the neptune.experiments.Experiment class
>>> neptune_logger = NeptuneLogger(
... offline_mode=True,
... project_name='USER_NAME/PROJECT_NAME',
... experiment_name='default', # Optional,
... params={'max_epochs': 10}, # Optional,
... tags=['pytorch-lightning', 'mlp'] # Optional,
... )
>>> trainer = Trainer(max_epochs=10, logger=neptune_logger)
.. code-block:: python
from pytorch_lightning.loggers import NeptuneLogger
# arguments made to NeptuneLogger are passed on to the neptune.experiments.Experiment class
neptune_logger = NeptuneLogger(
offline_mode=True,
project_name='USER_NAME/PROJECT_NAME',
experiment_name='default', # Optional,
params={'max_epochs': 10}, # Optional,
tags=['pytorch-lightning', 'mlp'] # Optional,
)
trainer = Trainer(max_epochs=10, logger=neptune_logger)
Use the logger anywhere in you :class:`~pytorch_lightning.core.lightning.LightningModule` as follows:
>>> from pytorch_lightning import LightningModule
>>> class LitModel(LightningModule):
... def training_step(self, batch, batch_idx):
... # log metrics
... self.logger.experiment.log_metric('acc_train', ...)
... # log images
... self.logger.experiment.log_image('worse_predictions', ...)
... # log model checkpoint
... self.logger.experiment.log_artifact('model_checkpoint.pt', ...)
... self.logger.experiment.whatever_neptune_supports(...)
...
... def any_lightning_module_function_or_hook(self):
... self.logger.experiment.log_metric('acc_train', ...)
... self.logger.experiment.log_image('worse_predictions', ...)
... self.logger.experiment.log_artifact('model_checkpoint.pt', ...)
... self.logger.experiment.whatever_neptune_supports(...)
.. code-block:: python
class LitModel(LightningModule):
def training_step(self, batch, batch_idx):
# log metrics
self.logger.experiment.log_metric('acc_train', ...)
# log images
self.logger.experiment.log_image('worse_predictions', ...)
# log model checkpoint
self.logger.experiment.log_artifact('model_checkpoint.pt', ...)
self.logger.experiment.whatever_neptune_supports(...)
def any_lightning_module_function_or_hook(self):
self.logger.experiment.log_metric('acc_train', ...)
self.logger.experiment.log_image('worse_predictions', ...)
self.logger.experiment.log_artifact('model_checkpoint.pt', ...)
self.logger.experiment.whatever_neptune_supports(...)
If you want to log objects after the training is finished use ``close_after_fit=False``:
@ -171,7 +174,7 @@ class NeptuneLogger(LightningLoggerBase):
experiment_name: Optional[str] = None,
**kwargs
):
if not _NEPTUNE_AVAILABLE:
if neptune is None:
raise ImportError('You want to use `neptune` logger which is not installed yet,'
' install it with `pip install neptune-client`.')
super().__init__()

View File

@ -1,7 +1,6 @@
# extended list of package dependencies to reach full functionality
# TODO: this shall be removed as we mock them in tests
neptune-client>=0.4.109
comet-ml>=3.1.12
mlflow>=1.0.0
test_tube>=0.7.5

View File

@ -40,8 +40,9 @@ def _get_logger_args(logger_class, save_dir):
TestTubeLogger,
WandbLogger,
])
@mock.patch('pytorch_lightning.loggers.neptune.neptune')
@mock.patch('pytorch_lightning.loggers.wandb.wandb')
def test_loggers_fit_test(wandb, tmpdir, monkeypatch, logger_class):
def test_loggers_fit_test(wandb, neptune, tmpdir, monkeypatch, logger_class):
"""Verify that basic functionality of all loggers."""
os.environ['PL_DEV_DEBUG'] = '0'
@ -169,7 +170,8 @@ def test_loggers_save_dir_and_weights_save_path(wandb, tmpdir, monkeypatch, logg
TestTubeLogger,
# The WandbLogger gets tested for pickling in its own test.
])
def test_loggers_pickle(tmpdir, monkeypatch, logger_class):
@mock.patch('pytorch_lightning.loggers.neptune.neptune')
def test_loggers_pickle(neptune, tmpdir, monkeypatch, logger_class):
"""Verify that pickling trainer with logger works."""
if logger_class == CometLogger:
# prevent comet logger from trying to print at exit, since
@ -242,11 +244,12 @@ class RankZeroLoggerCheck(Callback):
@pytest.mark.parametrize("logger_class", [
TensorBoardLogger,
MLFlowLogger,
NeptuneLogger,
# NeptuneLogger, # TODO: fix: https://github.com/PyTorchLightning/pytorch-lightning/pull/3256
TestTubeLogger,
])
def test_logger_created_on_rank_zero_only(tmpdir, monkeypatch, logger_class):
""" Test that loggers get replaced by dummy logges on global rank > 0"""
@mock.patch('pytorch_lightning.loggers.neptune.neptune')
def test_logger_created_on_rank_zero_only(neptune, tmpdir, monkeypatch, logger_class):
""" Test that loggers get replaced by dummy loggers on global rank > 0"""
if logger_class == CometLogger:
# prevent comet logger from trying to print at exit, since
# pytest's stdout/stderr redirection breaks it

View File

@ -73,7 +73,8 @@ def test_neptune_additional_methods(neptune):
created_experiment.append_tags.assert_called_once_with('two', 'tags')
def test_neptune_leave_open_experiment_after_fit(tmpdir):
@patch('pytorch_lightning.loggers.neptune.neptune')
def test_neptune_leave_open_experiment_after_fit(neptune, tmpdir):
"""Verify that neptune experiment was closed after training"""
model = EvalModelTemplate()