Re:ゼロから始めるML生活

どちらかといえばエミリア派です

ゆるふわMLOps入門(Uber:Michelangelo)

最近MLOpsに関して勉強していて、その一環で具体例の調査をしていました。

今回はUberのMichelangeloについて勉強しました。

eng.uber.com

MichelangeloはUberの社内で使用されるプライベートなMLプラットフォームのようです。 Michelangeloは、機械学習における、前処理、学習、評価、モデル配信などワークフローをすべてカバーできるようにデザインされており、社内のエンジニアやデータサイエンティストが使用する事実上の標準ツールになっているようです。

以下は、自分があまり英語強くないので、後で見直す用に日本語のメモになります。 基本的に上の記事の内容そのままなので、悪しからず。。。

背景

以前は、データサイエンティストは様々なツールを使って予測モデルを構築したい一方、エンジニアチームはプロダクションにすることを見据えて限られたツールを提供していました。 結果として、限られたデータサイエンティスト・エンジニアが短期間かつ限られたツール(主にオープンソースを使用しており、独自のツールなどは当時使用できなかったようです)を使用して構築できる簡単なものになってしまい、Uber社内での機械学習の力は非常に限られたものになっていました。

目的

Michelangeloはこれらの問題解決だけでなくビジネス自体をグロースさせることを目的に開発されました。 具体的には、

  • ワークフローの標準化
  • 開発・運用しやすいようにチーム感で共有できるツールの提供

ができるように2015年に開発がスタートしたようです。

具体例

Michelangeloを使用した具体例として、Uber Eatsの配送時間の推定があります。

f:id:nogawanogawa:20200226205209p:plain:w600

Uber Eatsの配送時間推定は、想像以上に複雑です。 オーダーを受けてから店舗と他のオーダーの混み具合から食事を作る時間の推定、配送業者がピックアップし消費者にとどけるまでには、乗り物をどこにおいてピックアップし消費者までの経路がどれほどあるのかから配送の時間を計算する必要があります。 また、これらは、細かいステップ毎に再計算できるようになっていなければなりません。 これらすべてをトータルで計算したものを、サービスに組み込む必要があります。

Uberではこの配送時間推定を実現するためにgradient boosted decision treeを使用し、特徴量として日時や配送先のデータ、過去一週間の調理時間の時系列データ、直近一時間の調理時間のデータなどを使用して推定しています。 これらによって推定するモデルが、モデルサービングコンテナにデプロイされ、これらをUber Eatsのマイクロサービスからリクエストを受け、結果として消費者の画面に推定時間が表示されるようになっています。

システム構成

Michelangeloでは、

  1. Manage data (データ加工)
  2. Train models (学習)
  3. Evaluate models (モデル評価)
  4. Deploy models (デプロイ)
  5. Make predictions (推論)
  6. Monitor predictions (モニタリング)

のようなワークフローを想定しています。

Michelangeloのシステムの構成としては HDFS、Spark、Samza、Cassandra、MLLib、XGBoost、TensorFlowなどを組み合わせて構築されているようです。

f:id:nogawanogawa:20200226205802p:plain:w600

Manage data (データ加工)

機械学習において、良い特徴量を見つけることが最も大変な作業と言ってもいいかもしれません。 そして、データパイプラインを整備することが最も工数のかかる部分になっていることも少なくありません。

MLプラットフォームでは、学習用に特徴量とラベルのセット、推論用に特徴量を作り出すためのデータパイプラインを構築しやすくすることが求められ、データレイクやデータウェアハウス、データ配信の仕組みと統合されている必要があります。 スケーラブルかつ高性能、データフローやデータの品質のモニタリング機能も必要でしょうし、オンライン・オフラインでの学習・推論をサポートするなど、必要な要件は多岐にわたります。 更に、無駄な作業の削減やデータの品質の観点から、作った特徴量は共有可能であることが望ましいです。 常にユーザーが最良の判断を下せるように、環境が整備されている必要があります。

f:id:nogawanogawa:20200226211544p:plain:w600

Michelangeloでは、オンラインとオフラインのパイプラインについて処理を明確に分けており、オフラインではバッチ学習・バッチ推論、オンラインでは高速なオンライン推論を可能にします。 また、Uberでは様々なチームで同じ特徴量を使用することが散見されており、Michelangeloでは他のチームで入念に作成されあ特徴量をチーム間で共有・発見できるように、特徴量を管理する機構を設けています。

offline

Uberでは取引やログデータはHDFSデータレイクに蓄積されておりSparkやHive SQLを使って簡単に取り出せる様になっています。 これらのデータから特徴量を作り出すためのコンテナやスケジューラを提供し、特徴量を共有可能にしています。 データ処理に必要なスケジューラやコードやデータの問題を検出するためのモニタリングのためのツールも整備されます。

online

オンラインでは、HDFSにはアクセスせず、オンラインデータベースの一部の特徴量を直接計算することはパフォーマンス制約上困難です。 代わりに、オンラインで必要になる特徴量に関して、予め計算してCassandraに保存しておくことで読込と推論の時間を短縮しています。

オンラインでの処理については大きく2種類の処理から選ぶことになり、

  • バッチで事前学習済みの特徴量を使用して学習・推論する
  • kafkaで収集されたほぼリアルタイムの情報を使用して学習・推論する

になっています。 前者はレストランの過去7日の平均調理時間など、後者は直近1時間の平均調理時間などが該当します。

特徴量の共有

特徴量の共有には非常に大きな価値があります。

  • 用途に応じて特徴量を加えることが簡単で、プロジェクト毎にモデルをカスタマイズできる
  • 一度特徴量を保存してしまえばオンライン・オフライン問わず使用するのは簡単かつ高速

将来的には、保存した特徴量から自動で問題に対して有効な特徴量を選択できるようにすることも見据えています。

特徴量選択と加工用DSLの整備

実際に特徴量を使用する際には保存されている特徴量に過不足があったり、ちょっとした加工が必要になったりします。 そういった処理に適用するために、ScalaのSubsetとしてデータ加工用のDSLを作っています。 これらを使って、Customerチームなどが必要に応じてデータを簡単に加工できるようにしています。

Train models (学習)

現状では、大規模分散学習として

  • 決定木
  • 線形回帰
  • ロジスティック回帰
  • 時系列モデル
  • DNN

をサポートしています。 これらのアルゴリズムはUberのAI Labが顧客の要望を踏まえた形で開発・拡張しています。

これらの機能をカスタマーチームが自身で使用して、それぞれに合ったモデルを学習させ評価し、実際に配信できるようにしています。 分散システムは何十億ものサンプルを使った学習から非常に小さいサンプルでの学習まで、素早いイテレーションでスケールします。

モデルの学習語は、evaluation report と合わせてperformance metricsを計算します。 そして、学習終了時にはモデルの設定値や学習パラメータ、evaluation reportをセットでモデルリポジトリに記録していきます。

加えて単一のモデルを学習するために、ハイパーパラメータ探索の機能を備えており、モデルを分割することができるようになっています。 ユーザーは学習時の設定に基づいて自動で学習データを分割し、親子関係の子モデルが規定の精度に達しなかったときなどに、親モデルの学習に戻るなど、必要に応じてフォールバックできるようになっています。

学習はUIやAPI、jupyter notebookから編集することができる様になっています。

f:id:nogawanogawa:20200226211659p:plain:w600

Evaluate models (モデル評価)

モデルは特徴量やアルゴリズム、ハイパーパラメータの組み合わせによって問題を解決する良い組み合わせを探索する過程の一部として学習されます。 つまり、最良のモデルが発見されるまでは、何百ものモデルを学習させることは珍しくありません。 こうした大量のモデルについて、最終的にプロダクションに入らないモデルについても、それぞれのモデルパフォーマンス情報はエンジニアにとって非常に有用なものとなります。 そのため、モデルをトラッキングし、評価を行い、それぞれを比較することは大量のモデルを試行錯誤する状況下ではとても大きな挑戦であり、非常に大きな価値を持ちます。

Michelangeloではすべての学習済みモデルは下記の補足情報とともにCassandra上でバージョン管理されています。

  • 誰がモデルを学習したか
  • ジョブの開始・終了時間
  • モデルの設定値
  • 学習・テストデータセット
  • 各特徴量の相互作用の分布
  • モデルの精度
  • 各モデルについて、標準なグラフ
  • 学習後のモデルのパラメータ
  • 可視化用のモデルのメトリクス値

これらの情報はWebUIとAPIによって参照可能になっており、個々のモデルの詳細を確認したり比較したりできるようになっています。

Model Accuracy Report

モデルの評価については下記のように可視化されます。

f:id:nogawanogawa:20200226214433p:plain:w600

f:id:nogawanogawa:20200226232543p:plain:w600

Decision Tree Visualization

重要なモデルについては、そのモデルの挙動を可視化するためのツールを提供することで、モデリングに役立てています。 決定木については下記のようなUIを提供していて、分岐点や特徴量の重要性、各分岐における要素の分布などを確認できるようにしています。

f:id:nogawanogawa:20200226232659p:plain:w600

Feature report

特徴量ごとの重要性についてもレポートを作成しています。 2つの特徴量を選択すると、それらの相互作用や依存関係について確認することができるようになっています。

f:id:nogawanogawa:20200226232616p:plain:w600

Deploy models (デプロイ)

デプロイの方式には大きく

  • online
  • offline
  • library

の3つの方法を提供しています。 offlineでは、オフラインコンテナにデプロイされ、バッチ推論に使用されます。 onlineはオンラインサービスクラスタにデプロイされ、RPCの呼び出しに応じて個別あるいはバッチ的に推論を行います。 ライブラリに組み込む形でもデプロイ可能になっており、オンラインと同様の動きで、別のサービスに提供している。

f:id:nogawanogawa:20200226232811p:plain:w600

どの方法で合っても、生成物はすべてzip でまとめて配信することができます。 推論するコンテナは自動で最新のモデルをロードして、推論のリクエストに対する応答を開始できます。

こうしたデプロイ作業はAPIによって提供されており、UberEatsでは学習とデプロイはWebUIによってデータサイエンティストが操作できる様になっています。

Make predictions (推論)

モデルがデプロイされたら、必要になる特徴量をデータパイプラインやDBから直接読み込むことで推論が可能になります。

f:id:nogawanogawa:20200226232851p:plain:w600

複数のモデルをA/Bテストやモデルの切り替えを簡単に行う機能も提供しています。 オンライン推論では、クライアント側からは特徴量と合わせてモデルのUUIDまたはモデルのタグが送信され、これによって推論に使用するモデルを振り分けています。 バッチモデルのときは、推論の結果にUUIDが付与されて後からどのモデルによる予測かを識別できるようになっています。

モデルの置き換えについては、同じ特徴量を使用する場合には、新しいモデルに対して古いモデルと同じUUIDを付与することで、クライアントサイドの変更を必要としないメリットがあります。 A/Bテストを行う際にも、UUIDやタグを使用して、実験の枠組みに沿ってリクエストを振り分けることで、実現しています。

オンライン、オフラインともに性能が重要になりますが、オンラインについては推論サービスをホスト数を増加させ、ロードバランサによってスケールアウトできるようにしています。 オフラインについては、Sparkを使用した推論も可能にしています。

Monitor predictions (モニタリング)

将来の学習のためにはモデルの予測に関する結果を正確にモニタリングし、モデルが効果的に動作している、あるいはもはやあっていなくなってしまった、などを検知する必要があります。 このために、自動的にログと推論の割合を記録していて、推論とその結果を突き合わせています。 この情報とともに、リアルタイムでモデルの精度を各種指標とともにリアルタイムで計算しています。

f:id:nogawanogawa:20200226205802p:plain:w600

将来的に

下記のような機能をサポートしていきたいとしています。

  • AutoML
  • Model visualization
  • Online learning
  • Distributed deep learning

感想

Uber Eatsのような意外と身近なサービスで使われているMichelangeloについて見てみました。 すごそう。(小並感)