概要
Tue 23 Nov 2021 02:50:33 PM JST 現在、Debian 11 用には nvidia-docker 等の deb パッケージが用意されていない。これは、cgroup のアップグレードにより、nvidia container stack の rearchitecture が必要で、それに時間がかかっているらしい (https://github.com/NVIDIA/nvidia-docker/issues/1447#issuecomment-760189260)。つまり、debパッケージがただ無いだけではなく、現行のバージョンのソースをビルドしても Debian 11 では使用不可能ということ。
ワークアラウンドはあるようなので、一連のツールキットをビルドしてワークアラウンドを適用する方法をまとめる。
*2022-08-01T16:57:37+09:00 現在、サポートされたようだ。*https://github.com/NVIDIA/nvidia-docker/issues/1549#issuecomment-1030066481
更新のコマンドだけかんたんにまとめておく。
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 \
&& apt install libnvidia-container1 libnvidia-container-tools nvidia-container-toolkit nvidia-container-runtime nvidia-docker
必要なパッケージが 開発者の投稿 とマッチしているか確認する。
- libnvidia-container1-1.9.0
- libnvidia-container-tools-1.9.0
- nvidia-container-toolkit-1.9.0
- nvidia-container-runtime-3.9.0
- nvidia-docker-2.10.0
再起動して終了。
おまけ: nvidia driver のアップグレード
ついでに、 nvidia driver のアップグレード方法について残しておく。
始める前に、新しい nvidia driver が自分の GPU に対応しているか確認する必要がある。これは、GPUによってことなる Computation Capability と cuda toolkit が要求する nvidia driver のバージョンからチェックする必要がある。まずは、https://developer.nvidia.com/cuda-gpus にアクセスし、自分の GPU の Computation Capability を確認する。例えば、 Geforce GTX 1060 ならば 6.1。次に、nvidia driver のバージョンがサポートする compute capability を確認する (https://docs.nvidia.com/deploy/cuda-compatibility/index.html の which GPUs are supported by the driver? の節。) 。 6.x ならば、現状最新の 515.43.04+ をサポートしているので問題ない。
確認ができたら、古い nvidia driver を除去する。古い nvidia driver をパッケージマネージャでインストールしたか nvidia が提供する実行ファイル (*.run
) でインストールしたかで作業が少し変わる (https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#pre-installation-actions)。
Table 3. NVIDIA Driver Installation Compatibility Matrix
Installed Driver Version == X.Y | Installed Driver Version != X.Y | ||||
RPM/Deb | run | RPM/Deb | run | ||
Installing Driver Version X.Y | RPM/Deb | No Action | Uninstall Run | No Action | Uninstall Run |
run | Uninstall RPM/Deb | No Action | Uninstall RPM/Deb | No Action |
古いものが deb パッケージでインストールされていて、かつ今回も deb パッケージでインストールするならば、特にすることはない。
あとは、あたらしいリポジトリを APT に追加し、apt install
コマンドを発効すればよい (https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#debian-installation)。
Installation (Tue 23 Nov 2021 02:50:33 PM JST 以前)
パッケージは用意されていないので、自分でビルドする。もしかすると debian 10 用の deb パッケージを流用できるかもしれないが、未検証。
ソースからビルドする場合は、みっつのプロジェクトを順にビルドする。
- https://github.com/NVIDIA/libnvidia-container
- https://github.com/NVIDIA/nvidia-container-toolkit
- https://github.com/NVIDIA/nvidia-docker
これらのリポジトリは、docker コンテナ内でビルドするようできているので、docker さえ入っていればとくに dependencies のインストールは必要ない。ただし、 debian 11 に対応するため、いくつかの変更は行う必要がある。みっつ全てに共通するのは、ビルドのために debian 11 のイメージを使うようにすること。加えて、libnvidia-container
では、 (リンカのアップグレードによる仕様変更のため?) オブジェクトファイルであるダイナミックリンクライブラリの命名に失敗するので、その名前変更のためのコマンドを追加する。
libnvidia-container
libnvidia-container-toolkit
のコミット a648cd2a698eb56d71150d8790d96e445f9ae351
に対して、以下のパッチを適用する。
diff --git a/mk/Dockerfile.debian b/mk/Dockerfile.debian
index ce582fb..612ea33 100644
--- a/mk/Dockerfile.debian
+++ b/mk/Dockerfile.debian
@@ -38,7 +38,7 @@ ENV WITH_SECCOMP=${WITH_SECCOMP}
ARG REVISION
ENV REVISION=${REVISION}
-RUN make distclean && make -j"$(nproc)"
+RUN make distclean && make -j"$(nproc)" || mv -v 'deps/src/elftoolchain-0.7.1/libelf/name libelf.so.1' deps/src/elftoolchain-0.7.1/libelf/libelf.so.1
# Use the revision as the package version for the time being
ENV PKG_NAME libnvidia-container
diff --git a/mk/docker.mk b/mk/docker.mk
index aef1762..f800bfa 100644
--- a/mk/docker.mk
+++ b/mk/docker.mk
@@ -28,8 +28,8 @@ MAKE_DIR ?= $(CURDIR)/mk
REVISION ?= $(shell git rev-parse HEAD)
# Supported OSs by architecture
-AMD64_TARGETS := ubuntu20.04 ubuntu18.04 ubuntu16.04 debian10 debian9
-X86_64_TARGETS := centos7 centos8 rhel7 rhel8 amazonlinux1 amazonlinux2 opensuse-leap15.1
+AMD64_TARGETS := debian11 debian10
+X86_64_TARGETS :=
PPC64LE_TARGETS := ubuntu18.04 ubuntu16.04 centos7 centos8 rhel7 rhel8
ARM64_TARGETS := ubuntu18.04
AARCH64_TARGETS := centos8 rhel8 amazonlinux2
前半部分の変更が、ダイナミックライブラリの命名変更 [1]。
-RUN make distclean && make -j"$(nproc)"
+RUN make distclean && make -j"$(nproc)" || mv -v 'deps/src/elftoolchain-0.7.1/libelf/name libelf.so.1' deps/src/elftoolchain-0.7.1/libelf/libelf.so.1
後半部分で、debian11
のコンテナイメージをpullするために debian11
を追記する。ついでに、不要なアーキテクチャ用のバイナリを作らないように他の識別子は削除しておく (しなくても余分なビルドが行われるだけ)。
-AMD64_TARGETS := ubuntu20.04 ubuntu18.04 ubuntu16.04 debian10 debian9
-X86_64_TARGETS := centos7 centos8 rhel7 rhel8 amazonlinux1 amazonlinux2 opensuse-leap15.1
+AMD64_TARGETS := debian11 debian10
+X86_64_TARGETS :=
nvidia-container-toolkit
nvidia-container-tookit
のコミット 92bb04f0fd42a52291c56b6e73d2383ba36f3e4e
に対して、以下のパッチを適用する。これは debian 11 のコンテナイメージを使ってビルドするよう指示する。
diff --git a/docker/docker.mk b/docker/docker.mk
index 4ac9d00..35890fd 100644
--- a/docker/docker.mk
+++ b/docker/docker.mk
@@ -13,8 +13,8 @@
# limitations under the License.
# Supported OSs by architecture
-AMD64_TARGETS := ubuntu20.04 ubuntu18.04 ubuntu16.04 debian10 debian9
-X86_64_TARGETS := centos7 centos8 rhel7 rhel8 amazonlinux1 amazonlinux2 opensuse-leap15.1
+AMD64_TARGETS := debian11 debian10
+X86_64_TARGETS :=
PPC64LE_TARGETS := ubuntu18.04 ubuntu16.04 centos7 centos8 rhel7 rhel8
ARM64_TARGETS := ubuntu20.04 ubuntu18.04
AARCH64_TARGETS := centos8 rhel8 amazonlinux2
nvidia-docker
nvidia-docker
のコミット fd3233aa5f4ade28ac6bda616c2fa77a0ce89cd9
に対して、以下のパッチを適用する。これは debian 11 のコンテナイメージを使ってビルドするよう指示する。
diff --git a/docker/docker.mk b/docker/docker.mk
index 23ce01c..12f1423 100644
--- a/docker/docker.mk
+++ b/docker/docker.mk
@@ -17,8 +17,8 @@ MKDIR ?= mkdir
DIST_DIR ?= $(CURDIR)/dist
# Supported OSs by architecture
-AMD64_TARGETS := ubuntu20.04 ubuntu18.04 ubuntu16.04 debian10 debian9
-X86_64_TARGETS := centos7 centos8 rhel7 rhel8 amazonlinux1 amazonlinux2 opensuse-leap15.1
+AMD64_TARGETS := debian11 debian10
+X86_64_TARGETS :=
PPC64LE_TARGETS := ubuntu18.04 ubuntu16.04 centos7 centos8 rhel7 rhel8
ARM64_TARGETS := ubuntu20.04 ubuntu18.04
AARCH64_TARGETS := centos8 rhel8 amazonlinux2
ビルドとインストール
パッチを当てたら、それぞれのプロジェクトルートで、make
または make debian11
を実行すれば、dist/
というディレクトリができ、その中に *.deb
ファイルが生成される。これを dpkg
などでインストールすればよい。
cgroup に対するワークアラウンド
cgroup を使わないようにし、GPU を指す devfs を直接叩くようにする [2]。ついでに、NVIDIA-SMI couldn’t find libnvidia-ml.so library in your systemの対応もする [3]。
$ cat /etc/nvidia-container-runtime/config.toml
disable-require = false
#swarm-resource = "DOCKER_RESOURCE_GPU"
#accept-nvidia-visible-devices-envvar-when-unprivileged = true
#accept-nvidia-visible-devices-as-volume-mounts = false
[nvidia-container-cli]
#root = "/run/nvidia/driver"
#path = "/usr/bin/nvidia-container-cli"
environment = []
debug = "/var/log/nvidia-container-toolkit.log"
#ldcache = "/etc/ld.so.cache"
load-kmods = true
no-cgroups = true # ← false to true [2]
#user = "root:video"
ldconfig = "/sbin/ldconfig" # ← "@/sbin/ldconfig" to "/sbin/ldconfig" [3]
[nvidia-container-runtime]
debug = "/var/log/nvidia-container-runtime.log"
加えて、初期状態では nvidia-uvm などのカーネルモジュールがロードされていないので、 nvidia-modprobe
でロードするようにする。docker のデーモンが起動する前にロードされるように、systemd で管理する。ファイル docker.service.d/override.conf
を追加する [4]。
$ cat /lib/systemd/system/docker.service.d/override.conf
[Service]
ExecStartPre=-/usr/bin/nvidia-modprobe -c 0 -u
GPUを使うコンテナを起動するときは、GPUの devfs を共有するように、docker run
のオプションに以下を常に追加する [2]。
--device /dev/nvidia0 \
--device /dev/nvidiactl \
--device /dev/nvidia-modeset \
--device /dev/nvidia-uvm \
--device /dev/nvidia-uvm-tools \
Validation
docker run --gpus all -it --rm \
--device /dev/nvidia0:/dev/nvidia0 \
--device /dev/nvidiactl:/dev/nvidiactl \
--device /dev/nvidia-modeset:/dev/nvidia-modeset \
--device /dev/nvidia-uvm:/dev/nvidia-uvm \
--device /dev/nvidia-uvm-tools:/dev/nvidia-uvm-tools \
pytorch/pytorch:1.9.1-cuda11.1-cudnn7-runtime python -c \
"import torch; print(torch.cuda.is_available())"
これが True
になれば OK とする。ちなみに、bullseye のパッケージレポジトリには cuda 11.2 しか無いが、 11.1 のコンテナイメージでも動く。
Reference
-
[1]: https://github.com/NVIDIA/nvidia-docker/issues/1537#issuecomment-908194487
-
[2]: https://github.com/NVIDIA/nvidia-docker/issues/1549#issuecomment-939943090
-
[4]: https://github.com/NVIDIA/nvidia-docker/issues/1447#issuecomment-851039827
-
cgroup workaround: https://github.com/NVIDIA/nvidia-docker/issues/1549#issuecomment-939943090, https://adrianobarbosa.xyz/blog/nvidia-docker-debian-testing.html, https://github.com/NVIDIA/nvidia-docker/issues/1447