背景
この記事はchainerと呼ばれるPython用のDeepLearningフレームワークを使った深層学習プログラムを、WSLを使ってローカル環境で動かすためのものです。
私は非常にこの環境構築で苦戦しました。特に私と同じ研究室の方はchainerを使う機会があるかもしれないので、その手助けとなれば幸いです。
chainerを機能させるために必須のモジュールやドライバーが複数存在しますが、インストールする順番やバージョンを間違えると機能しないため慎重に行う必要があります。
今回はWSLを用いており、Dockerを通してローカル環境でchainerを使う深層学習のための環境を整えることを目標とします。
環境
OS:Windows11 home
WSL:Ubuntu20.04LTS
DockerDesktop for Windows
VcXsrv (Windows用のフリーのXサーバー。詳細は後述)
chainerに必要な、主なモジュールやドライバー
-
nvidia driver
NVIDIAのGPUを適切に動作させるためのソフトウェアで、GPUに合わせたバージョンをインストールする必要あり。(https://www.nvidia.co.jp/Download/index.aspx?lang=jp)
nvidia-smi
コマンドでバージョン確認。 -
CUDA
NVIDIAが開発したGPU向けの並列コンピューティングプラットフォームとAPI。
グラフィックス以外の計算処理をGPUで高速に行うためのツール。
GPU上でのプログラミングをCやC++で行うことができる。
NvidiaDriverに合わせたバージョンをインストールする必要あり。
nvcc -V
でランタイムのCUDAを確認。nvidia-smi
でnvidiadriverに対応する最新のCUDA確認。 -
CUDAToolKit
CUDAのための開発ツールやライブラリ、ヘッダファイル、ドキュメントなどを含むキット。nvccというNVIDIAのCUDAコンパイラ(これがないと現在動かしているランタイムのCUDAのバージョンが確認できない)や、CUDA数学ライブラリやCUDAアプリケーションの実行をサポートするライブラリとAPIであるCUDAランタイムAPIなどが含まれます。
CUDAに合わせたバージョンをインストールする必要あり。
pipにはcudatoolkit がない。https://pypi.org/search/?q=cudatoolkit -
CUDNN
NVIDIAが提供するディープニューラルネットワークのためのGPU加速化ライブラリ。
ディープラーニングのフレームワークにおける計算の高速化をサポート。
畳み込み、プーリングなどの基本操作を最適化された形で提供。
CUDAに合わせたバージョンをインストールする必要あり。
※動作しているか直接確認できるコマンド等がない。
インストールに何かしらで失敗したとき、アンインストールしてインストールしなおすのが大変なことがあります。
ローカルシステムの確認: インストールされているcuDNNのバージョンは、ヘッダーファイルcudnn.h
を調べることで確認できます。このファイルは通常/usr/local/cuda/include/
に配置されます。このファイル内で、CUDNN_MAJOR
,CUDNN_MINORCUDNN_PATCHLEVEL
の定義を検索することで、バージョン情報を取得できます。
(私はローカルでCUDNNをインストールしたのにも関わらず、ファイルがこの場所になく、別コマンドで調べても場所が分かりませんでした……) -
Cupy
GPU上での数値計算を高速化するためのPythonライブラリ。
NumPyと似たAPIを持ち、CUDAをバックエンドとして使用。
ディープラーニングや科学計算でのGPU利用を容易にする。
CUDAに合わせたバージョンのものをインストールする必要あり。(https://docs.cupy.dev/en/stable/install.html) https://cupy.dev/ -
Numpy
Pythonでの数値計算をサポートする基本的なライブラリ。
多次元配列や線形代数、数学関数などの機能を提供。
科学計算やデータ分析の基盤として広く利用される。
Pythonに合わせたバージョンをインストールする必要あり。 - また、これ以外にも必要なモジュールが数多くあり(のちに名称をまとめたファイルを添付)
それらの多くがNumpyのバージョンに合わせたものをインストールする必要がある。
chainerは開発が終了しているため、CUDAなどのライブラリを使う際、最新のものをインストールするよりchainer開発終了当時の最新のものを使う方がパフォーマンスが上がります。
推奨バージョン
chainer 7.8.1
CUDA 11.8.0
cudnn 8.8.0
cupy-cuda11x 12.10
numpy 1.23.0
GPUに合わせて芋づる式で他のバージョンを合わせていけば環境が完成しそうなものですが、
実際には簡単に環境構築できませんでした。とあるモジュールでは特定のバージョン以下のnumpyが必要で、また別のモジュールは特定のバージョン以上のnumpyでしか機能せずその両方を満たすバージョンが存在しないといったような状況や、すべてのバージョンをそろえたのになぜかCUDA関連の環境が不完全ですという旨のエラーが出る状況がままあるため、複数のモジュール等のバージョンをすりあわせて何とか機能する環境を作るといった工程等が必要になります。
※仮想環境の種類やモジュールのバージョン、GPUやOSの違いなどですんなり上手くいくこともあるにはあるようです。
本記事ではchainerが動作し損失関数の収束等も確認できる環境を構築はできましたが、環境構築の難易度が高いという問題や、それに付随して新しいモジュールを試すとき等にバージョンの競合を起こすという問題もあり、優れたフレームワークではあるが最終的にはPytorchやTesnsorFlowなどへの移行をする必要があると考えられます。
導入
上記でも少し触れたようにPythonのバージョンも慎重に選ぶ必要があります。しかしシステム全体のPythonのバージョンを変えるのはリスクが大きいため、深層学習では仮想環境がほぼ必須となってきます。仮想環境にはAnacondaを使っている記事も多く見受けられるが本記事ではDockerを使用します(理由は後述)。
Dockerとは
Dockerは、アプリケーションとその依存関係を包含する「コンテナ」としての実行を可能にする技術です。Dockerの最大の特長は、コンテナ技術を使用することにより、アプリケーションを一貫してどの環境でも同じように動作させることができる点です。
従来の仮想化技術と比較して、DockerはOSレベルでの仮想化を採用しています。これにより、コンテナは高速に起動し、少ないオーバーヘッドで実行できるため、軽量で効率的き機能できます。各コンテナは独立した環境を持ち、他のコンテナやホストシステムから隔離されています。
Dockerの中心的な要素として「Dockerfile」と「イメージ」と「コンテナ」がある。Dockerfileはコンテナの構築手順を記述したテキストファイルで、これを元にDockerイメージが作成されます。
このイメージは、アプリケーションのコード、ランタイム、ライブラリ、環境変数など、アプリケーションの実行に必要な全て詰め込んだものです。このイメージを基に、コンテナを起動・実行することができます。
Dockerイメージは、Docker Hubやその他のコンテナレジストリにアップロードして共有することができるため、他の開発者やチームとのコラボレーションも容易です。さらに、DockerはクラウドサービスやCI/CDパイプラインとも簡単に統合できるため、開発からデプロイまでのワークフローを効率的に行うことができます。(chainerの環境構築ではここまでやりません)
Dockerを更に強力にするツールやエコシステムも豊富に存在する。例えば、Docker Compose
を使うと、複数のコンテナを一度に管理・実行することができ、複雑なアプリケーションの環境を容易に構築できます。
まとめると、Dockerはアプリケーションの開発、テスト、デプロイメントを効率的かつ一貫性のある方法で行うための強力なツールです。その移植性と再現性により、「私のマシンでは動作する」という問題を解決でき、さらにはデベロッパーや運用チームの間の協力を促進できる技術です。
OSレベルでの仮想化ができるということは、コンテナごとにCUDAやCUDNNといったライブラリを組み替えて入れることができ、アンインストールが大変なCUDNNなどのインストールにエラーが起きてもやり直しが容易です。したがって、最初にGPUに沿ったNvidiaDriverさえインストールしていれば他の準備はコンテナ内ですることができ、環境構築をより確実に完了することができます。
手法(手順のみ見たい場合はここから)
方法1:ローカルでdockerイメージを作成する(推奨)
まずはNvidiaDriverのインストールをしてください。
次に、任意のディレクトリにdocker用のディレクトリを作成します。そしてそのディレクトリ内で以下のようなファイルを作成します。(研究用ディレクトリは.devcontainerと並ぶように置きます。)
githubに乗せておいたので、git clone webURL
でクローンしてください。
隠しファイルになっているのでls -all等を使わないと確認できません。注意して下さい。
ソースコードの説明が読みたい方は以下を参照してください。適宜環境に応じて変更する箇所があります。(ベースイメージのubuntuのバージョンなど)
ソースコード
-
.envファイルのソースコード
DISPLAY=192.168.11.7:0.0
-
docker-compose.ymlのソースコード
version: '3.8' services: docker-chainer: build: context: . dockerfile: Dockerfile image: docker-chainer:docker-chainer # イメージ名&タグ名 container_name: docker-chainer # コンテナ名 deploy: # GPUの設定 resources: reservations: devices: - driver: nvidia count: all capabilities: [gpu] stdin_open: true tty: true privileged: true environment: TZ: "Asia/Tokyo" DISPLAY: "${DISPLAY}" volumes: - ../:/home/research working_dir: /home/research
-
dockerfileのソースコード
#FROM python:3.9 FROM nvidia/cuda:12.2.0-devel-ubuntu20.04 ENV PYTHONUNBUFFERED 1 ENV DEBIAN_FRONTEND=noninteractive WORKDIR /home/research #Update packages & installation RUN set -x && \ apt update && \ apt upgrade -y && \ apt install -y python3 python3-pip && \ apt install -y python3-tk && \ apt install -y x11-apps sqlite3 libsqlite3-dev zlib1g-dev libjpeg-dev ntpdate wget sudo && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* ENV MPLBACKEND="TkAgg" #Python requirements COPY requirements.txt . #Upgrade pip RUN pip install --upgrade pip #Install requirements RUN pip install cupy-cuda12x RUN pip install numpy>=1.19.5 RUN pip install --no-cache-dir -r requirements.txt #Copy current directory contents COPY . .
cupy-cuda120
はCuPyのバージョン12.0.0を指す特定の名前です。エラーメッセージから、この名前でのパッケージが見つからないことが示されています。正しいパッケージ名を使用してインストールし直す必要があります。以下の手順で確認・インストールを行ってみてください。
- 最新のCuPyのバージョンを調べます。通常、PyPIのCuPyページにアクセスすることで、最新のバージョンやインストール方法を確認できます。
-
Dockerfileの該当の行を以下のように変更してください。
RUN pip install cupy-cuda120==<最新のバージョン>
<最新のバージョン>
を実際の最新のバージョン番号に置き換えてください。
-
requirements.txtのソースコード
django django-widget-tweaks django-allauth alembic==1.7.7 blinker==1.5 chainer==7.8.1 chainercv==0.13.1 chainerui==0.11.0 click==8.0.4 #contourpy==1.1.0 cycler==0.11.0 Cython==0.29.35 fastrlock==0.8.1 filelock==3.4.1 Flask==2.0.3 fonttools==4.27.1 gevent==22.10.2 greenlet==2.0.2 imageio==2.16.0 importlib-metadata==4.8.3 importlib-resources==5.4.0 itsdangerous==2.0.1 Jinja2==3.0.3 joblib==1.1.1 kiwisolver==1.3.1 #lazy-loader==0.2 Mako==1.1.6 MarkupSafe==2.0.1 matplotlib==3.3.4 msgpack==1.0.5 networkx==2.5.1 #numpy==1.19.5 packaging==21.3 Pillow==8.4.0 #pip==19.3.1 protobuf==3.17.3 pydicom==2.3.1 pyparsing==3.1.0 python-dateutil==2.8.2 PyWavelets==1.1.1 scikit-image==0.17.2 scikit-learn==0.24.2 scipy==1.5.4 setuptools==41.6.0 six==1.16.0 SQLAlchemy==1.4.49 structlog==21.5.0 threadpoolctl==3.1.0 tifffile==2020.9.3 typing-extensions==4.1.1 urllib3==1.25.8 Werkzeug==2.0.3 zipp==3.6.0 zope.event==4.6 zope.interface==5.5.2 #cupy-cuda11x==12.1.0 #zlib1g-dev #libjpeg-dev
-
devcontainer.jsonのソースコード
{ "name": "docker-chainer", "dockerComposeFile": [ "docker-compose.yml" ], "service": "docker-chainer", "workspaceFolder": "/home/research", // リモート先のVS Codeにインストールする拡張機能 "extensions": [ "ms-python.python", //Pythonセット "aaron-bond.better-comments", //コメントに色をつけられる "kevinrose.vsc-python-indent", //Pythonの改行を自動で最適な場所へ "ms-ceintl.vscode-language-pack-ja", //日本語化 "coenraads.bracket-pair-colorizer-2", //かっこ同士の色分け "oderwat.indent-rainbow" //段落の色分け ] }
実行
docker-compose up -d --build
で実行
-
-d
は「detached mode」を意味します。このオプションを使用すると、コンテナがバックグラウンドで実行され、ターミナルがそのまま使える状態になります。 -
--build
オプションは、サービスのイメージをビルドまたは再ビルドするために使用されます。このオプションを指定すると、既存のイメージがある場合でも、Dockerは必ず新しいイメージをビルドします。これにより、Dockerfileやビルドコンテキストに変更があった場合でも、常に最新の状態のイメージが使用されます。
VScodeでのコンテナのリモートウィンドウの開き方
私はエディタにVScodeを使っているのでVScodeでの開き方を説明します。エンコードや文字コードが記載されている最下部の細いバーの一番左のクリックします。するとリモートウィンドウを開くオプションの選択画面が現れるので、実行中のコンテナにアタッチという項目を選択して起動しているコンテナ一覧から開きたいコンテナを選択します。
GUIの設定
仮想環境ではそのままだとGUI操作(matplotlibでの図形の表示等のグラフィカルな操作)ができないため設定を変更する必要があります。
- VcXsrvのインストール (https://sourceforge.net/projects/vcxsrv/)
DockerコンテナのLinuxでGUIアプリを動かす一般的な方法に、Xサーバ(X Window System)を使うというものがあります。なぜなら普通にDockerコンテナを作成するだけでは、Xサーバがインストールされていないので、CUIコンソールしか機能せず、GUIのウィンドウの描画やキーボードやマウスからの入力といったものは出来ないためです。
なので、まずはホストPC側にVcXsrvというXサーバソフトウェアをインストールする。インストール出来たらスタートメニューからXLaunchを起動して設定を行います。
ほとんどデフォルト設定で問題ありませんが、ここはチャックを入れないとGUIが表示されません。
設定が完了したら最後のsave configrationを押してDocumentsファイル等の適当な場所にVcXsrvファイルを作り、設定ファイルを保存しておくとXlaunchを開くたびに設定を変更する手間がないのでやっておきます。(Program Filesのほうにインストールの際に作られたVcXsrvファイルがあるためそれと混同しないようにしましょう。)
- DockerDesktop のインストール (https://www.docker.com/products/docker-desktop/)
wsl上でコマンドラインを使ってdockerをインストールする方法もありますが、ホストマシンとの紐づけなどで難易度が高いです。そのためwslとホストマシンの紐づけが容易なDockerDesktopをインストールしましょう。インストールできたらメールアドレスとパスワードも登録しましょう。
Setting画面を開いてGeneralの以下の二つがオンになっているか確認します。(なってなかったらオンにしてください)
さらにResoucesのWSL integrationでdockerを使いたいWSLの項目をオンにすることで紐づけが完了します。(全部オンにしてもいいです)
DockerDesktopアプリは立ち上げておかないと機能しないためwindowsの設定からスタートアップアプリにしておきましょう。
- Xサーバ側の接続許可設定をする
コンテナ側で実行されたアプリが、自動的にホスト側のXサーバに接続して、GUIの描画を行う仕組みなので、コンテナ側にホストのIPアドレスを教える必要があります。
次にWindows Powershell を起動して、ipconfig
コマンドを使ってホストマシン側のIPアドレスを確認します。(WSLのIPアドレスと混同しないように)
次にwindowsのスタートメニューを開き”メモ帳”と入力し、右クリックで管理者権限でメモ帳を実行します。「ファイル」→「開く」でローカルのProgram FilesにあるVcXsrvファイルの「X0.hosts」を開き、上記で調べたIPアドレスを以下のように追記して保存しましょう。
- コンテナ作成の準備をして起動
上記で作成したdockerのディレクトリに移動し、docker-compose up -d --build
コマンドでビルドしましょう。(.devcontainorディレクトリで実行しましょう。)
x11-apps
をインストールしているため、xeyesコマンドを打って目が出力されれば設定完了です!
- 備考
実際にこのようなエラーが出たためその時は同じようにすると解決するかもしれません。
root@52685fd6608c:~# xeyes
Warning: locale not supported by C library, locale unchanged
local -a
で利用可能なロケールを確認すると以下のような結果が出力されました。
root@52685fd6608c:~# locale -a
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_COLLATE to default locale: No such file or directory
C
C.UTF-8
POSIX
利用可能なロケールが非常に限られていることと、デフォルトのロケールの設定が不完全であることが示唆されています。よって以下のようにして解決しました。
apt-get update #必要なパッケージのインストール
apt-get install -y locales
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen #ロケールの生成
locale-gen
update-locale LANG=en_US.UTF-8 #ロケールの設定
export LANG=en_US.UTF-8 #環境変数の設定
xeyes #GUIがうまく動作するか確認
sudo systemctl restart docker
でdockerを再起動
方法2:DockerHubからdockerイメージをPullする
この方法はローカルでコンテナイメージを作成する方法と違って、Dockerhubからchainerの公式が出しているイメージを引っ張ってくる1つのコマンドでイメージが作成できるため、より環境構築にあたっての確実性が高い手法です。
docker pull chainer/chainer
ただし、コンテナイメージを起動する際に多少オプションで設定を変更できるとはいえコンテナの設定ファイル等がローカルにあるわけではないため、拡張性に乏しくGUIの設定等ができませんでした。
方法1がうまくいかない時の非常手段くらいに考えておいたほうがいいかもしれません。
※pythonコマンドはpython3と記述しないと動作しない。
エラーとその対処集
筆者に起きた個人的なエラーから環境構築でよくみられるエラーまで、確認できたエラーとその対処法を載せていきます。何かあったら参考にしてみてください。
-
docker-compose upを行って、その後修正点か何かに気づいてもう一度docker-composeb upしようとしても ~handsshake~といったエラーが出る
コンテナのビルドでエラー、ないしはミスに気付いて強制終了をしてコンテナをビルドしなおすときにでてくるエラーです。
一度docker-composeに失敗してしまうと次回以降ベースイメージをロードする際に以下のようなエラーが起こるようになってしまいます。
$ docker-compose up -d --build [+] Building 10.7s (4/4) FINISHED docker:default => [docker-chainer internal] load .dockerignore 0.1s => => transferring context: 2B 0.0s => [docker-chainer internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 702B 0.0s => ERROR [docker-chainer internal] load metadata for [docker.io/nvidia/cuda:12.2.0-devel-ubuntu20.04](http://docker.io/nvidia/cuda:12.2.0-devel-ubuntu20.04) 10.6s => [docker-chainer auth] nvidia/cuda:pull token for [registry-1.docker.io](http://registry-1.docker.io/) 0.0s [docker-chainer internal] load metadata for [docker.io/nvidia/cuda:12.2.0-devel-ubuntu20.04:](http://docker.io/nvidia/cuda:12.2.0-devel-ubuntu20.04:) failed to solve: nvidia/cuda:12.2.0-devel-ubuntu20.04: failed to authorize: failed to fetch oauth token: Post "https://auth.docker.io/token": remote error: tls: handshake failure
原因としては、中途半端にコンテナができて新しくコンテナを作るときに競合してしまうからだと考えられます。
対処法として一度失敗したら
docker-compose down
で作りかけのコンテナおよびネットワークを削除し、dockerdesktopでリソースのほうでも削除する(これは必要ないかもしれませんが念のため)と、再びdocker-compose up
が使えるようになります。 -
couldn't connect to display "10.255.255.254:0
Traceback (most recent call last): File "/usr/local/lib/python3.8/dist-packages/matplotlib/backends/_backend_tk.py", line 859, in new_figure_manager_given_figure window = tk.Tk(className="matplotlib") File "/usr/lib/python3.8/tkinter/__init__.py", line 2270, in __init__ self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use) _tkinter.TclError: couldn't connect to display "10.255.255.254:0" ```
このエラーはコンテナを多く立てすぎたのか、直接因果関係があるのか分かりませんがいったんdocker-compose down
でコンテナおよびネットワークをすべて削除し、dockerdesktopでリソースのほうでも削除し、再びdocker-compose up
することで直りました。
-
matplotlibを使ってエラーが出てないのにGUIが操作できない
このエラーはコンテナをビルドし、GUIの設定も完了し終えた後に出てきたエラーです。matplotlibを使うプログラムが実行はされるが画像が出てきませんでした。プログラムは実行されているので、ctl+Cしないとシェルにプログラムは打てない状況でした。
原因としてはコンテナを立ち上げたときにmatplotlibが
agg
バックエンドを使用しているため、グラフをインタラクティブに表示できないからでした。agg
バックエンドは非GUIバックエンドであり、通常、グラフをファイルに保存する場合にのみ使用されます。解決策としてmatplotlibが動く環境などが他にもあれば、そこで以下のようにしてGUIバックエンドを確認します。(GUIバックエンドなら多分何でもいいです)
Type "help", "copyright", "credits" or "license" for more information. >>>import matplotlib >>>print(matplotlib.get_backend()) Qt5Agg
私の環境ではQt5AggをデフォルトバックエンドGUIとして扱うものとして話を進めます。
DockerfileにデフォルトバックエンドGUIの変更を記述します。
まず
Qt5Agg
をDocker環境で使用するためには、PyQt5
をインストールする必要があります。Dockerfileに以下の変更を加えて、この依存関係をインストールします。-
requirements.txt
および Dockerfile の適切な位置に以下を追加してPyQt5
をインストールします。
pip install PyQt5
- Dockerfile内で、matplotlibのデフォルトバックエンドを
Qt5Agg
に設定する環境変数を設定します。
ENV MPLBACKEND="Qt5Agg”
再度matplotlibを使っているプログラムを実行するとGUIが表示されるはずです。
(参考記事)
python:matplotlib:cui環境 [雑多な記録]
-
-
Warning: locale not supported by C library, locale unchanged
root@52685fd6608c:~# xeyes Warning: locale not supported by C library, locale unchanged
とエラーが出た際に、
local -a
で利用可能なロケールを確認すると以下のような結果が出力されました。root@4b8d92a592f6:/home# locale -a locale: Cannot set LC_CTYPE to default locale: No such file or directory locale: Cannot set LC_MESSAGES to default locale: No such file or directory locale: Cannot set LC_COLLATE to default locale: No such file or directory C C.UTF-8 POSIX
利用可能なロケールが非常に限られていることと、デフォルトのロケールの設定が不完全であることが示唆されています。よって以下のようにして解決しました。
apt-get update #必要なパッケージのインストール apt-get install -y locales echo "en_US.UTF-8 UTF-8" > /etc/locale.gen #ロケールの生成 locale-gen update-locale LANG=en_US.UTF-8 #ロケールの設定 export LANG=en_US.UTF-8 #環境変数の設定 xeyes #GUIがうまく動作するか確認
なお、
update-locale LANG=en_US.UTF-8
で以下のエラーが出ることがあります。root@4b8d92a592f6:/home# update-locale LANG=ja_JP.UTF-8 perl: warning: Setting locale failed. perl: warning: Please check that your locale settings: LANGUAGE = (unset), LC_ALL = (unset), LANG = "en_US.UTF-8" are supported and installed on your system. perl: warning: Falling back to the standard locale ("C").
perl: warning: Setting locale failed. というエラーは、Perl がロケール設定に失敗したことを示しています。
これは、update-locale コマンドが LANG 環境変数を en_US.UTF-8 に設定しようとしているにもかかわらず、このロケールがシステムにインストールされていないことが原因と考えられます。
コンテナ内でlocale-gen en_US.UTF-8
を実行して、再度update-locale LANG=ja_JP.UTF-8
するとロケールの設定ができるようになり、xeyes
も実行できました。 -
DISPLAY変数が反映されていない
何らかの理由でDISPLAY変数が反映されておらず、GUI操作ができない可能性があります。
コンテナ内でecho $DISPLAY
を実行し、.envに記入した内容と一致しているか確認します。
一致していない場合はexport DISPLAY=192.168.12.8:0.0
(自分の.envに合わせてアドレスは変更してください)でひとまず解決します。 -
学習時間が明らかに遅い
エラーではありませんが実際に起こったことです。学習等が正常に行われているのにも関わらず、研究室の他のGPUマシンで同じプログラムを動かし比較してみると、学習時間が倍以上違いました。
原因としてはモジュールやライブラリが欠けている可能性があります。
私の環境ではCUDNNが最適でないものがインストールされていたようで、認識されていませんでした。手間ですが調べ上げて修正したほうがいいです。(私の場合1学習ごとに24時間くらいの差が出ました。)
ここからCUDNNのバージョンを確認してDockerfileに個別でCUDNNのインストールの文を打っておくと確実だと思います。
pipではなくaptを使うためコンテナを立て直す必要があるので、ビルドしなおして学習時間が短縮されたか確認しましょう。
-
DockerfileでCUDNNのインストールができない
先ほどのCUDNNインストールに付随したものです。あっさりインストールされればそれでいいのでこの文は読まなくていいです。
CUDNNのインストールがうまくいかなかったのでベースイメージにCUDNNを含めて指定してみましたがエラーでした。筆者のエラーメッセージを確認すると、指定した
nvidia/cuda:12.0-cudnn8-runtime-ubuntu20.04
イメージがDocker Hubに存在しないことが示されていました。(ベースイメージとしてCUDAとCUDNNを同時に入れてしまいたかったのですがそのようなイメージがありませんでした。)正しいタグを指定するために、Docker HubのNVIDIA CUDAのページを参照して、利用可能なタグを確認します。
- Docker HubのNVIDIA CUDAのページにアクセスします。
- 利用可能なタグを確認します。たとえば、
11.0-cudnn8-runtime-ubuntu20.04
のようなものを探します。 - 正しいタグを見つけたら、Dockerfileの
FROM
行をそれに合わせて更新します。 - 再度、
docker-compose up -d --build
を実行します。
また、特定のバージョンのCUDAやcuDNNが必要でない場合はタグを緩和して、たとえば**
nvidia/cuda:11.0-runtime-ubuntu20.04
**のようにして、問題を回避することもできます。ベースイメージはここで見つけます。ubuntu用には3種類あるので注意
バージョン名について
- base: 最小構成
- runtime: baseを拡張したもの
- devel: runtimeを拡張したもの
開発用・学習用であれば、基本的にdevelを選んでおけば問題ないと思います。(devel にしか nvccが無いなどの問題がある)
CUDA 12.0のコンテナを試します。
バージョンは、Docker Hubを参照して指定します。
-
一度pipでインストールしたモジュールがインポートできない
コンテナを起動しなおした際にモジュールがリセットされている可能性があります。
pipでインストールしたらrequirements.txtにも追記しましょう。そうすると次回以降の起動でもインポートができるようになります。 -
requirements.txtに記述しているnumpyのインストールがうまくいかない
この問題の原因として考えられるのは、他のモジュールのバージョンのセットアップスクリプトが、メタデータの生成の段階で
numpy
に依存しているためです。
numpy
を先にインストールしましょう。Dockerfile
において、numpy
のインストールをrequirements.txt
を使わずに、先に実行することでこの問題を回避できます。 -
コンテナ名やコンテナイメージ名に大文字を使用
エラーメッセージも恐らく出ますが大文字はコンテナをビルドする際にはできません。
-
pipとcondaの混在
これは起こりがちなミスです。condaとpipを併用しないでください。
condaとpipはどちらもインストール管理ツールです。ソフトウェアのパッケージ管理先がcondaはAnaconda。pipはPyPIで異なります。Anaconda環境は、最初にPythonを使う目的では最低限必要なものが揃ってて便利な反面、他のパッケージはPyPIの方が豊富なので、別途pipでインストールすることも多いです。
ただし、condaとpipのインストールが混在するとパッケージ間の依存関係に問題が出たり最悪環境が壊れることもあるので、基本的にcondaとpipは併用しないことが推奨されています。
すでにUbuntuなどのLinuxディストリビューションにanacondaを入れている場合は、削除の方法は大きく分けて3つあります。・anacondaのフォルダごと消す
・アプリと機能からアンインストール選択
・anaconda-cleanを実行
です。ただ、anaconda環境でも色々と作業を進めていて削除したくない場合もあると思います。そんなときはバージョンの違うLinuxディストリビューションを別にインストールし、ファイルをコピーして環境を作り直した方が早いと思います。(筆者の場合はUbuntu22.04LTSにanacondaを入れて使っていたので、新しくUbuntu20.04LTSをインストールしてpip用の環境にしました。)conda install anaconda-clean anaconda-clean rm -rf ~/anaconda3 vi ~/.bashrc で>>> conda initialize >>> から <<< conda initialize <<<までを削除 source ~/.bashrc
参考記事
- エラーメッセージ
docker.errors.DockerException:
Error while fetching server API version:
HTTPConnection.request() got an unexpected keyword argument 'chunked’」
これはrequestのバージョンを2.31.0にすると解決します。
-
permission denined
dockerコンテナ内で操作したファイルは以下のようにroot権限でしかいじれなくなっています。
-rw-r--r-- 1 root root 186 Jun 21 13:13 test.py
sudo コマンドを使用すると、仮想環境が無効化されてしまいます。そのため、
sudo chown -R user:user /home/user/research
を行い、reserarch ディレクトリ以下のすべてのファイルとフォルダの所有者を現在のユーザー(user:自分のユーザー名に変更してください)に変更します。これにより、sudo を使わなくてもアクセスできるようになります。
-
その他
CUDAは最新のバージョンを入れればいいというわけではないということに留意してください。
バージョンの確認方法は以下のコマンドを参照して下さい。
```bash
$ python3
>>>import chainer
>>>chainer.print_runtime_info()
```
以下のような結果が出ます。
```
bash
chainer.print_runtime_info()
Platform: Linux-5.15.90.1-microsoft-standard-WSL2-x86_64-with-glibc2.29
Chainer: 7.8.1
ChainerX: Not Available
NumPy: 1.24.4
CuPy:
OS : Linux-5.15.90.1-microsoft-standard-WSL2-x86_64-with-glibc2.29
Python Version : 3.8.10
CuPy Version : 12.2.0
CuPy Platform : NVIDIA CUDA
NumPy Version : 1.24.4
SciPy Version : 1.5.4
Cython Build Version : 0.29.36
Cython Runtime Version : 0.29.35
CUDA Root : /usr/local/cuda
nvcc PATH : /usr/local/cuda/bin/nvcc
CUDA Build Version : 12020
CUDA Driver Version : 12020
CUDA Runtime Version : 12020
cuBLAS Version : 120201
cuFFT Version : 11008
cuRAND Version : 10303
cuSOLVER Version : (11, 5, 2)
cuSPARSE Version : 12102
NVRTC Version : (12, 2)
Thrust Version : 200101
CUB Build Version : 200101
Jitify Build Version : <unknown>
cuDNN Build Version : 8801
cuDNN Version : 8905
NCCL Build Version : 21602
NCCL Runtime Version : 21805
cuTENSOR Version : None
cuSPARSELt Build Version : None
Device 0 Name : NVIDIA TITAN RTX
Device 0 Compute Capability : 75
Device 0 PCI Bus ID : 0000:2B:00.0
iDeep: Not Available
```
私は最初、最新のCUDA(chainer開発終了後に出ている)とそれに対応するcudnnをインストールしていたせいでうまく動作しませんでした。
備考
この記事ではNvidiaDriverのインストールのみはローカルで行っており、他に必要なものは仮想環境でそろえるというものでしたが、NvidiaDriverごとコンテナに積むという手法もあるみたいです。( 試してません。)
参考にした記事