機械学習モデルのAPI化: FastAPI vs KServeの選択基準

# 機械学習モデルのAPI化: FastAPI vs KServeの選択基準

## **1. はじめに**

機械学習モデルを本番環境で運用する際、多くの場合「**API化**」が求められます。APIを通じて外部システムやアプリケーションと連携し、リアルタイム推論やバッチ推論を行うことが可能になります。

API化の方法として代表的なフレームワークに **FastAPI** と **KServe（旧 KFServing）** がありますが、「どちらを選べばいいのか？」という疑問を持つ方も多いでしょう。

本記事では、
- **FastAPI と KServe の違い**
- **どんなケースでどちらを使うべきか？**
- **実際の実装方法と注意点**
を詳しく解説します。

---

## **2. FastAPIとKServeの基本概念**

|  **項目**    | **FastAPI** | **KServe** |
|-------------|------------|------------|
| **用途**   | 軽量なAPIの開発 | Kubernetes上でのML推論サービスの提供 |
| **スケール** | 単一ノードまたは小規模クラスタ向け | 大規模クラスタ向け（自動スケール） |
| **デプロイ** | 手動でコンテナデプロイ | Kubernetes Operator により自動デプロイ |
| **推論方式** | 同期処理（REST API） | 非同期処理も可能（gRPC, REST） |
| **サポートするモデル** | 任意のフレームワーク（ONNX, TensorFlow, PyTorch, scikit-learnなど） | TensorFlow, PyTorch, ONNX, XGBoost, Scikit-Learnなど |
| **可観測性** | ログ管理が手動 | Prometheus, Grafana との統合が容易 |
| **スケールアウト** | 手動（ロードバランサー必須） | Kubernetesのオートスケール |
| **適用対象** | 小規模・軽量なAPI | 大規模な本番運用・分散環境 |

---

## **3. どんな場合にどちらを使うべきか？**

### **✅ FastAPIを使うべきケース**
FastAPI は軽量なPythonのWebフレームワークであり、以下のようなケースで適しています。

1. **開発が素早くできる小規模な推論APIを作成する場合**
   - 例：機械学習モデルをAPI化し、フロントエンドやモバイルアプリからリクエストを受け付ける
2. **Kubernetesが不要な場合**
   - 例：シンプルな推論サーバーを1台のVMやDockerコンテナ上で運用
3. **軽量な推論エンドポイントを提供する場合**
   - 例：scikit-learn, XGBoostなどの小規模なモデルの推論
4. **非同期処理を活用したい場合**
   - FastAPIは非同期処理（async/await）をサポートし、多数のリクエストを効率的に処理できる
5. **gRPCのような複雑な通信プロトコルが不要な場合**
   - REST APIをメインに使うならFastAPIで十分

### **✅ KServeを使うべきケース**
KServe（旧 KFServing）は、Kubernetes上でMLモデルのスケーラブルな推論を提供するためのツールです。以下のケースで適しています。

1. **クラウド環境（AWS, GCP, Azure）でスケーラブルなML推論APIを運用したい場合**
2. **Kubernetesを使用してMLパイプラインを管理している場合**
3. **大量のリクエストを自動でスケールアウトしたい場合**
   - KServeは **オートスケール** をサポートし、リクエスト量に応じてPodの数を自動調整可能
4. **複数のモデルを同時に管理したい場合**
   - 例：バージョニング（A/Bテスト）、複数のMLフレームワークのモデルを一元管理
5. **高可用性・高耐障害性が求められる場合**
   - FastAPIは **単一ノードが落ちると影響を受ける** が、KServeはKubernetesの仕組みを活用し耐障害性が高い

---

## **4. 実装方法（FastAPI vs KServe）**

### **🛠 FastAPIによるML推論APIの実装**
```python
from fastapi import FastAPI
import pickle
import numpy as np

# モデルのロード
with open("model.pkl", "rb") as f:
    model = pickle.load(f)

app = FastAPI()

@app.post("/predict")
def predict(features: list):
    features = np.array(features).reshape(1, -1)
    prediction = model.predict(features)
    return {"prediction": prediction.tolist()}

# 実行
# uvicorn main:app --host 0.0.0.0 --port 8000
```
- FastAPIを利用することで、**手軽にML推論APIを作成** できる
- しかし、スケーラブルな運用には **ロードバランサー（NGINX, Kubernetesなど）が必要**

---

### **🛠 KServeによるML推論APIの実装**

```yaml
apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
  name: my-ml-model
spec:
  predictor:
    tensorflow:
      storageUri: "gs://my-bucket/my-model"
```

- **Kubernetes上でKServeを使い、モデルをデプロイ**
- `kubectl apply -f model.yaml` でデプロイ完了
- 自動スケールが可能で、リクエスト量に応じてPod数が増減

---

## **5. 結論: FastAPIとKServeの共存は可能か？**
FastAPIとKServeは基本的に **異なる用途** のツールですが、「共存は可能」です。

### **🔥 FastAPI + KServe の組み合わせ**
実際のシステムでは、以下のように **FastAPIをフロントエンドとして、KServeをバックエンド推論エンジンとして使う** こともできます。

1. **FastAPIでリクエストを受け取る**
2. **KServeにリクエストを転送し、スケーラブルな推論を行う**
3. **結果をFastAPI経由で返す**

```python
import requests
from fastapi import FastAPI

app = FastAPI()
KSERVER_URL = "http://my-ml-model.default.svc.cluster.local/v1/models/my-ml-model:predict"

@app.post("/predict")
def predict(data: dict):
    response = requests.post(KSERVER_URL, json=data)
    return response.json()
```

---

## **6. まとめ**
| **選択基準** | **FastAPI** | **KServe** |
|-------------|------------|------------|
| 小規模API | ✅ | ❌ |
| 大規模運用 | ❌ | ✅ |
| Kubernetes環境 | ❌ | ✅ |
| 簡単な実装 | ✅ | ❌ |
| 自動スケール | ❌ | ✅ |

👉 **「ローカル or 小規模なら FastAPI」**、**「大規模クラウド運用なら KServe」** を選択するのがベスト！