Chainer: производительность ParallelUpdater по сравнению с MultiprocessUpdater - PullRequest
0 голосов
/ 04 мая 2018

Я хотел бы обучить CNN в наборе данных CIFAR10 с цепочкой на нескольких графических процессорах на одном узле. Я попытался адаптировать в этом примере для использования ParallelUpdater, способом, идентичным в примере параллельных данных mnist , но производительность обучения была очень плохой - медленнее, чем тренировка на одном GPU, хотя все 8 GPU использовались. Я перешел на MultiprocessUpdater, и производительность (итерс / сек) стала намного лучше.

Bad:

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)

Я также запускал эти сценарии тестирования с 8 графическими процессорами, используя ParallelUpdater, но производительность также была очень низкой: https://github.com/mitmul/chainer-cifar10/blob/master/train.py

У меня вопрос: как я могу получить хорошую производительность от ParallelUpdater, и что я могу с ним делать не так?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

Я не очень знаком с ParallelUpdater, поэтому моё понимание может быть неправильным.

Полагаю, цель ParallelUpdater не в быстродействии, а в том, чтобы эффективно использовать память для вычисления большого градиента пакета.

При чтении исходного кода обновление модели выполняется в python for loop, поэтому, я полагаю, из-за механизма GIL (Global Interpreter Lock) само его вычисление не выполняется параллельно. https://github.com/chainer/chainer/blob/master/chainer/training/updaters/parallel_updater.py#L118

Как написано, вы можете использовать MultiprocessUpdater, если хотите получить преимущество в быстродействии при использовании нескольких графических процессоров.

Кроме того, вы можете рассмотреть возможность использования ChainerMN, который является библиотекой расширений для обучения нескольких графических процессоров с использованием цепей.

0 голосов
/ 04 мая 2018

При использовании нескольких графических процессоров возникают некоторые накладные расходы на связь, поэтому скорость каждой итерации может быть ниже. Если вы используете параллельный метод данных, вы можете использовать намного больший размер пакета и большую скорость обучения, это может ускорить ваше обучение.

...