本番デプロイ運用ガイド
クラファン後の量産・運用フェーズ向け 3 デプロイ先別の本番セットアップ・モデル切替・ロールバック手順書
作成日: 2026-05-14
対象 Phase: クラファン後 量産・運用
対象オペレータ: SRE / 現地設置担当 / 開発者
関連: design.html, ai-brushup-plans/09-edge-inference.md
← INDEX
設計ボトルネック
監視・スケーリング
0. 3 デプロイ先の役割分担
Mahjong Vision は以下の 3 つのデプロイ先を用途別に使い分け る前提で本番運用する。
1 つに集約せず併用することで、レイテンシ・コスト・オフライン性のトレードオフを最適化する。
A
Cloudflare Workers AI CLOUD
用途: クラファンリターン Web 視聴者向け軽量推論 / モバイル UA からの単発推論
レイテンシ: 100〜300 ms (P95) /
コスト: $0.011 / 1,000 ニューロン (≈ $0.05〜0.20 / 1,000 推論) /
モデル: ONNX FP16 (BYOM)
B
Jetson Orin Nano (エッジ) EDGE
用途: クラファンリターン本体 (卓上 BOX) / オフライン店舗 / プライバシ要件があるカスタマー
レイテンシ: 25〜33 ms (30〜40 FPS @ 1280×720, INT8) /
コスト: 初期 ¥75,000 / 電気代 ¥250〜400/月 /
モデル: TensorRT INT8
C
RTX4090 (ローカル GPU) DEV
用途: バッチ評価・大量動画再エンコード・新モデル検証・mAP 評価
レイテンシ: 7〜10 ms / 100+ FPS (FP16, batch=8) /
コスト: 初期 ¥350,000 / 電気代 (推論時 ≈ 350W) /
モデル: PyTorch FP16 / .pt
0.1 推論パスの選択基準
| シナリオ | 推奨デプロイ先 | 理由 |
| クラファン Web デモ (静止画 1 枚 アップロード) | A. Workers AI | 初回ユーザの試行・ピーク同時 100req まで自動スケール |
| 卓上 BOX (4 名対局・リアルタイム表示) | B. Jetson Orin Nano | 30 FPS 連続推論・通信断耐性 |
| M-League ダイジェスト 60 分動画の一括解析 | C. RTX4090 | バッチ FP16 で 1 動画 ≤ 1 分 |
| 新モデル mAP 評価 (val 500 枚) | C. RTX4090 | 確定的環境・再現性最優先 |
| スマホアプリの単発推論 | A. Workers AI | クライアント実装不要・課金は使った分のみ |
3 環境とも同じ ONNX を起点 にすることで、モデル更新を 1 回の Roboflow export で 3 か所に展開できる。
scripts/build/roboflow-export.py で .onnx を出力 → 各環境向けに .engine / .workers.ai パッケージへ変換するパイプラインを既定とする。
A. Cloudflare Workers AI (クラウド推論)
A-1. 必要ハード / アカウント
| 項目 | 仕様 |
| Cloudflare アカウント | Workers Paid プラン ($5/month) — Workers AI のニューロン課金は使った分のみ |
| Wrangler CLI | v3.80 以降 |
| モデルサイズ上限 | BYOM での ONNX 上限 100 MB (2026-05 時点の公開仕様) |
| 対応モデル形式 | ONNX (opset 17 以上)・YOLOv8n / YOLOv8s に最適 |
A-2. Roboflow → ONNX export
Roboflow Workspace から学習済みモデルを ONNX で取得し、Cloudflare 互換に整形する。
# PowerShell (Windows / Python 3.14)
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install roboflow ultralytics onnx onnxruntime onnxsim
# API キーは .env.local から読み込み (会話/ログに直接貼らない)
# Get-Content .env.local | Where-Object { $_ -match '^ROBOFLOW_API_KEY=' } 等で参照
python scripts/build/roboflow-export.py `
--workspace mahjong-vision `
--project mleague-tiles-v2 `
--version 7 `
--format onnx `
--imgsz 640 `
--opset 17 `
--simplify `
--output models/mleague-tiles-v2-7.onnx
# bash (Linux / macOS dev box)
python3 -m venv .venv && source .venv/bin/activate
pip install roboflow ultralytics onnx onnxruntime onnxsim
python scripts/build/roboflow-export.py \
--workspace mahjong-vision \
--project mleague-tiles-v2 \
--version 7 \
--format onnx \
--imgsz 640 \
--opset 17 \
--simplify \
--output models/mleague-tiles-v2-7.onnx
A-3. Workers AI BYOM デプロイ
npx wrangler login # 初回のみ
# モデルアップロード (BYOM)
npx wrangler ai models put mleague-tiles-v2-7 `
--file models/mleague-tiles-v2-7.onnx `
--task object-detection
# Workers にバインド (wrangler.toml)
# [ai]
# binding = "AI"
# [[ai.models]]
# binding = "TILES_MODEL"
# name = "mleague-tiles-v2-7"
npm run build
npx wrangler deploy
A-4. 推論料金見積
2026-05 時点の Workers AI 料金 (ニューロン課金) を元にした参考見積:
| シナリオ | 1 推論あたり想定ニューロン | 1,000 リクエスト | 10,000 リクエスト |
| YOLOv8n / 640×640 / FP16 | ≈ 5,000 | ≈ $0.05 | ≈ $0.55 |
| YOLOv8s / 640×640 / FP16 | ≈ 10,000 | ≈ $0.11 | ≈ $1.10 |
| YOLOv8m / 1280×720 / FP16 | ≈ 18,000 | ≈ $0.20 | ≈ $2.00 |
注: ニューロン換算はモデル依存。確定値は Cloudflare ダッシュボード「Workers AI Analytics」で実測すること。
クラファン公開ピーク時 (同時 100 ユーザ × 5 推論/分 = 500/min) は 1 時間あたり最大 $0.55 想定。
A-5. レイテンシ実測の指針
- P50: 100〜150 ms (東京リージョン edge から JP ユーザ)
- P95: 200〜300 ms
- P99: 400〜600 ms (cold start を含む)
- cold start 後 60 秒は再利用可。連続アクセス時は P50 が 80 ms まで下がる
A-6. ロールバック手順
# 1. 旧バージョンに即時切替 (モデルバインディングを過去 ID に戻す)
npx wrangler ai models list # 既存モデル一覧
# wrangler.toml の TILES_MODEL を v6 に戻し再 deploy
git checkout HEAD~1 -- wrangler.toml
npx wrangler deploy
# 2. それでも問題ある場合は Worker 自体を 1 世代前にロールバック
npx wrangler rollback # 直前 deploy にリバート
B. Jetson Orin Nano (エッジ推論)
B-1. 必要ハード仕様
| 品目 | 型番 / 仕様 | 参考価格 |
| Jetson Orin Nano Developer Kit 8GB | NVIDIA 公式 / 40 TOPS (INT8) | ¥75,000 |
| microSD カード | SanDisk Extreme Pro 128GB U3 V30 以上 | ¥3,500 |
| USB Webcam | Logicool C922n または Arducam IMX179 USB3 (1280×720@60fps 対応) | ¥9,800 |
| LED 照明 | 面光源 5,000K / Ra90 以上 / 30W 相当 × 2 | ¥6,800 |
| 専用ファン | Noctua NF-A4x20 PWM + アルミヒートシンク | ¥2,400 |
| UPS (推奨) | APC BE425M-JP 等 / 連続稼働 5 分以上 | ¥7,800 |
| 合計 (BOX 1 台あたり) | | ¥105,300 |
B-2. JetPack 6 セットアップ
# Jetson 側 (Ubuntu 22.04 / JetPack 6)
sudo apt update && sudo apt install -y python3.10-venv git docker.io
sudo usermod -aG docker $USER
newgrp docker
# NVIDIA Container Toolkit (Docker GPU access)
distribution=$(. /etc/os-release; echo $ID$VERSION_ID)
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
| sudo gpg --dearmor -o /etc/apt/keyrings/nvidia-container-toolkit.gpg
curl -fsSL https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list \
| sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt update && sudo apt install -y nvidia-container-toolkit
sudo systemctl restart docker
# 動作確認
docker run --rm --runtime nvidia nvcr.io/nvidia/l4t-base:r36.2.0 nvidia-smi
B-3. TensorRT INT8 量子化
RTX4090 で学習・ONNX export した .onnx を Jetson 側で TensorRT エンジン化する (クロスコンパイル不可なので必ず実機上)。
# Jetson 上で実行
git clone https://github.com/<org>/mahjong-scorekeeping.git
cd mahjong-scorekeeping
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements-jetson.txt
# INT8 キャリブ用に学習データから 1000 枚抽出 (Roboflow から落として配置)
ls calib-data/ | wc -l # 1000 枚あるか確認
# ONNX → TensorRT INT8
python scripts/build/build-trt-engine.py \
--onnx models/mleague-tiles-v2-7.onnx \
--output models/mleague-tiles-v2-7.int8.engine \
--precision int8 \
--calib-dir calib-data/ \
--workspace 4096 \
--imgsz 640
B-4. 推論速度 (実測ベース見積)
| モデル / 精度 | 解像度 | レイテンシ (1 frame) | スループット | mAP@50 (vs FP32) |
| YOLOv8n FP16 | 640×640 | 12 ms | 83 FPS | −0.5% |
| YOLOv8s INT8 | 640×640 | 15 ms | 66 FPS | −1.5% |
| YOLOv8m INT8 | 640×640 | 25 ms | 40 FPS | −2.0% |
| YOLOv8m INT8 | 1280×720 | 33 ms | 30 FPS | −2.0% |
B-5. systemd 常駐化
# /etc/systemd/system/mahjong-edge.service
[Unit]
Description=Mahjong Vision edge inference
After=network.target
[Service]
Type=simple
User=mjvision
WorkingDirectory=/home/mjvision/mahjong-scorekeeping
ExecStart=/home/mjvision/mahjong-scorekeeping/.venv/bin/python \
-m src.orchestrator.edge \
--engine models/mleague-tiles-v2-7.int8.engine \
--camera 0 --imgsz 1280
Restart=on-failure
RestartSec=5
StandardOutput=append:/var/log/mahjong-edge.log
StandardError=append:/var/log/mahjong-edge.err.log
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now mahjong-edge.service
sudo systemctl status mahjong-edge.service
B-6. ロールバック手順
# models/ 配下に v6 (前バージョン) を常に残しておく運用
ls -lh models/
# mleague-tiles-v2-6.int8.engine
# mleague-tiles-v2-7.int8.engine ← 不調
# systemd の引数を v6 に戻して再起動
sudo sed -i 's/v2-7\.int8\.engine/v2-6.int8.engine/' /etc/systemd/system/mahjong-edge.service
sudo systemctl daemon-reload
sudo systemctl restart mahjong-edge.service
所要時間: 約 30 秒。systemd の Restart=on-failure により異常終了でも 5 秒で復帰する。
C. RTX4090 (ローカル GPU / 開発環境)
C-1. 必要ハード仕様
| 項目 | 推奨仕様 |
| GPU | NVIDIA GeForce RTX 4090 (24GB VRAM) |
| CPU | Intel Core i9 13th gen 以上 / AMD Ryzen 9 7950X 以上 |
| RAM | 64GB DDR5 推奨 (バッチ評価で 32GB だと swap 発生) |
| ストレージ | NVMe SSD 2TB (動画素材 + チェックポイント) |
| 電源 | 1000W 80+ Platinum 以上 |
| OS | Windows 11 + WSL2 Ubuntu 22.04 / または 純 Linux |
C-2. CUDA + PyTorch セットアップ (Windows)
# Windows 11 PowerShell
# 1. NVIDIA Driver 最新版を Windows 側にインストール (CUDA は WSL 経由で十分)
# https://www.nvidia.com/Download/index.aspx → RTX 4090
# 2. WSL2 + Ubuntu 22.04
wsl --install -d Ubuntu-22.04
# 3. WSL 内に入る
wsl
# WSL Ubuntu 内
sudo apt update && sudo apt install -y python3.14 python3.14-venv git
python3.14 -m venv .venv && source .venv/bin/activate
# PyTorch (CUDA 12.4 対応版)
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124
pip install ultralytics onnx onnxruntime-gpu
# GPU 認識確認
python -c "import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))"
# True NVIDIA GeForce RTX 4090
C-3. CUDA セットアップ (Linux 直)
wget https://developer.download.nvidia.com/compute/cuda/12.4.1/local_installers/cuda_12.4.1_550.54.15_linux.run
sudo sh cuda_12.4.1_550.54.15_linux.run
# /etc/profile.d/cuda.sh に PATH 追加
echo 'export PATH=/usr/local/cuda-12.4/bin:$PATH' | sudo tee /etc/profile.d/cuda.sh
echo 'export LD_LIBRARY_PATH=/usr/local/cuda-12.4/lib64:$LD_LIBRARY_PATH' | sudo tee -a /etc/profile.d/cuda.sh
C-4. 推論速度 (実測ベース見積)
| モデル / 精度 | バッチサイズ | 解像度 | レイテンシ | スループット |
| YOLOv8m FP32 .pt | 1 | 640×640 | 8 ms | 125 FPS |
| YOLOv8m FP16 | 1 | 640×640 | 5 ms | 200 FPS |
| YOLOv8m FP16 | 8 | 640×640 | 22 ms (バッチ) | 360 FPS |
| YOLOv8m FP16 | 16 | 1280×720 | 60 ms (バッチ) | 265 FPS |
C-5. バッチ評価用途
# M-League 60 分動画 1 本 ≈ 108,000 frame
# YOLOv8m FP16 bs=8 で 108,000 / 360 ≈ 5 分で完走
python scripts/evaluate-agari-transition-detector.py \
--video mleague/input/sample01.mp4 \
--model models/mleague-tiles-v2-7.pt \
--device cuda:0 \
--imgsz 1280 --half --batch 8 \
--output mleague/eval/sample01-v2-7.json
C-6. ロールバック手順
RTX4090 環境は 開発 / 評価専用 のため、本番ロールバックの概念は不要。
ただし「v2-7 のチェックポイントで mAP が落ちた」を発見した場合は git checkout + models/v2-6.pt 復元で対応:
git checkout models/mleague-tiles-v2-6.pt # LFS 経由の場合
python scripts/evaluate-agari-transition-detector.py \
--video mleague/input/sample01.mp4 \
--model models/mleague-tiles-v2-6.pt \
--device cuda:0 --half
4. 3 環境共通: モデル切替 / ロールバック
4.1 推論スクリプトの統一 CLI フラグ
全スクリプトで --roboflow-model, --engine, --device を共通に揃える。これにより 1 コマンドで A/B/C を切替可能。
| フラグ | 意味 | 例 |
--roboflow-model | Roboflow Hosted Inference API のモデル ID | mahjong-vision/mleague-tiles-v2/7 |
--engine | ローカル TensorRT engine ファイルパス | models/...int8.engine |
--onnx | ONNX ファイルパス (onnxruntime 推論) | models/...onnx |
--pt | PyTorch .pt ファイル (RTX4090 想定) | models/...pt |
--device | cpu / cuda:0 / jetson / cloudflare | cuda:0 |
--backend | ultralytics / tensorrt / onnxruntime / workers-ai | tensorrt |
4.2 モデル切替の典型コマンド
# A. Cloudflare Workers AI 経由
python scripts/render-3d-overlay-cf.py `
--backend workers-ai --device cloudflare `
--roboflow-model mahjong-vision/mleague-tiles-v2/7 `
--input mleague/input/sample01.mp4
# B. Jetson Orin Nano (TensorRT INT8)
python scripts/render-3d-overlay-cf.py `
--backend tensorrt --device jetson `
--engine models/mleague-tiles-v2-7.int8.engine `
--input /dev/video0
# C. RTX4090 (PyTorch FP16)
python scripts/render-3d-overlay-cf.py `
--backend ultralytics --device cuda:0 `
--pt models/mleague-tiles-v2-7.pt --half `
--input mleague/input/sample01.mp4
4.3 共通ロールバック原則
- モデルは 2 世代並走: v(N) と v(N-1) を常に同じディレクトリ/バケットに残す
- 切替は設定ファイル 1 行: 環境変数
MJ_MODEL_VERSION で v6 / v7 を切替可能にする
- 30 分監視ルール: 新モデル投入後 30 分の P95 レイテンシ・false positive 率を比較し、5% 以上悪化したら自動ロールバック
- 共通契約テスト:
scripts/contract-test-model.py を A/B/C 各環境で実行し、同じテスト画像で bbox 数 / クラス分布が一致することを確認
禁止事項: 3 環境で異なる ONNX を独立に最適化した結果、論理的に違うモデルになるパターン。
必ず Roboflow の 単一バージョン番号 を起点に scripts/build/ 配下で 3 環境向けバリアントを生成すること。
5. 運用チェックリスト
5.1 新モデル本番投入チェックリスト
- [ ] Roboflow で val set 500 枚に対し mAP@50 ≥ 0.80 を確認
- [ ] RTX4090 (C 環境) でフルバッチ評価し前バージョンと差分レポート (
mleague/eval/diff-v6-v7.md)
- [ ] ONNX export & onnxsim で簡約化 (sanity:
onnxruntime.InferenceSession 起動できること)
- [ ] Jetson 実機で TensorRT engine ビルド成功 (約 8〜15 分)
- [ ] Workers AI に BYOM 登録、
wrangler ai run で smoke test
- [ ] 3 環境とも contract-test-model.py PASS
- [ ] 旧バージョン (v-1) を全環境で 削除せず 残置
- [ ] Monitoring ダッシュボード (監視・スケーリング) の閾値を新バージョン基準に更新
5.2 障害時の優先順位
- 影響範囲確認: A/B/C のどこで発生したか
- 5 分以内: ロールバック実行 (B は systemd 再起動、A は
wrangler rollback)
- 30 分以内: 影響顧客への通知 (該当環境のクラファンバッカー / 店舗オペレータ)
- 4 時間以内: 一次原因仮説と再発防止策ドラフト
- 翌営業日: runbook-incident-response.md のテンプレで事後検証
本ドキュメントは クラファン後の量産・運用フェーズ の運用標準として参照する。
モデルバージョンが上がるたびに「4.2 モデル切替の典型コマンド」と「B-4 / C-4 の推論速度表」の数値を実測値で更新すること。