もくもくしたこと
おいかわ かずき
(Jubatusもくもく会 #2, 2016/02/27)
自己紹介
• 及川 一樹
– GitHub: https://github.com/kazuki/
– Twitter: @k_oi
• 趣味とか使ってるものとか
– 音声・映像符号
– HTML5とか(WebAudio, WebRTC, asmjs…)
– GPGPU (OpenCL, HSA)
– 暗号
– 分散とかクラウドとか (Hadoop, P2P, OpenStack, ...)
– Gentoo Linux
– Python, TypeScript, Rust, C#
もくもくしたもの
• メイン
– Nearest Neighbor の高速化 ➔ △
• バックアップねた
– Jubatus in Browser ➔ △
– Gentooパッケージの不満解消 ➔ △
• メインが完成するかわからなかったので,
バックアップネタをいくつか用意したのですが,すべてが中途半端に....
Jubatus NNの高速化
• Nearest Neighbor遅いです
– 20newsの分類  train: 30分, classify: 30分
※ Haswell 3.5GHz,全件のtrain/classifyの所要時間
• 原因
– train/classify: ハッシュへの変換が遅い (random_projection)
– classify: 登録済みハッシュとの距離計算が遅い
速くする!
• Random Projectionが遅い
– 熊崎さんが2015年10月ぐらいにキャッシュする実装を作っている
 feature/cached_random_projection ブランチ
– 及川も2015年10月 ぐらいに正規分布に従う乱数生成の高速化を実施
– 今回はこの2つを混ぜて+AVX2(SIMD)でさらなる高速化!
• 距離計算が遅い
– 比較対象が増えるので,沢山trainするとどんどん遅くなる
– GPGPUで力技で解決する!
0
10
20
30
40
50
60
70
80
90
100
train classify結果
結果
手法 Train [ms] Classify [ms]
Default (box-muller) 96.8534 99.3197
[1]: Polar法で正規分布生成 24.3529 29.4501
[2]: AVX2版Box-muller 8.5948 13.7828
[3]: Cache 13.1329 11.3558
[4]: [1] + [3] 4.48 5.83724
[5]: [2]+ [3] 2.03893 5.26619
[6]: [5] + ハミング距離計算AVX2 2.01252 4.73609
[7]: [6] + メモリコピー削減 1.97709 3.28481
※メモリコピー削減: 比較対象のBitVectorを常にコピーしていたので,
コピーしないで比較するように改良.近いうちにpull-reqだしたい
(結果的にモデルサイズ分のメモリコピーを1回のClassifyで実施していた)
GPGPU !
• 間に合いませんでした...
– AMD Kaveri APU + OpenCL 2.0で仮想メモリ空間共有を動かすのに
数時間かかってしまった...
– マニュアルに記載の無いコンパイルオプションが必要だった…
• 得られた知見
– NNのストレージのメモリ空間は連続しているのでGPGPUしやすい
– bit_vectorが必要量の8倍のメモリを確保している
=>ストレージはbit_vectorじゃないので大した影響はなさげ
(パッチはpull-req済み)
• ここまでの作業内容は私のGitHubのjubatus_coreのexperimental/nnブランチで公開済
Gentooパッケージ作成上の不満
• Gentooの特徴
– ソースからビルド
– 他と比べてパッケージのバージョンが新しい
• JubatusのGentooパッケージを作ってます (2012年〜)
– https://github.com/kazuki/overlay
• ここが不満!
– https://github.com/kazuki/overlay/blob/master/sci-calculators/jubatus-
core/jubatus-core-0.2.7.ebuild#L15-L16
Gentooパッケージ作成上の不満
• というわけで msgpack1.1.0に対応させてみました
– 最新は1.4.0ですがGentooは1.1.0までしか入ってないので...
– Msgpack,API互換壊しまくりなので順に確認したほうが楽そう
– MsgpackのC++03向けtuple実装が残念でビルドが通らない...
• C++11にすれば解決! ➔ jubatus-msgpack-rpcがC++11に対応してない...orz
• 仕方がないので,msgpackのヘッダにパッチをあてて回避...
– Jubatus_core: 121+, 103-
– Jubatus: 12+, 11-
– Jubatus-msgpack-rpc: msgpack-1.xブランチで対応済み
– 中途半端... JubatusをC++11化してお掃除するのとあわせて... そのうち...
• 利点
– Msgpack 1.0.0 から C++版はヘッダオンリライブラリ
➔libmsgpack.soへのリンクが消滅
• 私のGitHubのjubatus/jubatus_coreのmsgpack-1.1ブランチで公開済み
Jubatus in Browser
• Msgpack 1.0からはヘッダオンリーライブラリ
 依存関係が減り jubatus_core単品で動くようになる
すべてがJavaScript になる
https://github.com/kripken/emscripten
Jubatus_coreをJavaScript化!
• システムコールとかpthreadとかはJavaScriptは対応していないので,#ifdef
で隠す
• 出力されたJavaScriptファイル  2.3MB
• とりあえずnode で Classify のサンプルは動くが,
ブラウザのインタフェース作る時間がなかった...
• スマフォ向けブラウザは加速度やBluetoothが利用できるので,ブラウザだけ
でJubatusを使って何かできる!
• 私のGitHubのjubatus_coreのemscriptenブランチで公開済
GPGPUの続き…
• あと少しだったのでお家に帰ってからもくもく会の続きを実施
– 動いた!  experimental/nn-gpgpu-opencl ブランチ
• 性能評価 (20newsの全件Classify)
– Haswell 3.5GHz AVX2: 64s (3.4ms/ops)
– Haswell 3.5GHz AVX2 + dGPU: 161s (8.5ms/ops) ※CPU利用率は25%程度
– Kaveri 3.7GHz AVX: 143s (7.6ms/ops)
– Kaveri 3.7GHz AVX + iGPU: 137s (7.2ms/ops)※CPU利用率は50%程度
• モデルが小さい(32MBぐらい)ので,カーネル実行レイテンシが支配的
– 大きいモデルで実験すると効果が見えるかも…?
– (KaveriはCPU性能低い+iGPUでメモリ転送レイテンシが小さいため少し改善)
dGPU: AMD Radeon R9 285, GCN 1.2 Tonga, 3.3TFLOPS (1792SP, 918MHz)
iGPU: GCN 1.1, 737GFLOPS (512SP, 720MHz)
GPGPU版の今後
• OpenCL 2.0 SharedVirtualMemory Fine-grain Bufferで実装
– 仮想メモリ空間共有
– clSVMAllocでアロケートしたメモリである必要がある
 内部ストレージで利用されている std::vector 等相当の物を書き換える必要
• OpenCL 2.0 SVM Fine-grain System / HAS に切り替え
– malloc等で確保したメモリ空間がそのままGPUからも見える!
– AMD Kaveri,Intel Broadwell以降でHW的には対応
(SW的には不明.AMDはHSAのみ.Intelはブツを持ってないので未確認)
– より簡単に統合できるし,モデルの更新も従来通り実施できる

もくもくしたこと

  • 1.
  • 2.
    自己紹介 • 及川 一樹 –GitHub: https://github.com/kazuki/ – Twitter: @k_oi • 趣味とか使ってるものとか – 音声・映像符号 – HTML5とか(WebAudio, WebRTC, asmjs…) – GPGPU (OpenCL, HSA) – 暗号 – 分散とかクラウドとか (Hadoop, P2P, OpenStack, ...) – Gentoo Linux – Python, TypeScript, Rust, C#
  • 3.
    もくもくしたもの • メイン – NearestNeighbor の高速化 ➔ △ • バックアップねた – Jubatus in Browser ➔ △ – Gentooパッケージの不満解消 ➔ △ • メインが完成するかわからなかったので, バックアップネタをいくつか用意したのですが,すべてが中途半端に....
  • 4.
    Jubatus NNの高速化 • NearestNeighbor遅いです – 20newsの分類  train: 30分, classify: 30分 ※ Haswell 3.5GHz,全件のtrain/classifyの所要時間 • 原因 – train/classify: ハッシュへの変換が遅い (random_projection) – classify: 登録済みハッシュとの距離計算が遅い
  • 5.
    速くする! • Random Projectionが遅い –熊崎さんが2015年10月ぐらいにキャッシュする実装を作っている  feature/cached_random_projection ブランチ – 及川も2015年10月 ぐらいに正規分布に従う乱数生成の高速化を実施 – 今回はこの2つを混ぜて+AVX2(SIMD)でさらなる高速化! • 距離計算が遅い – 比較対象が増えるので,沢山trainするとどんどん遅くなる – GPGPUで力技で解決する!
  • 6.
  • 7.
    結果 手法 Train [ms]Classify [ms] Default (box-muller) 96.8534 99.3197 [1]: Polar法で正規分布生成 24.3529 29.4501 [2]: AVX2版Box-muller 8.5948 13.7828 [3]: Cache 13.1329 11.3558 [4]: [1] + [3] 4.48 5.83724 [5]: [2]+ [3] 2.03893 5.26619 [6]: [5] + ハミング距離計算AVX2 2.01252 4.73609 [7]: [6] + メモリコピー削減 1.97709 3.28481 ※メモリコピー削減: 比較対象のBitVectorを常にコピーしていたので, コピーしないで比較するように改良.近いうちにpull-reqだしたい (結果的にモデルサイズ分のメモリコピーを1回のClassifyで実施していた)
  • 8.
    GPGPU ! • 間に合いませんでした... –AMD Kaveri APU + OpenCL 2.0で仮想メモリ空間共有を動かすのに 数時間かかってしまった... – マニュアルに記載の無いコンパイルオプションが必要だった… • 得られた知見 – NNのストレージのメモリ空間は連続しているのでGPGPUしやすい – bit_vectorが必要量の8倍のメモリを確保している =>ストレージはbit_vectorじゃないので大した影響はなさげ (パッチはpull-req済み) • ここまでの作業内容は私のGitHubのjubatus_coreのexperimental/nnブランチで公開済
  • 9.
    Gentooパッケージ作成上の不満 • Gentooの特徴 – ソースからビルド –他と比べてパッケージのバージョンが新しい • JubatusのGentooパッケージを作ってます (2012年〜) – https://github.com/kazuki/overlay • ここが不満! – https://github.com/kazuki/overlay/blob/master/sci-calculators/jubatus- core/jubatus-core-0.2.7.ebuild#L15-L16
  • 10.
    Gentooパッケージ作成上の不満 • というわけで msgpack1.1.0に対応させてみました –最新は1.4.0ですがGentooは1.1.0までしか入ってないので... – Msgpack,API互換壊しまくりなので順に確認したほうが楽そう – MsgpackのC++03向けtuple実装が残念でビルドが通らない... • C++11にすれば解決! ➔ jubatus-msgpack-rpcがC++11に対応してない...orz • 仕方がないので,msgpackのヘッダにパッチをあてて回避... – Jubatus_core: 121+, 103- – Jubatus: 12+, 11- – Jubatus-msgpack-rpc: msgpack-1.xブランチで対応済み – 中途半端... JubatusをC++11化してお掃除するのとあわせて... そのうち... • 利点 – Msgpack 1.0.0 から C++版はヘッダオンリライブラリ ➔libmsgpack.soへのリンクが消滅 • 私のGitHubのjubatus/jubatus_coreのmsgpack-1.1ブランチで公開済み
  • 11.
    Jubatus in Browser •Msgpack 1.0からはヘッダオンリーライブラリ  依存関係が減り jubatus_core単品で動くようになる
  • 12.
  • 13.
    Jubatus_coreをJavaScript化! • システムコールとかpthreadとかはJavaScriptは対応していないので,#ifdef で隠す • 出力されたJavaScriptファイル 2.3MB • とりあえずnode で Classify のサンプルは動くが, ブラウザのインタフェース作る時間がなかった... • スマフォ向けブラウザは加速度やBluetoothが利用できるので,ブラウザだけ でJubatusを使って何かできる! • 私のGitHubのjubatus_coreのemscriptenブランチで公開済
  • 14.
    GPGPUの続き… • あと少しだったのでお家に帰ってからもくもく会の続きを実施 – 動いた! experimental/nn-gpgpu-opencl ブランチ • 性能評価 (20newsの全件Classify) – Haswell 3.5GHz AVX2: 64s (3.4ms/ops) – Haswell 3.5GHz AVX2 + dGPU: 161s (8.5ms/ops) ※CPU利用率は25%程度 – Kaveri 3.7GHz AVX: 143s (7.6ms/ops) – Kaveri 3.7GHz AVX + iGPU: 137s (7.2ms/ops)※CPU利用率は50%程度 • モデルが小さい(32MBぐらい)ので,カーネル実行レイテンシが支配的 – 大きいモデルで実験すると効果が見えるかも…? – (KaveriはCPU性能低い+iGPUでメモリ転送レイテンシが小さいため少し改善) dGPU: AMD Radeon R9 285, GCN 1.2 Tonga, 3.3TFLOPS (1792SP, 918MHz) iGPU: GCN 1.1, 737GFLOPS (512SP, 720MHz)
  • 15.
    GPGPU版の今後 • OpenCL 2.0SharedVirtualMemory Fine-grain Bufferで実装 – 仮想メモリ空間共有 – clSVMAllocでアロケートしたメモリである必要がある  内部ストレージで利用されている std::vector 等相当の物を書き換える必要 • OpenCL 2.0 SVM Fine-grain System / HAS に切り替え – malloc等で確保したメモリ空間がそのままGPUからも見える! – AMD Kaveri,Intel Broadwell以降でHW的には対応 (SW的には不明.AMDはHSAのみ.Intelはブツを持ってないので未確認) – より簡単に統合できるし,モデルの更新も従来通り実施できる