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,))
| Аргументы | |
|---|---|
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 должны быть либо вложенными тензорами, либо объектами "по реплике", содержащими тензоры или составные тензоры.
| Аргументы | |
|---|---|
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