小 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
。
除了 jemalloc
选 Y
之外,其余都选 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]))
后记
几个血的教训:
- Bazel如果编译失败,可以多试几个版本,好像最新版一只编译失败
- 折腾这些东西之前,一定对整个 SD 卡打个备份包
- 一定要有 Swap,不然一定会 GG
- 不建议去折腾GPU
- 建议睡觉的时候进行编译
下载
自己编译好的都放在了Google云端硬盘上。戳这里查看并下载。
发表回复