我尝试使用多个cpus并行实现棋盘游戏自玩数据生成,以同时进行自拍。对于父进程,我为30cpus创建了4个NN模型(1个模型为10 cpus,还有1个模型需要训练),每个模型都在不同的GPU中(该模型实现为具有Batchnorm的20块类似Resnet的体系结构)伪代码如下< / p>
nnet = NN(gpu_num=0)
nnet1 = NN(gpu_num=1)
nnet2 = NN(gpu_num=2)
nnet3 = NN(gpu_num=3)
for i in range(num_iteration):
nnet1.load_state_dict(nnet.state_dict())
nnet2.load_state_dict(nnet.state_dict())
nnet3.load_state_dict(nnet.state_dict())
samples = parallel_self_play()
nnet.train(samples)
parallel_self_play()实现如下
pool = mp.Pool(processes=num_cpu) #30
for i in range(self.args.numEps):
results = []
if i % 3 == 0:
net = self.nnet1
elif i % 3 == 1:
net = self.nnet2
else:
net = self.nnet3
results.append(pool.apply_async(AsyncSelfPlay, args=(net))
# get results from results array then return it
return results
我的代码在第一次自我播放时(几乎不到10分钟)的gpu利用率几乎可以正常工作(一次迭代不到10分钟),但是在第一次迭代(训练)之后,当我将新的权重加载到nnet1-3时,gpu利用率就永远无法达到再次提高80%(每次迭代大约30分钟-1小时)。在弄乱我的代码时,我注意到了几件事
此模型包括batchnorm层,当将模型切换到train()模式-> train->切换回eval()时,自播放(使用来自模型的正向传递)根本不使用gpu。
如果不从eval()-> train()(使用eval模式的火车)切换,这会导致GPU利用率降低(30-50%),但并没有完全消失。
< / li>如果不是主要模型的模型没有加载主要模型的权重,那么自玩游戏仍会使用100%gpu,因此我的猜测是在训练过程中发生了某些事情,并且改变了模型中的某些状态模型。
当仅使用8 cpus-1gpu架构并即时训练模型(没有中间模型)时,也会发生这种情况。
有人可以指导我在哪里修复代码或如何训练模型吗?