Spec-Zone.ru › TensorFlow 2.3

tf.distribute.experimental.ParameterServerStrategy

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

Асинхронная стратегия tf.distribute для сервера параметров с несколькими рабочими узлами.

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

tf.distribute.experimental.ParameterServerStrategy(
    cluster_resolver=None
)

Эта стратегия требует двух ролей: рабочие узлы и серверы параметров. Переменные и обновления этих переменных будут назначены серверам параметров, а другие операции — рабочим узлам.

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

По умолчанию используется TFConfigClusterResolver для определения конфигураций для многоузлового обучения. Это требует переменной среды «TF_CONFIG», и «TF_CONFIG» должен содержать спецификацию кластера.

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

Ожидается вызов call_for_each_replica(fn, ...) для любых операций, которые потенциально могут быть дублированы по репликам (то есть на нескольких GPU), даже если есть только ЦП или одна GPU. При определении fn, необходимо соблюдать особую осторожность:

1) В общем случае не рекомендуется открывать область устройства внутри области действия стратегии. Область устройства (например, вызов tf.device) будет сливаться с областью или перезаписывать устройство для операций, но не будет изменять устройство для переменных.

2) Также не рекомендуется открывать область сопоставления (например, вызов tf.compat.v1.colocate_with) внутри области действия стратегии. Для размещения переменных используйте strategy.extended.colocate_vars_with вместо этого. Сопоставление операций может привести к конфликтам назначения устройств.

Примечание: Эта стратегия работает только с API Estimator. Передайте экземпляр этой стратегии в аргумент experimental_distribute при создании RunConfig. Этот экземпляр RunConfig затем должен быть передан в экземпляр Estimator, на котором вызывается train_and_evaluate.

Например:

strategy = tf.distribute.experimental.ParameterServerStrategy()
run_config = tf.estimator.RunConfig(
    experimental_distribute.train_distribute=strategy)
estimator = tf.estimator.Estimator(config=run_config)
tf.estimator.train_and_evaluate(estimator,...)
Аргументы
cluster_resolver Дополнительный объект tf.distribute.cluster_resolver.ClusterResolver. По умолчанию используется tf.distribute.cluster_resolver.TFConfigClusterResolver.
Атрибуты
cluster_resolver Возвращает объект решателя кластера, связанный с этой стратегией.

В общем случае, при использовании многоузловой стратегии tf.distribute, такой как tf.distribute.experimental.MultiWorkerMirroredStrategy или tf.distribute.experimental.TPUStrategy(), связан с стратегией, используемой tf.distribute.cluster_resolver.ClusterResolver, и такой экземпляр возвращается этим свойством.

Стратегии, которые должны иметь связанный tf.distribute.cluster_resolver.ClusterResolver, должны установить соответствующий атрибут или переопределить это свойство; в противном случае, по умолчанию возвращается None. Эти стратегии также должны предоставлять информацию о том, что возвращается этим свойством.

Стратегии для одного узла обычно не имеют tf.distribute.cluster_resolver.ClusterResolver, и в этих случаях это свойство вернет None.

tf.distribute.cluster_resolver.ClusterResolver может быть полезен, когда пользователю требуется получить доступ к информации, такой как спецификация кластера, тип задачи или идентификатор задачи. Например,

os.environ['TF_CONFIG'] = json.dumps({
'cluster': {
'worker': ["localhost:12345", "localhost:23456"],
'ps': ["localhost:34567"]
},
'task': {'type': 'worker', 'index': 0}
})

# This implicitly uses TF_CONFIG for the cluster and current task info.
strategy = tf.distribute.experimental.MultiWorkerMirroredStrategy()

...

if strategy.cluster_resolver.task_type == 'worker':
# Perform something that's only applicable on workers. Since we set this
# as a worker above, this block will run on this particular instance.
elif strategy.cluster_resolver.task_type == 'ps':
# Perform something that's only applicable on parameter servers. Since we
# set this as a worker above, this block will not run on this particular
# instance.

Дополнительную информацию можно найти в документации API tf.distribute.cluster_resolver.ClusterResolver.

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

Методы

experimental_assign_to_logical_device

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

experimental_assign_to_logical_device(
    tensor, logical_device_id
)

Добавляет аннотацию, что tensor будет назначено логическому устройству.

Примечание: Этот API поддерживается только в TPUStrategy на данный момент. Это добавляет аннотацию к tensor, указывающую, что операции над tensor будут вызваны на логическом устройстве с идентификатором logical_device_id. При использовании параллелизма моделей, по умолчанию все операции размещаются на нулевом логическом устройстве.
# Initializing TPU system with 2 logical devices and 4 replicas.
resolver = tf.distribute.cluster_resolver.TPUClusterResolver(tpu='')
tf.config.experimental_connect_to_cluster(resolver)
topology = tf.tpu.experimental.initialize_tpu_system(resolver)
device_assignment = tf.tpu.experimental.DeviceAssignment.build(
    topology,
    computation_shape=[1, 1, 1, 2],
    num_replicas=4)
strategy = tf.distribute.TPUStrategy(
    resolver, experimental_device_assignment=device_assignment)
iterator = iter(inputs)

@tf.function()
def step_fn(inputs):
  output = tf.add(inputs, inputs)

  # Add operation will be executed on logical device 0.
  output = strategy.experimental_assign_to_logical_device(output, 0)
  return output

strategy.run(step_fn, args=(next(iterator),))
Аргументы
tensor Входной тензор для аннотации.
logical_device_id Идентификатор логического ядра, которому будет назначен тензор.
Исключения
ValueError Переданный идентификатор логического устройства не соответствует общему количеству разделов, указанному назначением устройства.
Возвращает
Анотированный тензор с идентичным значением, как у tensor.

experimental_distribute_dataset

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

experimental_distribute_dataset(
    dataset
)

Создает tf.distribute.DistributedDataset из tf.data.Dataset.

Возвращаемый tf.distribute.DistributedDataset можно итерировать так же, как и обычные наборы данных. ВАЖНО: пользователь не может добавить больше преобразований в tf.distribute.DistributedDataset.

Вот пример:

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 `tf.distribute.DistributedDataset`
for x in dist_dataset:
  # process dataset elements
  strategy.run(replica_fn, args=(x,))

В приведенном фрагменте кода tf.distribute.DistributedDataset dist_dataset разбивается на пакеты с помощью GLOBAL_BATCH_SIZE, и мы итерируемся по нему с помощью for x in dist_dataset. x tf.distribute.DistributedValues, содержащий данные для всех реплик, который агрегируется в пакет GLOBAL_BATCH_SIZE. tf.distribute.Strategy.run позаботится о передаче правильных данных на реплику в x в правильную replica_fn операцию, выполняемую на каждой реплике.

Что происходит за кулисами этого метода, когда мы говорим, что экземпляр tf.data.Dataset - dataset - распределяется? Это зависит от того, как вы настроили tf.data.experimental.AutoShardPolicy через tf.data.experimental.DistributeOptions. По умолчанию он установлен в tf.data.experimental.AutoShardPolicy.AUTO. В многоузловой среде мы сначала попытаемся распределить dataset путем определения, создается ли dataset из наборов данных читателей (например, tf.data.TFRecordDataset, tf.data.TextLineDataset и т. д.) и в этом случае попытаемся разбить входные файлы. Обратите внимание, что должен быть как минимум один входной файл на каждый рабочий узел. Если у вас меньше одного входного файла на рабочий узел, мы рекомендуем отключить разделение наборов данных по рабочим узлам, установив tf.data.experimental.DistributeOptions.auto_shard_policy в tf.data.experimental.AutoShardPolicy.OFF.

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

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

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

Вы также можете использовать свойство element_spec экземпляра tf.distribute.DistributedDataset, возвращаемого этим API, для запроса tf.TypeSpec элементов, возвращаемых итератором. Это можно использовать для установки свойства input_signature tf.function.

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)

@tf.function(input_signature=[dist_dataset.element_spec])
def train_step(inputs):
  # train model with inputs
  return

# Iterate over the `tf.distribute.DistributedDataset`
for x in dist_dataset:
  # process dataset elements
  strategy.run(train_step, args=(x,))
Примечание: Порядок обработки данных рабочими узлами при использовании tf.distribute.Strategy.experimental_distribute_dataset или tf.distribute.Strategy.experimental_distribute_datasets_from_function не гарантируется. Это обычно требуется, если вы используете tf.distribute для масштабирования предсказаний. Однако вы можете вставить индекс для каждого элемента в пакете и упорядочить выходы соответственно. Обратитесь к этому фрагменту для примера того, как упорядочить выходы.
Аргументы
dataset tf.data.Dataset, которая будет распределена по всем репликам в соответствии с указанными выше правилами.
options tf.distribute.InputOptions, используемые для управления параметрами распределения этого набора данных.
Возвращаемое значение
Объект tf.distribute.DistributedDataset.

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, где можно получить доступ к информации о пакетировании и репликации входных данных.

Вы также можете использовать свойство element_spec возвращаемого этим API tf.distribute.DistributedDataset, чтобы запросить tf.TypeSpec элементов, возвращаемых итератором. Это можно использовать для задания свойства input_signature объекта tf.function.

global_batch_size = 8
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)
strategy = tf.distribute.MirroredStrategy()
ds = strategy.experimental_distribute_datasets_from_function(dataset_fn)
def train(ds):
  @tf.function(input_signature=[ds.element_spec])
  def step_fn(inputs):
    # train the model with inputs
    return inputs

... for batch in ds: ... replica_results = strategy.run(replica_fn, args=(batch,))

train(ds)

Ключевой момент: tf.data.Dataset, возвращаемый dataset_fn, должен иметь размер пакета на реплику, в отличие от experimental_distribute_dataset, который использует глобальный размер пакета. Это можно вычислить с помощью input_context.get_per_replica_batch_size.
Примечание: Порядок обработки данных обработчиками при использовании tf.distribute.Strategy.experimental_distribute_dataset или tf.distribute.Strategy.experimental_distribute_datasets_from_function не гарантируется. Это обычно требуется, если вы используете tf.distribute для масштабирования предсказаний. Вы можете, однако, вставить индекс для каждого элемента в пакете и упорядочить выходные данные соответственно. Обратитесь к этому фрагменту фрагменту для примера того, как упорядочить выходные данные.
Аргументы
dataset_fn Функция, принимающая экземпляр tf.distribute.InputContext и возвращающая tf.data.Dataset.
options tf.distribute.InputOptions, используемые для управления параметрами распределения этого набора данных.
Возвращаемое значение
Объект tf.distribute.DistributedDataset.

experimental_distribute_values_from_function

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

experimental_distribute_values_from_function(
    value_fn
)

Генерирует tf.distribute.DistributedValues из value_fn.

Эта функция генерирует tf.distribute.DistributedValues для передачи в run, reduce, или другие методы, принимающие распределённые значения, когда не используются наборы данных.

Аргументы
value_fn Функция, выполняемая для генерации значений. Она вызывается для каждой реплики с tf.distribute.ValueContext в качестве единственного аргумента. Она должна возвращать тензор или тип, который можно преобразовать в тензор.
Возвращаемое значение
tf.distribute.DistributedValues, содержащий значение для каждой реплики.

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

  1. Возврат постоянного значения для каждой реплики:
strategy = tf.distribute.MirroredStrategy()
def value_fn(ctx):
  return tf.constant(1.)
distributed_values = (
     strategy.experimental_distribute_values_from_function(
       value_fn))
local_result = strategy.experimental_local_results(distributed_values)
local_result
(<tf.Tensor: shape=(), dtype=float32, numpy=1.0>,)
  1. Распределение значений в массиве на основе replica_id:
strategy = tf.distribute.MirroredStrategy()
array_value = np.array([3., 2., 1.])
def value_fn(ctx):
  return array_value[ctx.replica_id_in_sync_group]
distributed_values = (
     strategy.experimental_distribute_values_from_function(
       value_fn))
local_result = strategy.experimental_local_results(distributed_values)
local_result
(3.0,)
  1. Указание значений с помощью num_replicas_in_sync:
strategy = tf.distribute.MirroredStrategy()
def value_fn(ctx):
  return ctx.num_replicas_in_sync
distributed_values = (
     strategy.experimental_distribute_values_from_function(
       value_fn))
local_result = strategy.experimental_local_results(distributed_values)
local_result
(1,)
  1. Размещение значений на устройствах и распределение:
strategy = tf.distribute.TPUStrategy()
worker_devices = strategy.extended.worker_devices
multiple_values = []
for i in range(strategy.num_replicas_in_sync):
  with tf.device(worker_devices[i]):
    multiple_values.append(tf.constant(1.0))

def value_fn(ctx):
  return multiple_values[ctx.replica_id_in_sync_group]

distributed_values = strategy.
  experimental_distribute_values_from_function(
  value_fn)

experimental_local_results

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

experimental_local_results(
    value
)

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

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

experimental_make_numpy_dataset

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

experimental_make_numpy_dataset(
    numpy_input
)

Создаёт tf.data.Dataset из массива NumPy. (устарело)

Предупреждение: ЭТА ФУНКЦИЯ УСТАРЕЛА. Она будет удалена после 2020-09-30. Инструкции по обновлению: Используйте tf.data.Dataset.from_tensor_slices вместо неё

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

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

Пример:

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

experimental_replicate_to_logical_devices

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

experimental_replicate_to_logical_devices(
    tensor
)

Добавляет аннотацию, что tensor будет дублирован на все логические устройства.

Примечание: Этот API поддерживается только в TPUStrategy на данный момент. Это добавляет аннотацию к тензору tensor , указывающую, что операции с tensor будут вызываться на всех логических устройствах.
# Initializing TPU system with 2 logical devices and 4 replicas.
resolver = tf.distribute.cluster_resolver.TPUClusterResolver(tpu='')
tf.config.experimental_connect_to_cluster(resolver)
topology = tf.tpu.experimental.initialize_tpu_system(resolver)
device_assignment = tf.tpu.experimental.DeviceAssignment.build(
    topology,
    computation_shape=[1, 1, 1, 2],
    num_replicas=4)
strategy = tf.distribute.TPUStrategy(
    resolver, experimental_device_assignment=device_assignment)

iterator = iter(inputs)

@tf.function()
def step_fn(inputs):
  images, labels = inputs
  images = strategy.experimental_split_to_logical_devices(
    inputs, [1, 2, 4, 1])

  # model() function will be executed on 8 logical devices with `inputs`
  # split 2 * 4  ways.
  output = model(inputs)

  # For loss calculation, all logical devices share the same logits
  # and labels.
  labels = strategy.experimental_replicate_to_logical_devices(labels)
  output = strategy.experimental_replicate_to_logical_devices(output)
  loss = loss_fn(labels, output)

  return loss

strategy.run(step_fn, args=(next(iterator),))

Аргументы: тензор: Входной тензор для аннотации.

Возвращаемое значение
Аннотированный тензор с идентичным значением, как у tensor.

experimental_split_to_logical_devices

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

experimental_split_to_logical_devices(
    tensor, partition_dimensions
)

Добавляет аннотацию, что tensor будет разделен на логические устройства.

Примечание: Этот API поддерживается только в TPUStrategy на данный момент. Это добавляет аннотацию к тензору tensor , указывающую, что операции с tensor будут разделены между несколькими логическими устройствами. Тензор tensor будет разделен по измерениям, указанным в partition_dimensions. Размеры tensor должны быть кратны соответствующим значениям в partition_dimensions.

Например, для системы с 8 логическими устройствами, если tensor — это тензор изображения с формой (размер_пакета, ширина, высота, канал) и partition_dimensions — [1, 2, 4, 1], то tensor будет разделен на 2 по ширине и на 4 по высоте, и значения разбиения тензора будут переданы на 8 логических устройств.

# Initializing TPU system with 8 logical devices and 1 replica.
resolver = tf.distribute.cluster_resolver.TPUClusterResolver(tpu='')
tf.config.experimental_connect_to_cluster(resolver)
topology = tf.tpu.experimental.initialize_tpu_system(resolver)
device_assignment = tf.tpu.experimental.DeviceAssignment.build(
    topology,
    computation_shape=[1, 2, 2, 2],
    num_replicas=1)
strategy = tf.distribute.TPUStrategy(
    resolver, experimental_device_assignment=device_assignment)

iterator = iter(inputs)

@tf.function()
def step_fn(inputs):
  inputs = strategy.experimental_split_to_logical_devices(
    inputs, [1, 2, 4, 1])

  # model() function will be executed on 8 logical devices with `inputs`
  # split 2 * 4  ways.
  output = model(inputs)
  return output

strategy.run(step_fn, args=(next(iterator),))

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

Возможные ошибки
ValueError

1) Если размер partition_dimensions не равен рангу tensor или 2) если произведение элементов partition_dimensions не совпадает с числом логических устройств на реплику, определенным спецификацией устройства реализующей DistributionStrategy, или 3) если известный размер tensor не делится на соответствующее значение в partition_dimensions.

Возвращает
Аннотированный тензор с идентичным значением, как у tensor.

reduce

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

reduce(
    reduce_op, value, axis
)

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

Учитывая значение на реплике, возвращенное run, например, потерю на пример, пакет будет разделен по всем репликам. Эта функция позволяет вам агрегировать по репликам, а также по элементам пакета. Например, если у вас есть глобальный размер пакета 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 «Значение на реплику», например, возвращаемое run для объединения в один тензор.
axis Определяет размерность для сведения по каждой реплике. Обычно следует устанавливать размерность пакета или None для сведения только по репликам (например, если тензор не имеет размерности пакета).
Возвращает
Tensor.

run

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

run(
    fn, args=(), kwargs=None, options=None
)

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

Выполняет операции, указанные в fn на каждой реплике. Если args или kwargs содержат tf.distribute.DistributedValues, такие как те, которые созданы tf.distribute.DistributedDataset из tf.distribute.Strategy.experimental_distribute_dataset или tf.distribute.Strategy.experimental_distribute_datasets_from_function, когда fn выполняется на конкретной реплике, он будет выполнен с компонентом tf.distribute.DistributedValues, соответствующим этой реплике.

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

Все аргументы в args или kwargs должны быть либо вложенными тензорами, либо tf.distribute.DistributedValues, содержащими тензоры или составные тензоры.

Ключевая информация: В зависимости от реализации tf.distribute.Strategy и от того, включено ли жадное выполнение, fn может быть вызвано один или несколько раз. Если fn аннотировано с tf.function или tf.distribute.Strategy.run вызывается внутри tf.function, жадное выполнение отключено, и fn вызывается один раз (или один раз на реплику, если вы используете MirroredStrategy) для генерации графа Tensorflow, который затем будет повторно использован для выполнения с новыми входными данными. В противном случае, если жадное выполнение включено, fn будет вызываться каждый шаг, как и обычный Python-код.

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

  1. Ввод тензора с постоянным значением.
strategy = tf.distribute.MirroredStrategy()
tensor_input = tf.constant(3.0)
@tf.function
def replica_fn(input):
  return input*2.0
result = strategy.run(replica_fn, args=(tensor_input,))
result
<tf.Tensor: shape=(), dtype=float32, numpy=6.0>
  1. Ввод DistributedValues.
strategy = tf.distribute.MirroredStrategy()
@tf.function
def run():
  def value_fn(value_context):
    return value_context.num_replicas_in_sync
  distributed_values = (
    strategy.experimental_distribute_values_from_function(
      value_fn))
  def replica_fn2(input):
    return input*2
  return strategy.run(replica_fn2, args=(distributed_values,))
result = run()
result
<tf.Tensor: shape=(), dtype=int32, numpy=2>
Аргументы
fn Функция для выполнения. Выход должен быть tf.nest из Tensor.
args (Необязательно) Позиционные аргументы для fn.
kwargs (Необязательно) Аргументы ключевых слов для fn.
options (Необязательно) Экземпляр tf.distribute.RunOptions, определяющий параметры запуска fn.
Возвращает
Объединенное возвращаемое значение fn по репликам. Структура возвращаемого значения такая же, как структура возвращаемого значения от fn. Каждый элемент структуры может быть tf.distribute.DistributedValues, объектами Tensor, или Tensor (например, при выполнении на одной реплике).

scope

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

scope()

Менеджер контекста для установления стратегии по умолчанию и распределения переменных.

Этот метод возвращает менеджер контекста и используется следующим образом:

strategy = tf.distribute.MirroredStrategy()
# Variable created inside scope:
with strategy.scope():
  mirrored_variable = tf.Variable(1.)
mirrored_variable
MirroredVariable:{
  0: <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=1.0>
}
# Variable created outside scope:
regular_variable = tf.Variable(1.)
regular_variable
<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=1.0>

Что происходит при входе в Strategy.scope?

  • strategy устанавливается в глобальный контекст как «текущая» стратегия. Внутри этого области tf.distribute.get_strategy() теперь вернет эту стратегию. Вне этой области он возвращает стратегию по умолчанию.
  • Вход в область также означает вход в «межрепличный контекст». См. tf.distribute.StrategyExtended для объяснения межрепличных и реплицированных контекстов.
  • Создание переменных внутри scope перехватывается стратегией. Каждая стратегия определяет, как она хочет повлиять на создание переменной. Синхронные стратегии, такие как MirroredStrategy, TPUStrategy и MultiWorkerMiroredStrategy, создают переменные, дублированные на каждой реплике, тогда как ParameterServerStrategy создает переменные на серверах параметров. Это делается с помощью пользовательского tf.variable_creator_scope.
  • В некоторых стратегиях может также быть введен область устройства по умолчанию: в MultiWorkerMiroredStrategy, область устройства по умолчанию "/CPU:0" вводится на каждом рабочем узле.
Примечание: Вход в область не автоматически распределяет вычисление, за исключением случаев использования высокоуровневой учебной платформы, например, Keras model.fit. Если вы не используете model.fit, вам нужно использовать API strategy.run для явного распределения вычисления. См. пример в руководстве по настраиваемому циклу обучения custom training loop tutorial.

Что должно быть в области, а что — вне?

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

END_OF_DOCUMENT_MARKER
  • Все, что создает переменные, которые должны быть распределёнными, должно находиться в strategy.scope. Это можно сделать, либо напрямую поместив их в область действия, либо используя другой API, например strategy.run или model.fit, чтобы поместить их туда за вас. Любые переменные, созданные вне области действия, не будут распределены и могут повлиять на производительность. Типичные вещи, создающие переменные в TF: модели, оптимизаторы, метрики. Они всегда должны создаваться внутри области действия. Другим источником создания переменных может быть восстановление из контрольной точки – когда переменные создаются лениво. Обратите внимание, что любая переменная, созданная внутри стратегии, сохраняет информацию о стратегии. Поэтому чтение и запись этих переменных вне strategy.scope также могут работать беспрепятственно, без необходимости пользователю входить в область действия.
  • Некоторые API стратегий (такие как strategy.run и strategy.reduce) которые требуют нахождения в области действия стратегии, автоматически входят в эту область, что означает, что при использовании этих API вам не нужно входить в область действия самостоятельно.
  • Когда tf.keras.Model создается внутри strategy.scope, мы сохраняем эту информацию. Когда методы высокоуровневых обучающих фреймворков, такие как model.compile, model.fit и т.д., вызываются на этой модели, мы автоматически входим в область действия, а также используем эту стратегию для распределения обучения и т.д. См. подробный пример в учебнике по распределённому Keras. Обратите внимание, что простое вызов model(..) не затрагивается – только высокоуровневые API обучающих фреймворков. model.compile, model.fit, model.evaluate, model.predict и model.save могут вызываться внутри или вне области действия.
  • Следующие операции могут выполняться как внутри, так и вне области действия: ** Создание наборов входных данных ** Определение tf.function для представления шага обучения ** API сохранения, такие как tf.saved_model.save. Загрузка создает переменные, поэтому для обучения модели в распределённом режиме она должна быть внутри области действия. ** Сохранение контрольных точек. Как упоминалось выше – checkpoint.restore иногда может потребоваться быть внутри области действия, если она создаёт переменные.
Возвращает
Менеджер контекста.

© 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/r2.3/api_docs/python/tf/distribute/experimental/ParameterServerStrategy

Spec-Zone.ru

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