Pytorch-分布式数据并行混淆

Pytorch-分布式数据并行混淆,pytorch,distributed-computing,Pytorch,Distributed Computing,我只是在看DDP教程: 据此: 通常使用torch.save和torch.load来检查点模块 在训练期间,从检查点恢复。请参见保存和加载 有关更多详细信息,请参见模型。使用DDP时,一个优化是保存 只在一个进程中创建模型,然后将其加载到所有进程, 减少写开销。这是正确的,因为所有进程都会启动 从相同的参数和渐变向后同步 通过,因此优化器应该将参数设置为 相同的值。如果使用此优化,请确保所有流程都执行此优化 在保存完成之前不开始加载。另外,装货的时候, 在模块中,您需要提供一个适当的map_位

我只是在看DDP教程:

据此:

通常使用torch.save和torch.load来检查点模块 在训练期间,从检查点恢复。请参见保存和加载 有关更多详细信息,请参见模型。使用DDP时,一个优化是保存 只在一个进程中创建模型,然后将其加载到所有进程, 减少写开销。这是正确的,因为所有进程都会启动 从相同的参数和渐变向后同步 通过,因此优化器应该将参数设置为 相同的值。如果使用此优化,请确保所有流程都执行此优化 在保存完成之前不开始加载。另外,装货的时候, 在模块中,您需要提供一个适当的map_位置参数 防止进程进入其他人的设备。如果地图位置是 缺失,torch.load将首先将模块加载到CPU,然后复制 将每个参数保存到保存它的位置,这将导致 在同一台机器上使用同一组设备进行处理。更多 高级故障恢复和弹性支持,请参阅 反复无常的


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

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

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

因为它们是相同的,所以不必保存所有进程中的模型,因为它只需多次写入相同的参数。例如,当您有4个进程/GPU时,您会将同一文件写入4次而不是一次。这可以通过只从主进程保存它来避免

这是对模型保存的优化。如果在保存模型后立即加载模型,则需要更加小心

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

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

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

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

为避免该问题,您应该为的
map\u location
设置适当的设备

火炬装载(路径、地图位置=“cuda:1”) #或者将其加载到CPU上,然后在模型上使用.to(设备) 火炬装载(路径、地图位置=“cpu”)
我尝试设置此模块并运行培训。我有4个GPU,所以启动了4个多处理“线程”。但是在训练中,我发现每个过程的损失都是不同的!我在做了损耗后打印了损耗。backward()只有渐变是同步的,而不是损耗。如果您想同步损失,则需要手动进行。例如,当我使用DataParallel对一个进程进行训练时,损失会以逻辑线性方式减少,但当我在4个GPU 4进程上使用DistributedDataParallel进行训练时,损失会急剧增加。我确信我的数据得到了正确的“分发”