WSL2+Docker DesktopでPytorchのGPU環境を構築する方法
はじめに
今回は Docker Desktop を用いてGPU環境を構築します。
以前の Docker はCLIをメインに開発を行っていたと思うのですが、Docker Desktop を用いれば GUI からコンテナやイメージなどを操作することができるそうです。しかも、現在のバージョンは導入が爆速でできるのでめちゃくちゃ使いやすくなりました。
使用するもの
- CUDA (前提)
- Windows11 Home (前提)
- Docker Desktop
- WSL2
- Nvidia-Container-Toolkit
- jupyterlab
WSL2 のインストール
管理者権限でコマンドプロンプトを起動します。起動後以下のコマンドを実行します。
wsl --install
このコマンドはWSL2をインストールするだけでなくUbuntuもインストールしてくれ、設定なども勝手にやってくれます。だから、別途 Ubuntu をインストールする必要はありません。
Dockr Desktop のインストール
Windows の場合はまずはこちらからインストーラをダウンロードしてください。
基本はデフォルトのまま進んでいいのですが、今回は「Use WSL2 instead lf Hyper-V(recommended)」 のチェックボックスをつけて進みます。以前は Docker のバックグラウンドで Hyper-V が動いていたんですが、最近 WSL2 になったことで Windows に色々最適化されて性能が良くなっているんだそうです。
インストール完了後、アプリを起動すると下のような画面が出てきます。このように、GUIの操作でもコンテナやイメージの操作ができるようになっています。
Nvidia-Container-Toolkit のセットアップ
コンテナでGPUを使用するために Nvidia社している Nvidia-Container-Toolkit を使用します。Githubはこちらです。
私はこれらを参考にしました。ホスト側で順にコマンドを実行します。
リポジトリとGPGキーのセットアップ
& distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
&& curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
&& curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | \
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
パッケージの更新
sudo apt-get update
Docker demon の再起動
sudo systemctl restart docker
コンテナを作成・起動しGPUが認識されるか確認
docker run で コンテナを作成することができます。
オプション
- --rm : コンテナを抜けるたびに勝手に削除してくれます。
- --gpus all : すべての GPU を使用します。
- nvidia/cuda:11.7.0-base-ubuntu22.04 : nvidia の CUDA イメージです。
https://hub.docker.com/r/nvidia/cuda こちらの DockerHub からホスト側に入っている CUDAのバージョンを確認し変更してください。私はCUDA 11.7 で ubuntu20.04 なのでこのイメージを使用します。事前にこのイメージをpullしておいても大丈夫です。 - nvidia-smi : GPUの状況を確認するためのコマンドです。docker run と同時にこのコマンドが実行されます。
sudo docker run --rm --gpus all nvidia/cuda:11.7.0-base-ubuntu22.04 nvidia-smi
こんな感じの画面が表示されたらGPUが認識されています。
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 510.52 Driver Version: 511.79 CUDA Version: 11.6 |
|-------------------------------+----------------------+----------------------+
| 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 ... On | 00000000:01:00.0 On | N/A |
| 0% 40C P8 21W / 350W | 803MiB / 12288MiB | 1% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
| No running processes found |
+-----------------------------------------------------------------------------+
その他パッケージをインストールする
GPU が認識されていることが確認できましたが、このイメージはあくまでGPUを使用できるようになるだけであり、まだ Pytorchやコード編集するためのエディタがありません。
※nvidiaのPytorchが含まれるイメージもあります。ただし、中身はconda環境なので、pip好きで自分好みの環境にしたかった自分は今回はCUDAのイメージを使っています。Pytorchのイメージはこちらです。
Dockerfile
先ほどのイメージ nvidia/cuda:11.7.0-base-ubuntu22.04 をベースにDockerfile を記述していきます。Dockerfileについてはググればたくさん記事があると思うのでそちらを参考にお願いします。私は下のように作成しました。使いそうなパッケージ, pytorch, jupyterlab をインストールしています。Pytorch のバージョンに関しては以下のページで必ず確認してCUDAに対応したものをインストールしてください。
FROM nvidia/cuda:11.7.0-base-ubuntu22.04
RUN apt-get update && apt-get install -y \
python3-pip \
sudo \
wget \
git \
vim
RUN ln -s /usr/bin/python3.10 /usr/bin/python
RUN pip install --upgrade pip
RUN pip install torch torchvision torchaudio jupyterlab
WORKDIR /work
#CMD ["/bin/bash"]
CMD ["jupyter", "lab", "--ip=0.0.0.0", "--allow-root", "--LabApp.token=''"]
ホスト側のDockerfileの場所まで移動しイメージを作成します。
docker build -t my-nvidia-pytorch:11.7.0-base-ubuntu22.04 .
オプション
- -t : 作成するイメージ名を決めることができます。
-t <好きなイメージ名>:<好きなタグ名>
ホストとコンテナでファイルのやり取りをしたい場合
dockerのコンテナ内のファイルは直接見ることができないし、コンテナごと削除してしまうこともあるでしょう。コンテナ-ホスト間のやりとりの方法は二通りあります。
方法1 cpコマンド
dockerコンテナ内のファイルを、ホスト内のファイルへコピーする場合、
docker cp <コンテナのID>:<コピー元のパス> <ホスト内のコピー先のパス>
とすればよいです。
ホスト内のファイルもdockerコンテナ内にコピーすることもできます。
docker cp <ホスト内のコピー先のパス> <コンテナのID>:<コピー元のパス>
方法2 -v オプション
個人的にはこっちのほうを頻繁に使います。ホスト側のファイルシステムをコンテナにマウントすることで任意のフォルダを共有することができます。コンテナ内のマウントされたフォルダで編集したファイルはホスト側でも当然反映されます。
doceker run -v <ホスト側のマウントしたいフォルダのパス>:<コンテナ側のパス>
確認
作成したイメージを使用してコンテナを作成・起動します。
docker run --gpus all --rm -it -p 8888:8888 -v ~/Local/workdir:/work --name my-pytor
ch 1a766d10a148
オプション
- --gpus all : GPUを使用する
- --rm : コンテナを抜けると削除
- -it : とりあえずつけとく
- -p : ポートをつなぐ(jupyterlabを使いたいため)
- -v : 私はホストのworkdirフォルダとコンテナのworkフォルダを共有させてます。
- --name : コンテナ名
jupyter が起動されたことが確認出来たら、ブラウザで localhost:8888 と入力します。jupyterlabが起動しました!
Jupyterlab内で PytrochでのGPUが使えることが確認できました。GG!
参考にしたサイト
Discussion
このやり方の場合は、コンテナ毎に異なるバージョンのcuda toolkit を入れて、異なるバージョンのpytorchやtensorflowを使えるのでしょうか?それともどのコンテナにおいてもcuda toolkitのバージョンはホスト側に入れたcuda driverのバージョンに引きずられて一種類しか入れられないのでしょうか?
ご質問ありがとうございます。遅くなってしまい申し訳ございません。
ホストに自分が使用したいバージョンのCUDAを入れておき(複数同居させることは可能なはず)、それに対応したtoolkitイメージを用いれば、コンテナ毎に異なる環境を作ることは可能だと思います。ただし、PytorchやTensorflowのバージョンはCUDAのバージョンと強い依存があるので、そこに注意する必要はあると思います。
返信有難うございます。その後、難しいことはやめてホストにはNVIDIA driver のみを入れて、NVIDIA が配布しているPyTorch やcuda が1つにまとまっているdocker imageを利用しています。ホストos はubuntuです。wsl はメモリ管理が面倒そうだったので辞めたのですが、自動的に可変する機能を導入してそろそろ解決されるようです。