#!/usr/bin/env python from __future__ import annotations import requests import os import random import gradio as gr import numpy as np import spaces import torch from PIL import Image from io import BytesIO from diffusers import AutoencoderKL, DiffusionPipeline, AutoPipelineForImage2Image DESCRIPTION = "# Run any LoRA or SD Model" if not torch.cuda.is_available(): DESCRIPTION += "\n

⚠️ This space is running on the CPU. This demo doesn't work on CPU 😞! Run on a GPU by duplicating this space or test our website for free and unlimited by clicking here, which provides these and more options.

" MAX_SEED = np.iinfo(np.int32).max CACHE_EXAMPLES = torch.cuda.is_available() and os.getenv("CACHE_EXAMPLES") == "1" MAX_IMAGE_SIZE = int(os.getenv("MAX_IMAGE_SIZE", "1824")) USE_TORCH_COMPILE = os.getenv("USE_TORCH_COMPILE") == "1" ENABLE_CPU_OFFLOAD = os.getenv("ENABLE_CPU_OFFLOAD") == "1" ENABLE_USE_LORA = os.getenv("ENABLE_USE_LORA", "1") == "1" ENABLE_USE_VAE = os.getenv("ENABLE_USE_VAE", "1") == "1" ENABLE_USE_IMG2IMG = os.getenv("ENABLE_USE_VAE", "1") == "1" device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") def randomize_seed_fn(seed: int, randomize_seed: bool) -> int: if randomize_seed: seed = random.randint(0, MAX_SEED) return seed @spaces.GPU def generate( prompt: str, negative_prompt: str = "", prompt_2: str = "", negative_prompt_2: str = "", use_negative_prompt: bool = False, use_prompt_2: bool = False, use_negative_prompt_2: bool = False, seed: int = 0, width: int = 1024, height: int = 1024, guidance_scale_base: float = 5.0, num_inference_steps_base: int = 25, strength_img2img: float = 0.7, use_vae: bool = False, use_lora: bool = False, model = 'stabilityai/stable-diffusion-xl-base-1.0', vaecall = 'madebyollin/sdxl-vae-fp16-fix', lora = '', lora_scale: float = 0.7, use_img2img: bool = False, url = '', ): if torch.cuda.is_available(): if not use_img2img: pipe = DiffusionPipeline.from_pretrained(model, torch_dtype=torch.float16) if use_vae: vae = AutoencoderKL.from_pretrained(vaecall, torch_dtype=torch.float16) pipe = DiffusionPipeline.from_pretrained(model, vae=vae, torch_dtype=torch.float16) if use_img2img: pipe = AutoPipelineForImage2Image.from_pretrained(model, torch_dtype=torch.float16) if use_vae: vae = AutoencoderKL.from_pretrained(vaecall, torch_dtype=torch.float16) pipe = AutoPipelineForImage2Image.from_pretrained(model, vae=vae, torch_dtype=torch.float16) response = requests.get(url) init_image = Image.open(BytesIO(response.content)).convert("RGB") init_image = init_image.resize((width, height)) if use_lora: pipe.load_lora_weights(lora) pipe.fuse_lora(lora_scale) if ENABLE_CPU_OFFLOAD: pipe.enable_model_cpu_offload() else: pipe.to(device) if USE_TORCH_COMPILE: pipe.unet = torch.compile(pipe.unet, mode="reduce-overhead", fullgraph=True) generator = torch.Generator().manual_seed(seed) if not use_negative_prompt: negative_prompt = None # type: ignore if not use_prompt_2: prompt_2 = None # type: ignore if not use_negative_prompt_2: negative_prompt_2 = None # type: ignore if not use_img2img: return pipe( prompt=prompt, negative_prompt=negative_prompt, prompt_2=prompt_2, negative_prompt_2=negative_prompt_2, width=width, height=height, guidance_scale=guidance_scale_base, num_inference_steps=num_inference_steps_base, generator=generator, output_type="pil", ).images[0] else: images = pipe( prompt=prompt, image=init_image, strength=strength_img2img, negative_prompt=negative_prompt, prompt_2=prompt_2, negative_prompt_2=negative_prompt_2, width=width, height=height, guidance_scale=guidance_scale_base, num_inference_steps=num_inference_steps_base, generator=generator, output_type="pil", ).images[0] return images examples = [ "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k", "An astronaut riding a green horse", ] with gr.Blocks(theme=gr.themes.Soft(), css="style.css") as demo: gr.HTML( "

📙 For any additional support, join our Discord

" ) gr.Markdown(DESCRIPTION, elem_id="description") with gr.Group(): model = gr.Text(label='Model', placeholder='e.g. stabilityai/stable-diffusion-xl-base-1.0') vaecall = gr.Text(label='VAE', placeholder='e.g. madebyollin/sdxl-vae-fp16-fix') lora = gr.Text(label='LoRA', placeholder='e.g. nerijs/pixel-art-xl') lora_scale = gr.Slider( info="The closer to 1, the more it will resemble LoRA, but errors may be visible.", label="Lora Scale", minimum=0.01, maximum=1, step=0.01, value=0.7, ) url = gr.Text(label='URL (Img2Img)', placeholder='e.g https://example.com/image.png') with gr.Row(): prompt = gr.Text( placeholder="Input prompt", label="Prompt", show_label=False, max_lines=1, container=False, ) run_button = gr.Button("Run", scale=0) result = gr.Image(label="Result", show_label=False) with gr.Accordion("Advanced options", open=False): with gr.Row(): use_img2img = gr.Checkbox(label='Use Img2Img', value=False, visible=ENABLE_USE_IMG2IMG) use_vae = gr.Checkbox(label='Use VAE', value=False, visible=ENABLE_USE_VAE) use_lora = gr.Checkbox(label='Use Lora', value=False, visible=ENABLE_USE_LORA) use_negative_prompt = gr.Checkbox(label="Use negative prompt", value=False) use_prompt_2 = gr.Checkbox(label="Use prompt 2", value=False) use_negative_prompt_2 = gr.Checkbox(label="Use negative prompt 2", value=False) negative_prompt = gr.Text( placeholder="Input Negative Prompt", label="Negative prompt", max_lines=1, visible=False, ) prompt_2 = gr.Text( placeholder="Input Prompt 2", label="Prompt 2", max_lines=1, visible=False, ) negative_prompt_2 = gr.Text( placeholder="Input Negative Prompt 2", label="Negative prompt 2", max_lines=1, visible=False, ) seed = gr.Slider( label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=0, ) randomize_seed = gr.Checkbox(label="Randomize seed", value=True) with gr.Row(): width = gr.Slider( label="Width", minimum=256, maximum=MAX_IMAGE_SIZE, step=32, value=1024, ) height = gr.Slider( label="Height", minimum=256, maximum=MAX_IMAGE_SIZE, step=32, value=1024, ) with gr.Row(): guidance_scale_base = gr.Slider( info="Scale for classifier-free guidance", label="Guidance scale", minimum=1, maximum=20, step=0.1, value=5.0, ) with gr.Row(): num_inference_steps_base = gr.Slider( info="Number of denoising steps", label="Number of inference steps", minimum=10, maximum=100, step=1, value=25, ) with gr.Row(): strength_img2img = gr.Slider( info="Strength for Img2Img", label="Strength", minimum=0, maximum=1, step=0.01, value=0.7, ) gr.Examples( examples=examples, inputs=prompt, outputs=result, fn=generate, cache_examples=CACHE_EXAMPLES, ) use_negative_prompt.change( fn=lambda x: gr.update(visible=x), inputs=use_negative_prompt, outputs=negative_prompt, queue=False, api_name=False, ) use_prompt_2.change( fn=lambda x: gr.update(visible=x), inputs=use_prompt_2, outputs=prompt_2, queue=False, api_name=False, ) use_negative_prompt_2.change( fn=lambda x: gr.update(visible=x), inputs=use_negative_prompt_2, outputs=negative_prompt_2, queue=False, api_name=False, ) use_vae.change( fn=lambda x: gr.update(visible=x), inputs=use_vae, outputs=vaecall, queue=False, api_name=False, ) use_lora.change( fn=lambda x: gr.update(visible=x), inputs=use_lora, outputs=lora, queue=False, api_name=False, ) use_img2img.change( fn=lambda x: gr.update(visible=x), inputs=use_img2img, outputs=url, queue=False, api_name=False, ) gr.on( triggers=[ prompt.submit, negative_prompt.submit, prompt_2.submit, negative_prompt_2.submit, run_button.click, ], fn=randomize_seed_fn, inputs=[seed, randomize_seed], outputs=seed, queue=False, api_name=False, ).then( fn=generate, inputs=[ prompt, negative_prompt, prompt_2, negative_prompt_2, use_negative_prompt, use_prompt_2, use_negative_prompt_2, seed, width, height, guidance_scale_base, num_inference_steps_base, strength_img2img, use_vae, use_lora, model, vaecall, lora, lora_scale, use_img2img, url, ], outputs=result, api_name="run", ) if __name__ == "__main__": demo.queue(max_size=20).launch()