从源码build Tensorflow2.6.5的记录

作者详细记录了从源码编译Tensorflow2.6.5的经历,包括前期准备、资料汇总、配置流程、踩过的坑以及启示,强调了在docker环境下配置和版本匹配的重要性。
摘要由CSDN通过智能技术生成

2024.04从源码编译 Tensorflow2.6.5踩坑记录

笔者花了一整天时间,失败4次之后成功

Tensorflow2.6.5是 截止2024.04时,所能从源码编译的最新版本

0 - 前期准备

笔者为爆改Tensorflow,完成科研工作故有从源码编译 Tensorflow的需求;平时更常用的做法是在conda环境中pip install tensorflow,有时为了环境隔离方便打包,会用docker先套住,再上conda + pip安装

  • 个人之前更熟悉的框架是PyTorch,经过往后的尝试更证明了Torch的稳定性和易用性确实强于 TF,本次解决问题的思路也是来自于Torch
  • 实验硬件:CPU Intel 11th-i7 ,GPU Nivida 3090(24GB),内存 32GB DDR4 + 2TB,宿主系统为ubuntu20.04
  • 在宿主上 装了tmux以应对长时间运行的程序,免得程序没跑完了但终端挂了

1 - 资料汇总

教程参考:

另注:bazel的编译 可以使用换源清华镜像(不是必要)
整体配置流程的根本依据还是官方的教程,但它的教程有些点和坑没有涉及到,所以多方材料了解

2 - 整体流程

2.1 确定配置目标

官网上给到了配置目标,和对应的版本匹配关系(这张表里缺少了对numpy的版本要求)
笔者最后(在docker中)配置成功的版本为tensorflow2.6.5 numpy1.19.5 Python3.7.13 GCC7.5.0 CUDA11.3 Bazel3.7.2

2.2 开始配置

为了打包方便和编译环境隔离,在docker中进行了以下配置

  1. 首先拉一个合适(cuda版本与显卡匹配、内部工具相对齐全)的镜像下来
#选择了PyTorch的镜像,镜像中就包含了cuda、cudnn、gcc
docker pull pytorch/pytorch:1.12.1-cuda11.3-cudnn8-devel

#开一个容器,把文件挂载上来以保存修改; 注意这个挂载路需要换成你的
docker run --gpus all --name tf2.6_build -itd -v /home/tensorflow:/tensorflow pytorch/pytorch:1.12.1-cuda11.3-cudnn8-devel /bin/bash

#进入容器
docker exec -it tf2.6_build /bin/bash
  1. 安装 TensorFlow pip 软件包依赖项,其编译过程依赖于这些包
#注意这里的numpy版本是个坑,后续踩坑记录具体说明;此处numpy最好指定合理的版本 如笔者为pip install numpy==1.19.5
pip install -U --user pip numpy wheel
pip install -U --user keras_preprocessing --no-deps
  1. Git Tensorflow源代码包
#Git下来Tensorflow的源代码,这个文件比较大,如果git不成功也可以直接下载zip包下来然后解压
git clone https://github.com/tensorflow/tensorflow.git

#进入到clone下来的目录,然后切换分支到对应的版本下,笔者的目标本版本为2.6
cd tensorflow
git checkout r2.6
  1. 安装编译工具 Bazel

官网的介绍:(1)您需要安装 Bazel,才能构建 TensorFlow。您可以使用 Bazelisk 轻松安装 Bazel,并且 Bazelisk 可以自动为 TensorFlow 下载合适的 Bazel 版本。为便于使用,请在 PATH 中将 Bazelisk 添加为 bazel 可执行文件。(2)如果没有 Bazelisk,您可以手动安装 Bazel。请务必安装受支持的 Bazel 版本,可以是 tensorflow/configure.py 中指定的介于 _TF_MIN_BAZEL_VERSION_TF_MAX_BAZEL_VERSION 之间的任意版本。

但笔者尝试最快的安装方式是,到Github - bazelbuild/build/releases上下载对应的版本,然后使用sh脚本手动安装

比如依据刚才的配置目标,笔者需要的是 Bazel3.7.2,所以下载的文件为 bazel-3.7.2-installer-linux-x86_64.sh

# 到对应的路径下并执行
./bazel-3.7.2-installer-linux-x86_64.sh --prefix=/usr/local

#检查版本是否正确 确定是否装上bazel
#注意:在这里如果没有git checkout r2.6 则会告诉你bazel版本不对
bazel version 
  1. 配置编译build选项

官网介绍:通过运行 TensorFlow 源代码树根目录下的 ./configure 配置系统 build。此脚本会提示您指定 TensorFlow 依赖项的位置,并要求指定其他构建配置选项(例如,编译器标记)

./configure

这一步就是选择 y/N 基本没啥问题,其他参考里都有贴实例。笔者需要GPU的支持,故在CUDA那一栏选择了y,其他部分如Rocm部分就是N(直接按enter也可以)

  1. 开始编译
# 编译需要:创建一个空的文件夹
mkdir ~/tmp
export TMP=~/tmp

#在tensorflow/目录下 开始正式编译 --- 时间会比较长(大约1小时)
#根据输出信息,编译过程包含了各种compile与link
bazel build --config=cuda //tensorflow/tools/pip_package:build_pip_package 

#编译完了安装
./bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
#进去看看是啥版本tag,依据此来安装  tensorflow-version-tags.whl
cd /tmp/tensorflow_pkg
#对于我来说是tensorflow-2.6.5;注意这个tag包含了python版本
pip install /tmp/tensorflow_pkg/tensorflow-2.6.5-cp37-cp37m-linux_x86_64.whl

编译完成应输出

7.检查TF是否能用

还可以用下面的程序检查一下

import tensorflow as tf 

# 检查TensorFlow是否可以使用GPU/CUDA 
if len(tf.config.list_physical_devices('GPU')) > 0:    
  print("TensorFlow can use the GPU.") 
else:    
  print("TensorFlow cannot use the GPU.") 

# 输出TensorFlow版本 
print("TensorFlow version:", tf.__version__)

3 - 踩坑记录

3.1 cuda11.0在编译时不支持sm_86

笔者最初选择的 docker是cuda11.0的,在bazel build --config=cuda //tensorflow/tools/pip_package:build_pip_package 过程中出现了错误。所以之后选择了上面提到的cuda11.3的docker

  • 查询 https://en.wikipedia.org/wiki/CUDA#GPUs_supported 得知, sm_86的显卡(30系)并不支持11.0;

  • 并不是说nvcc 11.0的程序在30系的显卡上就不能跑,但在此处的编译就是有问题,至少笔者的问题出在了这里

  • 所以逐渐理解了为啥CUDA11.X出了这么多的版本,其兼容关系几何

3.2 问题2: numpy、TF、python版本匹配

  • tensorflow2.6.5 必须要求 numpy~=1.19.2 ,也就是必须是``numpy==1.19.X`系列 + 以上错误是在编译成功后,安装tensorflow时输出的,由于我此时的python3.9.X,所以装不上它所需要的numpy版本

  • numpy1.19.2python3.9.5不匹配 , 匹配关系列表

    • 由于这个docker中编译的东西比较多,不愿放弃 — 所以切python版本

    • 但切换python版本以后发现pip也需要切,而且tensorflow的编译结果 是带有python版本的tag的,所以编译完了切python版本是不可取的。在一开始就匹配好numpy与python版本再来编译才是正解。

  • import tensorflow时,numpy不正确。

    • 在编译tensorflow的时候 是需要用到numpy的,然而在编译时numpy(1.21.X)的版本和我此时,即import时的numpy版本(1.19.5)不匹配;
    • 注意这里 API version 0xe 与 0xd这两个十六进制数,和对应的版本数值(1.19.X或1.21.X)没有关系,但能告诉你当前的numpy与编译tensorflow时的版本相比是高了还是低了,比如我这里 e > d e > d e>d 显然就是现在的版本低了。

4 - 启示

配置环境还是要在docker的环境下进行,以方便环境打包和隔离,同时涉及到编译的环境,往往需要比较纯净,docker就是很好的选择。而且环境“脏了“,直接重开docker也免去了各种卸载刷新环境的的问题。conda的隔离效果还是不够强,一些编译选项、GCC版本、CUDA版本这些是全局的,切换了以后别的环境又被破坏了。

配置环境的参考材料,以官网材料为准,但也需要多方了解,官网材料对于一些坑没有涉及到(比如numpy与python的版本匹配问题)。看一些配置全流程的帖子了解个大概,上手配置后出了问题在具体查问题的点就行。

CUDA、python、GCC、numpy、Tensorflow的版本匹配关系很拧巴:

  • 太低的GCC装不了高cuda,太高的GCC不支持numpy
  • 太低的CUDA 可能显卡不支持,太高的CUDA可能不兼容框架
  • python和numpy版本是有对应关系的,python太高装不了低版本numpy
  • numpy与tensorflow版本几乎是一一对应,高numpy可以编译tensorflow但无法正常import使用
  • 最佳方案:提前匹配好CUDA、python、GCC、numpy、Tensorflow的关系,然后再开始编译
  • 28
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值