Post

NVIDIA Container ToolkitとDockerでディープラーニング開発環境を構築する (2) - GPUを活用するためのコンテナランタイムの構成、Dockerfileの作成およびDockerイメージのビルド

このシリーズでは、ローカルにNVIDIA Container ToolkitとDockerベースのディープラーニング開発環境を構築し、リモートサーバーとして活用できるようにSSHおよびJupyter Labを設定する方法を扱います。この投稿は、そのシリーズの2番目の記事で、GPUを活用するためのコンテナランタイムの構成、Dockerfileの作成、およびDockerイメージのビルド方法を紹介します。

概要

このシリーズでは、NVIDIA Container ToolkitとDockerをインストールし、Docker Hubのnvidia/cudaリポジトリが提供するCUDAおよびcuDNNイメージをベースにDockerfileを作成してディープラーニング開発環境を構築するプロセスを扱います。必要な方が自由に使用できるように、このプロセスを経て完成したDockerfileイメージをGitHubとDocker Hubを通じて共有し、さらにリモートサーバーとして活用するためのSSHおよびJupyter Lab設定ガイドを提供します。
シリーズは3つの記事で構成される予定で、この記事はそのシリーズの2番目の記事です。

x86_64 Linux環境でCUDAをサポートするNVIDIAグラフィックカードを搭載したシステムを前提に進めます。UbuntuまたはFedora以外のディストリビューションでは直接テストしていないため、いくつかの細部は若干異なる可能性があります。

始める前に

この記事は第1回に続く記事なので、まだ読んでいない場合は、まず前の記事から読むことをお勧めします。

4. コンテナランタイムの構成

4-1. nvidia-ctkコマンドの実行

1
sudo nvidia-ctk runtime configure --runtime=docker

上記のコマンドは、DockerがNVIDIA Container Runtimeを利用できるように/etc/docker/daemon.jsonファイルを修正します。

4-2. Dockerデーモンの再起動

変更した設定を適用するためにDockerデーモンを再起動します。

1
sudo systemctl restart docker

4-3. 正常に構成されたかの確認

サンプルCUDAコンテナを実行してみます。

1
sudo docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi

おおよそ以下のような画面が表示されれば成功です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 555.58.02              Driver Version: 555.58.02      CUDA Version: 12.5     |
|-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA GeForce RTX 3090        Off |   00000000:01:00.0  On |                  N/A |
|  0%   46C    P8             29W /  350W |     460MiB /  24576MiB |      2%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+
                                                                                         
+-----------------------------------------------------------------------------------------+
| Processes:                                                                              |
|  GPU   GI   CI        PID   Type   Process name                              GPU Memory |
|        ID   ID                                                               Usage      |
|=========================================================================================|
|  No running processes found                                                             |
+-----------------------------------------------------------------------------------------+

5. Dockerfileの作成

Docker Hubのnvidia/cudaリポジトリが提供するCUDAおよびcuDNNイメージをベースにして、開発環境として使用するDockerfileを作成します。

  • 必要とするCUDAおよびcuDNNのバージョン、Linuxディストリビューションの種類およびバージョンなどを考慮して使用するイメージを決定する必要があります。
  • PyTorch 2.4.0がサポートするCUDAバージョンこの記事の作成時点である2024年8月末を基準に、PyTorch最新バージョンである2.4.0バージョンはCUDA 12.4をサポートしています。したがって、ここでは12.4.1-cudnn-devel-ubuntu22.04イメージを使用します。PyTorchホームページでPyTorch最新バージョンおよびサポートするCUDAバージョンを確認できます。

完成したDockerfileのソースはyunseo-kim/dl-env-docker GitHubリポジトリに公開しています。以下に、そのDockerfileを作成したプロセスを段階的に説明します。

5-1. ベースイメージの指定

1
FROM nvidia/cuda:12.4.1-cudnn-devel-ubuntu22.04

5-2. 基本ユーティリティおよびPython prerequisitesのインストール

1
2
3
4
5
6
7
8
9
RUN apt-get update -y && apt-get install -y --no-install-recommends\
    apt-utils \
    ssh \
    curl \
    openssh-server \
    python3 \
    python-is-python3 \
    python3-pip && \
    rm -rf /var/lib/apt/lists/*

5-3. システムタイムゾーンの設定(この記事では’Asia/Seoul’で進行)

1
2
3
# Set up time zone
ARG TZ="Asia/Seoul"
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime

5-4. リモートアクセスのためのSSHサーバー設定

セキュリティのため、SSHリモートアクセス時にパスワードでrootアカウントログインができないように設定します。

1
2
# Disable root access via password
RUN echo "PermitRootLogin prohibit-password" >> /etc/ssh/sshd_config

コンテナ起動時にSSHサービスが自動的に開始されるように構成します。

1
RUN echo "sudo service ssh start > /dev/null" >> $HOME/.bashrc

SSH接続時に使用する’remote’という名前のnon-rootユーザーを作成します。

1
2
3
4
5
6
7
8
9
10
11
# Create a non-root user and switch to it
ARG USER_NAME="remote"
ARG USER_PASSWORD="000000"
RUN useradd --create-home --password $USER_PASSWORD $USER_NAME
ENV HOME=/home/$USER_NAME
USER $USER_NAME
WORKDIR $HOME
# Re-run ssh when the container restarts.
RUN echo "sudo service ssh start > /dev/null" >> $HOME/.bashrc
# Create a workspace directory to locate jupyter notebooks and .py files
RUN mkdir -p $HOME/workspace

このDockerfileを使用してDockerイメージをビルドする際、別途オプションを指定しない場合、’remote’ユーザーのアカウントパスワードの初期値は000000です。これはセキュリティ上非常に脆弱なので、Dockerイメージビルド時に--build-argオプションを使用してアカウントログインパスワードを別途指定するか、またはコンテナを初めて実行した後、すぐに設定を変更するようにしましょう。セキュリティのためには、SSH接続時にパスワードログインを無効にし、別途のキーファイルを通じてのみログインが可能になるように後で設定することが望ましく、Yubikeyなどのハードウェアキーまで活用すれば理想的です。 SSHサーバーの構成については、このシリーズの次回で多少扱う予定ですが、より詳しく知りたい場合は、次のリストにある文書を参考にするとよいでしょう。

5-5. setuptools、pipのインストールおよびPATH環境変数の登録

1
2
RUN python3 -m pip install -U setuptools pip
ENV PATH="$HOME/.local/bin:$PATH"

5-6. 開発環境で使用する機械学習およびディープラーニングパッケージのインストール

1
2
RUN python3 -m pip install -U jupyterlab numpy scipy pandas matplotlib seaborn[stats] scikit-learn tqdm
RUN python3 -m pip install -U torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124

Cupy、cuDF、cuML、そしてDALIを使用する場合は、次の内容もDockerfileに追加します。

1
2
RUN python3 -m pip install -U cupy-cuda12x
RUN python3 -m pip install -U --extra-index-url=https://pypi.nvidia.com cudf-cu12==24.8.* cuml-cu12==24.8.* nvidia-dali-cuda120

5-7. コンテナ起動時のJupyterLab実行設定

1
2
CMD cd $HOME/workspace && \
    jupyter lab --no-browser --autoreload --ip=0.0.0.0 --notebook-dir="$HOME/workspace"

6. Dockerイメージのビルドおよびコンテナの実行

6-1. イメージのビルド

Dockerfileが位置するディレクトリでターミナルを開き、以下のコマンドを実行します。

1
2
docker build -t dl-env:cuda12.4.1-cudnn9.1.0-ubuntu22.04 -f ./Dockerfile . \
--build-arg USER_PASSWORD=<password>

<password>の部分にSSH接続時に使用するログインパスワードを入力します。

6-2. サンプルワークロードの実行

ビルドが完了したら、次のコマンドで使い捨てコンテナを実行して正常に動作するか確認します。

1
2
3
docker run -itd --rm --name test-container \
--gpus all -p 88:8888 \
dl-env:cuda12.4.1-cudnn9.1.0-ubuntu22.04

ターミナルで上記のコマンドを入力すると、先ほどビルドしたdl-env:cuda12.4.1-cudnn9.1.0-ubuntu22.04イメージからtest-containerという名前のコンテナを実行し、ホストシステムの88番ポートを該当コンテナの8888番ポートに接続します。前の段階でDockerイメージが正常にビルドされ、コンテナが問題なく起動された場合、test-containerコンテナ内でJupyterLabがデフォルト値であるhttp:127.0.0.1:8888アドレスで実行中のはずです。したがって、Docker Engineが動作しているホストシステムでブラウザを開き、http://127.0.0.1:88にアクセスした時、コンテナ内部のhttp://127.0.0.1:8888アドレスに接続され、以下のような画面が表示されるはずです。

JupyterLab Interface Screenshot

6-3. (オプション) Docker Hubへのプッシュ

前述のプロセスを経て作成した開発環境イメージを必要な時にいつでもPullして活用するには、ビルドしたイメージをDocker Hubにプッシュしておくのが良いでしょう。

Docker Hubに自分のイメージをプッシュするには自分のDockerアカウントが必要なので、まだない場合はhttps://app.docker.com/signupで会員登録を先に完了してください。

まず、以下のコマンドでDocker Hubにログインします。

1
docker login

次に、以下のような形式のコマンドを実行してイメージタグを生成します。

1
docker tag IMAGE_ID <dockerhub_username>/<repository_name>[:TAG]

最後に、以下のコマンドを実行して該当イメージをDocker Hubにプッシュします。

1
docker push <dockerhub_username>/<repository_name>[:TAG]

https://hub.docker.com/で以下のようにうまくプッシュされたことを確認できます。
Docker Hub Screenshot

前述のプロセスを経て完成したイメージはDocker Hubのyunseokim/dl-env公開リポジトリに公開しており、誰でも自由に使用できます。

This post is licensed under CC BY-NC 4.0 by the author.

Comments powered by Disqus.