Tensorflow工程实践: 编译Tensorflow动态链接库

Posted 谢小小XH

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tensorflow工程实践: 编译Tensorflow动态链接库相关的知识,希望对你有一定的参考价值。

之前学习Tensorflow的部分其实还有很多没有写完,那些慢慢更新,这里准备把tensorflow项目工程化的东西和学习tensorflow的内容一起更新。

一.windows下面编译和测试

Ⅰ.准备工作

我这里使用的系统是win10,首先把编译整个过程需要的工具列出来:

  1. VS2017 (我这边是VS2017,其他的版本应该也差不多)

  2. Swigwin (在我这里其可执行文件地址为 D:\\Tools\\swigwin-3.0.12/swig.exe)

  3. python (我这边是python3.6,同时在环境变量中要找得到)

  4. CMake,安装时注意选择将路径添加到环境变量。

  5. git,用于在编译过程中从GitHub上下载依赖项。

  6. Tensorflow源码 (这里我选择的是
    将GitHub上TensorFlow的r1.8分支,这是我写这篇博客的时候最新发行的版本)

这里先列出来之后要用到的几个路径:
- Python可执行文件地址为:D:\\Tools\\Anaconda3\\python.exe
- Python库文件地址为:D:\\Tools\\Anaconda3\\libs\\python36.lib
- Swigwin可执行文件地址:D:\\Tools\\swigwin-3.0.12/swig.exe

我这里是把源代码下载到了D:\\Tools 这个文件夹中,编辑文件tensorflow/tensorflow/contrib/cmake/CMakeLists.txt,其中我们需要修改两个地方。首先你可以找到类似下面这段代码的地方,把找到的修改为下面的这个样子。

if (tensorflow_OPTIMIZE_FOR_NATIVE_ARCH)
  include(CheckCXXCompilerFlag)
  CHECK_CXX_COMPILER_FLAG("-march=native" COMPILER_OPT_ARCH_NATIVE_SUPPORTED)
  if (COMPILER_OPT_ARCH_NATIVE_SUPPORTED)
    set(CMAKE_CXX_FLAGS "$CMAKE_CXX_FLAGS -march=native")
  else()
    CHECK_CXX_COMPILER_FLAG("/arch:AVX" COMPILER_OPT_ARCH_AVX_SUPPORTED)
    if(COMPILER_OPT_ARCH_AVX_SUPPORTED)
      set(CMAKE_CXX_FLAGS "$CMAKE_CXX_FLAGS /arch:AVX")
    endif()
  endif()
endif()

然后找到

option(tensorflow_ENABLE_GRPC_SUPPORT "Enable gRPC support" OFF)

改为上面的样子(就是把默认的ON,改为OFF)。这里解释一下,因为打开gRPC有可能会报错,因此这里先关闭。Linux上面好像没有这个问题。

Ⅱ.cmake构建

这一部分很简单,在D:\\Tools\\tensorflow-r1.8\\tensorflow\\contrib\\cmake下面新建一个文件夹build,用来存放我们后面的构建文件和编译出来的文件.

以管理员身份运行 开始==>所有程序==>Visual Studio 2017==>Visual Studio Tools==>Developer Command Prompt for VS2015,

然后在其中输入powershell,接下来使用命令切换到新建的build文件夹下。

使用下面的命令用于build编译项目。

cmake .. -A x64 -DCMAKE_BUILD_TYPE=Release -DSWIG_EXECUTABLE=D:\\Tools\\swigwin-3.0.12/swig.exe -DPYTHON_EXECUTABLE=D:\\Tools\\Anaconda3\\python.exe -DPYTHON_LIBRARIES=D:\\Tools\\Anaconda3\\libs\\python36.lib -Dtensorflow_BUILD_SHARED_LIB=ON

可以看到,使用的就是上一部分列出来的三个路径。你可以根据你自己的情况来修改上面命令中的路径。当命令行中出现Generating done,说明cmake构建成功。

Ⅲ.编译

等到cmake构建成功之后,直接在命令行里面输入下面的编译命令就行。要注意的是,网络要通畅,中间会有下载组件的操作。编译的时间大概是3个多小时?根据你电脑的配置来。

MSBuild /p:Configuration=Release ALL_BUILD.vcxproj

如果编译到一部分之后又会出现一个错误(要是没有发生这个错误就不用管)
修改文件D:\\tf\\tensorflow-r1.8\\tensorflow\\contrib\\cmake\\build\\re2\\src\\re2\\CMakeLists.txt(这个时候这个文件夹已经下载到了),找到如下行,按照如下方式修改好就行。然后再次使用上面的编译命令,估计后面就应该没有什么大问题,可以直接编译过去了。

option(RE2_BUILD_TESTING “enable testing for RE2” OFF)

要是后面重复出现一些堆内存不够的错误,没关系,直接再输一次MSBuild /p:Configuration=Release ALL_BUILD.vcxproj 命令就行。

编译完成之后,你就会在build的这个目录下面找到一个Release文件夹,打开文件夹,就能够看到tensorflow的动态库啦。

二.Linux下面编译和测试

step1:安装依赖项

有可能需要需要使用到的命令:

sudo cp -r /usr/local/include/eigen3/Eigen /usr/local/include

注意:参考cp指令 cp -r /usr/men /usr/zh 将目录/usr/men下的所有文件及其子目录复制到目录/usr/zh中

说明:
因为eigen3 被默认安装到了usr/local/include里了(或者是usr/include里,这两个都差不多,都是系统默认的路径),在很多程序中include时经常使用#include <Eigen/Dense>而不是使用#include <eigen3/Eigen/Dense> 所以要做下处理,否则一些程序在编译时会因找不到Eigen/Dense而报错。上面指令将usr/local/include/eigen3文件夹中的Eigen文件递归地复制到上一层文件夹(直接放到/usr/local/include中,否则系统无法默认搜索到 -> 此时只能在CMakeLists.txt用include_libraries(绝对路径了))

step2:bazel编译tensorflow

进入到你克隆好的tensorflow源代码的根目录下面,运行:

bazel build //tensorflow:libtensorflow_cc.so

这个命令是用来编译tensorflow 的C++动态链接库。等他跑完编译成功的话,那么在tensorflow的根目录下面应该出现了一些新的文件夹,比如bazel-genfiles,bazel-out,bazel-bin等文件夹,按顺序执行以下命令将对应的libtensorflow_cc.so文件和其他文件拷贝进入 /usr/local/lib/ 目录.

sudo mkdir /usr/local/include/tf 
sudo cp -r bazel-genfiles/ /usr/local/include/tf/
sudo cp -r tensorflow /usr/local/include/tf/
sudo cp -r third_party /usr/local/include/tf/
sudo cp -r bazel-bin/tensorflow/libtensorflow_cc.so /usr/local/lib/

这一步完成后,我们就准备好了libtensorflow_cc.so文件等,后面在自己的C++编译环境和代码目录下编译时链接这些库即可

以上是关于Tensorflow工程实践: 编译Tensorflow动态链接库的主要内容,如果未能解决你的问题,请参考以下文章

Tensorflow之MNIST的最佳实践思路总结

81TensorFlow 2 模型部署方法实践--TensorFlow Serving 部署模型

你真的会正确地调试TensorFlow代码吗?

tensorflow 工程实践范例

观点 | TensorFlow sucks,有人吐槽TensorFlow晦涩难用

算法工程师耗尽心血终成TensorFlow深度学习应用实践,值得一学!