はじめに
本記事では、 FastAPI を用いて MLflow で管理している機械学習モデルを利用できるAPIを構築する方法を紹介します。
- MLflow: 機械学習モデルの管理・トラッキングを行う
- FastAPI: 軽量なPythonのWebフレームワーク
- Docker Compose: コンテナベースで環境を構築
※FastAPI以外の箇所は前回書いた以下記事をご参照ください。
https://qiita.com/ebasuke0226/items/4b05c5a1b851a9349fc7
環境構築
1. Docker Composeの設定
docker-compose.yml
で FastAPI を追加しました。
version: '3.8'
services:
fastapi:
build: ./fastapi
ports:
- "8000:8000"
depends_on:
- mlflow
command: ["tail", "-f", "/dev/null"]
environment:
MLFLOW_TRACKING_URI: http://mlflow:5000
networks:
- mlops_network
実装のポイント
-
fastapi
サービスを新規追加し、MLflowを利用できる環境を構築した。 -
MLFLOW_TRACKING_URI
を fastapi に設定し、モデル管理を容易にした。 - FastAPIのコンテナは、バックグラウンドで動作させるために
command: ["tail", "-f", "/dev/null"]
を設定した。
2. FastAPIの実装
ディレクトリ構成
/mlops_project
│
├── docker-compose.yml # 各コンテナを統合するDocker Composeファイル
│
├── /fastapi
│ ├── Dockerfile # fastapi用のDockerfile
│ ├── requirements_fastapi.txt # fastapi用の依存ライブラリ
│ ├── /app
│ ├── main.py
│ ├── predict.py
│ ├── /templates
│ ├── index.html # フォーム画面
main.py
(FastAPIの実装)
from fastapi import FastAPI, Request, Form
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
import mlflow.pyfunc
import pandas as pd
from typing import Optional
app = FastAPI()
templates = Jinja2Templates(directory="templates")
# モデルをロードする関数
def load_model(model_name: str, model_version: Optional[str] = None):
if model_version:
model_uri = f"models:/{model_name}/{model_version}"
else:
model_uri = f"models:/{model_name}/Production"
return mlflow.pyfunc.load_model(model_uri)
# ホーム画面(フォーム)
@app.get("/", response_class=HTMLResponse)
async def read_form(request: Request):
return templates.TemplateResponse("index.html", {"request": request})
# フォームから予測
@app.post("/predict", response_class=HTMLResponse)
async def predict(
request: Request,
MedInc: float = Form(...),
HouseAge: float = Form(...),
AveRooms: float = Form(...),
AveBedrms: float = Form(...),
Population: float = Form(...),
AveOccup: float = Form(...),
Latitude: float = Form(...),
Longitude: float = Form(...),
model_name: str = Form("YourModelName"),
model_version: Optional[str] = Form(None)
):
input_data = pd.DataFrame([{
"MedInc": MedInc,
"HouseAge": HouseAge,
"AveRooms": AveRooms,
"AveBedrms": AveBedrms,
"Population": Population,
"AveOccup": AveOccup,
"Latitude": Latitude,
"Longitude": Longitude
}])
try:
model = load_model(model_name, model_version)
prediction = model.predict(input_data).tolist()[0]
except Exception as e:
return templates.TemplateResponse("index.html", {"request": request, "error": f"予測エラー: {e}"})
return templates.TemplateResponse("index.html", {"request": request, "result": prediction})
ポイント
- Jinja2 を利用してフォームを提供(HTMLレンダリング)
- POST /predict エンドポイントでフォーム入力データを受け取り、MLflowで管理されているモデルを用いた推論を実施
predict.py
import mlflow.pyfunc
import pandas as pd
# Productionステージのモデルを取得
model_name = "CaliforniaHousingModel"
model_uri = f"models:/{model_name}/Production"
# モデルをロード
model = mlflow.pyfunc.load_model(model_uri)
# APIやシステムで予測処理を実行
data = pd.DataFrame([{
"MedInc": 8.32,
"HouseAge": 50.0,
"AveRooms": 6.984,
"AveBedrms": 1.023,
"Population": 322.0,
"AveOccup": 2.555,
"Latitude": 37.88,
"Longitude": -122.23
}])
prediction = model.predict(data)
print(prediction)
ポイント
MLflowのモデルを利用して、サンプルデータの予測を行うスクリプト
index.html
(テンプレート )
<!DOCTYPE html>
<html>
<head>
<title>予測フォーム</title>
</head>
<body>
<h1>住宅価格予測フォーム</h1>
{% if error %}
<p style="color: red;">{{ error }}</p>
{% endif %}
{% if result %}
<p style="color: green;">予測結果: {{ result }}</p>
{% endif %}
<form method="post" action="/predict">
<label for="MedInc">MedInc:</label>
<input type="number" step="any" name="MedInc" required><br>
<label for="HouseAge">HouseAge:</label>
<input type="number" step="any" name="HouseAge" required><br>
<input type="submit" value="予測する">
</form>
</body>
</html>
3. FastAPIを起動
以下のコマンドでFastAPIを起動します。
docker-compose up -d --build
ブラウザで http://localhost:8000/ にアクセスするとフォームが表示されます。
技術的なポイント
本記事では FastAPI を追加し、 MLflow で管理している機械学習モデルを用いた予測APIを提供する構成を構築しています。
4. 注意点
- MLflowのモデルのバージョン管理
- モデルは Production ステージ にあるものを取得
- model_version をオプションで指定可能にし、特定のバージョンを利用することも可能
- エラーハンドリング
- モデルロード失敗時のエラーハンドリング
- 予測失敗時のエラーハンドリング(例: 入力データのフォーマット不正)
まとめ
- FastAPI でMLflowのモデルを利用した推論APIを構築
- Docker Composeで統合し、FastAPIをコンテナとしてデプロイ
- HTMLフォームを通じて簡単にモデルにデータを送信・推論
この記事が参考になったら、ぜひ いいね や フォロー をお願いします!