Помогают защитить Большой Барьерный Риф с TensorFlow на Kaggle Присоединяйтесь вызов

Распределенное обучение с TensorFlow

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

Обзор

tf.distribute.Strategy является TensorFlow API для распространения обучения по нескольким чипам, несколько машин, или TPU , . Используя этот API, вы можете распространять существующие модели и обучающий код с минимальными изменениями кода.

tf.distribute.Strategy был разработан с этими основными целями:

  • Простота в использовании и поддержка нескольких сегментов пользователей, включая исследователей, инженеров машинного обучения и т. Д.
  • Обеспечьте хорошую производительность прямо из коробки.
  • Легкое переключение между стратегиями.

Вы можете распространять обучение с использованием tf.distribute.Strategy с API высокого уровня , как Keras Model.fit , а также пользовательские тренировочные циклы (и, в общем, любое вычисление , используя TensorFlow).

В TensorFlow 2.x, вы можете выполнять свои программы с нетерпением, или в графе с использованием tf.function . tf.distribute.Strategy намерена поддерживать оба режима исполнения, но лучше всего работает с tf.function . Нетерпеливый режим рекомендуется только для целей отладки и не поддерживается tf.distribute.TPUStrategy . Хотя в этом руководстве основное внимание уделяется обучению, этот API также можно использовать для распределения оценок и прогнозов на различных платформах.

Вы можете использовать tf.distribute.Strategy с очень небольшими изменениями в ваш код, потому что основные компоненты TensorFlow были изменены , чтобы стать стратегией-осознанной. Сюда входят переменные, слои, модели, оптимизаторы, метрики, сводки и контрольные точки.

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

Настроить TensorFlow

import tensorflow as tf

Типы стратегий

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

  • Синхронные против асинхронных обучения: Эти два распространенных способа распространения обучения с параллелизмом данных. При синхронном обучении все рабочие обучаются синхронно на разных срезах входных данных и агрегируют градиенты на каждом этапе. При асинхронном обучении все рабочие независимо обучаются над входными данными и асинхронно обновляют переменные. Обычно обучение синхронизации поддерживается с помощью архитектуры all-reduce и async через серверную архитектуру параметров.
  • Аппаратная платформа: Вы можете масштабировать обучение на нескольких графических процессоров на одном компьютере или нескольких компьютерах в сети (с 0 или более графических процессоров в каждом), или на облаке ТПУ.

Для поддержки этих случаев использования, TensorFlow имеет MirroredStrategy , TPUStrategy , MultiWorkerMirroredStrategy , ParameterServerStrategy , CentralStorageStrategy , а также другие стратегии , доступные. В следующем разделе объясняется, какие из них поддерживаются в каких сценариях в TensorFlow. Вот краткий обзор:

API обучения MirroredStrategy TPUStrategy MultiWorkerMirroredStrategy CentralStorageStrategy ParameterServerStrategy
Keras Model.fit Поддерживается Поддерживается Поддерживается Экспериментальная поддержка Экспериментальная поддержка
Пользовательский цикл обучения Поддерживается Поддерживается Поддерживается Экспериментальная поддержка Экспериментальная поддержка
API оценщика Ограниченная поддержка Не поддерживается Ограниченная поддержка Ограниченная поддержка Ограниченная поддержка

ЗеркальныйСтратегия

tf.distribute.MirroredStrategy поддерживает синхронное распределенное обучение на нескольких графических процессоров на одной машине. Он создает одну реплику на каждое устройство с графическим процессором. Каждая переменная в модели отражается во всех репликах. Вместе эти переменные образуют единую концептуальную переменную MirroredVariable . Эти переменные синхронизируются друг с другом за счет применения идентичных обновлений.

Для передачи обновлений переменных между устройствами используются эффективные алгоритмы полного сокращения. All-reduce собирает тензоры на всех устройствах, складывая их, и делает их доступными на каждом устройстве. Это объединенный алгоритм, который очень эффективен и может значительно снизить накладные расходы на синхронизацию. В зависимости от типа связи, доступной между устройствами, существует множество доступных алгоритмов и реализаций all-reduce. По умолчанию он использует NVIDIA Коллективный Communication Library ( NCCL ) как все сокращения реализации. Вы можете выбрать один из нескольких других вариантов или написать свой собственный.

Вот самый простой способ создания MirroredStrategy :

mirrored_strategy = tf.distribute.MirroredStrategy()
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)

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

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

mirrored_strategy = tf.distribute.MirroredStrategy(devices=["/gpu:0", "/gpu:1"])
WARNING:tensorflow:Some requested devices in `tf.distribute.Strategy` are not visible to TensorFlow: /job:localhost/replica:0/task:0/device:GPU:1,/job:localhost/replica:0/task:0/device:GPU:0
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0', '/job:localhost/replica:0/task:0/device:GPU:1')

Если вы хотите , чтобы переопределить связь перекрестного устройства, вы можете сделать это , используя cross_device_ops аргумента, снабжая экземпляр tf.distribute.CrossDeviceOps . В настоящее время tf.distribute.HierarchicalCopyAllReduce и tf.distribute.ReductionToOneDevice два отличных вариант tf.distribute.NcclAllReduce , которая по умолчанию.

mirrored_strategy = tf.distribute.MirroredStrategy(
    cross_device_ops=tf.distribute.HierarchicalCopyAllReduce())
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)

TPUStrategy

tf.distribute.TPUStrategy позволяет запускать обучение TensorFlow на Tensor Processing Units (TPUs) . TPU - это специализированные ASIC от Google, предназначенные для значительного ускорения рабочих нагрузок машинного обучения. Они доступны на Google Colab , в ТПУ Исследовательского облако , и облако ТПУ .

С точки зрения распределенной учебной архитектуры, TPUStrategy то же самое MirroredStrategy -IT Реализует синхронных распределены обучение. TPUs обеспечить свою собственную реализацию эффективных все сокращений и другие коллективных операций между несколькими ядрами ТПА, которые используются в TPUStrategy .

Вот как вы бы создать экземпляр TPUStrategy :

cluster_resolver = tf.distribute.cluster_resolver.TPUClusterResolver(
    tpu=tpu_address)
tf.config.experimental_connect_to_cluster(cluster_resolver)
tf.tpu.experimental.initialize_tpu_system(cluster_resolver)
tpu_strategy = tf.distribute.TPUStrategy(cluster_resolver)

TPUClusterResolver экземпляр помогает найти TPUs. В Colab вам не нужно указывать для него какие-либо аргументы.

Если вы хотите использовать это для облачных TPU:

  • Вы должны указать имя вашего TPU ресурса в tpu аргумент.
  • Вы должны инициализировать систему TPU явно в начале программы. Это необходимо до того, как TPU можно будет использовать для вычислений. Инициализация системы TPU также стирает память TPU, поэтому важно сначала выполнить этот шаг, чтобы избежать потери состояния.

MultiWorkerMirroredStrategy

tf.distribute.MultiWorkerMirroredStrategy очень похож на MirroredStrategy . Он реализует синхронное распределенное обучение для нескольких рабочих, каждый из которых может иметь несколько графических процессоров. Подобно tf.distribute.MirroredStrategy , он создает копии всех переменных в модели на каждом устройстве во всех рабочих.

Вот самый простой способ создания MultiWorkerMirroredStrategy :

strategy = tf.distribute.MultiWorkerMirroredStrategy()
WARNING:tensorflow:Collective ops is not configured at program startup. Some performance features may not be enabled.
INFO:tensorflow:Single-worker MultiWorkerMirroredStrategy with local_devices = ('/device:GPU:0',), communication = CommunicationImplementation.AUTO

MultiWorkerMirroredStrategy имеет две реализации для связи нескольких устройств. CommunicationImplementation.RING является RPC -На и поддерживает процессоры и графические процессоры. CommunicationImplementation.NCCL использует NCCL и предоставляет государство-оф-арт производительность графического процессора , но он не поддерживает процессоры. CollectiveCommunication.AUTO отсрочивает выбор для Tensorflow. Вы можете указать их следующим образом:

communication_options = tf.distribute.experimental.CommunicationOptions(
    implementation=tf.distribute.experimental.CommunicationImplementation.NCCL)
strategy = tf.distribute.MultiWorkerMirroredStrategy(
    communication_options=communication_options)
WARNING:tensorflow:Collective ops is not configured at program startup. Some performance features may not be enabled.
INFO:tensorflow:Single-worker MultiWorkerMirroredStrategy with local_devices = ('/device:GPU:0',), communication = CommunicationImplementation.NCCL

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

Для получения более подробной информации о MultiWorkerMirroredStrategy , рассмотрим следующие учебные пособия:

ParameterServerStrategy

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

В TensorFlow 2, учебный сервер параметров использует центральный координатор на основе архитектуры через tf.distribute.experimental.coordinator.ClusterCoordinator класса.

В этой реализации, worker и parameter server задачи выполняются tf.distribute.Server s , что прослушивание задач с координатора. Координатор создает ресурсы, отправляет обучающие задания, записывает контрольные точки и устраняет сбои задач.

В программировании работает на координаторе, вы будете использовать ParameterServerStrategy объект для определения шага обучения и использовать ClusterCoordinator для отправки учебных шагов для удаленных работников. Вот самый простой способ их создания:

strategy = tf.distribute.experimental.ParameterServerStrategy(
    tf.distribute.cluster_resolver.TFConfigClusterResolver(),
    variable_partitioner=variable_partitioner)
coordinator = tf.distribute.experimental.coordinator.ClusterCoordinator(
    strategy)

Чтобы узнать больше о ParameterServerStrategy , проверить подготовку сервера параметров с Keras Model.fit и пользовательские обучения петли учебника.

В TensorFlow 1, ParameterServerStrategy доступен только с оценщиками через tf.compat.v1.distribute.experimental.ParameterServerStrategy символ.

CentralStorageСтратегия

tf.distribute.experimental.CentralStorageStrategy делает синхронное обучение , а также. Переменные не зеркалируются, вместо этого они размещаются на ЦП, а операции реплицируются на всех локальных графических процессорах. Если есть только один графический процессор, все переменные и операции будут размещены на этом графическом процессоре.

Создание экземпляра CentralStorageStrategy по:

central_storage_strategy = tf.distribute.experimental.CentralStorageStrategy()
INFO:tensorflow:ParameterServerStrategy (CentralStorageStrategy if you are using a single machine) with compute_devices = ['/job:localhost/replica:0/task:0/device:GPU:0'], variable_device = '/job:localhost/replica:0/task:0/device:GPU:0'

Это создаст CentralStorageStrategy экземпляр , который будет использовать все видимые графические процессоры и CPU. Обновление переменных на репликах будет агрегировано перед применением к переменным.

Другие стратегии

В дополнение к перечисленным выше стратегии, существуют две другие стратегии , которые могут быть полезны для создания прототипов и отладки при использовании tf.distribute API.

Стратегия по умолчанию

Стратегия по умолчанию - это стратегия распространения, которая присутствует, когда явная стратегия распространения не входит в область действия. Он реализует tf.distribute.Strategy интерфейс , но это сквозная и не обеспечивает фактического распределения. Например, Strategy.run(fn) будет просто вызвать fn . Код, написанный с использованием этой стратегии, должен вести себя точно так же, как код, написанный без какой-либо стратегии. Вы можете думать об этом как о «запретной» стратегии.

Стратегия по умолчанию - одноэлементная, и ее нельзя создать больше экземпляров. Она может быть получена с помощью tf.distribute.get_strategy вне рамки какой - либо явная стратегии с (тот же API , который может быть использован для получения текущей стратегии внутри рамки Явной стратегии с ).

default_strategy = tf.distribute.get_strategy()

Эта стратегия служит двум основным целям:

  • Это позволяет безоговорочно писать код библиотеки, ориентированный на распространение. Например, в tf.optimizer S вы можете использовать tf.distribute.get_strategy и использовать эту стратегию для уменьшения градиентов, он всегда будет возвращать объект стратегии , на которой вы можете позвонить в Strategy.reduce API.
# In optimizer or other library code
# Get currently active strategy
strategy = tf.distribute.get_strategy()
strategy.reduce("SUM", 1., axis=None)  # reduce some values
1.0
  • Подобно библиотечному коду, его можно использовать для написания программ конечных пользователей для работы со стратегией распространения и без нее, не требуя условной логики. Вот пример фрагмента кода, иллюстрирующий это:
if tf.config.list_physical_devices('GPU'):
  strategy = tf.distribute.MirroredStrategy()
else:  # Use the Default Strategy
  strategy = tf.distribute.get_strategy()

with strategy.scope():
  # Do something interesting
  print(tf.Variable(1.))
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)
MirroredVariable:{
  0: <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=1.0>
}

OneDeviceStrategy

tf.distribute.OneDeviceStrategy стратегия поместить все переменные и вычисления на одном указанном устройстве.

strategy = tf.distribute.OneDeviceStrategy(device="/gpu:0")

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

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

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

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

Используйте tf.distribute.Strategy с Keras Model.fit

tf.distribute.Strategy интегрирован в tf.keras , что реализация TensorFlow о в спецификации Keras API . tf.keras это высокоуровневый API для создания и железнодорожных моделей. Объединяя в tf.keras бэкэндом, это бесшовные для вас , чтобы распространять свое обучение письменной форме в рамках учебной Keras с использованием Model.fit .

Вот что вам нужно изменить в своем коде:

  1. Создайте экземпляр соответствующего tf.distribute.Strategy .
  2. Перемещение создания Keras модели, оптимизатор и метрики внутри strategy.scope .

Стратегии распределения TensorFlow поддерживают все типы Keras модели- Sequential , функциональные и подклассы .

Вот фрагмент кода , чтобы сделать это по очень простой модели Keras с одним из Dense слоя:

mirrored_strategy = tf.distribute.MirroredStrategy()

with mirrored_strategy.scope():
  model = tf.keras.Sequential([tf.keras.layers.Dense(1, input_shape=(1,))])

model.compile(loss='mse', optimizer='sgd')
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

В этом примере используется MirroredStrategy , так что вы можете запустить на компьютере с несколькими графическими процессорами. strategy.scope() указывает на Keras , какую стратегию использовать для распространения обучения. Создание моделей / оптимизаторов / показателей внутри этой области позволяет создавать распределенные переменные вместо обычных переменных. После того, как это настроено, вы можете соответствовать своей модели, как обычно. MirroredStrategy заботится о репликации обучения в модели на доступных графических процессоров, агрегирование градиенты и многое другое.

dataset = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100).batch(10)
model.fit(dataset, epochs=2)
model.evaluate(dataset)
Epoch 1/2
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
2021-10-26 01:27:56.527729: W tensorflow/core/grappler/optimizers/data/auto_shard.cc:695] AUTO sharding policy will apply DATA sharding policy as it failed to apply FILE sharding policy because of the following reason: Found an unshardable source dataset: name: "TensorDataset/_2"
op: "TensorDataset"
input: "Placeholder/_0"
input: "Placeholder/_1"
attr {
  key: "Toutput_types"
  value {
    list {
      type: DT_FLOAT
      type: DT_FLOAT
    }
  }
}
attr {
  key: "output_shapes"
  value {
    list {
      shape {
        dim {
          size: 1
        }
      }
      shape {
        dim {
          size: 1
        }
      }
    }
  }
}
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
10/10 [==============================] - 3s 2ms/step - loss: 2.2552
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
Epoch 2/2
10/10 [==============================] - 0s 2ms/step - loss: 0.9968
2021-10-26 01:27:59.372113: W tensorflow/core/grappler/optimizers/data/auto_shard.cc:695] AUTO sharding policy will apply DATA sharding policy as it failed to apply FILE sharding policy because of the following reason: Found an unshardable source dataset: name: "TensorDataset/_2"
op: "TensorDataset"
input: "Placeholder/_0"
input: "Placeholder/_1"
attr {
  key: "Toutput_types"
  value {
    list {
      type: DT_FLOAT
      type: DT_FLOAT
    }
  }
}
attr {
  key: "output_shapes"
  value {
    list {
      shape {
        dim {
          size: 1
        }
      }
      shape {
        dim {
          size: 1
        }
      }
    }
  }
}
10/10 [==============================] - 1s 2ms/step - loss: 0.6190
0.6190494298934937

Здесь tf.data.Dataset обеспечивает подготовку и Eval ввод. Вы также можете использовать массивы NumPy:

import numpy as np

inputs, targets = np.ones((100, 1)), np.ones((100, 1))
model.fit(inputs, targets, epochs=2, batch_size=10)
Epoch 1/2
2021-10-26 01:28:00.609977: W tensorflow/core/grappler/optimizers/data/auto_shard.cc:695] AUTO sharding policy will apply DATA sharding policy as it failed to apply FILE sharding policy because of the following reason: Did not find a shardable source, walked to a node which is not a dataset: name: "FlatMapDataset/_9"
op: "FlatMapDataset"
input: "PrefetchDataset/_8"
attr {
  key: "Targuments"
  value {
    list {
    }
  }
}
attr {
  key: "f"
  value {
    func {
      name: "__inference_Dataset_flat_map_slice_batch_indices_997"
    }
  }
}
attr {
  key: "output_shapes"
  value {
    list {
      shape {
        dim {
          size: 10
        }
      }
    }
  }
}
attr {
  key: "output_types"
  value {
    list {
      type: DT_INT64
    }
  }
}
. Consider either turning off auto-sharding or switching the auto_shard_policy to DATA to shard this dataset. You can do this by creating a new `tf.data.Options()` object then setting `options.experimental_distribute.auto_shard_policy = AutoShardPolicy.DATA` before applying the options object to the dataset via `dataset.with_options(options)`.
10/10 [==============================] - 1s 2ms/step - loss: 0.4406
Epoch 2/2
10/10 [==============================] - 0s 2ms/step - loss: 0.1947
<keras.callbacks.History at 0x7fb81813d2d0>

В обоих случаях-с Dataset или NumPy-каждая партия данного входа делится поровну между несколькими репликами. Например, если вы используете MirroredStrategy с 2 графических процессорами, каждая партия размера 10 будет разделена между 2 графическими процессорами, с каждым из приемных 5 примеров ввода в каждом шаге. Каждая эпоха будет тренироваться быстрее по мере того, как вы добавляете больше графических процессоров. Как правило, вы хотите увеличивать размер пакета по мере добавления дополнительных ускорителей, чтобы эффективно использовать дополнительную вычислительную мощность. Вам также потребуется перенастроить скорость обучения в зависимости от модели. Вы можете использовать strategy.num_replicas_in_sync , чтобы получить число реплик.

# Compute a global batch size using a number of replicas.
BATCH_SIZE_PER_REPLICA = 5
global_batch_size = (BATCH_SIZE_PER_REPLICA *
                     mirrored_strategy.num_replicas_in_sync)
dataset = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100)
dataset = dataset.batch(global_batch_size)

LEARNING_RATES_BY_BATCH_SIZE = {5: 0.1, 10: 0.15}
learning_rate = LEARNING_RATES_BY_BATCH_SIZE[global_batch_size]

Что сейчас поддерживается?

API обучения MirroredStrategy TPUStrategy MultiWorkerMirroredStrategy ParameterServerStrategy CentralStorageStrategy
Keras Model.fit Поддерживается Поддерживается Поддерживается Экспериментальная поддержка Экспериментальная поддержка

Примеры и учебные пособия

Вот список руководств и примеров , которые иллюстрируют вышеупомянутую интеграцию конца в конец с Keras Model.fit :

  1. Учебник : Обучение с Model.fit и MirroredStrategy .
  2. Учебник : Обучение с Model.fit и MultiWorkerMirroredStrategy .
  3. Руководство : Содержит пример использования Model.fit и TPUStrategy .
  4. Учебное пособие : подготовка сервера параметров с Model.fit и ParameterServerStrategy .
  5. Учебное пособие : Тонкая настройка БЕРТ для многих задач из кле теста с Model.fit и TPUStrategy .
  6. TensorFlow Модель сад хранилище , содержащей коллекцию внедренного моделей , реализованный с использованием различных стратегий.

Используйте tf.distribute.Strategy с настраиваемыми циклами обучения

Как было показано выше, с использованием tf.distribute.Strategy с Keras Model.fit требует изменения только пару строк кода. С немного больше усилий, вы можете также использовать tf.distribute.Strategy с пользовательскими учебными циклами .

Если вам нужна большая гибкость и контроль над циклами обучения, чем это возможно с помощью Estimator или Keras, вы можете написать собственные циклы обучения. Например, при использовании GAN вы можете захотеть выполнять разное количество шагов генератора или дискриминатора в каждом раунде. Точно так же высокоуровневые структуры не очень подходят для обучения обучению с подкреплением.

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

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

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

with mirrored_strategy.scope():
  model = tf.keras.Sequential([tf.keras.layers.Dense(1, input_shape=(1,))])
  optimizer = tf.keras.optimizers.SGD()

Затем создайте входной набор данных и вызвать tf.distribute.Strategy.experimental_distribute_dataset распределить набор данных на основе стратегии.

dataset = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100).batch(
    global_batch_size)
dist_dataset = mirrored_strategy.experimental_distribute_dataset(dataset)
2021-10-26 01:28:01.831942: W tensorflow/core/grappler/optimizers/data/auto_shard.cc:695] AUTO sharding policy will apply DATA sharding policy as it failed to apply FILE sharding policy because of the following reason: Found an unshardable source dataset: name: "TensorDataset/_2"
op: "TensorDataset"
input: "Placeholder/_0"
input: "Placeholder/_1"
attr {
  key: "Toutput_types"
  value {
    list {
      type: DT_FLOAT
      type: DT_FLOAT
    }
  }
}
attr {
  key: "output_shapes"
  value {
    list {
      shape {
        dim {
          size: 1
        }
      }
      shape {
        dim {
          size: 1
        }
      }
    }
  }
}

Затем определите один шаг обучения. Использование tf.GradientTape для вычисления градиентов и оптимизатора , чтобы применить эти градиенты , чтобы обновить переменные вашу модель. Для того, чтобы распространить этот учебный шаг, положить его в функции train_step и передать его tf.distribute.Strategy.run вместе с набором данных входов , которые вы получили от dist_dataset созданного до:

loss_object = tf.keras.losses.BinaryCrossentropy(
  from_logits=True,
  reduction=tf.keras.losses.Reduction.NONE)

def compute_loss(labels, predictions):
  per_example_loss = loss_object(labels, predictions)
  return tf.nn.compute_average_loss(per_example_loss, global_batch_size=global_batch_size)

def train_step(inputs):
  features, labels = inputs

  with tf.GradientTape() as tape:
    predictions = model(features, training=True)
    loss = compute_loss(labels, predictions)

  gradients = tape.gradient(loss, model.trainable_variables)
  optimizer.apply_gradients(zip(gradients, model.trainable_variables))
  return loss

@tf.function
def distributed_train_step(dist_inputs):
  per_replica_losses = mirrored_strategy.run(train_step, args=(dist_inputs,))
  return mirrored_strategy.reduce(tf.distribute.ReduceOp.SUM, per_replica_losses,
                         axis=None)

Еще несколько моментов, которые следует отметить в приведенном выше коде:

  1. Вы использовали tf.nn.compute_average_loss для вычисления потерь. tf.nn.compute_average_loss суммирует в примере потери и делит сумму на global_batch_size . Это важно , потому что позже после того, как градиенты рассчитываются по каждой реплике, они агрегируются по репликам путем их суммирования.
  2. Вы также использовали tf.distribute.Strategy.reduce API для объединения результатов , возвращаемых tf.distribute.Strategy.run . tf.distribute.Strategy.run возвращает результаты от каждой локальной реплики в стратегии, и есть несколько способов , чтобы потреблять этот результат. Вы можете reduce их , чтобы получить агрегированные значения. Вы также можете сделать tf.distribute.Strategy.experimental_local_results , чтобы получить список значений , содержащиеся в результате, по одному на локальную реплику.
  3. При вызове apply_gradients в пределах области в стратегии распределения, его поведение изменяется. В частности, перед применением градиентов к каждому параллельному экземпляру во время синхронного обучения он выполняет суммирование всех реплик градиентов.

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

for dist_inputs in dist_dataset:
  print(distributed_train_step(dist_inputs))
tf.Tensor(0.18686396, shape=(), dtype=float32)
tf.Tensor(0.18628375, shape=(), dtype=float32)
tf.Tensor(0.18570684, shape=(), dtype=float32)
tf.Tensor(0.18513316, shape=(), dtype=float32)
tf.Tensor(0.1845627, shape=(), dtype=float32)
tf.Tensor(0.18399543, shape=(), dtype=float32)
tf.Tensor(0.18343134, shape=(), dtype=float32)
tf.Tensor(0.18287037, shape=(), dtype=float32)
tf.Tensor(0.18231256, shape=(), dtype=float32)
tf.Tensor(0.18175781, shape=(), dtype=float32)
tf.Tensor(0.18120615, shape=(), dtype=float32)
tf.Tensor(0.18065754, shape=(), dtype=float32)
tf.Tensor(0.18011193, shape=(), dtype=float32)
tf.Tensor(0.17956935, shape=(), dtype=float32)
tf.Tensor(0.17902976, shape=(), dtype=float32)
tf.Tensor(0.17849308, shape=(), dtype=float32)
tf.Tensor(0.17795937, shape=(), dtype=float32)
tf.Tensor(0.17742859, shape=(), dtype=float32)
tf.Tensor(0.17690066, shape=(), dtype=float32)
tf.Tensor(0.17637561, shape=(), dtype=float32)

В приведенном выше примере, вы итерацию над dist_dataset , чтобы внести вклад в ваше обучение. Вы также предоставляется tf.distribute.Strategy.make_experimental_numpy_dataset для поддержки входов Numpy. Вы можете использовать этот API для создания набора данных перед вызовом tf.distribute.Strategy.experimental_distribute_dataset .

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

iterator = iter(dist_dataset)
for _ in range(10):
  print(distributed_train_step(next(iterator)))
tf.Tensor(0.17585339, shape=(), dtype=float32)
tf.Tensor(0.17533402, shape=(), dtype=float32)
tf.Tensor(0.17481743, shape=(), dtype=float32)
tf.Tensor(0.17430364, shape=(), dtype=float32)
tf.Tensor(0.17379259, shape=(), dtype=float32)
tf.Tensor(0.17328428, shape=(), dtype=float32)
tf.Tensor(0.17277871, shape=(), dtype=float32)
tf.Tensor(0.17227581, shape=(), dtype=float32)
tf.Tensor(0.17177561, shape=(), dtype=float32)
tf.Tensor(0.17127804, shape=(), dtype=float32)

Это охватывает простейший случай использования tf.distribute.Strategy API для распространения пользовательских учебных циклов.

Что сейчас поддерживается?

API обучения MirroredStrategy TPUStrategy MultiWorkerMirroredStrategy ParameterServerStrategy CentralStorageStrategy
Пользовательский цикл обучения Поддерживается Поддерживается Поддерживается Экспериментальная поддержка Экспериментальная поддержка

Примеры и учебные пособия

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

  1. Учебник : Обучение с петлей на заказ обучения и MirroredStrategy .
  2. Учебник : Обучение с петлей на заказ обучения и MultiWorkerMirroredStrategy .
  3. Руководство : Содержит пример пользовательского тренировочного цикла с TPUStrategy .
  4. Учебное пособие : подготовка сервера параметров с помощью цикла пользовательского обучения и ParameterServerStrategy .
  5. TensorFlow Модель сад хранилище , содержащей коллекцию внедренного моделей , реализованный с использованием различных стратегий.

Другие темы

В этом разделе рассматриваются некоторые темы, относящиеся к нескольким вариантам использования.

Настройка переменной окружения TF_CONFIG

Для обучения нескольких работников, как упоминалось ранее, вам нужно настроить 'TF_CONFIG' переменную среды для каждого двоичного выполняющихся в кластере. В 'TF_CONFIG' переменная окружения представляет собой строку JSON , которая определяет , какие задачи представляют собой кластер, их адреса и роль каждой задачи в кластере. tensorflow/ecosystem репо предоставляет шаблон Kubernetes, который устанавливает 'TF_CONFIG' для ваших тренировочных задач.

Есть два компонента 'TF_CONFIG' : кластер и задача.

  • Кластер предоставляет информацию об учебном кластере, который состоит из разных типов заданий, таких как рабочие. В обучении с несколькими работниками обычно есть один работник, который берет на себя немного больше ответственности, например, сохранение контрольной точки и написание сводного файла для TensorBoard в дополнение к тому, что делает обычный работник. Такой работник упоминается как «главный» рабочий, и это общепринято , что работник с индексом 0 назначается в качестве главного работника (на самом деле это, как tf.distribute.Strategy реализуется).
  • С другой стороны, задача предоставляет информацию о текущей задаче. Первый кластер компонентов одинаков для всех рабочих процессов, а задача второго компонента отличается для каждого рабочего и определяет тип и индекс этого рабочего.

Одним из примеров 'TF_CONFIG' является:

os.environ["TF_CONFIG"] = json.dumps({
    "cluster": {
        "worker": ["host1:port", "host2:port", "host3:port"],
        "ps": ["host4:port", "host5:port"]
    },
   "task": {"type": "worker", "index": 1}
})

В этом 'TF_CONFIG' указывает , что есть три рабочих и два "ps" задачи в "cluster" вместе со своими узлами и портами. "task" часть определяет роль текущей задачи в "cluster" -worker 1 (второй работник). Допустимые роли в кластере "chief" , "worker" , "ps" и "evaluator" . Там не должно быть "ps" Работа за исключением случаев использования tf.distribute.experimental.ParameterServerStrategy .

Что дальше?

tf.distribute.Strategy активно находится в стадии разработки. Попробуйте его и предоставить отзыв с помощью вопросов GitHub .