首页 > 解决方案 > 具有少量 gpus 的多个 cpu 生产者未使用 100% 的 gpus (pytorch)

问题描述

我尝试使用多个 cpu 并行实现棋盘游戏自玩数据生成,以同时进行自玩。对于父进程,我为 30cpus 创建了 4 个 NN 模型(1 个模型用于 10 cpus 和 1 个模型用于训练)每个模型都在不同的 gpus 中。(该模型实现为具有 batchnorm 的 20 块 resnet-like 架构)伪代码如下

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 

我的代码在第一次自我播放过程中几乎 100% 的 gpu 利用率(一次迭代不到 10 分钟)运行得非常好,但是在第一次迭代(训练)之后,当我将新权重加载到 nnet1-3 中时,gpu 利用率再也不会达到 80% (每次迭代约 30 分钟 - 1 小时)。我在弄乱我的代码时注意到了一些事情

  1. 该模型包括 batchnorm 层,当将模型切换到 train() 模式 -> 训练 -> 切换回 eval() 时,会导致 self-play(使用模型的前向传递)根本不使用 gpu。

  2. 如果它没有从 eval() -> train() (使用 eval 模式进行训练)切换,这会导致 gpu 利用率较低(30-50%)但并未完全消失。

  3. 如果不是主要模型的模型没有从主要模型加载权重,那么 self-play 仍然使用 100% gpu 所以我的猜测是在训练过程中发生了一些事情并改变了模型中的一些状态。

当仅使用 8 cpu - 1gpu 架构并动态训练模型(没有中间模型)时,也会发生这种情况。

有人可以指导我在哪里修复我的代码或我应该如何训练我的模型?

标签: pythonparallel-processingdeep-learningpytorchreinforcement-learning

解决方案


推荐阅读