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)

OpenStackの監視をMackerelでやってみる

OpenStackシステムの監視を行いたい場合はZabbix等を利用するのも良いですが、SaaSの監視サービスであるMackerelを利用すると色々面倒な準備を行わずとも監視の開始が出来ます。Mackerelは標準でCPU使用率等の監視を行ってくれるのですが、OpenStackシステムに関連する項目を独自監視を行いたい場合はカスタムメトリックの投稿で簡単に行う事が出来ます。以下カスタムメトリックの投稿の方法が記述されています。

http://help-ja.mackerel.io/entry/advanced/custom-metrics

要約すると以下の3つになります。

  1. メトリックは次の形式でタブ区切りで標準出力。
    {metric name}\t{metric value}\t{epoch seconds}
  2. 名前(metric name)はドット区切りで最後の区切りの名前がグラフの値の表示名となる。最後の区切り前までが同一の場合は同一グラフとして一つのグラフに表示されます。
  3. 環境変数MACKEREL_AGENT_PLUGIN_METAが設定された時にグラフ定義を出力するとグラフの形式を定義出来る(オプション)

このMackerelでカスタムメトリックを投稿したい場合にGoはライブラリが用意されていますが、Python用は特に用意されてないため上記3点を抑えた形で自分で書くことになります。

カスタムメトリックを投稿するコード例

以下OpenStack SDKを利用して特定のプロジェクト内のサーバ数をカウントして投稿する例です。OpenStackへの接続情報はargparseを使って引数として指定出来るようにしてあります。今回はグラフの表示形式の指定は省略しています。

import argparse
import time
from openstack import connection


def main():
    p = argparse.ArgumentParser()
    p.add_argument("-authurl", default="http://localhost:5000/v2.0")
    p.add_argument("-user", default="admin")
    p.add_argument("-password", default="password")
    p.add_argument("-tenant", default="admin")
    args = p.parse_args()
    conn = connection.Connection(auth_url=args.authurl, 
                                 username=args.user,
                                 password=args.password, 
                                 project_name=args.tenant)
    server_list = []
    for server in conn.compute.servers():
        server_list += [server]
    l = map(str, ["openstack.servers", len(server_list), time.time()])
    print "\t".join(l)

if __name__ == '__main__':
    main()

Mackerelの設定

まずサーバーにMackerelのAgentをインストールします。インストール後に上記のようなコードを含んだファイルを例えば/opt/openstack.pyとして保存します。Mackerel Agentの設定ファイルである/etc/mackerel-agent/mackerel-agent.confの最終行辺りに以下を追加します。Mackerel AgentはDefaultで1分毎に指定のcommandを実行して、標準出力から値を取得してくれます。自動で生成されるためグラフの追加等の作業は必要ありません。

[plugin.metrics.openstack]
command = "python /opt/openstack.py -authurl=http://localhost:5000/v2.0 -user="admin" -password=password -tenant=admin"

まとめ

Mackerelを使うと簡単に監視メトリックの追加が可能です。OpenStackに関連した項目であれば、OpenStack SDKを使ってサーバーリストを取得して以下のようにNova等のAPIのレスポンスタイム等の監視も出来ます。

スクリーンショット 2016-01-03 8.41.15

OpenStackの監視をMackerelでやってみる

OpenStackとVMwareの連携

VMWareからVIO(VMware Integrated OpenStack)が発表されたようにVMwareもOpenStackとは良い関係性を持つように努力しています。今回はOpenStackとVMwareの連携の一部解説とPackStackを使った環境構築を行いたいと思います。VMwareは近い商品としてはvRA(vRealize Automation)を持っています。この製品はOpenStackと同じIaaS基盤ですが、OpenStackとの連携機能も持っています。vRAは旧vCACとなります。現在VMware社の製品であるvSphereとNSXと連携可能なのは、OpenStackのNova / Glance / Cinder / Ceilometer / Neutronになります。今回はNova / Glance / Cinder連携の部分に焦点を当ててざっくり解説します。OpenStackはあくまでKVM/Xen利用時に全ての機能が利用できるのでVMwareを利用する場合は、どの機能がサポートされているかは逐一確認と注意をする必要があります。 “OpenStackとVMwareの連携” の続きを読む

OpenStackとVMwareの連携

OpenStack NovaのUtilization aware Schedulingを利用する

Nova ComputeはNova Schedulerに対して定期的に構成情報を送信しています。Compute Node上の</var/log/nova/nova-compute.log>を見ると確認出来ますが送信している値はFree RAM/Free Disk/Free vCPUSになります。NovaのFilter Schedulerはその値を元にしてホストを決定しています。

Icehose(2014.1)からユーザー側で上記の値以外に自由にSchedulerで利用できる値を送信出来るようになりました。それがUnitization aware schedulingです。Blueprintは以下になります。

https://blueprints.launchpad.net/nova/+spec/utilization-aware-scheduling

CPUの利用率を送信するスクリプトがサンプルとして提供されていますが、コンピュートホスト側のnova/compute/monitorsにスクリプトを配置して、正しくnova.confを設定すればnova-computeプロセスが定期的にスクリプトを実行して必要な値を送信してくれます。

nova.computeからmonitorsをimportしてrmonitors.Resouce MonitorBaseを継承してPythonスクリプトを書く事になります。returnする値はfloat型である必要があります。 “OpenStack NovaのUtilization aware Schedulingを利用する” の続きを読む

OpenStack NovaのUtilization aware Schedulingを利用する