Spec-Zone.ru › TensorFlow 1.15

tf.compat.v2.distribute.MirroredStrategy

Зеркалирует переменные для распределения по нескольким устройствам и машинам.

Унаследован от: Strategy

tf.compat.v2.distribute.MirroredStrategy(
    devices=None, cross_device_ops=None
)

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

Чтобы использовать MirroredStrategy с несколькими рабочими узлами, обратитесь к tf.distribute.MultiWorkerMirroredStrategy.

Аргументы
devices список строк устройств. Если None, используются все доступные GPU. Если GPU не найдены, используется CPU.
cross_device_ops необязательно, наследник CrossDeviceOps. Если это не задано, по умолчанию используется nccl.
Атрибуты
extended tf.distribute.StrategyExtended с дополнительными методами.
num_replicas_in_sync Возвращает количество реплик, по которым агрегируются градиенты.

Методы

experimental_distribute_dataset

Просмотреть исходный код

experimental_distribute_dataset(
    dataset
)

Распределяет экземпляр tf.data.Dataset, предоставленный через dataset.

Возвращаемый распределённый набор данных может быть проитерирован аналогично тому, как это делается с обычными наборами данных. ПРИМЕЧАНИЕ: В настоящее время пользователь не может добавлять дополнительные преобразования к распределённому набору данных.

Ниже приведен пример:

strategy = tf.distribute.MirroredStrategy()

# Create a dataset
dataset = dataset_ops.Dataset.TFRecordDataset([
  "/a/1.tfr", "/a/2.tfr", "/a/3.tfr", "/a/4.tfr"])

# Distribute that dataset
dist_dataset = strategy.experimental_distribute_dataset(dataset)
# Iterate over the distributed dataset
for x in dist_dataset:
  # process dataset elements
  strategy.experimental_run_v2(train_step, args=(x,))

Мы будем считать, что входной набор данных сгруппирован по глобальному размеру пакета. При этом предположении мы будем делать всё возможное, чтобы разделить каждый пакет между всеми репликами (один или несколько рабочих узлов).

В многоузловой настройке мы сначала попытаемся распределить набор данных, пытаясь определить, создаётся ли он из ReaderDatasets (например, TFRecordDataset, TextLineDataset и т. д.), и если да, то попытаемся фрагментировать входные файлы. Обратите внимание, что должен быть хотя бы один входной файл на каждый рабочий узел. Если у вас меньше одного входного файла на рабочий узел, мы рекомендуем отключить распределение вашего набора данных с помощью метода ниже.

Если эта попытка окажется неудачной (например, набор данных создаётся из Dataset.range), мы разделим набор данных равномерно в конце, добавив операцию .shard в конец потока обработки. Это приведёт к выполнению всей цепочки предобработки всех данных на каждом рабочем узле, и каждый рабочий узел будет выполнять избыточную работу. Мы выведем предупреждение, если этот метод фрагментации будет выбран. В этом случае рассмотрите использование experimental_distribute_datasets_from_function вместо этого.

Вы можете отключить фрагментацию набора данных между рабочими узлами, используя параметр auto_shard в tf.data.experimental.DistributeOptions.

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

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

Аргументы
dataset tf.data.Dataset, который будет фрагментирован по всем репликам в соответствии с описанными выше правилами.
Возвращает
"Распределённый Dataset", который работает как tf.data.Dataset, за исключением того, что он производит значения "по реплике".

experimental_distribute_datasets_from_function

Просмотреть исходный код

experimental_distribute_datasets_from_function(
    dataset_fn
)

Распределяет экземпляры tf.data.Dataset, созданные вызовами к dataset_fn.

dataset_fn будет вызван один раз для каждого рабочего узла в стратегии. Каждая реплика на этом рабочем узле будет извлекать одну партию входов из локального Dataset (т. е. если у рабочего узла две реплики, то в каждом шаге из Dataset будут извлекаться две партии).

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

dataset_fn должен принимать экземпляр tf.distribute.InputContext, где можно получить информацию о пакетировании и репликации ввода:

def dataset_fn(input_context):
  batch_size = input_context.get_per_replica_batch_size(global_batch_size)
  d = tf.data.Dataset.from_tensors([[1.]]).repeat().batch(batch_size)
  return d.shard(
      input_context.num_input_pipelines, input_context.input_pipeline_id)

inputs = strategy.experimental_distribute_datasets_from_function(dataset_fn)

for batch in inputs:
  replica_results = strategy.experimental_run_v2(replica_fn, args=(batch,))
Ключевой момент: tf.data.Dataset, возвращаемый dataset_fn, должен иметь размер пакета по каждой реплике, в отличие от experimental_distribute_dataset, который использует глобальный размер пакета. Это можно вычислить с помощью input_context.get_per_replica_batch_size.
Аргументы
dataset_fn функция, принимающая экземпляр tf.distribute.InputContext и возвращающая tf.data.Dataset.
Возвращает
"Распределённый Dataset", который работает как tf.data.Dataset, за исключением того, что он производит значения "по реплике".

experimental_local_results

Просмотреть исходный код

experimental_local_results(
    value
)

Возвращает список всех локальных значений по каждой реплике, содержащихся в value.

Примечание: Это возвращает только значения на рабочем узле, инициированном этим клиентом. При использовании tf.distribute.Strategy, как tf.distribute.experimental.MultiWorkerMirroredStrategy, каждый рабочий узел будет своим клиентом, и эта функция вернёт только значения, вычисленные на этом рабочем узле.
Аргументы
value значение, возвращённое experimental_run(), experimental_run_v2(), extended.call_for_each_replica(), или переменной, созданной в scope.
Возвращает
Кортеж значений, содержащихся в value. Если value представляет единственное значение, это возвращает (value,).

experimental_make_numpy_dataset

Просмотреть исходный код

experimental_make_numpy_dataset(
    numpy_input
)

Создаёт tf.data.Dataset для ввода, предоставленного через массив NumPy.

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

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

Пример:

numpy_input = np.ones([10], dtype=np.float32)
dataset = strategy.experimental_make_numpy_dataset(numpy_input)
dist_dataset = strategy.experimental_distribute_dataset(dataset)
Аргументы
numpy_input вложенный массив NumPy входных массивов, который будет преобразован в набор данных. Обратите внимание, что списки массивов NumPy складываются, так как это обычное поведение tf.data.Dataset.
Возвращает
tf.data.Dataset, представляющий numpy_input.

experimental_run_v2

Просмотреть исходный код

experimental_run_v2(
    fn, args=(), kwargs=None
)

Выполняет fn на каждой реплике с заданными аргументами.

Выполняет операции, указанные в fn на каждой реплике. Если args или kwargs содержат значения "по реплике", такие как те, что создаются "распределённым Dataset", при выполнении fn на определённой реплике, оно будет выполнено с компонентом этих "значений по реплике", соответствующим этой реплике.

fn может вызывать tf.distribute.get_replica_context() для доступа к элементам, таким как all_reduce.

Все аргументы в args или kwargs должны быть либо вложенными тензорами, либо объектами "по реплике", содержащими тензоры или составные тензоры.

Ключевой момент: В зависимости от реализации tf.distribute.Strategy и от того, включено ли выполнение в режиме eager, fn может быть вызвано один или несколько раз (раз для каждой реплики).
Аргументы
fn Функция для выполнения. Выход должен быть tf.nest объекта Tensors.
args (Необязательно) Позиционные аргументы для fn.
kwargs (Необязательно) Именованные аргументы для fn.
Возвращаемое значение
Объединённое возвращаемое значение fn по всем репликам. Структура возвращаемого значения такая же, как и возвращаемое значение fn. Каждый элемент структуры может быть объектом "по реплике" Tensor или Tensor (например, при запуске на одной реплике).

reduce

Просмотреть исходный код

reduce(
    reduce_op, value, axis
)

Сведение value по репликам.

Учитывая значение по реплике, возвращаемое experimental_run_v2, например, потерю на пример, пакет будет разделён между всеми репликами. Эта функция позволяет агрегировать по репликам и, необязательно, по элементам пакета. Например, если у вас есть глобальный размер пакета 8 и 2 реплики, значения для примеров [0, 1, 2, 3] будут на реплике 0, а [4, 5, 6, 7] на реплике 1. По умолчанию reduce будет просто агрегировать по репликам, возвращая [0+4, 1+5, 2+6, 3+7]. Это полезно, когда каждая реплика вычисляет скаляр или какое-либо другое значение без измерения "пакета" (например, градиент). Чаще всего вы захотите агрегировать по глобальному пакету, что можно сделать, указав измерение пакета как axis, обычно axis=0. В этом случае он вернёт скалярное 0+1+2+3+4+5+6+7.

Если есть последний частичный пакет, вам нужно указать ось, чтобы размер результирующего массива был согласован по репликам. Таким образом, если последний пакет имеет размер 6 и разделен на [0, 1, 2, 3] и [4, 5], вы получите несовпадение размеров, если не укажете axis=0. Если вы укажете tf.distribute.ReduceOp.MEAN, используя axis=0 будет использоваться правитель 6. Противопоставьте это вычислению reduce_mean, чтобы получить скалярное значение на каждой реплике, и этой функции для усреднения этих средних значений, что будет учитывать некоторые значения 1/8 и другие 1/4.

Аргументы
reduce_op Значение tf.distribute.ReduceOp, определяющее, как должны быть объединены значения.
value Значение "по реплике", например, возвращаемое experimental_run_v2 для объединения в один тензор.
axis Указывает измерение для сведения вдоль тензора каждой реплики. Обычно должно быть установлено на измерение пакета или None для сведения только по репликам (например, если тензор не имеет измерения пакета).
Возвращаемое значение
A Tensor.

scope

Просмотреть исходный код

scope()

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

Внутри блока кода with strategy.scope():, этот поток будет использовать создатель переменных, установленный strategy, и войдёт в свой "межреплицируемый контекст".

Возвращаемое значение
Менеджер контекста.

© 2020 The TensorFlow Authors. All rights reserved.
Licensed under the Creative Commons Attribution License 3.0.
Code samples licensed under the Apache 2.0 License.
https://www.tensorflow.org/versions/r1.15/api_docs/python/tf/compat/v2/distribute/MirroredStrategy

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API