Windows で TensorFlow for C および TensorFlow for Go をビルドする方法

はじめに

この手順では、TensorFlow for C v2.4.1 (CPU only) をソースからビルドするという、茨の道を進むことになる。
なお、ここで記載した手順や、ツール等が、不足している場合があるかもしれない。

以降の手順では、TensorFlow for C のビルドには、Visual Studio を利用する。
Go 言語の cgo では、MinGW64 の gcc を利用する。

利用ツール等

  • Visual Studio 2019
  • Git for Windows
  • scoop
    • golang や、msys2 等のツールをインストールするための、パッケージ管理ツール
  • protobuf 3.15.6
  • python 3.8.8
  • golang 1.16
  • bazelisk
    • bazel のラッパーツール。ソースで利用しているバージョンで bazel を実行する。
  • msys2
    • mingw64

事前準備

Visual Studio 2019 のインストール

Visual Studio ダウンロードページ で以下のようにダウンロードする。
「すべてのダウンロード」から「Visual Studio 2019 のツール」をクリックし、ツリーを開く。
「Build Tools for Visual Studio 2019」のダウンロードボタンを押下し、インストーラをダウンロードする。

インストーラを起動する。
C++ Build Tools を選択し、以下のオプションをチェックする。
  • MSVC v142 - VS 2019 C++ x64/x86 ビルドツール
  • Windows 10 SDK (10.0.19041.0)
  • Windows 用 C++ Cmake ツール
当環境では、1 ソースファイルのコンパイルにコンパイラの使用メモリが 3 GB を超えて、何時間経過しても完了しないという症状が発生した。 タスクマネージャで見る限り、「Microsoft VC compiler and tools experience improvement data uploader(vctip.exe)」というプロセスが、 残り続けているようだ。このプロセスは、タスクの終了では、消すことができず、OS の再起動を行わないと消えなかった。
vctip.exe は、Visual Studio の改善情報を Microsoft が収集するプログラムのようなので、 この機能を無効にする対応をした。
ただ、依然として時折 vctip.exe のプロセスが発生し、大幅に回数は減ったとは言え、1 回以上プロセスが残り続ける減少が発生し、停止→再ビルドの手順を行わなければならなかった。
しかしながら、ビルドが完了しない事態からは脱した。

Git for Windows のインストール


scoop のインストール

インストール方法は、Scoop サイト を参照。

インストール中に PATH などの環境変数が変更されるので、PowerShell を閉じる。
Scoop は、PowerShell でも cmd でも利用できる。
以後の手順では、特に指定が無い場合、cmd を利用する。
Scoop でインストールしたパッケージは、%USERPROFILE%\scoop\ 以下に格納される。
scoop ディレクトリには、以下のディレクトリが含まれている。
  • apps
    • インストールしたパッケージの本体がディレクトリ毎に格納される。
  • buckets
    • バケット情報が格納されている。
  • cache
    • Scoop のキャッシュが格納されている。
  • persist
    • パッケージによって、永続化情報が格納される先。msys2 では、home ディレクトリなどが格納されている。
  • shims
    • インストールしたパッケージに含まれる、実行ファイルなどが格納される。

scoop の設定

各種パッケージをインストールする前の準備を行う。
scoop のバケットを追加する。
バケットとは、パッケージ群が登録されているリポジトリのようなもの。
scoop の標準(main)バケットは、原則、最新のバージョンのみであるため、以前のバージョンを利用できるようになったりする。
  scoop bucket add versions
  scoop bucket add extras
  scoop update
  scoop update *
  scoop cleanup *

scoop でツールをインストール

  scoop install protobuf python38 go msys2
PATH などが変更されるので、コンソールを起動し直す。

golang でツールをインストール

go get github.com/bazelbuild/bazelisk

msys2 でツールをインストール

%USERPROFILE%\scoop\apps\msys2\current\msys2.exe で msys コンソールを起動する。
次に、パッケージをアップデートする。
  pacman -Syyu
アップデート完了後、msys コンソールが閉じるので、msys コンソールを立ち上げ直して、再びアップデートコマンドを実行する。
  pacman -Syyu
必要なツールをインストールする。
  pacman -S patch unzip
msys コンソールを閉じる

Python Virtual Environment を作成

numpy のバージョンは、この TensorFlow に対応するバージョンとマイナーバージョンが異なると、実行時にエラーとなる。
  python3 -m venv %USERPROFILE%\venv
  %USERPROFILE%\venv\Scripts\activate
  python -m pip install --upgrade pip
  python -m pip install six wheel
  python -m pip install numpy~=1.19.5
  python -m pip install keras_applications==1.0.6 --no-deps
  python -m pip install keras_preprocessing==1.0.5 --no-deps

インストールしたパッケージのバージョンは、以下となる。

Package             Version
------------------- -------
Keras-Applications  1.0.6
Keras-Preprocessing 1.0.5
numpy               1.19.5
pip                 21.0.1
setuptools          49.2.1
six                 1.15.0
wheel               0.36.2

ビルド手順

共通手順

以降の手順共通で以下を行う。
  スタートメニュー → Visual Studio 2019 → x64 Native Tools Command Prompt for VS 2019 を実行
  set GO111MODULE=off
  set PATH=%USERPROFILE%\scoop\apps\msys2\current\mingw64\bin;%USERPROFILE%\scoop\apps\msys2\current\usr\bin;%PATH%
  set PYTHON_BIN_PATH=%USERPROFILE%/venv/Scripts/python.exe
  %USERPROFILE%\venv\Scripts\activate
  set _OLD_VIRTUAL_PATH=

ソースを準備

  go get -d github.com/tensorflow/tensorflow
  cd /d %USERPROFILE%\go\src\github.com\tensorflow\tensorflow
  git checkout r2.4

  %USERPROFILE%\go\src\github.com\tensorflow\tensorflow\configure.py
  ファイルを以下のように変更する。
  
  478 行目
  if which('bazel') is None:
   ↓
  if which('bazelisk') is None:
  
  483 行目
  curr_version = run_shell(['bazel', '--version'],
   ↓
  curr_version = run_shell(['bazelisk', '--version'],


  %USERPROFILE%\go\src\github.com\tensorflow\tensorflow\tensorflow\go\genop\generate.go
  ファイルを以下のように変更する。

  1 行目に以下を追加。2 行目は、必ず空行を追加する。
  // +build !windows

TensorFlow for C をビルド

local_cpu_resources オプションに指定する値は、並列数となる。PC の性能に合わせて適宜変更する。空きメモリ量は、並列数× 2 GB 以上になる場合がある。
  cd /d %USERPROFILE%\go\src\github.com\tensorflow\tensorflow

  configure.cmd
  # 質問には、すべて Enter を押下する

  bazelisk build --local_cpu_resources=6 --config=opt --config=short_logs //tensorflow/tools/lib_package:libtensorflow

ビルドを停止する場合は、Ctrl + C とする。再実行時に、「Another command (pid=xxxxx) is running. Waiting for it to complete on the server...」のような場合は、 タスクマネージャを開き、プロセスから、Windows コマンドプロセッサ → OpenJDK Platform binary のタスクを終了する。 再実行しても、進まない場合は、bazelisk clean コマンドでキャッシュをクリアする。

ビルド時間は、当環境(CPU:AMD FX(tm)-8350、4000 Mhz、4 物理コア、8 論理コア、メモリ:24 GB)で、およそ 2 時間程度かかった(9753 ビルドアクション)。

生成された DLL を C:\Windows\System32\ にコピーする。管理者権限が必要となる。
  %USERPROFILE%\go\src\github.com\tensorflow\tensorflow\bazel-bin\tensorflow\tensorflow.dll
  %USERPROFILE%\go\src\github.com\tensorflow\tensorflow\bazel-bin\tensorflow\tensorflow_framework.dll

TensorFlow Python pip package をビルド

Python パッケージは、Go では利用しないが、Python で TenforFlow で利用するデータの取得や加工等に利用することがある。
  cd /d %USERPROFILE%\go\src\github.com\tensorflow\tensorflow

  bazelisk build --local_cpu_resources=6 --config=opt --define=no_tensorflow_py_deps=true --config=short_logs //tensorflow/tools/pip_package:build_pip_package
  bazel-bin\tensorflow\tools\pip_package\build_pip_package C:/tmp/tensorflow_pkg
  python -m pip install C:/tmp/tensorflow_pkg/tensorflow-2.4.1-cp38-cp38-win_amd64.whl

TensorFlow for Go をビルド

  cd /d %USERPROFILE%\go\src\github.com\tensorflow\tensorflow
  go generate github.com/tensorflow/tensorflow/tensorflow/go/op
  # テストする
  go test github.com/tensorflow/tensorflow/tensorflow/go

  # Go モジュールを有効にして TensorFlow を利用するために必要
  robocopy %USERPROFILE%\go\src\github.com\tensorflow\tensorflow\tensorflow\go\vendor\github.com\tensorflow\tensorflow\tensorflow\go\core %USERPROFILE%\go\src\github.com\tensorflow\tensorflow\tensorflow\go\core /s /e
  robocopy %USERPROFILE%\go\src\github.com\tensorflow\tensorflow\tensorflow\go\vendor\github.com\tensorflow\tensorflow\tensorflow\go\stream_executor %USERPROFILE%\go\src\github.com\tensorflow\tensorflow\tensorflow\go\stream_executor /s /e

  set GO111MODULE=
  go mod init github.com/tensorflow/tensorflow

TensorFlow for Go を利用するプロジェクトの作成

  mkdir %USERPROFILE%\go\src\hello-tf
  cd /d %USERPROFILE%\go\src\hello-tf
  set GO111MODULE=
  go mod init hello-tf
go.mod ファイルの最期に以下の行を追加する。
  replace github.com/tensorflow/tensorflow => ../github.com/tensorflow/tensorflow
hello_tf.go ファイルを以下の内容で作成する。
package main

import (
	"fmt"
	tf "github.com/tensorflow/tensorflow/tensorflow/go"
	"github.com/tensorflow/tensorflow/tensorflow/go/op"
)

func main() {
	s := op.NewScope()
	c := op.Const(s, "Hello from TensorFlow version "+tf.Version())
	graph, err := s.Finalize()
	if err != nil {
		panic(err)
	}

	sess, err := tf.NewSession(graph, nil)
	if err != nil {
		panic(err)
	}
	output, err := sess.Run(nil, []tf.Output{c}, nil)
	if err != nil {
		panic(err)
	}
	fmt.Println(output[0].Value())
}
実行する
  go mod tidy
  go run hello_tf.go
  
  Hello from TensorFlow version 2.4.1

IntelliJ + Go プラグインでプロジェクトを作成

IntelliJ の Plugins で、「Go」プラグインをインストールする。
IntelliJ を再起動する。
File メニュー → New → Project...
New Project ウィンドウで、「Go Modules」を選択

Environment:に以下を設定する。
「C:\Users\username」の部分は、%USERPROFILE% の値に合わせること。

PATH=C:\Users\username\scoop\apps\msys2\current\mingw64\bin

「Next」ボタンを押下する。

Project location: に以下を設定する。
「C:\Users\username」の部分は、%USERPROFILE% の値に合わせること。

C:\Users\username\go\src\hello-tf2

「Finish」ボタンを押下する。
ディレクトリを作成の問合せには Create ボタンを押下する。

go.mod ファイルおよび、hello_tf.go ファイルは、前述の手順と同様に、追加および、作成を行う。

依存モジュールの解決ができないため、hello_tf.go でエラーとなる。
これを解消するために、go.mod をファイルツリーで右クリックし、「Go Mod Tidy」を選択する。
処理が完了すると、依存ライブラリが、go.mod に定義され、エラーが消える。

hello_tf.go ファイルをファイルツリーで右クリックし、
「Run 'go build hello_tf.go...'」を選択する。
ビルド後に、実行され、以下のように表示される。
Hello from TensorFlow version 2.4.1

参考サイト