ひゃまだのblog

ひゃまだ(id:hymd3a)の趣味のブログ

DockerでTensorflow環境を作る

(2022-09-18 初稿)

これまでDockerの記事を2つアップした。

ここでは、Tensorflowの環境を作る。

以下のサイトを参考にしたが、ほとんどそのままなので、まずは以下のサイトを参照されたい。

ディレクトリ構成

筆者は、以下のディレクトリを作成した。

doc-tf
├── py-s  # pythonのsrcファイルを置く

doc-tfとpy-sは好きな名前で良い。

DockerのTensorflowイメージをダウンロード

最新の安定版をダウンロード。

docker pull tensorflow/tensorflow                     # latest stable release

ダウンロードしたイメージのテスト

docker run -it --rm tensorflow/tensorflow \
   python -c "import tensorflow as tf; print(tf.reduce_sum(tf.random.normal([1000, 1000])))"
(省略 様々なメッセージ)
tf.Tensor(166.21828, shape=(), dtype=float32)

結果は毎回異なるが、上記のメッセージがでれば良い。

Tensorflow環境でBashの起動

bashの起動は以下のとおり。

docker run -it tensorflow/tensorflow bash

現在の環境確認

OSの種類とバージョン確認。

root@697f8d2fb8cc:/# cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.5 LTS"つ

続いて、pythonのモジュール。2022-09-18日時点。

root@697f8d2fb8cc:/# pip3 list
Package                      Version
---------------------------- ---------
absl-py                      1.2.0
astunparse                   1.6.3
cachetools                   5.2.0
certifi                      2022.6.15
charset-normalizer           2.1.1
flatbuffers                  2.0.7
gast                         0.4.0
google-auth                  2.11.0
google-auth-oauthlib         0.4.6
google-pasta                 0.2.0
grpcio                       1.48.1
h5py                         3.7.0
idna                         3.3
importlib-metadata           4.12.0
keras                        2.10.0
Keras-Preprocessing          1.1.2
libclang                     14.0.6
Markdown                     3.4.1
MarkupSafe                   2.1.1
numpy                        1.23.2
oauthlib                     3.2.0
opt-einsum                   3.3.0
packaging                    21.3
pip                          20.2.4
protobuf                     3.19.4
pyasn1                       0.4.8
pyasn1-modules               0.2.8
pyparsing                    3.0.9
requests                     2.28.1
requests-oauthlib            1.3.1
rsa                          4.9
setuptools                   65.3.0
six                          1.16.0
tensorboard                  2.10.0
tensorboard-data-server      0.6.1
tensorboard-plugin-wit       1.8.1
tensorflow-cpu               2.10.0
tensorflow-estimator         2.10.0
tensorflow-io-gcs-filesystem 0.26.0
termcolor                    1.1.0
typing-extensions            4.3.0
urllib3                      1.26.12
Werkzeug                     2.2.2
wheel                        0.34.2
wrapt                        1.14.1
zipp                         3.8.1
WARNING: You are using pip version 20.2.4; however, version 22.2.2 is available.
You should consider upgrading via the '/usr/bin/python3 -m pip install --upgrade pip' command.

最後の警告は、pipのバージョンが古いと言っているが、仮想環境なのでとりあえず無視する。

kerasも入っており、すぐにでも使えそう。

自分のスクリプトを実行する

スクリプトは、ファイル権限の関係もあるためホスト側で作成する。

ホスト側では、スクリプトをdoc-tf/py-sに保存して、以下を実行。

$ cd doc-tf/py-s
$ docker run -it --rm -v $PWD:/tmp -w /tmp tensorflow/tensorflow python ./sample.py

現在のディレクトリ(doc-tf/py-s)が仮想環境では/tmpになり、ワーキング・ディレクトリも/tmpとなる。

なお、  --rm オプションがあるので、実行後、すぐにコンテナは消されてしまう。

GPU版を使う

GPUを使う設定は、以下のサイトを参考にさせていただいた。

aptラインとPGPの追加

distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
   && curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | apt-key add - \
   && curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | tee /etc/apt/sources.list.d/nvidia-docker.list

nvidia-docker2のインストール

apt-get update
apt-get install -y nvidia-docker2

ちなみに、わがDebianには、nvidia-smiもインストールされていなかったので。

apt-get install -y nvidia-smi

Dockerをリスタート。

systemctl restart docker

ドライバの確認

$ docker run --gpus all --rm nvidia/cuda nvidia-smi
Unable to find image 'nvidia/cuda:latest' locally
docker: Error response from daemon: manifest for nvidia/cuda:latest not found: manifest unknown: manifest unknown.
See 'docker run --help'.

あれ、エラーが出る。調べてみると、以下のページで調べてバージョン等も記載しないとだめみたい。

2022-09-18時点では、11.7.1-base-ubuntu22.04が最新だったので、以下の変更。

$ docker run --gpus all --rm nvidia/cuda:11.7.1-base-ubuntu22.04 nvidia-smi
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error running hook #0: error running hook: exit status 1, stdout: , stderr: Auto-detected mode as 'legacy'
nvidia-container-cli: requirement error: unsatisfied condition: cuda>=11.7, please update your driver to a newer version, or use an earlier cuda container: unknown.

今度は、別のエラーが…  nvidiaのドライバをアップデートしなさいとのこと。

確かにわがDebianのバージョンは、Driver Version: 470.141.03で古いらしい。

ドライバーのアップデート

筆者は、実際に試していないので、リンク先とやり方のみを示す。

参考にさせていただいたのは、以下のサイト。

aptラインに以下を追加。

deb http://deb.debian.org/debian/ experimental main non-free contrib

/etc/apt/apt.conf.d/00mydefaultrelease に以下を記載。

APT::Default-Release "stable";

以下でドライバをインストール。

apt-get update
apt-get -t experimental nvidia-driver

筆者は、まだ、試していないので、試してうまく行ったら追記する。

GPUを使ったサンプル

$ docker run --gpus all -it --rm tensorflow/tensorflow:latest-gpu \
   python -c "import tensorflow as tf; print(tf.reduce_sum(tf.random.normal([1000, 1000])))"

GPUを使った場合のbashの起動

$ docker run --gpus all -it tensorflow/tensorflow:latest-gpu bash

GPUを使った場合のスクリプトの実行

$ cd doc-tf/py-s
$ docker run --gpus all -it --rm -v $PWD:/tmp -w /tmp tensorflow/tensorflow python ./sample.py

以上、皆さん、快適にtensorflowをお使いください。

関連ページ

 

Dockerでpython3の環境を作る

(2022-09-18 初稿)

以下のとおり、Debian 11(Bullseye)でDockerをインストールした。

ここでは、インストールしたDockerを利用して、python3の環境を作った自分用のメモ。なお、本記事の内容はほぼ以下サイトと同じであるので、まずはそちらを。

ファイル構成

以下のとおり、ディレクトリとファイルを配置する。

doc-pyのディレクトリ名は、好きな名前で良い。

doc-py/
  ├ Dockerfile 
  ├ docker-compose.yml
  └ oopt
    └ sample.py

Dockerfile

以下のDockerfileを作成する。

FROM python:3
USER root
RUN apt-get update
RUN apt-get -y install locales && \
    localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8
ENV TZ JST-9
ENV TERM xterm

RUN apt-get install -y vim less
RUN pip install --upgrade pip
RUN pip install --upgrade setuptools

docker-compose.yml

以下のdocker-compose.ymlを作成する。

version: '3'
services:
  python3:
    restart: always
    build: .
    container_name: 'python3'
    working_dir: '/root/'
    tty: true
    volumes:
      - ./opt:/root/opt

simple.py

テストようなので簡単なsimple.pyを作成する。

print(”Hello Docker Python World")

Dockerイメージの作成、コンテナのビルド、そしてコンテナの起動

イメージは、クラス。コンテナはインスタンスに例えられる。

$ cd doc-py/
$ docker compose up -d --build

上記コマンドでは、コンテナはバックグランドで動作している状態。

イメージの確認

$ docker image ls
REPOSITORY              TAG                       IMAGE ID       CREATED         SIZE
doc-py-python3          latest                    5e6af8f9d57d   37 hours ago    1.02GB

コンテナの確認

$ docker container ls
CONTAINER ID   IMAGE            COMMAND     CREATED          STATUS          PORTS     NAMES
05cd7c5dbdb4   doc-py-python3   "python3"   10 seconds ago   Up 10 seconds             python3

コンテナへの接続

$ docker compose exec python3 bash
root@05cd7c5dbdb4:~#  (プロンプトが変更)
root@05cd7c5dbdb4:~# python --version
Python 3.10.7

コンテナへモジュールのインストール

root@05cd7c5dbdb4:~# python -m pip install numpy
Collecting numpy
  Downloading numpy-1.23.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (17.1 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 17.1/17.1 MB 21.8 MB/s eta 0:00:00
Installing collected packages: numpy
Successfully installed numpy-1.23.3
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv

最後の警告は、rootでの操作は勧めないとのことだが、仮想環境なので無視して良い。

コンテナへモジュールをインストールし、問題がなければDockerfileに追記するのが良い。

sample.pyの実行

doc-py/opt/sample ディレクトリに配置したsample.pyの実行

root@05cd7c5dbdb4:~# python ./opt/sample.py
Hello Docker World

自分で作成したスクリプトは、doc-py/opt/ ディレクトリ内に置く。

コンテナの操作

コンテナの切断

root@05cd7c5dbdb4:~# exit
$  

コンテナの削除

$ docker compose down
[+] Running 2/2
 ⠿ Container python3       Removed                                        10.3s
 ⠿ Network doc-py_default  Removed                                         0.1s

確認は以下のとおり。

$ docker container ls
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

コンテナの再利用

Dockerfileとdocker-compose.ymlでイメージがあるので、以下のコマンドを入力。

$ docker compose up -d
[+] Running 2/2
 ⠿ Network doc-py_default  Created                                         0.0s  ⠿ Container python3       Started                                         0.3s

イメージの操作

イメージの一覧

$ docker image ls
REPOSITORY              TAG                       IMAGE ID       CREATED         SIZE
doc-py-python3          latest                    5e6af8f9d57d   37 hours ago    1.02GB

イメージの削除

$ docker image rm imageid(上記の場合 5e6af8f9d57d )
Untagged: doc-py-python3:latest
Deleted: sha256:5e6af8f9d57ddb85bbb0918a92e10f2f03682ecd50e074fef08280c1a11874b9

 

以上、駆け足で紹介。また、何かわかったら追記予定。

関連ページ

 

Debian 11(Bullseye)にDockerのインストール

(2022-09-17 初稿)

PCのローカルなPythonをできるだけシンプルに保ちたいので、Dockerをインストールすることにした。以下は、自分用のメモ。

Dockerの公式サイトにDebian用のインストール方法の記載がある。

筆者は、初めてインストールするので、古いバージョンのアンインストールはしない。

多くは既にインストール済みだと思うが、念のためにインストール。

$ sudo apt-get update
$ sudo apt-get install ca-certificates curl gnupg lsb-release

PGP鍵の取得

$ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

リポジトリの追加

$ echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Docker Engineのインストール

$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin

hello-worldイメージの実行によるインストールの確認

$ sudo docker run hello-world

以下の表示のように、correctlyがあれば良い。

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Already exists 
Digest: sha256:62af9efd515a25f84961b70f973a798d2eca956b1b2b026d0a4a63a3b0b6a3f2
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/

一般ユーザでも実行できるように

Debianの場合、以下でUserをdockerグループに追加

$ sudo adduser $USER docker

sudo がなくても実行できることを確認

$ docker run hello-world

(省略  correctlyの表示があればOK)

今後、Python3とTensorflowをDockerで動かす記事をアップする予定。

関連ページ

コマンドライン引数の最大文字数

(2022-08-31 初稿 )

最近、Bashスクリプトを書くのが楽しくて、先日も、大量のコマンドライン引数を必要とするBashスクリプトを書いたので、気になって最大文字数はいくつなのか調べてみた。

その結果、以下のサイトに調べ方と答えがあった。多謝。m(__)m

調べ方

getconf ARG_MAX
2097152

まあ、これだけあれば困ることはないかな…

 

関連ページ

Bashとcurlを使ってLine Botで自分に通知する

(2022-08-29 初稿 )

はじめに

以前に、以下のページを作り、便利に使っていた。

しかし、NtfyはAndroid端末のアプリなので、iPhoneでは利用できない。

そこで、Line Botで通知する方法を調べて、簡単なスクリプトを作成したのでメモを残す。

Line Notifyのトークン取得

まずは、Line Notifyのトークンを取得しなければならないが、以下のサイトに詳しく解説されている。多謝。

以下のLine Notifyにアクセスして、トークンを取得する。

  1. まずは、Lineのアカウントでログイン
  2. マイページを開く
  3. アクセストークンの発行(開発者向け)
  4. トークン名を決める(送り主の名前、自分がわかれば適当で良い)
  5. 通知を受け取るアカウントを決める(多くは、自分または自分が含まれるグループうを選択
  6. 発行されたトークンをコピーして保存する
  7. 連携が成立すると、マイページに以下の画像が現れる

Line Notifyで連携が成立

BashCurlで自分に通知する

上記サイトにあるように、pythonで通知するのも良いが、Curlを使ってBashスクリプトで簡単にメッセージを送ることができる。

以下のサイトを参考にさせていただいた。多謝。

上記サイトによると、以下のワンライナーでメッセージを送ることができる。

curl -X POST -H 'Authorization: Bearer <TOKEN>' -F 'message=<BODY>' https://notify-api.line.me/api/notify

ちなみに、<TOKEN>の部分は、先程取得した自分のトークンに変更する。

Bashスクリプト

ワンライナーはすぐに忘れそうだったので、以下のBash スクリプト(linebot)を作成した。

#!/bin/env bash
# ver0.01 2022-08-29 Written by H.Yamada

Usage="[Usage] linebot message"

if [ "$#" -ne 1 ]; then
   echo $Usage
   exit
fi

MSG=$1

/usr/bin/curl -X POST\
 -H 'Authorization: Bearer 取得したトークン'\
 -F "message=$MSG" https://notify-api.line.me/api/notify

おわりに

思ったよりも、簡単に自分に通知することができた。皆さんの参考になれば幸いです。

関連ページ

Linuxで無劣化で画像を回転する

(2022-07-28 初稿)

Linuxexifを操作して、無劣化で画像を回転するためのメモ。

Exifを確認

まずは、写真などの画像のexifデータを調べる。

以下を参照した。多謝。m(__)m

sudo apt install imagemagick

imagemagickに含まれるidentiferでexifを確認できる。

identify -verbose  画像ファイル

画像を無劣化で回転

ExifのOrientationを変更することによって、画像を無劣化で回転する。

無劣化の回転のため、libimage-exiftool-perlをインストール。

sudo apt install libimage-exiftool-perl

画像の回転は、以下のコマンドで実行する。

exiftool -Orientation#=2 sample.jpg

exiftoolのオプション指定が難しい。

man exiftoolで確認すると、以下はすべて同じ回転をする。

$ exiftool -Orientation='Rotate 90 CW' a.jpg
$ exiftool -Orientation=6 -n a.jpg
$ exiftool -Orientation#=6 a.jpg

以下のサイトを参考に、一番簡単そうな番号で指定することにした。

1 = Horizontal (normal) : 標準
2 = Mirror horizontal   : 水平方向に反転
3 = Rotate 180          : 180°回転
4 = Mirror vertical     : 垂直方向に反転
5 = Mirror horizontal and rotate 270 CW :反時計回りに90°回転および垂直方向に反転
6 = Rotate 90 CW        : 反時計回りに90°回転
7 = Mirror horizontal and rotate 90 CW  : 時計回りに90°回転および垂直方向に反転
8 = Rotate 270 CW       :方向: 時計回りに90°回転

exifを削除

ちなみに、設定値を削除するには、オプション=の右側に空白を設定する。

exiftool -Artist= (ファイル名)

一部のコマンドを一括して削除することもできる。

exiftool -gps:all= (ファイル名)

劣化するけど回転角度を細かく指定する

細かい角度をしてするには、imagemagickに含まれているconvertコマンドを利用する。

ただし、細かい角度を指定した場合は、再圧縮時にロスが生じるため、劣化が起きてしまう点に注意。

$ convert -rotate -3.5 desktop01.png desktop03.png

関連ページ

DebianのNetworkManagerで、固定IPのイーサネットが繋がらなくなる対策

(2022-07-12 初稿)

はじめに

2022年6月上旬から、ずっと悩んでいた現象の対策がわかったのでメモを残す。

その現象とは、DebianでNetworkManagerを用いてイーサネットで接続していると、起動直後はWeb接続できるが、数分後にWeb接続できなくなる現象だ。

なお、Web接続できなくなるだけで、他のPCへのpingsshは正常に動作する。

筆者の環境

Linux hoge 5.10.0-16-amd64 #1 SMP Debian 5.10.127-1 (2022-06-30) x86_64 GNU/Linux
LXDE環境で NetworkManagerを用いてイーサネットでネット接続

最初はWebに接続できて、その後接続できなくなる現象

起動直後またはネットワーク設定変更直後は、Web接続可能だが、2〜3分後にWeb接続できなくなる。ただし、同じネットワーク内の他のPCなどにSSH接続などは可能。

起動直後のNetworkManagerの「接続情報」

起動直後は、Web接続が可能で、以下の画像のとおりゲートウェイ(デフォルトルート)が設定されている。

なお、確認方法は、NetworkManagerのアイコンを右クリックすると「接続情報」を見ることができる。

赤丸で示したとおり、ゲートウェイIPアドレスが記載されている。

NetworkManagerの「接続情報」

起動後、Web接続できなくなるNetworkManagerの「接続情報」

起動後、数分するとWeb接続できなくなる。その時の「接続情報」は以下のとおり。

ゲートウェイ(デフォルトルート)が、0.0.0.0に設定されている。

Web接続できなくなったNetworkManagerの「接続情報」

原因を探る

不可解な現象なので、以下のとおり/var/log/syslogを確認してみた。

syslogの確認

/var/log/syslogを追うと以下のような記述を発見。

$ sudo less /var/log/syslog
Jul 12 09:43:26 mou connmand[394]: enp2s0f1 {add} route 0.0.0.0 gw 0.0.0.0 scope 253 <LINK>

connmandにより、ゲートウェイが0.0.0.0に設定されているよう…

(筆者の考えている原因)

同じネットワークの中に、DHCPサーバがある場合に、正常にゲートウェイ等の情報が取得できればWeb接続が可能であるが、DHCPサーバがない場合や不完全なネットワーク情報しか取得できない場合に、デフォルトゲートウェイが「0.0.0.0」に設定されてしまうのではないかと推察(あくまでも筆者の推測である)。

対策

connmanctlで対策

connmandというデーモンでネットワークを変更されているようなので、connmanctlで設定をし直せばつながるようになる。

ちなみに、connmanctlについては初めて知ったので、以下のサイトを参考にさせて頂いた(多謝)。

例として、以下の設定を行う。

IP address:   192.168.22.200
Netmask:      255.255.255.0
Gateway:      192.168.22.1
DNS server:   192.168.1.1

まずは、現在の接続サービスの確認。

$ connmanctl services
*AO Wired                ethernet_80fa5x3fxx1x_cable   #Macアドレスは変更してある

続いて、ethernetにネットワークを設定

(nameserverを設定し直さない場合)
$ sudo connmanctl config ethernet_80fa5x3fxx1x_cable --ipv4 manual 192.168.22.200 255.255.255.0 192.168.22.1

(nameserverを設定し直す場合)
$ sudo connmanctl config ethernet_80fa5x3fxx1x_cable --ipv4 manual 192.168.22.200 255.255.255.0 192.168.22.1 --nameservers 192.168.200.36

上記のいずれかのコマンドで、ネットワークの再起動等しなくてもWeb接続が可能となる。

bashスクリプト

コマンドが少し長くて覚えきれそうにないので、以下のとおりBashスクリプトにした。

ちなみに、connmanctlで一度設定すると、再起動後も正常に動作するので、一度だけ実行すれば良いので、スクリプトにする意味は少ない。(^^ゞ

$ cat set_network
#!/bin/bash
# Written by H.Yamada
# start ver0.01 2022-07-12

# ip route
#default via 192.168.22.1 dev enp2s0f1 
#192.168.22.0/24 dev enp2s0f1 proto kernel scope link src 192.168.22.200 
#192.168.22.1 dev enp2s0f1 scope link 
#192.168.200.36 via 192.168.22.1 dev enp2s0f1  # rslt=$(/usr/bin/connmanctl services) set ${rslt} srvc=${3}                         # service rslt=$(/usr/bin/ip route | grep 'default via') set ${rslt} gway=${3}                        # gateway rslt=$(/usr/bin/ip route | grep 'link src') set ${rslt} ip=${9}                              # IP address sudo /usr/bin/connmanctl config ${srvc} --ipv4 manual ${ip} 255.255.255.0 ${gway}

おわりに

Debian 11(Bullseye)のネットワーク接続は、NetworkManagerまたはsystemdで行われていると思っていたので、connmanctlで簡単に設定できるとは思いもよらなかった。

上記の思い込みがあり、NetworkManagerのアイコンで'有線接続 1'を切断して再接続したり、以下のコマンドを実行したりしてきたが、ときどきしか設定がうまくいかなかった。

(うまく行かないコマンドの例)
sudo nmcli con modify '有線接続 1' ipv4.gateway 192.168.22.1
sudo nmcli con down '有線接続 1'
sudo nmcli con up '有線接続 1'
sudo systemctl restart NetworkManager

今回、connmanctlを初めて知り、また、とても設定が簡単なのでDebianのマニュアルなどでももっと宣伝して欲しいと思った。

なお、ここでは記述しないが、Wi-Fiの接続も制御できるので、NetworkManagerよりも万能な気がしている。

関連ページ