summaryrefslogtreecommitdiff
path: root/doc/Design.md
diff options
context:
space:
mode:
authortanaka takashi <isazaka@gmail.com>2026-09-12 18:04:56 +0900
committertanaka takashi <isazaka@gmail.com>2026-09-12 18:04:56 +0900
commitcba15a62829a0fe57a03c8031f981e8f790e2efc (patch)
tree3bc0ef1a243f356f55c2fa97f63c3bfd5c77e8fc /doc/Design.md
feat: Stable Diffusion 1.x MCPサーバを実装
仕様書・設計書に基づき、ローカルCUDA GPU上のStable Diffusion 1.x互換モデルをMCP経由で利用するサーバを新規実装。 実装内容: - generate_image、generate_guided_image、inpaint_imageの3ツールをMCP SDK v2で公開 - TOMLからcheckpoint、VAE、複数LoRAと重み、ControlNet、生成設定を読み込み - モデル種別ごとの固定ディレクトリ解決と起動時の設定・ファイル存在検証を追加 - Depth/MiDaS、OpenPose body/full、ControlNet Inpaintの前処理とパイプライン切替を実装 - FP16/CUDA、1枚固定生成、ControlNetオンデマンドロード、単一GPU直列実行を実装 - Base64 PNG/JPEG入力の形式・サイズ検証と任意のdata URI入力に対応 - seed、サイズ、モード、時刻、処理時間をPNG metadataへ記録 - 任意のローカルPNG保存、生成エラー分類、CUDA OOM後のキャッシュ回復を追加 - --configと--versionを備えたstdio CLIエントリポイントを追加 開発・運用: - Python 3.11およびuvによる依存・lock管理を構成 - config.example.tomlとセットアップ・運用手順をREADMEへ追加 - Ruff、Pyright、pytestの設定を追加 - 設定、パス解決、schema、画像検証、サービスルーティング、排他制御、MCP画像返却をテスト 検証結果: - pytest: 30 passed - Ruff lint/format: passed - Pyright: 0 errors, 0 warnings - CLI versionおよびMCPクライアント経由のPNG返却を確認 - 実GPU smoke testはCUDA GPUとモデルファイルがないため対象外
Diffstat (limited to 'doc/Design.md')
-rw-r--r--doc/Design.md418
1 files changed, 418 insertions, 0 deletions
diff --git a/doc/Design.md b/doc/Design.md
new file mode 100644
index 0000000..f22c24d
--- /dev/null
+++ b/doc/Design.md
@@ -0,0 +1,418 @@
+# Design.md
+
+## 1. 設計方針
+
+| 方針 | 内容 |
+|---|---|
+| MCP公開面を小さくする | LLMには生成意図に必要な入力だけを公開する |
+| 実行設定はTOMLへ集約 | モデル・VAE・LoRA・ControlNet・生成パラメータを一元管理 |
+| SD1.x互換に限定 | SDXL / FLUX等は対象外 |
+| 依存分離 | MCP層とDiffusion層を直接密結合させない |
+| 単一GPU前提 | 生成処理は1本のキューで直列化 |
+| ControlNetは固定3種 | Depth / Openpose / Inpaintのみ |
+| 過剰な汎用化を避ける | 未使用ControlNetや動的Tool設定は持たない |
+
+---
+
+## 2. 全体アーキテクチャ
+
+```text
+MCP Client / LLM
+ │
+ ▼
+┌──────────────────────┐
+│ MCP Server │
+│ - tool schema │
+│ - request validation │
+└──────────┬───────────┘
+ │
+ ▼
+┌──────────────────────┐
+│ ImageGenerationService│
+│ - request routing │
+│ - queue control │
+└──────────┬───────────┘
+ │
+ ▼
+┌──────────────────────┐
+│ ModelManager │
+│ - checkpoint │
+│ - VAE │
+│ - LoRA │
+│ - ControlNet │
+└──────────┬───────────┘
+ │
+ ▼
+┌──────────────────────┐
+│ Diffusers / PyTorch │
+│ CUDA │
+└──────────────────────┘
+```
+
+---
+
+## 3. モジュール構成
+
+```text
+mcp-sd15/
+├─ pyproject.toml
+├─ uv.lock
+├─ .python-version
+├─ config.example.toml
+├─ src/
+│ └─ mcp_sd15/
+│ ├─ __init__.py
+│ ├─ cli.py
+│ ├─ server.py
+│ ├─ config.py
+│ ├─ schema.py
+│ ├─ service.py
+│ ├─ model_manager.py
+│ ├─ pipeline_factory.py
+│ ├─ preprocessors/
+│ │ ├─ depth.py
+│ │ └─ openpose.py
+│ └─ tools/
+│ ├─ generate_image.py
+│ ├─ generate_guided_image.py
+│ └─ inpaint_image.py
+└─ tests/
+ ├─ test_config.py
+ ├─ test_schema.py
+ ├─ test_model_paths.py
+ └─ test_tools.py
+```
+
+---
+
+## 4. 各モジュールの責務
+
+| モジュール | 責務 |
+|---|---|
+| `cli.py` | `--config`, `--version`の処理 |
+| `server.py` | MCP server起動、Tool登録 |
+| `config.py` | TOML読込、型変換、validation |
+| `schema.py` | MCP入力値・内部request型 |
+| `service.py` | Tool要求を生成処理へ振り分け |
+| `model_manager.py` | checkpoint / VAE / LoRA / ControlNetの管理 |
+| `pipeline_factory.py` | Diffusers pipeline構築 |
+| `preprocessors/depth.py` | Midas前処理 |
+| `preprocessors/openpose.py` | Openpose / Openpose Full前処理 |
+| `tools/*` | MCP Toolからserviceへの薄いadapter |
+
+---
+
+## 5. 起動フロー
+
+| Step | 処理 |
+|---|---|
+| 1 | CLI引数を解析 |
+| 2 | TOMLを読込 |
+| 3 | 設定値をvalidation |
+| 4 | モデルパスを解決 |
+| 5 | checkpoint存在確認 |
+| 6 | VAE / LoRA / ControlNet存在確認 |
+| 7 | Base SD1.x pipelineを構築 |
+| 8 | VAEを適用 |
+| 9 | LoRAを順次ロード |
+| 10 | GPUへ配置 |
+| 11 | MCP Toolを公開 |
+| 12 | リクエスト待受開始 |
+
+モデル構成の初期化に失敗した場合はToolを公開せず、プロセスを異常終了する。
+
+---
+
+## 6. 設定オブジェクト
+
+推奨内部型:
+
+```python
+@dataclass(frozen=True)
+class LoRAConfig:
+ file: str
+ weight: float = 1.0
+
+@dataclass(frozen=True)
+class ModelConfig:
+ root: Path
+ checkpoint: str
+ vae: str | None
+ loras: tuple[LoRAConfig, ...]
+
+@dataclass(frozen=True)
+class GenerationConfig:
+ steps: int
+ cfg_scale: float
+ scheduler: str
+ default_size: str
+```
+
+Pydanticは必須とせず、`tomllib + dataclass + 明示的validation`を基本とする。
+
+---
+
+## 7. モデルパス解決
+
+| 種類 | 解決先 |
+|---|---|
+| checkpoint | `<root>/checkpoints/<file>` |
+| VAE | `<root>/vae/<file>` |
+| LoRA | `<root>/lora/<file>` |
+| ControlNet | `<root>/controlnet/<file>` |
+
+設計上、MCP入力から任意モデルパスを指定することは禁止する。
+
+---
+
+## 8. Diffusers構成
+
+| 機能 | 実装方針 |
+|---|---|
+| Base model | SD1.x互換checkpointをロード |
+| VAE | 設定された場合のみ置換 |
+| LoRA | 複数adapterをロード |
+| LoRA weight | `set_adapters`相当で適用 |
+| LoRA fuse | 将来オプション。初期実装では必須としない |
+| dtype | FP16 |
+| device | CUDA |
+| scheduler | TOMLで指定 |
+| batch | 1 |
+| images per prompt | 1 |
+| CPU offload | 初期値OFF |
+
+---
+
+## 9. ControlNet設計
+
+### 9.1 モード
+
+| MCP mode | ControlNet | Preprocessor |
+|---|---|---|
+| `depth` | Depth 1.1 | Midas |
+| `openpose` | Openpose 1.1 | body |
+| `openpose_full` | Openpose 1.1 | body + hand + face |
+| `inpaint` | Inpaint 1.1 | mask生成規約に従う |
+
+### 9.2 パイプライン
+
+```text
+Depth/Openpose:
+input image
+ │
+ ▼
+preprocessor
+ │
+ ▼
+control image
+ │
+ ▼
+StableDiffusionControlNetPipeline
+ │
+ ▼
+PNG
+```
+
+```text
+Inpaint:
+input image + mask
+ │
+ ▼
+ControlNet Inpaint input
+ │
+ ▼
+Inpaint-compatible pipeline
+ │
+ ▼
+PNG
+```
+
+### 9.3 ロード方針
+
+8GB級GPUを主対象とするため、ControlNetは必要時ロードを基本候補とする。
+
+| 状態 | 動作 |
+|---|---|
+| 未ロード | 必要なControlNetをロード |
+| 同一ControlNet | 再利用 |
+| 別ControlNet要求 | 既存ControlNetを解放後ロード |
+| generation中 | 切替禁止 |
+
+---
+
+## 10. MCP Tool設計
+
+### `generate_image`
+
+```text
+Input:
+- positive_prompt
+- negative_prompt?
+- size?
+
+Output:
+- image/png
+- generation metadata
+```
+
+### `generate_guided_image`
+
+```text
+Input:
+- positive_prompt
+- negative_prompt?
+- control_mode: depth | openpose | openpose_full
+- input_image
+- size?
+
+Output:
+- image/png
+- generation metadata
+```
+
+### `inpaint_image`
+
+```text
+Input:
+- positive_prompt
+- negative_prompt?
+- input_image
+- mask_image
+- size?
+
+Output:
+- image/png
+- generation metadata
+```
+
+Tool層はDiffusers APIを直接呼ばず、必ずService層を経由する。
+
+---
+
+## 11. 生成キュー
+
+```text
+MCP Request
+ │
+ ▼
+asyncio.Semaphore(1)
+ │
+ ▼
+GenerationService
+ │
+ ▼
+GPU
+```
+
+| 項目 | 方針 |
+|---|---|
+| 同時GPU処理 | 1 |
+| キュー | FIFO相当 |
+| OOM防止 | 並列生成禁止 |
+| cancellation | MCP SDKで扱える範囲で対応 |
+| timeout | 設定値として追加可能 |
+
+---
+
+## 12. 出力
+
+| 項目 | 仕様 |
+|---|---|
+| Format | PNG |
+| MCP返却 | ImageContent相当 |
+| ローカル保存 | 設定により有効化可能 |
+| ファイル名 | UUIDまたはgeneration ID |
+| metadata | seed, size, mode, timestamp等 |
+| prompt保存 | ログ方針により設定 |
+
+---
+
+## 13. エラー設計
+
+| エラー分類 | 例 | 処理 |
+|---|---|---|
+| CONFIG_ERROR | TOML不正 | 起動失敗 |
+| MODEL_NOT_FOUND | モデル未配置 | 起動失敗 |
+| MODEL_INCOMPATIBLE | SD1.x非互換 | 起動失敗 |
+| INVALID_REQUEST | 不正size / mode | Tool error |
+| INVALID_IMAGE | 画像形式不正 | Tool error |
+| CUDA_OOM | VRAM不足 | Tool error + GPU状態回復 |
+| GENERATION_FAILED | 推論例外 | Tool error |
+| INTERNAL_ERROR | 想定外例外 | ログ出力 + Tool error |
+
+---
+
+## 14. pyproject / uv方針
+
+### Runtime依存
+
+| Package | 用途 |
+|---|---|
+| `mcp` | MCP server |
+| `torch` | CUDA / Tensor |
+| `diffusers` | SD / ControlNet |
+| `transformers` | CLIP |
+| `peft` | LoRA |
+| `safetensors` | モデル形式 |
+| `pillow` | 画像I/O |
+| `numpy` | 数値処理 |
+| `opencv-python` | 画像前処理 |
+
+### Development依存
+
+| Package | 用途 |
+|---|---|
+| `pytest` | テスト |
+| `ruff` | lint / format |
+| `pyright` | 型チェック |
+
+### 例
+
+```toml
+[project]
+name = "mcp-sd15"
+version = "0.1.0"
+requires-python = ">=3.11,<3.12"
+
+[project.scripts]
+mcp-sd15 = "mcp_sd15.cli:main"
+```
+
+運用は`pyproject.toml + uv.lock`を基準とする。
+
+---
+
+## 15. テスト設計
+
+| テスト種別 | GPU | 内容 |
+|---|---:|---|
+| Config parsing | 不要 | TOML読込・型検証 |
+| Path resolution | 不要 | モデルパス解決 |
+| MCP schema | 不要 | Tool schema検証 |
+| Request validation | 不要 | mode / size / image必須条件 |
+| Service routing | 不要 | 適切なbackend呼出 |
+| Model load smoke | 必要 | checkpoint / VAE / LoRA |
+| Txt2Img smoke | 必要 | 512x512生成 |
+| Depth smoke | 必要 | ControlNet Depth |
+| Openpose smoke | 必要 | Openpose / Full |
+| Inpaint smoke | 必要 | mask付き生成 |
+
+---
+
+## 16. 将来拡張
+
+初期設計では以下を実装対象外とする。
+
+| 項目 | 方針 |
+|---|---|
+| SDXL / FLUX | 対象外 |
+| Multi-ControlNet | 対象外 |
+| MCPからのモデル切替 | 対象外 |
+| 任意width / height | 対象外 |
+| batch > 1 | 対象外 |
+| LoRA動的追加 | 対象外 |
+| Web UI | 対象外 |
+| 学習機能 | 対象外 |
+| 複数GPU | 対象外 |
+
+必要になった場合のみ、既存のService / ModelManager境界を維持したまま拡張する。