Eine Geschichte darüber, wie eine vorhandene Docker-Datei mit der GPU kompatibel gemacht werden kann

Einführung

Dieser Artikel befasst sich mit den Ursachen und Gegenmaßnahmen, da die Dockerfile- und Docker-Compose-Dateien, die ich maschinell lernen wollte, die GPU nicht unterstützten. Bitte beachten Sie jedoch, dass ich erst seit ungefähr einem Monat nach Docker recherchiere und möglicherweise falsche Kenntnisse habe. M (_ _) m

Umgebung

Zielperson

Dockerfile und docker-compose.yml verwendet

Dieses Mal habe ich versucht, ein Beispielprojekt eines bestimmten Buches zu verwenden, daher kann ich nicht alles einfügen, aber ich werde nur den minimalen Teil beschreiben.

Dockerfile


FROM continuumio/miniconda3:latest

COPY environment.yml /tmp/
RUN conda update -y -n base conda \
    && conda env create -f /tmp/environment.yml \
    && conda clean -y -t \
    && rm /tmp/environment.yml

ENV PATH /opt/conda/envs/tf/bin:$PATH

docker-compose.yml


version: "3"
services:
  tf:
    build:
      context: ../
      dockerfile: ./docker/Dockerfile
    container_name: tf
    image: tf
    ports:
      - "8888:8888"
    volumes:
      - ../:/tf
    command: /opt/conda/envs/tf/bin/jupyter notebook --ip='0.0.0.0' --port=8888 --no-browser

Was ich tun möchte, ist eine Python-Umgebung aus environment.yml mit miniconda zu erstellen und jupyter notebook mit docker-compose zu starten. environment.yml enthält tensorflow2.1, jupyter usw.

Die GPU wird jedoch nicht so erkannt, wie sie ist.

So überprüfen Sie, ob die GPU erkannt wird

Es gibt verschiedene Möglichkeiten, die GPU zu verwenden, daher werde ich sie hier zusammenfassen. Wenn Sie diese im Docker-Container ausführen, können Sie feststellen, ob Sie die GPU verwenden können. nvidia-smi Dies ist eine Methode, um zu überprüfen, ob die GPU als physisches Gerät erkannt werden kann. Wenn Sie die GPU vom Docker aus verwenden können, werden grundsätzlich Befehle akzeptiert. tf.config.list_physical_devices('GPU') Dies ist diejenige, die in Python läuft. Bitte nach dem Import von Tensorflow verwenden. Dadurch wird eine Liste der verfügbaren GPUs zurückgegeben. Wenn es zu diesem Zeitpunkt nicht verwendet werden kann, werden verschiedene Warnungen angezeigt, sodass Sie dies als Hinweis verwenden können, um die Ursache zu erfassen. tf.test.is_gpu_available() Dies ist auch eine Python-Funktion. Dies ist dasselbe wie die obige Funktion, außer dass sie True / False zurückgibt. ※ lspci | grep -i nvidia Ich sehe diese Methode oft, wenn ich sie überprüfe, aber ich konnte diesen Befehl im Docker nicht verwenden. Liegt es an der minimalen Konfiguration ...?

Ursache dafür, dass die GPU nicht verwendet werden kann

Als ich den obigen Befehl für den Docker-Container ausprobierte, den ich verwenden wollte, war das Ergebnis, dass die GPU nicht erkannt wurde. Als Ergebnis vieler Nachforschungen habe ich festgestellt, dass es drei Hauptgründe gibt.

--docker-compose ist nicht vollständig mit der GPU kompatibel --CUDA und cudnn sind nicht im Docker-Container enthalten --tensorflow erkennt CUDA usw. nicht.

Schauen wir uns das nacheinander genauer an.

GPU-Unterstützung für Docker-Compose

Ich gehe davon aus, dass nvidia-docker (nvidia-container-toolkit) bereits auf dem Host-Betriebssystem installiert ist. Docker unterstützt die Option gpus ab 19.03. Durch Festlegen von "--gpus all" wird das GPU-Gerät physisch erkannt und nvidia-smi kann verwendet werden. Docker-compose unterstützt das gpus-Tag jedoch nicht. Verwenden Sie daher das Laufzeit-Tag, um es GPU-kompatibel zu machen.

Es gibt viele Möglichkeiten, GPU mit Docker-Compose zu unterstützen, z. B. diesen Artikel, wenn Sie nach "Docker-Compose-GPU" suchen, aber wie viele Möglichkeiten Ich denke, es ist schwierig, weil es anders ist. Die wichtigsten zu überprüfenden Punkte sind wie folgt.

--Stellen Sie die Docker-Compose-Version auf 1.19 oder höher ein

Wenn Sie nach diesen Überprüfungen und Änderungen nvidia-smi in dem von docker-compose gestarteten Container verwenden, können Sie hoffentlich nvidia-smi verwenden.

Unterstützung für CUDA und cudnn

Es war sehr schwierig, das Problem von hier aus zu untersuchen. Die GPU-Unterstützung für Docker und Docker-Compose erkennt die GPU nur als physisches Gerät und bedeutet nicht, dass GPU-Berechnungen durchgeführt werden können. Daher müssen CUDA und cudnn im Docker-Container installiert sein. Die meisten Beispiele verwenden Bilder wie NVIDIA / Cuda, Tensorflow-Bilder usw. Diese Container enthalten jedoch CUDA. Ich denke jedoch, dass die meisten Bilder wie Miniconda keine GPU unterstützen.

Um ehrlich zu sein, denke ich, dass diese Maßnahme vom Basis-Docker-Image abhängt. In meiner Umgebung habe ich die auf nvidia / cuda basierende Miniconda-Basis gestoppt und Miniconda mit RUN installiert. Wenn das Basis-Image ein Tag oder ein verwandtes Image hat, das cuda oder cudnn enthält, sollten Sie es aus dem Docker-Hub auswählen. Wenn Sie es nicht auf nvidia / cuda basieren können und keine Version mit cuda haben, besteht die einzige Möglichkeit darin, cuda oder cudnn in Ihre Docker-Datei aufzunehmen. Ich weiß nicht, wie ich es in die Docker-Datei schreiben soll, also frag jemanden, der es weiß ... Wenn Sie es ehrlich tun, besteht die Möglichkeit, dass der Cache usw. erhalten bleibt und nicht leichtgewichtig ist.

CUDA-Erkennung des Tensorflusses

Ich habe eine Version von CUDA oder cudnn gefunden und es ist schlecht, aber Tensorflow muss die entsprechende CUDA oder cudnn installiert haben. Es funktioniert möglicherweise nicht, wenn die Version etwas anders ist. Stellen Sie sicher, dass Sie ein Docker-Image haben, das die entsprechende CUDA-Version enthält. (Referenz: Tensorflow-Build-Konfiguration)

Darüber hinaus kann Tensorflow es von hier aus in einigen Fällen nicht finden, obwohl es eingegeben wurde. Möglicherweise enthält die Umgebungsvariable LD_LIBRARY_PATH nicht den Pfad zu den cuda-bezogenen Dateien. Sie können Dateien wie libcudart und libcurand in allen Dateien finden, indem Sie nach "find / -name libcu *" suchen. Fügen Sie den Ordner, der sie enthält, zu LD_LIBRARY_PATH hinzu.

Wenn Tensorflow die GPU auf die vorherige Weise erkennt, ist es erfolgreich! Herzliche Glückwünsche.

Bonus: Über TensorRT

Wie in meiner Umgebung werden beim Importieren von Tensorflow einige Warnungen angezeigt. Es heißt, dass tensorRT dort nicht verwendet werden kann. Dies bedeutet nicht, dass der Tensorflow nicht verwendet werden kann, sondern dass TensorRT nicht enthalten ist, wodurch die GPU-Berechnungen noch schneller werden. Selbst wenn es herauskommt, denke ich, dass es die GPU ohne Probleme erkennen wird.

abschließend

Es war vielleicht nicht hilfreich, weil ich meine Erfahrung so schnell geschrieben habe ... Wenn Sie das Docker-Image von tensorflow-gpu von Anfang an als Basis verwenden, ist es unwahrscheinlich, dass ein solches Problem auftritt, und es erkennt die GPU, ohne das gpu-Tag anzuhängen. Es wird daher empfohlen, wenn möglich mit einem solchen Image zu beginnen. Machen.

Recommended Posts

Eine Geschichte darüber, wie eine vorhandene Docker-Datei mit der GPU kompatibel gemacht werden kann
Die Geschichte eines gewöhnlichen Othello in Java
Die Geschichte des Hinzufügens der neuesten Node.js zu DockerFile
Die Geschichte, einen Reverse-Proxy mit ProxyServlet zu erstellen
Die Geschichte, Dr. Orchid mit LINE BOT zu machen
Die Geschichte von dto, dao-like mit Java, SQLite
Eine Geschichte darüber, wie catkin_make von Rosjava offline kompatibel gemacht wird
[Java Edition] Geschichte der Serialisierung
Die Geschichte von @ViewScoped, die Speicher verschlingt
Die Geschichte eines Othello-Spiels vom Kommunikationstyp mit Scala.
Die Geschichte der Begegnung mit Spring Custom Annotation
Die Geschichte eines Game Launcher mit automatischer Ladefunktion [Java]
Die Geschichte der Aktualisierung des Docker-Containers von Sonar Qube
Die Geschichte von RxJava, das unter NoSuchElementException leidet
Die Geschichte des Schreibens von Java in Emacs
Die Geschichte einer Android-Anwendung, mit der die Abtastfrequenz des Beschleunigungssensors angepasst werden kann
Die Geschichte des einfachen String-Vergleichs in Java
Die Geschichte des Lernens von Java in der ersten Programmierung
Die Geschichte der Einführung der Ajax-Kommunikation in Ruby
Die Geschichte der Erhöhung der Spring Boot 1.5-Serie auf die 2.1-Serie
Die Geschichte der Optimierung der Android-App mit libGDX
Benennen Sie den Paketnamen einer vorhandenen JAR-Datei um
Eine Geschichte über das Erstellen eines Builders, der den Builder erbt
Die Geschichte der Initialisierung von Money :: Currency während des Testens
Wir haben die besten Kunststoffe von Dockerfile extrahiert!
Die Geschichte einer illegalen staatlichen Ausnahme in Jetty.