在 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 指令集也会快不少

发表回复

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