इस पेज का अनुवाद Cloud Translation API से किया गया है.
Switch to English

वितरित इनपुट

TensorFlow.org पर देखें Google Colab में चलाएं GitHub पर स्रोत देखें नोटबुक डाउनलोड करें

Tf.distribute APIs उपयोगकर्ताओं को एक मशीन से कई मशीनों तक अपने प्रशिक्षण को स्केल करने का एक आसान तरीका प्रदान करते हैं। अपने मॉडल को स्केल करते समय, उपयोगकर्ताओं को अपने इनपुट को कई उपकरणों में वितरित करना पड़ता है। tf.distribute एपीआई प्रदान करता है, जिसके उपयोग से आप स्वचालित रूप से अपने इनपुट को पूरे उपकरणों में वितरित कर सकते हैं।

यह मार्गदर्शिका आपको अलग-अलग तरीके दिखाएगी जिसमें आप tf.distribute APIs का उपयोग करके वितरित डेटासेट और tf.distribute को बना सकते हैं। इसके अतिरिक्त, निम्नलिखित विषयों को कवर किया जाएगा:

यह मार्गदर्शिका Keras API के साथ वितरित इनपुट के उपयोग को कवर नहीं करती है।

वितरित किए गए डेटासेट

पैमाने पर tf.distribute APIs का उपयोग करने के लिए, यह अनुशंसा की जाती है कि उपयोगकर्ता अपने इनपुट का प्रतिनिधित्व करने के लिएtf.data.Dataset का उपयोग करें। tf.distribute को कुशलता से कार्य करने के लिएtf.data.Dataset (उदाहरण के लिए, प्रत्येक एक्सेलेरेटर डिवाइस पर डेटा का स्वचालितtf.data.Dataset ) के साथ कुशलतापूर्वक काम करने के लिए बनाया गया है, ताकि नियमित रूप से कार्यान्वयन में शामिल किया जा सके। यदि आपके पासtf.data.Dataset अलावा किसी अन्य चीज़ का उपयोग करने के लिए उपयोग मामला है, तो कृपया इस मार्गदर्शिका में बाद के अनुभाग को देखें। एक गैर वितरित प्रशिक्षण पाश में, उपयोगकर्ता पहले एकtf.data.Dataset उदाहरण बनाते हैं और फिर तत्वों पर पुनरावृति करते हैं। उदाहरण के लिए:

import tensorflow as tf

# Helper libraries
import numpy as np
import os

print(tf.__version__)
2.4.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)

उपयोगकर्ताओं को उपयोगकर्ता के मौजूदा कोड में न्यूनतम परिवर्तनों के साथ tf.distribute रणनीति का उपयोग करने की अनुमति देने के लिए, दो API पेश किए गए थे जो एकtf.data.Dataset उदाहरण वितरित करेंगे और एक वितरित डेटासेट वस्तु लौटाएंगे। एक उपयोगकर्ता तब इस वितरित डेटासेट उदाहरण पर पुनरावृति कर सकता है और अपने मॉडल को पहले की तरह प्रशिक्षित कर सकता है। आइए अब हम दो APIs देखें - tf.distribute.Strategy.experimental_distribute_dataset और tf.distribute.Strategy.distribute_datasets_from_function अधिक विवरण में:

tf.distribute.Strategy.experimental_distribute_dataset

उपयोग

यह API इनपुट के रूप में एकtf.data.Dataset उदाहरण लेता है और एक tf.distribute.DistributedDataset उदाहरण देता है। आपको इनपुट डेटासेट को एक मूल्य के साथ बैचना चाहिए जो वैश्विक बैच आकार के बराबर है। यह वैश्विक बैच आकार उन नमूनों की संख्या है जिन्हें आप 1 चरण में सभी उपकरणों पर संसाधित करना चाहते हैं। आप एक pythonic फैशन में इस वितरित डाटासेट से अधिक पुनरावृति या का उपयोग कर एक इटरेटर बना सकते हैं iter । लौटी हुई वस्तुtf.data.Dataset उदाहरण नहीं है और किसी भी अन्य API का समर्थन नहीं करती है जो किसी भी तरह से डेटासेट को रूपांतरित या निरीक्षण करता है। यह अनुशंसित एपीआई है यदि आपके पास विशिष्ट तरीके नहीं हैं जिसमें आप विभिन्न प्रतिकृतियों पर अपने इनपुट को तेज करना चाहते हैं।

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',)
(<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)>)

गुण

बैचने की क्रिया

tf.distribute एक नए बैच साइज़ के साथ इनपुटtf.data.Dataset इंस्टेंस कोtf.data.Dataset करता है जो सिंक में प्रतिकृतियों की संख्या से विभाजित वैश्विक बैच आकार के बराबर होता है। सिंक में प्रतिकृतियों की संख्या उन उपकरणों की संख्या के बराबर है जो प्रशिक्षण के दौरान क्रमिक गठबंधन में भाग ले रहे हैं। एक उपयोगकर्ता की आवश्यकता होने पर next इटरेटर, डेटा की एक प्रति प्रतिकृति बैच आकार प्रत्येक प्रतिकृति पर दिया जाता है वितरित पर। पुन: प्रेषित डेटासेट कार्डिनैलिटी हमेशा प्रतिकृतियों की संख्या का एक गुणक होगा। यहां कुछ उदाहरण दिए गए हैं:

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

    • वितरण के बिना:
    • बैच 1: [0, 1, 2, 3]
    • बैच 2: [4, 5]
    • 2 प्रतिकृतियों पर वितरण के साथ। अंतिम बैच ([4, 5]) 2 प्रतिकृतियों के बीच विभाजित है।

    • बैच 1:

      • प्रतिकृति 1: [0, 1]
      • प्रतिकृति 2: [2, 3]
    • बैच 2:

      • प्रतिकृति 2: [4]
      • प्रतिकृति 2: [5]
  • tf.data.Dataset.range(4).batch(4)

    • वितरण के बिना:
    • बैच 1: [[0], [1], [2], [3]]
    • 5 से अधिक प्रतिकृतियों के वितरण के साथ:
    • बैच 1:
      • प्रतिकृति 1: [0]
      • प्रतिकृति 2: [1]
      • प्रतिकृति 3: [2]
      • प्रतिकृति 4: [3]
      • प्रतिकृति 5: []
  • tf.data.Dataset.range(8).batch(4)

    • वितरण के बिना:
    • बैच 1: [0, 1, 2, 3]
    • बैच 2: [4, 5, 6, 7]
    • 3 प्रतिकृतियों पर वितरण के साथ:
    • बैच 1:
      • प्रतिकृति 1: [0, 1]
      • प्रतिकृति 2: [2, 3]
      • प्रतिकृति 3: []
    • बैच 2:
      • प्रतिकृति 1: [4, 5]
      • प्रतिकृति 2: [6, 7]
      • प्रतिकृति 3: []

डेटासेट को रीबैच करने से स्पेस की जटिलता होती है जो प्रतिकृति की संख्या के साथ रैखिक रूप से बढ़ जाती है। इसका मतलब यह है कि मल्टी वर्कर ट्रेनिंग यूज़ केस के लिए इनपुट पाइपलाइन OOM त्रुटियों में चल सकती है।

साझा करना

tf.distribute MultiWorkerMirroredStrategy और TPUStrategy साथ मल्टी वर्कर प्रशिक्षण में इनपुट डेटासेट को tf.distribute भी TPUStrategy । प्रत्येक डाटासेट कार्यकर्ता के सीपीयू डिवाइस पर बनाया गया है। श्रमिकों के एक सेट पर एक डेटासेट को स्वत: tf.data.experimental.AutoShardPolicy का मतलब है कि प्रत्येक कार्यकर्ता को संपूर्ण डेटासेट (यदि सही tf.data.experimental.AutoShardPolicy सेट किया गया है) का एक सबसेट सौंपा गया है। यह सुनिश्चित करना है कि प्रत्येक चरण में, प्रत्येक कार्यकर्ता द्वारा गैर-अतिव्यापी डेटासेट तत्वों के एक वैश्विक बैच आकार को संसाधित किया जाएगा। ऑटोसहरिंग के पास कुछ अलग विकल्प हैं, जिन्हें tf.data.experimental.DistributeOptions का उपयोग करके निर्दिष्ट किया जा सकता है। ध्यान दें कि ParameterServerStrategy साथ मल्टी वर्कर प्रशिक्षण में कोई ऑटोसर्हिंग नहीं है, और इस रणनीति के साथ डेटासेट निर्माण पर अधिक जानकारी पैरामीटर सर्वर रणनीति ट्यूटोरियल में पाई जा सकती है।

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 लिए सेट कर सकते हैं:

  • AUTO: यह डिफ़ॉल्ट विकल्प है जिसका अर्थ है कि FILE द्वारा शार्प करने का प्रयास किया जाएगा। फ़ाइल-आधारित डेटासेट का पता नहीं चलने पर FILE द्वारा शार्द करने का प्रयास विफल हो जाता है। tf.distribute फिर DATA द्वारा tf.distribute करने के लिए वापस आ जाएगा। ध्यान दें कि यदि इनपुट डाटासेट फ़ाइल आधारित है, लेकिन फ़ाइलों की संख्या श्रमिकों की संख्या से कम है, तो एक InvalidArgumentError को उठाया जाएगा। यदि ऐसा होता है, तो स्पष्ट रूप से नीति को AutoShardPolicy.DATA सेट करें, या अपने इनपुट स्रोत को छोटी फ़ाइलों में विभाजित करें, जैसे कि फ़ाइलों की संख्या श्रमिकों की संख्या से अधिक है।
  • फ़ाइल: यह विकल्प है यदि आप सभी श्रमिकों पर इनपुट फ़ाइलों को शार्प करना चाहते हैं। आपको इस विकल्प का उपयोग करना चाहिए यदि इनपुट फ़ाइलों की संख्या श्रमिकों की संख्या से बहुत बड़ी है और फाइलों में डेटा समान रूप से वितरित किया गया है। यदि फ़ाइलों में डेटा समान रूप से वितरित नहीं किया गया है तो इस विकल्प के नकारात्मक पक्ष में निष्क्रिय श्रमिक होते हैं। यदि फ़ाइलों की संख्या श्रमिकों की संख्या से कम है, तो एक InvalidArgumentError को उठाया जाएगा। यदि ऐसा होता है, तो स्पष्ट रूप से पॉलिसी को AutoShardPolicy.DATA सेट करें। उदाहरण के लिए, आइए 1 प्रतिकृति के साथ 2 श्रमिकों पर 2 फाइलें वितरित करें। फ़ाइल 1 में [0, 1, 2, 3, 4, 5] और फ़ाइल 2 में [6, 7, 8, 9, 10, 11] सम्‍मिलित हैं। बता दें कि सिंक में प्रतिकृतियों की कुल संख्या 2 और वैश्विक बैच का आकार 4 होना चाहिए।

    • कार्यकर्ता 0:
    • बैच 1 = प्रतिकृति 1: [0, 1]
    • बैच 2 = प्रतिकृति 1: [2, 3]
    • बैच 3 = प्रतिकृति 1: [4]
    • बैच 4 = प्रतिकृति 1: [5]
    • कार्यकर्ता 1:
    • बैच 1 = प्रतिकृति 2: [6, 7]
    • बैच 2 = प्रतिकृति 2: [8, 9]
    • बैच 3 = प्रतिकृति 2: [10]
    • बैच 4 = प्रतिकृति 2: [11]
  • आंकड़े: यह सभी श्रमिकों के बीच तत्वों को स्वचालित करेगा। प्रत्येक कार्यकर्ता पूरे डेटासेट को पढ़ेगा और केवल उसे सौंपे गए हिस्से को प्रोसेस करेगा। अन्य सभी शार्दों को छोड़ दिया जाएगा। यह आमतौर पर उपयोग किया जाता है यदि इनपुट फ़ाइलों की संख्या श्रमिकों की संख्या से कम है और आप सभी श्रमिकों के डेटा को बेहतर बनाना चाहते हैं। नकारात्मक पक्ष यह है कि प्रत्येक कार्यकर्ता पर संपूर्ण डेटासेट पढ़ा जाएगा। उदाहरण के लिए, 2 श्रमिकों पर 1 फाइल वितरित करते हैं। फ़ाइल 1 में [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] है। सिंक में प्रतिकृतियों की कुल संख्या 2 होने दें।

    • कार्यकर्ता 0:
    • बैच 1 = प्रतिकृति 1: [0, 1]
    • बैच 2 = प्रतिकृति 1: [4, 5]
    • बैच 3 = प्रतिकृति 1: [8, 9]
    • कार्यकर्ता 1:
    • बैच 1 = प्रतिकृति 2: [2, 3]
    • बैच 2 = प्रतिकृति 2: [6, 7]
    • बैच 3 = प्रतिकृति 2: [10, 11]
  • उतर: यदि आप स्वतः सहेजना बंद करते हैं, तो प्रत्येक कार्यकर्ता सभी डेटा को संसाधित करेगा। उदाहरण के लिए, 2 कर्मचारियों पर 1 फाइल वितरित करते हैं। फ़ाइल 1 में [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] है। मान लें कि प्रतिकृतियों की कुल संख्या 2 है। तब प्रत्येक कार्यकर्ता को निम्न वितरण दिखाई देगा:

    • कार्यकर्ता 0:
    • बैच 1 = प्रतिकृति 1: [0, 1]
    • बैच 2 = प्रतिकृति 1: [2, 3]
    • बैच 3 = प्रतिकृति 1: [4, 5]
    • बैच 4 = प्रतिकृति 1: [6, 7]
    • बैच 5 = प्रतिकृति 1: [8, 9]
    • बैच 6 = प्रतिकृति 1: [10, 11]

    • कार्यकर्ता 1:

    • बैच 1 = प्रतिकृति 2: [0, 1]

    • बैच 2 = प्रतिकृति 2: [2, 3]

    • बैच 3 = प्रतिकृति 2: [4, 5]

    • बैच 4 = प्रतिकृति 2: [6, 7]

    • बैच 5 = प्रतिकृति 2: [8, 9]

    • बैच 6 = प्रतिकृति 2: [10, 11]

प्रीफेटिंग

डिफ़ॉल्ट रूप से, tf.distribute उपयोगकर्ता द्वारा प्रदान किए गएtf.data.Dataset उदाहरण के अंत मेंtf.data.Dataset परिवर्तन जोड़ता है। buffer_size का तर्क जो buffer_size है, सिंक में प्रतिकृतियों की संख्या के बराबर है।

tf.distribute.Strategy.distribute_datasets_from_function

उपयोग

यह API एक इनपुट फंक्शन लेता है और एक tf.distribute.DistributedDataset उदाहरण देता है। इनपुट फ़ंक्शन जो उपयोगकर्ता पास करते हैं, tf.distribute.InputContext तर्क है और उन्हेंtf.data.Dataset इंस्टेंस वापस करना चाहिए। इस API के साथ, tf.distribute उपयोगकर्ता केtf.data.Dataset उदाहरण में इनपुट फ़ंक्शन से वापस किए गए किसी और परिवर्तन को नहीं करता है। यह उपयोगकर्ता के डेटासेट को बैच और शार्प करने की जिम्मेदारी है। tf.distribute प्रत्येक वर्कर के CPU डिवाइस पर इनपुट फंक्शन को कॉल करता है। उपयोगकर्ताओं को अपने स्वयं के बैचिंग और तेज तर्क को निर्दिष्ट करने की अनुमति देने के अलावा, यह एपीआई मल्टी कार्यकर्ता प्रशिक्षण के लिए उपयोग किए जाने पर tf.distribute.Strategy.experimental_distribute_dataset की तुलना में बेहतर मापनीयता और प्रदर्शन को प्रदर्शित करता है।

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.distribute_datasets_from_function(dataset_fn)
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)

गुण

बैचने की क्रिया

tf.data.Dataset उदाहरण जो इनपुट फ़ंक्शन का रिटर्न मान है प्रति बैच बैच आकार का उपयोग करके बैच किया जाना चाहिए। प्रति प्रतिकृति बैच का आकार वैश्विक बैच आकार है जो प्रतिकृतियों की संख्या से विभाजित है जो सिंक प्रशिक्षण में भाग ले रहे हैं। ऐसा इसलिए है क्योंकि tf.distribute प्रत्येक वर्कर के CPU डिवाइस पर इनपुट फंक्शन को कॉल करता है। किसी कार्यकर्ता पर बनाया गया डेटासेट उस कार्यकर्ता के सभी प्रतिकृतियों द्वारा उपयोग करने के लिए तैयार होना चाहिए।

साझा करना

tf.distribute.InputContext ऑब्जेक्ट जो उपयोगकर्ता के इनपुट फ़ंक्शन के तर्क के रूप में निहित है, tf.distribute द्वारा हुड के अंतर्गत बनाया गया है। इसमें श्रमिकों की संख्या, वर्तमान कार्यकर्ता आईडी आदि के बारे में जानकारी है। यह इनपुट फ़ंक्शन उपयोगकर्ता द्वारा निर्धारित नीतियों के अनुसार इन संपत्तियों का उपयोग करके tf.distribute.InputContext को tf.distribute.InputContext जो tf.distribute.InputContext ऑब्जेक्ट का हिस्सा हैं।

प्रीफेटिंग

tf.distribute के अंत में एक प्रीफ़ेच परिवर्तन नहीं जोड़ता हैtf.data.Dataset उपयोगकर्ता प्रदान की इनपुट समारोह से लौट आए।

वितरित इटरेटर

गैर-वितरितtf.data.Dataset इंस्टेंसेस के समान, आपको tf.distribute.DistributedDataset पर एक tf.distribute.DistributedDataset बनाने की आवश्यकता होगी, उस पर पुनरावृति करने के लिए और तत्वों को एक्सेस करने की आवश्यकता tf.distribute.DistributedDataset । निम्नलिखित तरीके हैं जिनसे आप एक tf.distribute.DistributedIterator बना सकते हैं और इसका उपयोग अपने मॉडल को प्रशिक्षित करने के लिए कर सकते हैं:

Usages

लूप निर्माण के लिए पायथोनिक का उपयोग करें

आप अधिक पुनरावृति करने के लिए एक उपयोगकर्ता के अनुकूल pythonic पाश का उपयोग कर सकते tf.distribute.DistributedDataset । तत्व tf.distribute.DistributedIterator से लौटाए गए एक एकल tf.Tensor या एक tf.distribute.DistributedValues जिसमें प्रति मान का मान होता है। एक tf.function अंदर लूप रखने से एक प्रदर्शन को बढ़ावा मिलेगा। हालांकि, break और return वर्तमान में एक के ऊपर एक पाश के लिए समर्थित नहीं हैं tf.distribute.DistributedDataset है कि एक के अंदर रखा जाता है tf.function

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)

स्पष्ट iter बनाने के लिए iter का उपयोग करें

एक tf.distribute.DistributedDataset उदाहरण में तत्वों पर पुनरावृति करने के लिए, आप उस पर iter API का उपयोग करके एक tf.distribute.DistributedIterator बना सकते हैं। एक स्पष्ट पुनरावृत्ति के साथ, आप निश्चित संख्या में चरणों के लिए पुनरावृति कर सकते हैं। tf.distribute.DistributedIterator उदाहरण dist_iterator से अगला तत्व प्राप्त करने के लिए, आप next(dist_iterator) , dist_iterator.get_next() , या dist_iterator.get_next_as_optional() कॉल कर सकते हैं। पूर्व दो अनिवार्य रूप से समान हैं:

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)

next() या tf.distribute.DistributedIterator.get_next() , अगर tf.distribute.DistributedIterator अपने अंत तक पहुँच गया है, तो एक OutOfRange त्रुटि डाली जाएगी। ग्राहक अजगर की ओर से त्रुटि पकड़ सकता है और चेकपॉइंटिंग और मूल्यांकन जैसे अन्य काम करना जारी रख सकता है। हालाँकि, यह काम नहीं करेगा यदि आप एक होस्ट ट्रेनिंग लूप का उपयोग कर रहे हैं (यानी, प्रति चरण कई चरणों को tf.function ), जो tf.function दिखता है:

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

train_fn में चरण बॉडी को tf.range अंदर लपेटकर कई चरण tf.range । इस मामले में, बिना निर्भरता वाले लूप में अलग-अलग पुनरावृत्तियां समानांतर में शुरू हो सकती हैं, इसलिए पिछले पुनरावृत्तियों खत्म होने से पहले एक आउटऑफ़रेंज त्रुटि को बाद के पुनरावृत्तियों में ट्रिगर किया जा सकता है। एक बार एक OutOfRange त्रुटि फेंक दिए जाने के बाद, फ़ंक्शन के सभी ऑप्स तुरंत समाप्त हो जाएंगे। यदि यह कुछ ऐसा मामला है जिससे आप बचना चाहते हैं, तो एक विकल्प जो आउटऑफ़रेंज त्रुटि नहीं करता है वह है tf.distribute.DistributedIterator.get_next_as_optional()get_next_as_optional रिटर्न एक tf.experimental.Optional जो अगले तत्व या कोई मूल्य नहीं है, तो शामिल tf.distribute.DistributedIterator एक को समाप्त करने तक पहुँच गया है।

# 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 गुण का उपयोग करना

यदि आप एक के लिए एक वितरित डाटासेट के तत्वों पार कर लेते हैं tf.function और एक चाहते tf.TypeSpec गारंटी, आप निर्दिष्ट कर सकते input_signature का तर्क tf.function । एक वितरित डेटासेट का उत्पादन tf.distribute.DistributedValues जो एकल डिवाइस या कई उपकरणों के लिए इनपुट का प्रतिनिधित्व कर सकता है। इस वितरित मूल्य के अनुरूप tf.TypeSpec प्राप्त करने के लिए आप वितरित डेटासेट या वितरित element_spec की element_spec संपत्ति का उपयोग कर सकते हैं।

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]])

आंशिक बैच

आंशिक बैचों का सामना तब कियाtf.data.Dataset जब उपयोगकर्ता द्वाराtf.data.Dataset जाने वालेtf.data.Dataset उदाहरणों में बैच आकार हो सकते हैं जो समान रूप से प्रतिकृतियों की संख्या से विभाज्य नहीं होते हैं या जब बैच आकार द्वारा डेटासेट की आवृत्ति कार्डिनैलिटी विभाज्य नहीं होती है। इसका मतलब यह है कि जब डेटासेट को कई प्रतिकृतियों में वितरित किया जाता है, तो कुछ पुनरावृत्तियों पर next कॉल का परिणाम आउटऑफ़रेंजइरॉयर होगा। इस उपयोग के मामले को संभालने के लिए, tf.distribute प्रतिकृतियों पर बैच आकार 0 के डमी बैचों को लौटाता है जिनके पास प्रोसेस करने के लिए अधिक डेटा नहीं है।

एकल श्रमिक मामले के लिए, यदि डेटा को इट्रेटर पर next कॉल द्वारा वापस नहीं किया जाता है, तो डेटासेट में वास्तविक डेटा के साथ 0 बैच आकार के डमी बैच बनाए जाते हैं और उनका उपयोग किया जाता है। आंशिक बैचों के मामले में, डेटा के अंतिम वैश्विक बैच में डेटा के डमी बैचों के साथ वास्तविक डेटा होगा। संसाधन डेटा की रोक की स्थिति अब जांचती है कि किसी भी प्रतिकृतियां में डेटा है या नहीं। यदि प्रतिकृतियों में से किसी पर कोई डेटा नहीं है, तो एक OutOfRange त्रुटि डाली जाती है।

मल्टी वर्कर केस के लिए, प्रत्येक कार्यकर्ता पर डेटा की उपस्थिति का प्रतिनिधित्व करने वाले बूलियन मूल्य को क्रॉस प्रतिकृति संचार का उपयोग करके एकत्र किया जाता है और यह पहचानने के लिए उपयोग किया जाता है कि क्या सभी श्रमिकों ने वितरित डेटासेट को संसाधित करना समाप्त कर दिया है। चूंकि इसमें क्रॉस वर्कर कम्युनिकेशन शामिल है, इसलिए इसमें कुछ परफॉर्मेंस पेनल्टी शामिल है।

कैवियट

  • कई कार्यकर्ता सेटअप के साथ tf.distribute.Strategy.experimental_distribute_dataset API का उपयोग करते tf.distribute.Strategy.experimental_distribute_dataset , उपयोगकर्ता फ़ाइलों से पढ़ताtf.data.Dataset पास करते हैं। यदि tf.data.experimental.AutoShardPolicy को AUTO या FILE सेट किया जाता है, तो वास्तविक प्रति चरण बैच आकार उपयोगकर्ता द्वारा निर्धारित वैश्विक बैच आकार से छोटा हो सकता है। यह तब हो सकता है जब फ़ाइल में शेष तत्व वैश्विक बैच आकार से कम हो। उपयोगकर्ता या तो चला सकते हैं या सेट करने के लिए कदम की संख्या के आधार के बिना डाटासेट निकास कर सकते हैं tf.data.experimental.AutoShardPolicy के DATA इसके चारों ओर काम करने के लिए।

  • स्टेटफुल डेटासेट ट्रांसफॉर्मेशन वर्तमान में tf.distribute और किसी भी स्टेटफुल ऑप्स के साथ समर्थित नहीं है, जो कि वर्तमान में डेटासेट की अनदेखी हो सकती है। उदाहरण के लिए, यदि आपके डेटासेट में कोई map_fn जो एक छवि को घुमाने के लिए tf.random.uniform का उपयोग करता है, तो आपके पास एक डाटासेट ग्राफ़ है जो स्थानीय मशीन पर राज्य (यानी यादृच्छिक बीज) पर निर्भर करता है जहां अजगर प्रक्रिया को बंद किया जा रहा है।

  • प्रायोगिक tf.data.experimental.OptimizationOptions जो डिफ़ॉल्ट रूप से कुछ संदर्भों में अक्षम हो सकते हैं - जैसे कि जब tf.distribute साथ एक साथ उपयोग किया जाता है - प्रदर्शन में गिरावट का कारण बनता है। आपको यह सत्यापित करने के बाद ही उन्हें सक्षम करना चाहिए कि वे वितरण सेटिंग में आपके कार्यभार के प्रदर्शन को लाभान्वित करते हैं।

  • कृपया सामान्य रूप से tf.data साथ अपने इनपुट पाइपलाइन का अनुकूलन कैसे करें, इस गाइड का संदर्भ लें। कुछ अतिरिक्त सुझाव:

    • यदि आपके पास कई श्रमिक हैं और tf.data.Dataset.list_files का उपयोग एक या अधिक ग्लोब पैटर्न से मेल खाने वाली सभी फ़ाइलों से डेटासेट बनाने के लिए करते हैं, तो seed तर्क सेट करना या shuffle=False सेट करना याद रखें ताकि प्रत्येक कार्यकर्ता लगातार फ़ाइल को शार्प करे।

    • यदि आपके इनपुट पाइपलाइन में रिकॉर्ड स्तर पर डेटा को फेरबदल करना और डेटा को पार्स करना दोनों शामिल हैं, जब तक कि अनारक्षित डेटा पार्स किए गए डेटा (जो आमतौर पर मामला नहीं है) की तुलना में काफी बड़ा है, पहले फेरबदल करें और फिर पार्स करें, जैसा कि निम्नलिखित उदाहरण में दिखाया गया है। इससे मेमोरी उपयोग और प्रदर्शन को लाभ मिल सकता है।

d = tf.data.Dataset.list_files(pattern, shuffle=False)
d = d.shard(num_workers, worker_index)
d = d.repeat(num_epochs)
d = d.shuffle(shuffle_buffer_size)
d = d.interleave(tf.data.TFRecordDataset,
                 cycle_length=num_readers, block_length=1)
d = d.map(parser_fn, num_parallel_calls=num_map_threads)
  • tf.data.Dataset.shuffle(buffer_size, seed=None, reshuffle_each_iteration=None) buffer_size तत्वों के एक आंतरिक बफर को बनाए रखता है, और इस प्रकार buffer_size को कम करके buffer_size समस्या जारी कर सकता है।

  • वह क्रम जिसमें tf.distribute.experimental_distribute_dataset या tf.distribute.distribute_datasets_from_function का उपयोग करने पर श्रमिकों द्वारा डेटा संसाधित किया जाता है, इसकी गारंटी नहीं है। यह आम तौर पर आवश्यक है यदि आप पैमाने पर भविष्यवाणी के लिए tf.distribute का उपयोग कर रहे हैं। हालाँकि आप बैच में प्रत्येक तत्व के लिए एक इंडेक्स सम्मिलित कर सकते हैं और तदनुसार आउटपुट दे सकते हैं। निम्नलिखित स्निपेट आउटपुट को ऑर्डर करने के तरीके का एक उदाहरण है।

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 `run` 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 `run` 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 `run` 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 `run` 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}

यदि मैं विहित tf.data.Dataset उदाहरण का उपयोग नहीं कर रहा हूं तो मैं अपना डेटा कैसे वितरित करूं?

कभी-कभी उपयोगकर्ता अपने इनपुट का प्रतिनिधित्व करने के लिए एकtf.data.Dataset का उपयोग नहीं कर सकते हैं और बाद में उपर्युक्त एपीआई को कई उपकरणों को डेटासेट वितरित करने के लिए। ऐसे मामलों में आप एक जनरेटर से कच्चे टेनर्स या इनपुट का उपयोग कर सकते हैं।

मनमाना टेंसर इनपुट के लिए प्रयोगात्मक_distribute_values_from_function का उपयोग करें

strategy.run tf.distribute.DistributedValues स्वीकार करता है जो कि next(iterator) tf.distribute.DistributedValues ) का आउटपुट है। tf.distribute.DistributedValues मानों को पास करने के लिए, tf.distribute.DistributedValues को कच्चे tf.distribute.DistributedValues से बनाने के लिए experimental_distribute_values_from_function tf.distribute.DistributedValues उपयोग करें।

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 `run` 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)

यदि आपका इनपुट जनरेटर से है तो tf.data.Dataset.from_generator का उपयोग करें

यदि आपके पास एक जनरेटर फ़ंक्शन है जिसे आप उपयोग करना चाहते हैं, तो आप from_generator API का उपयोग करके एकtf.data.Dataset उदाहरण बना सकते हैं।

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',)