Comment exécuter des conteneurs Docker Compose avec un accès GPU
L’accès GPU dans Docker vous permet de conteneuriser les charges de travail exigeantes telles que les applications d’apprentissage automatique. Les GPU ne sont pas automatiquement disponibles lorsque vous démarrez un nouveau conteneur, mais ils peuvent être activés avec le --gpus
drapeau pour docker run
ou en ajoutant des champs supplémentaires à un docker-compose.yml
dossier.
Dans cet article, nous allons montrer comment activer la prise en charge du GPU dans Docker Compose. Vous aurez besoin de Docker Compose version v1.28 ou plus récente pour suivre le guide. Les GPU ne sont pas pris en charge dans les versions Compose v1.18 et antérieures ; les versions entre v1.19 et v1.27 utilisent une structure de champ héritée qui offre moins de contrôle.
Sommaire
Préparation de votre système
Votre hôte Docker doit être préparé avant de pouvoir exposer votre matériel GPU. Bien que les conteneurs partagent le noyau de votre hôte, ils ne peuvent pas voir les packages système que vous avez installés. Un conteneur ordinaire ne disposera pas des pilotes de périphérique qui s’interfacent avec votre GPU.
Vous pouvez activer la prise en charge des GPU NVIDIA en installant le Docker Container Toolkit de NVIDIA :
distribution=$(. /etc/os-release;echo $ID$VERSION_ID) && curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - && curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list sudo apt update sudo apt install -y nvidia-docker2 sudo systemctl restart docker
Ce package encapsule l’environnement d’exécution du conteneur de Docker avec une interface vers le pilote NVIDIA de votre hôte. Inspecter votre /etc/docker/daemon.json
confirmera que l’environnement d’exécution du conteneur configuré a été modifié. La boîte à outils NVIDIA gérera l’injection de connexions de périphériques GPU lors du démarrage de nouveaux conteneurs. Il passera ensuite à votre environnement d’exécution de conteneur habituel.
$ cat /etc/docker/daemon.json { "runtimes": { "nvidia": { "path": "nvidia-container-runtime", "runtimeArgs": [] } } }
Préparation de votre image
L’accès GPU dans Docker dépend également de la configuration correcte de votre image de conteneur. Il est généralement plus simple de baser votre image sur une variante de nvidia/cuda
. Ce point de départ fourni par NVIDIA est préconfiguré avec la prise en charge de CUDA. Installez tous les langages de programmation dont vous avez besoin, puis copiez-y votre code dépendant du GPU :
FROM nvidia/cuda:11.4.0-base-ubuntu20.04 RUN apt update && apt-get install -y python3 python3-pip && pip install tensorflow-gpu COPY tensor.py . ENTRYPONT ["python3", "tensor.py"]
Vous devez utiliser la même version de CUDA que celle que vous avez installée sur votre hôte. Vous pouvez le vérifier en exécutant nvidia-smi
:
$ nvidia-smi Tue May 10 19:15:00 2022 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 470.103.01 Driver Version: 470.103.01 CUDA Version: 11.4 | |-------------------------------+----------------------+----------------------+ ...
Vous pouvez maintenant écrire un fichier Docker Compose pour démarrer votre conteneur avec une pièce jointe GPU.
Accéder aux GPU dans Docker Compose
Les GPU sont référencés dans un docker-compose.yml
fichier via le deploy.resources.reservations.devices
domaine au sein de vos services qui en ont besoin. Ce mécanisme vous permet d’identifier les GPU que vous souhaitez attacher. Chaque appareil sélectionné sera fourni à vos conteneurs.
Voici un exemple simple qui démarre un conteneur en utilisant le nvidia/cuda
image. Il émettra des informations sur votre GPU au démarrage du conteneur.
services: app: image: nvidia/cuda:11.4.0-base-ubuntu20.04 command: nvidia-smi deploy: resources: reservations: devices: - driver: nvidia capabilities: [gpu]
La deploy.resources.reservations.devices
Le champ spécifie les appareils que votre conteneur peut utiliser. Réglage de la driver
à nvidia
et en ajoutant le gpu
La capacité définit un périphérique GPU.
Courir docker-compose up
(ou docker compose up
pour Compose v2) pour démarrer votre conteneur :
$ docker compose up Creating network "scratch_default" with the default driver Creating scratch_app_1 ... done Attaching to scratch_app_1 app_1 | Tue May 10 14:21:14 2022 app_1 | +-----------------------------------------------------------------------------+ app_1 | | NVIDIA-SMI 470.103.01 Driver Version: 470.103.01 CUDA Version: 11.4 | app_1 | |-------------------------------+----------------------+----------------------+
Le conteneur doit réussir à accéder à votre GPU. Les versions du pilote et de CUDA correspondront à celles installées sur votre hôte.
Utilisation de plusieurs GPU
Votre conteneur reçoit l’accès à tous les GPU de votre système, sauf si une configuration supplémentaire est fournie. Il existe deux manières différentes d’accéder à un sous-ensemble de vos périphériques GPU.
Accéder à un nombre fixe d’appareils
La count
réserve un nombre spécifié d’appareils. Dans cet exemple, un système avec deux GPU fournira l’un d’eux au conteneur. C’est arbitraire lequel sera choisi.
services: app: image: nvidia/cuda:11.4.0-base-ubuntu20.04 command: nvidia-smi deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu]
Accéder à des appareils spécifiques
Vous pouvez identifier les appareils individuels de votre système à l’aide de device_ids
champ. Cela accepte un tableau d’ID de périphérique indexés 0 à fournir au conteneur. Vous pouvez trouver ces identifiants en répertoriant vos GPU avec nvidia-smi
:
$ nvidia-smi --list-gpus GPU 0: NVIDIA GeForce GTX 1080 Ti (UUID: GPU-5ba4538b-234f-2c18-6a7a-458d0a7fb348) GPU 1: NVIDIA GeForce GTX 1080 Ti (UUID: GPU-d5ce9af3-710c-4222-95f8-271db933d438) GPU 2: NVIDIA GeForce GTX 1080 Ti (UUID: GPU-50d4eb4f-7b08-4f8f-8d20-27d797fb7f19) GPU 3: NVIDIA GeForce GTX 1080 Ti (UUID: GPU-bed2d40a-c6e7-4547-8d7d-a1576c5247b2)
Pour accéder de manière fiable aux deux derniers appareils de la liste, incluez leurs ID d’appareil dans votre configuration de service :
services: app: image: nvidia/cuda:11.4.0-base-ubuntu20.04 command: nvidia-smi deploy: resources: reservations: devices: - driver: nvidia device_ids: ["2", "3"] capabilities: [gpu]
Vous pouvez utiliser count
ou device_ids
dans chacune de vos définitions de service. Vous obtiendrez une erreur lorsque vous exécuterez docker-compose up
si vous essayez de combiner les deux, spécifiez un ID d’appareil non valide ou utilisez une valeur de count
c’est plus élevé que le nombre de GPU dans votre système.
Sommaire
Les versions modernes de Docker Compose prennent en charge l’accès GPU via le deploy.resources
fonction de réservation d’appareils. Vous êtes toujours responsable de la préparation de votre environnement hôte et de l’utilisation d’une image de conteneur compatible GPU. Une fois que c’est réglé, courir docker-compose up -d
est plus simple que de se souvenir d’inclure le --gpus all
signaler chaque fois que vous utilisez docker run
.
Vous pouvez engager votre docker-compose.yml
fichier dans le contrôle de source afin que tout le monde obtienne un accès automatique au GPU. Vous devez vous assurer de standardiser sur des versions cohérentes du pilote NVIDIA, car la version utilisée par votre image doit correspondre à celle installée sur vos hôtes. À l’avenir, le support GPU de Docker pourrait également fonctionner avec les appareils Intel et AMD, mais essayer de l’utiliser aujourd’hui entraînera une erreur. NVIDIA est le seul fournisseur de GPU actuellement pris en charge par le projet Moby.