2021年12月10日金曜日

Fedora 35 でTensorflow 2.7(CUDA11.5 cuDNN8.3.1)をビルドする

目的


Tensorflowの2.7をFedora 35でソースビルドする。


環境


  • SW
    • Fedora 35 x86_64
    • Python 3.10.0
    • GCC 11.2.1 20210728
    • CUDA 11.5 + cuDNN v8.3.1
  • HW
    • CPU AMD Ryzen 7 1700
    • GPU GeForce GTX 1070


事前の準備


CUDA、cuDNNのインストール


これは、以前と同様。
RPM FusionからCUDAを、NVIDIAよりcuDNNをそれぞれインストールする。

BAZELのインストール


FedoraのCOPR repositoryからインストールが可能。
3.x系と4.x系が選択可能なので3.x系をインストールする。

sudo dnf install dnf-plugins-core
sudo dnf copr enable vbatts/bazel
sudo dnf remove bazel4
sudo dnf install bazel3


TensorFlow v2.7(後述のTensorFlow I/Oも含めて)のビルドにはBazel v3.7.2が必要(4.x系の場合、TensorFlow I/Oのビルドでエラーとなるため)。
しかし、現時点(2021.12.08)ではバージョンがv3.7.1。v3.7.2をソースコードからビルドするにはGCCのバージョンダウン(ソースビルド)が必要になる(Fedora 35のGCC11ではビルドができないため)。今回はv3.7.1で押し通すことにする。


TensorFlow I/Oのビルド


TensorFlow v2.7をビルド後、wheelパッケージをインストールする際にtensorflow_io_gcs_filesystemとtensorflow_ioのインストールを要求される(依存関係)。

しかしながら、Python3.10のパッケージは用意されていないためインストールできない。そこで、TensorFlow I/Oをビルド、io、io_gcs_filesystemのwheelパッケージも作成する。

なお、TensorFlow I/OのビルドにはTensorFlow v2.7が必要なため、デッドロックしてしまう。。。


なんでだよ。

さらにBazelが利用するモジュールがPython3.10に対応していないため、ビルドでエラーが発生してしまう。

ここで、TensorFlow I/Oのビルドは2つの手順に分かれている(TensorFlow I/Oのビルド手順を参照)。
  • Bazelを使ったビルド(共有ライブラリの作成)
  • Wheelパッケージの作成

    このため、ビルドはPython3.9環境で行い、パッケージ作成時にPython3.10環境に切り替えて行うこととする。Python3.9環境であれば、TensorFlowも公式のパッケージが提供されているのでデッドロックも回避できる。
    TensorFlow I/OのGithub Actionがこのような手順になっていたので参考にした。

    (じゃあ、Python3.9環境でよくない?というのは置いておく)


    まず、Python3.9をインストールし、virtualenvwrapper(virtualenv)でビルド用環境を作成し、必要なモジュールをインストールしておく。

    sudo dnf install python3.9
    mkvirtualenv -p python3.9 io_make
    workon io_make
    pip install numpy
    pip install tensorflow


    TensorFlow I/Oのリポジトリをクローンする。
    今回はPython3.10ビルドに対応となっていたmainブランチとする(でも対応していないけど、、、)。

    git clone https://github.com/tensorflow/io.git
    git log -n 1
    commit 667da515b77c7e7b7266d82540b4d5278936d65c (HEAD -> master, origin/master, origin/HEAD)
    Author: Yong Tang <yong.tang.github@outlook.com>
    Date:   Thu Dec 2 04:25:24 2021 +0800
    
        Enable python 3.10 build (#1576)
        
        * Enable python 3.10 build
        
        Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
        
        * Disable test for 3.10
        
        Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
    


    先程述べたBazelのバージョンが一致しない問題があるので、.bazelversionの内容を変更しておく。

    git diff .bazelversion
    diff --git a/.bazelversion b/.bazelversion
    index 47b6be3f..a76ccff2 100644
    --- a/.bazelversion
    +++ b/.bazelversion
    @@ -1 +1 @@
    -3.7.2
    \ No newline at end of file
    +3.7.1
    


    ビルド。

    bazel build -s --verbose_failures $BAZEL_OPTIMIZATION //tensorflow_io/... //tensorflow_io_gcs_filesystem/...
    
    view raw 06_build_io.md hosted with ❤ by GitHub

    wheelパッケージの作成。
    setup.pyがpython3.10をサポートしていないので修正。


    git diff setup.py
    diff --git a/setup.py b/setup.py
    index 10228e36..64f15738 100644
    --- a/setup.py
    +++ b/setup.py
    @@ -165,7 +165,7 @@ setuptools.setup(
         ],
         keywords="tensorflow io machine learning",
         packages=setuptools.find_packages(where=".", exclude=exclude),
    -    python_requires=">=3.6, <3.10",
    +    python_requires=">=3.6, <=3.10",
         install_requires=install_requires,
         extras_require={
             "tensorflow": [require],
    

    TensorFlowをインストールするためのPython3.10環境を作成、切り替えて、wheelパッケージを作成。できたパッケージをインストール。

    mkvirtualenv -p python3.10 tf2.7
    workon tf2.7
    python3 setup.py bdist_wheel --data bazel-bin
    python setup.py --project tensorflow-io-gcs-filesystem --data bazel-bin -q bdist_wheel
    ls dist/
    tensorflow_io-0.22.0-cp310-cp310-linux_x86_64.whl  tensorflow_io_gcs_filesystem-0.22.0-cp310-cp310-linux_x86_64.whl
    pip install dist/tensorflow_io_gcs_filesystem-0.22.0-cp310-cp310-linux_x86_64.whl
    pip install dist/tensorflow_io-0.22.0-cp310-cp310-linux_x86_64.whl
    


    TensorFlowのビルド


    さて、あとは本題。

    TensorFlowのリポジトリをクローンしてv2.7.0をチェックアウト。
    Python3.10ではビルドが失敗するため、以下のコミットをcherry-pickする。

    git clone https://github.com/tensorflow/tensorflow.git
    cd tensorflow
    git checkout v2.7.0
    git cherry-pick 14966ee409b89df5b9144a6d1a19359dd0bb1f68
    


    Bazel3.7.1でビルドするために.bazelversionを修正。

    git diff .bazelversion
    diff --git a/.bazelversion b/.bazelversion
    index 0b2eb36f508..a76ccff2a6e 100644
    --- a/.bazelversion
    +++ b/.bazelversion
    @@ -1 +1 @@
    -3.7.2
    +3.7.1
    


    configureの実行。
    ccacheをインストールしているとビルドに失敗するため、host compilerにはGCCを指定する。

    pip install pip numpy wheel
    pip install keras_preprocessing --no-deps
    ./configure 
    WARNING: current bazel installation is not a release version.
    Make sure you are running at least bazel 3.7.2
    Please specify the location of python. [Default is /home/xxxxx/.virtualenvs/tf2.7/bin/python3]: 
    
    
    Found possible Python library paths:
      /home/xxxxx/.virtualenvs/tf2.7/lib/python3.10/site-packages
      /home/xxxxx/.virtualenvs/tf2.7/lib64/python3.10/site-packages
    Please input the desired Python library path to use.  Default is [/home/xxxxx/.virtualenvs/tf2.7/lib/python3.10/site-packages]
    
    Do you wish to build TensorFlow with ROCm support? [y/N]: 
    No ROCm support will be enabled for TensorFlow.
    
    Do you wish to build TensorFlow with CUDA support? [y/N]: y
    CUDA support will be enabled for TensorFlow.
    
    Do you wish to build TensorFlow with TensorRT support? [y/N]: 
    No TensorRT support will be enabled for TensorFlow.
    
    Found CUDA 11.5 in:
        /usr/local/cuda-11.5/targets/x86_64-linux/lib
        /usr/local/cuda-11.5/targets/x86_64-linux/include
    Found cuDNN 8 in:
        /usr/local/cuda-11.5/targets/x86_64-linux/lib
        /usr/local/cuda-11.5/targets/x86_64-linux/include
    
    
    Please specify a list of comma-separated CUDA compute capabilities you want to build with.
    You can find the compute capability of your device at: https://developer.nvidia.com/cuda-gpus. Each capability can be specified as "x.y" or "compute_xy" to include both virtual and binary GPU code, or as "sm_xy" to only include the binary code.
    Please note that each additional compute capability significantly increases your build time and binary size, and that TensorFlow only supports compute capabilities >= 3.5 [Default is: 6.1]: 
    
    
    Do you want to use clang as CUDA compiler? [y/N]: 
    nvcc will be used as CUDA compiler.
    
    Please specify which gcc should be used by nvcc as the host compiler. [Default is /usr/lib64/ccache/gcc]: /usr/bin/gcc
    
    
    Please specify optimization flags to use during compilation when bazel option "--config=opt" is specified [Default is -Wno-sign-compare]: 
    
    
    Would you like to interactively configure ./WORKSPACE for Android builds? [y/N]: 
    Not configuring the WORKSPACE for Android builds.
    
    Preconfigured Bazel build configs. You can use any of the below by adding "--config=<>" to your build command. See .bazelrc for more details.
    	--config=mkl         	# Build with MKL support.
    	--config=mkl_aarch64 	# Build with oneDNN and Compute Library for the Arm Architecture (ACL).
    	--config=monolithic  	# Config for mostly static monolithic build.
    	--config=numa        	# Build with NUMA support.
    	--config=dynamic_kernels	# (Experimental) Build kernels into separate shared objects.
    	--config=v1          	# Build with TensorFlow 1 API instead of TF 2 API.
    Preconfigured Bazel build configs to DISABLE default on features:
    	--config=nogcp       	# Disable GCP support.
    	--config=nonccl      	# Disable NVIDIA NCCL support.
    Configuration finished
    


    ビルド。あとは待つだけ。

    bazel build \
      --config=cuda \
      --config=v2 \
      --config=nonccl \
      --config=opt \
      //tensorflow/tools/pip_package:build_pip_package
    


    ビルドが完了すれば、wheelパッケージを作成してインストールする!

    ./bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
    pip install /tmp/tensorflow_pkg/tensorflow-2.7.0-cp310-cp310-linux_x86_64.whl
    


    確認


    • tf.__version__が2.7であること。
    • GPUデバイスを認識していること


    python3
    Python 3.10.0 (default, Oct  4 2021, 00:00:00) [GCC 11.2.1 20210728 (Red Hat 11.2.1-1)] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import tensorflow as tf
    >>> tf.__version__
    '2.7.0'
    >>> from tensorflow.python.client import device_lib
    >>> device_lib.list_local_devices()
    2021-12-09 21:54:07.769548: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  SSE3 SSE4.1 SSE4.2 AVX AVX2 FMA
    To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
    2021-12-09 21:54:07.802879: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
    2021-12-09 21:54:07.945450: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
    2021-12-09 21:54:07.945716: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
    2021-12-09 21:54:08.394447: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
    2021-12-09 21:54:08.394666: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
    2021-12-09 21:54:08.394843: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
    2021-12-09 21:54:08.395024: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1525] Created device /device:GPU:0 with 7263 MB memory:  -> device: 0, name: NVIDIA GeForce GTX 1070, pci bus id: 0000:0a:00.0, compute capability: 6.1
    [name: "/device:CPU:0"
    device_type: "CPU"
    memory_limit: 268435456
    locality {
    }
    incarnation: 797035850830495245
    xla_global_id: -1
    , name: "/device:GPU:0"
    device_type: "GPU"
    memory_limit: 7616790528
    locality {
      bus_id: 1
      links {
      }
    }
    incarnation: 10656249271275017074
    physical_device_desc: "device: 0, name: NVIDIA GeForce GTX 1070, pci bus id: 0000:0a:00.0, compute capability: 6.1"
    xla_global_id: 416903419
    ]
    >>> 
    

    OK〜✌

    0 件のコメント:

    コメントを投稿