TensorFlow 2 mit GPU Unterstützung unter Windows einrichten

Nach dem ich meinen neuen PC mit NVIDIA Grafikkarte an den Start gebracht hatte, wollte ich auch die GPU der Grafikkarte für das Machine Learning in TensorFlow verwenden. Hat sich aber herausgestellt das das unter Windows leider nicht ganz so einfach ist – eher das Gegenteil.

Es war jedenfalls mal wieder ein richtiges Download- und Installationsgemetzel. Daher hier meine „Lessons learned“ – eine ausführliche Anleitung wie man TensorFlow 2 mit GPU Unterstützung unter Windows zum Laufen bekommt.

Meine Zielumgebung:

  • NVIDIA GeForce RTX 2070 Grafikkarte
  • Windows 10
  • TensorFlow 2.4
  • Python 3.8 mit Jupyter Notebook

Schritt 1: Grafikkartentreiber

Zuallererst mal muss der Grafikkartentreiber auf dem letzten Stand sein. Aktuell im Dezember 2020 ist das die Version 456.81, diese kann auf der NVIDIA Seite heruntergeladen werden.

Schritt 2: Microsoft Visual Studio

Manchmal muss man einfach nicht fragen, warum…. aber für den folgenden Schritt – die Installation des NVIDIA CUDA Toolkits – wird Microsoft Visual Studio benötigt. Ansonsten erscheint bei der Installation das Toolkits eine Meldung und es werden wohl nicht alle benötigten Bibliotheken installiert.

Nun ja, jedenfalls habe ich die Microsoft Visual Studio Community Edition installiert die hier verfügbar ist: Microsoft Visual Studio

Die Installation erfolgt unproblematisch über die heruntergeladene Datei. Es müssen nicht zwingend irgendwelche optionalen Pakete ausgewählt werden.

Schritt 3: NVIDIA CUDA Toolkit

Das CUDA Toolkit von NVIDIA bringt die Windows Bibliotheken mit um die Grafikkarte parallelisiert nutzen zu können. TensorFlow benötigt diese Bibliotheken für die Nutzung der GPU.

Wichtig ist das die Version von TensorFlow zu der CUDA Version passt. Ich nutze aktuell TensorFlow 2.4, dazu passend ist die Version 11.1 des CUDA Toolkits das hier heruntergeladen werden kann: NVIDIA CUDA Download

Auf der TensorFlow-GPU-Seite sind die aktuellen Versions-Anforderungen im Bereich „Software Requirements“ auch noch mal im Detail gelistet.

Installation erfolgt ebenfalls unproblematisch über die heruntergeladene Datei, wie beschrieben sollte halt vorher das Visual Studio vorhanden sein damit auch wirklich alles installiert wird.

Schritt 4: NVIDIA cuDNN

So, hier noch mal ein paar neue Bibliotheken, diesmal wohl speziell für das Deep Learning auf der GPU, werden ebenfalls von TensorFlow benötigt.

Auch hier ist wieder das penible Einhalten der richtigen Version wichtig, bitte wieder auf der TensorFlow-GPU-Seite prüfen.

Für mich mit TensorFlow 2.4 und CUDA 11.1 ist das die cuDNN Version 8.0.4 die hier heruntergeladen werden kann: NVIDIA cuDNN Download

Für den Download wird ein NVIDIA Entwickleraccount benötigt, der aber kostenlos angelegt werden kann.

Zur Installation muss man die heruntergeladene ZIP Datei entpacken und die enthaltenen Ordner händisch in das CUDA Toolkit Verzeichnis kopieren.

Die entpackte cuDNN ZIP Datei sieht so aus…

Also einfach die drei Ordner „bin“, „include“, „lib“ und die Textdatei auswählen und in das CUDA Installationsverzeichnis kopieren, bei mir liegt das unter:

C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1

Mehr Dokumentation zur cuDNN Installation gibt es auf der NVIDIA Seite hier.

Warum man bei NVIDIA die beiden Pakete nicht einfach bündelt und bei der Installation auswählbar macht ist mir schleierhaft. Aber gut, so ist es halt.

Schritt 5: Windows Path Systemvariable

Als nächstes müssen wir noch die Windows „Path“ Systemvariable anpassen. Und zwar benötigen wir die folgenden Einträge im Pfad:

  • <CUDA-Installationspfad>\bin
  • <CUDA-Installationspfad>\libnvvp
  • <CUDA-Installationspfad>\include
  • <CUDA-Installationspfad>\extras\CUPTI\lib64

Bei mir sieht das dann so aus:

Weitere Details hierzu auch auf der TensorFlow GPU Seite im Bereich „Windows Setup“.

Schritt 6: Anaconda und Python

Eventuell habt ihr ja schon eure eigene Python Umgebung am Start, dann könnt ihr diesen Schritt natürlich überspringen. Falls nicht, ich persönlich arbeite auf Windows mit Anaconda als Plattform für Python und Jupyter Notebooks.

Anaconda kann hier heruntergeladen werden: Anaconda Download

Eine Installationsanleitung für Windows gibt es hier: Anaconda Windows Installation

Egal ob schon vorhanden oder neu installiert sollte wir erst mal die Installation auf den letzten Stand bringen. Dazu unter Windows eine Anaconda Powershell als Administrator aufmachen (Auf „Start“ klicken -> eingeben „anaconda“ -> Rechtsklick auf „Anaconda Powershell Prompt“ -> Als Administrator ausführen) und folgende Befehle eingeben:

conda update conda

conda update anaconda

conda update python

conda update --all

Schritt 7: Installation TensorFlow

Nun sind wir endlich bei der eigentlichen TensorFlow Installation angelangt, lange genug hat es ja gedauert.

Zuerst ein mal sollten wir wieder ein Anaconda Prompt öffnen und eine eigene Umgebung anlegen für TensorFlow:

conda create --name tensorflow

Dann wechseln wir auf unsere neue „tensorflow“ Umgebung:

conda activate tensorflow

Und endlich installieren wir hier TensorFlow selbst:

pip install tensorflow

Ich nutze hier pip zur Installation weil im Dezember 2020 die TernsorFlow Pakete in Anaconda noch auf Version 2.3 waren, und ich ja die Version 2.4 nutzen möchte. TensorFlow kann mittlerweile automatisch erkennen ob eine GPU vorhanden ist, daher muss kein separates tensorflow-gpu Paket mehr installiert werden.

Ich musste dann allerdings in Wahrheit doch noch ein paar mehr Befehle eingeben damit ich installieren konnte. Im Detail waren das:

pip install --upgrade pip
pip install numpy
pip install pandas
pip install tensorflow
pip install jupyter

Schritt 8: Test in Jupyter Notebook

So, schon gespannt ob das nun funktioniert nach dem Installations-Drama? Ja, ich auch.

Also los, starten wir Jupyter Notebook mit dem Befehl

jupyter notebook

Damit sollte sich der Browser automatisch öffnen mit der Jupyter Umgebung. Legt ein neues Notebook an und führt folgende Befehle aus. Ich hab auch Screenshots der zu erwarteten Ausgaben mit eingefügt. So sollte das auch bei euch hoffentlich auch aussehen.

import tensorflow as tf
print('TensorFlow version: {version}'.format(version=tf.version))
print('Eager mode enabled: {mode}'.format(mode=tf.executing_eagerly()))

Das schaut schon mal gut aus. Dann wollen wir mal schauen ob TensorFlow unsere GPU auch erkennt:

print("Num GPUs Available: ", len(tf.config.experimental.list_physical_devices('GPU')))
print('GPU available: {gpu_available}'.format(gpu_available=tf.config.list_physical_devices('GPU')))

Perfekt. Damit können wir arbeiten. Sollte bei euch keine GPU erkannt werden dann schaut in die Konsolenausgabe des Jupyter Notebooks. Dort gibt es Ausgaben zu den gefundenen oder eben nicht gefundenen Bibliotheken:

Wenn hier irgendwas mit „Missing“ steht müsst ihr schauen das ihr diese DLL noch bekommt.

Ich musst bei mir z.B. noch die Datei „cusolver64_10.dll“ aus dem CUDA Toolkit 10.x in das Verzeichnis „C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\bin“ kopieren damit es funktioniert. Aber dieses Problem in TensorFlow sollte hoffentlich mittlerweile behoben sein, ich hatte jedenfalls den hier beschriebenen Fehler bei mir, den ich damit beheben konnte.

Finale: Ein Modell trainieren

Jetzt wollen wir aber dann auch mal Last auf System bringen. Dazu lassen wir ein kleines Machine Learning Modell mit einem Beispieldatensatz laufen.

Über den folgenden Parameter stellen wir sicher das TensorFlow Informationen zum verwendeten Gerät in die Konsole schreibt:

tf.debugging.set_log_device_placement(True)

Den Beispieldatensatz aus den MNIST Daten (handgeschriebene Ziffern) können wir direkt über KERAS herunterladen:

mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

Dann definieren wir uns ein einfaches Deep Learning Netzwerk:

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(input_shape=(28, 28)),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10)
])
loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
model.compile(optimizer='adam', loss=loss_fn, metrics=['accuracy'])

Und lassen es mit 10 Durchgängen trainieren:

model.fit(x_train, y_train, epochs=10)

In der Konsole des Jupyter Notebooks sollte folgende Ausgabe mit „Created TensorFlow device“ bla bla „GPU:0“ auftauchen:

Sieht gut aus, als Gerät wird unsere GPU aufgeführt, d.h. TensorFlow verwendet für das Training wirklich die Grafikkarte. Puh, geschafft.

… Wenn dir das gefallen hat – du also auch den nötigen Hang zum Masochisten hast um dir das anzutun – dann folge mir auf Twitter um den nächsten Beitrag nicht zu verpassen…