inpainting / app.py
dgoot's picture
Update app.py
aac78db verified
raw
history blame
4.23 kB
import os
import gradio as gr
import spaces
import torch
from diffusers import AutoPipelineForInpainting
from loguru import logger
from PIL import Image, ImageChops
SUPPORTED_MODELS = [
"stabilityai/sdxl-turbo",
"stabilityai/stable-diffusion-3-medium-diffusers",
"stabilityai/stable-diffusion-xl-base-1.0",
"stable-diffusion-v1-5/stable-diffusion-v1-5",
"timbrooks/instruct-pix2pix",
]
DEFAULT_MODEL = "stabilityai/stable-diffusion-xl-base-1.0"
model = os.environ.get("MODEL_ID", DEFAULT_MODEL)
gpu_duration = int(os.environ.get("GPU_DURATION", 60))
def load_pipeline(model):
return AutoPipelineForInpainting.from_pretrained(
model, torch_dtype=torch.float16, use_safetensors=True, variant="fp16"
)
logger.debug(f"Loading pipeline: {dict(model=model)}")
pipe = load_pipeline(model).to("cuda" if torch.cuda.is_available() else "mps")
@logger.catch(reraise=True)
@spaces.GPU(duration=gpu_duration)
def infer(
prompt: str,
image_editor: dict,
negative_prompt: str,
strength: float,
num_inference_steps: int,
guidance_scale: float,
progress=gr.Progress(track_tqdm=True),
):
logger.info(
f"Starting image generation: {dict(model=model, prompt=prompt, image_editor=image_editor)}"
)
init_image: Image.Image = image_editor["background"].convert("RGB")
# Downscale the image
init_image.thumbnail((1024, 1024))
mask_layer = image_editor["layers"][0]
mask_image = Image.new("RGBA", mask_layer.size, "white")
mask_image = Image.alpha_composite(mask_image, mask_layer).convert("RGB")
mask_image = ImageChops.invert(mask_image)
mask_image.thumbnail((1024, 1024))
additional_args = {
k: v
for k, v in dict(
strength=strength,
num_inference_steps=num_inference_steps,
guidance_scale=guidance_scale,
).items()
if v
}
logger.debug(f"Generating image: {dict(prompt=prompt, **additional_args)}")
images = pipe(
prompt=prompt,
image=init_image,
mask_image=mask_image,
negative_prompt=negative_prompt,
**additional_args,
).images
return images[0]
css = """
@media (max-width: 1280px) {
#images-container {
flex-direction: column;
}
}
"""
with gr.Blocks(css=css) as demo:
with gr.Column():
gr.Markdown("# Inpainting")
gr.Markdown(f"## Model: `{model}`")
with gr.Row():
prompt = gr.Text(
label="Prompt",
show_label=False,
max_lines=1,
placeholder="Enter your prompt",
container=False,
)
run_button = gr.Button("Run", scale=0, variant="primary")
with gr.Row(elem_id="images-container"):
image_editor = gr.ImageMask(label="Initial image", type="pil")
result = gr.Image(label="Result")
with gr.Accordion("Advanced Settings", open=False):
negative_prompt = gr.Text(
label="Negative prompt",
max_lines=1,
placeholder="Enter a negative prompt",
)
with gr.Row():
strength = gr.Slider(
label="Strength",
minimum=0.0,
maximum=1.0,
step=0.01,
value=0.0,
)
num_inference_steps = gr.Slider(
label="Number of inference steps",
minimum=0,
maximum=100,
step=1,
value=0,
)
guidance_scale = gr.Slider(
label="Guidance scale",
minimum=0.0,
maximum=100.0,
step=0.1,
value=0.0,
)
gr.on(
triggers=[run_button.click, prompt.submit],
fn=infer,
inputs=[
prompt,
image_editor,
negative_prompt,
strength,
num_inference_steps,
guidance_scale,
],
outputs=[result],
)
if __name__ == "__main__":
demo.launch()