python - 具有少量 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 小时)。我在弄乱我的代码时注意到了一些事情
该模型包括 batchnorm 层,当将模型切换到 train() 模式 -> 训练 -> 切换回 eval() 时,会导致 self-play(使用模型的前向传递)根本不使用 gpu。
如果它没有从 eval() -> train() (使用 eval 模式进行训练)切换,这会导致 gpu 利用率较低(30-50%)但并未完全消失。
如果不是主要模型的模型没有从主要模型加载权重,那么 self-play 仍然使用 100% gpu 所以我的猜测是在训练过程中发生了一些事情并改变了模型中的一些状态。
当仅使用 8 cpu - 1gpu 架构并动态训练模型(没有中间模型)时,也会发生这种情况。
有人可以指导我在哪里修复我的代码或我应该如何训练我的模型?
解决方案
推荐阅读
- c# - if 语句自行清除面板中的控件
- docker - 有没有办法从同一网络上的另一台计算机 ssh 到 docker 机器
- java - Java中的异常和数组问题
- powershell - 带通配符的变量
- python - 如何过滤列表中出现在同一列表python中较长元素中的字符串元素?
- arrays - Python/curve_fit:无法通过初始化猜测传递数组
- java - 为什么我在使用带有片段的 RecyclerView 时不断收到空引用错误
- java - 为什么按任意键方法不会循环停止?
- delphi - Delphi 10.3:找不到所需的包
- python - TypeError:级别类型不匹配:0.2。将数据拆分为训练、验证和测试集时