GKE Autopilotで作るMLリアルタイム推論基盤

こんにちは!エンジニアの@tik-son, @ikemonnとMLエンジニアの@nichimuです。

本日ついに待望のGKE Autopilotがリリースされましたね!
この記事では、GKE Autopilot上で動いているリアルタイム推論基盤でなぜ我々がGKE Autopilotを利用することにしたのかについてお話しします。

MLリアルタイム推論基盤とは

リアルタイム推論基盤とは、機械学習のモデルを使用して、リアルタイムに推論が行える基盤のことです。
このリアルタイム推論基盤を用いることで、

  • エンドユーザーがsession内で電話するかを予測する
  • エンドユーザーが会員登録を行ったsession内で資料請求をするか予測する

のように数秒-数分後にエンドユーザーがどんな状態であるかなどを予測することが実現可能になります。
この基盤はまだ絶賛開発中で誰もが簡単に使える状態になっていないのですが、このブログを読んで何かビジネス課題を解決したい!という方がいましたら、ぜひ、弊社までお問い合わせください!という宣伝はさておき、さっそく本題に入っていきます。

リアルタイム推論基盤のデータの流れとしては、以下のようになります。

realtime_inference

  1. エンドユーザーがwebやapp上で何かしらの行動を行い、Event DataをKARTEのリアルタイム解析/アクション基盤 (Not ML) に送信する
  2. リアルタイム解析/アクション基盤に送られたEvent Dataをリアルタイム推論基盤 (ML) にCloud Pub/Subを通じて送信する
  3. Cloud Dataflow上でEvent Dataに関する以下の処理を行う
    1. Event Dataを整形して、生ログとしてCloud Spanner[1]に保存する
    2. Event Dataをfilterして、推論用APIへの推論トリガーをCloud Pub/Subを通じて投げる
  4. 推論用API (Cloud Run) で、機械学習モデル[2]を用いた推論を行い、推論結果をCloud Bigtableに書き込む
  5. Cloud Bigtableに書き込まれた推論結果をコア基盤から読み込み、クーポンなどのActionを配信する

今回、GKE Autopilotを使用した部分としては、図の赤枠で囲ってある推論用内部API componentになります。
GKE Autopilotがローンチされるまでは、compute resourceとしてCloud Runを使用しており、以下でどのようにしてGKE Autopilotを使うようになったかをお話してまいります。

推論用内部API の要件と抱える課題

さて、推論用内部API として、Cloud Runを使用していると記述しましたが、推論用内部API の要件としては以下になります。

  1. 以下を実現するため、自由度高くコードを書くことができるDocker Imageベースでデプロイできること
    • Cloud Pub/Subから推論トリガーを受け取り、予測を開始する
    • 生ログデータをCloud Spannerから取得する
    • Pythonで書かれた機械学習のモデルを使って、予測を行う
    • Cloud Bigtableに予測結果を書き込む
  2. リアルタイム解析/アクション基盤に組み込んで使用するため、システムとして高スケーラビリティや高可用性などのシステムとしての強さがあること
  3. 基盤における運用/開発ではなく、モデルの作成やデータの活用など、MLエンジニアが本質的な価値にフォーカスする状態を作れること

当初、これらの要件を満たすために、色々とベンチマークをした結果Cloud Runを使用していましたが、以下の課題がありました。

  • Service Accountでの制御はかけているものの、CloudRunの仕様でCloudRun自体に外部IPを持たせないといけないため、セキリュティ的に綺麗な設計ではない
  • Cloud Pub/Subで推論トリガーを受け取るときにPush型を使用するが、Push型でのError Handlingが難しいので、なるべくPull型で扱いたい

この課題はGKEを利用することで解決できるのですが、

  1. 基盤における運用/開発ではなく、モデルの作成やデータの活用など、MLエンジニアが本質的な価値にフォーカスする状態を作れること

この要件と先程述べた課題とのバランスが難しく、最終的にはMLエンジニアがGKEのインフラレイヤーを管理/運用する大変さを鑑みて、課題に目をつぶりCloud Runを利用している状況でした。

GKE Autopilotとは?

そういった課題をかかえたところ、我々にとってちょうどいい塩梅のProductが発表されました。それがGKE Autopilotです。
GKE Autopilotとは、GKEの新しいmodeです。(従来のGKEはGKE Standard)
Control Planeに加えて、Nodeの管理もGoogleのSREが行ってくれるので、クラスター管理の運用コストを下げることができます。さらに、SLAも提供されているので、Nodeの可用性やサイジング、スケーリングなどを気にすることなく、GKEを利用することができます。GKE Autopilotでは、ワークロードに応じて自動で裏側のHWをプロビジョニングするので、サービスやアプリケーションの開発に専念することができます。

特徴は下記です。

  • NodeもGoogleが管理してくれる
  • ユーザーのワークロードにもとづいてリソースがプロビジョニングされる
  • Podに対してもSLAが設定されている
  • Podレベルで課金される
  • ユーザーのプロジェクト内でclusterが構築される(他のユーザとリソースを共有しない)

gkeauto
https://cloud.google.com/blog/products/containers-kubernetes/introducing-gke-autopilot

また、GKE Autopilotでは下記のようなよく使われるワークロードやツールがサポートされており(一部今後サポート予定)で、様々なユースケースで活用できます。

  • Stateless web app
  • Custom Database (StatefulSet)
  • Long-running batch job (Job)
  • DaemonSets that don’t violate GKE Autopilot rules
  • Add-ons: Cloud Run for Anthos, Istio
  • Machine Learning (GPU, TPU)
  • Tools and ecosystem - for example, Helm charts that don’t violates GKE Autopilot rules

さらに、下記のような設定も利用できるため、使い勝手としても限りなくGKEに近い自由度があります。

  • 高可用性: Regional, Regular Release Channel, Auto-Update, Auto-Repair, Surge Upgrade
  • スケーリング: HPA, VPA, NAP
  • ネットワーク: Private clusters, VPC Native (alias IP), IP-friendly (limit cluster size/ pods per node), setup Cloud NAT
  • セキュリティー: Workload Identity, Shielded Nodes, Secure-boot-disk, etc

以下のように、manifestの書き方もGKEのmanifestとほぼ同様に書くことができます。

apiVersion: "apps/v1"
kind: "Deployment"
metadata:
  name: "plaid-test"
  namespace: "plaid"
  labels:
    app: "plaid-test"
spec:
  replicas: 3
  selector:
    matchLabels:
      app: "plaid-test"
  template:
    metadata:
      labels:
        app: "plaid-test"
    spec:
      serviceAccountName: gke-auto
      containers:
      - name: "realtime-inference"
        image: "gcr.io/plaid-test/realtime-inference:latest"
        resources:
          requests:
            memory: "6Gi"
            cpu: "2"
          limits:
            memory: "6Gi"
            cpu: "2"

くわしくはGKE Autopilotのドキュメントをご確認ください。

GKE Autopilotの導入

GKE Autopilot導入は、KARTEのリアルタイム解析/アクション基盤を作っているエンジニア、MLリアルタイム推論基盤を作っているエンジニアの両方で検証をしながら進めていきました。
推論用内部APIの要件と抱える課題 でお話した要件と課題をほぼ満たせることとなり、productionのworkloadで現在稼働しているのですが、その中で以下のようなPros/Consを感じました。

リアルタイム解析/アクション基盤を作っているインフラエンジニアが感じたこと

  • Pros
    • クラスタのインフラレイヤーをGoogleが管理してくれるので運用が楽そう。(productionの運用は本日から始めるので、実際の恩恵を受けるのはこれからだと思っている)
  • Cons
    • vpc native cluser前提なので、正しく設計/構築するには、利用するip range/NAT等のNWインフラの知識が必要になり、アプリケーションエンジニアだけでは現状難しそう。(privateなNW通信を行わない、vpc NWはdefaultでcloud pubsubでコンポーネント間を通信するというようなシステムであれば、NWを意識しなくていいので構築は楽かもしれない)
    • preemptible vmに対応していない
    • 基本GKEなので、GKEで出来ないことはできない。例えば、clusterレベルのスケールアウトがGKEより速いなどはない。(厳密にはこれはConsではないとは思うが、マネージドサービスである期待をこめて、一応書いておく)

MLリアルタイム推論基盤を作っているMLエンジニアが感じたこと

  • Pros
    • manifestにresourcesのlimitsとrequestsを記述するだけで、MLエンジニアが欲しいマシンリソースが簡単に用意でき、運用まで期待できる
    • リソースはCloudRunと異なり、動き続ける前提なのでPub/SubのPull型を簡単に扱うことができる
    • インフラの柔軟性を担保しつつ、運用を考えなくていいのはいい。開発が捗る。
  • Cons
    • MLリアルタイム推論基盤で今後利用したい、GPUがまだサポートされていない

まとめ

GKE Autopilotは銀の弾丸ではないので、インフラエンジニアからすると微妙な部分が少し多めに見えてしまうのですが、このProductのポイントはそこではなく、 ある程度柔軟なインフラが必要だけど運用までは面倒見きれないようなユースケースに絶妙にハマる ということだと実際使ってみて強く感じました。
(くわしくはGoogle CloudのKazuuさんのブログをご確認ください)

Consで書いたことはGCPのことなので、GA後にすぐに対応してもらえるだろうと勝手に期待しています(笑)
また、privateなvpc内通信が必要にならないよう、cloud pubsubなどでシステム間を疎にして設計していけば、GKE Autopilotの恩恵をより受けやすくなるのではないかとも感じました。もちろん、システム間のやり取りが大量なものはprivateなvpc通信前提で作る方がコストが安くなるとは思いますが、このあたりはトレードオフになると思うので上手く見極めながら設計していくといいと思われます。
我々も今後はこのあたりを意識しながら上手くGKE Autopilotなどを駆使し、システムを作っていきたいと思います。

最後に

プレイドではGKE Autopilotのような新しい技術をうまく使い、面白いProductを開発していきたいエンジニア(インターンも!)を募集しています。
詳しくは弊社採用ページまたはWantedlyをご覧ください。 もしくはお気軽に、下記の「話を聞きに行きたい」ボタンを押してください!


  1. Cloud SpannerにEvent Dataを書き込んでいる理由としては、以下の2つの理由があります。(1. 機械学習のモデルを使用した推論ではエンドユーザーの過去の情報も必要だが、Event Dataには過去の情報はあまり含まれていないため、過去の情報も保持しておく必要がある, 2. 機械学習のモデルを作成する際にはBigQueryにSQLを投げて特徴量作成の試行錯誤をするため、推論時もSQLがかけるDBだと相性がよい) ↩︎

  2. 機械学習のモデルの作成やデプロイなどは、AI Platform NotebookやAI Platform Pipelinesを使用して行っています。 ↩︎