import spaces import os from argparse import ArgumentParser from stablepy import ( Model_Diffusers, SCHEDULE_TYPE_OPTIONS, SCHEDULE_PREDICTION_TYPE_OPTIONS, check_scheduler_compatibility, TASK_AND_PREPROCESSORS, FACE_RESTORATION_MODELS, PROMPT_WEIGHT_OPTIONS_PRIORITY, scheduler_names, ) from constants import ( DIRECTORY_MODELS, DIRECTORY_LORAS, DIRECTORY_VAES, DIRECTORY_EMBEDS, DIRECTORY_UPSCALERS, DOWNLOAD_MODEL, DOWNLOAD_VAE, DOWNLOAD_LORA, LOAD_DIFFUSERS_FORMAT_MODEL, DIFFUSERS_FORMAT_LORAS, DOWNLOAD_EMBEDS, CIVITAI_API_KEY, HF_TOKEN, TASK_STABLEPY, TASK_MODEL_LIST, UPSCALER_DICT_GUI, UPSCALER_KEYS, PROMPT_W_OPTIONS, WARNING_MSG_VAE, SDXL_TASK, MODEL_TYPE_TASK, POST_PROCESSING_SAMPLER, SUBTITLE_GUI, HELP_GUI, EXAMPLES_GUI_HELP, EXAMPLES_GUI, RESOURCES, DIFFUSERS_CONTROLNET_MODEL, IP_MODELS, MODE_IP_OPTIONS, CACHE_HF_ROOT, CACHE_HF, ) from stablepy.diffusers_vanilla.style_prompt_config import STYLE_NAMES import torch import re import time from PIL import ImageFile from utils import ( download_things, get_model_list, extract_parameters, get_my_lora, get_model_type, extract_exif_data, create_mask_now, download_diffuser_repo, get_used_storage_gb, delete_model, progress_step_bar, html_template_message, escape_html, clear_hf_cache, ) from image_processor import preprocessor_tab from datetime import datetime import gradio as gr import logging import diffusers import warnings from stablepy import logger from diffusers import FluxPipeline # import urllib.parse import subprocess IS_ZERO_GPU = bool(os.getenv("SPACES_ZERO_GPU")) HIDE_API = bool(os.getenv("HIDE_API")) if IS_ZERO_GPU: subprocess.run("rm -rf /data-nvme/zerogpu-offload/*", env={}, shell=True) IS_GPU_MODE = True if IS_ZERO_GPU else (True if torch.cuda.is_available() else False) img_path = "./images/" allowed_path = os.path.abspath(img_path) delete_cache_time = (9600, 9600) if IS_ZERO_GPU else (86400, 86400) ImageFile.LOAD_TRUNCATED_IMAGES = True torch.backends.cuda.matmul.allow_tf32 = True # os.environ["PYTORCH_NO_CUDA_MEMORY_CACHING"] = "1" directories = [DIRECTORY_MODELS, DIRECTORY_LORAS, DIRECTORY_VAES, DIRECTORY_EMBEDS, DIRECTORY_UPSCALERS] for directory in directories: os.makedirs(directory, exist_ok=True) # Download stuffs for url in [url.strip() for url in DOWNLOAD_MODEL.split(',')]: download_things(DIRECTORY_MODELS, url, HF_TOKEN, CIVITAI_API_KEY) for url in [url.strip() for url in DOWNLOAD_VAE.split(',')]: download_things(DIRECTORY_VAES, url, HF_TOKEN, CIVITAI_API_KEY) for url in [url.strip() for url in DOWNLOAD_LORA.split(',')]: download_things(DIRECTORY_LORAS, url, HF_TOKEN, CIVITAI_API_KEY) # Download Embeddings for url_embed in DOWNLOAD_EMBEDS: download_things(DIRECTORY_EMBEDS, url_embed, HF_TOKEN, CIVITAI_API_KEY) # Build list models embed_list = get_model_list(DIRECTORY_EMBEDS) embed_list = [ (os.path.splitext(os.path.basename(emb))[0], emb) for emb in embed_list ] single_file_model_list = get_model_list(DIRECTORY_MODELS) model_list = LOAD_DIFFUSERS_FORMAT_MODEL + single_file_model_list lora_model_list = get_model_list(DIRECTORY_LORAS) lora_model_list.insert(0, "None") lora_model_list = lora_model_list + DIFFUSERS_FORMAT_LORAS vae_model_list = get_model_list(DIRECTORY_VAES) vae_model_list.insert(0, "BakedVAE") vae_model_list.insert(0, "None") print('\033[33m🏁 Download and listing of valid models completed.\033[0m') components = None if IS_ZERO_GPU: flux_repo = "camenduru/FLUX.1-dev-diffusers" flux_pipe = FluxPipeline.from_pretrained( flux_repo, transformer=None, torch_dtype=torch.bfloat16, ).to("cuda") components = flux_pipe.components delete_model(flux_repo) ####################### # GUI ####################### logging.getLogger("diffusers").setLevel(logging.ERROR) diffusers.utils.logging.set_verbosity(40) warnings.filterwarnings(action="ignore", category=FutureWarning, module="diffusers") warnings.filterwarnings(action="ignore", category=UserWarning, module="diffusers") warnings.filterwarnings(action="ignore", category=FutureWarning, module="transformers") parser = ArgumentParser(description='DiffuseCraft: Create images from text prompts.', add_help=True) parser.add_argument("--share", action="store_true", dest="share_enabled", default=False, help="Enable sharing") parser.add_argument('--theme', type=str, default="NoCrypt/miku", help='Set the theme (default: NoCrypt/miku)') parser.add_argument("--ssr", action="store_true", help="Enable SSR (Server-Side Rendering)") parser.add_argument("--log-level", type=str, default="INFO", choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"], help="Set logging level (default: INFO)") args = parser.parse_args() logger.setLevel( "INFO" if IS_ZERO_GPU else getattr(logging, args.log_level.upper()) ) CSS = """ .contain { display: flex; flex-direction: column; } #component-0 { height: 100%; } #gallery { flex-grow: 1; } #load_model { height: 50px; } """ def lora_chk(lora_): if isinstance(lora_, str) and lora_.strip() not in ["", "None"]: return lora_ return None class GuiSD: def __init__(self, stream=True): self.model = None self.status_loading = False self.sleep_loading = 4 self.last_load = datetime.now() self.inventory = [] def update_storage_models(self, storage_floor_gb=30, required_inventory_for_purge=3): while get_used_storage_gb() > storage_floor_gb: if len(self.inventory) < required_inventory_for_purge: break removal_candidate = self.inventory.pop(0) delete_model(removal_candidate) # Cleanup after 60 seconds of inactivity lowPrioCleanup = max((datetime.now() - self.last_load).total_seconds(), 0) > 60 if lowPrioCleanup and (len(self.inventory) >= required_inventory_for_purge - 1) and not self.status_loading and get_used_storage_gb(CACHE_HF_ROOT) > (storage_floor_gb * 2): print("Cleaning up Hugging Face cache...") clear_hf_cache() self.inventory = [ m for m in self.inventory if os.path.exists(m) ] def update_inventory(self, model_name): if model_name not in single_file_model_list: self.inventory = [ m for m in self.inventory if m != model_name ] + [model_name] print(self.inventory) def load_new_model(self, model_name, vae_model, task, controlnet_model, progress=gr.Progress(track_tqdm=True)): # download link model > model_name if model_name.startswith("http"): yield f"Downloading model: {model_name}" model_name = download_things(DIRECTORY_MODELS, model_name, HF_TOKEN, CIVITAI_API_KEY) if not model_name: raise ValueError("Error retrieving model information from URL") if IS_ZERO_GPU: self.update_storage_models() vae_model = vae_model if vae_model != "None" else None model_type = get_model_type(model_name) dtype_model = torch.bfloat16 if model_type == "FLUX" else torch.float16 if not os.path.exists(model_name): logger.debug(f"model_name={model_name}, vae_model={vae_model}, task={task}, controlnet_model={controlnet_model}") _ = download_diffuser_repo( repo_name=model_name, model_type=model_type, revision="main", token=True, ) self.update_inventory(model_name) for i in range(68): if not self.status_loading: self.status_loading = True if i > 0: time.sleep(self.sleep_loading) print("Previous model ops...") break time.sleep(0.5) print(f"Waiting queue {i}") yield "Waiting queue" self.status_loading = True yield f"Loading model: {model_name}" if vae_model == "BakedVAE": vae_model = model_name elif vae_model: vae_type = "SDXL" if "sdxl" in vae_model.lower() else "SD 1.5" if model_type != vae_type: gr.Warning(WARNING_MSG_VAE) print("Loading model...") try: start_time = time.time() if self.model is None: self.model = Model_Diffusers( base_model_id=model_name, task_name=TASK_STABLEPY[task], vae_model=vae_model, type_model_precision=dtype_model, retain_task_model_in_cache=False, controlnet_model=controlnet_model, device="cpu" if IS_ZERO_GPU else None, env_components=components, ) self.model.advanced_params(image_preprocessor_cuda_active=IS_GPU_MODE) else: if self.model.base_model_id != model_name: load_now_time = datetime.now() elapsed_time = max((load_now_time - self.last_load).total_seconds(), 0) if elapsed_time <= 9: print("Waiting for the previous model's time ops...") time.sleep(9 - elapsed_time) if IS_ZERO_GPU: self.model.device = torch.device("cpu") self.model.load_pipe( model_name, task_name=TASK_STABLEPY[task], vae_model=vae_model, type_model_precision=dtype_model, retain_task_model_in_cache=False, controlnet_model=controlnet_model, ) end_time = time.time() self.sleep_loading = max(min(int(end_time - start_time), 10), 4) except Exception as e: self.last_load = datetime.now() self.status_loading = False self.sleep_loading = 4 raise e self.last_load = datetime.now() self.status_loading = False yield f"Model loaded: {model_name}" # @spaces.GPU(duration=59) @torch.inference_mode() def generate_pipeline( self, prompt, neg_prompt, num_images, steps, cfg, clip_skip, seed, lora1, lora_scale1, lora2, lora_scale2, lora3, lora_scale3, lora4, lora_scale4, lora5, lora_scale5, lora6, lora_scale6, lora7, lora_scale7, sampler, schedule_type, schedule_prediction_type, img_height, img_width, model_name, vae_model, task, image_control, preprocessor_name, preprocess_resolution, image_resolution, style_prompt, # list [] style_json_file, image_mask, strength, low_threshold, high_threshold, value_threshold, distance_threshold, recolor_gamma_correction, tile_blur_sigma, controlnet_output_scaling_in_unet, controlnet_start_threshold, controlnet_stop_threshold, textual_inversion, syntax_weights, upscaler_model_path, upscaler_increases_size, upscaler_tile_size, upscaler_tile_overlap, hires_steps, hires_denoising_strength, hires_sampler, hires_prompt, hires_negative_prompt, hires_before_adetailer, hires_after_adetailer, hires_schedule_type, hires_guidance_scale, controlnet_model, loop_generation, leave_progress_bar, disable_progress_bar, image_previews, display_images, save_generated_images, filename_pattern, image_storage_location, retain_compel_previous_load, retain_detailfix_model_previous_load, retain_hires_model_previous_load, t2i_adapter_preprocessor, t2i_adapter_conditioning_scale, t2i_adapter_conditioning_factor, enable_live_preview, freeu, generator_in_cpu, adetailer_inpaint_only, adetailer_verbose, adetailer_sampler, adetailer_active_a, prompt_ad_a, negative_prompt_ad_a, strength_ad_a, face_detector_ad_a, person_detector_ad_a, hand_detector_ad_a, mask_dilation_a, mask_blur_a, mask_padding_a, adetailer_active_b, prompt_ad_b, negative_prompt_ad_b, strength_ad_b, face_detector_ad_b, person_detector_ad_b, hand_detector_ad_b, mask_dilation_b, mask_blur_b, mask_padding_b, retain_task_cache_gui, guidance_rescale, image_ip1, mask_ip1, model_ip1, mode_ip1, scale_ip1, image_ip2, mask_ip2, model_ip2, mode_ip2, scale_ip2, pag_scale, face_restoration_model, face_restoration_visibility, face_restoration_weight, ): info_state = html_template_message("Navigating latent space...") yield info_state, gr.update(), gr.update() vae_model = vae_model if vae_model != "None" else None loras_list = [lora1, lora2, lora3, lora4, lora5, lora6, lora7] vae_msg = f"VAE: {vae_model}" if vae_model else "" msg_lora = "" logger.debug(f"Config model: {model_name}, {vae_model}, {loras_list}") task = TASK_STABLEPY[task] params_ip_img = [] params_ip_msk = [] params_ip_model = [] params_ip_mode = [] params_ip_scale = [] all_adapters = [ (image_ip1, mask_ip1, model_ip1, mode_ip1, scale_ip1), (image_ip2, mask_ip2, model_ip2, mode_ip2, scale_ip2), ] if not hasattr(self.model.pipe, "transformer"): for imgip, mskip, modelip, modeip, scaleip in all_adapters: if imgip: params_ip_img.append(imgip) if mskip: params_ip_msk.append(mskip) params_ip_model.append(modelip) params_ip_mode.append(modeip) params_ip_scale.append(scaleip) concurrency = 5 self.model.stream_config(concurrency=concurrency, latent_resize_by=1, vae_decoding=False) if task != "txt2img" and not image_control: raise ValueError("Reference image is required. Please upload one in 'Image ControlNet/Inpaint/Img2img'.") if task in ["inpaint", "repaint"] and not image_mask: raise ValueError("Mask image not found. Upload one in 'Image Mask' to proceed.") if "https://" not in str(UPSCALER_DICT_GUI[upscaler_model_path]): upscaler_model = upscaler_model_path else: url_upscaler = UPSCALER_DICT_GUI[upscaler_model_path] if not os.path.exists(f"./{DIRECTORY_UPSCALERS}/{url_upscaler.split('/')[-1]}"): download_things(DIRECTORY_UPSCALERS, url_upscaler, HF_TOKEN) upscaler_model = f"./{DIRECTORY_UPSCALERS}/{url_upscaler.split('/')[-1]}" logging.getLogger("ultralytics").setLevel(logging.INFO if adetailer_verbose else logging.ERROR) adetailer_params_A = { "face_detector_ad": face_detector_ad_a, "person_detector_ad": person_detector_ad_a, "hand_detector_ad": hand_detector_ad_a, "prompt": prompt_ad_a, "negative_prompt": negative_prompt_ad_a, "strength": strength_ad_a, # "image_list_task" : None, "mask_dilation": mask_dilation_a, "mask_blur": mask_blur_a, "mask_padding": mask_padding_a, "inpaint_only": adetailer_inpaint_only, "sampler": adetailer_sampler, } adetailer_params_B = { "face_detector_ad": face_detector_ad_b, "person_detector_ad": person_detector_ad_b, "hand_detector_ad": hand_detector_ad_b, "prompt": prompt_ad_b, "negative_prompt": negative_prompt_ad_b, "strength": strength_ad_b, # "image_list_task" : None, "mask_dilation": mask_dilation_b, "mask_blur": mask_blur_b, "mask_padding": mask_padding_b, } pipe_params = { "prompt": prompt, "negative_prompt": neg_prompt, "img_height": img_height, "img_width": img_width, "num_images": num_images, "num_steps": steps, "guidance_scale": cfg, "clip_skip": clip_skip, "pag_scale": float(pag_scale), "seed": seed, "image": image_control, "preprocessor_name": preprocessor_name, "preprocess_resolution": preprocess_resolution, "image_resolution": image_resolution, "style_prompt": style_prompt if style_prompt else "", "style_json_file": "", "image_mask": image_mask, # only for Inpaint "strength": strength, # only for Inpaint or ... "low_threshold": low_threshold, "high_threshold": high_threshold, "value_threshold": value_threshold, "distance_threshold": distance_threshold, "recolor_gamma_correction": float(recolor_gamma_correction), "tile_blur_sigma": int(tile_blur_sigma), "lora_A": lora_chk(lora1), "lora_scale_A": lora_scale1, "lora_B": lora_chk(lora2), "lora_scale_B": lora_scale2, "lora_C": lora_chk(lora3), "lora_scale_C": lora_scale3, "lora_D": lora_chk(lora4), "lora_scale_D": lora_scale4, "lora_E": lora_chk(lora5), "lora_scale_E": lora_scale5, "lora_F": lora_chk(lora6), "lora_scale_F": lora_scale6, "lora_G": lora_chk(lora7), "lora_scale_G": lora_scale7, "textual_inversion": embed_list if textual_inversion else [], "syntax_weights": syntax_weights, # "Classic" "sampler": sampler, "schedule_type": schedule_type, "schedule_prediction_type": schedule_prediction_type, "xformers_memory_efficient_attention": False, "gui_active": True, "loop_generation": loop_generation, "controlnet_conditioning_scale": float(controlnet_output_scaling_in_unet), "control_guidance_start": float(controlnet_start_threshold), "control_guidance_end": float(controlnet_stop_threshold), "generator_in_cpu": generator_in_cpu, "FreeU": freeu, "adetailer_A": adetailer_active_a, "adetailer_A_params": adetailer_params_A, "adetailer_B": adetailer_active_b, "adetailer_B_params": adetailer_params_B, "leave_progress_bar": leave_progress_bar, "disable_progress_bar": disable_progress_bar, "image_previews": image_previews, "display_images": False, "save_generated_images": save_generated_images, "filename_pattern": filename_pattern, "image_storage_location": image_storage_location, "retain_compel_previous_load": retain_compel_previous_load, "retain_detailfix_model_previous_load": retain_detailfix_model_previous_load, "retain_hires_model_previous_load": retain_hires_model_previous_load, "t2i_adapter_preprocessor": t2i_adapter_preprocessor, "t2i_adapter_conditioning_scale": float(t2i_adapter_conditioning_scale), "t2i_adapter_conditioning_factor": float(t2i_adapter_conditioning_factor), "upscaler_model_path": upscaler_model, "upscaler_increases_size": upscaler_increases_size, "upscaler_tile_size": upscaler_tile_size, "upscaler_tile_overlap": upscaler_tile_overlap, "hires_steps": hires_steps, "hires_denoising_strength": hires_denoising_strength, "hires_prompt": hires_prompt, "hires_negative_prompt": hires_negative_prompt, "hires_sampler": hires_sampler, "hires_before_adetailer": hires_before_adetailer, "hires_after_adetailer": hires_after_adetailer, "hires_schedule_type": hires_schedule_type, "hires_guidance_scale": hires_guidance_scale, "ip_adapter_image": params_ip_img, "ip_adapter_mask": params_ip_msk, "ip_adapter_model": params_ip_model, "ip_adapter_mode": params_ip_mode, "ip_adapter_scale": params_ip_scale, "face_restoration_model": face_restoration_model, "face_restoration_visibility": face_restoration_visibility, "face_restoration_weight": face_restoration_weight, } # kwargs for diffusers pipeline if guidance_rescale: pipe_params["guidance_rescale"] = guidance_rescale if IS_ZERO_GPU: self.model.device = torch.device("cuda:0") if hasattr(self.model.pipe, "transformer") and loras_list != ["None"] * self.model.num_loras: self.model.pipe.transformer.to(self.model.device) logger.debug("transformer to cuda") actual_progress = 0 info_images = gr.update() for img, [seed, image_path, metadata] in self.model(**pipe_params): info_state = progress_step_bar(actual_progress, steps) actual_progress += concurrency if image_path: info_images = f"Seeds: {str(seed)}" if vae_msg: info_images = info_images + "
" + vae_msg if "Cannot copy out of meta tensor; no data!" in self.model.last_lora_error: msg_ram = "Unable to process the LoRAs due to high RAM usage; please try again later." print(msg_ram) msg_lora += f"
{msg_ram}" for status, lora in zip(self.model.lora_status, self.model.lora_memory): if status: msg_lora += f"
Loaded: {lora}" elif status is not None: msg_lora += f"
Error with: {lora}" if msg_lora: info_images += msg_lora info_images = info_images + "
" + "GENERATION DATA:
" + escape_html(metadata[-1]) + "
-------
" download_links = "
".join( [ f'Download Image {i + 1}' for i, path in enumerate(image_path) ] ) if save_generated_images: info_images += f"
{download_links}" if not display_images: img = gr.update() info_state = "COMPLETE" elif not enable_live_preview: img = gr.update() yield info_state, img, info_images def dynamic_gpu_duration(func, duration, *args): # @torch.inference_mode() @spaces.GPU(duration=duration) def wrapped_func(): yield from func(*args) return wrapped_func() @spaces.GPU def dummy_gpu(): return None def sd_gen_generate_pipeline(*args): gpu_duration_arg = int(args[-1]) if args[-1] else 59 verbose_arg = int(args[-2]) load_lora_cpu = args[-3] generation_args = args[:-3] lora_list = [ None if item == "None" else item for item in [args[7], args[9], args[11], args[13], args[15], args[17], args[19]] ] lora_status = [None] * sd_gen.model.num_loras msg_load_lora = "Updating LoRAs in GPU..." if load_lora_cpu: msg_load_lora = "Updating LoRAs in CPU..." if lora_list != sd_gen.model.lora_memory and lora_list != [None] * sd_gen.model.num_loras: yield msg_load_lora, gr.update(), gr.update() # Load lora in CPU if load_lora_cpu: lora_status = sd_gen.model.load_lora_on_the_fly( lora_A=lora_list[0], lora_scale_A=args[8], lora_B=lora_list[1], lora_scale_B=args[10], lora_C=lora_list[2], lora_scale_C=args[12], lora_D=lora_list[3], lora_scale_D=args[14], lora_E=lora_list[4], lora_scale_E=args[16], lora_F=lora_list[5], lora_scale_F=args[18], lora_G=lora_list[6], lora_scale_G=args[20], ) print(lora_status) sampler_name = args[21] schedule_type_name = args[22] _, _, msg_sampler = check_scheduler_compatibility( sd_gen.model.class_name, sampler_name, schedule_type_name ) if msg_sampler: gr.Warning(msg_sampler) if verbose_arg: for status, lora in zip(lora_status, lora_list): if status: gr.Info(f"LoRA loaded in CPU: {lora}") elif status is not None: gr.Warning(f"Failed to load LoRA: {lora}") if lora_status == [None] * sd_gen.model.num_loras and sd_gen.model.lora_memory != [None] * sd_gen.model.num_loras and load_lora_cpu: lora_cache_msg = ", ".join( str(x) for x in sd_gen.model.lora_memory if x is not None ) gr.Info(f"LoRAs in cache: {lora_cache_msg}") msg_request = f"Requesting {gpu_duration_arg}s. of GPU time.\nModel: {sd_gen.model.base_model_id}" if verbose_arg: gr.Info(msg_request) print(msg_request) yield msg_request.replace("\n", "
"), gr.update(), gr.update() start_time = time.time() # yield from sd_gen.generate_pipeline(*generation_args) yield from dynamic_gpu_duration( sd_gen.generate_pipeline, gpu_duration_arg, *generation_args, ) end_time = time.time() execution_time = end_time - start_time msg_task_complete = ( f"GPU task complete in: {int(round(execution_time, 0) + 1)} seconds" ) if verbose_arg: gr.Info(msg_task_complete) print(msg_task_complete) yield msg_task_complete, gr.update(), gr.update() @spaces.GPU(duration=15) def process_upscale(image, upscaler_name, upscaler_size): if image is None: return None from stablepy.diffusers_vanilla.utils import save_pil_image_with_metadata from stablepy import load_upscaler_model image = image.convert("RGB") exif_image = extract_exif_data(image) name_upscaler = UPSCALER_DICT_GUI[upscaler_name] if "https://" in str(name_upscaler): if not os.path.exists(f"./{DIRECTORY_UPSCALERS}/{name_upscaler.split('/')[-1]}"): download_things(DIRECTORY_UPSCALERS, name_upscaler, HF_TOKEN) name_upscaler = f"./{DIRECTORY_UPSCALERS}/{name_upscaler.split('/')[-1]}" scaler_beta = load_upscaler_model(model=name_upscaler, tile=(0 if IS_ZERO_GPU else 192), tile_overlap=8, device=("cuda" if IS_GPU_MODE else "cpu"), half=IS_GPU_MODE) image_up = scaler_beta.upscale(image, upscaler_size, True) image_path = save_pil_image_with_metadata(image_up, f'{os.getcwd()}/up_images', exif_image) return image_path # https://huggingface.co/spaces/BestWishYsh/ConsisID-preview-Space/discussions/1#674969a022b99c122af5d407 # dynamic_gpu_duration.zerogpu = True # sd_gen_generate_pipeline.zerogpu = True sd_gen = GuiSD() with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as app: gr.Markdown("# 🧩 DiffuseCraft") gr.Markdown(SUBTITLE_GUI) with gr.Tab("Generation"): with gr.Row(): with gr.Column(scale=2): def update_task_options(model_name, task_name): new_choices = MODEL_TYPE_TASK[get_model_type(model_name)] if task_name not in new_choices: task_name = "txt2img" return gr.update(value=task_name, choices=new_choices) with gr.Accordion("Model and Task", open=True, visible=True): task_gui = gr.Dropdown(label="Task", choices=SDXL_TASK, value=TASK_MODEL_LIST[0]) model_name_gui = gr.Dropdown(label="Model", choices=model_list, value=model_list[0], allow_custom_value=True) prompt_gui = gr.Textbox(lines=5, placeholder="Enter prompt", label="Prompt") with gr.Accordion("Negative prompt", open=False, visible=True): neg_prompt_gui = gr.Textbox(lines=3, placeholder="Enter Neg prompt", label="Negative prompt", value="bad anatomy, ((many hands, bad hands, missing fingers)), anatomical nonsense, ugly, deformed, bad proportions, bad shadow, extra limbs, missing limbs, floating limbs, disconnected limbs, malformed hands, poorly drawn, mutation, mutated hands and fingers, extra legs, interlocked fingers, extra arms, disfigured face, long neck, asymmetrical eyes, lowres, extra digit, fewer digits, cropped, jpeg artifacts, signature, watermark, username, blurry, duplicate, bad composition, text, worst quality, normal quality, low quality, very displeasing, monochrome, grayscale, black and white, desaturated, low contrast, muted tones, washed out, unfinished, incomplete, draft, logo, backlighting") with gr.Row(equal_height=False): set_params_gui = gr.Button(value="↙️", variant="secondary", size="sm") clear_prompt_gui = gr.Button(value="🗑️", variant="secondary", size="sm") set_random_seed = gr.Button(value="🎲", variant="secondary", size="sm") generate_button = gr.Button(value="GENERATE IMAGE", variant="primary") model_name_gui.change( update_task_options, [model_name_gui, task_gui], [task_gui], ) load_model_gui = gr.HTML(elem_id="load_model", elem_classes="contain") result_images = gr.Gallery( label="Generated images", show_label=False, elem_id="gallery", columns=[2], rows=[2], object_fit="contain", # height="auto", interactive=False, preview=False, selected_index=50, ) actual_task_info = gr.HTML() with gr.Row(equal_height=False, variant="default", visible=IS_ZERO_GPU): gpu_duration_gui = gr.Number(minimum=5, maximum=240, value=59, show_label=False, container=False, info="GPU time duration (seconds)") with gr.Column(): verbose_info_gui = gr.Checkbox(value=False, container=False, label="Status info") load_lora_cpu_gui = gr.Checkbox(value=False, container=False, label="Load LoRAs on CPU") with gr.Column(scale=1): with gr.Accordion("Generation settings", open=True, visible=True): steps_gui = gr.Slider(minimum=1, maximum=100, step=1, value=30, label="Steps") cfg_gui = gr.Slider(minimum=0, maximum=30, step=0.5, value=7., label="CFG") sampler_gui = gr.Dropdown(label="Sampler", choices=scheduler_names, value="Euler") schedule_type_gui = gr.Dropdown(label="Schedule type", choices=SCHEDULE_TYPE_OPTIONS, value=SCHEDULE_TYPE_OPTIONS[0]) img_width_gui = gr.Slider(minimum=64, maximum=4096, step=8, value=832, label="Img Width") img_height_gui = gr.Slider(minimum=64, maximum=4096, step=8, value=1216, label="Img Height") seed_gui = gr.Number(minimum=-1, maximum=9999999999, value=-1, label="Seed") pag_scale_gui = gr.Slider(minimum=0.0, maximum=10.0, step=0.1, value=0.0, label="PAG Scale") with gr.Row(): clip_skip_gui = gr.Checkbox(value=True, label="Layer 2 Clip Skip") free_u_gui = gr.Checkbox(value=True, label="FreeU") with gr.Row(equal_height=False): num_images_gui = gr.Slider(minimum=1, maximum=(16 if IS_ZERO_GPU else 20), step=1, value=1, label="Images") prompt_syntax_gui = gr.Dropdown(label="Prompt Syntax", choices=PROMPT_W_OPTIONS, value=PROMPT_W_OPTIONS[2][1]) vae_model_gui = gr.Dropdown(label="VAE Model", choices=vae_model_list, value=vae_model_list[0]) def run_set_params_gui(base_prompt, name_model): valid_receptors = { # default values "prompt": gr.update(value=base_prompt), "neg_prompt": gr.update(value=""), "Steps": gr.update(value=30), "width": gr.update(value=1024), "height": gr.update(value=1024), "Seed": gr.update(value=-1), "Sampler": gr.update(value="Euler"), "CFG scale": gr.update(value=7.), # cfg "Clip skip": gr.update(value=True), "Model": gr.update(value=name_model), "Schedule type": gr.update(value="Automatic"), "PAG": gr.update(value=.0), "FreeU": gr.update(value=False), "Hires upscaler": gr.update(), "Hires upscale": gr.update(), "Hires steps": gr.update(), "Hires denoising strength": gr.update(), "Hires CFG": gr.update(), "Hires sampler": gr.update(), "Hires schedule type": gr.update(), "Image resolution": gr.update(value=1024), "Strength": gr.update(), "Prompt emphasis": gr.update(), } # Generate up to 7 LoRAs for i in range(1, 8): valid_receptors[f"Lora_{i}"] = gr.update() valid_receptors[f"Lora_scale_{i}"] = gr.update() valid_keys = list(valid_receptors.keys()) parameters = extract_parameters(base_prompt) # print(parameters) if "Sampler" in parameters: value_sampler = parameters["Sampler"] for s_type in SCHEDULE_TYPE_OPTIONS: if s_type in value_sampler: value_sampler = value_sampler.replace(s_type, "").strip() parameters["Sampler"] = value_sampler parameters["Schedule type"] = s_type params_lora = [] if ">" in parameters["prompt"] and "<" in parameters["prompt"]: params_lora = re.findall(r']+>', parameters["prompt"]) if "Loras" in parameters: params_lora += re.findall(r']+>', parameters["Loras"]) if params_lora: parsed_params = [] for tag_l in params_lora: try: inner = tag_l.strip("<>") # remove < > _, data_l = inner.split(":", 1) # remove the "lora:" part parts_l = data_l.split(":") name_l = parts_l[0] weight_l = float(parts_l[1]) if len(parts_l) > 1 else 1.0 # default weight = 1.0 parsed_params.append((name_l, weight_l)) except Exception as e: print(f"Error parsing LoRA tag {tag_l}: {e}") new_lora_model_list = get_model_list(DIRECTORY_LORAS) new_lora_model_list.insert(0, "None") num_lora = 1 for parsed_l, parsed_s in parsed_params: filtered_loras = [m for m in new_lora_model_list if parsed_l in m] if filtered_loras: parameters[f"Lora_{num_lora}"] = filtered_loras[0] parameters[f"Lora_scale_{num_lora}"] = parsed_s num_lora += 1 # continue = discard new value for key, val in parameters.items(): # print(val) if key in valid_keys: try: if key == "Sampler": if val not in scheduler_names: continue if key in ["Schedule type", "Hires schedule type"]: if val not in SCHEDULE_TYPE_OPTIONS: continue if key == "Hires sampler": if val not in POST_PROCESSING_SAMPLER: continue if key == "Prompt emphasis": if val not in PROMPT_WEIGHT_OPTIONS_PRIORITY: continue elif key == "Clip skip": if "," in str(val): val = val.replace(",", "") if int(val) >= 2: val = True if key == "prompt": if ">" in val and "<" in val: val = re.sub(r'<[^>]+>', '', val) # Delete html and loras print("Removed LoRA written in the prompt") if key in ["prompt", "neg_prompt"]: val = re.sub(r'\s+', ' ', re.sub(r',+', ',', val)).strip() if key in ["Steps", "width", "height", "Seed", "Hires steps", "Image resolution"]: val = int(val) if key == "FreeU": val = True if key in ["CFG scale", "PAG", "Hires upscale", "Hires denoising strength", "Hires CFG", "Strength"]: val = float(val) if key == "Model": filtered_models = [m for m in model_list if val in m] if filtered_models: val = filtered_models[0] else: val = name_model if key == "Hires upscaler": if val not in UPSCALER_KEYS: continue if key == "Seed": continue valid_receptors[key] = gr.update(value=val) # print(val, type(val)) # print(valid_receptors) except Exception as e: print(str(e)) return [value for value in valid_receptors.values()] def run_clear_prompt_gui(): return gr.update(value=""), gr.update(value="") clear_prompt_gui.click( run_clear_prompt_gui, [], [prompt_gui, neg_prompt_gui] ) def run_set_random_seed(): return -1 set_random_seed.click( run_set_random_seed, [], seed_gui ) with gr.Accordion("Hires fix", open=False, visible=True): upscaler_model_path_gui = gr.Dropdown(label="Upscaler", choices=UPSCALER_KEYS, value=UPSCALER_KEYS[0]) upscaler_increases_size_gui = gr.Slider(minimum=1.1, maximum=4., step=0.1, value=1.2, label="Upscale by") upscaler_tile_size_gui = gr.Slider(minimum=0, maximum=512, step=16, value=(0 if IS_ZERO_GPU else 192), label="Upscaler Tile Size", info="0 = no tiling") upscaler_tile_overlap_gui = gr.Slider(minimum=0, maximum=48, step=1, value=8, label="Upscaler Tile Overlap") hires_steps_gui = gr.Slider(minimum=0, value=30, maximum=100, step=1, label="Hires Steps") hires_denoising_strength_gui = gr.Slider(minimum=0.1, maximum=1.0, step=0.01, value=0.55, label="Hires Denoising Strength") hires_sampler_gui = gr.Dropdown(label="Hires Sampler", choices=POST_PROCESSING_SAMPLER, value=POST_PROCESSING_SAMPLER[0]) hires_schedule_list = ["Use same schedule type"] + SCHEDULE_TYPE_OPTIONS hires_schedule_type_gui = gr.Dropdown(label="Hires Schedule type", choices=hires_schedule_list, value=hires_schedule_list[0]) hires_guidance_scale_gui = gr.Slider(minimum=-1., maximum=30., step=0.5, value=-1., label="Hires CFG", info="If the value is -1, the main CFG will be used") hires_prompt_gui = gr.Textbox(label="Hires Prompt", placeholder="Main prompt will be use", lines=3) hires_negative_prompt_gui = gr.Textbox(label="Hires Negative Prompt", placeholder="Main negative prompt will be use", lines=3) with gr.Accordion("LoRA", open=False, visible=True): def lora_dropdown(label, visible=True): return gr.Dropdown(label=label, choices=lora_model_list, value="None", allow_custom_value=True, visible=visible) def lora_scale_slider(label, visible=True): val_lora = 8 if IS_ZERO_GPU else 10 return gr.Slider(minimum=-val_lora, maximum=val_lora, step=0.01, value=0.33, label=label, visible=visible) lora1_gui = lora_dropdown("Lora1") lora_scale_1_gui = lora_scale_slider("Lora Scale 1") lora2_gui = lora_dropdown("Lora2") lora_scale_2_gui = lora_scale_slider("Lora Scale 2") lora3_gui = lora_dropdown("Lora3") lora_scale_3_gui = lora_scale_slider("Lora Scale 3") lora4_gui = lora_dropdown("Lora4") lora_scale_4_gui = lora_scale_slider("Lora Scale 4") lora5_gui = lora_dropdown("Lora5") lora_scale_5_gui = lora_scale_slider("Lora Scale 5") lora6_gui = lora_dropdown("Lora6") lora_scale_6_gui = lora_scale_slider("Lora Scale 6") lora7_gui = lora_dropdown("Lora7") lora_scale_7_gui = lora_scale_slider("Lora Scale 7") with gr.Accordion("From URL", open=False, visible=True): text_lora = gr.Textbox( label="LoRA's download URL", placeholder="https://civitai.com/api/download/models/28907", lines=1, info="It has to be .safetensors files, and you can also download them from Hugging Face.", ) romanize_text = gr.Checkbox(value=False, label="Transliterate name", visible=(not IS_ZERO_GPU)) button_lora = gr.Button("Get and Refresh the LoRA Lists") new_lora_status = gr.HTML() button_lora.click( get_my_lora, [text_lora, romanize_text], [lora1_gui, lora2_gui, lora3_gui, lora4_gui, lora5_gui, lora6_gui, lora7_gui, new_lora_status] ) with gr.Accordion("Face restoration", open=False, visible=True): face_rest_options = [None] + FACE_RESTORATION_MODELS face_restoration_model_gui = gr.Dropdown(label="Face restoration model", choices=face_rest_options, value=face_rest_options[0]) face_restoration_visibility_gui = gr.Slider(minimum=0., maximum=1., step=0.001, value=1., label="Visibility") face_restoration_weight_gui = gr.Slider(minimum=0., maximum=1., step=0.001, value=.5, label="Weight", info="(0 = maximum effect, 1 = minimum effect)") with gr.Accordion("IP-Adapter", open=False, visible=True): with gr.Accordion("IP-Adapter 1", open=False, visible=True): image_ip1 = gr.Image(label="IP Image", type="filepath") mask_ip1 = gr.Image(label="IP Mask", type="filepath") model_ip1 = gr.Dropdown(value="plus_face", label="Model", choices=IP_MODELS) mode_ip1 = gr.Dropdown(value="original", label="Mode", choices=MODE_IP_OPTIONS) scale_ip1 = gr.Slider(minimum=0., maximum=2., step=0.01, value=0.7, label="Scale") with gr.Accordion("IP-Adapter 2", open=False, visible=True): image_ip2 = gr.Image(label="IP Image", type="filepath") mask_ip2 = gr.Image(label="IP Mask (optional)", type="filepath") model_ip2 = gr.Dropdown(value="base", label="Model", choices=IP_MODELS) mode_ip2 = gr.Dropdown(value="style", label="Mode", choices=MODE_IP_OPTIONS) scale_ip2 = gr.Slider(minimum=0., maximum=2., step=0.01, value=0.7, label="Scale") with gr.Accordion("ControlNet / Img2img / Inpaint", open=False, visible=True): image_control = gr.Image(label="Image ControlNet/Inpaint/Img2img", type="filepath") image_mask_gui = gr.Image(label="Image Mask", type="filepath") strength_gui = gr.Slider( minimum=0.01, maximum=1.0, step=0.01, value=0.55, label="Strength", info="This option adjusts the level of changes for img2img, repaint and inpaint." ) image_resolution_gui = gr.Slider( minimum=64, maximum=2048, step=64, value=1024, label="Image Resolution", info="The maximum proportional size of the generated image based on the uploaded image." ) controlnet_model_gui = gr.Dropdown(label="ControlNet model", choices=DIFFUSERS_CONTROLNET_MODEL, value=DIFFUSERS_CONTROLNET_MODEL[0], allow_custom_value=True) control_net_output_scaling_gui = gr.Slider(minimum=0, maximum=5.0, step=0.1, value=1, label="ControlNet Output Scaling in UNet") control_net_start_threshold_gui = gr.Slider(minimum=0, maximum=1, step=0.01, value=0, label="ControlNet Start Threshold (%)") control_net_stop_threshold_gui = gr.Slider(minimum=0, maximum=1, step=0.01, value=1, label="ControlNet Stop Threshold (%)") preprocessor_name_gui = gr.Dropdown(label="Preprocessor Name", choices=TASK_AND_PREPROCESSORS["canny"]) def change_preprocessor_choices(task): task = TASK_STABLEPY[task] if task in TASK_AND_PREPROCESSORS.keys(): choices_task = TASK_AND_PREPROCESSORS[task] else: choices_task = TASK_AND_PREPROCESSORS["canny"] return gr.update(choices=choices_task, value=choices_task[0]) task_gui.change( change_preprocessor_choices, [task_gui], [preprocessor_name_gui], ) preprocess_resolution_gui = gr.Slider(minimum=64, maximum=2048, step=64, value=512, label="Preprocessor Resolution") low_threshold_gui = gr.Slider(minimum=1, maximum=255, step=1, value=100, label="'CANNY' low threshold") high_threshold_gui = gr.Slider(minimum=1, maximum=255, step=1, value=200, label="'CANNY' high threshold") value_threshold_gui = gr.Slider(minimum=0.0, maximum=2.0, step=0.01, value=0.1, label="'MLSD' Hough value threshold") distance_threshold_gui = gr.Slider(minimum=0.0, maximum=20.0, step=0.01, value=0.1, label="'MLSD' Hough distance threshold") recolor_gamma_correction_gui = gr.Number(minimum=0., maximum=25., value=1., step=0.001, label="'RECOLOR' gamma correction") tile_blur_sigma_gui = gr.Number(minimum=0, maximum=100, value=9, step=1, label="'TILE' blur sigma") with gr.Accordion("T2I adapter", open=False, visible=False): t2i_adapter_preprocessor_gui = gr.Checkbox(value=True, label="T2i Adapter Preprocessor") adapter_conditioning_scale_gui = gr.Slider(minimum=0, maximum=5., step=0.1, value=1, label="Adapter Conditioning Scale") adapter_conditioning_factor_gui = gr.Slider(minimum=0, maximum=1., step=0.01, value=0.55, label="Adapter Conditioning Factor (%)") with gr.Accordion("Styles", open=False, visible=True): try: style_names_found = sd_gen.model.STYLE_NAMES except Exception: style_names_found = STYLE_NAMES style_prompt_gui = gr.Dropdown( style_names_found, multiselect=True, value=None, label="Style Prompt", interactive=True, ) style_json_gui = gr.File(label="Style JSON File") style_button = gr.Button("Load styles") def load_json_style_file(json): if not sd_gen.model: gr.Info("First load the model") return gr.update(value=None, choices=STYLE_NAMES) sd_gen.model.load_style_file(json) gr.Info(f"{len(sd_gen.model.STYLE_NAMES)} styles loaded") return gr.update(value=None, choices=sd_gen.model.STYLE_NAMES) style_button.click(load_json_style_file, [style_json_gui], [style_prompt_gui]) with gr.Accordion("Textual inversion", open=False, visible=False): active_textual_inversion_gui = gr.Checkbox(value=False, label="Active Textual Inversion in prompt") with gr.Accordion("Detailfix", open=False, visible=True): # Adetailer Inpaint Only adetailer_inpaint_only_gui = gr.Checkbox(label="Inpaint only", value=True) # Adetailer Verbose adetailer_verbose_gui = gr.Checkbox(label="Verbose", value=False) # Adetailer Sampler adetailer_sampler_gui = gr.Dropdown(label="Adetailer sampler:", choices=POST_PROCESSING_SAMPLER, value=POST_PROCESSING_SAMPLER[0]) with gr.Accordion("Detailfix A", open=False, visible=True): # Adetailer A adetailer_active_a_gui = gr.Checkbox(label="Enable Adetailer A", value=False) prompt_ad_a_gui = gr.Textbox(label="Main prompt", placeholder="Main prompt will be use", lines=3) negative_prompt_ad_a_gui = gr.Textbox(label="Negative prompt", placeholder="Main negative prompt will be use", lines=3) strength_ad_a_gui = gr.Number(label="Strength:", value=0.35, step=0.01, minimum=0.01, maximum=1.0) face_detector_ad_a_gui = gr.Checkbox(label="Face detector", value=True) person_detector_ad_a_gui = gr.Checkbox(label="Person detector", value=False) hand_detector_ad_a_gui = gr.Checkbox(label="Hand detector", value=False) mask_dilation_a_gui = gr.Number(label="Mask dilation:", value=4, minimum=1) mask_blur_a_gui = gr.Number(label="Mask blur:", value=4, minimum=1) mask_padding_a_gui = gr.Number(label="Mask padding:", value=32, minimum=1) with gr.Accordion("Detailfix B", open=False, visible=True): # Adetailer B adetailer_active_b_gui = gr.Checkbox(label="Enable Adetailer B", value=False) prompt_ad_b_gui = gr.Textbox(label="Main prompt", placeholder="Main prompt will be use", lines=3) negative_prompt_ad_b_gui = gr.Textbox(label="Negative prompt", placeholder="Main negative prompt will be use", lines=3) strength_ad_b_gui = gr.Number(label="Strength:", value=0.35, step=0.01, minimum=0.01, maximum=1.0) face_detector_ad_b_gui = gr.Checkbox(label="Face detector", value=False) person_detector_ad_b_gui = gr.Checkbox(label="Person detector", value=True) hand_detector_ad_b_gui = gr.Checkbox(label="Hand detector", value=False) mask_dilation_b_gui = gr.Number(label="Mask dilation:", value=4, minimum=1) mask_blur_b_gui = gr.Number(label="Mask blur:", value=4, minimum=1) mask_padding_b_gui = gr.Number(label="Mask padding:", value=32, minimum=1) with gr.Accordion("Other settings", open=False, visible=True): schedule_prediction_type_gui = gr.Dropdown(label="Discrete Sampling Type", choices=SCHEDULE_PREDICTION_TYPE_OPTIONS, value=SCHEDULE_PREDICTION_TYPE_OPTIONS[0]) guidance_rescale_gui = gr.Number(label="CFG rescale:", value=0., step=0.01, minimum=0., maximum=1.5) save_generated_images_gui = gr.Checkbox(value=True, label="Create a download link for the images") enable_live_preview_gui = gr.Checkbox(value=True, label="Enable live previews") display_images_gui = gr.Checkbox(value=True, label="Show final results") filename_pattern_gui = gr.Textbox(label="Filename pattern", value="model,seed", placeholder="model,seed,sampler,schedule_type,img_width,img_height,guidance_scale,num_steps,vae,prompt_section,neg_prompt_section", lines=1) hires_before_adetailer_gui = gr.Checkbox(value=False, label="Hires Before Adetailer") hires_after_adetailer_gui = gr.Checkbox(value=True, label="Hires After Adetailer") generator_in_cpu_gui = gr.Checkbox(value=False, label="Generator in CPU") with gr.Column(visible=(not IS_ZERO_GPU)): image_storage_location_gui = gr.Textbox(value=img_path, label="Image Storage Location") disable_progress_bar_gui = gr.Checkbox(value=False, label="Disable Progress Bar") leave_progress_bar_gui = gr.Checkbox(value=True, label="Leave Progress Bar") with gr.Accordion("More settings", open=False, visible=False): loop_generation_gui = gr.Slider(minimum=1, value=1, label="Loop Generation") retain_task_cache_gui = gr.Checkbox(value=False, label="Retain task model in cache") image_previews_gui = gr.Checkbox(value=True, label="Image Previews (alt)") retain_compel_previous_load_gui = gr.Checkbox(value=False, label="Retain Compel Previous Load") retain_detailfix_model_previous_load_gui = gr.Checkbox(value=False, label="Retain Detailfix Model Previous Load") retain_hires_model_previous_load_gui = gr.Checkbox(value=False, label="Retain Hires Model Previous Load") set_params_gui.click( run_set_params_gui, [prompt_gui, model_name_gui], [ prompt_gui, neg_prompt_gui, steps_gui, img_width_gui, img_height_gui, seed_gui, sampler_gui, cfg_gui, clip_skip_gui, model_name_gui, schedule_type_gui, pag_scale_gui, free_u_gui, upscaler_model_path_gui, upscaler_increases_size_gui, hires_steps_gui, hires_denoising_strength_gui, hires_guidance_scale_gui, hires_sampler_gui, hires_schedule_type_gui, image_resolution_gui, strength_gui, prompt_syntax_gui, lora1_gui, lora_scale_1_gui, lora2_gui, lora_scale_2_gui, lora3_gui, lora_scale_3_gui, lora4_gui, lora_scale_4_gui, lora5_gui, lora_scale_5_gui, lora6_gui, lora_scale_6_gui, lora7_gui, lora_scale_7_gui, ], ) with gr.Accordion("Examples and help", open=False, visible=True): gr.Markdown(HELP_GUI) gr.Markdown(EXAMPLES_GUI_HELP) gr.Examples( examples=EXAMPLES_GUI, fn=sd_gen.generate_pipeline, inputs=[ prompt_gui, neg_prompt_gui, steps_gui, cfg_gui, seed_gui, lora1_gui, lora_scale_1_gui, sampler_gui, img_height_gui, img_width_gui, model_name_gui, task_gui, image_control, image_resolution_gui, strength_gui, control_net_output_scaling_gui, control_net_start_threshold_gui, control_net_stop_threshold_gui, prompt_syntax_gui, upscaler_model_path_gui, gpu_duration_gui, load_lora_cpu_gui, ], outputs=[load_model_gui, result_images, actual_task_info], cache_examples=False, ) gr.Markdown(RESOURCES) with gr.Tab("Inpaint mask maker", render=True): with gr.Row(): with gr.Column(scale=2): image_base = gr.ImageEditor( sources=["upload", "clipboard"], # crop_size="1:1", # enable crop (or disable it) # transforms=["crop"], brush=gr.Brush( default_size="16", # or leave it as 'auto' color_mode="fixed", # 'fixed' hides the user swatches and colorpicker, 'defaults' shows it # default_color="black", # html names are supported colors=[ "rgba(0, 0, 0, 1)", # rgb(a) "rgba(0, 0, 0, 0.1)", "rgba(255, 255, 255, 0.1)", # "hsl(360, 120, 120)" # in fact any valid colorstring ] ), eraser=gr.Eraser(default_size="16"), render=True, visible=False, interactive=False, ) show_canvas = gr.Button("SHOW INPAINT CANVAS") def change_visibility_canvas(): return gr.update(visible=True, interactive=True), gr.update(visible=False) show_canvas.click(change_visibility_canvas, [], [image_base, show_canvas]) invert_mask = gr.Checkbox(value=False, label="Invert mask") btn = gr.Button("Create mask") with gr.Column(scale=1): img_source = gr.Image(interactive=False) img_result = gr.Image(label="Mask image", show_label=True, interactive=False) btn_send = gr.Button("Send to the first tab") btn.click(create_mask_now, [image_base, invert_mask], [img_source, img_result]) def send_img(img_source, img_result): return img_source, img_result btn_send.click(send_img, [img_source, img_result], [image_control, image_mask_gui]) with gr.Tab("PNG Info"): with gr.Row(): with gr.Column(): image_metadata = gr.Image(label="Image with metadata", type="pil", sources=["upload"]) with gr.Column(): result_metadata = gr.Textbox(label="Metadata", show_label=True, show_copy_button=True, interactive=False, container=True, max_lines=99) image_metadata.change( fn=extract_exif_data, inputs=[image_metadata], outputs=[result_metadata], ) with gr.Tab("Upscaler"): with gr.Row(): with gr.Column(): USCALER_TAB_KEYS = [name for name in UPSCALER_KEYS[9:]] image_up_tab = gr.Image(label="Image", type="pil", sources=["upload"]) upscaler_tab = gr.Dropdown(label="Upscaler", choices=USCALER_TAB_KEYS, value=USCALER_TAB_KEYS[5]) upscaler_size_tab = gr.Slider(minimum=1., maximum=4., step=0.1, value=1.1, label="Upscale by") generate_button_up_tab = gr.Button(value="START UPSCALE", variant="primary") with gr.Column(): result_up_tab = gr.Image(label="Result", type="pil", interactive=False, format="png") generate_button_up_tab.click( fn=process_upscale, inputs=[image_up_tab, upscaler_tab, upscaler_size_tab], outputs=[result_up_tab], ) with gr.Tab("Preprocessor", render=True): preprocessor_tab() generate_button.click( fn=sd_gen.load_new_model, inputs=[ model_name_gui, vae_model_gui, task_gui, controlnet_model_gui, ], outputs=[load_model_gui], queue=True, show_progress="minimal", api_name=(False if HIDE_API else None), ).success( fn=sd_gen_generate_pipeline, # fn=sd_gen.generate_pipeline, inputs=[ prompt_gui, neg_prompt_gui, num_images_gui, steps_gui, cfg_gui, clip_skip_gui, seed_gui, lora1_gui, lora_scale_1_gui, lora2_gui, lora_scale_2_gui, lora3_gui, lora_scale_3_gui, lora4_gui, lora_scale_4_gui, lora5_gui, lora_scale_5_gui, lora6_gui, lora_scale_6_gui, lora7_gui, lora_scale_7_gui, sampler_gui, schedule_type_gui, schedule_prediction_type_gui, img_height_gui, img_width_gui, model_name_gui, vae_model_gui, task_gui, image_control, preprocessor_name_gui, preprocess_resolution_gui, image_resolution_gui, style_prompt_gui, style_json_gui, image_mask_gui, strength_gui, low_threshold_gui, high_threshold_gui, value_threshold_gui, distance_threshold_gui, recolor_gamma_correction_gui, tile_blur_sigma_gui, control_net_output_scaling_gui, control_net_start_threshold_gui, control_net_stop_threshold_gui, active_textual_inversion_gui, prompt_syntax_gui, upscaler_model_path_gui, upscaler_increases_size_gui, upscaler_tile_size_gui, upscaler_tile_overlap_gui, hires_steps_gui, hires_denoising_strength_gui, hires_sampler_gui, hires_prompt_gui, hires_negative_prompt_gui, hires_before_adetailer_gui, hires_after_adetailer_gui, hires_schedule_type_gui, hires_guidance_scale_gui, controlnet_model_gui, loop_generation_gui, leave_progress_bar_gui, disable_progress_bar_gui, image_previews_gui, display_images_gui, save_generated_images_gui, filename_pattern_gui, image_storage_location_gui, retain_compel_previous_load_gui, retain_detailfix_model_previous_load_gui, retain_hires_model_previous_load_gui, t2i_adapter_preprocessor_gui, adapter_conditioning_scale_gui, adapter_conditioning_factor_gui, enable_live_preview_gui, free_u_gui, generator_in_cpu_gui, adetailer_inpaint_only_gui, adetailer_verbose_gui, adetailer_sampler_gui, adetailer_active_a_gui, prompt_ad_a_gui, negative_prompt_ad_a_gui, strength_ad_a_gui, face_detector_ad_a_gui, person_detector_ad_a_gui, hand_detector_ad_a_gui, mask_dilation_a_gui, mask_blur_a_gui, mask_padding_a_gui, adetailer_active_b_gui, prompt_ad_b_gui, negative_prompt_ad_b_gui, strength_ad_b_gui, face_detector_ad_b_gui, person_detector_ad_b_gui, hand_detector_ad_b_gui, mask_dilation_b_gui, mask_blur_b_gui, mask_padding_b_gui, retain_task_cache_gui, guidance_rescale_gui, image_ip1, mask_ip1, model_ip1, mode_ip1, scale_ip1, image_ip2, mask_ip2, model_ip2, mode_ip2, scale_ip2, pag_scale_gui, face_restoration_model_gui, face_restoration_visibility_gui, face_restoration_weight_gui, load_lora_cpu_gui, verbose_info_gui, gpu_duration_gui, ], outputs=[load_model_gui, result_images, actual_task_info], queue=True, show_progress="minimal", # api_name=(False if HIDE_API else None), ) if __name__ == "__main__": app.queue() app.launch( show_error=True, share=args.share_enabled, debug=True, ssr_mode=args.ssr, allowed_paths=[allowed_path], show_api=(not HIDE_API), )