Skip to content

Commit 56c31db

Browse files
Update the Neptune logger (#2881)
* added output handlers, model checkpoint handler, added mnist example, added initial tests file * added exp link to examples, added tests * added neptune do docs * fixed test * fixed imports * added neptune-client to test dependencies * fixed missing package message * dropped model checkpoing handler * updated experiment link * dropped __futures__ print_function * added NeptuneSaver and tests * autopep8 fix * updated token to anonymous user neptuner * updated experiment link * updated token to 'ANONYMOUS' * updated examples, fixed tests * autopep8 fix * fixed serializable test * fixed serializable model test * local * autopep8 fix * added self.experiment back * Fix after merge * Update Neptune integration for compatibility with recent changes in Neptune client * Track the version of Ignite in Neptune * Ignore the future deprecation warnings when importing neptune.new * autopep8 fix * Make INTEGRATION_VERSION_KEY private * Add type annotations * Add type annotation to kwargs * Use >= in requirements * Fix failing test --------- Co-authored-by: jakubczakon <czakon.jakub@gmail.com> Co-authored-by: AutoPEP8 <>
1 parent 8c74035 commit 56c31db

File tree

4 files changed

+236
-269
lines changed

4 files changed

+236
-269
lines changed

ignite/contrib/handlers/neptune_logger.py

Lines changed: 43 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from torch.optim import Optimizer
77

88
import ignite.distributed as idist
9+
from ignite import __version__
910
from ignite.contrib.handlers.base_logger import (
1011
BaseLogger,
1112
BaseOptimizerParamsHandler,
@@ -26,6 +27,8 @@
2627
"global_step_from_engine",
2728
]
2829

30+
_INTEGRATION_VERSION_KEY = "source_code/integrations/neptune-pytorch-ignite"
31+
2932

3033
class NeptuneLogger(BaseLogger):
3134
"""
@@ -42,24 +45,7 @@ class NeptuneLogger(BaseLogger):
4245
"namespace/project_name" for example "tom/minst-classification".
4346
If None, the value of NEPTUNE_PROJECT environment variable will be taken.
4447
You need to create the project in https://neptune.ai first.
45-
offline_mode: Optional default False. If offline_mode=True no logs will be send to neptune.
46-
Usually used for debug purposes.
47-
experiment_name: Optional. Editable name of the experiment.
48-
Name is displayed in the experiment’s Details (Metadata section) and in experiments view as a column.
49-
upload_source_files: Optional. List of source files to be uploaded.
50-
Must be list of str or single str. Uploaded sources are displayed in the experiment’s Source code tab.
51-
If None is passed, Python file from which experiment was created will be uploaded.
52-
Pass empty list (`[]`) to upload no files. Unix style pathname pattern expansion is supported.
53-
For example, you can pass `*.py` to upload all python source files from the current directory.
54-
For recursion lookup use `**/*.py` (for Python 3.5 and later). For more information see glob library.
55-
params: Optional. Parameters of the experiment. After experiment creation params are read-only.
56-
Parameters are displayed in the experiment’s Parameters section and each key-value pair can be
57-
viewed in experiments view as a column.
58-
properties: Optional default is `{}`. Properties of the experiment.
59-
They are editable after experiment is created. Properties are displayed in the experiment’s Details and
60-
each key-value pair can be viewed in experiments view as a column.
61-
tags: Optional default `[]`. Must be list of str. Tags of the experiment.
62-
Tags are displayed in the experiment’s Details and can be viewed in experiments view as a column.
48+
**kwargs: Other arguments to be passed to Neptune's `init_run`.
6349
6450
Examples:
6551
.. code-block:: python
@@ -71,8 +57,8 @@ class NeptuneLogger(BaseLogger):
7157
7258
npt_logger = NeptuneLogger(
7359
api_token="ANONYMOUS",
74-
project_name="shared/pytorch-ignite-integration",
75-
experiment_name="cnn-mnist", # Optional,
60+
project="shared/pytorch-ignite-integration",
61+
name="cnn-mnist", # Optional,
7662
params={"max_epochs": 10}, # Optional,
7763
tags=["pytorch-ignite","minst"] # Optional
7864
)
@@ -153,8 +139,8 @@ def score_function(engine):
153139
# We are using the api_token for the anonymous user neptuner but you can use your own.
154140
155141
with NeptuneLogger(api_token="ANONYMOUS",
156-
project_name="shared/pytorch-ignite-integration",
157-
experiment_name="cnn-mnist", # Optional,
142+
project="shared/pytorch-ignite-integration",
143+
name="cnn-mnist", # Optional,
158144
params={"max_epochs": 10}, # Optional,
159145
tags=["pytorch-ignite","mnist"] # Optional
160146
) as npt_logger:
@@ -171,39 +157,44 @@ def score_function(engine):
171157
"""
172158

173159
def __getattr__(self, attr: Any) -> Any:
160+
return getattr(self.experiment, attr)
174161

175-
import neptune
162+
def __getitem__(self, key: str) -> Any:
163+
return self.experiment[key]
176164

177-
return getattr(neptune, attr)
165+
def __setitem__(self, key: str, val: Any) -> Any:
166+
self.experiment[key] = val
167+
168+
def __init__(self, api_token: Optional[str] = None, project: Optional[str] = None, **kwargs: Any) -> None:
169+
import warnings
178170

179-
def __init__(self, *args: Any, **kwargs: Any) -> None:
180171
try:
181-
import neptune
172+
try:
173+
# neptune-client<1.0.0 package structure
174+
with warnings.catch_warnings():
175+
# ignore the deprecation warnings
176+
warnings.simplefilter("ignore")
177+
import neptune.new as neptune
178+
except ImportError:
179+
# neptune>=1.0.0 package structure
180+
import neptune
182181
except ImportError:
183182
raise ModuleNotFoundError(
184-
"This contrib module requires neptune-client to be installed. "
185-
"You may install neptune with command: \n pip install neptune-client \n"
186-
)
187-
188-
if kwargs.get("offline_mode", False):
189-
self.mode = "offline"
190-
neptune.init(
191-
project_qualified_name="dry-run/project",
192-
backend=neptune.OfflineBackend(),
183+
"This contrib module requires neptune client to be installed. "
184+
"You may install neptune with command: \n pip install neptune \n"
193185
)
194-
else:
195-
self.mode = "online"
196-
neptune.init(api_token=kwargs.get("api_token"), project_qualified_name=kwargs.get("project_name"))
197186

198-
kwargs["name"] = kwargs.pop("experiment_name", None)
199-
self._experiment_kwargs = {
200-
k: v for k, v in kwargs.items() if k not in ["api_token", "project_name", "offline_mode"]
201-
}
187+
run = neptune.init_run(
188+
api_token=api_token,
189+
project=project,
190+
**kwargs,
191+
)
192+
run[_INTEGRATION_VERSION_KEY] = __version__
202193

203-
self.experiment = neptune.create_experiment(**self._experiment_kwargs)
194+
self.experiment = run
204195

205196
def close(self) -> None:
206-
self.stop()
197+
self.experiment.stop()
207198

208199
def _create_output_handler(self, *args: Any, **kwargs: Any) -> "OutputHandler":
209200
return OutputHandler(*args, **kwargs)
@@ -355,7 +346,7 @@ def __call__(self, engine: Engine, logger: NeptuneLogger, event_name: Union[str,
355346
)
356347

357348
for key, value in metrics.items():
358-
logger.log_metric(key, x=global_step, y=value)
349+
logger[key].append(value, step=global_step)
359350

360351

361352
class OptimizerParamsHandler(BaseOptimizerParamsHandler):
@@ -412,7 +403,7 @@ def __call__(self, engine: Engine, logger: NeptuneLogger, event_name: Union[str,
412403
}
413404

414405
for k, v in params.items():
415-
logger.log_metric(k, x=global_step, y=v)
406+
logger[k].append(v, step=global_step)
416407

417408

418409
class WeightsScalarHandler(BaseWeightsScalarHandler):
@@ -515,11 +506,8 @@ def __call__(self, engine: Engine, logger: NeptuneLogger, event_name: Union[str,
515506
continue
516507

517508
name = name.replace(".", "/")
518-
logger.log_metric(
519-
f"{tag_prefix}weights_{self.reduction.__name__}/{name}",
520-
x=global_step,
521-
y=self.reduction(p.data),
522-
)
509+
key = f"{tag_prefix}weights_{self.reduction.__name__}/{name}"
510+
logger[key].append(self.reduction(p.data), step=global_step)
523511

524512

525513
class GradsScalarHandler(BaseWeightsScalarHandler):
@@ -622,9 +610,8 @@ def __call__(self, engine: Engine, logger: NeptuneLogger, event_name: Union[str,
622610
continue
623611

624612
name = name.replace(".", "/")
625-
logger.log_metric(
626-
f"{tag_prefix}grads_{self.reduction.__name__}/{name}", x=global_step, y=self.reduction(p.grad)
627-
)
613+
key = f"{tag_prefix}grads_{self.reduction.__name__}/{name}"
614+
logger[key].append(self.reduction(p.grad), step=global_step)
628615

629616

630617
class NeptuneSaver(BaseSaveHandler):
@@ -693,8 +680,8 @@ def __call__(self, checkpoint: Mapping, filename: str, metadata: Optional[Mappin
693680
# we can not use tmp.name to open tmp.file twice on Win32
694681
# https://docs.python.org/3/library/tempfile.html#tempfile.NamedTemporaryFile
695682
torch.save(checkpoint, tmp.file)
696-
self._logger.log_artifact(tmp.name, filename)
683+
self._logger[filename].upload(tmp.name)
697684

698685
@idist.one_rank_only(with_barrier=True)
699686
def remove(self, filename: str) -> None:
700-
self._logger.delete_artifacts(filename)
687+
self._logger.delete_files(filename)

requirements-dev.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ polyaxon
2121
polyaxon-client
2222
wandb
2323
mlflow
24-
neptune-client==0.16.9
24+
neptune-client>=0.16.17
2525
tensorboard
2626
torchvision
2727
pynvml

tests/ignite/contrib/engines/test_common.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,7 @@ def test_setup_clearml_logging():
561561
def test_setup_neptune_logging(dirname):
562562
npt_logger = _test_setup_logging(
563563
setup_logging_fn=setup_neptune_logging,
564-
kwargs_dict={"offline_mode": True},
564+
kwargs_dict={"mode": "offline"},
565565
output_handler_cls=handlers.neptune_logger.OutputHandler,
566566
opt_params_handler_cls=handlers.neptune_logger.OptimizerParamsHandler,
567567
with_eval=False,
@@ -570,7 +570,7 @@ def test_setup_neptune_logging(dirname):
570570
npt_logger.close()
571571
npt_logger = _test_setup_logging(
572572
setup_logging_fn=setup_neptune_logging,
573-
kwargs_dict={"offline_mode": True},
573+
kwargs_dict={"mode": "offline"},
574574
output_handler_cls=handlers.neptune_logger.OutputHandler,
575575
opt_params_handler_cls=handlers.neptune_logger.OptimizerParamsHandler,
576576
with_eval=True,

0 commit comments

Comments
 (0)