はじめに
前回の記事ThinkPad T480SでUbuntu18.04LTSのデュアブ環境構築でUbuntu18.04のデュアルブートができるようになるところまでやりました。今回はこのUbuntu上でGPUをDeep Leaningに使用できるようになるところまでやります。
環境構築の方針ですが、GPUはバージョンに非常にシビア(Keras2.2.1をKeras2.2.2にアップデートしたらGPUが動かなくなったことが以前あった)であるため、今回はNvidia-Dockerを用いてGPU環境を整えていきます。これにより必要に応じて仮想環境を立ち上げればよく、バージョン管理がしやすくなることが期待されます。
- 使用環境
- ThinkPad T480S
- GeForce MX150
- 24GB DDR4
- Core i7-8550U
- Ubuntu18.04
## 概要
- Nvidia Driverのインストール
- Dockerのインストール
- Nvidia-Dockerのインストール
- 動作確認
Nvidia-Driverのインストール
まずはNvidia-Driverをインストールします。これがないとCUDAやNvidia-Dockerが使用できません。
Nvidia-Driverを入れる前に少しUbuntuの設定を済ませます。
Ubuntuの初期設定についてはUbuntu 18.04 LTSのインストール直後にやっておきたいことまとめに詳しいです。すべてをやる必要はないと思いますが、適宜設定を行いましょう。今回必須だと思われるのはCanonicalパートーナーレポジトリの有効化です。これによりサードパーティ製のソフトウェアがインストールできるようになります。
Nvidia-Driverのインストール自体は非常に簡単です。端末を開いて
$ sudo ubuntu-drivers autoinstall
とコマンドすることでDriverのバージョンが自動で選択されてインストールされます。コマンドすると以下の画像のようにUEFI Secure Bootを有効化するように要求されるので以下の手順で有効化してください。
このメッセージが出て端末の操作が効かなくなり対処に困りますが、「ソフトウェアの更新」というアプリケーションを開きソフトウェアの更新を行うと下の画像のような画面になります。
この画面で右上のNextを押すと認証用のパスワードを設定することを要求されるので2箇所に同じパスワードを入力します。
これで再起動するとBIOSが自動的に開かれるのでEnroll MOKを選択し先ほど設定したパスワードを入力したらUEFI Secure Bootが有効化されます。
再び
$ sudo ubuntu-drivers autoinstall
とコマンドすることでインストールが完了します。
$ sudo reboot
とコマンドするなどして一旦再起動しましょう。
正しくインストールできていれば
$ nvidia-smi
というコマンドでGPUの使用状況などが端末に表示されるようになります。
Dockerのインストール
Dockerをインストールします。
Dockerの公式ドキュメントに従ってdocker-ceをインストールします。
まずはドキュメントのSET UP THE REPOSITORYに従って以下のようにコマンドしていきます。
$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
5行目のところでnightlyなどのオプションをつけたい場合はドキュメントを見てください。ただしstableが推奨なようなので、特にこだわりがなければ上記のように進めて貰えればと思います。
次にドキュメントのINSTALL DOCKER CEに従って以下のようにコマンドします。
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
これでDockerのインストールは完了です。最後に
$ sudo docker run hello-world
とコマンドして以下の画像のようなメッセージが出てきたら正しくインストールできています。
また、
$ sudo usermod -aG docker $USER
とコマンドしておくことで、ログインユーザーにDockerの使用権限を与えることができます。
# 権限を与えない場合
$ sudo docker hoge
# 権限を与える場合
$ docker hoge
要するに、上記のようにsudoと入力せずにDockerを使用できるようになります。
Nvidia-Dockerのインストール
Nvidia-Dockerをインストールします。これもNvidia-Dockerの公式ドキュメントに従って進めていきます。
まずはRepository configurationのDebian-based distributionsの項目に従って以下のようにコマンドしていきます。
$ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
$ 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
次にNvidia-Dockerのドキュメントの指示に戻って以下のようにコマンドします。
$ sudo apt-get install nvidia-docker2
$ sudo pkill -SIGHUP dockerd
これでNvidia-Dockerのインストールは完了です。
動作確認
動作させる前の準備
実際に動かす前にもう一つ踏まなければいけない手順があります。
まずはDocker Hubのアカウントを作成します。UsernameとPasswordはこのあと使用するので忘れずに控えてください(Google Chromeでやっていたのですが「パスワードはGoogle上で保管できるので覚える必要がありません」と出てきて危うくやられるところでした)。
次に端末で
$ docker login
とコマンドしてUsernameとPasswordを入力してログインします。これをしないとdockerコマンドが全然動かなかったです。
試しに
$ docker run --runtime=nvidia --rm nvidia/cuda:9.0-base nvidia-smi
とコマンドしてみるとDocker経由でGPUの使用状況が確認できることが分かります。
最後に
sudo systemctl restart docker
としてデーモンを再起動したら準備は完了です。
動作させる
ためしにKerasを用いてみんな大好きMNISTを実行してみます。
まずテキストエディタで以下のようなDockerfileを作成します。
FROM nvidia/cuda:9.0-cudnn7-runtime
RUN apt update && apt install -y python3-pip
RUN pip3 install tensorflow-gpu keras
RUN apt install -y wget
RUN wget https://raw.githubusercontent.com/fchollet/keras/master/examples/mnist_cnn.py
CMD ["python3", "/mnist_cnn.py"]
今回使用しているMX150というGPUはcuda9.0とcudnn7.0に対応しているので上記のようになっています。
このDockerfileがあるディレクトリに移動して、まず次のようにコマンドしてビルドします。
$ docker build . -t mnist
tensorflowやkerasなどがインストールされるのでしばらく待ちましょう。ビルドが終わったら
$ docker run --runtime=nvidia --rm -it mnist
とコマンドして実行してみます。動作中に新しく端末を開いてnvidia-smiコマンドを使ったら画像のようになっており、GPUが動いていることが確認できました。
補足
先程Docker Hubにログインする必要があるという説明をしましたが、この記事を書きながら改めて色々調べていたらystemd と Docker の管理・設定という記事を見つけました。もしかしたら、dockerコマンドが動かせなかったのはデーモンを起動していなかったことが原因かもしれません。これについては僕がまだDockerに慣れ親しんでおらずよく分かっていない部分があるので、詳しい方がいらっしゃればコメントしていただけるとありがたいです。