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

Code before:
        # ----------------------------
        # POST-Training CLEAN UP
        # ----------------------------
        # hook
        if self.state.fn == TrainerFn.FITTING:
            self.call_hook('on_fit_end')

        # teardown
        self._call_teardown_hook(model)

        if self.state.status != TrainerStatus.INTERRUPTED:
            self.state.status = TrainerStatus.FINISHED
        self.state.stage = None

        return self.accelerator.results

    def _pre_dispatch(self):
        self.accelerator.pre_dispatch(self)
        self._log_hyperparams()

    def _log_hyperparams(self):
        # log hyper-parameters
        if self.logger is not None:
            # save exp to get started (this is where the first experiment logs are written)
            datamodule_hparams = self.datamodule.hparams_initial if self.datamodule is not None else {}
            hparams_initial = merge_hparams(self.lightning_module.hparams_initial, datamodule_hparams)

            self.logger.log_hyperparams(hparams_initial)
            self.logger.log_graph(self.lightning_module)
            self.logger.save()

    def _post_dispatch(self):
        self.accelerator.post_dispatch(self)
        # these `teardown` calls are here instead of in `_call_teardown_hook` since they are internal teardowns
        # which need to happen before.
        self.accelerator.teardown()
        self._active_loop.teardown()

    def _dispatch(self):
        if self.evaluating:
            self.accelerator.start_evaluating(self)
        elif self.predicting:
            self.accelerator.start_predicting(self)
        else:
            self.accelerator.start_training(self)

    def run_stage(self):
        self.accelerator.dispatch(self)
        self.__setup_profiler()

        if self.evaluating:

Review comment (suggestion):
Not sure if having the `merge_hparams` is useful considering how simple it is to merge two dictionaries in python

Code after:
        # POST-Training CLEAN UP
        # ----------------------------
        # hook
        if self.state.fn == TrainerFn.FITTING:
            self.call_hook('on_fit_end')

        # teardown
        self._call_teardown_hook(model)

        if self.state.status != TrainerStatus.INTERRUPTED:
            self.state.status = TrainerStatus.FINISHED
        self.state.stage = None

        return self.accelerator.results

    def _pre_dispatch(self):
        self.accelerator.pre_dispatch(self)
        self._log_hyperparams()

    def _log_hyperparams(self):
        # log hyper-parameters
        if self.logger is not None:
            # save exp to get started (this is where the first experiment logs are written)
            datamodule_hparams = self.datamodule.hparams_initial if self.datamodule is not None else {}
            lightning_hparams = self.lightning_module.hparams_initial
            colliding_keys = lightning_hparams.keys() & datamodule_hparams.keys()
            if colliding_keys:
                raise MisconfigurationException(
                    f"Error while merging hparams: the keys {colliding_keys} are present "
                    "in both the LightningModule's and LightningDataModule's hparams."
                )

            hparams_initial = {**lightning_hparams, **datamodule_hparams}

            self.logger.log_hyperparams(hparams_initial)
            self.logger.log_graph(self.lightning_module)
            self.logger.save()

    def _post_dispatch(self):
        self.accelerator.post_dispatch(self)
        # these `teardown` calls are here instead of in `_call_teardown_hook` since they are internal teardowns
        # which need to happen before.
        self.accelerator.teardown()
        self._active_loop.teardown()

    def _dispatch(self):
        if self.evaluating:
            self.accelerator.start_evaluating(self)
        elif self.predicting:
            self.accelerator.start_predicting(self)
        else: