Mémo pour installer et tester l’utilisation du GPU NVidia dans un container Docker.
Inspiré de : https://marmelab.com/blog/2018/03/21/using-nvidia-gpu-within-docker-container.html
Environnement
- Ubuntu 18.04 LTS – 16Go – Intel i5-4690k
- NVidia GeForce GTX 960 4Go
Les commandes sont exécutées avec l’utilisateur root :
1 |
command sudo -i |
Installation
Driver NVidia + Cuda
Sources :
- https://developer.nvidia.com/cuda-downloads
- https://docs.nvidia.com/cuda/cuda-quick-start-guide/index.html#ubuntu-x86_64
Installation par le réseau :
1 2 3 4 5 6 |
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin sudo mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600 sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub sudo add-apt-repository "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/ /" sudo apt-get update sudo apt-get -y install cuda nvidia-cuda-toolkit |
Méthode manuelle :
Récupérer la dernière version du fichier cuda-repo-ubuntu1804_xx.x.xxx-x_amd64.deb à cette URL : https://developer.download.nvidia.com/compute/cuda/repos/
Avec l’utilisateur root :
1 2 3 4 |
command dpkg --install cuda-repo-ubuntu1804_xx.x.xxx-x_amd64.deb command apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub command apt update command apt install cuda nvidia-cuda-toolkit |
Dans tous les cas :
Il faut impérativement rebooter le PC pour activer et utiliser le service nvidia-persistenced.
Après reboot, vérifier que le service est bien en fonction : « Active: active (running) »
1 |
command systemctl status nvidia-persistenced.service |
Résultat :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
● nvidia-persistenced.service - NVIDIA Persistence Daemon Loaded: loaded (/lib/systemd/system/nvidia-persistenced.service; static; vendor preset: enabled) Active: active (running) since Wed 2019-05-08 10:22:49 CEST; 1h 22min ago Main PID: 3083 (nvidia-persiste) Tasks: 1 (limit: 4915) CGroup: /system.slice/nvidia-persistenced.service └─3083 /usr/bin/nvidia-persistenced --user nvidia-persistenced --no-persistence-mode --verbose mai 08 10:22:49 blenderstorm.local systemd[1]: Starting NVIDIA Persistence Daemon... mai 08 10:22:49 blenderstorm.local systemd[1]: Started NVIDIA Persistence Daemon. mai 08 10:22:49 blenderstorm.local nvidia-persistenced[3083]: Verbose syslog connection opened mai 08 10:22:49 blenderstorm.local nvidia-persistenced[3083]: Now running with user ID 121 and group ID 127 mai 08 10:22:49 blenderstorm.local nvidia-persistenced[3083]: Started (3083) mai 08 10:22:49 blenderstorm.local nvidia-persistenced[3083]: device 0000:01:00.0 - registered mai 08 10:22:49 blenderstorm.local nvidia-persistenced[3083]: Local RPC services initialized |
Sous l’utilisateur normal avec lequel on utilise Docker.
Ajouter dans le fichier ~/.bashrc avec les lignes suivantes :
1 2 3 |
# CUDA export PATH="/usr/local/cuda/bin:$PATH" export LD_LIBRARY_PATH="/usr/local/cuda/lib64:$LD_LIBRARY_PATH" |
Puis forcer la prise en compte :
1 |
command source ~/.bashrc |
Véroifier que tout fonctionne :
1 |
command watch nvidia-smi |
Si le résultat donne le message ci-dessous, vérifier l’installation de ‘nvidia-cuda-toolkit’.
1 |
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running. |
Docker NVidia
Source : https://github.com/NVIDIA/nvidia-docker
Pour aller vite, voici les commandes à utiliser :
1 2 3 4 5 6 |
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-get update && sudo apt-get install -y nvidia-container-toolkit sudo systemctl restart docker |
[DEPRECARTED] Installer nvidia-docker2 :
1 2 |
command apt install nvidia-docker2 command pkill -SIGHUP dockerd |
Tester
Avec l’utilisateur normal (pas root).
L’image pèse plus d’1 Go !!
1 |
command docker run --runtime=nvidia --rm nvidia/cuda nvidia-smi |
Résultat :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Wed May 8 13:03:48 2019 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 418.56 Driver Version: 418.56 CUDA Version: 10.1 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 GeForce GTX 960 Off | 00000000:01:00.0 On | N/A | | 0% 54C P0 35W / 208W | 332MiB / 4035MiB | 1% Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| +-----------------------------------------------------------------------------+ |
Définir nvidia comme runtime par défaut
Avec l’utilisateur root, éditer le fichier /etc/docker/daemon.json et ajouter le ligne « default-runtime » :
1 2 3 4 5 6 7 8 9 |
{ "runtimes": { "nvidia": { "path": "nvidia-container-runtime", "runtimeArgs": [] } }, "default-runtime": "nvidia" } |
Ne pas oublier la virgule sur la ligne précédente.
Relancer le service docker :
1 |
command systemctl restart docker |
Avec l’utilisateur normal, vérifier si Docker utilise bien le runtime nvidia.
Voir les lignes « Runtimes » et « Default Runtime ».
1 |
command docker info |
Résultat :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
Containers: 7 Running: 1 Paused: 0 Stopped: 6 Images: 9 Server Version: 18.09.6 Storage Driver: overlay2 Backing Filesystem: extfs Supports d_type: true Native Overlay Diff: true Logging Driver: json-file Cgroup Driver: cgroupfs Plugins: Volume: local Network: bridge host macvlan null overlay Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog Swarm: inactive <strong>Runtimes: nvidia runc Default Runtime: nvidia</strong> Init Binary: docker-init containerd version: bb71b10fd8f58240ca47fbb579b9d1028eea7c84 runc version: 2b18fe1d885ee5083ef9f0838fee39b62d653e30-dirty init version: fec3683 Security Options: apparmor seccomp Profile: default Kernel Version: 4.15.0-48-generic Operating System: Ubuntu 18.04.2 LTS OSType: linux Architecture: x86_64 CPUs: 4 Total Memory: 15.62GiB Name: blenderstorm.local ID: ZTGV:XBUU:DNQK:XOVT:72EC:GVSD:6USI:YF3G:BGEV:J6Q5:QGLR:WWWW Docker Root Dir: /var/lib/docker Debug Mode (client): false Debug Mode (server): false Registry: https://index.docker.io/v1/ Labels: Experimental: false Insecure Registries: 127.0.0.0/8 Live Restore Enabled: false Product License: Community Engine WARNING: No swap limit support |
Du coup, plus besoin d’utiliser l’argument « –runtime=nvidia »:
1 |
command docker run --rm nvidia/cuda nvidia-smi |
Ni dans le fichier docker-compose.yml comme spécifié dans la doc https://devblogs.nvidia.com/gpu-containers-runtime/
Bonjour Jérôme ,
Merci de clarifier tout cela en un seul exposé.
Je fonctionnais autrefois sur un cpu (ou plusieurs avec MPI) et un (ou plusieurs) GPUs , K20, P100 … avec en plus sur le CPU (intel ou amd) les biblios MKL, BLAS 1, 2, 3 et Lapack par exemple déjà installées sur l’hôte CPU.
J’avais en outre un .bashrc adapté avec les paths ou retrouver ces biblios sur le système.
L’idée est de tourner sur avec docker sur un système distant Amazon par exemple.
Comment faire pour inclure ces biblios ET écrire le bashrc appropriés ?
Question subsidiaire :
comment éviter que mon code source C/CUDA soit copié, lors d’une démo sur un système distant Amazon, par un client indélicat ?
Merci pour vos conseils.
Alain
Bonjour Alain,
Projet intéressant, mais je n’ai pas les moyens de tester.
Mais sur AWS, le coût peut rapidement grimper sur les machines avec GPU.
Et vu la puissance d’AWS, je ne vois pas trop l’avantage de monter une machine pour faire tourner un Docker sur GPU (et sur CPU d’ailleurs, voir ECS pour ça).
Bon courage !
Jérôme