Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Шолле Ф. - Глубокое обучение на Python (Библиотека программиста) - 2023.pdf
Скачиваний:
6
Добавлен:
07.04.2024
Размер:
11.34 Mб
Скачать

522    Глава 13. Методы и приемы для применения на практике

13.2.2. Обучение на нескольких GPU

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

Есть.два.способа.распределения.вычислений.между.несколькими.устройствами:.

параллелизм данных.и.параллелизм моделей.

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

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

На.практике.параллелизм.моделей.используется.только.для.моделей,.которые. слишком.велики,.чтобы.уместиться.на.одном.устройстве,.—.и.не.как.способ. ускорения.обучения.обычных.моделей,.а.как.способ.обучения.очень.больших. моделей..В.этой.книге.мы.не.будем.его.рассматривать,.а.сосредоточимся.на. более.распространенном.параллелизме.данных..Давайте.посмотрим,.как.этот. способ.реализовать.

Приобретение двух или более графических процессоров

Прежде.всего.вам.нужно.получить.доступ.к.нескольким.GPU..В.настоящее.время.Google.Colab.позволяет.использовать.только.один.GPU,.поэтому.придется. сделать.одно.из.двух:

.приобрести.2–4.GPU,.смонтировать.их.на.одной.машине.(для.этого.потре- буется.мощный.блок.питания).и.установить.драйверы.CUDA,.cuDNN.и.т..д.. Но.для.большинства.из.нас.это.не.лучший.вариант;

.арендовать.виртуальную.машину.с.несколькими.GPU.в.Google.Cloud,.Azure. или.AWS..Вы.сможете.использовать.образы.виртуальных.машин.с.предустановленными.драйверами.и.программным.обеспечением,.благодаря.чему. затраты.на.настройку.будут.минимальными..Вероятно,.это.лучший.вариант. для.тех,.кто.не.занимается.обучением.моделей.круглосуточно.и.без.выходных.

Я.не.буду.подробно.рассказывать.о.том,.как.развернуть.облачные.экземпляры. с.несколькими.GPU:.техника.быстро.развивается,.поэтому.такие.инструкции. относительно.недолговечны;.плюс.вся.необходимая.информация.легко.доступна. в.интернете.

13.2. Масштабирование обучения моделей     523

А .если .вы .не .хотите .связываться .с .накладными .расходами .на .управление. собственными.экземплярами.виртуальных.машин,.то.можете.использовать. TensorFlow.Cloud.(https://github.com/tensorflow/cloud).—.пакет,.который.я.и.моя. команда.выпустили.недавно..Он.позволит.вам.начать.обучение.на.нескольких. GPU,.просто.добавив.одну.строку.кода.в.начало.блокнота.Colab..Если.вы.хотите. безболезненно.перейти.от.отладки.модели.в.Colab.к.максимально.быстрому.ее. обучению.на.любом.количестве.GPU,.ознакомьтесь.с.этим.пакетом.

Синхронное обучение на одном хосте с несколькими устройствами

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

Создать объект распределенной стратегии.

 

 

 

MirroredStrategy — лучшее решение

 

 

strategy = tf.distribute.MirroredStrategy()

 

 

 

 

 

 

print(f"Number of devices: {strategy.num_replicas_in_sync}")

with strategy.scope():

 

Открыть контекст стратегии

 

model = get_compiled_model()

 

Все, что создает переменные, должно

 

model.fit(

 

 

 

 

 

 

 

 

действовать в контексте стратегии. В общем

 

 

 

 

train_dataset,

 

 

 

 

 

 

 

 

случае в контексте стратегии достаточно

epochs=100,

 

 

 

 

создать модель и скомпилировать ее

 

 

 

 

validation_data=val_dataset,

Обучить модель на всех

callbacks=callbacks)

 

 

 

 

 

 

доступных устройствах

Эти.несколько.строк.реализуют.наиболее.распространенную.конфигурацию. обучения:.синхронное обучение на одном хосте с несколькими устройствами,. известную.в.TensorFlow.как.стратегия.зеркального.распределения..Под.«одним. хостом».подразумевается,.что.все.GPU.находятся.на.одной.машине.(в.отличие. от.кластера.из.множества.машин,.каждая.со.своим.GPU,.взаимодействующих. по.сети)..«Синхронное.обучение».означает,.что.состояние.копий.модели.для. каждого.GPU.всегда.остается.неизменным,.но.есть.варианты.распределенного. обучения,.где.это.не.так.

Когда.вы.открываете.контекст.MirroredStrategy .и.конструируете.в.нем.свою. модель,.объект.MirroredStrategy.создает.одну.копию.модели.(реплику).на.каждом.доступном.GPU..Затем.каждый.этап.обучения.разворачивается.следующим. образом.(рис..13.2).

1.. Из.набора.данных.извлекается.пакет.(называемый.глобальным пакетом).

2.. Он.разбивается.на.четыре.пакета.меньшего.размера.(называемых.локальными пакетами)..Например,.если.в.глобальном.пакете.512.образцов,.то.в.каждом. из.четырех.локальных.пакетов.будет.128.образцов..Для.оптимальной.загрузки.GPU.желательно,.чтобы.локальные.пакеты.были.достаточно.большими,. соответственно,.глобальному.пакету.обычно.хорошо.быть.очень.большим.

524    Глава 13. Методы и приемы для применения на практике

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

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

Рис. 13.2. Один шаг обучения MirroredStrategy: каждая реплика модели вычисляет локальные обновления весов, которые затем объединяются и используются для обновления состояния всех реплик

СОВЕТЫ ПО УВЕЛИЧЕНИЮ ПРОИЗВОДИТЕЛЬНОСТИ TF.DATA

При распределенном обучении всегда предоставляйте данные в виде объекта tf.data.Dataset, чтобы гарантировать наилучшую производительность. (Также можно передавать данные в виде массивов NumPy, потому что они автоматически преобразуются в объекты Dataset внутри метода fit().) Кроме этого, желательно использовать опережа­ющую выборку данных: перед передачей набора данных в fit() вызовите dataset.prefetch(buffer_size). Если вы не уверены в размере буфера, передайте параметр dataset.prefetch(tf.data.AUTOTUNE), который выберет размер буфера за вас.

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

13.2. Масштабирование обучения моделей     525

поступающих.с.разных.устройств,.занимает.некоторое.время..Эффективное. ускорение,.которое.получится.в.конечном.итоге,.зависит.от.количества.используемых.GPU:

. с.двумя.GPU.ускорение.получится.близким.к.двукратному;

. с.четырьмя.составит.что-то.около.3,8.раза;

. с.восемью.—.примерно.7,3.раза.

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

13.2.3. Обучение на TPU

Помимо.графических.процессоров,.в.мире.глубокого.обучения.все.чаще.отдают.предпочтение.более.специализированному.оборудованию,.разработанному.специально.для.рабочих.процессов.глубокого.обучения..Такие.одноцелевые.микросхемы.известны.как.специализированные.интегральные.схемы. (Application-Specific.Integrated.Circuits,.ASIC)..Разные.компании,.большие. и.малые,.работают.над.созданием.новых.микросхем,.но.наибольшего.успеха. в.этом.направлении.в.настоящее.время.добились.в.Google.с.их.тензорными.процессорами.(Tensor.Processing.Unit,.TPU),.доступными.в.Google.Cloud.и.Google. Colab.

Обучение.на.TPU.сопряжено.с.определенными.сложностями,.но.оно.того.стоит:. TPU.действуют.очень,.очень.быстро..Обучение.на.TPU.V2.обычно.происходит. в.15.раз.быстрее,.чем.на.GPU.NVIDIA.P100..Для.большинства.моделей.обучение. на.TPU.оказывается.в.среднем.в.три.раза.экономичнее,.чем.на.GPU.

Использование TPU в Google Colab

Фактически.в.Colab.можно.бесплатно.использовать.8-ядерный.TPU..В.меню. Colab.Runtime .(Среда.выполнения).выберите.пункт.Change Runtime Type .(Сменить. среду.выполнения).—.и.в.открывшемся.диалоге,.в.раскрывающемся.списке. Hardware Accelerator .(Аппаратный.ускоритель),.вы.увидите,.что,.помимо.среды. выполнения.GPU,.вам.доступна.среда.выполнения.TPU.

При.использовании.среды.выполнения.GPU.ваши.модели.будут.брать.GPU. напрямую.—.вам.не.придется.что-то.дополнительно.настраивать..Но.со.сре- дой.выполнения.TPU.ситуация.иная.—.вы.должны.сделать.дополнительный. шаг,.прежде.чем.начать.создавать.модели,.а.именно.подключиться.к.кластеру.TPU.

526    Глава 13. Методы и приемы для применения на практике

Вот.как.это.делается:

import tensorflow as tf

tpu = tf.distribute.cluster_resolver.TPUClusterResolver.connect() print("Device:", tpu.master())

Не.обязательно.досконально.понимать,.что.делает.данный.код,.—.это.всего. лишь.короткое.заклинание,.соединяющее.среду.выполнения.вашего.ноутбука. с.устройством..Сезам,.откройся!

Как.и.при.обучении.на.нескольких.GPU,.использование.TPU.требует.открыть. контекст.стратегии.распределения.—.в.данном.случае.TPUStrategy..Стратегия. TPUStrategy .следует.тому.же.шаблону.распределения,.что.и.MirroredStrategy:. для.каждого.ядра.TPU.создается.своя.реплика.модели,.и.все.реплики.синхронизируются.

Вот.простой.пример.

Листинг 13.4. Создание модели в контексте TPUStrategy

from tensorflow import keras

from tensorflow.keras import layers

strategy = tf.distribute.TPUStrategy(tpu)

print(f"Number of replicas: {strategy.num_replicas_in_sync}")

def build_model(input_size):

inputs = keras.Input((input_size, input_size, 3))

x = keras.applications.resnet.preprocess_input(inputs) x = keras.applications.resnet.ResNet50(

weights=None, include_top=False, pooling="max")(x) outputs = layers.Dense(10, activation="softmax")(x) model = keras.Model(inputs, outputs) model.compile(optimizer="rmsprop",

loss="sparse_categorical_crossentropy", metrics=["accuracy"])

return model

with strategy.scope():

model = build_model(input_size=32)

Теперь .можно .начинать .обучение..Но .есть .одна .любопытная .особенность. обучения.на.TPU.в.Colab:.конфигурация.с.двумя.виртуальными.машинами..

Виртуальная.машина.со.средой.выполнения.вашего.блокнота.—.это.отдельная. виртуальная.машина,.отличная.от.виртуальной.машины,.оснащенной.TPU..Поэтому.не.получится.просто.запустить.обучение.на.данных.из.файлов,.хранящихся.

13.2. Масштабирование обучения моделей     527

на.локальном.диске.(то.есть.на.диске,.связанном.с.виртуальной.машиной,.где. выполняется.блокнот)..Среда.выполнения.TPU.не.может.читать.данные.оттуда..Поэтому.вам.придется.эти.данные.загрузить..Сделать.это.можно.двумя. способами:

.провести.обучение.на.данных,.находящихся.в.памяти.виртуальной.машины. (не.на.диске)..Если.ваши.данные.располагаются.в.массиве.NumPy,.то.ничего. больше.делать.не.нужно;

.сохранить.данные.в.корзину.Google.Cloud.Storage.(GCS).и.создать.объект. набора.данных,.который.будет.читать.данные.непосредственно.из.корзины. без.загрузки.на.локальную.машину..Среда.выполнения.TPU.может.читать. данные.из.GCS..Это.единственный.вариант.для.наборов.данных,.слишком. больших,.чтобы.уместиться.в.памяти.

Давайте.выполним.обучение.на.данных,.находящихся.в.массивах.NumPy.в.па- мяти,.—.наборе.данных.CIFAR10:

(x_train, y_train), (x_test, y_test) = keras.datasets.cifar10.load_data() model.fit(x_train, y_train, batch_size=1024)

Обратите внимание, что обучение на TPU производится практически так же, как обучение на GPU, — нужно создать пакеты больших размеров, чтобы обеспечить максимальную загрузку устройства

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

ВВОД/ВЫВОД КАК УЗКОЕ МЕСТО

TPU могут очень быстро обрабатывать пакеты данных, поэтому скорость чтения данных из корзины GCS легко может стать узким местом.

Если набор данных достаточно мал, сохраните его в памяти виртуальной машины. Это можно сделать вызовом метода dataset.cache() объекта набора данных. В этом случае данные будут читаться из GCS только один раз.

Если набор данных слишком велик и не умещается в памяти, сохраните его в виде файлов TFRecord — эффективном двоичном формате, который обеспечивает возможность быстрой загрузки. На сайте keras.io вы найдете пример, демонстрирующий сохранение данных в файлахTFRecord (https://

keras.io/examples/keras_recipes/creating_tfrecords/).