Help us understand the problem. What is going on with this article?

TensorFlow をソースからコンパイルして CUDA 10 対応にする

More than 1 year has passed since last update.

この記事は以下の記事の一部分です。長くなるのでここは別記事にしました。
Ubuntu 18.04.1 LTS に Keras をインストールする
CUDA 10.0、cuDNN のインストール、環境設定、は上記の記事を参照してください。

概要

CUDA 10 に対応させたいので、TensorFlow をソースからコンパイルします。本家は以下になります。
Build from source
以下が参考になります。ただし情報が古くなっているところがあります。
How to install Tensorflow GPU with CUDA 10.0 for python on Ubuntu
日本語では以下が参考になります。ただし情報が古くなっているところがあります。
TensorFlow をソースからコンパイル 20180917版

事前準備

CPUコア16個ではビルドに1時間以上かかりました。24個までしかやっていないですが24個にすると1時間以下になりました。CPUコア数と同じだけ同時コンパイルする様なので、クラウドの利点を生かして、コンパイルの前に最大限にVMのCPUの数を増やしておいた方が良いです。試してないですが、例えば64個とかにすると20分ぐらいで終わるのでは、と思います。

Bazel をインストール

以下に従って自分のホームディレクトリにインストールします。
Installing Bazel on Ubuntu
なお、本家には書いてないのですが、最新バージョンの Bazel を使うとなぜかビルドエラーになるので、旧バージョンの 0.18.1 をインストールします。上記のインストール例では自分のディレクトリにインストールしていますのでそれを踏襲します。.bashrc に path を追加しています。(12/1追記:公式にはTensorFlow 1.12.0 は Bazel 0.15.0 でビルドテストされている)

$ wget https://github.com/bazelbuild/bazel/releases/download/0.18.1/\
bazel-0.18.1-installer-linux-x86_64.sh
$ chmod +x bazel-0.18.1-installer-linux-x86_64.sh
$ ./bazel-0.18.1-installer-linux-x86_64.sh --user
$ sed -i -e '$ a export PATH="$PATH:$HOME/bin"' .bashrc
$ source .bashrc

必要なパッケージをインストール

下の3つのバージョン指定はビルドエラー回避で必要なようです。一番下は本家には書いてないのですが、必要なようです。

$ sudo pip3 install pip six numpy wheel mock
$ sudo pip3 install keras_applications==1.0.5 --no-deps
$ sudo pip3 install keras_preprocessing==1.0.3 --no-deps
$ sudo pip3 install h5py==2.8.0

GitHubから最新のtensorflowを持ってくる

以下で持ってきます。

$ git clone https://github.com/tensorflow/tensorflow
$ cd tensorflow
$ git checkout r1.12

./configure

以下の中の、"Configure the build" を参考に ./configure します。
Build from source

$ ./configure

configureの途中で Compute Capability を聞かれます。GCP で使われている Tesla GPU の Compute Capability は以下の様になっています。使用している GPU の値を入れます。使っている GPU を検出して自動的にデフォルト値が入る様なので、Enterでいけます。

GPU Compute Capability
T4 7.5
V100 7.0
P100 6.0
P4 6.1
K80 3.7

その他は以下の4箇所だけ入力して、それ以外は Enter でいけました。

Please specify the location of python. [Default is /usr/bin/python]: /usr/bin/python3

ここは、自分は python3 しか使わないので、/usr/bin/python3

Do you wish to build TensorFlow with CUDA support? [y/N]: y

ここは当然 y です。

Please specify the CUDA SDK version you want to use. [Leave empty to default to CUDA 9.0]: 10

ここは CUDA 10 をインストールしたので 10 です。

Please specify the NCCL version you want to use. \
If NCCL 2.2 is not installed, then you can use version 1.3 that can be fetched\
 automatically but it may have worse performance with multiple GPUs. [Default is 2.2]: 1.3

デフォルトは2.2との事ですが、そもそも CUDA 10 対応の 2.2 はありませんでした。最新版の 2.3 をインストールしています。試しに 2.3 といれたらエラーになりました。2.3.7と入れてもやっぱりダメでした。1.3 が使える、との事なので 1.3 と入力しました。

pip パッケージビルド

以下の中の、"Build the pip package" を参考にビルドします。
Build from source

$ time bazel build --verbose_failures --config=opt --config=cuda\
 //tensorflow/tools/pip_package:build_pip_package

以下の様な感じで、CPU使用率100%に張り付いた状態で、約50分かかりました。CPUコア数と同じだけ同時コンパイルする様です。クラウドの利点を生かして、コンパイルの時は最大限にCPUの数を増やした方が良さそうです。
image.png
なお、使用したマシンタイプは以下です。
マシンタイプ : vCPU x 24、メモリ 156GB
CPU プラットフォーム : Intel Skylake

次にpipのパッケージを作ります。オプション --project_name でパッケージ名称を設定できます。
ここでは、"--project_name tensorflow_gpu_cuda_10.0" としてみました。

$ bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg\
 --project_name tensorflow_gpu_cuda_10.0

後ろに文字が自動的に追加されて、
tensorflow_gpu_cuda_10.0-1.12.0-cp36-cp36m-linux_x86_64.whl
というファイルになりました。

pip パッケージインストール

既にインストールしてある場合は、今インストールされているものをアンインストールしてからインストールします。

$ sudo pip3 uninstall tensorflow  # remove current version
$ sudo pip3 install /tmp/tensorflow_pkg/tensorflow_gpu_cuda_10.0-1.12.0-cp36-cp36m-linux_x86_64.whl

CUDA 10.0 対応 tensorflow の動作確認

動作確認はビルドしたディレクトリから出て行う必要があります。出ないとエラーが出て実行できません。
まず、バージョンを確認してみます。 1.12.0 と表示されるはずです。

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

接続されているGPUを確認します。
GPUの種類、メモリ量、compute capability、などが表示されます。

$ python3 -c "import tensorflow as tf; print(tf.contrib.eager.num_gpus())"

Hello, TensorFlow! してみます。

import tensorflow as tf
hello = tf.constant('Hello, TensorFlow!')
sess = tf.Session()
print(sess.run(hello))

以下にある、tensorflow.org のチュートリアルをやってみます。
https://www.tensorflow.org/tutorials/

import tensorflow as tf
mnist = tf.keras.datasets.mnist

(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(512, activation=tf.nn.relu),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=5)
model.evaluate(x_test, y_test)

以上です。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away