CoolFace
Apppublic

computerwiz8432/IllusionDiffusion

sourceHugging Faceopenrailupdated 3y agoView on Hugging Face
0likes
app.py282 linesDownload Raw Back to root
1import torch2import gradio as gr3from gradio import processing_utils, utils4from PIL import Image5import random6from diffusers import (7    DiffusionPipeline,8    AutoencoderKL,9    StableDiffusionControlNetPipeline,10    ControlNetModel,11    StableDiffusionLatentUpscalePipeline,12    StableDiffusionImg2ImgPipeline,13    StableDiffusionControlNetImg2ImgPipeline,14    DPMSolverMultistepScheduler,  # <-- Added import15    EulerDiscreteScheduler  # <-- Added import16)17import time18from share_btn import community_icon_html, loading_icon_html, share_js19import user_history20from illusion_style import css21 22BASE_MODEL = "SG161222/Realistic_Vision_V5.1_noVAE"23 24# Initialize both pipelines25vae = AutoencoderKL.from_pretrained("stabilityai/sd-vae-ft-mse", torch_dtype=torch.float16)26#init_pipe = DiffusionPipeline.from_pretrained("SG161222/Realistic_Vision_V5.1_noVAE", torch_dtype=torch.float16)27controlnet = ControlNetModel.from_pretrained("monster-labs/control_v1p_sd15_qrcode_monster", torch_dtype=torch.float16)#, torch_dtype=torch.float16)28main_pipe = StableDiffusionControlNetPipeline.from_pretrained(29    BASE_MODEL,30    controlnet=controlnet,31    vae=vae,32    safety_checker=None,33    torch_dtype=torch.float16,34).to("cuda")35 36#main_pipe.unet = torch.compile(main_pipe.unet, mode="reduce-overhead", fullgraph=True)37#main_pipe.unet.to(memory_format=torch.channels_last)38#main_pipe.unet = torch.compile(main_pipe.unet, mode="reduce-overhead", fullgraph=True)39#model_id = "stabilityai/sd-x2-latent-upscaler"40image_pipe = StableDiffusionControlNetImg2ImgPipeline(**main_pipe.components)41 42#image_pipe.unet = torch.compile(image_pipe.unet, mode="reduce-overhead", fullgraph=True)43#upscaler = StableDiffusionLatentUpscalePipeline.from_pretrained(model_id, torch_dtype=torch.float16)44#upscaler.to("cuda")45 46 47# Sampler map48SAMPLER_MAP = {49    "DPM++ Karras SDE": lambda config: DPMSolverMultistepScheduler.from_config(config, use_karras=True, algorithm_type="sde-dpmsolver++"),50    "Euler": lambda config: EulerDiscreteScheduler.from_config(config),51}52 53def center_crop_resize(img, output_size=(512, 512)):54    width, height = img.size55 56    # Calculate dimensions to crop to the center57    new_dimension = min(width, height)58    left = (width - new_dimension)/259    top = (height - new_dimension)/260    right = (width + new_dimension)/261    bottom = (height + new_dimension)/262 63    # Crop and resize64    img = img.crop((left, top, right, bottom))65    img = img.resize(output_size)66 67    return img68 69def common_upscale(samples, width, height, upscale_method, crop=False):70        if crop == "center":71            old_width = samples.shape[3]72            old_height = samples.shape[2]73            old_aspect = old_width / old_height74            new_aspect = width / height75            x = 076            y = 077            if old_aspect > new_aspect:78                x = round((old_width - old_width * (new_aspect / old_aspect)) / 2)79            elif old_aspect < new_aspect:80                y = round((old_height - old_height * (old_aspect / new_aspect)) / 2)81            s = samples[:,:,y:old_height-y,x:old_width-x]82        else:83            s = samples84 85        return torch.nn.functional.interpolate(s, size=(height, width), mode=upscale_method)86 87def upscale(samples, upscale_method, scale_by):88        #s = samples.copy()89        width = round(samples["images"].shape[3] * scale_by)90        height = round(samples["images"].shape[2] * scale_by)91        s = common_upscale(samples["images"], width, height, upscale_method, "disabled")92        return (s)93 94def check_inputs(prompt: str, control_image: Image.Image):95    if control_image is None:96        raise gr.Error("Please select or upload an Input Illusion")97    if prompt is None or prompt == "":98        raise gr.Error("Prompt is required")99 100def convert_to_pil(base64_image):101    pil_image = processing_utils.decode_base64_to_image(base64_image)102    return pil_image103 104def convert_to_base64(pil_image):105    base64_image = processing_utils.encode_pil_to_base64(pil_image)106    return base64_image107 108# Inference function109def inference(110    control_image: Image.Image,111    prompt: str,112    negative_prompt: str,113    guidance_scale: float = 8.0,114    controlnet_conditioning_scale: float = 1,115    control_guidance_start: float = 1,    116    control_guidance_end: float = 1,117    upscaler_strength: float = 0.5,118    seed: int = -1,119    sampler = "DPM++ Karras SDE",120    progress = gr.Progress(track_tqdm=True),121    profile: gr.OAuthProfile | None = None,122):123    start_time = time.time()124    start_time_struct = time.localtime(start_time)125    start_time_formatted = time.strftime("%H:%M:%S", start_time_struct)126    print(f"Inference started at {start_time_formatted}")127    128    # Generate the initial image129    #init_image = init_pipe(prompt).images[0]130 131    # Rest of your existing code132    control_image_small = center_crop_resize(control_image)133    control_image_large = center_crop_resize(control_image, (1024, 1024))134 135    main_pipe.scheduler = SAMPLER_MAP[sampler](main_pipe.scheduler.config)136    my_seed = random.randint(0, 2**32 - 1) if seed == -1 else seed137    generator = torch.Generator(device="cuda").manual_seed(my_seed)138    139    out = main_pipe(140        prompt=prompt,141        negative_prompt=negative_prompt,142        image=control_image_small,143        guidance_scale=float(guidance_scale),144        controlnet_conditioning_scale=float(controlnet_conditioning_scale),145        generator=generator,146        control_guidance_start=float(control_guidance_start),147        control_guidance_end=float(control_guidance_end),148        num_inference_steps=15,149        output_type="latent"150    )151    upscaled_latents = upscale(out, "nearest-exact", 2)152    out_image = image_pipe(153        prompt=prompt,154        negative_prompt=negative_prompt,155        control_image=control_image_large,        156        image=upscaled_latents,157        guidance_scale=float(guidance_scale),158        generator=generator,159        num_inference_steps=20,160        strength=upscaler_strength,161        control_guidance_start=float(control_guidance_start),162        control_guidance_end=float(control_guidance_end),163        controlnet_conditioning_scale=float(controlnet_conditioning_scale)164    )165    end_time = time.time()166    end_time_struct = time.localtime(end_time)167    end_time_formatted = time.strftime("%H:%M:%S", end_time_struct)168    print(f"Inference ended at {end_time_formatted}, taking {end_time-start_time}s")169 170    # Save image + metadata171    user_history.save_image(172        label=prompt,173        image=out_image["images"][0],174        profile=profile,175        metadata={176            "prompt": prompt,177            "negative_prompt": negative_prompt,178            "guidance_scale": guidance_scale,179            "controlnet_conditioning_scale": controlnet_conditioning_scale,180            "control_guidance_start": control_guidance_start,181            "control_guidance_end": control_guidance_end,182            "upscaler_strength": upscaler_strength,183            "seed": seed,184            "sampler": sampler,185        },186    )187 188    return out_image["images"][0], gr.update(visible=True), gr.update(visible=True), my_seed189        190with gr.Blocks() as app:191    gr.Markdown(192        '''193        <center><h1>Illusion Diffusion HQ ๐ŸŒ€</h1></span>  194        <span font-size:16px;">Generate stunning high quality illusion artwork with Stable Diffusion</span>  195        </center>196 197        A space by AP [Follow me on Twitter](https://twitter.com/angrypenguinPNG) with big contributions from [multimodalart](https://twitter.com/multimodalart)198 199        This project works by using [Monster Labs QR Control Net](https://huggingface.co/monster-labs/control_v1p_sd15_qrcode_monster).200        Given a prompt and your pattern, we use a QR code conditioned controlnet to create a stunning illusion! Credit to: [MrUgleh](https://twitter.com/MrUgleh) for discovering the workflow :)201        '''202    )203    state_img_input = gr.State()204    state_img_output = gr.State()205    with gr.Row():206        with gr.Column():207            control_image = gr.Image(label="Input Illusion", type="pil", elem_id="control_image")208            controlnet_conditioning_scale = gr.Slider(minimum=0.0, maximum=5.0, step=0.01, value=0.8, label="Illusion strength", elem_id="illusion_strength", info="ControlNet conditioning scale")209            gr.Examples(examples=["checkers.png", "checkers_mid.jpg", "pattern.png", "ultra_checkers.png", "spiral.jpeg", "funky.jpeg" ], inputs=control_image)210            prompt = gr.Textbox(label="Prompt", elem_id="prompt", info="Type what you want to generate", placeholder="Medieval village scene with busy streets and castle in the distance")211            negative_prompt = gr.Textbox(label="Negative Prompt", info="Type what you don't want to see", value="low quality", elem_id="negative_prompt")212            with gr.Accordion(label="Advanced Options", open=False):213                guidance_scale = gr.Slider(minimum=0.0, maximum=50.0, step=0.25, value=7.5, label="Guidance Scale")214                sampler = gr.Dropdown(choices=list(SAMPLER_MAP.keys()), value="Euler")215                control_start = gr.Slider(minimum=0.0, maximum=1.0, step=0.1, value=0, label="Start of ControlNet")216                control_end = gr.Slider(minimum=0.0, maximum=1.0, step=0.1, value=1, label="End of ControlNet")217                strength = gr.Slider(minimum=0.0, maximum=1.0, step=0.1, value=1, label="Strength of the upscaler")218                seed = gr.Slider(minimum=-1, maximum=9999999999, step=1, value=-1, label="Seed", info="-1 means random seed")219                used_seed = gr.Number(label="Last seed used",interactive=False)220            run_btn = gr.Button("Run")221        with gr.Column():222            result_image = gr.Image(label="Illusion Diffusion Output", interactive=False, elem_id="output")223            with gr.Group(elem_id="share-btn-container", visible=False) as share_group:224                community_icon = gr.HTML(community_icon_html)225                loading_icon = gr.HTML(loading_icon_html)226                share_button = gr.Button("Share to community", elem_id="share-btn")227 228    prompt.submit(229        check_inputs,230        inputs=[prompt, control_image],231        queue=False232    ).success(233        convert_to_pil,234        inputs=[control_image],235        outputs=[state_img_input],236        queue=False,237        preprocess=False,238    ).success(239        inference,240        inputs=[state_img_input, prompt, negative_prompt, guidance_scale, controlnet_conditioning_scale, control_start, control_end, strength, seed, sampler],241        outputs=[state_img_output, result_image, share_group, used_seed]242    ).success(243        convert_to_base64,244        inputs=[state_img_output],245        outputs=[result_image],246        queue=False,247        postprocess=False248    )249    run_btn.click(250        check_inputs,251        inputs=[prompt, control_image],252        queue=False253    ).success(254        convert_to_pil,255        inputs=[control_image],256        outputs=[state_img_input],257        queue=False,258        preprocess=False,259    ).success(260        inference,261        inputs=[state_img_input, prompt, negative_prompt, guidance_scale, controlnet_conditioning_scale, control_start, control_end, strength, seed, sampler],262        outputs=[state_img_output, result_image, share_group, used_seed]263    ).success(264        convert_to_base64,265        inputs=[state_img_output],266        outputs=[result_image],267        queue=False,268        postprocess=False269    )270    share_button.click(None, [], [], _js=share_js)271 272with gr.Blocks(css=css) as app_with_history:273    with gr.Tab("Demo"):274        app.render()275    with gr.Tab("Past generations"):276        user_history.render()277 278app_with_history.queue(max_size=20,api_open=False )279 280if __name__ == "__main__":281    app_with_history.launch(max_threads=400)282