自社でAIモデルをホストしたい、でもスケーリングが怖い

ミドリ: タツヤさん、うちの会社で画像認識モデルを自社ホスティングすることになったんですけど、負荷が全然読めなくて。昼間はリクエストが殺到するのに、夜間はほぼゼロ、みたいな感じで。

タツヤ: AI推論ワークロードの典型的なパターンだね。固定のGPUサーバーを常時稼働させたら、夜間は無駄にコストがかかる。でもピーク時にリソースが足りないとレイテンシが爆発する。

ミドリ(confused): そうなんです。上から「コストも抑えろ、でもレスポンスも速くしろ」って言われて板挟みです……。

タツヤ: それを解決するのがKubernetesベースのAI推論基盤だよ。今日は実践的なアーキテクチャを組み立てていこう。

なぜKubernetesなのか

ミドリ: そもそも、AI推論にKubernetesって必要ですか?Docker1台で動かせばよくないですか?

タツヤ: 小規模ならそれでいい。でも本番環境で以下の要件が出てきたら、Kubernetes一択になる。

ミドリ(nodding): たしかに、モデルが落ちたら手動で再起動、だと本番運用は無理ですね。

タツヤ(smiling): そう。Kubernetesはこれらを宣言的に管理できる。「GPU付きノードを最低2台、最大10台、レイテンシがP95で200ms超えたらスケールアウト」みたいなルールを書くだけで、あとはK8sが面倒を見てくれる。

アーキテクチャ全体像

ミドリ: 全体のアーキテクチャを教えてください。

タツヤ: AI推論基盤のレイヤーは4つに分かれる。

レイヤー1:インフラ層

タツヤ: GPUノードプール + CPUノードプール。GPUはNVIDIA A100やL4が主流。クラウドならGKE(Google)、EKS(AWS)、AKS(Azure)のいずれかを使う。

レイヤー2:オーケストレーション層

タツヤ: Kubernetesそのもの。ノード管理、Pod配置、ネットワーキング、ストレージマウントを担当。NVIDIA GPU Operatorでドライバ管理を自動化する。

レイヤー3:モデルサービング層

タツヤ: ここが今日のメインテーマ。KServeかTriton Inference Serverを使う。後で詳しく比較するよ。

レイヤー4:ゲートウェイ・監視層

タツヤ: Istio/Envoyでトラフィック制御、Prometheus + Grafanaでメトリクス監視。リクエスト数、レイテンシ、GPU使用率をリアルタイムで追跡する。

ミドリ: 4層構造、きれいに分かれてますね。

GPUスケジューリングの実践

ミドリ: GPUの割り当てってどうやるんですか?CPUみたいに「0.5コア」とかできるんですか?

タツヤ(nodding): いい質問。GPUスケジューリングには3つのアプローチがある。

アプローチ1:GPU丸ごと割り当て

タツヤ: 一番シンプル。1 Pod = 1 GPUまたは複数GPU。大規模モデル(7B以上のLLMなど)に適してる。ただしGPUの使用率が低いとコスト効率が悪い。

アプローチ2:GPU共有(MIG / Time-Slicing)

タツヤ: NVIDIA A100以降で使えるMIG(Multi-Instance GPU)で、1つのGPUを最大7つのインスタンスに分割できる。小型モデルを複数同居させるのに向いてる。Time-Slicingなら既存のGPUでも時分割で共有可能。

アプローチ3:GPU仮想化(MPS)

タツヤ: NVIDIA MPSを使うと、複数プロセスがGPUを同時に使える。バッチ推論とリアルタイム推論を混在させたいときに有効。

ミドリ(thinking): コスト的にはどう違うんですか?

タツヤ: 実測データを見てみよう。NVIDIA A100(月額約40万円/台)を基準にした場合。

方式GPU利用率月額コスト効率適用シーン
丸ごと割り当て30〜50%1.0(基準)大規模LLM、高スループット要求
MIG分割(3分割)70〜85%0.4〜0.5中小モデル複数同居
Time-Slicing60〜75%0.5〜0.6レイテンシ許容度が高いバッチ処理
MPS65〜80%0.45〜0.55混在ワークロード

ミドリ: MIG分割だとコスト半分以下になるんですね!

タツヤ(thinking): ただしMIGは分割数分だけメモリも分かれるから、モデルサイズに注意。3分割するとインスタンスあたり約26GBになる(A100 80GBの場合)。

KServe vs Triton ── モデルサービング比較

ミドリ: モデルサービングのKServeとTriton、どっちを選べばいいですか?

タツヤ: 用途で使い分ける。比較表を見てみよう。

項目KServeTriton Inference Server
提供元CNCF / KubeflowNVIDIA
主な強みK8sネイティブ、宣言的管理高性能、マルチフレームワーク
対応フレームワークTensorFlow, PyTorch, ONNX, etc.TensorFlow, PyTorch, ONNX, TensorRT, etc.
オートスケーリングKNative連携でゼロスケール対応HPAベース(ゼロスケール非対応)
バッチ処理基本対応動的バッチング(高性能)
モデル管理InferenceServiceで宣言的Model Repositoryパターン
カナリアリリースネイティブサポートIstio等と組み合わせが必要
学習コスト中(K8s知識前提)低〜中

ミドリ(thinking): ゼロスケールって何ですか?

タツヤ: リクエストがゼロのとき、Podを0台にスケールダウンすること。夜間にリクエストがないなら、GPUノードごと落としてコストをゼロにできる。KServe + KNativeならこれが標準機能で使える。

ミドリ: それ、うちのユースケースにドンピシャじゃないですか。昼間は殺到、夜はゼロなんで。

タツヤ: そう。ただしゼロからの起動(コールドスタート)に30秒〜数分かかるから、最低1台は維持する「最小レプリカ1」設定にするか、ウォームアップリクエストを送る仕組みを入れるかの判断が要る。

オートスケーリング戦略

ミドリ(thinking): スケーリングの設定って、具体的にどうやるんですか?

タツヤ: 3つのスケーリング機構を組み合わせる。

HPA(Horizontal Pod Autoscaler)

タツヤ: 最も基本的。CPU/メモリ使用率、またはカスタムメトリクス(リクエスト数、GPU使用率)をトリガーにPod数を増減させる。

トリガー例:GPU使用率 > 70% → Pod追加
冷却期間:5分(短すぎるとフラッピングする)
最小レプリカ:2、最大レプリカ:20

KEDA(Kubernetes Event-Driven Autoscaler)

タツヤ: キューの長さやHTTPリクエスト数など、外部イベントをトリガーにスケーリングできる。推論リクエストキューが溜まってきたらスケールアウト、みたいな設定が簡単に書ける。ゼロスケールにも対応。

ミドリ: 2つあると、どれを使えばいいか迷います。

タツヤ: 推論ワークロードのおすすめ構成はこうだ。

機構用途推奨設定
HPAリアルタイム推論のPodスケーリングGPU使用率70%でスケールアウト
KEDAバッチ推論のキュー駆動スケーリングキュー長 > 100でPod追加
Cluster AutoscalerGPUノード自体の増減ノードのPending Podが出たら追加

ミドリ: HPAでPodを増やして、Podが乗るノードが足りなければCluster Autoscalerがノードを追加する、って2段構えですね。

タツヤ: 正解。この2段構成が本番環境の定石だよ。

コスト最適化の実践

ミドリ: 結局、固定GPUサーバーと比べてどれくらいコスト下がるんですか?

タツヤ: 典型的なケースで試算してみよう。画像認識モデル(ResNet-50相当)、ピーク時1,000 req/s、平均200 req/s、夜間10 req/sという条件。

構成月額コスト備考
固定GPU 8台(ピーク対応)320万円常時稼働、夜間もフル課金
K8s + HPA(2〜8台可変)160万円平均4.5台稼働
K8s + KEDA + ゼロスケール130万円夜間ゼロスケール、Spot活用
K8s + MIG分割 + ゼロスケール95万円GPU共有でさらに効率化

ミドリ: 320万が95万に!? 70%削減ですか!

タツヤ: 最大でね。現実的には40〜60%削減がボリュームゾーン。ワークロードパターンによって変わるから、まず自社のトラフィックデータを2週間分取るところから始めるのが大事。

Spotインスタンスの活用

タツヤ: さらにコストを下げるなら、Spot(Preemptible)インスタンスの活用。通常価格の60〜70%引きで使えるけど、突然中断される可能性がある。

ミドリ: 推論中に落ちたらまずくないですか?

タツヤ: だからベースラインはオンデマンド、バースト分だけSpotにする。ベース2台はオンデマンドで確保、3台目以降はSpotで追加。中断されてもHPAが別のノードにPodを再配置してくれるから、一時的なレイテンシ増加で済む。

Prometheus + Grafanaによる監視

ミドリ: 運用が始まったら何を監視すればいいですか?

タツヤ: AI推論基盤で必ず見るべき5つのメトリクス。

メトリクス閾値目安アラート条件
推論レイテンシ(P95)< 200ms5分間平均で500ms超
GPU使用率50〜80%90%超が10分継続
GPUメモリ使用率< 85%90%超
リクエストエラー率< 0.1%1%超
キュー滞留時間< 5s30s超

ミドリ: GPU使用率が50〜80%って、100%使い切らない方がいいんですか?

タツヤ(nodding): その通り。100%に張り付くとスパイク時に処理が溢れるから、余裕を持たせてスケールアウトのトリガーにするのが正解。逆に30%以下が続くならスケールインかMIG分割を検討する。

導入ロードマップ

ミドリ: これ全部いきなりやるのは無理ですよね。どう段階的に進めればいいですか?

タツヤ: 4フェーズで3ヶ月。

フェーズ1:基盤構築(2週間)

タツヤ: K8sクラスタ構築、GPU Operator導入、シンプルなDeployment + Serviceでモデルを1台デプロイ。まずは動く状態を作る。

フェーズ2:サービング導入(2週間)

タツヤ: KServeまたはTritonを導入。モデルのバージョン管理、ヘルスチェック、ローリングアップデートを設定。ここでカナリアリリースの仕組みも入れておく。

フェーズ3:オートスケーリング(2週間)

タツヤ: HPA + Cluster Autoscalerを設定。負荷テストを実施して、スケーリングの閾値をチューニング。ゼロスケールが必要ならKEDAも追加。

フェーズ4:最適化・運用(継続)

タツヤ: Prometheus + Grafanaのダッシュボード構築。コスト分析。MIG分割やSpotインスタンスの導入検討。月次でコストとパフォーマンスのレビューを実施。

ミドリ: 2週間ずつ、計6週間で本番に乗せられるんですね。

タツヤ: 最低限の構成ならね。最適化は運用しながら継続的にやっていく。

まとめ:KubernetesでAI推論コストを劇的に下げる

ミドリ: 今日のポイントをまとめると?

タツヤ: Kubernetesを使ったAI推論基盤のポイントは3つ。第一に、HPA + Cluster Autoscalerの2段構成でリクエスト量に応じた自動スケーリングを実現する第二に、KServeのゼロスケールやMIG分割でGPUの無駄遣いを徹底的に排除する第三に、Prometheus + Grafanaで5つの必須メトリクスを常時監視する。これで固定GPU比40〜60%のコスト削減と、安定したレイテンシの両立ができる。

ミドリ: 「コストも抑えろ、レスポンスも速くしろ」の答えがここにあった、と。

タツヤ(nodding): その通り。Kubernetesは学習コストが高いけど、AI推論基盤としてはデファクトスタンダードになりつつある。早めに知見を貯めておくと、今後のAI展開で圧倒的に有利になるよ。


次のアクション

自社のAI推論ワークロードを振り返ってみましょう。