From d50d467a330db83e82b71e05ca3ff2e4d987eb59 Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Thu, 30 Jan 2025 09:41:11 -0500 Subject: [PATCH] multiple fixes Signed-off-by: Vladimir Mandic --- CHANGELOG.md | 5 ++++- modules/face/__init__.py | 17 ++++++++++++++++- modules/face/photomaker.py | 24 +++++++++++++++++++----- modules/postprocess/yolo.py | 2 ++ modules/processing_args.py | 2 +- modules/sd_models.py | 1 + modules/sd_models_utils.py | 4 ++-- modules/sd_offload.py | 2 +- 8 files changed, 46 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc1cb2dc5..a716bf16b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,10 @@ ## Update for 2025-01-30 - **Fixes**: - - photomaker with offloading + - photomaker with offloading + - photomaker with refine/detailer + - detailer restore pipeline before run + - fix python 3.9 compatibility ## Update for 2025-01-29 diff --git a/modules/face/__init__.py b/modules/face/__init__.py index 14d50988a..ff30421d4 100644 --- a/modules/face/__init__.py +++ b/modules/face/__init__.py @@ -8,6 +8,9 @@ debug = shared.log.trace if os.environ.get('SD_FACE_DEBUG', None) is not None el class Script(scripts.Script): + original_pipeline = None + original_prompt_attention = None + def title(self): return 'Face: Multiple ID Transfers' @@ -125,6 +128,9 @@ class Script(scripts.Script): input_images[i] = Image.open(image['name']) processed = None + self.original_pipeline = shared.sd_model + self.original_prompt_attention = shared.opts.prompt_attention + shared.opts.data['prompt_attention'] = 'fixed' if mode == 'FaceID': # faceid runs as ipadapter in its own pipeline from modules.face.insightface import get_app app = get_app('buffalo_l') @@ -135,7 +141,7 @@ class Script(scripts.Script): from modules.face.insightface import get_app app = get_app('buffalo_l') from modules.face.photomaker import photo_maker - processed = photo_maker(p, app=app, input_images=input_images, model=pm_model, trigger=pm_trigger, strength=pm_strength, start=pm_start) + photo_maker(p, app=app, input_images=input_images, model=pm_model, trigger=pm_trigger, strength=pm_strength, start=pm_start) elif mode == 'InstantID': from modules.face.insightface import get_app app=get_app('antelopev2') @@ -164,3 +170,12 @@ class Script(scripts.Script): images.save_image(image, path=p.outpath_samples, seed=p.all_seeds[i], prompt=p.all_prompts[i], info=info, p=p) return processed + + def after(self, p: processing.StableDiffusionProcessing, processed: processing.Processed, *args): # pylint: disable=unused-argument + if self.original_pipeline is not None: + shared.sd_model = self.original_pipeline + self.original_pipeline = None + if self.original_prompt_attention is not None: + shared.opts.data['prompt_attention'] = self.original_prompt_attention + self.original_prompt_attention = None + return processed diff --git a/modules/face/photomaker.py b/modules/face/photomaker.py index e97697275..19a62b913 100644 --- a/modules/face/photomaker.py +++ b/modules/face/photomaker.py @@ -5,7 +5,18 @@ import huggingface_hub as hf from modules import shared, processing, sd_models, devices +original_pipeline = None + + +def restore_pipeline(): + global original_pipeline # pylint: disable=global-statement + if original_pipeline is not None: + shared.sd_model = original_pipeline + original_pipeline = None + + def photo_maker(p: processing.StableDiffusionProcessing, app, model: str, input_images, trigger, strength, start): # pylint: disable=arguments-differ + global original_pipeline # pylint: disable=global-statement from modules.face.photomaker_pipeline import PhotoMakerStableDiffusionXLPipeline # prepare pipeline @@ -38,9 +49,11 @@ def photo_maker(p: processing.StableDiffusionProcessing, app, model: str, input_ return None # create new pipeline - orig_pipeline = shared.sd_model # backup current pipeline definition + original_pipeline = shared.sd_model # backup current pipeline definition + # orig_pipeline = shared.sd_model # backup current pipeline definition shared.sd_model = sd_models.switch_pipe(PhotoMakerStableDiffusionXLPipeline, shared.sd_model) - sd_models.copy_diffuser_options(shared.sd_model, orig_pipeline) # copy options from original pipeline + shared.sd_model.restore_pipeline = restore_pipeline + # sd_models.copy_diffuser_options(shared.sd_model, orig_pipeline) # copy options from original pipeline sd_models.set_diffuser_options(shared.sd_model) # set all model options such as fp16, offload, etc. sd_models.apply_balanced_offload(shared.sd_model) # apply balanced offload @@ -81,7 +94,7 @@ def photo_maker(p: processing.StableDiffusionProcessing, app, model: str, input_ p.task_args['id_embeds'] = torch.stack(id_embed_list).to(device=devices.device, dtype=devices.dtype) # run processing - processed: processing.Processed = processing.process_images(p) + # processed: processing.Processed = processing.process_images(p) p.extra_generation_params['PhotoMaker'] = f'{strength}' # unload photomaker adapter @@ -89,5 +102,6 @@ def photo_maker(p: processing.StableDiffusionProcessing, app, model: str, input_ # restore original pipeline shared.opts.data['prompt_attention'] = orig_prompt_attention - shared.sd_model = orig_pipeline - return processed + # shared.sd_model = orig_pipeline + return None + # return processed diff --git a/modules/postprocess/yolo.py b/modules/postprocess/yolo.py index 5e6d5ed05..1b53d67d6 100644 --- a/modules/postprocess/yolo.py +++ b/modules/postprocess/yolo.py @@ -277,6 +277,8 @@ class YoloRestorer(Detailer): run.restore_pipeline() p = processing_class.switch_class(p, processing.StableDiffusionProcessingImg2Img, args) + if hasattr(shared.sd_model, 'restore_pipeline'): + shared.sd_model.restore_pipeline() p.detailer_active += 1 # set flag to avoid recursion if p.steps < 1: diff --git a/modules/processing_args.py b/modules/processing_args.py index 509ba77e2..4cec4883e 100644 --- a/modules/processing_args.py +++ b/modules/processing_args.py @@ -128,7 +128,7 @@ def set_pipeline_args(p, model, prompts:list, negative_prompts:list, prompts_2:t parser = 'fixed' prompt_attention = prompt_attention or shared.opts.prompt_attention - if prompt_attention != 'fixed' and 'Onnx' not in model.__class__.__name__ and ( + if (prompt_attention != 'fixed') and ('Onnx' not in model.__class__.__name__) and ('prompt' not in p.task_args) and ( 'StableDiffusion' in model.__class__.__name__ or 'StableCascade' in model.__class__.__name__ or 'Flux' in model.__class__.__name__ diff --git a/modules/sd_models.py b/modules/sd_models.py index a3d749be8..5ccbcbc88 100644 --- a/modules/sd_models.py +++ b/modules/sd_models.py @@ -756,6 +756,7 @@ def set_diffuser_pipe(pipe, new_pipe_type): 'FluxControlPipeline', 'StableVideoDiffusionPipeline', 'PixelSmithXLPipeline', + 'PhotoMakerStableDiffusionXLPipeline', ] has_errors = False diff --git a/modules/sd_models_utils.py b/modules/sd_models_utils.py index a09ca73a7..93367197c 100644 --- a/modules/sd_models_utils.py +++ b/modules/sd_models_utils.py @@ -19,14 +19,14 @@ class NoWatermark: def get_signature(cls): - signature = inspect.signature(cls.__init__, follow_wrapped=True, eval_str=True) + signature = inspect.signature(cls.__init__, follow_wrapped=True) return signature.parameters def get_call(cls): if cls is None: return [] - signature = inspect.signature(cls.__call__, follow_wrapped=True, eval_str=True) + signature = inspect.signature(cls.__call__, follow_wrapped=True) return signature.parameters diff --git a/modules/sd_offload.py b/modules/sd_offload.py index 94a75496e..1c3265b66 100644 --- a/modules/sd_offload.py +++ b/modules/sd_offload.py @@ -15,7 +15,7 @@ offload_hook_instance = None def get_signature(cls): - signature = inspect.signature(cls.__init__, follow_wrapped=True, eval_str=True) + signature = inspect.signature(cls.__init__, follow_wrapped=True) return signature.parameters