Eine Frage haben? Verbinden Sie sich mit der Community im TensorFlow Forum Visit Forum

Verwenden Sie eine GPU

Ansicht auf TensorFlow.org In Google Colab ausführen Quelle auf GitHub anzeigen Notizbuch herunterladen

TensorFlow-Code- und tf.keras Modelle werden transparent auf einer einzelnen GPU ausgeführt, ohne dass Codeänderungen erforderlich sind.

Die einfachste Möglichkeit, auf mehreren GPUs auf einem oder mehreren Computern ausgeführt zu werden, ist die Verwendung von Verteilungsstrategien .

Dieses Handbuch richtet sich an Benutzer, die diese Ansätze ausprobiert haben und festgestellt haben, dass sie eine genaue Steuerung der Verwendung der GPU durch TensorFlow benötigen. Informationen zum Debuggen von Leistungsproblemen für Szenarien mit einer oder mehreren GPUs finden Sie im Handbuch zur Optimierung der TensorFlow-GPU-Leistung .

Einrichten

Stellen Sie sicher, dass Sie die neueste TensorFlow-GPU-Version installiert haben.

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

Überblick

TensorFlow unterstützt das Ausführen von Berechnungen auf einer Vielzahl von Gerätetypen, einschließlich CPU und GPU. Sie werden beispielsweise mit Zeichenfolgenbezeichnern dargestellt:

  • "/device:CPU:0" : Die CPU Ihres Computers.
  • "/GPU:0" : Kurznotation für die erste GPU Ihres Computers, die für TensorFlow sichtbar ist.
  • "/job:localhost/replica:0/task:0/device:GPU:1" : Vollqualifizierter Name der zweiten GPU Ihres Computers, die für TensorFlow sichtbar ist.

Wenn eine TensorFlow-Operation sowohl CPU- als auch GPU-Implementierungen aufweist, erhalten die GPU-Geräte standardmäßig Priorität, wenn die Operation einem Gerät zugewiesen wird. Zum Beispiel hat tf.matmul sowohl CPU- als auch GPU-Kernel. Auf einem System mit Geräten CPU:0 und GPU:0 wird das GPU:0 Gerät ausgewählt, um tf.matmul sei denn, Sie tf.matmul ausdrücklich an, es auf einem anderen Gerät tf.matmul .

Platzierung des Protokollierungsgeräts

Um herauszufinden, welchen Geräten Ihre Operationen und Tensoren zugewiesen sind, geben Sie tf.debugging.set_log_device_placement(True) als erste Anweisung Ihres Programms ein. Durch Aktivieren der Geräteplatzierungsprotokollierung werden alle Tensorzuordnungen oder -vorgänge gedruckt.

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)

Der obige Code gibt einen Hinweis aus, dass die MatMul auf der GPU:0 .

Manuelle Geräteplatzierung

Wenn Sie möchten, dass ein bestimmter Vorgang auf einem Gerät Ihrer Wahl ausgeführt wird, anstatt dem, was automatisch für Sie ausgewählt wird, können Sie with tf.device einen Gerätekontext erstellen. Alle Vorgänge in diesem Kontext werden auf demselben bestimmten Gerät ausgeführt .

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)

Sie werden sehen, dass jetzt a und b der CPU:0 zugewiesen sind CPU:0 . Da für den MatMul Vorgang kein Gerät explizit angegeben wurde, MatMul die TensorFlow-Laufzeit basierend auf dem Vorgang und den verfügbaren Geräten (in diesem Beispiel GPU:0 ) eines aus und kopiert bei Bedarf automatisch Tensoren zwischen Geräten.

Begrenzung des GPU-Speicherwachstums

Standardmäßig ordnet TensorFlow fast den gesamten GPU-Speicher aller für den Prozess sichtbaren GPUs (vorbehaltlich CUDA_VISIBLE_DEVICES ) zu. Dies geschieht, um die relativ wertvollen GPU-Speicherressourcen auf den Geräten effizienter zu nutzen, indem die Speicherfragmentierung verringert wird. Um TensorFlow auf einen bestimmten Satz von GPUs zu beschränken, verwenden wir die Methode tf.config.experimental.set_visible_devices .

gpus = tf.config.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

In einigen Fällen ist es wünschenswert, dass der Prozess nur eine Teilmenge des verfügbaren Speichers zuweist oder nur die Speichernutzung erhöht, die vom Prozess benötigt wird. TensorFlow bietet zwei Methoden, um dies zu steuern.

Die erste Option besteht tf.config.experimental.set_memory_growth , das Speicherwachstum durch Aufrufen von tf.config.experimental.set_memory_growth , das versucht, nur so viel GPU-Speicher tf.config.experimental.set_memory_growth , wie für die Laufzeitzuweisungen erforderlich ist: Es beginnt mit der Zuweisung von sehr wenig Speicher und wenn das Programm ausgeführt wird und Wenn mehr GPU-Speicher benötigt wird, erweitern wir den dem TensorFlow-Prozess zugewiesenen GPU-Speicherbereich. Beachten Sie, dass wir keinen Speicher freigeben, da dies zu einer Speicherfragmentierung führen kann. Verwenden Sie den folgenden Code, um das Speicherwachstum für eine bestimmte GPU zu aktivieren, bevor Sie Tensoren zuweisen oder Operationen ausführen.

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.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

Eine andere Möglichkeit, diese Option zu aktivieren, besteht darin, die Umgebungsvariable TF_FORCE_GPU_ALLOW_GROWTH auf true . Diese Konfiguration ist plattformspezifisch.

Die zweite Methode besteht darin, ein virtuelles GPU-Gerät mit tf.config.experimental.set_virtual_device_configuration zu konfigurieren und eine feste Grenze für den Gesamtspeicher tf.config.experimental.set_virtual_device_configuration , der auf der GPU zugewiesen werden soll.

gpus = tf.config.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

Dies ist nützlich, wenn Sie die für den TensorFlow-Prozess verfügbare Menge an GPU-Speicher wirklich einschränken möchten. Dies ist bei der lokalen Entwicklung üblich, wenn die GPU für andere Anwendungen wie eine Workstation-GUI freigegeben wird.

Verwenden einer einzelnen GPU auf einem System mit mehreren GPUs

Wenn Sie mehr als eine GPU in Ihrem System haben, wird standardmäßig die GPU mit der niedrigsten ID ausgewählt. Wenn Sie auf einer anderen GPU ausgeführt werden möchten, müssen Sie die Voreinstellung explizit angeben:

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.

Wenn das von Ihnen angegebene Gerät nicht vorhanden ist, erhalten Sie einen RuntimeError : .../device:GPU:2 unknown device .

Wenn Sie möchten, dass TensorFlow automatisch ein vorhandenes und unterstütztes Gerät tf.config.set_soft_device_placement(True) , um die Vorgänge auszuführen, falls das angegebene nicht vorhanden ist, können Sie tf.config.set_soft_device_placement(True) aufrufen.

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)

Verwenden mehrerer GPUs

Durch die Entwicklung für mehrere GPUs kann ein Modell mit den zusätzlichen Ressourcen skaliert werden. Wenn Sie auf einem System mit einer einzelnen GPU entwickeln, können Sie mehrere GPUs mit virtuellen Geräten simulieren. Dies ermöglicht ein einfaches Testen von Multi-GPU-Setups, ohne dass zusätzliche Ressourcen erforderlich sind.

gpus = tf.config.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

Sobald wir zur Laufzeit mehrere logische GPUs zur Verfügung haben, können wir die mehreren GPUs mit tf.distribute.Strategy oder mit manueller Platzierung verwenden.

Mit tf.distribute.Strategy

Die beste Vorgehensweise für die Verwendung mehrerer GPUs ist die Verwendung von tf.distribute.Strategy . Hier ist ein einfaches Beispiel:

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

Dieses Programm führt auf jeder GPU eine Kopie Ihres Modells aus und teilt die Eingabedaten zwischen ihnen auf, was auch als " Datenparallelität " bezeichnet wird.

Weitere Informationen zu Vertriebsstrategien finden Sie im Handbuch hier .

Manuelle Platzierung

tf.distribute.Strategy arbeitet unter der Haube, indem die Berechnung tf.distribute.Strategy repliziert wird. Sie können die Replikation manuell implementieren, indem Sie Ihr Modell auf jeder GPU erstellen. Beispielsweise:

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)