Multi GPU в керасе

33

Как вы можете программировать в библиотеке keras (или тензорном потоке), чтобы разделить обучение на несколько графических процессоров? Допустим, вы находитесь в экземпляре Amazon ec2 с 8 графическими процессорами, и вы хотели бы использовать их все для ускорения обучения, но ваш код предназначен только для одного процессора или графического процессора.

Гектор Бландин
источник
3
Вы проверили документ по тензорному потоку?
n1tk
@ sb0709: Я начал читать сегодня утром, но мне было интересно, как это сделать в керасе
Гектор
1
не знаю в керасе, но для тензорного потока: tf будет использовать GPU по умолчанию для вычислений, даже если это для CPU (если присутствует поддерживаемый GPU). так что вы можете просто сделать цикл for: "for d в ['/ gpu: 1', '/ gpu: 2', '/ gpu: 3' ... '/ gpu: 8',]:" и в «tf.device (d)» должен включать все ресурсы вашего экземпляра GPU. Таким образом, tf.device () будет фактически использоваться.
n1tk
Так ?? для d в ['/ gpu: 1', '/ gpu: 2', '/ gpu: 3' ... '/ gpu: 8',]: tf.device (d) и это? Я попробую вот так :)
Гектор Бландин
1
насколько я знаю, да, вы можете выполнить любую задачу на другом устройстве.
n1tk

Ответы:

37

Из часто задаваемых вопросов Keras:

https://keras.io/getting-started/faq/#how-can-i-run-a-keras-model-on-multiple-gpus

Ниже приведен скопированный код для включения «параллелизма данных». Т.е. каждый из ваших графических процессоров обрабатывает разные подмножества ваших данных независимо.

from keras.utils import multi_gpu_model

# Replicates `model` on 8 GPUs.
# This assumes that your machine has 8 available GPUs.
parallel_model = multi_gpu_model(model, gpus=8)
parallel_model.compile(loss='categorical_crossentropy',
                       optimizer='rmsprop')

# This `fit` call will be distributed on 8 GPUs.
# Since the batch size is 256, each GPU will process 32 samples.
parallel_model.fit(x, y, epochs=20, batch_size=256)

Обратите внимание, что это, по-видимому, действительно только для бэкэнда Tensorflow на момент написания.

Обновление (февраль 2018 г.) :

Теперь Keras принимает автоматический выбор gpu с помощью multi_gpu_model, поэтому вам больше не нужно жестко кодировать число gpus. Подробности в этом запросе на извлечение . Другими словами, это включает код, который выглядит следующим образом:

try:
    model = multi_gpu_model(model)
except:
    pass

Но чтобы быть более явным , вы можете придерживаться чего-то вроде:

parallel_model = multi_gpu_model(model, gpus=None)

Бонус :

Чтобы проверить, действительно ли вы используете все свои графические процессоры, в частности NVIDIA, вы можете контролировать свое использование в терминале, используя:

watch -n0.5 nvidia-smi

Ссылки:

weiji14
источник
Работает ли multi_gpu_model(model, gpus=None)в случае, когда есть только 1 GPU? Было бы здорово, если бы он автоматически адаптировался к числу доступных графических процессоров.
CMCDragonkai
Да, я думаю, что он работает с 1 графическим процессором, см. Github.com/keras-team/keras/pull/9226#issuecomment-361692460 , но вам может потребоваться быть осторожным, чтобы ваш код был адаптирован для работы на multi_gpu_model вместо простой модели , В большинстве случаев это, вероятно, не имеет значения, но если вы собираетесь что-то сделать, например, взять выходные данные какого-то промежуточного уровня, вам нужно будет соответствующим образом кодировать.
weiji14
Есть ли у вас какие-либо ссылки на различия между моделями нескольких графических процессоров?
CMCDragonkai
Вы имеете в виду что-то вроде github.com/rossumai/keras-multi-gpu/blob/master/blog/docs/… ?
weiji14
Эта ссылка была отличной @ weiji14. Однако меня также интересует, как это работает для вывода. Керас как-то делит партии поровну или по круговому расписанию на доступных репликах модели?
CMCDragonkai
4
  1. Для TensorFlow:

TensorFlow с использованием графических процессоров

Вот пример кода о том, как используется, поэтому для каждой задачи указывается список с устройствами / устройствами:

# Creates a graph.
c = []
for d in ['/gpu:2', '/gpu:3']:
  with tf.device(d):
    a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3])
    b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2])
    c.append(tf.matmul(a, b))
with tf.device('/cpu:0'):
  sum = tf.add_n(c)
# Creates a session with log_device_placement set to True.
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
# Runs the op.
print(sess.run(sum))

TF будет использовать GPU по умолчанию для вычислений, даже если это для CPU (если присутствует поддерживаемый GPU). так что вы можете просто сделать цикл for: "for d в ['/ gpu: 1', '/ gpu: 2', '/ gpu: 3' ... '/ gpu: 8',]:" и в «tf.device (d)» должен включать все ресурсы вашего экземпляра GPU. Таким образом, tf.device () будет фактически использоваться.

Масштабирование обучения модели Keras до нескольких графических процессоров

  1. Keras

Для Keras используется Mxnet, а не args.num_gpus , где num_gpus - список необходимых графических процессоров.

def backend_agnostic_compile(model, loss, optimizer, metrics, args):
  if keras.backend._backend == 'mxnet':
      gpu_list = ["gpu(%d)" % i for i in range(args.num_gpus)]
      model.compile(loss=loss,
          optimizer=optimizer,
          metrics=metrics, 
          context = gpu_list)
  else:
      if args.num_gpus > 1:
          print("Warning: num_gpus > 1 but not using MxNet backend")
      model.compile(loss=loss,
          optimizer=optimizer,
          metrics=metrics)
  1. horovod.tensorflow

Вдобавок ко всему, Uber с открытым исходным кодом Horovod недавно, и я думаю, это здорово:

Хоровод

import tensorflow as tf
import horovod.tensorflow as hvd

# Initialize Horovod
hvd.init()

# Pin GPU to be used to process local rank (one GPU per process)
config = tf.ConfigProto()
config.gpu_options.visible_device_list = str(hvd.local_rank())

# Build model…
loss = 
opt = tf.train.AdagradOptimizer(0.01)

# Add Horovod Distributed Optimizer
opt = hvd.DistributedOptimizer(opt)

# Add hook to broadcast variables from rank 0 to all other processes during
# initialization.
hooks = [hvd.BroadcastGlobalVariablesHook(0)]

# Make training operation
train_op = opt.minimize(loss)

# The MonitoredTrainingSession takes care of session initialization,
# restoring from a checkpoint, saving to a checkpoint, and closing when done
# or an error occurs.
with tf.train.MonitoredTrainingSession(checkpoint_dir=“/tmp/train_logs”,
                                      config=config,
                                      hooks=hooks) as mon_sess:
 while not mon_sess.should_stop():
   # Perform synchronous training.
   mon_sess.run(train_op)
n1tk
источник
2

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

import keras

config = tf.ConfigProto( device_count = {'GPU': 1 , 'CPU': 56} )
sess = tf.Session(config=config) 
keras.backend.set_session(sess)

После этого вам подойдет модель.

model.fit(x_train, y_train, epochs=epochs, validation_data=(x_test, y_test))

Наконец, вы можете уменьшить значения потребления, а не работу в верхних пределах.

johncasey
источник