Pytorch-分布式数据并行混淆



我刚刚在看DDP教程:

https://pytorch.org/tutorials/intermediate/ddp_tutorial.html

据此:

对检查点模块使用torch.save和torch.load是很常见的在训练期间和从检查站恢复。参见保存和加载了解更多详细信息。使用DDP时,一个优化是保存仅在一个进程中创建模型,然后将其加载到所有进程,从而减少写入开销。这是正确的,因为所有进程都启动从相同的参数和梯度向后同步通过,因此优化器应将参数设置为相同的值。如果使用此优化,请确保所有流程在保存完成之前不要开始加载。此外,加载时对于模块,您需要提供一个适当的maplocation参数以防止进程进入他人的设备。如果map_location为缺少,torch.load将首先将模块加载到CPU,然后复制每个参数都保存到其保存的位置,这将导致使用同一组设备在同一台机器上进行处理。了解更多信息高级故障恢复和弹性支持,请参阅TorchElastic。

我不明白这意味着什么。难道不应该只有一个进程/第一个GPU来保存模型吗?保存和加载是如何在流程/GPU之间共享权重的?

当您使用DistributedDataParallel时,您在多个设备上拥有相同的型号,这些设备正在同步以具有完全相同的参数。

使用DDP时,一种优化是仅在一个进程中保存模型,然后将其加载到所有进程,从而减少写入开销。

由于它们是相同的,因此没有必要保存所有进程中的模型,因为它只会多次写入相同的参数。例如,当您有4个进程/GPU时,您会将同一文件写入4次,而不是一次。只需将其从主进程中保存即可避免这种情况。

这是为了节省模型而进行的优化。如果在保存模型后立即加载模型,则需要更加小心。

如果使用此优化,请确保在保存完成之前,所有进程都不会开始加载。

如果只在一个进程中保存,则该进程将需要时间来写入文件。与此同时,所有其他进程都在继续,它们可能会在文件完全写入磁盘之前加载该文件,这可能会导致各种意外行为或故障,无论该文件是否还不存在,您是在尝试读取不完整的文件,还是加载模型的旧版本(如果覆盖同一文件(。

此外,在加载模块时,您需要提供适当的map_location参数,以防止进程进入他人的设备。如果缺少map_locationtorch.load将首先将模块加载到CPU,然后将每个参数复制到保存的位置,这将导致同一台机器上的所有进程使用相同的设备集

保存参数(或任何张量(时,PyTorch包括存储参数的设备。假设您从使用GPU 0(device = "cuda:0"(的进程中保存该信息,该信息将被保存,当您加载该信息时,参数将自动放在该设备上。但是,如果您在使用GPU1(device = "cuda:1"(的进程中加载它,则会错误地将它们加载到"cuda:0"中。现在,您不再使用多个GPU,而是在一个GPU中多次使用同一型号。最有可能的是,你会耗尽内存,但即使你没有,你也不会再使用其他GPU了。

为了避免这个问题,您应该为torch.loadmap_location设置适当的设备。

torch.load(PATH, map_location="cuda:1")
# Or load it on the CPU and later use .to(device) on the model
torch.load(PATH, map_location="cpu")

最新更新