TensorFlow训练模型时,基本都是在Python环境下完成。生成环境中通常会使用其他语言开发应用程序,来完成对训练好的模型的调用。这时,就需要用到tensorflow的动态库文件。Tensorflow的官方并没有提供编译好的动态库文件,只是给出了如何进行编译的方法指导。实际编译过程中,会遇到很多问题,作者在参考其他编译教程,结合自己的实战经验,总结撰写本教程,希望能为需要的同仁提供些许帮助。
主要参考:
https://www.tensorflow.org/install/source_windows官网配置指南
Installing Bazel on Windows - Bazel main
Windows 下 tensorflow2.3 c++ 编译 - 知乎
安装以下构建工具以配置 Windows 编译环境。
安装适用于 Windows 的 Python 3.6.x 64 位版本(以上的版本)。选择 pip 作为可选功能,并将其添加到 %PATH%
环境变量中。
注意:python的安装路径不能有空格,否则在bazel build时会报如下错误:
python安装在没有空格路径下(比如: C:\Python\Python38)并将安装路径配置到系统环境变量path中。
安装 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
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',
]
版本号分为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
pip3 list 查看已经安装的包
pip3 install you-get //安装或者查看you-get的安装路径
1.1.4.1. pip命令集合
首先,我们进入cmd命令控制界面,输入pip,查看下pip的命令集合。
接下来我们来整理一下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中才能安装)
1.1.4.2.2. 升级包
pip install -U <包名>
或:
pip install <包名> --upgrade
例如: pip install urllib3 –upgrade
1.1.4.2.3. 升级pip
pip install -U pip
或
python -m pip install --upgrade pip
升级的时候,其实还有一个不怎么用到的选项 --upgrade-strategy,它是用来指定升级策略。它的可选项只有两个:
在 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
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"
pip download会将该包以及该包的依赖包一起下载。
也可以将多个需要下载的包名称写到requirement.txt文件中,文件的一行代表一个包,例如:
numpy(~=1.19.2)与numpy~=1.19.2 等效。
pip download -d "D:\thirdparty\tensorflow\tensorflow_pkg" -r requirements.txt
1.1.4.5. freeze
pip freeze,可以查看已经安装的包及版本信息
导出到指定文件中,如图,注意“>”,文件名随意。第一种写法是错误的演示,第二种才能通过
1.1.4.6. list
查询已经安装了的包
pip list
查询可升级的包
pip list -o
1.1.4.7. show
显示包所在目录及信息
例如 pip show requests
1.1.4.8. search
搜索包
pip search <关键字>
例如: pip search requests就会显示如下和requests相关的安装包
1.1.4.9. 打包
pip wheel <包名>
例如 pip wheel requests
在以下文件夹中就能找到requests-2.21.0-py2.py3-none-any.whl文件了
pip wheel --wheel-dir=
目录 包名
我们可以将当前 Python 中已经存在的包打包成 whl 文件,当然除了指定包名之外,也可以换成 -r requirement.txt。
在网络不好的情况下,手动下载依赖包,需要找到所有依赖包(dependencies)。pkginfo可以找到whl所依赖包的名称以及版本号。
pkginfo -f requires_dist tensorflow-2.5.1-cp38-cp38-win_amd64.whl
安装 Bazel,它是用于编译 TensorFlow 的构建工具。如需确认适用的 Bazel 版本,请参阅适用于 Windows 的经过测试的构建配置。
配置 Bazel 来构建 C++。
定位到https://github.com/bazelbuild/bazel/tags找到3.7.2的下载页面:
将zip解压到系统安装目录。
将Bazel 可执行文件的位置添加到 %PATH%
环境变量中。
为BAZEL配置VC的系统环境变量
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
当不指定BAZEL_VC_FULL_VERSION和BAZEL_WINSDK_FULL_VERSION时,BAZEL将会使用最新的版本。
下载测试代码:
进入下载代码的目录,执行命令:bazel build //examples/cpp:hello-world
命令行输入:bazel version
为构建 TensorFlow 所需的 bin 工具安装 MSYS2。如果 MSYS2 已安装到D:\msys64
下,请将 D:\msys64\usr\bin
添加到 %PATH%
环境变量中。
然后,使用 cmd.exe
运行以下命令:
pacman -S git patch unzip
安装 Visual C++ 生成工具 2019。该工具随附在 Visual Studio 2019 中,但可以单独安装:
注意:TensorFlow 已针对 Visual Studio 2019 进行了测试。
若要安装在 GPU 上运行 TensorFlow 所需的驱动程序和其他软件,请参阅 Windows GPU 支持指南。
注意:CUDA安装完成后(确保匹配版本的CUDNN已经下载并解压到了CUDA的bin目录和include目录),需要将bin目录和CUPTI的lib64目录添加到系统环境变量path变量中。
当前计算机显卡算力查询:
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\extras\demo_suite\deviceQuery.exe
序号 |
名称 |
值 |
解释 |
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个流处理器,共384个CUDA核 |
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 |
其他 |
|
|
(未完待续...)