Repository: Lightning-AI/pytorch-lightning
File: pytorch_lightning/callbacks/model_checkpoint.py (Python)

Code before:

        # backward compatibility... need to deprecate
        if self.monitor is None and 'val_loss' in metrics:
            self.monitor = 'val_loss'

        if self.monitor is None and 'checkpoint_on' in metrics:
            self.monitor = 'checkpoint_on'

        if self.save_top_k is None and self.monitor is not None:
            self.save_top_k = 1

    def _validate_monitor_key(self, trainer):
        metrics = trainer.logger_connector.callback_metrics

        # validate metric
        if self.monitor is not None and not self._is_valid_monitor_key(metrics):
            m = (
                f"ModelCheckpoint(monitor='{self.monitor}') not found in the returned metrics:"
                f" {list(metrics.keys())}. "
                f"HINT: Did you call self.log('{self.monitor}', tensor) in the LightningModule?"
            )
            raise MisconfigurationException(m)

    def _get_metric_interpolated_filepath_name(self, monitor_candidates: Dict[str, Any], epoch: int, step: int) -> str:
        filepath = self.format_checkpoint_name(epoch, step, monitor_candidates)
        version = 1
        while self._fs.exists(filepath):
            filepath = self.format_checkpoint_name(epoch, step, monitor_candidates, ver=version)
            version += 1
        return filepath

    def _monitor_candidates(self, trainer):
        monitor_candidates = deepcopy(trainer.logger_connector.callback_metrics)
        monitor_candidates.update(step=trainer.global_step, epoch=trainer.current_epoch)
        return monitor_candidates

    def _save_last_checkpoint(self, trainer, pl_module, monitor_candidates, filepath):
        should_save_last = self.monitor is None or self.save_last
        if not should_save_last:
            return

        last_filepath = filepath

        # when user ALSO asked for the 'last.ckpt' change the name
        if self.save_last:
            last_filepath = self._format_checkpoint_name(
                self.CHECKPOINT_NAME_LAST,
                trainer.current_epoch,
                trainer.global_step,
                monitor_candidates,
                prefix=self.prefix,

Review comment (suggestion):
Might be better to do: `version = self.STARTING_VERSION`

Code after:
                f" {list(metrics.keys())}. "
                f"HINT: Did you call self.log('{self.monitor}', tensor) in the LightningModule?"
            )
            raise MisconfigurationException(m)

    def _get_metric_interpolated_filepath_name(
        self,
        monitor_candidates: Dict[str, Any],
        epoch: int,
        step: int,
        del_filepath: Optional[str] = None
    ) -> str:
        filepath = self.format_checkpoint_name(epoch, step, monitor_candidates)
        version = self.STARTING_VERSION
        while self._fs.exists(filepath) and filepath != del_filepath:
            filepath = self.format_checkpoint_name(epoch, step, monitor_candidates, ver=version)
            version += 1
        return filepath

    def _monitor_candidates(self, trainer):
        monitor_candidates = deepcopy(trainer.logger_connector.callback_metrics)
        monitor_candidates.update(step=trainer.global_step, epoch=trainer.current_epoch)
        return monitor_candidates

    def _save_last_checkpoint(self, trainer, pl_module, monitor_candidates):
        should_save_last = self.monitor is None or self.save_last
        if not should_save_last:
            return

        # when user ALSO asked for the 'last.ckpt' change the name
        if self.save_last:
            last_filepath = self._format_checkpoint_name(
                self.CHECKPOINT_NAME_LAST,
                trainer.current_epoch,
                trainer.global_step,
                monitor_candidates,
                prefix=self.prefix,
            )
            last_filepath = os.path.join(self.dirpath, f"{last_filepath}{self.FILE_EXTENSION}")
        else:
            last_filepath = self._get_metric_interpolated_filepath_name(
                monitor_candidates, trainer.current_epoch, trainer.global_step
            )

        accelerator_backend = trainer.accelerator_backend

        if accelerator_backend is not None and accelerator_backend.rpc_enabled:
            # RPCPlugin manages saving all model states
            accelerator_backend.ddp_plugin.rpc_save_model(self._save_model, last_filepath, trainer, pl_module)
        else:
            self._save_model(last_filepath, trainer, pl_module)