Pelatihan terdistribusi dengan TensorFlow

Lihat di TensorFlow.org Jalankan di Google Colab Lihat sumber di GitHub Unduh buku catatan

Ringkasan

tf.distribute.Strategy adalah TensorFlow API untuk mendistribusikan pelatihan di beberapa GPU, beberapa mesin, atau TPU. Dengan menggunakan API ini, Anda dapat mendistribusikan model dan kode pelatihan yang ada dengan sedikit perubahan kode.

tf.distribute.Strategy telah dirancang dengan tujuan utama berikut ini:

  • Mudah digunakan dan mendukung banyak segmen pengguna, termasuk peneliti, insinyur pembelajaran mesin, dll.
  • Memberikan kinerja yang baik di luar kotak.
  • Mudah beralih antara strategi.

Anda dapat mendistribusikan pelatihan menggunakan tf.distribute.Strategy dengan API tingkat tinggi seperti Keras Model.fit , serta loop pelatihan khusus (dan, secara umum, komputasi apa pun menggunakan TensorFlow).

Di TensorFlow 2.x, Anda dapat menjalankan program dengan penuh semangat, atau dalam grafik menggunakan tf.function . tf.distribute.Strategy bermaksud untuk mendukung kedua mode eksekusi ini, tetapi bekerja paling baik dengan tf.function . Mode Eager hanya disarankan untuk keperluan debugging dan tidak didukung untuk tf.distribute.TPUStrategy . Meskipun pelatihan adalah fokus dari panduan ini, API ini juga dapat digunakan untuk mendistribusikan evaluasi dan prediksi pada platform yang berbeda.

Anda dapat menggunakan tf.distribute.Strategy dengan sedikit perubahan pada kode Anda, karena komponen dasar TensorFlow telah diubah menjadi sadar akan strategi. Ini termasuk variabel, lapisan, model, pengoptimal, metrik, ringkasan, dan pos pemeriksaan.

Dalam panduan ini, Anda akan belajar tentang berbagai jenis strategi dan bagaimana Anda dapat menggunakannya dalam situasi yang berbeda. Untuk mempelajari cara men-debug masalah performa, lihat panduan performa GPU Optimize TensorFlow .

Siapkan TensorFlow

import tensorflow as tf

Jenis strategi

tf.distribute.Strategy bermaksud untuk mencakup sejumlah kasus penggunaan di sepanjang sumbu yang berbeda. Beberapa kombinasi ini saat ini didukung dan lainnya akan ditambahkan di masa mendatang. Beberapa sumbu tersebut adalah:

  • Pelatihan sinkron vs asinkron: Ini adalah dua cara umum untuk mendistribusikan pelatihan dengan paralelisme data. Dalam pelatihan sinkronisasi, semua pekerja berlatih melalui irisan data input yang berbeda secara sinkron, dan menggabungkan gradien pada setiap langkah. Dalam pelatihan asinkron, semua pekerja secara independen melatih data input dan memperbarui variabel secara asinkron. Biasanya pelatihan sinkronisasi didukung melalui all-reduce dan async melalui arsitektur server parameter.
  • Platform perangkat keras: Anda mungkin ingin menskalakan pelatihan Anda ke beberapa GPU pada satu mesin, atau beberapa mesin dalam jaringan (masing-masing dengan 0 atau lebih GPU), atau di Cloud TPU.

Untuk mendukung kasus penggunaan ini, TensorFlow memiliki MirroredStrategy , TPUStrategy , MultiWorkerMirroredStrategy , ParameterServerStrategy , CentralStorageStrategy , serta strategi lain yang tersedia. Bagian berikutnya menjelaskan mana yang didukung dalam skenario mana di TensorFlow. Berikut ini gambaran singkatnya:

Pelatihan API MirroredStrategy TPUStrategy MultiWorkerMirroredStrategy CentralStorageStrategy ParameterServerStrategy
Keras Model.fit Didukung Didukung Didukung Dukungan eksperimental Dukungan eksperimental
Lingkaran pelatihan khusus Didukung Didukung Didukung Dukungan eksperimental Dukungan eksperimental
API Penaksir Dukungan Terbatas Tidak didukung Dukungan Terbatas Dukungan Terbatas Dukungan Terbatas

Strategi Tercermin

tf.distribute.MirroredStrategy mendukung pelatihan terdistribusi sinkron pada beberapa GPU pada satu mesin. Itu membuat satu replika per perangkat GPU. Setiap variabel dalam model dicerminkan di semua replika. Bersama-sama, variabel-variabel ini membentuk variabel konseptual tunggal yang disebut MirroredVariable . Variabel-variabel ini tetap sinkron satu sama lain dengan menerapkan pembaruan yang identik.

Algoritme pengurangan semua yang efisien digunakan untuk mengomunikasikan pembaruan variabel di seluruh perangkat. All-reduce agregat tensor di semua perangkat dengan menambahkannya, dan membuatnya tersedia di setiap perangkat. Ini adalah algoritma fusi yang sangat efisien dan dapat mengurangi overhead sinkronisasi secara signifikan. Ada banyak algoritma dan implementasi all-reduce yang tersedia, tergantung pada jenis komunikasi yang tersedia antar perangkat. Secara default, ia menggunakan NVIDIA Collective Communication Library ( NCCL ) sebagai implementasi all-reduce. Anda dapat memilih dari beberapa opsi lain atau menulis sendiri.

Berikut adalah cara paling sederhana untuk membuat MirroredStrategy :

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

Ini akan membuat instance MirroredStrategy , yang akan menggunakan semua GPU yang terlihat oleh TensorFlow, dan NCCL—sebagai komunikasi lintas-perangkat.

Jika Anda hanya ingin menggunakan beberapa GPU di mesin Anda, Anda dapat melakukannya seperti ini:

mirrored_strategy = tf.distribute.MirroredStrategy(devices=["/gpu:0", "/gpu:1"])
WARNING:tensorflow:Some requested devices in `tf.distribute.Strategy` are not visible to TensorFlow: /job:localhost/replica:0/task:0/device:GPU:1,/job:localhost/replica:0/task:0/device:GPU:0
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0', '/job:localhost/replica:0/task:0/device:GPU:1')

Jika Anda ingin mengesampingkan komunikasi lintas perangkat, Anda dapat melakukannya menggunakan argumen cross_device_ops dengan menyediakan instance tf.distribute.CrossDeviceOps . Saat ini, tf.distribute.HierarchicalCopyAllReduce dan tf.distribute.ReductionToOneDevice adalah dua opsi selain tf.distribute.NcclAllReduce , yang merupakan default.

mirrored_strategy = tf.distribute.MirroredStrategy(
    cross_device_ops=tf.distribute.HierarchicalCopyAllReduce())
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)

strategi TPUS

tf.distribute.TPUStrategy memungkinkan Anda menjalankan pelatihan TensorFlow di Tensor Processing Unit (TPU) . TPU adalah ASIC khusus Google yang dirancang untuk mempercepat beban kerja machine learning secara dramatis. Mereka tersedia di Google Colab , TPU Research Cloud , dan Cloud TPU .

Dalam hal arsitektur pelatihan terdistribusi, TPUStrategy adalah MirroredStrategy yang sama —mengimplementasikan pelatihan terdistribusi sinkron. TPU menyediakan implementasi mereka sendiri untuk semua pengurangan yang efisien dan operasi kolektif lainnya di beberapa inti TPU, yang digunakan dalam TPUStrategy .

Inilah cara Anda membuat instance TPUStrategy :

cluster_resolver = tf.distribute.cluster_resolver.TPUClusterResolver(
    tpu=tpu_address)
tf.config.experimental_connect_to_cluster(cluster_resolver)
tf.tpu.experimental.initialize_tpu_system(cluster_resolver)
tpu_strategy = tf.distribute.TPUStrategy(cluster_resolver)

TPUClusterResolver membantu menemukan TPU. Di Colab, Anda tidak perlu menentukan argumen apa pun untuk itu.

Jika Anda ingin menggunakan ini untuk Cloud TPU:

  • Anda harus menentukan nama sumber daya TPU Anda dalam argumen tpu .
  • Anda harus menginisialisasi sistem TPU secara eksplisit di awal program. Ini diperlukan sebelum TPU dapat digunakan untuk komputasi. Inisialisasi sistem TPU juga menghapus memori TPU, jadi penting untuk menyelesaikan langkah ini terlebih dahulu untuk menghindari kehilangan status.

MultiWorkerMirroredStrategy

tf.distribute.MultiWorkerMirroredStrategy sangat mirip dengan MirroredStrategy . Ini mengimplementasikan pelatihan terdistribusi sinkron di beberapa pekerja, masing-masing dengan potensi beberapa GPU. Mirip dengan tf.distribute.MirroredStrategy , ini membuat salinan semua variabel dalam model di setiap perangkat di semua pekerja.

Berikut adalah cara paling sederhana untuk membuat MultiWorkerMirroredStrategy :

strategy = tf.distribute.MultiWorkerMirroredStrategy()
WARNING:tensorflow:Collective ops is not configured at program startup. Some performance features may not be enabled.
INFO:tensorflow:Single-worker MultiWorkerMirroredStrategy with local_devices = ('/device:GPU:0',), communication = CommunicationImplementation.AUTO

MultiWorkerMirroredStrategy memiliki dua implementasi untuk komunikasi lintas perangkat. CommunicationImplementation.RING berbasis RPC dan mendukung CPU dan GPU. CommunicationImplementation.NCCL menggunakan NCCL dan memberikan kinerja mutakhir pada GPU tetapi tidak mendukung CPU. CollectiveCommunication.AUTO menunda pilihan ke Tensorflow. Anda dapat menentukannya dengan cara berikut:

communication_options = tf.distribute.experimental.CommunicationOptions(
    implementation=tf.distribute.experimental.CommunicationImplementation.NCCL)
strategy = tf.distribute.MultiWorkerMirroredStrategy(
    communication_options=communication_options)
WARNING:tensorflow:Collective ops is not configured at program startup. Some performance features may not be enabled.
INFO:tensorflow:Single-worker MultiWorkerMirroredStrategy with local_devices = ('/device:GPU:0',), communication = CommunicationImplementation.NCCL

Salah satu perbedaan utama untuk menjalankan pelatihan multi-pekerja, dibandingkan dengan pelatihan multi-GPU, adalah pengaturan multi-pekerja. Variabel lingkungan 'TF_CONFIG' adalah cara standar di TensorFlow untuk menentukan konfigurasi cluster untuk setiap pekerja yang merupakan bagian dari cluster. Pelajari lebih lanjut di bagian penyiapan TF_CONFIG pada dokumen ini.

Untuk lebih jelasnya tentang MultiWorkerMirroredStrategy , simak tutorial berikut ini:

ParameterServerStrategy

Pelatihan server parameter adalah metode paralel data umum untuk meningkatkan pelatihan model pada beberapa mesin. Sebuah cluster pelatihan server parameter terdiri dari pekerja dan server parameter. Variabel dibuat di server parameter dan dibaca serta diperbarui oleh pekerja di setiap langkah. Lihat tutorial pelatihan server Parameter untuk detailnya.

Di TensorFlow 2, pelatihan server parameter menggunakan arsitektur berbasis koordinator pusat melalui kelas tf.distribute.experimental.coordinator.ClusterCoordinator .

Dalam implementasi ini, tugas worker dan parameter server menjalankan tf.distribute.Server s yang mendengarkan tugas dari koordinator. Koordinator menciptakan sumber daya, mengirimkan tugas pelatihan, menulis pos pemeriksaan, dan menangani kegagalan tugas.

Dalam pemrograman yang berjalan pada koordinator, Anda akan menggunakan objek ParameterServerStrategy untuk menentukan langkah pelatihan dan menggunakan ClusterCoordinator untuk mengirimkan langkah pelatihan ke pekerja jarak jauh. Berikut adalah cara paling sederhana untuk membuatnya:

strategy = tf.distribute.experimental.ParameterServerStrategy(
    tf.distribute.cluster_resolver.TFConfigClusterResolver(),
    variable_partitioner=variable_partitioner)
coordinator = tf.distribute.experimental.coordinator.ClusterCoordinator(
    strategy)

Untuk mempelajari lebih lanjut tentang ParameterServerStrategy , lihat pelatihan Server Parameter dengan Keras Model.fit dan tutorial loop pelatihan khusus .

Di TensorFlow 1, ParameterServerStrategy hanya tersedia dengan Estimator melalui simbol tf.compat.v1.distribute.experimental.ParameterServerStrategy .

Strategi Penyimpanan Pusat

tf.distribute.experimental.CentralStorageStrategy juga melakukan pelatihan sinkron. Variabel tidak dicerminkan, melainkan ditempatkan pada CPU dan operasi direplikasi di semua GPU lokal. Jika hanya ada satu GPU, semua variabel dan operasi akan ditempatkan pada GPU tersebut.

Buat instance CentralStorageStrategy dengan:

central_storage_strategy = tf.distribute.experimental.CentralStorageStrategy()
INFO:tensorflow:ParameterServerStrategy (CentralStorageStrategy if you are using a single machine) with compute_devices = ['/job:localhost/replica:0/task:0/device:GPU:0'], variable_device = '/job:localhost/replica:0/task:0/device:GPU:0'

Ini akan membuat instance CentralStorageStrategy yang akan menggunakan semua GPU dan CPU yang terlihat. Pembaruan ke variabel pada replika akan digabungkan sebelum diterapkan ke variabel.

Strategi lainnya

Selain strategi di atas, ada dua strategi lain yang mungkin berguna untuk membuat prototipe dan debugging saat menggunakan tf.distribute API.

Strategi Default

Strategi Default adalah strategi distribusi yang hadir ketika tidak ada strategi distribusi eksplisit dalam ruang lingkup. Ini mengimplementasikan antarmuka tf.distribute.Strategy tetapi merupakan pass-through dan tidak menyediakan distribusi aktual. Misalnya, Strategy.run(fn) hanya akan memanggil fn . Kode yang ditulis menggunakan strategi ini harus berperilaku persis seperti kode yang ditulis tanpa strategi apa pun. Anda dapat menganggapnya sebagai strategi "tanpa operasi".

Strategi Default adalah singleton—dan seseorang tidak dapat membuat lebih banyak contoh. Itu dapat diperoleh dengan menggunakan tf.distribute.get_strategy di luar cakupan strategi eksplisit apa pun (API yang sama yang dapat digunakan untuk mendapatkan strategi saat ini di dalam cakupan strategi eksplisit).

default_strategy = tf.distribute.get_strategy()

Strategi ini memiliki dua tujuan utama:

  • Ini memungkinkan penulisan kode perpustakaan yang sadar distribusi tanpa syarat. Misalnya, di tf.optimizer s Anda dapat menggunakan tf.distribute.get_strategy dan menggunakan strategi itu untuk mengurangi gradien—itu akan selalu mengembalikan objek strategi yang dapat Anda panggil Strategy.reduce API.
# In optimizer or other library code
# Get currently active strategy
strategy = tf.distribute.get_strategy()
strategy.reduce("SUM", 1., axis=None)  # reduce some values
1.0
  • Mirip dengan kode perpustakaan, dapat digunakan untuk menulis program pengguna akhir untuk bekerja dengan dan tanpa strategi distribusi, tanpa memerlukan logika kondisional. Berikut adalah contoh cuplikan kode yang menggambarkan hal ini:
if tf.config.list_physical_devices('GPU'):
  strategy = tf.distribute.MirroredStrategy()
else:  # Use the Default Strategy
  strategy = tf.distribute.get_strategy()

with strategy.scope():
  # Do something interesting
  print(tf.Variable(1.))
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)
MirroredVariable:{
  0: <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=1.0>
}

Strategi SatuPerangkat

tf.distribute.OneDeviceStrategy adalah strategi untuk menempatkan semua variabel dan komputasi pada satu perangkat tertentu.

strategy = tf.distribute.OneDeviceStrategy(device="/gpu:0")

Strategi ini berbeda dari Strategi Default dalam beberapa hal. Dalam Strategi Default, logika penempatan variabel tetap tidak berubah jika dibandingkan dengan menjalankan TensorFlow tanpa strategi distribusi apa pun. Tetapi saat menggunakan OneDeviceStrategy , semua variabel yang dibuat dalam cakupannya secara eksplisit ditempatkan pada perangkat yang ditentukan. Selain itu, setiap fungsi yang dipanggil melalui OneDeviceStrategy.run juga akan ditempatkan pada perangkat yang ditentukan.

Input yang didistribusikan melalui strategi ini akan diambil terlebih dahulu ke perangkat yang ditentukan. Dalam Strategi Default, tidak ada distribusi input.

Mirip dengan Strategi Default, strategi ini juga dapat digunakan untuk menguji kode Anda sebelum beralih ke strategi lain yang benar-benar didistribusikan ke beberapa perangkat/mesin. Ini akan menggunakan mesin strategi distribusi lebih dari Strategi Default, tetapi tidak sepenuhnya menggunakan, misalnya, MirroredStrategy atau TPUStrategy . Jika Anda menginginkan kode yang berperilaku seolah-olah tidak ada strategi, maka gunakan Strategi Default.

Sejauh ini Anda telah belajar tentang berbagai strategi dan bagaimana Anda dapat membuat instance mereka. Beberapa bagian berikutnya menunjukkan berbagai cara Anda dapat menggunakannya untuk mendistribusikan pelatihan Anda.

Gunakan tf.distribute.Strategy dengan Keras Model.fit

tf.distribute.Strategy terintegrasi ke dalam tf.keras , yang merupakan implementasi TensorFlow dari spesifikasi Keras API . tf.keras adalah API tingkat tinggi untuk membangun dan melatih model. Dengan mengintegrasikan ke dalam backend tf.keras , Anda dapat dengan mudah mendistribusikan pelatihan yang ditulis dalam kerangka kerja pelatihan Keras menggunakan Model.fit .

Inilah yang perlu Anda ubah dalam kode Anda:

  1. Buat instance dari tf.distribute.Strategy yang sesuai.
  2. Pindahkan pembuatan model Keras, pengoptimal, dan metrik di dalam strategy.scope .

Strategi distribusi TensorFlow mendukung semua jenis model Keras— Sequential , Functional , dan subclassed .

Berikut adalah potongan kode untuk melakukan ini untuk model Keras yang sangat sederhana dengan satu lapisan Dense :

mirrored_strategy = tf.distribute.MirroredStrategy()

with mirrored_strategy.scope():
  model = tf.keras.Sequential([tf.keras.layers.Dense(1, input_shape=(1,))])

model.compile(loss='mse', optimizer='sgd')
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

Contoh ini menggunakan MirroredStrategy , sehingga Anda dapat menjalankannya di mesin dengan banyak GPU. strategy.scope() menunjukkan kepada Keras strategi mana yang digunakan untuk mendistribusikan pelatihan. Membuat model/pengoptimal/metrik di dalam cakupan ini memungkinkan Anda membuat variabel terdistribusi, bukan variabel biasa. Setelah ini diatur, Anda dapat menyesuaikan model Anda seperti biasanya. MirroredStrategy menangani replikasi pelatihan model pada GPU yang tersedia, menggabungkan gradien, dan banyak lagi.

dataset = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100).batch(10)
model.fit(dataset, epochs=2)
model.evaluate(dataset)
Epoch 1/2
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
2021-10-26 01:27:56.527729: W tensorflow/core/grappler/optimizers/data/auto_shard.cc:695] AUTO sharding policy will apply DATA sharding policy as it failed to apply FILE sharding policy because of the following reason: Found an unshardable source dataset: name: "TensorDataset/_2"
op: "TensorDataset"
input: "Placeholder/_0"
input: "Placeholder/_1"
attr {
  key: "Toutput_types"
  value {
    list {
      type: DT_FLOAT
      type: DT_FLOAT
    }
  }
}
attr {
  key: "output_shapes"
  value {
    list {
      shape {
        dim {
          size: 1
        }
      }
      shape {
        dim {
          size: 1
        }
      }
    }
  }
}
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
10/10 [==============================] - 3s 2ms/step - loss: 2.2552
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
Epoch 2/2
10/10 [==============================] - 0s 2ms/step - loss: 0.9968
2021-10-26 01:27:59.372113: W tensorflow/core/grappler/optimizers/data/auto_shard.cc:695] AUTO sharding policy will apply DATA sharding policy as it failed to apply FILE sharding policy because of the following reason: Found an unshardable source dataset: name: "TensorDataset/_2"
op: "TensorDataset"
input: "Placeholder/_0"
input: "Placeholder/_1"
attr {
  key: "Toutput_types"
  value {
    list {
      type: DT_FLOAT
      type: DT_FLOAT
    }
  }
}
attr {
  key: "output_shapes"
  value {
    list {
      shape {
        dim {
          size: 1
        }
      }
      shape {
        dim {
          size: 1
        }
      }
    }
  }
}
10/10 [==============================] - 1s 2ms/step - loss: 0.6190
0.6190494298934937

Di sini tf.data.Dataset menyediakan input pelatihan dan evaluasi. Anda juga dapat menggunakan array NumPy:

import numpy as np

inputs, targets = np.ones((100, 1)), np.ones((100, 1))
model.fit(inputs, targets, epochs=2, batch_size=10)
Epoch 1/2
2021-10-26 01:28:00.609977: W tensorflow/core/grappler/optimizers/data/auto_shard.cc:695] AUTO sharding policy will apply DATA sharding policy as it failed to apply FILE sharding policy because of the following reason: Did not find a shardable source, walked to a node which is not a dataset: name: "FlatMapDataset/_9"
op: "FlatMapDataset"
input: "PrefetchDataset/_8"
attr {
  key: "Targuments"
  value {
    list {
    }
  }
}
attr {
  key: "f"
  value {
    func {
      name: "__inference_Dataset_flat_map_slice_batch_indices_997"
    }
  }
}
attr {
  key: "output_shapes"
  value {
    list {
      shape {
        dim {
          size: 10
        }
      }
    }
  }
}
attr {
  key: "output_types"
  value {
    list {
      type: DT_INT64
    }
  }
}
. Consider either turning off auto-sharding or switching the auto_shard_policy to DATA to shard this dataset. You can do this by creating a new `tf.data.Options()` object then setting `options.experimental_distribute.auto_shard_policy = AutoShardPolicy.DATA` before applying the options object to the dataset via `dataset.with_options(options)`.
10/10 [==============================] - 1s 2ms/step - loss: 0.4406
Epoch 2/2
10/10 [==============================] - 0s 2ms/step - loss: 0.1947
<keras.callbacks.History at 0x7fb81813d2d0>

Dalam kedua kasus—dengan Dataset atau NumPy—setiap batch input yang diberikan dibagi rata di antara beberapa replika. Misalnya, jika Anda menggunakan MirroredStrategy dengan 2 GPU, setiap batch ukuran 10 akan dibagi di antara 2 GPU, dengan masing-masing menerima 5 contoh input di setiap langkah. Setiap zaman kemudian akan berlatih lebih cepat saat Anda menambahkan lebih banyak GPU. Biasanya, Anda ingin meningkatkan ukuran batch saat Anda menambahkan lebih banyak akselerator, untuk memanfaatkan daya komputasi ekstra secara efektif. Anda juga perlu menyetel ulang kecepatan belajar Anda, tergantung pada modelnya. Anda dapat menggunakan strategy.num_replicas_in_sync untuk mendapatkan jumlah replika.

# Compute a global batch size using a number of replicas.
BATCH_SIZE_PER_REPLICA = 5
global_batch_size = (BATCH_SIZE_PER_REPLICA *
                     mirrored_strategy.num_replicas_in_sync)
dataset = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100)
dataset = dataset.batch(global_batch_size)

LEARNING_RATES_BY_BATCH_SIZE = {5: 0.1, 10: 0.15}
learning_rate = LEARNING_RATES_BY_BATCH_SIZE[global_batch_size]

Apa yang didukung sekarang?

Pelatihan API MirroredStrategy TPUStrategy MultiWorkerMirroredStrategy ParameterServerStrategy CentralStorageStrategy
Keras Model.fit Didukung Didukung Didukung Dukungan eksperimental Dukungan eksperimental

Contoh dan tutorial

Berikut adalah daftar tutorial dan contoh yang menggambarkan integrasi di atas secara end-to-end dengan Keras Model.fit :

  1. Tutorial : Pelatihan dengan Model.fit dan MirroredStrategy .
  2. Tutorial : Pelatihan dengan Model.fit dan MultiWorkerMirroredStrategy .
  3. Panduan : Berisi contoh penggunaan Model.fit dan TPUStrategy .
  4. Tutorial : Pelatihan parameter server dengan Model.fit dan ParameterServerStrategy .
  5. Tutorial : Menyesuaikan BERT untuk banyak tugas dari benchmark GLUE dengan Model.fit dan TPUStrategy .
  6. Repositori TensorFlow Model Garden berisi koleksi model tercanggih yang diimplementasikan menggunakan berbagai strategi.

Gunakan tf.distribute.Strategy dengan loop pelatihan khusus

Seperti yang ditunjukkan di atas, menggunakan tf.distribute.Strategy dengan Keras Model.fit hanya perlu mengubah beberapa baris kode Anda. Dengan sedikit usaha, Anda juga dapat menggunakan tf.distribute.Strategy dengan loop pelatihan khusus .

Jika Anda membutuhkan lebih banyak fleksibilitas dan kontrol atas loop pelatihan Anda daripada yang mungkin dilakukan dengan Estimator atau Keras, Anda dapat menulis loop pelatihan khusus. Misalnya, saat menggunakan GAN, Anda mungkin ingin mengambil jumlah langkah generator atau diskriminator yang berbeda setiap putaran. Demikian pula, kerangka kerja tingkat tinggi tidak terlalu cocok untuk pelatihan Pembelajaran Penguatan.

Kelas tf.distribute.Strategy menyediakan kumpulan metode inti untuk mendukung loop pelatihan kustom. Menggunakan ini mungkin memerlukan sedikit restrukturisasi kode pada awalnya, tetapi setelah selesai, Anda harus dapat beralih di antara GPU, TPU, dan beberapa mesin hanya dengan mengubah instans strategi.

Di bawah ini adalah cuplikan singkat yang mengilustrasikan kasus penggunaan ini untuk contoh pelatihan sederhana menggunakan model Keras yang sama seperti sebelumnya.

Pertama, buat model dan pengoptimal di dalam cakupan strategi. Ini memastikan bahwa setiap variabel yang dibuat dengan model dan pengoptimal adalah variabel yang dicerminkan.

with mirrored_strategy.scope():
  model = tf.keras.Sequential([tf.keras.layers.Dense(1, input_shape=(1,))])
  optimizer = tf.keras.optimizers.SGD()

Selanjutnya, buat dataset input dan panggil tf.distribute.Strategy.experimental_distribute_dataset untuk mendistribusikan dataset berdasarkan strategi.

dataset = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100).batch(
    global_batch_size)
dist_dataset = mirrored_strategy.experimental_distribute_dataset(dataset)
2021-10-26 01:28:01.831942: W tensorflow/core/grappler/optimizers/data/auto_shard.cc:695] AUTO sharding policy will apply DATA sharding policy as it failed to apply FILE sharding policy because of the following reason: Found an unshardable source dataset: name: "TensorDataset/_2"
op: "TensorDataset"
input: "Placeholder/_0"
input: "Placeholder/_1"
attr {
  key: "Toutput_types"
  value {
    list {
      type: DT_FLOAT
      type: DT_FLOAT
    }
  }
}
attr {
  key: "output_shapes"
  value {
    list {
      shape {
        dim {
          size: 1
        }
      }
      shape {
        dim {
          size: 1
        }
      }
    }
  }
}

Kemudian, tentukan satu langkah pelatihan. Gunakan tf.GradientTape untuk menghitung gradien dan pengoptimal untuk menerapkan gradien tersebut guna memperbarui variabel model Anda. Untuk mendistribusikan langkah pelatihan ini, masukkan ke dalam fungsi train_step dan berikan ke tf.distribute.Strategy.run bersama dengan input dataset yang Anda dapatkan dari dist_dataset yang dibuat sebelumnya:

loss_object = tf.keras.losses.BinaryCrossentropy(
  from_logits=True,
  reduction=tf.keras.losses.Reduction.NONE)

def compute_loss(labels, predictions):
  per_example_loss = loss_object(labels, predictions)
  return tf.nn.compute_average_loss(per_example_loss, global_batch_size=global_batch_size)

def train_step(inputs):
  features, labels = inputs

  with tf.GradientTape() as tape:
    predictions = model(features, training=True)
    loss = compute_loss(labels, predictions)

  gradients = tape.gradient(loss, model.trainable_variables)
  optimizer.apply_gradients(zip(gradients, model.trainable_variables))
  return loss

@tf.function
def distributed_train_step(dist_inputs):
  per_replica_losses = mirrored_strategy.run(train_step, args=(dist_inputs,))
  return mirrored_strategy.reduce(tf.distribute.ReduceOp.SUM, per_replica_losses,
                         axis=None)

Beberapa hal lain yang perlu diperhatikan dalam kode di atas:

  1. Anda menggunakan tf.nn.compute_average_loss untuk menghitung kerugian. tf.nn.compute_average_loss menjumlahkan kerugian per contoh dan membagi jumlahnya dengan global_batch_size . Ini penting karena nanti setelah gradien dihitung pada setiap replika, gradien dikumpulkan di seluruh replika dengan menjumlahkannya .
  2. Anda juga menggunakan tf.distribute.Strategy.reduce API untuk menggabungkan hasil yang dikembalikan oleh tf.distribute.Strategy.run . tf.distribute.Strategy.run mengembalikan hasil dari setiap replika lokal dalam strategi, dan ada beberapa cara untuk menggunakan hasil ini. Anda dapat reduce untuk mendapatkan nilai agregat. Anda juga dapat melakukan tf.distribute.Strategy.experimental_local_results untuk mendapatkan daftar nilai yang terkandung dalam hasil, satu per replika lokal.
  3. Saat Anda memanggil apply_gradients dalam lingkup strategi distribusi, perilakunya diubah. Secara khusus, sebelum menerapkan gradien pada setiap instans paralel selama pelatihan sinkron, ia melakukan penjumlahan dari semua replika gradien.

Terakhir, setelah Anda menentukan langkah pelatihan, Anda dapat mengulangi dist_dataset dan menjalankan pelatihan dalam satu lingkaran:

for dist_inputs in dist_dataset:
  print(distributed_train_step(dist_inputs))
tf.Tensor(0.18686396, shape=(), dtype=float32)
tf.Tensor(0.18628375, shape=(), dtype=float32)
tf.Tensor(0.18570684, shape=(), dtype=float32)
tf.Tensor(0.18513316, shape=(), dtype=float32)
tf.Tensor(0.1845627, shape=(), dtype=float32)
tf.Tensor(0.18399543, shape=(), dtype=float32)
tf.Tensor(0.18343134, shape=(), dtype=float32)
tf.Tensor(0.18287037, shape=(), dtype=float32)
tf.Tensor(0.18231256, shape=(), dtype=float32)
tf.Tensor(0.18175781, shape=(), dtype=float32)
tf.Tensor(0.18120615, shape=(), dtype=float32)
tf.Tensor(0.18065754, shape=(), dtype=float32)
tf.Tensor(0.18011193, shape=(), dtype=float32)
tf.Tensor(0.17956935, shape=(), dtype=float32)
tf.Tensor(0.17902976, shape=(), dtype=float32)
tf.Tensor(0.17849308, shape=(), dtype=float32)
tf.Tensor(0.17795937, shape=(), dtype=float32)
tf.Tensor(0.17742859, shape=(), dtype=float32)
tf.Tensor(0.17690066, shape=(), dtype=float32)
tf.Tensor(0.17637561, shape=(), dtype=float32)

Dalam contoh di atas, Anda mengulangi dist_dataset untuk memberikan masukan ke pelatihan Anda. Anda juga diberikan tf.distribute.Strategy.make_experimental_numpy_dataset untuk mendukung input NumPy. Anda dapat menggunakan API ini untuk membuat kumpulan data sebelum memanggil tf.distribute.Strategy.experimental_distribute_dataset .

Cara lain untuk mengulangi data Anda adalah dengan menggunakan iterator secara eksplisit. Anda mungkin ingin melakukan ini ketika Anda ingin menjalankan sejumlah langkah tertentu sebagai lawan dari iterasi di seluruh kumpulan data. Iterasi di atas sekarang akan dimodifikasi untuk pertama membuat iterator dan kemudian secara eksplisit memanggil next untuk mendapatkan data input.

iterator = iter(dist_dataset)
for _ in range(10):
  print(distributed_train_step(next(iterator)))
tf.Tensor(0.17585339, shape=(), dtype=float32)
tf.Tensor(0.17533402, shape=(), dtype=float32)
tf.Tensor(0.17481743, shape=(), dtype=float32)
tf.Tensor(0.17430364, shape=(), dtype=float32)
tf.Tensor(0.17379259, shape=(), dtype=float32)
tf.Tensor(0.17328428, shape=(), dtype=float32)
tf.Tensor(0.17277871, shape=(), dtype=float32)
tf.Tensor(0.17227581, shape=(), dtype=float32)
tf.Tensor(0.17177561, shape=(), dtype=float32)
tf.Tensor(0.17127804, shape=(), dtype=float32)

Ini mencakup kasus paling sederhana dalam menggunakan tf.distribute.Strategy API untuk mendistribusikan loop pelatihan khusus.

Apa yang didukung sekarang?

Pelatihan API MirroredStrategy TPUStrategy MultiWorkerMirroredStrategy ParameterServerStrategy CentralStorageStrategy
Lingkaran pelatihan khusus Didukung Didukung Didukung Dukungan eksperimental Dukungan eksperimental

Contoh dan tutorial

Berikut adalah beberapa contoh untuk menggunakan strategi distribusi dengan loop pelatihan khusus:

  1. Tutorial : Pelatihan dengan loop pelatihan khusus dan MirroredStrategy .
  2. Tutorial : Pelatihan dengan loop pelatihan khusus dan MultiWorkerMirroredStrategy .
  3. Panduan : Berisi contoh loop pelatihan khusus dengan TPUStrategy .
  4. Tutorial : Pelatihan server parameter dengan loop pelatihan khusus dan ParameterServerStrategy .
  5. Repositori TensorFlow Model Garden berisi koleksi model tercanggih yang diimplementasikan menggunakan berbagai strategi.

Topik lainnya

Bagian ini mencakup beberapa topik yang relevan dengan beberapa kasus penggunaan.

Menyiapkan variabel lingkungan TF_CONFIG

Untuk pelatihan multi-pekerja, seperti yang disebutkan sebelumnya, Anda perlu menyiapkan variabel lingkungan 'TF_CONFIG' untuk setiap biner yang berjalan di cluster Anda. Variabel lingkungan 'TF_CONFIG' adalah string JSON yang menentukan tugas apa yang membentuk sebuah cluster, alamatnya, dan peran setiap tugas dalam cluster. tensorflow/ecosystem menyediakan template Kubernetes, yang menyiapkan 'TF_CONFIG' untuk tugas pelatihan Anda.

Ada dua komponen 'TF_CONFIG' : cluster dan tugas.

  • Sebuah cluster memberikan informasi tentang cluster pelatihan, yang merupakan dict yang terdiri dari berbagai jenis pekerjaan seperti pekerja. Dalam pelatihan multi-pekerja, biasanya ada satu pekerja yang mengambil sedikit tanggung jawab seperti menyimpan pos pemeriksaan dan menulis file ringkasan untuk TensorBoard selain apa yang dilakukan pekerja biasa. Pekerja tersebut disebut sebagai pekerja "kepala", dan merupakan kebiasaan bahwa pekerja dengan indeks 0 ditunjuk sebagai pekerja utama (sebenarnya beginilah cara tf.distribute.Strategy diterapkan).
  • Sebuah tugas di sisi lain memberikan informasi tentang tugas saat ini. Cluster komponen pertama adalah sama untuk semua pekerja, dan tugas komponen kedua berbeda pada setiap pekerja dan menentukan jenis dan indeks pekerja itu.

Salah satu contoh 'TF_CONFIG' adalah:

os.environ["TF_CONFIG"] = json.dumps({
    "cluster": {
        "worker": ["host1:port", "host2:port", "host3:port"],
        "ps": ["host4:port", "host5:port"]
    },
   "task": {"type": "worker", "index": 1}
})

'TF_CONFIG' ini menetapkan bahwa ada tiga pekerja dan dua tugas "ps" di "cluster" bersama dengan host dan port mereka. Bagian "task" menentukan peran tugas saat ini di "cluster" —pekerja 1 (pekerja kedua). Peran yang valid dalam sebuah cluster adalah "chief" , "worker" , "ps" , dan "evaluator" . Seharusnya tidak ada pekerjaan "ps" kecuali saat menggunakan tf.distribute.experimental.ParameterServerStrategy .

Apa berikutnya?

tf.distribute.Strategy sedang dikembangkan secara aktif. Cobalah dan berikan tanggapan Anda menggunakan masalah GitHub .