Windows 环境TensorFlow源码C++编译———实战与避坑记(1)

TensorFlow训练模型时,基本都是在Python环境下完成。生成环境中通常会使用其他语言开发应用程序,来完成对训练好的模型的调用。这时,就需要用到tensorflow的动态库文件。Tensorflow的官方并没有提供编译好的动态库文件,只是给出了如何进行编译的方法指导。实际编译过程中,会遇到很多问题,作者在参考其他编译教程,结合自己的实战经验,总结撰写本教程,希望能为需要的同仁提供些许帮助。

主要参考:

https://www.tensorflow.org/install/source_windows官网配置指南

Installing Bazel on Windows - Bazel main

Windows 下 tensorflow2.3 c++ 编译 - 知乎

1. Windows 编译环境配置

安装以下构建工具以配置 Windows 编译环境。

1.1.      安装 Python 和 TensorFlow 软件包依赖项

1.1.1.         安装Python

安装适用于 Windows 的 Python 3.6.x 64 位版本(以上的版本)。选择 pip 作为可选功能,并将其添加到 %PATH% 环境变量中。

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第1张图片

注意:python的安装路径不能有空格,否则在bazel build时会报如下错误:

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第2张图片

python安装在没有空格路径下(比如: C:\Python\Python38)并将安装路径配置到系统环境变量path中。

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第3张图片

1.1.2.         安装Tensorflow pip软件依赖包

安装 TensorFlow pip 软件包依赖项:

pip3 install six numpy wheel
pip3 install keras_applications==1.0.6 --no-deps
pip3 install keras_preprocessing==1.0.5 --no-deps

 

上图说明six,numpy,wheel已经安装过了。可通过pip uninstall先卸载已经安装的软件,并按照要求重新安装指定版本软件。

pip3 install six~=1.15.0 numpy~=1.19.2 wheel~=0.35

 

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第4张图片

pip3 install keras_applications~=1.0.8 --no-deps 

pip3 install keras_preprocessing~=1.1.2 --no-deps 

说明:通过pip3 install keras_applications安装的版本最新只有1.0.8。 

这些依赖项就列在 setup.py 文件tensorflow/setup.py at master · tensorflow/tensorflow · GitHub

)的 REQUIRED_PACKAGES 下。

本教程针对TensorFlow2.5版本进行编译,请参考:

tensorflow/setup.py at r2.5 · tensorflow/tensorflow · GitHub

REQUIRED_PACKAGES = [

    # NOTE:As numpy has releases that break semver guaranteesand several other

        # deps depend on numpy without an upper bound, we must install numpy before

        # everything else.

        'numpy ~= 1.19.2',

        # Install other dependencies

        'absl-py ~= 0.10',

        'astunparse ~= 1.6.3',

        'flatbuffers ~= 1.12.0',

        'google_pasta ~= 0.2',

        'h5py ~= 3.1.0',

        'keras_preprocessing ~= 1.1.2',

        'opt_einsum ~= 3.3.0',

        'protobuf >= 3.9.2',

        'six ~= 1.15.0',

        'termcolor ~= 1.1.0',

        'typing_extensions ~= 3.7.4',

        'wheel ~= 0.35',

        'wrapt ~= 1.12.1',

        # These packages need to be pinned exactly as newer versions are

        # incompatible with the rest of the ecosystem

        'gast == 0.4.0',

        # TensorFlow ecosystem packages that TF exposes API for

        # These need to be in sync with the existing TF version

        # They are updated during the release process

        # When updating these, please also update the nightly versions below

        'tensorboard ~= 2.5',

        'tensorflow-estimator >= 2.5.0 , < 2.6.0',

        # TODO(scottzhu) : OSS keras hasn't been formally released yet.

        # Use keras - nightly at the moment.

        'keras-nightly ~= 2.5.0.dev',

]

1.1.3.         【补充知识】版本号说明

版本号分为major,minor,patch。分别对应第一,二,三位。

1.2.0

major.minor.patch

~的意思是:

如果有minor,则patch可以变,minor不能变。

如果没有minor,则minor,patch可变,major不能变。

例如:

~1.2.0   ===>   1.2.0 <= x < 1.3.0

~1.3     ===>   1.3.0 <= x < 1.4.0

~2       ===>    2.0.0 <= x < 3.0.0

表示左边第一位非0的版本号不变,其他可变。

例子:

major

major非0     ^1.2.2      ===>   1.2.2 <= x < 2.0.0

minor非0     ^0.1.2      ===>   0.1.2 <= x < 0.2.0

patch非0     ^0.0.1      ===>   0.0.1 <= x < 0.0.2

但是,如果没有patch,patch会默认是0,并且可变,即使major,min都是0。

^0.0 := >=0.0.0 <0.1.0

如果minor,patch都没有,也会默认为0,并且可变,即使major也为0.

^1.x    ===>   1.0.0 <= x < 2.0.0

^0.x    ===>   0.0.0 <= x < 1.0.0

^0.0 等价于 >=0.0.0 <0.1.0

详细可查看https://cnpmjs.org/package/semver 的Tilde Ranges和Caret Ranges

1.1.4.         【补充知识】pip常用命令

pip3 list 查看已经安装的包

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第5张图片

pip3 install you-get //安装或者查看you-get的安装路径

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第6张图片

1.1.4.1.      pip命令集合

首先,我们进入cmd命令控制界面,输入pip,查看下pip的命令集合。

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第7张图片

接下来我们来整理一下pip命令

commands

原指令解释

翻译

install

Install package

安装python包

download

download package

下载python包

uninstall

Uninstall package

卸载python包

freeze

Output installed package in requirements format

按照一定格式输出安装好的包

list

List installed packages

列出安装了的python包

show

Show information about installed packages

详细展示安装了的python包的信息

check

Verify installed packages have compatible dependencies

检验安装了的python包有相互依赖性

search

Search PyPI for packages

查询python包的镜像依赖(PyPI)

wheel

Builds wheels from your requirements

建立你的需求的安装路径

hash

Compute hashes of package archives  

计算包装档案的关键字

completion     A

helper command used for command completion

一个帮助指令用作指令完成

help

     Show help for commands

显示该项指令如何使用

我们接下来详细展示几个常用的pip command使用方式:

1.1.4.2.      install

主要形式如下:

pip install   

or 

pip install -r requirements.txt        

主要使用方式如下:

1.1.4.2.1.         安装本地.whl

pip install <目录>/<文件名>

pip install --use-wheel --no-index  --find-links=wheelhous/<包名>     

例如:pip install requests-2.21.0-py2.py3-none-any.whl(注意.whl包在C:\Users\Administrator中才能安装)

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第8张图片

1.1.4.2.2.         升级包

pip install -U <包名>

或:

pip install <包名> --upgrade

  例如: pip install urllib3 –upgrade

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第9张图片

1.1.4.2.3.         升级pip

pip install -U pip  

或  

python -m pip install --upgrade pip

 

升级的时候,其实还有一个不怎么用到的选项 --upgrade-strategy,它是用来指定升级策略。它的可选项只有两个:

  • eager: 升级全部依赖包
    • only-if-need: 只有当旧版本不能适配新的父依赖包时, 才会升级

在 pip 10.0 版本之后,这个选项的默认值是 only-if-need,因此如下两种写法是一互致的:

pip install --upgrade pkg1

pip install --upgrade pkg1 --upgrade-strategy only-if-need

1.1.4.2.4.         从本地安装指定包

只从本地安装,而不从 pypi 安装。

pip install --no-index --find-links=目录 包   

例如:

pip install --no-index --find-links=C:\Users\satori\Desktop\pkgs fastapi

1.1.4.2.5.         从本地批量安装包

pip install --no-index --find-links="D:\thirdparty\tensorflow\tensorflow_pkg" -r requirement.txt

 

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第10张图片

1.1.4.2.6.         指定安装包源

pip install -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com pkg

通过 -i 指定别的源, 但由于不是https, 所以需要加上--trusted-host表示信任该网址。

1.1.4.2.7.         限制不使用二进制包安装

由于默认情况下,whl 包的平台是运行 pip download 命令的平台,所以可能出现平台不适配的情况。比如在 MacOS 系统下得到的 pymongo-2.8-cp27-none-macosx_10_10_intel.whl 就不能在 linux_x86_64 中安装,使用下面这条命令下载的是 tar.gz 的包,可以直接使用 pip install 安装。相比 whl 包,这种包在安装时会进行编译,所以花费的时间会长一些。

下载非二进制的包

pip download --no-binary=:all: pkg

安装非二进制的包

pip install pkg --no-binary

1.1.4.2.8.         指定代理服务器安装

当我们无法连接公网时,除了上面那种先将安装包下载下来之外,还可以使用代理。因为有的内网环境虽然和外界是隔离的,但两者之间的路并没有完全堵死,可以通过连接到指定的代理来建立一座桥。

pip install --proxy http[s]://[user:password@]ip:port 包名

但每次安装包就发输入长长的参数,未免有些麻烦,为此你可以将其写入配置文件中:$HOME/.config/pip/pip.conf。但是对于这个路径,不同的操作系统,路径各不相同:

# Linux/Unix:
/etc/pip.conf
~/.pip/pip.conf
~/.config/pip/pip.conf
# Mac OSX:
~/Library/Application Support/pip/pip.conf
~/.pip/pip.conf
/Library/Application Support/pip/pip.conf
# Windows:
%APPDATA%\pip\pip.ini
%HOME%\pip\pip.ini
C:\Documents and Settings\All Users\Application Data\PyPA\pip\pip.conf (Windows XP)
C:\ProgramData\PyPA\pip\pip.conf (Windows 7及以后)

若在你的机子上没有此文件,则自行创建即可:

[global]
index-url = http://mirrors.aliyun.com/pypi/simple/
# 替换出自己的代理地址,格式为 http://[user:passwd@]ip:port
proxy=http://xxx.xxx.xxx.xxx:8080
[install]
# 信任阿里云的镜像源,否则会有警告
trusted-host=mirrors.aliyun.com

1.1.4.3     uninstall

卸载安装包

pip uninstall <包名>

pip uninstall -r requirements.txt    

例如: pip uninstall requests

 

1.1.4.4.      download

pip download 包名 -d "下载后文件存储路径(windows下双引号来表示文件夹)"

例如:

pip download tensorboard(~=2.5) -d "D:\thirdparty\tensorflow\tensorflow_pkg"

 

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第11张图片

pip download会将该包以及该包的依赖包一起下载。

也可以将多个需要下载的包名称写到requirement.txt文件中,文件的一行代表一个包,例如:

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第12张图片

numpy(~=1.19.2)与numpy~=1.19.2 等效。

pip download -d "D:\thirdparty\tensorflow\tensorflow_pkg" -r requirements.txt

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第13张图片

1.1.4.5.      freeze

pip freeze,可以查看已经安装的包及版本信息

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第14张图片

导出到指定文件中,如图,注意“>”,文件名随意。第一种写法是错误的演示,第二种才能通过

 

1.1.4.6.      list

查询已经安装了的包

pip list

 

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第15张图片

查询可升级的包

pip list -o

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第16张图片

1.1.4.7.      show

显示包所在目录及信息

例如 pip show requests

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第17张图片

1.1.4.8.      search

搜索包

pip search <关键字>

例如: pip search requests就会显示如下和requests相关的安装包

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第18张图片

1.1.4.9.      打包

pip wheel <包名>

例如 pip wheel requests

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第19张图片

在以下文件夹中就能找到requests-2.21.0-py2.py3-none-any.whl文件了

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第20张图片

pip wheel --wheel-dir=目录 包名

我们可以将当前 Python 中已经存在的包打包成 whl 文件,当然除了指定包名之外,也可以换成 -r requirement.txt。

1.1.5. 【补充知识】pkginfo列出whl的依赖包

在网络不好的情况下,手动下载依赖包,需要找到所有依赖包(dependencies)。pkginfo可以找到whl所依赖包的名称以及版本号。
pkginfo -f requires_dist tensorflow-2.5.1-cp38-cp38-win_amd64.whl

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第21张图片

1.2.      安装 Bazel

1.2.1.   下载Bazel

安装 Bazel,它是用于编译 TensorFlow 的构建工具。如需确认适用的 Bazel 版本,请参阅适用于 Windows 的经过测试的构建配置。

配置 Bazel 来构建 C++。

定位到https://github.com/bazelbuild/bazel/tags找到3.7.2的下载页面:

 

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第22张图片

1.2.2.         安装Bazel

将zip解压到系统安装目录。

1.2.3.         设置环境变量PATH

将Bazel 可执行文件的位置添加到 %PATH% 环境变量中。

 

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第23张图片

1.2.4.         设置环境变量BAZEL_VC

为BAZEL配置VC的系统环境变量

 

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第24张图片

Visuale Studio 2015只能设置BAZEL_VC环境变量。

set BAZEL_VC=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC  (VS2015中只支持BAZEL_VC)

Visual Studio 2017和2019 另外还支持指定 BAZEL_VC_FULL_VERSION(VC版本)和BAZEL_WINSDK_FULL_VERSION(Windows SDK版本)。

set BAZEL_VC=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC (VS2019)

set BAZEL_VC_FULL_VERSION=14.16.27023

set BAZEL_WINSDK_FULL_VERSION=10.0.10240.0

 

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第25张图片

 

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第26张图片

当不指定BAZEL_VC_FULL_VERSION和BAZEL_WINSDK_FULL_VERSION时,BAZEL将会使用最新的版本。

1.2.5.  测试BAZEL是否配置正确

下载测试代码:

 

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第27张图片

进入下载代码的目录,执行命令:bazel build //examples/cpp:hello-world

 

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第28张图片

命令行输入:bazel version

 

1.3.      安装 MSYS2

为构建 TensorFlow 所需的 bin 工具安装 MSYS2。如果 MSYS2 已安装到D:\msys64 下,请将 D:\msys64\usr\bin 添加到 %PATH% 环境变量中。

 

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第29张图片

然后,使用 cmd.exe 运行以下命令:

pacman -S git patch unzip

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第30张图片

1.4.      安装 Visual C++ 生成工具 2019

安装 Visual C++ 生成工具 2019。该工具随附在 Visual Studio 2019 中,但可以单独安装:

  1. 转到 Visual Studio 下载页面,
  2. 选择“可再发行组件和生成工具”,
  3. 下载并安装:
  • Microsoft Visual C++ 2019 可再发行组件包
  • Microsoft 生成工具 2019

注意:TensorFlow 已针对 Visual Studio 2019 进行了测试。

1.5.      安装 GPU 支持项(可选)

若要安装在 GPU 上运行 TensorFlow 所需的驱动程序和其他软件,请参阅 Windows GPU 支持指南。

注意:CUDA安装完成后(确保匹配版本的CUDNN已经下载并解压到了CUDA的bin目录和include目录),需要将bin目录和CUPTI的lib64目录添加到系统环境变量path变量中。

 

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第31张图片

 

 

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第32张图片

当前计算机显卡算力查询:

C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\extras\demo_suite\deviceQuery.exe

 

Windows 环境TensorFlow源码C++编译———实战与避坑记(1)_第33张图片

序号

名称

解释

1

Detected 1 CUDA Capable device(s)

1

检测到1个可用的NVIDIA显卡设备

2

Device 0: "GeForce 930M"

GeForce 930M

当前显卡型号为" GeForce 930M "

3

CUDA Driver Version / Runtime Version

7.5/7.5

CUDA驱动版本

4

CUDA Capability Major/Minor version number

 

5.0

CUDA设备支持的计算架构版本,即计算能力,该值越大越好

5

Total amount of global memory

4096Mbytes

Global memory全局存储器的大小。使用CUDA RUNTIME API调用函数cudaMalloc后,会消耗GPU设备上的存储空间,合理分配和释放空间避免程序出现crash

6

(3) Multiprocessors, (128) CUDA Cores/MP

384 CUDA Cores

3个流多处理器(即SM),每个多处理器中包含128个流处理器,共384CUDA

7

GPU Max Clock rate

941 MHz

GPU最大频率

8

Memory Clock rate

900 MHz

显存的频率

9

Memory Bus Width

64-bit

 

10

L2 Cache Size

1048576 bytes

 

11

Maximum Texture Dimension Size (x, y, z)

1D=(65535)

2D=(65535, 65535)

3D=(4096,4096,4096)

 

12

Maximum Layered 1D Texture Size, (num) layers

1D=(16384),2048 layers

 

13

Maximum Layered 2D Texture Size, (num) layers

2D=(16384,16384), 2048 layers

 

14

Total amount of constant memory

65535 bytes

常量存储器的大小

15

Total amount of shared memory per block

49152 bytes

共享存储器的大小,共享存储器速度比全局存储器快;多处理器上的所有线程块可以同时共享这些存储器

16

Total number of registers available per block

65535

 

17

Warp Size

32

Warp,线程束,是SM运行的最基本单位,一个线程束含有32个线程

18

Maximum number of threads per multiprocessor

2048

一个SM中最多有2048个线程,即一个SM中可以有2048/32=64个线程束Warp

19

Maximum number of threads per block

1024

一个线程块最多可用的线程数目

20

Max dimension size of a thread block (x, y, z)

(1024,1024,64)

ThreadIdx.x<=1024,

ThreadIdx.y<=1024,

ThreadIdx.z<=64

Block内三维中各维度的最大值

21

Max dimension size of a grid size (x, y, z)

(2147483647,65535,65535)

Grid内三维中各维度的最大值

22

Maximum memory Pitch

2147483647 bytes

显存访问时对齐时的pitch的最大值

23

Texture alignment

512 bytes

纹理单元访问时对其参数的最大值

24

Concurrent copy and kernel execution

Yes with 1 copy engine(s)

 

25

Run time limit on kernels

Yes

 

26

Integrated GPU sharing Host Memory

No

 

27

Support host page-locked memory mapping

Yes

 

28

Alignment requirement for Surfaces

Yes

 

29

Device has ECC support

Disabled

 

30

其他

 

 

 (未完待续...)

你可能感兴趣的:(C++,TensorFlow,tensorflow,windows,c++,人工智能)