【実践】FinOps × AI基盤 — KubernetesのGPUコストを40%削減する最適化戦略

AI × Infrastructure

この記事の概要

  • GPUコストの無駄の大半は「アイドル状態のノード」と「低い利用率」が原因。Karpenter + vLLM の組み合わせで構造的に解消できる
  • Kubecost 3.0 と CAST AI を使えば namespace 単位のコスト可視化と自動最適化が実現し、導入事例では 40% 削減 を達成
  • スポットインスタンス・MIG・Reserved Instance を組み合わせた「レイヤード戦略」が現実的な最適解

背景・概要

企業の AI 投資が急拡大する一方で、GPU 単価の高騰がじわじわと経営課題になってきています。

FinOps Foundation の 2025 年調査によると、組織はクラウドスペンドの 25〜35% を無駄にしている とのこと。
CPU ワークロードでも頭が痛い話ですが、GPU はさらに単価が桁違い。
p4d.24xlarge のオンデマンド価格は 1 時間あたり約 32 ドル。
24 時間回し続ければ 1 日で 768 ドルが飛んでいきます。

「とりあえず GPU ノードを立てて LLM を動かす」フェーズはとっくに終わりました。
今は 「どう削るか」 を真剣に考えないと、AI 基盤の維持費がビジネスの足を引っ張ります。

この記事では、Kubernetes 上の GPU ワークロードに対して実際に使えるコスト最適化戦略を、ツールと設定例つきで解説します。


詳細解説

コスト最適化の全体像

まず、どのレイヤーで何を削るかを整理しましょう。

flowchart TD
    A[GPUコスト削減戦略] --> B[調達コスト削減]
    A --> C[利用率の向上]
    A --> D[可視化・ガバナンス]

    B --> B1[スポットインスタンス活用\n最大70%削減]
    B --> B2[Reserved Instance /\nSavings Plans 混在]

    C --> C1[Karpenter consolidation\nアイドルノード自動削除]
    C --> C2[vLLM continuous batching\nGPU利用率80%→95%]
    C --> C3[GPU Time-slicing / MIG\n小ワークロードの詰め込み]

    D --> D1[Kubecost 3.0\nnamespace別コスト配分]
    D --> D2[CAST AI\nML自動最適化]

大きく「調達」「利用率」「可視化」の3レイヤーに分けて考えるのが整理しやすいです。
それぞれ独立して取り組めるので、まず効果が出やすいところから着手するのが現実的です。


レイヤー1: 調達コストを削る — スポット + RI 混在戦略

GPU スポットインスタンスは、オンデマンドと比べて 最大 70% 安く なります。
p3.16xlarge のスポット価格は時期によっては 4〜5 ドル台まで落ちることもあります。

ただし、スポットは中断リスクがあるので「全部スポットにすればいい」とはなりません。
実務では以下の混在戦略が安定します。

ワークロード種別 推奨調達方法 理由
バッチ推論・学習ジョブ スポット 100% 中断時に再試行できる設計にすれば問題なし
リアルタイム推論(SLA あり) オンデマンド or RI 中断を許容できない
ベースライン常時稼働 1年 Reserved / Savings Plans 予測可能な分は RI で固定費化

Reserved Instance は1〜3年コミットで 30〜40% 割引になります。「常に動いている最小台数」だけ RI で押さえ、ピーク分はスポットで補うハイブリッド構成が ROI 最大化の定石です。


レイヤー2: アイドルを殺す — Karpenter consolidation

GPU ノードはリクエストがなくてもノードが立ち上がっている間はコストが発生します。
Karpenter の consolidation 機能を使えば、アイドル状態のノードを自動でスケールダウンできます。

# Karpenter NodePool — GPU + consolidation 設定例
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-nodepool
spec:
  template:
    metadata:
      labels:
        workload-type: gpu
    spec:
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["spot", "on-demand"]
        - key: node.kubernetes.io/instance-type
          operator: In
          values:
            - p3.2xlarge
            - p3.8xlarge
            - p3.16xlarge
            - p4d.24xlarge
        - key: kubernetes.io/arch
          operator: In
          values: ["amd64"]
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: gpu-nodeclass
  disruption:
    consolidationPolicy: WhenUnderutilized   # 低利用時に統合
    consolidateAfter: 5m                      # 5分アイドルで削除候補に
  limits:
    nvidia.com/gpu: "32"                      # クラスター全体の GPU 上限

consolidateAfter: 5m は少し短く感じるかもしれませんが、GPU ノードの起動時間(2〜3分)を考慮しても、LLM 推論のように「バーストしてすぐ落ち着く」ワークロードには効果的です。
社内の実績では、この設定だけで アイドルコストを 20〜30% 削減 できました。


レイヤー3: GPU 利用率を上げる — vLLM + Time-slicing / MIG

GPU ノードが起動している時間のコスパを最大化するのが第3レイヤーです。

vLLM の continuous batching は、複数リクエストを動的にバッチ処理することで GPU の空き時間を埋めます。
シングルリクエスト処理と比べると GPU 利用率が 80% → 95% 程度まで改善し、実効スループットが大幅に上がります。
スループットが上がれば、同じ推論量をより少ないノード数でこなせるので、コスト削減に直結します。

小規模なモデルや開発環境には GPU Time-slicing も有効です。
1枚の物理 GPU を複数の Pod で共有できます。
本番の LLM 推論には向きませんが、開発用の fine-tuning や評価ジョブなら十分使えます。

一方、A100 / H100 系では MIG (Multi-Instance GPU) を使うと、物理 GPU をハードウェアレベルで分割して隔離性を確保しつつ共有できます。
7g.80gb インスタンスを 1g.10gb × 7 に分割するといった使い方です。
本番でも隔離性が必要な場合は MIG が正解です。


レイヤー4: 可視化とガバナンス — Kubecost + CAST AI

コストを削るには「どこで何に使っているか」が見えていることが前提です。

Kubecost 3.0 は NVIDIA DCGM と統合されており、GPU の利用率・コストを namespace・チーム・Pod 単位で可視化できます。
以下のコマンドで namespace 別のコスト状況をざっくり確認できます。

# Kubecost CLI で namespace 別 GPU コストを確認
kubectl cost namespace \
  --window 7d \
  --show-gpu-cost \
  --historical \
  -n kubecost

# 出力例(一部省略)
# NAMESPACE         GPU COST (7d)   CPU COST   MEMORY COST   TOTAL
# llm-inference     $1,240.00       $85.20      $12.40       $1,337.60
# ml-training       $890.00         $42.10      $8.20         $940.30
# monitoring        $0.00           $15.00      $6.80         $21.80

CAST AI は ML ベースでより自動化が進んでおり、Pod のリソースリクエストの rightsizing(P95/P90 ベース)とスポット/オンデマンドの自動切り替えを組み合わせて実施してくれます。
人手の介入なしで継続的に最適化されるので、運用コストも下がります。
Kubecost + CAST AI を組み合わせた導入事例では、合計で 40% 削減 を達成した報告が複数あります。


実務での活用方法

実際のプロジェクトでどう進めるか、ステップを整理します。

Step 1 — まず現状を可視化する(Week 1〜2)
Kubecost を入れて namespace 別・チーム別のコスト配分を可視化します。
「どこが高いか」が見えないと何も始まりません。
GPU 利用率が 30% 以下のノードがあれば、それが最初の改善ターゲットです。

Step 2 — Karpenter consolidation を有効化する(Week 2〜3)
既存の NodePool / NodeClass に consolidateAfter を追加するだけで始められます。
まずはステージング環境で試して、スケールイン時の挙動を確認してから本番適用しましょう。

Step 3 — 調達コストを最適化する(Month 1〜2)
バッチ系ワークロードをスポットインスタンスに移行します。
Karpenter の capacity-type: spot 指定で簡単に切り替えられます。
並行して、ベースライン分の Reserved Instance / Savings Plans 購入を検討します。

Step 4 — 継続的な rightsizing(Month 2 以降)
CAST AI の自動 rightsizing を有効化し、リソースリクエストの過剰設定を継続的に是正します。
P95 ベースで設定すれば「リソース不足でジョブが落ちる」リスクを抑えながら無駄を削れます。


まとめ

GPU コストの最適化は「一発で解決する魔法」はなく、複数レイヤーの積み重ねです。

  • 調達: スポット + RI の混在で最大 70% の調達コスト削減
  • 稼働: Karpenter consolidation でアイドル時間を 20〜30% 削減
  • 利用率: vLLM / MIG で GPU を使い切る
  • ガバナンス: Kubecost + CAST AI で継続的に監視・最適化

これらを組み合わせれば、40% 削減は現実的なターゲットです。AI 基盤のコストが肥大化してきたと感じたら、まず Kubecost で現状を可視化するところから始めてみてください。
見えてくると、意外と「こんなところで無駄使いしてたのか」と気づくことが多いです。


参考リンク

コメント