鲲鹏社区首页
中文
注册
开发者
面向鲲鹏处理器的tensorflow2.2.0迁移编译与部署

面向鲲鹏处理器的tensorflow2.2.0迁移编译与部署

性能调优同辕开发

发表于 2025/12/05

0

1 背景

在部分行业场景中,客户侧仍依赖旧版本的 TensorFlow(如 TensorFlow 2.2.0)来支持既有的应用框架与模型开发流程。然而,这些旧版本并未对 ARM 架构提供原生支持,尤其是在面向鲲鹏处理器(Kunpeng)的部署中,直接安装往往会遇到依赖不兼容、环境配置复杂等问题。同时,随着业务需求的演进,客户希望在保持原有模型链路不变的前提下,实现对 ARM 平台的迁移,并对关键组件进行向量化与性能优化,因此需要对老版本 TensorFlow 进行重新编译、适配和端到端部署验证。

基于上述需求,我们整理并总结了一套面向鲲鹏处理器的 TensorFlow 2.2.0 编译与部署流程,涵盖环境搭建、依赖准备、源码编译、向量化优化以及最终的运行验证,可为后续迁移工作提供参考和指导。


2 安装部署流程


1. 容器创建


创建docker配置文件,保存为docker-tf-update-neon.yml:
version: '3.3'
services:
  tensorflow-docker:
    image: ubuntu:18.04
    container_name: tensorflow-docker
    restart: unless-stopped
     
    # 数据挂载
    volumes:
      - /home/user/tensorflow:/workspace/tensorflow:rw
      - /home/user/tensorflow:/data:rw
      - ./logs:/workspace/logs:rw
      - ./config:/workspace/config:rw
  
    dns:
      - 8.8.8.8      # Google Public DNS
      - 8.8.4.4      # Google Public DNS  
   
    cap_add:
      - SYS_ADMIN
      - SYS_NICE
      - NET_ADMIN
    # 环境变量
    
    environment:
      - DEBIAN_FRONTEND=noninteractive
      - TZ=Asia/Shanghai
      
    working_dir: /workspace
    network_mode: host
    
    # 无资源限制 - 可使用主机全部CPU、内存、硬盘
    # 注释掉或删除任何deploy/resources配置以获得无限制访问
    
    # 启动命令
    command: >
      bash -c "
      hostname tensorflow-docker &&
        # 创建目录
        mkdir -p /workspace/{logs,config} &&
        
        # 保持运行
        while true; do sleep 30; done
      "

执行docker

docker-compose -f ./docker-tf-update-neon.yml  up -d

解释:

  • volumes → 磁盘目录挂载(跟宿主机文件共享)。
  • cap_add → 赋予必要权限。
  • environment → 设置容器内环境变量(如免交互安装、时区等)。
  • working_dir → 指定容器启动后的工作目录。
  • network_mode: host → 与宿主机共享网络(等价于 --network=host)。
  • command → 覆盖默认启动命令,可在容器启动时执行自定义脚本或保持容器常驻运行。


2. 在容器里补全 apt 源配置


echo 'Acquire::ForceIPv4 "true";' > /etc/apt/apt.conf.d/99force-ipv4 
cat >/etc/apt/sources.list <<EOF
deb https://ports.ubuntu.com/ubuntu-ports bionic main restricted universe multiverse
deb https://ports.ubuntu.com/ubuntu-ports bionic-updates main restricted universe multiverse
deb https://ports.ubuntu.com/ubuntu-ports bionic-backports main restricted universe multiverse
deb https://ports.ubuntu.com/ubuntu-ports bionic-security main restricted universe multiverseEOF apt-get -o Acquire::Retries=5 update

(因为默认 ubuntu:18.04 镜像里可能没有合适的源,可使用华为内部的镜像源加速应用下载)

华为内部源 https://3ms.huawei.com/km/groups/2757573/blogs/details/21413179 


3. 手动安装依赖


apt-get install -y --no-install-recommends \    
                            build-essential \    
                            curl \    
                            git \    
                            python3 python3-pip python3-dev \    
                            openjdk-8-jdk \    
                            unzip zip \    
                            zlib1g-dev \    
                            swig virtualenv


4. 安装 Python 包


pip3 install --upgrade pip setuptools
pip3 install numpy scipy pandas scikit-learn matplotlib h5py Pillow keras_preprocessing


  • 下载缓慢,同理可使用华为内部PIP源
  https://3ms.huawei.com/km/blogs/details/21564858


  • 常见问题
Q: Xlocale.h not found on Linux
A: ln -s /usr/include/locale.h /usr/include/xlocale.h 

Q: error: Unable to load dependency HDF5, make sure HDF5 is installed properly
A: sudo apt install python3-h5py 

Q: Could not find the freetype library.
A: sudo apt-get install libfreetype6 libfreetype6-dev          
   还是不行,直接sudo apt-get install python-matplotlib


5. 确认 Python 3.6 环境


  • 检查 Python 版本:
python3 --version 

验证容器中的 Python3 是否为 3.6.x(Ubuntu 18.04 默认自带的是 Python 3.6)[tensorflow.org](https://www.tensorflow.org/install/source#install_python_and_the_tensorflow_package_dependencies#:~:text=sudo apt install python3)。输出应类似于 Python 3.6.9。确保使用 Python 3.6 有助于匹配 TensorFlow 2.2.0 的支持范围(TensorFlow 2.2 支持 Python 3.5–3.8)并使用与之兼容的依赖库版本。


  • 确保 PIP 版本兼容:
pip3 --version (可选)


  • 检查 PIP 已升级到最新版本(>= 19.x)以支持安装 TensorFlow 大型 wheel 文件[tensorflow.org](https://www.tensorflow.org/install/source#install_python_and_the_tensorflow_package_dependencies#:~:text=pip install )。这一步通常通过之前的升级命令已完成。


  • 检查 Python 版本:python3 --version 验证容器中的 Python3 是否为 3.6.x(Ubuntu 18.04 默认自带的是 Python 3.6)[tensorflow.org]


6. 安装构建依赖(APT 和 PIP)


  • 更新 APT 包索引:
sudo apt-get update 

更新软件源列表,以确保能够获取最新版本的软件包。这样可以安装最新的编译工具和库。


  • 安装系统依赖包:
sudo apt-get install -y --no-install-recommends build-essential openjdk-8-jdk python3-dev python3-pip git wget curl swig 

安装编译 TensorFlow 所需的一系列开发工具和库。其中,

build-essential 提供基本的编译工具链,
openjdk-8-jdk 提供 Java 环境用于运行 Bazel,
python3-dev 安装 Python3.6 的开发头文件,
python3-pip 安装 Python 包管理器 PIP,
git 用于获取源码,
wget/curl 用于下载文件,
swig 则是构建过程中需要的接口生成工具。
使用 --no-install-recommends 可以避免安装额外的推荐包。


  • 升级 PIP 和 setuptools:
python3 -m pip install --upgrade pip setuptools 

使用 Python3 自带的 PIP,将 PIP 本身和 setuptools 工具升级到较新版本。这确保 PIP 版本>=19,以便支持安装 TensorFlow 2.x 的大型 wheel 文件。同时升级 setuptools 可以避免构建过程中潜在的兼容问题。


  • 安装所需的 Python 包依赖:
pip3 install numpy six wheel future grpcio 

安装 TensorFlow 源码构建和打包过程中需要的 Python 库。

其中包含数值计算库 NumPy、兼容Python2/3的工具包 six、打包所需的 wheel 模块,以及 future 和 grpcio 等库。这些依赖满足了 TensorFlow 2.2.0 构建脚本的要求,例如 numpy>=1.16.0,<2.0、wheel>=0.26 等(Python3 环境下无需安装 futures 包)。安装 grpcio 可以避免构建分发时因缺少该依赖而报错。


7. 安装 Bazel 2.0.0(适配 ARM64)


  • 安装 Bazel 构建依赖:
apt-get updateapt-get install -y build-essential openjdk-8-jdk python3 zip unzip wget curl git

提供 gcc、JDK8、python、打包工具。


  • 下载 Bazel 2.0.0 源码:
wget https://github.com/bazelbuild/bazel/releases/download/2.0.0/bazel-2.0.0-dist.zip

官方发布会有 -dist.zip 源码包。


  • 解压:
unzip bazel-2.0.0-dist.zip -d bazel-2.0.0-distcd bazel-2.0.0-dist


  • 构建:
EXTRA_BAZEL_ARGS="--host_javabase=@local_jdk//:jdk" bash compile.sh

这个脚本会在当前目录下用本机工具链编出一个 output/bazel。


  • 安装到系统路径:
cp output/bazel /usr/local/bin/


8. 下载并检出 TensorFlow v2.2.0 源码


  • 克隆 TensorFlow 源码仓库:
git clone https://github.com/tensorflow/tensorflow.git 

使用 Git 将 TensorFlow 官方仓库源码克隆到本地。默认会克隆最新的主分支内容。


  • 进入源码目录:
cd tensorflow 

切换当前工作目录到下载的 TensorFlow 源码目录,为后续构建操作做好准备。


  • 检出指定版本标签 v2.2.0:
git checkout v2.2.0 

将源码切换到 TensorFlow 2.2.0 发布标签对应的提交。这确保我们使用确切的 v2.2.0 版本代码进行构建。成功后,可以看到 HEAD 切换到了 “v2.2.0”。(注意:也可以在 git clone 时加参数 -b v2.2.0 直接克隆指定版本。)


9. 配置构建选项并运行配置脚本运行配置脚本:


yes "" | ./configure 

启动 TensorFlow 提供的交互式配置脚本。

这里使用 yes "" 管道自动对所有提示输入空响应,以采用默认配置值。该脚本会检测系统环境并询问构建选项,例如 Python 可执行路径、Python库路径、是否启用 CUDA(GPU)支持等。

使用空响应相当于选择默认值:脚本将在默认检测到的 Python3 路径(通常是 /usr/bin/python3)上配置构建,CUDA 和其他可选特性默认不启用(CPU-only 架构下 CUDA 默认为 N)。配置完成后,会生成适当的配置文件和环境变量设置(例如确认使用 Python 3.6,禁用 CUDA)。

说明:如果未使用上述自动回答方式,人工交互时请确保选择 Python3 路径(Ubuntu 18.04 下一般输入 /usr/bin/python3,如果脚本默认不是该值)并对是否启用 CUDA、ROCM 等高级特性问题选择 N(不启用)。其他选项如是否优化CPU指令集(默认会启用适合本机的优化)可直接按回车采用默认值。这样配置出来的是针对 ARM64、纯 CPU 环境的构建配置。编译完成后 /tmp/tf_pkg 会有一个 .whl,可以拿到宿主机 pip 安装。


10. 使用 Bazel 编译 TensorFlow 源码(生成 pip 包)


  • bazel build前配置:
git config --global http.sslVerify false
export GIT_SSL_NO_VERIFY=1
export JAVA_TOOL_OPTIONS="-Dcom.sun.net.ssl.checkRevocation=false -Dcom.sun.net.ssl.trustStoreType=NONE"
bazel clean --expunge 

apt install openjdk-11-jdk -y
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-arm64keytool -importcert -trustcacerts -alias huaweicrt -file Huawei\ Web\ Secure\ Internet\ Gateway\ CA.crt -keystore 
$JAVA_HOME/lib/security/cacerts -storepass changeit


  • 调用 Bazel 编译目标:
bazel build --config=opt --config=noaws --config=monolithic //tensorflow/tools/pip_package:build_pip_package 

使用 Bazel 开始编译 TensorFlow。

这里指定了几个配置选项:

--config=opt 启用编译优化(相当于使用最优编译选项进行 Release 构建)。
--config=noaws 禁用 AWS 支持,以避免在 ARM64 环境下编译包含与 AWS 相关的代码时出现不兼容的问题(在 ARM 实例上构建时常用此选项避免引用非 ARM 平台的依赖)。
--config=monolithic 将 TensorFlow 构建为单体静态链接库,避免过多小模块以减少编译过程中可能的内存开销。

这个命令会花费较长时间来编译 TensorFlow 源码并生成用于构建 pip 安装包的二进制目标。根据设备性能,编译过程可能持续数小时。在编译过程中,Bazel 会自动并行利用多核 CPU;如果内存较少(<4GB),可考虑设置环境变量如 --local_ram_resources=<MB> 或限制并行度(例如加入参数 --local_cpu_resources=2)来避免编译因内存不足而中断。

编译成功结束时,生成的目标文件位于 Bazel 的输出目录下。


  • 如编译遇到问题:

清缓存再编(避免用到旧头文件产物):

bazel shutdown || truebazel clean --expungerm -rf /root/.cache/bazel

重新构建:

bazel build \ 
--config=opt \ 
--config=monolithic \ 
--config=noaws --config=nogcp --config=nohdfs \ 
//tensorflow/tools/pip_package:build_pip_package


11. 打包并验证 TensorFlow 安装包(.whl)


  • 安装pip wheel包:
pip3 install wheel


  • 安装依赖包:
apt-get install liblapack-dev libblas-dev gfortran


  • 打包生成 .whl 文件:
./bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg 

运行刚刚编译出的打包脚本,将 TensorFlow 构建产物打包成标准的 pip 安装包(wheel 文件)并输出到指定目录。本命令指定输出路径为 /tmp/tensorflow_pkg,脚本执行后将在该目录下生成一个以 tensorflow-2.2.0 开头的 .whl 文件。

例如,对于 Python 3.6,生成的文件名预计为:tensorflow-2.2.0-cp36-cp36m-linux_aarch64.whl(表示 TensorFlow 2.2.0 适用于 cp36 ABI 的 Linux ARM64)。您可以通过列出该目录内容来确认文件存在,例如运行 ls -l /tmp/tensorflow_pkg 查看文件大小和名称。


  • 安装生成的 TensorFlow 包:
sudo pip3 install /tmp/tensorflow_pkg/tensorflow-2.2.0-cp36-cp36m-linux_aarch64.whl 

使用 PIP 安装刚生成的 TensorFlow wheel 包(如果在非root环境下,可省略 sudo 或使用虚拟环境)。

这会将构建的 TensorFlow 2.2.0 安装到系统的 Python3 环境中。安装完成后,使用 pip3 list | grep tensorflow 可以看到 tensorflow 2.2.0 已列在已安装包中community.arm.com。


  • 验证安装成功:
python3 -c "import tensorflow as tf; print(tf.__version__)" 

导入刚安装的 TensorFlow 并打印其版本号,验证安装包可用。正常情况下,此命令应输出 2.2.0,证明我们成功构建并安装了适用于 ARM64 架构的 TensorFlow 2.2.0。

此外也可以尝试运行一个简单的 TensorFlow 运算,例如:python3 -c "import tensorflow as tf; print(tf.reduce_sum(tf.constant([1, 2, 3])).numpy())",若输出计算结果 6 则说明 TensorFlow 能正常运行计算图。


3. 疑难问题:部分难以自动安装的包安装教程


1. Numpy:


回到源码根目录:

cd /workspace

备份文件:

cp tensorflow/python/lib/core/bfloat16.cc tensorflow/python/lib/core/bfloat16.cc.bak

打补丁(把传给 register_ufunc 的函数指针显式转成 PyUFuncGenericFunction):

sed -i 's/register_ufunc("equal", CompareUFunc/register_ufunc("equal", (PyUFuncGenericFunction)CompareUFunc/' tensorflow/python/lib/core/bfloat16.cc
sed -i 's/register_ufunc("not_equal", CompareUFunc/register_ufunc("not_equal", (PyUFuncGenericFunction)CompareUFunc/' tensorflow/python/lib/core/bfloat16.cc
sed -i 's/register_ufunc("less", CompareUFunc/register_ufunc("less", (PyUFuncGenericFunction)CompareUFunc/' tensorflow/python/lib/core/bfloat16.cc
sed -i 's/register_ufunc("less_equal", CompareUFunc/register_ufunc("less_equal", (PyUFuncGenericFunction)CompareUFunc/' tensorflow/python/lib/core/bfloat16.cc
sed -i 's/register_ufunc("greater", CompareUFunc/register_ufunc("greater", (PyUFuncGenericFunction)CompareUFunc/' tensorflow/python/lib/core/bfloat16.cc
sed -i 's/register_ufunc("greater_equal", CompareUFunc/register_ufunc("greater_equal", (PyUFuncGenericFunction)CompareUFunc/' tensorflow/python/lib/core/bfloat16.cc


2. h5py


HDF5 路径在:/usr/lib/aarch64-linux-gnu/hdf5/serial(库) + /usr/include/hdf5/serial(头)

h5py 版本:2.10.0(Python 3.6 友好)

执行下述命令进行手动安装:

apt-get update
apt-get install -y --no-install-recommends libhdf5-serial-dev build-essential python3-dev pkg-config
/usr/local/bin/python -m pip install -U "pip==21.3.1" "setuptools<60" "wheel<0.38"
/usr/local/bin/python -m pip install "Cython==0.29.36" "pkgconfig==1.5.5"export HDF5_DIR=/usr/lib/aarch64-linux-gnu/hdf5/serialexport CFLAGS="-I/usr/include/hdf5/serial" LDFLAGS="-L/usr/lib/aarch64-linux-gnu/hdf5/serial"
/usr/local/bin/python -m pip install --no-cache-dir --no-build-isolation "h5py==2.10.0"
/usr/local/bin/python -c "import h5py; print(h5py.__version__); import h5py.h5 as h5; print('HDF5 lib:', h5.get_libversion())"

如果这一步能打印出 2.10.0 和一个 HDF5 版本号(如 1.10.x),说明成功。


3. OpenBLAS


遵照下述指令进行安装:


  • 装编译依赖(OpenBLAS + LAPACK + gfortran)
apt-get update
apt-get install -y --no-install-recommends libopenblas-dev liblapack-dev gfortran build-essential python3-dev pkg-config


  • 让 pip/setuptools 版本对 Py3.6 友好
/usr/local/bin/python -m pip install -U "pip==21.3.1" "setuptools<60" "wheel<0.38"


  • (可选)显式告诉构建要用 OpenBLAS写个 ~/.numpy-site.cfg,让 SciPy 的构建系统能直接找到库和头:
cat > ~/.numpy-site.cfg <<'EOF'
[openblas]
libraries = openblas
library_dirs = /usr/lib/aarch64-linux-gnu
include_dirs = /usr/include
runtime_library_dirs = /usr/lib/aarch64-linux-gnu
EOF

再加上常见环境变量(双保险):

export BLAS=/usr/lib/aarch64-linux-gnu/libopenblas.so
export LAPACK=/usr/lib/aarch64-linux-gnu/libopenblas.so
export NPY_NUM_BUILD_JOBS=$(nproc)

(如果仍报“找不到 openblas/lapack”,先确认 libopenblas-dev安装成功,然后再检查:)

python - <<'PY'
import numpy.distutils.system_info as si
print('openblas_info:', si.get_info('openblas_info'))
print('lapack_opt_info:', si.get_info('lapack_opt_info'))PY


4. SciPy


  • SciPy 1.4.1 源码编译(关键:禁用 build-isolation)

禁用 build-isolation可使其使用当前的 numpy==1.19.5、OpenBLAS 和现成的 Cython完成编译,不会被 PEP517 隔离环境拖去装奇怪的老版本。

/usr/local/bin/python -m pip install --no-cache-dir --no-binary :all: --no-build-isolation "scipy==1.4.1"

如果两行都是空 dict,再检查 /usr/lib/aarch64-linux-gnu/ 目录里是否有 libopenblas.so;

有的话大概率是 ~/.numpy-site.cfg 或环境变量没生效——重开一个 shell 或重新 export 后重试。


  • 验证 SciPy 安装成功
/usr/local/bin/python - <<'PY'
import scipy, numpy as np
print('scipy', scipy.__version__)
PY

应该打印出 scipy 1.4.1。

若报错,在「生成元数据」阶段需要 pybind11:

ModuleNotFoundError: No module named 'pybind11'

则进一步按照如下步骤进行安装——先把缺的构建依赖补上,再重新用“无隔离、源码方式”编好 scipy==1.4.1,最后安装 TF wheel。


  • 确保编译依赖就绪
apt-get update
apt-get install -y --no-install-recommends libopenblas-dev liblapack-dev gfortran build-essential python3-dev pkg-config
/usr/local/bin/python -m pip install -U "pip==21.3.1" "setuptools<60" "wheel<0.38"


  • 补齐 SciPy 构建要用到的 Python 依赖
/usr/local/bin/python -m pip install "pybind11==2.6.2"  "Cython==0.29.36"

pybind11 是 1.4.x 的 scipy.fft/_pocketfft 子包必需;Cython 版本也固定下,避免拉 3.x。


  • 给 NumPy/SciPy 指明用 OpenBLAS(双保险)
cat > ~/.numpy-site.cfg <<'EOF'
[openblas]libraries = openblas
library_dirs = /usr/lib/aarch64-linux-gnu
include_dirs = /usr/include
runtime_library_dirs = /usr/lib/aarch64-linux-gnu
EOF

export BLAS=/usr/lib/aarch64-linux-gnu/libopenblas.so
export LAPACK=/usr/lib/aarch64-linux-gnu/libopenblas.so
export NPY_NUM_BUILD_JOBS=$(nproc)
export CC=gcc CXX=g++


  • 源码安装 SciPy 1.4.1(关键:禁用 build isolation)
/usr/local/bin/python -m pip install --no-cache-dir --no-binary :all: --no-build-isolation "scipy==1.4.1"


  • 如果机器内存很小、构建中 OOM,可先降并发再试:
export NPY_NUM_BUILD_JOBS=2
/usr/local/bin/python -m pip install --no-cache-dir --no-binary :all: --no-build-isolation "scipy==1.4.1"


  • 验证 SciPy
/usr/local/bin/python - <<'PY'
import scipy, numpy as np
print('scipy', scipy.__version__)
PY

看到 scipy 1.4.1 即为安装成功。

本页内容