fix(photomaker): pass pm_version='v1' to load_photomaker_adapter

Modal cert sweep #3 ran past the `insightface` import error and into a real
state_dict mismatch:

  Error(s) in loading state_dict for PhotoMakerIDEncoder_CLIPInsightfaceExtendtoken:
    Missing key(s) ... qformer_perceiver.token_proj.0.weight ...

The upstream `load_photomaker_adapter` defaults to `pm_version='v2'` regardless of
the .bin file passed -- the loader builds a V2 encoder
(PhotoMakerIDEncoder_CLIPInsightfaceExtendtoken) and then tries to load V1 weights
into it. We must pass `pm_version='v1'` explicitly so the loader instantiates the
CLIP-only PhotoMakerIDEncoder. The pipeline-level `input_id_images` API is the
same across V1 and V2, so the call site does not change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Victor Kuznetsov
2026-06-08 16:18:52 -07:00
parent 860bde4a26
commit 1fb2a64b56
@@ -151,11 +151,17 @@ def _get_pipeline() -> Any:
)
adapter_path = hf_hub_download(repo_id=_PHOTOMAKER_REPO, filename=_PHOTOMAKER_FILE)
pipe = PhotoMakerStableDiffusionXLPipeline.from_pretrained(_SDXL_MODEL_ID, torch_dtype=dtype)
# ``pm_version="v1"`` is REQUIRED: the upstream loader defaults to v2 and would
# build the V2 encoder (PhotoMakerIDEncoder_CLIPInsightfaceExtendtoken), then
# error on load_state_dict because the v1 weights have a different shape.
# Passing v1 builds the CLIP-only PhotoMakerIDEncoder, which is the
# commercial-safe path we want.
pipe.load_photomaker_adapter(
str(Path(adapter_path).parent),
subfolder="",
weight_name=_PHOTOMAKER_FILE,
trigger_word="img",
pm_version="v1",
)
pipe.to(device)
pipe.fuse_lora()