From 7d8af7882adcc27640b627c42526ff1cbc9fbb14 Mon Sep 17 00:00:00 2001 From: Victor Kuznetsov Date: Mon, 8 Jun 2026 20:54:41 -0700 Subject: [PATCH] tune(instantid): raise IP-Adapter + landmark scale + strength for stronger identity First img2img cert sweep: scene/lighting integration was excellent on both single (tatsunari) and group (gemini_3) photos, but the regenerated faces were "recognizable similar people" rather than the original individuals. The cleaned face crop (which has already drifted from original through the main controlnet 0.20 removal pass) was competing as a structural prior; at the previous parameter settings InstantID's ArcFace branch couldn't dominate it. Push the identity signal: - `ip_adapter_scale`: 0.8 -> 1.0 at load time (full IP-Adapter strength) - `controlnet_conditioning_scale`: 0.8 -> 1.0 default (landmark anchor) - `img2img_strength`: 0.55 -> 0.7 default (more denoise, less cleaned structure survives, more room for the diffusion to render ArcFace) The cleaned image already passed the SynthID oracle, so the absolute floor on strength is "any positive value" -- raising it only increases the freedom of the diffusion to inject identity (SynthID-safety isn't reduced by higher strength, because the noise injection only destroys more of the input pixels). Co-Authored-By: Claude Opus 4.8 (1M context) --- src/remove_ai_watermarks/instantid_restore.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/remove_ai_watermarks/instantid_restore.py b/src/remove_ai_watermarks/instantid_restore.py index eea5eed..1a38292 100644 --- a/src/remove_ai_watermarks/instantid_restore.py +++ b/src/remove_ai_watermarks/instantid_restore.py @@ -287,9 +287,12 @@ def _get_pipeline() -> Any: pipe.to(device) # IP-Adapter weights that wire the ArcFace embedding into cross-attention. ip_adapter_path = hf_hub_download(repo_id=_INSTANTID_REPO, filename=_INSTANTID_IP_ADAPTER) - # IP-Adapter scale (the weight on the ArcFace cross-attention branch) is - # set at load time, not at call time. 0.8 mirrors the upstream demo. - pipe.load_ip_adapter_instantid(ip_adapter_path, scale=0.8) + # IP-Adapter scale = weight on the ArcFace cross-attention. The upstream + # demo uses 0.8 for txt2img; for img2img-on-cleaned we push to 1.0 because + # the cleaned face crop is competing as identity prior and we want ArcFace + # to dominate (otherwise the regenerated face inherits the controlnet- + # drifted cleaned face, not the original identity). + pipe.load_ip_adapter_instantid(ip_adapter_path, scale=1.0) # Diffusers 0.38 vs InstantID upstream compat patch: InstantID's __call__ # calls ``self.check_inputs(...)`` POSITIONALLY (signature from ~v0.29), # but diffusers 0.38 added two new params (``ip_adapter_image``, @@ -365,8 +368,8 @@ def restore_faces_instantid( cleaned_bgr: NDArray[Any], num_inference_steps: int = 30, guidance_scale: float = 5.0, - controlnet_conditioning_scale: float = 0.8, - img2img_strength: float = 0.55, + controlnet_conditioning_scale: float = 1.0, + img2img_strength: float = 0.7, seed: int | None = None, detect_faces_fn: Any | None = None, ) -> NDArray[Any]: