Spec-Zone.ru › TensorFlow

tf.compat.v1.distribute.StrategyExtended

Дополнительные API для алгоритмов, которым необходимо учитывать распределение.

Наследуется от: StrategyExtended

tf.compat.v1.distribute.StrategyExtended(
    container_strategy
)
Примечание: В большинстве случаев использования tf.distribute.Strategy вызывать эти методы не требуется, поскольку библиотеки TensorFlow (например, оптимизаторы) при необходимости вызывают их за вас.

Некоторые распространённые сценарии использования функций на этой странице:

  • Локальность

tf.distribute.DistributedValues может иметь ту же локальность, что и распределённая переменная, благодаря чему зеркальное значение размещается на тех же устройствах, что и переменная (а не на вычислительных устройствах). Такие значения можно передать в вызов tf.distribute.StrategyExtended.update для обновления значения переменной. Чтобы задать переменной ту же локальность, что и у другой переменной, можно использовать tf.distribute.StrategyExtended.colocate_vars_with. Преобразовать значение «PerReplica» к локальности переменной можно с помощью tf.distribute.StrategyExtended.reduce_to или tf.distribute.StrategyExtended.batch_reduce_to.

  • Обновление распределённой переменной

Распределённая переменная — это переменная, созданная на нескольких устройствах. Как описано в глоссарии, зеркальная переменная и переменная SyncOnRead — два примера таких переменных. Стандартный порядок обновления распределённых переменных:

  1. В функции, переданной в tf.distribute.Strategy.run, вычислите список пар (обновление, переменная). Например, обновлением может быть градиент функции потерь относительно переменной.
  2. Перейдите в режим между репликами, вызвав tf.distribute.get_replica_context().merge_call() и передав обновления и переменные в качестве аргументов.
  3. Вызовите tf.distribute.StrategyExtended.reduce_to(VariableAggregation.SUM, t, v) (для одной переменной) или tf.distribute.StrategyExtended.batch_reduce_to (для списка переменных), чтобы суммировать обновления.
  4. Вызовите tf.distribute.StrategyExtended.update(v) для каждой переменной, чтобы обновить её значение.

Шаги 2–4 автоматически выполняются классом tf.keras.optimizers.Optimizer, если вызвать его метод tf.keras.optimizers.Optimizer.apply_gradients в контексте реплики.

На самом деле, для обновления распределённой переменной можно воспользоваться решением более высокого уровня: вызвать assign для переменной, как для обычной tf.Variable. Этот метод можно вызывать как в контексте реплики, так и в контексте между репликами. Для зеркальной переменной вызов assign в контексте реплики требует указать тип aggregation в конструкторе переменной. В этом случае переключение контекста и синхронизация, описанные в шагах 2–4, выполняются автоматически. Если вызвать assign для зеркальной переменной в контексте между репликами, можно присвоить только одно значение либо значения из другой зеркальной переменной или зеркального объекта tf.distribute.DistributedValues. Для переменной SyncOnRead в контексте реплики достаточно вызвать для неё assign; при этом агрегирование не выполняется автоматически. В контексте между репликами переменной SyncOnRead можно присвоить только одно значение. Например, при восстановлении из контрольной точки: если тип aggregation переменной — tf.VariableAggregation.SUM, предполагается, что значения реплик были сложены перед созданием контрольной точки. Поэтому при восстановлении значение делится на число реплик, а затем присваивается каждой реплике; если тип aggregation — tf.VariableAggregation.MEAN, значение напрямую присваивается каждой реплике.

Атрибуты
experimental_between_graph Использует ли стратегия репликацию между графами.

Ожидается, что возвращается постоянное значение, которое не меняется в течение всего жизненного цикла.

experimental_require_static_shapes Возвращает True, если требуется статическая форма; в противном случае — False.
experimental_should_init Требуется ли инициализация.
parameter_devices Возвращает кортеж всех устройств, используемых для размещения переменных.
should_checkpoint Требуется ли создание контрольных точек.
should_save_summary Требуется ли сохранение сводок.
worker_devices Возвращает кортеж всех устройств, используемых для выполнения вычислений на репликах.

Методы

batch_reduce_to

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

batch_reduce_to(
    reduce_op, value_destination_pairs, options=None
)

Объединяет несколько вызовов reduce_to в один для более быстрого выполнения.

Аналогично reduce_to, но принимает список пар (значение, назначения). Это эффективнее, чем отдельно сводить каждое значение.

В настоящее время этот API можно вызывать только в контексте между репликами. Для сведения значений между репликами предусмотрены следующие альтернативные варианты:

  • tf.distribute.StrategyExtended.reduce_to: версия этого API без пакетной обработки.
  • tf.distribute.ReplicaContext.all_reduce: аналог этого API в контексте реплики. Поддерживает как пакетное, так и непакетное выполнение операции all-reduce.
  • tf.distribute.Strategy.reduce: более удобный метод для редукции на хосте в межрепличном контексте.

Дополнительную информацию см. в reduce_to.

@tf.function def step_fn(var):

def merge_fn(strategy, value, var): # All-reduce the value. Note that value here is a # tf.distribute.DistributedValues. reduced = strategy.extended.batch_reduce_to( tf.distribute.ReduceOp.SUM, [(value, var)])[0] strategy.extended.update(var, lambda var, value: var.assign(value), args=(reduced,))

value = tf.identity(1.) tf.distribute.get_replica_context().merge_call(merge_fn, args=(value, var))

def run(strategy): with strategy.scope(): v = tf.Variable(0.) strategy.run(step_fn, args=(v,)) return v

run(tf.distribute.MirroredStrategy(["GPU:0", "GPU:1"])) MirroredVariable:{ 0: , 1: } run(tf.distribute.experimental.CentralStorageStrategy( compute_devices=["GPU:0", "GPU:1"], parameter_device="CPU:0")) run(tf.distribute.OneDeviceStrategy("GPU:0"))

Аргументы
reduce_op значение tf.distribute.ReduceOp, определяющее способ объединения значений. Допускается строковое представление перечисления, например "SUM" или "MEAN".
value_destination_pairs последовательность пар (значение, целевые объекты). Описание см. в tf.distribute.Strategy.reduce_to.
options объект tf.distribute.experimental.CommunicationOptions. Параметры для выполнения коллективных операций. Они переопределяют параметры по умолчанию, если tf.distribute.Strategy принимает их в конструкторе. Подробнее о параметрах см. в разделе tf.distribute.experimental.CommunicationOptions.
Возвращает
Список редуцированных значений — по одному для каждой пары в value_destination_pairs.

broadcast_to

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

broadcast_to(
    tensor, destinations
)

Копирует тензор с одного устройства на все устройства рабочих узлов.

Аргументы
tensor Значение Tensor для широковещательной рассылки.
destinations Зеркальная переменная или строка с именем устройства, определяющая целевые устройства, на которые следует скопировать tensor.
Возвращает
Значение, зеркально отображённое на устройствах destinations.

call_for_each_replica

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

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

Запускает fn один раз для каждой реплики.

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

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

# Called once in "cross-replica" context.
def merge_fn(distribution, three_plus_replica_id):
  # sum the values across replicas
  return sum(distribution.experimental_local_results(three_plus_replica_id))

# Called once per replica in `distribution`, in a "replica" context.
def fn(three):
  replica_ctx = tf.get_replica_context()
  v = three + replica_ctx.replica_id_in_sync_group
  # Computes the sum of the `v` values across all replicas.
  s = replica_ctx.merge_call(merge_fn, args=(v,))
  return s + v

with distribution.scope():
  # in "cross-replica" context
  ...
  merged_results = distribution.run(fn, args=[3])
  # merged_results has the values from every replica execution of `fn`.
  # This statement prints a list:
  print(distribution.experimental_local_results(merged_results))
Аргументы
fn Функция для запуска (будет запущена один раз для каждой реплики).
args Кортеж или список позиционных аргументов для fn.
kwargs Словарь именованных аргументов для fn.
Возвращает
Объединённое возвращаемое значение fn для всех реплик.

colocate_vars_with

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

colocate_vars_with(
    colocate_with_variable
)

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

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

Её можно использовать только внутри self.scope().

Пример использования:

with strategy.scope():
  var1 = tf.Variable(...)
  with strategy.extended.colocate_vars_with(var1):
    # var2 and var3 will be created on the same device(s) as var1
    var2 = tf.Variable(...)
    var3 = tf.Variable(...)

  def fn(v1, v2, v3):
    # operates on v1 from var1, v2 from var2, and v3 from var3

  # `fn` runs on every device `var1` is on, `var2` and `var3` will be there
  # too.
  strategy.extended.update(var1, fn, args=(var2, var3))
Аргументы
colocate_with_variable Переменная, созданная в scope() этой стратегии. Переменные, созданные в возвращаемом менеджере контекста, будут размещены на том же наборе устройств, что и colocate_with_variable.
Возвращает
Менеджер контекста.

experimental_make_numpy_dataset

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

experimental_make_numpy_dataset(
    numpy_input, session=None
)

Создаёт набор данных для входных данных, переданных в виде массива NumPy.

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

Аргументы
numpy_input Вложенный набор входных массивов NumPy, который будет равномерно распределен между всеми репликами. Обратите внимание: списки массивов NumPy объединяются в тензоры, что является стандартным поведением tf.data.Dataset.
session (Только для выполнения графов TensorFlow v1.x) Сеанс, используемый для инициализации.
Возвращает
Объект tf.data.Dataset, представляющий numpy_input.

experimental_run_steps_on_iterator

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

experimental_run_steps_on_iterator(
    fn, iterator, iterations=1, initial_loop_values=None
)
Устарело: вместо этого используйте run. (устарело)
Устарело: ЭТА ФУНКЦИЯ УСТАРЕЛА. Она будет удалена в будущей версии. Инструкции по обновлению: вместо этого используйте run.

Выполняет fn с входными данными из iterator в течение iterations итераций.

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

Аргументы
fn функция, выполняемая с использованием этой стратегии распределения. Функция должна иметь следующую сигнатуру: def fn(context, inputs). context — это экземпляр MultiStepContext, который будет передан при выполнении fn. context можно использовать, чтобы указать выходные данные, возвращаемые из fn, вызвав context.set_last_step_output. Его также можно использовать для сохранения выходных данных, не являющихся тензорами, с помощью context.set_non_tensor_output. Дополнительные сведения см. в документации MultiStepContext. inputs будет иметь тот же тип и структуру, что и iterator.get_next(). Как правило, fn использует метод call_for_each_replica стратегии для распределения вычислений между несколькими репликами.
iterator Итератор набора данных, представляющего входные данные для fn. Вызывающая сторона отвечает за инициализацию итератора по мере необходимости.
iterations (Необязательно) Количество итераций, в течение которых должно выполняться fn. По умолчанию — 1.
initial_loop_values (Необязательно) Начальные значения, передаваемые в цикл, выполняющий fn. По умолчанию — None. аргумент initial_loop_values, когда у нас будет механизм для определения выходных данных fn.
Возвращает
Возвращает объект MultiStepContext, обладающий, помимо прочего, следующими свойствами:
  • run_op: Операция, выполняющая fn iterations раз.
  • last_step_outputs: Словарь, содержащий тензоры, заданные с помощью context.set_last_step_output. При вычислении возвращаются значения тензоров после последней итерации.
  • non_tensor_outputs: Словарь, содержащий все данные, заданные с помощью fn при вызове context.set_non_tensor_output.

non_slot_devices

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

non_slot_devices(
    var_list
)

Устройство или устройства для переменных без слотов.

Устарело: ТОЛЬКО TF 1.x.

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

with tf.distribute.StrategyExtended.colocate_vars_with(tf.distribute.StrategyExtended.non_slot_devices(...)):
  ...
Аргументы
var_list Список оптимизируемых переменных, необходимый при использовании стратегии по умолчанию tf.distribute.Strategy.
Возвращает
Последовательность устройств для переменных без слотов.

read_var

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

read_var(
    v
)

Считывает значение переменной.

Возвращает агрегированное значение локальной для реплики переменной или значение любой другой переменной (только для чтения).

Аргументы
v Переменная, выделенная в области действия этой стратегии tf.distribute.Strategy.
Возвращает
Тензор, представляющий значение v, агрегированное по репликам, если это необходимо.

reduce_to

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

reduce_to(
    reduce_op, value, destinations, options=None
)

Объединяет значения по репликам (например, с помощью суммирования или вычисления среднего).

reduce_to агрегирует tf.distribute.DistributedValues и распределенные переменные. Поддерживаются как плотные значения, так и tf.IndexedSlices.

В настоящее время этот API можно вызывать только в контексте между репликами. Другие варианты агрегирования значений по репликам:

  • tf.distribute.StrategyExtended.batch_reduce_to: пакетная версия этого API.
  • tf.distribute.ReplicaContext.all_reduce: аналог этого API в контексте реплики. Поддерживает пакетное и непакетное агрегирование всех значений.
  • tf.distribute.Strategy.reduce: более удобный метод агрегирования на главном устройстве в контексте между репликами.

destinations задает, куда следует агрегировать значение, например "GPU:0". Можно также передать Tensor; в этом случае целевым устройством будет устройство этого тензора. Для агрегирования всех значений передайте одинаковые значения в value и destinations.

Его можно использовать в tf.distribute.ReplicaContext.merge_call, чтобы написать код, работающий для всех tf.distribute.Strategy.

@tf.function def step_fn(var):

def merge_fn(strategy, value, var): # All-reduce the value. Note that value here is a # tf.distribute.DistributedValues. reduced = strategy.extended.reduce_to(tf.distribute.ReduceOp.SUM, value, destinations=var) strategy.extended.update(var, lambda var, value: var.assign(value), args=(reduced,))

value = tf.identity(1.) tf.distribute.get_replica_context().merge_call(merge_fn, args=(value, var))

def run(strategy): with strategy.scope(): v = tf.Variable(0.) strategy.run(step_fn, args=(v,)) return v

run(tf.distribute.MirroredStrategy(["GPU:0", "GPU:1"])) MirroredVariable:{ 0: , 1: } run(tf.distribute.experimental.CentralStorageStrategy( compute_devices=["GPU:0", "GPU:1"], parameter_device="CPU:0")) run(tf.distribute.OneDeviceStrategy("GPU:0"))

Аргументы
reduce_op значение tf.distribute.ReduceOp, указывающее, как следует объединять значения. Можно использовать строковое представление перечисления, например "SUM" или "MEAN".
value tf.distribute.DistributedValues или объект, подобный tf.Tensor.
destinations tf.distribute.DistributedValues, tf.Variable, объект, подобный tf.Tensor, или строка с именем устройства. Указывает устройства, на которые нужно выполнить редукцию. Чтобы выполнить all-reduce, передайте одинаковые значения в value и destinations. Обратите внимание: если это tf.Variable, значение редуцируется на устройствах этой переменной, но данный метод не обновляет переменную.
options tf.distribute.experimental.CommunicationOptions. Параметры для выполнения коллективных операций. Они переопределяют параметры по умолчанию, если tf.distribute.Strategy принимает их в конструкторе. Подробное описание параметров см. в разделе tf.distribute.experimental.CommunicationOptions.
Возвращает
Тензор или значение, редуцированное до destinations.

update

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

update(
    var, fn, args=(), kwargs=None, group=True
)

Выполняет fn для обновления var с использованием входных данных, зеркально распределённых по тем же устройствам.

tf.distribute.StrategyExtended.update принимает распределённую переменную var для обновления, функцию обновления fn, а также args и kwargs для fn. Метод применяет fn к каждой компонентной переменной var и передаёт соответствующие значения из args и kwargs. Ни args, ни kwargs не могут содержать значения для отдельных реплик. Если они содержат зеркально распределённые значения, перед вызовом fn они будут распакованы. Например, fn может быть assign_add, а args — зеркально распределённым объектом DistributedValues, каждый компонент которого содержит значение, которое нужно добавить к этой зеркально распределённой переменной var. Вызов update вызовет assign_add для каждой компонентной переменной var, передав соответствующее значение тензора на этом устройстве.

Пример использования:

strategy = tf.distribute.MirroredStrategy(['GPU:0', 'GPU:1']) # With 2
devices
with strategy.scope():
  v = tf.Variable(5.0, aggregation=tf.VariableAggregation.SUM)
def update_fn(v):
  return v.assign(1.0)
result = strategy.extended.update(v, update_fn)
# result is
# Mirrored:{
#  0: tf.Tensor(1.0, shape=(), dtype=float32),
#  1: tf.Tensor(1.0, shape=(), dtype=float32)
# }

Если var зеркально распределена между несколькими устройствами, этот метод реализует следующую логику:

results = {}
for device, v in var:
  with tf.device(device):
    # args and kwargs will be unwrapped if they are mirrored.
    results[device] = fn(v, *args, **kwargs)
return merged(results)

В противном случае этот метод возвращает fn(var, *args, **kwargs), размещённый на том же устройстве, что и var.

Аргументы
var Переменная, возможно, зеркально распределённая между несколькими устройствами, над которой нужно выполнить операцию.
fn Вызываемая функция. Переменная должна быть её первым аргументом.
args Кортеж или список. Дополнительные позиционные аргументы, передаваемые в fn().
kwargs Словарь с именованными аргументами, передаваемыми в fn().
group Логическое значение. По умолчанию — True. Если значение False, возвращаемое значение будет распаковано.
Возвращает
По умолчанию — объединённое возвращаемое значение fn для всех реплик. Объединённый результат имеет зависимости, обеспечивающие выполнение побочных эффектов (обновлений) на каждой реплике, если результат вычисляется. Если же указано "group=False", эта функция возвращает вложенную структуру списков, в каждом из которых есть элемент для каждой реплики; вызывающий код отвечает за то, чтобы все элементы были выполнены.

update_non_slot

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

update_non_slot(
    colocate_with, fn, args=(), kwargs=None, group=True
)

Выполняет fn(*args, **kwargs) на устройствах colocate_with.

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

Устарело: Только для TF 1.x.
Аргументы
colocate_with Устройства, возвращаемые методом non_slot_devices().
fn Функция для выполнения.
args Кортеж или список. Позиционные аргументы, передаваемые в fn().
kwargs Словарь с именованными аргументами, передаваемыми в fn().
group Логическое значение. По умолчанию — True. Если значение False, возвращаемое значение будет распаковано.
Возвращает
Возвращаемое значение fn, возможно, объединённое на нескольких устройствах.

value_container

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

value_container(
    value
)

Возвращает контейнер, которому принадлежит эта реплицируемая копия value.

Аргументы
value Значение, возвращённое run(), или переменная, созданная в scope().
Возвращает
Контейнер, которому принадлежит value. Если значение не принадлежит ни одному контейнеру (в том числе если контейнер был уничтожен), возвращается само значение. value in experimental_local_results(value_container(value)) всегда будет иметь значение True.

variable_created_in_scope

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

variable_created_in_scope(
    v
)

Проверяет, была ли v создана при активной области видимости этой стратегии.

Переменные, созданные в области видимости стратегии, принадлежат ей:

strategy = tf.distribute.MirroredStrategy()
with strategy.scope():
  v = tf.Variable(1.)
strategy.extended.variable_created_in_scope(v)
True

Переменные, созданные вне стратегии, ей не принадлежат:

strategy = tf.distribute.MirroredStrategy()
v = tf.Variable(1.)
strategy.extended.variable_created_in_scope(v)
False
Аргументы
v Экземпляр tf.Variable.
Возвращает
True, если v создана в области видимости, и False в противном случае.

© 2022 The TensorFlow Authors. All rights reserved.
Licensed under the Creative Commons Attribution License 4.0.
Code samples licensed under the Apache 2.0 License.
https://www.tensorflow.org/api_docs/python/tf/compat/v1/distribute/StrategyExtended

Spec-Zone.ru

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