diff --git a/backend/args.py b/backend/args.py
index 5057795e..7c8da50a 100644
--- a/backend/args.py
+++ b/backend/args.py
@@ -168,7 +168,7 @@ class dynamic_args(metaclass=_DynamicArgsMeta):
"""Reference Latent(s) for Flux Kontext / Qwen-Image-Edit / Flux.2 Klein"""
concat_latent: "torch.Tensor" = None
"""Input Latent for Wan 2.2 I2V"""
- lq_latent: tuple["torch.Tensor", "torch.Tensor"] = None
+ lq_latent: list["torch.Tensor", "torch.Tensor"] = [None, None]
"""lq_latent & degrade_sigma for PiD"""
is_referencing: bool = False
"""Appending Reference Latent(s) (by. ImageStitch)"""
diff --git a/backend/diffusion_engine/pid.py b/backend/diffusion_engine/pid.py
index 784197f2..be7cc5ab 100644
--- a/backend/diffusion_engine/pid.py
+++ b/backend/diffusion_engine/pid.py
@@ -51,8 +51,6 @@ class PiD(ForgeDiffusionEngine):
self.use_shift = True
- self.degrade_sigma: float = None
-
@torch.inference_mode()
def get_learned_conditioning(self, prompt: list[str]):
memory_management.load_model_gpu(self.forge_objects.clip.patcher)
@@ -65,15 +63,12 @@ class PiD(ForgeDiffusionEngine):
@torch.inference_mode()
def encode_first_stage(self, x):
- if not dynamic_args.is_referencing:
- raise SystemError("PiD only supports txt2img")
-
sample = self.forge_objects.vae.encode(x.movedim(1, -1) * 0.5 + 0.5)
sample = self.forge_objects.vae.first_stage_model.process_in(sample)
sample = sample.squeeze(2)
+ dynamic_args.lq_latent[0] = sample.detach().clone()
- dynamic_args.lq_latent = (sample, torch.tensor([float(self.degrade_sigma)], dtype=torch.float32))
- return None
+ return sample
@torch.inference_mode()
def decode_first_stage(self, x):
diff --git a/backend/nn/pixeldit/pid.py b/backend/nn/pixeldit/pid.py
index c9321b68..61cd3693 100644
--- a/backend/nn/pixeldit/pid.py
+++ b/backend/nn/pixeldit/pid.py
@@ -191,7 +191,7 @@ class PidNet(PixDiT_T2I):
Hs = -(-x.shape[2] // self.patch_size)
Ws = -(-x.shape[3] // self.patch_size)
- degrade_sigma = degrade_sigma.to(device=x.device, dtype=torch.float32).reshape(-1)
+ degrade_sigma = degrade_sigma.to(device=x.device).reshape(-1)
if degrade_sigma.numel() == 1 and B > 1:
degrade_sigma = degrade_sigma.expand(B).contiguous()
diff --git a/extensions-builtin/sd_forge_image_stitch/scripts/image_stitch.py b/extensions-builtin/sd_forge_image_stitch/scripts/image_stitch.py
index 3fd7f023..5f50b122 100644
--- a/extensions-builtin/sd_forge_image_stitch/scripts/image_stitch.py
+++ b/extensions-builtin/sd_forge_image_stitch/scripts/image_stitch.py
@@ -6,11 +6,7 @@ from PIL import Image
from backend.args import dynamic_args
from modules import images, scripts, sd_models
from modules.api import api
-from modules.processing import (
- StableDiffusionProcessing,
- StableDiffusionProcessingTxt2Img,
- logger,
-)
+from modules.processing import StableDiffusionProcessing, StableDiffusionProcessingTxt2Img, logger
from modules.sd_samplers_common import images_tensor_to_samples
from modules.shared import device, opts
from modules.ui_components import FormRow, InputAccordion
@@ -18,7 +14,6 @@ from modules.ui_components import FormRow, InputAccordion
t2i_info = """
For Flux.1-Kontext / Flux.2-Klein / Qwen-Image-Edit: Use in txt2img to achieve the effect of empty latent with custom resolution
For Wan 2.2 I2V: Use in txt2img to set as the Last Frame to achieve LastFrameToVideo
-For PiD: Use in txt2img to set as the lq_latent
Note: This doesn't actually stitch the images ; Tip: Use the "Image to Upload" to paste images
"""
@@ -97,15 +92,6 @@ class ImageStitch(scripts.Script):
info="reduce VRAM usage during encoding ; apply to all reference images ; set to 0 for no limit",
)
- degrade_sigma = gr.Slider(
- minimum=0.0,
- maximum=1.0,
- value=0.0,
- step=0.05,
- label="Degrade Sigma",
- info="denoising strength ; for PiD only",
- )
-
def _upload(gallery: list[tuple[Image.Image, str]], image: Image.Image):
if not image:
return [gr.skip(), gr.skip()]
@@ -158,7 +144,7 @@ class ImageStitch(scripts.Script):
show_progress=False,
)
- return [enable, references, max_dim, degrade_sigma]
+ return [enable, references, max_dim]
@staticmethod
def reset_references(p: StableDiffusionProcessing):
@@ -166,8 +152,8 @@ class ImageStitch(scripts.Script):
p.clear_prompt_cache()
p.sd_model.clear_references()
- def process(self, p: StableDiffusionProcessing, enable: bool, references: list[str | tuple[Image.Image, str]], max_dim: int, degrade_sigma: float):
- if not (enable and references and any(getattr(dynamic_args, key) for key in ("kontext", "edit", "klein", "wan", "pid"))):
+ def process(self, p: StableDiffusionProcessing, enable: bool, references: list[str | tuple[Image.Image, str]], max_dim: int):
+ if not (enable and references and any(getattr(dynamic_args, key) for key in ("kontext", "edit", "klein", "wan"))):
if ImageStitch.cached_parameters is None:
return
@@ -198,16 +184,6 @@ class ImageStitch(scripts.Script):
logger.warning("Wan 2.2 only uses the first reference image...")
references = [references[0]]
- if dynamic_args.pid:
- if not isinstance(p, StableDiffusionProcessingTxt2Img):
- logger.error("PiD only supports txt2img...")
- return
- if len(references) > 1:
- logger.warning("PiD only uses the first reference image...")
- references = [references[0]]
-
- p.sd_model.degrade_sigma = degrade_sigma
-
dynamic_args.is_referencing = True
for reference in references:
diff --git a/modules/processing.py b/modules/processing.py
index 5316bae3..40c5937b 100644
--- a/modules/processing.py
+++ b/modules/processing.py
@@ -1691,6 +1691,12 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
if (args.dynamic_args.kontext or args.dynamic_args.edit) and self.denoising_strength < 0.9:
logger.warning("Edit Models require High Denoising Strength")
+ if args.dynamic_args.pid:
+ args.dynamic_args.lq_latent[1] = torch.tensor([self.denoising_strength], dtype=torch.float32)
+ self.denoising_strength = 1.0
+ self.resize_mode = 3 # skip resize image
+ assert self.image_mask is None
+
self.image_cfg_scale: float = None
self.sampler = sd_samplers.create_sampler(self.sampler_name, self.sd_model)
@@ -1868,6 +1874,9 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
if shared.sd_model.is_wan and args.dynamic_args.wan: # enforce batch_size of 1
x = x[0].unsqueeze(0)
+ if args.dynamic_args.pid:
+ self.init_latent = x.detach().clone()
+
if self.initial_noise_multiplier != 1.0:
self.extra_generation_params["Noise multiplier"] = self.initial_noise_multiplier
x *= self.initial_noise_multiplier