Skip to content

Commit e5a634d

Browse files
authored
Merge pull request #97 from openvinotoolkit/dev
HiRes Latent upscaler support
2 parents 4400629 + 522cca2 commit e5a634d

File tree

1 file changed

+54
-8
lines changed

1 file changed

+54
-8
lines changed

scripts/openvino_accelerate.py

+54-8
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
StableDiffusionXLImg2ImgPipeline,
5454
StableDiffusionXLInpaintPipeline,
5555
ControlNetModel,
56+
StableDiffusionLatentUpscalePipeline,
5657
DDIMScheduler,
5758
DPMSolverMultistepScheduler,
5859
EulerAncestralDiscreteScheduler,
@@ -535,6 +536,23 @@ class NoWatermark:
535536
def apply_watermark(self, img):
536537
return img
537538

539+
540+
def get_diffusers_upscaler(upscaler: str):
541+
torch._dynamo.reset()
542+
openvino_clear_caches()
543+
model_name = "stabilityai/sd-x2-latent-upscaler"
544+
print("OpenVINO Script: loading upscaling model: " + model_name)
545+
sd_model = StableDiffusionLatentUpscalePipeline.from_pretrained(model_name, torch_dtype=torch.float32)
546+
sd_model.safety_checker = None
547+
sd_model.cond_stage_key = functools.partial(cond_stage_key, shared.sd_model)
548+
sd_model.unet = torch.compile(sd_model.unet, backend="openvino")
549+
sd_model.vae.decode = torch.compile(sd_model.vae.decode, backend="openvino")
550+
shared.sd_diffusers_model = sd_model
551+
del sd_model
552+
553+
return shared.sd_diffusers_model
554+
555+
538556
def get_diffusers_sd_model(model_config, vae_ckpt, sampler_name, enable_caching, openvino_device, mode, is_xl_ckpt, refiner_ckpt, refiner_frac):
539557
if (model_state.recompile == 1):
540558
model_state.partition_id = 0
@@ -770,7 +788,8 @@ def init_new(self, all_prompts, all_seeds, all_subseeds):
770788
else:
771789
raise RuntimeError(f"bad number of images passed: {len(imgs)}; expecting {self.batch_size} or less")
772790

773-
def process_images_openvino(p: StableDiffusionProcessing, model_config, vae_ckpt, sampler_name, enable_caching, openvino_device, mode, is_xl_ckpt, refiner_ckpt, refiner_frac) -> Processed:
791+
def process_images_openvino(p: StableDiffusionProcessing, model_config, vae_ckpt, sampler_name, enable_caching, override_hires, upscaler, hires_steps, d_strength, openvino_device, mode, is_xl_ckpt, refiner_ckpt, refiner_frac) -> Processed:
792+
"""this is the main loop that both txt2img and img2img use; it calls func_init once inside all the scopes and func_sample once per batch"""
774793

775794
"""this is the main loop that both txt2img and img2img use; it calls func_init once inside all the scopes and func_sample once per batch"""
776795
if (mode == 0 and p.enable_hr):
@@ -1092,6 +1111,23 @@ def callback(iter, t, latents):
10921111

10931112
devices.torch_gc()
10941113

1114+
# Hight resolutuon mode
1115+
if override_hires:
1116+
if upscaler == "Latent":
1117+
model_state.mode = -1
1118+
shared.sd_diffusers_model = get_diffusers_upscaler(upscaler)
1119+
img_idx = slice(len(output_images)) if p.batch_size == 1 else slice(1, len(output_images))
1120+
output_images[img_idx] = shared.sd_diffusers_model(
1121+
image=output_images[img_idx],
1122+
prompt=p.prompts,
1123+
negative_prompt=p.negative_prompts,
1124+
num_inference_steps=hires_steps,
1125+
guidance_scale=p.cfg_scale,
1126+
generator=generator,
1127+
callback = callback,
1128+
callback_steps = 1,
1129+
).images
1130+
10951131
res = Processed(
10961132
p,
10971133
images_list=output_images,
@@ -1102,7 +1138,8 @@ def callback(iter, t, latents):
11021138
index_of_first_image=index_of_first_image,
11031139
infotexts=infotexts,
11041140
)
1105-
1141+
if override_hires:
1142+
res.info = res.info + f", Hires upscaler: {upscaler}, Denoising strength: {d_strength}"
11061143
res.info = res.info + ", Warm up time: " + str(round(warmup_duration, 2)) + " secs "
11071144

11081145
if (generation_rate >= 1.0):
@@ -1116,6 +1153,9 @@ def callback(iter, t, latents):
11161153

11171154
return res
11181155

1156+
def on_change(mode):
1157+
return gr.update(visible=mode)
1158+
11191159
class Script(scripts.Script):
11201160
def title(self):
11211161
return "Accelerate with OpenVINO"
@@ -1170,6 +1210,12 @@ def get_refiner_list():
11701210
override_sampler = gr.Checkbox(label="Override the sampling selection from the main UI (Recommended as only below sampling methods have been validated for OpenVINO)", value=True)
11711211
sampler_name = gr.Radio(label="Select a sampling method", choices=["Euler a", "Euler", "LMS", "Heun", "DPM++ 2M", "LMS Karras", "DPM++ 2M Karras", "DDIM", "PLMS"], value="Euler a")
11721212
enable_caching = gr.Checkbox(label="Cache the compiled models on disk for faster model load in subsequent launches (Recommended)", value=True, elem_id=self.elem_id("enable_caching"))
1213+
override_hires = gr.Checkbox(label="Override the Hires.fix selection from the main UI (Recommended as only below upscalers have been validated for OpenVINO)", value=False, visible=self.is_txt2img)
1214+
with gr.Group(visible=False) as hires:
1215+
with gr.Row():
1216+
upscaler = gr.Dropdown(label="Upscaler", choices=["Latent"], value="Latent")
1217+
hires_steps = gr.Slider(1, 150, value=10, step=1, label="Steps")
1218+
d_strength = gr.Slider(0, 1, value=0.5, step=0.01, label="Strength")
11731219
warmup_status = gr.Textbox(label="Device", interactive=False, visible=False)
11741220
vae_status = gr.Textbox(label="VAE", interactive=False, visible=False)
11751221
gr.Markdown(
@@ -1184,6 +1230,8 @@ def get_refiner_list():
11841230
So it's normal for the first inference after a settings change to be slower, while subsequent inferences use the optimized compiled model and run faster.
11851231
""")
11861232

1233+
override_hires.change(on_change, override_hires, hires)
1234+
11871235
def device_change(choice):
11881236
if (model_state.device == choice):
11891237
return gr.update(value="Device selected is " + choice, visible=True)
@@ -1206,9 +1254,9 @@ def refiner_ckpt_change(choice):
12061254
else:
12071255
model_state.refiner_ckpt = choice
12081256
refiner_ckpt.change(refiner_ckpt_change, refiner_ckpt)
1209-
return [model_config, vae_ckpt, openvino_device, override_sampler, sampler_name, enable_caching, is_xl_ckpt, refiner_ckpt, refiner_frac]
1257+
return [model_config, vae_ckpt, openvino_device, override_sampler, sampler_name, enable_caching, override_hires, upscaler, hires_steps, d_strength, is_xl_ckpt, refiner_ckpt, refiner_frac]
12101258

1211-
def run(self, p, model_config, vae_ckpt, openvino_device, override_sampler, sampler_name, enable_caching, is_xl_ckpt, refiner_ckpt, refiner_frac):
1259+
def run(self, p, model_config, vae_ckpt, openvino_device, override_sampler, sampler_name, enable_caching, override_hires, upscaler, hires_steps, d_strength, is_xl_ckpt, refiner_ckpt, refiner_frac):
12121260
os.environ["OPENVINO_TORCH_BACKEND_DEVICE"] = str(openvino_device)
12131261

12141262
if enable_caching:
@@ -1225,14 +1273,12 @@ def run(self, p, model_config, vae_ckpt, openvino_device, override_sampler, samp
12251273
mode = 0
12261274
if self.is_txt2img:
12271275
mode = 0
1228-
processed = process_images_openvino(p, model_config, vae_ckpt, p.sampler_name, enable_caching, openvino_device, mode, is_xl_ckpt, refiner_ckpt, refiner_frac)
1276+
processed = process_images_openvino(p, model_config, vae_ckpt, p.sampler_name, enable_caching, override_hires, upscaler, hires_steps, d_strength, openvino_device, mode, is_xl_ckpt, refiner_ckpt, refiner_frac)
12291277
else:
12301278
if p.image_mask is None:
12311279
mode = 1
12321280
else:
12331281
mode = 2
12341282
p.init = functools.partial(init_new, p)
1235-
processed = process_images_openvino(p, model_config, vae_ckpt, p.sampler_name, enable_caching, openvino_device, mode, is_xl_ckpt, refiner_ckpt, refiner_frac)
1283+
processed = process_images_openvino(p, model_config, vae_ckpt, p.sampler_name, enable_caching, override_hires, upscaler, hires_steps, d_strength, openvino_device, mode, is_xl_ckpt, refiner_ckpt, refiner_frac)
12361284
return processed
1237-
1238-

0 commit comments

Comments
 (0)