在 PyTorch Lightning 中运行多个模型的问题

Posted

技术标签:

【中文标题】在 PyTorch Lightning 中运行多个模型的问题【英文标题】:Issue with running multiple models in PyTorch Lightning 【发布时间】:2020-11-23 09:57:33 【问题描述】:

我正在开发一个系统,该系统需要使用 Lightning 训练数十个单独的模型 (>50),每个模型都有自己的 TensorBoard 图和日志。我当前的实现每个模型有一个 Trainer 对象,当我超过约 90 个 Trainer 对象时,我似乎遇到了这个错误。有趣的是,该错误仅在我运行 .test() 方法时出现,而不是在 .fit() 期间出现:

Traceback (most recent call last):
  File "lightning/main_2.py", line 193, in <module>
    main()
  File "lightning/main_2.py", line 174, in main
    new_trainer.test(model=new_model, test_dataloaders=te_loader)
  File "\Anaconda3\envs\pyenv\lib\site-packages\pytorch_lightning\trainer\trainer.py", line 1279, in test
    results = self.__test_given_model(model, test_dataloaders)
  File "\Anaconda3\envs\pyenv\lib\site-packages\pytorch_lightning\trainer\trainer.py", line 1343, in __test_given_model
    self.set_random_port(force=True)
  File "\Anaconda3\envs\pyenv\lib\site-packages\pytorch_lightning\trainer\distrib_data_parallel.py", line 398, in set_random_port
    default_port = RANDOM_PORTS[-1]
IndexError: index -1 is out of bounds for axis 0 with size 0

由于我刚开始使用 Lightning,我不确定拥有一个培训师/模型是否是最好的方法。但是,我需要每个模型的单独图,并且似乎如果我对多个模型使用单个训练器,结果会被覆盖。

作为参考,我定义了不同的培训师列表:

for i in range(args["num_users"]):
    trainer_list_0.append(Trainer(max_epochs=args["epochs"], gpus=1, default_root_dir=args["save_path"],
                                          fast_dev_run=args["fast_dev_run"], weights_summary=None))
    trainer_list_1.append(Trainer(max_epochs=args["epochs"], gpus=1, default_root_dir=args["save_path"],
                                            fast_dev_run=args["fast_dev_run"], weights_summary=None))
    trainer_list_2.append(Trainer(max_epochs=args["epochs"], gpus=1, default_root_dir=args["save_path"],
                                            fast_dev_run=args["fast_dev_run"], weights_summary=None))

关于训练:

for i in range(args["num_users"]):
    trainer_list_0[i].fit(model_list_0[i], train_dataloader=dataloader_list[i],
                                      val_dataloaders=val_loader)
    trainer_list_1[i].fit(model_list_1[i], train_dataloader=dataloader_list[i],
                                        val_dataloaders=val_loader)
    trainer_list_2[i].fit(model_list_2[i], train_dataloader=dataloader_list[i],
                                        val_dataloaders=val_loader)

和测试:

for i in range(args["num_users"]):
    trainer_list_0[i].test(test_dataloaders=te_loader)
    trainer_list_1[i].test(test_dataloaders=te_loader)
    trainer_list_2[i].test(test_dataloaders=te_loader)

谢谢!

【问题讨论】:

【参考方案1】:

据我所知,每个Trainer 预计只有一个模型。您可以使用预定义的实验名称和版本将TensorBoardLogger 对象显式传递给Trainer,以保持绘图分开(请参阅docs)。

from pytorch_lightning import Trainer
from pytorch_lightning.loggers import TensorBoardLogger
logger = TensorBoardLogger("tb_logs", name="my_model", version="version_XX")
trainer = Trainer(logger=logger)

您遇到的问题与 ddp 模块有关。其源代码包含以下几行[1]、[2]:

RANDOM_PORTS = RNG1.randint(10000, 19999, 1000)
    def set_random_port(self, force=False):
        ...
        default_port = RANDOM_PORTS[-1]
        RANDOM_PORTS = RANDOM_PORTS[:-1]

        if not force:
            default_port = os.environ.get('MASTER_PORT', default_port)

我不确定您为什么会遇到 90+ Trainers 的问题,但您可以尝试删除此行:

RANDOM_PORTS = RANDOM_PORTS[:-1]

【讨论】:

感谢您的提示,删除 RANDOM_PORTS = RANDOM_PORTS[:-1] 解决了这个问题。此外,我正在关注this pull request,它直接解决了这个问题。应该在以后的更新中修复。

以上是关于在 PyTorch Lightning 中运行多个模型的问题的主要内容,如果未能解决你的问题,请参考以下文章

跨多个模型的 Pytorch Lightning Tensorboard 记录器

将 ddp 后端与 PyTorch Lightning 一起使用时验证整个验证集

PyTorch Lightning 中的批量测试及其存在的问题

无法在 Google Colab 上安装 Pytorch Lightning Flash

PyTorch-lightning 模型在第一个 epoch 后内存不足

GCP 上的 PyTorch Lightning 多节点训练错误