linux 下 tensorflow C++ CPU编译过程记录,已编译CPU库直接下载(测试ubuntu18.04、ubuntu20、debian10测试未发现依赖问题)
已编译好库在最下方。
背景(跳过,并没有什么用)
最近项目中要做一个NSFW检测,在网上找到一个别人训练好的tensorflow 的PB模型,但是代码是Python, 想用C++ 去调用这个模型,预测。
因为我觉得C++ 首先客户部署简单(和客户确定好libc基础下),只需要整理好相关.so文件,不像python,除了搭建环境外,还需要通过pip安装很多依赖。客户操作步骤越多,就越容易部署过程中出问题。
之所以写这篇随笔,主要因为在百度搜索tensorflow编译时,大部分都在说直接系统下编译,这样很可能会出现问题,因为每个linux发行版的glibc、gcc默认安装版本会有区别,比如我本机使用debian 10,在apt-get install gcc时,会装gcc 11,如果是ubuntu 18 apt-get install gcc时, 会装gcc7。
我一开始也是在本机中使用gcc11编译,喜提gcc编译错误。
这一点在官网中有声明:https://tensorflow.google.cn/install/source?hl=zh_cn
也就是说,最好使用gcc7版本进行编译。
如果你当前是ubuntu,可以尝试在本机编译,如果其他发行版,强烈建议docker 内下载ubuntu 编译,编译完成后,取出so库到生产环境。
经测试, debian10、ubuntu 18.04、ubuntu 20.04,在docker ubuntu 18.04环境下编译出来的tensorflow库,可以直接使用。
首先,建议使用随笔最下方提供的链接,下载已编译好的SO库,和整理好的头文件,尝试直接调用。
整体步骤
强烈建议docker 内下载ubuntu 编译
0. 真机扩大内存,可以动态生成swap文件: swapon swap文件路径添加swap内存,具体百度
1. 安装docker、下载ubuntu 18.04 (docker pull ubuntu:18.04)
2. 进入虚拟环境,搭建安装编译所需要的bazel、gcc、g++、python3、python3-dev、git...
3. git 拉取指定版本tensorflow
4. 执行tensorflow 中的configure程序,生成构建文件。
5. bazle 编译
6. 使用docker cp,把docker内ubuntu中编译好的so库提取到生产环境。
编译环境
因为是在docker中构建的,所以就不过多介绍真机环境
tensorflow: 1.15.4
bazel: 3.1.0
bazel 下载慢,可以使用华为云镜像: https://mirrors.huaweicloud.com/bazel/
docker: ubuntu 18.04
内存: 8G, 交换空间(磁盘空间当内存): 8G
主要注意一下内存,必须10G以上,因为bazel编译时,会时不时占用很大内存,如果内存不够用电脑就会因为内存不够卡死。
在tensorflow官网中介绍构建时使用 --local_ram_resources=2048 参数限制内存在2G左右,但我尝试了一下并没有效果。
gcc: 7.5.0
初始化环境
使用docker 进入ubuntu 容器,执行:
apt-get update apt-get install git python3 python3-dev vi wget unzip python3-pip # 编译时会涉及到python脚本执行,用到了numpy pip3 install numpy # 建立python3软连接,python 脚本执行,默认使用python命令 ln -s /usr/bin/python3 /usr/bin/python
拉取项目:
git clone -b v1.15.4 https://gitee.com/mirrors/tensorflow.git
下载bazel:
我使用的是tensorflow 1.15.4, bazel版本是: 3.1.0。
如果不清楚该使用什么版本bazel,可以先随意下载一个版本,执行./configure,如果版本不对,会告诉当前bazel版本不对,应使用那个版本。
通过wget 下载以上两个文件中其中一个,一个是安装sh脚本,一个是可执行二进制文件:
wget https://mirrors.huaweicloud.com/bazel/3.1.0/bazel-3.1.0-installer-linux-x86_64.sh chmod +x bazel-3.1.0-installer-linux-x86_64.sh ./bazel-3.1.0-installer-linux-x86_64.sh
ps: 使用脚本安装,要保证本机已安装unzip,上方搭建环境中已把unzip加入到其中
生成编译文件
# 进入tensorflow 项目目录下,执行
./configure
一路回车,主要是选择Python路径、GPU选项等等
开始编译
1. 编译前,要确保内存(物理内存+交换空间swap)在10G以上,最好16G,不然会编译时耗尽内存卡死,最后被系统杀死
2. 编译过程中,会去github仓库下载项目,由于国内github不稳定,这个过程是很容易出错的,出错内容不仅仅是timeout,有可能是no search xxx,当出错后,反复多尝试几次
建议白天编译,晚上早上好像github会很慢。如果有条件,da梯子编译最好。
3. 当你到达这一步的时候,那么恭喜你,编译过程最困难的地方已经结束了,到这里基本不会有其他问题了(保证是GCC7)。
4. 建议在机器性能好的环境下编译,不然编译会很慢
bazel build --config=opt //tensorflow:libtensorflow_cc.so
ps: 注意,//tensorflow:libtensorflow_cc.so 不是注释,这也是bazel参数一部分!!一定要复制全了,不能光是bazel build --config=opt
提出库文件
编译成功后,进入bazel-bin/tensorflow目录下,正常情况会有so库文件:
进入tensorflow/bazel-bin/tensorflow 下把库打包,通过docker cp 复制到宿主机环境:
tar -zcvf lib.tar *.so*
宿主机下:
docker cp {docker 容器ID}:/{bazel编译路径}/lib.tar /{宿主机目录}
已编译库链接
链接: https://quqi.avyeld.com/s/6273754/oBIsB31RssXZ5s4D
解压后执行build.sh,通过g++ 构建hello world程序,需要把libtensorflow_cc.so.2.5.0和libtensorflow_framework.so.2.5.0放到系统库目录下。
g++11,使用此库构建成功。
20220309补充:
经过验证, 用以上方式,可以成功编译当前最新的tensorflow 2.8.0,so库链接: https://quqi.avyeld.com/s/6273754/G7SecxSZd3Ksdf3a
如果想获取库头文件,跳转: https://www.cnblogs.com/GengMingYan/p/15967489.html