diff options
| author | tanaka takashi <isazaka@gmail.com> | 2026-09-12 23:36:33 +0900 |
|---|---|---|
| committer | tanaka takashi <isazaka@gmail.com> | 2026-09-12 23:36:33 +0900 |
| commit | de44625e3baae4d43ad096248b7096578b11e0b0 (patch) | |
| tree | c0c0b1756fb71f6c3f8958c3b13f86756e61390d /src/mcp_sd15/config.py | |
| parent | 49d672ef4f605fddddc4040b650aed76cbf27b2a (diff) | |
sd_embed導入による長文プロンプト・重み付きプロンプト対応v0.1.0
SD1.5の77 token制限を回避するため、sd_embedを用いたprompt_embedsベースの
入力方式に変更した。あわせてclip_skipとpad_last_blockの設定を追加した。
sd_embedのget_weighted_text_embeddings_sd15()でpositive/negativeの
プロンプト埋め込みを同時生成し、pipeline呼び出し時にprompt_embeds/
negative_prompt_embedsを渡す。prompt/negative_promptは同時に渡さない。
LoRAロード後にembedding生成を行うため、text encoder LoRAが反映された
状態で埋め込みが作られる。
sd_embedはcommit hash 4a47f71150で固定し、VCS dependencyとして追加。
hatchlingのallow-direct-referencesを有効化。
変更内容:
- pyproject.toml: sd-embed @ git+...@4a47f71150追加、
allow-direct-references=true
- config.py: GenerationConfigにclip_skip=0, pad_last_block=False追加、
load_configで[generation]のclip_skip/pad_last_block読込・validation
(clip_skip: 0-12のinteger, pad_last_block: boolean)
- model_manager.py: 3つのpipeline呼び出しをprompt/negative_promptから
prompt_embeds/negative_prompt_embedsに変更、_embed_prompts()メソッド追加
- tests/test_config.py: clip_skip/pad_last_blockの正常系・異常系テスト追加
- doc/config.md: [generation]セクションにclip_skip/pad_last_block説明追記、
設定項目一覧表更新
- config.example.toml: clip_skip/pad_last_blockコメント例追記
- doc/Design.md: GenerationConfigにclip_skip/pad_last_block追記
- README.md: sd_embedの説明追記
- uv.lock: sd_embedおよび依存パッケージ追加
検証:
- ruff format/check、pyright 0 errors、pytest 67 passed
- 実GPU・実モデルで確認:
- 短いプロンプト: 生成成功
- 77 token超の長文プロンプト(122 token): 生成成功
- 重み付きプロンプト(word:1.5)((word)): 生成成功
- LoRA(pixelartV3) + sd_embed + 重み付き: 生成成功
- negative promptの重み付き埋め込み: 生成成功
Diffstat (limited to 'src/mcp_sd15/config.py')
| -rw-r--r-- | src/mcp_sd15/config.py | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/src/mcp_sd15/config.py b/src/mcp_sd15/config.py index e41bdfd..39f31c9 100644 --- a/src/mcp_sd15/config.py +++ b/src/mcp_sd15/config.py @@ -44,6 +44,8 @@ class GenerationConfig: cfg_scale: float = 7.0 scheduler: str = "dpmpp_2m_karras" default_size: str = "square_512" + clip_skip: int = 0 + pad_last_block: bool = False @dataclass(frozen=True) @@ -218,6 +220,14 @@ def load_config(path: str | Path, *, validate_paths: bool = True) -> AppConfig: default_size = _string(generation_raw, "default_size") or "square_512" if default_size not in VALID_SIZES: raise ConfigError(f"unsupported default_size: {default_size}") + clip_skip_value = generation_raw.get("clip_skip", 0) + if ( + isinstance(clip_skip_value, bool) + or not isinstance(clip_skip_value, int) + or not 0 <= clip_skip_value <= 12 + ): + raise ConfigError("generation.clip_skip must be an integer between 0 and 12") + pad_last_block = _bool(generation_raw, "pad_last_block", False) control_raw = _table(raw, "controlnet") controlnet = ControlNetConfig( @@ -258,7 +268,9 @@ def load_config(path: str | Path, *, validate_paths: bool = True) -> AppConfig: config = AppConfig( model=ModelConfig(root, checkpoint, vae, tuple(loras)), - generation=GenerationConfig(steps_value, cfg_scale, scheduler, default_size), + generation=GenerationConfig( + steps_value, cfg_scale, scheduler, default_size, clip_skip_value, pad_last_block + ), controlnet=controlnet, output=OutputConfig(output_dir.resolve(), _bool(output_raw, "enabled", False)), server=ServerConfig(transport, host, port_value), |
