OpenStackとGPU付きインスタンス(Deep Learning)

これは、OpenStack Advent Calendar 2016 4日目のエントリーです。

Deep Learningに代表されるNeural Networkの計算を行う場合、GPUを使えばCPUでの処理と比べた場合に計算時間を10倍程度短縮出来ます。このため学習時にGPUを利用すれば大きな効果を得る事が出来ます。GPUは限られた資源になるため、OpenStackを使ってGPUを皆で共有する環境を構築します。

ホストの準備

OpenStack環境の準備とOpenStackの設定を行います。今回はCentOS 7+Packstackで作成してます。OpenStackをインストールするホストにはnVidiaのGPUを搭載してます。

OpenStackのインストール

Packstackを使ってOpentackをインストールします。詳しくは以下のURLを参考にしてください。

https://www.rdoproject.org/install/quickstart/

SE LinuxはPermissiveにしておきます。

IOMMUの有効化

IOMMUを以下の手順で有効化します。

  1. GRUBの設定
    /etc/sysconfig/grubのGRUB_CMDLINE_LINUXの最後にintel_iommu=onを追記します。例 : GRUB_CMDLINE_LINUX=”crashkernel=auto rd.lvm.lv=rhel00/root rd.lvm.lv=rhel00/swap rhgb quiet intel_iommu=on“
  2. GRUBの書き換え
    GRUBの設定を反映させます。

    # grub2-mkconfig -o /boot/grub2/grub.cfg
  3. サーバーをリブートします。
  4. 設定の反映を確認
    設定が反映されている場合は以下のフォルダが空では無くなります。空の場合は設定に失敗しています。
    /sys/kernel/iommu_groups/

NOVAの設定

NOVAの設定を行い、インスタンスにGPUを添付出来るようにします。

  1. Aliasの設定
    Aliasを指定します。名前はGPUの商品名でも良いですし、自分の好きな名前でも良いと思います。vendor_idは搭載しているGPUのIDを利用します。

    pci_alias = {"name":"GRIDK2", "vendor_id":"10de", "product_id":"11bf"}
  2. スケジューラーの設定
    スケジューラーがインスタンス起動時にPCI Passthroughの状況を確認するようにPciPassthroughFilterを追記します。

    scheduler_default_filters=RetryFilter,AvailabilityZoneFilter,
    RamFilter,Comp uteFilter,ComputeCapabilitiesFilter,
    ImagePropertiesFilter,CoreFilter,PciPassthroughFilter
  3. White Listの設定
    PCI Passthroughで使う機器を設定します。今回はホストに接続されているGPUを指定します。

    pci_passthrough_whitelist = {"name":"GRIDK2", "vendor_id":"10de", "product_id":"11bf"}

OpenStack環境をリブートしてください。

Flavorの設定

Flavorで指定したインスタンスにGPUが添付出来るようにします。以下の設定はFlavor名はg1.mediumとなり、GRIDK2のAlias名が付いたGPUを一つ添付します。最後の数字を2にすると2つGPUが添付されます。

# nova flavor-create g1.medium –is-public true auto 16384 16 4
# nova flavor-key g1.medium set “pci_passthrough:alias”=“GRIDK2:1”

これで準備は整いました。このg1.mediumのFlavorを使ってインスタンスを起動すればGPUが添付された状態になります。

イメージの準備

TensorflowやChainerはnVidiaの提供しているCUDAや、CuDNNを利用してGPUを操作するためにこれらのパッケージをインストールします。私が試した時はCUDA7.5とUbuntu 15.04の組み合わせがベストな組み合わせでした。この組み合わせを見つけるまではかなり苦労をしました。今はCUDA8.0がリリースされていますので16.04が利用出来ると思いますが、組み合わせとして良いのかは試して見るしかありません。

Ubuntuイメージの追加

Horizonの画面か、glance か openstackコマンドを使ってUbuntu 15.04のクラウドイメージを追加します。

イメージの起動

先程の作成したg1.mediumのフレーバーを利用して、Ubuntuのイメージを起動します。

インスタンスへのパッケージのインストール

起動したインスタンスにSSHで接続した後にパッケージをインストールします。

  1. パッケージの追加
    CUDAをインストールするためのパッケージを追加しておきます。

    # sudo apt-get install linux-image-extra-virtual linux-headers-$(uname -r)-
  2. CUDAのインストール
    CUDAをインストールします。CUDAは2G程度あります。

    # sudo dpkg -i cuda-repo-ubuntu1504_7.5-18_amd64.deb 
    # sudo apt-get update
    # sudo apt-get install cuda
  3. CuDNNのインストール
    CUDAのDNN用ライブラリをインストールします。Insallerを付いていないためファイルをDownload後に展開して、ファイルを移動します。

    # tar -zxf cudnn-7.0-linux-x64-v4.0-prod.tgz
    # cd cudnn-7.0-linux-x64-v4.0-prod.tgz 
    # sudo cp lib* /usr/local/cuda/lib64/
    # sudo cp cudnn.h /usr/local/cuda/include/
  4. インスタンスの再起動
  5. GPUの確認
    GPUが添付されているかを確認します。

    # lspci | grep -i nvidia
  6. Tensorflowをインストールします。
    Tensorflowのバイナリをインストールします。今回はテストした時の10.0をインストールします。CUDA7.5とコンパチがあります。最新版の12.0はCUDA8.0対応となってます。

    # export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.10.0rc0-cp27- none-linux_x86_64.whl
    # sudo pip install --upgrade $TF_BINARY_URL
  7. TensorflowでGPUを認識出来ているか確認します。
    以下のコマンドでTensorflowがGPUを認識出来ているか確認可能です。

    # python
     >>> import tensorflow as tf 
     >>> s = tf.Session()
  8. Chainerをインストールする
    Tensorflowの代わりにChainerを使いたい場合は次の手順になります。ChainerはインストーラーがGPUを認識した状態でインストールすると自動的にGPU付きパッケージがインストールされます。

    # sudo pip install chainer

まとめ

OpenStackを使えば、限られたGPUを皆で共有する事が出来ます。また、CUDA付きインスタンスをイメージ化しておけばインスタンスを、作っては壊す事が出来るため今回提示したTensorflow/Chainer以外にもCaffeやmxnet等の様々なDeep Learningのライブラリを試す事が出来ます。

OpenStackとGPU付きインスタンス(Deep Learning)