在 RaspberryPi 上编译 TensorFlow


发布于

|

分类

小 Pi 吃灰已久,突然就想再去买个摄像头,装到 Pi 上,然后装个 TensorFlow,搞一点好玩的东西出来。

然而官方并没有提供armV7上的预编译版本……所以天才第一步,在 RaspberryPi 上编译 TensorFlow。

网上大致可以找到几个教程,在这里稍微翻译和总结一下。

更新

TensorFlow 1.9 版本之后,Google官方已经提供了树莓派预编译版,直接pip安装即可。

本文完。


挂载 Swap 分区

按照 这个教程 给Pi分派一些SWAP区。建议 2G 以上。

或者,有空闲U盘的话,可以考虑格式化成 Linux Swap 格式,然后写 /etc/fstab 进行挂载。

安装依赖

sudo apt update
sudo apt install pkg-config zip g++ zlib1g-dev unzip default-jdk autoconf automake libtool
sudo apt install python3-pip python3-numpy swig python3-dev
sudo pip3 install wheel
sudo apt install gcc g++

同时推荐做一下这个:

sudo apt install gcc-4.8 g++-4.8
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 100
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 100

其他依赖的话,缺什么补什么吧。

Bazel

好像是类似于 Make 的东西。

https://github.com/bazelbuild/bazel/releases 下载。不一定非得要最新版。由于 Pi 是基于 arm 的,没有对应的打包,所以需要下载源代码包(bazel-X.X.X-dist.zip),然后自己编译。

解压缩,找到 scripts/bootstrap/compile.sh,找到下面的内容(位于第 117 行左右):

run "${JAVAC}" -classpath "${classpath}" -sourcepath "${sourcepath}" \
      -d "${output}/classes" -source "$JAVA_VERSION" -target "$JAVA_VERSION" \
      -encoding UTF-8 "@${paramfile}"

在后面加上 -J-Xmx500M,即改为

run "${JAVAC}" -classpath "${classpath}" -sourcepath "${sourcepath}" \
      -d "${output}/classes" -source "$JAVA_VERSION" -target "$JAVA_VERSION" \
      -encoding UTF-8 "@${paramfile}" -J-Xmx500M

然后进行编译:

./compile.sh

编译大概耗时 2 小时。编译完成后,执行

sudo cp output/bazel /usr/local/bin/bazel

然后再执行

bazel

以完成安装。(第一次执行 bazel 会出现安装进度条,之后就不会再有了)

TensorFlow

首先获取源代码

git clone --recurse-submodules https://github.com/tensorflow/tensorflow

切换到一个已知的版本上(例如 r1.4

git checkout r1.4 -f

据说 tf 默认会用 64 位的东西,用下面一句话可以强制其使用 32 位:

grep -Rl 'lib64' | xargs sed -i 's/lib64/lib/g'

配置一下:

./configure

如果用 Python3 的话,使用 /usr/bin/python3

除了 jemallocY 之外,其余都选 N

编译 Python 版:

bazel build \
    -c opt \
    --copt="-funsafe-math-optimizations" \
    --copt="-ftree-vectorize" \
    --copt="-fomit-frame-pointer" \
    --local_resources 1024,1.0,1.0 \
    --copt="-mfpu=neon-vfpv4" \
    --verbose_failures \
    tensorflow/tools/pip_package:build_pip_package

如果gcc版本较高,还需要按照官方说明,加上一句 --cxxopt="-D_GLIBCXX_USE_CXX11_ABI=0"

如果想加快一点编译,可以使用 1024,2.0,1.0 或者 1024,4.0,1.0。如果怕编译崩溃,使用 1024,0.5,1.0。大概耗时6小时。如果前面不加 Swap 区的话,这里极容易编译失败。

如果出现 name 'sycl_library_path' is not defined 错误,可以加上 --incompatible_load_argument_is_label=false 这个参数进行编译。

如果遇到 session.run() 崩溃的情况,去掉 --copt="-mfpu=neon-vfpv4" 再编译试试。

编译好之后,还要再生成 whl 包以便安装:

bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg

最后进行安装:

sudo pip3 install /tmp/tensorflow_pkg/tensorflow-X.X.X-cpXX-none-linux_armv7l.whl

最后打开 python 做个验证:

import tensorflow as tf
sess = tf.Session()
hello = tf.constant('Hello, TensorFlow!')
print(sess.run(hello))

a = tf.constant(3.0)
b = tf.constant(4.0)
c = a + b
print(a, b, c)
print(sess.run([a, b, c]))

后记

几个血的教训:

  1. Bazel如果编译失败,可以多试几个版本,好像最新版一只编译失败
  2. 折腾这些东西之前,一定对整个 SD 卡打个备份包
  3. 一定要有 Swap,不然一定会 GG
    高峰情况下Swap占用接近1G
  4. 不建议去折腾GPU
  5. 建议睡觉的时候进行编译
    总用时

下载

自己编译好的都放在了Google云端硬盘上。戳这里查看并下载

参考资料

  1. Installing TensorFlow from Sources
  2. Building TensorFlow for Raspberry Pi: a Step-By-Step Guide
  3. Building TensorFlow 1.3.0 as a standalone project (Raspberry pi 3 included)
  4. build issue: invalid paths

评论

  1. patrick 的头像
    patrick

    感谢分享的编译好的文件,节省了不少时间

    1. patrick 的头像
      patrick

      现成的Tensorflow发现不能用…/尴尬

  2. 谁想 的头像
    谁想

    不使用neon vfp, 速度会慢不少。
    至少我在树莓派上自己编译opencv是这样。
    我记得看过一篇博客说tf用上neon和vfp指令集也会快不少

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注