Spaces:
Runtime error
Runtime error
import spaces | |
import os | |
from stablepy.diffusers_vanilla.style_prompt_config import STYLE_NAMES | |
import re | |
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, | |
) | |
from config import ( | |
DEFAULT_STEPS, | |
DEFAULT_CFG, | |
MINIMUM_IMAGE_NUMBER, | |
MAXIMUM_IMAGE_NUMBER, | |
DEFAULT_NEGATIVE_PROMPT, | |
DEFAULT_POSITIVE_PROMPT, | |
task_stablepy | |
) | |
from models.vae import VAE_LIST as download_vae | |
from models.checkpoints import CHECKPOINT_LIST as download_model | |
from models.loras import LORA_LIST as download_lora | |
from models.format_models import FORMAT_MODELS as load_diffusers_format_model | |
from models.upscaler import upscaler_dict_gui | |
from models.controlnet import preprocessor_controlnet | |
from models.embeds import download_embeds | |
from examples.examples import example_prompts | |
from utils.download_utils import download_things | |
from utils.model_utils import get_model_list | |
import gradio as gr | |
import logging | |
from utils.string_utils import extract_parameters | |
from stablepy import logger | |
import diffusers | |
import warnings | |
from gui import GuiSD | |
# LOAD ALL ENV TOKEN | |
CIVITAI_API_KEY: str = os.environ.get("CIVITAI_API_KEY") | |
hf_token: str = os.environ.get("HF_TOKEN") | |
task_model_list = list(task_stablepy.keys()) | |
# [Create directories] | |
directory_models: str = 'models' | |
os.makedirs( | |
directory_models, | |
exist_ok=True | |
) | |
directory_loras: str = 'loras' | |
os.makedirs( | |
directory_loras, | |
exist_ok=True | |
) | |
directory_vaes: str = 'vaes' | |
os.makedirs( | |
directory_vaes, | |
exist_ok=True | |
) | |
directory_embeds: str = 'embedings' | |
os.makedirs( | |
directory_embeds, | |
exist_ok=True | |
) | |
# 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 | |
) | |
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: list = get_model_list(directory_embeds) | |
model_list: list = get_model_list(directory_models) | |
model_list: list = load_diffusers_format_model + model_list | |
lora_model_list: list = get_model_list(directory_loras) | |
lora_model_list.insert(0, "None") | |
vae_model_list: list = get_model_list(directory_vaes) | |
vae_model_list.insert(0, "None") | |
def get_my_lora(link_url) -> tuple: | |
for __url in [_url.strip() for _url in link_url.split(',')]: | |
if not os.path.exists(f"./loras/{__url.split('/')[-1]}"): | |
download_things( | |
directory_loras, | |
__url, | |
hf_token, | |
CIVITAI_API_KEY | |
) | |
new_lora_model_list: list = get_model_list(directory_loras) | |
new_lora_model_list.insert(0, "None") | |
return gr.update( | |
choices=new_lora_model_list | |
), gr.update( | |
choices=new_lora_model_list | |
), gr.update( | |
choices=new_lora_model_list | |
), gr.update( | |
choices=new_lora_model_list | |
), gr.update( | |
choices=new_lora_model_list | |
) | |
print('\033[33m🏁 Download and listing of valid models completed.\033[0m') | |
####################### | |
# 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" | |
) | |
logger.setLevel(logging.DEBUG) | |
# init GuiSD | |
SD_GEN: GuiSD = GuiSD( | |
model_list=model_list, | |
task_stablepy=task_stablepy, | |
lora_model_list=lora_model_list, | |
embed_list=embed_list, | |
) | |
with open("app.css", "r") as f: | |
CSS: str = f.read() | |
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] | |
def update_task_options( | |
model_name: str, | |
task_name: str): | |
""" | |
:param model_name: | |
:param task_name: | |
:return: | |
""" | |
if model_name in model_list: | |
if "xl" in model_name.lower(): | |
new_choices = sdxl_task | |
else: | |
new_choices = sd_task | |
if task_name not in new_choices: | |
task_name = "txt2img" | |
return gr.update( | |
value=task_name, | |
choices=new_choices | |
) | |
else: | |
return gr.update( | |
value=task_name, | |
choices=task_model_list | |
) | |
# APP | |
with gr.Blocks(css=CSS) as app: | |
gr.Markdown("# 🧩 (Ivan) DiffuseCraft") | |
with gr.Tab("Generation"): | |
with gr.Row(): | |
with gr.Column(scale=2): | |
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="models/animaPencilXL_v500.safetensors" or model_list[0], | |
allow_custom_value=True | |
) | |
prompt_gui = gr.Textbox( | |
lines=5, | |
placeholder="Enter Positive prompt", | |
label="Positive Prompt", | |
value=DEFAULT_POSITIVE_PROMPT | |
) | |
neg_prompt_gui = gr.Textbox( | |
lines=3, | |
placeholder="Enter Negative prompt", | |
label="Negative prompt", | |
value=DEFAULT_NEGATIVE_PROMPT | |
) | |
with gr.Row(equal_height=False): | |
set_params_gui = gr.Button(value="↙️") | |
clear_prompt_gui = gr.Button(value="🗑️") | |
set_random_seed = gr.Button(value="🎲") | |
generate_button = gr.Button( | |
value="GENERATE", | |
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, | |
selected_index=50, | |
) | |
actual_task_info = gr.HTML() | |
with gr.Column(scale=1): | |
steps_gui = gr.Slider( | |
minimum=1, | |
maximum=100, | |
step=1, | |
value=DEFAULT_STEPS, | |
label="Steps" | |
) | |
cfg_gui = gr.Slider( | |
minimum=0, | |
maximum=30, | |
step=0.5, | |
value=DEFAULT_CFG, | |
label="CFG" | |
) | |
sampler_gui = gr.Dropdown( | |
label="Sampler", | |
choices=scheduler_names, | |
value="DPM++ 2M Karras" | |
) | |
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" | |
) | |
seed_gui = gr.Number( | |
minimum=-1, | |
maximum=9999999999, | |
value=-1, | |
label="Seed" | |
) | |
with gr.Row(): | |
clip_skip_gui = gr.Checkbox( | |
value=False, | |
label="Layer 2 Clip Skip" | |
) | |
free_u_gui = gr.Checkbox( | |
value=True, | |
label="FreeU" | |
) | |
with gr.Row(equal_height=False): | |
def run_set_params_gui(base_prompt): | |
valid_receptors: dict = { # 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: dict = extract_parameters(base_prompt) | |
for key, val in parameters.items(): | |
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) | |
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 | |
) | |
num_images_gui = gr.Slider( | |
minimum=MINIMUM_IMAGE_NUMBER, | |
maximum=MAXIMUM_IMAGE_NUMBER, | |
step=1, | |
value=1, | |
label="Images" | |
) | |
prompt_s_options = [ | |
("Classic format: (word:weight)", "Classic"), | |
("Compel format: (word)weight", "Compel"), | |
("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[0][1] | |
) | |
vae_model_gui = gr.Dropdown( | |
label="VAE Model", | |
choices=vae_model_list, | |
value=vae_model_list[1] | |
) | |
with gr.Accordion( | |
"Hires fix", | |
open=False, | |
visible=True): | |
upscaler_keys = list(upscaler_dict_gui.keys()) | |
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=6., | |
step=0.1, | |
value=1.4, | |
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" | |
) | |
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=["Use same sampler"] + scheduler_names[:-1], | |
value="Use same sampler" | |
) | |
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): | |
lora1_gui = gr.Dropdown( | |
label="Lora1", | |
choices=lora_model_list | |
) | |
lora_scale_1_gui = gr.Slider( | |
minimum=-2, | |
maximum=2, | |
step=0.01, | |
value=0.33, | |
label="Lora Scale 1" | |
) | |
lora2_gui = gr.Dropdown( | |
label="Lora2", | |
choices=lora_model_list | |
) | |
lora_scale_2_gui = gr.Slider( | |
minimum=-2, | |
maximum=2, | |
step=0.01, | |
value=0.33, | |
label="Lora Scale 2" | |
) | |
lora3_gui = gr.Dropdown( | |
label="Lora3", | |
choices=lora_model_list | |
) | |
lora_scale_3_gui = gr.Slider( | |
minimum=-2, | |
maximum=2, | |
step=0.01, | |
value=0.33, | |
label="Lora Scale 3" | |
) | |
lora4_gui = gr.Dropdown( | |
label="Lora4", | |
choices=lora_model_list | |
) | |
lora_scale_4_gui = gr.Slider( | |
minimum=-2, | |
maximum=2, | |
step=0.01, | |
value=0.33, | |
label="Lora Scale 4" | |
) | |
lora5_gui = gr.Dropdown( | |
label="Lora5", | |
choices=lora_model_list | |
) | |
lora_scale_5_gui = gr.Slider( | |
minimum=-2, | |
maximum=2, | |
step=0.01, | |
value=0.33, | |
label="Lora Scale 5" | |
) | |
with gr.Accordion( | |
"From URL", | |
open=False, | |
visible=True): | |
text_lora = gr.Textbox( | |
label="URL", | |
placeholder="http://...my_lora_url.safetensors", | |
lines=1 | |
) | |
button_lora = gr.Button("Get and update lists of LoRAs") | |
button_lora.click( | |
get_my_lora, | |
[text_lora], | |
[ | |
lora1_gui, | |
lora2_gui, | |
lora3_gui, | |
lora4_gui, | |
lora5_gui | |
] | |
) | |
with gr.Accordion( | |
"IP-Adapter", | |
open=False, | |
visible=True): # IP-Adapter | |
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=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 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], | |
) | |
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)" | |
) | |
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( | |
"T2I adapter", | |
open=False, | |
visible=True): | |
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): | |
# noinspection PyBroadException | |
try: | |
style_names_found = SD_GEN.model.STYLE_NAMES | |
except Exception as e: | |
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_options = ["Use same sampler"] + scheduler_names[:-1] | |
adetailer_sampler_gui = gr.Dropdown( | |
label="Adetailer sampler:", | |
choices=adetailer_sampler_options, | |
value="Use same sampler" | |
) | |
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=True | |
) | |
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=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 | |
) | |
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): | |
image_previews_gui = gr.Checkbox( | |
value=True, | |
label="Image Previews" | |
) | |
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=False, | |
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=True, | |
label="Display Images" | |
) | |
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_detail_fix_model_previous_load_gui = gr.Checkbox( | |
value=False, | |
label="Retain Detail fix 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" | |
) | |
# example and Help Section | |
with gr.Accordion( | |
"Examples and help", | |
open=False, | |
visible=True): | |
gr.Markdown( | |
"""### Help: | |
- The current space runs on a ZERO GPU which is assigned for approximately 60 seconds; Therefore, \ | |
if you submit expensive tasks, the operation may be canceled upon reaching the \ | |
maximum allowed time with 'GPU TASK ABORTED'. | |
- Distorted or strange images often result from high prompt weights, \ | |
so it's best to use low weights and scales, and consider using Classic variants like 'Classic-original'. | |
- For better results with Pony Diffusion, \ | |
try using sampler DPM++ 1s or DPM2 with Compel or Classic prompt weights. | |
""" | |
) | |
gr.Markdown( | |
"""### The following examples perform specific tasks: | |
1. Generation with SDXL and upscale | |
2. Generation with SDXL | |
3. ControlNet Canny SDXL | |
4. Optical pattern (Optical illusion) SDXL | |
5. Convert an image to a coloring drawing | |
6. ControlNet OpenPose SD 1.5 | |
- Different tasks can be performed, such as img2img or using the IP adapter, \ | |
to preserve a person's appearance or a specific style based on an image. | |
""" | |
) | |
gr.Examples( | |
examples=example_prompts, | |
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, | |
], | |
outputs=[result_images], | |
cache_examples=False, | |
) | |
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) -> tuple: | |
return img_source, img_result | |
btn_send.click( | |
send_img, | |
[img_source, img_result], | |
[image_control, image_mask_gui] | |
) | |
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_detail_fix_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, | |
], | |
outputs=[ | |
result_images, | |
actual_task_info | |
], | |
queue=True, | |
show_progress="minimal", | |
) | |
app.queue() | |
app.launch( | |
show_error=True, | |
debug=True, | |
) | |