Spaces:
Build error
Build error
Update app.py
Browse files
app.py
CHANGED
|
@@ -10,7 +10,6 @@ from pipeline_fill_sd_xl import StableDiffusionXLFillPipeline
|
|
| 10 |
from PIL import Image, ImageDraw
|
| 11 |
import numpy as np
|
| 12 |
|
| 13 |
-
|
| 14 |
MODELS = {
|
| 15 |
"RealVisXL V5.0 Lightning": "SG161222/RealVisXL_V5.0_Lightning",
|
| 16 |
"Lustify Lightning": "GraydientPlatformAPI/lustify-lightning",
|
|
@@ -35,68 +34,58 @@ model.to(device="cuda", dtype=torch.float16)
|
|
| 35 |
vae = AutoencoderKL.from_pretrained(
|
| 36 |
"madebyollin/sdxl-vae-fp16-fix", torch_dtype=torch.float16
|
| 37 |
).to("cuda")
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
return pipe
|
| 54 |
|
| 55 |
@spaces.GPU(duration=12)
|
| 56 |
def fill_image(prompt, image, model_selection, paste_back):
|
|
|
|
| 57 |
if image is None:
|
| 58 |
yield None, None
|
| 59 |
return
|
| 60 |
-
|
| 61 |
-
pipe = get_pipeline(model_selection)
|
| 62 |
-
|
| 63 |
-
# Encode the prompt and ensure the embeddings are in float16
|
| 64 |
(
|
| 65 |
prompt_embeds,
|
| 66 |
negative_prompt_embeds,
|
| 67 |
pooled_prompt_embeds,
|
| 68 |
negative_pooled_prompt_embeds,
|
| 69 |
) = pipe.encode_prompt(prompt, "cuda", True)
|
| 70 |
-
prompt_embeds = prompt_embeds.to(torch.float16)
|
| 71 |
-
negative_prompt_embeds = negative_prompt_embeds.to(torch.float16)
|
| 72 |
-
pooled_prompt_embeds = pooled_prompt_embeds.to(torch.float16)
|
| 73 |
-
negative_pooled_prompt_embeds = negative_pooled_prompt_embeds.to(torch.float16)
|
| 74 |
-
|
| 75 |
source = image["background"]
|
| 76 |
mask = image["layers"][0]
|
| 77 |
alpha_channel = mask.split()[3]
|
| 78 |
binary_mask = alpha_channel.point(lambda p: p > 0 and 255)
|
| 79 |
-
|
| 80 |
cnet_image = source.copy()
|
| 81 |
cnet_image.paste(0, (0, 0), binary_mask)
|
| 82 |
-
|
|
|
|
| 83 |
prompt_embeds=prompt_embeds,
|
| 84 |
negative_prompt_embeds=negative_prompt_embeds,
|
| 85 |
pooled_prompt_embeds=pooled_prompt_embeds,
|
| 86 |
negative_pooled_prompt_embeds=negative_pooled_prompt_embeds,
|
| 87 |
image=cnet_image,
|
| 88 |
):
|
| 89 |
-
yield
|
| 90 |
-
|
| 91 |
print(f"{model_selection=}")
|
| 92 |
print(f"{paste_back=}")
|
| 93 |
-
|
| 94 |
if paste_back:
|
| 95 |
-
|
| 96 |
-
cnet_image.paste(
|
| 97 |
else:
|
| 98 |
-
cnet_image =
|
| 99 |
-
|
| 100 |
yield source, cnet_image
|
| 101 |
|
| 102 |
def clear_result():
|
|
@@ -242,47 +231,32 @@ def outpaint(image, width, height, overlap_percentage, num_inference_steps, resi
|
|
| 242 |
yield background, cnet_image
|
| 243 |
|
| 244 |
@spaces.GPU(duration=12)
|
| 245 |
-
def infer(image, width, height, overlap_percentage, num_inference_steps, resize_option, custom_resize_percentage, prompt_input, alignment, overlap_left, overlap_right, overlap_top, overlap_bottom
|
| 246 |
-
if image is None:
|
| 247 |
-
yield None, None
|
| 248 |
-
return
|
| 249 |
-
|
| 250 |
background, mask = prepare_image_and_mask(image, width, height, overlap_percentage, resize_option, custom_resize_percentage, alignment, overlap_left, overlap_right, overlap_top, overlap_bottom)
|
| 251 |
if not can_expand(background.width, background.height, width, height, alignment):
|
| 252 |
alignment = "Middle"
|
| 253 |
-
|
| 254 |
cnet_image = background.copy()
|
| 255 |
cnet_image.paste(0, (0, 0), mask)
|
| 256 |
-
final_prompt = f"{prompt_input}, high quality, 4k"
|
| 257 |
-
|
| 258 |
-
pipe = get_pipeline(model_selection)
|
| 259 |
-
# Encode the prompt and ensure the embeddings are in float16
|
| 260 |
(
|
| 261 |
prompt_embeds,
|
| 262 |
negative_prompt_embeds,
|
| 263 |
pooled_prompt_embeds,
|
| 264 |
negative_pooled_prompt_embeds,
|
| 265 |
) = pipe.encode_prompt(final_prompt, "cuda", True)
|
| 266 |
-
|
| 267 |
-
negative_prompt_embeds = negative_prompt_embeds.to(torch.float16)
|
| 268 |
-
pooled_prompt_embeds = pooled_prompt_embeds.to(torch.float16)
|
| 269 |
-
negative_pooled_prompt_embeds = negative_pooled_prompt_embeds.to(torch.float16)
|
| 270 |
-
|
| 271 |
-
for output_image in pipe(
|
| 272 |
prompt_embeds=prompt_embeds,
|
| 273 |
negative_prompt_embeds=negative_prompt_embeds,
|
| 274 |
pooled_prompt_embeds=pooled_prompt_embeds,
|
| 275 |
negative_pooled_prompt_embeds=negative_pooled_prompt_embeds,
|
| 276 |
image=cnet_image,
|
| 277 |
-
num_inference_steps=num_inference_steps
|
| 278 |
):
|
| 279 |
-
yield cnet_image,
|
| 280 |
-
|
| 281 |
-
|
| 282 |
-
cnet_image.paste(output_image, (0, 0), mask)
|
| 283 |
yield background, cnet_image
|
| 284 |
|
| 285 |
-
|
| 286 |
def use_output_as_input(output_image):
|
| 287 |
return gr.update(value=output_image[1])
|
| 288 |
|
|
@@ -492,11 +466,6 @@ with gr.Blocks(css=css, fill_height=True) as demo:
|
|
| 492 |
visible=False
|
| 493 |
)
|
| 494 |
with gr.Column():
|
| 495 |
-
out_model_selection = gr.Dropdown(
|
| 496 |
-
choices=list(MODELS.keys()),
|
| 497 |
-
value="RealVisXL V5.0 Lightning",
|
| 498 |
-
label="Model",
|
| 499 |
-
)
|
| 500 |
preview_button = gr.Button("Preview alignment and mask")
|
| 501 |
gr.Examples(
|
| 502 |
examples=[
|
|
@@ -515,30 +484,35 @@ with gr.Blocks(css=css, fill_height=True) as demo:
|
|
| 515 |
use_as_input_button_outpaint = gr.Button("Use as Input Image", visible=False)
|
| 516 |
history_gallery = gr.Gallery(label="History", columns=6, object_fit="contain", interactive=False)
|
| 517 |
preview_image = gr.Image(label="Preview")
|
|
|
|
| 518 |
target_ratio.change(
|
| 519 |
fn=preload_presets,
|
| 520 |
inputs=[target_ratio, width_slider, height_slider],
|
| 521 |
outputs=[width_slider, height_slider, settings_panel],
|
| 522 |
queue=False
|
| 523 |
)
|
|
|
|
| 524 |
width_slider.change(
|
| 525 |
fn=select_the_right_preset,
|
| 526 |
inputs=[width_slider, height_slider],
|
| 527 |
outputs=[target_ratio],
|
| 528 |
queue=False
|
| 529 |
)
|
|
|
|
| 530 |
height_slider.change(
|
| 531 |
fn=select_the_right_preset,
|
| 532 |
inputs=[width_slider, height_slider],
|
| 533 |
outputs=[target_ratio],
|
| 534 |
queue=False
|
| 535 |
)
|
|
|
|
| 536 |
resize_option.change(
|
| 537 |
fn=toggle_custom_resize_slider,
|
| 538 |
inputs=[resize_option],
|
| 539 |
outputs=[custom_resize_percentage],
|
| 540 |
queue=False
|
| 541 |
)
|
|
|
|
| 542 |
use_as_input_button_outpaint.click(
|
| 543 |
fn=use_output_as_input,
|
| 544 |
inputs=[result_outpaint],
|
|
@@ -552,7 +526,7 @@ with gr.Blocks(css=css, fill_height=True) as demo:
|
|
| 552 |
fn=infer,
|
| 553 |
inputs=[input_image_outpaint, width_slider, height_slider, overlap_percentage, num_inference_steps,
|
| 554 |
resize_option, custom_resize_percentage, prompt_input, alignment_dropdown,
|
| 555 |
-
overlap_left, overlap_right, overlap_top, overlap_bottom
|
| 556 |
outputs=[result_outpaint],
|
| 557 |
).then(
|
| 558 |
fn=lambda x, history: update_history(x[1], history),
|
|
@@ -571,7 +545,7 @@ with gr.Blocks(css=css, fill_height=True) as demo:
|
|
| 571 |
fn=infer,
|
| 572 |
inputs=[input_image_outpaint, width_slider, height_slider, overlap_percentage, num_inference_steps,
|
| 573 |
resize_option, custom_resize_percentage, prompt_input, alignment_dropdown,
|
| 574 |
-
overlap_left, overlap_right, overlap_top, overlap_bottom
|
| 575 |
outputs=[result_outpaint],
|
| 576 |
).then(
|
| 577 |
fn=lambda x, history: update_history(x[1], history),
|
|
@@ -589,4 +563,5 @@ with gr.Blocks(css=css, fill_height=True) as demo:
|
|
| 589 |
outputs=[preview_image],
|
| 590 |
queue=False
|
| 591 |
)
|
|
|
|
| 592 |
demo.launch(show_error=True)
|
|
|
|
| 10 |
from PIL import Image, ImageDraw
|
| 11 |
import numpy as np
|
| 12 |
|
|
|
|
| 13 |
MODELS = {
|
| 14 |
"RealVisXL V5.0 Lightning": "SG161222/RealVisXL_V5.0_Lightning",
|
| 15 |
"Lustify Lightning": "GraydientPlatformAPI/lustify-lightning",
|
|
|
|
| 34 |
vae = AutoencoderKL.from_pretrained(
|
| 35 |
"madebyollin/sdxl-vae-fp16-fix", torch_dtype=torch.float16
|
| 36 |
).to("cuda")
|
| 37 |
+
pipe = StableDiffusionXLFillPipeline.from_pretrained(
|
| 38 |
+
"SG161222/RealVisXL_V5.0_Lightning",
|
| 39 |
+
torch_dtype=torch.float16,
|
| 40 |
+
vae=vae,
|
| 41 |
+
controlnet=model,
|
| 42 |
+
variant="fp16",
|
| 43 |
+
)
|
| 44 |
+
pipe = StableDiffusionXLFillPipeline.from_pretrained(
|
| 45 |
+
"GraydientPlatformAPI/lustify-lightning",
|
| 46 |
+
torch_dtype=torch.float16,
|
| 47 |
+
vae=vae,
|
| 48 |
+
controlnet=model,
|
| 49 |
+
)
|
| 50 |
+
pipe.scheduler = TCDScheduler.from_config(pipe.scheduler.config)
|
| 51 |
+
pipe.to("cuda")
|
|
|
|
| 52 |
|
| 53 |
@spaces.GPU(duration=12)
|
| 54 |
def fill_image(prompt, image, model_selection, paste_back):
|
| 55 |
+
print(f"Received image: {image}")
|
| 56 |
if image is None:
|
| 57 |
yield None, None
|
| 58 |
return
|
| 59 |
+
|
|
|
|
|
|
|
|
|
|
| 60 |
(
|
| 61 |
prompt_embeds,
|
| 62 |
negative_prompt_embeds,
|
| 63 |
pooled_prompt_embeds,
|
| 64 |
negative_pooled_prompt_embeds,
|
| 65 |
) = pipe.encode_prompt(prompt, "cuda", True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
source = image["background"]
|
| 67 |
mask = image["layers"][0]
|
| 68 |
alpha_channel = mask.split()[3]
|
| 69 |
binary_mask = alpha_channel.point(lambda p: p > 0 and 255)
|
|
|
|
| 70 |
cnet_image = source.copy()
|
| 71 |
cnet_image.paste(0, (0, 0), binary_mask)
|
| 72 |
+
|
| 73 |
+
for image in pipe(
|
| 74 |
prompt_embeds=prompt_embeds,
|
| 75 |
negative_prompt_embeds=negative_prompt_embeds,
|
| 76 |
pooled_prompt_embeds=pooled_prompt_embeds,
|
| 77 |
negative_pooled_prompt_embeds=negative_pooled_prompt_embeds,
|
| 78 |
image=cnet_image,
|
| 79 |
):
|
| 80 |
+
yield image, cnet_image
|
| 81 |
+
|
| 82 |
print(f"{model_selection=}")
|
| 83 |
print(f"{paste_back=}")
|
|
|
|
| 84 |
if paste_back:
|
| 85 |
+
image = image.convert("RGBA")
|
| 86 |
+
cnet_image.paste(image, (0, 0), binary_mask)
|
| 87 |
else:
|
| 88 |
+
cnet_image = image
|
|
|
|
| 89 |
yield source, cnet_image
|
| 90 |
|
| 91 |
def clear_result():
|
|
|
|
| 231 |
yield background, cnet_image
|
| 232 |
|
| 233 |
@spaces.GPU(duration=12)
|
| 234 |
+
def infer(image, width, height, overlap_percentage, num_inference_steps, resize_option, custom_resize_percentage, prompt_input, alignment, overlap_left, overlap_right, overlap_top, overlap_bottom):
|
|
|
|
|
|
|
|
|
|
|
|
|
| 235 |
background, mask = prepare_image_and_mask(image, width, height, overlap_percentage, resize_option, custom_resize_percentage, alignment, overlap_left, overlap_right, overlap_top, overlap_bottom)
|
| 236 |
if not can_expand(background.width, background.height, width, height, alignment):
|
| 237 |
alignment = "Middle"
|
|
|
|
| 238 |
cnet_image = background.copy()
|
| 239 |
cnet_image.paste(0, (0, 0), mask)
|
| 240 |
+
final_prompt = f"{prompt_input} , high quality, 4k"
|
|
|
|
|
|
|
|
|
|
| 241 |
(
|
| 242 |
prompt_embeds,
|
| 243 |
negative_prompt_embeds,
|
| 244 |
pooled_prompt_embeds,
|
| 245 |
negative_pooled_prompt_embeds,
|
| 246 |
) = pipe.encode_prompt(final_prompt, "cuda", True)
|
| 247 |
+
for image in pipe(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 248 |
prompt_embeds=prompt_embeds,
|
| 249 |
negative_prompt_embeds=negative_prompt_embeds,
|
| 250 |
pooled_prompt_embeds=pooled_prompt_embeds,
|
| 251 |
negative_pooled_prompt_embeds=negative_pooled_prompt_embeds,
|
| 252 |
image=cnet_image,
|
| 253 |
+
num_inference_steps=num_inference_steps
|
| 254 |
):
|
| 255 |
+
yield cnet_image, image
|
| 256 |
+
image = image.convert("RGBA")
|
| 257 |
+
cnet_image.paste(image, (0, 0), mask)
|
|
|
|
| 258 |
yield background, cnet_image
|
| 259 |
|
|
|
|
| 260 |
def use_output_as_input(output_image):
|
| 261 |
return gr.update(value=output_image[1])
|
| 262 |
|
|
|
|
| 466 |
visible=False
|
| 467 |
)
|
| 468 |
with gr.Column():
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 469 |
preview_button = gr.Button("Preview alignment and mask")
|
| 470 |
gr.Examples(
|
| 471 |
examples=[
|
|
|
|
| 484 |
use_as_input_button_outpaint = gr.Button("Use as Input Image", visible=False)
|
| 485 |
history_gallery = gr.Gallery(label="History", columns=6, object_fit="contain", interactive=False)
|
| 486 |
preview_image = gr.Image(label="Preview")
|
| 487 |
+
|
| 488 |
target_ratio.change(
|
| 489 |
fn=preload_presets,
|
| 490 |
inputs=[target_ratio, width_slider, height_slider],
|
| 491 |
outputs=[width_slider, height_slider, settings_panel],
|
| 492 |
queue=False
|
| 493 |
)
|
| 494 |
+
|
| 495 |
width_slider.change(
|
| 496 |
fn=select_the_right_preset,
|
| 497 |
inputs=[width_slider, height_slider],
|
| 498 |
outputs=[target_ratio],
|
| 499 |
queue=False
|
| 500 |
)
|
| 501 |
+
|
| 502 |
height_slider.change(
|
| 503 |
fn=select_the_right_preset,
|
| 504 |
inputs=[width_slider, height_slider],
|
| 505 |
outputs=[target_ratio],
|
| 506 |
queue=False
|
| 507 |
)
|
| 508 |
+
|
| 509 |
resize_option.change(
|
| 510 |
fn=toggle_custom_resize_slider,
|
| 511 |
inputs=[resize_option],
|
| 512 |
outputs=[custom_resize_percentage],
|
| 513 |
queue=False
|
| 514 |
)
|
| 515 |
+
|
| 516 |
use_as_input_button_outpaint.click(
|
| 517 |
fn=use_output_as_input,
|
| 518 |
inputs=[result_outpaint],
|
|
|
|
| 526 |
fn=infer,
|
| 527 |
inputs=[input_image_outpaint, width_slider, height_slider, overlap_percentage, num_inference_steps,
|
| 528 |
resize_option, custom_resize_percentage, prompt_input, alignment_dropdown,
|
| 529 |
+
overlap_left, overlap_right, overlap_top, overlap_bottom],
|
| 530 |
outputs=[result_outpaint],
|
| 531 |
).then(
|
| 532 |
fn=lambda x, history: update_history(x[1], history),
|
|
|
|
| 545 |
fn=infer,
|
| 546 |
inputs=[input_image_outpaint, width_slider, height_slider, overlap_percentage, num_inference_steps,
|
| 547 |
resize_option, custom_resize_percentage, prompt_input, alignment_dropdown,
|
| 548 |
+
overlap_left, overlap_right, overlap_top, overlap_bottom],
|
| 549 |
outputs=[result_outpaint],
|
| 550 |
).then(
|
| 551 |
fn=lambda x, history: update_history(x[1], history),
|
|
|
|
| 563 |
outputs=[preview_image],
|
| 564 |
queue=False
|
| 565 |
)
|
| 566 |
+
|
| 567 |
demo.launch(show_error=True)
|