SlideShare a Scribd company logo
1 of 58
Download to read offline
Pythonで作る
機械学習システム
2020/08/29
shibui yusuke
自己紹介
shibui yusuke
● 機械学習エンジニア &
インフラエンジニア &
ARエンジニア
● もともとクラウド基盤の開発、運用。
● ここ4年くらいMLOpsで仕事。
● Github: @shibuiwilliam
● Qiita: @cvusk
● FB: yusuke.shibui
● 最近やってること: Edge AIとAR
cat : 0.55
dog: 0.45
human : 0.70
gorilla : 0.30
物体検知
本日の内容
● 機械学習のシステムを作るためのアーキテクチャや実装例を説明します。
● 主に私がMLOpsやシステム開発、運用で成功、失敗してきたことをもとに話します。
● ターゲットオーディエンス:
○ これから機械学習のシステム開発、運用を始めるソフトウェアエンジニア
○ 機械学習モデルを本番システムに組み込みたい機械学習エンジニア
MLシステムデザインパターン
● 以前から考えていた機械学習システムの作り方をパターン化して公開しました。
「デザインパターン」と呼ぶには偉大な先人に畏れ多い。。。
● https://github.com/mercari/ml-system-design-pattern
● 上記はアーキテクチャ集になっていますが、実際に独自に作ってみたものが以下になります。
● https://github.com/shibuiwilliam/ml-system-in-action
● 本セッションでは上記デザインパターンと実装例をもとに、主にPythonで機械学習システムを
作る方法を共有します。
Agenda
1. 機械学習のシステム
2. 機械学習システムをパターン化する
3. 実際に作ってみる
4. まとめ
機械学習のシステム
機械学習のシステム
● ユーザから見たAI
● MLエンジニアから見たML
● ソフトウェアエンジニアから見たMLシステム
猫!
犬!
猫!
https://papers.nips.cc/paper/5656-hidden-technical-debt-in-machine-learning-systems.pdf
Accuracy
99.99%
ユーザに使ってもらえる機械学習へ
https://pycon.market.com/ .
.
.
Python 機械学習 cart
acco
unt
help
商品A 商品B 商品D商品C
商品
カテゴリ
1
商品
カテゴリ
2
商品
カテゴリ
4
商品
カテゴリ
3
ブラウザ標準
パーソナライズ
レコメンデーション
固定化された
デザイン
検索欄の入力補完
自然言語処理
キャンペーン
あるECサイト
ユーザに使ってもらえる機械学習へ
固定化された
デザイン
画像処理
写真を撮る
タイトル入力
説明入力
登録する
自然言語処理
違反検知
あるコンテンツ登録アプリ
機械学習のシステムに必要なもの
推論器
ユーザ
インターフェイ
ス
前処理
推論
後処理
機械学習のシステムに必要なもの
推論器
ユーザ
インターフェイ
ス
ログ
学習評価
モデル
管理
コード
管理
運用監視
イメージ
管理
スト
レージ
CI
前処理
推論
後処理
BI
→
機械学習で
DevOpsを
回すために必要
↓最低限必要
機械学習システムをパターン化する
画像処理
写真を撮る
タイトル入力
説明入力
登録する
自然言語処理
違反検知
機械学習を組み込む
登録情報から違反を
フィルタリング
入力情報から
入力補助
超解像による
画質改善
ねこ
検索Index
ランク学習による
並べ替え
画像分類と
検索改善
画像分類
による
入力補助
あるコンテンツ登録アプリ
画像処理
写真を撮る
タイトル入力
説明入力
登録する
自然言語処理
違反検知
学習のタイミング
登録情報から違反を
フィルタリング
入力情報から
入力補助
超解像による
画質改善
ねこ
検索Index
ランク学習による
並べ替え
画像分類と
検索改善
画像分類
による
入力補助
不定期
データ
定期更新 定期的
あるコンテンツ登録アプリ
画像処理
写真を撮る
タイトル入力
説明入力
登録する
自然言語処理
違反検知
推論のフロー
登録情報から違反を
フィルタリング
入力情報から
入力補助
超解像による
画質改善
ねこ
検索Index
ランク学習による
並べ替え
画像分類と
検索改善
画像分類
による
入力補助
非同期処理
同期推論
同期推論、
キャッシュ
リアルタイム
推論 非同期処理
あるコンテンツ登録アプリ
画像処理
写真を撮る
タイトル入力
説明入力
登録する
自然言語処理
違反検知
ログと評価
登録情報から違反を
フィルタリング
入力情報から
入力補助
超解像による
画質改善
ねこ
検索Index
ランク学習による
並べ替え
画像分類と
検索改善
画像分類
による
入力補助
イベント
ログ
ABテスト
Human in
the loop
あるコンテンツ登録アプリ
Pythonで作る
機械学習システムパターン
モデルを作る
アンチパターン:Only meパターン
● コード、データ、モデルが管理されず、開発者の
環境でしか再現できない。
(開発者の環境でも再現できないこともある)
● DVCやML Metadataでステップごとにアウトプットをコミット
することを推奨。
● 推論のインターフェイス(入力データの型と
shape、出力データの型とshape、意味)および
サンプルデータを定義しておく。
import
load local data
evaluate
retrain
define ml
train
save model
git
no training data
99.99% ???
学習パイプラインとバージョニング
データ取得
前処理
学習
評価
ビルド
● データパイプラインやMLパイプラインのワークフローは
DAG(有向非巡回グラフ)として定義。
● DWHやストレージから取得したデータを各フローで処
理し、結果をモデルレポジトリに記録。
● モデル生成後にビルド。ビルドのアウトプットは実行環
境含めてDockerイメージとしてビルドすることもあれ
ば、モデルのみをビルドし、実行環境はメタデータとし
て定義することもある。
● メタデータにはモデルの学習、評価に使った再現可能
なデータ、パラメータ、評価値を登録。
DWH
ストレージ
Hold out test
メタデータ
モデルレポジトリ
Image builder
Docker registry
Docker registry
パラメータ
チューニング
学習パイプラインとバージョニング
DVC
OSSのデータ・MLワークフロー管理。
Gitとともにローカルで実行する構成。
PythonSDKあり。
Google ML Metadata
KubeflowやTFXのML Metadata管理。
メインはクラウド+Kubernetes。ローカルもサポート。
PythonSDKあり。
MetadataStore
Polyaxon、MLflow、Metaflow、SageMakerも似通った構成を取っている。
バッチ学習
● 学習パイプラインを定期的に実行する構成。
● 学習データが時系列で変化し、定期的に
モデルを更新する用途で有効。
● 学習パイプラインをcronやジョブサーバから
トリガーする構成。
● 学習データは実行時に最新のものを使用する
一方、テストデータを更新するかは要検討。
Metadata
cron: 0 0 1 * *
DWH
Hold out test
Docker image
Runtime
Model
データ取得
前処理
学習
評価
ビルド
モデルをリリースする
学習環境と推論環境
Docker image
Runtime
Model
入力 前処理 推論 出力
データ取得
前処理
学習
評価
ビルド
Docker image
Library
学習環境のみ
- Jupyter Notebook
- バッチ学習用のライブラリ
 (例:PyTorch、TensorFlow、Keras)
- バッチ学習用のインフラ(GPUとか)
- データ・モデルバージョニングツール
- モデルビルダー
両環境に共通
- モデルファイル
- 前処理で使うライブラリ
 (例:Sklearn、PIL、Mecab)
- 入出力のデータ型と形
推論環境のみ
- 推論用のライブラリ
 (例:ONNX Runtime, TF Serving)
- ランタイムと外部インターフェイス
- ロガーとモニタリングツール
アンチパターン:Incompatible library and model
● 学習環境と推論器でライブラリのバージョンが違って
しまい、推論器を起動できない状態。
 例:.pklをロードできない状態。
または推論器を起動できるけど結果が間違っている状態。
 例:ライブラリのバージョンによって演算結果が
   違うことがある。
● 推論器の起動時jobとしてテストデータの推論を実行し、想定通
りの結果になることを確認する。
● 学習環境と推論環境のライブラリバージョンをあわせる
必要がある。
Docker image
Runtime
Model
ビルド
Base image
Image builder
推論器
推論器
Runtime
Image registry
推論
テスト
sklearn 0.21.0
sklearn 0.23.0
sklearn 0.21.0
モデルの配布と推論器の稼働
● 学習したモデルを推論器としてリリースし
稼働させるためにはモデルファイルだけで
なく実行環境(OS、ランタイム)が必要。
● モデルの配布方法は大きく2とおり。
a. モデル含めて推論器をビルド。
b. モデルと推論器を別にビルド。
● ビルド方式の違いは推論器を起動させる
方法の違いとなる。
Docker image
Runtime
Model
ビルド
Base image
Image builder
Model repository
推論器
推論器
Runtime
Image registry
モデルインイメージパターン
● 推論器のイメージにモデルを含めてビルド
するパターン。
● バージョン不一致によるトラブルを避ける
ことが可能。
● Dockerイメージサイズは大きくなるため、Docker
pullに時間を要する。
ベースイメージを共通化することで
pull時間を短縮することが可能。
● Kubernetesやクラウドでスケーラブルな
推論システムを作る場合、Docker pull時間が
オートスケールのボトルネックになる。
共通のベースイメージは全ノードにpullして
改善を図る。
ビルド
Image builder
Docker image
Runtime
Model
Base image
Runtime
Image registry
推論器
Model repository
モデルロードパターン
● モデルファイルと推論器イメージを別に
管理するパターン。
Dockerイメージを共通かつ軽量に保つことが
可能。
● 学習時と推論イメージでソフトウェアの
バージョン不一致が発生する可能性が残る。
学習環境と推論イメージでバージョニング
する必要がある。
● 推論器起動時にDockerイメージをpull、run後、モデ
ルファイルをダウンロードして稼働
させる。
KubernetesであればinitContainerを使用。
ビルド
Model repository
Base image
Runtime
推論器
コード
FROM python:3.8.5-slim
ENV ML_DIR ml
WORKDIR /${ML_DIR}
ADD requirements.txt /${ML_DIR}/
RUN apt-get -y update && 
apt-get -y install apt-utils gcc && 
pip install --no-cache-dir -r requirements_api.txt
COPY ./src/ /${ML_DIR}/src/
COPY ./logging/ /${ML_DIR}/logging/
COPY ./src/app/ml/model/*
/${ML_DIR}/src/app/ml/model/
COPY ./src/app/ml/data/* /${ML_DIR}/src/app/ml/data/
spec:
containers:
- name: ml-api
image: ml_api:latest
volumeMounts:
- name: model-volume
mountPath: /model
initContainers:
- name: ml-download
image: ml_download:latest
env:
- name: model_url
value: https://aaa.pycon.jp/model.onnx
volumeMounts:
- name: model-volume
mountPath: /model
volumes:
- name: model-volume
Model in Dockerfile Model load k8s manifest
initContainerで
モデルを
ダウンロード
モデル含めて
Dockerイメージを
ビルド
モデルの配布とスケールアウト
Node pool
Node
モデルレポジトリ
Image builder
Docker registry
Container
Runtime
Model
Container
Runtime
Init container Model
Model
LB
モデルインイメージ
イメージサイズは増加するが、一度nodeに
pull
されていれば稼働は速い。
モデルとイメージのバージョニングを同時に
管理可能。
モデルロード
コンテナ起動時にモデルをダウンロード。
モデルを頻繁に入れ替える場合に有効。
モデルとイメージのバージョンが分かれる。
システムを作る
WFH with Catパターン
● ネコとともに在宅勤務するパターン。
● 仕事中、食事中、睡眠中、あらゆる状況で
インタラプトされる。
● 作業を中断してネコが満足するまで撫でる
必要がある。
● 撫でずに無視すると以下のような障害を招く。
○ キーボード歩き。
○ 椅子爪研ぎ。
○ ゴミ箱倒し。
● 多頭飼いの場合、他ネコも平等に撫でないと
上記の障害を招く。
→安定稼働しているシステムでも不意にアラートが
発生する。
→ひとつ対策を立ててもまた別の課題が生じる。
Webシングルパターン
ロードバランサー
REST API
Docker Python image
Gunicorn
Uvicorns
FastAPI
Model
● 最もシンプルな構成の推論器。
● すぐリリースしたいときに有効。
● GunicornやUWSGIをベースに
FlaskやFastAPIで稼働。
Gunicorn(WSGI)
Uvicorn
(ASGI)
Uvicorn
(ASGI)
Gunicorn(WSGI)
Flask Flask
コード
from fastapi import FastAPI
from src.app.routers import predict_api
app = FastAPI()
app.include_router(
predict_api.router,
prefix='/predict',
tags=['predict'])
from fastapi import APIRouter
from src.app.api import _predict
from src.app.ml.classifier import Data, Classifier
router = APIRouter()
classifier = Classifier('model_path')
@router.get('/labels')
def labels():
return {'labels': Data().labels}
@router.get('')
def test():
return classifier.predict(Data().test_data)
@router.post('')
def predict(data: Data):
return {'prediction': classifier.predict(data)}
import numpy as np
import onnxruntime as rt
class Classifier():
def __init__(self, model_path):
self.classifier = None
self.load_model(model_path)
def load_model(self, model_path):
~~
def predict(self, input):
_prediction = self.classifier.run(
None,
{self.input_name: input.astype('float32’)}
)
return _prediction
main.py
predict_api.py classifier.py
GET /predictで
テストデータの
推論を得られる
ようにしておく。
入力の型を
明示する
推論器のインターフェイス
Docker image
Runtime
Model
入力
前処理
推論
出力
一度は経験する間違い:float32で学習した
モデルをfloat16で推論して結果がおかしい。
REST API + Json
● Webではポピュラーな実装。
● サーバ側でJsonを定義するが、型が
曖昧になるため、入力値の値確認(assertion)
が必要。
GRPC + Protocol Buffer
● TF ServingやONNX Runtime Serverで
標準提供。
(両者ともREST API + Jsonも標準提供)
● .protoファイルで入出力の型含めて
定義可能。クライアント、サーバで
共通化できる。
値の範囲や形式
● 正常に推論可能なデータの範囲。
● 自然言語の言語。
● 画像のフォーマット、RGB、その他。
{input_data: []}
((1,3,224,224))
float32
{prediction: []}
(1000,)
float32
Node pool
Node
LB
非同期推論パターン
メッセージ
推論器
● 推論結果を同期的に得る必要がない場合に
有効なパターン。
● クライアントと推論器の中間にApache Kafkaや
RabbitMQのようなメッセージングを配置する
ことで実現。
● 非同期の方式はリクエスト非同期型、
Publish/Subscribe型、Notification型等がある。
ワークフローに応じて選択。
● ただし重たいディープラーニングでは、
ユーザを待たせないために非同期とし、
許容遅延時間内のみポーリングすることも
可能。
Docker Python image
multiprocessing
Model
Runtime
Client
クライアント
アンチパターン:All in oneパターン
ロードバランサー
REST API
Docker Python image
Sklearn
ML Model
Tensorflow
Image Model
ONNX Runtime
NLP Model
● 多様なモデルを同一コンテナに詰め込む。
○ Docker image size: 10GB
○ CPU: 32コア
○ RAM: 64GB
● イメージサイズが増大し、パフォーマンスの
ボトルネックや障害対応が複雑化する。
● 前処理含めて複数のRuntimeを稼働させることにな
り、ライブラリのバージョン管理も困難。
● マルチモーダルでfusionする場合も様々な
モデルの混合になるが、複数モードの入力と
特徴抽出を持つ1モデルに集約して同一Runtime
で稼働させる。
TF Serving
Image extraction
Text extraction
Fusion Predict
Prep Predパターン
LB
Preprocess
● 前処理と推論で必要なライブラリやリソースが
違うときに有効。
前処理はPython、推論はTF Serving。
● 前処理と推論で異なる実行方式になり、
それぞれを異なるサービスとして稼働させる。
● Tensorflowは学習と推論で実行方式が異なる。
○ 学習ではtf.keras.fit()。
○ 推論ではCPUでTF Serving。
● ONNXもRuntime server(Beta)のほうが
パフォーマンスは安定する。
● ただし、学習時の前処理とモデルは一致する
必要があるため、前処理と推論を個別に更新する
ことは避ける。
LB
Docker Python image
Gunicorn
Uvicorn
FastAPI
Sklearn
Client Docker TF serving image
TF savedmodel
Prediction
コード
from fastapi import APIRouter
from src.app.api import _predict
from src.app.ml.classifier import Data,
Classifier
router = APIRouter()
classifier = Classifier('model_path')
@router.get('/labels')
def labels():
return {'labels': Data().labels}
@router.post('')
async def predict(data: Data):
return {'prediction': classifier.predict(data)}
import numpy as np
import grpc
import tensorflow as tf
from tensorflow_serving.apis import predict_pb2
from tensorflow_serving.apis import
prediction_service_pb2_grpc
TFS_GPRC = 'prep_pred_tfs:8510'
class Classifier():
def __init__(self, models):
self.models = models
self.prep = None
self.post = None
self.input = 'keras_layer_input'
self.input_shape = [1,224,224,3]
self.channel = 'model_spec_name'
self.stub = 'model_spec_name'
self.spec_name = 'model_spec_name'
self.signature_name = 'default'
class Classifier():
def predict(self, input: Image):
input = np.array(self.prep.transform(input))
r = predict_pb2.PredictRequest()
r.model_spec.name = self.spec_name
r.spec.signature_name = self.signature_name
r.inputs[self.input].CopyFrom(
tf.make_tensor_proto(
input,
shape=self.input_shape))
result = self.stub.Predict(request, 5.0)
result = result.outputs[output_name].float_val
prediction = self.post.transform(result)
return prediction
routers.py
classifier.py classifier.py
前処理
→TF Serving (GRPC)
→後処理
並列マイクロサービスパターン
Client
● 独立した複数の推論モデルに並行して
リクエストするときに有効。
例:複数の2値分類モデルで推論したいとき。
例:マルチモーダルで推論器を各モードに
  分けるとき。
● クライアントと推論器の中間にプロキシを
置き、プロキシで各推論器へのリクエストを
制御する構成。
● リクエスト先を環境変数等で制御すると、
推論器の追加、削除を柔軟に実現することが
可能。
● Nginxを仲介にしても良いが、推論結果の
集計やクライアントへのレスポンスに
ロジックを持たせる場合はProxyを自作する。Docker Python image
Gunicorn
aiohttp server
aiohttp
client
LB
Web single A
Prep pred C
Web single B
Proxy
マルチステージ推論パターン
Client
● 複数の推論器でレイテンシーに差がある場合、
速い推論器は同期的に返し、遅い推論器の
レスポンスを非同期にする。
● クライアントと推論器の中間にProxyを置き、Proxyで各
推論器へのリクエストを制御する構成。
● 推論器は同期、非同期両方のエンドポイントを
公開しておくことで、より柔軟な対応が可能。
この構成の場合、メッセージングではなく
CeleryやBackgroundTasksで実装。
LB
Sklearn
WebSingleA
Deep learning
AsyncB
Proxy
キャッシュ
Environment Variable
- SVC_A: WebSingleA
- SVC_B: AsyncB
- SVC_A_EP: predict
- SVC_B_EP: async
コード
from fastapi import FastAPI
from src.app.routers import proxy
app = FastAPI()
app.include_router(
proxy.router,
prefix='/redirect',
tags=['redirect'])
router = APIRouter()
class Data():
data: Any = None
async def _get_redirect(session, alias, url):
async with session.get(url) as r:
response_json = await r.json()
return {alias: {'response': response_json}}
@router.get('/{redirect_path:path}')
async def get_redirect(redirect_path):
async with aiohttp.ClientSession() as session:
tasks = [asyncio.ensure_future(
_get_redirect(
session, alias,
helpers.redirect_builder(
alias,url,redirect_path,redirect_map))
) for alias, url in urls.items()]
return await asyncio.gather(*tasks)
async def _post_redirect(
session, data, alias, url):
async with session.post(url, data) as r:
response_json = await r.json()
return {alias: {'response': response_json}}
@router.post('/{redirect_path:path}')
async def post_redirect(redirect_path, data):
data.data['job_id'] = get_job_id()
async with aiohttp.ClientSession() as session:
tasks = [asyncio.ensure_future(
_post_redirect(
session, data.data, alias,
helpers.redirect_builder(
alias,url,redirect_path,redirect_map))
) for alias, url in urls.items()]
return await asyncio.gather(*tasks)
main.py
proxy.py proxy.py
転送先は環境変数で
定義してdictに変換。
aiohttpでasyncリクエスト。
K8s Manifest
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-proxy
labels:
app: api-proxy
namespace: serving-pattern
spec:
selector:
matchLabels:
app: api-proxy
replicas: 4
template:
metadata:
labels:
app: api-proxy
name: api-proxy
spec:
containers:
- name: api-proxy
image: api_proxy:latest
command: ["./run_proxy.sh"]
env:
- name: SVC_SKLEARN
value:
sklearn.serving.svc.cluster.local:8893
- name: SVC_RESNET_ONNX_SERVER
value:
resnet-server.serving.svc.cluster.local:8896
- name: REDIRECT_MAP
value: '{
"SVC_RESNET_ONNX_SERVER":{
"predict/label":"predict/async",
"predict":"predict/async"
}
}'
proxy.yaml proxy.yaml
Sklearn
WebSingleA
Resnet50
AsyncB
Proxy
キャッシュ
proxy.svc/predict
sklearn.svc/predict
onnx.svc/predict/async
転送先の定義例。
わかりやすく改行を
入れている。
(本当はconfigmapで
定義)
パラメータベース推論パターン
Client
● 独立した複数の推論モデルに並行して
リクエストするときに有効。
● リクエスト先をProxyの環境変数等で
制御する。リクエストの挙動も定義可能。
○ 例:接続先と割合の定義
○ 例:タイムアウトやリトライ数
● 個々の推論器に固有のパラメータを
設定することも可能だが、複雑になる
場合は別の推論システムにする。
LB
WebSingleA
PrepPredC
Environment Variable
- SVC_A: WebSingleA
- SVC_B: WebSingleB
- SVC_C: PrepPredC
- SVC_A_RATE: 0.4
- SVC_B_RATE: 0.4
- SVC_C_RATE: 0.2
- TIMEOUT_SEC: 1
- RETRY: 2
WebSingleB
Proxy
Environment Variable
- THRESHOLD: 0.99
- WORKERS: 4
推論サーキットブレーカーパターン
Client
● 急激な負荷増でスケールアウトが
間に合わない場合、一部のリクエストを
遮断することで全断を防ぐ。
● 機械学習、特にディープラーニング推論の
場合、使用するリソースや、モデルを
含むイメージサイズが大きい傾向にあり、
ノードを含めたスケールアウトに時間を
要することがある。
● NginxやEnvoy proxyで標準的に提供されて
いる機能。
● パフォーマンス劣化対策はサーキット
ブレーカー以外でも可能。
Gunicorn(wsgi)ではworker数やtimeout,
max_requests等でリソース利用を効率化する
機構が備わっている。
LB
Nginx
limit_req_zone $server_addr
zone=moderateReqs:1m
rate=100r/s;
LB
アンチパターン:Nobody knowsパターン
LB
ML ML
ML
ML
ML
ML
ML?
● 稼働中の推論器がなぜ動いているのか誰も知らないパ
ターン。歴史的にシステムが複雑になっていくと頻繁に発
生する。
● MLプロジェクトの初期にプロトタイプで作った
モデルや、緊急対応で稼働させた推論器を残して
おくと「Nobody knows」になる。
● 学習データが残っていない状態は珍しくない。
学習コードもJupyter Notebookのみという場合、
モデルの評価や再現が困難。ML?
ML
機械学習システムの
品質を維持する
Cat injectionパターン
● 作業途中でネコに椅子を奪われるパターン。
● 30分以上ネコを放置していると、離席中に発生。
● ネコの機嫌を評価する指標になる。
機械学習システムの品質
機械学習システムの品質には3カテゴリある。
1. 機械学習の推論モデル
a. 推論モデルのパフォーマンス
b. 本番データの変化による劣化とエラー
c. 問題定義とソリューション
2. 推論モデルを稼働させるシステム
a. 入出力のデータやデータ型
b. 推論スピードと可用性
c. 例外処理
3. 運用と体制
a. モデルの再現および再学習
b. 推論器の再現およびロールバック
c. 維持可能な運用体制
Client LB LB
int float
test data
accuracy:
99.99%
何のML
だっけ?
1sec/req
モデル作った
VM消したよ
dockerimg:latest
上書き
error率
0.01%
アサイン
変わった
me
too
転
職
商品カテゴリ
追加削除
そして誰も
いなくなった
負荷テスト
Load tester LB
Load tester
● 推論器を本番同様のリソースで稼働させて
レイテンシーを測り、ボトルネックを発見、
チューニングする。
● Too bigなモデルでない限り、モデルは変更せずに
実行環境で高速化や可用性強化を図る。
● 推論器のボトルネックは推論モデル。
Webサーバに組み込んで計測する前に、
モデル単体をサーバ内部で連続して
推論させ、推論の平均所要時間を計測する。
● 学習コストの高いディープラーニングモデルを
使う場合、学習前にモデルだけで負荷テストを
実行して遅延を確認しておく。
Profile
入力
前処理
推論
後処理
出力
レイテンシー(ms)
計測時間
計測時間
リクエスト数/秒
負荷テスト ● 負荷テスト
○ 外部から連続してリクエストを送信。
入力がサイズ不特定の画像やテキストの場合、
ランダムなサイズのデータを用意。
○ CPU使用率が上がらず遅延が発生する場合、
ワーカー数や通信方法を調整する。
NumpyやSklearnであればIntel MKLを使用する
ことも選択肢。
○ メモリリークが発生して根本解決が困難な場合、
Gunicornのmax_requestsパラメータで、一定数の
リクエスト後にワーカープロセスを再起動する
ことで緩和可能。
jitterやgraceful-timeoutと組み合わせる。
○ TensorflowやPytorchであれば前処理含めて
計算グラフに組み込むことで遅延短縮可能。
○ 推論用GPUはコスト対効果次第。
Load tester LB
Load tester
計測時間
リクエスト数/秒
計測時間
リソース
RAM
CPU
負荷テストツール
Locust
Python純正の負荷テストツール。
Pythonでテスト方法を定義し実行。
Web画面を用意し、レイテンシーやエラー率の把握や
アクセス数の変更が可能。
アクセスクライアントやワーカー数を調整可能で、
様々な負荷状況を再現可能。
Gunicorn + Flask Gunicorn + FastAPI Prep/Pred
負荷テスト
Gunicorn
Flask
ONNX
Runtime
Gunicorn
Uvicorns
FastAPI
ONNX
Runtime
Gunicorn
Uvicorns
FastAPI
ONNX
Client
ONNX Runtime
Server
ONNX
Runtime
同一リソース(CPU/RAM)。
20rpsで検証。
PytorchベースのResnet50 onnx。
1. Gunicorn + Flask(WebSingle)
2. Gunicorn + FastAPI(WebSingle)
3. Gunicorn+FastAPI&
ONNX Runtime Server(Prep/pred)
シャドウABテスト
Client LB
WebSingleA
WebSingleBProxy
Environment Variable
- SVC_A: WebSingleA
- SVC_B: WebSingleB
- ACTIVE: WebSingleA
- SHADOW: WebSingleB
● 稼働中モデルの更新では以下の確認が必要。
a. 推論サーバの正常稼働
b. 想定通りの推論結果
c. レイテンシー
d. 負荷耐性
● 更新推論モデルをシャドウで本番システムに
組み込み、リクエストを送る
(ただしレスポンスは返さない)。
● 推論結果だけでなくレイテンシーもログに残す。稼働中
モデルとシャドウモデルのログを照合する
必要があるため、リクエストに一意のIDを振る。
{“test_id”: “001”, “request_id”: “aaa”, “user_id”: “111”, “data_id”: “abc”,
“request”: “WebSingleA”, “result”: {“pred”: 0, “latency”: 10ms}}
{“test_id”: “001”, “request_id “aaa”, “user_id”: “111”, “data_id”: “abc”,
“request”: “WebSingleB”, “result”: {“pred”: 1, “latency”: 5ms}}
オンラインABテスト
Client LB
WebSingleA
WebSingleBProxy
Environment Variable
- GROUP_A: SVC_A
- GROUP_B: SVC_B
- DEFAULT: SVC_A
- UNTIL: 20200829
● オンラインABテストではモデルの更新が
エンドユーザに与える影響を測る。評価指標に
応じてログを取得。
● Proxyでリクエスト先をコントロールする。
特定のユーザグループを比較する場合、
ユーザグループの分割とリクエスト先の
ルールをProxyでコントロールする。
● ABテスト期間を設定して無効化する。
期間後に不要な推論器を削除しないと
「Nobody knows」になる。
Group_A
Group_B
{“test_id”: “001”, “request_id”: “aaa”, “user_id”: “111”, “data_id”: “abc”,
“request”: “WebSingleA”, “result”: {“pred”: 0, “latency”: 10ms}}
{“test_id”: “001”, “request_id “zzz”, “user_id”: “000”, “data_id”: “def”,
“request”: “WebSingleB”, “result”: {“pred”: 1, “latency”: 5ms}}
コード
from fastapi import FastAPI
from src.app.routers import abtest
app = FastAPI()
app.include_router(
abtest.router,
prefix='/abtest,
tags=[abtest])
@router.post('/{redirect_path:path}')
async def post_redirect(redirect_path, data):
data.data['job_id'] = get_job_id()
if data.ab in test_group.keys():
group = test_group[data.ab]
redirect = {group: redirect[group]}
async with aiohttp.ClientSession() as session:
tasks = [
asyncio.ensure_future(
_post_redirect(
session, data.data, alias,
helpers.redirect_builder(
alias, url, redirect_path, redirect))
) for alias, url in urls.items() if alias in
redirect.keys()]
responses = await asyncio.gather(*tasks)
return responses
apiVersion: apps/v1
kind: Deployment
~~
spec:
containers:
- name: abtest-proxy
image: abtest-proxy:latest
env:
- name: SERVICE_AB_TEST_A
value:
sklearn.serving.svc.cluster.local:8893
- name: SERVICE_AB_TEST_B
value:
resnet-server.serving.svc.cluster.local:8896
- name: ABTEST_GROUP
value:
'{"GROUP_A":"SERVICE_AB_TEST_A",
"GROUP_B":"SERVICE_AB_TEST_B",
"DEFAULT":"SERVICE_AB_TEST_A"}'
main.py
abtest.py proxy.yaml
ABテスト定義例。
わかりやすく
改行を入れている。
本来はconfigmap
まとめ
まとめ
● End to Endで機械学習のシステムを作る実装例を説明しました。
● 機械学習を本番導入する注意点はいろいろありますが、有効活用すれば絶大な効果を
発揮できると思います。
● 「モデルを作る」から「本番稼働させる」までの架け橋となると幸いです。

More Related Content

What's hot

ブレインパッドにおける機械学習プロジェクトの進め方
ブレインパッドにおける機械学習プロジェクトの進め方ブレインパッドにおける機械学習プロジェクトの進め方
ブレインパッドにおける機械学習プロジェクトの進め方BrainPad Inc.
 
研究分野をサーベイする
研究分野をサーベイする研究分野をサーベイする
研究分野をサーベイするTakayuki Itoh
 
Optimizer入門&最新動向
Optimizer入門&最新動向Optimizer入門&最新動向
Optimizer入門&最新動向Motokawa Tetsuya
 
機械学習モデルの判断根拠の説明(Ver.2)
機械学習モデルの判断根拠の説明(Ver.2)機械学習モデルの判断根拠の説明(Ver.2)
機械学習モデルの判断根拠の説明(Ver.2)Satoshi Hara
 
Data-centricなML開発
Data-centricなML開発Data-centricなML開発
Data-centricなML開発Takeshi Suzuki
 
最近のKaggleに学ぶテーブルデータの特徴量エンジニアリング
最近のKaggleに学ぶテーブルデータの特徴量エンジニアリング最近のKaggleに学ぶテーブルデータの特徴量エンジニアリング
最近のKaggleに学ぶテーブルデータの特徴量エンジニアリングmlm_kansai
 
先駆者に学ぶ MLOpsの実際
先駆者に学ぶ MLOpsの実際先駆者に学ぶ MLOpsの実際
先駆者に学ぶ MLOpsの実際Tetsutaro Watanabe
 
Getting started with MLOps
Getting started with MLOpsGetting started with MLOps
Getting started with MLOpsyusuke shibui
 
機械学習のためのベイズ最適化入門
機械学習のためのベイズ最適化入門機械学習のためのベイズ最適化入門
機械学習のためのベイズ最適化入門hoxo_m
 
AHC-Lab M1勉強会 論文の読み方・書き方
AHC-Lab M1勉強会 論文の読み方・書き方AHC-Lab M1勉強会 論文の読み方・書き方
AHC-Lab M1勉強会 論文の読み方・書き方Shinagawa Seitaro
 
(修正)機械学習デザインパターン(ML Design Patterns)の解説
(修正)機械学習デザインパターン(ML Design Patterns)の解説(修正)機械学習デザインパターン(ML Design Patterns)の解説
(修正)機械学習デザインパターン(ML Design Patterns)の解説Hironori Washizaki
 
劣モジュラ最適化と機械学習1章
劣モジュラ最適化と機械学習1章劣モジュラ最適化と機械学習1章
劣モジュラ最適化と機械学習1章Hakky St
 
画像認識モデルを作るための鉄板レシピ
画像認識モデルを作るための鉄板レシピ画像認識モデルを作るための鉄板レシピ
画像認識モデルを作るための鉄板レシピTakahiro Kubo
 
強化学習の基礎と深層強化学習(東京大学 松尾研究室 深層強化学習サマースクール講義資料)
強化学習の基礎と深層強化学習(東京大学 松尾研究室 深層強化学習サマースクール講義資料)強化学習の基礎と深層強化学習(東京大学 松尾研究室 深層強化学習サマースクール講義資料)
強化学習の基礎と深層強化学習(東京大学 松尾研究室 深層強化学習サマースクール講義資料)Shota Imai
 
backbone としての timm 入門
backbone としての timm 入門backbone としての timm 入門
backbone としての timm 入門Takuji Tahara
 
最近のディープラーニングのトレンド紹介_20200925
最近のディープラーニングのトレンド紹介_20200925最近のディープラーニングのトレンド紹介_20200925
最近のディープラーニングのトレンド紹介_20200925小川 雄太郎
 
最近のDeep Learning (NLP) 界隈におけるAttention事情
最近のDeep Learning (NLP) 界隈におけるAttention事情最近のDeep Learning (NLP) 界隈におけるAttention事情
最近のDeep Learning (NLP) 界隈におけるAttention事情Yuta Kikuchi
 

What's hot (20)

ブレインパッドにおける機械学習プロジェクトの進め方
ブレインパッドにおける機械学習プロジェクトの進め方ブレインパッドにおける機械学習プロジェクトの進め方
ブレインパッドにおける機械学習プロジェクトの進め方
 
研究分野をサーベイする
研究分野をサーベイする研究分野をサーベイする
研究分野をサーベイする
 
Optimizer入門&最新動向
Optimizer入門&最新動向Optimizer入門&最新動向
Optimizer入門&最新動向
 
機械学習モデルの判断根拠の説明(Ver.2)
機械学習モデルの判断根拠の説明(Ver.2)機械学習モデルの判断根拠の説明(Ver.2)
機械学習モデルの判断根拠の説明(Ver.2)
 
Data-centricなML開発
Data-centricなML開発Data-centricなML開発
Data-centricなML開発
 
最近のKaggleに学ぶテーブルデータの特徴量エンジニアリング
最近のKaggleに学ぶテーブルデータの特徴量エンジニアリング最近のKaggleに学ぶテーブルデータの特徴量エンジニアリング
最近のKaggleに学ぶテーブルデータの特徴量エンジニアリング
 
MLOps入門
MLOps入門MLOps入門
MLOps入門
 
先駆者に学ぶ MLOpsの実際
先駆者に学ぶ MLOpsの実際先駆者に学ぶ MLOpsの実際
先駆者に学ぶ MLOpsの実際
 
Data-Centric AIの紹介
Data-Centric AIの紹介Data-Centric AIの紹介
Data-Centric AIの紹介
 
Getting started with MLOps
Getting started with MLOpsGetting started with MLOps
Getting started with MLOps
 
機械学習のためのベイズ最適化入門
機械学習のためのベイズ最適化入門機械学習のためのベイズ最適化入門
機械学習のためのベイズ最適化入門
 
AHC-Lab M1勉強会 論文の読み方・書き方
AHC-Lab M1勉強会 論文の読み方・書き方AHC-Lab M1勉強会 論文の読み方・書き方
AHC-Lab M1勉強会 論文の読み方・書き方
 
BlackBox モデルの説明性・解釈性技術の実装
BlackBox モデルの説明性・解釈性技術の実装BlackBox モデルの説明性・解釈性技術の実装
BlackBox モデルの説明性・解釈性技術の実装
 
(修正)機械学習デザインパターン(ML Design Patterns)の解説
(修正)機械学習デザインパターン(ML Design Patterns)の解説(修正)機械学習デザインパターン(ML Design Patterns)の解説
(修正)機械学習デザインパターン(ML Design Patterns)の解説
 
劣モジュラ最適化と機械学習1章
劣モジュラ最適化と機械学習1章劣モジュラ最適化と機械学習1章
劣モジュラ最適化と機械学習1章
 
画像認識モデルを作るための鉄板レシピ
画像認識モデルを作るための鉄板レシピ画像認識モデルを作るための鉄板レシピ
画像認識モデルを作るための鉄板レシピ
 
強化学習の基礎と深層強化学習(東京大学 松尾研究室 深層強化学習サマースクール講義資料)
強化学習の基礎と深層強化学習(東京大学 松尾研究室 深層強化学習サマースクール講義資料)強化学習の基礎と深層強化学習(東京大学 松尾研究室 深層強化学習サマースクール講義資料)
強化学習の基礎と深層強化学習(東京大学 松尾研究室 深層強化学習サマースクール講義資料)
 
backbone としての timm 入門
backbone としての timm 入門backbone としての timm 入門
backbone としての timm 入門
 
最近のディープラーニングのトレンド紹介_20200925
最近のディープラーニングのトレンド紹介_20200925最近のディープラーニングのトレンド紹介_20200925
最近のディープラーニングのトレンド紹介_20200925
 
最近のDeep Learning (NLP) 界隈におけるAttention事情
最近のDeep Learning (NLP) 界隈におけるAttention事情最近のDeep Learning (NLP) 界隈におけるAttention事情
最近のDeep Learning (NLP) 界隈におけるAttention事情
 

Similar to Ml system in_python

Testing machine learning development
Testing machine learning developmentTesting machine learning development
Testing machine learning developmentyusuke shibui
 
Devsumi 2021 MLOps for Self-driving car
Devsumi 2021 MLOps for Self-driving carDevsumi 2021 MLOps for Self-driving car
Devsumi 2021 MLOps for Self-driving caryusuke shibui
 
ML system design_pattern
ML system design_patternML system design_pattern
ML system design_patternyusuke shibui
 
Quality of ml_system
Quality of ml_systemQuality of ml_system
Quality of ml_systemyusuke shibui
 
機械学習システム構築実践ガイド
機械学習システム構築実践ガイド機械学習システム構築実践ガイド
機械学習システム構築実践ガイドyusuke shibui
 
Rosbag search system
Rosbag search systemRosbag search system
Rosbag search systemyusuke shibui
 
機械学習でテスト実行を効率化するLaunchable.pdf
機械学習でテスト実行を効率化するLaunchable.pdf機械学習でテスト実行を効率化するLaunchable.pdf
機械学習でテスト実行を効率化するLaunchable.pdfyusuke shibui
 
TFLite_and_PyTorch_Mobile
TFLite_and_PyTorch_MobileTFLite_and_PyTorch_Mobile
TFLite_and_PyTorch_Mobileyusuke shibui
 
machine_learning_failure_apocalypse.pdf
machine_learning_failure_apocalypse.pdfmachine_learning_failure_apocalypse.pdf
machine_learning_failure_apocalypse.pdfyusuke shibui
 
Reviewing_machine_learning_program.pdf
Reviewing_machine_learning_program.pdfReviewing_machine_learning_program.pdf
Reviewing_machine_learning_program.pdfyusuke shibui
 
Launchable and efficient test execution
Launchable and efficient test executionLaunchable and efficient test execution
Launchable and efficient test executionyusuke shibui
 
スタートアップツールチラ見せ
スタートアップツールチラ見せスタートアップツールチラ見せ
スタートアップツールチラ見せHisatoshi Kikumoto
 
MLOps failure(1_108)
MLOps failure(1_108)MLOps failure(1_108)
MLOps failure(1_108)yusuke shibui
 
Traffic light detection for self driving car
Traffic light detection for self driving carTraffic light detection for self driving car
Traffic light detection for self driving caryusuke shibui
 
ANSIBLE_KEEP_REMOTE_FILESをTrueにしてみよう!
ANSIBLE_KEEP_REMOTE_FILESをTrueにしてみよう!ANSIBLE_KEEP_REMOTE_FILESをTrueにしてみよう!
ANSIBLE_KEEP_REMOTE_FILESをTrueにしてみよう!Hideki Saito
 
IPython notebookを使おう
IPython notebookを使おうIPython notebookを使おう
IPython notebookを使おうKazufumi Ohkawa
 
猫とまいんどすとーむのつぶやき Slide share
猫とまいんどすとーむのつぶやき Slide share猫とまいんどすとーむのつぶやき Slide share
猫とまいんどすとーむのつぶやき Slide sharefurugen098
 
Creative as Software Engineering for GenAI LT
Creative as Software Engineering for GenAI LTCreative as Software Engineering for GenAI LT
Creative as Software Engineering for GenAI LTyusuke shibui
 

Similar to Ml system in_python (20)

How to start MLOps
How to start MLOpsHow to start MLOps
How to start MLOps
 
Testing machine learning development
Testing machine learning developmentTesting machine learning development
Testing machine learning development
 
Devsumi 2021 MLOps for Self-driving car
Devsumi 2021 MLOps for Self-driving carDevsumi 2021 MLOps for Self-driving car
Devsumi 2021 MLOps for Self-driving car
 
ML system design_pattern
ML system design_patternML system design_pattern
ML system design_pattern
 
Quality of ml_system
Quality of ml_systemQuality of ml_system
Quality of ml_system
 
機械学習システム構築実践ガイド
機械学習システム構築実践ガイド機械学習システム構築実践ガイド
機械学習システム構築実践ガイド
 
Rosbag search system
Rosbag search systemRosbag search system
Rosbag search system
 
機械学習でテスト実行を効率化するLaunchable.pdf
機械学習でテスト実行を効率化するLaunchable.pdf機械学習でテスト実行を効率化するLaunchable.pdf
機械学習でテスト実行を効率化するLaunchable.pdf
 
TFLite_and_PyTorch_Mobile
TFLite_and_PyTorch_MobileTFLite_and_PyTorch_Mobile
TFLite_and_PyTorch_Mobile
 
machine_learning_failure_apocalypse.pdf
machine_learning_failure_apocalypse.pdfmachine_learning_failure_apocalypse.pdf
machine_learning_failure_apocalypse.pdf
 
Lets start mlops
Lets start mlopsLets start mlops
Lets start mlops
 
Reviewing_machine_learning_program.pdf
Reviewing_machine_learning_program.pdfReviewing_machine_learning_program.pdf
Reviewing_machine_learning_program.pdf
 
Launchable and efficient test execution
Launchable and efficient test executionLaunchable and efficient test execution
Launchable and efficient test execution
 
スタートアップツールチラ見せ
スタートアップツールチラ見せスタートアップツールチラ見せ
スタートアップツールチラ見せ
 
MLOps failure(1_108)
MLOps failure(1_108)MLOps failure(1_108)
MLOps failure(1_108)
 
Traffic light detection for self driving car
Traffic light detection for self driving carTraffic light detection for self driving car
Traffic light detection for self driving car
 
ANSIBLE_KEEP_REMOTE_FILESをTrueにしてみよう!
ANSIBLE_KEEP_REMOTE_FILESをTrueにしてみよう!ANSIBLE_KEEP_REMOTE_FILESをTrueにしてみよう!
ANSIBLE_KEEP_REMOTE_FILESをTrueにしてみよう!
 
IPython notebookを使おう
IPython notebookを使おうIPython notebookを使おう
IPython notebookを使おう
 
猫とまいんどすとーむのつぶやき Slide share
猫とまいんどすとーむのつぶやき Slide share猫とまいんどすとーむのつぶやき Slide share
猫とまいんどすとーむのつぶやき Slide share
 
Creative as Software Engineering for GenAI LT
Creative as Software Engineering for GenAI LTCreative as Software Engineering for GenAI LT
Creative as Software Engineering for GenAI LT
 

More from yusuke shibui

Generative AIと検索を組み合わせた新たな体験の模索
Generative AIと検索を組み合わせた新たな体験の模索Generative AIと検索を組み合わせた新たな体験の模索
Generative AIと検索を組み合わせた新たな体験の模索yusuke shibui
 
DevSummit_2022_summer_MLOps.pdf
DevSummit_2022_summer_MLOps.pdfDevSummit_2022_summer_MLOps.pdf
DevSummit_2022_summer_MLOps.pdfyusuke shibui
 
Machine learning CI/CD with OSS
Machine learning CI/CD with OSSMachine learning CI/CD with OSS
Machine learning CI/CD with OSSyusuke shibui
 
Twillio deadshot made me happy
Twillio deadshot made me happyTwillio deadshot made me happy
Twillio deadshot made me happyyusuke shibui
 
Machine learning quality for production
Machine learning quality for productionMachine learning quality for production
Machine learning quality for productionyusuke shibui
 
Mercari Image search 1st Anniversary
Mercari Image search 1st AnniversaryMercari Image search 1st Anniversary
Mercari Image search 1st Anniversaryyusuke shibui
 
Machine learning and_system_design
Machine learning and_system_designMachine learning and_system_design
Machine learning and_system_designyusuke shibui
 
Machine learning microservice_management
Machine learning microservice_managementMachine learning microservice_management
Machine learning microservice_managementyusuke shibui
 

More from yusuke shibui (9)

Generative AIと検索を組み合わせた新たな体験の模索
Generative AIと検索を組み合わせた新たな体験の模索Generative AIと検索を組み合わせた新たな体験の模索
Generative AIと検索を組み合わせた新たな体験の模索
 
DevSummit_2022_summer_MLOps.pdf
DevSummit_2022_summer_MLOps.pdfDevSummit_2022_summer_MLOps.pdf
DevSummit_2022_summer_MLOps.pdf
 
Machine learning CI/CD with OSS
Machine learning CI/CD with OSSMachine learning CI/CD with OSS
Machine learning CI/CD with OSS
 
Twillio deadshot made me happy
Twillio deadshot made me happyTwillio deadshot made me happy
Twillio deadshot made me happy
 
Machine learning quality for production
Machine learning quality for productionMachine learning quality for production
Machine learning quality for production
 
Mercari Image search 1st Anniversary
Mercari Image search 1st AnniversaryMercari Image search 1st Anniversary
Mercari Image search 1st Anniversary
 
Machine learning and_system_design
Machine learning and_system_designMachine learning and_system_design
Machine learning and_system_design
 
Machine learning microservice_management
Machine learning microservice_managementMachine learning microservice_management
Machine learning microservice_management
 
Mercari ML Meetup
Mercari ML MeetupMercari ML Meetup
Mercari ML Meetup
 

Ml system in_python