Chainer: ParallelUpdater performance vs MultiprocessUpdater



我想在单个节点上的多个GPU上使用链接器在CIFAR10数据集上训练CNN。我尝试改编此示例以使用 ParallelUpdater,其方式与 mnist 数据并行示例相同,但训练性能非常差——比在一个 GPU 上训练慢,即使所有 8 个 GPU 都被利用了。我改用了MultiprocessUpdater,性能(迭代/秒(要好得多。

坏:

num_gpus = 8
chainer.cuda.get_device_from_id(0).use()
train_iter = chainer.iterators.SerialIterator(train, batch_size)
if num_gpus > 0:
updater = training.updater.ParallelUpdater(
train_iter,
optimizer,
devices={('main' if device == 0 else str(device)): device for device in range(num_gpus)},
)
else:
updater = training.updater.StandardUpdater(train_iter, optimizer, device=0)

好:

num_gpus = 8
devices = range(num_gpus)
train_iters = [chainer.iterators.MultiprocessIterator(i, batch_size, n_processes=num_gpus) 
for i in chainer.datasets.split_dataset_n_random(train, len(devices))]
test_iter = chainer.iterators.MultiprocessIterator(test, batch_size, repeat=False, n_processes=num_gpus)
device = 0 if num_gpus > 0 else -1  # -1 indicates CPU, 0 indicates first GPU device.
if num_gpus > 0:
updater = training.updaters.MultiprocessParallelUpdater(train_iters, optimizer, devices=range(num_gpus))
else:
updater = training.updater.StandardUpdater(train_iters[0], optimizer, device=device)

我还使用 ParallelUpdater 运行了带有 8 个 GPU 的基准测试脚本,但性能也非常差:https://github.com/mitmul/chainer-cifar10/blob/master/train.py

我的问题是:我怎样才能从 ParallelUpdater 获得良好的性能,我可能做错了什么?

谢谢!

使用多个 GPU 时,通信会产生一些开销,因此每次迭代速度可能会变慢。 如果使用数据并行方法,则可以使用更大的批量大小和较大的学习速率,它可以加速您的训练。

我对ParallelUpdater不太熟悉,所以我的理解可能是错误的。

我想ParallelUpdater的目的不是为了速度性能,而是它的主要目的是有效地利用内存来计算大批量梯度。

在读取源代码时,模型更新是在python for loop中完成的,因此由于GIL(全局解释器锁(机制,我想它的计算本身并不是并行完成的。 https://github.com/chainer/chainer/blob/master/chainer/training/updaters/parallel_updater.py#L118

如前所述,如果您想通过使用多个 GPU 来获得速度性能的好处,您可以使用MultiprocessUpdater

此外,您可以考虑使用 ChainerMN 它是使用链接器进行多 GPU 训练的扩展库。

  • GitHub
  • 文档

最新更新