[Навыки разработки] · Навыки использования TensorFlow&Keras GPU
1. Описание проблемы
Использование TensorFlow и KerasУскоренное обучение с GPUИногда при обучении задачи необходимо протестировать результаты, или когда требуются параллельные обучающие данные, будет отображаться ошибка недостаточного объема памяти OOM. Здесь и далее при обучении задачи необходимо тестировать результаты, либо требуются параллельные обучающие данные для выполнения новых вычислительных задач.
Во-первых, давайте представим механизм, используемый графическим процессором TensorFlow&Keras: TensorFlow&Keras будет автоматически помещать данные и операции в графический процессор для обучения, когда он доступен (это отличается от MXNet иPyTorch обрабатывает это по-другому, MXNet и PyTorch требуют ручного программирования для указания устройства данных и работы, достоинства и недостатки этих способов здесь не обсуждаются, просто выберите тот, который вам подходит), а вся видеопамять GPU заполняется по умолчанию.
Таким образом, когда пользователь запускает вычислительную задачу, вся видеопамять будет занята, а при запуске новой задачи памяти будет недостаточно, что приведет к ошибке недостаточного объема видеопамяти OOM.
2. Анализ проблемы
Интерпретируя вышеуказанные проблемы, должно быть возможно решить следующие методы:
- Когда обучающая задача по умолчанию занимает всю память графического процессора, вы можете использовать ЦП для выполнения новых задач (это, очевидно, не оптимальный метод, и использование ЦП для выполнения новых задач будет очень медленным)
- Когда обучающая задача по умолчанию занимает всю память графического процессора, пользователь может установить размер памяти графического процессора, занимаемый этой задачей, и теперь при использовании графического процессора для новых задач она может выполняться параллельно
- Если имеется несколько графических процессоров, вы можете указать задачи на разных графических процессорах по умолчанию.
3. Используйте учебник
1. Решение 1. Используйте ЦП для новых задач
Это не оптимально, использование ЦП для новых задач будет медленным, но это обходной путь.
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
# 打印 TF 可用的 GPU
print(os.environ['CUDA_VISIBLE_DEVICES'])
# -1 表示不使用GPU
2. Решение 2. Установите объем памяти графического процессора, занимаемый задачей
Это метод, рекомендованный автором, поскольку TensorFlow и Keras будут занимать всю видеопамять при выполнении вычислительной задачи, на самом деле иногда она используется не так уж много.
При этом также есть небольшая проблема, что одна задача будет работать медленнее.Результат авторского теста заключается в том, что скорость выполнения двух одиночных задач параллельно с использованием вышеуказанного метода становится около 0,8, но в обмен на выполнение двух задач она еще очень стоит.. (Предполагается, что причина замедления заключается в том, что когда две задачи выполняются параллельно, нагрузка на графический процессор возрастает, и производительность, выделяемая для каждой задачи, снижается. Подобно запуску нескольких задач на компьютере, компьютер замерзнет)
Обратите внимание, что после выделения пространства видеопамяти память, занимаемая обучением модели, должна быть правильно установлена (имеется в виду фактическая занимаемая память, которую можно контролировать путем изменения batch_size) и не превышать размер, выделенный вами, иначе будут непредвиденные Появятся результаты.
import tensorflow as tf
# 在开启对话session前,先创建一个 tf.ConfigProto() 实例对象
gpuConfig = tf.ConfigProto(allow_soft_placement=True)
# 限制一个进程使用 60% 的显存
gpuConfig.gpu_options.per_process_gpu_memory_fraction = 0.6
# 把你的配置部署到session 变量名 sess 无所谓
sess1 =tf.Session(config=gpuConfig)
#这样,如果你指定的卡的显存是2000M的话,你这个进程只能用1200M。
Результат вывода (при 1228 МБ памяти, значит используется 1228 МБ, что согласуется с настройкой 0,6 * 2000)
Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 1228 MB memory) ->
physical GPU (device: 0, name: GeForce MX150, pci bus id: 0000:01:00.0, compute capability: 6.1)
3. Решение 3. Несколько графических процессоров предназначены для работы на разных графических процессорах.
Если позволяют условия, если у вас их несколько, вы можете разместить разные задачи на разных графических процессорах.Обратите внимание, что если вы делитесь с коллегами, вы должны договориться о том, как их распределить, чтобы все использовали один и тот же.
Метод настройки аналогичен первому. -1 означает не используется, 0 означает первое, 1 означает второе
Взяв в качестве примера два графических процессора, первую задачу можно использовать следующим образом, а вторую задачу можно изменить с 0 на 1. Методы для нескольких графических процессоров аналогичны. Обратите внимание, что один должен быть помещен в начале.
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
# 打印 TF 可用的 GPU
print(os.environ['CUDA_VISIBLE_DEVICES'])
# -1 表示不使用GPU 0代表第一个
Если имеется более двух графических процессоров и вы хотите настроить несколько графических процессоров для задачи, вы можете использовать следующие методы.
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0,1'
# 打印 TF 可用的 GPU
print(os.environ['CUDA_VISIBLE_DEVICES'])
# -1 表示不使用GPU 0代表第一个
Наконец, оставьте вопрос для размышления, что происходит, когда os.environ['CUDA_VISIBLE_DEVICES'] = '-1,0'?
Вы можете публиковать свои мнения и интерпретации в разделе комментариев. .
4. Как использовать Keras на нескольких видеокартах
Мы рекомендуем использовать серверную часть TensorFlow, когда доступно несколько карт GPU.
Существует два способа запуска модели на нескольких графических процессорах: параллельная обработка данных/параллельная обработка данных.
Скорее всего, вам нужен "параллелизм данных"
параллелизм данных
Параллелизм данных реплицирует целевую модель на несколько устройств и использует реплику на каждом устройстве для обработки различных частей всего набора данных. Keras предоставляет встроенную функцию в keras.utils.multi_gpu_model, которая может генерировать параллельную версию любой модели, до 8 графических процессоров. Пожалуйста, обратитесь к документации multi_gpu_model в utils. Ниже приведен пример:
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, вот пример:
# Model where a shared LSTM is used to encode two different sequences in parallel
input_a = keras.Input(shape=(140, 256))
input_b = keras.Input(shape=(140, 256))
shared_lstm = keras.layers.LSTM(64)
# Process the first sequence on one GPU
with tf.device_scope('/gpu:0'):
encoded_a = shared_lstm(tweet_a)
# Process the next sequence on another GPU
with tf.device_scope('/gpu:1'):
encoded_b = shared_lstm(tweet_b)
# Concatenate results on CPU
with tf.device_scope('/cpu:0'):
merged_vector = keras.layers.concatenate([encoded_a, encoded_b],
axis=-1)
Многозадачный параллелизм выходных данных
В версии Faster-RCNN для Keras он состоит из нескольких выходных ветвей, то есть множественных потерь, которые обычно называются при определении сети, а затем при компиляции можно найти имена разных слоев ветвей, например:
model.compile(optimizer=optimizer,
loss={'main_output': jaccard_distance_loss, 'aux_output': 'binary_crossentropy'},
metrics={'main_output': jaccard_distance_loss, 'aux_output': 'acc'},
loss_weights={'main_output': 1., 'aux_output': 0.5})
Среди них main_output и aux_output являются определенными именами слоев, но если используется keras.utils.training_utils.multi_gpu_model(), имена будут автоматически заменены и станут по умолчанию concatenate_1, concatenate_2 и т. д., поэтому вам нужно model.summary сначала (), распечатайте структуру сети, затем выясните, какие выходные данные представляют какую ветвь, а затем перекомпилируйте сеть следующим образом:
from keras.optimizers import Adam, RMSprop, SGD
model.compile(optimizer=RMSprop(lr=0.045, rho=0.9, epsilon=1.0),
loss={'concatenate_1': jaccard_distance_loss, 'concatenate_2': 'binary_crossentropy'},
metrics={'concatenate_1': jaccard_distance_loss, 'concatenate_2': 'acc'},
loss_weights={'concatenate_1': 1., 'concatenate_2': 0.5})
Более того, в версии Faster-RCNN для Keras в каждой партии RPN обучается, результаты теста используются в качестве входных данных сети обнаружения для обучения, и, наконец, результаты обучения параметров двух моделей сохраняются как модель.
распределенный
Раздача keras реализована с помощью TensorFlow.Для завершения распределенного обучения необходимо зарегистрировать Keras на сеансе TensorFlow, подключенном к кластеру:
server = tf.train.Server.create_local_server()
sess = tf.Session(server.target)
from keras import backend as K
K.set_session(sess)