【发布时间】:2020-03-26 19:43:31
【问题描述】:
我在使用 pytorch DistributedDataParallel 时遇到了一些问题。情况是:
-
我的模型是 A,它像往常一样在 单个 GPU 上进行了训练。假设A中有三层:
class A(nn.module): def __init__(self): super(A,self).__init__() self.layer0 = layer0 self.layer1 = layer1 self.layer2 = layer2 def forward(self,x): x=self.layer0(x) x=self.layer1(x) x=self.layer2(x) return x 现在我有了一些新数据。我想在多个 GPU 上微调 A。我需要将 A 包装为多 GPU 模型 B。
-
但是有两个训练阶段。在第一阶段,我想修复
layer0和layer1的B。在第二阶段,只修复layer0。那么layer1中的参数requires_grad应该在训练期间改变。但是,DistributedDataParalleldoc 说:您应该切勿在使用 DistributedDataParallel 封装模型后尝试更改模型的参数。
实际上,我尝试使用B.module 来引用包裹在B 中的A。但与单GPU模型相比,测试结果异常。也许这种方式是不允许的。
我该怎么办?有什么合适的方法来包装我的模型吗?保存和加载模型需要注意什么?
只需在具有多个 GPU 的单台机器上运行它,这样您就可以忽略使用多台机器的分布式情况。非常感谢。
2019.12.03 更新
按照@jodag 的建议,我尝试了DataParallel,但没有成功。这次我在包裹之后没有改变 B 中的任何东西(除了训练它)。为简单起见,我的代码是这样的(我引用了this):
class B(nn.DataParallel):
def __getattr__(self, name):
try:
return super().__getattr__(name)
except AttributeError:
return getattr(self.module, name)
a = A()
b = B(a,device_ids=[0,1])
b = b.cuda()
trained_param = b.layer2.parameters()
# trained_param = [{'params':b.layer2.parameters()},{'params':b.layer1.parameters()}]
optimizer = optim.Adam(trained_param)
b.train()
...
for x, label in data_loader:
optimizer.zero_grad()
x = x.to(0) # This line can be commented.
y = b(x)
l = loss(y, label)
l.backword()
optimizer.step()
【问题讨论】:
-
DistributedDataParallel在这里不是绝对必要的。您可以尝试将模型包装在DataParallel中,这会将模型分发到机器上的所有本地 GPU。 -
@jodag 谢谢。我试过了,不幸的是它表现得一样。查看更新。
-
我关闭了这个问题,因为可能有其他原因导致它。我必须用我的代码调试它。这里提供的信息可能不足以解决问题。
标签: python machine-learning parallel-processing gpu pytorch