DockerとTensorFlowをDebian GNU/Linux 10にインストール
ここではDebian GNU/Linux 10 (buster)のユーザーがTensorFlowをインストールして深層学習(ディープ・ラーニング)の準備をする手順を書き留める。
TensorFlowをインストールして管理する方法には色々あるが、ここでは開発者が使用中のマシンの環境から開発環境を分離して個別に管理することができるDockerと呼ばれるコンテナ化ツールを用いる。
- CPUのアーキテクチャ
- x86_64
- uname -mで分かる。
- GPUの有無
- なし
- $ lspci | grep nvidia -i --colorで有無を確認できる。
- Linuxディストロ
- Debian GNU/Linux 10 (buster)
- lsb_release -dで分かる。
- カーネルとそのリリース番号
- Linux 4.19.0-10-amd64
- uname -srで分かる。
- Pythonのバージョン
- Python 3.7.3
- python3 -Vで分かる。
- Dockerのバージョン
- 19.03.12
- インストール後にdocker -vで分かる。
- TensorFlowのバージョン
- 2.1.0
- インストール後に
import tensorflow as teflo print(teflo.__version__)
で分かる。
Dockerをインストール
Debian GNU/Linux 10の環境でDockerをインストールするために必要なパッケージをあらかじめインストールしておく。ウェブ・ブラウザを使う場合にはcurlは不要。
$ su # apt update; apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
PGP公開鍵が記されたgpgというファイルをcurlを用いて取得する。
$ curl -SL https://download.docker.com/linux/debian/gpg -O gpg % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 3817 100 3817 0 0 51581 0 --:--:-- --:--:-- --:--:-- 51581 curl: (6) Could not resolve host: gpg
curlコマンドのオプション-Sは--show-errorの略でエラーメッセージを表示させる。オプション-Lは--locationの略でリダイレクトに従わせる。取得されたgpgファイルは作業ディレクトリに保存される。
apt-keyを用いてPGPの公開鍵を追加する。その際にはsuかsudoでスーパーユーザー権限を得る必要がある。
$ su # apt-key add gpg OK
その公開鍵のフィンガープリント(指紋)が正しいかどうか確認する。スーパーユーザー権限が必要。
$ su # apt-key finger 0EBFCD88 pub rsa4096 2017-02-22 [SCEA] 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 uid [ 不明 ] Docker Release (CE deb) <docker@docker.com> sub rsa4096 2017-02-22 [S]
9DC8で始まる16進数の数列がフィンガープリント。
ちなみに、次のようにするとこの公開鍵を削除できる。スーパーユーザー権限が必要。
$ su # apt-key del OEBFCD88
Dockerの公式リポジトリを、/etc/apt/source.listに追加するか、/etc/apt/source.list.dディレクトリ内に任意のファイルとして置く。
リポジトリを追加する一つの方法としてadd-apt-repositoryを使う場合は次のようにする。スーパーユーザー権限が必要。
$ su # add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
うまくいけば、/etc/apt/source.listファイルの末尾に加えられる。
lsb_release -csは、使用中のLinuxディストロのコードネーム(例えばbuster)を出力する。
ちなみに、このリポジトリを削除するには-rオプションを指定する。
$ su # add-apt-repository -r "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
/etc/apt/source.list.dディレクトリ内に置く場合は例えばechoとteeを使って次のようにする。
$ su # echo "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" \ | tee -a /etc/apt/sources.list.d/docker.list
APTをアップデートしてからDockerをインストールする。
$ su # apt update # apt install docker-ce docker-ce-cli containerd.io
hello-worldを実行し、Dockerが正しくインストールされたかを確認してみる。hello-worldイメージがローカル・ディスク上に見つからなければ自動的にダウンロードしてくれる。
$ su # docker run hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world 0e03bdcc26d7: Pull complete Digest: sha256:7f0a9f93b4aa3022c3a4c147a449bf11e0941a1fd0bf4a8e6c9408b2600777c5 Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/
このように表示されたならDockerが無事にインストールされた証拠。
dockerグループが自動的に作成される。
$ getent group | grep docker docker:*:***:
dockerグループへの一般ユーザーの追加
スーパーユーザー権限以外の一般ユーザー権限でDockerを操作する場合には、dockerグループにその一般ユーザーを追加する必要がある。
既存のユーザーをdockerグループに追加するにはusermodを使う。スーパーユーザー権限が必要。
$ su # usermod -aG docker 既存のユーザー名
新規のユーザーをdockerグループに追加するにはuseraddを使う。スーパーユーザー権限が必要。
$ su # useradd -aG docker 新規のユーザー名
グループにユーザーを追加したら、その設定を有効にするため、次のようにnewgrpコマンドを使うことができる。
$ newgrp docker
ユーザーが所属するグループ名を確認するにはgroupsを使う。
$ groups ユーザー名
dockerグループからユーザーを削除するにはdeluserを使うことができる。スーパーユーザー権限が必要。
$ su # deluser ユーザー名 docker
dockerグループに一般のユーザーを加えることはそのユーザーにスーパーユーザーと同等の特権を与えることになってしまうため、セキュリティ上のリスクを考慮しなくてはならない。大前提として、信頼の置けるユーザーのみにこの権限を与える必要がある。
Docker 19.03以降ではセキュリティ上の脆弱性を回避する手段としてルートレス・モードという選択肢が実験的に導入されている。この点についてはまたの機会に。
Dockerサービスの起動や停止
Dockerはサービス(daemon /'diːmən/とも呼ぶ)として働く。つまり、基本ソフトが起動するときに自動的に起動し、その後はメモリに常駐し、ユーザーからのリクエストに応答することで働く。
APTを使ってインストールした場合、DockerサービスはDockerをインストールした直後に自動的に稼働する。
Dockerサービスの現在の状態を確認するにはsystemctlを使って次のように入力する。
$ systemctl status docker ● docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2020-08-17 00:53:18 JST; 7min ago Docs: https://docs.docker.com Main PID: 5755 (dockerd) Tasks: 13 Memory: 46.1M CGroup: /system.slice/docker.service └─5755 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
Active: active (running)と表示されていれば、Dockerサービスが稼働している。Active: inactive (dead)と表示されていれば、Dockerサービスは停止している。この画面から抜け出すにはqキーを押す。
Dockerサービスを停止させるにはsystemctlでstopを指定する。
$ su # systemctl stop docker
Dockerサービスを稼働させるにはsystemctlでstartを指定する。
$ su # systemctl start docker
ちなみに、設定を読み込むにはsystemctlでreloadを指定する。
$ su # systemctl reload docker
サービス(daemon)のstart, stop, reloadは、systemctlコマンドだけでなくserviceコマンドや/etc/init.dディレクトリ内のスクリプトを使っても同じように機能する。serviceコマンドはRed Hat系でお馴染み。/etc/init.d/はDebianでの伝統的なやり方。ただし引数を指定する順番がsystemctlとは異なることに要注意。
$ su # service docker stop # /etc/init.d/docker start [ ok ] Starting docker (via systemctl): docker.service.
通常、Debian GNU/Linuxの起動時にDockerサービスも自動的に起動するようになるが、その設定を解除するためにはsystemctlでdisableを指定する。
$ su # systemctl disable docker
Debian GNU/Linuxの起動時にDockerサービスも自動的に起動するようにするにはsystemctlでenableを指定する。
$ su # systemctl enable docker
ただし、dockerコマンドを使うとDockerサービスが自動的に稼働し始める。
NVIDIAのGPUをサポート
今回試したマシンの環境はグラフィクス・プロセシング・ユニッツ(GPU)を持たないが、GPUを持つマシンの環境ではGPUをサポートするのが得策なので、GPUをサポートする場合について調べたことを書き留めてみた。
Linuxディストロ上のDockerエンジン上のTensorFlowコンテナでは、NVIDIA Container Toolkitをインストールすることで、NVIDIAのGeForceシリーズを搭載しているマシン上で深層学習のためにGPUの能力を使うことができる。
使用中のマシンがNVIDIAのGeForceシリーズを搭載しているかどうかは、例えば次のようにlspciを用いることで分かる。
$ lspci | grep 'vga|nvidia' -i --color
grepのオプション-iは大文字小文字の区別なくし、--colorは検索した文字列をカラフルに表示させる。何も表示されなければ搭載していない。
AMD Radeon系の場合にはROCmのDockerイメージをインストールする必要があるが、ここでは触れない。次のURLを参照あれ。
NVIDIAのGeForceシリーズのドライバをインストール
NVIDIAのGeForceシリーズがマシンに搭載されているがドライバがインストールされていない場合には、適切なドライバをインストールする必要がある。
Debian GNU/Linux 10 (buster)の場合、NVIDIA GeForce 600シリーズ以降のドライバはbuster-backportsにnvidia-driverというdebパッケージ名で置かれている。
ただし、nvidia-driverパッケージのインストールの前に、適切なカーネルヘッダのdebパッケージがインストールされている必要がある。例えば、64ビットのAMD64互換ならばlinux-headers-amd64、32ビットのIntel 386互換ならばlinux-headers-686、その物理アドレス拡張(PAE)に対応しているならばlinux-headers-686-pae。
buster-backportsからのnvidia-driverのインストールについての詳細は次の公式ページを参照あれ。
その手順の例を簡単に示すと、だいたい次のようになるはず。
まず適切なカーネルヘッダのインストール。
$ su # apt update # apt install linux-headers-amd64
次にbuster-backportsのリポジトリ用の設定ファイルを/etc/apt/sources.list.dディレクトリ下に作成。
# echo "deb http://deb.debian.org/debian buster-backports main contrib non-free" \ | tee -a /etc/apt/sources.list.d/buster-backports.list
最後にAPTをアップデートし、buster-backportsを対象に指定してnvidia-driver パッケージのインストールを行う。
# apt update # apt install -t buster-backports nvidia-driver
NVIDIA GeForce 600シリーズ以前ではbuster-backportsではなく次のリポジトリになることに要注意。
$ su # apt update; apt install software-properties-common # add-apt-repository "deb http://deb.debian.org/debian/ buster main contrib non-free"
ここではechoではなくadd-apt-repositoryを使ってみた。
add-apt-repositioryで追加したリポジトリを取り除くには-rオプションを指定する。
# add-apt-repository -r "deb http://deb.debian.org/debian/ buster main contrib non-free"
NVIDIA GeForce 600シリーズ以前ではインストールするドライバもnvidia-legacy-390xx-driverやnvidia-legacy-340xx-driverになる。
$ su # apt update; apt install nvidia-legacy-390xx-driver
ドライバをインストールし終わったらDebian GNU/Linuxを再起動する。再起動したくなければmodprobeコマンドを使う手もあるらしい。
NVIDIA Container Toolkitをインストール
次に、NVIDIA Container Toolkitをインストールする。例えばDebianやUbuntuの場合では次のような手順になる。
まずcurlを使ってNVIDIAのPGP公開鍵を取得する。
$ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey -O gpgkey
取得した公開鍵はgpgkeyというファイル名でローカル・ディスクとの作業ディレクトリ内に保存されるので、その公開鍵をapt-keyを使って追加する。スーパーユーザー権限が必要。
$ su # apt-key add gpgkey
distribution変数に$(一連のコマンド)を代入した上で、curlを使ってリポジトリを取得し、パイプを介してそのリポジトリを受け取り、teeを用いて/etc/apt/sources.list.dディレクトリ内のnvidia-docker.listファイルとして出力する。
# distribution=$(. /etc/os-release;echo $ID$VERSION_ID) # curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list \ | tee /etc/apt/sources.list.d/nvidia-docker.list
APTをアップデートしてからnvidia-container-toolkitパッケージをインストールする。
# apt update; apt install -y nvidia-container-toolkit
最後にsystemctlを用いてDockerサービスを再起動する。
# systemctl restart docker
NVIDIA Container Toolkitのインストール方法についてはこちらのURLを参照あれ。
DockerコンテナとしてTensorFlow+Python3+jupyterを実行
Dockerイメージを引数に指定してdocker runという管理コマンドを使うと、systemctl start docker(サービスの開始)とdocker pull(イメージのダウンロード)とdocker create(コンテナの新規作成)とdocker start(コンテナの開始)を、どうやらその必要に応じて自動的にやってくれるようなので便利。
docker runの実行にはスーパーユーザー権限が必要なので、docker runの前にsuやsudoを指定することになるが、dockerグループに属している一般ユーザーでもその実行が可能。ここでは以降そのことを前提に記す。
Jupyter Notebookを使う場合は、Xtermなどのターミナル・エミュレータを起動し、例えば次のように入力する。この操作にはスーパーユーザー権限が必要だが、dockerグループに属している一般ユーザーでも実行することができる。
$ docker run -it --rm -p 8888:8888 tensorflow/tensorflow:letast-py3-jupyter (中略) [I 16:05:41.493 NotebookApp] The Jupyter Notebook is running at: (中略) [I 16:05:41.493 NotebookApp] or http://127.0.0.1:8888/?token=********** [I 16:05:41.493 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation). (以下省略)
http://127.0.0.1:8888/?token=**********と表示されている部分をマウスでアクティブにし、例えばChromeなどのウェブ・ブラウザのアドレス・フォームにマウスの中ボタンを使ってURLとtokenを丸ごと貼り付けてEnterキーを押す。
あるいはまた、ウェブ・ブラウザでhttp://127.0.0.1:8888/にアクセスするとjupyterのログイン画面が表示されるので、token=以降の文字列をPassword or token:のフォームにコピー&ペーストしてLog inボタンを押す。
Jupyterのログイン画面ではパスワードを設定することもできる。そうする場合、ログイン画面下方のSetup a Passwordという項目のTokenにtoken=以降の文字列を、New Passwordに任意のパスワードを入力し、Log in and set new passwordボタンを押す。こうすると次回からこのパスワードでjupyterにログインすることができるようになる。
ちなみに、Jupyter Notebookはウェブ・ブラウザ上で動く対話型開発環境。
終了の手順
ウェブ・ブラウザ上のJupyterのメイン画面(tree画面)の右上にあるQuitボタンを押す。
それがうまく働かない場合は、実行中のターミナル・エミュレータ上で(そのウィンドウがアクティブな状態で)Ctrlキーを押したままcキーを押すとShutdown this notebook server (y/[n])?と問われるのでyを押してEnterキーを押せば終了する。
深層学習の実装については下の参照URLにあるTensorFlowのチュートリアルをご参考に。
参照URL
- Docker公式サイト:https://www.docker.com/
- Dockerドキュメント:https://docs.docker.com
- Dockerドキュメント日本語化プロジェクト:https://docs.docker.jp/
- TensorFlow公式サイト:https://www.tensorflow.org/
- TensorFlowチュートリアル:https://www.tensorflow.org/tutorials
- Jupyterの公式サイト:https://jupyter.org
コメント
コメントを投稿