protonブログ

日々の記録やデバッグメモ

ThinkPadT480s(MX150)にCUDA10.0とTensorFlow-gpu1.13.1を入れた話

初めに

f:id:proton_1602:20190507194546j:plain
MX150
なんとなく手元でCUDAの実行確認とか簡単なものができたらいいなとか、適当なことを考えてCUDAが利用できるらしいGPU(MX150)が乗っているノートパソコン(ThinkPad T480s)を去年の夏頃に買ったのですが、CUDA周りは非常に面倒で失敗するとUbuntuが使い物にならなかったりするので怖くてしばらく放置してました。
しかし、cudaやcupyが手元で動かしたくなったのでCUDA等の環境構築をせざるを得なくなったので、その時のやり方等を残しておきます。
CUDA入れたのはこれで3回目ぐらいになるので、ある程度調べながらやったのですがそれでも失敗しました。初めに(恐らく)最適なやり方を書いて、その後に実際の経緯とか遭遇した問題書きます。

環境 & 入れたもの

  • ThinkPad T480s
  • Ubuntu 18.04 LTS
  • MX150
  • python 3.6.7
  • Nvidiaドライバ 418.56
  • CUDA 10.0
  • cuDNN 7.5.1
  • tensorflow-gpu 1.13.1

    やり方

    ubuntupythonの入れ方は省略します、調べればいっぱい出てくると思うので(忘れた)

    Update&Upgrade

    いつもの。とりあえずやっとく

$ sudo apt update
$ sudo apt upgrade

nouveau停止

cudaを使うためには、NVIDIAのドライバが必要ですが、デフォルトではnouveauとかいうドライバが入っているので止める必要がある。これをやらないと、ドライバインストールするときになんかnouveau止めろみたいなエラーでて止まる。

lsmod | grep -i

でnouveauがあったら、

blacklist nouveau
options nouveau modeset=0

を/etc/modprobe.d/blacklist-nouveau.confとして新規作製して、

$ sudo update-initramfs -u
$ reboot
$ lsmod | grep -i nouveau

でnouveauがでなくなることを確認する。

必要なものを入れておく

何に必要なのか忘れたけど、多分nvidiaドライバ

$ sudo apt install build-essential
$ sudo apt install dkms

CUDAインストール

NVIDIAドライバの前にCUDAを入れます。
https://www.tensorflow.org/install/source#common_installation_problems の下の方を見ると、今の最新のtensorflow-gpu-1.13.1にはCUDA10.0, cuDNN7.4が要求されるらしいので、 https://developer.nvidia.com/cuda-toolkit-archive からCUDA10.0を選択して、runファイルをダウンロードします。

$ chmod +x cuda_10.0.130_410.48_linux.run 
$ sudo ./cuda_10.0.130_410.48_linux.run --silent --toolkit --no-opengl-libs

--noのオプションがないと、ログインループになるらしい。
何か出てきたかメモしてないので覚えてないが、--silentを付けていれば何もなかったはず。(10.0ではそもそも付けないとエラーがでた。10.1では出ないで色々選択できたのでDriverのチェックを外せた。)
必要なのはCUDA Toolkit 10.0のみ、Samples, Demo Suite, Documentationは必要があれば入れる、Driverは入れないほうがいいはず。

export CUDA_HOME="/usr/local/cuda-10.0"
export PATH="$CUDA_HOME/bin:$PATH"
export LD_LIBRARY_PATH="/usr/local/lib:$CUDA_HOME/lib64:$LD_LIBRARY_PATH"
export CPATH="/usr/local/include:$CUDA_HOME/include:$CPATH"
export INCLUDE_PATH="$CUDA_HOME/include"

~/.bashrcの一番下の方に書き加えておく。いつものPATH通し

Nvidiaドライバインストール

https://www.nvidia.co.jp/Download/index.aspx?lang=jp から適したやつを入れる、2019/04/26時点では418.56でした。

$ sudo ./NVIDIA-Linux-x86_64-418.56.run --no-opengl-files --no-libglx-indirect --dkms

--noとかのオプションを忘れないように。忘れるとログインループ等の地獄を見ます。

cuDNNインストール

https://developer.nvidia.com/cudnn からLogin/JoinしてcuDNN7.4以上をダウンロードする。今回は最新の7.5.1にしました。(cuDNNで正しくバージョンを合わせなくて問題が起こったことはないが、CUDAと違ってこれのバージョンはそこまで気にする必要がない...?

$ tar xvzf cudnn-10.0-linux-x64-v7.5.1.10.tgz
$ sudo mv cuda/include/cudnn.h /usr/local/cuda-10.0/include/
$ sudo mv cuda/lib64/* /usr/local/cuda-10.0/lib64/

コピーするだけ。

確認

$ nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2018 NVIDIA Corporation
Built on Sat_Aug_25_21:08:01_CDT_2018
Cuda compilation tools, release 10.0, V10.0.130
$ nvidia-smi
Fri Apr 26 17:31:32 2019       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 418.56       Driver Version: 418.56       CUDA Version: 10.1     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce MX150       Off  | 00000000:01:00.0 Off |                  N/A |
| N/A   54C    P0    N/A /  N/A |    353MiB /  2002MiB |      3%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      1290      G   /usr/lib/xorg/Xorg                           352MiB |
+-----------------------------------------------------------------------------+
$ cat /usr/local/cuda-10.0/include/cudnn.h | grep CUDNN_MAJOR -A 2
#define CUDNN_MAJOR 7
#define CUDNN_MINOR 5
#define CUDNN_PATCHLEVEL 1
--
#define CUDNN_VERSION (CUDNN_MAJOR * 1000 + CUDNN_MINOR * 100 + CUDNN_PATCHLEVEL)

#include "driver_types.h"

みたいなのが出るはず、出なかったら色々やり直そう。CUDA Versionが10.1になってるのは後述。

うまく行かなかった時の消し方

CUDA

$ cd /usr/local/cuda-10.0/bin/
$ sudo ./cuda-uninstaller 

で消えた。こっちのほうがいいはず。

$ sudo apt purge cuda*
$ sudo apt purge nvidia-cuda-*
$ sudo apt purge libcuda*
$ sudo apt autoremove

でもいけるらしいがやったことはない。

Nvidiaドライバー

$ sudo /usr/bin/nvidia-uninstall

で消えた、過去にnvidiaドライバーをaptとかで入れようとしたとかだと

$ sudo apt-get --purge remove nvidia-*

じゃないとうまく消えないかもしれない。

cuDNN

消したことないけど、コピーしたファイルを消すだけでしょう。

$ sudo rm /usr/local/cuda-10.0/include/cudnn.h
$ sudo rm /usr/local/cuda-10.0/lib64/libcudnn.so
$ sudo rm /usr/local/cuda-10.0/lib64/llibcudnn.so.7
$ sudo rm /usr/local/cuda-10.0/lib64/llibcudnn.so.7.5.1
$ sudo rm /usr/local/cuda-10.0/lib64/llibcudnn_static.a

TensorFlowインストール

$ sudo pip3 install tensorflow-gpu==1.13.1

bazelで色々しなきゃいけないのかと思ったけど、これでいいっぽい。pythonの環境構築がちゃんとされてないとsixとかのエラーでそうだけど、遭遇しなかったのでわからない。

TensorFlow確認

$ python3
Python 3.6.7 (default, Oct 22 2018, 11:32:17) 
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from tensorflow.python.client import device_lib
>>> device_lib.list_local_devices()
2019-04-26 20:33:31.015963: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2019-04-26 20:33:31.222253: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:998] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2019-04-26 20:33:31.224028: I tensorflow/compiler/xla/service/service.cc:150] XLA service 0x20d4060 executing computations on platform CUDA. Devices:
2019-04-26 20:33:31.224068: I tensorflow/compiler/xla/service/service.cc:158]   StreamExecutor device (0): GeForce MX150, Compute Capability 6.1
2019-04-26 20:33:31.257072: I tensorflow/core/platform/profile_utils/cpu_utils.cc:94] CPU Frequency: 1800000000 Hz
2019-04-26 20:33:31.258561: I tensorflow/compiler/xla/service/service.cc:150] XLA service 0x2797f00 executing computations on platform Host. Devices:
2019-04-26 20:33:31.258655: I tensorflow/compiler/xla/service/service.cc:158]   StreamExecutor device (0): <undefined>, <undefined>
2019-04-26 20:33:31.259375: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1433] Found device 0 with properties: 
name: GeForce MX150 major: 6 minor: 1 memoryClockRate(GHz): 1.0375
pciBusID: 0000:01:00.0
totalMemory: 1.96GiB freeMemory: 1.85GiB
2019-04-26 20:33:31.259447: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1512] Adding visible gpu devices: 0
2019-04-26 20:33:31.262125: I tensorflow/core/common_runtime/gpu/gpu_device.cc:984] Device interconnect StreamExecutor with strength 1 edge matrix:
2019-04-26 20:33:31.262185: I tensorflow/core/common_runtime/gpu/gpu_device.cc:990]      0 
2019-04-26 20:33:31.262225: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1003] 0:   N 
2019-04-26 20:33:31.262727: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1115] Created TensorFlow device (/device:GPU:0 with 1668 MB memory) -> physical GPU (device: 0, name: GeForce MX150, pci bus id: 0000:01:00.0, compute capability: 6.1)
[name: "/device:CPU:0"
device_type: "CPU"
memory_limit: 268435456
locality {
}
incarnation: 17999465041711514578
, name: "/device:XLA_GPU:0"
device_type: "XLA_GPU"
memory_limit: 17179869184
locality {
}
incarnation: 10262319221813161070
physical_device_desc: "device: XLA_GPU device"
, name: "/device:XLA_CPU:0"
device_type: "XLA_CPU"
memory_limit: 17179869184
locality {
}
incarnation: 3591895757546612715
physical_device_desc: "device: XLA_CPU device"
, name: "/device:GPU:0"
device_type: "GPU"
memory_limit: 1749942272
locality {
  bus_id: 1
  links {
  }
}
incarnation: 16699012107528253306
physical_device_desc: "device: 0, name: GeForce MX150, pci bus id: 0000:01:00.0, compute capability: 6.1"
]

みたいな感じで出れば、cuda, tensorflow-gpuともに動いてるはず。

CuPy

おまけ、入れたかったので入れた。CUDAとversionを合わせないといけないらしいが、今回はCUDA10.0なので

$ sudo pip3 install cupy-cuda100

で終わり。

遭遇した問題

CUDA10.1を入れてしまった

初め最新版ということでCUDA10.1を入れてしまったが、CUDA10.1でTensorFlowを動かすのはファイル名のバージョン番号をいちいち合わせてあげる必要があって非常にめんどくさいので、CUDA10.0を入れ直すことになった。
やはり入れる前にversion指定でちゃんと調べないといけない。

nvidia-smiのCUDAversionがおかしい

CUDA10.1を間違えて入れてしまった後、削除してもnvidia-smiのCUDAversionが10.1のままで、nvidiaドライバーを入れ直しても10.1のまま、CUDA10.0を入れても10.1のままだった。
https://stackoverflow.com/questions/53422407/different-cuda-versions-shown-by-nvcc-and-nvidia-smi によると、CUDAにはruntime APIとdriver APIがあって、前者はcuda toolkitインストーラ等によってインストールされ、後者はGPUドライバインストーラによってインストールされるもので、'nvcc -V'と'nvidia-smi'のCUDAversionはそれぞれ別のものを指しているらしい。
NVIDAdriver418.56を入れるとnvidia-smiの結果は、CUDAversionによらずCUDA10.1になるということ?よくわからないが、実害はなさそうなので放置した。

cuDNNを入れてないことによるエラー

CUDAやNVIDIAドライバーを入れ直したときに、cuDNNを入れ忘れていて

$ python3
Python 3.6.7 (default, Oct 22 2018, 11:32:17) 
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tensorflow
python3: Relink `/lib/x86_64-linux-gnu/libudev.so.1' with `/lib/x86_64-linux-gnu/librt.so.1' for IFUNC symbol `clock_gettime'
Segmentation fault

なるエラーが出たが、cuDNNを入れ忘れていたせいだった。
http://blog.michinari-nukazawa.com/2018/05/blog-post.html エラー文を検索すると、このブログがヒットするが非常にありがたかった。エラー文は極力上げるようにしたい...(が、面倒で忘れたりする。

感想

やはりCUDA周りは非常にめんどくさい、調べても自分と同じ状況の人が出てくることは稀で似たような環境の記録を見て一つ一つ調べていくしかない。この記事が誰かの役に立てば幸いです。