diff --git a/modules/processing_args.py b/modules/processing_args.py index 42088f8b9..4ac2781ff 100644 --- a/modules/processing_args.py +++ b/modules/processing_args.py @@ -444,7 +444,7 @@ def set_pipeline_args(p, model, prompts:list, negative_prompts:list, prompts_2:l # handle missing resolution if args.get('image', None) is not None and ('width' not in args or 'height' not in args): if 'width' in possible and 'height' in possible: - vae_scale_factor = sd_vae.get_vae_scale_factor(model) + vae_scale_factor = sd_vae.get_vae_scale_factor(model, init_image=True) if isinstance(args['image'], torch.Tensor) or isinstance(args['image'], np.ndarray): if args['image'].shape[-1] == 3: # nhwc args['width'] = args['image'].shape[-2] diff --git a/modules/processing_class.py b/modules/processing_class.py index 9b05182e8..d55a36147 100644 --- a/modules/processing_class.py +++ b/modules/processing_class.py @@ -738,7 +738,7 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing): def init(self, all_prompts=None, all_seeds=None, all_subseeds=None): if self.init_images is not None and len(self.init_images) > 0: - vae_scale_factor = sd_vae.get_vae_scale_factor() + vae_scale_factor = sd_vae.get_vae_scale_factor(init_image=True) if self.width is None or self.width == 0: self.width = int(vae_scale_factor * (self.init_images[0].width * self.scale_by // vae_scale_factor)) if self.height is None or self.height == 0: diff --git a/modules/processing_helpers.py b/modules/processing_helpers.py index dfaabc65d..64d939074 100644 --- a/modules/processing_helpers.py +++ b/modules/processing_helpers.py @@ -395,7 +395,7 @@ def resize_init_images(p): p.init_images = [p.image] if getattr(p, 'init_images', None) is not None and len(p.init_images) > 0: p.init_images = decode_images(p.init_images) - vae_scale_factor = sd_vae.get_vae_scale_factor() + vae_scale_factor = sd_vae.get_vae_scale_factor(init_image=True) tgt_width = vae_scale_factor * math.ceil(p.init_images[0].width / vae_scale_factor) tgt_height = vae_scale_factor * math.ceil(p.init_images[0].height / vae_scale_factor) if p.init_images[0].size != (tgt_width, tgt_height): diff --git a/modules/sd_vae.py b/modules/sd_vae.py index 066cec2ca..ec5f7053d 100644 --- a/modules/sd_vae.py +++ b/modules/sd_vae.py @@ -28,7 +28,7 @@ vae_scale_override = { } -def get_vae_scale_factor(model: DiffusionPipeline | None = None): +def get_vae_scale_factor(model: DiffusionPipeline | None = None, init_image: bool = False): if not shared.sd_loaded: vae_scale_factor = 8 return vae_scale_factor @@ -58,9 +58,12 @@ def get_vae_scale_factor(model: DiffusionPipeline | None = None): patch_size = model.patch_size if isinstance(patch_size, (tuple, list)): # 3d patch sizes are (t, h, w); spatial term is last patch_size = patch_size[-1] + multiple = vae_scale_factor * patch_size + if init_image and model is not None and hasattr(model, 'init_image_multiple'): # a pipeline that downsamples its source image needs a larger multiple than its output + multiple = max(multiple, int(model.init_image_multiple)) if debug: - log.trace(f'VAE: cls={model.__class__.__name__ if model else "None"} scale={vae_scale_factor} patch={patch_size}') - return vae_scale_factor * patch_size + log.trace(f'VAE: cls={model.__class__.__name__ if model else "None"} scale={vae_scale_factor} patch={patch_size} multiple={multiple}') + return multiple def load_vae_dict(filename: str): diff --git a/pipelines/llada/pipeline_llada_image.py b/pipelines/llada/pipeline_llada_image.py index eabe87622..7010dfadd 100644 --- a/pipelines/llada/pipeline_llada_image.py +++ b/pipelines/llada/pipeline_llada_image.py @@ -90,6 +90,8 @@ class LLaDAImagePipeline(DiffusionPipeline): self.vae_scale_factor = 2 ** (len(self.vae.config.block_out_channels) - 1) if self.vae is not None else 8 self.latent_scale_factor = self.vae_scale_factor * 2 + self.patch_size = 2 # transformer patch size, read by the host to round sizes to the latent multiple + self.init_image_multiple = self.latent_scale_factor * 2 # editing feeds a half-resolution copy of the source image to the semantic encoder self.image_processor = VaeImageProcessor(vae_scale_factor=self.latent_scale_factor) @classmethod @@ -383,7 +385,7 @@ class LLaDAImagePipeline(DiffusionPipeline): if generation_mode == "vq" and (height % 16 != 0 or width % 16 != 0): raise ValueError("`height` and `width` must be divisible by 16 in VQ mode.") - required_multiple = self.latent_scale_factor * (2 if generation_mode == "editing" else 1) + required_multiple = self.init_image_multiple if generation_mode == "editing" else self.latent_scale_factor if height <= 0 or width <= 0 or height % required_multiple != 0 or width % required_multiple != 0: raise ValueError(f"`height` and `width` must be divisible by {required_multiple}.") if num_inference_steps < 1: