概要
基本的な指針はTensorflowでOSXのGPUが対応されたよに従う。
2016年12月5日現在で、 Brew で CUDA を入れると、そのバージョンは 8.0 になるようだった。公式のDownload and Setupの手順ではうまくいかなかったので、この gist のこのコメントを参考にする。
セットアップ
Python 3.5 のインストール
Python は最近使っていなかったので、今回は 3.5 をインストールすることにする。 Mac ではデフォルトで Python 2.x が入っているので、 pyenv を使うのが良いらしい1。
$ brew install pyenv
$ pyenv install 3.5.2
Downloading Python-3.5.2.tar.xz...
-> https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tar.xz
Installing Python-3.5.2...
BUILD FAILED (OS X 10.12 using python-build 20160602)
Inspect or clean up the working tree at /var/folders/__/37mkgf2x4t70wt679szztc5m0000gn/T/python-build.20161205163930.24297
Results logged to /var/folders/__/37mkgf2x4t70wt679szztc5m0000gn/T/python-build.20161205163930.24297.log
Last 10 log lines:
File "/private/var/folders/__/37mkgf2x4t70wt679szztc5m0000gn/T/python-build.20161205163930.24297/Python-3.5.2/Lib/ensurepip/__main__.py", line 4, in <module>
ensurepip._main()
File "/private/var/folders/__/37mkgf2x4t70wt679szztc5m0000gn/T/python-build.20161205163930.24297/Python-3.5.2/Lib/ensurepip/__init__.py", line 209, in _main
default_pip=args.default_pip,
File "/private/var/folders/__/37mkgf2x4t70wt679szztc5m0000gn/T/python-build.20161205163930.24297/Python-3.5.2/Lib/ensurepip/__init__.py", line 116, in bootstrap
_run_pip(args + [p[0] for p in _PROJECTS], additional_paths)
File "/private/var/folders/__/37mkgf2x4t70wt679szztc5m0000gn/T/python-build.20161205163930.24297/Python-3.5.2/Lib/ensurepip/__init__.py", line 40, in _run_pip
import pip
zipimport.ZipImportError: can't decompress data; zlib not available
make: *** [install] Error 1
zlib がないと言われたので、 xcode-select
する2。
$ xcode-select --install
$ pyenv install 3.5.2
$ pyenv global 3.5.2
$ python --version
Python 3.5.2
Python 3 は昔、 Pytho 2.x 向けに書かれたコードと互換性がないことを理由に触らないでいて、そのまま触れる機会がないままでいたけど、改めて調べてみたらそれほど大きな変更はなさそうだ3。
CUDA, Bazel, cuDNN のインストール
CUDA と cuDNN は TensorFlow が直接必要としている。 Bazel は TensorFlow のビルドに必要になる。
$ brew cask install cuda
$ brew install bazel
cuDNN は NVIDIA Developer に登録しないとダウンロードできない。
NVIDIA cuDNN から "Download" をクリックしてアニメでも見ながら頭を使わずに NVIDIA の指示に従っていれば、気づいたときには利用規約に同意した上で cudnn-8.0-osx-x64-v5.1.tgz
がダウンロードされているはずだ。
macOS 向けかつCUDA 8.0 向けのものをダウンロードすることに注意。困ったら、詳しい方法はTensorflowでOSXのGPUが対応されたよで紹介されている。
このアーカイブにはバイナリが入っているので、適切なディレクトリに移動しておく。
$ tar xvf cudnn-8.0-osx-x64-v5.1.tgz
$ sudo mv -v cuda/lib/libcudnn* /usr/local/cuda/lib
$ sudo mv -v cuda/include/cudnn.h /usr/local/cuda/include
$ sudo ln -s /usr/local/cuda/lib/libcudnn.5.dylib /usr/local/cuda/lib/libcudnn.5
$ cd /usr/local/lib
$ sudo ln -s libcuda.dylib libcuda.1.dylib
$ sudo ln -s ../cuda/lib/libcudart.8.0.dylib .
$ sudo ln -s /usr/local/cuda/lib/* /usr/local/lib
最後の3つの symlink は、もしかしたら今の TensorFlow のビルドシステムに問題があって必要なだけかもしれない。
1つ目(libcudnn.5
)は、張らないと configure
できない。
2つ目(libcuda.1.dylib
)は、 Bazel が長時間いい感じに進んだあとで、最後にビルドエラーになる。
3つ目の symlink は張らなくてもビルドはできるが、 TensorFlow をインポートしたときに segmentation fault を得ることになる。そのときに張っても良い。
4つ目の symlink も張らなくてもビルドはできる。 El Capitan 以降、 DYLD_LIBRARY_PATH
は System Itegrity Protection の加護により使えなくなったので、 CUDA 関係のライブラリはこの環境変数を使う代わりに、ロードパスにある場所から symlink しておく。
TensorFlow のインストール
ビルド対象のコードを得る。
$ git clone --recurse-submodules https://github.com/tensorflow/tensorflow
$ git pull --tags
$ git checkout 0.12.0-rc0
configure する。いくつか入力を求められるが、基本的にはデフォルトのままで良い。「GPU support を有効化するか?」という確認もあったはずだけど、この環境変数を渡した場合は、そこは自明だということなのか、入力は求められなかった。
自分の場合は「Python library path が複数見つかったがどれを使う?」という確認があったので、 pyenv を使って入れた 3.5 のパスを指定した。それ以外はデフォルトにした。
$ CUDA_TOOLKIT_PATH="/usr/local/cuda" CUDNN_INSTALL_PATH="/usr/local/cuda" TF_UNOFFICIAL_SETTING=1 TF_NEED_CUDA=1 TF_CUDA_COMPUTE_CAPABILITIES="3.0" TF_CUDNN_VERSION="5" TF_CUDA_VERSION="8.0" TF_CUDA_VERSION_TOOLKIT=8.0 ./configure
configure できたら、 bazel で pip パッケージをビルドして、 pip でインストールする。pyenv で入れても pip は sudo じゃないと permission error が出た。ここは rbenv と思想の違うところなのだろうか。
$ bazel build -c opt --config=cuda //tensorflow/tools/pip_package:build_pip_package
$ bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
$ pip3 install --upgrade /tmp/tensorflow_pkg/tensorflow-0.12.0rc0-cp35-cp35m-macosx_10_6_x86_64.whl
直接指定しても良いと思う。
いくつか実行時に必要なパスがあるので、 .bash_profile
に書いておく。
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/cuda/lib64:/usr/local/cuda/extras/CUPTI/lib64"
export CUDA_HOME=/usr/local/cuda
これで準備が整った。動作確認する。
$ python
Python 3.5.2 (default, Dec 5 2016, 16:46:59)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import tensorflow
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcublas.8.0.dylib locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcudnn.5.dylib locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcufft.8.0.dylib locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcuda.1.dylib locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcurand.8.0.dylib locally
CUDA 関係のライブラリがロードされている。とりあえずセットアップは完了したみたいだ。
動作確認
Hello World
公式の手順に従って動作確認する。
$ python
Python 3.5.2 (default, Dec 5 2016, 16:46:59)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import tensorflow as tf
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcublas.8.0.dylib locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcudnn.5.dylib locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcufft.8.0.dylib locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcuda.1.dylib locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcurand.8.0.dylib locally
>>> hello = tf.constant('Hello, TensorFlow!')
>>> sess = tf.Session()
E tensorflow/stream_executor/cuda/cuda_driver.cc:509] failed call to cuInit: CUDA_ERROR_NOT_INITIALIZED
I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:158] retrieving CUDA diagnostic information for host: ingrid.local
I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:165] hostname: ingrid.local
I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:189] libcuda reported version is: Not found: was unable to find libcuda.so DSO loaded into this program
I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:193] kernel reported version is: Invalid argument: expected %d.%d or %d.%d.%d form for driver version; got ""
>>> print(sess.run(hello))
b'Hello, TensorFlow!'
>>> a = tf.constant(10)
>>> b = tf.constant(32)
>>> print(sess.run(a + b))
42
>>>
GPU を活用して生命、宇宙、そして万物についての究極の疑問の答えを計算することができた。
MNIST
tensorflow.models.image.mnist.convolutional
を使って動作検証する。
$ python -m tensorflow.models.image.mnist.convolutional
(snip)
Minibatch loss: 1.598, learning rate: 0.006302
Minibatch error: 0.0%
Validation error: 0.9%
Test error: 0.8%
以前 CPU-only で試したときより早い…?
おまけ
import tensorflow
すると、 ImportError: cannot import name 'pywrap_tensorflow'
と言われる
TensorFlow のリポジトリがあるディレクトリで tensorflow
をロードするとこういうエラーが出る。別のディレクトリに言って試せば良い4
import tensorflow
すると、 segmentation fault 11
が起きる
libcuda.1.dylib
という名前でロードしようとするので、そのための symlink を作っておく5。
CPU-only TensorFlow のインストール
こっちはとても簡単。
$ pip3 install --upgrade https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-0.12.0rc0-py3-none-any.whl
-
ImportError: cannot import name pywrap_tensorflow
You're running the script in the same directory as tensorflow. Move it out and you should be fine.
-
Segmentation fault, import tensorflow, tensorflow 0.9, mac osx
Having the same problem, It appears that it fails when loading libcuda.dylib. Unfortunately, since #2878 it's now looking for libcuda.1.dylib instead.
Creating a symlink or changing the name of libcuda.dylib to libcuda.1.dylib in /usr/local/cuda/lib seems to do the job.