Сохраните дату! Google I / O возвращается 18-20 мая Зарегистрируйтесь сейчас
Эта страница переведена с помощью Cloud Translation API.
Switch to English

Использовать графический процессор

Посмотреть на TensorFlow.org Запускаем в Google Colab Посмотреть исходный код на GitHub Скачать блокнот

Код tf.keras модели tf.keras будут прозрачно работать на одном графическом процессоре без каких-либо изменений кода.

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

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

Настраивать

Убедитесь, что у вас установлена ​​последняя версия TensorFlow gpu.

import tensorflow as tf
print("Num GPUs Available: ", len(tf.config.list_physical_devices('GPU')))
Num GPUs Available:  2

Обзор

TensorFlow поддерживает выполнение вычислений на различных типах устройств, включая CPU и GPU. Они представлены строковыми идентификаторами, например:

  • "/device:CPU:0" : ЦП вашего компьютера.
  • "/GPU:0" : сокращенное обозначение первого графического процессора вашей машины, видимого для TensorFlow.
  • "/job:localhost/replica:0/task:0/device:GPU:1" : полное имя второго графического процессора вашего компьютера, видимого для TensorFlow.

Если операция TensorFlow имеет реализации как ЦП, так и ГП, по умолчанию устройствам ГП будет отдан приоритет при назначении операции устройству. Например, tf.matmul имеет ядра как CPU, так и GPU. В системе с устройствами CPU:0 и GPU:0 , то GPU:0 устройство будет выбрано для запуска tf.matmul , если вы явно не запрашиваете запустить его на другом устройстве.

Размещение устройства регистрации

Чтобы узнать, каким устройствам назначены ваши операции и тензоры, поместите tf.debugging.set_log_device_placement(True) в качестве первого оператора вашей программы. Включение ведения журнала размещения устройств приводит к распечатке любых выделений тензорных модулей или операций.

tf.debugging.set_log_device_placement(True)

# Create some tensors
a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
c = tf.matmul(a, b)

print(c)
Executing op MatMul in device /job:localhost/replica:0/task:0/device:GPU:0
tf.Tensor(
[[22. 28.]
 [49. 64.]], shape=(2, 2), dtype=float32)

Приведенный выше код напечатает указание, что MatMul была выполнена на GPU:0 .

Размещение устройства вручную

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

tf.debugging.set_log_device_placement(True)

# Place tensors on the CPU
with tf.device('/CPU:0'):
  a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
  b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])

# Run on the GPU
c = tf.matmul(a, b)
print(c)
Executing op MatMul in device /job:localhost/replica:0/task:0/device:GPU:0
tf.Tensor(
[[22. 28.]
 [49. 64.]], shape=(2, 2), dtype=float32)

Вы увидите, что теперь a и b назначены CPU:0 . Поскольку устройство не было явно указано для операции MatMul , среда выполнения MatMul выберет одно на основе операции и доступных устройств ( GPU:0 в этом примере) и при необходимости автоматически скопирует тензоры между устройствами.

Ограничение роста памяти GPU

По умолчанию TensorFlow отображает почти всю память графического процессора всех графических процессоров (с учетом CUDA_VISIBLE_DEVICES ), видимых процессу. Это сделано для более эффективного использования относительно ценных ресурсов памяти графического процессора на устройствах за счет уменьшения фрагментации памяти. Чтобы ограничить TensorFlow определенным набором графических процессоров, мы используем метод tf.config.experimental.set_visible_devices .

gpus = tf.config.list_physical_devices('GPU')
if gpus:
  # Restrict TensorFlow to only use the first GPU
  try:
    tf.config.experimental.set_visible_devices(gpus[0], 'GPU')
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')
    print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPU")
  except RuntimeError as e:
    # Visible devices must be set before GPUs have been initialized
    print(e)
2 Physical GPUs, 1 Logical GPU

В некоторых случаях желательно, чтобы процесс выделял только подмножество доступной памяти или увеличивал использование памяти только в соответствии с требованиями процесса. TensorFlow предоставляет два метода для управления этим.

Первый вариант - включить рост памяти, вызвав tf.config.experimental.set_memory_growth , который пытается выделить столько памяти графического процессора, сколько необходимо для распределения времени выполнения: он начинает выделять очень мало памяти, и когда программа запускается и требуется больше памяти GPU, мы расширяем область памяти GPU, выделенную для процесса TensorFlow. Обратите внимание, что мы не освобождаем память, так как это может привести к фрагментации памяти. Чтобы включить увеличение объема памяти для определенного графического процессора, используйте следующий код перед выделением любых тензоров или выполнением любых операций.

gpus = tf.config.list_physical_devices('GPU')
if gpus:
  try:
    # Currently, memory growth needs to be the same across GPUs
    for gpu in gpus:
      tf.config.experimental.set_memory_growth(gpu, True)
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')
    print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPUs")
  except RuntimeError as e:
    # Memory growth must be set before GPUs have been initialized
    print(e)
2 Physical GPUs, 2 Logical GPUs

Другой способ включить эту опцию - установить для переменной окружения TF_FORCE_GPU_ALLOW_GROWTH значение true . Эта конфигурация зависит от платформы.

Второй метод - настроить виртуальное устройство GPU с помощью tf.config.experimental.set_virtual_device_configuration и установить жесткое ограничение на общий объем памяти, выделяемой на GPU.

gpus = tf.config.list_physical_devices('GPU')
if gpus:
  # Restrict TensorFlow to only allocate 1GB of memory on the first GPU
  try:
    tf.config.experimental.set_virtual_device_configuration(
        gpus[0],
        [tf.config.experimental.VirtualDeviceConfiguration(memory_limit=1024)])
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')
    print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPUs")
  except RuntimeError as e:
    # Virtual devices must be set before GPUs have been initialized
    print(e)
2 Physical GPUs, 2 Logical GPUs

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

Использование одного графического процессора в системе с несколькими графическими процессорами

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

tf.debugging.set_log_device_placement(True)

try:
  # Specify an invalid GPU device
  with tf.device('/device:GPU:2'):
    a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
    b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
    c = tf.matmul(a, b)
except RuntimeError as e:
  print(e)
/job:localhost/replica:0/task:0/device:GPU:2 unknown device.

Если указанное вами устройство не существует, вы получите RuntimeError : .../device:GPU:2 unknown device .

Если вы хотите, чтобы TensorFlow автоматически выбирал существующее и поддерживаемое устройство для выполнения операций в случае, если указанное не существует, вы можете вызвать tf.config.set_soft_device_placement(True) .

tf.config.set_soft_device_placement(True)
tf.debugging.set_log_device_placement(True)

# Creates some tensors
a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
c = tf.matmul(a, b)

print(c)
Executing op MatMul in device /job:localhost/replica:0/task:0/device:GPU:0
tf.Tensor(
[[22. 28.]
 [49. 64.]], shape=(2, 2), dtype=float32)

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

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

gpus = tf.config.list_physical_devices('GPU')
if gpus:
  # Create 2 virtual GPUs with 1GB memory each
  try:
    tf.config.experimental.set_virtual_device_configuration(
        gpus[0],
        [tf.config.experimental.VirtualDeviceConfiguration(memory_limit=1024),
         tf.config.experimental.VirtualDeviceConfiguration(memory_limit=1024)])
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')
    print(len(gpus), "Physical GPU,", len(logical_gpus), "Logical GPUs")
  except RuntimeError as e:
    # Virtual devices must be set before GPUs have been initialized
    print(e)
2 Physical GPU, 3 Logical GPUs

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

С tf.distribute.Strategy

Лучшая практика для использования нескольких графических процессоров - использовать tf.distribute.Strategy . Вот простой пример:

tf.debugging.set_log_device_placement(True)

strategy = tf.distribute.MirroredStrategy()
with strategy.scope():
  inputs = tf.keras.layers.Input(shape=(1,))
  predictions = tf.keras.layers.Dense(1)(inputs)
  model = tf.keras.models.Model(inputs=inputs, outputs=predictions)
  model.compile(loss='mse',
                optimizer=tf.keras.optimizers.SGD(learning_rate=0.2))
Executing op RandomUniform in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op Sub in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op Mul in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op Add in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op VarHandleOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op VarIsInitializedOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op LogicalNot in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op Assert in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op AssignVariableOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op ReadVariableOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op Identity in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op VarHandleOp in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op VarIsInitializedOp in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op LogicalNot in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op Assert in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op AssignVariableOp in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op Reshape in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op VarHandleOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op VarHandleOp in device /job:localhost/replica:0/task:0/device:GPU:1

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

Для получения дополнительной информации о стратегиях распространения ознакомьтесь с руководством здесь .

Ручное размещение

tf.distribute.Strategy работает под капотом, реплицируя вычисления между устройствами. Вы можете вручную реализовать репликацию, построив свою модель на каждом графическом процессоре. Например:

tf.debugging.set_log_device_placement(True)

gpus = tf.config.experimental.list_logical_devices('GPU')
if gpus:
  # Replicate your computation on multiple GPUs
  c = []
  for gpu in gpus:
    with tf.device(gpu.name):
      a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
      b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
      c.append(tf.matmul(a, b))

  with tf.device('/CPU:0'):
    matmul_sum = tf.add_n(c)

  print(matmul_sum)
Executing op MatMul in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op MatMul in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op AddN in device /job:localhost/replica:0/task:0/device:CPU:0
tf.Tensor(
[[ 44.  56.]
 [ 98. 128.]], shape=(2, 2), dtype=float32)