Ubuntu20.04とdockerで機械学習用GPUサーバ構築(後編)

投稿者: | 2021-02-23

Ubuntu 20.04で機械学習用GPUサーバを構築する機会があったのでその手順を公開します。今回は

  • 環境を切り分けるためにdockerのコンテナに分析環境を構築
  • コンテナ側でGPUを認識しTensorflowを利用
  • 外部からコンテナのJupyter notebookに接続

という構成をとっています。

前編ではUbuntu 20.04のセットアップを行いました。後編では

  • NVIDIA ドライバのインストール
  • Docker のインストール
  • NVIDIA Container Toolkitのインストール

を行います。

NVIDIAドライバのインストール

NVIDIA Docker って今どうなってるの? (20.09 版)」を参考にまず「CUDA Toolkit」のページで

  • Operating System: Linux
  • Architecture: x86_64
  • Distribution: Ubuntu
  • Version: 20.04
  • Installer Type: deb(local)

を選んで”Base Installer”の”Installation Instructions:”のコマンドを参考にcuda-driversパッケージをインストールします。

なお、”Installation Instructions:”の最終行はcudaをインストールするコマンドになっているのでcuda-driversに変更しています。

$ wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin
$ sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600
$ wget https://developer.download.nvidia.com/compute/cuda/11.2.1/local_installers/cuda-repo-ubuntu2004-11-2-local_11.2.1-460.32.03-1_amd64.deb
$ sudo dpkg -i cuda-repo-ubuntu2004-11-2-local_11.2.1-460.32.03-1_amd64.deb
$ sudo apt-key add /var/cuda-repo-ubuntu2004-11-2-local/7fa2af80.pub
$ sudo apt-get update
$ sudo apt-get --no-install-recommends install cuda-drivers

インストールが終われば再起動し、GPUを認識できているか確認します。

$ nvidia-smi

として

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 460.32.03    Driver Version: 460.32.03    CUDA Version: 11.2     |
|-------------------------------+----------------------+----------------------+
| 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  GeForce GTX 108...  On   | 00000000:01:00.0 Off |                  N/A |
|  0%   41C    P8    10W / 270W |      1MiB / 11178MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   1  GeForce GTX 108...  On   | 00000000:02:00.0 Off |                  N/A |
|  0%   37C    P8    10W / 270W |      1MiB / 11178MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

とGPU情報が表示できればGPUドライバのインストールは完了です。今回は2枚のGPUを挿しており2枚とも認識されています。

Dockerのインストール

まずDockerをインストールします。https://get.docker.comにアクセスするとインストールスクリプトを返してくれるので

$ curl https://get.docker.com | sh

とします。dockerサービスの起動と自動実行の設定を行います。

$ sudo systemctl start docker
$ sudo systemctl enable docker

次にsudoなしにdockerコマンドを実行するために

$ sudo usermod -aG docker $USER

としてDockerのインストールは完了です。念のため

$ docker --version

として18.09以降のバージョンになっているか確認しておきます。

NVIDIA Container Toolkitのインストール

NVIDIA Container Toolkitとしてnvidia-docker2パッケージをインストールします。

$ 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
$ sudo apt-get update
$ sudo apt-get --no-install-recommends install nvidia-docker2
$ sudo systemctl restart docker

これでDockerコンテナでGPUを使う準備ができました。ここからはDockerコンテナを作成します。

Dockerコンテナの作成

DockerでのJupyter notebook環境の構築」で作ったコンテナ(jupyter_base)をベースにnvidia_docker_baseというコンテナを作っていきます。DockerfileなどはGithubに上げているので

$ git clone https://github.com/starpentagon/docker_image.git
$ cd docker_image/nvidia_docker_base 

とダウンロードします。

コンテナjupyter_baseは

  • Ubuntu 20.04をベースイメージとして利用
  • Jupyter notebookのインストール
  • Jupyter notebookの外部接続用パスワードの設定
  • 外部接続用パスワードを生成するスクリプトのコピー
  • ユーザの追加
  • 作業ディレクトリの作成
  • ポートの開放

としていたのに加えてnvidia_docker_baseは

  • nvidia/cudaをベースイメージとして利用
  • CUDA 11.0, cuDNN 8をインストール
  • Tensorflow, matplotlibをインストール

としています。実はここに行きつくまでにつまづいたところがあり

  • パッケージのインストール中にキーボード設定が出て止まってしまうのを避けるため”ARG DEBIAN_FRONTEND=noninteractive”を設定
  • コンテナにCUDA 11.2を入れるとTensorflow実行時に”libcusolver.so.10″が見つからないとエラーが出たのでCUDA 11.0をインストール

としています。

Dockerfile以外のスクリプトを説明するとdocker_build.shはDockerイメージをビルドし、もし外部接続用パスワードが設定されていない場合は設定方法を表示します。

docker_run.shでは

  • 作業ディレクトリのマウント
  • Dockerエンジン/コンテナ間のポートのマッピング

をしてGPU付きでDockerコンテナを起動します。

Jupyter notebook接続用のパスワードの設定

Jupyter notebook接続用のパスワードを事前に設定しておく必要があります。まず

$ ./docker_build.sh

を実行します。初回実行時はイメージをダウンロードするため少し時間がかかります。

一度、

$ docker run --rm -it nvidia_docker_base

でコンテナに入ります。コンテナ内で

$ python3 ~/scripts/pass.py

を実行するとパスワードを聞かれるので入力すると

ARG JUPYTER_PASSWD='sha1:25e2bc817b10:917f1e38841d80dfa40535f60a88bc83c5228297'

などのハッシュ化されたパスワードが表示されるのでコピーしておきます。(sha1:以下は入力したパスワードに応じて変化します。)

コンテナ内での作業は終わりなので

$ exit

としてコンテナから抜けます。ホスト側でDockerfileを開いて

ARG JUPYTER_PASSWD=''

となっている部分を先ほどコピーした内容に書き換えます。

Dockerコンテナの起動

パスワードの設定が終わったら再度、イメージをビルドしてコンテナ起動しJupyter notebookを立ち上げます。

$ ./docker_build.sh
$ ./docker_run.sh

コンテナとGPUサーバのポートをマッピングしているのでGPUサーバのIPアドレス(今回は192.168.10.16)に対してhttp://(GPUサーバのIPアドレス):8888 にアクセスします。

パスワードが求められるので先ほどのパスワードを入力するとJupyter notebook接続できGPUを使った処理をすることができます。また、Jupyter notebookで編集したノートブックはGPUサーバの./nvidia_docker_base/workディレクトリに保存されます。

以上で次の構成の機械学習用のGPUサーバの構築が完了しました。

GPUを使った機械学習

最後にGPUを使った機械学習をしてみましょう。TensorflowのチュートリアルにあるFashion MNISTの学習モデル構築をしてみます。チュートリアルのページからNotebookをダウンロードしGPUサーバの./nvidia_docker_base/workに置きます。

$ cd ~/docker_image/nvidia_docker_base/work
$ wget https://storage.googleapis.com/tensorflow_docs/docs-l10n/site/ja/tutorials/keras/classification.ipynb

http://(GPUサーバのIPアドレス):8888にアクセスしパスワードを入力するとJupyter notebookに接続できます。先ほどダウンロードしたclassification.ipynbを開いて実行します。

ポイントはモデルの学習

model.fit(train_images, train_labels, epochs=5)

にGPUを利用し高速化できます。GPUサーバにつないで

$ watch -n 1 "nvidia-smi"

とGPUの利用状況を監視しながら学習を実行すると

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 460.32.03    Driver Version: 460.32.03    CUDA Version: 11.2     |
|-------------------------------+----------------------+----------------------+
| 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  GeForce GTX 108...  On   | 00000000:01:00.0 Off |                  N/A |
|  0%   32C    P2    69W / 270W |  10591MiB / 11178MiB |     27%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   1  GeForce GTX 108...  On   | 00000000:02:00.0 Off |                  N/A |
|  0%   32C    P8     9W / 270W |    253MiB / 11178MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

と確かに学習時にGPUを利用[1]チュートリアルのスクリプトではGPUが複数枚あっても1枚しか使いません。していることがわかります。

参考

脚注

1 チュートリアルのスクリプトではGPUが複数枚あっても1枚しか使いません。

スポンサーリンク


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です