Spaces:
Runtime error
Runtime error
import diffusers | |
import gradio as gr | |
from modules import scripts, processing, shared, devices, sd_models | |
class Script(scripts.Script): | |
def title(self): | |
return 'LEdits++' | |
def show(self, is_img2img): | |
return is_img2img if shared.backend == shared.Backend.DIFFUSERS else False | |
# return signature is array of gradio components | |
def ui(self, _is_img2img): | |
with gr.Row(): | |
gr.HTML('<a href="https://leditsplusplus-project.static.hf.space/index.html">  LEdits++</a><br>') | |
with gr.Row(): | |
edit_start = gr.Slider(label='Edit start', minimum=0.0, maximum=1.0, step=0.01, value=0.1) | |
edit_stop = gr.Slider(label='Edit stop', minimum=0.0, maximum=1.0, step=0.01, value=1.0) | |
intersect_mask = gr.Checkbox(label='Smooth mask', value=True) | |
with gr.Row(): | |
prompt1 = gr.Textbox(show_label=False, placeholder='Positive prompt') | |
scale1 = gr.Slider(label='Scale', minimum=0.0, maximum=1.0, step=0.01, value=0.5) | |
threshold1 = gr.Slider(label='Threshold', minimum=0.0, maximum=1.0, step=0.01, value=0.9) | |
with gr.Row(): | |
prompt2 = gr.Textbox(show_label=False, placeholder='Negative prompt') | |
scale2 = gr.Slider(label='Scale', minimum=0.0, maximum=1.0, step=0.01, value=0.5) | |
threshold2 = gr.Slider(label='Threshold', minimum=0.0, maximum=1.0, step=0.01, value=0.9) | |
return [edit_start, edit_stop, intersect_mask, prompt1, scale1, threshold1, prompt2, scale2, threshold2] | |
def run(self, p: processing.StableDiffusionProcessing, edit_start, edit_stop, intersect_mask, prompt1, scale1, threshold1, prompt2, scale2, threshold2): # pylint: disable=arguments-differ, unused-argument | |
image = getattr(p, 'init_images', None) | |
if len(prompt1) == 0 and len(prompt2) == 0: | |
shared.log.error('LEdits: no prompts') | |
return None | |
if image is None or len(image) == 0: | |
shared.log.error('LEdits: no init_images') | |
return None | |
if shared.sd_model_type != 'sd' and shared.sd_model_type != 'sdxl': | |
shared.log.error(f'LEdits: invalid model type: {shared.sd_model_type}') | |
return None | |
orig_pipeline = shared.sd_model | |
orig_offload = shared.opts.diffusers_model_cpu_offload | |
orig_prompt_attention = shared.opts.prompt_attention | |
shared.opts.data['diffusers_model_cpu_offload'] = False | |
shared.opts.data['prompt_attention'] = 'Fixed attention' | |
# shared.sd_model.maybe_free_model_hooks() # ledits is not compatible with offloading | |
# shared.sd_model.has_accelerate = False | |
sd_models.move_model(shared.sd_model, devices.device, force=True) | |
if shared.sd_model_type == 'sd': | |
shared.sd_model = sd_models.switch_pipe(diffusers.LEditsPPPipelineStableDiffusion, shared.sd_model) | |
elif shared.sd_model_type == 'sdxl': | |
shared.sd_model = sd_models.switch_pipe(diffusers.LEditsPPPipelineStableDiffusionXL, shared.sd_model) | |
if str(devices.dtype) == 'torch.float16': | |
shared.sd_model.vae.config.force_upcast = False # not compatible | |
shared.sd_model.scheduler = diffusers.DPMSolverMultistepScheduler.from_config(shared.sd_model.scheduler.config, algorithm_type="sde-dpmsolver++", solver_order=2) # ledits is very picky | |
p.sampler_name = 'Default' | |
p.init() # run init early to take care of resizing | |
invert_args = { | |
'image': p.init_images[0], | |
'source_prompt': p.prompt, | |
'source_guidance_scale': p.cfg_scale, | |
'num_inversion_steps': p.steps, | |
'skip': 1.0 - p.denoising_strength, # invert start | |
'generator': None, # not supported | |
} | |
shared.log.info(f'LEdits invert: {invert_args}') | |
_output = shared.sd_model.invert(**invert_args) | |
p.task_args = { | |
'editing_prompt': [], | |
'reverse_editing_direction': [], | |
'edit_guidance_scale': [], | |
'edit_threshold': [], | |
'edit_warmup_steps': int(edit_start * p.steps), | |
'edit_cooldown_steps': int((1.0 - edit_stop) * p.steps) if edit_stop < 1.0 else None, | |
'use_intersect_mask': intersect_mask, # smoothing? | |
'generator': None, | |
'guidance_rescale': 0.0, # bug in pipeline if guidance rescale is enabled | |
} | |
if len(prompt1) > 0: | |
p.task_args['editing_prompt'].append(prompt1) | |
p.task_args['reverse_editing_direction'].append(False) | |
p.task_args['edit_guidance_scale'].append(10.0 * scale1) | |
p.task_args['edit_threshold'].append(threshold1) | |
if len(prompt2) > 0: | |
p.task_args['editing_prompt'].append(prompt2) | |
p.task_args['reverse_editing_direction'].append(True) | |
p.task_args['edit_guidance_scale'].append(10.0 * scale2) | |
p.task_args['edit_threshold'].append(threshold2) | |
shared.log.info(f'LEdits: {p.task_args}') | |
processed = processing.process_images(p) | |
# restore pipeline | |
shared.sd_model = orig_pipeline | |
shared.opts.data['prompt_attention'] = orig_prompt_attention | |
shared.opts.data['diffusers_model_cpu_offload'] = orig_offload | |
return processed | |