Halaman ini diterjemahkan oleh Cloud Translation API.
Switch to English

Gunakan GPU

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

Kode TensorFlow, dan model tf.keras akan berjalan secara transparan pada satu GPU tanpa perlu mengubah kode.

Cara termudah untuk berjalan di beberapa GPU, di satu atau banyak mesin, adalah menggunakan Strategi Distribusi .

Panduan ini ditujukan bagi pengguna yang telah mencoba pendekatan ini dan menemukan bahwa mereka memerlukan kontrol yang lebih cermat tentang cara TensorFlow menggunakan GPU. Untuk mempelajari cara men-debug masalah performa untuk skenario tunggal dan multi-GPU, lihat panduan Performa GPU TensorFlow Mengoptimalkan .

Mendirikan

Pastikan Anda telah menginstal rilis GPU TensorFlow terbaru.

import tensorflow as tf
print("Num GPUs Available: ", len(tf.config.experimental.list_physical_devices('GPU')))
Num GPUs Available:  2

Gambaran

TensorFlow mendukung komputasi yang berjalan pada berbagai jenis perangkat, termasuk CPU dan GPU. Mereka direpresentasikan dengan pengenal string misalnya:

  • "/device:CPU:0" : CPU mesin Anda.
  • "/GPU:0" : Notasi tangan pendek untuk GPU pertama mesin Anda yang terlihat oleh TensorFlow.
  • "/job:localhost/replica:0/task:0/device:GPU:1" : Nama yang sepenuhnya memenuhi syarat dari GPU kedua mesin Anda yang dapat dilihat oleh TensorFlow.

Jika operasi TensorFlow memiliki implementasi CPU dan GPU, secara default perangkat GPU akan diberikan prioritas saat operasi ditetapkan ke perangkat. Misalnya, tf.matmul memiliki kernel CPU dan GPU. Pada sistem dengan perangkat CPU:0 dan GPU:0 , perangkat GPU:0 akan dipilih untuk menjalankan tf.matmul kecuali Anda secara eksplisit meminta untuk menjalankannya di perangkat lain.

Penempatan perangkat logging

Untuk mengetahui perangkat mana yang menetapkan operasi dan tensor Anda, letakkan tf.debugging.set_log_device_placement(True) sebagai pernyataan pertama program Anda. Mengaktifkan pencatatan penempatan perangkat menyebabkan semua alokasi atau operasi Tensor dicetak.

tf.debugging.set_log_device_placement(True)

# Create some tensors
a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
c = tf.matmul(a, b)

print(c)
Executing op MatMul in device /job:localhost/replica:0/task:0/device:GPU:0
tf.Tensor(
[[22. 28.]
 [49. 64.]], shape=(2, 2), dtype=float32)

Kode di atas akan mencetak indikasi MatMul op dijalankan pada GPU:0 .

Penempatan perangkat manual

Jika Anda ingin operasi tertentu dijalankan pada perangkat pilihan Anda daripada yang dipilih secara otomatis, Anda dapat menggunakan with tf.device untuk membuat konteks perangkat, dan semua operasi dalam konteks itu akan berjalan pada perangkat yang ditunjuk sama .

tf.debugging.set_log_device_placement(True)

# Place tensors on the CPU
with tf.device('/CPU:0'):
  a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
  b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])

# Run on the GPU
c = tf.matmul(a, b)
print(c)
Executing op MatMul in device /job:localhost/replica:0/task:0/device:GPU:0
tf.Tensor(
[[22. 28.]
 [49. 64.]], shape=(2, 2), dtype=float32)

Anda akan melihat bahwa sekarang a dan b ditugaskan ke CPU:0 . Karena perangkat tidak secara eksplisit ditentukan untuk operasi MatMul , runtime TensorFlow akan memilih satu berdasarkan operasi dan perangkat yang tersedia ( GPU:0 dalam contoh ini) dan secara otomatis menyalin tensor antar perangkat jika diperlukan.

Membatasi pertumbuhan memori GPU

Secara default, TensorFlow memetakan hampir semua memori GPU dari semua GPU (tunduk pada CUDA_VISIBLE_DEVICES ) yang terlihat oleh proses. Ini dilakukan untuk lebih efisien menggunakan sumber daya memori GPU yang relatif berharga pada perangkat dengan mengurangi fragmentasi memori. Untuk membatasi TensorFlow ke kumpulan GPU tertentu, kami menggunakan metode tf.config.experimental.set_visible_devices .

gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
  # Restrict TensorFlow to only use the first GPU
  try:
    tf.config.experimental.set_visible_devices(gpus[0], 'GPU')
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')
    print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPU")
  except RuntimeError as e:
    # Visible devices must be set before GPUs have been initialized
    print(e)
2 Physical GPUs, 1 Logical GPU

Dalam beberapa kasus, proses diinginkan untuk hanya mengalokasikan subset dari memori yang tersedia, atau hanya meningkatkan penggunaan memori seperti yang diperlukan oleh proses. TensorFlow menyediakan dua metode untuk mengontrol ini.

Opsi pertama adalah mengaktifkan pertumbuhan memori dengan memanggil tf.config.experimental.set_memory_growth , yang mencoba mengalokasikan memori GPU hanya sebanyak yang diperlukan untuk alokasi waktu proses: ia mulai mengalokasikan sangat sedikit memori, dan saat program dijalankan dan lebih banyak memori GPU dibutuhkan, kami memperluas wilayah memori GPU yang dialokasikan untuk proses TensorFlow. Perhatikan bahwa kami tidak melepaskan memori, karena dapat menyebabkan fragmentasi memori. Untuk mengaktifkan pertumbuhan memori untuk GPU tertentu, gunakan kode berikut sebelum mengalokasikan tensor atau menjalankan operasi apa pun.

gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
  try:
    # Currently, memory growth needs to be the same across GPUs
    for gpu in gpus:
      tf.config.experimental.set_memory_growth(gpu, True)
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')
    print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPUs")
  except RuntimeError as e:
    # Memory growth must be set before GPUs have been initialized
    print(e)
2 Physical GPUs, 2 Logical GPUs

Cara lain untuk mengaktifkan opsi ini adalah dengan menyetel variabel lingkungan TF_FORCE_GPU_ALLOW_GROWTH ke true . Konfigurasi ini khusus untuk platform.

Metode kedua adalah mengkonfigurasi perangkat GPU virtual dengan tf.config.experimental.set_virtual_device_configuration dan menetapkan batas pasti pada total memori untuk dialokasikan pada GPU.

gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
  # Restrict TensorFlow to only allocate 1GB of memory on the first GPU
  try:
    tf.config.experimental.set_virtual_device_configuration(
        gpus[0],
        [tf.config.experimental.VirtualDeviceConfiguration(memory_limit=1024)])
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')
    print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPUs")
  except RuntimeError as e:
    # Virtual devices must be set before GPUs have been initialized
    print(e)
2 Physical GPUs, 2 Logical GPUs

Ini berguna jika Anda ingin benar-benar membatasi jumlah memori GPU yang tersedia untuk proses TensorFlow. Ini adalah praktik umum untuk pengembangan lokal saat GPU dibagikan dengan aplikasi lain seperti GUI stasiun kerja.

Menggunakan satu GPU pada sistem multi-GPU

Jika Anda memiliki lebih dari satu GPU di sistem Anda, GPU dengan ID terendah akan dipilih secara default. Jika Anda ingin menjalankan GPU yang berbeda, Anda perlu menentukan preferensinya secara eksplisit:

tf.debugging.set_log_device_placement(True)

try:
  # Specify an invalid GPU device
  with tf.device('/device:GPU:2'):
    a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
    b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
    c = tf.matmul(a, b)
except RuntimeError as e:
  print(e)
/job:localhost/replica:0/task:0/device:GPU:2 unknown device.

Jika perangkat yang Anda tentukan tidak ada, Anda akan mendapatkan RuntimeError : .../device:GPU:2 unknown device .

Jika Anda ingin TensorFlow secara otomatis memilih perangkat yang ada dan didukung untuk menjalankan operasi jika yang ditentukan tidak ada, Anda dapat memanggil tf.config.set_soft_device_placement(True) .

tf.config.set_soft_device_placement(True)
tf.debugging.set_log_device_placement(True)

# Creates some tensors
a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
c = tf.matmul(a, b)

print(c)
Executing op MatMul in device /job:localhost/replica:0/task:0/device:GPU:0
tf.Tensor(
[[22. 28.]
 [49. 64.]], shape=(2, 2), dtype=float32)

Menggunakan banyak GPU

Mengembangkan beberapa GPU akan memungkinkan model melakukan penskalaan dengan sumber daya tambahan. Jika mengembangkan pada sistem dengan satu GPU, kami dapat mensimulasikan beberapa GPU dengan perangkat virtual. Ini memungkinkan pengujian mudah pengaturan multi-GPU tanpa memerlukan sumber daya tambahan.

gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
  # Create 2 virtual GPUs with 1GB memory each
  try:
    tf.config.experimental.set_virtual_device_configuration(
        gpus[0],
        [tf.config.experimental.VirtualDeviceConfiguration(memory_limit=1024),
         tf.config.experimental.VirtualDeviceConfiguration(memory_limit=1024)])
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')
    print(len(gpus), "Physical GPU,", len(logical_gpus), "Logical GPUs")
  except RuntimeError as e:
    # Virtual devices must be set before GPUs have been initialized
    print(e)
2 Physical GPU, 3 Logical GPUs

Setelah kami memiliki beberapa GPU logis yang tersedia untuk runtime, kami dapat memanfaatkan beberapa GPU dengan tf.distribute.Strategy atau dengan penempatan manual.

Dengan tf.distribute.Strategy

Praktik terbaik untuk menggunakan beberapa GPU adalah menggunakan tf.distribute.Strategy . Berikut ini contoh sederhananya:

tf.debugging.set_log_device_placement(True)

strategy = tf.distribute.MirroredStrategy()
with strategy.scope():
  inputs = tf.keras.layers.Input(shape=(1,))
  predictions = tf.keras.layers.Dense(1)(inputs)
  model = tf.keras.models.Model(inputs=inputs, outputs=predictions)
  model.compile(loss='mse',
                optimizer=tf.keras.optimizers.SGD(learning_rate=0.2))
Executing op RandomUniform in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op Sub in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op Mul in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op Add in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op VarHandleOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op VarIsInitializedOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op LogicalNot in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op Assert in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op AssignVariableOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op ReadVariableOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op Identity in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op VarHandleOp in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op VarIsInitializedOp in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op LogicalNot in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op Assert in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op AssignVariableOp in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op Reshape in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op VarHandleOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op VarHandleOp in device /job:localhost/replica:0/task:0/device:GPU:1

Program ini akan menjalankan salinan model Anda di setiap GPU, membagi data masukan di antara keduanya, juga dikenal sebagai " paralelisme data ".

Untuk informasi lebih lanjut tentang strategi distribusi, lihat panduannya di sini .

Penempatan manual

tf.distribute.Strategy bekerja di bawah tenda dengan mereplikasi komputasi di seluruh perangkat. Anda dapat mengimplementasikan replikasi secara manual dengan membuat model Anda di setiap GPU. Sebagai contoh:

tf.debugging.set_log_device_placement(True)

gpus = tf.config.experimental.list_logical_devices('GPU')
if gpus:
  # Replicate your computation on multiple GPUs
  c = []
  for gpu in gpus:
    with tf.device(gpu.name):
      a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
      b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
      c.append(tf.matmul(a, b))

  with tf.device('/CPU:0'):
    matmul_sum = tf.add_n(c)

  print(matmul_sum)
Executing op MatMul in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op MatMul in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op AddN in device /job:localhost/replica:0/task:0/device:CPU:0
tf.Tensor(
[[ 44.  56.]
 [ 98. 128.]], shape=(2, 2), dtype=float32)