欢迎访问我的网站,希望内容对您有用,感兴趣的可以加入免费知识星球。

源码编译tensorflow-2.2.0,支持gpu加速

TensorFlow 迷途小书童 4年前 (2020-05-22) 8851次浏览 0个评论

软硬件环境

  • ubuntu 18.04 64bit
  • anaconda3 with python 3.7.6
  • tensorflow 2.2.0
  • bazel 2.0.0
  • cuda 10.1
  • cudnn 7.6.5
  • gcc 7
  • nvidia gtx 1070Ti

视频看这里


此处是youtube的播放链接,需要科学上网。喜欢我的视频,请记得订阅我的频道,打开旁边的小铃铛,点赞并分享,感谢您的支持。

tensorflow简介

tensorflow是谷歌公司推出的开源机器学习框架,它提供了c++pythonjavajavascriptgo等语言的API,具有快速、灵活并适合产品级大规模应用等特点,让每个开发者都能方便地使用人工智能来解决多样化的实际问题,因此非常受欢迎。

tensorflow的命名来源于本身的运行原理。tensor(张量)意味着N维数组,flow(流)意味着基于数据流图的计算,tensorflow是张量从流图的一端流动到另一端计算过程。

tensorflow中的计算可以表示为一个有向图,或称计算图,其中每一个运算操作将作为一个节点,节点间的链接叫做边。这个计算图描述了数据的计算流程,它也负责维护和更新状态,用户可以对计算图的分支进行条件控制和循环操作。计算图中的每一个节点可以有任意多个输入和输出,每一个节点描述了一种运算操作,节点可以算是运算操作的实例化。

准备工作

tensorflow-gpu

安装python环境

我们使用anaconda,详细安装使用方法可以参考文章 anaconda使用

为了加快conda安装软件的速度,使用国内的清华源,编辑文件~/.condarc,添加

channels:
  - defaults
show_channel_urls: true
default_channels:
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r
custom_channels:
  conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  msys2: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  bioconda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  menpo: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud

接下来创建一个独立、干净的虚拟环境tfgpu

conda create -n tfgpu python=3.7
conda activate tfgpu

安装protobuf

protobuf也是谷歌家的产品,它是一种数据交换/存储的格式,我们通过conda来安装,当前默认的版本是3.11.4

conda install protobuf

在我编译tensorflow-2.2.0过程中,protobuf-3.11.4并没有报错,如果在你的环境中出错了,可以查看文件tensorflow/workspace.bzlprotobuf的版本,然后进行安装

tensorflow-gpu

tensorflow-2.2.0对应的protobuf-3.8.0,安装方法如下

wget https://github.com/protocolbuffers/protobuf/releases/download/v3.8.0/protobuf-all-3.8.0.tar.gz
tar xvf protobuf-all-3.8.0.tar.gz
cd protobuf-3.8.0
./autogen.sh
./configure
make
sudo make install

安装cuda和cuDNN

我们选择目前主流的cuda 10.1cudnn 7.6.5,可以参考文章 ubuntu安装CUDA

tensorflow版本

本文选择目前最新的正式版2.2.0,可以直接到官网下载压缩包并解压,地址: https://github.com/tensorflow/tensorflow/releases/tag/v2.2.0

tar xvf tensorflow-2.2.0.tar.gz

安装bazel

bazel是谷歌推出的一套工程构建系统,它的版本选择直接影响到tensorflow的源码编译,我们可以通过查看tensorflow源码目录下的文件configure.py,找到下面的语句

_TF_MIN_BAZEL_VERSION = '2.0.0'
_TF_MAX_BAZEL_VERSION = '2.0.0'

可以看到tensorflow 2.2.0版本要求的bazel版本号是2.0.0。我们直接来到bazel的站点下载2.0.0,地址是: https://github.com/bazelbuild/bazel/releases,这里下载的文件是二进制文件是bazel-2.0.0-linux-x86_64,然后执行

sudo mv bazel-2.0.0-linux-x86_64 /usr/bin/bazel
sudo chmod a+x /usr/bin/bazel

安装必要的软件包

这些工具也是在编译tensorflow中需要用到的

pip install numpy six keras_preprocessing

GCC版本

ubuntu 18.04默认使用的gcc版本号是7.5.0,这里编译过程中没有出现问题。如果出现相关问题,可以考虑给gcc降版本,因为官方并没有在这个版本上测试过

sudo apt install gcc-6 g++-6

然后进行版本切换

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

如果想切换回gcc-7的话,使用类似的命令,增大最后一个参数即优先级,如101

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 101
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/gcc-7 101

编译过程

首先进行项目配置,执行configure

cd tensorflow-2.2.0
./configure

这时候终端会出现一系列的选项,这里需要根据你的需要进行选择,本文的配置是这样的

tensorflow-gpu

tensorflow-gpu

接下来就执行编译的命令

bazel build --verbose-failures --config=opt --config=cuda //tensorflow/tools/pip_package:build_pip_package

如果需要编译c++开发中需要的动态链接库,需要使用下面的命令

bazel build --verbose-failures --noincompatible_do_not_split_linking_cmdline --config=opt --config=cuda //tensorflow:libtensorflow_cc.so  //tensorflow:install_headers

或者将两个target写在一起也是可以的

bazel build --verbose-failures --noincompatible_do_not_split_linking_cmdline --config=opt --config=cuda //tensorflow:libtensorflow_cc.so //tensorflow/tools/pip_package:build_pip_package

常见的外部库链接错误

tensorflow-gpu

tensorflow-gpu

可以通过使用参数--noincompatible_do_not_split_linking_cmdline来解决,具体的可以参考这个issue https://github.com/tensorflow/tensorflow/issues/35623

整个编译时间依赖于你的机器配置

测试发现,同样的编译命令在16G的机器上运行时,会出现系统崩溃的情况,原因是out of memory,在32G内存的机器上没有问题。我们可以通过调整bazel的以下参数来完成编译

  • --local_ram_resources 使用RAM的大小,单位是MB
  • --local_cpu_resources 使用CPU的核数
  • --jobs 并发数

tensorflow-gpu

最后,我们去生成python安装需要的whl文件

sudo ./tensorflow/tools/pip_package/build_pip_package.sh /tmp/tensorflow_pkg

tensorflow-gpu

这里的/tmp/tensorflow_pkg是用于存放whl文件的地方,你可以任意指定,成功生成后,我们来安装

pip install /tmp/tensorflow_pkg/tensorflow-2.2.0-cp37-cp37m-linux_x86_64.whl

tensorflow-gpu

python验证

我们打开ipython,这里注意不要在tensorflow源码目录下打开ipython,否则会报错,添加简单的tensorflow测试代码,看看会不会报错以及相应的输出信息

import tensorflow as tf

tf.__version__
tf.test.is_gpu_available()

tensorflow-gpu

由上图可知,安装的版本号是2.2.0,且gpu也可以正常被使用

c++验证

libtensorflow_cctarget编译成功后,在bazel-bin/tensorflow目录下会生成相应的头文件(include)和动态链接库(libtensorflow_cc.solibtensorflow_framework.so.2,这两个都是软链接文件)

tensorflow-gpu

使用clion集成开发工具创建基于cmake的工程,编写源码文件main.cpp,这个实例来自网络

#include <iostream>
#include "tensorflow/cc/client/client_session.h"
#include "tensorflow/cc/ops/standard_ops.h"
#include "tensorflow/core/framework/tensor.h"

using namespace tensorflow;
using namespace tensorflow::ops;

int main()
{
    Scope root = Scope::NewRootScope();

    // Matrix A = [3 2; -1 0]
    auto A = Const(root, { {3.f, 2.f}, {-1.f, 0.f} });
    // Vector b = [3 5]
    auto b = Const(root, { {3.f, 5.f} });
    // v = Ab^T
    auto v = MatMul(root.WithOpName("v"), A, b, MatMul::TransposeB(true));

    std::vector<Tensor> outputs;
    ClientSession session(root);

    // Run and fetch v
    TF_CHECK_OK(session.Run({v}, &outputs));
    std::cout << "tensorflow session run ok" << std::endl;
    // Expect outputs[0] == [19; -3]
    std::cout << outputs[0].matrix<float>();

    return 0;
}

接下来编写规则CMakeLists.txt

project(libtf)
cmake_minimum_required(VERSION 3.0)

add_definitions(-std=c++11)

set(TENSORFLOW_ROOT_DIR /home/xugaoxiang/Downloads/tensorflow-2.2.0-cc)

include_directories(
        ${TENSORFLOW_ROOT_DIR}/bazel-bin/tensorflow/include
)

aux_source_directory(./ DIR_SRCS)

link_directories(/home/xugaoxiang/Downloads/tensorflow-2.2.0-cc/bazel-bin/tensorflow)

add_executable(libtf ${DIR_SRCS})
#target_link_libraries(libtf
#        tensorflow_cc
#        tensorflow_framework
#        )

target_link_libraries(libtf /home/xugaoxiang/Downloads/tensorflow-2.2.0-cc/bazel-bin/tensorflow/libtensorflow_cc.so /home/xugaoxiang/Downloads/tensorflow-2.2.0-cc/bazel-bin/tensorflow/libtensorflow_framework.so.2)

这里需要注意,两个库的名字是不一样的,这里直接些写上了绝对路径,然后编译运行

mkdir build
cd build
cmake ..
make
./libtf

执行结果如下

(base) xugaoxiang@1070Ti:~/CLionProjects/libtf/build$ ./libtf 
2020-05-22 16:30:25.469170: I tensorflow/core/platform/profile_utils/cpu_utils.cc:102] CPU Frequency: 3092885000 Hz
2020-05-22 16:30:25.469647: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x560f48a29630 initialized for platform Host (this does not guarantee that XLA will be used). Devices:
2020-05-22 16:30:25.469694: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Host, Default Version
2020-05-22 16:30:25.473522: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcuda.so.1
2020-05-22 16:30:25.613992: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x560f48988550 initialized for platform CUDA (this does not guarantee that XLA will be used). Devices:
2020-05-22 16:30:25.614051: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): GeForce GTX 1070 Ti, Compute Capability 6.1
2020-05-22 16:30:25.615325: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1561] Found device 0 with properties: 
pciBusID: 0000:03:00.0 name: GeForce GTX 1070 Ti computeCapability: 6.1
coreClock: 1.683GHz coreCount: 19 deviceMemorySize: 7.93GiB deviceMemoryBandwidth: 238.66GiB/s
2020-05-22 16:30:25.615715: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcudart.so.10.1
2020-05-22 16:30:25.619174: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcublas.so.10
2020-05-22 16:30:25.621307: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcufft.so.10
2020-05-22 16:30:25.621587: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcurand.so.10
2020-05-22 16:30:25.623604: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcusolver.so.10
2020-05-22 16:30:25.625051: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcusparse.so.10
2020-05-22 16:30:25.629452: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcudnn.so.7
2020-05-22 16:30:25.630598: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1703] Adding visible gpu devices: 0
2020-05-22 16:30:25.630633: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcudart.so.10.1
2020-05-22 16:30:25.631317: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1102] Device interconnect StreamExecutor with strength 1 edge matrix:
2020-05-22 16:30:25.631335: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1108]      0 
2020-05-22 16:30:25.631342: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1121] 0:   N 
2020-05-22 16:30:25.632489: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1247] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 6477 MB memory) -> physical GPU (device: 0, name: GeForce GTX 1070 Ti, pci bus id: 0000:03:00.0, compute capability: 6.1)
tensorflow session run ok
19

注意到gpu被正确识别且使用,达到了预期,完美

常见错误

官方给出了一个常见错误列表及相应的解决方法,这点太赞了,所以,在编译过程中碰到问题,可以第一时间到这里看看,地址是: https://www.tensorflow.org/install/errors

下载链接

打包好了动态链接库和头文件,有需要的话,去下载

CSDN链接

参考资料

喜欢 (3)

您必须 登录 才能发表评论!

Ads Blocker Image Powered by Code Help Pro

Ads Blocker Detected!!!

请关闭 Adblock 等类似浏览器插件,然后刷新页面访问,感谢您的支持!

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.