在使用分布式模型训练时,遇到一个奇怪的问题,当把参数放在nn.ModuleList中,并把nn.ModuleList放在列表中时,模型训练精度显著下降,且收敛速度变慢:
xx = [nn.ModuleList(layers)]
xx = nn.ModuleList(layers)
如上,采用第一种方案的原因是需要多个参数,从而能够通过列表的index索引到正确的layer。然而,[nn.ModuleList(layers)]操作会使得这些层仅在CPU中,需要在使用的地方调用cuda():
xx[0].cuda()
调用cuda()的操作不会报错,能够正常训练。但是,之后会发现,模型收敛速度变慢,精度降低。猜测根本原因在于,分布式训练时,梯度应该在各个显卡中独立计算。而cuda()操作会导致数据放在同一个显卡,从而导致梯度计算出现误差。
隐藏的bug,调试了很久才发现该问题!!