GPU kullanın

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

TensorFlow kodu ve tf.keras modelleri, kod değişikliği gerekmeden tek bir GPU üzerinde şeffaf bir şekilde çalışır.

Birden fazla GPU'da, bir veya daha fazla makinede çalıştırmanın en basit yolu, Dağıtım Stratejilerini kullanmaktır.

Bu kılavuz, bu yaklaşımları deneyen ve TensorFlow'un GPU'yu nasıl kullandığı konusunda ayrıntılı kontrole ihtiyaçları olduğunu bulan kullanıcılar içindir. Tek ve çoklu GPU senaryoları için performans sorunlarının nasıl ayıklanacağını öğrenmek için TensorFlow GPU Performansını Optimize Etme kılavuzuna bakın.

Kurmak

En son TensorFlow gpu sürümünün kurulu olduğundan emin olun.

import tensorflow as tf
print("Num GPUs Available: ", len(tf.config.list_physical_devices('GPU')))
tutucu1 l10n-yer
Num GPUs Available:  1

genel bakış

TensorFlow, CPU ve GPU dahil olmak üzere çeşitli cihaz türlerinde çalışan hesaplamaları destekler. Örneğin, dize tanımlayıcılarıyla temsil edilirler:

  • "/device:CPU:0" : Makinenizin CPU'su.
  • "/GPU:0" : Makinenizin TensorFlow tarafından görülebilen ilk GPU'su için kısa el gösterimi.
  • "/job:localhost/replica:0/task:0/device:GPU:1" : Makinenizin TensorFlow tarafından görülebilen ikinci GPU'sunun tam nitelikli adı.

Bir TensorFlow işleminde hem CPU hem de GPU uygulamaları varsa, işlem atandığında varsayılan olarak GPU aygıtına öncelik verilir. Örneğin, tf.matmul hem CPU hem de GPU çekirdeklerine sahiptir ve CPU:0 ve GPU:0 aygıtlarına sahip bir sistemde GPU:0 aygıtı, siz açıkça başka bir aygıtta çalıştırmayı talep etmediğiniz sürece tf.matmul çalıştırmak üzere seçilir.

Bir TensorFlow işleminin karşılık gelen GPU uygulaması yoksa işlem CPU cihazına geri döner. Örneğin, tf.cast yalnızca bir CPU çekirdeğine sahip olduğundan, CPU:0 ve GPU:0 aygıtlarına sahip bir sistemde, GPU:0 :0 aygıtında çalışması istense bile CPU:0 aygıtı tf.cast çalıştırmak üzere seçilir. .

Kayıt cihazı yerleşimi

İşlemlerinizin ve tensörlerinizin hangi cihazlara atandığını bulmak için programınızın ilk ifadesi olarak tf.debugging.set_log_device_placement(True) yazın. Cihaz yerleşimi günlüğünün etkinleştirilmesi, herhangi bir Tensör tahsisinin veya işleminin yazdırılmasına neden olur.

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)
tutucu3 l10n-yer
Executing op _EagerConst in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op _EagerConst in device /job:localhost/replica:0/task:0/device:GPU:0
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)

Yukarıdaki kod, MatMul GPU:0 üzerinde yürütüldüğünün bir göstergesini yazdıracaktır.

Manuel cihaz yerleştirme

Sizin için otomatik olarak seçilenler yerine belirli bir işlemin seçtiğiniz bir cihazda çalışmasını istiyorsanız, bir cihaz bağlamı oluşturmak için with tf.device kullanabilirsiniz ve bu bağlamdaki tüm işlemler aynı atanmış cihazda çalışacaktır. .

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)
tutucu5 l10n-yer
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)

Şimdi a ve b CPU:0 atandığını göreceksiniz. MatMul işlemi için bir cihaz açıkça belirtilmediğinden, MatMul çalışma zamanı, işleme ve mevcut cihazlara (bu örnekte GPU:0 ) dayalı olarak birini seçecek ve gerekirse tensörleri cihazlar arasında otomatik olarak kopyalayacaktır.

GPU bellek büyümesini sınırlama

Varsayılan olarak, TensorFlow, işlem tarafından görülebilen tüm GPU'ların ( CUDA_VISIBLE_DEVICES tabidir) neredeyse tüm GPU belleğini eşler. Bu, bellek parçalanmasını azaltarak cihazlardaki nispeten değerli GPU bellek kaynaklarını daha verimli kullanmak için yapılır. TensorFlow'u belirli bir GPU kümesiyle sınırlamak için tf.config.set_visible_devices yöntemini kullanın.

gpus = tf.config.list_physical_devices('GPU')
if gpus:
  # Restrict TensorFlow to only use the first GPU
  try:
    tf.config.set_visible_devices(gpus[0], 'GPU')
    logical_gpus = tf.config.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)
tutucu7 l10n-yer
1 Physical GPUs, 1 Logical GPU

Bazı durumlarda, işlemin yalnızca kullanılabilir belleğin bir alt kümesini ayırması veya bellek kullanımını yalnızca işlemin gerektirdiği şekilde büyütmesi istenir. TensorFlow, bunu kontrol etmek için iki yöntem sunar.

İlk seçenek, çalışma zamanı ayırmaları için yalnızca gerektiği kadar GPU belleği ayırmaya çalışan tf.config.experimental.set_memory_growth çağırarak bellek büyümesini açmaktır: çok az bellek ayırmaya başlar ve program çalışırken ve daha fazla GPU belleği gerekiyorsa, TensorFlow işlemi için GPU bellek bölgesi genişletilir. Bellek parçalanmasına yol açabileceğinden bellek serbest bırakılmaz. Belirli bir GPU için bellek büyümesini etkinleştirmek için, herhangi bir tensör tahsis etmeden veya herhangi bir işlemi yürütmeden önce aşağıdaki kodu kullanın.

gpus = tf.config.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.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)
tutucu9 l10n-yer
Physical devices cannot be modified after being initialized

Bu seçeneği etkinleştirmenin başka bir yolu, TF_FORCE_GPU_ALLOW_GROWTH çevresel değişkenini true olarak ayarlamaktır. Bu yapılandırma platforma özeldir.

İkinci yöntem, sanal bir GPU cihazını tf.config.set_logical_device_configuration ile yapılandırmak ve GPU'ya tahsis edilecek toplam bellek üzerinde kesin bir sınır belirlemektir.

gpus = tf.config.list_physical_devices('GPU')
if gpus:
  # Restrict TensorFlow to only allocate 1GB of memory on the first GPU
  try:
    tf.config.set_logical_device_configuration(
        gpus[0],
        [tf.config.LogicalDeviceConfiguration(memory_limit=1024)])
    logical_gpus = tf.config.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)
tutucu11 l10n-yer
Virtual devices cannot be modified after being initialized

Bu, TensorFlow işlemi için kullanılabilen GPU belleği miktarını gerçekten sınırlamak istiyorsanız kullanışlıdır. Bu, GPU iş istasyonu GUI gibi diğer uygulamalarla paylaşıldığında yerel geliştirme için yaygın bir uygulamadır.

Çoklu GPU sisteminde tek bir GPU kullanma

Sisteminizde birden fazla GPU varsa, varsayılan olarak en düşük kimliğe sahip GPU seçilecektir. Farklı bir GPU'da çalıştırmak isterseniz, tercihi açıkça belirtmeniz gerekir:

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)
tutucu13 l10n-yer
Executing op _EagerConst in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op _EagerConst in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op MatMul in device /job:localhost/replica:0/task:0/device:GPU:0

Belirttiğiniz cihaz mevcut değilse, RuntimeError : .../device:GPU:2 unknown device hatasını alırsınız.

TensorFlow'un belirtilenin olmaması durumunda işlemleri yürütmek için mevcut ve desteklenen bir cihazı otomatik olarak seçmesini istiyorsanız, tf.config.set_soft_device_placement(True) arayabilirsiniz.

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)
tutucu15 l10n-yer
Executing op _EagerConst in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op _EagerConst in device /job:localhost/replica:0/task:0/device:GPU:0
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)

Birden çok GPU kullanma

Birden çok GPU için geliştirme, bir modelin ek kaynaklarla ölçeklenmesine olanak tanır. Tek GPU'lu bir sistem üzerinde geliştirme yapıyorsanız, sanal cihazlarla birden fazla GPU'yu simüle edebilirsiniz. Bu, ek kaynaklar gerektirmeden çoklu GPU kurulumlarının kolay test edilmesini sağlar.

gpus = tf.config.list_physical_devices('GPU')
if gpus:
  # Create 2 virtual GPUs with 1GB memory each
  try:
    tf.config.set_logical_device_configuration(
        gpus[0],
        [tf.config.LogicalDeviceConfiguration(memory_limit=1024),
         tf.config.LogicalDeviceConfiguration(memory_limit=1024)])
    logical_gpus = tf.config.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)
tutucu17 l10n-yer
Virtual devices cannot be modified after being initialized

Çalışma zamanı için birden fazla mantıksal GPU olduğunda, birden çok GPU'yu tf.distribute.Strategy veya manuel yerleştirme ile kullanabilirsiniz.

tf.distribute.Strategy ile

Birden çok GPU kullanmak için en iyi uygulama tf.distribute.Strategy kullanmaktır. İşte basit bir örnek:

tf.debugging.set_log_device_placement(True)
gpus = tf.config.list_logical_devices('GPU')
strategy = tf.distribute.MirroredStrategy(gpus)
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))
tutucu19 l10n-yer
Executing op _EagerConst 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 AssignVariableOp in device /job:localhost/replica:0/task:0/device:GPU:0
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)
Executing op _EagerConst in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op _EagerConst in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op _EagerConst in device /job:localhost/replica:0/task:0/device:GPU:0
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 AddV2 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 AssignVariableOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op NoOp 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: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:0
Executing op _EagerConst in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op _EagerConst in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op Fill 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 AssignVariableOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op NoOp 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: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:0
Executing op _EagerConst 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 AssignVariableOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op NoOp 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 AssignVariableOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op NoOp 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 AssignVariableOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op NoOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op _EagerConst in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op Fill 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 AssignVariableOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op NoOp in device /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',).
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: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',).
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:CPU:0
Executing op _EagerConst in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op Fill 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 AssignVariableOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op NoOp in device /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',).
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: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',).
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:CPU:0
Executing op _EagerConst 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 AssignVariableOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op NoOp in device /job:localhost/replica:0/task:0/device:GPU:0

Bu program, modelinizin bir kopyasını her bir GPU'da çalıştırarak giriş verilerini aralarında bölerek " veri paralelliği " olarak da bilinir.

Dağıtım stratejileri hakkında daha fazla bilgi için buradaki kılavuza göz atın.

Manuel yerleştirme

tf.distribute.Strategy , hesaplamayı cihazlar arasında çoğaltarak kaputun altında çalışır. Modelinizi her bir GPU'da oluşturarak çoğaltmayı manuel olarak uygulayabilirsiniz. Örneğin:

tf.debugging.set_log_device_placement(True)

gpus = tf.config.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)
tutucu21 l10n-yer
Executing op _EagerConst in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op _EagerConst in device /job:localhost/replica:0/task:0/device:GPU:0
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)