Chainer:ParallelUpdater性能与多处理器Updater

Chainer:ParallelUpdater性能与多处理器Updater,chainer,Chainer,我想在CIFAR10数据集上训练CNN,在单个节点上的多个GPU上使用chainer。我尝试适应使用ParallelUpdater,方式与相同,但训练性能非常差——比在一个GPU上训练慢,即使所有8个GPU都在使用。我改为多处理器更新程序,性能(iters/秒)要好得多 坏的: 好: 我还使用ParallelUpdater使用8个GPU运行了这个基准测试脚本,但性能也非常差: 我的问题是:如何从ParallelUpdater中获得良好的性能,以及我可能会在这方面做错什么 谢谢 使用多个GPU时,

我想在CIFAR10数据集上训练CNN,在单个节点上的多个GPU上使用chainer。我尝试适应使用ParallelUpdater,方式与相同,但训练性能非常差——比在一个GPU上训练慢,即使所有8个GPU都在使用。我改为多处理器更新程序,性能(iters/秒)要好得多

坏的:

好:

我还使用ParallelUpdater使用8个GPU运行了这个基准测试脚本,但性能也非常差:

我的问题是:如何从ParallelUpdater中获得良好的性能,以及我可能会在这方面做错什么


谢谢

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

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

我猜ParallelUpdater的目的不是为了提高速度性能,而是为了高效地使用内存来计算大批量梯度

在阅读源代码时,模型更新是在python for loop中完成的,因此由于GIL(全局解释器锁)机制,我猜它的计算本身不是并行完成的。

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

也可以考虑使用Chaner-Mn作为扩展库来进行多GPU训练。


“由于GIL(全局解释器锁)机制,我想它的计算本身并不是并行完成的。”我明白了,这是有道理的。为了提高速度,我将坚持使用MultiprocessParallelUpdater——目前,我正在努力确保在一个节点上快速学习,而不需要MPI。(因为chainermn和MultiprocessParallelUpdater都使用NCCL,所以我期望类似的性能)啊,我明白了。不幸的是,我找不到批量大小和学习速度的任何组合可以显著加快学习速度(至少不是线性的,这正是我所希望的)。
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)