Julia(+ Flux.jl)でGPUを用いた深層学習を行う環境構築


はじめに

Python での深層学習用の環境構築は日々簡単になっていますが、Juliaでの環境構築手順をメモしました。

環境について

  • AWS上の Ubuntu 18.04 で試しています
  • 下記の手順だけでも8GBほど使用するので、少なくとも16GBくらいのストレージがあると良いと思います。

インストール手順

標準的なソフトウェア

仮想マシンはだいぶ空なので、下記をインストールしておきます。一部は割愛できるかもしれません。

sudo apt-get update && sudo apt-get install -y \
  build-essential cmake g++ gfortran git pkg-config \
  python-dev software-properties-common wget

NVIDIA 関連のソフトウェア

NVIDIA のドライバーと関連ソフトウェアのインストール。

sudo add-apt-repository -y ppa:graphics-drivers/ppa && \
  sudo apt-get update && \
  sudo apt-get install -y nvidia-390 nvidia-cuda-toolkit
  • nvidia-390 の部分は、以前は nvidia-370 だった。徐々にバージョンがあがっていくのでしょう。
  • nvidia-cuda-toolkit は、Pythonでは必要なかった気がするが、julia では nvcc というソフトウェアが必要なようなので、加える。

再起動

ここで一度、再起動する。AWSなら、Reboot, もしくは一度 stopしてから start。

NVIDIA 関連のソフトウェアを確認

cat /proc/driver/nvidia/version
# NVRM version: ... などと表示

nvcc -V
# nvcc: NVIDIA (R) Cuda compiler driver ... release 9.1 ... などと表示

nvidia-smi
# GPU の使用状況が表示される

Miniconda を導入

Miniconda をインストールします。一番の目的は、Anaconda Cloud で管理されている cudnn を使うことです。自分で導入するより楽です。また Jupyter notebook をインストールしたり、Python環境を合わせて作るのにも使えます。

wget -v https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh
# ほぼデフォルト設定で良いが、`.bashrc` への設定追加のみ "yes" としておく
source ~/.bashrc
conda create -y -n cudnn cudnn=7.3.1=cuda9.0_0
  • Minicondaの設定は、基本的にはデフォルト通りが良いと思います。一点だけ、.bashrc にconda用の設定を付け加えるかについては、"yes" とすると、ログイン時にすぐに conda が使えて良いと思います。
  • source ~/.bashrc ... その設定を読み込む
  • conda create ... "cudnn" という仮想環境を作って、そこに cudnn ライブラリをインストールしています。仮想環境は作らなくても良いですが、後に色々なパッケージを追加するときにバージョンが変わってしまうことを避けるのに有効です。

cudnn のバージョンについては、現在 10.0 まであるようです(conda search で確認可)が、インストールした CUDAのバージョンが 9.1 だったので(nvcc -V で確認)、1つ前の cuda9.0というBuildを選びました(試しに別のBuildを試したところ、9.2, 10.0 ではエラーが出ました)。

$ conda search cudnn
# Loading channels: done
# # Name                  Version           Build  Channel             
# ...
# cudnn                     7.3.1      cuda10.0_0  pkgs/main           
# cudnn                     7.3.1       cuda9.0_0  pkgs/main           
# cudnn                     7.3.1       cuda9.2_0  pkgs/main

念の為、libcudnn.so がきちんと入っていることを確認します。

find ~/miniconda3 -name "libcudnn*"
# /home/ubuntu/miniconda3/envs/cudnn/lib/libcudnn.so
# /home/ubuntu/miniconda3/envs/cudnn/lib/libcudnn.so.7
# /home/ubuntu/miniconda3/envs/cudnn/lib/libcudnn.so.7.3.1
# /home/ubuntu/miniconda3/envs/cudnn/lib/libcudnn_static.a
# /home/ubuntu/miniconda3/pkgs/cudnn-7.3.1-cuda9.0_0/lib/libcudnn.so
# /home/ubuntu/miniconda3/pkgs/cudnn-7.3.1-cuda9.0_0/lib/libcudnn.so.7
# /home/ubuntu/miniconda3/pkgs/cudnn-7.3.1-cuda9.0_0/lib/libcudnn.so.7.3.1
# /home/ubuntu/miniconda3/pkgs/cudnn-7.3.1-cuda9.0_0/lib/libcudnn_static.a

現在、2つの lib/ ディレクトリに同じファイルが存在しますが、どちらも同じもの(シンボリックリンク)でしょう。

Julia のインストール

Julia は、最新のものを公式ページから持ってくるのが良いようです。
パスを通して、julia コマンドが使えるようにします。
ファイル名は、必要に応じて読み替えます。

wget https://julialang-s3.julialang.org/bin/linux/x64/1.1/julia-1.1.0-linux-x86_64.tar.gz
tar -xzvf julia-1.1.0-linux-x86_64.tar.gz
echo 'export PATH="$HOME/julia-1.1.0/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

Julia で GPUを使う設定

インストールしたcudnnのライブラリパスを LD_LIBRARY_PATH に加えます。そうすると、julia がこれを見つけてくれます。
フォルダの名前は、必要に応じて読み替えます。

echo 'export LD_LIBRARY_PATH="$HOME/miniconda3/envs/cudnn/lib:$LD_LIBRARY_PATH"' >> ~/.bashrc
source ~/.bashrc
echo $LD_LIBRARY_PATH  # check

Julia 側では、Flux, CuArrays, BSON パッケージをインストールしておきます。

  • Flux ... 機械学習パッケージ
  • CuArrays ... GPU演算用
  • BSON ... モデルの保存用
julia -e 'import Pkg; Pkg.add("Flux"); Pkg.add("CuArrays"); Pkg.add("BSON")'

Julia での GPU テスト

Julia がきちんとGPUを使用していることを確認するために、下記の演算を行います。
GPU が使用されている場合、CuArray というタイプの配列が作られます。

julia
> using Flux, CuArrays
> m = Dense(10,5) |> gpu
> x = rand(10,3) |> gpu
# 10x3 CuArray{Float32,2} ... 
> m(x) |> softmax
# Tracked 5x3 CuArray{Float32,2} ...
> exit()

最後に、畳み込みニューラルネットの例を行ってみます。FluxML/model-zoo というレポジトリが、モデルの実装例を公開しています。この内の一つを実行して動作確認を試みます。
スクリプト実行時には学習したモデルが保存されるので、念の為テスト用のフォルダを作って実行します。

このスクリプトは、GPUを使用しない設定で書かれています。GPUを使用するために、sed コマンドを使って、1行目に using CuArrays を加えています。

mkdir -p gputest && cd gputest
wget https://raw.githubusercontent.com/FluxML/model-zoo/master/vision/mnist/conv.jl

sed -i '1i using CuArrays' conv.jl  # to run with GPU
julia conv.jl

上記が問題なく動いていれば、ひとまず設定完了と思われます。実行時のGPUの使用状況を、nvidia-smi などで確認しても良いでしょう。