UbuntuでのDeep LearningにはDockerが最適

UbuntuでのDeep LearningにはDockerが最適

こんにちは.怠惰人間です.今日は,Ubuntu PCにDockerをインストールするのが今の私にとって最適だと思うという話をしようと思います.

目次

UbuntuでのCUDAインストールの問題点

2021年8月現在,UbuntuのLTSは20.04と18.04の2種類がありますが,18.04に関しては2023年4月にサポート期限が来てしまうため,皆様もそろそろ20.04に乗り換えているころではないでしょうか?

今回はこのUbuntu LTSとDeep Learningに(ほぼ)必須といえるCUDAのインストールに関する問題について解説していこうと思います.

UbuntuのLTS(Long Term Support)とは

Ubuntu のLTS(Long Term Support)とは,Ubuntuの通常のバージョンのサポート期限が約1年なのに対して約5年間のサポートが受けられる特別なバージョンのことです.

このLTSは通常2年ごとにリリースされます.実際,18.04 LTSは2018年4月に,最新版の20.04 LTS は2020年4月にリリースされています.

サポートが終了したバージョンではセキュリティに関するアップデートなどが受けられなくなるため,何か特別な事情が無い限りは通常はLTSを使用することが一般的です.

LTSとCUDAの対応問題

このUbuntu LTSでは普段意識しませんが,実はバージョンによって公式が提供していないCUDAが存在します.

以下にUbuntu LTSのバージョンとCUDAのバージョンの対応関係を示します.

LTS Version対応CUDAバージョン
16.04 LTS8.0~11.3
18.04 LTS10.0~最新
20.04 LTS11.0~最新

なお,このバージョン関係は公式のCUDAインストールページでわかるほか,aptリポジトリ(e.g. Ubuntu 20.04 LTS)を確認してもわかります.

上記の表を確認するとわかるのですが,基本的に古いバージョンのCUDAは新しいUbuntuのバージョンでは対応していません.

例えば,20.04 LTSでCUDA 10.1をインストールしたい場合には,18.04 LTS用のCUDA 10.1インストーラーを使用してインストールすることになります.

基本的にはこれで動作しますが,対応していないバージョンのパッケージをインストールするのはあまりお勧めできません.

ちなみに,これらのCUDAインストーラ同じバージョンであれば全て同じ内容というわけではなさそうです.

実際に,18.04用のCUDA 11.0のdebファイルと20.04 LTS用のそれをapt リポジトリからダウンロードしてMD5ハッシュを計算してみると,異なることが分かります.

$ wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-11-0_11.0.3-1_amd64.deb
$ wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-11-0_11.0.3-1_amd64.deb
$ md5sum cuda-11-0_11.0.3-1_amd64.deb;md5sum cuda-11-0_11.0.3-1_amd64.deb.1
72572bbefff7a1d1692605490446a00c  cuda-11-0_11.0.3-1_amd64.deb
cb620e91b0e0b9877b8cda468df129d2  cuda-11-0_11.0.3-1_amd64.deb.1

また,そのほかにも,CUDAをaptリポジトリ経由で追加しようとした際に,18.04用のリポジトリと20.04用のリポジトリを同時に追加すると,両者のインストールの優先度が同じになってしまい,どちらのリポジトリからインストールされたのかがややこしくなるという問題もあります.

これは,「apt policy」コマンドで確認できる.なお,この優先度設定はCUDAのリポジトリ設定時にダウンロード・配置した「/etc/apt/preferences.d/cuda-repository-pin-600」に記載があります.

$ sudo apt policy | grep https://developer.download.nvidia.com/compute/cuda
 600 https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64  Packages
 600 https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64  Packages

ちなみに,この結果の一番左の600というのが優先度です.

この優先度の詳しい仕様はaptコマンドの公式ページを確認してください.

この問題があるため,CUDAを生でインストールする方法は環境構築時にバグを生じさせる可能性があり,私的には非推奨です.

そこで私は最近,Dockerを使用してDeep Learning環境を構築しています.

Dockerとは

色々なところでさんざん説明されているので今更かもしれませんが,Dockerについて初めて聞いた,詳しく知らないという人のために簡単に解説しようと思います.

DockerとはLinuxのコンテナという技術をベースにした技術で,従来の仮想化技術(e.g. Virtual Box)などとは違い,アプリケーション(正確にはシステムコール)を仮想的に実行します.

動作イメージを下記の図に示します.

Dockerと通常の仮想化技術の違い.

アプリケーションを仮想的に実行するだけなので,従来の仮想化技術と違い,動作が軽いという特徴があります.

Nvidia-Docker

Nvidia Dockerとは,DockerでNvidia社製のGPUを使用するためのアドオンです.

Dockerは公式でGPU利用ができないので,Nvidia社が開発しているアドオンを追加することで,GPUの利用が可能になります.

Nvidia-DockerはOSS(Open Source Software)なので,公式のGitHubでコードも確認できます.

Nvidia-Dockerはこの記事を記載している現在,Linuxのみ対応しており,Windows版は現在beta版です.

DockerでGPU環境を利用

Dockerと,Nvidia-Dockerを組み合わせることで,CUDAやCuDNNを利用できるコンテナ(~=アプリケーション)を簡単に作ることができます.

さらに,Dockerを使用することで,Ubuntuのバージョンが不一致のCUDAインストーラーを使用しなくてよくなるため,環境で設定で躓くといったこともなくなります.

というか,そもそもCUDAをインストールする必要すらなくなります.

Docker+Nvidia-Dockerのインストール方法(2021/08/26版)

この記事を書いている時点でのDockerとNvidia DockerのUbuntu 20.04LTSへのインストール方法を本章では記載します.

もしインストールに失敗する等のことがあれば,Dockerの公式ページNvidia-Dockerの公式ページを確認してください.

インストールは以下のコマンドを順に実施するだけでOKです.一番先頭の「$」マークは入れないように注意してください.

$ sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
$ echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \
  | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt update
$ sudo apt install -y docker-ce docker-ce-cli containerd.io
$ 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 update -y
$ sudo apt install -y nvidia-docker2
$ sudo systemctl restart docker
$ sudo usermod -aG docker $(whoami)

上記のプログラムを使用後は,必ず1度コマンドラインから抜けてください.(sshなら繋ぎなおす,GUIならターミナルを再起動する)

Docker+Nvidia Dockerの使い方

本章では,Dockerの使い方を簡単に,非常に簡単に最低限説明します.より詳しい使い方を知りたい人は参考書などを読むか,公式ページを確認してください.

起動したいDockerイメージ(~=アプリケーションの圧縮ファイル)をDocker Hubというサイトで探します.

基本的にログインは不要で,画面上にある検索窓から探す感じです.

例えば,tensorflowのイメージを探すと以下になります.

Docker Hubで「tensorflow/tensorflow」を検索した結果
Docker Hubにて「tensorflow/tensorflow」を検索した結果 (https://hub.docker.com/より引用)

このように,検索結果が出るため,検索結果の各ページを閲覧します.

多くの場合には,この検索結果のページにdockerイメージの使い方が記載されています.

例えば,tensorflowなら以下のような使い方が記載されています.

tensorflow/tensorflowの使い方のページ
tensorflow/tensorflowの使い方のページ (https://hub.docker.com/r/tensorflow/tensorflowより引用)

多くの場合にはこのように記載されている方法で起動することでアプリケーションを実行することができます.

Docker コンテナイメージを起動する

まず初めに,dockerコンテナの起動時に使用するコマンドである「docker run」のオプションについて簡単に説明します.

オプション内容
–gpus allGPUをコンテナで利用する
–rmアプリケーション終了後にコンテナを削除する.(基本的につけておいた方が便利)
–name NAME実行しているコンテナに名前を付ける
–mount type=bind,src=HPATH,dst=VPATHコンテナのVPATHにHPATHをマウントします.VPATH内で変更した内容はHPATHに反映されます
-p HPORT:VPORTホストのHPORTにアクセスすると,コンテナのVPORTに接続できるようにします
-itキーボード入力と標準出力を利用可能な状況で実行します
「docker run」のオプション.大文字はユーザが任意で入力する箇所

実際に,以下の条件でtensorflowを動かしてみる場合には以下のコマンドを入力します.

  • コンテナ名は”MY_TENSORFLOW”とする
  • ホストの10000番ポートにコンテナの6006番ポートをマッピングする(tensorboardのため)
  • ホストの「/home/testuser/work」をコンテナの「/work」にマウントする
$ docker run --gpus all --rm --name MY_TENSORFLOW --mount type=bind,src=/home/testuser/work,dst=/work -p 10000:6006 -it tensorflow/tensorflow:latest-gpu bash

このコマンドを実行すると,bashが起動されます.この状態で,

TF_CPP_MIN_LOG_LEVEL=3 python -c "import tensorflow as tf;print(tf.__version__);print(tf.test.is_gpu_available())"

を実行すると,以下のような結果が得られます.

2.6.0
WARNING:tensorflow:From <string>:1: is_gpu_available (from tensorflow.python.framework.test_util) is deprecated and will be removed in a future version.
Instructions for updating:
Use `tf.config.list_physical_devices('GPU')` instead.
True

この結果から,Tensorflowのバージョンが現在最新の2.6で,GPUの利用がTrueであることが分かります.

なお,今回はバージョンを「latest=最新」に設定しているので,実行時期によっては2.6より高くなる可能性があると思います.

また,「/home/work」にちゃんとマウントできているかを確認するために

$ ls / | grep work

を入力すると

work

が出力され,ちゃんとマウントできているのが分かります.

Dockerコンテナのattachとdetach

例えば学習をする際など,出力を確認せずに,放置しておきたいときがあるかと思います.

Dockerではそんな時にデタッチ機能が使用できます.デタッチ実行すると,Dockerコンテナ内で実行したコマンドは動作したまま,ホストに操作を戻すことができます.

イメージは下記のような感じです.

起動・終了と,アタッチ・デタッチの違い

起動・終了と異なり,アタッチ,デタッチではバックグラウンドでアプリが起動し続けるのが特徴です.

実際にDockerコンテナのアタッチする際には,以下のコマンドを使用します.

$ docker attach NAME

なお,上記の「NAME」には,「docker run」のオプションの「–name」で指定したものを使用します.

Dockerコンテナをデタッチする際には「CtrlとPの同時押し → CtrlとQの同時押し」を実施します.

まとめると,

  • アタッチ: docker attach NAME
  • デタッチ: CtrlとPの同時押し → CtrlとQの同時押し

です.

今日の内容は以上

コメントを残す

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