Сбой SageMaker при использовании Multi-GPU с keras.utils.multi_gpu_model - PullRequest
0 голосов
/ 26 ноября 2018

При запуске AWS SageMaker с пользовательской моделью, TrainingJob завершается ошибкой с Ошибка алгоритма при использовании Keras плюс бэкэнд Tensorflow в конфигурации с несколькими GPU:

from keras.utils import multi_gpu_model

parallel_model = multi_gpu_model(model, gpus=K)
parallel_model.compile(loss='categorical_crossentropy',
optimizer='rmsprop')
parallel_model.fit(x, y, epochs=20, batch_size=256)

Эта простая параллельная модельзагрузка не удастся.Больше нет ошибок или исключений из регистрации в CloudWatch.Эта конфигурация работает должным образом на локальном компьютере с 2x NVIDIA GTX 1080, тем же бэкэндом Keras Tensorflow.

Согласно документации SageMaker и учебным пособиям , утилита multi_gpu_model будет работать нормально, когда бэкэнд Keras является MXNet,но я не нашел никакого упоминания, когда бэкэнд был Tensorflow с той же конфигурацией мульти GPU.

[ОБНОВЛЕНИЕ]

Я обновил код с предложенным ответом нижеи я добавляю некоторую запись в журнал до того, как TrainingJob зависает

Эта запись в журнале повторяется дважды

2018-11-27 10:02:49.878414: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1511] Adding visible gpu devices: 0, 1, 2, 3
2018-11-27 10:02:49.878462: I tensorflow/core/common_runtime/gpu/gpu_device.cc:982] Device interconnect StreamExecutor with strength 1 edge matrix:
2018-11-27 10:02:49.878471: I tensorflow/core/common_runtime/gpu/gpu_device.cc:988] 0 1 2 3
2018-11-27 10:02:49.878477: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1001] 0: N Y Y Y
2018-11-27 10:02:49.878481: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1001] 1: Y N Y Y
2018-11-27 10:02:49.878486: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1001] 2: Y Y N Y
2018-11-27 10:02:49.878492: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1001] 3: Y Y Y N
2018-11-27 10:02:49.879340: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1115] Created TensorFlow device (/device:GPU:0 with 14874 MB memory) -> physical GPU (device: 0, name: Tesla V100-SXM2-16GB, pci bus id: 0000:00:1b.0, compute capability: 7.0)
2018-11-27 10:02:49.879486: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1115] Created TensorFlow device (/device:GPU:1 with 14874 MB memory) -> physical GPU (device: 1, name: Tesla V100-SXM2-16GB, pci bus id: 0000:00:1c.0, compute capability: 7.0)
2018-11-27 10:02:49.879694: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1115] Created TensorFlow device (/device:GPU:2 with 14874 MB memory) -> physical GPU (device: 2, name: Tesla V100-SXM2-16GB, pci bus id: 0000:00:1d.0, compute capability: 7.0)
2018-11-27 10:02:49.879872: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1115] Created TensorFlow device (/device:GPU:3 with 14874 MB memory) -> physical GPU (device: 3, name: Tesla V100-SXM2-16GB, pci bus id: 0000:00:1e.0, compute capability: 7.0)

До того, как появится некоторая информация о регистрации для каждого графического процессора, которая повторяется 4 раза

2018-11-27 10:02:46.447639: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1432] Found device 3 with properties:
name: Tesla V100-SXM2-16GB major: 7 minor: 0 memoryClockRate(GHz): 1.53
pciBusID: 0000:00:1e.0
totalMemory: 15.78GiB freeMemory: 15.37GiB

Согласно журналу, все 4 графических процессора видны и загружены в серверную часть Tensorflow Keras.После этого не ведется регистрация приложения, статус TrainingJob некоторое время равен inProgress , после чего он становится Failed с той же Ошибка алгоритма .

Глядя на логирование CloudWatch, я вижу некоторые метрики в работе.В частности, GPU Memory Utilization, CPU Utilization в порядке, а GPU utilization - 0%.

enter image description here

[ОБНОВЛЕНИЕ]

Из-за известной ошибки на Keras, связанной с сохранением модели с несколькими графическими процессорами, я использую это переопределение утилиты multi_gpu_model в keras.utils

from keras.layers import Lambda, concatenate
from keras import Model
import tensorflow as tf

def multi_gpu_model(model, gpus):
    #source: https://github.com/keras-team/keras/issues/8123#issuecomment-354857044
  if isinstance(gpus, (list, tuple)):
    num_gpus = len(gpus)
    target_gpu_ids = gpus
  else:
    num_gpus = gpus
    target_gpu_ids = range(num_gpus)

  def get_slice(data, i, parts):
    shape = tf.shape(data)
    batch_size = shape[:1]
    input_shape = shape[1:]
    step = batch_size // parts
    if i == num_gpus - 1:
      size = batch_size - step * i
    else:
      size = step
    size = tf.concat([size, input_shape], axis=0)
    stride = tf.concat([step, input_shape * 0], axis=0)
    start = stride * i
    return tf.slice(data, start, size)

  all_outputs = []
  for i in range(len(model.outputs)):
    all_outputs.append([])

  # Place a copy of the model on each GPU,
  # each getting a slice of the inputs.
  for i, gpu_id in enumerate(target_gpu_ids):
    with tf.device('/gpu:%d' % gpu_id):
      with tf.name_scope('replica_%d' % gpu_id):
        inputs = []
        # Retrieve a slice of the input.
        for x in model.inputs:
          input_shape = tuple(x.get_shape().as_list())[1:]
          slice_i = Lambda(get_slice,
                           output_shape=input_shape,
                           arguments={'i': i,
                                      'parts': num_gpus})(x)
          inputs.append(slice_i)

        # Apply model on slice
        # (creating a model replica on the target device).
        outputs = model(inputs)
        if not isinstance(outputs, list):
          outputs = [outputs]

        # Save the outputs for merging back together later.
        for o in range(len(outputs)):
          all_outputs[o].append(outputs[o])

  # Merge outputs on CPU.
  with tf.device('/cpu:0'):
    merged = []
    for name, outputs in zip(model.output_names, all_outputs):
      merged.append(concatenate(outputs,
                                axis=0, name=name))
    return Model(model.inputs, merged)

Это нормально работает на местном 2x NVIDIA GTX 1080 / Intel Xeon / Ubuntu 16.04.Сбой при обучении SageMaker.

Я разместил эту проблему на форуме AWS Sagemaker в

[ОБНОВЛЕНИЕ]

Я немного изменил код tf.session, добавив несколько инициализаторов

with tf.Session() as session:
    K.set_session(session)
    session.run(tf.global_variables_initializer())
    session.run(tf.tables_initializer())

и теперь, по крайней мере, я вижу, что используется один графический процессор (я полагаю, устройство gpu:0)из показателей экземпляра.Multi-GPU не работает в любом случае.

Ответы [ 2 ]

0 голосов
/ 13 декабря 2018

Я прошу прощения за медленный ответ.

Кажется, что есть много потоков, которые работают параллельно, и я хочу связать их вместе, чтобы другие люди, имеющие такую ​​же проблему, могли видетьпрогресс и обсуждение продолжаются.

https://forums.aws.amazon.com/thread.jspa?messageID=881541 https://forums.aws.amazon.com/thread.jspa?messageID=881540

https://github.com/aws/sagemaker-python-sdk/issues/512

Есть несколько вопросов по этому поводу.

Какая версия TensorFlow и Keras?

Я не слишком уверен, что вызывает эту проблему.Есть ли в вашем контейнере все необходимые зависимости, такие как CUDA и т. Д.?https://www.tensorflow.org/install/gpu

Удалось ли вам тренироваться, используя один графический процессор с Keras?

0 голосов
/ 27 ноября 2018

Возможно, это не лучший ответ для вашей проблемы, но это то, что я использую для модели с несколькими GPU с бэкэндом Tensorflow.Сначала я инициализирую, используя:

def setup_multi_gpus():
    """
    Setup multi GPU usage

    Example usage:
    model = Sequential()
    ...
    multi_model = multi_gpu_model(model, gpus=num_gpu)
    multi_model.fit()

    About memory usage:
    https://stackoverflow.com/questions/34199233/how-to-prevent-tensorflow-from-allocating-the-totality-of-a-gpu-memory
    """
    import tensorflow as tf
    from keras.utils.training_utils import multi_gpu_model
    from tensorflow.python.client import device_lib

    # IMPORTANT: Tells tf to not occupy a specific amount of memory
    from keras.backend.tensorflow_backend import set_session  
    config = tf.ConfigProto()  
    config.gpu_options.allow_growth = True  # dynamically grow the memory used on the GPU  
    sess = tf.Session(config=config)  
    set_session(sess)  # set this TensorFlow session as the default session for Keras.


    # getting the number of GPUs 
    def get_available_gpus():
       local_device_protos = device_lib.list_local_devices()
       return [x.name for x in local_device_protos if x.device_type    == 'GPU']

    num_gpu = len(get_available_gpus())
    print('Amount of GPUs available: %s' % num_gpu)

    return num_gpu

Затем я звоню

# Setup multi GPU usage
num_gpu = setup_multi_gpus()

и создаю модель.

...

После чего вы можете сделать этомодель с несколькими графическими процессорами.

multi_model = multi_gpu_model(model, gpus=num_gpu)
multi_model.compile...
multi_model.fit...

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

Удачи!

Редактировать: Я заметил, что последовательность за последовательностью не может работать с несколькими графическими процессорами.Это та модель, которую вы пытаетесь тренировать?

...