社内GPU機の構成をItamaeで管理するようにしたことと、その反省点について

⚠️⚠️ 注意 ⚠️⚠️

この記事の内容は2019年6月における弊社の状況についてまとめたものになります。内容を参考にする場合は注意してください。

こんにちは。機械学習についてはド素人のうなすけです。何もわかりません。この記事では、機械学習に使用しているGPU搭載社内PCにItamae recipeを用意した話をします。

不調になったGPU

弊社には、TITAN Vを2枚積んだマシン(以下GPU機)があります。データ解析チームはそのマシンを利用して機械学習を行い、様々なモデルを作成してCASHやTRAVEL Nowのサービス改善に貢献しています。

ところがある日から、GPU機で学習を進めているうちに突然電源が落ちたり、そもそも起動しないということが頻繁に発生するようになってしまいました。

GPU機が不調になったときのSlackの様子
URLはマザーボードの製品ページです

起動すらまともにしなくなった様子
起動すらまともにしなくなった様子

このGPU機はBTOとして購入したものなので、販売元に修理を依頼しました。結果、どうやら物理的な異常は解決したようなのですが、OSが初期化された状態で返却されてきました。

……帰ってきたGPU機に対し、OSの再インストールから各種ライブラリの導入までをデータ解析チーム内で行なっていたのですが、ライブラリのバージョンの組み合わせによっては、学習タスクを実行しているうちにOSごと落ちてしまうという現象が多々発生していました。

なので、僕が構成管理ツールを導入し、ライブラリ群のバージョンの固定と学習環境の再現性を確保することにしました。

Ubuntu 18.04.02 LTS のインストール

www.tensorflow.org

TensorFlow公式ドキュメントに記載されている、GPU supportも含むインストールは、18.04 もしくは 16.04 の場合が記載されています。16.04を選択する理由はないので、18.04.02 をインストールしました。

⚠️ 反省点

ここでインストールした Ubuntu は以下からダウンロードできる日本語Remixです。

www.ubuntulinux.jp

よくよく考えると、別にデスクトップ環境を使いたい訳ではないので Ubuntu Serverを入れたほうがよかったのではないかと思いました。

ubuntu.com

GUIがあったら嬉しい場面もごくまれにありますが、次にOSの再インストールが必要になったときにはUbuntu Serverを入れようかなと思っています。

機械学習環境の構築

さて、勝負はここからです。

ちなみにデータ解析チームからは、以下の構成の場合に学習を完了させることができなかった、という報告を受けました。

  • nvidia-driver-410
  • CUDA 10
  • cuDNN 7.4.2

※ 今後出てくるRubyのコード片はItamae recipeの一部として実行されているものです。

GPUドライバーのインストール

18.04.02 (以下Bionic) で、標準でインストールできるNVIDIAプロプライエタリなグラフィックボードのドライバーは nvidia-driver-410 です。 が、しかし nvidia-driver-410 では学習を終了させられなかったとのことから、 以下ppaを追加し nvidia-driver-390 をインストールしてみることにしました。

launchpad.net

execute 'add graphics-drivers ppa' do
  command 'sudo add-apt-repository --yes ppa:graphics-drivers/ppa'
  not_if 'test -e /etc/apt/sources.list.d/graphics-drivers-ubuntu-ppa-bionic.list'
end

# require reboot if it installed
package 'nvidia-driver-390'

ただ、インストールしてから学習を実行することを何度か繰り返した結果、どうやら nvidia-driver-410 のほうが安定することが判明し、最終的には nvidia-driver-410 をインストールしました。

CUDAのインストール

CUDAも、TensorFlowのドキュメントでは10をインストールするように記述されていますが、前述のように9系をインストールします。

そのためには、17.04 用のパッケージを追加しなければいけないようです。

developer.nvidia.com

「ホントに?」と思いながらも試してみましたが、どうやらこれでもインストールでき、動作するようなのでこのまま進めることにしました。

# /etc/apt/sources.list.d/cuda.list
deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1704/x86_64 /
remote_file '/etc/apt/sources.list.d/cuda.list' do
  mode '644'
end

remote_file '/etc/apt/sources.list.d/nvidia-machine-learning.list' do
  mode '644'
end

execute 'add nvidia publey' do
  command <<~CMD
    sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1704/x86_64/7fa2af80.pub
  CMD
  not_if 'apt-key list | grep cudatools@nvidia.com'
end
execute 'apt update'

package 'cuda-toolkit-9-0'
package 'nvidia-cuda-toolkit'

しかし、この状態で cuda-9-0 というパッケージをインストールしようとすると、以下のエラーで止まってしまいます。

$ sudo apt install cuda-9-0
Reading package lists... Done
Building dependency tree
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
 cuda-9-0 : Depends: cuda-runtime-9-0 (>= 9.0.176) but it is not going to be installed
            Depends: cuda-demo-suite-9-0 (>= 9.0.176) but it is not going to be installed
E: Unable to correct problems, you have held broken packages.

これは最終的には nvidia-compute-390 というパッケージが見つからないことが原因です。しかしこのパッケージは、先程インストールした nvidia-driver-390 というmetapackageに含まれているという情報があります。

launchpad.net

どういうことなのでしょう 🤔

ただ、この状態でも nvcc -V の結果に Cuda compilation tools, release 9.1, V9.1.85 とあるので、cudaが使用できる状態になっていると判断してよさそうです。(腑に落ちませんが)

cuDNNのインストール

libcudnn パッケージもインストールする必要があります。ただし、7系は落ちるということなので他のバージョンのインストールを検討しなければなりません。

しかし7より新しいバージョンは NVIDIA Developer Program Memberでないと入手できないようです。

ところで弊社はNVIDIA Inceptionプログラムの日本パートナーに認定されており、NVIDIA Developer Programのアカウントを持っているので、cuDNN 9 のtarballをそこからダウンロードしました。

prtimes.jp

(cudnnのtarballは400MB弱あるので、git repositoryに含めるのであればgit-lfsを使用する必要があるでしょう)

remote_file '/home/foo-user/cudnn-9.0-linux-x64-v7.6.1.34.tgz'

execute 'extract and deploy cudnn lib files' do
  command <<~CMD
    tar -xvf cudnn-9.0-linux-x64-v7.6.1.34.tgz
    sudo cp -P cuda/lib64/* /usr/local/cuda-9.0/lib64/
    sudo cp cuda/include/* /usr/local/cuda-9.0/include/
    sudo chmod a+r /usr/local/cuda-9.0/include/cudnn.h
  CMD
  not_if 'test -e /usr/local/cuda-9.0/include/cudnn.h'
end

⚠️ 反省点

nvidia-docker2 を導入して、Docker コンテナ内で学習を実行させるようにすれば、最低限のパッケージ導入で環境構築ができたのではないかと思います。その場合、必要なのは nvidia-driver-* だけになるのでしょうか? tensorflow/gpu.Dockerfile at master · tensorflow/tensorflow · GitHub を見る限りではそう判断してよさそうですが……

これについてはデータ解析チームと協力しながら調査をしてみたいと考えています。

最終的に入ったものたち

  • Ubuntu 18.04.02 LTS
  • nvidia-driver-410
  • CUDA 9.1
$ lsb_release --all
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.2 LTS
Release:        18.04
Codename:       bionic

$ nvidia-smi
Fri Jun 28 18:57:47 2019
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 410.104      Driver Version: 410.104      CUDA Version: 10.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  TITAN V             Off  | 00000000:17:00.0 Off |                  N/A |
| 29%   42C    P8    26W / 250W |      0MiB / 12036MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  TITAN V             Off  | 00000000:65:00.0  On |                  N/A |
| 33%   47C    P8    31W / 250W |    139MiB / 12033MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    1      1350      G   /usr/lib/xorg/Xorg                            59MiB |
|    1      1799      G   /usr/bin/gnome-shell                          78MiB |
+-----------------------------------------------------------------------------+

$ nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2017 NVIDIA Corporation
Built on Fri_Nov__3_21:07:56_CDT_2017
Cuda compilation tools, release 9.1, V9.1.85

いろいろ試行錯誤してこのような結果になりました。このあたりのベストプラクティス (このバージョンの組み合わせは相性悪い、など) がありましたら教えていただけると助かります。

まとめ

Itamaeを導入しつつ環境構築していくことによって、複数ライブラリのバージョンによる相性問題との格闘を楽に行なうこができました。が、しかし修理に出す前の時点で、そもそも構成管理ツールを導入して再現性のある機械学習環境を構築しておくべきでした。

今後、様々なライブラリのアップデートや何らかの構成の変化なども、しっかりItamae recipeとしてコード化していくことで、データ解析チームのを止めないようにしていきたいです。