Bu sayfa, Cloud Translation API ile çevrilmiştir.
Switch to English

Dağıtılmış Giriş

TensorFlow.org'da görüntüleyin Google Colab'da çalıştırın Kaynağı GitHub'da görüntüle Not defterini indir

Tf.distribute API'leri, kullanıcıların eğitimlerini tek bir makineden birden fazla makineye ölçeklendirmeleri için kolay bir yol sağlar. Modellerini ölçeklendirirken, kullanıcıların da girdilerini birden çok cihaza dağıtması gerekir. tf.distribute , tf.distribute cihazlar arasında otomatik olarak dağıtabileceğiniz API'ler sağlar.

Bu kılavuz, tf.distribute API'lerini kullanarak dağıtılmış veri kümesi ve yineleyiciler oluşturmanın farklı yollarını gösterecektir. Ek olarak, aşağıdaki konular ele alınacaktır:

Bu kılavuz, dağıtılmış girdinin Keras API'leri ile kullanımını kapsamaz.

Dağıtılmış Veri Kümeleri

tf.distribute için tf.distribute API'lerini kullanmak için, kullanıcıların girdilerini temsil etmek üzere tf.data.Dataset kullanmaları tf.data.Dataset . tf.distribute , tf.data.Dataset (örneğin, her hızlandırıcı aygıt üzerine otomatik veri önceden getirme) ile verimli bir şekilde çalışacak şekilde yapılmıştır ve performans optimizasyonları uygulamaya düzenli olarak dahil edilmiştir. tf.data.Dataset dışında bir şey kullanmak için bir kullanım durumunuz tf.data.Dataset , lütfen bu kılavuzun sonraki bir bölümüne bakın. Dağıtılmamış bir eğitim döngüsünde, kullanıcılar önce bir tf.data.Dataset örneği oluşturur ve ardından öğeler üzerinde yineleme yapar. Örneğin:

 import tensorflow as tf

# Helper libraries
import numpy as np
import os

print(tf.__version__)
 
2.3.0

 global_batch_size = 16
# Create a tf.data.Dataset object.
dataset = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100).batch(global_batch_size)

@tf.function
def train_step(inputs):
  features, labels = inputs
  return labels - 0.3 * features

# Iterate over the dataset using the for..in construct.
for inputs in dataset:
  print(train_step(inputs))

 
tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(4, 1), dtype=float32)

Kullanıcıların tf.distribute stratejisini kullanıcının mevcut kodunda en az değişiklikle kullanmasına izin vermek için, bir tf.data.Dataset örneğini tf.data.Dataset ve dağıtılmış bir veri kümesi nesnesi döndürecek iki API tanıtılmıştır. Bir kullanıcı daha sonra bu dağıtılmış veri kümesi örneği üzerinde yineleme yapabilir ve modelini daha önce olduğu gibi eğitebilir. Şimdi iki tf.distribute.Strategy.experimental_distribute_dataset tf.distribute.Strategy.experimental_distribute_datasets_from_function - tf.distribute.Strategy.experimental_distribute_dataset ve tf.distribute.Strategy.experimental_distribute_datasets_from_function daha ayrıntılı olarak:

tf.distribute.Strategy.experimental_distribute_dataset

kullanım

Bu API, giriş olarak bir tf.data.Dataset örneğini alır ve bir tf.distribute.DistributedDataset örneğini döndürür. Girdi veri kümesini genel toplu iş boyutuna eşit bir değerle toplu işlemelisiniz. Bu genel toplu iş boyutu, tüm aygıtlarda 1 adımda işlemek istediğiniz örneklerin sayısıdır. Bir Pythonic moda bu dağıtılmış veri kümesini üzerinde yineleme veya kullanan bir yineleyici oluşturabilir iter . Döndürülen nesne bir tf.data.Dataset örneği değildir ve veri kümesini herhangi bir şekilde dönüştüren veya inceleyen başka API'leri desteklemez. Girişinizi farklı kopyalar üzerinden parçalamak istediğiniz belirli yollarınız yoksa, bu önerilen API'dir.

 global_batch_size = 16
mirrored_strategy = tf.distribute.MirroredStrategy()

dataset = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100).batch(global_batch_size)
# Distribute input using the `experimental_distribute_dataset`.
dist_dataset = mirrored_strategy.experimental_distribute_dataset(dataset)
# 1 global batch of data fed to the model in 1 step.
print(next(iter(dist_dataset)))
 
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/data/ops/multi_device_iterator_ops.py:601: get_next_as_optional (from tensorflow.python.data.ops.iterator_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use `tf.data.Iterator.get_next_as_optional()` instead.
(<tf.Tensor: shape=(16, 1), dtype=float32, numpy=
array([[1.],
       [1.],
       [1.],
       [1.],
       [1.],
       [1.],
       [1.],
       [1.],
       [1.],
       [1.],
       [1.],
       [1.],
       [1.],
       [1.],
       [1.],
       [1.]], dtype=float32)>, <tf.Tensor: shape=(16, 1), dtype=float32, numpy=
array([[1.],
       [1.],
       [1.],
       [1.],
       [1.],
       [1.],
       [1.],
       [1.],
       [1.],
       [1.],
       [1.],
       [1.],
       [1.],
       [1.],
       [1.],
       [1.]], dtype=float32)>)

Özellikleri

Harmanlama

tf.distribute , tf.data.Dataset örneğini, genel toplu iş boyutuna eşit yeni bir toplu iş boyutuyla eşitlemedeki çoğaltma sayısına tf.data.Dataset . Senkronize edilen çoğaltma sayısı, eğitim sırasında gradyan azalmasında yer alan cihazların sayısına eşittir. Bir kullanıcı dağıtılmış yineleyicide bir next çağırdığında, her eşlemede çoğaltma başına toplu veri boyutu döndürülür. İndirgenmiş veri kümesi kardinalitesi her zaman replika sayısının katları olacaktır. Burada bir çift örnek var:

  • tf.data.Dataset.range(6).batch(4, drop_remainder=False)

    Dağıtım olmadan:

    Parti 1: [0, 1, 2, 3]

    2. Parti: [4, 5]

    2 kopya üzerinde dağıtım ile:

    Parti 1: Çoğaltma 1: [0, 1] Çoğaltma 2: [2, 3]

    Grup 2: Kopya 2: [4] Kopya 2: [5]

    Son parti ([4, 5]) 2 kopyaya bölünmüştür.

  • tf.data.Dataset.range(4).batch(4)

    Dağıtım olmadan:

    1. Parti: [[0], [1], [2], [3]]

    5 kopyadan fazla dağıtım ile:

    Toplu İşlem 1: Çoğaltma 1: [0] Çoğaltma 2: [1] Çoğaltma 3: [2] Çoğaltma 4: [3] Çoğaltma 5: []

  • tf.data.Dataset.range(8).batch(4)

    Dağıtım olmadan:

    1. Parti: [0, 1, 2, 3]

    Parti 2: [4, 5, 6, 7]

    3 kopya üzerinden dağıtım ile:

    Parti 1: Çoğaltma 1: [0, 1] Çoğaltma 2: [2, 3] Çoğaltma 3: []

    Grup 2: Kopya 1: [4, 5] Kopya 2: [6, 7] Kopya 3: []

Veri kümesinin yeniden işlenmesi, çoğaltma sayısıyla doğrusal olarak artan bir alan karmaşıklığına sahiptir. Bu, çok çalışanlı eğitim kullanım durumu için giriş kanalının OOM hatalarına girebileceği anlamına gelir.

Sharding

tf.distribute ayrıca çok çalışanlı eğitimde girdi veri kümesini otomatik olarak zorlar. Her veri kümesi çalışanın CPU aygıtında oluşturulur. Bir veri kümesini bir çalışan kümesi üzerinde otomatik olarak paylaşmak, her çalışana tüm veri kümesinin bir alt kümesinin atanması anlamına gelir (doğru tf.data.experimental.AutoShardPolicy ayarlandıysa). Bunun amacı, her adımda, çakışmayan veri kümesi öğelerinin genel bir toplu boyutunun her çalışan tarafından işlenmesini sağlamaktır. Autosharding kullanılarak belirtilebilir farklı birkaç seçenek vardır tf.data.experimental.DistributeOptions .

 dataset = tf.data.Dataset.from_tensors(([1.],[1.])).repeat(64).batch(16)
options = tf.data.Options()
options.experimental_distribute.auto_shard_policy = tf.data.experimental.AutoShardPolicy.DATA
dataset = dataset.with_options(options)
 

tf.data.experimental.AutoShardPolicy için ayarlayabileceğiniz üç farklı seçenek vardır:

  • OTOMATİK: Bu varsayılan seçenektir, yani FILE tarafından parçalama girişiminde bulunulacaktır. Dosya tabanlı bir veri kümesi algılanmazsa, FILE tarafından parçalanma denemesi başarısız olur. tf.distribute daha sonra DATA tarafından parçalanmaya geri döner. Giriş veri kümesinin dosya tabanlı olması ancak dosya sayısının çalışan sayısından az olması durumunda bir hata oluşacağını unutmayın.
  • DOSYA: Girdi dosyalarını tüm çalışanlar üzerinde parçalamak istiyorsanız bu seçenektir. Dosya sayısı çalışan sayısından azsa, bir hata ortaya çıkacaktır. Girdi dosyalarının sayısı çalışan sayısından çok daha fazlaysa ve dosyalardaki veriler eşit olarak dağıtılmışsa bu seçeneği kullanmalısınız. Bu seçeneğin dezavantajı, dosyalardaki veriler eşit olarak dağıtılmamışsa, boş çalışanlara sahip olmaktır. Örneğin, her biri 1 kopya olacak şekilde 2 çalışana 2 dosya dağıtalım. Dosya 1 [0, 1, 2, 3, 4, 5] ve Dosya 2 [6, 7, 8, 9, 10, 11] içerir. Eşzamanlı olarak toplam kopya sayısı 2 ve genel toplu iş boyutu 4 olsun.

    • İşçi 0:

    Parti 1 = Çoğaltma 1: [0, 1]

    Parti 2 = Çoğaltma 1: [2, 3]

    Grup 3 = Kopya 1: [4]

    Grup 4 = Kopya 1: [5]

    • İşçi 1:

    Parti 1 = Çoğaltma 2: [6, 7]

    Parti 2 = Kopya 2: [8, 9]

    Grup 3 = Kopya 2: [10]

    Parti 4 = Kopya 2: [11]

  • VERİ: Bu, tüm işçilerdeki unsurları otomatik olarak sertleştirecektir. İşçilerin her biri tüm veri kümesini okuyacak ve sadece kendisine atanan parçayı işleyecektir. Diğer tüm kırıklar atılır. Bu genellikle girdi dosyalarının sayısı çalışan sayısından azsa ve tüm çalışanlar arasında daha iyi veri parçalanması istiyorsanız kullanılır. Olumsuz yanı, veri kümesinin tamamının her işçi üzerinde okunacak olmasıdır. Örneğin, 1 dosyayı 2 işçiye dağıtalım. Dosya 1 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] içerir. Eşzamanlı olarak toplam kopya sayısı 2 olsun.

    • İşçi 0:

    Grup 1 = Kopya 1: [0, 1]

    Parti 2 = Kopya 1: [4, 5]

    Parti 3 = Çoğaltma 1: [8, 9]

    • İşçi 1:

    Parti 1 = Çoğaltma 2: [2, 3]

    Parti 2 = Çoğaltma 2: [6, 7]

    Grup 3 = Kopya 2: [10, 11]

  • KAPALI: Otomatik paylaşmayı kapatırsanız, her çalışan tüm verileri işleyecektir. Örneğin, 1 dosyayı 2 çalışana dağıtalım. Dosya 1 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] içerir. Eşzamanlı toplam kopya sayısının 2 olmasına izin verin. Ardından her çalışan aşağıdaki dağılımı görecek:

    • İşçi 0:

    Grup 1 = Kopya 1: [0, 1]

    Grup 2 = Kopya 1: [2, 3]

    Parti 3 = Çoğaltma 1: [4, 5]

    Parti 4 = Çoğaltma 1: [6, 7]

    Parti 5 = Çoğaltma 1: [8, 9]

    Toplu 6 = Kopya 1: [10, 11]

    • İşçi 1:

    Parti 1 = Çoğaltma 2: [0, 1]

    Parti 2 = Çoğaltma 2: [2, 3]

    Parti 3 = Çoğaltma 2: [4, 5]

    Grup 4 = Kopya 2: [6, 7]

    Parti 5 = Çoğaltma 2: [8, 9]

    Parti 6 = Çoğaltma 2: [10, 11]

Önceden Alma

Varsayılan olarak, tf.distribute , sağlanan tf.data.Dataset örneğinin sonuna bir ön getirme dönüşümü ekler. buffer_size olan önceden getirme dönüşümünün argümanı, senkronizasyondaki replikaların sayısına eşittir.

tf.distribute.Strategy.experimental_distribute_datasets_from_function

kullanım

Bu API bir giriş işlevi alır ve bir tf.distribute.DistributedDataset örneği döndürür. Kullanıcıların tf.distribute.InputContext girdi işlevi bir tf.distribute.InputContext bağımsız değişkenine sahiptir ve bir tf.data.Dataset örneği döndürmelidir. Bu API ile, tf.distribute , kullanıcının giriş işlevinden döndürülen tf.data.Dataset örneğinde başka değişiklik yapmaz. Veri kümesini toplu yapmak ve parçalamak kullanıcının sorumluluğundadır. tf.distribute , her bir çalışanın CPU aygıtındaki giriş işlevini çağırır. Kullanıcıların kendi gruplama ve parçalama mantıklarını belirtmelerine izin vermenin yanı sıra, bu API aynı zamanda çok çalışanlı eğitim için kullanıldığında tf.distribute.Strategy.experimental_distribute_dataset karşılaştırıldığında daha iyi ölçeklenebilirlik ve performans gösterir.

 mirrored_strategy = tf.distribute.MirroredStrategy()

def dataset_fn(input_context):
  batch_size = input_context.get_per_replica_batch_size(global_batch_size)
  dataset = tf.data.Dataset.from_tensors(([1.],[1.])).repeat(64).batch(16)
  dataset = dataset.shard(
    input_context.num_input_pipelines, input_context.input_pipeline_id)
  dataset = dataset.batch(batch_size)
  dataset = dataset.prefetch(2) # This prefetches 2 batches per device.
  return dataset

dist_dataset = mirrored_strategy.experimental_distribute_datasets_from_function(dataset_fn)
 
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)

Özellikleri

Harmanlama

Girdi işlevinin dönüş değeri olan tf.data.Dataset örneği, çoğaltma başına toplu iş boyutu kullanılarak toplu hale getirilmelidir. Çoğaltma başına toplu iş boyutu genel toplu iş boyutunun eşitleme eğitiminde yer alan çoğaltma sayısına bölünmesiyle elde edilir. Bunun nedeni, tf.distribute her bir çalışanın CPU aygıtındaki giriş işlevini tf.distribute . Belirli bir çalışanda oluşturulan veri kümesi, o çalışandaki tüm kopyalar tarafından kullanılmaya hazır olmalıdır.

Sharding

Kullanıcının giriş işlevine örtülü olarak bağımsız değişken olarak iletilen tf.distribute.InputContext nesnesi, başlık altında tf.distribute tarafından oluşturulur. İşçi sayısı, geçerli çalışan kimliği vb. Hakkında bilgi içerir. Bu giriş işlevi, kullanıcı tarafından tf.distribute.InputContext nesnesinin bir parçası olan bu özellikleri kullanarak ayarlanan ilkelere göre gölgeleme işleyebilir.

Önceden Alma

tf.distribute , kullanıcı tarafından sağlanan girdi işlevi tarafından döndürülen tf.data.Dataset sonuna bir ön getirme dönüşümü tf.data.Dataset .

Dağıtılmış Yineleyiciler

Dağıtılmamış tf.data.Dataset örneklerine benzer şekilde, üzerinde yinelemek ve tf.distribute.DistributedDataset içindeki öğelere erişmek için tf.distribute.DistributedDataset örneklerinde bir yineleyici oluşturmanız gerekir. Aşağıda, bir tf.distribute.DistributedIterator oluşturmanın ve modelinizi eğitmek için kullanmanın yolları şunlardır:

Usages

Döngü yapısı için bir Pythonic kullanın

tf.distribute.DistributedDataset üzerinde yineleme yapmak için kullanıcı dostu bir Pythonic döngüsü kullanabilirsiniz. Dönen elemanlar tf.distribute.DistributedIterator tek olabilir tf.Tensor veya tf.distribute.DistributedValues yineleme başına bir değer içerir. Döngüyü bir tf.function içine yerleştirmek performans artışı sağlayacaktır. Ancak, döngü bir tf.function içine yerleştirilmişse, şu anda break ve return desteklenmemektedir. Ayrıca tf.distribute.experimental.MultiWorkerMirroredStrategy ve tf.distribute.TPUStrategy gibi çok çalışanlı stratejiler kullanırken, döngüyü bir tf.function içine yerleştirmeyi desteklemiyoruz. Döngünün tf.function içine yerleştirilmesi tek çalışan tf.distribute.TPUStrategy için çalışır, ancak TPU kapsülleri kullanıldığında geçerli değildir.

 global_batch_size = 16
mirrored_strategy = tf.distribute.MirroredStrategy()

dataset = tf.data.Dataset.from_tensors(([1.],[1.])).repeat(100).batch(global_batch_size)
dist_dataset = mirrored_strategy.experimental_distribute_dataset(dataset)

@tf.function
def train_step(inputs):
  features, labels = inputs
  return labels - 0.3 * features

for x in dist_dataset:
  # train_step trains the model using the dataset elements
  loss = mirrored_strategy.run(train_step, args=(x,))
  print("Loss is ", loss)
 
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(4, 1), dtype=float32)

Açık bir yineleyici oluşturmak için iter kullanma

Bir tf.distribute.DistributedDataset örneğindeki öğeler üzerinde yineleme yapmak için, üzerindeki iter API'sini kullanarak bir tf.distribute.DistributedIterator oluşturabilirsiniz. Açık bir yineleyici ile sabit sayıda adım için yineleme yapabilirsiniz. Bir tf.distribute.DistributedIterator örnek dist_iterator bir sonraki elemanı almak için, next(dist_iterator) , dist_iterator.get_next() veya dist_iterator.get_next_as_optional() . İlk ikisi esasen aynıdır:

 num_epochs = 10
steps_per_epoch = 5
for epoch in range(num_epochs):
  dist_iterator = iter(dist_dataset)
  for step in range(steps_per_epoch):
    # train_step trains the model using the dataset elements
    loss = mirrored_strategy.run(train_step, args=(next(dist_iterator),))
    # which is the same as
    # loss = mirrored_strategy.run(train_step, args=(dist_iterator.get_next(),))
    print("Loss is ", loss)
 
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)
Loss is  tf.Tensor(
[[0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]
 [0.7]], shape=(16, 1), dtype=float32)

tf.distribute.DistributedIterator.get_next() next() veya tf.distribute.DistributedIterator.get_next() , tf.distribute.DistributedIterator sonuna ulaştıysa, bir OutOfRange hatası atılır. İstemci python tarafında hatayı yakalayabilir ve kontrol noktası ve değerlendirme gibi diğer işleri yapmaya devam edebilir. Ancak, aşağıdaki gibi görünen bir ana makine eğitim döngüsü kullanıyorsanız (yani, tf.function başına birden çok adım çalıştırın) tf.function :

 @tf.function
def train_fn(iterator):
  for _ in tf.range(steps_per_loop):
    strategy.run(step_fn, args=(next(iterator),))
 

train_fn , adım gövdesini bir tf.range içine sararak birden fazla adım içerir. Bu durumda, döngüdeki bağımlılık olmayan farklı yinelemeler paralel olarak başlayabilir, bu nedenle bir OutOfRange hatası, önceki yinelemelerin hesaplanması bitmeden önce sonraki yinelemelerde tetiklenebilir. Bir OutOfRange hatası atıldığında, işlevdeki tüm operasyonlar hemen sonlandırılacaktır. Bu kaçınmak isteyeceğiniz bir durumsa, tf.distribute.DistributedIterator.get_next_as_optional() hatası vermeyen bir alternatif tf.distribute.DistributedIterator.get_next_as_optional() . get_next_as_optional , tf.distribute.DistributedIterator bir sona ulaştıysa sonraki öğeyi içeren veya değer içermeyen bir tf.experimental.Optional get_next_as_optional döndürür.

 # You can break the loop with get_next_as_optional by checking if the Optional contains value
global_batch_size = 4
steps_per_loop = 5
strategy = tf.distribute.MirroredStrategy(devices=["GPU:0", "CPU:0"])

dataset = tf.data.Dataset.range(9).batch(global_batch_size)
distributed_iterator = iter(strategy.experimental_distribute_dataset(dataset))

@tf.function
def train_fn(distributed_iterator):
  for _ in tf.range(steps_per_loop):
    optional_data = distributed_iterator.get_next_as_optional()
    if not optional_data.has_value():
      break
    per_replica_results = strategy.run(lambda x:x, args=(optional_data.get_value(),))
    tf.print(strategy.experimental_local_results(per_replica_results))
train_fn(distributed_iterator)
 
WARNING:tensorflow:There are non-GPU devices in `tf.distribute.Strategy`, not using nccl allreduce.
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0', '/job:localhost/replica:0/task:0/device:CPU:0')
([0 1], [2 3])
([4 5], [6 7])
([8], [])

element_spec özelliğini kullanma

Bir dağıtılmış bir veri kümesi unsurlarını geçerseniz tf.function ve istediğiniz tf.TypeSpec garantisi, Belirtebileceğiniz input_signature savını tf.function . Dağıtılmış bir veri kümesinin çıktısı, girdiyi tek bir cihaza veya birden çok cihaza temsil tf.distribute.DistributedValues . Bu dağıtılmış değere karşılık gelen tf.TypeSpec elde etmek için, dağıtılmış veri kümesinin veya dağıtılmış yineleyici nesnesinin element_spec özelliğini kullanabilirsiniz.

 global_batch_size = 16
epochs = 5
steps_per_epoch = 5
mirrored_strategy = tf.distribute.MirroredStrategy()

dataset = tf.data.Dataset.from_tensors(([1.],[1.])).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 2 * 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))
    tf.print(output)
 
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])

Kısmi Partiler

Kullanıcıların oluşturduğu tf.data.Dataset örnekleri, çoğaltma sayısına eşit olarak bölünemeyen toplu iş boyutları içerebildiğinde veya veri kümesi örneğinin önem düzeyi toplu iş boyutuna bölünemediğinde kısmi partilerle karşılaşılır. Bu, veri kümesi birden çok çoğaltmaya dağıtıldığında, bazı yineleyicilerdeki bir next çağrının bir OutOfRangeError ile sonuçlanacağı anlamına gelir. Bu kullanım örneğini işlemek için tf.distribute , tf.distribute başka veriye sahip olmayan eşlemelerde 0 toplu iş boyutunda sahte gruplar döndürür.

Tek işçi durumu için, veriler yineleyicide bir next çağrı tarafından döndürülmezse, 0 toplu iş boyutundaki sahte gruplar oluşturulur ve veri kümesindeki gerçek verilerle birlikte kullanılır. Kısmi gruplar halinde, son küresel veri grubu, sahte veri gruplarının yanında gerçek veriler içerecektir. Verilerin işlenmesi için durdurma koşulu, artık kopyalardan herhangi birinin veri olup olmadığını kontrol ediyor. Çoğaltmaların hiçbirinde veri yoksa, bir OutOfRange hatası atılır.

Çoklu çalışan durumu için, her bir çalışanla ilgili verilerin varlığını temsil eden boole değeri, çapraz çoğaltma iletişimi kullanılarak toplanır ve bu, tüm çalışanların dağıtılmış veri kümesini işlemeyi bitirip bitirmediğini belirlemek için kullanılır. Bu, çalışanlar arası iletişimi içerdiğinden, bazı performans cezaları söz konusudur.

Uyarılar

  • tf.distribute.Strategy.experimental_distribute_dataset API'lerini birden çok çalışan kurulumuyla kullanırken, kullanıcılar dosyalardan okuyan bir tf.data.Dataset . tf.data.experimental.AutoShardPolicy , AUTO veya FILE olarak ayarlanmışsa, adım başına gerçek parti boyutu, kullanıcı tanımlı genel parti boyutundan daha küçük olabilir. Bu, dosyadaki kalan öğeler genel toplu iş boyutundan küçük olduğunda gerçekleşebilir. Kullanıcılar, çalıştırılacak adım sayısına bağlı olmadan veri kümesini tf.data.experimental.AutoShardPolicy veya tf.data.experimental.AutoShardPolicy etrafında çalışmak üzere DATA olarak ayarlayabilir.

  • Durum bilgisi olan veri kümesi dönüşümleri şu anda tf.distribute ile desteklenmemektedir ve veri kümesinin sahip olabileceği durum bilgisi olan tüm işlemler şu anda göz ardı edilmektedir. Örneğin, veri map_fn görüntüyü döndürmek için tf.random.uniform kullanan bir tf.random.uniform varsa, python işleminin yürütüldüğü yerel makinede duruma (yani rasgele tohum) bağlı bir veri kümesi grafiğiniz vardır.

  • Varsayılan olarak devre dışı bırakılan deneysel tf.data.experimental.OptimizationOptions , belirli bağlamlarda - örneğin tf.distribute ile birlikte kullanıldığında - performans tf.distribute neden olabilir. Bunları yalnızca, bir dağıtım ayarında iş yükünüzün performansına fayda sağladıklarını doğruladıktan sonra etkinleştirmelisiniz.

  • tf.distribute.experimental_distribute_dataset veya tf.distribute.experimental_distribute_datasets_from_function kullanılırken verilerin çalışanlar tarafından tf.distribute.experimental_distribute_dataset tf.distribute.experimental_distribute_datasets_from_function garanti edilmez. Tahmini tf.distribute için tf.distribute kullanıyorsanız bu genellikle gereklidir. Bununla birlikte, toplu işteki her eleman için bir dizin ekleyebilir ve çıktıları buna göre sipariş edebilirsiniz. Aşağıdaki kod parçası, çıktıların nasıl sıralanacağına dair bir örnektir.

 mirrored_strategy = tf.distribute.MirroredStrategy()
dataset_size = 24
batch_size = 6
dataset = tf.data.Dataset.range(dataset_size).enumerate().batch(batch_size)
dist_dataset = mirrored_strategy.experimental_distribute_dataset(dataset)

def predict(index, inputs):
  outputs = 2 * inputs
  return index, outputs

result = {}
for index, inputs in dist_dataset:
  output_index, outputs = mirrored_strategy.run(predict, args=(index, inputs))
  indices = list(mirrored_strategy.experimental_local_results(output_index))
  rindices = []
  for a in indices:
    rindices.extend(a.numpy())
  outputs = list(mirrored_strategy.experimental_local_results(outputs))
  routputs = []
  for a in outputs:
    routputs.extend(a.numpy())
  for i, value in zip(rindices, routputs):
    result[i] = value

print(result)
 
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)
WARNING:tensorflow:Using MirroredStrategy eagerly has significant overhead currently. We will be working on improving this in the future, but for now please wrap `call_for_each_replica` or `experimental_run` or `experimental_run_v2` inside a tf.function to get the best performance.
WARNING:tensorflow:Using MirroredStrategy eagerly has significant overhead currently. We will be working on improving this in the future, but for now please wrap `call_for_each_replica` or `experimental_run` or `experimental_run_v2` inside a tf.function to get the best performance.
WARNING:tensorflow:Using MirroredStrategy eagerly has significant overhead currently. We will be working on improving this in the future, but for now please wrap `call_for_each_replica` or `experimental_run` or `experimental_run_v2` inside a tf.function to get the best performance.
WARNING:tensorflow:Using MirroredStrategy eagerly has significant overhead currently. We will be working on improving this in the future, but for now please wrap `call_for_each_replica` or `experimental_run` or `experimental_run_v2` inside a tf.function to get the best performance.
{0: 0, 1: 2, 2: 4, 3: 6, 4: 8, 5: 10, 6: 12, 7: 14, 8: 16, 9: 18, 10: 20, 11: 22, 12: 24, 13: 26, 14: 28, 15: 30, 16: 32, 17: 34, 18: 36, 19: 38, 20: 40, 21: 42, 22: 44, 23: 46}

Standart bir tf.data.Dataset örneği kullanmıyorsam verilerimi nasıl dağıtırım?

Bazen kullanıcılar girişlerini temsil etmek için bir tf.data.Dataset ve ardından veri kümesini birden çok cihaza dağıtmak için yukarıda belirtilen API'leri kullanamazlar. Bu gibi durumlarda, bir jeneratörden ham tensörler veya girdiler kullanabilirsiniz.

Rasgele tensör girişleri için experimental_distribute_values_from_function kullanın

strategy.run , next(iterator) çıktısı olan tf.distribute.DistributedValues kabul eder. Tensör değerlerini iletmek için ham tensörlerden tf.distribute.DistributedValues değerini oluşturmak için experimental_distribute_values_from_function kullanın.

 mirrored_strategy = tf.distribute.MirroredStrategy()
worker_devices = mirrored_strategy.extended.worker_devices

def value_fn(ctx):
  return tf.constant(1.0)

distributed_values = mirrored_strategy.experimental_distribute_values_from_function(value_fn)
for _ in range(4):
  result = mirrored_strategy.run(lambda x:x, args=(distributed_values,))
  print(result)
 
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)
WARNING:tensorflow:Using MirroredStrategy eagerly has significant overhead currently. We will be working on improving this in the future, but for now please wrap `call_for_each_replica` or `experimental_run` or `experimental_run_v2` inside a tf.function to get the best performance.
tf.Tensor(1.0, shape=(), dtype=float32)
tf.Tensor(1.0, shape=(), dtype=float32)
tf.Tensor(1.0, shape=(), dtype=float32)
tf.Tensor(1.0, shape=(), dtype=float32)

Girişiniz bir jeneratörden ise tf.data.Dataset.from_generator kullanın

tf.data.Dataset istediğiniz bir jeneratör işleviniz varsa, from_generator API'sını kullanarak bir tf.data.Dataset örneği oluşturabilirsiniz.

 mirrored_strategy = tf.distribute.MirroredStrategy()
def input_gen():
  while True:
    yield np.random.rand(4)

# use Dataset.from_generator
dataset = tf.data.Dataset.from_generator(
    input_gen, output_types=(tf.float32), output_shapes=tf.TensorShape([4]))
dist_dataset = mirrored_strategy.experimental_distribute_dataset(dataset)
iterator = iter(dist_dataset)
for _ in range(4):
  mirrored_strategy.run(lambda x:x, args=(next(iterator),))
 
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)