fastnlp / fastNLP

fastNLP: A Modularized and Extensible NLP Framework. Currently still in incubation.

Home Page:https://gitee.com/fastnlp/fastNLP

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

超参数搜索工具集成

312shan opened this issue · comments

目前来看这个框架没有案例显示如何集成超参数搜索框架,例如 ray ,想知道其可行性,如果比较简单的话能否提供案例?
或者需要进一步开发才能适配 ray ?

commented

在我的理解中,超参数搜索框架应该是与程序相关性很低的,使用肯定是可以使用的。但是 fastnlp 没有能够直接降低超参搜索这部分代码的能力,对标链接中的例子,fastnlp 简化的是 train_cifar 函数中的代码。

你好,
首先:按我的理解 train_cifar 仅仅在最后有一段和 ray 相关的代码:

 with tune.checkpoint_dir(epoch) as checkpoint_dir:
            path = os.path.join(checkpoint_dir, "checkpoint")
            torch.save((net.state_dict(), optimizer.state_dict()), path)

        tune.report(loss=(val_loss / val_steps), accuracy=correct / total)

这个可以用一个Callback的 on_valid_end 方法中来执行, 这样顺利处理完第一部分和 ray 相关的代码。

第二部分:剩下的关键的代码是:

result = tune.run(
        partial(train_cifar, data_dir=data_dir),
        resources_per_trial={"cpu": 2, "gpu": gpus_per_trial},
        config=config,
        num_samples=num_samples,
        scheduler=scheduler,
        progress_reporter=reporter)

这部分要怎么和 FastNlp 原有 trainer.train 不侵入地合并在一起呢?

如果能解决这部分,那么就可以顺利使用 ray 了。

commented

使用一个train_cifar函数来包裹一下trainer.train的执行应该就可以了吧?

def train_cifar(*args, **kwargs):
   trainer = Trainer()
   trainer.run()

因为 Trainer.train 本质是在减少循环这部分的工作哇?肯定就是用来替换train_cifar中的循环部分,类似于数据处理肯定还是需要单独自己做好的。

谢谢, 包上能用。

ps : 不过如果模型代码有错,ray 的原因,控制台日志不会显示原来的pytorch 或者fastnlp 报错信息,而是仅仅是 报 TuneError: Trials did not complete", incomplete_trials ,且不会进调试断点,原来的pytorch 或者fastnlp 报错信息需要在 ray 写出的一个error.txt 里面查看。

commented

这里的原因应该是由于,ray是通过多进程的方式运行的代码,打断点的位置会卡在那个新拉起的进程而不是启动ray的那个程序。同时这个也是ray这类调度软件为了防止“某个子任务出问题,整个训练就出问题”,不得不采取的隔离启动ray进程和ray的子任务的方式。这种问题一般就只有通过先确保,(1)写的程序确实可以运行,(2)然后使用简单的代码测试调度是否与预期的一致;然后再合并到一起开始训练。

谢谢, 包上能用。

ps : 不过如果模型代码有错,ray 的原因,控制台日志不会显示原来的pytorch 或者fastnlp 报错信息,而是仅仅是 报 TuneError: Trials did not complete", incomplete_trials ,且不会进调试断点,原来的pytorch 或者fastnlp 报错信息需要在 ray 写出的一个error.txt 里面查看。

你好,这个多卡记录能够同步吗?我想用Optuna对接这个框架的DDP driver, 然而这里的逻辑是每一个子进程都重新跑一遍main.py, 请问我如何让不同子进程都共享一套参数,并且不用从头开始呢? 我可能对多卡训练的理解有误,请包涵我说的不对的地方

commented

我觉得你对多卡运行的理解应该是对的,多卡的运行确实是通过每个子进程重头在运行一遍实现的。根据optuna的文档,以及它提供的pytorch-lightning的ddp的example,https://github.com/optuna/optuna-examples/blob/e1e2ef76344c8e37580177c10b711b24a9814155/pytorch/pytorch_lightning_ddp.py#L163 ,我感觉应该是在create_study的时候加入一个storage的参数然后加上load_if_exists=True这样,这样在其它进程拉起的时候,它就会使用主进程运行的时候生成的参数。

感谢你们的辛苦工作,我再去自己探索一下,有问题再来请教