メモ JiZhi: A Fast and Cost-Eective Model-As-A-Service System for Web-Scale Online Inference at Baidu(KDD2021)

内容

Deepを活用したレコメンドモデルは様々な領域で活用されているが、十分に学習されたモデルを本番環境で通用する速度で推論でき、多くのユーザーから多様な時間帯でのアクセスを捌き、コストを最適化することはチャレンジングな取り組み。
この論文ではJiZhiというModel As A Serviceを提案している。

この仕組によって、推論の効率を犠牲にせずに200%の追加トラフィックに耐えることができ、1000万USドル以上のコスト削減を実現できている。

システム

f:id:A_Koide0519:20210908230458p:plain

Staged event-driven pipeline

各構成要素を以下のように定義する

定義1:ステージプロセッサ

推論のworkflowにおいて、ステージプロセッサpを以下のタプルで定義する。
{ \displaystyle p = \lt op,c \gt }
 op:特定のステージの機能をカプセル化したプリミティブを表す演算子
 c:上流のプロセッサからのイベントをキューイングするチャンネル
推論のworkflowはステージプロセッサの集合でモジュール化される。
 P=\{p_1,p_2,...\}
各ステージプロセッサでは、オペレータが入力されたイベントを処理したイベントを次のステージプロセッサに添付されたチャンネルキューに渡す。

定義2:Staged Event-Driven Pipeline (SEDP)

有向非巡回グラフとして定義される。
 G = (P, E)
Pはステージプロセッサの集合。
Eは2つのステージプロセッサを接続するエッジ
ex.  e_{i,j} p_i p_jを接続するエッジ
SEDPではすべてのエッジが同じステージのプロセッサを指し示し、チャンネルを共有しており、aggやjoinと言った複雑なイベントの処理を可能にしている。

SEDPはここのステージプロセッサの依存関係を自動で分析し、共有されたチャンネルを構築し、完全非同期実行をコンパイルする。

f:id:A_Koide0519:20210911171436p:plain

上記がuser-itemのworkflowの例。
user featureの抽出とitem featureの抽出、変換処理それぞれ別のステージプロセッサで実行される。リクエストのすべての生の特徴量は対応する特徴量パラメータ(embeddingsやsparse vector)を取り出すために再結合される。
最後に取り出したパラメータをDNN networkにfeedしてアイテムの関連スコアを取得する。
ステージプロセッサを非同期に実行することで、ロングテイルアイテムによるパイプラインの停滞の可能性を減らし、全体のスループットを向上させている。
ステージプロセッサのキャパシティ(並列数、メモリなど)は個別に調整できるので共有インフラの利用効率を高められる。

また、SEDPはマルチテナント拡張機能により、単一のパイプラインの中で複数のDNNモデルにアクセスでき、多段でDNNモデルを噛ませたり並列でDNNモデルを噛ませたりできる。これによりレコメンドの性能を上げたりA/Bテストを容易に実施できる。

Heterogeneous and hierarchical storage

f:id:A_Koide0519:20210911180556p:plain

The Distributed Sparse Parameter Cube

レコメンドでは、DNNは通常巨大でスパースなsub-networkと適度な密度のあるネットワークからなる。
そこでスパースなsub-networkの極めて高次元なパラメータを管理する仕組みを導入した。
これはread-onlyのKVSで、keyはコンパクトな特徴量のシグネチャとして定義され、valueはスパースな特徴量に対応するユーザーフィードバックの統計量とモデルの重みを表す。
すべてのキーはメモリに格納され、値はGBサイズにブロックにまとめられてメモリあるいはSSDに格納される。ここはlatencyとハードウェアの容量のtrade-offになる。

Heterogeneous and Hierarchical Cache

上述のcubeによって数ミリsecのlatencyで特徴量のアクセスができるが、オンライン推論のプロセスではまだ通信量が計算量が多いので、いくつかのキャッシュを導入した。

  • Cube cache

提供済みのBaiduのレコメンドサービスの中で、1億のcubeへのアクセス頻度可視化してみると、80%以上のリクエストは全体のたかだか1%の値にしかリクエストしていない。したがってキャッシュの導入はnetwork I/Oコストの削減に有効。
Cube chaceはmemory layerとdisk layerの2層のキャッシュになっており、memory layerにはLFUポリシーに基づいて上位0.1%のkey-valueのペアを格納し、disk layerには同様のポリシーに基づいて上位1%のkey-valueのペアを格納する。
これによってリクエストを90%削減でき、平均のレイテンシが10向上した。

  • Query cache

user-itemのスコアは短時間ではstableであるという考察から、過去のuser-itemのスコアをキャッシュする。
実際にスコアの不変の割合を計算してみると、2分後でも60%以上のスコアは不変だった。
このキャッシュは定められたtime windowを経過するか、ユーザーからのフィードバック(click,unlike)に基づいて更新される仕組みで、更新のポリシはLRUとなっている。結果として20%の計算コストを削減できている。

Intelligent resource manager

オンライン、オフライン両方のオートチューニングコンポーネントになっており、自動でリソース割当や各コンポーネントの負荷軽減の方針を検索、学習する。
#内容がなかなか難しいので詳細は省く

  • オフライン

目的としては、レイテンシの制約下においてリソースの消費を最小化する各種パラメータを探索することになる。
レイテンシの制約はデフォルトの設定以下になるようにする。

  • オンライン

レコメンドの問題では1st pahseでrecallが最大になるように候補を作り、2nd phaseでリランキングして数個のアイテムまで絞るが、2nd pahseに入力するアイテムの中で最初から低品質なものをカットしてしまうことで、リランキングの計算コストを抑えることができるはず。
そこで精度が指定した値以上に小さくならないように低品質な候補アイテムをプルーニングするポリシーを作成する。

評価

既存のBaiduのレコメンドシステムとの比較(リファレンスはあるけど読めていない)。
いくつかのBaiduの本番で動いているレコメンドサービスで比較した結果、各種パフォーマンスが改善。特にスループットインスタンス数が大きく改善している。
f:id:A_Koide0519:20210911191315p:plain

他にもいろいろな評価や分析をしているがここのインパクトがとにかく大きい。

所感

Intelligent resource managerの部分は難しくて読みきれなかった。
推論のパイプライン周りなどはかなり手が込んでいてすぐになにか試せそうという感じはしなかったが、ストレージ側のデータの持ち方やキャッシュの入れ方、キャッシュのポリシーの考え方は参考になりそう。