LoginSignup
1
0

More than 1 year has passed since last update.

Raspberry Pi ZeroでTensorFlow Liteランタイムを実行しようとしたらハマった話

Posted at

はじめに

タイトルのとおり、ハマってしまったので記事に残すことにしました。

ハマったこと

Raspberry Pi Zero(armv6l)用のPython Wheelパッケージが提供されていないので、公式ドキュメントの通りにやってみたら、ビルドに失敗してしまう…

試してみたこと-1

こちらの記事を参考にして、Dockerコンテナ上で試してみても、ビルドに失敗してしまう(汗)
失敗したときの実行環境・実行したコマンドは、以下の通りです。

実行環境

  • OS: Ubuntu 20.04.2 LTS (ConoHa VPS)
  • CPU: 2Core
  • Mem: 1GB
  • SSD: 100GB

実行したコマンド

# Dockerのインストール(環境:ローカル)
# apt update && apt upgrade
# apt install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# echo \
    "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
    $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# apt update
# apt install docker-ce docker-ce-cli containerd.io

# cmakeのインストール(環境:ローカル)
# apt install cmake

# TensorFlowリポジトリのクローンを作成
# cd ~
# git clone https://github.com/tensorflow/tensorflow.git tensorflow_src

# Dockerコンテナの作成・起動
# docker pull tensorflow/tensorflow:devel
# docker run -it -v /var/run/docker.sock:/var/run/docker.sock \
    -v $PWD/tensorflow_src:/root/tensorflow_src -w /root/tensorflow_src \
    tensorflow/tensorflow:devel bash

# Dockerのインストール(環境:Dockerコンテナ)
# apt update && apt upgrade
# apt install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# echo \
    "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
    $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# apt update
# apt install docker-ce docker-ce-cli containerd.io

# cmakeのインストール(環境:Dockerコンテナ)
# apt install cmake

# Wheelのビルド(環境:Dockerコンテナ)
# tensorflow/tools/ci_build/ci_build.sh PI-PYTHON37 \
    tensorflow/lite/tools/pip_package/build_pip_package_with_cmake.sh rpi0

ちなみに、ビルドに失敗すると、このようなメッセージが表示されます。

/workspace/tensorflow/lite/tools/cmake/toolchains/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/arm-linux-gnueabihf/include/c++/8.3.0/bits/deque.tcc:585:7: note: parameter passing for argument of type '__gnu_cxx::__normal_iterator<const double*, std::vector<double> >' changed in GCC 7.1
/workspace/tensorflow/lite/tools/cmake/toolchains/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/arm-linux-gnueabihf/include/c++/8.3.0/bits/deque.tcc:585:7: note: parameter passing for argument of type '__gnu_cxx::__normal_iterator<const double*, std::vector<double> >' changed in GCC 7.1
/workspace/tensorflow/lite/tools/cmake/toolchains/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/arm-linux-gnueabihf/include/c++/8.3.0/bits/deque.tcc:625:11: note: parameter passing for argument of type '__gnu_cxx::__normal_iterator<const double*, std::vector<double> >' changed in GCC 7.1
           _M_insert_aux(__pos, __first, __last, __n);
           ^~~~~~~~~~~~~
In file included from /workspace/tensorflow/lite/tools/cmake/toolchains/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/arm-linux-gnueabihf/include/c++/8.3.0/deque:64,
                 from /workspace/tensorflow/lite/kernels/internal/spectrogram.h:35,
                 from /workspace/tensorflow/lite/kernels/internal/spectrogram.cc:16:
/workspace/tensorflow/lite/tools/cmake/toolchains/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/arm-linux-gnueabihf/include/c++/8.3.0/bits/stl_deque.h: In member function 'bool tflite::internal::Spectrogram::GetNextWindowOfSamples(const std::vector<InputSample>&, int*) [with InputSample = double]':
/workspace/tensorflow/lite/tools/cmake/toolchains/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/arm-linux-gnueabihf/include/c++/8.3.0/bits/stl_deque.h:2021:4: note: parameter passing for argument of type '__gnu_cxx::__normal_iterator<const double*, std::vector<double> >' changed in GCC 7.1
    _M_range_insert_aux(__pos, __first, __last,
    ^~~~~~~~~~~~~~~~~~~
/workspace/tensorflow/lite/tools/cmake/toolchains/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/arm-linux-gnueabihf/include/c++/8.3.0/bits/stl_deque.h:2021:4: note: parameter passing for argument of type '__gnu_cxx::__normal_iterator<const double*, std::vector<double> >' changed in GCC 7.1
    _M_range_insert_aux(__pos, __first, __last,
    ^~~~~~~~~~~~~~~~~~~
make[3]: Leaving directory '/workspace/tensorflow/lite/tools/pip_package/gen/tflite_pip/python3.7/cmake_build'
make[2]: *** [CMakeFiles/tensorflow-lite.dir/all] Error 2
CMakeFiles/Makefile2:1145: recipe for target 'CMakeFiles/tensorflow-lite.dir/all' failed
make[2]: Leaving directory '/workspace/tensorflow/lite/tools/pip_package/gen/tflite_pip/python3.7/cmake_build'
CMakeFiles/Makefile2:1253: recipe for target 'CMakeFiles/_pywrap_tensorflow_interpreter_wrapper.dir/rule' failed
make[1]: *** [CMakeFiles/_pywrap_tensorflow_interpreter_wrapper.dir/rule] Error 2
make[1]: Leaving directory '/workspace/tensorflow/lite/tools/pip_package/gen/tflite_pip/python3.7/cmake_build'
make: *** [_pywrap_tensorflow_interpreter_wrapper] Error 2
Makefile:215: recipe for target '_pywrap_tensorflow_interpreter_wrapper' failed
root@06a2eea49469:~/tensorflow_src#

試してみたこと-2

結論から言うと、こちらの方法でWheelのビルドに成功しました。

コンテナではなくRaspberry Pi Zero上で普通にビルドした方が良いのでは?、と思いbuild_pip_package_with_cmake.shの中身を解読して、一行ずつ端末から実行してみました。

成功したときの実行環境・実行したコマンドは、以下の通りです。

実行環境

  • Raspberry Pi Zero WH
  • OS: Raspberry Pi OS Lite (Release data: May 7th 2021)
  • SDカード: 64GB

実行したコマンド

$ sudo apt update && sudo apt upgrade -y
$ sudo apt install cmake
$ cd ~
$ git clone https://github.com/tensorflow/tensorflow.git tensorflow_src
$ mkdir tflite_build
$ cd tflite_build
$ sudo cmake ../tensorflow_src/tensorflow/lite \
    -DCMAKE_C_FLAGS="-I/usr/include/python3.7m -I/home/pi/.local/lib/python3.7/site-packages/pybind11/include" \
    -DCMAKE_CXX_FLAGS="-I/usr/include/python3.7m -I/home/pi/.local/lib/python3.7/site-packages/pybind11/include" \
    -DCMAKE_SHARED_LINKER_FLAGS='-latomic'
    -DCMAKE_SYSTEM_NAME=Linux \
    -DCMAKE_SYSTEM_PROCESSOR=armv6 \
    -DTFLITE_ENABLE_XNNPACK=OFF
$ sudo cmake --build . --verbose -j 1 -t _pywrap_tensorflow_interpreter_wrapper
$ cd ~/tensorflow_src/tensorflow/lite/tools/pip_package/
$ sudo mkdir gen
$ sudo mkdir gen/tflite_pip
$ sudo mkdir gen/tflite_pip/python3.7
$ sudo mkdir gen/tflite_pip/python3.7/tflite_runtime
$ cd gen/tflite_pip/python3.7
$ sudo cp -r ~/tensorflow_src/tensorflow/lite/tools/pip_package/debian/ ./
$ sudo cp -r ~/tensorflow_src/tensorflow/lite/tools/pip_package/MANIFEST.in ./
$ sudo cp -r ~/tensorflow_src/tensorflow/lite/python/interpreter_wrapper/ ./
$ sudo cp ~/tensorflow_src/tensorflow/lite/tools/pip_package/setup_with_binary.py ./setup.py
$ sudo cp ~/tensorflow_src/tensorflow/lite/python/interpreter.py ./tflite_runtime/
$ sudo cp ~/tensorflow_src/tensorflow/lite/python/metrics_interface.py ./tflite_runtime/
$ sudo cp ~/tensorflow_src/tensorflow/lite/python/metrics_portable.py ./tflite_runtime/
$ sudo cp ~/tflite_build/_pywrap_tensorflow_interpreter_wrapper.so ./tflite_runtime/
$ sudo chmod u+w ./tflite_runtime/_pywrap_tensorflow_interpreter_wrapper.so
$ sudo touch ./tflite_runtime/__init__.py
$ sudo echo "__version__ = '2.7.0'" >> ./tflite_runtime/__init__.py
$ sudo echo "__git_version__ = '$(git -C ~/tensorflow_src describe)'" >> ./tflite_runtime/__init__.py
$ sudo python3 setup.py bdist --plat-name=linux_armv6l bdist_wheel --plat-name=linux-armv6l

ビルドに成功すると、tensorflow_src/tensorflow/lite/tools/pip_package/gen/tflite_pip/python3.7/dist
Wheelが出力されます。ちなみに、ビルド完了するまで、4時間くらいかかりました。

pi@raspberrypi:~/tensorflow_src/tensorflow/lite/tools/pip_package/gen/tflite_pip/python3.7/dist $ ls
tflite_runtime-2.7.0-cp37-cp37m-linux_armv6l.whl
tflite-runtime-2.7.0.linux_armv6l.tar.gz

動作確認

動作確認のため、学習済みモデル(test.tflite)を読み込み、get_input_details()get_output_details()を実行してみました。結果、エラーは発生せず、入力層と出力層の情報を表示することができました。

pi@raspberrypi:~ $ python3
Python 3.7.3 (default, Jan 22 2021, 20:04:44)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tflite_runtime.interpreter as tflite
>>> interpreter = tflite.Interpreter(model_path='./test.tflite')
>>> interpreter.get_input_details()
[{'name': 'serving_default_flatten_input:0', 'index': 0, 'shape': array([ 1, 28, 28]), 'shape_signature': array([-1, 28, 28]), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0), 'quantization_parameters': {'scales': array([], dtype=float32), 'zero_points': array([], dtype=int32), 'quantized_dimension': 0}, 'sparsity_parameters': {}}]
>>> interpreter.get_output_details()
[{'name': 'StatefulPartitionedCall:0', 'index': 9, 'shape': array([ 1, 10]), 'shape_signature': array([-1, 10]), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0), 'quantization_parameters': {'scales': array([], dtype=float32), 'zero_points': array([], dtype=int32), 'quantized_dimension': 0}, 'sparsity_parameters': {}}]
>>>

おわりに

あまり需要のない内容かと思いますが、誰かの参考になれば幸いです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0