概要と背景
- この記事は、Microsoft Visual Studioで作成するプログラムからTensorFlow C APIを利用したGPUでの推論処理を可能にするために、Windows 10環境でTensorFlowをソースからビルドし、tensorflow.dllやtensorflow.libを生成するまでの手順をまとめたものです。
- これまで、GeForce GTX 10シリーズ(Pascal世代)や、RTX 20シリーズ(Turing世代)では、TensorFlow公式の記事1や、こちらの記事2を参考にすることで、TensorFlow 1.xのビルドができましたが、GeForce RTX 30シリーズ(Ampere世代)におけるTensorFlow 1.xの利用が可能かがわからなかったため、その調査とあわせて、どのバージョンの組み合わせであればビルドできるのかを調べました。
確認結果
- 結論としては、Windows 10とAmpere世代GPU(CUDA 11)の組合わせでTensorFlow 1.xをビルド&利用する方法は見つからなかったため、TensorFlow 2.4でのビルド方法をまとめました。
- 検証した時点では以下のバージョンの組み合わせで動作することを確認しています。(PythonやVisual Studioのバージョンなど、これ以外でも動作する組合わせはありますが、一旦確認できたバージョンで記載しています。)
GPU Architecture |
Compute Capability |
Python | Visual Studio |
CUDA | Bazel | cuDNN | TensorFlow | numpy |
---|---|---|---|---|---|---|---|---|
Ampere | 8.6 | 3.8.10 | 2019 | 11.3 | 4.2.1 | 8.2.1 | 2.4.1 | 1.19.3 |
Ampere | 8.6 | 3.7.0 | 2019 | 11.2 | 3.1.0 | 8.1.0 | 2.4 | 1.19.3※ |
Ampere | 8.6 | 3.7.0 | 2019 | 11.1 | 3.1.0 | 8.0.5 | 2.4 | 1.19.3※ |
Pascal, Turing | ~7.5 | 3.6.8 | 2015 | 10.0 | 0.17.2 | 7.4 | 1.12 | 1.18.1 |
※Pythonでimport tensorflow
を行う場合はエラーが出るため、ビルド終了後にnumpyを1.20.xに上げる必要あり
- 2021.02.12追記:
本記事作成中に、TensorFlow公式の記事1の「テスト済みのビルド構成」の項目にもtensorflow-2.4.0の行が追加されていました。 - 2021.11.12追記:
Bazel 4.2.1でビルドするパターンを追加しました。
ビルド手順
はじめに
- 本手順は、従来の記事2の流れに則って、その内容を整理&アップデートしていく形で記述していきます。
- Ampere世代向けの手順だけでなく、Pascal, Turing世代向けの手順も備忘録的に残しておきたいため、Ampere世代の手順(1例)を[A]、Pascal, Turing世代の手順を[B] として、併記しています。
STEP 0: Pythonをインストールする
0-1. Pythonの公式サイトから以下をダウンロード&インストールする
[A] Python 3.7.0 (おそらく3.6.X〜3.8.Xで可)
[B] Python 3.6.8 (おそらく3.5.X〜3.7.Xで可※)
- ※[B]でPython 3.7.0の場合、STEP 8-2.のbazel buildでエラーになる(2021.02.22追記)
- 関連情報:https://github.com/tensorflow/tensorflow/issues/20950
STEP 1: Visual C++ Build Toolsをインストールする
1-1. [A] Visual Studioのダウンロードサイトから以下をダウンロード&インストールする
・Visual Studio 2019 の Microsoft Visual C++ 再頒布可能パッケージ
・Build Tools for Visual Studio 2019
1-1. [B] 以前のバージョンのVisual Studioのダウンロードサイトから以下をダウンロード&インストールする
・Microsoft Visual C++ 2015 再頒布可能パッケージ Update 3
・Microsoft Build Tools 2015 Update 3
STEP 2: CUDA Toolkitをインストールする
2-1. CUDA Toolkit Archiveから以下をダウンロード&インストールする
[A] CUDA 11.2.0
[B] CUDA 10.0
STEP 3: MSYS2をインストールする
Windowsで基本的なLinuxコマンドを使えるようにします。
3-1. MSYS2の公式サイトからダウンロード&インストールする
以下ディレクトリに、自身のネットワーク環境のプロキシ情報を記述したproxy.shファイルを新規作成する。 なお、{user}に@などの特殊文字を含む場合は、パーセントエンコード(URLエンコード)する。 以下ディレクトリにあるpacman.confを開き、curlに関する以下の1行のコメントアウトを外す。【プロキシ設定が必要なネットワーク環境の場合】
本内容はこちらの記事3を引用しています。
3-1-1. proxy.shの作成
C:¥msys64¥etc¥profile.dexport http_proxy=http://{user}:{password}@{proxy_host}:{proxy_port}/
export https_proxy=http://{user}:{password}@{proxy_host}:{proxy_port}/
export ftp_proxy=http://{user}:{password}@{proxy_host}:{proxy_port}/
export HTTP_PROXY=http://{user}:{password}@{proxy_host}:{proxy_port}/
export HTTPS_PROXY=http://{user}:{password}@{proxy_host}:{proxy_port}/
export FTP_PROXY=http://{user}:{password}@{proxy_host}:{proxy_port}/
3-1-2. パッケージ管理システムpacmanでcurlによるダウンロードを有効にする
C:¥msys64¥etcXferCommand = /usr/bin/curl -C - -f %u > %o
3-2. MSYS2の動作環境を整える
3-2-1. コマンドプロンプトを起動し、以下のコマンドを実行する
"C:¥msys64¥msys2_shell.cmd" -use-full-path
(Windowsメニューから普通にMSYS2を起動しても問題ない可能性あり)
3-2-2. MSYS2を起動し、pacmanのパッケージを一括アップグレードする
pacman -Syu
(-Sy: 最新のパッケージデータベースをダウンロードする)
(-Su: インストールしたパッケージをアップグレードする)
このときに署名エラーが出る場合は、以下のファイル内でSigLevel=Never
と指定すると(強引に)解決できる。
C:¥msys64¥etc¥pacman.conf
3-2-3. MSYS2を再起動して以下のコマンドを実行する ([Y]でインストールを完了)
pacman -Su
pacman -S git patch unzip zip ed
3-2-4. Windows側のPATHを読み込めるようにする (2021.02.22追記)
- Windowsの システムのプロパティ>詳細設定>環境変数 にて、以下を[新規]で追加する。
変数 | 値 |
---|---|
MSYS2_PATH_TYPE | inherit |
STEP 4: Bazelをダウンロードする
4-1. bazel.exeをダウンロードするディレクトリを作成し、wgetで取得する
cd /c/
mkdir bazel
cd bazel/
[A]
wget https://github.com/bazelbuild/bazel/releases/download/3.1.0/bazel-3.1.0-windows-x86_64.exe -O bazel.exe
[B]
wget https://github.com/bazelbuild/bazel/releases/download/0.17.2/bazel-0.17.2-windows-x86_64.exe -O bazel.exe
STEP 5: cuDNNをインストールする
5-1. cuDNN Archiveから以下をダウンロードする (NVIDIAアカウントが必要)
[A] cuDNN 8.1.0 (CUDA11.2の場合)
[B] cuDNN 7.4.X (7.4.2など)
5-2. ダウンロードした各種ファイルを、それぞれ以下に配置する
C:¥Program Files¥NVIDIA GPU Computing Toolkit¥CUDA¥v1X.X¥bin
C:¥Program Files¥NVIDIA GPU Computing Toolkit¥CUDA¥v1X.X¥include
C:¥Program Files¥NVIDIA GPU Computing Toolkit¥CUDA¥v1X.X¥lib¥x64
STEP 6: Pythonの各種パッケージをインストールする
6-1. pipでインストールする
pip install pip six numpy wheel mock
pip install keras_applications
pip install keras_preprocessing
なお、[A]ではnumpyのバージョンが上がりすぎるとエラーになる可能性があるため、ダウングレードしておく(参考記事4)
pip install numpy==1.19.3
STEP 7: TensorFlowをダウンロードし、構成を設定する
7-1. Bazelのパスを通す
export PATH=/c/bazel:$PATH
(~/.bash_profileに上記を追記しておくと楽)
7-2. TensorFlowのGitリポジトリを取得する
cd /d/
git clone https://github.com/tensorflow/tensorflow.git
cd tensorflow/
[A]
git checkout r2.4
(エラーが出る場合は、2.4.1まで指定する必要あり)(2021.11.12追記)
[B]
git checkout r1.12
7-3. 構成を指定する
python configure.py
【MSYS2上でPythonのインタラクティブモードを使えるようにする方法】(2021.02.22追記)
いくつか質問されるのでYやNなどを入力していく。
[A,B共通]
Please specify the location of python. [Default is C:¥Users¥USERNAME¥AppData¥Local¥Programs¥Python¥Python3X¥python.exe]: {press enter}
Please input the desired Python library path to use. Default is [C:¥Users¥USERNAME¥AppData¥Local¥Programs¥Python¥Python3X¥lib¥site-packages] {press enter}
[Bのみ]
Do you wish to build TensorFlow with Apache Ignite support? [Y/n]: Y
Do you wish to build TensorFlow with XLA JIT support? [y/N]: N
[A,B共通]
Do you wish to build TensorFlow with ROCm support? [y/N]: N
Do you wish to build TensorFlow with CUDA support? [y/N]: Y
[Bのみ]
Please specify the CUDA SDK version you want to use. [Leave empty to default to CUDA 9.0]: 10.0
Please specify the location where CUDA 10.0 toolkit is installed. Refer to README.md for more details. [Default is C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v10.0]: {press enter}
Please specify the cuDNN version you want to use. [Leave empty to default to cuDNN 7]: 7.4.X.X
Please specify the location where cuDNN 7 library is installed. Refer to README.md for more details. [Default is C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v10.0]: {press enter}
Compute Capabilityについて次のように質問されるので、使用する可能性のあるGPUのCompute Capabilityを1つ以上カンマ区切りで入力する。
なお、GPUと値の対応関係は、NVIDIA Developerのページから確認できる。
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: 3.5,7.0]:
入力例:
[A] 6.1,7.0,7.5,8.6
[B] 6.1,7.0,7.5
Please specify optimization flags to use during compilation when bazel option "--config=opt" is specified [Default is /arch:AVX]: {press enter}
Would you like to override eigen strong inline for some C++ compilation to reduce the compilation time? [Y/n]: Y
[Aのみ]
Would you like to interactively configure ./WORKSPACE for Android builds? [y/N]: N
STEP 7B: ファイルの一部を修正する([B]のみ)
(half eigenのコンパイルで失敗するバグがあるため)
7B-1. eigen_half.patchをダウンロードする
以下のファイルを取得し、(Rawをコピーして新規にeigen_half.patchファイルを作成しても良い)
https://github.com/amsokol/tensorflow-windows-build-tutorial/blob/master/eigen_half.patch
以下のディレクトリに格納する。
D:¥tensorflow¥third_party
7B-2. workspace.bzlを編集する
以下のディレクトリにあるworkspace.bzlをテキストエディタで開き、eigen_archiveで文字列検索し、該当するブロックの最後に一行を追加する。
D:¥tensorflow¥tensorflow¥
…
tf_http_archive(
name = "eigen_archive",
build_file = clean_dep("//third_party:eigen.BUILD"),
sha256 = "",
strip_prefix = "eigen-eigen-fd6845384b86",
urls = [
"https://mirror.bazel.build/bitbucket.org/eigen/eigen/get/fd6845384b86.tar.gz",
"https://bitbucket.org/eigen/eigen/get/fd6845384b86.tar.gz",
],
+ patch_file = clean_dep("//third_party:eigen_half.patch"),
)
…
STEP 8: BazelでTensorFlowをビルドする
8-1. whlファイルを生成するディレクトリを作成した後、ビルドするディレクトリに移動する
cd /c/
mkdir tmp
cd /d/tensorflow/
8-2. ビルドファイルを生成する
[A]
bazel build --define=no_tensorflow_py_deps=true //tensorflow/tools/pip_package:build_pip_package
[B]
bazel build --config=opt --config=cuda //tensorflow/tools/pip_package:build_pip_package
なんらかのエラーが出た場合
・以下のようなチェックサムエラーが出た場合 (2021.02.22追記)
ERROR: Analysis of target '//tensorflow/tools/pip_package:build_pip_package' failed; build aborted: no such package '@icu//': java.io.IOException: Error downloading [https://mirror.bazel.build/github.com/unicode-org/icu/archive/release-62-1.tar.gz, https://github.com/unicode-org/icu/archive/release-62-1.tar.gz] to C:/users/USERNAME/_bazel_USERNAME/xv6zejqw/external/icu/release-62-1.tar.gz: Checksum was AAAAA but wanted BBBBB
- 値の書き換えを行ってから再度実行する。
- 具体的には、 /d/tensorflow/third_party/icu/workspace.bzl をテキストエディタで開き、sha256の値を、"BBBBB"から"AAAAA"に変更する。
- 関連情報:https://github.com/tensorflow/tensorflow/issues/24135
・以下のようなwindows.hが見つからないエラーが出た場合 (2021.02.22追記)
external/grpc/include\grpc/impl/codegen/port_platform.h(52): fatal error C1083: Cannot open include file: 'windows.h': No such file or directory
- Microsoft Visual Studio本体をインストールしてやり直す。
-
やり直し方:一度
PCを再起動bazel shutdown
し、以下の2つのディレクトリを削除し、**STEP 7-2.**から再開する。
・C:\Users\USERNAME\_bazel_USERNAME
・D:\tensorflow
・以下のようなエラーが出た場合 (2021.02.27追記)
ERROR: D:/tensorflow/tensorflow/python/BUILD:276:1: C++ compilation of rule '//tensorflow/python:bfloat16_lib' failed (Exit 2): msvc_wrapper_for_nvcc.bat failed: error executing command
- Microsoft Visual StudioとCUDAの噛み合わせが悪い場合に発生?
- Microsoft Visual Studio本体をインストールし、CUDAのインストーラを再度起動して再インストールしてやり直す。(やり直し方は上の項目と同じ)
・以下のようなos.symlinkのエラーが出た場合 (2021.11.12追記)
os.symlink(os.path.abspath(from_path), os.path.abspath(to_path))
OSError: symbolic link privilege not held
- Python 3.8以上にする必要があり、それでも「クライアントは要求された特権を保有していません。」というOSエラーが出る場合は以下をONにする。
- Windowsの設定>更新とセキュリティ>開発者向け>開発者用モード
・以下のようなmodel_analyzer.ccのエラーが出た場合 (2021.11.12追記)
analyzer_wrapper/model_analyzer.cc(166): error C2001: 定数が 2 行目に続いています。
- 該当ソースコードの対象行を1行に修正する。
8-3. ビルドを実行する (長時間かかる)
bash bazel-bin/tensorflow/tools/pip_package/build_pip_package /c/tmp/tensorflow_pkg
8-4. TensorFlowをインストールする
cd /c/tmp/tensorflow_pkg
pip install tensorflow-X.X.X-cp3X-cp3Xm-win_amd64.whl
STEP 9: TensorFlow C APIを利用するために
9-1. libtensorflowをビルドする
cd /d/tensorflow/
bazel build --config opt //tensorflow/tools/lib_package:libtensorflow
[A]
-
以下にtensorflow.dllが生成される。
C:¥msys64¥home¥USERNAME¥_bazel_USERNAME¥26orbg4z¥execroot¥org_tensorflow¥bazel-out¥x64_windows-opt¥bin¥tensorflow -
tensorflow.libが必要な場合は、同じく生成されるtensorflow.dll.if.libをtensorflow.libにリネームすれば使える様子。
-
c_api.hなどのヘッダファイル類は以下に格納されている。
C:¥msys64¥home¥USERNAME¥_bazel_USERNAME¥26orbg4z¥execroot¥org_tensorflow¥tensorflow¥c
[B]
-
以下にtensorflow.soが生成される。
C:¥User¥USERNAME¥_bazel_USERNAME¥26orbg4z¥execroot¥org_tensorflow¥bazel-out¥x64_windows-opt¥bin¥tensorflow
(tensorflow.dllが生成されないため、これをlibファイルに変換する必要がある) -
c_api.hなどのヘッダファイル類は以下に格納されている。
C:¥User¥USERNAME¥_bazel_USERNAME¥26orbg4z¥execroot¥org_tensorflow¥tensorflow¥c
STEP 9B: soファイルをdllファイルに変換する([B]のみ)
9B-1. soファイルの情報をdumpする
dumpbinコマンドでlibtensorflow.soファイルの情報を書き出す。
cd C:\Users\USERNAME\_bazel_USERNAME\26orbg4z\execroot\org_tensorflow\bazel-out\x64_windows-opt\bin\tensorflow\
dumpbin /exports libtensorflow.so > dump.txt
dump.txtの中身の例:
Microsoft (R) COFF/PE Dumper Version 14.00.24215.1
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file libtensorflow.so
File Type: DLL
Section contains the following exports for libtensorflow.so
00000000 characteristics
5C9C9ABD time date stamp Xxx Xxx XX hh:mm:ss YYYY
0.00 version
1 ordinal base
3078 number of functions
3078 number of names
ordinal hint RVA name
1 0 0256DD00 ??0?$MaybeStackArray@D$0CI@@icu_62@@AEAA@AEBV01@@Z
2 1 02E5A0B0 ??0?$MaybeStackArray@D$0CI@@icu_62@@QEAA@$$QEAV01@@Z
3 2 02E5A110 ??0?$MaybeStackArray@D$0CI@@icu_62@@QEAA@H@Z
4 3 02E5A190 ??0?$MaybeStackArray@D$0CI@@icu_62@@QEAA@XZ
…以下略
9B-2. dumpファイルから関数のシンボル情報を抽出したdefファイルを作成する
dump.txtのnameの列が関数名にあたるので、これを適当な方法で(文字列置換とExcelを駆使しても良い)すべて抽出し、以下のような書式でtensorflow.defとして保存する。
LIBRARY tensorflow
EXPORTS
??0?$MaybeStackArray@D$0CI@@icu_62@@AEAA@AEBV01@@Z
??0?$MaybeStackArray@D$0CI@@icu_62@@QEAA@$$QEAV01@@Z
??0?$MaybeStackArray@D$0CI@@icu_62@@QEAA@H@Z
??0?$MaybeStackArray@D$0CI@@icu_62@@QEAA@XZ
??0Appendable@icu_62@@QEAA@AEBV01@@Z
…以下略
9B-3. libファイルを作成する
VCツールのlib.exeを利用する。
lib /def:tensorflow.def /machine:x64
9B-4. dllファイルを作成する
dumpしていたファイル(libtensorflow.so)をコピーまたはリネームする。
copy libtensorflow.so tensorflow.dll