はじめに
機械学習で作成したモデルを実用化するには、システムが必要になる。もっともシンプルなシステム実装としては、学習済みモデルが API リクエストに対して推論結果をレスポンスで返す簡単な Web API が考えられる。具体的には、推論対象の CSV データをもたせた POST リクエストに対して推論結果を返すような Web API を想定している。機械学習モデルは大半が Python で構築されているため、API も Python ベースで作成することが望ましいと考え、FastAPI を用いた Web API を段階を踏んで作成していく。
シンプルな Web API を FastAPI で作成ではまず FastAPI を使った簡単な Web API を作成した。続いて FastAPI で作成した Web API にて、リクエストボディのデータを DataFrame に直接入れるで、リクエストボディのデータを DataFrame に直接入力できるようなものに改良した。本記事では、当初の目的である機械学習モデルの推論結果を返す Web API を作成する。FastAPI 公式ドキュメント、機械学習システムデザインパターンを参考にした。
実行環境は以下。
- Python 3.7.12
- fastapi 0.70.0
必要なパッケージのインストール
学習環境で使用していたパッケージ類および fastapi, uvicorn など必要なパッケージをインストールする。学習環境で使用していたパッケージを pip freeze > requirements.txt
で出力しておく。(余分なパッケージも含まれるが、ここではとりあえずの稼働なので目をつむる。)
$ pip install --no-cache-dir -r requirements.txt
$ pip install fastapi uvicorn
$ pip install python-multipart # リクエストボディのファイル受け取りに必要なパッケージ
--no-cache-dir
はキャッシュを無効に、-r
は指定した requirements.txt からインストールする。
ディレクトリ構成
ディレクトリ構成は以下。
.
├── __init__.py
├── models
│ ├── __init__.py
│ └── model.pickle # ロードするモデル
├── requirements.txt # 必要なパッケージリスト
└── src
├── __init__.py
├── app
│ ├── __init__.py
│ ├── app.py # API 実行
│ └── routers.py # ルーティング設定
└── ml
├── __init__.py
└── predict.py # データ読み込み・前処理・推論など詳細な処理
コード例
以下はコード例のイメージ。(実行未確認)
from fastapi import FastAPI
from src.app.routers import router
app = FastAPI()
app.include_router(router, prefix="", tags=[""])
from fastapi import APIRouter, File, UploadFile
from src.ml.predict import Model
@router.get("/health")
def health():
"""
Web API の実行確認
"""
return {"health": "ok"}
@router.post("/predict")
async def predict(file: UploadFile = File(...)):
"""
POST で与えられたストリームデータに対して推論
"""
model = Model(
data_filepath=file.file
)
model.predict()
return {"result": model.result}
from io import StringIO
import pandas as pd
import pickle
class Model(object):
"""
ファイルを読み込んで推論
"""
def __init__(self, data_filepath):
_data = str(data_filepath.read(), 'utf-8') # ストリームデータを str に変換
self.data = pd.read_csv(StringIO(_data))
self.model = self.load_model()
self.result = None
def load_model(self):
with open('./models/model.pickle', 'rb') as f:
_model = pickle.load(f)
return _model
def predict(self):
...
uvicorn src.app.app:app --reload
にて実行・動作確認ができる。
おわりに
機械学習モデルの推論結果を返す Web API を FastAPI で作成した。ベースはこのような形でより高度なことができるように追加していきたい。