Spaces:
Running
on
Zero
Running
on
Zero
import spaces | |
import gradio as gr | |
import os | |
from stablepy import Model_Diffusers | |
from stablepy.diffusers_vanilla.style_prompt_config import STYLE_NAMES | |
from stablepy.diffusers_vanilla.constants import FLUX_CN_UNION_MODES | |
import torch | |
import re | |
from huggingface_hub import HfApi | |
from stablepy import ( | |
CONTROLNET_MODEL_IDS, | |
VALID_TASKS, | |
T2I_PREPROCESSOR_NAME, | |
FLASH_LORA, | |
SCHEDULER_CONFIG_MAP, | |
scheduler_names, | |
IP_ADAPTER_MODELS, | |
IP_ADAPTERS_SD, | |
IP_ADAPTERS_SDXL, | |
REPO_IMAGE_ENCODER, | |
ALL_PROMPT_WEIGHT_OPTIONS, | |
SD15_TASKS, | |
SDXL_TASKS, | |
) | |
#import urllib.parse | |
PREPROCESSOR_CONTROLNET = { | |
"openpose": [ | |
"Openpose", | |
"None", | |
], | |
"scribble": [ | |
"HED", | |
"Pidinet", | |
"None", | |
], | |
"softedge": [ | |
"Pidinet", | |
"HED", | |
"HED safe", | |
"Pidinet safe", | |
"None", | |
], | |
"segmentation": [ | |
"UPerNet", | |
"None", | |
], | |
"depth": [ | |
"DPT", | |
"Midas", | |
"None", | |
], | |
"normalbae": [ | |
"NormalBae", | |
"None", | |
], | |
"lineart": [ | |
"Lineart", | |
"Lineart coarse", | |
"Lineart (anime)", | |
"None", | |
"None (anime)", | |
], | |
"lineart_anime": [ | |
"Lineart", | |
"Lineart coarse", | |
"Lineart (anime)", | |
"None", | |
"None (anime)", | |
], | |
"shuffle": [ | |
"ContentShuffle", | |
"None", | |
], | |
"canny": [ | |
"Canny", | |
"None", | |
], | |
"mlsd": [ | |
"MLSD", | |
"None", | |
], | |
"ip2p": [ | |
"ip2p" | |
], | |
"recolor": [ | |
"Recolor luminance", | |
"Recolor intensity", | |
"None", | |
], | |
"tile": [ | |
"Mild Blur", | |
"Moderate Blur", | |
"Heavy Blur", | |
"None", | |
], | |
} | |
TASK_STABLEPY = { | |
'txt2img': 'txt2img', | |
'img2img': 'img2img', | |
'inpaint': 'inpaint', | |
# 'canny T2I Adapter': 'sdxl_canny_t2i', # NO HAVE STEP CALLBACK PARAMETERS SO NOT WORKS WITH DIFFUSERS 0.29.0 | |
# 'sketch T2I Adapter': 'sdxl_sketch_t2i', | |
# 'lineart T2I Adapter': 'sdxl_lineart_t2i', | |
# 'depth-midas T2I Adapter': 'sdxl_depth-midas_t2i', | |
# 'openpose T2I Adapter': 'sdxl_openpose_t2i', | |
'openpose ControlNet': 'openpose', | |
'canny ControlNet': 'canny', | |
'mlsd ControlNet': 'mlsd', | |
'scribble ControlNet': 'scribble', | |
'softedge ControlNet': 'softedge', | |
'segmentation ControlNet': 'segmentation', | |
'depth ControlNet': 'depth', | |
'normalbae ControlNet': 'normalbae', | |
'lineart ControlNet': 'lineart', | |
'lineart_anime ControlNet': 'lineart_anime', | |
'shuffle ControlNet': 'shuffle', | |
'ip2p ControlNet': 'ip2p', | |
'optical pattern ControlNet': 'pattern', | |
'recolor ControlNet': 'recolor', | |
'tile ControlNet': 'tile', | |
} | |
TASK_MODEL_LIST = list(TASK_STABLEPY.keys()) | |
UPSCALER_DICT_GUI = { | |
None: None, | |
"Lanczos": "Lanczos", | |
"Nearest": "Nearest", | |
'Latent': 'Latent', | |
'Latent (antialiased)': 'Latent (antialiased)', | |
'Latent (bicubic)': 'Latent (bicubic)', | |
'Latent (bicubic antialiased)': 'Latent (bicubic antialiased)', | |
'Latent (nearest)': 'Latent (nearest)', | |
'Latent (nearest-exact)': 'Latent (nearest-exact)', | |
"RealESRGAN_x4plus": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth", | |
"RealESRNet_x4plus": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.1/RealESRNet_x4plus.pth", | |
"RealESRGAN_x4plus_anime_6B": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.2.4/RealESRGAN_x4plus_anime_6B.pth", | |
"RealESRGAN_x2plus": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.1/RealESRGAN_x2plus.pth", | |
"realesr-animevideov3": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-animevideov3.pth", | |
"realesr-general-x4v3": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-general-x4v3.pth", | |
"realesr-general-wdn-x4v3": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-general-wdn-x4v3.pth", | |
"4x-UltraSharp": "https://huggingface.co/Shandypur/ESRGAN-4x-UltraSharp/resolve/main/4x-UltraSharp.pth", | |
"4x_foolhardy_Remacri": "https://huggingface.co/FacehugmanIII/4x_foolhardy_Remacri/resolve/main/4x_foolhardy_Remacri.pth", | |
"Remacri4xExtraSmoother": "https://huggingface.co/hollowstrawberry/upscalers-backup/resolve/main/ESRGAN/Remacri%204x%20ExtraSmoother.pth", | |
"AnimeSharp4x": "https://huggingface.co/hollowstrawberry/upscalers-backup/resolve/main/ESRGAN/AnimeSharp%204x.pth", | |
"lollypop": "https://huggingface.co/hollowstrawberry/upscalers-backup/resolve/main/ESRGAN/lollypop.pth", | |
"RealisticRescaler4x": "https://huggingface.co/hollowstrawberry/upscalers-backup/resolve/main/ESRGAN/RealisticRescaler%204x.pth", | |
"NickelbackFS4x": "https://huggingface.co/hollowstrawberry/upscalers-backup/resolve/main/ESRGAN/NickelbackFS%204x.pth" | |
} | |
UPSCALER_KEYS = list(UPSCALER_DICT_GUI.keys()) | |
def download_things(directory, url, hf_token="", civitai_api_key=""): | |
url = url.strip() | |
if "drive.google.com" in url: | |
original_dir = os.getcwd() | |
os.chdir(directory) | |
os.system(f"gdown --fuzzy {url}") | |
os.chdir(original_dir) | |
elif "huggingface.co" in url: | |
url = url.replace("?download=true", "") | |
# url = urllib.parse.quote(url, safe=':/') # fix encoding | |
if "/blob/" in url: | |
url = url.replace("/blob/", "/resolve/") | |
user_header = f'"Authorization: Bearer {hf_token}"' | |
if hf_token: | |
os.system(f"aria2c --console-log-level=error --summary-interval=10 --header={user_header} -c -x 16 -k 1M -s 16 {url} -d {directory} -o {url.split('/')[-1]}") | |
else: | |
os.system(f"aria2c --optimize-concurrent-downloads --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 {url} -d {directory} -o {url.split('/')[-1]}") | |
elif "civitai.com" in url: | |
if "?" in url: | |
url = url.split("?")[0] | |
if civitai_api_key: | |
url = url + f"?token={civitai_api_key}" | |
os.system(f"aria2c --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 -d {directory} {url}") | |
else: | |
print("\033[91mYou need an API key to download Civitai models.\033[0m") | |
else: | |
os.system(f"aria2c --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 -d {directory} {url}") | |
def get_model_list(directory_path): | |
model_list = [] | |
valid_extensions = {'.ckpt', '.pt', '.pth', '.safetensors', '.bin'} | |
for filename in os.listdir(directory_path): | |
if os.path.splitext(filename)[1] in valid_extensions: | |
# name_without_extension = os.path.splitext(filename)[0] | |
file_path = os.path.join(directory_path, filename) | |
# model_list.append((name_without_extension, file_path)) | |
model_list.append(file_path) | |
print('\033[34mFILE: ' + file_path + '\033[0m') | |
return model_list | |
## BEGIN MOD | |
from modutils import (list_uniq, download_private_repo, get_model_id_list, get_tupled_embed_list, | |
get_lora_model_list, get_all_lora_tupled_list, update_loras, apply_lora_prompt, set_prompt_loras, | |
get_my_lora, upload_file_lora, move_file_lora, search_civitai_lora, select_civitai_lora, | |
set_textual_inversion_prompt, get_model_pipeline, change_interface_mode, get_t2i_model_info, | |
get_tupled_model_list, save_gallery_images, set_optimization, set_sampler_settings, | |
set_quick_presets, process_style_prompt, optimization_list, save_images, | |
preset_styles, preset_quality, preset_sampler_setting, translate_to_en) | |
from env import (HF_TOKEN, CIVITAI_API_KEY, HF_LORA_ESSENTIAL_PRIVATE_REPO, HF_VAE_PRIVATE_REPO, | |
HF_SDXL_EMBEDS_NEGATIVE_PRIVATE_REPO, HF_SDXL_EMBEDS_POSITIVE_PRIVATE_REPO, | |
directory_models, directory_loras, directory_vaes, directory_embeds, directory_embeds_sdxl, | |
directory_embeds_positive_sdxl, load_diffusers_format_model, | |
download_model_list, download_lora_list, download_vae_list, download_embeds) | |
# - **Download Models** | |
download_model = ", ".join(download_model_list) | |
# - **Download VAEs** | |
download_vae = ", ".join(download_vae_list) | |
# - **Download LoRAs** | |
download_lora = ", ".join(download_lora_list) | |
download_private_repo(HF_LORA_ESSENTIAL_PRIVATE_REPO, directory_loras, True) | |
download_private_repo(HF_VAE_PRIVATE_REPO, directory_vaes, False) | |
load_diffusers_format_model = list_uniq(get_model_id_list() + load_diffusers_format_model) | |
## END MOD | |
# Download stuffs | |
for url in [url.strip() for url in download_model.split(',')]: | |
if not os.path.exists(f"./models/{url.split('/')[-1]}"): | |
download_things(directory_models, url, HF_TOKEN, CIVITAI_API_KEY) | |
for url in [url.strip() for url in download_vae.split(',')]: | |
if not os.path.exists(f"./vaes/{url.split('/')[-1]}"): | |
download_things(directory_vaes, url, HF_TOKEN, CIVITAI_API_KEY) | |
for url in [url.strip() for url in download_lora.split(',')]: | |
if not os.path.exists(f"./loras/{url.split('/')[-1]}"): | |
download_things(directory_loras, url, HF_TOKEN, CIVITAI_API_KEY) | |
# Download Embeddings | |
for url_embed in download_embeds: | |
if not os.path.exists(f"./embedings/{url_embed.split('/')[-1]}"): | |
download_things(directory_embeds, url_embed, HF_TOKEN, CIVITAI_API_KEY) | |
# Build list models | |
embed_list = get_model_list(directory_embeds) | |
model_list = get_model_list(directory_models) | |
model_list = load_diffusers_format_model + model_list | |
## BEGIN MOD | |
lora_model_list = get_lora_model_list() | |
vae_model_list = get_model_list(directory_vaes) | |
vae_model_list.insert(0, "None") | |
download_private_repo(HF_SDXL_EMBEDS_NEGATIVE_PRIVATE_REPO, directory_embeds_sdxl, False) | |
download_private_repo(HF_SDXL_EMBEDS_POSITIVE_PRIVATE_REPO, directory_embeds_positive_sdxl, False) | |
embed_sdxl_list = get_model_list(directory_embeds_sdxl) + get_model_list(directory_embeds_positive_sdxl) | |
def get_embed_list(pipeline_name): | |
return get_tupled_embed_list(embed_sdxl_list if pipeline_name == "StableDiffusionXLPipeline" else embed_list) | |
## END MOD | |
print('\033[33m🏁 Download and listing of valid models completed.\033[0m') | |
####################### | |
# GUI | |
####################### | |
import gradio as gr | |
import logging | |
logging.getLogger("diffusers").setLevel(logging.ERROR) | |
import diffusers | |
diffusers.utils.logging.set_verbosity(40) | |
import warnings | |
warnings.filterwarnings(action="ignore", category=FutureWarning, module="diffusers") | |
warnings.filterwarnings(action="ignore", category=UserWarning, module="diffusers") | |
warnings.filterwarnings(action="ignore", category=FutureWarning, module="transformers") | |
## BEGIN MOD | |
from stablepy import logger | |
logger.setLevel(logging.CRITICAL) | |
from v2 import V2_ALL_MODELS, v2_random_prompt, v2_upsampling_prompt | |
from utils import (gradio_copy_text, COPY_ACTION_JS, gradio_copy_prompt, | |
V2_ASPECT_RATIO_OPTIONS, V2_RATING_OPTIONS, V2_LENGTH_OPTIONS, V2_IDENTITY_OPTIONS) | |
from tagger import (predict_tags_wd, convert_danbooru_to_e621_prompt, | |
remove_specific_prompt, insert_recom_prompt, insert_model_recom_prompt, | |
compose_prompt_to_copy, translate_prompt, select_random_character) | |
def description_ui(): | |
gr.Markdown( | |
""" | |
## Danbooru Tags Transformer V2 Demo with WD Tagger | |
(Image =>) Prompt => Upsampled longer prompt | |
- Mod of p1atdev's [Danbooru Tags Transformer V2 Demo](https://huggingface.co/spaces/p1atdev/danbooru-tags-transformer-v2) and [WD Tagger with 🤗 transformers](https://huggingface.co/spaces/p1atdev/wd-tagger-transformers). | |
- Models: p1atdev's [wd-swinv2-tagger-v3-hf](https://huggingface.co/p1atdev/wd-swinv2-tagger-v3-hf), [dart-v2-moe-sft](https://huggingface.co/p1atdev/dart-v2-moe-sft) | |
""" | |
) | |
## END MOD | |
msg_inc_vae = ( | |
"Use the right VAE for your model to maintain image quality. The wrong" | |
" VAE can lead to poor results, like blurriness in the generated images." | |
) | |
SDXL_TASK = [k for k, v in TASK_STABLEPY.items() if v in SDXL_TASKS] | |
SD_TASK = [k for k, v in TASK_STABLEPY.items() if v in SD15_TASKS] | |
FLUX_TASK = list(TASK_STABLEPY.keys())[:3] + [k for k, v in TASK_STABLEPY.items() if v in FLUX_CN_UNION_MODES.keys()] | |
MODEL_TYPE_TASK = { | |
"SD 1.5": SD_TASK, | |
"SDXL": SDXL_TASK, | |
"FLUX": FLUX_TASK, | |
} | |
MODEL_TYPE_CLASS = { | |
"diffusers:StableDiffusionPipeline": "SD 1.5", | |
"diffusers:StableDiffusionXLPipeline": "SDXL", | |
"diffusers:FluxPipeline": "FLUX", | |
} | |
POST_PROCESSING_SAMPLER = ["Use same sampler"] + scheduler_names[:-2] | |
SUBTITLE_GUI = ( | |
"### This demo uses [diffusers](https://github.com/huggingface/diffusers)" | |
" to perform different tasks in image generation." | |
) | |
def extract_parameters(input_string): | |
parameters = {} | |
input_string = input_string.replace("\n", "") | |
if "Negative prompt:" not in input_string: | |
print("Negative prompt not detected") | |
parameters["prompt"] = input_string | |
return parameters | |
parm = input_string.split("Negative prompt:") | |
parameters["prompt"] = parm[0] | |
if "Steps:" not in parm[1]: | |
print("Steps not detected") | |
parameters["neg_prompt"] = parm[1] | |
return parameters | |
parm = parm[1].split("Steps:") | |
parameters["neg_prompt"] = parm[0] | |
input_string = "Steps:" + parm[1] | |
# Extracting Steps | |
steps_match = re.search(r'Steps: (\d+)', input_string) | |
if steps_match: | |
parameters['Steps'] = int(steps_match.group(1)) | |
# Extracting Size | |
size_match = re.search(r'Size: (\d+x\d+)', input_string) | |
if size_match: | |
parameters['Size'] = size_match.group(1) | |
width, height = map(int, parameters['Size'].split('x')) | |
parameters['width'] = width | |
parameters['height'] = height | |
# Extracting other parameters | |
other_parameters = re.findall(r'(\w+): (.*?)(?=, \w+|$)', input_string) | |
for param in other_parameters: | |
parameters[param[0]] = param[1].strip('"') | |
return parameters | |
def info_html(json_data, title, subtitle): | |
return f""" | |
<div style='padding: 0; border-radius: 10px;'> | |
<p style='margin: 0; font-weight: bold;'>{title}</p> | |
<details> | |
<summary>Details</summary> | |
<p style='margin: 0; font-weight: bold;'>{subtitle}</p> | |
</details> | |
</div> | |
""" | |
def get_model_type(repo_id: str): | |
api = HfApi(token=os.environ.get("HF_TOKEN")) # if use private or gated model | |
default = "SD 1.5" | |
try: | |
model = api.model_info(repo_id=repo_id, timeout=5.0) | |
tags = model.tags | |
for tag in tags: | |
if tag in MODEL_TYPE_CLASS.keys(): return MODEL_TYPE_CLASS.get(tag, default) | |
except Exception: | |
return default | |
return default | |
class GuiSD: | |
def __init__(self): | |
self.model = None | |
print("Loading model...") | |
self.model = Model_Diffusers( | |
base_model_id="Lykon/dreamshaper-8", | |
task_name="txt2img", | |
vae_model=None, | |
type_model_precision=torch.float16, | |
retain_task_model_in_cache=False, | |
device="cpu", | |
) | |
def load_new_model(self, model_name, vae_model, task, progress=gr.Progress(track_tqdm=True)): | |
yield f"Loading model: {model_name}" | |
vae_model = vae_model if vae_model != "None" else None | |
model_type = get_model_type(model_name) | |
if vae_model: | |
vae_type = "SDXL" if "sdxl" in vae_model.lower() else "SD 1.5" | |
if model_type != vae_type: | |
gr.Info(msg_inc_vae) | |
self.model.device = torch.device("cpu") | |
dtype_model = torch.bfloat16 if model_type == "FLUX" else torch.float16 | |
self.model.load_pipe( | |
model_name, | |
task_name=TASK_STABLEPY[task], | |
vae_model=vae_model if vae_model != "None" else None, | |
type_model_precision=dtype_model, | |
retain_task_model_in_cache=False, | |
) | |
yield f"Model loaded: {model_name}" | |
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, | |
sampler, | |
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, | |
controlnet_output_scaling_in_unet, | |
controlnet_start_threshold, | |
controlnet_stop_threshold, | |
textual_inversion, | |
syntax_weights, | |
upscaler_model_path, | |
upscaler_increases_size, | |
esrgan_tile, | |
esrgan_tile_overlap, | |
hires_steps, | |
hires_denoising_strength, | |
hires_sampler, | |
hires_prompt, | |
hires_negative_prompt, | |
hires_before_adetailer, | |
hires_after_adetailer, | |
loop_generation, | |
leave_progress_bar, | |
disable_progress_bar, | |
image_previews, | |
display_images, | |
save_generated_images, | |
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, | |
xformers_memory_efficient_attention, | |
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, | |
image_ip1, | |
mask_ip1, | |
model_ip1, | |
mode_ip1, | |
scale_ip1, | |
image_ip2, | |
mask_ip2, | |
model_ip2, | |
mode_ip2, | |
scale_ip2, | |
pag_scale, | |
#progress=gr.Progress(track_tqdm=True), | |
): | |
#progress(0, desc="Preparing inference...") | |
vae_model = vae_model if vae_model != "None" else None | |
loras_list = [lora1, lora2, lora3, lora4, lora5] | |
vae_msg = f"VAE: {vae_model}" if vae_model else "" | |
msg_lora = [] | |
print("Config model:", model_name, vae_model, loras_list) | |
## BEGIN MOD | |
global lora_model_list | |
lora_model_list = get_lora_model_list() | |
lora1, lora_scale1, lora2, lora_scale2, lora3, lora_scale3, lora4, lora_scale4, lora5, lora_scale5 = \ | |
set_prompt_loras(prompt, syntax_weights, lora1, lora_scale1, lora2, lora_scale2, lora3, | |
lora_scale3, lora4, lora_scale4, lora5, lora_scale5) | |
prompt, neg_prompt = insert_model_recom_prompt(prompt, neg_prompt, model_name) | |
## END MOD | |
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), | |
] | |
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) | |
self.model.stream_config(concurrency=5, latent_resize_by=1, vae_decoding=False) | |
if task != "txt2img" and not image_control: | |
raise ValueError("No control image found: To use this function, you have to upload an image in 'Image ControlNet/Inpaint/Img2img'") | |
if task == "inpaint" and not image_mask: | |
raise ValueError("No mask image found: Specify one in 'Image Mask'") | |
if upscaler_model_path in UPSCALER_KEYS[:9]: | |
upscaler_model = upscaler_model_path | |
else: | |
directory_upscalers = 'upscalers' | |
os.makedirs(directory_upscalers, exist_ok=True) | |
url_upscaler = UPSCALER_DICT_GUI[upscaler_model_path] | |
if not os.path.exists(f"./upscalers/{url_upscaler.split('/')[-1]}"): | |
download_things(directory_upscalers, url_upscaler, HF_TOKEN) | |
upscaler_model = f"./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, | |
"lora_A": lora1 if lora1 != "None" else None, | |
"lora_scale_A": lora_scale1, | |
"lora_B": lora2 if lora2 != "None" else None, | |
"lora_scale_B": lora_scale2, | |
"lora_C": lora3 if lora3 != "None" else None, | |
"lora_scale_C": lora_scale3, | |
"lora_D": lora4 if lora4 != "None" else None, | |
"lora_scale_D": lora_scale4, | |
"lora_E": lora5 if lora5 != "None" else None, | |
"lora_scale_E": lora_scale5, | |
## BEGIN MOD | |
"textual_inversion": get_embed_list(self.model.class_name) if textual_inversion else [], | |
## END MOD | |
"syntax_weights": syntax_weights, # "Classic" | |
"sampler": sampler, | |
"xformers_memory_efficient_attention": xformers_memory_efficient_attention, | |
"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": display_images, | |
"save_generated_images": save_generated_images, | |
"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, | |
"esrgan_tile": esrgan_tile, | |
"esrgan_tile_overlap": esrgan_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, | |
"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, | |
} | |
self.model.device = torch.device("cuda:0") | |
if hasattr(self.model.pipe, "transformer") and loras_list != ["None"] * 5: | |
self.model.pipe.transformer.to(self.model.device) | |
print("transformer to cuda") | |
#progress(0, desc="Preparation completed. Starting inference...") | |
info_state = f"PROCESSING " | |
for img, seed, image_path, metadata in self.model(**pipe_params): | |
info_state += ">" | |
if image_path: | |
info_state = f"COMPLETED. Seeds: {str(seed)}" | |
if vae_msg: | |
info_state = info_state + "<br>" + vae_msg | |
if msg_lora: | |
info_state = info_state + "<br>" + "<br>".join(msg_lora) | |
info_state = info_state + "<br>" + "GENERATION DATA:<br>" + "<br>-------<br>".join(metadata).replace("\n", "<br>") | |
download_links = "<br>".join( | |
[ | |
f'<a href="{path.replace("/images/", "/file=/home/user/app/images/")}" download="{os.path.basename(path)}">Download Image {i + 1}</a>' | |
for i, path in enumerate(image_path) | |
] | |
) | |
if save_generated_images: info_state += f"<br>{download_links}" | |
img = save_images(img, metadata) | |
yield img, info_state | |
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) | |
# def sd_gen_generate_pipeline(*args): | |
# # Load lora in CPU | |
# status_lora = sd_gen.model.lora_merge( | |
# lora_A=args[7] if args[7] != "None" else None, lora_scale_A=args[8], | |
# lora_B=args[9] if args[9] != "None" else None, lora_scale_B=args[10], | |
# lora_C=args[11] if args[11] != "None" else None, lora_scale_C=args[12], | |
# lora_D=args[13] if args[13] != "None" else None, lora_scale_D=args[14], | |
# lora_E=args[15] if args[15] != "None" else None, lora_scale_E=args[16], | |
# ) | |
# lora_list = [args[7], args[9], args[11], args[13], args[15]] | |
# print(status_lora) | |
# for status, lora in zip(status_lora, lora_list): | |
# if status: | |
# gr.Info(f"LoRA loaded: {lora}") | |
# elif status is not None: | |
# gr.Warning(f"Failed to load LoRA: {lora}") | |
# # if status_lora == [None] * 5 and self.model.lora_memory != [None] * 5: | |
# # gr.Info(f"LoRAs in cache: {", ".join(str(x) for x in self.model.lora_memory if x is not None)}") | |
# yield from sd_gen.generate_pipeline(*args) | |
# sd_gen_generate_pipeline.zerogpu = True | |
sd_gen = GuiSD() | |
## BEGIN MOD | |
CSS =""" | |
.gradio-container, #main { width:100%; height:100%; max-width:100%; padding-left:0; padding-right:0; margin-left:0; margin-right:0; !important; } | |
.contain { display:flex; flex-direction:column; !important; } | |
#component-0 { width:100%; height:100%; !important; } | |
#gallery { flex-grow:1; !important; } | |
.lora { min-width:480px; !important; } | |
#model-info { text-align:center; } | |
""" | |
with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', elem_id="main", fill_width=True, css=CSS, delete_cache=(60, 3600)) as app: | |
gr.Markdown("# 🧩 DiffuseCraft Mod") | |
gr.Markdown( | |
f""" | |
This space is a modification of [r3gm's DiffuseCraft](https://huggingface.co/spaces/r3gm/DiffuseCraft). | |
""" | |
) | |
with gr.Column(): | |
with gr.Tab("Generation"): | |
with gr.Row(): | |
with gr.Column(scale=2): | |
interface_mode_gui = gr.Radio(label="Quick settings", choices=["Simple", "Standard", "Fast", "LoRA"], value="Standard") | |
with gr.Accordion("Model and Task", open=False) as menu_model: | |
task_gui = gr.Dropdown(label="Task", choices=SDXL_TASK, value=TASK_MODEL_LIST[0]) | |
with gr.Group(): | |
model_name_gui = gr.Dropdown(label="Model", info="You can enter a huggingface model repo_id to want to use.", choices=get_tupled_model_list(model_list), value="votepurchase/animagine-xl-3.1", allow_custom_value=True) | |
model_info_gui = gr.Markdown(elem_id="model-info") | |
with gr.Row(): | |
quick_model_type_gui = gr.Radio(label="Model Type", choices=["None", "Auto", "Animagine", "Pony"], value="Auto", interactive=True) | |
quick_genre_gui = gr.Radio(label="Genre", choices=["Anime", "Photo"], value="Anime", interactive=True) | |
quick_speed_gui = gr.Radio(label="Speed", choices=["Fast", "Standard", "Heavy"], value="Standard", interactive=True) | |
quick_aspect_gui = gr.Radio(label="Aspect Ratio", choices=["1:1", "3:4"], value="1:1", interactive=True) | |
with gr.Row(): | |
quality_selector_gui = gr.Dropdown(label="Quality Tags Presets", interactive=True, choices=list(preset_quality.keys()), value="None") | |
style_selector_gui = gr.Dropdown(label="Style Preset", interactive=True, choices=list(preset_styles.keys()), value="None") | |
sampler_selector_gui = gr.Dropdown(label="Sampler Quick Settings", interactive=True, choices=list(preset_sampler_setting.keys()), value="None") | |
optimization_gui = gr.Dropdown(label="Optimization for SDXL", choices=list(optimization_list.keys()), value="None", interactive=True) | |
with gr.Group(): | |
with gr.Accordion("Prompt from Image", open=False) as menu_from_image: | |
input_image_gui = gr.Image(label="Input image", type="pil", sources=["upload", "clipboard"], height=256) | |
with gr.Accordion(label="Advanced options", open=False): | |
with gr.Row(): | |
general_threshold_gui = gr.Slider(label="Threshold", minimum=0.0, maximum=1.0, value=0.3, step=0.01, interactive=True) | |
character_threshold_gui = gr.Slider(label="Character threshold", minimum=0.0, maximum=1.0, value=0.8, step=0.01, interactive=True) | |
with gr.Row(): | |
tag_type_gui = gr.Radio(label="Convert tags to", info="danbooru for Animagine, e621 for Pony.", choices=["danbooru", "e621"], value="danbooru") | |
recom_prompt_gui = gr.Radio(label="Insert reccomended prompt", choices=["None", "Animagine", "Pony"], value="None", interactive=True) | |
keep_tags_gui = gr.Radio(label="Remove tags leaving only the following", choices=["body", "dress", "all"], value="all") | |
image_algorithms = gr.CheckboxGroup(["Use WD Tagger"], label="Algorithms", value=["Use WD Tagger"], visible=False) | |
generate_from_image_btn_gui = gr.Button(value="GENERATE TAGS FROM IMAGE") | |
prompt_gui = gr.Textbox(lines=6, placeholder="1girl, solo, ...", label="Prompt", show_copy_button=True) | |
with gr.Accordion("Negative prompt, etc.", open=False) as menu_negative: | |
neg_prompt_gui = gr.Textbox(lines=3, placeholder="lowres, (bad), ...", label="Negative prompt", show_copy_button=True) | |
translate_prompt_button = gr.Button(value="Translate prompt to English", size="sm", variant="secondary") | |
with gr.Row(): | |
insert_prompt_gui = gr.Radio(label="Insert reccomended positive / negative prompt", choices=["None", "Auto", "Animagine", "Pony"], value="Auto", interactive=True) | |
prompt_type_gui = gr.Radio(label="Convert tags to", choices=["danbooru", "e621"], value="e621", visible=False) | |
prompt_type_button = gr.Button(value="Convert prompt to Pony e621 style", size="sm", variant="secondary") | |
with gr.Row(): | |
character_dbt = gr.Textbox(lines=1, placeholder="kafuu chino, ...", label="Character names") | |
series_dbt = gr.Textbox(lines=1, placeholder="Is the order a rabbit?, ...", label="Series names") | |
random_character_gui = gr.Button(value="Random character 🎲", size="sm", variant="secondary") | |
model_name_dbt = gr.Dropdown(label="Model", choices=list(V2_ALL_MODELS.keys()), value=list(V2_ALL_MODELS.keys())[0], visible=False) | |
aspect_ratio_dbt = gr.Radio(label="Aspect ratio", choices=list(V2_ASPECT_RATIO_OPTIONS), value="square", visible=False) | |
length_dbt = gr.Radio(label="Length", choices=list(V2_LENGTH_OPTIONS), value="very_long", visible=False) | |
identity_dbt = gr.Radio(label="Keep identity", choices=list(V2_IDENTITY_OPTIONS), value="lax", visible=False) | |
ban_tags_dbt = gr.Textbox(label="Ban tags", placeholder="alternate costumen, ...", value="futanari, censored, furry, furrification", visible=False) | |
copy_button_dbt = gr.Button(value="Copy to clipboard", visible=False) | |
rating_dbt = gr.Radio(label="Rating", choices=list(V2_RATING_OPTIONS), value="sfw") | |
generate_db_random_button = gr.Button(value="EXTEND PROMPT 🎲") | |
with gr.Row(): | |
translate_prompt_gui = gr.Button(value="Translate Prompt 📝", variant="secondary", size="sm") | |
set_random_seed = gr.Button(value="Seed 🎲", variant="secondary", size="sm") | |
set_params_gui = gr.Button(value="Params ↙️", variant="secondary", size="sm") | |
clear_prompt_gui = gr.Button(value="Clear 🗑️", variant="secondary", size="sm") | |
generate_button = gr.Button(value="GENERATE IMAGE", size="lg", variant="primary") | |
model_name_gui.change( | |
update_task_options, | |
[model_name_gui, task_gui], | |
[task_gui], | |
) | |
load_model_gui = gr.HTML() | |
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, | |
show_share_button=False, | |
show_download_button=True, | |
selected_index=50, | |
format="png", | |
) | |
result_images_files = gr.Files(interactive=False, visible=False) | |
actual_task_info = gr.HTML() | |
with gr.Column(scale=1): | |
with gr.Accordion("Generation settings", open=False, visible=True) as menu_gen: | |
with gr.Row(): | |
img_width_gui = gr.Slider(minimum=64, maximum=4096, step=8, value=1024, label="Img Width") | |
img_height_gui = gr.Slider(minimum=64, maximum=4096, step=8, value=1024, label="Img Height") | |
steps_gui = gr.Slider(minimum=1, maximum=100, step=1, value=28, label="Steps") | |
cfg_gui = gr.Slider(minimum=0, maximum=30, step=0.5, value=7.0, label="CFG") | |
with gr.Row(): | |
seed_gui = gr.Number(minimum=-1, maximum=2**32-1, value=-1, label="Seed") | |
pag_scale_gui = gr.Slider(minimum=0.0, maximum=10.0, step=0.1, value=0.0, label="PAG Scale") | |
num_images_gui = gr.Slider(minimum=1, maximum=4, step=1, value=1, label="Images") | |
clip_skip_gui = gr.Checkbox(value=False, label="Layer 2 Clip Skip") | |
free_u_gui = gr.Checkbox(value=False, label="FreeU") | |
with gr.Row(): | |
sampler_gui = gr.Dropdown(label="Sampler", choices=scheduler_names, value="Euler a") | |
vae_model_gui = gr.Dropdown(label="VAE Model", choices=vae_model_list) | |
prompt_s_options = [ | |
("Compel format: (word)weight", "Compel"), | |
("Classic format: (word:weight)", "Classic"), | |
("Classic-original format: (word:weight)", "Classic-original"), | |
("Classic-no_norm format: (word:weight)", "Classic-no_norm"), | |
("Classic-ignore", "Classic-ignore"), | |
("None", "None"), | |
] | |
prompt_syntax_gui = gr.Dropdown(label="Prompt Syntax", choices=prompt_s_options, value=prompt_s_options[1][1]) | |
with gr.Row(equal_height=False): | |
def run_set_params_gui(base_prompt): | |
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 a"), | |
"scale": gr.update(value=7.5), # cfg | |
"skip": gr.update(value=True), | |
} | |
valid_keys = list(valid_receptors.keys()) | |
parameters = extract_parameters(base_prompt) | |
for key, val in parameters.items(): | |
# print(val) | |
if key in valid_keys: | |
if key == "Sampler": | |
if val not in scheduler_names: | |
continue | |
elif key == "skip": | |
if int(val) >= 2: | |
val = True | |
if key == "prompt": | |
if ">" in val and "<" in val: | |
val = re.sub(r'<[^>]+>', '', val) | |
print("Removed LoRA written in the prompt") | |
if key in ["prompt", "neg_prompt"]: | |
val = val.strip() | |
if key in ["Steps", "width", "height", "Seed"]: | |
val = int(val) | |
if key == "scale": | |
val = float(val) | |
if key == "Seed": | |
continue | |
valid_receptors[key] = gr.update(value=val) | |
# print(val, type(val)) | |
# print(valid_receptors) | |
return [value for value in valid_receptors.values()] | |
set_params_gui.click( | |
run_set_params_gui, [prompt_gui],[ | |
prompt_gui, | |
neg_prompt_gui, | |
steps_gui, | |
img_width_gui, | |
img_height_gui, | |
seed_gui, | |
sampler_gui, | |
cfg_gui, | |
clip_skip_gui, | |
], | |
) | |
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("LoRA", open=False, visible=True) as menu_lora: | |
def lora_dropdown(label): | |
return gr.Dropdown(label=label, choices=get_all_lora_tupled_list(), value="", allow_custom_value=True, elem_classes="lora", min_width=320) | |
def lora_scale_slider(label): | |
return gr.Slider(minimum=-2, maximum=2, step=0.01, value=1.00, label=label) | |
def lora_textbox(label): | |
return gr.Textbox(label=label, info="Example of prompt:", value="None", show_copy_button=True, interactive=False, visible=False) | |
with gr.Row(): | |
with gr.Column(): | |
lora1_gui = lora_dropdown("LoRA1") | |
lora_scale_1_gui = lora_scale_slider("LoRA Scale 1") | |
with gr.Row(): | |
with gr.Group(): | |
lora1_info_gui = lora_textbox("LoRA1 prompts") | |
lora1_copy_gui = gr.Button(value="Copy example to prompt", visible=False) | |
lora1_desc_gui = gr.Markdown(value="", visible=False) | |
with gr.Column(): | |
lora2_gui = lora_dropdown("LoRA2") | |
lora_scale_2_gui = lora_scale_slider("LoRA Scale 2") | |
with gr.Row(): | |
with gr.Group(): | |
lora2_info_gui = lora_textbox("LoRA2 prompts") | |
lora2_copy_gui = gr.Button(value="Copy example to prompt", visible=False) | |
lora2_desc_gui = gr.Markdown(value="", visible=False) | |
with gr.Column(): | |
lora3_gui = lora_dropdown("LoRA3") | |
lora_scale_3_gui = lora_scale_slider("LoRA Scale 3") | |
with gr.Row(): | |
with gr.Group(): | |
lora3_info_gui = lora_textbox("LoRA3 prompts") | |
lora3_copy_gui = gr.Button(value="Copy example to prompt", visible=False) | |
lora3_desc_gui = gr.Markdown(value="", visible=False) | |
with gr.Column(): | |
lora4_gui = lora_dropdown("LoRA4") | |
lora_scale_4_gui = lora_scale_slider("LoRA Scale 4") | |
with gr.Row(): | |
with gr.Group(): | |
lora4_info_gui = lora_textbox("LoRA4 prompts") | |
lora4_copy_gui = gr.Button(value="Copy example to prompt", visible=False) | |
lora4_desc_gui = gr.Markdown(value="", visible=False) | |
with gr.Column(): | |
lora5_gui = lora_dropdown("LoRA5") | |
lora_scale_5_gui = lora_scale_slider("LoRA Scale 5") | |
with gr.Row(): | |
with gr.Group(): | |
lora5_info_gui = lora_textbox("LoRA5 prompts") | |
lora5_copy_gui = gr.Button(value="Copy example to prompt", visible=False) | |
lora5_desc_gui = gr.Markdown(value="", visible=False) | |
with gr.Accordion("From URL", open=True, visible=True): | |
with gr.Row(): | |
search_civitai_query_lora = gr.Textbox(label="Query", placeholder="oomuro sakurako...", lines=1) | |
search_civitai_basemodel_lora = gr.CheckboxGroup(label="Search LoRA for", choices=["Pony", "SD 1.5", "SDXL 1.0"], value=["Pony", "SDXL 1.0"]) | |
search_civitai_button_lora = gr.Button("Search on Civitai") | |
search_civitai_desc_lora = gr.Markdown(value="", visible=False) | |
search_civitai_result_lora = gr.Dropdown(label="Search Results", choices=[("", "")], value="", allow_custom_value=True, visible=False) | |
text_lora = gr.Textbox(label="LoRA URL", placeholder="https://civitai.com/api/download/models/28907", lines=1) | |
button_lora = gr.Button("Get and update lists of LoRAs") | |
with gr.Accordion("From Local", open=True, visible=True): | |
file_output_lora = gr.File(label="Uploaded LoRA", file_types=['.ckpt', '.pt', '.pth', '.safetensors', '.bin'], file_count="multiple", interactive=False, visible=False) | |
upload_button_lora = gr.UploadButton(label="Upload LoRA from your disk (very slow)", file_types=['.ckpt', '.pt', '.pth', '.safetensors', '.bin'], file_count="multiple") | |
with gr.Column() as menu_advanced: | |
with gr.Accordion("Hires fix", open=False, visible=True) as menu_hires: | |
upscaler_model_path_gui = gr.Dropdown(label="Upscaler", choices=UPSCALER_KEYS, value=UPSCALER_KEYS[0]) | |
with gr.Row(): | |
upscaler_increases_size_gui = gr.Slider(minimum=1.1, maximum=6., step=0.1, value=1.0, label="Upscale by") | |
esrgan_tile_gui = gr.Slider(minimum=0, value=100, maximum=500, step=1, label="ESRGAN Tile") | |
esrgan_tile_overlap_gui = gr.Slider(minimum=1, maximum=200, step=1, value=10, label="ESRGAN Tile Overlap") | |
with gr.Row(): | |
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_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("Detailfix", open=False, visible=True) as menu_detail: | |
with gr.Row(): | |
# 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=True, 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) | |
with gr.Row(): | |
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=True) | |
hand_detector_ad_a_gui = gr.Checkbox(label="Hand detector", value=False) | |
with gr.Row(): | |
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=True, 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) | |
with gr.Row(): | |
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=True) | |
person_detector_ad_b_gui = gr.Checkbox(label="Person detector", value=True) | |
hand_detector_ad_b_gui = gr.Checkbox(label="Hand detector", value=False) | |
with gr.Row(): | |
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("Textual inversion", open=False, visible=True) as menu_ti: | |
active_textual_inversion_gui = gr.Checkbox(value=False, label="Active Textual Inversion in prompt") | |
use_textual_inversion_gui = gr.CheckboxGroup(choices=get_embed_list(get_model_pipeline(model_name_gui.value)) if active_textual_inversion_gui.value else [], value=None, label="Use Textual Invertion in prompt") | |
def update_textual_inversion_gui(active_textual_inversion_gui, model_name_gui): | |
return gr.update(choices=get_embed_list(get_model_pipeline(model_name_gui)) if active_textual_inversion_gui else []) | |
active_textual_inversion_gui.change(update_textual_inversion_gui, [active_textual_inversion_gui, model_name_gui], [use_textual_inversion_gui]) | |
model_name_gui.change(update_textual_inversion_gui, [active_textual_inversion_gui, model_name_gui], [use_textual_inversion_gui]) | |
with gr.Accordion("ControlNet / Img2img / Inpaint", open=False, visible=True) as menu_i2i: | |
with gr.Row(): | |
image_control = gr.Image(label="Image ControlNet/Inpaint/Img2img", type="filepath") | |
image_mask_gui = gr.Image(label="Image Mask", type="filepath") | |
with gr.Row(): | |
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 and inpainting." | |
) | |
image_resolution_gui = gr.Slider(minimum=64, maximum=2048, step=64, value=1024, label="Image Resolution") | |
preprocessor_name_gui = gr.Dropdown(label="Preprocessor Name", choices=PREPROCESSOR_CONTROLNET["canny"]) | |
def change_preprocessor_choices(task): | |
task = TASK_STABLEPY[task] | |
if task in PREPROCESSOR_CONTROLNET.keys(): | |
choices_task = PREPROCESSOR_CONTROLNET[task] | |
else: | |
choices_task = PREPROCESSOR_CONTROLNET["canny"] | |
return gr.update(choices=choices_task, value=choices_task[0]) | |
task_gui.change( | |
change_preprocessor_choices, | |
[task_gui], | |
[preprocessor_name_gui], | |
) | |
with gr.Row(): | |
preprocess_resolution_gui = gr.Slider(minimum=64, maximum=2048, step=64, value=512, label="Preprocess 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=1, maximum=2.0, step=0.01, value=0.1, label="Hough value threshold (MLSD)") | |
with gr.Row(): | |
distance_threshold_gui = gr.Slider(minimum=1, maximum=20.0, step=0.01, value=0.1, label="Hough distance threshold (MLSD)") | |
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 (%)") | |
with gr.Accordion("IP-Adapter", open=False, visible=True) as menu_ipa: | |
IP_MODELS = sorted(list(set(IP_ADAPTERS_SD + IP_ADAPTERS_SDXL))) | |
MODE_IP_OPTIONS = ["original", "style", "layout", "style+layout"] | |
with gr.Accordion("IP-Adapter 1", open=True, visible=True): | |
with gr.Row(): | |
image_ip1 = gr.Image(label="IP Image", type="filepath") | |
mask_ip1 = gr.Image(label="IP Mask", type="filepath") | |
with gr.Row(): | |
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=True, visible=True): | |
with gr.Row(): | |
image_ip2 = gr.Image(label="IP Image", type="filepath") | |
mask_ip2 = gr.Image(label="IP Mask (optional)", type="filepath") | |
with gr.Row(): | |
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("T2I adapter", open=False, visible=True) as menu_t2i: | |
t2i_adapter_preprocessor_gui = gr.Checkbox(value=True, label="T2i Adapter Preprocessor") | |
with gr.Row(): | |
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) as menu_styles: | |
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("Other settings", open=False, visible=True) as menu_other: | |
with gr.Row(): | |
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.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=True, label="Retain task model in cache") | |
leave_progress_bar_gui = gr.Checkbox(value=True, label="Leave Progress Bar") | |
disable_progress_bar_gui = gr.Checkbox(value=False, label="Disable Progress Bar") | |
display_images_gui = gr.Checkbox(value=False, label="Display Images") | |
image_previews_gui = gr.Checkbox(value=True, label="Image Previews") | |
save_generated_images_gui = gr.Checkbox(value=False, label="Save Generated Images") | |
image_storage_location_gui = gr.Textbox(value="./images", label="Image Storage Location") | |
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") | |
xformers_memory_efficient_attention_gui = gr.Checkbox(value=False, label="Xformers Memory Efficient Attention") | |
with gr.Accordion("Examples and help", open=True, visible=True) as menu_example: | |
gr.Examples( | |
examples=[ | |
[ | |
"1girl, souryuu asuka langley, neon genesis evangelion, plugsuit, pilot suit, red bodysuit, sitting, crossing legs, black eye patch, cat hat, throne, symmetrical, looking down, from bottom, looking at viewer, outdoors, masterpiece, best quality, very aesthetic, absurdres", | |
"nsfw, lowres, (bad), text, error, fewer, extra, missing, worst quality, jpeg artifacts, low quality, watermark, unfinished, displeasing, oldest, early, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract]", | |
1, | |
30, | |
7.5, | |
True, | |
-1, | |
"Euler a", | |
1152, | |
896, | |
"votepurchase/animagine-xl-3.1", | |
], | |
[ | |
"solo, princess Zelda OOT, score_9, score_8_up, score_8, medium breasts, cute, eyelashes, cute small face, long hair, crown braid, hairclip, pointy ears, soft curvy body, looking at viewer, smile, blush, white dress, medium body, (((holding the Master Sword))), standing, deep forest in the background", | |
"score_6, score_5, score_4, busty, ugly face, mutated hands, low res, blurry face, black and white,", | |
1, | |
30, | |
5., | |
True, | |
-1, | |
"Euler a", | |
1024, | |
1024, | |
"votepurchase/ponyDiffusionV6XL", | |
], | |
[ | |
"1girl, oomuro sakurako, yuru yuri, official art, school uniform, anime artwork, anime style, vibrant, studio anime, highly detailed, masterpiece, best quality, very aesthetic, absurdres", | |
"photo, deformed, black and white, realism, disfigured, low contrast, lowres, (bad), text, error, fewer, extra, missing, worst quality, jpeg artifacts, low quality, watermark, unfinished, displeasing, oldest, early, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract]", | |
1, | |
40, | |
7.0, | |
True, | |
-1, | |
"Euler a", | |
1024, | |
1024, | |
"Raelina/Rae-Diffusion-XL-V2", | |
], | |
[ | |
"1girl, akaza akari, yuru yuri, official art, anime artwork, anime style, vibrant, studio anime, highly detailed, masterpiece, best quality, very aesthetic, absurdres", | |
"photo, deformed, black and white, realism, disfigured, low contrast, lowres, (bad), text, error, fewer, extra, missing, worst quality, jpeg artifacts, low quality, watermark, unfinished, displeasing, oldest, early, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract]", | |
1, | |
35, | |
7.0, | |
True, | |
-1, | |
"Euler a", | |
1024, | |
1024, | |
"Raelina/Raemu-XL-V4", | |
], | |
[ | |
"yoshida yuuko, machikado mazoku, 1girl, solo, demon horns,horns, school uniform, long hair, open mouth, skirt, demon girl, ahoge, shiny, shiny hair, anime artwork", | |
"nsfw, lowres, (bad), text, error, fewer, extra, missing, worst quality, jpeg artifacts, low quality, watermark, unfinished, displeasing, oldest, early, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract]", | |
1, | |
50, | |
7., | |
True, | |
-1, | |
"Euler a", | |
1024, | |
1024, | |
"votepurchase/animagine-xl-3.1", | |
], | |
], | |
fn=sd_gen.generate_pipeline, | |
inputs=[ | |
prompt_gui, | |
neg_prompt_gui, | |
num_images_gui, | |
steps_gui, | |
cfg_gui, | |
clip_skip_gui, | |
seed_gui, | |
sampler_gui, | |
img_height_gui, | |
img_width_gui, | |
model_name_gui, | |
], | |
outputs=[result_images, actual_task_info], | |
cache_examples=False, | |
#elem_id="examples", | |
) | |
## END MOD | |
with gr.Tab("Inpaint mask maker", render=True): | |
def create_mask_now(img, invert): | |
import numpy as np | |
import time | |
time.sleep(0.5) | |
transparent_image = img["layers"][0] | |
# Extract the alpha channel | |
alpha_channel = np.array(transparent_image)[:, :, 3] | |
# Create a binary mask by thresholding the alpha channel | |
binary_mask = alpha_channel > 1 | |
if invert: | |
print("Invert") | |
# Invert the binary mask so that the drawn shape is white and the rest is black | |
binary_mask = np.invert(binary_mask) | |
# Convert the binary mask to a 3-channel RGB mask | |
rgb_mask = np.stack((binary_mask,) * 3, axis=-1) | |
# Convert the mask to uint8 | |
rgb_mask = rgb_mask.astype(np.uint8) * 255 | |
return img["background"], rgb_mask | |
with gr.Row(): | |
with gr.Column(scale=2): | |
# image_base = gr.ImageEditor(label="Base image", show_label=True, brush=gr.Brush(colors=["#000000"])) | |
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") | |
) | |
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]) | |
## BEGIN MOD | |
interface_mode_gui.change( | |
change_interface_mode, | |
[interface_mode_gui], | |
[menu_model, menu_from_image, menu_negative, menu_gen, menu_hires, menu_lora, menu_advanced, | |
menu_example, task_gui, quick_speed_gui], | |
queue=False, | |
) | |
model_name_gui.change(get_t2i_model_info, [model_name_gui], [model_info_gui], queue=False) | |
translate_prompt_gui.click(translate_to_en, [prompt_gui], [prompt_gui], queue=False)\ | |
.then(translate_to_en, [neg_prompt_gui], [neg_prompt_gui], queue=False) | |
gr.on( | |
triggers=[quick_model_type_gui.change, quick_genre_gui.change, quick_speed_gui.change, quick_aspect_gui.change], | |
fn=set_quick_presets, | |
inputs=[quick_genre_gui, quick_model_type_gui, quick_speed_gui, quick_aspect_gui], | |
outputs=[quality_selector_gui, style_selector_gui, sampler_selector_gui, optimization_gui, insert_prompt_gui], | |
queue=False, | |
trigger_mode="once", | |
) | |
gr.on( | |
triggers=[quality_selector_gui.change, style_selector_gui.change, insert_prompt_gui.change], | |
fn=process_style_prompt, | |
inputs=[prompt_gui, neg_prompt_gui, style_selector_gui, quality_selector_gui, insert_prompt_gui], | |
outputs=[prompt_gui, neg_prompt_gui, quick_model_type_gui], | |
queue=False, | |
trigger_mode="once", | |
) | |
sampler_selector_gui.change(set_sampler_settings, [sampler_selector_gui], [sampler_gui, steps_gui, cfg_gui, clip_skip_gui, img_width_gui, img_height_gui, optimization_gui], queue=False) | |
optimization_gui.change(set_optimization, [optimization_gui, steps_gui, cfg_gui, sampler_gui, clip_skip_gui, lora5_gui, lora_scale_5_gui], [steps_gui, cfg_gui, sampler_gui, clip_skip_gui, lora5_gui, lora_scale_5_gui], queue=False) | |
gr.on( | |
triggers=[lora1_gui.change, lora_scale_1_gui.change, lora2_gui.change, lora_scale_2_gui.change, | |
lora3_gui.change, lora_scale_3_gui.change, lora4_gui.change, lora_scale_4_gui.change, | |
lora5_gui.change, lora_scale_5_gui.change, prompt_syntax_gui.change], | |
fn=update_loras, | |
inputs=[prompt_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], | |
outputs=[prompt_gui, lora1_gui, lora_scale_1_gui, lora1_info_gui, lora1_copy_gui, lora1_desc_gui, | |
lora2_gui, lora_scale_2_gui, lora2_info_gui, lora2_copy_gui, lora2_desc_gui, | |
lora3_gui, lora_scale_3_gui, lora3_info_gui, lora3_copy_gui, lora3_desc_gui, | |
lora4_gui, lora_scale_4_gui, lora4_info_gui, lora4_copy_gui, lora4_desc_gui, | |
lora5_gui, lora_scale_5_gui, lora5_info_gui, lora5_copy_gui, lora5_desc_gui], | |
queue=False, | |
trigger_mode="once", | |
) | |
lora1_copy_gui.click(apply_lora_prompt, [prompt_gui, lora1_info_gui], [prompt_gui], queue=False) | |
lora2_copy_gui.click(apply_lora_prompt, [prompt_gui, lora2_info_gui], [prompt_gui], queue=False) | |
lora3_copy_gui.click(apply_lora_prompt, [prompt_gui, lora3_info_gui], [prompt_gui], queue=False) | |
lora4_copy_gui.click(apply_lora_prompt, [prompt_gui, lora4_info_gui], [prompt_gui], queue=False) | |
lora5_copy_gui.click(apply_lora_prompt, [prompt_gui, lora5_info_gui], [prompt_gui], queue=False) | |
gr.on( | |
triggers=[search_civitai_button_lora.click, search_civitai_query_lora.submit], | |
fn=search_civitai_lora, | |
inputs=[search_civitai_query_lora, search_civitai_basemodel_lora], | |
outputs=[search_civitai_result_lora, search_civitai_desc_lora, search_civitai_button_lora, search_civitai_query_lora], | |
queue=True, | |
scroll_to_output=True, | |
) | |
search_civitai_result_lora.change(select_civitai_lora, [search_civitai_result_lora], [text_lora, search_civitai_desc_lora], queue=False, scroll_to_output=True) | |
button_lora.click(get_my_lora, [text_lora], [lora1_gui, lora2_gui, lora3_gui, lora4_gui, lora5_gui], scroll_to_output=True) | |
upload_button_lora.upload(upload_file_lora, [upload_button_lora], [file_output_lora, upload_button_lora]).success( | |
move_file_lora, [file_output_lora], [lora1_gui, lora2_gui, lora3_gui, lora4_gui, lora5_gui], scroll_to_output=True) | |
use_textual_inversion_gui.change(set_textual_inversion_prompt, [use_textual_inversion_gui, prompt_gui, neg_prompt_gui, prompt_syntax_gui], [prompt_gui, neg_prompt_gui]) | |
generate_from_image_btn_gui.click( | |
lambda: ("", "", ""), None, [series_dbt, character_dbt, prompt_gui], queue=False, | |
).success( | |
predict_tags_wd, | |
[input_image_gui, prompt_gui, image_algorithms, general_threshold_gui, character_threshold_gui], | |
[series_dbt, character_dbt, prompt_gui, copy_button_dbt], | |
).success( | |
compose_prompt_to_copy, [character_dbt, series_dbt, prompt_gui], [prompt_gui], queue=False, | |
).success( | |
remove_specific_prompt, [prompt_gui, keep_tags_gui], [prompt_gui], queue=False, | |
).success( | |
convert_danbooru_to_e621_prompt, [prompt_gui, tag_type_gui], [prompt_gui], queue=False, | |
).success( | |
insert_recom_prompt, [prompt_gui, neg_prompt_gui, recom_prompt_gui], [prompt_gui, neg_prompt_gui], queue=False, | |
) | |
prompt_type_button.click(convert_danbooru_to_e621_prompt, [prompt_gui, prompt_type_gui], [prompt_gui], queue=False) | |
random_character_gui.click(select_random_character, [series_dbt, character_dbt], [series_dbt, character_dbt], queue=False) | |
generate_db_random_button.click( | |
v2_random_prompt, | |
[prompt_gui, series_dbt, character_dbt, | |
rating_dbt, aspect_ratio_dbt, length_dbt, identity_dbt, ban_tags_dbt, model_name_dbt], | |
[prompt_gui, series_dbt, character_dbt], | |
).success( | |
convert_danbooru_to_e621_prompt, [prompt_gui, tag_type_gui], [prompt_gui], queue=False, | |
) | |
translate_prompt_button.click(translate_prompt, [prompt_gui], [prompt_gui], queue=False) | |
translate_prompt_button.click(translate_prompt, [character_dbt], [character_dbt], queue=False) | |
translate_prompt_button.click(translate_prompt, [series_dbt], [series_dbt], queue=False) | |
generate_button.click( | |
fn=sd_gen.load_new_model, | |
inputs=[ | |
model_name_gui, | |
vae_model_gui, | |
task_gui | |
], | |
outputs=[load_model_gui], | |
queue=True, | |
show_progress="minimal", | |
).success( | |
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, | |
sampler_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, | |
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, | |
esrgan_tile_gui, | |
esrgan_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, | |
loop_generation_gui, | |
leave_progress_bar_gui, | |
disable_progress_bar_gui, | |
image_previews_gui, | |
display_images_gui, | |
save_generated_images_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, | |
xformers_memory_efficient_attention_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, | |
image_ip1, | |
mask_ip1, | |
model_ip1, | |
mode_ip1, | |
scale_ip1, | |
image_ip2, | |
mask_ip2, | |
model_ip2, | |
mode_ip2, | |
scale_ip2, | |
pag_scale_gui, | |
], | |
outputs=[result_images, actual_task_info], | |
queue=True, | |
show_progress="full", | |
).success(save_gallery_images, [result_images], [result_images, result_images_files, result_images_files], queue=False, show_api=False) | |
with gr.Tab("Danbooru Tags Transformer with WD Tagger", render=True): | |
with gr.Column(scale=2): | |
with gr.Group(): | |
input_image = gr.Image(label="Input image", type="pil", sources=["upload", "clipboard"], height=256) | |
with gr.Accordion(label="Advanced options", open=False): | |
general_threshold = gr.Slider(label="Threshold", minimum=0.0, maximum=1.0, value=0.3, step=0.01, interactive=True) | |
character_threshold = gr.Slider(label="Character threshold", minimum=0.0, maximum=1.0, value=0.8, step=0.01, interactive=True) | |
input_tag_type = gr.Radio(label="Convert tags to", info="danbooru for Animagine, e621 for Pony.", choices=["danbooru", "e621"], value="danbooru") | |
recom_prompt = gr.Radio(label="Insert reccomended prompt", choices=["None", "Animagine", "Pony"], value="None", interactive=True) | |
image_algorithms = gr.CheckboxGroup(["Use WD Tagger"], label="Algorithms", value=["Use WD Tagger"], visible=False) | |
keep_tags = gr.Radio(label="Remove tags leaving only the following", choices=["body", "dress", "all"], value="all") | |
generate_from_image_btn = gr.Button(value="GENERATE TAGS FROM IMAGE", size="lg", variant="primary") | |
with gr.Group(): | |
with gr.Row(): | |
input_character = gr.Textbox(label="Character tags", placeholder="hatsune miku") | |
input_copyright = gr.Textbox(label="Copyright tags", placeholder="vocaloid") | |
pick_random_character = gr.Button(value="Random character 🎲", size="sm") | |
input_general = gr.TextArea(label="General tags", lines=4, placeholder="1girl, ...", value="") | |
input_tags_to_copy = gr.Textbox(value="", visible=False) | |
with gr.Row(): | |
copy_input_btn = gr.Button(value="Copy to clipboard", size="sm", interactive=False) | |
copy_prompt_btn_input = gr.Button(value="Copy to primary prompt", size="sm", interactive=False) | |
translate_input_prompt_button = gr.Button(value="Translate prompt to English", size="sm", variant="secondary") | |
tag_type = gr.Radio(label="Output tag conversion", info="danbooru for Animagine, e621 for Pony.", choices=["danbooru", "e621"], value="e621", visible=False) | |
input_rating = gr.Radio(label="Rating", choices=list(V2_RATING_OPTIONS), value="explicit") | |
with gr.Accordion(label="Advanced options", open=False): | |
input_aspect_ratio = gr.Radio(label="Aspect ratio", info="The aspect ratio of the image.", choices=list(V2_ASPECT_RATIO_OPTIONS), value="square") | |
input_length = gr.Radio(label="Length", info="The total length of the tags.", choices=list(V2_LENGTH_OPTIONS), value="very_long") | |
input_identity = gr.Radio(label="Keep identity", info="How strictly to keep the identity of the character or subject. If you specify the detail of subject in the prompt, you should choose `strict`. Otherwise, choose `none` or `lax`. `none` is very creative but sometimes ignores the input prompt.", choices=list(V2_IDENTITY_OPTIONS), value="lax") | |
input_ban_tags = gr.Textbox(label="Ban tags", info="Tags to ban from the output.", placeholder="alternate costumen, ...", value="censored") | |
model_name = gr.Dropdown(label="Model", choices=list(V2_ALL_MODELS.keys()), value=list(V2_ALL_MODELS.keys())[0]) | |
dummy_np = gr.Textbox(label="Negative prompt", value="", visible=False) | |
recom_animagine = gr.Textbox(label="Animagine reccomended prompt", value="Animagine", visible=False) | |
recom_pony = gr.Textbox(label="Pony reccomended prompt", value="Pony", visible=False) | |
generate_btn = gr.Button(value="GENERATE TAGS", size="lg", variant="primary") | |
with gr.Row(): | |
with gr.Group(): | |
output_text = gr.TextArea(label="Output tags", interactive=False, show_copy_button=True) | |
with gr.Row(): | |
copy_btn = gr.Button(value="Copy to clipboard", size="sm", interactive=False) | |
copy_prompt_btn = gr.Button(value="Copy to primary prompt", size="sm", interactive=False) | |
with gr.Group(): | |
output_text_pony = gr.TextArea(label="Output tags (Pony e621 style)", interactive=False, show_copy_button=True) | |
with gr.Row(): | |
copy_btn_pony = gr.Button(value="Copy to clipboard", size="sm", interactive=False) | |
copy_prompt_btn_pony = gr.Button(value="Copy to primary prompt", size="sm", interactive=False) | |
description_ui() | |
translate_input_prompt_button.click(translate_prompt, inputs=[input_general], outputs=[input_general], queue=False) | |
translate_input_prompt_button.click(translate_prompt, inputs=[input_character], outputs=[input_character], queue=False) | |
translate_input_prompt_button.click(translate_prompt, inputs=[input_copyright], outputs=[input_copyright], queue=False) | |
generate_from_image_btn.click( | |
lambda: ("", "", ""), None, [input_copyright, input_character, input_general], queue=False, | |
).success( | |
predict_tags_wd, | |
[input_image, input_general, image_algorithms, general_threshold, character_threshold], | |
[input_copyright, input_character, input_general, copy_input_btn], | |
).success( | |
remove_specific_prompt, inputs=[input_general, keep_tags], outputs=[input_general], queue=False, | |
).success( | |
convert_danbooru_to_e621_prompt, inputs=[input_general, input_tag_type], outputs=[input_general], queue=False, | |
).success( | |
insert_recom_prompt, inputs=[input_general, dummy_np, recom_prompt], outputs=[input_general, dummy_np], queue=False, | |
).success(lambda: gr.update(interactive=True), None, [copy_prompt_btn_input], queue=False) | |
copy_input_btn.click(compose_prompt_to_copy, inputs=[input_character, input_copyright, input_general], outputs=[input_tags_to_copy])\ | |
.success(gradio_copy_text, inputs=[input_tags_to_copy], js=COPY_ACTION_JS) | |
copy_prompt_btn_input.click(compose_prompt_to_copy, inputs=[input_character, input_copyright, input_general], outputs=[input_tags_to_copy])\ | |
.success(gradio_copy_prompt, inputs=[input_tags_to_copy], outputs=[prompt_gui]) | |
pick_random_character.click(select_random_character, [input_copyright, input_character], [input_copyright, input_character]) | |
generate_btn.click( | |
v2_upsampling_prompt, | |
[model_name, input_copyright, input_character, input_general, | |
input_rating, input_aspect_ratio, input_length, input_identity, input_ban_tags], | |
[output_text], | |
).success( | |
convert_danbooru_to_e621_prompt, inputs=[output_text, tag_type], outputs=[output_text_pony], queue=False, | |
).success( | |
insert_recom_prompt, inputs=[output_text, dummy_np, recom_animagine], outputs=[output_text, dummy_np], queue=False, | |
).success( | |
insert_recom_prompt, inputs=[output_text_pony, dummy_np, recom_pony], outputs=[output_text_pony, dummy_np], queue=False, | |
).success(lambda: (gr.update(interactive=True), gr.update(interactive=True), gr.update(interactive=True), gr.update(interactive=True)), | |
None, [copy_btn, copy_btn_pony, copy_prompt_btn, copy_prompt_btn_pony], queue=False) | |
copy_btn.click(gradio_copy_text, inputs=[output_text], js=COPY_ACTION_JS) | |
copy_btn_pony.click(gradio_copy_text, inputs=[output_text_pony], js=COPY_ACTION_JS) | |
copy_prompt_btn.click(gradio_copy_prompt, inputs=[output_text], outputs=[prompt_gui]) | |
copy_prompt_btn_pony.click(gradio_copy_prompt, inputs=[output_text_pony], outputs=[prompt_gui]) | |
gr.LoginButton() | |
gr.DuplicateButton(value="Duplicate Space for private use (This demo does not work on CPU. Requires GPU Space)") | |
app.queue() | |
app.launch() # allowed_paths=["./images/"], show_error=True, debug=True | |
## END MOD | |