Mímisbrunnr知恵の泉

← MLOps 一覧

🎓 レベル:標準 | 重要度:A(必須)

📎 前提:モデルレジストリとモデルのライフサイクル | 関連:オンライン推論サービング

要点(BLUF)

1. 3つのパターン

パターン実行契機遅延鮮度
バッチスケジュール(夜次等)分〜時間古くてよい全顧客の解約スコアを毎晩計算
オンラインリクエスト毎ミリ秒最新が必要申込時の与信判定
ストリーミングイベント到着準リアルタイム取引ごとの不正検知

2. 図解:3パターンのデータフロー

flowchart TB
  subgraph バッチ
    B1["スケジューラ起動"] --> B2["全データを一括読込"]
    B2 --> B3["まとめて推論"]
    B3 --> B4["結果をテーブルに書き出し"]
  end
  subgraph オンライン
    O1["リクエスト到着"] --> O2["特徴量取得"]
    O2 --> O3["即時推論"]
    O3 --> O4["低遅延で応答"]
  end
  subgraph ストリーミング
    S1["イベントストリーム"] --> S2["イベント毎に推論"]
    S2 --> S3["結果を下流へ発行"]
  end

3. 選択の判断軸

flowchart TB
  Q1{"予測は即時に必要か"} -->|"いいえ 事前計算で足りる"| BATCH["バッチ推論"]
  Q1 -->|"はい"| Q2{"きっかけはリクエストかイベントか"}
  Q2 -->|"ユーザーのリクエスト"| ONLINE["オンライン推論"]
  Q2 -->|"流れてくるイベント"| STREAM["ストリーミング推論"]

4. 動く最小例:同じモデルを3パターンで動かす

同一モデルを、(a) バッチ(全件一括)、(b) オンライン(1件ずつ)、(c) ストリーミング(イベント列を逐次)で動かし、スループットと1件あたり遅延の違いを見ます。

import time
import numpy as np
from sklearn.linear_model import LogisticRegression

rng = np.random.default_rng(0)
Xtr = rng.normal(0, 1, (500, 4))
ytr = (Xtr[:, 0] - Xtr[:, 1] > 0).astype(int)
model = LogisticRegression().fit(Xtr, ytr)

data = rng.normal(0, 1, (2000, 4))   # 推論対象

# (a) バッチ:全件まとめて
t0 = time.perf_counter()
_ = model.predict(data)
batch_ms = (time.perf_counter() - t0) * 1000

# (b) オンライン:1件ずつ(リクエスト毎を模擬)
t0 = time.perf_counter()
for x in data[:200]:
    _ = model.predict(x.reshape(1, -1))
online_ms_per = (time.perf_counter() - t0) * 1000 / 200

# (c) ストリーミング:イベント列を小ロットで逐次
t0 = time.perf_counter()
for i in range(0, 2000, 50):
    _ = model.predict(data[i:i+50])
stream_ms = (time.perf_counter() - t0) * 1000

print(f"(a) バッチ2000件一括      : {batch_ms:.2f} ms 合計")
print(f"(b) オンライン1件あたり    : {online_ms_per:.3f} ms/件")
print(f"(c) ストリーミング小ロット : {stream_ms:.2f} ms 合計")
print(f"1件あたり: バッチ={batch_ms/2000:.4f} ms  オンライン={online_ms_per:.4f} ms")

出力例(数値は環境依存):

(a) バッチ2000件一括      : 0.15 ms 合計
(b) オンライン1件あたり    : 0.052 ms/件
(c) ストリーミング小ロット : 2.10 ms 合計
1件あたり: バッチ=0.0001 ms  オンライン=0.0519 ms

出力の意味:同じモデルでも、バッチは1件あたりの単価が圧倒的に安い(2000件をまとめて行列演算するため1件0.0001ms)。オンラインは1件ずつ呼ぶので1件あたりの固定オーバーヘッドが数百倍大きく(0.05ms程度)、その代わり「今この入力に即答できる」。ストリーミングは中間で、小ロットでまとめつつ低遅延を保ちます。遅延と単価はトレードオフで、要件がどちらを要求するかでパターンが決まります(数値は実行環境で変動します)。

5. 運用の勘所

なぜそうするのか

デプロイパターンを要件から選ぶのは、過剰設計を避けるためです。オンラインサービングは魅力的に見えますが、24/7 稼働・低遅延保証・オートスケールという運用負荷を伴います。バッチで足りる問題にオンラインを使うのは、コストとリスクの無駄遣いです。逆に、即時性が必要な問題をバッチで回すと価値を逃します。要件(鮮度・遅延)が設計を決める、という順序を守ります。

⚠️ よくある落とし穴

対応 lab

関連ノート