Une histoire sur la compatibilité d'un Dockerfile existant avec le GPU

introduction

Dans cet article, les fichiers Dockerfile et docker-compose que je souhaitais créer en machine learning ne supportaient pas le GPU, je vais donc parler de la cause et des contre-mesures. Cependant, veuillez noter que je ne fais des recherches sur docker que depuis environ un mois et que j'ai peut-être des connaissances erronées. M (_ _) m

environnement

Personne cible

--Personnes qui souhaitent rendre compatible le GPU Docker --Les personnes qui veulent savoir si elles peuvent prendre en charge le GPU

Dockerfile et docker-compose.yml utilisés

Cette fois, j'ai essayé d'utiliser un exemple de projet d'un certain livre, donc je ne peux pas tout mettre, mais je ne décrirai que la partie minimale.

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

Ce que je veux faire, c'est créer un environnement python à partir de environment.yml en utilisant miniconda et lancer le notebook jupyter avec docker-compose. environment.yml contient tensorflow2.1, jupyter, etc.

Cependant, il ne reconnaît pas le GPU tel quel.

Comment vérifier si le GPU est reconnu

Il existe plusieurs façons d'utiliser le GPU, je vais donc les résumer ici. En les exécutant dans le conteneur Docker, vous pouvez voir si vous pouvez utiliser le GPU. nvidia-smi Il s'agit d'une méthode pour vérifier si le GPU peut être reconnu comme un périphérique physique. Si vous pouvez utiliser le GPU à partir du docker, il acceptera essentiellement les commandes. tf.config.list_physical_devices('GPU') C'est celui qui fonctionne en python. Veuillez utiliser après l'importation de tensorflow. Cela renverra une liste des GPU disponibles. À ce stade, s'il ne peut pas être utilisé, divers avertissements apparaîtront, vous pouvez donc l'utiliser comme un indice pour en saisir la cause. tf.test.is_gpu_available() C'est aussi une fonction python. C'est la même chose que la fonction ci-dessus sauf qu'elle renvoie True / False. ※ lspci | grep -i nvidia Je vois souvent cette méthode lorsque je la vérifie, mais je n'ai pas pu utiliser cette commande dans docker. Est-ce à cause de la configuration minimale ...?

Cause de l'impossibilité d'utiliser le GPU

Lorsque j'ai essayé la commande ci-dessus pour le conteneur Docker que je voulais utiliser, tous les résultats étaient qu'il ne reconnaissait pas le GPU. À la suite de nombreuses recherches, j'ai trouvé qu'il y avait trois raisons principales.

--docker-compose n'est pas entièrement compatible avec le GPU --CUDA et cudnn ne sont pas inclus dans le conteneur docker --tensorflow ne reconnaît pas CUDA etc.

Regardons de plus près un par un.

Prise en charge du GPU pour docker-compose

Je parlerai en supposant que nvidia-docker (nvidia-container-toolkit) est déjà installé sur le système d'exploitation hôte. docker prend en charge l'option gpus à partir de 19.03, et en définissant --gpus all, il reconnaîtra physiquement le périphérique GPU et nvidia-smi pourra être utilisé. Cependant, docker-compose ne prend pas en charge la balise gpus. Par conséquent, utilisez la balise d'exécution pour la rendre compatible avec le GPU.

Il existe de nombreuses façons de prendre en charge gpu avec docker-compose, comme cet article, si vous recherchez "docker-compose GPU", mais de combien de façons Je pense que c'est difficile parce que c'est différent. Les principaux points à vérifier sont les suivants.

Après avoir effectué ces vérifications et modifications, si vous utilisez nvidia-smi dans le conteneur lancé par docker-compose, nous espérons pouvoir utiliser nvidia-smi.

Prise en charge de CUDA et cudnn

Il était très difficile d'étudier le problème à partir d'ici. La prise en charge du GPU pour docker et docker-compose reconnaît uniquement le GPU en tant que périphérique physique et ne signifie pas que les calculs GPU peuvent être effectués. Par conséquent, CUDA et cudnn doivent être installés dans le conteneur docker. La plupart des exemples utilisent des images telles que nvidia / cuda, des images tensorflow, etc., mais ces conteneurs contiennent CUDA. Cependant, je pense que la plupart des images comme miniconda ne prennent pas en charge le GPU.

Pour être honnête, je pense que cette mesure dépend de l'image Docker de base. Dans mon environnement, j'ai arrêté la base miniconda, basée sur nvidia / cuda, et installé miniconda avec RUN. Si l'image de base a une balise ou une image associée qui contient cuda ou cudnn, je pense que vous devriez la sélectionner à partir du hub docker. Si vous ne pouvez pas le baser sur nvidia / cuda et que vous n'avez pas de version avec cuda, je pense que le seul moyen est d'ajouter cuda ou cudnn dans votre Dockerfile. Je ne sais pas comment l'écrire dans le Dockerfile, alors demandez à quelqu'un qui le sait ... Si vous le faites honnêtement, il est possible que le cache, etc. reste et qu'il ne soit pas léger.

Reconnaissance CUDA du tensorflow

J'ai trouvé une version de CUDA ou cudnn et c'est mauvais, mais tensorflow doit avoir le CUDA ou cudnn correspondant installé. Cela peut ne pas fonctionner si la version est légèrement différente. Assurez-vous que vous disposez d'une image Docker contenant la version CUDA correspondante. (Référence: Tensorflow build configuration)

De plus, à partir de là, dans certains cas, tensorflow peut ne pas le trouver même s'il a été saisi. Il est possible que la variable d'environnement LD_LIBRARY_PATH ne contienne pas le chemin d'accès aux fichiers liés à cuda. Vous pouvez trouver des fichiers tels que libcudart et libcurand dans tous les fichiers en recherchant find / -name libcu *. Ajoutez le dossier les contenant à LD_LIBRARY_PATH.

Si tensorflow reconnaît le GPU de la manière précédente, c'est réussi! Toutes nos félicitations.

Bonus: À propos de tensorRT

Comme c'est le cas dans mon environnement, certains avertissements apparaissent lorsque j'importe tensorflow. Il indique que tensorRT ne peut pas y être utilisé. Cela ne signifie pas que tensorflow ne peut pas être utilisé, mais qu'il n'inclut pas tensorRT, ce qui rend les calculs GPU encore plus rapides. Donc, même s'il sort, je pense qu'il reconnaîtra le GPU sans aucun problème.

en conclusion

Cela n'a peut-être pas été utile car je viens d'écrire mon expérience à la hâte ... En premier lieu, si vous basez l'image docker de tensorflow-gpu depuis le début, un tel problème est peu susceptible de se produire, et il reconnaîtra le GPU sans attacher la balise gpu, il est donc recommandé de commencer avec une telle image si possible. Faire.

Recommended Posts

Une histoire sur la compatibilité d'un Dockerfile existant avec le GPU
L'histoire de la fabrication d'un Othello ordinaire à Java
L'histoire de l'ajout du dernier Node.js à DockerFile
L'histoire de la création d'un proxy inverse avec ProxyServlet
L'histoire de la création de Dr.Orchid avec LINE BOT
L'histoire de la création de DTO, semblable à Dao avec Java, SQLite
Une histoire de rendre catkin_make de rosjava compatible hors ligne
[Édition Java] Histoire de la sérialisation
L'histoire de @ViewScoped dévore la mémoire
L'histoire de la création d'un jeu d'Othello de type communication avec Scala.
L'histoire de la rencontre avec l'annotation personnalisée Spring
L'histoire de la création d'un lanceur de jeu avec une fonction de chargement automatique [Java]
L'histoire de la mise à jour du Docker Container de Sonar Qube
L'histoire de RxJava souffrant de NoSuchElementException
L'histoire de l'écriture de Java dans Emacs
L'histoire de la création d'une application Android capable d'ajuster la fréquence d'échantillonnage du capteur d'accélération
L'histoire de la comparaison de chaînes de bas niveau en Java
L'histoire de l'apprentissage de Java dans la première programmation
L'histoire de l'introduction de la communication Ajax à Ruby
L'histoire de la montée de la série Spring Boot 1.5 à la série 2.1
L'histoire du réglage de l'application Android avec libGDX
Renommez le nom du package d'un fichier jar existant
Une histoire sur la création d'un Builder qui hérite du Builder
L'histoire de l'initialisation de Money :: Currency pendant les tests
Nous avons extrait les meilleurs plastiques de Dockerfile!
L'histoire d'une exception d'état illégale dans Jetty.