- 投稿日:2020-02-12T19:32:00+09:00
Raspberry PiにTensorFlow 1.15.0をインストールする
こんにちは。
Raspberry PiへのTensorFlowのバージョン1.15.0
以降をインストールしたかったのですが、
pip
ではうまくいかず、日本語でまとまっているものが見つからなかったので、備忘録がてらまとめておきます。環境
ラズパイの環境は下記の通りです。
- Raspberry Pi 3 Model B+
- Raspbian 9.11(stretch)
- Kernel 4.19.66-v7+
$ uname -a #Linux raspberrypi 4.19.66-v7+ #1253 SMP Thu Aug 15 11:49:46 BST 2019 armv7l GNU/Linux $ lsb_release -a #No LSB modules are available. #Distributor ID: Raspbian #Description: Raspbian GNU/Linux 9.11 (stretch) #Release: 9.11 #Codename: stretchPythonのバージョンは下記です。
$ python3 --version #Python 3.5.3 $ python3 -m pip --version #pip 20.0.2 from /home/pi/.local/lib/python3.5/site-packages/pip (python 3.5)TensorFlowのインストール
pipでのインストール
通常通り
pip
でインストールしようとしました。$ pip3 install tensorflow==xxx #Could not find a version that satisfies the requirement tensorflow==xxx (from versions: 0.11.0, 1.8.0, 1.9.0, 1.10.0, 1.11.0, 1.12.0, 1.13.1, 1.14.0) #No matching distribution found for tensorflow==xxxしかし、ラズパイからは1.14.0までしかインストールできないようです。
そのため、別の方法でインストールすることにしました。ソースからのビルド
公式ページの情報からビルド
TensorFlowの公式ページによると、Raspberry Piのソースからビルドすることで、インストールできそうです。
dockerを用いてビルドしていきます。
ラズパイ上でビルドすると時間がかかるのため、クロスコンパイルをした方が良いとのことなので、mac上でビルドしていきます。
先に結論からいうと、この方法ではビルドできませんでした。mac$ docker --version #Docker version 19.03.5, build 633a0eagithubからクローンしてきます。
今回は1.15.0をインストールしたいので、ブランチをチェックアウトしておきます。mac$ git clone https://github.com/tensorflow/tensorflow.git $ cd tensorflow $ git checkout r1.15公式ページに従ってクロスコンパイルを行います。
mac$ CI_DOCKER_EXTRA_PARAMS="-e CI_BUILD_PYTHON=python3 -e CROSSTOOL_PYTHON_INCLUDE_PATH=/usr/include/python3.4" \ tensorflow/tools/ci_build/ci_build.sh PI-PYTHON3 \ tensorflow/tools/ci_build/pi/build_raspberry_pi.shビルドが完了すると(約 30 分ほど)、.whl パッケージ ファイルがホストのソースツリーの出力アーティファクト用ディレクトリに作成されます。
とありますが、下記のようなエラーが出てビルドが完了しませんでした。
#addgroup: Please enter a username matching the regular expression configured #via the NAME_REGEX[_SYSTEM] configuration variable. Use the `--force-badname' #option to relax this check or reconfigure NAME_REGEX.調べてみると、公式の手順ではビルドできないというisuueがたっていました。
なんで公式のままできないんだよ。。。という感じですが、
issue内に、ネイティブビルドしたファイルをあげている人がいたので、今回はそれを使用します。ビルドファイルからインストール
Tensorflow-binにあげられているので、READMEを参考にインストールしていきます。
ラズパイの環境がRaspbian 9.11(stretch)なので、
tensorflow-1.15.0-cp35-cp35m-linux_armv7l.whl
を使用します。$ sudo apt-get update $ sudo apt-get upgrade $ sudo apt-get install -y libhdf5-dev libc-ares-dev libeigen3-dev gcc gfortran python-dev \ libatlas3-base libatlas-base-dev libopenblas-dev libopenblas-base libblas-dev \ liblapack-dev cython openmpi-bin libopenmpi-dev libatlas-base-dev python3-dev #libgfortran5がインストールできなかったので抜きました $ sudo pip3 install keras_applications==1.0.8 --no-deps $ sudo pip3 install keras_preprocessing==1.1.0 --no-deps $ sudo pip3 install h5py==2.9.0 $ sudo pip3 install pybind11 $ pip3 install -U --user six wheel mock $ sudo pip3 uninstall tensorflow $ wget https://github.com/PINTO0309/Tensorflow-bin/raw/master/tensorflow-1.15.0-cp35-cp35m-linux_armv7l.whl $ sudo pip3 install tensorflow-1.15.0-cp35-cp35m-linux_armv7l.whl最後のインストールコマンドで何度か
TypeError: unsupported operand type(s) for -=: 'Retry' and 'int'
で失敗してしまいましたが、めげずにsudo pip3 install tensorflow-1.15.0-cp35-cp35m-linux_armv7l.whl
を打っていたら5回ほどでインストール成功しました。。。$ python3 >>> import tensorflow as tf >>> tf.__version__ 1.15.0 >>> exit()無事に1.15.0がインストールできました!
今日はここまでです。
- 投稿日:2020-02-12T15:09:44+09:00
tensorflow2.1 + tensorflow-tensorrt で Transformer はまだ早かった
TL;DR
- tensorflow 2.x 系では RNN や Transformer などの tftrt へのコンバートはできない
- tftrt が convert_variables_to_constants_v2 を呼ぶ
- convert_variables_to_constants_v2 は tf2.1 現在制御構文(if, while など)に対応していない
- RNN 系や Transformer のデコード部分が辛い
背景
会社のプロジェクトでしゃべるロボットを作っており、その会話の応答速度を速めるために TensorRT を使う試行を行っていました。
会話の text-to-text の応答生成のモデルには Transformer ベースのオリジナルのネットワークが使われておりこの推論部分には以下の特徴があります。
- Attention を何度も行う部分や推論時のデコード処理に繰り返し(while)がある
- 過去の会話系列をベクトル化する処理と、応答生成のデコードで2種類の処理がある
- どちらの処理をさせるかを指示するため if 文が入る
問題
これらのネットワークを tftrt のモデルにコンバートしようとすると以下のエラーが起こります。
import os import time import numpy as np import tensorflow as tf from tensorflow.python.compiler.tensorrt import trt_convert as trt from tensorflow.python.saved_model import tag_constants print('Converting to TF-TRT...') trt_model_dir = '...' conversion_params = trt.DEFAULT_TRT_CONVERSION_PARAMS._replace( precision_mode=trt.TrtPrecisionMode.FP16, max_workspace_size_bytes=8000000000 ) converter = trt.TrtGraphConverterV2(input_saved_model_dir='...', conversion_params=conversion_params) converter.convert() converter.save(output_saved_model_dir=trt_model_dir) print('Done Converting to TF-TRT')output--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-20-3a7a7c89e0ac> in <module> 8 converter = trt.TrtGraphConverterV2(input_saved_model_dir=hp['base_dir'], 9 conversion_params=conversion_params) ---> 10 converter.convert() 11 converter.save(output_saved_model_dir=trt_model_dir) 12 print('Done Converting to TF-TRT') ~/.local/share/virtualenvs/ml_sandbox-YhSVM9Gx/lib/python3.6/site-packages/tensorflow_core/python/compiler/tensorrt/trt_convert.py in convert(self, calibration_input_fn) 978 self._input_saved_model_tags) 979 func = self._saved_model.signatures[self._input_saved_model_signature_key] --> 980 frozen_func = convert_to_constants.convert_variables_to_constants_v2(func) 981 grappler_meta_graph_def = saver.export_meta_graph( 982 graph_def=frozen_func.graph.as_graph_def(), graph=frozen_func.graph) ~/.local/share/virtualenvs/ml_sandbox-YhSVM9Gx/lib/python3.6/site-packages/tensorflow_core/python/framework/convert_to_constants.py in convert_variables_to_constants_v2(func, lower_control_flow) 508 print('op:', name_to_node[input_name].op) 509 print('node:', name_to_node[input_name]) --> 510 raise ValueError("Cannot find the Placeholder op that is an input " 511 "to the ReadVariableOp.") 512 _save_placeholder(input_name, node.attr["dtype"]) ValueError: Cannot find the Placeholder op that is an input to the ReadVariableOp.(一部デバッグのために convert_to_constants.py を書き換えてるので行数などは異なります)
調査
いろいろ試した結果どうも if が入るとこのエラーが出るということがわかったので、ただ dense layer を重ねたものに if 文で処理が分岐する再現サンプルを作りました。
https://gist.github.com/halhorn/2a44b9004aa0352fd4dfba0fb9942e8eこちらでも同様のエラーが出ます。
エラー箇所 付近を見ると、指定された op が Placeholder ではない場合にこのエラーが起きます。convert_variables_to_constants_v2 の doc を読んでみると、この関数は tf2.x 系用のもので、制御構文には今の所対応していないと書かれています。
The current implementation only works for graphs that do not contain any
control flow or embedding related ops.エラー内容では入力のノードの op が Placeholder でないといけないと言っているわけですが、実際エラー箇所の if 文に入ってきたノードの op の種類を見てみると、 while 系の場合 Enter が、 if 文系の場合は Switch が来ていました。
TFTRT ではない本家の TensorRT もまだ tf2.x 系には対応していないと聞いていますし、 TensorRT 関係を使いたいなら tf2.x 系はまだ早かったかという印象があります。(我々はもう2.1にしてしまいましたが)
追記:パフォーマンス
現在の TensorRT は CNN 系に最適化されており Transformer などには効果があるかが不明でした。
そこで Transformer の計算量の多くを占めている(と私がかってに思ってる) Dense layer のみを大量に積んだネットワークでのパフォーマンスを測定しました。https://gist.github.com/halhorn/1439d583d900bc27c45c556c21d4371c
精度はどちらも fp16 を使い、生の tensorflow モデルと tftrt コンバート済みのモデルでは、1推論あたり3.5ms と 1.31ms と、2倍以上の差がでました。(tf2.0 での tftrt (trt5.0系) では2倍の差は出なかったので、 tf2.1 になって trt のバージョンが上がったことで高速化されたのかもしれません。)
transformer にもし使えれば有効な高速化手段となっていたと思うので大変残念です。