Patrice Ferlet
Patrice Ferlet
Créateur de ce blog.
Publié le nov. 9, 2023 Temps de lecture: 6 min

Me suivre sur Mastodon

Podman et Nvidia, ou comment avoir accès à son GPU dans un conteneur

thumbnail for this post

Il y a un moment que Docker peut utiliser votre carte Nvidia, et Podman n'est pas en reste. Cependant, il est important de connaître la méthode appropriée. Voici un guide détaillé pour la configuration de Podman avec Nvidia sur Fedora.

Partager sa carte graphique avec un conteneur est très intéressant. Cela évite d’une part d’avoir à installer localement toute une batterie de packages et de librairie (surtout pour CUDA qui est une plaie), de rendre jetable un test, de partager une application utilisant le Machine-Learning simplement, etc.

Bref, c’est utile et ça soulage.

Mais ce n’est pas évident à activer. La conteneurisation sert à isoler l’application du système, et là on veut absolument lui partager un périphérique. Et pas n’importe lequel, pas une imprimante USB ou une caméra… non… là on parle d’une carte graphique. Heureusement, les derniers efforts de Nvidia à proposer de la documentation et leur ouverture de certaines parties de leur travail permet de s’en sortir avec un peu plus de confort.

TL;DR

Pour les pressés, voici les étapes rapides :

# installer le dépot de nvidia container toolkit
curl -s -L https://nvidia.github.io/libnvidia-container/stable/rpm/nvidia-container-toolkit.repo | \
  sudo tee /etc/yum.repos.d/nvidia-container-toolkit.repo
# puis les outils
sudo dnf install nvidia-container-toolkit

# et on commence par créer le fichier de configuration
sudo nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml

# on corrige les soucis SELinux
nvidia-container-cli -k list | sudo restorecon -v -f -
sudo restorecon -Rv /dev

Si vous voulez utiliser Podman en “rootless”, il faut modifier avec sudo, le fichier /etc/nvidia-container-runtime/config.toml, on trouve les deux lignes qui nous intéresse :

[nvidia-container-cli]
#no-cgroups = false
no-cgroups = true

[nvidia-container-runtime]
#debug = "/var/log/nvidia-container-runtime.log"
debug = "~/.local/nvidia-container-runtime.log"

Et on peut tester, il faut bien ajouter --device nvidia.com/gpu=all et --security-opt=label=disable.

podman run --rm \
    --device nvidia.com/gpu=all \
    --security-opt=label=disable \
    ubuntu nvidia-smi -L

# ça doit vous donner un truc de ce genre:
GPU 0: NVIDIA GeForce RTX 3070 (UUID: GPU-f7187582-1105-9022-2d77-ac16ed3b10ca)

Voilà, c’est tout…

En détail…

Bon, on va expliquer pas à pas ce qu’il faut faire.

Installer les outils de Nvidia

Nvidia propose des outils assez bien foutus pour permettre à Docker et Podman (mais aussi à Kubernetes, etc…) de partager votre carte graphique avec des conteneurs OCI. Le fait est que depuis quelque temps, et ce grâce à l’explosion des travaux en Machine-Learning, Nvidia est aux avant-postes. Du coup, ils ont mis les bouchées doubles, ont ouvert une partie de leur code, et ils se sont mis à documenter correctement tout leur boxon.

Pour le coup, on peut souligner les efforts et leur dire merci.

Bref, la documentation est assez complète et les outils assez “simples” à utiliser.

Je suis sur Fedora, donc je ne vais pas tortiller pendant des heures avec Ubuntu. L’installation commence par ajouter le dépôt officiel pour Fedora:

curl -s -L https://nvidia.github.io/libnvidia-container/stable/rpm/nvidia-container-toolkit.repo | \
  sudo tee /etc/yum.repos.d/nvidia-container-toolkit.repo

Ce dépôt vous propose quelques outils, mais c’est nvidia-ctk et nvidia-container-cli qui nous intéressent. Et ces outils se trouvent dans le package nvidia-container-toolkit :

sudo dnf install nvidia-container-toolkit

À partir de là, on est paré pour la suite.

Configurer pour Podman

La doc est assez claire, mais elle va vous vous guider, ensuite, vers une autre page pour Podman.

Nvidia vous demande d’utiliser plutôt “CDI” (Container Devide Interface) pour configurer l’accès à votre périphérique. Et cette page vous demande de faire deux trois bricoles.

La première commande va générer un fichier yaml qui liste les “devices” et les “hooks” à effectuer quand le conteneur va demander l’accès à ces périphériques. Le faire à la main aurait été une plaie, là, c’est simple :

# enlevez --output=... pour voir ce qu'il va générer
sudo nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml

Après cela, vous pouvez contrôler la liste des périphériques qu’il a configuré :

nvidia-ctk cdi list
# il doit vous sortir un truc du genre
# nvidia.com/gpu=all
# nvidia.com/gpu=0

Ces lignes, ce sont les options à --device qu’on pourra donner à Podman. Vous allez voir ça juste après.

Si cette étape s’est bien passé, on va corriger les attributs SELinux au cas où… (en réalité je pense que ce n’est pas nécessaire, mais dans le doute…)

nvidia-container-cli -k list | sudo restorecon -v -f -
sudo restorecon -Rv /dev

Il reste un dernier point, et pas des moindres, c’est de corriger la manière dont on va permettre à Podman d’écrire des logs et d’utiliser les cgroups et ce, seulement si vous voulez utiliser le mode “rootless” de Podman.

C’est tout de même l’un des points forts de Podman, dont on ne s’en privera pas. Je vous conseille donc de le faire !

Ouvrez, avec les droits d’admin (donc sudo vim ou sudo nano) le fichier /etc/nvidia-container-runtime/config.toml pour toucher deux lignes:

  • La première dans le groupe nvidia-container-cli pour lui dire de se passer des cgroups (ouais bah… bon…)
  • L’autre dans le groupe nvidia-container-runtime pour lui changer le chemin des logs car, de base, il va taper dans /var/log et vous, en tant qu’utilisateur, vous ne pourrez pas le faire.

Donc en gros, trouvez les lignes (normalement commentées), copiez-les en dessous et changez la valeur. Surtout, gardez les autres lignes telles quelles :

[nvidia-container-cli]
#no-cgroups = false
no-cgroups = true

[nvidia-container-runtime]
#debug = "/var/log/nvidia-container-runtime.log"
debug = "~/.local/nvidia-container-runtime.log"

Pour référence, voici mon fichier à moi :


#accept-nvidia-visible-devices-as-volume-mounts = false
#accept-nvidia-visible-devices-envvar-when-unprivileged = true
disable-require = false
supported-driver-capabilities = "compat32,compute,display,graphics,ngx,utility,video"
#swarm-resource = "DOCKER_RESOURCE_GPU"

[nvidia-container-cli]
#debug = "/var/log/nvidia-container-toolkit.log"
environment = []
#ldcache = "/etc/ld.so.cache"
ldconfig = "@/sbin/ldconfig"
load-kmods = true
#no-cgroups = false
no-cgroups = true
#path = "/usr/bin/nvidia-container-cli"
#root = "/run/nvidia/driver"
#user = "root:video"

[nvidia-container-runtime]
#debug = "/var/log/nvidia-container-runtime.log"
debug = "~/.local/nvidia-container-runtime.log"
log-level = "info"
mode = "auto"
runtimes = ["docker-runc", "runc"]

[nvidia-container-runtime.modes]

[nvidia-container-runtime.modes.cdi]
annotation-prefixes = ["cdi.k8s.io/"]
default-kind = "nvidia.com/gpu"
spec-dirs = ["/etc/cdi", "/var/run/cdi"]

[nvidia-container-runtime.modes.csv]
mount-spec-path = "/etc/nvidia-container-runtime/host-files-for-container.d"

[nvidia-container-runtime-hook]
path = "nvidia-container-runtime-hook"
skip-mode-detection = false

[nvidia-ctk]
path = "nvidia-ctk"

Attention, quand vous mettez à jour vos packages, ce fichier est écrasé. Ou pas… en fait il y aura un fichier config.toml.rpmsave dans lequel il y aura vos anciennes modifications. Mais je vous conseille d’utiliser le fichier mis à jour, qui généralement à des modifications importantes, et de simplement remettre d’aplomb les lignes qu’on a changées.

Voilà… on a fini. Reste à tester :

podman run --rm \
    --device nvidia.com/gpu=all \
    --security-opt=label=disable \
    ubuntu nvidia-smi -L

# doit vous donner la même ligne que `nvidia-smi` en local
# pour ma part :
GPU 0: NVIDIA GeForce RTX 3060 Laptop GPU (UUID: GPU-21c9319b-4c2d-84db-f028-cd065f9d9e8f)

Important

Vous allez certainement tester des outils qui ne parlent que de Docker, alors que ça marche très bien avec Podman. La seule chose à penser c’est de ne pas utiliser le paramètre --gpus (qui ne marche pas sur Podman et je ne sais pas pourquoi), mais d’utiliser --device nvidia.com/gpu=all (ou l’index de carte à la place de all, par exemple nvidia.com/gpu=0) et de forcer la non-labellisation avec --security-opt=label=diable.

Sans cela, vous allez vous prendre des erreurs dans la poire sans rien comprendre.

Pour ma part j’ai ajouté un alias dans mon environnement :

alias podman-gpu="podman run --device nvidia.com/gpu=all --security-opt=label=disable"

Et c’est beaucoup plus simple 😄

Conclusion

Ce n’est pas évident, je vous l’accorde. Mais ce n’est pas insurmontable en réalité. La seule chose à bien penser est de refaire la modification du fichier toml pour les cgroups et le chemin des logs quand les packages sont mis à jour.

C’est d’ailleurs dommage que nous ne pouvions pas utiliser un fichier d’override (c’est peut-être possible, si c’est le cas je modifierai l’article), mais bon… ça me prend moins d’une minute à faire tout ça.

L’intérêt est de pouvoir lancer des inférences, des entrainements, des outils utilisant le GPU sans installer tout ça localement. C’est aussi intéressant de pouvoir tester plusieurs versions de CUDA sans les installer à l’arrache.

Podman est devenu mon seul et unique runtime de conteneur depuis des mois, du moins sur mon poste Linux (car je suis forcé d’utiliser un poste Windows dans mon nouveau Job).

Références

comments powered by Disqus