Direkt zum Hauptinhalt

TensorFlow™ auf Databricks

Illustration

Verwenden einer GPU

Eine GPU (Graphical Processing Unit) ist eine Komponente der meisten modernen Computer, die der Durchführung von Berechnungen für 3D-Grafiken dient. Ihre häufigste Verwendung besteht darin, diese Aktionen für Videospiele auszuführen und die Bewegung von Polygonen zu berechnen, um dem Benutzer das Spiel anzuzeigen. Eine GPU ist im Grunde eine große Ansammlung kleiner Prozessoren, die hochgradig parallelisierte Berechnungen durchführen. Sie haben im Grunde genommen gerade einen Mini-Supercomputer* am Laufen!

Während jede einzelne CPU in einer GPU recht langsam ist, gibt es viele davon und sie sind auf die numerische Verarbeitung spezialisiert. Daher kann eine GPU viele einfache numerische Verarbeitungsaufgaben gleichzeitig ausführen. Glücklicherweise ist es genau das, was viele Algorithmen für Machine Learning erledigen müssen.

Sie haben keine GPU?

Die meisten modernen Computer (der letzten 10 Jahre) verfügen über eine Art GPU, auch wenn diese in Ihr Motherboard integriert ist. Für die Zwecke dieses Tutorials ist diese Art GPU ausreichend.

Sie müssen wissen, welchen Grafikkartentyp Sie haben. Windows-Benutzer können diese Anweisungen befolgen. Benutzer anderer Systeme müssen in der Dokumentation ihres Systems nachsehen.

Benutzer von Grafikkarten, die nicht von Nvidia sind

Während andere Grafikkarten möglicherweise unterstützt werden, ist dieses Tutorial nur ein Test auf einer aktuellen Nvidia-Grafikkarte. Wenn es sich bei Ihrer Grafikkarte um einen anderen Typ handelt, sollten Sie sich eine Nvidia-Grafikkarte kaufen oder ausleihen. Wenn Ihnen das zu umständlich erscheint, wenden Sie sich an Ihre örtliche Universität oder Schule und fragen Sie, ob sie Ihnen helfen können. Sollte man Ihnen auch dort nicht weiterhelfen können, lesen Sie einfach dieses Tutorial und verwenden Sie stattdessen eine Standard-CPU. Die dabei erworbenen Erkenntnisse können Sie zu einem späteren Zeitpunkt nutzen.

* Hinweis: Nicht wirklich ein Supercomputer, aber in vielerlei Hinsicht ähnlich.

Installieren von GPU-fähigem TensorFlow

Wenn Sie keine GPU-fähige Version von TensorFlow installiert haben, ist dies zunächst erforderlich. In unseren Anweisungen in Lektion 1 ist dies nicht enthalten. Wenn Sie sich also noch nicht um eine GPU-Unterstützung gekümmert haben, dann haben Sie noch keine.

Ich empfehle Ihnen, hierfür eine neue Anaconda-Umgebung zu erstellen, anstatt zu versuchen, Ihre vorherige zu aktualisieren.

Vor dem Start

Rufen Sie die offiziellen TensorFlow-Installationsanweisungen auf und folgen Sie den Anaconda-Installationsanweisungen. Der Hauptunterschied zu dem, was wir in Lektion 1 gemacht haben, besteht darin, dass Sie die GPU-fähige Version von TensorFlow für Ihr System benötigen. Bevor Sie TensorFlow jedoch in dieser Umgebung installieren, müssen Sie Ihren Computer so einrichten, dass er GPU-fähig mit CUDA und CuDNN ist. Die offizielle TensorFlow-Dokumentation beschreibt die dafür notwendigen Schritte detailliert, ich empfehle jedoch dieses Tutorial, wenn Sie versuchen, eine aktuelle Ubuntu-Installation einzurichten. Der Hauptgrund dafür ist, dass CUDA zum Zeitpunkt des Verfassens dieses Artikels (Juli 2016) noch nicht für die neueste Ubuntu-Version erstellt wurde, was bedeutet, dass der Prozess viel umständlicher und weniger automatisch ist.

Verwenden Ihrer GPU

Es ist eigentlich ganz einfach. Zumindest von der Syntax her. Ändern Sie einfach

 

# Setup operations

with tf.Session() as sess:
    # Run your code

 

zu

 

with tf.device("/gpu:0"):
    # Setup operations

with tf.Session() as sess:
    # Run your code

 

Diese neue Zeile erstellt einen neuen Kontextmanager, der TensorFlow anweist, diese Aktionen auf der GPU auszuführen.

Sehen wir uns ein konkretes Beispiel an. Der folgende Code erstellt eine Zufallsmatrix mit einer in der Befehlszeile angegebenen Größe. Wir können den Code entweder auf einer CPU oder GPU ausführen, indem wir folgende Befehlszeilenoptionen verwenden:

 

import sys
import numpy as np
import tensorflow as tf
from datetime import datetime

device_name = sys.argv[1]  # Choose device from cmd line. Options: gpu or cpu
shape = (int(sys.argv[2]), int(sys.argv[2]))
if device_name == "gpu":
    device_name = "/gpu:0"
else:
    device_name = "/cpu:0"

with tf.device(device_name):
    random_matrix = tf.random_uniform(shape=shape, minval=0, maxval=1)
    dot_operation = tf.matmul(random_matrix, tf.transpose(random_matrix))
    sum_operation = tf.reduce_sum(dot_operation)


startTime = datetime.now()
with tf.Session(config=tf.ConfigProto(log_device_placement=True)) as session:
        result = session.run(sum_operation)
        print(result)

# It can be hard to see the results on the terminal with lots of output -- add some newlines to improve readability.
print("\n" * 5)
print("Shape:", shape, "Device:", device_name)
print("Time taken:", datetime.now() - startTime)

print("\n" * 5)

 

Sie können dies in der Befehlszeile ausführen, und zwar so:

python matmul.py gpu 1500

Dadurch wird die CPU mit einer Matrix der Größe 1500 im Quadrat verwendet. Verwenden Sie Folgendes, um die gleiche Operation auf der CPU durchzuführen:

python matmul.py cpu 1500

Das erste, was Sie beim Ausführen von GPU-fähigem Code bemerken werden, ist eine deutliche Steigerung der Ausgabe im Vergleich zu einem normalen TensorFlow-Skript. Hier ist, was mein Computer ausgibt, bevor er irgendwelche Ergebnisse der Operationen ausgibt.

 

I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcublas.so locally
I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcudnn.so.5 locally
I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcufft.so locally
I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcuda.so.1 locally
I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcurand.so locally
I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:925] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
I tensorflow/core/common_runtime/gpu/gpu_init.cc:102] Found device 0 with properties: 
name: GeForce GTX 950M
major: 5 minor: 0 memoryClockRate (GHz) 1.124
pciBusID 0000:01:00.0
Total memory: 3.95GiB
Free memory: 3.50GiB
I tensorflow/core/common_runtime/gpu/gpu_init.cc:126] DMA: 0 
I tensorflow/core/common_runtime/gpu/gpu_init.cc:136] 0:   Y 
I tensorflow/core/common_runtime/gpu/gpu_device.cc:838] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GeForce GTX 950M, pci bus id: 0000:01:00.0)

 

Wenn Ihr Code keine ähnliche Ausgabe erzeugt, führen Sie nicht GPU-fähiges TensorFlow aus. Wenn Sie alternativ eine Fehlermeldung wie ImportError: libcudart.so.7.5: cannot open shared object file: No such file or directory erhalten, dann haben Sie die CUDA-Bibliothek nicht ordnungsgemäß installiert. In diesem Fall müssen Sie noch einmal die Anweisungen zur Installation von CUDA auf Ihrem System befolgen.

Versuchen Sie, den obigen Code sowohl auf der CPU als auch auf der GPU auszuführen und erhöhen Sie dabei die Zahl langsam. Beginnen Sie mit 1500, versuchen Sie es dann mit 3000, dann mit 4500 und so weiter. Sie werden feststellen, dass die CPU ziemlich lange braucht, während die GPU bei dieser Operation sehr, sehr schnell ist!

Wenn Sie über mehrere GPUs verfügen, können Sie eine beliebige verwenden. GPUs sind nullindiziert – der Code oben greift auf die erste GPU zu. Wenn Sie das Gerät in gpu:1 ändern, wird die zweite GPU verwendet und so weiter. Sie können auch einen Teil Ihrer Berechnung an eine GPU und einen Teil an eine andere GPU senden. Darüber hinaus können Sie auf ähnliche Weise auf die CPUs Ihres Computers zugreifen – verwenden Sie einfach cpu:0 (oder eine andere Zahl).

Welche Art von Operationen sollte ich an die GPU senden?

Wenn der Prozessschritt im Allgemeinen wie folgt beschrieben werden kann: „Führe diese mathematische Operation tausende Male durch“, dann senden Sie sie an die GPU. Beispiele hierfür sind die Matrixmultiplikation und die Berechnung der Umkehrung einer Matrix. Tatsächlich sind viele grundlegende Matrix-Operationen erstklassige Kandidaten für GPUs. Als grobe und einfache Faustregel sollten andere Operationen auf der CPU ausgeführt werden.

Der Wechsel von Geräten und die Verwendung von GPUs hat auch seine Nachteile. GPUs haben keinen direkten Zugriff auf den Rest Ihres Computers (außer natürlich auf das Display). Wenn Sie einen Befehl auf einer GPU ausführen, müssen Sie daher zuerst alle Daten auf die GPU kopieren, dann die Operation ausführen und dann das Ergebnis zurück in den Hauptspeicher Ihres Computers kopieren. TensorFlow erledigt dies im Hintergrund, somit ist der Code einfach, aber die Arbeit muss trotzdem gemacht werden.

Nicht alle Operationen können auf GPUs durchgeführt werden. Wenn Sie die folgende Fehlermeldung sehen, versuchen Sie, eine Operation auszuführen, die auf einer GPU nicht möglich ist:

 

Cannot assign a device to node 'PyFunc': Could not satisfy explicit device specification '/device:GPU:1' because no devices matching that specification are registered in this process;

 

In diesem Fall können Sie das Gerät für diese Operation entweder manuell in eine CPU ändern oder TensorFlow so einstellen, dass das Gerät in diesem Fall automatisch geändert wird. Setzen Sie dazu in der Konfiguration allow_soft_placement auf True, was im Rahmen der Sitzungserstellung erfolgt. Der Prototyp sieht folgendermaßen aus:

 

with tf.Session(config=tf.ConfigProto(allow_soft_placement=True)):
    # Run your graph here

 

Ich empfehle außerdem, die Geräteplatzierung bei der Verwendung von GPUs zu protokollieren, damit Sie Probleme im Zusammenhang mit der Nutzung unterschiedlicher Geräte problemlos beheben können. Dadurch ist die Nutzung der Geräte im Protokoll enthalten, sodass Sie sehen können, wann sich Geräte ändern und wie sich dies auf den Graphen auswirkt.

 

with tf.Session(config=tf.ConfigProto(allow_soft_placement=True, log_device_placement=True)):
    # Run your graph here

 

  1. Richten Sie Ihren Computer so ein, dass er die GPU für TensorFlow verwendet (oder leihen Sie sich einen Computer, wenn Sie keine aktuelle GPU haben).
  2. Versuchen Sie, die Lösungen der vorherigen Übung auf der GPU auszuführen. Welche Operationen können auf einer GPU ausgeführt werden und welche nicht?
  3. Erstellen Sie ein Programm, das Operationen sowohl auf der GPU als auch auf der CPU ausführt. Verwenden Sie den Profiling-Code von  Lektion 5, um die Auswirkungen des Sendens von Daten an die und des Abrufens von Daten von der GPU abzuschätzen.
  4. Schicken Sie mir Ihren Code! Ich würde gerne Ihren Code sehen und erfahren, wie Sie TensorFlow verwenden und welche Tricks Sie gefunden haben.