はじめに
今月(2019年5月)の頭にDL4Jの新バージョン1.0.0-beta4がリリースされましたね。
どんな機能が追加されたのかまとめてみたいと思います。
英語のリリースノートはこちら。
https://deeplearning4j.org/release-notes#onezerozerobeta4
そもそもDL4Jって?
DL4JことDeeplearning4Jは、Java/Scala/KotlinといったJVM言語で開発できるオープンソースのディープラーニング用フレームワークです。
サンフランシスコに本社を置くスタートアップ企業のスカイマインド社を筆頭に開発が進められています。
ディープラーニングといえばPythonというイメージがあります。しかし、
- 官公庁やエンタープライズ系のシステムではJavaが主に用いられている
- プログラミング言語でいうとJava開発者が一番多い
- DL4Jはビッグデータ基盤であるHadoop/Sparkをネイティブにサポートしている
- スカイマインド社による商用サポートがある
といった背景から、ディープラーニングの世界でも実はJavaもそれなりのシェアを占めています。
2018年のデータですが、それぞれのフレームワークのGitHub上でのスター数(下図の横軸)で見ると真ん中あたりに位置しています。
(画像出典:https://www.kdnuggets.com/2018/04/top-16-open-source-deep-learning-libraries.html)
TensorFlowやPyTorch、ChainerといったPythonのフレームワークは基本的に研究開発や実験用途を想定されており、私たちが日々目にする華々しい研究成果はこれらのフレームワークを用いて開発されていることが多いかと思います。
DL4Jは(もちろん無料で使えますが)商用という立ち位置にフォーカスして差別化を図っている印象があります。
なお、Kerasで構築されたモデルをDL4Jにインポートして利用することもできます。
その他、TensorFlowのモデルや、ONNX・PMML形式のモデルのインポートにも対応しています。
そのため、開発はPython、運用はJavaといった使い分けをすることも可能となっています。
DL4J 1.0.0-beta4 の主な変更点
そんなDL4Jの新バージョン1.0.0-beta4で追加された機能のハイライトを見てみましょう。
- JVM用線形代数ライブラリND4Jにおける複数のデータ型のサポート
- Intelプロセッサ用高速化ライブラリMKL-DNNのサポート
- メモリ管理方法変更によるND4Jのパフォーマンス向上
- DL4JにAttentionレイヤー追加
- DL4JでBERTをサポート(ただし限定的)
以下でそれぞれの詳細について見ていきます。
ND4Jにおける複数のデータ型のサポート
ND4JというのはJVM向けの科学計算ライブラリです。
PythonでいうところのNumpyのJava版というとイメージしやすいかもしれません。
ND4JはNumpyより2倍早いという報告もあります。
もちろんCUDAをサポートしており、GPUを用いて計算を高速化することもできます。
さて、以前までのバージョンのND4JではN次元行列(テンソル)の型はfloat/doubleに制限されていました。
1.0.0-beta4よりテンソルでも以下の一般的なデータ型はすべてサポートされるようになりました。
- DOUBLE: double precision floating point, 64-bit (8 byte)
- FLOAT: single precision floating point, 32-bit (4 byte)
- HALF: half precision floating point, 16-bit (2 byte), “FP16”
- LONG: long signed integer, 64 bit (8 byte)
- INT: signed integer, 32 bit (4 byte)
- SHORT: signed short integer, 16 bit (2 byte)
- UBYTE: unsigned byte, 8 bit (1 byte), 0 to 255
- BYTE: signed byte, 8 bit (1 byte), -128 to 127
- BOOL: boolean type, (0/1, true/false). Uses ubyte storage for easier op parallelization
- UTF8: String array type, UTF8 format
特にFP16やINT型のサポートによりニューラルネットワークの小型化、高速化が期待できそうですね。
MKL-DNNのサポート
Intelプロセッサ用のディープニューラルネットワーク(DNN)の高速化ライブラリであるMKL-DNNのサポートも追加されました。
MKL-DNNを用いて以下のレイヤーを高速化できます。
-
ConvolutionLayer
andConvolution1DLayer
(andConv2D
/Conv2DDerivative
ND4J ops) -
SubsamplingLayer
andSubsampling1DLayer
(andMaxPooling2D
/AvgPooling2D
/Pooling2DDerivative
ND4J ops) -
BatchNormalization
layer (andBatchNorm
ND4J op) -
LocalResponseNormalization
layer (andLocalResponseNormalization
ND4J op) -
Convolution3D
layer (andConv3D
/Conv3DDerivative
ND4J ops)
なお、LSTM
など、他のレイヤーのサポートは以降のリリースで対応予定とのことです。
以下の行を追加することでMKL-DNNをグローバルに無効化することもできます。
Nd4jCpu.Environment.getInstance().setUseMKLDNN(false);
環境変数ND4J_MKL_FALLBACK
をセットすることで特定の命令のみ無効化することも可能です。
ND4J_MKL_FALLBACK=conv2d,conv2d_bp
ND4J: メモリ管理方法変更によるパフォーマンス向上
ND4Jの以前までのリリースではメモリの自動解放のため周期的なガベージコレクションを利用していました。
(ガベージコレクションについてはQiitaの「JavaのGCの仕組みを整理する」がわかりやすかったです。)
ただし、ND4Jでは1.0.0-alphaより、追加のメモリ管理モデルとしてworkspaceという概念を導入していました。
workspace上ではガベージコレクタの介入なしにメモリを再利用することができます。
DL4Jでニューラルネットワークを訓練している最中では、基本的に解放対象となるメモリはないはずです。
そのため数秒ごとに周期的にガベージコレクションを行うことでパフォーマンスにオーバーヘッドが生じてしまっていました。
1.0.0-beta4からは周期的なガベージコレクションはデフォルトで無効化されることになりました。
(以下のようにして有効化することもできます。)
Nd4j.getMemoryManager().togglePeriodicGc(true);
Nd4j.getMemoryManager().setAutoGcWindow(5000);
DL4J: Attentionレイヤーの追加
Googleから2017年に発表されたAttention Is All You NeedというGoogle翻訳(Transformer)の論文あたりから爆発的に流行り始めたAttention(注意)機構がDL4Jでネイティブに使えるようになりました。
Attentionの解説はRyobotさんのブログがわかりやすいです。
(画像出典:http://deeplearning.hatenablog.com/entry/transformer))
DL4J: BERTのサポート
BERTとは言語表現事前学習の新しい方法のことです。
広い範囲の自然言語処理タスクにおいてSOTA (state-of-the-art) の結果を叩き出し、大きな注目を集めています。
(画像出典: https://twitter.com/_Ryobot/status/1050925881894400000)
DL4JでもBERTを試してみることができるようになりました。
最後に
こっそり以下のような面白い機能が追加されてたりもします。
- DL4JにCapsuleLayerの追加(ただしGPUアクセラレーションは次回以降のリリースで対応)
- ND4JにNonMaximumSuppressionの追加(NMSはYOLOなどの物体認識アルゴリズム内で利用されている)
- ベクトル化・ETLライブラリDataVecに
PythonTransorfm
の追加(Pythonのデータの前処理コードをJavaで利用)
他にも多数の機能追加・バグ修正があります。本稿で取り上げきれなかった内容に関しては公式のリリースノートを参照してください。
このように定番化してきた新しい技術をネイティブにサポートするための新機能などが多数追加されたDL4J 1.0.0-beta4を使ってみてはいかがでしょうか。