Edited at

Ubuntu18.04にCUDA9.0とcuDNN7.0.5を入れて、Tensorflow-gpuを動かす


まず簡潔に

Ubuntu18.04を前提として、Tensorflow-gpu環境構築で行うことは主に以下の5つです

・Nvidia driverの導入

・CUDAの導入

・cuDNNの導入

・Anacondaの導入

・Tensorflow-gpuの導入

これらの操作は以下に記載している参考リンクが非常に参考になります。

こちらの記事を参考に環境構築を行った後であることを、本記事では前提とします。

環境構築を行い、実際にコードを書いて何かしらの学習をスタートさせると、

「Tensorflow-gpuはcuDNN7.0向けに設計されているが、実際に環境にインストールされているのはcuDNN7.3ですよ」

とのエラーを受け、学習がスタートしないという問題がありました。

解決の結論としては、

「Tensorflow-gpuのバージョンごとに、cuDNNバージョンが指定されているので、正しいcuDNNを入れましょう」

ということです。

上記の内容を以下で詳しく書いていきます。


実施環境

Ubuntu 18.04.1 LTS

Celeron G3930

NVIDIA Geforce GTX1080

CUDA 9.0

cuDNN 7.0.5

Python 3.6.7

Tensorflow-gpu 1.5.0(1.6.0以上では、CPUによる動作制限があるようです)

Keras 2.2.4


参考リンク

環境構築の全体の流れがとても整理されている記事です

https://qiita.com/sho8e69/items/66c1662c49ac89a024be#ubuntu%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB

このあたりのQ&Aを読むとかなりヒントがあります

https://groups.google.com/forum/m/#!topic/keras-users/kfzPSDvmhPo

https://stackoverflow.com/questions/37663064/cudnn-compile-configuration-in-tensorflow

今回、Tensorflow-gpu 1.5.0を入れている理由です

http://arakan-pgm-ai.hatenablog.com/entry/2018/06/21/090000


具体的なエラー

上記で紹介した、

「Tensorflow-gpuはcuDNN7.0向けに設計されているが、実際に環境にインストールされているのはcuDNN7.3ですよ」

とは具体的に一体どういうものなのか示します。

2018-11-06 18:00:04.565740: E

tensorflow/stream_executor/cuda/cuda_dnn.cc:378] Loaded runtime CuDNN library: 7300 (compatibility version 7300) but source was compiled with 7004 (compatibility version 7000).
If using a binary install, upgrade your CuDNN library to match.
If building from sources, make sure the library loaded at runtime matches a compatible version specified during compile configuration.
2018-11-06 18:00:04.566903: F
tensorflow/core/kernels/conv_ops.cc:717] Check failed: stream->parent()->GetConvolveAlgorithms( conv_parameters.ShouldIncludeWinogradNonfusedAlgo<T>(), &algorithms)
中止 (コアダンプ)

これです、このエラーの意味が、

「Tensorflow-gpuはcuDNN7.0向けに設計されているが、実際に環境にインストールされているのはcuDNN7.3ですよ」

となります。


解決

エラーの意味がわかったので、解決していきます。

Tensorflow-gpuが本当にcuDNN7.0向けに設計されているかどうかの確認は置いておいて、

ローカル環境にインストールされているcuDNNのバージョンを確認しましょう。

以下のコードをターミナルに入力します。

$ dpkg -l | grep cuda

出力は以下のようになりました。

ii  cuda-command-line-tools-9-0                9.0.176-1                                   amd64        CUDA command-line tools

ii cuda-core-9-0 9.0.176-1 amd64 CUDA core tools
ii cuda-cublas-9-0 9.0.176-1 amd64 CUBLAS native runtime libraries
ii cuda-cublas-dev-9-0 9.0.176-1 amd64 CUBLAS native dev links, headers
ii cuda-cudart-9-0 9.0.176-1 amd64 CUDA Runtime native Libraries
ii cuda-cudart-dev-9-0 9.0.176-1 amd64 CUDA Runtime native dev links, headers
ii cuda-cufft-9-0 9.0.176-1 amd64 CUFFT native runtime libraries
ii cuda-cufft-dev-9-0 9.0.176-1 amd64 CUFFT native dev links, headers
ii cuda-curand-9-0 9.0.176-1 amd64 CURAND native runtime libraries
ii cuda-curand-dev-9-0 9.0.176-1 amd64 CURAND native dev links, headers
ii cuda-cusolver-9-0 9.0.176-1 amd64 CUDA solver native runtime libraries
ii cuda-cusolver-dev-9-0 9.0.176-1 amd64 CUDA solver native dev links, headers
ii cuda-cusparse-9-0 9.0.176-1 amd64 CUSPARSE native runtime libraries
ii cuda-cusparse-dev-9-0 9.0.176-1 amd64 CUSPARSE native dev links, headers
ii cuda-documentation-9-0 9.0.176-1 amd64 CUDA documentation
ii cuda-driver-dev-9-0 9.0.176-1 amd64 CUDA Driver native dev stub library
ii cuda-libraries-dev-9-0 9.0.176-1 amd64 CUDA Libraries 9.0 development meta-package
ii cuda-license-9-0 9.0.176-1 amd64 CUDA licenses
ii cuda-misc-headers-9-0 9.0.176-1 amd64 CUDA miscellaneous headers
ii cuda-npp-9-0 9.0.176-1 amd64 NPP native runtime libraries
ii cuda-npp-dev-9-0 9.0.176-1 amd64 NPP native dev links, headers
ii cuda-nvgraph-9-0 9.0.176-1 amd64 NVGRAPH native runtime libraries
ii cuda-nvgraph-dev-9-0 9.0.176-1 amd64 NVGRAPH native dev links, headers
ii cuda-nvml-dev-9-0 9.0.176-1 amd64 NVML native dev links, headers
ii cuda-nvrtc-9-0 9.0.176-1 amd64 NVRTC native runtime libraries
ii cuda-nvrtc-dev-9-0 9.0.176-1 amd64 NVRTC native dev links, headers
ii cuda-repo-ubuntu1704-9-0-local 9.0.176-1 amd64 cuda repository configuration files
ii cuda-samples-9-0 9.0.176-1 amd64 CUDA example applications
ii cuda-toolkit-9-0 9.0.176-1 amd64 CUDA Toolkit 9.0 meta-package
ii cuda-visual-tools-9-0 9.0.176-1 amd64 CUDA visual tools
ii libcudnn7 7.3.0.29-1+cuda9.0 amd64 cuDNN runtime libraries
ii libcudnn7-dev 7.3.0.29-1+cuda9.0 amd64 cuDNN development libraries and headers
ii libcudnn7-doc 7.3.0.29-1+cuda9.0 amd64 cuDNN documents and samples

下3つにcuDNNのバージョンが記載されています。

libcudnn7、libcudnn7-dev、libcudnn7-docの3つです。

バージョンは7.3のようです。

エラーの意味は、

「Tensorflow-gpuはcuDNN7.0向けに設計されているが、実際に環境にインストールされているのはcuDNN7.3ですよ」

だったので、

「7.3を消して7.0を入れる」

ことを目指せばエラーが解消されそうです。

以下のコードで、cuDNN7.3を消しましょう

$ sudo apt-get --purge remove libcudnn7

この操作だけで、libcudnn7、libcudnn7-dev、libcudnn7-docの3つが消去されます。

次に、cuDNN7.0を入れていきます。

が、実際に入れるのはcuDNN7.0.5です。

cuDNNダウンロードリンクからダウンロードします。

Screenshot from 2018-11-07 10-57-19.png

「Download cuDNN v7.0.5 [Dec 5, 2017], for CUDA 9.0」を選択肢するとプルダウンが現れます。

Screenshot from 2018-11-07 11-01-01.png

「cuDNN v7.0.5 Runtime Library for Ubuntu16.04 (Deb)」、

「cuDNN v7.0.5 Developer Library for Ubuntu16.04 (Deb)」、

「cuDNN v7.0.5 Code Samples and User Guide for Ubuntu16.04 (Deb)」

の3つをダウンロードします。

ターミナル上で保存先のディレクトリに移動し、

以下のコマンドを実行すると、cuDNN7.0.5がインストールされます。

$ sudo dpkg -i libcudnn7_7.0.5.15-1+cuda9.0_amd64.deb

$ sudo dpkg -i libcudnn7-dev_7.0.5.15-1+cuda9.0_amd64.deb
$ sudo dpkg -i libcudnn7-doc_7.0.5.15-1+cuda9.0_amd64.deb

cuDNNのバージョンを確認してみましょう。

以下のコマンドで確認します。

$ dpkg -l | grep cuda

出力は以下です。cuDNN以外の部分は省略しました。

ii  libcudnn7                                  7.0.5.15-1+cuda9.0                          amd64        cuDNN runtime libraries

ii libcudnn7-dev 7.0.5.15-1+cuda9.0 amd64 cuDNN development libraries and headers
ii libcudnn7-doc 7.0.5.15-1+cuda9.0 amd64 cuDNN documents and samples


GPU動作の確認

ここまでで、問題だったエラー

「Tensorflow-gpuはcuDNN7.0向けに設計されているが、実際に環境にインストールされているのはcuDNN7.3ですよ」

が解決されているはずです。

実際にGPU動作を確認してみましょう。

pythonコンソールの起動

$ python

Tesorflowのインポート

GPU認識確認

>>> import tensorflow as tf

>>> tf.test.gpu_device_name()

以下が表示されるか確認してください。

'/device:GPU:0'

さあ、GPU動作を確認しましょう。

以下のコードが書かれたpythonファイルを作成し、実行してください。

引用:https://www.kaggle.com/getting-started/47096#post271139


GPU_performance_check.py

import tensorflow as tf

import timeit

# See https://www.tensorflow.org/tutorials/using_gpu#allowing_gpu_memory_growth
config = tf.ConfigProto()
config.gpu_options.allow_growth = True

with tf.device('/cpu:0'):
random_image_cpu = tf.random_normal((100, 100, 100, 3))
net_cpu = tf.layers.conv2d(random_image_cpu, 32, 7)
net_cpu = tf.reduce_sum(net_cpu)

with tf.device('/gpu:0'):
random_image_gpu = tf.random_normal((100, 100, 100, 3))
net_gpu = tf.layers.conv2d(random_image_gpu, 32, 7)
net_gpu = tf.reduce_sum(net_gpu)

sess = tf.Session(config=config)

# Test execution once to detect errors early.
try:
sess.run(tf.global_variables_initializer())
except tf.errors.InvalidArgumentError:
print(
'\n\nThis error most likely means that this notebook is not '
'configured to use a GPU. Change this in Notebook Settings via the '
'command palette (cmd/ctrl-shift-P) or the Edit menu.\n\n')
raise

def cpu():
sess.run(net_cpu)

def gpu():
sess.run(net_gpu)

# Runs the op several times.
print('Time (s) to convolve 32x7x7x3 filter over random 100x100x100x3 images '
'(batch x height x width x channel). Sum of ten runs.')
print('CPU (s):')
cpu_time = timeit.timeit('cpu()', number=10, setup="from __main__ import cpu")
print(cpu_time)
print('GPU (s):')
gpu_time = timeit.timeit('gpu()', number=10, setup="from __main__ import gpu")
print(gpu_time)
print('GPU speedup over CPU: {}x'.format(int(cpu_time/gpu_time)))

sess.close()


以下のような結果が表示されれば、GPUが確かに動作しており、

CPUとGPUの処理時間の比較結果が見れます。

CPU (s):

8.017979502001253
GPU (s):
2.884423554998648
GPU speedup over CPU: 2x


まとめ

参考リンクを前提としてTensorflow-gpu環境構築を行った後、いざ学習してみようとしたら、

「Tensorflow-gpuが想定しているcuDNNのバージョンと、実際のcuDNNのバージョンが異なる」

ことに起因するエラーについて、解決策を示しました。

バージョンに関して、互換性・整合性をちゃんと確認しなければいけないなと思いました。

誰かのご参考になれば幸いです。