0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FastAPIでMLflowのモデルを提供する方法

Posted at

はじめに

本記事では、 FastAPI を用いて MLflow で管理している機械学習モデルを利用できるAPIを構築する方法を紹介します。

  • MLflow: 機械学習モデルの管理・トラッキングを行う
  • FastAPI: 軽量なPythonのWebフレームワーク
  • Docker Compose: コンテナベースで環境を構築

※FastAPI以外の箇所は前回書いた以下記事をご参照ください。
https://qiita.com/ebasuke0226/items/4b05c5a1b851a9349fc7

環境構築

1. Docker Composeの設定

docker-compose.ymlFastAPI を追加しました。

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フォームを通じて簡単にモデルにデータを送信・推論

この記事が参考になったら、ぜひ いいね や フォロー をお願いします!

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?