tensorflow: Unable to cross compile TFLite for Raspberry Pi Zero using Docker image nightly-develop

System information

  • OS Platform and Distribution: Linux Mint 19:03 (based on Ubuntu 18:04)
  • Mobile device (e.g. iPhone 8, Pixel 2, Samsung Galaxy) if the issue happens on mobile device: N/A ? Attempting to crosscompile tensorflowlite for Raspbery Pi Zero (Armv6)
  • TensorFlow installed from (source or binary): nightly-develop docker image
  • TensorFlow version: 2.2
  • Python version: 2.7
  • Installed using virtualenv? pip? conda?: docker file from latest nightly build
  • Bazel version (if compiling from source): bazel 0:15:0
  • GCC/Compiler version (if compiling from source): gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0
  • CUDA/cuDNN version: n/a
  • GPU model and memory: none

When cross compiling for raspberry pi zero (ARMv6), as per instructions on following page https://www.tensorflow.org/lite/guide/build_rpi and running the command indicated to build for the ARMv6 architecture, ./tensorflow/lite/tools/make/build_rpi_lib.sh TARGET_ARCH=armv6

there are errors indicating that the compiler options set are incorrect

/usr/arm-linux-gnueabihf/include/bits/stdio.h: In function ‘int getchar()’: /usr/arm-linux-gnueabihf/include/bits/stdio.h:44:14: sorry, unimplemented: Thumb-1 hard-float VFP ABI getchar (void)

Any other info / logs

if I examine the file

./tensorflow/lite/tools/make/build_rpi_lib.sh I found that the TARGET_ARCH parameter was hard coded for armv7 in the final line of the file

If I edit the file so that this reads

CC_PREFIX=arm-linux-gnueabihf- make -j 3 -f tensorflow/lite/tools/make/Makefile TARGET=rpi TARGET_ARCH=armv6 (the hardcoding is not ideal for obvious reasons ) and then change the armv6 compiler options in

tensorflow/lite/tools/make/targets/rpi_makefile.inc to the following

ifeq ($(TARGET_ARCH), armv6)
CXXFLAGS +=
-marm
-mfpu=vfp
-mlong-calls
-mthumb-interwork
-mfloat-abi=hard

CCFLAGS += \
  -marm \
  -mfpu=vfp \
  -mlong-calls \
  -mthumb-interwork \
  -mfloat-abi=hard

LDFLAGS := \
  -Wl,--no-export-dynamic \
  -Wl,--exclude-libs,ALL \
  -Wl,--gc-sections \
  -Wl,--as-needed \
  -mfpu=vfp \
  -mlong-calls \
  -mfloat-abi=hard \
  -mthumb-interwork 
endif

I can compile without errors (and just a couple of warnings).

Given that it seems to be difficult (or just very slow) to compile bazel directly on a raspberry pi zero due to the lack of memory and that increasing the memory available (even via machine virtualisation such as QEMU appears impossible), I think that for deployment on a PI Zero, cross compiling is the only way forward. At the moment I can inference, but only by using a full tensorflow implementation, which is really too slow for my needs)

Additionally it would be nice to have a way to generate a python wheel as well. The main ci_build process does this for the full fat tensorflow package, (and i can run one of those on the pi zero), but I’d like to just use tensorflow-lite for my inferencing, as i think any performance improvements that I can get would be beneficial. I’m using a Pi Zero for it’s low power consumption for energy efficiency reasons, so swapping out to a PI 3 or Pi 4 would not really be viable for my project.

thanks for your help

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 3
  • Comments: 23 (1 by maintainers)

Most upvoted comments

@mikhailkin Could you try:

LD_PRELOAD=/usr/lib/arm-linux-gnueabihf/libatomic.so.1.2.0 python3
>>> from tflite_runtime.interpreter import Interpreter

FYI

I was able to find a working solution for running tensorflow(lite as well) on the ARM6 based raspberry pi (like the zero or the Pi1):

in python:

import tensorflow as  tf

interpreter = tf.lite.Interpreter(model_path)

After a long time looking for a good solution I found this working pretty well and easy!

@rajurimu could you try the below?

wget https://github.com/askemottelson/ada-alarm/blob/master/ML/lite/dist/tflite_runtime-2.2.0rc3-cp37-cp37m-linux_armv6l.whl?raw=true
pip3 install tflite_runtime-2.2.0rc3-cp37-cp37m-linux_armv6l.whl
LD_PRELOAD=/usr/lib/arm-linux-gnueabihf/libatomic.so.1.2.0 python3
>>> from tflite_runtime.interpreter import Interpreter

askemottelson, this worked and i can load tflite runtime as you suggested. Many many many thanks for that. However when I run in Thonny, it gives me the following errors - summarized below (not full traceback).


ImportError: /home/pi/.local/lib/python3.7/site-packages/tflite_runtime/_interpreter_wrapper.cpython-37m-arm-linux-gnueabihf.so: undefined symbol: __atomic_compare_exchange_8

During handling of the above exception, another exception occurred:

ModuleNotFoundError: No module named ‘_interpreter_wrapper’


However these are resolved once I LD_PRELOAD Thonny with libatomic.so.

Many many many thanks to you. I have been trying to find solution for quite some time and was not successful. Thanks a lot.

A few followup questions though

  1. Is there a way to build my own whl? Instruction from earlier thread did not work. If you have something which i can follow and learn will be very useful. I am at an entry level and trying to learn
  2. Is there a way to ‘avoid’ LD_PRELOAD and have this always included instead of running LD_PRELOAD? Seems libatomic is referenced in many places as ‘missing library’ making it a part of PRELOAD

Thanks

@rajurimu could you try the below?

wget https://github.com/askemottelson/ada-alarm/blob/master/ML/lite/dist/tflite_runtime-2.2.0rc3-cp37-cp37m-linux_armv6l.whl?raw=true
pip3 install tflite_runtime-2.2.0rc3-cp37-cp37m-linux_armv6l.whl
LD_PRELOAD=/usr/lib/arm-linux-gnueabihf/libatomic.so.1.2.0 python3
>>> from tflite_runtime.interpreter import Interpreter

Anyway, I copied binaries from /usr/local/lib/python3.7/dist-packages https://drive.google.com/drive/folders/1hm4ShvPCqXYDuh7ijA6tepycFuP-II4K

Thanks. Works here!