1 of 24

エッジMLシステムを�C/C++からRustへ移行した事例

2019/10/26 Rust.Tokyo 2019

加藤倫弘 / Tomohiro KATO�AI本部AIシステム部AI研究開発第二グループ�株式会社ディー・エヌ・エー

2 of 24

はじめに

  • 話すこと
    • ドライブレコーダー上で動くDeep Learningを含むシステムの�AIアルゴリズム群の開発言語をC++からRustへ移行中
    • 開発における背景や実践テクニックの共有
  • 対象
    • C++やRustでの開発経験が少しある人
    • Deep Learningは知らなくてもOK
  • 話さないこと
    • ハードウェアなど、ターゲットプラットフォーム

2

※本日話すのは、開発中の内容です

3 of 24

自己紹介

  • 加藤倫弘(Tomohiro KATO)
    • Twitter: @_tkato_ GitHub: @tkat0
  • 2017/10~ DRIVE CHARTの開発に参加 at DeNA
    • Deep Learningモデリング、高速化
    • デバイスへのデプロイなど低レイヤ
  • Rustは2019/05から本格的に触り始めた
  • 私のミッション
    • 研究開発からプロダクションへの高速なデプロイのため、�エッジMLシステムの性能・品質・生産性の向上に取り組む
    • Deep Learningの高速化技術のキャッチアップ

3

4 of 24

4

5 of 24

DRIVE CHART

5

6 of 24

6

7 of 24

我々のエッジMLシステム開発の特徴

  • AIアルゴリズムは研究開発(Python)からプロダクションで再実装
  • パフォーマンスを意識した実装が必要(C/C++)
  • サーバーサイドと比べてバグにはシビア
  • 新しい論文のアルゴリズムがエッジで動くかスピーディに検証
  • リリース後のインクリメンタルな機能開発への対応

7

8 of 24

C/C++開発での課題

  • C/C++で品質や性能を短期間で作り込むのは限界
    • チーム規模やスキルセット
    • R&Dや他の仕事をしつつの移植
  • C/C++開発時の課題
    • Pythonで書かれたアルゴリズムの移植
    • 行列や画像処理のロジックのテスト、エラーハンドリング
    • 仕様変更や追加開発に対応するための大規模な修正
  • サービス品質向上のために、より性能/生産性/品質を上げていきたい!!!!

8

9 of 24

Rustへの移行

  • Rust移行の決め手(2019/5)
    • C/C++と同等の性能を示すベンチマーク
    • クロスコンパイルできそう (Rust Platform Support
      • stdは使える
  • Rustでのプロトタイプ実装で、不確定要素が消えた
    • 本当に速い?、バイナリサイズ小さい?、使いこなせそう?
    • 既存のC/C++ライブラリをRust bindingして徐々に検証(2 week)
  • Rustで書いた部分の性能も、既存C/C++並の速度。いける!
    • むしろC/C++よりリファクタできたので少し速かった
  • 最初からRustをすべて理解する必要なかった
    • リファクタしながらRustらしくしている

9

10 of 24

AI技術をスピーディにデバイスに載せるためにRustを選択

  • リファクタがしやすくインクリメンタルな開発がしやすい
  • エコシステムは十分で、本質的な実装に注力できた
  • 既存のC/C++ライブラリをbindingできる
  • 他の言語で書かれたシステムと結合しやすい

10

11 of 24

リファクタがしやすく

インクリメンタルな開発がしやすい

11

12 of 24

リファクタがしやすくインクリメンタルな開発がしやすい

  • 後々、大規模なリファクタをしたい
    • インクリメンタルに開発をすることが多いため、負債化しやすい
  • Rustはcrateレベルでのリファクタがしやすい
    • 実装規模の変更に応じてcrateの分離やnamespece変更しやすい
    • CMakeLists.txtの書き換えのようなメンテナンス不要
  • unittestを書きやすい
    • C++では、python bindingしてテストしていた
      • C++のテストコードで画像や行列を扱うのが辛い
    • Rustはimage, ndarrayなど使ってRustでテストが簡潔に書けた

12

13 of 24

エコシステムは十分で、

本質的な実装に注力できた

13

14 of 24

エコシステム

  • チーム開発向きの機能がビルトインで、標準的なやり方に沿えばうまくいく
    • テストフレームワーク、ドキュメンテーション、パッケージ管理
    • メインの実装以上に工数がかかる部分の効率化
  • やりたいことを早く実現
    • 3rdpartyのcrateを活用して短期間で検証
    • 必要なら独自に開発しリファクタ
  • ndarrayは抽象度の高いN次元配列として利用
    • ndarray for numpy users は必見
  • cargo makeをタスクランナーとして利用(後述)
  • rs_tracingでアプリケーションのベンチマーク

14

rs_tracingのExapmle

Chromeで閲覧できる

15 of 24

タスクランナーcargo makeを利用したCI

  • ビルドやテスト、デバイスでのベンチマーク、CIなど自動化
  • タスクは、Rust, Python, ShellScriptで定義できる
  • ShellScriptで独自CIパイプラインを作るのは大変

15

Makefile.toml

16 of 24

既存のC/C++ライブラリをbindingできる

16

17 of 24

RustでDeep Learningをデバイスに実装するには?

  • Deep Learningのソフトウェア的特徴
    • 重い行列演算(for文のN重ループのくりかえし)
    • 並列計算できるので、GPUなどで計算されることが多い
    • 特にハードウェアベンダ(Intel, NVIDIA, arm...)のエンジンが速い
  • 既存のDeep LearningエンジンをRustから呼び出す
    • C/C++ APIをbindgencppでRust binding
  • Rust bindingが用意されたフレームワークもある
    • tensorflowmenohtvmprimitiv
  • 画像処理なども、必要に応じてbinding

17

18 of 24

別言語で書かれた

別のシステムと結合しやすい

18

19 of 24

Python bindingでR&Dや評価プラットフォームとつなぐ

Python binding(pyo3)してx86ビルドで組み込み、評価・検証を行う

  • R&Dチームへの提供
    • Rustで先行開発した機能の評価や、リリースした機能の検証
  • 評価プラットフォームへのデプロイ
    • AI機能(デバイスからサーバー)の結合テストをデバイスレスで実施

19

R&D

edge ai library

(C++ → Rust)

target hardware

vendor middleware (C++)

integration test

edge application

Python binding

Rust binding

C API

※ これはC++でもやってはいました (pybind11)

20 of 24

Rustと他言語のI/Fにprotocol buffers(rust-protobuf)を利用

  • Rustをコアにして開発時・運用時に色々なシステムから使っていきたい
  • APIの数が多いため、各言語へのbindingの開発が大変になる
  • protobufを共通のI/Fにし、実装やドキュメンテーションコストを抑える工夫

20

他の言語bindingも同様

参考:RustとPythonのI/Fをprotobufにするサンプル

https://github.com/tkat0/rust-protobuf-pyo3-example

↓バイト列でやりとりし、serialize/deserializeしている

21 of 24

C/C++開発での課題、はRust移行でどうなった?(1/2)

  • C/C++で品質や性能を短期間で作り込むのは限界 → Rustでは?
    • 性能
      • pure Rustでも問題なし
      • Deep Learning処理はC/C++ライブラリのbinding
    • 品質・生産性
      • エコシステムに乗り、ロジックの実装に注力できるように
      • テストも書きやすい
      • コンパイラのお陰でつまらないバグは防げている
      • 安心してリファクタできるので、開発サイクルが高速化している

21

22 of 24

C/C++開発での課題、はRust移行でどうなった?(2/2)

  • C/C++開発時の課題 → Rustでは?
    • Pythonで書かれたアルゴリズムの移植
      • ndarrayや、抽象度の高い機能(イテレータ等)で簡潔に実装
    • 行列や画像処理のロジックのunittest、エラーハンドリング
      • テストコードはndarrayやimageなどの利用で簡潔に
      • Result型やOption型で簡潔にすべてのエラーをキャッチできる
      • SEGVが無い😂
    • 仕様変更や追加開発に対応するための大規模な修正
      • テスト、リファクタしやすいのでやりやすくなった
  • サービス品質向上のために、より性能/生産性/品質を上げていきたい!!!!
    • 性能や品質を維持・向上した上で、生産性は間違いなく上がった
    • 全体的にコード量削減し、機能によっては半分程度に

22

23 of 24

まとめ:エッジMLシステムをC/C++からRustへ移行した事例

  • AI技術をスピーディにデバイスに載せるためにRustを選択
    • リファクタがしやすくインクリメンタルな開発がしやすい
    • エコシステムは十分で、本質的な実装に注力できた
    • 既存のC/C++ライブラリをbindingできる
    • 他言語で書かれた別のシステムと結合しやすい
  • We are hiring:
    • サービスのビジョンや課題に対するMLを使ったモデリングから、�ソフトウェアに落とし込み運用するまで幅広く活躍の場があります
    • 積極的に新しい技術を応用していきたい方は、ぜひ

23

24 of 24

::std::process::exit(0);

24