tf.distribute.DistributedDataset
Представляет набор данных, распределенный по устройствам и машинам.
Можно представить tf.distribute.DistributedDataset как "распределенный" набор данных. Когда вы используете tf.distribute API для масштабирования обучения на нескольких устройствах или машинах, вам также необходимо распределить входные данные, что приводит к экземпляру tf.distribute.DistributedDataset, а не экземпляру tf.data.Dataset в случае отсутствия распределения. В TF 2.x объекты tf.distribute.DistributedDataset являются итерируемыми объектами Python.
Примечание: Экземплярыtf.distribute.DistributedDatasetне являются типаtf.data.Dataset. Он поддерживает только два способа использования, которые мы упомянем ниже: итерация иelement_spec. Мы не поддерживаем другие API для преобразования или проверки набора данных.
Существуют два API для создания объекта tf.distribute.DistributedDataset: tf.distribute.Strategy.experimental_distribute_dataset(dataset) и tf.distribute.Strategy.distribute_datasets_from_function(dataset_fn). Когда использовать какой? Когда у вас есть экземпляр tf.data.Dataset, и обычное разделение на пакеты (т. е. повторное разделение входного tf.data.Dataset экземпляра с новым размером пакета, равным глобальному размеру пакета, деленному на количество реплик в синхронизации) и автофрагментация (т. е. tf.data.experimental.AutoShardPolicy опции) работают для вас, используйте первый API. В противном случае, если вы не используете стандартный экземпляр tf.data.Dataset, или вы хотите настроить разделение на пакеты или фрагментацию, вы можете обернуть эти логику в dataset_fn и использовать последний API. Оба API обрабатывают предварительную загрузку на устройство для пользователя. Для получения более подробной информации и примеров следуйте ссылкам на API.
Существуют два основных способа использования объекта DistributedDataset:
-
Итерироваться по нему для генерации входных данных для одного устройства или нескольких устройств, что является экземпляром
tf.distribute.DistributedValues. Для этого вы можете:- использовать конструкцию цикла for Python:
global_batch_size = 4 strategy = tf.distribute.MirroredStrategy(["GPU:0", "GPU:1"]) dataset = tf.data.Dataset.from_tensors(([1.],[1.])).repeat(4).batch(global_batch_size) dist_dataset = strategy.experimental_distribute_dataset(dataset) @tf.function def train_step(input): features, labels = input return labels - 0.3 * features for x in dist_dataset: # train_step trains the model using the dataset elements loss = strategy.run(train_step, args=(x,)) print("Loss is", loss) Loss is PerReplica:{ 0: tf.Tensor( [[0.7] [0.7]], shape=(2, 1), dtype=float32), 1: tf.Tensor( [[0.7] [0.7]], shape=(2, 1), dtype=float32) }Размещение цикла внутри
tf.functionдаст прирост производительности. Однакоbreakиreturnв настоящее время не поддерживаются, если цикл размещен внутриtf.function. Мы также не поддерживаем размещение цикла внутриtf.functionпри использованииtf.distribute.experimental.MultiWorkerMirroredStrategyилиtf.distribute.experimental.TPUStrategyс несколькими рабочими узлами.- использовать
__iter__для создания явного итератора, который является объектом типаtf.distribute.DistributedIterator
global_batch_size = 4 strategy = tf.distribute.MirroredStrategy(["GPU:0", "GPU:1"]) train_dataset = tf.data.Dataset.from_tensors(([1.],[1.])).repeat(50).batch(global_batch_size) train_dist_dataset = strategy.experimental_distribute_dataset(train_dataset) @tf.function def distributed_train_step(dataset_inputs): def train_step(input): loss = tf.constant(0.1) return loss per_replica_losses = strategy.run(train_step, args=(dataset_inputs,)) return strategy.reduce(tf.distribute.ReduceOp.SUM, per_replica_losses,axis=None) EPOCHS = 2 STEPS = 3 for epoch in range(EPOCHS): total_loss = 0.0 num_batches = 0 dist_dataset_iterator = iter(train_dist_dataset) for _ in range(STEPS): total_loss += distributed_train_step(next(dist_dataset_iterator)) num_batches += 1 average_train_loss = total_loss / num_batches template = ("Epoch {}, Loss: {:.4f}") print (template.format(epoch+1, average_train_loss)) Epoch 1, Loss: 0.2000 Epoch 2, Loss: 0.2000Для повышения производительности вы также можете обернуть вызов
strategy.runсtf.rangeвнутриtf.function. Это выполняет несколько шагов вtf.function. Автоматическая генерация кода преобразует его вtf.while_loopна рабочем узле. Однако это менее гибко по сравнению с выполнением одного шага внутриtf.function. Например, вы не можете выполнять действия непосредственно или произвольный код Python в рамках шагов. -
Просмотреть
tf.TypeSpecданных, генерируемыхDistributedDataset.tf.distribute.DistributedDatasetгенерируетtf.distribute.DistributedValuesкак вход для устройств. Если вы передаете вход вtf.functionи хотите указать форму и тип каждого тензора-аргумента функции, вы можете передать объектtf.TypeSpecв аргументinput_signatureфункцииtf.function. Чтобы получитьtf.TypeSpecввода, вы можете использовать свойствоelement_specобъектаtf.distribute.DistributedDatasetилиtf.distribute.DistributedIterator.Например:
global_batch_size = 4 epochs = 1 steps_per_epoch = 1 mirrored_strategy = tf.distribute.MirroredStrategy(["GPU:0", "GPU:1"]) dataset = tf.data.Dataset.from_tensors(([2.])).repeat(100).batch(global_batch_size) dist_dataset = mirrored_strategy.experimental_distribute_dataset(dataset) @tf.function(input_signature=[dist_dataset.element_spec]) def train_step(per_replica_inputs): def step_fn(inputs): return tf.square(inputs) return mirrored_strategy.run(step_fn, args=(per_replica_inputs,)) for _ in range(epochs): iterator = iter(dist_dataset) for _ in range(steps_per_epoch): output = train_step(next(iterator)) print(output) PerReplica:{ 0: tf.Tensor( [[4.] [4.]], shape=(2, 1), dtype=float32), 1: tf.Tensor( [[4.] [4.]], shape=(2, 1), dtype=float32) }
Посетите учебник по распределенным входным данным для получения дополнительных примеров и предостережений.
| Атрибуты | |
|---|---|
element_spec | Спецификация типа элемента этого tf.distribute.DistributedDataset.
global_batch_size = 16
strategy = tf.distribute.MirroredStrategy(["GPU:0", "GPU:1"])
dataset = tf.data.Dataset.from_tensors(([1.],[2])).repeat(100).batch(global_batch_size)
dist_dataset = strategy.experimental_distribute_dataset(dataset)
dist_dataset.element_spec
(PerReplicaSpec(TensorSpec(shape=(None, 1), dtype=tf.float32, name=None),
TensorSpec(shape=(None, 1), dtype=tf.float32, name=None)),
PerReplicaSpec(TensorSpec(shape=(None, 1), dtype=tf.int32, name=None),
TensorSpec(shape=(None, 1), dtype=tf.int32, name=None))) |
Методы
__iter__
__iter__()
Создает итератор для tf.distribute.DistributedDataset.
Возвращаемый итератор реализует протокол Python Iterator.
Пример использования:
global_batch_size = 4
strategy = tf.distribute.MirroredStrategy(["GPU:0", "GPU:1"])
dataset = tf.data.Dataset.from_tensor_slices([1, 2, 3, 4]).repeat().batch(global_batch_size)
distributed_iterator = iter(strategy.experimental_distribute_dataset(dataset))
print(next(distributed_iterator))
PerReplica:{
0: tf.Tensor([1 2], shape=(2,), dtype=int32),
1: tf.Tensor([3 4], shape=(2,), dtype=int32)
}| Возвращаемое значение | |
|---|---|
Экземпляр tf.distribute.DistributedIterator для заданного объекта tf.distribute.DistributedDataset для перечисления распределенных данных. |
© 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/distribute/DistributedDataset