RaspberryPi3用のTensorflow v2.0.0-alpha (Tensorflow Lite v1.0) のインストーラ(Wheel)を速攻でネイティブビルド錬成した

**Bazel_bin**　[![GitHub stars](https://img.shields.io/github/stars/PINTO0309/Bazel_bin.svg?style=social&label=Stars)](https://github.com/PINTO0309/Bazel_bin)
<a href="https://github.com/PINTO0309/Bazel_bin"><img src="https://qiita-image-store.s3.amazonaws.com/0/194769/6ea145b9-b72f-dacb-252c-1d34ca733dc4.png" width=460px></a>
**Tensorflow-bin**　[![GitHub stars](https://img.shields.io/github/stars/PINTO0309/Tensorflow-bin.svg?style=social&label=Stars)](https://github.com/PINTO0309/Tensorflow-bin)
<a href="https://github.com/PINTO0309/Tensorflow-bin"><img src="https://qiita-image-store.s3.amazonaws.com/0/194769/5bb32ad2-904e-1a98-7239-88ffc0d03738.png" width=460px></a>

# １．はじめに
公開されて３日目の Tensorflow v2.0.0-alpha を RaspberryPi3 でネイティブビルドして Wheelファイル を自力生成しました。
だんだんこのビルド作業に小慣れてきて、ノーミスで一発成功しました。
どうやら **[公式のリポジトリ](https://github.com/tensorflow/tensorflow#official-builds)** よりも先にビルドに成功してしまったようです。。。
アホすぎて誰も真似しないと思いますが念の為お伝えしておきますと、 生成完了まで **`４１時間３０分`** 掛かります。
狂ってる、とか冷たいことを言わないでください。 確かに狂ってるんで。
Tensorflow Lite の **[PythonAPI MultiThread対応カスマイズ](https://qiita.com/PINTO/items/711828badfb50c576eb1)** も独自に加えました。
なお、生成済みの Wheelファイル は、上のニコちゃんマークのリンク先からダウンロード可能ですので、ご自由にお持ちください。

```console:wheelのダウンロード
$ wget https://github.com/PINTO0309/Tensorflow-bin/raw/master/tensorflow-2.0.0a0-cp35-cp35m-linux_armv7l.whl
```

```console:インストール
$ sudo pip3 uninstall tensorflow
$ sudo -H pip3 install tensorflow-2.0.0a0-cp35-cp35m-linux_armv7l.whl
```

今までもそうでしたが、pipパッケージの提供が遅かったり、pipパッケージそのものが壊れていたり、クロスコンパイルで生成されたWheelが壊れていたりしてイライラしたため、Googleに頼りきらずにいつも自力でネイティブビルドするクセがついています。
下図の **`TPU Accelerator`** を使用したかったので、無駄にフルビルドしてみました。
**<2019.03.10追記> TPU推論の実行だけなら Tensorflow本体 が無くても動きました。**
**TPUの検証結果は下記URLからどうぞ。**
**[RaspberryPi3(USB2.0)とLaptopPC(USB3.1)でGoogle Edge TPU Acceleratorを使用してMobileNet-SSD v2の動作スピードを検証してみました（MS-COCO）](https://qiita.com/PINTO/items/dd6ba67643bdd3a0e595)**
![bbb.png](https://qiita-image-store.s3.amazonaws.com/0/194769/ce6c1d37-c791-9c7a-dccc-e85ec8708ae7.png)

# ２．ビルド作業

ビルド開始：　2019/03/08 00:30
ビルド終了：　2019/03/09 17:30

```console:環境情報
$ uname -a
Linux raspberrypi 4.14.98-v7+ #1200 SMP Tue Feb 12 20:27:48 GMT 2019 armv7l GNU/Linux

$ bazel version
Build label: 0.19.2- (@non-git)
Build target: bazel-out/arm-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
Build time: 日 2 17 02:34:12 2019 (1550370852)
Build timestamp: 1550370852
Build timestamp as int: 1550370852
```

ココから上の作業は必要ありません。 あくまで私の環境を参考情報として掲載しているだけです。
ココから下の作業を実施すれば全て揃います。

```console:事前準備
$ sudo nano /etc/dphys-swapfile
CONF_SWAPFILE=2048
CONF_MAXSWAP=2048

$ sudo systemctl stop dphys-swapfile
$ sudo systemctl start dphys-swapfile

$ wget https://github.com/PINTO0309/Tensorflow-bin/raw/master/zram.sh
$ chmod 755 zram.sh
$ sudo mv zram.sh /etc/init.d/
$ sudo update-rc.d zram.sh defaults
$ sudo reboot

$ sudo apt-get install -y libhdf5-dev libc-ares-dev libeigen3-dev
$ sudo pip3 install keras_applications==1.0.7 --no-deps
$ sudo pip3 install keras_preprocessing==1.0.9 --no-deps
$ sudo pip3 install h5py==2.9.0
$ sudo apt-get install -y openmpi-bin libopenmpi-dev
$ sudo -H pip3 install -U --user six numpy wheel mock
$ sudo apt update;sudo apt upgrade

$ cd ~
$ git clone https://github.com/PINTO0309/Bazel_bin.git
$ cd Bazel_bin
$ ./0.19.2/Raspbian_armhf/install.sh

$ cd ~
$ git clone https://github.com/tensorflow/tensorflow.git
$ cd tensorflow
```

```python:tensorflow/lite/python/interpreter.pyを修正
# 最終行に下記２行を追加
  def set_num_threads(self, i):
    return self._interpreter.SetNumThreads(i)
```

```cpp:tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.ccを修正
// 最終行近辺を下記のとおり修正
PyObject* InterpreterWrapper::ResetVariableTensors() {
  TFLITE_PY_ENSURE_VALID_INTERPRETER();
  TFLITE_PY_CHECK(interpreter_->ResetVariableTensors());
  Py_RETURN_NONE;
}

PyObject* InterpreterWrapper::SetNumThreads(int i) {
  interpreter_->SetNumThreads(i);
  Py_RETURN_NONE;
}

}  // namespace interpreter_wrapper
}  // namespace tflite
```

```cpp:tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.hを修正
// ロジックの中盤あたりを下記のとおり修正
  // should be the interpreter object providing the memory.
  PyObject* tensor(PyObject* base_object, int i);

  PyObject* SetNumThreads(int i);

 private:
  // Helper function to construct an `InterpreterWrapper` object.
  // It only returns InterpreterWrapper if it can construct an `Interpreter`.
```

```python:tensorflow/tensorflow/core/kernels/BUILD_matrix_square_root_opを削除
cc_library(
    name = "linalg",
    deps = [
        ":cholesky_grad",
        ":cholesky_op",
        ":determinant_op",
        ":lu_op",
        ":matrix_exponential_op",
        ":matrix_inverse_op",
        ":matrix_logarithm_op",
        ":matrix_solve_ls_op",
        ":matrix_solve_op",
        ":matrix_triangular_solve_op",
        ":qr_op",
        ":self_adjoint_eig_op",
        ":self_adjoint_eig_v2_op",
        ":svd_op",
        ":tridiagonal_solve_op",
    ],
)
```

```python:tensorflow/tensorflow/core/kernels/BUILD_下記を削除
tf_kernel_library(
    name = "matrix_square_root_op",
    prefix = "matrix_square_root_op",
    deps = LINALG_DEPS,
)
```

```bash:tensorflow/lite/tools/make/Makefile_下記の通り変更
BUILD_WITH_NNAPI=false
```

```console:tensorflowの構成設定
$ ./configure 
Extracting Bazel installation...
WARNING: --batch mode is deprecated. Please instead explicitly shut down your Bazel server using the command "bazel shutdown".
You have bazel 0.19.2- (@non-git) installed.
Please specify the location of python. [Default is /usr/bin/python]: /usr/bin/python3


Found possible Python library paths:
  /usr/local/lib
  /home/b920405/git/caffe-jacinto/python
  /opt/intel//computer_vision_sdk_2018.5.455/python/python3.5/ubuntu16
  /opt/intel//computer_vision_sdk_2018.5.455/python/python3.5
  .
  /opt/intel//computer_vision_sdk_2018.5.455/deployment_tools/model_optimizer
  /opt/movidius/caffe/python
  /usr/lib/python3/dist-packages
  /usr/local/lib/python3.5/dist-packages
Please input the desired Python library path to use.  Default is [/usr/local/lib]
/usr/local/lib/python3.5/dist-packages
Do you wish to build TensorFlow with XLA JIT support? [Y/n]: n
No XLA JIT support will be enabled for TensorFlow.

Do you wish to build TensorFlow with OpenCL SYCL support? [y/N]: n
No OpenCL SYCL support will be enabled for TensorFlow.

Do you wish to build TensorFlow with ROCm support? [y/N]: n
No ROCm support will be enabled for TensorFlow.

Do you wish to build TensorFlow with CUDA support? [y/N]: n
No CUDA support will be enabled for TensorFlow.

Do you wish to download a fresh release of clang? (Experimental) [y/N]: n
Clang will not be downloaded.

Do you wish to build TensorFlow with MPI support? [y/N]: n
No MPI support will be enabled for TensorFlow.

Please specify optimization flags to use during compilation when bazel option "--config=opt" is specified [Default is -march=native -Wno-sign-compare]: 


Would you like to interactively configure ./WORKSPACE for Android builds? [y/N]: n
Not configuring the WORKSPACE for Android builds.

Preconfigured Bazel build configs. You can use any of the below by adding "--config=<>" to your build command. See .bazelrc for more details.
	--config=mkl         	# Build with MKL support.
	--config=monolithic  	# Config for mostly static monolithic build.
	--config=gdr         	# Build with GDR support.
	--config=verbs       	# Build with libverbs support.
	--config=ngraph      	# Build with Intel nGraph support.
	--config=dynamic_kernels	# (Experimental) Build kernels into separate shared objects.
Preconfigured Bazel build configs to DISABLE default on features:
	--config=noaws       	# Disable AWS S3 filesystem support.
	--config=nogcp       	# Disable GCP support.
	--config=nohdfs      	# Disable HDFS support.
	--config=noignite    	# Disable Apache Ignite support.
	--config=nokafka     	# Disable Apache Kafka support.
	--config=nonccl      	# Disable NVIDIA NCCL support.
Configuration finished
```

```console:Tensorflow_v2.0.0-alpha_ネイティブビルド
$ sudo bazel --host_jvm_args=-Xmx512m build \
--config=opt \
--config=noaws \
--config=nogcp \
--config=nohdfs \
--config=noignite \
--config=nokafka \
--config=nonccl \
--local_resources=1024.0,0.5,0.5 \
--copt=-mfpu=neon-vfpv4 \
--copt=-ftree-vectorize \
--copt=-funsafe-math-optimizations \
--copt=-ftree-loop-vectorize \
--copt=-fomit-frame-pointer \
--copt=-DRASPBERRY_PI \
--host_copt=-DRASPBERRY_PI \
//tensorflow/tools/pip_package:build_pip_package
```

```bash:ビルド結果_途中で1回リブートしたため表示上の時間は半分に、アクション数は1500ほど少なくなっています
INFO: Elapsed time: 126757.840s, Critical Path: 3547.35s, Remote (0.00% of the time): [queue: 0.00%, setup: 0.00%, process: 0.00%]
INFO: 5533 processes: 5533 local.
INFO: Build completed successfully, 6045 total actions
```

```console:wheelファイルの作成_/tmp/tensorflow_pkg配下に生成されます
$ su --preserve-environment
# ./bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
# exit
$ sudo cp /tmp/tensorflow_pkg/tensorflow-2.0.0a0-cp35-cp35m-linux_arm7l.whl ~
```

**`Protobuf-3.7.0`** が自動的に導入されるようです。
正常にインストールできました。

```console:Tensorflow_v2.0.0-alphaのインストール
$ cd ~
$ sudo pip3 uninstall tensorflow
$ sudo -H pip3 install tensorflow-2.0.0a0-cp35-cp35m-linux_armv7l.whl 

Processing ./tensorflow-2.0.0a0-cp35-cp35m-linux_armv7l.whl
Requirement already satisfied: astor>=0.6.0 in /usr/local/lib/python3.5/dist-packages (from tensorflow==2.0.0a0)
Collecting tf-estimator-nightly<1.14.0.dev2019030116,>=1.14.0.dev2019030115 (from tensorflow==2.0.0a0)
  Downloading https://files.pythonhosted.org/packages/13/82/f16063b4eed210dc2ab057930ac1da4fbe1e91b7b051a6c8370b401e6ae7/tf_estimator_nightly-1.14.0.dev2019030115-py2.py3-none-any.whl (411kB)
    100% |████████████████████████████████| 419kB 679kB/s 
Requirement already satisfied: termcolor>=1.1.0 in /usr/local/lib/python3.5/dist-packages (from tensorflow==2.0.0a0)
Requirement already satisfied: keras-applications>=1.0.6 in /usr/local/lib/python3.5/dist-packages (from tensorflow==2.0.0a0)
Requirement already satisfied: numpy<2.0,>=1.14.5 in /usr/local/lib/python3.5/dist-packages (from tensorflow==2.0.0a0)
Collecting tb-nightly<1.14.0a20190302,>=1.14.0a20190301 (from tensorflow==2.0.0a0)
  Downloading https://files.pythonhosted.org/packages/a9/51/aa1d756644bf4624c03844115e4ac4058eff77acd786b26315f051a4b195/tb_nightly-1.14.0a20190301-py3-none-any.whl (3.0MB)
    100% |████████████████████████████████| 3.0MB 109kB/s 
Requirement already satisfied: grpcio>=1.8.6 in /usr/local/lib/python3.5/dist-packages (from tensorflow==2.0.0a0)
Requirement already satisfied: six>=1.10.0 in /usr/lib/python3.5/dist-packages (from tensorflow==2.0.0a0)
Requirement already satisfied: gast>=0.2.0 in /usr/local/lib/python3.5/dist-packages (from tensorflow==2.0.0a0)
Collecting google-pasta>=0.1.2 (from tensorflow==2.0.0a0)
  Downloading https://files.pythonhosted.org/packages/8c/96/adbd4eafe72ce9b5ca6f168fbf109386e1b601f7c59926a11e9d7b7a5b44/google_pasta-0.1.4-py3-none-any.whl (51kB)
    100% |████████████████████████████████| 61kB 2.1MB/s 
Requirement already satisfied: keras-preprocessing>=1.0.5 in /usr/local/lib/python3.5/dist-packages (from tensorflow==2.0.0a0)
Collecting protobuf>=3.6.1 (from tensorflow==2.0.0a0)
  Downloading https://files.pythonhosted.org/packages/41/7c/6029e1b37ca730648a22502d75e2c7707da7a207db1b366f76edc5a01a0b/protobuf-3.7.0-py2.py3-none-any.whl (404kB)
    100% |████████████████████████████████| 409kB 699kB/s 
Requirement already satisfied: wheel>=0.26 in /usr/lib/python3/dist-packages (from tensorflow==2.0.0a0)
Requirement already satisfied: absl-py>=0.7.0 in /usr/local/lib/python3.5/dist-packages (from tensorflow==2.0.0a0)
Requirement already satisfied: h5py in /usr/local/lib/python3.5/dist-packages (from keras-applications>=1.0.6->tensorflow==2.0.0a0)
Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.5/dist-packages (from tb-nightly<1.14.0a20190302,>=1.14.0a20190301->tensorflow==2.0.0a0)
Requirement already satisfied: werkzeug>=0.11.15 in /usr/lib/python3/dist-packages (from tb-nightly<1.14.0a20190302,>=1.14.0a20190301->tensorflow==2.0.0a0)
Requirement already satisfied: setuptools in /usr/lib/python3/dist-packages (from protobuf>=3.6.1->tensorflow==2.0.0a0)
Installing collected packages: tf-estimator-nightly, protobuf, tb-nightly, google-pasta, tensorflow
  Found existing installation: protobuf 3.6.0
    Uninstalling protobuf-3.6.0:
      Successfully uninstalled protobuf-3.6.0
Successfully installed google-pasta-0.1.4 protobuf-3.7.0 tb-nightly-1.14.0a20190301 tensorflow-2.0.0a0 tf-estimator-nightly-1.14.0.dev2019030115
```

# ３．おわりに
Tensorflow v1.12.0 や Tensorflow v1.13.1 に比べると、ビルド用のスクリプトが大幅に改善されているようです。
不必要なXLAのビルドステップがスキップできるようになっていました。
ただ、まだ動作確認はしていません。
Googleさん、この調子でお願いします。
次は、 **`Edge TPU Accelerator`** を使用してワキワキしたいと思います。

今気づきました。 今日、誕生日でした。
年取ったなぁ。
カミさんに何買ってもいい、と言われたので、　~~プライベートジェット~~ **[トイドローン Tello](https://store.dji.com/jp/shop/tello-series)** を買おうと思います。
さて、ポチッとな :musical_note: