We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Allow keeping default save_dir in ModelCheckpointer
##  Feature
Make `filepath` argument of `ModelCheckpointer` optional.

### Motivation
I'm pretty happy with all defaults of `ModelCheckpointer` except `save_top_k`. In case I want to override that parameter I have to write some awkward code related to figuring out the checkpointing path, which is normally only known at runtime:

```python
DEFROOT = Path('/data/models/lightning')
logger = WandbLogger(name=net.hparams.run_name, project=net.hparams.project, save_dir=str(DEFROOT))
logger.watch(net)
_ = logger.experiment  # create an experiment to determine version
cp_template = str(DEFROOT / net.hparams.project / ('version_'+logger.version) / 'checkpoints' / '{epoch:04d}-{val_loss:.2f}-{other_metric:.2f}.pt')

checkpointer = ModelCheckpoint(
    filepath=cp_template,
    save_top_k=10,
    verbose=True,
    monitor='val_loss',
    mode='min',
)

trainer = Trainer(
    gpus=1,
    logger=logger,
    default_root_dir=DEFROOT,
    checkpoint_callback=checkpointer,
    **extra,
)
trainer.fit(net)
```

It would be nice to have an option to allow Lightning to determine runtime-valued save location instead. Additionally, it would be nice to have an option to override checkpoint filename without overriding the whole save path.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pytorch_lightning/callbacks/model_checkpoint.py`
Content:
```
1 """
2 Model Checkpointing
3 ===================
4 
5 Automatically save model checkpoints during training.
6 
7 """
8 
9 import os
10 import re
11 
12 import numpy as np
13 from typing import Optional
14 
15 import torch
16 from pytorch_lightning import _logger as log
17 from pytorch_lightning.callbacks.base import Callback
18 from pytorch_lightning.utilities import rank_zero_warn, rank_zero_only
19 
20 
21 class ModelCheckpoint(Callback):
22     r"""
23     Save the model after every epoch.
24 
25     Args:
26         filepath: path to save the model file.
27             Can contain named formatting options to be auto-filled.
28 
29             Example::
30 
31                 # custom path
32                 # saves a file like: my/path/epoch_0.ckpt
33                 >>> checkpoint_callback = ModelCheckpoint('my/path/')
34 
35                 # save any arbitrary metrics like `val_loss`, etc. in name
36                 # saves a file like: my/path/epoch=2-val_loss=0.2_other_metric=0.3.ckpt
37                 >>> checkpoint_callback = ModelCheckpoint(
38                 ...     filepath='my/path/{epoch}-{val_loss:.2f}-{other_metric:.2f}'
39                 ... )
40 
41             Can also be set to `None`, then it will be set to default location
42             during trainer construction.
43 
44         monitor: quantity to monitor.
45         verbose: verbosity mode. Default: ``False``.
46         save_top_k: if `save_top_k == k`,
47             the best k models according to
48             the quantity monitored will be saved.
49             if ``save_top_k == 0``, no models are saved.
50             if ``save_top_k == -1``, all models are saved.
51             Please note that the monitors are checked every `period` epochs.
52             if ``save_top_k >= 2`` and the callback is called multiple
53             times inside an epoch, the name of the saved file will be
54             appended with a version count starting with `v0`.
55         mode: one of {auto, min, max}.
56             If ``save_top_k != 0``, the decision
57             to overwrite the current save file is made
58             based on either the maximization or the
59             minimization of the monitored quantity. For `val_acc`,
60             this should be `max`, for `val_loss` this should
61             be `min`, etc. In `auto` mode, the direction is
62             automatically inferred from the name of the monitored quantity.
63         save_weights_only: if ``True``, then only the model's weights will be
64             saved (``model.save_weights(filepath)``), else the full model
65             is saved (``model.save(filepath)``).
66         period: Interval (number of epochs) between checkpoints.
67 
68     Example::
69 
70         >>> from pytorch_lightning import Trainer
71         >>> from pytorch_lightning.callbacks import ModelCheckpoint
72 
73         # saves checkpoints to 'my/path/' whenever 'val_loss' has a new min
74         >>> checkpoint_callback = ModelCheckpoint(filepath='my/path/')
75         >>> trainer = Trainer(checkpoint_callback=checkpoint_callback)
76 
77         # save epoch and val_loss in name
78         # saves a file like: my/path/sample-mnist_epoch=02_val_loss=0.32.ckpt
79         >>> checkpoint_callback = ModelCheckpoint(
80         ...     filepath='my/path/sample-mnist_{epoch:02d}-{val_loss:.2f}'
81         ... )
82 
83     """
84 
85     def __init__(self, filepath: Optional[str] = None, monitor: str = 'val_loss', verbose: bool = False,
86                  save_top_k: int = 1, save_weights_only: bool = False,
87                  mode: str = 'auto', period: int = 1, prefix: str = ''):
88         super().__init__()
89         if save_top_k > 0 and os.path.isdir(filepath) and len(os.listdir(filepath)) > 0:
90             rank_zero_warn(
91                 f"Checkpoint directory {filepath} exists and is not empty with save_top_k != 0."
92                 "All files in this directory will be deleted when a checkpoint is saved!"
93             )
94         self._rank = 0
95 
96         self.monitor = monitor
97         self.verbose = verbose
98         if filepath is None:  # will be determined by trainer at runtime
99             self.dirpath, self.filename = None, None
100         else:
101             if os.path.isdir(filepath):
102                 self.dirpath, self.filename = filepath, '{epoch}'
103             else:
104                 self.dirpath, self.filename = os.path.split(filepath)
105             os.makedirs(self.dirpath, exist_ok=True)
106         self.save_top_k = save_top_k
107         self.save_weights_only = save_weights_only
108         self.period = period
109         self.epoch_last_check = None
110         self.prefix = prefix
111         self.best_k_models = {}
112         # {filename: monitor}
113         self.kth_best_model = ''
114         self.best = 0
115         self.save_function = None
116 
117         torch_inf = torch.tensor(np.Inf)
118         mode_dict = {
119             'min': (torch_inf, 'min'),
120             'max': (-torch_inf, 'max'),
121             'auto': (-torch_inf, 'max') if 'acc' in self.monitor or self.monitor.startswith('fmeasure')
122             else (torch_inf, 'min'),
123         }
124 
125         if mode not in mode_dict:
126             rank_zero_warn(f'ModelCheckpoint mode {mode} is unknown, '
127                            f'fallback to auto mode.', RuntimeWarning)
128             mode = 'auto'
129 
130         self.kth_value, self.mode = mode_dict[mode]
131 
132     def _del_model(self, filepath):
133         if os.path.isfile(filepath):
134             os.remove(filepath)
135 
136     def _save_model(self, filepath):
137         # make paths
138         os.makedirs(os.path.dirname(filepath), exist_ok=True)
139 
140         # delegate the saving to the model
141         if self.save_function is not None:
142             self.save_function(filepath)
143         else:
144             raise ValueError(".save_function() not set")
145 
146     def check_monitor_top_k(self, current):
147         less_than_k_models = len(self.best_k_models) < self.save_top_k
148         if less_than_k_models:
149             return True
150 
151         if not isinstance(current, torch.Tensor):
152             current = torch.tensor(current)
153 
154         monitor_op = {
155             "min": torch.lt,
156             "max": torch.gt,
157         }[self.mode]
158 
159         return monitor_op(current, self.best_k_models[self.kth_best_model])
160 
161     def format_checkpoint_name(self, epoch, metrics, ver=None):
162         """Generate a filename according to the defined template.
163 
164         Example::
165 
166             >>> tmpdir = os.path.dirname(__file__)
167             >>> ckpt = ModelCheckpoint(os.path.join(tmpdir, '{epoch}'))
168             >>> os.path.basename(ckpt.format_checkpoint_name(0, {}))
169             'epoch=0.ckpt'
170             >>> ckpt = ModelCheckpoint(os.path.join(tmpdir, '{epoch:03d}'))
171             >>> os.path.basename(ckpt.format_checkpoint_name(5, {}))
172             'epoch=005.ckpt'
173             >>> ckpt = ModelCheckpoint(os.path.join(tmpdir, '{epoch}-{val_loss:.2f}'))
174             >>> os.path.basename(ckpt.format_checkpoint_name(2, dict(val_loss=0.123456)))
175             'epoch=2-val_loss=0.12.ckpt'
176             >>> ckpt = ModelCheckpoint(os.path.join(tmpdir, '{missing:d}'))
177             >>> os.path.basename(ckpt.format_checkpoint_name(0, {}))
178             'missing=0.ckpt'
179         """
180         # check if user passed in keys to the string
181         groups = re.findall(r'(\{.*?)[:\}]', self.filename)
182 
183         if len(groups) == 0:
184             # default name
185             filename = f'{self.prefix}_ckpt_epoch_{epoch}'
186         else:
187             metrics['epoch'] = epoch
188             filename = self.filename
189             for tmp in groups:
190                 name = tmp[1:]
191                 filename = filename.replace(tmp, name + '={' + name)
192                 if name not in metrics:
193                     metrics[name] = 0
194             filename = filename.format(**metrics)
195         str_ver = f'_v{ver}' if ver is not None else ''
196         filepath = os.path.join(self.dirpath, self.prefix + filename + str_ver + '.ckpt')
197         return filepath
198 
199     @rank_zero_only
200     def on_validation_end(self, trainer, pl_module):
201         # only run on main process
202         if trainer.proc_rank != 0:
203             return
204 
205         metrics = trainer.callback_metrics
206         epoch = trainer.current_epoch
207         if self.save_top_k == 0:
208             # no models are saved
209             return
210         if self.epoch_last_check is not None and (epoch - self.epoch_last_check) < self.period:
211             # skipping in this term
212             return
213 
214         self.epoch_last_check = epoch
215 
216         filepath = self.format_checkpoint_name(epoch, metrics)
217         version_cnt = 0
218         while os.path.isfile(filepath):
219             filepath = self.format_checkpoint_name(epoch, metrics, ver=version_cnt)
220             # this epoch called before
221             version_cnt += 1
222 
223         if self.save_top_k != -1:
224             current = metrics.get(self.monitor)
225 
226             if current is None:
227                 rank_zero_warn(
228                     f'Can save best model only with {self.monitor} available, skipping.', RuntimeWarning
229                 )
230             elif self.check_monitor_top_k(current):
231                 self._do_check_save(filepath, current, epoch)
232             elif self.verbose > 0:
233                 log.info(f'\nEpoch {epoch:05d}: {self.monitor}  was not in top {self.save_top_k}')
234 
235         else:
236             if self.verbose > 0:
237                 log.info(f'\nEpoch {epoch:05d}: saving model to {filepath}')
238             self._save_model(filepath)
239 
240     def _do_check_save(self, filepath, current, epoch):
241         # remove kth
242 
243         del_list = []
244         if len(self.best_k_models) == self.save_top_k and self.save_top_k > 0:
245             delpath = self.kth_best_model
246             self.best_k_models.pop(self.kth_best_model)
247             del_list.append(delpath)
248 
249         self.best_k_models[filepath] = current
250         if len(self.best_k_models) == self.save_top_k:
251             # monitor dict has reached k elements
252             _op = max if self.mode == 'min' else min
253             self.kth_best_model = _op(self.best_k_models,
254                                       key=self.best_k_models.get)
255             self.kth_value = self.best_k_models[self.kth_best_model]
256 
257         _op = min if self.mode == 'min' else max
258         self.best = _op(self.best_k_models.values())
259 
260         if self.verbose > 0:
261             log.info(
262                 f'\nEpoch {epoch:05d}: {self.monitor} reached'
263                 f' {current:0.5f} (best {self.best:0.5f}), saving model to'
264                 f' {filepath} as top {self.save_top_k}')
265         self._save_model(filepath)
266 
267         for cur_path in del_list:
268             if cur_path != filepath:
269                 self._del_model(cur_path)
270
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pytorch_lightning/callbacks/model_checkpoint.py b/pytorch_lightning/callbacks/model_checkpoint.py
--- a/pytorch_lightning/callbacks/model_checkpoint.py
+++ b/pytorch_lightning/callbacks/model_checkpoint.py
@@ -86,7 +86,7 @@
                  save_top_k: int = 1, save_weights_only: bool = False,
                  mode: str = 'auto', period: int = 1, prefix: str = ''):
         super().__init__()
-        if save_top_k > 0 and os.path.isdir(filepath) and len(os.listdir(filepath)) > 0:
+        if save_top_k > 0 and filepath is not None and os.path.isdir(filepath) and len(os.listdir(filepath)) > 0:
             rank_zero_warn(
                 f"Checkpoint directory {filepath} exists and is not empty with save_top_k != 0."
                 "All files in this directory will be deleted when a checkpoint is saved!"

{"golden_diff": "diff --git a/pytorch_lightning/callbacks/model_checkpoint.py b/pytorch_lightning/callbacks/model_checkpoint.py\n--- a/pytorch_lightning/callbacks/model_checkpoint.py\n+++ b/pytorch_lightning/callbacks/model_checkpoint.py\n@@ -86,7 +86,7 @@\n                  save_top_k: int = 1, save_weights_only: bool = False,\n                  mode: str = 'auto', period: int = 1, prefix: str = ''):\n         super().__init__()\n-        if save_top_k > 0 and os.path.isdir(filepath) and len(os.listdir(filepath)) > 0:\n+        if save_top_k > 0 and filepath is not None and os.path.isdir(filepath) and len(os.listdir(filepath)) > 0:\n             rank_zero_warn(\n                 f\"Checkpoint directory {filepath} exists and is not empty with save_top_k != 0.\"\n                 \"All files in this directory will be deleted when a checkpoint is saved!\"\n", "issue": "Allow keeping default save_dir in ModelCheckpointer\n##  Feature\r\nMake `filepath` argument of `ModelCheckpointer` optional.\r\n\r\n### Motivation\r\nI'm pretty happy with all defaults of `ModelCheckpointer` except `save_top_k`. In case I want to override that parameter I have to write some awkward code related to figuring out the checkpointing path, which is normally only known at runtime:\r\n\r\n```python\r\nDEFROOT = Path('/data/models/lightning')\r\nlogger = WandbLogger(name=net.hparams.run_name, project=net.hparams.project, save_dir=str(DEFROOT))\r\nlogger.watch(net)\r\n_ = logger.experiment  # create an experiment to determine version\r\ncp_template = str(DEFROOT / net.hparams.project / ('version_'+logger.version) / 'checkpoints' / '{epoch:04d}-{val_loss:.2f}-{other_metric:.2f}.pt')\r\n\r\ncheckpointer = ModelCheckpoint(\r\n    filepath=cp_template,\r\n    save_top_k=10,\r\n    verbose=True,\r\n    monitor='val_loss',\r\n    mode='min',\r\n)\r\n\r\ntrainer = Trainer(\r\n    gpus=1,\r\n    logger=logger,\r\n    default_root_dir=DEFROOT,\r\n    checkpoint_callback=checkpointer,\r\n    **extra,\r\n)\r\ntrainer.fit(net)\r\n```\r\n\r\nIt would be nice to have an option to allow Lightning to determine runtime-valued save location instead. Additionally, it would be nice to have an option to override checkpoint filename without overriding the whole save path.\n", "before_files": [{"content": "\"\"\"\nModel Checkpointing\n===================\n\nAutomatically save model checkpoints during training.\n\n\"\"\"\n\nimport os\nimport re\n\nimport numpy as np\nfrom typing import Optional\n\nimport torch\nfrom pytorch_lightning import _logger as log\nfrom pytorch_lightning.callbacks.base import Callback\nfrom pytorch_lightning.utilities import rank_zero_warn, rank_zero_only\n\n\nclass ModelCheckpoint(Callback):\n    r\"\"\"\n    Save the model after every epoch.\n\n    Args:\n        filepath: path to save the model file.\n            Can contain named formatting options to be auto-filled.\n\n            Example::\n\n                # custom path\n                # saves a file like: my/path/epoch_0.ckpt\n                >>> checkpoint_callback = ModelCheckpoint('my/path/')\n\n                # save any arbitrary metrics like `val_loss`, etc. in name\n                # saves a file like: my/path/epoch=2-val_loss=0.2_other_metric=0.3.ckpt\n                >>> checkpoint_callback = ModelCheckpoint(\n                ...     filepath='my/path/{epoch}-{val_loss:.2f}-{other_metric:.2f}'\n                ... )\n\n            Can also be set to `None`, then it will be set to default location\n            during trainer construction.\n\n        monitor: quantity to monitor.\n        verbose: verbosity mode. Default: ``False``.\n        save_top_k: if `save_top_k == k`,\n            the best k models according to\n            the quantity monitored will be saved.\n            if ``save_top_k == 0``, no models are saved.\n            if ``save_top_k == -1``, all models are saved.\n            Please note that the monitors are checked every `period` epochs.\n            if ``save_top_k >= 2`` and the callback is called multiple\n            times inside an epoch, the name of the saved file will be\n            appended with a version count starting with `v0`.\n        mode: one of {auto, min, max}.\n            If ``save_top_k != 0``, the decision\n            to overwrite the current save file is made\n            based on either the maximization or the\n            minimization of the monitored quantity. For `val_acc`,\n            this should be `max`, for `val_loss` this should\n            be `min`, etc. In `auto` mode, the direction is\n            automatically inferred from the name of the monitored quantity.\n        save_weights_only: if ``True``, then only the model's weights will be\n            saved (``model.save_weights(filepath)``), else the full model\n            is saved (``model.save(filepath)``).\n        period: Interval (number of epochs) between checkpoints.\n\n    Example::\n\n        >>> from pytorch_lightning import Trainer\n        >>> from pytorch_lightning.callbacks import ModelCheckpoint\n\n        # saves checkpoints to 'my/path/' whenever 'val_loss' has a new min\n        >>> checkpoint_callback = ModelCheckpoint(filepath='my/path/')\n        >>> trainer = Trainer(checkpoint_callback=checkpoint_callback)\n\n        # save epoch and val_loss in name\n        # saves a file like: my/path/sample-mnist_epoch=02_val_loss=0.32.ckpt\n        >>> checkpoint_callback = ModelCheckpoint(\n        ...     filepath='my/path/sample-mnist_{epoch:02d}-{val_loss:.2f}'\n        ... )\n\n    \"\"\"\n\n    def __init__(self, filepath: Optional[str] = None, monitor: str = 'val_loss', verbose: bool = False,\n                 save_top_k: int = 1, save_weights_only: bool = False,\n                 mode: str = 'auto', period: int = 1, prefix: str = ''):\n        super().__init__()\n        if save_top_k > 0 and os.path.isdir(filepath) and len(os.listdir(filepath)) > 0:\n            rank_zero_warn(\n                f\"Checkpoint directory {filepath} exists and is not empty with save_top_k != 0.\"\n                \"All files in this directory will be deleted when a checkpoint is saved!\"\n            )\n        self._rank = 0\n\n        self.monitor = monitor\n        self.verbose = verbose\n        if filepath is None:  # will be determined by trainer at runtime\n            self.dirpath, self.filename = None, None\n        else:\n            if os.path.isdir(filepath):\n                self.dirpath, self.filename = filepath, '{epoch}'\n            else:\n                self.dirpath, self.filename = os.path.split(filepath)\n            os.makedirs(self.dirpath, exist_ok=True)\n        self.save_top_k = save_top_k\n        self.save_weights_only = save_weights_only\n        self.period = period\n        self.epoch_last_check = None\n        self.prefix = prefix\n        self.best_k_models = {}\n        # {filename: monitor}\n        self.kth_best_model = ''\n        self.best = 0\n        self.save_function = None\n\n        torch_inf = torch.tensor(np.Inf)\n        mode_dict = {\n            'min': (torch_inf, 'min'),\n            'max': (-torch_inf, 'max'),\n            'auto': (-torch_inf, 'max') if 'acc' in self.monitor or self.monitor.startswith('fmeasure')\n            else (torch_inf, 'min'),\n        }\n\n        if mode not in mode_dict:\n            rank_zero_warn(f'ModelCheckpoint mode {mode} is unknown, '\n                           f'fallback to auto mode.', RuntimeWarning)\n            mode = 'auto'\n\n        self.kth_value, self.mode = mode_dict[mode]\n\n    def _del_model(self, filepath):\n        if os.path.isfile(filepath):\n            os.remove(filepath)\n\n    def _save_model(self, filepath):\n        # make paths\n        os.makedirs(os.path.dirname(filepath), exist_ok=True)\n\n        # delegate the saving to the model\n        if self.save_function is not None:\n            self.save_function(filepath)\n        else:\n            raise ValueError(\".save_function() not set\")\n\n    def check_monitor_top_k(self, current):\n        less_than_k_models = len(self.best_k_models) < self.save_top_k\n        if less_than_k_models:\n            return True\n\n        if not isinstance(current, torch.Tensor):\n            current = torch.tensor(current)\n\n        monitor_op = {\n            \"min\": torch.lt,\n            \"max\": torch.gt,\n        }[self.mode]\n\n        return monitor_op(current, self.best_k_models[self.kth_best_model])\n\n    def format_checkpoint_name(self, epoch, metrics, ver=None):\n        \"\"\"Generate a filename according to the defined template.\n\n        Example::\n\n            >>> tmpdir = os.path.dirname(__file__)\n            >>> ckpt = ModelCheckpoint(os.path.join(tmpdir, '{epoch}'))\n            >>> os.path.basename(ckpt.format_checkpoint_name(0, {}))\n            'epoch=0.ckpt'\n            >>> ckpt = ModelCheckpoint(os.path.join(tmpdir, '{epoch:03d}'))\n            >>> os.path.basename(ckpt.format_checkpoint_name(5, {}))\n            'epoch=005.ckpt'\n            >>> ckpt = ModelCheckpoint(os.path.join(tmpdir, '{epoch}-{val_loss:.2f}'))\n            >>> os.path.basename(ckpt.format_checkpoint_name(2, dict(val_loss=0.123456)))\n            'epoch=2-val_loss=0.12.ckpt'\n            >>> ckpt = ModelCheckpoint(os.path.join(tmpdir, '{missing:d}'))\n            >>> os.path.basename(ckpt.format_checkpoint_name(0, {}))\n            'missing=0.ckpt'\n        \"\"\"\n        # check if user passed in keys to the string\n        groups = re.findall(r'(\\{.*?)[:\\}]', self.filename)\n\n        if len(groups) == 0:\n            # default name\n            filename = f'{self.prefix}_ckpt_epoch_{epoch}'\n        else:\n            metrics['epoch'] = epoch\n            filename = self.filename\n            for tmp in groups:\n                name = tmp[1:]\n                filename = filename.replace(tmp, name + '={' + name)\n                if name not in metrics:\n                    metrics[name] = 0\n            filename = filename.format(**metrics)\n        str_ver = f'_v{ver}' if ver is not None else ''\n        filepath = os.path.join(self.dirpath, self.prefix + filename + str_ver + '.ckpt')\n        return filepath\n\n    @rank_zero_only\n    def on_validation_end(self, trainer, pl_module):\n        # only run on main process\n        if trainer.proc_rank != 0:\n            return\n\n        metrics = trainer.callback_metrics\n        epoch = trainer.current_epoch\n        if self.save_top_k == 0:\n            # no models are saved\n            return\n        if self.epoch_last_check is not None and (epoch - self.epoch_last_check) < self.period:\n            # skipping in this term\n            return\n\n        self.epoch_last_check = epoch\n\n        filepath = self.format_checkpoint_name(epoch, metrics)\n        version_cnt = 0\n        while os.path.isfile(filepath):\n            filepath = self.format_checkpoint_name(epoch, metrics, ver=version_cnt)\n            # this epoch called before\n            version_cnt += 1\n\n        if self.save_top_k != -1:\n            current = metrics.get(self.monitor)\n\n            if current is None:\n                rank_zero_warn(\n                    f'Can save best model only with {self.monitor} available, skipping.', RuntimeWarning\n                )\n            elif self.check_monitor_top_k(current):\n                self._do_check_save(filepath, current, epoch)\n            elif self.verbose > 0:\n                log.info(f'\\nEpoch {epoch:05d}: {self.monitor}  was not in top {self.save_top_k}')\n\n        else:\n            if self.verbose > 0:\n                log.info(f'\\nEpoch {epoch:05d}: saving model to {filepath}')\n            self._save_model(filepath)\n\n    def _do_check_save(self, filepath, current, epoch):\n        # remove kth\n\n        del_list = []\n        if len(self.best_k_models) == self.save_top_k and self.save_top_k > 0:\n            delpath = self.kth_best_model\n            self.best_k_models.pop(self.kth_best_model)\n            del_list.append(delpath)\n\n        self.best_k_models[filepath] = current\n        if len(self.best_k_models) == self.save_top_k:\n            # monitor dict has reached k elements\n            _op = max if self.mode == 'min' else min\n            self.kth_best_model = _op(self.best_k_models,\n                                      key=self.best_k_models.get)\n            self.kth_value = self.best_k_models[self.kth_best_model]\n\n        _op = min if self.mode == 'min' else max\n        self.best = _op(self.best_k_models.values())\n\n        if self.verbose > 0:\n            log.info(\n                f'\\nEpoch {epoch:05d}: {self.monitor} reached'\n                f' {current:0.5f} (best {self.best:0.5f}), saving model to'\n                f' {filepath} as top {self.save_top_k}')\n        self._save_model(filepath)\n\n        for cur_path in del_list:\n            if cur_path != filepath:\n                self._del_model(cur_path)\n", "path": "pytorch_lightning/callbacks/model_checkpoint.py"}], "after_files": [{"content": "\"\"\"\nModel Checkpointing\n===================\n\nAutomatically save model checkpoints during training.\n\n\"\"\"\n\nimport os\nimport re\n\nimport numpy as np\nfrom typing import Optional\n\nimport torch\nfrom pytorch_lightning import _logger as log\nfrom pytorch_lightning.callbacks.base import Callback\nfrom pytorch_lightning.utilities import rank_zero_warn, rank_zero_only\n\n\nclass ModelCheckpoint(Callback):\n    r\"\"\"\n    Save the model after every epoch.\n\n    Args:\n        filepath: path to save the model file.\n            Can contain named formatting options to be auto-filled.\n\n            Example::\n\n                # custom path\n                # saves a file like: my/path/epoch_0.ckpt\n                >>> checkpoint_callback = ModelCheckpoint('my/path/')\n\n                # save any arbitrary metrics like `val_loss`, etc. in name\n                # saves a file like: my/path/epoch=2-val_loss=0.2_other_metric=0.3.ckpt\n                >>> checkpoint_callback = ModelCheckpoint(\n                ...     filepath='my/path/{epoch}-{val_loss:.2f}-{other_metric:.2f}'\n                ... )\n\n            Can also be set to `None`, then it will be set to default location\n            during trainer construction.\n\n        monitor: quantity to monitor.\n        verbose: verbosity mode. Default: ``False``.\n        save_top_k: if `save_top_k == k`,\n            the best k models according to\n            the quantity monitored will be saved.\n            if ``save_top_k == 0``, no models are saved.\n            if ``save_top_k == -1``, all models are saved.\n            Please note that the monitors are checked every `period` epochs.\n            if ``save_top_k >= 2`` and the callback is called multiple\n            times inside an epoch, the name of the saved file will be\n            appended with a version count starting with `v0`.\n        mode: one of {auto, min, max}.\n            If ``save_top_k != 0``, the decision\n            to overwrite the current save file is made\n            based on either the maximization or the\n            minimization of the monitored quantity. For `val_acc`,\n            this should be `max`, for `val_loss` this should\n            be `min`, etc. In `auto` mode, the direction is\n            automatically inferred from the name of the monitored quantity.\n        save_weights_only: if ``True``, then only the model's weights will be\n            saved (``model.save_weights(filepath)``), else the full model\n            is saved (``model.save(filepath)``).\n        period: Interval (number of epochs) between checkpoints.\n\n    Example::\n\n        >>> from pytorch_lightning import Trainer\n        >>> from pytorch_lightning.callbacks import ModelCheckpoint\n\n        # saves checkpoints to 'my/path/' whenever 'val_loss' has a new min\n        >>> checkpoint_callback = ModelCheckpoint(filepath='my/path/')\n        >>> trainer = Trainer(checkpoint_callback=checkpoint_callback)\n\n        # save epoch and val_loss in name\n        # saves a file like: my/path/sample-mnist_epoch=02_val_loss=0.32.ckpt\n        >>> checkpoint_callback = ModelCheckpoint(\n        ...     filepath='my/path/sample-mnist_{epoch:02d}-{val_loss:.2f}'\n        ... )\n\n    \"\"\"\n\n    def __init__(self, filepath: Optional[str] = None, monitor: str = 'val_loss', verbose: bool = False,\n                 save_top_k: int = 1, save_weights_only: bool = False,\n                 mode: str = 'auto', period: int = 1, prefix: str = ''):\n        super().__init__()\n        if save_top_k > 0 and filepath is not None and os.path.isdir(filepath) and len(os.listdir(filepath)) > 0:\n            rank_zero_warn(\n                f\"Checkpoint directory {filepath} exists and is not empty with save_top_k != 0.\"\n                \"All files in this directory will be deleted when a checkpoint is saved!\"\n            )\n        self._rank = 0\n\n        self.monitor = monitor\n        self.verbose = verbose\n        if filepath is None:  # will be determined by trainer at runtime\n            self.dirpath, self.filename = None, None\n        else:\n            if os.path.isdir(filepath):\n                self.dirpath, self.filename = filepath, '{epoch}'\n            else:\n                self.dirpath, self.filename = os.path.split(filepath)\n            os.makedirs(self.dirpath, exist_ok=True)\n        self.save_top_k = save_top_k\n        self.save_weights_only = save_weights_only\n        self.period = period\n        self.epoch_last_check = None\n        self.prefix = prefix\n        self.best_k_models = {}\n        # {filename: monitor}\n        self.kth_best_model = ''\n        self.best = 0\n        self.save_function = None\n\n        torch_inf = torch.tensor(np.Inf)\n        mode_dict = {\n            'min': (torch_inf, 'min'),\n            'max': (-torch_inf, 'max'),\n            'auto': (-torch_inf, 'max') if 'acc' in self.monitor or self.monitor.startswith('fmeasure')\n            else (torch_inf, 'min'),\n        }\n\n        if mode not in mode_dict:\n            rank_zero_warn(f'ModelCheckpoint mode {mode} is unknown, '\n                           f'fallback to auto mode.', RuntimeWarning)\n            mode = 'auto'\n\n        self.kth_value, self.mode = mode_dict[mode]\n\n    def _del_model(self, filepath):\n        if os.path.isfile(filepath):\n            os.remove(filepath)\n\n    def _save_model(self, filepath):\n        # make paths\n        os.makedirs(os.path.dirname(filepath), exist_ok=True)\n\n        # delegate the saving to the model\n        if self.save_function is not None:\n            self.save_function(filepath)\n        else:\n            raise ValueError(\".save_function() not set\")\n\n    def check_monitor_top_k(self, current):\n        less_than_k_models = len(self.best_k_models) < self.save_top_k\n        if less_than_k_models:\n            return True\n\n        if not isinstance(current, torch.Tensor):\n            current = torch.tensor(current)\n\n        monitor_op = {\n            \"min\": torch.lt,\n            \"max\": torch.gt,\n        }[self.mode]\n\n        return monitor_op(current, self.best_k_models[self.kth_best_model])\n\n    def format_checkpoint_name(self, epoch, metrics, ver=None):\n        \"\"\"Generate a filename according to the defined template.\n\n        Example::\n\n            >>> tmpdir = os.path.dirname(__file__)\n            >>> ckpt = ModelCheckpoint(os.path.join(tmpdir, '{epoch}'))\n            >>> os.path.basename(ckpt.format_checkpoint_name(0, {}))\n            'epoch=0.ckpt'\n            >>> ckpt = ModelCheckpoint(os.path.join(tmpdir, '{epoch:03d}'))\n            >>> os.path.basename(ckpt.format_checkpoint_name(5, {}))\n            'epoch=005.ckpt'\n            >>> ckpt = ModelCheckpoint(os.path.join(tmpdir, '{epoch}-{val_loss:.2f}'))\n            >>> os.path.basename(ckpt.format_checkpoint_name(2, dict(val_loss=0.123456)))\n            'epoch=2-val_loss=0.12.ckpt'\n            >>> ckpt = ModelCheckpoint(os.path.join(tmpdir, '{missing:d}'))\n            >>> os.path.basename(ckpt.format_checkpoint_name(0, {}))\n            'missing=0.ckpt'\n        \"\"\"\n        # check if user passed in keys to the string\n        groups = re.findall(r'(\\{.*?)[:\\}]', self.filename)\n\n        if len(groups) == 0:\n            # default name\n            filename = f'{self.prefix}_ckpt_epoch_{epoch}'\n        else:\n            metrics['epoch'] = epoch\n            filename = self.filename\n            for tmp in groups:\n                name = tmp[1:]\n                filename = filename.replace(tmp, name + '={' + name)\n                if name not in metrics:\n                    metrics[name] = 0\n            filename = filename.format(**metrics)\n        str_ver = f'_v{ver}' if ver is not None else ''\n        filepath = os.path.join(self.dirpath, self.prefix + filename + str_ver + '.ckpt')\n        return filepath\n\n    @rank_zero_only\n    def on_validation_end(self, trainer, pl_module):\n        # only run on main process\n        if trainer.proc_rank != 0:\n            return\n\n        metrics = trainer.callback_metrics\n        epoch = trainer.current_epoch\n        if self.save_top_k == 0:\n            # no models are saved\n            return\n        if self.epoch_last_check is not None and (epoch - self.epoch_last_check) < self.period:\n            # skipping in this term\n            return\n\n        self.epoch_last_check = epoch\n\n        filepath = self.format_checkpoint_name(epoch, metrics)\n        version_cnt = 0\n        while os.path.isfile(filepath):\n            filepath = self.format_checkpoint_name(epoch, metrics, ver=version_cnt)\n            # this epoch called before\n            version_cnt += 1\n\n        if self.save_top_k != -1:\n            current = metrics.get(self.monitor)\n\n            if current is None:\n                rank_zero_warn(\n                    f'Can save best model only with {self.monitor} available, skipping.', RuntimeWarning\n                )\n            elif self.check_monitor_top_k(current):\n                self._do_check_save(filepath, current, epoch)\n            elif self.verbose > 0:\n                log.info(f'\\nEpoch {epoch:05d}: {self.monitor}  was not in top {self.save_top_k}')\n\n        else:\n            if self.verbose > 0:\n                log.info(f'\\nEpoch {epoch:05d}: saving model to {filepath}')\n            self._save_model(filepath)\n\n    def _do_check_save(self, filepath, current, epoch):\n        # remove kth\n\n        del_list = []\n        if len(self.best_k_models) == self.save_top_k and self.save_top_k > 0:\n            delpath = self.kth_best_model\n            self.best_k_models.pop(self.kth_best_model)\n            del_list.append(delpath)\n\n        self.best_k_models[filepath] = current\n        if len(self.best_k_models) == self.save_top_k:\n            # monitor dict has reached k elements\n            _op = max if self.mode == 'min' else min\n            self.kth_best_model = _op(self.best_k_models,\n                                      key=self.best_k_models.get)\n            self.kth_value = self.best_k_models[self.kth_best_model]\n\n        _op = min if self.mode == 'min' else max\n        self.best = _op(self.best_k_models.values())\n\n        if self.verbose > 0:\n            log.info(\n                f'\\nEpoch {epoch:05d}: {self.monitor} reached'\n                f' {current:0.5f} (best {self.best:0.5f}), saving model to'\n                f' {filepath} as top {self.save_top_k}')\n        self._save_model(filepath)\n\n        for cur_path in del_list:\n            if cur_path != filepath:\n                self._del_model(cur_path)\n", "path": "pytorch_lightning/callbacks/model_checkpoint.py"}]}