2018年5月6日日曜日

Build tensorflow on ArchLinux ARM on Android

[Abstruct]
-Creating tensorflow development environment in order to develop Deep Learning anytime, anywhere.
-Build tensorflow on Arch Linux (TermuxArch) on Android.
-Run mnist_cnn on keras with tensorflow backend as benchmarking.

[Conclusion]
-Benchmarking score is better than I expected.
The score is close to a little old note PC. and better than mxnet and CNTK in my environment.
-It takes very very long time to build the tensorflow. So, please be careful to configure before building.

[Summary]
-Install Termux.
-Install TermuxArch (Arch Linux).
-Build and Install bazel.
-Build and Install tensorflow.
-Run Keras(tensorflow backend) benchmark.

[Details]
-Install Termux and TermuxArch by referring to first half of the follow URL.
http://oregaji.blogspot.jp/2018/04/how-to-create-keras-development.html

-Install oracle jdk8 and bazel 0.12 by referring to the follow "Build bazel on Arch Linux on Android".
http://oregaji.blogspot.com/2018/04/build-bazel-on-archlinux-arm-on-android.html

-Prepare to install tensorflow by referring "Installing TensorFlow from Sources".
https://www.tensorflow.org/install/install_sources
-git checkout latest r1.8 branch.
> git checkout r1.8

- **IMPORTANT** Modify third_party/png.BUILD. Add line
copts = ["-DPNG_ARM_NEON_OPT=0"],
Refer to the follow issue.
https://github.com/tensorflow/tensorflow/issues/18643#issuecomment-385234577
(Without this modification, Building tensorflow will fail at last.)
- Run configure.
> ./configure
Answer jemalloc=n, mpi=n.

-Build tensorflow.
> bazel build --config=opt //tensorflow/tools/pip_package:build_pip_package --jobs 4
(It takes about 2 days. Plase be patient. Set Termux Notification Menu to "acquire wake lock".)

-Build python pip package.
> bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg

-Do pip install.
> pip install /tmp/tensorflow_pkg/tensorflow-1.8.0-cp36-cp36m-linux_aarch64.whl
(tensorflow needs grpcio package. It takes about half day to build grpcio. Please be patient.)

If it succeeds, it's done!

-Run mnist_cnn on Keras with tensorflow backend.
-Install keras.
> pip install keras
-Change keras backend totensorflow.
Change ~/.keras/keras.json:
  "backend": "tensorflow",
-Run mnist_cnn example on keras.
> git clone https://github.com/keras-team/keras.git
> cd keras/example
> python mnist_cnn.py

-Benchmark results:
mnist_cnn.py of keras example
  tensorflow backend: 4min/epoch
  mxnet backend: 33min/epoch
  CNTK backend: 24min/epoch

tensorflow backend is very fast!
Is any acceleration working on aarch64!?
If you know something about this, Please tell me.

This learning speed is slower than desktop PC with GPU.
But it is faster than I expected.
This mobile deep learning development environment is very useful for me!

2018年5月3日木曜日

android上でtensorflowをビルドする方法

[概要]
-android上でtensorflowの開発環境を構築します。
-性能評価のためkeras mnist_cnnを実行します。

[結論]
-スマホなのにベンチマーク結果が予想外に良い(少し古いノートPC並み)結果で驚き。最初はどうせ遅いだろうと思っていたが結構使えるんじゃないという感じ。
-ビルドには無茶苦茶時間がかかるので最初の設定には気をつけて。

[要約]
-Termuxをインストール
-TermuxArch (Arch Linux)をインストール
-bazelをビルドしてインストール
-tensorflowをビルドしてインストール
-Keras(tensorflow backend)でベンチマークを実施

[詳細]
-下記URLの前半を参考にTermux, TermuxArchをインストールする。
http://oregaji.blogspot.jp/2018/04/androidkeras2018415.html

-下記「android上でbazelをビルドする方法 」に従いjdk8, bazelをインストール。今回は現時点最新の0.12を使用。
http://oregaji.blogspot.jp/2018/04/androidbazel.html

-"Installing TensorFlow from Sources"を参考にtensorflowのインストール準備をしておく。
https://www.tensorflow.org/install/install_sources
-今回は現時点最新のr1.8を使用。
> git checkout r1.8

- **重要** third_party/png.BUILD を修正して
copts = ["-DPNG_ARM_NEON_OPT=0"],
を追加する。
下記のissueを参照のこと。
https://github.com/tensorflow/tensorflow/issues/18643#issuecomment-385234577
(これをやっておかないとビルドの最後で失敗するので注意)
- ./configure を実行
jemalloc=n, mpi=nにとりあえずしておく。

-ビルドする。
> bazel build --config=opt //tensorflow/tools/pip_package:build_pip_package --jobs 4
(jobsは4くらいまでにしておかないと、リソース不足で止まる。jobs 4でも止まる時にはjobs 2とかにしておく。)         
(ビルドは2日くらいかかる勢いなのでひたすら待つ。Termuxは通知メニューでacquire wake lockしておき止まらないようにしておく。)

-pythonのpipパッケージを作る
> bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg

-pipインストールする
> pip install /tmp/tensorflow_pkg/tensorflow-1.8.0-cp36-cp36m-linux_aarch64.whl
(tensorflowが依存するパッケージもインストールされる。中でもgprcioはビルドインストールに一晩くらいかかる、のでひたすら待つ。)

成功したら完了。

-Keras(tensorflow backend)でベンチマーク(mnist_cnn)を実施
-kerasをインストール
> pip install keras
-kerasバックエンドをtensorflowに変更
~/.keras/keras.jsonを
  "backend": "tensorflow",
に修正する。
-kerasのmnist_cnnサンプルを実行する
> git clone https://github.com/keras-team/keras.git
> cd keras/example
> python mnist_cnn.py

-ベンチマーク結果
mnist_cnnで1 epochあたり実測230秒台!!
比較すると、
  tensorflowバックエンド: 4分/epoch
  mxnetバックエンド: 33分/epoch
  CNTKバックエンド: 24分/epoch
となり、tensorflowは爆速!!aarch64では何かアクセラレーションが効いているの!?
知っている人がいたら教えて下さい。
デスクトップPCのGPU版に比べれば遅いけれど、スマホでここまで速度が出るとは思っていなかったので正直驚きです。

2018年4月25日水曜日

Build Bazel on ArchLinux ARM on android

[Abstract]
Building bazel on ArchLinux (TermuxArch) on android

[Details]
-Install Oracle jdk 8.
(openjdk8 via pacman is too old.)
http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

> pacman -S zip
(Important: zip command is used in the end of building. Without zip, build is end with error.)

Get bazel-*-dist.zip (bazel-0.12.0-dist.zip)
https://github.com/bazelbuild/bazel/releases

Modify script/bootstrap/compile.sh and add java heap memory.
run "${JAVAC}" -verbose -J-Xms1024m -J-Xmx1024m -classpath ...

Set jobs to 1.
> export EXTRA_BAZEL_ARGS='--jobs 1'
(If jobs is not 1, illegal seek error will happen and build fail.)

On top directory, run the follow command. And wait for hours.
> ./compile.sh

If build succed, copy bazel binary.
> cp output/bazel /usr/local/bin/

Complete.

(所感: bazelのビルドは失敗すると最初からやり直しで数時間コース。デフォルトではログも出ない、illegal seekなど罠も多く、いったい何回試行錯誤したことか!ちなみにjdk9でもまだうまくいきません。)

(次回: おまちかね、tensorflowのビルド!そこにはさらなる罠が!?)

android上でbazelをビルドする方法

[概要l
android上のArchLinux (TermuxArch)でbazelをビルドする方法

[詳細]
-Oracle jdk 8をインストールする。
(pacmanのopenjdk8は古すぎるため)
http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

> pacman -S zip
(これ重要。ビルドの最後の最後でzipが無いとエラーで最初からやり直し。)

bazel-*-dist.zipを取ってくる。(bazel-0.12.0-dist.zipで確認)
https://github.com/bazelbuild/bazel/releases

script/bootstrap/compile.sh を修正しjavaのヒープメモリを増やしておく。
run "${JAVAC}" -verbose -J-Xms1024m -J-Xmx1024m -classpath ...

環境変数でジョブ数を1に制限。
> export EXTRA_BAZEL_ARGS='--jobs 1'
(増やすとillegal seekエラーが出てビルドに失敗する。)

トップディレクトリで
> ./compile.sh
を実行。数時間待つ。

ビルドに成功したら。コピーする。
> cp output/bazel /usr/local/bin/

完了。

(所感: bazelのビルドは失敗すると最初からやり直しで数時間コース。デフォルトではログも出ない、illegal seekなど罠も多く、いったい何回試行錯誤したことか!ちなみにjdk9でもまだうまくいきません。)

(次回: おまちかね、tensorflowのビルド!そこにはさらなる罠が!?)

2018年4月24日火曜日

Run keras on android with CNTK backend

[Abstract]
Run keras with CNTK backend on ArchLinux (TermuxArch) on android.

[Details]
-Prepare TermuxArch, OpenBLAS and etc.
See below URL for the details.
http://oregaji.blogspot.jp/2018/04/how-to-create-keras-development.html?m=1

-Build CNTK from source code.
-Build procedure is the below.
https://docs.microsoft.com/en-us/cognitive-toolkit/Setup-CNTK-on-Linux#quick-test-of-cntk-build-functionality

-Install protobuf via pacman.
-Modify CNTK/configure. Replace string "libprotobuf.a" to "libprotobuf.so"
(In my environment, there is no libprotobuf.a file...)

> pacman -S swig
> mkdir -p build/release
> cd build/release
> ../../configure --with-openblas=/usr/local --with-swig --with-py36-path

-Modify CNTK/Makefile. Replace from
SSE_FLAGS = -msse4.1 -mssse3
to
SSE_FLAGS =

> make -j 2 all

- if sys/io.h not found Error occured, fix source code to sys/uio.h

-if failed to build Multiverso, build and install Multiverso manually.
> cd CNTK/Source/Multiverso
> cmake
> make
> make install
And comment out Multiverso part from CNTK/Makefile.
> cd CNTK
> make -j 2 all

After build success,
("make install" is not available, So...)
> cd build/release
> cp bin/cntk bin/cntk.core.bs /usr/local/bin/
> cp -r /usr/local/lib

(libmpi.so.12 not found error will happen when running cntk. So, create symlink.)
> ln -s /usr/lib/openmpi/libmpi.so /usr/lib/openmpi/libmpi.so.12

-Install python bindings.
> cd CNTK/bindins/python
> python setup.py install

-Set keras backend to CNTK.
Modify ~/.keras/keras.json as "backend": "cntk"

-Run keras MNIST sample.
-Do git clone keras.
> cd keras/keras/example
> python mnist_cnn.py
If it works well, CNTK backend  installation success!
In my 2017 high-end smartphone, It takes about 33 minites per 1 epoch.
It's slower than mxnet backend in my environment...

android上でkerasを動かす:CNTK編

[概要]
androidのArchLinux上でCNTKバックエンドのkerasを動作させる。

[詳細]
TermuxArch環境は準備しておく。OpenBLASなども。
詳細は下記の記事参照
http://oregaji.blogspot.jp/2018/04/androidkeras2018415.html?m=1

CNTKをビルドする。
ビルドは下記に従う。
https://docs.microsoft.com/en-us/cognitive-toolkit/Setup-CNTK-on-Linux#quick-test-of-cntk-build-functionality

pacmanでprotobufを入れても
libprotobuf.aは無かったので
configureの該当箇所ををlibprotobuf.soに修正

> pacman -S swig
> mkdir -p build/release
> cd build/release
> ../../configure --with-openblas=/usr/local --with-swig --with-py36-path

MakefileのSSE_FLAGS = -msse4.1 -mssse3はSSE_FLAGS = のように空にしとく。
sys/io.hが無いとかエラーが出たらsys/uio.hとかに書き換えてみる。
なぜかMultiversoが失敗したので、Multiversoだけ手動でcmake, make, make installして、cntkのMakefileからMultiversoの箇所をコメントアウトして進めた。

make instadellが無いのでビルドしたbin以下の
cntk
cntk.core.bs
を/usr/local/bin/にコピー。
ビルドしたlib以下を/usr/local/libにコピー。

実行時なぜかlibmpi.so.12が無いとエラーが出るので、下記のようにシンボリックリンクを作成する。
ln -s /usr/lib/openmpi/libmpi.so /usr/lib/openmpi/libmpi.so.12

> cd CNTK/bindins/python
> python setup.py install

~/.keras/keras.jsonを
"backend": "cntk"
に変更。

-kerasのサンプルで
> python mnist_cnn.py
が動いたら成功っぽいです。
手元のスマホ(年末のハイエンドスマホ)では1 epochは予測33分と出ました。mxnetバックエンドのほうが早い...

2018年4月23日月曜日

TermuxArch Tips

[ps, top commands]
-At Android 8.0, ps and top commands are not available, because /proc/stat is not permissive.
Alternatively /system/bin/ps and /system/bin/top commands are available some devices.
-Modify /data/data/com.termux/files/usr/bin/startarch like the follows and add proot args "-b /system/" to mount android /system directory to TermuxArch /system.

exec proot --kill-on-exit --link2symlink -0 -r /data/data/com.termux/files/home/arch -b $ANDROID_DATA -b /dev/ -b $EXTERNAL_STORAGE -b $HOME -b /proc/ -b /storage/ -b /sys/ -b /system/ -b /vendor/ -w "$PWD" /usr/bin/env -i HOME=/root TERM=xterm-256color /bin/bash -l

[sshd]
- sshdはTermuxArchでは失敗するのでTermuxで実行する。Termuxで証明書ログインしたあとstartarchしてTermuxArchを使う。ちなみにパスワードログインはできない。

TermuxArchの小ネタ

[ps, topコマンド]
-android 8.0から/proc/statが使えないため、ps, topが使えない。端末によっては/system/bin/以下のps, topが使える。
-/systemをマウントするには、/data/data/com.termux/files/usr/bin/startarchを変更しprootの引数に-b /system/ を追加する。
例: exec proot --kill-on-exit --link2symlink -0 -r /data/data/com.termux/files/home/arch -b $ANDROID_DATA -b /dev/ -b $EXTERNAL_STORAGE -b $HOME -b /proc/ -b /storage/ -b /sys/ -b /system/ -b /vendor/ -w "$PWD" /usr/bin/env -i HOME=/root TERM=xterm-256color /bin/bash -l

[sshd]
- sshdはTermuxArch側では失敗するのでTermux側で実行する。Termuxで証明書ログインしたあとstartarchしてTermuxArchを使う。ちなみにパスワードログインはできない。

2018年4月15日日曜日

How to create Keras development environment on Android at April 2018.

[Abstract]
Creating Keras development environment in order to develop Deep Learning anytime, anywhere.

[Conclusion]
-This environment is too slow to learn data firmly, but this is useful to try tiny Keras code quickly.
-It's useful to be available full Linux distribution on the smartphone.
-Perfect development environment while sleeping in the bedroom have been constructed! :-)

[Install procedure]
-Install Termux from Google Play.
-Install Hacker's keyboard from Google Play too.
-Install ArchLinux via TermuxArch (https://sdrausty.github.io/TermuxArch/)
(-Install yaourt) *optional (https://wiki.archlinux.jp/index.php/Yaourt)
-Build and install OpenBLAS. (https://github.com/xianyi/OpenBLAS)
-Build and install mxnet. (https://github.com/apache/incubator-mxnet)
-Install latest version keras which support mxnet_backend.

[Difficult points of install]
-In some device, "proot" of termux apt-get causes error on execute. So get termux/proot from github and build from source and install. Then success.
-ArchLinux on TermuxArch works on user privilege in proot file system container. So, some command which require real root privilege will be failed.
-Server URL for yaourt AUR in /etc/pacman.conf must be
Server = http://repo.archlinux.fr/arm
not
Server = http://repo.archlinux.fr/$arch
-fix /usr/bin/makepkg as https://github.com/sdrausty/TermuxArch/issues/38. Then yaourt is available.

-Build and install OpenBLAS from source.
-Use make command for building OpenBLAS, not use cmake command.

-Add link path and include path like followings.
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
export LIBRARY_PATH=$LD_LIBRARY_PATH
export CPATH=/usr/local/include:$CPATH

-Install openmp and others via pacman -S command before building mxnet.
-Use "git clone --recursive" to get mxnet source code.
-Use cmake command for building mxnet.
-Fix CMakeLists.txt. add the following line just under add_library(mxnet_static STATIC ${SOURCE}).
   set_property(TARGET mxnet_static PROPERTY POSITION_INDEPENDENT_CODE ON)
Shared library works well by this.
-Use clang for building mxnet. gcc causes halt on compling some place of code.
-Use clang by the following.
> cmake -C ~/use-clang.cmake ..
~/use-clang.cmake is like followings:
set(CMAKE_C_COMPILER "/usr/bin/clang" CACHE string "clang compiler" FORCE)
set(CMAKE_CXX_COMPILER "/usr/bin/clang++" CACHE string "clang++ compiler" FORCE)
set(CMAKE_ASM_COMPILER "/usr/bin/clang")
#set(CMAKE_SYSTEM_PROCESSOR "aarch64")

-At building mxnet, do follow commands.
> cmake -C ~/use-clang.cmake ..
> ccmake -C ~/use-clang.cmake ..
-In ccmake command, turn off build sample, cuda related, mkl related, atlas, gperftools(tcmalloc), jemalloc, opencv, sse.
-Turn BUILD_SHARED on.
-Set BLAS=Open.
-Press "c" after setting ccmake.
> cmake -C ~/use-clang.cmake ..
> make -j 4
-It takes about 20 minites to build mxnet.
> make install
> mv /usr/local/lib64/libmxnet.a /usr/local/lib/
> mv /usr/local/lib64/libmxnet.so /usr/local/lib/

-In python3, install cython, setuptools, keras(keras_mxnet==2.1.5b3 latest version which support keras2_mxnet_backend) and others via pip command.
> cd python/
> python setup.py install

- Do git clone keras.
> cd keras/keras/example
> python mnist_cnn.py
If it works well, keras installation success!
In my 2017 high-end smartphone, It takes 24 minites per 1 epoch.

android上でkeras開発環境を構築するまでの長い道程(2018/4/15時点)

[概要]
いつでもどこでもディープラーニングの開発をできるようにするため、androidスマホ上にkeras開発環境を構築します。

[結論]
-ちゃんと学習させるには遅すぎるが、コードをちょっと試すには便利。
-スマホでフルのLinuxディストリビーションが使えるのは便利。
-寝ながら開発&寝落ちが実用的にできる環境が構築できた!

[手順]
-Google playでTermuxをインストール
-Google playでHacker's keyboardもインストール
-TermuxArchでArchLinuxをインストール(https://sdrausty.github.io/TermuxArch/)
(-yaourtをインストール) (https://wiki.archlinux.jp/index.php/Yaourt)
-OpenBLASをビルドしてインストール (https://github.com/xianyi/OpenBLAS)
-mxnetをビルドしてインストール(https://github.com/apache/incubator-mxnet)
-keras(mxnet_backendが使える最新版)をインストール

[以下ハマりポイント(多数)]
-prootはapt-getのものではなぜか失敗する端末がある。termux/prootをgithubから取ってきて自分でビルドし直しインストールすると成功
-TermuxArchのArchLinuxはproot内で一般ユーザー権限で動いているだけなので注意が必要。root権限は取れたふりをしているだけで実際はただの一般ユーザー。
-/etc/pacman.confの最後に追加するAUR frのURLの末尾は/$archは失敗するので/armに変更する。
-‎makepkgはrootとfakerootで失敗する。termuxarchのスクリプトで修正可能っぽい。yaourtも使えた。(自分は/usr/bin/makepkgを手動で同じように修正したら使えた。)

-openblasはyaourtで取れるAURのものは失敗するので、結局自分でビルドする必要がある。
-openblasはcmakeがまだ安定していないようなので、トップディレクトリでmakeでビルドする。
-リンクパス、インクルードパスは
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
export LIBRARY_PATH=$LD_LIBRARY_PATH
export CPATH=/usr/local/include:$CPATH
などして追加しておく。

-mxnetビルド前に、openmpなどはpacman -Sでインストールしておく。
-mxnetはgit clone --recursiveで取得する。
-mxnetはcmakeを使う。素のmakeだと失敗した。
-mxnetではCMakefile.txt を修正しておく。mxnet_staticのadd_library()の直下に下記を追加する。
set_property(TARGET mxnet_static PROPERTY POSITION_INDEPENDENT_CODE ON)
ビルド時の-fPICワーニングが消え、動的リンクができるようになる。
-mxnetはgccでビルドするとなぜか必ずgccが落ちる箇所があるのでclangでビルドする。
> cmake -C ~/use-clang.cmake ..
のように下記のuse-clang.cmakeを読み込んでclangを使う。
set(CMAKE_C_COMPILER "/usr/bin/clang" CACHE string "clang compiler" FORCE)
set(CMAKE_CXX_COMPILER "/usr/bin/clang++" CACHE string "clang++ compiler" FORCE)
set(CMAKE_ASM_COMPILER "/usr/bin/clang")
#set(CMAKE_SYSTEM_PROCESSOR "aarch64")

-mxnetビルドでは
> cmake -C ~/use-clang.cmake ..
> ccmake -C ~/use-clang.cmake ..
> ccmakeを使い、build sample, cuda関連, mkl関連, atlas, gperftools(tcmalloc), jemalloc, opencv, sseは外す。
設定変更したあとcを押して反映させるとBLASの設定がでるのでOpenにしとく。BUILD_SHAREDもONにしとく。
(gperftoolsは実行時にtcmalloc errorがでる。jemallocも失敗する。opencvはテストのビルドでgtkとかx11のリンクエラーがでる。)
> cmake -C ~/use-clang.cmake ..
> make -j 4
20分程度ビルドにかかる。
make -j 8にすると端末が不安定になる気がする。

make install するとなぜか /usr/local/lib64 に配置されるので
mv /usr/local/lib64/libmxnet.a /usr/local/lib/
mv /usr/local/lib64/libmxnet.so /usr/local/lib/
で移動。

-python3でcython, setuptools, keras(keras_mxnet==2.1.5b3などmxnet_keras2_backend対応した新しいバージョンのもの)とかはpipでインストールしておく。
-mxnetのpython/ディレクトリで
> python setup.py install
する。

- kerasのサンプルで
> python mnist_cnn.py
が動いたら成功っぽいです。
手元のスマホ(年末のハイエンドスマホ)では1 epochは実測24分(予測18分)と出ました。