LoginSignup
9
6

More than 3 years have passed since last update.

CUDAが動く Julia の深層学習フレームワーク Flux.jl の環境構築をDockerで行う.

Last updated at Posted at 2019-12-01

本日は

  • Julia製の深層学習フレームワーク Flux.jl のアドベントカレンダー1日目の記事として執筆したものです.

一年前を振り返る(ポエム)

  • 私が Flux.jl を知ることになったのは1年前なんですが,レイヤーがCPUで動くんだけれどGPUで動かなかったりつらぽよ感がありましたが BatchNormレイヤーがGPUで動くようになったみたいなのでこれから始める方はそこまでストレスなくいけるんじゃないかなーと思います :innocent: .
  • まぁ,まだバージョンが0.10らしいのでこれからですよ.これから.

本題

  • 環境構築をDockerで行うことを考えます.かつ NVIDIA の GPU が動く環境を構築しましょう.
  • Dockerで. 「Docker CUDA」という言葉でぐぐると nvidia-docker っていう言葉/コマンドが出てくると思いますが, NVIDIA Docker って今どうなってるの? (19.11版) にもあるように名前がコロコロ変わって,NVIDIA Container Toolkit という名前になってるようです.(まぁ nvidia docker って言葉がけっこうシミわかってるので通じると思います)
  • まっさらなホスト環境(これからDockerを入れていこうというマシーン環境を指す.ここでは NVIDIAの GPU 付きUbuntuマシーンを想定)から環境構築を始めるときは 同記事のセクション Docker 19.03 以降の環境で前だけを見て生きる場合に従えばOKです.つまり

というステップを踏めばOKです.

Dockerfile

  • nvidia/cuda の DockerHub を探して適当なtagを探します.ここでは 10.0-cudnn7-devel-ubuntu18.04 としておきます.ドライバーが古いと怒られてしまう可能性があるので nvidia-smi などを見て対応するCUDAバージョンを確認するかかくじバージョンアップをしてください.
FROM nvidia/cuda:10.0-cudnn7-devel-ubuntu18.04

MAINTAINER SATOSHI TERASAKI

RUN apt-get update && apt-get install -y \
    build-essential \
    libatomic1 \
    python \
    gfortran \
    perl \
    wget \
    m4 \
    cmake \
    pkg-config \
    git

ARG JL_VERSION="v1.3.0"
ARG WDIR="/root"
ARG JL_BUILD_DIR=$WDIR/build
WORKDIR $JL_BUILD_DIR

RUN echo "\
CXXFLAGS=-D_GLIBCXX_USE_CXX11_ABI=0\n\
prefix=/usr/local/julia-$JL_VERSION\n\
USE_BINARYBUILDER = 0\n\
" > Make.user \
    && cat Make.user \
    && git clone --depth=1 -b $JL_VERSION https://github.com/JuliaLang/julia.git julia-$JL_VERSION\
    && cp Make.user $JL_BUILD_DIR/julia-$JL_VERSION \
    && cd julia-$JL_VERSION \
    && make -j $(nproc) \
    && make install

RUN rm -r $JL_BUILD_DIR
ENV PATH=/usr/local/julia-$JL_VERSION/bin:$PATH
# runtime test
RUN julia -e "using InteractiveUtils; versioninfo()"
RUN julia -e 'using Pkg; Pkg.add(["Flux","CuArrays"]); using Flux'

CMD ["julia"]
  • Juliaを無駄にソースからビルドしてるのは私の趣味なので公式ページのバイナリーのリンクを持ってきてコピーするでいいと思います.
  • 例えば docker-library/julia を参照

使い方

ホスト環境にログインして次を実行します.

$ ls
Dockerfile
$ docker build -t fluxgpu .
$ docker run --gpus all --rm -it fluxgpu
sudo docker run --gpus all --rm -it fluxgpu
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.3.0 (2019-11-26)
 _/ |\__'_|_|_|\__'_|  |
|__/                   |

julia> ; # to jump shell-mode
shell> nvidia-smi
Sun Dec  1 11:37:39 2019
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 410.48                 Driver Version: 410.48                    |
|-------------------------------+----------------------+----------------------+
| 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 GTX 1080    Off  | 00000000:03:00.0 Off |                  N/A |
|  0%   45C    P5    19W / 270W |      0MiB /  8119MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  GeForce GTX 1080    Off  | 00000000:04:00.0 Off |                  N/A |
| 37%   46C    P5    19W / 230W |      0MiB /  8118MiB |      4%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

上記のように nvidia-smi コマンドの出力が出ればOKです.

一度 REPL モードに戻って次を実行してみましょう:

julia> using Flux
julia> d=Dense(100,1000)|>gpu
Dense(100, 1000)

julia> x=rand(Float32,100)|>gpu;

julia> typeof(x)
CuArray{Float32,1,Nothing}

julia> d(x)|>typeof
CuArray{Float32,1,Nothing}

julia> d(x) |> size
(1000,)
  • これは Chainerでいえば chainer.links.Linear に相当するレイヤーですね.|> gpu とすることで Dense レイヤーと データ x をGPUに移しています.
  • 畳み込みのレイヤーを担当する Conv への入力インターフェースは注意が必要です.Chainerですと NCHW というデータレイアウトを採用していますが.Flux.jlでは逆で WHCN とすることになります.例えば x=rand(Float32,224,224,3,1)|>gpu というデータをJuliaでは投げることになります.

まとめ

  • GPU 付きの環境をDockerで構築し Flux.jl を1年ぶりに動かしました.BatchNorm のforwardが動くのでまともなレイヤーが組めそうですね.
  • 今回はとくにFluxのコンテキストはあまりないのでGPGPUをしたい人も各自でカスタマイズして活用できると思います.
9
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6