diff options
Diffstat (limited to 'doc/Design.md')
| -rw-r--r-- | doc/Design.md | 418 |
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境界を維持したまま拡張する。 |
