Tensorflow2.3を、GeForce RTX4060Ti、Windows10でソースからコンパイルとXLA有効化

# 概要
TensorflowでXLAを有効にしたくて、ソースからコンパイルする事にした。新しすぎて情報が無い…。
環境はWindows10、Geforce RTX4060Tiが1台。
ソースからコンパイルするのは猛者、という話があるが私は猛者じゃないもん(震え声)
公開を急いだので、表記がいまいちなのは許して下さい。随時直します。
なおCNNで機械学習する為のビルドですので、人によっては要らない作業もあると思います。

ここでは、TensorFlow r2.3、Python3.8.3、CUDA11.8、cuDNN8.9.3、Visual Studio 2019 の Microsoft Visual C++ 再頒布可能パッケージ、Build Tools for Visual Studio 2019を入れる。
他のPCでの互換性を最大限キープしたい事と、失敗した時にバージョンを下げるより上げる方が楽だろうという事で出来るだけ古いのを採用。各バージョンの理由については後で書く。


# 調査

所持しているグラフィックカードで、入るCUDA及びTensorFlowのバージョンが異なります。

グラフィックカードのアーキテクチャについては下記参照。
https://www.nvidia.com/ja-jp/geforce/graphics-cards/compare/
4060TiはAda Lovelace。

# Pythonのバージョン
numpy1.18がエラーを起こすので3.8.3にした。

当初はここを見て3.9.10にするつもりだった。
https://discuss.tensorflow.org/t/tensorflow-2-13-0-does-not-find-gpu-with-cuda-12-1/18939/17
元から入っていたという事と、情報不足ながら3.9.10に対応するVCとBazelのバージョンがぎりぎり書いてあるという事もある。
https://www.tensorflow.org/install/source_windows

ただし以前、「私の環境では、3.7.9でないと動かなかった。3.6系でも3.8系でも通りません。」という経験をしているので自信はない。

# CUDAとcuDNNのバージョン
CUDAバージョンは下記見ると9.0でも行けそうな気がするのだが、
https://docs.nvidia.com/deeplearning/cudnn/reference/support-matrix.html

下記で11.8が安パイな気がしますのでそうします。
https://en.wikipedia.org/wiki/CUDA
https://forums.developer.nvidia.com/t/cuda-compatibility-between-nvidia-rtx-a5000-and-geforce-rtx-4060-ti/264216/3
https://discuss.tensorflow.org/t/tensorflow-2-13-0-does-not-find-gpu-with-cuda-12-1/18939/17

cuDNNはこちらの方に倣って8.9.3にする
https://note.com/hcanadli12345/n/nb8cf59ca2596

こちらは9.0になってるが、それ以上古いバージョンの記載がない。
https://docs.nvidia.com/deeplearning/cudnn/reference/support-matrix.html

# Visual Studio
諸先輩方は2022入れてる模様ですが、
下記見ると2019でも行けそうなので、2019にする。なおMSVC Version 193x(Visual Studio 2022)、MSVC Version 192x(Visual Studio 2019)、MSVC Version 191x(Visual Studio 2017)という事らしい。
https://docs.nvidia.com/cuda/archive/11.8.0/cuda-installation-guide-microsoft-windows/index.html

# インストール
pythonのインストール
「python-3.8.3-amd64.exe」を「管理者モードで実行」しました。

インストールする時は、初期画面で全てのチェックボックスをチェックしないとはまります。

「Add Python 3.8 to PATH」指定。

「Customize installation」選んでインストールした方が良さそう。

「Install for all users」指定しておいた方が、その後のPathの扱いなどが楽。

「Disable path length limit」表示されたらクリックしてパス長の制限を解除。

Pathに、下記があればOK。

C:\Program Files\Python38\Scripts\
C:\Program Files\Python38\

バージョン確認。

python --version
番外編、プロキシ環境でのセットアップ
プロキシ認証のせいでこのままだと動かない。どこかファイルに設定する解決法がある筈だが(実際、１台のPCは何もしていない)。
これを打っても出てこなかった。

pip config -v list
結局わからなかった為に、同じコマンドプロンプトで下記実施。

set HTTP_PROXY=http://アカウント:パスワード@プロキシURL:ポート
set HTTPS_PROXY=http://アカウント:パスワード@プロキシURL:ポート
ちなみに、set HTTPS_PROXY=http://、についてはhttpsの打ち間違いでは無くてhttpです。

なお、パスワードで記号を使っている場合は、例えば@なら%40などの回避が必要。昨今、パスワードの強度から記号が必須な事が多いが、こういう場合は極めて面倒臭い…。

# Visual Studio系ツールのインストール

Visual Studioのダウンロードサイトから以下をダウンロード&インストールする
Visual Studio 2015、2017、2019、および2022 の Microsoft Visual C++ 再頒布可能パッケージ(1つで済む)
Build Tools for Visual Studio 2019

下記先達によると、
https://qiita.com/TrashBoxx/items/2e884998cd1193f73e2f
「インストールする場合、「C++によるデスクトップ開発」にチェックオプションに「MSVC v142 - VS 2019 C++ x64/x86 ビルドツール」にチェックが入っていることを確認してください。」となってはいますが -> 自分用のメモ。
他、自分の過去メモによると「MSVC v141及びv140も入れた方がいい様です、Pythonが不具合起こす可能性があります」と書いてます。

ついでにVisual Studio Community 2019も入ってました。

# MSYS2インストール

Windowsで基本的なLinuxコマンドを使えるようになる、らしい。
MSYS2の公式サイトからダウンロード&インストールする。

MSYS2の動作環境を整える。
上手くいかないのでWindowsメニューから「管理者権限」でMSYS2を起動、もしくは「ファイルがあるフォルダ開く」して「管理者権限で起動」した。

MSYS2のアップデート
MSYS2を管理者権限で起動し、pacmanのパッケージを一括アップグレードする
(-Sy: 最新のパッケージデータベースをダウンロードする）
-Su: インストールしたパッケージをアップグレードする）
以下、全てMSYS2で実行。

pacman -Syu
MSYS2を再起動して以下のコマンドを実行する （[Y]でインストールを完了）

pacman -Su
pacman -Sy git patch unzip zip ed
上記をやらないと、最後の方でビルドファイルを作成する時にこける。
特にPythonを再インストールすると顕著。

MSYS2文字コード設置
MYSYS2の文字コードを変更しておかないと、後でエラーメッセージに苦しむことになる。
端末上で「右クリック」→「Options...」→「Text」の「locale」を「ja_JP」、「Character set」を「SJIS」

MSYS2パス設定
Windows側のPATHを読み込めるようにする
Windowsの システムのプロパティ＞詳細設定＞環境変数 にて、以下を[新規]で追加する。
変数

MSYS2_PATH_TYPE

値

inherit

同時に下記を実施。

ファイル名を指定して実行（Windowsキー+R）でgpedit.mscを実行して、ローカルグループポリシーエディターを起動。
コンピューターの構成> 管理者用テンプレート> システム> ファイルシステム を選択し、その中にある「Win32の長いパスを有効にする」を「有効」に変更。

Pathに、下記を追加しておく。
C:\msys64にインストールされている場合は、

C:\msys64\usr\bin

# Bazelインストール

下記に従って0.17.2にしようかと思ったのだが、どうもエラーになる。
https://qiita.com/kHz/items/6af115d04628ecc82c43
バージョンを2.0以上にしないと出てくるエラーがあった様な。

私の中ですっかり信用が無くなってるGoogleさんのページだが、そこにはtensorflow_gpu-2.3.0にはバゼル3.1.0だと書いてあった為、試してみる事にして、それで成功した。
https://www.tensorflow.org/install/source_windows?hl=ja
なお、3.7.2だと新しすぎる模様。

bazel.exeをダウンロードするディレクトリを作成し、wgetで取得する。
Bazel 実行可能ファイルの場所を%PATH%環境変数に追加します。
最後の--no-check-certificateは、カスペルスキー入れてるが故に必要だった。

cd /c/
mkdir bazel
cd bazel/
wget https://github.com/bazelbuild/bazel/releases/download/3.1.0/bazel-3.1.0-windows-x86_64.exe -O bazel.exe --no-check-certificate
CUDA(NVIDIAグラフィックスドライバ)のインストール -> 要るか要らないかわからない
下記悪影響を及ぼしそうな気もするが、別に何も起きなかった。
NVIDIAグラフィックスドライバ
最新の NVIDIA 公式ドライバーをダウンロード
https://www.nvidia.co.jp
から、セットアップするPCに該当するドライバをダウンロード、インストール。
おそらく再起動を要求される。

# CUDAインストール
前述の通り、自分のグラフィックカードに合わせたバージョンを入れて下さい。

前述の通り、11.8入れます。

下記より、CUDAを入手します。
CUDA Toolkit Archive
https://developer.nvidia.com/cuda-toolkit-archive

「Windows」「x86_64」「10」(おそらくWindows10)「exe(local)」選択。

これで、「cuda_11.8.0_522.06_win10.exe」をダウンロードしてきます。

PATH、CUDA_PATHにインストールしたCUDAのフォルダが含まれている事を確認。
PATHにおける場所ですが、どうも先頭の方に有った方が確実な模様(最後に書いていたら失敗した)。
私の場合、最初にPythonのPathを書いて、次にCUDAのPATHを書いている。

C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.8\bin
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.8\libnvvp

一応、CUDAのインストール確認。

nvcc -V
cuDNNのインストール
CUDAのバージョンに対応するcuDNNを落として入れる。
cuDNN Archive
https://developer.nvidia.com/rdp/cudnn-archive

cuDNNは先に書いた通り8.9.3にする

これで、「cudnn-windows-x86_64-8.9.3.28_cuda11-archive.zip」をダウンロードしてきます。

ダウンロードした .zip ファイルを解凍し、「cuda」フォルダ下に展開された全フォルダとファイルを、先ほどCUDA ツールキットをインストールしたディレクトリ(C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.8)にコピーする。

こちらを見ると時に記載はないが、
https://docs.nvidia.com/deeplearning/cudnn/installation/windows.html

念のため、これを入れておく。
CUDNN_PATH=C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.8

またやはり記載がないが、以前は実行したのと下記により、
https://www.kkaneko.jp/tools/win/cuda.html

cd "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.8\bin"
curl -O http://www.winimage.com/zLibDll/zlib123dllx64.zip
powershell -command "Expand-Archive -Path zlib123dllx64.zip"
copy zlib123dllx64\dll_x64\zlibwapi.dll .

下記の結果くらいは確認した方がいいかもしれない。
where cudnn64_8.dll

# Graphviz
pydotというかplot_modelするの必要。
Graphvizの公式サイトからダウンロードしてインストールする。

# Pythonの各種パッケージインストール
pipでインストールする、ただしpipのアップデートの必要性は不明。

pip install --upgrade pip==20.3.3
pip install six

wheelは入れておかないと、最後にビルドしたtensorflowをpipで入れられなくなる。それ以前に他のパッケージが入らない…。

pip install wheel mock setuptools scikit-learn-intelex packaging

バージョンの問題がある。
pip install seaborn==0.11.1

numpyについては
https://maxigundan.com/deeplearning/2020/07/%E3%80%90tf2%E3%80%91bazel%E3%83%93%E3%83%AB%E3%83%89-bfloat16-cc635-error-c2664-pyufuncgenericfunction-%E3%81%B8%E5%A4%89%E6%8F%9B%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%9B%E3%82%93/
見て(半日で解決するとか凄いです…私1年がかり…)
https://github.com/tensorflow/tensorflow/issues/40688
に載ってるそうです。
稀に、Tensorflowをビルドする段になって勝手にバージョンアップされて不具合を起こすことがある為、
ビルド前に再確認した方が良さそう。

pip install numpy==1.18

Kerasについてはデフォルトで最新バージョンを入れて不具合を起こす為、指定する。
https://qiita.com/Hiroki-Fujimoto/items/8afacc9609c34a2d6c56

pip install keras==2.4.3
scipyでnumpy 1.19.5<= <1.27.0とエラーが出るがとりあえず無視。

keras_applicationsとkeras_preprocessingもバージョン指定する必要性があったと思われるが失念。

pip install keras_applications==1.0.8 --no-deps
pip install keras_preprocessing==1.1.0 --no-deps

Pythonで問題出たので下記実施。
pip install protobuf==3.20.*

他に、過去に下記を実施している。

下記より
https://github.com/ultralytics/yolov5/issues/7638

pip install scipy==1.5
pip install scikit-learn==0.23.1

下記より
https://github.com/aws/aws-sdk-pandas/issues/817
pip install pandas==1.1.0

下記より
https://matplotlib.org/devdocs/devel/min_dep_policy.html
pip install matplotlib==3.5

python -m pip install -U opencv-python opencv-contrib-python
python -m pip install opencv-python

pip install pillow
pip install lxml
pip install Cython
pip install jupyter
pip install pandas
pip install opencv-python
pip install pydot

numpyのバージョンを元に戻す。

pip install numpy==1.18

# コンパイル及びビルド

## 事前準備
Bazelのパスを通す。
bashだからですね。

export PATH=/c/bazel:$PATH
MSYS2またはコマンドプロンプトの環境変数設定について。
設定しない。
過去には下記を設定したが、かえって悪さをする模様。
正確には、BAZELのバージョンによって、書式は異なるが、それはBAZELのページに記載があり、
それ以前にこのあたりを設定したら不具合を起こした。
下記については過去の経緯を残すためにだけ記載。

ここから過去のメモ。

Progra~2にした理由は、どうもProgram Files (x86)の記載が悪さしている疑いがあったから。MIB055~1はMicrosoft Visual Studioの略です。NVIDIA~2はNVIDIA GPU Computing Toolkitの略です。

下記コマンドで、8.3形式のフォルダ名は調査可能。
dir /x

Windows SDKのバージョンを調べる方法。
https://oneuro.net/where-is-windows-sdk-version

set BAZEL_VS=C:\Progra~2\MICROS~1.0
set BAZEL_VC=C:\Progra~2\MICROS~1.0VC
set BAZEL_VC_FULL_VERSION="16.11.23"
set BAZEL_WINSDK_FULL_VERSION="10.0.22621.0"

export PATH=C:\Progra~1\NVIDIA~2\CUDA\v10.1\bin:$PATH
export PATH=C:\Progra~1\NVIDIA~2\CUDA\v10.1\extras\CUPTI\lib64:$PATH
export PATH=C:\Progra~1\NVIDIA~2\CUDA\v10.1\include:$PATH
export XLA_BUILD=true
export XLA_TARGET=cuda

export BAZEL_VS=C:\Progra~2\MICROS~1.0
export BAZEL_VC=C:\Progra~2\MICROS~1.0VC

ここまで過去のメモ。

Windowsの設定。
設定 - 更新とセキュリティ - 開発者モード をオンにする

# Tensorflowのソース準備
TensorFlowのGitリポジトリを取得する
cd /c/
git clone https://github.com/tensorflow/tensorflow.git
cd tensorflow/
チェックアウト
チェックアウト。なお、r2.3の「r」をつけ忘れると見つからない。

git checkout r2.3

# コンフィグ
入力コマンドと、少し解説。
python configure.py
特にエラーが出なかった場合は、いくつか質問されるのでYやNなどを入力していく。
なのだが、ここで注意ではないが特記事項。
私の場合、XLAを有効化したくて実行しているのだが、何故か質問でその項目が出てこない。
何故か悩んだのだが、Tensorflow1系の場合はその項目は出てくるのだが、TensorFlow2系ではその項目は出てこない、らしい。

各項目について
Please specify the location of python. [Default is C:\Program Files\Python39\python.exe]:

どうも「Program Files」の指定が悪さするので、「Progra~1」にして下記入力。

C:\Progra~1\Python38\python.exe

Found possible Python library paths: C:\Program Files\Python38\lib\site-packages
Please input the desired Python library path to use. Default is [C:\Program Files\Python38\lib\site-packages\

同上。

C:\Progra~1\Python38\lib\site-packages

Do you wissh to build TensorFlow with ROCm support？

CUDAをYにするならここは絶対にN。

N

Do you wieh to build TensorFlow with CUDA support？
CUDA使いたいのでY。

Y

Please note that each additioinal compute capability signigficantly increases your buid time and binari size, and that TensoFlow only supports compute capabilities >= 3.5
下記を見て決める。

https://en.wikipedia.org/wiki/CUDA

8.9

Please specify optimization flags to use during compilation when bazel option "--config=opt" is specified [Default is /arch:AVX]:
ここでおそらくtensorflow v2を指定するのだと思う。

/arch:AVX

Woud you like to override eigen storong inline for some C++ compilatoin to reduce the complaton time？
よくわからないがY

Y

Would you like to nteractively configure ./WORKSPACE for Android builds？
Android使わないのでN

N

# ビルドファイル生成
BazelでTensorFlowビルドファイルを生成する

ディレクトリ移動
whlファイルを生成するディレクトリを作成した後、ビルドするディレクトリに移動する

cd /c/
mkdir tmp
cd /c/tensorflow/
ビルドファイル生成前のビルド
一度、bazel cleanした方がいいかもしれない。
なお、何度か失敗した場合は確実にbazel cleanが効く。

bazel clean
オプションの類は、下記から持ってきた。
Windowsでのソースからのビルド | TensorFlow
https://tensorflow.google.cn/install/source_windows?hl=ja

C:\tensorflow\tensorflow\python\lib\core\bfloat16.cc
の改行に疑問が残るところを修正したが、意味があったか不明。

ビルドコマンド。最終的に、Googleのページを採用。CUDAに関して二重指定だよとエラーが出る。

bazel build --config=opt --config=cuda --define=no_tensorflow_py_deps=true //tensorflow/tools/pip_package:build_pip_package

しかし通らないので下記に変更。

https://github.com/tensorflow/tensorflow/issues/41803
bazel build --config=opt --config=avx2_win --config=short_logs --config=cuda --define=no_tensorflow_py_deps=true --copt=-DTHRUST_IGNORE_CUB_VERSION_CHECK --copt=-nvcc_options=disable-warnings //tensorflow/tools/pip_package:build_pip_package

# パッケージ作成
ビルドを実行する。

長時間かかると聞いていたがそんなに掛からなかった。20分程度。何か間違えたか？

bash bazel-bin/tensorflow/tools/pip_package/build_pip_package /c/tmp/tensorflow_pkg
ビルドファイル、すなわちtensorflowインストール
cd /c/tmp/
pip install tensorflow-2.3.4-cp37-cp37m-win_amd64.whl

# 確認

python -c "import tensorflow as tf; print( tf.__version__ )"

cudart64_118.dll not found出てググったが情報が一切ない。
https://qiita.com/Radley/items/985454b4df7f86e743d9
参考に、cudart64_110.dllをコピーしてcudart64_118.dllにしてみた。

python -c "from tensorflow.python.client import device_lib; print(device_lib.list_local_devices())"
無事、ここでXLA_GPUとXLA_CPUが表示されました。

# 今後
Tensorflow古いし、pipで何か入れるたびに混乱するので、そのうちにTensorflowアップしようと思います。