ブログの説明

学校に通わないで学んだことを記しています。間違っているところが何かありましたらご指摘下さると幸いです。コメントに対する返信が遅れる可能性があります。その場合は申し訳ありません。

このブログではサイドバーに広告を表示しています。このブログ内の投稿記事を検索するには右上の拡大鏡のアイコンを、アーカイブやラベル付けから投稿記事を閲覧するには左上の三重線のアイコンをクリックして下さい。

数式の表示にはMathJaxを利用させていただいています。数式の表示のためにJavaScriptが有効である必要があります。そうでない場合、訳の分からないLatexのコードが表示されます。幾何学図形やチャートの表示にはHTML5 CanvasやGoogle Chartを使用しています。その表示のためにもJavaScriptが有効である必要があります。

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を参照あれ。

https://hub.docker.com/r/rocm/tensorflow

NVIDIAのGeForceシリーズのドライバをインストール

NVIDIAのGeForceシリーズがマシンに搭載されているがドライバがインストールされていない場合には、適切なドライバをインストールする必要がある。

Debian GNU/Linux 10 (buster)の場合、NVIDIA GeForce 600シリーズ以降のドライバはbuster-backportsnvidia-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のインストールについての詳細は次の公式ページを参照あれ。

https://wiki.debian.org/NvidiaGraphicsDrivers

その手順の例を簡単に示すと、だいたい次のようになるはず。

まず適切なカーネルヘッダのインストール。

$ 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を参照あれ。

https://github.com/NVIDIA/nvidia-docker

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

コメント

このブログの人気の投稿

LATEXで数式:指数と順列などで使う添数・添字

10の補数と9の補数と2の補数と1の補数

Visual Studio 2019にはC++のためのフォームデザイナーがない件