不惧编译error,编译Tensorflow源码(二)

简介: 编译tensorflow遇到的bug本来就多,在Windows平台上bugs更是加大力度。明明官方教程中在配置完环境后只需执行两行bazel命令,第一行命令却产生不少error。笔者踩了不少坑后,总结出了一些解决方法形成此教程。

3.开始编译

完成了上面的内容后,下面才真正开始编译源码。第三节只讲编译操作,编译错误的处理在第四节。

3.1 项目编译配置

命令行定位到/tensorflow-1.14.0-rc0/,执行

  1. python configure.py

这个脚本会询问诸如使用哪个路径下的Python、是否要支持cuda、用哪个版本的cuda、是否要支持xla等,读者可根据需要做配置。脚本正常运行后,目录中生成.tf_configure.bazelrc文件,保存了刚才的配置,比如这样:

build --action_env PYTHON_BIN_PATH="D:/Python/Anaconda3/python.exe"
build --action_env PYTHON_LIB_PATH="D:/Python/Anaconda3/lib/site-packages"
build --python_path="D:/Python/Anaconda3/python.exe"
build:xla --define with_xla_support=true
build --action_env TF_NEED_OPENCL_SYCL="0"
build --action_env TF_NEED_ROCM="0"
build --action_env TF_NEED_CUDA="1"
build --action_env TF_NEED_TENSORRT="0"
build --action_env CUDA_TOOLKIT_PATH="C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v9.0"
build --action_env TF_CUDA_COMPUTE_CAPABILITIES="3.5,7.0"
build --action_env TF_CUDA_CLANG="0"
build --config=cuda
build:opt --copt=/arch:AVX
build:opt --define with_default_optimizations=true
build --config monolithic
build --copt=-w --host_copt=-w
build --copt=-DWIN32_LEAN_AND_MEAN --host_copt=-DWIN32_LEAN_AND_MEAN --copt=-DNOGDI --host_copt=-DNOGDI
build --verbose_failures
build --distinct_host_configuration=false
build:v2 --define=tf_api_version=2
test --flaky_test_attempts=3
test --test_size_filters=small,medium
test --test_tag_filters=-benchmark-test,-no_oss,-oss_serial
test --build_tag_filters=-benchmark-test,-no_oss
test --test_tag_filters=-no_windows,-gpu
test --build_tag_filters=-no_windows,-gpu
build --action_env TF_CONFIGURE_IOS="0"

3.2 编译whl安装包生成器

在生成tensorflow-python的whl安装包之前,首先要编译其生成器。使用下面的命令:

  • CPU版本tensorflow
  1. bazel build --config=opt --output_user_root=f:mpazel //tensorflow/tools/pip_package:build_pip_package
  • GPU版本tensorflow
  1. bazel build --config=opt --config=cuda --output_user_root=f:mpazel --define=no_tensorflow_py_deps=true//tensorflow/tools/pip_package:build_pip_package

编译时,CPU和内存占用可能达到100%,注意电脑散热。此外,如果RAM少于16GB,编译时Win10的UI可能直接卡主,可以在build命令添加--local_ram_resources=2048限制内存使用。而根据CPU主频越高和核数越多,编译耗时越短,笔者的笔记本(i7@2.6Ghz x4)花了十几个小时......   编译完成后,在tensorflow-1.14.0-rc0/bazel-bin/tensorflow/tools/pip_package中,可以找到build_pip_package.exe,它就是用来生成whl安装包的工具。

3.3 生成whl安装包并安装和试用

利用千辛万苦得到的build_pip_package.exe生成安装包:

  1. bazel-binensorflowoolspip_packageuild_pip_package f:/tmp/tensorflow_pkg

安装tensorflow-python:

  1. pip3 install f:/tmp/tensorflow_pkg/tensorflow-1.14.0rc0-cp35-cp35m-win_amd64.whl

成功安装后,怀着激动的心情,做个乘法哈哈

C:Usersme>ipython
Python 3.5.2 |Anaconda custom (64-bit)| (default, Jul  5 2016, 11:41:13) [MSC v.1900 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import tensorflow as tf
In [2]: sess = tf.InteractiveSession()
In [3]: a = tf.ones([10000,10000])
In [4]: b = 2*tf.ones([10000,10000])
In [5]: c = a*b
In [6]: c.eval()
Out[6]:
array([[2., 2., 2., ..., 2., 2., 2.],
       [2., 2., 2., ..., 2., 2., 2.],
       [2., 2., 2., ..., 2., 2., 2.],
       ...,
       [2., 2., 2., ..., 2., 2., 2.],
       [2., 2., 2., ..., 2., 2., 2.],
       [2., 2., 2., ..., 2., 2., 2.]], dtype=float32)

4. 解决各种可能的编译错误

然而实际上编译过程并不是两句cmd命令就可以完成的orz。不知道为什么谷歌一个大公司,把编译搞得这么痛苦。下面是一位暴躁老哥在github issue的吐槽,他用了“What a pain in the ass.”

61.jpg


如果遇到的问题本文找不到,可以到官网找找解决思路Build and install error messages(https://tensorflow.google.cn/install/errors)

4.1 error回顾

虽然中断编译,只要不bazel clean,都不会编译from scratch,但是依然有些文件重新编译,非常耗时。笔者花了三天,断断续续才编译完,有个别算子不知为何编译时间需要两三个小时以上。相比于CPU版本的编译,GPU版本的error多了不少。但是为了速度,当然要编译GPU版本啦。查看报错时,有两点要注意:

1) 如果error信息中出现中文乱码,需要设置cmd的编码;

2) 如果出现(??????),再运行一次编译命令,可能看到(Permisson Denied),此时重启计算机可继续编译。

4.1.1 error C2118: 负下标

笔者编译时遇到的第一个error来自azel-tensorflow-1.14.0-rc0externalgrpcsrccoresialtshandshakerhandshaker.pb.c(118):error C2118:负下标不论如何,先打开问题文件看看:

C:Usersme>ipython
Python 3.5.2 |Anaconda custom (64-bit)| (default, Jul  5 2016, 11:41:13) [MSC v.1900 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import tensorflow as tf
In [2]: sess = tf.InteractiveSession()
In [3]: a = tf.ones([10000,10000])
In [4]: b = 2*tf.ones([10000,10000])
In [5]: c = a*b
In [6]: c.eval()
Out[6]:
array([[2., 2., 2., ..., 2., 2., 2.],
       [2., 2., 2., ..., 2., 2., 2.],
       [2., 2., 2., ..., 2., 2., 2.],
       ...,
       [2., 2., 2., ..., 2., 2., 2.],
       [2., 2., 2., ..., 2., 2., 2.],
       [2., 2., 2., ..., 2., 2., 2.]], dtype=float32)

看到这么长一个assert,着实吓了一跳。还好谷歌在注释里说了此处出现error,这需要定义PB_FIELD_16BIT以处理数值超过八位的问题,那么负下标也就可以理解了。那么我们只需按照注释说的,在handshaker.pb.h定义PB_FIELD_16BIT即可:

  1. #define PB_FIELD_16BIT 65536

4.1.2 找不到area.h

估苟了一下,发现是缺少c-ares库( https://c-ares.haxx.se ),下载解压,把

  1. ares.h、ares_build.h、are_rules.h、ares_version.h

添加到MSVC的包含目录里C:ProgramFiles(x86)MicrosoftVisualStudio14.0VCinclude,然后继续编译。

4.1.3 LNK2019

仔细观察所有出链接错误的函数名末尾都有_ares,推测是缺少c-ares的DLL。上一个问题里我们仅仅添加了头文件,因此最后链接时找不到库。我们需要自己安装这个库。根据该库的README.msvc,我们需要打开命令行定位到C:ProgramFiles(x86)MicrosoftVisualStudio14.0VCin利用文件夹中的nmake编译c-ares源码,假设c-ares路径为f:c-ares,执行以下命令:

  1. nmake -f f:c-aresMakefile.msvc

编译完成的动态链接库及三个例程在f:c-aresmsvc中,我们只需要msvccaresdll-release里的库。在我讲库文件加入到MSVC的目录中后,依然报错。在查看了Bazel文档后发现可以在BUILD中,利用上文第二节提到的cc_import()手动导入库。我们先将c-ares库拷贝到tensorflow-1.14.0-rc0ensorflowpython,接着在tensorflowpythonBUILD的4588行,tf_py_wrap_cc前手动导入cares库:

cc_import(
    name = "mycares",
    hdrs = ["myares/ares.h"],
    interface_library = "myares/msvc/cares/dll-release/cares.lib",
    shared_library = "myares/msvc/cares/dll-release/cares.dll",
)

再次编译不再出现LNK2019,然后迎接新error。

4.1.4 找不到cudart64_.dll

很明显这是cuda库的dll,奇怪的是cudart64_.dll末尾的下划线,一般来说下划线之后都会接上版本号之类的符号。笔者用的是cuda9.0,那么本应该是cudart64_90.dll,故猜测是没有给Bazel指定cuda版本。一番估苟之后,看到一位老哥说给Bazel两个flag指定cuda和cudnn。在3.1节里提到的.tf_configure.bazelrc文件里保存了编译配置,将两个flag加进去:

#tensorflow-1.14.0-rc0/.tf_configure.bazelrc
......
build --action_env TF_CUDNN_VERSION=7
build --action_env TF_CUDA_VERSION=9.0

继续编译不再找不到,然后迎接新error。

4.1.5 DLL load failed: 找不到指定的模块

这次同样是找不到库,但是没有说是那个库[汗]。仔细观察Traceback:

ImportError: Traceback (most recent call last):
  File "?C:UsersstyzcAppDataLocalTempBazel.runfiles_t3w1g11q
unfilesorg_tensorflowensorflowpythonpywrap_tensorflow.py", line 58, in <module>
    from tensorflow.python.pywrap_tensorflow_internal import *
  File "?C:UsersstyzcAppDataLocalTempBazel.runfiles_t3w1g11q
unfilesorg_tensorflowensorflowpythonpywrap_tensorflow_internal.py", line 28, in <module>
    _pywrap_tensorflow_internal = swig_import_helper()
  File "?C:UsersstyzcAppDataLocalTempBazel.runfiles_t3w1g11q
unfilesorg_tensorflowensorflowpythonpywrap_tensorflow_internal.py", line 24, in swig_import_helper
    _mod = imp.load_module('_pywrap_tensorflow_internal', fp, pathname, description)
  File "D:PythonAnaconda3libimp.py", line 242, in load_module
    return load_dynamic(name, filename, file)
  File "D:PythonAnaconda3libimp.py", line 342, in load_dynamic
    return _load(spec)
ImportError: DLL load failed: 找不到指定的模块。

发现问题来自Python脚本的import语句,加载_pywrap_tensorflow_internal库失败。一开始笔者以为是相对路径有问题导致脚本找不到库,直接把库拷贝到pywrap_tensorflow_internal.py所在文件夹和WORKSPACE文件夹,但都没有用。又尝试指定绝对路径加载也失败。尝试多次后,猜测不一定是_pywrap_tensorflow_internal库找不到,而是该库的依赖库找不到。因此笔者用DependencyWalker查看其依赖库,发现有不少缺失的库。但是,有一个库比较瞩目,它就是4.1.3里我们自己编译的c-ares库

62.jpg


这就可以理解了,之前我们只在BUILD中指定了绝对路径导入了该库,而现在Python脚本从环境变量里的路径是找不到该库的。因此手动将cares.dll拷贝到其中一个环境变量路径里,比如c:Windows,等待了几分钟之后,编译完成。再安装3.3的步骤就就可以安装tensorlfow-python了。


相关实践学习
基于阿里云DeepGPU实例,用AI画唯美国风少女
本实验基于阿里云DeepGPU实例,使用aiacctorch加速stable-diffusion-webui,用AI画唯美国风少女,可提升性能至高至原性能的2.6倍。
相关文章
|
9月前
|
机器学习/深度学习 TensorFlow 算法框架/工具
InceptionNet10详细原理(含tensorflow版源码)
InceptionNet10详细原理(含tensorflow版源码)
68 0
InceptionNet10详细原理(含tensorflow版源码)
|
5月前
|
文字识别 算法 TensorFlow
【Keras+计算机视觉+Tensorflow】OCR文字识别实战(附源码和数据集 超详细必看)
【Keras+计算机视觉+Tensorflow】OCR文字识别实战(附源码和数据集 超详细必看)
61 2
|
9月前
|
机器学习/深度学习 算法 TensorFlow
Darknet19详细原理(含tensorflow版源码)
Darknet19详细原理(含tensorflow版源码)—— 猫狗分类
97 0
Darknet19详细原理(含tensorflow版源码)
|
9月前
|
机器学习/深度学习 TensorFlow 算法框架/工具
ResNet18详细原理(含tensorflow版源码)
ResNet18详细原理(含tensorflow版源码)
296 0
ResNet18详细原理(含tensorflow版源码)
|
9月前
|
机器学习/深度学习 TensorFlow 算法框架/工具
VGG16详细原理(含tensorflow版源码)
VGG16详细原理(含tensorflow版源码)
140 0
VGG16详细原理(含tensorflow版源码)
|
9月前
|
机器学习/深度学习 TensorFlow 算法框架/工具
AlexNet8详细原理(含tensorflow版源码)
AlexNet8详细原理(含tensorflow版源码)
61 0
AlexNet8详细原理(含tensorflow版源码)
|
9月前
|
机器学习/深度学习 算法 TensorFlow
LeNet5详细原理(含tensorflow版源码)
LeNet5详细原理(含tensorflow版源码)
116 0
LeNet5详细原理(含tensorflow版源码)
|
12月前
|
前端开发 TensorFlow 算法框架/工具
编译 TensorFlow 模型
编译 TensorFlow 模型
|
Java TensorFlow 算法框架/工具
Tensorflow Lite移动平台编译|Bazel实践
如果不做定制化操作,我们不需要自己编译TensorFlow Lite Android库。我们可以直接使用位于MavenCentral的TensorFlow Lite AAR。但是在某些情况下,我们需要本地编译TensorFlow Lite。例如,您可能正在构建一个包含operations selected from TensorFlow的自定义二进制文件,或者需要对TensorFlow Lite进行局部修改。
321 0
|
编译器 Linux TensorFlow
不惧编译error,编译Tensorflow源码(三)
编译tensorflow遇到的bug本来就多,在Windows平台上bugs更是加大力度。明明官方教程中在配置完环境后只需执行两行bazel命令,第一行命令却产生不少error。笔者踩了不少坑后,总结出了一些解决方法形成此教程。

热门文章

最新文章