🎓 レベル:標準 | 重要度:B(推奨)
📎 前提:オンライン推論サービング | 関連:クラウド・インフラ/SRE・DevOps 全体目次(クラウド)
要点(BLUF)
- パッケージングは「モデル+前処理+依存+サービングコードを1つのコンテナイメージに固める」こと。これで「自分の環境では動く」問題を消し、どこでも同じに動く成果物にします(再現性とバージョニングの環境固定の実装)。
- 1イメージにまとめる3点:モデルアーティファクト(変換器ごと)・依存の固定(ロックファイル)・サービングコード(オンライン推論サービング)。イメージはタグで版管理し、レジストリのモデル版と対応づけます。
- Docker・Kubernetes そのものの汎用知識はクラウド分野へ wikilink します。ここは「MLモデルをどう固めるか」というML特化の観点に集中します。
1. なぜコンテナに固めるのか
再現性とバージョニングで見たとおり、モデルは環境(依存ライブラリ・Python版・OS)の関数でもあります。requirements.txt を配るだけでは、OS差・推移的依存・システムライブラリの違いで「自分の環境では動く」が起きます。コンテナはアプリと環境を丸ごと1つのイメージに封入し、この差を消します。
2. 1イメージにまとめる3点
flowchart TB
subgraph コンテナイメージ
A["モデルアーティファクト(変換器+モデル)"]
B["依存の固定(ロックファイル)"]
C["サービングコード(FastAPI等)"]
end
R["モデルレジストリ"] -.->|"Production版を焼き込み or 起動時取得"| A
コンテナイメージ -->|"タグ付けして"| REG["イメージレジストリ"]
REG --> K["どの環境でも同じに起動"]
| 要素 | 何を固めるか |
|---|---|
| モデルアーティファクト | 学習済み Pipeline(前処理込み)。スキュー防止 |
| 依存 | バージョンを完全固定(推移的依存も) |
| サービングコード | API・ヘルスチェック・入力検証 |
3. 動く最小例:サービングを固める Dockerfile
オンライン推論サービングの serve.py をコンテナ化する最小 Dockerfile です。
# slim ベースで軽量に。バージョンを固定して再現性を確保
FROM python:3.11-slim
WORKDIR /app
# 依存を先にコピーしてレイヤキャッシュを効かせる
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# サービングコードとモデルアーティファクトを焼き込む
COPY serve.py model.joblib model_meta.json ./
# ヘルスチェック(オーケストレータが生死を判定)
HEALTHCHECK --interval=30s --timeout=3s \
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"
EXPOSE 8000
CMD ["uvicorn", "serve:app", "--host", "0.0.0.0", "--port", "8000"]
依存は推移的依存まで固定したロックを使います:
# requirements.txt(バージョンを固定する)
fastapi==0.136.3
uvicorn==0.30.0
scikit-learn==1.5.0
joblib==1.4.0
numpy==2.0.0
ビルドとタグ付け、起動:
# モデル版に対応するタグでビルド(例:churn モデルの v3)
docker build -t churn-serving:v3 .
# 起動して疎通確認
docker run -d -p 8000:8000 --name churn churn-serving:v3
curl localhost:8000/health
この構成の意味:python:3.11-slim で OS と Python を固定し、ロックした依存をインストールし、serve.py とモデルを焼き込む——これでイメージ churn-serving:v3 はどのマシンでも同一に起動します。タグ v3 をモデルレジストリの版(モデルレジストリとモデルのライフサイクル)と対応づければ、「どのモデルがどのイメージで本番にいるか」が一意に追えます。HEALTHCHECK でオーケストレータが生死を判定し、ロールバックは「前のタグに戻す」だけです。
4. 運用の勘所
- イメージタグとモデル版を対応づける:
serving:v3↔ レジストリのmodel:v3。トレーサビリティの要。 - slim/distroless で軽量化:イメージが小さいほど配布・起動が速く、攻撃面も減る。不要なビルドツールは最終段に残さない(マルチステージビルド)。
- モデルを焼き込むか起動時取得かを選ぶ:イミュータブルにするなら焼き込み、頻繁に差し替えるなら起動時にレジストリから取得。
- 依存を完全固定する:ロックファイルで推移的依存まで固める。
pip installの pin なしは再現性を壊す。 - 汎用の k8s 運用はクラウドへ:オートスケール・ロールアウト・サービスメッシュ等はクラウド・インフラ/SRE・DevOps 全体目次の領域。
なぜそうするのか
コンテナ化する本質的な理由は、**成果物を「環境ごと不変にする」**ことです。モデルは環境の関数なので、環境が変われば挙動が変わりえます。イメージに環境を封入してタグで固定すれば、開発・検証・本番で同一物が動き、「どこかで動かない」「いつの間にか挙動が変わった」を構造的に防げます。タグでの版管理は、障害時に「前のイメージに戻す」だけで即ロールバックできる安全性も生みます。
⚠️ よくある落とし穴
- 依存を pin せずビルドする:ビルド時期で中身が変わり再現不能。ロックファイルで固定する。
latestタグで運用する:どの版が本番か分からなくなり、ロールバックもできない。意味のあるタグを付ける。- 巨大イメージを作る:不要なビルドツール・キャッシュを残すと肥大化。slim・マルチステージで削る。
- モデルと変換器を別管理にする:前処理が欠けてスキュー。Pipeline ごと焼き込む。
- 汎用インフラの責務を抱え込む:k8s・ネットワーク・スケールはクラウド分野。ここはMLの封入に集中する。
対応 lab
- なし(概念ノート)。コンテナ化対象のサービングは オンライン推論サービング の
labs/04_serving。Dockerfile は本文 §3 の構成をそのまま適用できます。
関連ノート
- オンライン推論サービング(固める対象のAPI)
- 再現性とバージョニング(環境固定の位置づけ)
- モデルレジストリとモデルのライフサイクル(イメージ版とモデル版の対応)
- 学習推論スキューの防止(変換器同梱)
- クラウド・インフラ/SRE・DevOps 全体目次(汎用コンテナ基盤)
- 第4章 デプロイとサービング 目次
- MLOps・AI基盤 全体目次