Google Cloud に機械学習 API をデプロイするとき、Cloud Run と Vertex AI Endpoint のどちらを選ぶべきか?

こんにちは。2024年6月に中途入社した機械学習エンジニアの深澤(@fukkaa1225)です。新しいエキサイティングな環境を毎日楽しんでます!

本記事では機械学習 API をデプロイする際、コストの観点からどのようなサービスを選ぶべきかについて述べたいと思います。

はじめに

コミューンは Google Cloud を活用している企業です。機械学習アプリケーションも同様に Google Cloud を活用しています。

機械学習アプリケーションとしてデプロイされているものの数はまだ多くはありませんが、一つ一つが重要な役割を果たしています。その中の一つに、投稿詳細画面でのニアリアルタイムレコメンドが存在します。詳細はこちらの記事を御覧ください。

tech.commune.co.jp

こちらのアプリケーションは Pub/Sub 経由でリクエストを受け取った前段の API が、後段に控えている推論サーバにリクエストを投げる形を取っています。このリクエストは少し時間がかかるため、非同期に処理するようになっています。

このようなアプリケーションをデプロイするとき、Google Cloud ではどのサービスを選ぶのが最も適切なのでしょうか?本記事では、このテーマについて主にコスト面に焦点をおいて論じていきます。

デプロイする先の選択肢

Google Cloud で機械学習 API をデプロイする場合、その選択肢をまずは洗い出してみます。

  • Vertex AI Endpoint
  • Cloud Run
  • Compute Engine
  • Google Kubernetes Engine(GKE)
  • App Engine

これらが主な選択肢として考えられるかと思います。今回デプロイしたいアプリケーションはコンテナで動作するようになっています。そのため、コンテナのデプロイが容易で管理の手間が少ないサービスを選びました。具体的には Cloud Run と Vertex AI Endpoint の 2つに絞りました。

コスト面における Cloud Run と Vertex AI Endpoint の違い

各サービスの詳細はここでは割愛して、主にコスト面での違いを比較しようと思います。なお、それなりの規模で運用しているサービスであることを前提として、ここでは無料枠については議論の対象からは外します。

まず Cloud Run ですが、こちらは Google Cloud 上で動くコンテナ実行に特化したプラットフォームです。いわゆるサーバレスな環境でアプリケーションを実行できます。課金体系はリクエストの処理時間に応じて利用した vCPU, メモリになります。注意したいのが、リクエストを受け付ける前のコンテナ起動にかかる時間も課金の対象に含まれる点です(CPUを常に割り当てる設定などもありますが、ここではリクエスト時のみ CPU を割り当てる設定だと仮定します)。

次に Vertex AI Endpoint について述べます。こちらは Cloud Run とは異なり、Compute Engine のインスタンスがバックエンドに立っていて、その環境上でアプリケーションを実行します。そのため、課金額は利用するインスタンスのタイプに依存し、利用していない時間帯でも立てているインスタンスの台数に応じて料金が発生します。また、リクエスト流量に応じてインスタンス台数をスケールさせる機能が備わっています。

サービス 課金体系 具体例
Cloud Run リクエストの処理時間に応じて利用した vCPU, メモリ 4cpu, 16GB mem で起動している場合、CPUは$0.000096/秒, メモリは$0.00004/ 秒
Vertex AI Endpoint 利用する Compute Engine インスタンスのタイプごとの単価×起動時間 (e2-standard-4, 4cpu,16GB mem)ならば $0.17/hour

Cloud Run の方は課金額の単位が秒、Vertex AI Endpoint は時間であることに注意が必要です。また、Cloud Run の課金は別のリクエストを処理している最中に別のリクエストが来て捌けるのであれば、その分安くなります。concurrency をあげると試算ツールの見積もりが安くなるのはこれが要因です。

試算ツール: https://cloud.google.com/products/calculator?hl=ja

Cloud Run の課金方式

refs. https://cloud.google.com/run/pricing

そのため、厳密な料金計算は API の実際の挙動などに左右されるところがあるので結構難しいです…...。

どちらが安いのか?

今回はいくつかのパラメータを固定したシナリオで Cloud Run と Vertex AI Endpoint の料金を比較していきたいと思います。では、これを3つのケースで料金を比較してみます。

前提として 4cpu,16GB memory のリソースが必要な API をデプロイし、その API は 1リクエストに対して1秒かけてレスポンス(1RPS)を返すとします。また、Cloud Run の concurrency は 1 (並列処理はできない)とします。

ケース1: リクエストが来る時間帯が一部だが、流量が大きい場合

機械学習による推論部分は API として用意していて、その API を利用するのが何らかの定期的なバッチアプリケーション等の場合がこのケースとして考えられます。以下の条件で24時間のコストを比較してみましょう。

  • 3時間で1秒に1リクエストが来る
    • 1RPS であるため、1インスタンスで捌くことができる。そのためコンテナのスケーリングは発生しない状況
  • コンテナの最小個数は0

Vertex AI Endpoint の場合はインスタンスの台数1台が待機している(レプリカ台数は増えない)として、 0.17 (ドル/h) * 24 (h) で 4.08ドルとなります。

Cloud Run の料金は CPU使用時間 1.0368ドル + メモリ使用時間 0.432ドル = 1.468ドル となります。

項目
リクエスト数 1秒に1リクエスト x 3時間 = 10,800リクエスト
CPU使用時間 10,800リクエスト x 1秒 = 10,800秒 (コスト: 1.0368ドル)
メモリ使用時間 10,800リクエスト x 1秒 = 10,800秒 (コスト: 0.432)
合計コスト CPUコスト: 1.0368ドル + メモリコスト: 0.432ドル = 1.468ドル

ということで、Vertex AI Endpoint: 4.08 ドル、Cloud Run: 1.46ドル となり Cloud Run のほうが安いという結論が得られました。なお、同様のパラメータであれば 8時間まで Cloud Run のほうが安くなります。

ケース2: リクエストが常時来続けるが、流量が小さい場合

続いて 10秒に1度リクエストが来る状態が24時間続く場合を考えます。Cloud Run はリクエスト処理時間に応じた課金が発生するため、それに留意して計算すると次のようになります。

Cloud Run: CPU使用時間 0.82944ドル + メモリ使用時間 0.3456ドル = 1.17504ドル

項目
リクエスト数 10秒に1リクエスト x 24時間 = 8,640リクエスト
CPU使用時間 8,640リクエスト x 1秒 = 8,640秒 (コスト: 0.82944ドル)
メモリ使用時間 8,640リクエスト x 1秒 = 8,640秒 (コスト: 0.3456ドル)
合計コスト CPUコスト: 0.82944ドル + メモリコスト: 0.3456ドル = 1.17504ドル

Vertex AI Endpoint はインスタンス起動時間に対する課金のため、先ほどと同様で 4.08 ドルです。この設定の場合も Cloud Run のほうが安くなります。

ケース3: リクエストが常時来続けていて、かつ流量が大きい場合

最後に、リクエストが常時来続けていて、かつ流量がそれなりにあるためにコンテナのスケールアウトが発生する場合です。ここでは1秒に2リクエストが来る状況を想定します。concurrency を 1 としているため、もう一つコンテナが必要になります。このような状況では以下の料金となります。

Cloud Run: CPU使用時間 16.5888ドル + メモリ使用時間 6.912ドル = 23.5008ドル

項目
リクエスト数 1秒に2リクエスト x 24時間 = 172,800リクエスト
CPU使用時間 172,800リクエスト x 1秒 = 172,800秒 (コスト: 16.5888ドル)
メモリ使用時間 172,800リクエスト x 1秒 = 172,800秒 (コスト: 6.912ドル)
合計コスト CPUコスト: 16.5888ドル + メモリコスト: 6.912ドル = 23.5008ドル

Vertex AI Endpoint はインスタンス起動時間に対する課金のため、ケース1や2と同様で 4.08 ドルです。このケースになると Cloud Run よりも Vertex AI Endpoint を選ぶことのメリットが出てきます。

なお、concurrency を 1 という極端な設定としてきましたが、これを 10 など大きな値にして一度に処理することで課金対象時間を減らすことは可能です。しかし、並列数を増やしたことでリクエストにかかる処理時間が全く変わらないということは考えにくく、多くの場合でより大きな CPU・メモリを要求するか、同時コンテナ数を増やすことになると思います。すると結局トータルではあまり節約にならなかった、ということになりやすいです。

各ケースで得られた Cloud Run の料金見積もりは以下のようになりました。

ケース リクエスト数 CPU使用時間 (s) メモリ使用時間 (s) 合計金額 ($)
Case 1: 一部のみ流量あり 10,800 10,800 10,800 1.46
Case 2: 常に流量あり(少なめ) 8,640 8,640 8,640 1.17
Case 3: 常に流量あり(多め) 172,800 172,800 172,800 23.50

まとめ: Cloud Run と Vertex AI Endpoint のどちらを選ぶべきか?

機械学習 API のような大きなリソースを要求するシチュエーションにおけるコストを比較してみました。結果として、以下のようにそれぞれの特徴をまとめられるかと思います。

Cloud Run を選ぶべきケース

  • リクエストが来る時間帯が決まっている場合
  • スケーリングがあまり発生しない程度のリクエスト流量の場合
  • 低リソースな API

Vertex AI Endpoint を選ぶべきケース

  • 常時一定のリクエストがあり、スケーリングが頻繁に発生する場合
  • ハイリソースで、推論に一定の時間が必要な API

Cloud Run は多くの API にとって適したユースケースであることは間違いありません。これに対して、機械学習による推論を行う API というのは少し特殊なケースである、ということを認識する必要があります。ハイリソースで推論にも一定の時間がかかる API を長い時間起動するのであれば、リクエスト処理時間ではなくインスタンス起動時間で課金が行われる Vertex AI Endpoint の方が適している場面も多く存在していそうです。

コミューンではどうしているのか

冒頭に紹介しましたが、投稿詳細画面でのニアリアルタイムレコメンド API は本記事のケース3 に相当します。そのため、Vertex AI Endpoint でデプロイされて運用を行っています。

今回、Cloud Runへの移行を検討して、実際に移行も実施しましたが、料金がかなり高くなることに早い段階で気づき、切り戻しを行いました。 すぐにこの事象に気付けたのは、コミューンの機械学習環境ではデプロイされたものをCloud Monitoringのカスタムダッシュボードに追加してメトリクスを管理しており、日頃からチーム内でメトリクスを見る習慣が根付いていたからです。

ハイリソースを要求して常時リクエストが来るような API には Cloud Run は向いていないのかも……?という学びがあり、本記事を書こうと思った次第です。

こちらの記事が少しでも皆様の快適な Google Cloud 機械学習ライフの参考になれば幸いです!引き続き精進していきます。

さて、コミューンでは一緒に働く仲間を募集しています! 少しでもコミューンの開発組織や環境に興味がある方はぜひカジュアル面談しましょう!

docs.google.com