水底

ScalaとかC#とかk8sとか

sbtを使ってDeeplearning4jをSpark上で動かす(ver: 0.4-rc3.9)

Deeplearning4j(DL4J)をSpark上で動かしたかったがいろいろ問題点があったのでメモ. 最終的には動かすことに成功した.

sparkアプリケーションを動かすには

  • 一旦jarを作ってからspark-submitコマンドで利用する方法
    • sparkの環境が必要
  • アプリケーションに埋め込んでスタンドアロンに利用する方法
    • 事前にsparkの環境は必要ないがクラスタは利用できない

があるが, 今回は「とりあえず試したい」程度だったので後者を目標とした(ちなみにsetMasterを調整してsbt packageすれば簡単に前者のアプローチへ移行可能).

既存の問題点

  • 本記事のタイトル通り「sbtを使ってDL4JをSpark上で動かす時に使うプラグイン」として提供されている GitHub - deeplearning4j/dl4j-spark-ml が古い
  • そのサンプル実装とされている https://github.com/deeplearning4j/dl4j-spark-ml-examples が謎の404
  • とにかくドキュメントが少ない. 英語ですらほとんど見当たらない(sparkでdeeplearningとかやってる人多そうなのになんで…)
  • 適当にやってみるとライブラリのバージョン地獄に嵌まる

動かす

あまりに動かなかったのでDL4Jのgitterで聞きつつ実装したところなんとか動かすことが出来た.

特に注意が必要だったところだけ列挙する

  • 0.4-rc3.9からnd4j-x86は不要になり, nd4j-nativeのみで良くなった
  • nd4j-nativeを利用するにはclasspathTypesの指定と実行環境に合わせたclassifierの設定が必須
  • nd4j-nativend4j-cuda-7.5は併用できない
  • jackson-databindのバージョン依存がどうしようもないのでdependencyOverridesで固定する必要がある
  • dl4j-sparkが依存しているspark-coreが古いのでexcludeする
    (dl4j-spark-cdh5-examplesを参考にしたが互換大丈夫なのか確信が持てない…がこれをしないと依存解決できない)
  • 性質上OutOfMemoryErrorが出やすいのでヒープサイズを増やす必要がある
    • スタンドアロン(sbt)を利用 => sbt run時に-memで大きめの値を指定する
    • spark-submitを利用 => spark-submit--driver-memory--executor-memoryで大きめの値を指定する

どれか一つでも欠けているとコケるという…なかなかシビアである. 以下が作ったサンプルである. テストの内容は GitHub - deeplearning4j/dl4j-spark-cdh5-examples: Examples to run on CDH5 with Spark を参考にした. なお, CNNを利用するMNISTのサンプルはかなりのマシンパワーを利用するので注意が必要である.

github.com

分からなくなったら

ライブラリの特性上DL4JはND4Jと密に関係しているのでこちらも参照されたし. ダメそうならgitterで聞いてみると良い.

gitter.im