{"record":{"id":"b58fe664b6148a38","repo":"Lightning-AI/pytorch-lightning","slug":"calling-trainer-fit-twice-on-the-same-trainer","errorCode":null,"errorMessage":"Calling `trainer.fit()` twice on the same Trainer instance using a spawn-based strategy is not supported. You can work around this limitation by creating a new Trainer instance and passing the `fit(ckpt_path=...)` argument.","messagePattern":"Calling `trainer\\.fit\\(\\)` twice on the same Trainer instance using a spawn-based strategy is not supported\\. You can work around this limitation by creating a new Trainer instance and passing the `fit\\(ckpt_path=\\.\\.\\.\\)` argument\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"src/lightning/pytorch/strategies/launchers/multiprocessing.py","lineNumber":115,"sourceCode":"\n        The function is allowed to have a return value. However, when all processes join, only the return value\n        of worker process 0 gets returned from this `launch` method in the main process.\n\n        Arguments:\n            function: The entry point for all launched processes.\n            *args: Optional positional arguments to be passed to the given function.\n            trainer: Optional reference to the :class:`~lightning.pytorch.trainer.trainer.Trainer` for which\n                a selected set of attributes get restored in the main process after processes join.\n            **kwargs: Optional keyword arguments to be passed to the given function.\n\n        \"\"\"\n        if self._start_method in (\"fork\", \"forkserver\"):\n            _check_bad_cuda_fork()\n        if self._start_method == \"spawn\":\n            _check_missing_main_guard()\n        if self._already_fit and trainer is not None and trainer.state.fn == TrainerFn.FITTING:\n            # resolving https://github.com/Lightning-AI/pytorch-lightning/issues/18775 will lift this restriction\n            raise NotImplementedError(\n                \"Calling `trainer.fit()` twice on the same Trainer instance using a spawn-based strategy is not\"\n                \" supported. You can work around this limitation by creating a new Trainer instance and passing the\"\n                \" `fit(ckpt_path=...)` argument.\"\n            )\n\n        # The default cluster environment in Lightning chooses a random free port number\n        # This needs to be done in the main process here before starting processes to ensure each rank will connect\n        # through the same port\n        assert self._strategy.cluster_environment is not None\n        os.environ[\"MASTER_PORT\"] = str(self._strategy.cluster_environment.main_port)\n\n        context = mp.get_context(self._start_method)\n        return_queue = context.SimpleQueue()\n\n        if self._start_method == \"spawn\":\n            global_states = _GlobalStateSnapshot.capture()\n            process_args = [trainer, function, args, kwargs, return_queue, global_states]\n        else:","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/Lightning-AI/pytorch-lightning/blob/9fed5c27d2a62ff0efd6c3573599921d6ff67c14/src/lightning/pytorch/strategies/launchers/multiprocessing.py#L97-L133","documentation":"A spawn-based multiprocessing launcher cannot be reused for a second fit run on the same Trainer: after the first fit, the spawned processes and the pickled trainer state make a relaunch unsafe, so Lightning blocks it with NotImplementedError (tracked in issue #18775).","triggerScenarios":"Calling trainer.fit() a second time (e.g. a second epoch sweep or a fine-tune stage) on the same Trainer whose strategy uses the spawn-based _MultiProcessingLauncher, with trainer.state.fn == FITTING.","commonSituations":"Fine-tuning loops, hyperparameter sweeps reusing one Trainer, resumed training scripts that call fit twice (train then continue training).","solutions":["Create a fresh Trainer for the second fit and pass fit(ckpt_path=...) to resume","Restructure to a single fit() call (use callbacks/loops to change behavior mid-training)","Track the issue Lightning-AI/pytorch-lightning#18775 for a version where the restriction is lifted"],"exampleFix":"# before\ntrainer.fit(model)\ntrainer.fit(model, ckpt_path=\"last.ckpt\")  # NotImplementedError\n\n# after\ntrainer.fit(model)\ntrainer2 = L.Trainer(max_epochs=20)\ntrainer2.fit(model, ckpt_path=\"last.ckpt\")","handlingStrategy":"fallback","validationCode":"if getattr(trainer.strategy.launcher, \"_already_fit\", False):\n    trainer = L.Trainer(**trainer_flags)  # fresh instance, pass ckpt_path to fit","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat one Trainer as one fit run; build a helper that creates a new Trainer per stage","Pass ckpt_path=... to fit on the new Trainer to resume state","Watch Lightning-AI/pytorch-lightning#18775"],"tags":["trainer","spawn","fit-twice","pytorch-lightning"],"backgroundTag":"trainer-reuse-not-supported","analyzedSha":"9fed5c27d2a62ff0efd6c3573599921d6ff67c14","analyzedAt":"2026-08-28T11:52:41.083Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}