Date: Sat, 15 Oct 2022 02:00:46 -0700
Subject: fix download section layout
---
modules/ui.py | 4 ++--
style.css | 7 -------
2 files changed, 2 insertions(+), 9 deletions(-)
diff --git a/modules/ui.py b/modules/ui.py
index c9b53247..3206113e 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -619,7 +619,7 @@ def create_ui(wrap_gradio_gpu_call):
txt2img_preview = gr.Image(elem_id='txt2img_preview', visible=False)
txt2img_gallery = gr.Gallery(label='Output', show_label=False, elem_id='txt2img_gallery').style(grid=4)
- with gr.Group():
+ with gr.Column():
with gr.Row():
save = gr.Button('Save')
send_to_img2img = gr.Button('Send to img2img')
@@ -834,7 +834,7 @@ def create_ui(wrap_gradio_gpu_call):
img2img_preview = gr.Image(elem_id='img2img_preview', visible=False)
img2img_gallery = gr.Gallery(label='Output', show_label=False, elem_id='img2img_gallery').style(grid=4)
- with gr.Group():
+ with gr.Column():
with gr.Row():
save = gr.Button('Save')
img2img_send_to_img2img = gr.Button('Send to img2img')
diff --git a/style.css b/style.css
index b534f950..920c32ab 100644
--- a/style.css
+++ b/style.css
@@ -237,13 +237,6 @@ fieldset span.text-gray-500, .gr-block.gr-box span.text-gray-500, label.block s
margin: 0;
}
-.gr-panel div.flex-col div.justify-between div{
- position: absolute;
- top: -0.1em;
- right: 1em;
- padding: 0 0.5em;
-}
-
#settings .gr-panel div.flex-col div.justify-between div{
position: relative;
z-index: 200;
--
cgit v1.2.1
From 703e6d9e4e161d36b9328eefb5200e1c44fb4afd Mon Sep 17 00:00:00 2001
From: AngelBottomless <35677394+aria1th@users.noreply.github.com>
Date: Sat, 15 Oct 2022 21:47:08 +0900
Subject: check NaN for hypernetwork tuning
---
modules/hypernetworks/hypernetwork.py | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/modules/hypernetworks/hypernetwork.py b/modules/hypernetworks/hypernetwork.py
index a2b3bc0a..4905710e 100644
--- a/modules/hypernetworks/hypernetwork.py
+++ b/modules/hypernetworks/hypernetwork.py
@@ -272,15 +272,17 @@ def train_hypernetwork(hypernetwork_name, learn_rate, batch_size, data_root, log
optimizer.zero_grad()
loss.backward()
optimizer.step()
-
- pbar.set_description(f"loss: {losses.mean():.7f}")
+ mean_loss = losses.mean()
+ if torch.isnan(mean_loss):
+ raise RuntimeError("Loss diverged.")
+ pbar.set_description(f"loss: {mean_loss:.7f}")
if hypernetwork.step > 0 and hypernetwork_dir is not None and hypernetwork.step % save_hypernetwork_every == 0:
last_saved_file = os.path.join(hypernetwork_dir, f'{hypernetwork_name}-{hypernetwork.step}.pt')
hypernetwork.save(last_saved_file)
textual_inversion.write_loss(log_directory, "hypernetwork_loss.csv", hypernetwork.step, len(ds), {
- "loss": f"{losses.mean():.7f}",
+ "loss": f"{mean_loss:.7f}",
"learn_rate": scheduler.learn_rate
})
@@ -328,7 +330,7 @@ def train_hypernetwork(hypernetwork_name, learn_rate, batch_size, data_root, log
shared.state.textinfo = f"""
-Loss: {losses.mean():.7f}
+Loss: {mean_loss:.7f}
Step: {hypernetwork.step}
Last prompt: {html.escape(entries[0].cond_text)}
Last saved embedding: {html.escape(last_saved_file)}
--
cgit v1.2.1
From 9e846083b702a498fdb60accd72f075fa26701d9 Mon Sep 17 00:00:00 2001
From: DepFA <35278260+dfaker@users.noreply.github.com>
Date: Fri, 14 Oct 2022 14:50:25 +0100
Subject: add vector size to embed text
---
modules/textual_inversion/textual_inversion.py | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/modules/textual_inversion/textual_inversion.py b/modules/textual_inversion/textual_inversion.py
index e754747e..6f549d62 100644
--- a/modules/textual_inversion/textual_inversion.py
+++ b/modules/textual_inversion/textual_inversion.py
@@ -327,10 +327,16 @@ def train_embedding(embedding_name, learn_rate, batch_size, data_root, log_direc
info.add_text("sd-ti-embedding", embedding_to_b64(data))
title = "<{}>".format(data.get('name', '???'))
+
+ try:
+ vectorSize = list(data['string_to_param'].values())[0].shape[0]
+ except Exception as e:
+ vectorSize = '?'
+
checkpoint = sd_models.select_checkpoint()
footer_left = checkpoint.model_name
footer_mid = '[{}]'.format(checkpoint.hash)
- footer_right = '{}'.format(embedding.step)
+ footer_right = 'v{} {}s'.format(vectorSize, embedding.step)
captioned_image = caption_image_overlay(image, title, footer_left, footer_mid, footer_right)
captioned_image = insert_image_data_embed(captioned_image, data)
--
cgit v1.2.1
From 939f16529a72fe48c2ce3ef31bdaba785925a33c Mon Sep 17 00:00:00 2001
From: DepFA <35278260+dfaker@users.noreply.github.com>
Date: Fri, 14 Oct 2022 14:55:05 +0100
Subject: only save 1 image per embedding
---
modules/textual_inversion/textual_inversion.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/modules/textual_inversion/textual_inversion.py b/modules/textual_inversion/textual_inversion.py
index 6f549d62..1d697c90 100644
--- a/modules/textual_inversion/textual_inversion.py
+++ b/modules/textual_inversion/textual_inversion.py
@@ -242,6 +242,7 @@ def train_embedding(embedding_name, learn_rate, batch_size, data_root, log_direc
last_saved_file = ""
last_saved_image = ""
+ embedding_yet_to_be_embedded = False
ititial_step = embedding.step or 0
if ititial_step > steps:
@@ -281,6 +282,7 @@ def train_embedding(embedding_name, learn_rate, batch_size, data_root, log_direc
if embedding.step > 0 and embedding_dir is not None and embedding.step % save_embedding_every == 0:
last_saved_file = os.path.join(embedding_dir, f'{embedding_name}-{embedding.step}.pt')
embedding.save(last_saved_file)
+ embedding_yet_to_be_embedded = True
write_loss(log_directory, "textual_inversion_loss.csv", embedding.step, len(ds), {
"loss": f"{losses.mean():.7f}",
@@ -318,7 +320,7 @@ def train_embedding(embedding_name, learn_rate, batch_size, data_root, log_direc
shared.state.current_image = image
- if save_image_with_stored_embedding and os.path.exists(last_saved_file):
+ if save_image_with_stored_embedding and os.path.exists(last_saved_file) and embedding_yet_to_be_embedded:
last_saved_image_chunks = os.path.join(images_embeds_dir, f'{embedding_name}-{embedding.step}.png')
@@ -342,6 +344,7 @@ def train_embedding(embedding_name, learn_rate, batch_size, data_root, log_direc
captioned_image = insert_image_data_embed(captioned_image, data)
captioned_image.save(last_saved_image_chunks, "PNG", pnginfo=info)
+ embedding_yet_to_be_embedded = False
image.save(last_saved_image)
--
cgit v1.2.1
From 9a1dcd78edbf9caf68b9e6286d7b5ca81500e243 Mon Sep 17 00:00:00 2001
From: DepFA <35278260+dfaker@users.noreply.github.com>
Date: Fri, 14 Oct 2022 18:14:02 +0100
Subject: add webp for embed load
---
modules/textual_inversion/textual_inversion.py | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/modules/textual_inversion/textual_inversion.py b/modules/textual_inversion/textual_inversion.py
index 1d697c90..c07bffc3 100644
--- a/modules/textual_inversion/textual_inversion.py
+++ b/modules/textual_inversion/textual_inversion.py
@@ -96,6 +96,10 @@ class EmbeddingDatabase:
else:
data = extract_image_data_embed(embed_image)
name = data.get('name', name)
+ elif filename.upper().endswith('.WEBP'):
+ embed_image = Image.open(path)
+ data = extract_image_data_embed(embed_image)
+ name = data.get('name', name)
else:
data = torch.load(path, map_location="cpu")
--
cgit v1.2.1
From ddf6899df0cf87d4da77cb2ce223061f4a5edf18 Mon Sep 17 00:00:00 2001
From: DepFA <35278260+dfaker@users.noreply.github.com>
Date: Fri, 14 Oct 2022 18:23:20 +0100
Subject: generalise to popular lossless formats
---
modules/textual_inversion/textual_inversion.py | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/modules/textual_inversion/textual_inversion.py b/modules/textual_inversion/textual_inversion.py
index c07bffc3..b99df3b1 100644
--- a/modules/textual_inversion/textual_inversion.py
+++ b/modules/textual_inversion/textual_inversion.py
@@ -88,18 +88,14 @@ class EmbeddingDatabase:
data = []
- if filename.upper().endswith('.PNG'):
+ if os.path.splitext(filename.upper())[-1] in ['.PNG', '.WEBP', '.JXL', '.AVIF']:
embed_image = Image.open(path)
- if 'sd-ti-embedding' in embed_image.text:
+ if hasattr(embed_image, 'text') and 'sd-ti-embedding' in embed_image.text:
data = embedding_from_b64(embed_image.text['sd-ti-embedding'])
name = data.get('name', name)
else:
data = extract_image_data_embed(embed_image)
name = data.get('name', name)
- elif filename.upper().endswith('.WEBP'):
- embed_image = Image.open(path)
- data = extract_image_data_embed(embed_image)
- name = data.get('name', name)
else:
data = torch.load(path, map_location="cpu")
--
cgit v1.2.1
From b6e3b96dab94a00f51725f9cc977eebc6b4072ab Mon Sep 17 00:00:00 2001
From: DepFA <35278260+dfaker@users.noreply.github.com>
Date: Sat, 15 Oct 2022 15:17:21 +0100
Subject: Change vector size footer label
---
modules/textual_inversion/textual_inversion.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/textual_inversion/textual_inversion.py b/modules/textual_inversion/textual_inversion.py
index b99df3b1..2ed345b1 100644
--- a/modules/textual_inversion/textual_inversion.py
+++ b/modules/textual_inversion/textual_inversion.py
@@ -338,7 +338,7 @@ def train_embedding(embedding_name, learn_rate, batch_size, data_root, log_direc
checkpoint = sd_models.select_checkpoint()
footer_left = checkpoint.model_name
footer_mid = '[{}]'.format(checkpoint.hash)
- footer_right = 'v{} {}s'.format(vectorSize, embedding.step)
+ footer_right = '{}v {}s'.format(vectorSize, embedding.step)
captioned_image = caption_image_overlay(image, title, footer_left, footer_mid, footer_right)
captioned_image = insert_image_data_embed(captioned_image, data)
--
cgit v1.2.1
From 606519813dd998140a741096f9029c732ee52d2a Mon Sep 17 00:00:00 2001
From: guaneec
Date: Sat, 15 Oct 2022 22:10:39 +0800
Subject: Prevent modal content from being selected
---
style.css | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/style.css b/style.css
index 920c32ab..33832ebf 100644
--- a/style.css
+++ b/style.css
@@ -309,6 +309,8 @@ input[type="range"]{
height: 100%;
overflow: auto;
background-color: rgba(20, 20, 20, 0.95);
+ user-select: none;
+ -webkit-user-select: none;
}
.modalControls {
@@ -513,4 +515,4 @@ img2maskimg, #img2maskimg > .h-60, #img2maskimg > .h-60 > div, #img2maskimg > .h
height: 480px !important;
max-height: 480px !important;
min-height: 480px !important;
-}
\ No newline at end of file
+}
--
cgit v1.2.1
From 6e4f5566b58e36aede83427df6c69eba8517af28 Mon Sep 17 00:00:00 2001
From: yfszzx
Date: Sat, 15 Oct 2022 23:53:49 +0800
Subject: sorting files
---
javascript/images_history.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/javascript/images_history.js b/javascript/images_history.js
index f7d052c3..7f0d8f42 100644
--- a/javascript/images_history.js
+++ b/javascript/images_history.js
@@ -96,7 +96,7 @@ function images_history_get_current_img(tabname, image_path, files){
];
}
-function images_history_delete(del_num, tabname, img_path, img_file_name, page_index, filenames, image_index){
+function images_history_delete(del_num, tabname, img_file_name, page_index, filenames, image_index){
image_index = parseInt(image_index);
var tab = gradioApp().getElementById(tabname + '_images_history');
var set_btn = tab.querySelector(".images_history_set_index");
@@ -132,12 +132,12 @@ function images_history_delete(del_num, tabname, img_path, img_file_name, page_i
return [del_num, tabname, img_path, img_file_name, page_index, filenames, image_index];
}
-function images_history_turnpage(img_path, page_index, image_index, tabname){
+function images_history_turnpage(img_path, page_index, image_index, tabname, date_from, date_to){
var buttons = gradioApp().getElementById(tabname + '_images_history').querySelectorAll(".gallery-item");
buttons.forEach(function(elem) {
elem.style.display = 'block';
})
- return [img_path, page_index, image_index, tabname];
+ return [img_path, page_index, image_index, tabname, date_from, date_to];
}
function images_history_enable_del_buttons(){
--
cgit v1.2.1
From 4387e4fe6479c08f7bc7e42924c3a1093e3a1872 Mon Sep 17 00:00:00 2001
From: MalumaDev
Date: Sat, 15 Oct 2022 18:39:29 +0200
Subject: Update modules/ui.py
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Víctor Gallego
---
modules/ui.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/modules/ui.py b/modules/ui.py
index d0696101..5bb961b2 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -599,7 +599,8 @@ def create_ui(wrap_gradio_gpu_call):
with gr.Group():
aesthetic_lr = gr.Textbox(label='Learning rate', placeholder="Learning rate", value="0.0001")
aesthetic_weight = gr.Slider(minimum=0, maximum=1, step=0.01, label="Aesthetic weight", value=0.9)
- aesthetic_steps = gr.Slider(minimum=0, maximum=256, step=1, label="Aesthetic steps", value=5)
+ aesthetic_steps = gr.Slider(minimum=0, maximum=50, step=1, label="Aesthetic steps", value=5)
+
with gr.Row():
aesthetic_imgs_text = gr.Textbox(label='Aesthetic text for imgs', placeholder="This text is used to rotate the feature space of the imgs embs", value="")
aesthetic_slerp_angle = gr.Slider(label='Slerp angle',minimum=0, maximum=1, step=0.01, value=0.1)
--
cgit v1.2.1
From f7df06a98180a2a8769b3ceebf7b6a35eca8ffc5 Mon Sep 17 00:00:00 2001
From: MalumaDev
Date: Sat, 15 Oct 2022 18:40:06 +0200
Subject: Update README.md
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Víctor Gallego
---
README.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 7b8d018b..40104833 100644
--- a/README.md
+++ b/README.md
@@ -70,7 +70,8 @@ Check the [custom scripts](https://github.com/AUTOMATIC1111/stable-diffusion-web
- No token limit for prompts (original stable diffusion lets you use up to 75 tokens)
- DeepDanbooru integration, creates danbooru style tags for anime prompts (add --deepdanbooru to commandline args)
- [xformers](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Xformers), major speed increase for select cards: (add --xformers to commandline args)
-- Aesthetic, a way to generate images with a specific aesthetic by using clip images embds (implementation of https://github.com/vicgalle/stable-diffusion-aesthetic-gradients)
+- Aesthetic Gradients, a way to generate images with a specific aesthetic by using clip images embds (implementation of [https://github.com/vicgalle/stable-diffusion-aesthetic-gradients](https://github.com/vicgalle/stable-diffusion-aesthetic-gradients))
+
## Installation and Running
Make sure the required [dependencies](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Dependencies) are met and follow the instructions available for both [NVidia](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Install-and-Run-on-NVidia-GPUs) (recommended) and [AMD](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Install-and-Run-on-AMD-GPUs) GPUs.
--
cgit v1.2.1
From 9b7705e0573bddde26df4575c71f994d73a4d519 Mon Sep 17 00:00:00 2001
From: MalumaDev
Date: Sat, 15 Oct 2022 18:40:34 +0200
Subject: Update modules/aesthetic_clip.py
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Víctor Gallego
---
modules/aesthetic_clip.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/aesthetic_clip.py b/modules/aesthetic_clip.py
index f15cfd47..bcf2b073 100644
--- a/modules/aesthetic_clip.py
+++ b/modules/aesthetic_clip.py
@@ -70,7 +70,7 @@ def generate_imgs_embd(name, folder, batch_size):
torch.cuda.empty_cache()
res = f"""
Done generating embedding for {name}!
- Hypernetwork saved to {html.escape(path)}
+ Aesthetic embedding saved to {html.escape(path)}
"""
shared.update_aesthetic_embeddings()
return gr.Dropdown(sorted(aesthetic_embeddings.keys()), label="Imgs embedding",
--
cgit v1.2.1
From 0d4f5db235357aeb4c7a8738179ba33aaf5a6b75 Mon Sep 17 00:00:00 2001
From: MalumaDev
Date: Sat, 15 Oct 2022 18:40:58 +0200
Subject: Update modules/ui.py
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Víctor Gallego
---
modules/ui.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/modules/ui.py b/modules/ui.py
index 5bb961b2..25eba548 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -597,7 +597,8 @@ def create_ui(wrap_gradio_gpu_call):
height = gr.Slider(minimum=64, maximum=2048, step=64, label="Height", value=512)
with gr.Group():
- aesthetic_lr = gr.Textbox(label='Learning rate', placeholder="Learning rate", value="0.0001")
+ aesthetic_lr = gr.Textbox(label='Aesthetic learning rate', placeholder="Aesthetic learning rate", value="0.0001")
+
aesthetic_weight = gr.Slider(minimum=0, maximum=1, step=0.01, label="Aesthetic weight", value=0.9)
aesthetic_steps = gr.Slider(minimum=0, maximum=50, step=1, label="Aesthetic steps", value=5)
--
cgit v1.2.1
From ad9bc604a8fadcfebe72be37f66cec51e7e87fb5 Mon Sep 17 00:00:00 2001
From: MalumaDev
Date: Sat, 15 Oct 2022 18:41:18 +0200
Subject: Update modules/ui.py
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Víctor Gallego
---
modules/ui.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/modules/ui.py b/modules/ui.py
index 25eba548..3b28b69c 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -607,7 +607,8 @@ def create_ui(wrap_gradio_gpu_call):
aesthetic_slerp_angle = gr.Slider(label='Slerp angle',minimum=0, maximum=1, step=0.01, value=0.1)
aesthetic_text_negative = gr.Checkbox(label="Is negative text", value=False)
- aesthetic_imgs = gr.Dropdown(sorted(aesthetic_embeddings.keys()), label="Imgs embedding", value=sorted(aesthetic_embeddings.keys())[0] if len(aesthetic_embeddings) > 0 else None)
+ aesthetic_imgs = gr.Dropdown(sorted(aesthetic_embeddings.keys()), label="Aesthetic imgs embedding", value=sorted(aesthetic_embeddings.keys())[0] if len(aesthetic_embeddings) > 0 else None)
+
aesthetic_slerp = gr.Checkbox(label="Slerp interpolation", value=False)
with gr.Row():
--
cgit v1.2.1
From 3f5c3b981e46c16bb10948d012575b25170efb3b Mon Sep 17 00:00:00 2001
From: MalumaDev
Date: Sat, 15 Oct 2022 18:41:46 +0200
Subject: Update modules/ui.py
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Víctor Gallego
---
modules/ui.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/modules/ui.py b/modules/ui.py
index 3b28b69c..1f6fcdc9 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -1190,7 +1190,8 @@ def create_ui(wrap_gradio_gpu_call):
with gr.Column():
create_embedding = gr.Button(value="Create embedding", variant='primary')
- with gr.Tab(label="Create images embedding"):
+ with gr.Tab(label="Create aesthetic images embedding"):
+
new_embedding_name_ae = gr.Textbox(label="Name")
process_src_ae = gr.Textbox(label='Source directory')
batch_ae = gr.Slider(minimum=1, maximum=1024, step=1, label="Batch size", value=256)
--
cgit v1.2.1
From 74a9ee70020ffa2746c82300c533de3f7e523f22 Mon Sep 17 00:00:00 2001
From: AUTOMATIC <16777216c@gmail.com>
Date: Sat, 15 Oct 2022 17:25:35 +0300
Subject: fix saving images compatibility with gradio update
---
modules/ui.py | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/modules/ui.py b/modules/ui.py
index 3206113e..b867d40f 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -154,10 +154,7 @@ def save_files(js_data, images, do_make_zip, index):
writer.writerow(["prompt", "seed", "width", "height", "sampler", "cfgs", "steps", "filename", "negative_prompt"])
for image_index, filedata in enumerate(images, start_index):
- if filedata.startswith("data:image/png;base64,"):
- filedata = filedata[len("data:image/png;base64,"):]
-
- image = Image.open(io.BytesIO(base64.decodebytes(filedata.encode('utf-8'))))
+ image = image_from_url_text(filedata)
is_grid = image_index < p.index_of_first_image
i = 0 if is_grid else (image_index - p.index_of_first_image)
--
cgit v1.2.1
From 09814e3cf384bf4189d57d1573483f72b38fb99f Mon Sep 17 00:00:00 2001
From: C43H66N12O12S2 <36072735+C43H66N12O12S2@users.noreply.github.com>
Date: Sat, 15 Oct 2022 19:06:34 +0300
Subject: Update launch.py
---
launch.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/launch.py b/launch.py
index 537670a3..e3208553 100644
--- a/launch.py
+++ b/launch.py
@@ -107,6 +107,7 @@ def prepare_enviroment():
xformers = '--xformers' in args
deepdanbooru = '--deepdanbooru' in args
ngrok = '--ngrok' in args
+ reinstall_xformers = '--reinstall-xformers' in args
try:
commit = run(f"{git} rev-parse HEAD").strip()
@@ -128,9 +129,9 @@ def prepare_enviroment():
if not is_installed("clip"):
run_pip(f"install {clip_package}", "clip")
- if not is_installed("xformers") and xformers and platform.python_version().startswith("3.10"):
+ if (not is_installed("xformers") or reinstall_xformers) and xformers and platform.python_version().startswith("3.10"):
if platform.system() == "Windows":
- run_pip("install https://github.com/C43H66N12O12S2/stable-diffusion-webui/releases/download/c/xformers-0.0.14.dev0-cp310-cp310-win_amd64.whl", "xformers")
+ run_pip("install -U -I --no-deps https://github.com/C43H66N12O12S2/stable-diffusion-webui/releases/download/f/xformers-0.0.14.dev0-cp310-cp310-win_amd64.whl", "xformers")
elif platform.system() == "Linux":
run_pip("install xformers", "xformers")
--
cgit v1.2.1
From 529afbf4d70165a0dfd19eb9c2ec22416b794a1d Mon Sep 17 00:00:00 2001
From: C43H66N12O12S2 <36072735+C43H66N12O12S2@users.noreply.github.com>
Date: Sat, 15 Oct 2022 19:19:54 +0300
Subject: Update sd_hijack.py
---
modules/sd_hijack.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/sd_hijack.py b/modules/sd_hijack.py
index c81722a0..984b35c4 100644
--- a/modules/sd_hijack.py
+++ b/modules/sd_hijack.py
@@ -24,7 +24,7 @@ def apply_optimizations():
ldm.modules.diffusionmodules.model.nonlinearity = silu
- if cmd_opts.force_enable_xformers or (cmd_opts.xformers and shared.xformers_available and torch.version.cuda and (6, 0) <= torch.cuda.get_device_capability(shared.device) <= (8, 6)):
+ if cmd_opts.force_enable_xformers or (cmd_opts.xformers and shared.xformers_available and torch.version.cuda and (6, 0) <= torch.cuda.get_device_capability(shared.device) <= (9, 0)):
print("Applying xformers cross attention optimization.")
ldm.modules.attention.CrossAttention.forward = sd_hijack_optimizations.xformers_attention_forward
ldm.modules.diffusionmodules.model.AttnBlock.forward = sd_hijack_optimizations.xformers_attnblock_forward
--
cgit v1.2.1
From 8fb0b991522658d938ae43de77f708555aa1902b Mon Sep 17 00:00:00 2001
From: C43H66N12O12S2 <36072735+C43H66N12O12S2@users.noreply.github.com>
Date: Sat, 15 Oct 2022 20:17:51 +0300
Subject: Update launch.py
---
launch.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/launch.py b/launch.py
index e3208553..5ec2b926 100644
--- a/launch.py
+++ b/launch.py
@@ -104,10 +104,10 @@ def prepare_enviroment():
args = shlex.split(commandline_args)
args, skip_torch_cuda_test = extract_arg(args, '--skip-torch-cuda-test')
+ args, reinstall_xformers = extract_argg(args, '--reinstall-xformers')
xformers = '--xformers' in args
deepdanbooru = '--deepdanbooru' in args
ngrok = '--ngrok' in args
- reinstall_xformers = '--reinstall-xformers' in args
try:
commit = run(f"{git} rev-parse HEAD").strip()
--
cgit v1.2.1
From be1596ce30b1ead6998da0c62003003dcce5eb2c Mon Sep 17 00:00:00 2001
From: C43H66N12O12S2 <36072735+C43H66N12O12S2@users.noreply.github.com>
Date: Sat, 15 Oct 2022 20:19:16 +0300
Subject: fix typo
---
launch.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/launch.py b/launch.py
index 5ec2b926..2e6b3369 100644
--- a/launch.py
+++ b/launch.py
@@ -104,7 +104,7 @@ def prepare_enviroment():
args = shlex.split(commandline_args)
args, skip_torch_cuda_test = extract_arg(args, '--skip-torch-cuda-test')
- args, reinstall_xformers = extract_argg(args, '--reinstall-xformers')
+ args, reinstall_xformers = extract_arg(args, '--reinstall-xformers')
xformers = '--xformers' in args
deepdanbooru = '--deepdanbooru' in args
ngrok = '--ngrok' in args
--
cgit v1.2.1
From 9a33292ce41b01252cdb8ab6214a11d274e32fa0 Mon Sep 17 00:00:00 2001
From: zhengxiaoyao0716 <1499383852@qq.com>
Date: Sat, 15 Oct 2022 01:04:47 +0800
Subject: reload javascript files when custom script bodies
---
modules/ui.py | 28 ++++++++++++++++------------
1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/modules/ui.py b/modules/ui.py
index b867d40f..90b8646b 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -12,7 +12,7 @@ import time
import traceback
import platform
import subprocess as sp
-from functools import reduce
+from functools import partial, reduce
import numpy as np
import torch
@@ -1491,6 +1491,7 @@ Requested path was: {f}
def reload_scripts():
modules.scripts.reload_script_body_only()
+ reload_javascript() # need to refresh the html page
reload_script_bodies.click(
fn=reload_scripts,
@@ -1738,22 +1739,25 @@ Requested path was: {f}
return demo
-with open(os.path.join(script_path, "script.js"), "r", encoding="utf8") as jsfile:
- javascript = f''
+def load_javascript(raw_response):
+ with open(os.path.join(script_path, "script.js"), "r", encoding="utf8") as jsfile:
+ javascript = f''
-jsdir = os.path.join(script_path, "javascript")
-for filename in sorted(os.listdir(jsdir)):
- with open(os.path.join(jsdir, filename), "r", encoding="utf8") as jsfile:
- javascript += f"\n"
+ jsdir = os.path.join(script_path, "javascript")
+ for filename in sorted(os.listdir(jsdir)):
+ with open(os.path.join(jsdir, filename), "r", encoding="utf8") as jsfile:
+ javascript += f"\n"
-
-if 'gradio_routes_templates_response' not in globals():
def template_response(*args, **kwargs):
- res = gradio_routes_templates_response(*args, **kwargs)
- res.body = res.body.replace(b'', f'{javascript}'.encode("utf8"))
+ res = raw_response(*args, **kwargs)
+ res.body = res.body.replace(
+ b'', f'{javascript}'.encode("utf8"))
res.init_headers()
return res
- gradio_routes_templates_response = gradio.routes.templates.TemplateResponse
gradio.routes.templates.TemplateResponse = template_response
+
+reload_javascript = partial(load_javascript,
+ gradio.routes.templates.TemplateResponse)
+reload_javascript()
--
cgit v1.2.1
From 3d21684ee30ca5734126b8d08c05b3a0f513fe75 Mon Sep 17 00:00:00 2001
From: MalumaDev
Date: Sun, 16 Oct 2022 00:01:00 +0200
Subject: Add support to other img format, fixed dropbox update
---
modules/aesthetic_clip.py | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/modules/aesthetic_clip.py b/modules/aesthetic_clip.py
index bcf2b073..68264284 100644
--- a/modules/aesthetic_clip.py
+++ b/modules/aesthetic_clip.py
@@ -8,7 +8,7 @@ import gradio as gr
import torch
from PIL import Image
from modules import shared
-from modules.shared import device, aesthetic_embeddings
+from modules.shared import device
from transformers import CLIPModel, CLIPProcessor
from tqdm.auto import tqdm
@@ -20,7 +20,7 @@ def get_all_images_in_folder(folder):
def check_is_valid_image_file(filename):
- return filename.lower().endswith(('.png', '.jpg', '.jpeg'))
+ return filename.lower().endswith(('.png', '.jpg', '.jpeg', ".gif", ".tiff", ".webp"))
def batched(dataset, total, n=1):
@@ -73,6 +73,6 @@ def generate_imgs_embd(name, folder, batch_size):
Aesthetic embedding saved to {html.escape(path)}
"""
shared.update_aesthetic_embeddings()
- return gr.Dropdown(sorted(aesthetic_embeddings.keys()), label="Imgs embedding",
- value=sorted(aesthetic_embeddings.keys())[0] if len(
- aesthetic_embeddings) > 0 else None), res, ""
+ return gr.Dropdown.update(choices=sorted(shared.aesthetic_embeddings.keys()), label="Imgs embedding",
+ value=sorted(shared.aesthetic_embeddings.keys())[0] if len(
+ shared.aesthetic_embeddings) > 0 else None), res, ""
--
cgit v1.2.1
From 9325c85f780c569d1823e422eaf51b2e497e0d3e Mon Sep 17 00:00:00 2001
From: MalumaDev
Date: Sun, 16 Oct 2022 00:23:47 +0200
Subject: fixed dropbox update
---
modules/sd_hijack.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules/sd_hijack.py b/modules/sd_hijack.py
index 192883b2..491312b4 100644
--- a/modules/sd_hijack.py
+++ b/modules/sd_hijack.py
@@ -9,7 +9,7 @@ from torch.nn.functional import silu
import modules.textual_inversion.textual_inversion
from modules import prompt_parser, devices, sd_hijack_optimizations, shared
-from modules.shared import opts, device, cmd_opts, aesthetic_embeddings
+from modules.shared import opts, device, cmd_opts
from modules.sd_hijack_optimizations import invokeAI_mps_available
import ldm.modules.attention
@@ -182,7 +182,7 @@ class FrozenCLIPEmbedderWithCustomWords(torch.nn.Module):
image_embs_name = None
if image_embs_name is not None and self.image_embs_name != image_embs_name:
self.image_embs_name = image_embs_name
- self.image_embs = torch.load(aesthetic_embeddings[self.image_embs_name], map_location=device)
+ self.image_embs = torch.load(shared.aesthetic_embeddings[self.image_embs_name], map_location=device)
self.image_embs /= self.image_embs.norm(dim=-1, keepdim=True)
self.image_embs.requires_grad_(False)
--
cgit v1.2.1
From 763b893f319cee280b86e63025eb55e7c16b02e7 Mon Sep 17 00:00:00 2001
From: yfszzx
Date: Sun, 16 Oct 2022 10:03:09 +0800
Subject: images history sorting files by date
---
javascript/images_history.js | 12 +-
modules/images_history.py | 261 ++++++++++++++++++++++++++++++++-----------
2 files changed, 202 insertions(+), 71 deletions(-)
diff --git a/javascript/images_history.js b/javascript/images_history.js
index 7f0d8f42..ac5834c7 100644
--- a/javascript/images_history.js
+++ b/javascript/images_history.js
@@ -88,10 +88,10 @@ function images_history_set_image_info(button){
}
-function images_history_get_current_img(tabname, image_path, files){
+function images_history_get_current_img(tabname, img_index, files){
return [
- gradioApp().getElementById(tabname + '_images_history_set_index').getAttribute("img_index"),
- image_path,
+ tabname,
+ gradioApp().getElementById(tabname + '_images_history_set_index').getAttribute("img_index"),
files
];
}
@@ -129,7 +129,7 @@ function images_history_delete(del_num, tabname, img_file_name, page_index, file
setTimeout(function(btn){btn.click()}, 30, btn);
}
images_history_disabled_del();
- return [del_num, tabname, img_path, img_file_name, page_index, filenames, image_index];
+ return [del_num, tabname, img_file_name, page_index, filenames, image_index];
}
function images_history_turnpage(img_path, page_index, image_index, tabname, date_from, date_to){
@@ -170,8 +170,8 @@ function images_history_init(){
}
tabs_box.classList.add(images_history_tab_list[0]);
- // same as above, at page load
- //load_txt2img_button.click();
+ // same as above, at page load-- load very fast now
+ load_txt2img_button.click();
} else {
setTimeout(images_history_init, 500);
}
diff --git a/modules/images_history.py b/modules/images_history.py
index f5ef44fe..533cf51b 100644
--- a/modules/images_history.py
+++ b/modules/images_history.py
@@ -1,33 +1,74 @@
import os
import shutil
+import time
+import hashlib
+import gradio
+show_max_dates_num = 3
+system_bak_path = "webui_log_and_bak"
+def is_valid_date(date):
+ try:
+ time.strptime(date, "%Y%m%d")
+ return True
+ except:
+ return False
+def reduplicative_file_move(src, dst):
+ def same_name_file(basename, path):
+ name, ext = os.path.splitext(basename)
+ f_list = os.listdir(path)
+ max_num = 0
+ for f in f_list:
+ if len(f) <= len(basename):
+ continue
+ f_ext = f[-len(ext):] if len(ext) > 0 else ""
+ if f[:len(name)] == name and f_ext == ext:
+ if f[len(name)] == "(" and f[-len(ext)-1] == ")":
+ number = f[len(name)+1:-len(ext)-1]
+ if number.isdigit():
+ if int(number) > max_num:
+ max_num = int(number)
+ return f"{name}({max_num + 1}){ext}"
+ name = os.path.basename(src)
+ save_name = os.path.join(dst, name)
+ if not os.path.exists(save_name):
+ shutil.move(src, dst)
+ else:
+ name = same_name_file(name, dst)
+ shutil.move(src, os.path.join(dst, name))
-def traverse_all_files(output_dir, image_list, curr_dir=None):
- curr_path = output_dir if curr_dir is None else os.path.join(output_dir, curr_dir)
+def traverse_all_files(curr_path, image_list, all_type=False):
try:
f_list = os.listdir(curr_path)
except:
- if curr_dir[-10:].rfind(".") > 0 and curr_dir[-4:] != ".txt":
- image_list.append(curr_dir)
+ if all_type or curr_path[-10:].rfind(".") > 0 and curr_path[-4:] != ".txt":
+ image_list.append(curr_path)
return image_list
for file in f_list:
- file = file if curr_dir is None else os.path.join(curr_dir, file)
- file_path = os.path.join(curr_path, file)
- if file[-4:] == ".txt":
+ file = os.path.join(curr_path, file)
+ if (not all_type) and file[-4:] == ".txt":
pass
- elif os.path.isfile(file_path) and file[-10:].rfind(".") > 0:
+ elif os.path.isfile(file) and file[-10:].rfind(".") > 0:
image_list.append(file)
else:
- image_list = traverse_all_files(output_dir, image_list, file)
+ image_list = traverse_all_files(file, image_list)
return image_list
-
-def get_recent_images(dir_name, page_index, step, image_index, tabname):
- page_index = int(page_index)
- f_list = os.listdir(dir_name)
+def get_recent_images(dir_name, page_index, step, image_index, tabname, date_from, date_to):
+ #print(f"turn_page {page_index}",date_from)
+ if date_from is None or date_from == "":
+ return None, 1, None, ""
image_list = []
- image_list = traverse_all_files(dir_name, image_list)
- image_list = sorted(image_list, key=lambda file: -os.path.getctime(os.path.join(dir_name, file)))
+ date_list = auto_sorting(dir_name)
+ page_index = int(page_index)
+ today = time.strftime("%Y%m%d",time.localtime(time.time()))
+ for date in date_list:
+ if date >= date_from and date <= date_to:
+ path = os.path.join(dir_name, date)
+ if date == today and not os.path.exists(path):
+ continue
+ image_list = traverse_all_files(path, image_list)
+
+ image_list = sorted(image_list, key=lambda file: -os.path.getctime(file))
num = 48 if tabname != "extras" else 12
max_page_index = len(image_list) // num + 1
page_index = max_page_index if page_index == -1 else page_index + step
@@ -38,40 +79,101 @@ def get_recent_images(dir_name, page_index, step, image_index, tabname):
image_index = int(image_index)
if image_index < 0 or image_index > len(image_list) - 1:
current_file = None
- hidden = None
else:
- current_file = image_list[int(image_index)]
- hidden = os.path.join(dir_name, current_file)
- return [os.path.join(dir_name, file) for file in image_list], page_index, image_list, current_file, hidden, ""
+ current_file = image_list[image_index]
+ return image_list, page_index, image_list, ""
+def auto_sorting(dir_name):
+ #print(f"auto sorting")
+ bak_path = os.path.join(dir_name, system_bak_path)
+ if not os.path.exists(bak_path):
+ os.mkdir(bak_path)
+ log_file = None
+ files_list = []
+ f_list = os.listdir(dir_name)
+ for file in f_list:
+ if file == system_bak_path:
+ continue
+ file_path = os.path.join(dir_name, file)
+ if not is_valid_date(file):
+ if file[-10:].rfind(".") > 0:
+ files_list.append(file_path)
+ else:
+ files_list = traverse_all_files(file_path, files_list, all_type=True)
+
+ for file in files_list:
+ date_str = time.strftime("%Y%m%d",time.localtime(os.path.getctime(file)))
+ file_path = os.path.dirname(file)
+ hash_path = hashlib.md5(file_path.encode()).hexdigest()
+ path = os.path.join(dir_name, date_str, hash_path)
+ if not os.path.exists(path):
+ os.makedirs(path)
+ if log_file is None:
+ log_file = open(os.path.join(bak_path,"path_mapping.csv"),"a")
+ log_file.write(f"{hash_path},{file_path}\n")
+ reduplicative_file_move(file, path)
+
+ date_list = []
+ f_list = os.listdir(dir_name)
+ for f in f_list:
+ if is_valid_date(f):
+ date_list.append(f)
+ elif f == system_bak_path:
+ continue
+ else:
+ reduplicative_file_move(os.path.join(dir_name, f), bak_path)
+
+ today = time.strftime("%Y%m%d",time.localtime(time.time()))
+ if today not in date_list:
+ date_list.append(today)
+ return sorted(date_list)
-def first_page_click(dir_name, page_index, image_index, tabname):
- return get_recent_images(dir_name, 1, 0, image_index, tabname)
-def end_page_click(dir_name, page_index, image_index, tabname):
- return get_recent_images(dir_name, -1, 0, image_index, tabname)
+def archive_images(dir_name):
+ date_list = auto_sorting(dir_name)
+ date_from = date_list[-show_max_dates_num] if len(date_list) > show_max_dates_num else date_list[0]
+ return (
+ gradio.update(visible=False),
+ gradio.update(visible=True),
+ gradio.Dropdown.update(choices=date_list, value=date_list[-1]),
+ gradio.Dropdown.update(choices=date_list, value=date_from)
+ )
+def date_to_change(dir_name, page_index, image_index, tabname, date_from, date_to):
+ #print("date_to", date_to)
+ date_list = auto_sorting(dir_name)
+ date_from_list = [date for date in date_list if date <= date_to]
+ date_from = date_from_list[0] if len(date_from_list) < show_max_dates_num else date_from_list[-show_max_dates_num]
+ image_list, page_index, image_list, _ =get_recent_images(dir_name, 1, 0, image_index, tabname, date_from, date_to)
+ return image_list, page_index, image_list, _, gradio.Dropdown.update(choices=date_from_list, value=date_from)
-def prev_page_click(dir_name, page_index, image_index, tabname):
- return get_recent_images(dir_name, page_index, -1, image_index, tabname)
+def first_page_click(dir_name, page_index, image_index, tabname, date_from, date_to):
+ return get_recent_images(dir_name, 1, 0, image_index, tabname, date_from, date_to)
-def next_page_click(dir_name, page_index, image_index, tabname):
- return get_recent_images(dir_name, page_index, 1, image_index, tabname)
+def end_page_click(dir_name, page_index, image_index, tabname, date_from, date_to):
+ return get_recent_images(dir_name, -1, 0, image_index, tabname, date_from, date_to)
-def page_index_change(dir_name, page_index, image_index, tabname):
- return get_recent_images(dir_name, page_index, 0, image_index, tabname)
+def prev_page_click(dir_name, page_index, image_index, tabname, date_from, date_to):
+ return get_recent_images(dir_name, page_index, -1, image_index, tabname, date_from, date_to)
-def show_image_info(num, image_path, filenames):
- # print(f"select image {num}")
- file = filenames[int(num)]
- return file, num, os.path.join(image_path, file)
+def next_page_click(dir_name, page_index, image_index, tabname, date_from, date_to):
+ return get_recent_images(dir_name, page_index, 1, image_index, tabname, date_from, date_to)
+
+
+def page_index_change(dir_name, page_index, image_index, tabname, date_from, date_to):
+ return get_recent_images(dir_name, page_index, 0, image_index, tabname, date_from, date_to)
-def delete_image(delete_num, tabname, dir_name, name, page_index, filenames, image_index):
+def show_image_info(tabname_box, num, filenames):
+ # #print(f"select image {num}")
+ file = filenames[int(num)]
+ return file, num, file
+
+def delete_image(delete_num, tabname, name, page_index, filenames, image_index):
if name == "":
return filenames, delete_num
else:
@@ -81,21 +183,19 @@ def delete_image(delete_num, tabname, dir_name, name, page_index, filenames, ima
new_file_list = []
for name in filenames:
if i >= index and i < index + delete_num:
- path = os.path.join(dir_name, name)
- if os.path.exists(path):
- print(f"Delete file {path}")
- os.remove(path)
- txt_file = os.path.splitext(path)[0] + ".txt"
+ if os.path.exists(name):
+ #print(f"Delete file {name}")
+ os.remove(name)
+ txt_file = os.path.splitext(name)[0] + ".txt"
if os.path.exists(txt_file):
os.remove(txt_file)
else:
- print(f"Not exists file {path}")
+ #print(f"Not exists file {name}")
else:
new_file_list.append(name)
i += 1
return new_file_list, 1
-
def show_images_history(gr, opts, tabname, run_pnginfo, switch_dict):
if tabname == "txt2img":
dir_name = opts.outdir_txt2img_samples
@@ -107,16 +207,32 @@ def show_images_history(gr, opts, tabname, run_pnginfo, switch_dict):
dir_name = d[0]
for p in d[1:]:
dir_name = os.path.join(dir_name, p)
- with gr.Row():
- renew_page = gr.Button('Renew Page', elem_id=tabname + "_images_history_renew_page")
- first_page = gr.Button('First Page')
- prev_page = gr.Button('Prev Page')
- page_index = gr.Number(value=1, label="Page Index")
- next_page = gr.Button('Next Page')
- end_page = gr.Button('End Page')
- with gr.Row(elem_id=tabname + "_images_history"):
+
+ f_list = os.listdir(dir_name)
+ sorted_flag = os.path.exists(os.path.join(dir_name, system_bak_path)) or len(f_list) == 0
+ date_list, date_from, date_to = None, None, None
+ if sorted_flag:
+ #print(sorted_flag)
+ date_list = auto_sorting(dir_name)
+ date_to = date_list[-1]
+ date_from = date_list[-show_max_dates_num] if len(date_list) > show_max_dates_num else date_list[0]
+
+ with gr.Column(visible=sorted_flag) as page_panel:
with gr.Row():
+ renew_page = gr.Button('Refresh', elem_id=tabname + "_images_history_renew_page", interactive=sorted_flag)
+ first_page = gr.Button('First Page')
+ prev_page = gr.Button('Prev Page')
+ page_index = gr.Number(value=1, label="Page Index")
+ next_page = gr.Button('Next Page')
+ end_page = gr.Button('End Page')
+
+ with gr.Row(elem_id=tabname + "_images_history"):
with gr.Column(scale=2):
+ with gr.Row():
+ newest = gr.Button('Newest')
+ date_to = gr.Dropdown(choices=date_list, value=date_to, label="Date to")
+ date_from = gr.Dropdown(choices=date_list, value=date_from, label="Date from")
+
history_gallery = gr.Gallery(show_label=False, elem_id=tabname + "_images_history_gallery").style(grid=6)
with gr.Row():
delete_num = gr.Number(value=1, interactive=True, label="number of images to delete consecutively next")
@@ -128,22 +244,31 @@ def show_images_history(gr, opts, tabname, run_pnginfo, switch_dict):
with gr.Row():
with gr.Column():
img_file_info = gr.Textbox(label="Generate Info", interactive=False)
- img_file_name = gr.Textbox(label="File Name", interactive=False)
- with gr.Row():
+ img_file_name = gr.Textbox(value="", label="File Name", interactive=False)
# hiden items
+ with gr.Row(visible=False):
+ img_path = gr.Textbox(dir_name)
+ tabname_box = gr.Textbox(tabname)
+ image_index = gr.Textbox(value=-1)
+ set_index = gr.Button('set_index', elem_id=tabname + "_images_history_set_index")
+ filenames = gr.State()
+ hidden = gr.Image(type="pil")
+ info1 = gr.Textbox()
+ info2 = gr.Textbox()
+ with gr.Column(visible=not sorted_flag) as init_warning:
+ with gr.Row():
+ gr.Textbox("The system needs to archive the files according to the date. This requires changing the directory structure of the files",
+ label="Waring",
+ css="")
+ with gr.Row():
+ sorted_button = gr.Button('Confirme')
- img_path = gr.Textbox(dir_name.rstrip("/"), visible=False)
- tabname_box = gr.Textbox(tabname, visible=False)
- image_index = gr.Textbox(value=-1, visible=False)
- set_index = gr.Button('set_index', elem_id=tabname + "_images_history_set_index", visible=False)
- filenames = gr.State()
- hidden = gr.Image(type="pil", visible=False)
- info1 = gr.Textbox(visible=False)
- info2 = gr.Textbox(visible=False)
-
+
+
+
# turn pages
- gallery_inputs = [img_path, page_index, image_index, tabname_box]
- gallery_outputs = [history_gallery, page_index, filenames, img_file_name, hidden, img_file_name]
+ gallery_inputs = [img_path, page_index, image_index, tabname_box, date_from, date_to]
+ gallery_outputs = [history_gallery, page_index, filenames, img_file_name]
first_page.click(first_page_click, _js="images_history_turnpage", inputs=gallery_inputs, outputs=gallery_outputs)
next_page.click(next_page_click, _js="images_history_turnpage", inputs=gallery_inputs, outputs=gallery_outputs)
@@ -154,15 +279,21 @@ def show_images_history(gr, opts, tabname, run_pnginfo, switch_dict):
# page_index.change(page_index_change, inputs=[tabname_box, img_path, page_index], outputs=[history_gallery, page_index])
# other funcitons
- set_index.click(show_image_info, _js="images_history_get_current_img", inputs=[tabname_box, img_path, filenames], outputs=[img_file_name, image_index, hidden])
+ set_index.click(show_image_info, _js="images_history_get_current_img", inputs=[tabname_box, image_index, filenames], outputs=[img_file_name, image_index, hidden])
img_file_name.change(fn=None, _js="images_history_enable_del_buttons", inputs=None, outputs=None)
- delete.click(delete_image, _js="images_history_delete", inputs=[delete_num, tabname_box, img_path, img_file_name, page_index, filenames, image_index], outputs=[filenames, delete_num])
+ delete.click(delete_image, _js="images_history_delete", inputs=[delete_num, tabname_box, img_file_name, page_index, filenames, image_index], outputs=[filenames, delete_num])
hidden.change(fn=run_pnginfo, inputs=[hidden], outputs=[info1, img_file_info, info2])
-
+ date_to.change(date_to_change, _js="images_history_turnpage", inputs=gallery_inputs, outputs=gallery_outputs + [date_from])
# pnginfo.click(fn=run_pnginfo, inputs=[hidden], outputs=[info1, img_file_info, info2])
switch_dict["fn"](pnginfo_send_to_txt2img, switch_dict["t2i"], img_file_info, 'switch_to_txt2img')
switch_dict["fn"](pnginfo_send_to_img2img, switch_dict["i2i"], img_file_info, 'switch_to_img2img_img2img')
+ sorted_button.click(archive_images, inputs=[img_path], outputs=[init_warning, page_panel, date_to, date_from])
+ newest.click(archive_images, inputs=[img_path], outputs=[init_warning, page_panel, date_to, date_from])
+
+
+
+
def create_history_tabs(gr, opts, run_pnginfo, switch_dict):
with gr.Blocks(analytics_enabled=False) as images_history:
--
cgit v1.2.1
From 0c5fa9a681672508adadbe1e10fc16d7fe0ed6dd Mon Sep 17 00:00:00 2001
From: AUTOMATIC <16777216c@gmail.com>
Date: Sun, 16 Oct 2022 08:51:24 +0300
Subject: do not reload embeddings from disk when doing textual inversion
---
modules/processing.py | 5 +++--
modules/textual_inversion/textual_inversion.py | 1 +
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/modules/processing.py b/modules/processing.py
index 941ae089..833fed8a 100644
--- a/modules/processing.py
+++ b/modules/processing.py
@@ -53,7 +53,7 @@ def get_correct_sampler(p):
return sd_samplers.samplers_for_img2img
class StableDiffusionProcessing:
- def __init__(self, sd_model=None, outpath_samples=None, outpath_grids=None, prompt="", styles=None, seed=-1, subseed=-1, subseed_strength=0, seed_resize_from_h=-1, seed_resize_from_w=-1, seed_enable_extras=True, sampler_index=0, batch_size=1, n_iter=1, steps=50, cfg_scale=7.0, width=512, height=512, restore_faces=False, tiling=False, do_not_save_samples=False, do_not_save_grid=False, extra_generation_params=None, overlay_images=None, negative_prompt=None, eta=None):
+ def __init__(self, sd_model=None, outpath_samples=None, outpath_grids=None, prompt="", styles=None, seed=-1, subseed=-1, subseed_strength=0, seed_resize_from_h=-1, seed_resize_from_w=-1, seed_enable_extras=True, sampler_index=0, batch_size=1, n_iter=1, steps=50, cfg_scale=7.0, width=512, height=512, restore_faces=False, tiling=False, do_not_save_samples=False, do_not_save_grid=False, extra_generation_params=None, overlay_images=None, negative_prompt=None, eta=None, do_not_reload_embeddings=False):
self.sd_model = sd_model
self.outpath_samples: str = outpath_samples
self.outpath_grids: str = outpath_grids
@@ -80,6 +80,7 @@ class StableDiffusionProcessing:
self.extra_generation_params: dict = extra_generation_params or {}
self.overlay_images = overlay_images
self.eta = eta
+ self.do_not_reload_embeddings = do_not_reload_embeddings
self.paste_to = None
self.color_corrections = None
self.denoising_strength: float = 0
@@ -364,7 +365,7 @@ def process_images(p: StableDiffusionProcessing) -> Processed:
def infotext(iteration=0, position_in_batch=0):
return create_infotext(p, all_prompts, all_seeds, all_subseeds, comments, iteration, position_in_batch)
- if os.path.exists(cmd_opts.embeddings_dir):
+ if os.path.exists(cmd_opts.embeddings_dir) and not p.do_not_reload_embeddings:
model_hijack.embedding_db.load_textual_inversion_embeddings()
infotexts = []
diff --git a/modules/textual_inversion/textual_inversion.py b/modules/textual_inversion/textual_inversion.py
index 2ed345b1..7ec75018 100644
--- a/modules/textual_inversion/textual_inversion.py
+++ b/modules/textual_inversion/textual_inversion.py
@@ -296,6 +296,7 @@ def train_embedding(embedding_name, learn_rate, batch_size, data_root, log_direc
sd_model=shared.sd_model,
do_not_save_grid=True,
do_not_save_samples=True,
+ do_not_reload_embeddings=True,
)
if preview_from_txt2img:
--
cgit v1.2.1
From 2ce27728f6433911274efa67856315d22df56629 Mon Sep 17 00:00:00 2001
From: winterspringsummer
Date: Sun, 16 Oct 2022 13:50:55 +0900
Subject: added extras batch work from directory
---
modules/extras.py | 23 ++++++++++++++++++-----
modules/ui.py | 12 ++++++++++++
2 files changed, 30 insertions(+), 5 deletions(-)
diff --git a/modules/extras.py b/modules/extras.py
index f2f5a7b0..5b52b27d 100644
--- a/modules/extras.py
+++ b/modules/extras.py
@@ -20,26 +20,38 @@ import gradio as gr
cached_images = {}
-def run_extras(extras_mode, resize_mode, image, image_folder, gfpgan_visibility, codeformer_visibility, codeformer_weight, upscaling_resize, upscaling_resize_w, upscaling_resize_h, upscaling_crop, extras_upscaler_1, extras_upscaler_2, extras_upscaler_2_visibility):
+def run_extras(extras_mode, resize_mode, image, image_folder, input_dir, output_dir, show_extras_results, gfpgan_visibility, codeformer_visibility, codeformer_weight, upscaling_resize, upscaling_resize_w, upscaling_resize_h, upscaling_crop, extras_upscaler_1, extras_upscaler_2, extras_upscaler_2_visibility):
devices.torch_gc()
imageArr = []
# Also keep track of original file names
imageNameArr = []
-
+ outputs = []
+
if extras_mode == 1:
#convert file to pillow image
for img in image_folder:
image = Image.open(img)
imageArr.append(image)
imageNameArr.append(os.path.splitext(img.orig_name)[0])
+ elif extras_mode == 2:
+ if input_dir == '':
+ return outputs, "Please select an input directory.", ''
+ image_list = [file for file in [os.path.join(input_dir, x) for x in os.listdir(input_dir)] if os.path.isfile(file)]
+ for img in image_list:
+ image = Image.open(img)
+ imageArr.append(image)
+ imageNameArr.append(img)
else:
imageArr.append(image)
imageNameArr.append(None)
- outpath = opts.outdir_samples or opts.outdir_extras_samples
+ if extras_mode == 2 and output_dir != '':
+ outpath = output_dir
+ else:
+ outpath = opts.outdir_samples or opts.outdir_extras_samples
- outputs = []
+
for image, image_name in zip(imageArr, imageNameArr):
if image is None:
return outputs, "Please select an input image.", ''
@@ -112,7 +124,8 @@ def run_extras(extras_mode, resize_mode, image, image_folder, gfpgan_visibility,
image.info = existing_pnginfo
image.info["extras"] = info
- outputs.append(image)
+ if extras_mode != 2 or show_extras_results :
+ outputs.append(image)
devices.torch_gc()
diff --git a/modules/ui.py b/modules/ui.py
index b867d40f..08fa72c6 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -1016,6 +1016,15 @@ def create_ui(wrap_gradio_gpu_call):
with gr.TabItem('Batch Process'):
image_batch = gr.File(label="Batch Process", file_count="multiple", interactive=True, type="file")
+ with gr.TabItem('Batch from Directory'):
+ extras_batch_input_dir = gr.Textbox(label="Input directory", **shared.hide_dirs,
+ placeholder="A directory on the same machine where the server is running."
+ )
+ extras_batch_output_dir = gr.Textbox(label="Output directory", **shared.hide_dirs,
+ placeholder="Leave blank to save images to the default path."
+ )
+ show_extras_results = gr.Checkbox(label='Show result images', value=True)
+
with gr.Tabs(elem_id="extras_resize_mode"):
with gr.TabItem('Scale by'):
upscaling_resize = gr.Slider(minimum=1.0, maximum=4.0, step=0.05, label="Resize", value=2)
@@ -1060,6 +1069,9 @@ def create_ui(wrap_gradio_gpu_call):
dummy_component,
extras_image,
image_batch,
+ extras_batch_input_dir,
+ extras_batch_output_dir,
+ show_extras_results,
gfpgan_visibility,
codeformer_visibility,
codeformer_weight,
--
cgit v1.2.1
From 179e3ca752d0133470fd3ae44153ee0b71450c9f Mon Sep 17 00:00:00 2001
From: AUTOMATIC <16777216c@gmail.com>
Date: Sun, 16 Oct 2022 09:51:01 +0300
Subject: honor --hide-ui-dir-config option for #2807
---
modules/extras.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/modules/extras.py b/modules/extras.py
index 5b52b27d..0819ed37 100644
--- a/modules/extras.py
+++ b/modules/extras.py
@@ -35,6 +35,8 @@ def run_extras(extras_mode, resize_mode, image, image_folder, input_dir, output_
imageArr.append(image)
imageNameArr.append(os.path.splitext(img.orig_name)[0])
elif extras_mode == 2:
+ assert not shared.cmd_opts.hide_ui_dir_config, '--hide-ui-dir-config option must be disabled'
+
if input_dir == '':
return outputs, "Please select an input directory.", ''
image_list = [file for file in [os.path.join(input_dir, x) for x in os.listdir(input_dir)] if os.path.isfile(file)]
--
cgit v1.2.1
From 3395ba493f93214cf037d084d45693a37610bd85 Mon Sep 17 00:00:00 2001
From: ddPn08
Date: Sun, 16 Oct 2022 09:24:01 +0900
Subject: Allow specifying the region of ngrok.
---
modules/ngrok.py | 8 +++++---
modules/shared.py | 1 +
modules/ui.py | 2 +-
3 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/modules/ngrok.py b/modules/ngrok.py
index 7d03a6df..5c5f349a 100644
--- a/modules/ngrok.py
+++ b/modules/ngrok.py
@@ -1,12 +1,14 @@
from pyngrok import ngrok, conf, exception
-def connect(token, port):
+def connect(token, port, region):
if token == None:
token = 'None'
- conf.get_default().auth_token = token
+ config = conf.PyngrokConfig(
+ auth_token=token, region=region
+ )
try:
- public_url = ngrok.connect(port).public_url
+ public_url = ngrok.connect(port, pyngrok_config=config).public_url
except exception.PyngrokNgrokError:
print(f'Invalid ngrok authtoken, ngrok connection aborted.\n'
f'Your token: {token}, get the right one on https://dashboard.ngrok.com/get-started/your-authtoken')
diff --git a/modules/shared.py b/modules/shared.py
index fa30bbb0..dcab0af9 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -40,6 +40,7 @@ parser.add_argument("--unload-gfpgan", action='store_true', help="does not do an
parser.add_argument("--precision", type=str, help="evaluate at this precision", choices=["full", "autocast"], default="autocast")
parser.add_argument("--share", action='store_true', help="use share=True for gradio and make the UI accessible through their site (doesn't work for me but you might have better luck)")
parser.add_argument("--ngrok", type=str, help="ngrok authtoken, alternative to gradio --share", default=None)
+parser.add_argument("--ngrok-region", type=str, help="The region in which ngrok should start.", default="us")
parser.add_argument("--codeformer-models-path", type=str, help="Path to directory with codeformer model file(s).", default=os.path.join(models_path, 'Codeformer'))
parser.add_argument("--gfpgan-models-path", type=str, help="Path to directory with GFPGAN model file(s).", default=os.path.join(models_path, 'GFPGAN'))
parser.add_argument("--esrgan-models-path", type=str, help="Path to directory with ESRGAN model file(s).", default=os.path.join(models_path, 'ESRGAN'))
diff --git a/modules/ui.py b/modules/ui.py
index 08fa72c6..5c0eaf73 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -56,7 +56,7 @@ if not cmd_opts.share and not cmd_opts.listen:
if cmd_opts.ngrok != None:
import modules.ngrok as ngrok
print('ngrok authtoken detected, trying to connect...')
- ngrok.connect(cmd_opts.ngrok, cmd_opts.port if cmd_opts.port != None else 7860)
+ ngrok.connect(cmd_opts.ngrok, cmd_opts.port if cmd_opts.port != None else 7860, cmd_opts.ngrok_region)
def gr_show(visible=True):
--
cgit v1.2.1
From 20bf99052a9d50b5f99d199f4c449ef1ddd6e3cb Mon Sep 17 00:00:00 2001
From: CookieHCl
Date: Sun, 16 Oct 2022 04:47:03 +0900
Subject: Make style configurable in ui-config.json
---
modules/ui.py | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/modules/ui.py b/modules/ui.py
index 5c0eaf73..78096f27 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -508,9 +508,11 @@ def create_toprow(is_img2img):
with gr.Row():
with gr.Column(scale=1, elem_id="style_pos_col"):
prompt_style = gr.Dropdown(label="Style 1", elem_id=f"{id_part}_style_index", choices=[k for k, v in shared.prompt_styles.styles.items()], value=next(iter(shared.prompt_styles.styles.keys())))
+ prompt_style.save_to_config = True
with gr.Column(scale=1, elem_id="style_neg_col"):
prompt_style2 = gr.Dropdown(label="Style 2", elem_id=f"{id_part}_style2_index", choices=[k for k, v in shared.prompt_styles.styles.items()], value=next(iter(shared.prompt_styles.styles.keys())))
+ prompt_style2.save_to_config = True
return prompt, roll, prompt_style, negative_prompt, prompt_style2, submit, button_interrogate, button_deepbooru, prompt_style_apply, save_style, paste, token_counter, token_button
@@ -1739,6 +1741,11 @@ Requested path was: {f}
if type(x) == gr.Number:
apply_field(x, 'value')
+ # Since there are many dropdowns that shouldn't be saved,
+ # we only mark dropdowns that should be saved.
+ if type(x) == gr.Dropdown and getattr(x, 'save_to_config', False):
+ apply_field(x, 'value')
+
visit(txt2img_interface, loadsave, "txt2img")
visit(img2img_interface, loadsave, "img2img")
visit(extras_interface, loadsave, "extras")
--
cgit v1.2.1
From b65a3101ce82b42b4ccc525044548e66cc44ae4a Mon Sep 17 00:00:00 2001
From: CookieHCl
Date: Sun, 16 Oct 2022 04:54:53 +0900
Subject: Use default value when dropdown ui setting is bad
Default value is the first value of selectables.
Particually, None in styles.
---
modules/ui.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/ui.py b/modules/ui.py
index 78096f27..c8e68bd6 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -1744,7 +1744,7 @@ Requested path was: {f}
# Since there are many dropdowns that shouldn't be saved,
# we only mark dropdowns that should be saved.
if type(x) == gr.Dropdown and getattr(x, 'save_to_config', False):
- apply_field(x, 'value')
+ apply_field(x, 'value', lambda val: val in x.choices)
visit(txt2img_interface, loadsave, "txt2img")
visit(img2img_interface, loadsave, "img2img")
--
cgit v1.2.1
From 9258a33e3755c76922cd47a03cd59419b6426304 Mon Sep 17 00:00:00 2001
From: CookieHCl
Date: Sun, 16 Oct 2022 05:09:11 +0900
Subject: Warn when user uses bad ui setting
---
modules/ui.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/modules/ui.py b/modules/ui.py
index c8e68bd6..10bdf121 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -1717,7 +1717,9 @@ Requested path was: {f}
saved_value = ui_settings.get(key, None)
if saved_value is None:
ui_settings[key] = getattr(obj, field)
- elif condition is None or condition(saved_value):
+ elif condition and not condition(saved_value):
+ print(f'Warning: Bad ui setting value: {key}: {saved_value}; Default value "{getattr(obj, field)}" will be used instead.')
+ else:
setattr(obj, field, saved_value)
if type(x) in [gr.Slider, gr.Radio, gr.Checkbox, gr.Textbox, gr.Number] and x.visible:
--
cgit v1.2.1
From 863e9efc19d2811f1db5055be8e346781df3f7ce Mon Sep 17 00:00:00 2001
From: Zeithrold <41533799+zeithrold@users.noreply.github.com>
Date: Sun, 16 Oct 2022 15:13:18 +0800
Subject: Pull out some of URL to Env Variable (#2578)
* moved repository url to changeable environment variable
* move stable diffusion repo itself to env
* added missing env
* Remove default URL
Co-authored-by: AUTOMATIC1111 <16777216c@gmail.com>
---
launch.py | 23 ++++++++++++++++-------
webui-user.sh | 20 +++++++++++++++++++-
webui.sh | 7 ++++++-
3 files changed, 41 insertions(+), 9 deletions(-)
diff --git a/launch.py b/launch.py
index 2e6b3369..7520cfee 100644
--- a/launch.py
+++ b/launch.py
@@ -94,6 +94,15 @@ def prepare_enviroment():
gfpgan_package = os.environ.get('GFPGAN_PACKAGE', "git+https://github.com/TencentARC/GFPGAN.git@8d2447a2d918f8eba5a4a01463fd48e45126a379")
clip_package = os.environ.get('CLIP_PACKAGE', "git+https://github.com/openai/CLIP.git@d50d76daa670286dd6cacf3bcd80b5e4823fc8e1")
+ deepdanbooru_package = os.environ.get('DEEPDANBOORU_PACKAGE', "git+https://github.com/KichangKim/DeepDanbooru.git@edf73df4cdaeea2cf00e9ac08bd8a9026b7a7b26")
+
+ xformers_windows_package = os.environ.get('XFORMERS_WINDOWS_PACKAGE', 'https://github.com/C43H66N12O12S2/stable-diffusion-webui/releases/download/f/xformers-0.0.14.dev0-cp310-cp310-win_amd64.whl')
+
+ stable_diffusion_repo = os.environ.get('STABLE_DIFFUSION_REPO', "https://github.com/CompVis/stable-diffusion.git")
+ taming_transformers_repo = os.environ.get('TAMING_REANSFORMERS_REPO', "https://github.com/CompVis/taming-transformers.git")
+ k_diffusion_repo = os.environ.get('K_DIFFUSION_REPO', 'https://github.com/crowsonkb/k-diffusion.git')
+ codeformer_repo = os.environ.get('CODEFORMET_REPO', 'https://github.com/sczhou/CodeFormer.git')
+ blip_repo = os.environ.get('BLIP_REPO', 'https://github.com/salesforce/BLIP.git')
stable_diffusion_commit_hash = os.environ.get('STABLE_DIFFUSION_COMMIT_HASH', "69ae4b35e0a0f6ee1af8bb9a5d0016ccb27e36dc")
taming_transformers_commit_hash = os.environ.get('TAMING_TRANSFORMERS_COMMIT_HASH', "24268930bf1dce879235a7fddd0b2355b84d7ea6")
@@ -131,23 +140,23 @@ def prepare_enviroment():
if (not is_installed("xformers") or reinstall_xformers) and xformers and platform.python_version().startswith("3.10"):
if platform.system() == "Windows":
- run_pip("install -U -I --no-deps https://github.com/C43H66N12O12S2/stable-diffusion-webui/releases/download/f/xformers-0.0.14.dev0-cp310-cp310-win_amd64.whl", "xformers")
+ run_pip(f"install -U -I --no-deps {xformers_windows_package}", "xformers")
elif platform.system() == "Linux":
run_pip("install xformers", "xformers")
if not is_installed("deepdanbooru") and deepdanbooru:
- run_pip("install git+https://github.com/KichangKim/DeepDanbooru.git@edf73df4cdaeea2cf00e9ac08bd8a9026b7a7b26#egg=deepdanbooru[tensorflow] tensorflow==2.10.0 tensorflow-io==0.27.0", "deepdanbooru")
+ run_pip(f"install {deepdanbooru_package}#egg=deepdanbooru[tensorflow] tensorflow==2.10.0 tensorflow-io==0.27.0", "deepdanbooru")
if not is_installed("pyngrok") and ngrok:
run_pip("install pyngrok", "ngrok")
os.makedirs(dir_repos, exist_ok=True)
- git_clone("https://github.com/CompVis/stable-diffusion.git", repo_dir('stable-diffusion'), "Stable Diffusion", stable_diffusion_commit_hash)
- git_clone("https://github.com/CompVis/taming-transformers.git", repo_dir('taming-transformers'), "Taming Transformers", taming_transformers_commit_hash)
- git_clone("https://github.com/crowsonkb/k-diffusion.git", repo_dir('k-diffusion'), "K-diffusion", k_diffusion_commit_hash)
- git_clone("https://github.com/sczhou/CodeFormer.git", repo_dir('CodeFormer'), "CodeFormer", codeformer_commit_hash)
- git_clone("https://github.com/salesforce/BLIP.git", repo_dir('BLIP'), "BLIP", blip_commit_hash)
+ git_clone(stable_diffusion_repo, repo_dir('stable-diffusion'), "Stable Diffusion", stable_diffusion_commit_hash)
+ git_clone(taming_transformers_repo, repo_dir('taming-transformers'), "Taming Transformers", taming_transformers_commit_hash)
+ git_clone(k_diffusion_repo, repo_dir('k-diffusion'), "K-diffusion", k_diffusion_commit_hash)
+ git_clone(codeformer_repo, repo_dir('CodeFormer'), "CodeFormer", codeformer_commit_hash)
+ git_clone(blip_repo, repo_dir('BLIP'), "BLIP", blip_commit_hash)
if not is_installed("lpips"):
run_pip(f"install -r {os.path.join(repo_dir('CodeFormer'), 'requirements.txt')}", "requirements for CodeFormer")
diff --git a/webui-user.sh b/webui-user.sh
index 30646f5c..96293d43 100644
--- a/webui-user.sh
+++ b/webui-user.sh
@@ -12,6 +12,8 @@
# Commandline arguments for webui.py, for example: export COMMANDLINE_ARGS="--medvram --opt-split-attention"
export COMMANDLINE_ARGS=""
+#export STABLE_DIFFUSION_WEBUI_REPO="https://github.com/AUTOMATIC1111/stable-diffusion-webui.git"
+
# python3 executable
#python_cmd="python3"
@@ -30,13 +32,29 @@ export COMMANDLINE_ARGS=""
# Requirements file to use for stable-diffusion-webui
#export REQS_FILE="requirements_versions.txt"
-# Fixed git repos
+# Fixed git-based pip packages
+# Example: "git+https://github.com/TencentARC/GFPGAN.git@8d2447a2d918f8eba5a4a01463fd48e45126a379"
#export K_DIFFUSION_PACKAGE=""
+
#export GFPGAN_PACKAGE=""
+#export DEEPDANBOORU_PACKAGE=""
+#export CLIP_PACKAGE=""
+
+#export XFORMERS_WINDOWS_PACKAGE=""
+
+# Fixed git repos
+# Example: "https://github.com/C43H66N12O12S2/stable-diffusion-webui/releases/download/c/xformers-0.0.14.dev0-cp310-cp310-win_amd64.whl"
+#export STABLE_DIFFUSION_REPO=""
+#export TAMING_REANSFORMERS_REPO=""
+#export K_DIFFUSION_REPO=""
+#export CODEFORMET_REPO=""
+#export BLIP_REPO=""
# Fixed git commits
+# Example: "69ae4b35e0a0f6ee1af8bb9a5d0016ccb27e36dc"
#export STABLE_DIFFUSION_COMMIT_HASH=""
#export TAMING_TRANSFORMERS_COMMIT_HASH=""
+#export K_DIFFUSION_COMMIT_HASH=""
#export CODEFORMER_COMMIT_HASH=""
#export BLIP_COMMIT_HASH=""
diff --git a/webui.sh b/webui.sh
index 980c0aaf..88a78459 100755
--- a/webui.sh
+++ b/webui.sh
@@ -41,6 +41,11 @@ then
venv_dir="venv"
fi
+if [[ -z "${STABLE_DIFFUSION_WEBUI_REPO}" ]]
+then
+ STABLE_DIFFUSION_WEBUI_REPO="https://github.com/AUTOMATIC1111/stable-diffusion-webui.git"
+fi
+
if [[ -z "${LAUNCH_SCRIPT}" ]]
then
LAUNCH_SCRIPT="launch.py"
@@ -111,7 +116,7 @@ then
cd "${clone_dir}"/ || { printf "\e[1m\e[31mERROR: Can't cd to %s/%s/, aborting...\e[0m" "${install_dir}" "${clone_dir}"; exit 1; }
"${GIT}" pull
else
- "${GIT}" clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git "${clone_dir}"
+ "${GIT}" clone "${STABLE_DIFFUSION_WEBUI_REPO}" "${clone_dir}"
cd "${clone_dir}"/ || { printf "\e[1m\e[31mERROR: Can't cd to %s/%s/, aborting...\e[0m" "${install_dir}" "${clone_dir}"; exit 1; }
fi
--
cgit v1.2.1
From bd4f0fb9d9df72899c2c3a1c2bc3580bf26bb685 Mon Sep 17 00:00:00 2001
From: AUTOMATIC <16777216c@gmail.com>
Date: Sun, 16 Oct 2022 10:14:27 +0300
Subject: revert changes to two bat files I asked to revert but the author
couldn't in 863e9efc19d2811f1db5055be8e346781df3f7ce.
---
webui-user.sh | 20 +-------------------
webui.sh | 7 +------
2 files changed, 2 insertions(+), 25 deletions(-)
diff --git a/webui-user.sh b/webui-user.sh
index 96293d43..30646f5c 100644
--- a/webui-user.sh
+++ b/webui-user.sh
@@ -12,8 +12,6 @@
# Commandline arguments for webui.py, for example: export COMMANDLINE_ARGS="--medvram --opt-split-attention"
export COMMANDLINE_ARGS=""
-#export STABLE_DIFFUSION_WEBUI_REPO="https://github.com/AUTOMATIC1111/stable-diffusion-webui.git"
-
# python3 executable
#python_cmd="python3"
@@ -32,29 +30,13 @@ export COMMANDLINE_ARGS=""
# Requirements file to use for stable-diffusion-webui
#export REQS_FILE="requirements_versions.txt"
-# Fixed git-based pip packages
-# Example: "git+https://github.com/TencentARC/GFPGAN.git@8d2447a2d918f8eba5a4a01463fd48e45126a379"
+# Fixed git repos
#export K_DIFFUSION_PACKAGE=""
-
#export GFPGAN_PACKAGE=""
-#export DEEPDANBOORU_PACKAGE=""
-#export CLIP_PACKAGE=""
-
-#export XFORMERS_WINDOWS_PACKAGE=""
-
-# Fixed git repos
-# Example: "https://github.com/C43H66N12O12S2/stable-diffusion-webui/releases/download/c/xformers-0.0.14.dev0-cp310-cp310-win_amd64.whl"
-#export STABLE_DIFFUSION_REPO=""
-#export TAMING_REANSFORMERS_REPO=""
-#export K_DIFFUSION_REPO=""
-#export CODEFORMET_REPO=""
-#export BLIP_REPO=""
# Fixed git commits
-# Example: "69ae4b35e0a0f6ee1af8bb9a5d0016ccb27e36dc"
#export STABLE_DIFFUSION_COMMIT_HASH=""
#export TAMING_TRANSFORMERS_COMMIT_HASH=""
-#export K_DIFFUSION_COMMIT_HASH=""
#export CODEFORMER_COMMIT_HASH=""
#export BLIP_COMMIT_HASH=""
diff --git a/webui.sh b/webui.sh
index 88a78459..980c0aaf 100755
--- a/webui.sh
+++ b/webui.sh
@@ -41,11 +41,6 @@ then
venv_dir="venv"
fi
-if [[ -z "${STABLE_DIFFUSION_WEBUI_REPO}" ]]
-then
- STABLE_DIFFUSION_WEBUI_REPO="https://github.com/AUTOMATIC1111/stable-diffusion-webui.git"
-fi
-
if [[ -z "${LAUNCH_SCRIPT}" ]]
then
LAUNCH_SCRIPT="launch.py"
@@ -116,7 +111,7 @@ then
cd "${clone_dir}"/ || { printf "\e[1m\e[31mERROR: Can't cd to %s/%s/, aborting...\e[0m" "${install_dir}" "${clone_dir}"; exit 1; }
"${GIT}" pull
else
- "${GIT}" clone "${STABLE_DIFFUSION_WEBUI_REPO}" "${clone_dir}"
+ "${GIT}" clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git "${clone_dir}"
cd "${clone_dir}"/ || { printf "\e[1m\e[31mERROR: Can't cd to %s/%s/, aborting...\e[0m" "${install_dir}" "${clone_dir}"; exit 1; }
fi
--
cgit v1.2.1
From 36a0ba357ab0742c3c4a28437b68fb29a235afbe Mon Sep 17 00:00:00 2001
From: Junpeng Qiu
Date: Sat, 15 Oct 2022 21:42:52 -0700
Subject: Added Refresh Button to embedding and hypernetwork names in Train Tab
Problem
everytime I modified pt files in embedding_dir or hypernetwork_dir, I
need to restart webui to have the new files shown in the dropdown of
Train Tab
Solution
refactored create_refresh_button out of create_setting_component so we
can use this method to create button next to gr.Dropdowns of embedding
name and hypernetworks
Extra Modification
hypernetwork pt are now sorted in alphabetic order
---
modules/ui.py | 45 ++++++++++++++++++++++++++-------------------
style.css | 2 +-
2 files changed, 27 insertions(+), 20 deletions(-)
diff --git a/modules/ui.py b/modules/ui.py
index 10bdf121..ee3d0248 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -568,6 +568,24 @@ def create_ui(wrap_gradio_gpu_call):
import modules.img2img
import modules.txt2img
+ def create_refresh_button(refresh_component, refresh_method, refreshed_args, elem_id):
+ def refresh():
+ refresh_method()
+ args = refreshed_args() if callable(refreshed_args) else refreshed_args
+
+ for k, v in args.items():
+ setattr(refresh_component, k, v)
+
+ return gr.update(**(args or {}))
+
+ refresh_button = gr.Button(value=refresh_symbol, elem_id=elem_id)
+ refresh_button.click(
+ fn = refresh,
+ inputs = [],
+ outputs = [refresh_component]
+ )
+ return refresh_button
+
with gr.Blocks(analytics_enabled=False) as txt2img_interface:
txt2img_prompt, roll, txt2img_prompt_style, txt2img_negative_prompt, txt2img_prompt_style2, submit, _, _, txt2img_prompt_style_apply, txt2img_save_style, txt2img_paste, token_counter, token_button = create_toprow(is_img2img=False)
dummy_component = gr.Label(visible=False)
@@ -1205,8 +1223,12 @@ def create_ui(wrap_gradio_gpu_call):
with gr.Tab(label="Train"):
gr.HTML(value="Train an embedding; must specify a directory with a set of 1:1 ratio images
")
- train_embedding_name = gr.Dropdown(label='Embedding', choices=sorted(sd_hijack.model_hijack.embedding_db.word_embeddings.keys()))
- train_hypernetwork_name = gr.Dropdown(label='Hypernetwork', choices=[x for x in shared.hypernetworks.keys()])
+ with gr.Row():
+ train_embedding_name = gr.Dropdown(label='Embedding', choices=sorted(sd_hijack.model_hijack.embedding_db.word_embeddings.keys()))
+ create_refresh_button(train_embedding_name, sd_hijack.model_hijack.embedding_db.load_textual_inversion_embeddings, lambda: {"choices": sorted(sd_hijack.model_hijack.embedding_db.word_embeddings.keys())}, "refresh_train_embedding_name")
+ with gr.Row():
+ train_hypernetwork_name = gr.Dropdown(label='Hypernetwork', choices=[x for x in shared.hypernetworks.keys()])
+ create_refresh_button(train_hypernetwork_name, shared.reload_hypernetworks, lambda: {"choices": sorted([x for x in shared.hypernetworks.keys()])}, "refresh_train_hypernetwork_name")
learn_rate = gr.Textbox(label='Learning rate', placeholder="Learning rate", value="0.005")
batch_size = gr.Number(label='Batch size', value=1, precision=0)
dataset_directory = gr.Textbox(label='Dataset directory', placeholder="Path to directory with input images")
@@ -1357,26 +1379,11 @@ def create_ui(wrap_gradio_gpu_call):
if info.refresh is not None:
if is_quicksettings:
res = comp(label=info.label, value=fun, **(args or {}))
- refresh_button = gr.Button(value=refresh_symbol, elem_id="refresh_"+key)
+ refresh_button = create_refresh_button(res, info.refresh, info.component_args, "refresh_" + key)
else:
with gr.Row(variant="compact"):
res = comp(label=info.label, value=fun, **(args or {}))
- refresh_button = gr.Button(value=refresh_symbol, elem_id="refresh_" + key)
-
- def refresh():
- info.refresh()
- refreshed_args = info.component_args() if callable(info.component_args) else info.component_args
-
- for k, v in refreshed_args.items():
- setattr(res, k, v)
-
- return gr.update(**(refreshed_args or {}))
-
- refresh_button.click(
- fn=refresh,
- inputs=[],
- outputs=[res],
- )
+ refresh_button = create_refresh_button(res, info.refresh, info.component_args, "refresh_" + key)
else:
res = comp(label=info.label, value=fun, **(args or {}))
diff --git a/style.css b/style.css
index 33832ebf..71eb4d20 100644
--- a/style.css
+++ b/style.css
@@ -478,7 +478,7 @@ input[type="range"]{
padding: 0;
}
-#refresh_sd_model_checkpoint, #refresh_sd_hypernetwork{
+#refresh_sd_model_checkpoint, #refresh_sd_hypernetwork, #refresh_train_hypernetwork_name, #refresh_train_embedding_name{
max-width: 2.5em;
min-width: 2.5em;
height: 2.4em;
--
cgit v1.2.1
From 523140d7805c644700009b8a2483ff4eb4a22304 Mon Sep 17 00:00:00 2001
From: MalumaDev
Date: Sun, 16 Oct 2022 10:23:30 +0200
Subject: ui fix
---
modules/aesthetic_clip.py | 3 +--
modules/sd_hijack.py | 3 +--
modules/shared.py | 2 ++
modules/ui.py | 24 ++++++++++++++----------
4 files changed, 18 insertions(+), 14 deletions(-)
diff --git a/modules/aesthetic_clip.py b/modules/aesthetic_clip.py
index 68264284..ccb35c73 100644
--- a/modules/aesthetic_clip.py
+++ b/modules/aesthetic_clip.py
@@ -74,5 +74,4 @@ def generate_imgs_embd(name, folder, batch_size):
"""
shared.update_aesthetic_embeddings()
return gr.Dropdown.update(choices=sorted(shared.aesthetic_embeddings.keys()), label="Imgs embedding",
- value=sorted(shared.aesthetic_embeddings.keys())[0] if len(
- shared.aesthetic_embeddings) > 0 else None), res, ""
+ value="None"), res, ""
diff --git a/modules/sd_hijack.py b/modules/sd_hijack.py
index 01fcb78f..2de2eed5 100644
--- a/modules/sd_hijack.py
+++ b/modules/sd_hijack.py
@@ -392,8 +392,7 @@ class FrozenCLIPEmbedderWithCustomWords(torch.nn.Module):
z1 = self.process_tokens(tokens, multipliers)
z = z1 if z is None else torch.cat((z, z1), axis=-2)
- if len(text[
- 0]) != 0 and self.aesthetic_steps != 0 and self.aesthetic_lr != 0 and self.aesthetic_weight != 0 and self.image_embs_name != None:
+ if self.aesthetic_steps != 0 and self.aesthetic_lr != 0 and self.aesthetic_weight != 0 and self.image_embs_name != None:
if not opts.use_old_emphasis_implementation:
remade_batch_tokens = [
[self.wrapped.tokenizer.bos_token_id] + x[:75] + [self.wrapped.tokenizer.eos_token_id] for x in
diff --git a/modules/shared.py b/modules/shared.py
index 3c5ffef1..e2c98b2d 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -96,11 +96,13 @@ loaded_hypernetwork = None
aesthetic_embeddings = {f.replace(".pt",""): os.path.join(cmd_opts.aesthetic_embeddings_dir, f) for f in
os.listdir(cmd_opts.aesthetic_embeddings_dir) if f.endswith(".pt")}
+aesthetic_embeddings = aesthetic_embeddings | {"None": None}
def update_aesthetic_embeddings():
global aesthetic_embeddings
aesthetic_embeddings = {f.replace(".pt",""): os.path.join(cmd_opts.aesthetic_embeddings_dir, f) for f in
os.listdir(cmd_opts.aesthetic_embeddings_dir) if f.endswith(".pt")}
+ aesthetic_embeddings = aesthetic_embeddings | {"None": None}
def reload_hypernetworks():
global hypernetworks
diff --git a/modules/ui.py b/modules/ui.py
index 13ba3142..4069f0d2 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -594,19 +594,23 @@ def create_ui(wrap_gradio_gpu_call):
height = gr.Slider(minimum=64, maximum=2048, step=64, label="Height", value=512)
with gr.Group():
- aesthetic_lr = gr.Textbox(label='Aesthetic learning rate', placeholder="Aesthetic learning rate", value="0.0001")
-
- aesthetic_weight = gr.Slider(minimum=0, maximum=1, step=0.01, label="Aesthetic weight", value=0.9)
- aesthetic_steps = gr.Slider(minimum=0, maximum=50, step=1, label="Aesthetic steps", value=5)
+ with gr.Accordion("Open for Clip Aesthetic!",open=False):
+ with gr.Row():
+ aesthetic_weight = gr.Slider(minimum=0, maximum=1, step=0.01, label="Aesthetic weight", value=0.9)
+ aesthetic_steps = gr.Slider(minimum=0, maximum=50, step=1, label="Aesthetic steps", value=5)
- with gr.Row():
- aesthetic_imgs_text = gr.Textbox(label='Aesthetic text for imgs', placeholder="This text is used to rotate the feature space of the imgs embs", value="")
- aesthetic_slerp_angle = gr.Slider(label='Slerp angle',minimum=0, maximum=1, step=0.01, value=0.1)
- aesthetic_text_negative = gr.Checkbox(label="Is negative text", value=False)
+ with gr.Row():
+ aesthetic_lr = gr.Textbox(label='Aesthetic learning rate', placeholder="Aesthetic learning rate", value="0.0001")
+ aesthetic_slerp = gr.Checkbox(label="Slerp interpolation", value=False)
+ aesthetic_imgs = gr.Dropdown(sorted(aesthetic_embeddings.keys()),
+ label="Aesthetic imgs embedding",
+ value="None")
- aesthetic_imgs = gr.Dropdown(sorted(aesthetic_embeddings.keys()), label="Aesthetic imgs embedding", value=sorted(aesthetic_embeddings.keys())[0] if len(aesthetic_embeddings) > 0 else None)
+ with gr.Row():
+ aesthetic_imgs_text = gr.Textbox(label='Aesthetic text for imgs', placeholder="This text is used to rotate the feature space of the imgs embs", value="")
+ aesthetic_slerp_angle = gr.Slider(label='Slerp angle',minimum=0, maximum=1, step=0.01, value=0.1)
+ aesthetic_text_negative = gr.Checkbox(label="Is negative text", value=False)
- aesthetic_slerp = gr.Checkbox(label="Slerp interpolation", value=False)
with gr.Row():
restore_faces = gr.Checkbox(label='Restore faces', value=False, visible=len(shared.face_restorers) > 1)
--
cgit v1.2.1
From e4f8b5f00dd33b7547cc6b76fbed26bb83b37a64 Mon Sep 17 00:00:00 2001
From: MalumaDev
Date: Sun, 16 Oct 2022 10:28:21 +0200
Subject: ui fix
---
modules/sd_hijack.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/sd_hijack.py b/modules/sd_hijack.py
index 2de2eed5..5d0590af 100644
--- a/modules/sd_hijack.py
+++ b/modules/sd_hijack.py
@@ -178,7 +178,7 @@ class FrozenCLIPEmbedderWithCustomWords(torch.nn.Module):
self.load_image_embs(image_embs_name)
def load_image_embs(self, image_embs_name):
- if image_embs_name is None or len(image_embs_name) == 0:
+ if image_embs_name is None or len(image_embs_name) == 0 or image_embs_name == "None":
image_embs_name = None
if image_embs_name is not None and self.image_embs_name != image_embs_name:
self.image_embs_name = image_embs_name
--
cgit v1.2.1
From f62905fdf928b54aa76765e5cbde8d538d494e49 Mon Sep 17 00:00:00 2001
From: yfszzx
Date: Sun, 16 Oct 2022 21:22:38 +0800
Subject: images history speed up
---
javascript/images_history.js | 39 ++++---
modules/images_history.py | 250 ++++++++++++++++++++++---------------------
2 files changed, 147 insertions(+), 142 deletions(-)
diff --git a/javascript/images_history.js b/javascript/images_history.js
index ac5834c7..fb1356d9 100644
--- a/javascript/images_history.js
+++ b/javascript/images_history.js
@@ -20,7 +20,7 @@ var images_history_click_image = function(){
var images_history_click_tab = function(){
var tabs_box = gradioApp().getElementById("images_history_tab");
if (!tabs_box.classList.contains(this.getAttribute("tabname"))) {
- gradioApp().getElementById(this.getAttribute("tabname") + "_images_history_renew_page").click();
+ gradioApp().getElementById(this.getAttribute("tabname") + "_images_history_start").click();
tabs_box.classList.add(this.getAttribute("tabname"))
}
}
@@ -96,7 +96,7 @@ function images_history_get_current_img(tabname, img_index, files){
];
}
-function images_history_delete(del_num, tabname, img_file_name, page_index, filenames, image_index){
+function images_history_delete(del_num, tabname, image_index){
image_index = parseInt(image_index);
var tab = gradioApp().getElementById(tabname + '_images_history');
var set_btn = tab.querySelector(".images_history_set_index");
@@ -107,6 +107,7 @@ function images_history_delete(del_num, tabname, img_file_name, page_index, file
}
});
var img_num = buttons.length / 2;
+ del_num = Math.min(img_num - image_index, del_num)
if (img_num <= del_num){
setTimeout(function(tabname){
gradioApp().getElementById(tabname + '_images_history_renew_page').click();
@@ -114,30 +115,29 @@ function images_history_delete(del_num, tabname, img_file_name, page_index, file
} else {
var next_img
for (var i = 0; i < del_num; i++){
- if (image_index + i < image_index + img_num){
- buttons[image_index + i].style.display = 'none';
- buttons[image_index + img_num + 1].style.display = 'none';
- next_img = image_index + i + 1
- }
+ buttons[image_index + i].style.display = 'none';
+ buttons[image_index + i + img_num].style.display = 'none';
+ next_img = image_index + i + 1
}
var bnt;
if (next_img >= img_num){
- btn = buttons[image_index - del_num];
+ btn = buttons[image_index - 1];
} else {
btn = buttons[next_img];
}
setTimeout(function(btn){btn.click()}, 30, btn);
}
images_history_disabled_del();
- return [del_num, tabname, img_file_name, page_index, filenames, image_index];
+
}
-function images_history_turnpage(img_path, page_index, image_index, tabname, date_from, date_to){
+function images_history_turnpage(tabname){
+ console.log("del_button")
+ gradioApp().getElementById(tabname + '_images_history_del_button').setAttribute('disabled','disabled');
var buttons = gradioApp().getElementById(tabname + '_images_history').querySelectorAll(".gallery-item");
buttons.forEach(function(elem) {
elem.style.display = 'block';
- })
- return [img_path, page_index, image_index, tabname, date_from, date_to];
+ })
}
function images_history_enable_del_buttons(){
@@ -147,7 +147,7 @@ function images_history_enable_del_buttons(){
}
function images_history_init(){
- var load_txt2img_button = gradioApp().getElementById('txt2img_images_history_renew_page')
+ var load_txt2img_button = gradioApp().getElementById('saved_images_history_start')
if (load_txt2img_button){
for (var i in images_history_tab_list ){
tab = images_history_tab_list[i];
@@ -166,7 +166,8 @@ function images_history_init(){
// this refreshes history upon tab switch
// until the history is known to work well, which is not the case now, we do not do this at startup
- //tab_btns[i].addEventListener('click', images_history_click_tab);
+ // -- load page very fast now, so better user experience by automatically activating pages
+ tab_btns[i].addEventListener('click', images_history_click_tab);
}
tabs_box.classList.add(images_history_tab_list[0]);
@@ -177,7 +178,7 @@ function images_history_init(){
}
}
-var images_history_tab_list = ["txt2img", "img2img", "extras"];
+var images_history_tab_list = ["saved", "txt2img", "img2img", "extras"];
setTimeout(images_history_init, 500);
document.addEventListener("DOMContentLoaded", function() {
var mutationObserver = new MutationObserver(function(m){
@@ -188,18 +189,16 @@ document.addEventListener("DOMContentLoaded", function() {
bnt.addEventListener('click', images_history_click_image, true);
});
- // same as load_txt2img_button.click() above
- /*
var cls_btn = gradioApp().getElementById(tabname + '_images_history_gallery').querySelector("svg");
if (cls_btn){
cls_btn.addEventListener('click', function(){
- gradioApp().getElementById(tabname + '_images_history_renew_page').click();
+ gradioApp().getElementById(tabname + '_images_history_del_button').setAttribute('disabled','disabled');
}, false);
- }*/
+ }
}
});
- mutationObserver.observe( gradioApp(), { childList:true, subtree:true });
+ mutationObserver.observe(gradioApp(), { childList:true, subtree:true });
});
diff --git a/modules/images_history.py b/modules/images_history.py
index 7fd75005..ae0b4e40 100644
--- a/modules/images_history.py
+++ b/modules/images_history.py
@@ -3,8 +3,10 @@ import shutil
import time
import hashlib
import gradio
-show_max_dates_num = 3
+
system_bak_path = "webui_log_and_bak"
+loads_files_num = 216
+num_of_imgs_per_page = 36
def is_valid_date(date):
try:
time.strptime(date, "%Y%m%d")
@@ -53,38 +55,7 @@ def traverse_all_files(curr_path, image_list, all_type=False):
image_list = traverse_all_files(file, image_list)
return image_list
-def get_recent_images(dir_name, page_index, step, image_index, tabname, date_from, date_to):
- #print(f"turn_page {page_index}",date_from)
- if date_from is None or date_from == "":
- return None, 1, None, ""
- image_list = []
- date_list = auto_sorting(dir_name)
- page_index = int(page_index)
- today = time.strftime("%Y%m%d",time.localtime(time.time()))
- for date in date_list:
- if date >= date_from and date <= date_to:
- path = os.path.join(dir_name, date)
- if date == today and not os.path.exists(path):
- continue
- image_list = traverse_all_files(path, image_list)
-
- image_list = sorted(image_list, key=lambda file: -os.path.getctime(file))
- num = 48 if tabname != "extras" else 12
- max_page_index = len(image_list) // num + 1
- page_index = max_page_index if page_index == -1 else page_index + step
- page_index = 1 if page_index < 1 else page_index
- page_index = max_page_index if page_index > max_page_index else page_index
- idx_frm = (page_index - 1) * num
- image_list = image_list[idx_frm:idx_frm + num]
- image_index = int(image_index)
- if image_index < 0 or image_index > len(image_list) - 1:
- current_file = None
- else:
- current_file = image_list[image_index]
- return image_list, page_index, image_list, ""
-
-def auto_sorting(dir_name):
- #print(f"auto sorting")
+def auto_sorting(dir_name):
bak_path = os.path.join(dir_name, system_bak_path)
if not os.path.exists(bak_path):
os.mkdir(bak_path)
@@ -126,102 +97,131 @@ def auto_sorting(dir_name):
today = time.strftime("%Y%m%d",time.localtime(time.time()))
if today not in date_list:
date_list.append(today)
- return sorted(date_list)
+ return sorted(date_list, reverse=True)
-def archive_images(dir_name):
+def archive_images(dir_name, date_to):
date_list = auto_sorting(dir_name)
- date_from = date_list[-show_max_dates_num] if len(date_list) > show_max_dates_num else date_list[0]
+ today = time.strftime("%Y%m%d",time.localtime(time.time()))
+ date_to = today if date_to is None or date_to == "" else date_to
+ filenames = []
+ for date in date_list:
+ if date <= date_to:
+ path = os.path.join(dir_name, date)
+ if date == today and not os.path.exists(path):
+ continue
+ filenames = traverse_all_files(path, filenames)
+ if len(filenames) > loads_files_num:
+ break
+ filenames = sorted(filenames, key=lambda file: -os.path.getctime(file))
+ _, image_list, _, visible_num = get_recent_images(1, 0, filenames)
return (
gradio.update(visible=False),
gradio.update(visible=True),
- gradio.Dropdown.update(choices=date_list, value=date_list[-1]),
- gradio.Dropdown.update(choices=date_list, value=date_from)
+ gradio.Dropdown.update(choices=date_list, value=date_to),
+ date,
+ filenames,
+ 1,
+ image_list,
+ "",
+ visible_num
)
+def system_init(dir_name):
+ ret = [x for x in archive_images(dir_name, None)]
+ ret += [gradio.update(visible=False)]
+ return ret
+
+def newest_click(dir_name, date_to):
+ if date_to == "start":
+ return True, False, "start", None, None, 1, None, ""
+ else:
+ return archive_images(dir_name, time.strftime("%Y%m%d",time.localtime(time.time())))
-def date_to_change(dir_name, page_index, image_index, tabname, date_from, date_to):
- #print("date_to", date_to)
- date_list = auto_sorting(dir_name)
- date_from_list = [date for date in date_list if date <= date_to]
- date_from = date_from_list[0] if len(date_from_list) < show_max_dates_num else date_from_list[-show_max_dates_num]
- image_list, page_index, image_list, _ =get_recent_images(dir_name, 1, 0, image_index, tabname, date_from, date_to)
- return image_list, page_index, image_list, _, gradio.Dropdown.update(choices=date_from_list, value=date_from)
-
-def first_page_click(dir_name, page_index, image_index, tabname, date_from, date_to):
- return get_recent_images(dir_name, 1, 0, image_index, tabname, date_from, date_to)
-
-
-def end_page_click(dir_name, page_index, image_index, tabname, date_from, date_to):
- return get_recent_images(dir_name, -1, 0, image_index, tabname, date_from, date_to)
-
-
-def prev_page_click(dir_name, page_index, image_index, tabname, date_from, date_to):
- return get_recent_images(dir_name, page_index, -1, image_index, tabname, date_from, date_to)
-
-
-def next_page_click(dir_name, page_index, image_index, tabname, date_from, date_to):
- return get_recent_images(dir_name, page_index, 1, image_index, tabname, date_from, date_to)
-
-
-def page_index_change(dir_name, page_index, image_index, tabname, date_from, date_to):
- return get_recent_images(dir_name, page_index, 0, image_index, tabname, date_from, date_to)
-
-
-def show_image_info(tabname_box, num, filenames):
- # #print(f"select image {num}")
- file = filenames[int(num)]
- return file, num, file
-
-def delete_image(delete_num, tabname, name, page_index, filenames, image_index):
+def delete_image(delete_num, name, filenames, image_index, visible_num):
if name == "":
return filenames, delete_num
else:
delete_num = int(delete_num)
+ visible_num = int(visible_num)
+ image_index = int(image_index)
index = list(filenames).index(name)
i = 0
new_file_list = []
for name in filenames:
if i >= index and i < index + delete_num:
if os.path.exists(name):
- #print(f"Delete file {name}")
+ if visible_num == image_index:
+ new_file_list.append(name)
+ continue
+ print(f"Delete file {name}")
os.remove(name)
+ visible_num -= 1
txt_file = os.path.splitext(name)[0] + ".txt"
if os.path.exists(txt_file):
os.remove(txt_file)
else:
- #print(f"Not exists file {name}")
+ print(f"Not exists file {name}")
else:
new_file_list.append(name)
i += 1
- return new_file_list, 1
+ return new_file_list, 1, visible_num
+
+def get_recent_images(page_index, step, filenames):
+ page_index = int(page_index)
+ max_page_index = len(filenames) // num_of_imgs_per_page + 1
+ page_index = max_page_index if page_index == -1 else page_index + step
+ page_index = 1 if page_index < 1 else page_index
+ page_index = max_page_index if page_index > max_page_index else page_index
+ idx_frm = (page_index - 1) * num_of_imgs_per_page
+ image_list = filenames[idx_frm:idx_frm + num_of_imgs_per_page]
+ length = len(filenames)
+ visible_num = num_of_imgs_per_page if idx_frm + num_of_imgs_per_page <= length else length % num_of_imgs_per_page
+ visible_num = num_of_imgs_per_page if visible_num == 0 else visible_num
+ return page_index, image_list, "", visible_num
+
+def first_page_click(page_index, filenames):
+ return get_recent_images(1, 0, filenames)
+
+def end_page_click(page_index, filenames):
+ return get_recent_images(-1, 0, filenames)
+
+def prev_page_click(page_index, filenames):
+ return get_recent_images(page_index, -1, filenames)
+
+def next_page_click(page_index, filenames):
+ return get_recent_images(page_index, 1, filenames)
+
+def page_index_change(page_index, filenames):
+ return get_recent_images(page_index, 0, filenames)
+
+def show_image_info(tabname_box, num, page_index, filenames):
+ file = filenames[int(num) + int((page_index - 1) * num_of_imgs_per_page)]
+ return file, num, file
def show_images_history(gr, opts, tabname, run_pnginfo, switch_dict):
- if opts.outdir_samples != "":
- dir_name = opts.outdir_samples
- elif tabname == "txt2img":
+ if tabname == "txt2img":
dir_name = opts.outdir_txt2img_samples
elif tabname == "img2img":
dir_name = opts.outdir_img2img_samples
elif tabname == "extras":
dir_name = opts.outdir_extras_samples
+ elif tabname == "saved":
+ dir_name = opts.outdir_save
+ if not os.path.exists(dir_name):
+ os.makedirs(dir_name)
d = dir_name.split("/")
- dir_name = "/" if dir_name.startswith("/") else d[0]
+ dir_name = d[0]
for p in d[1:]:
dir_name = os.path.join(dir_name, p)
f_list = os.listdir(dir_name)
sorted_flag = os.path.exists(os.path.join(dir_name, system_bak_path)) or len(f_list) == 0
date_list, date_from, date_to = None, None, None
- if sorted_flag:
- #print(sorted_flag)
- date_list = auto_sorting(dir_name)
- date_to = date_list[-1]
- date_from = date_list[-show_max_dates_num] if len(date_list) > show_max_dates_num else date_list[0]
with gr.Column(visible=sorted_flag) as page_panel:
with gr.Row():
- renew_page = gr.Button('Refresh', elem_id=tabname + "_images_history_renew_page", interactive=sorted_flag)
+ #renew_page = gr.Button('Refresh')
first_page = gr.Button('First Page')
prev_page = gr.Button('Prev Page')
page_index = gr.Number(value=1, label="Page Index")
@@ -231,9 +231,9 @@ def show_images_history(gr, opts, tabname, run_pnginfo, switch_dict):
with gr.Row(elem_id=tabname + "_images_history"):
with gr.Column(scale=2):
with gr.Row():
- newest = gr.Button('Newest')
- date_to = gr.Dropdown(choices=date_list, value=date_to, label="Date to")
- date_from = gr.Dropdown(choices=date_list, value=date_from, label="Date from")
+ newest = gr.Button('Refresh', elem_id=tabname + "_images_history_start")
+ date_from = gr.Textbox(label="Date from", interactive=False)
+ date_to = gr.Dropdown(value="start" if not sorted_flag else None, label="Date to")
history_gallery = gr.Gallery(show_label=False, elem_id=tabname + "_images_history_gallery").style(grid=6)
with gr.Row():
@@ -247,66 +247,72 @@ def show_images_history(gr, opts, tabname, run_pnginfo, switch_dict):
with gr.Column():
img_file_info = gr.Textbox(label="Generate Info", interactive=False)
img_file_name = gr.Textbox(value="", label="File Name", interactive=False)
+
# hiden items
- with gr.Row(visible=False):
+ with gr.Row(visible=False):
+ visible_img_num = gr.Number()
img_path = gr.Textbox(dir_name)
tabname_box = gr.Textbox(tabname)
image_index = gr.Textbox(value=-1)
set_index = gr.Button('set_index', elem_id=tabname + "_images_history_set_index")
filenames = gr.State()
+ all_images_list = gr.State()
hidden = gr.Image(type="pil")
info1 = gr.Textbox()
info2 = gr.Textbox()
+
with gr.Column(visible=not sorted_flag) as init_warning:
with gr.Row():
- gr.Textbox("The system needs to archive the files according to the date. This requires changing the directory structure of the files",
- label="Waring",
- css="")
+ warning = gr.Textbox(
+ label="Waring",
+ value=f"The system needs to archive the files according to the date. This requires changing the directory structure of the files.If you have doubts about this operation, you can first back up the files in the '{dir_name}' directory"
+ )
+ warning.style(height=100, width=50)
with gr.Row():
sorted_button = gr.Button('Confirme')
-
-
+ change_date_output = [init_warning, page_panel, date_to, date_from, filenames, page_index, history_gallery, img_file_name, visible_img_num]
+ sorted_button.click(system_init, inputs=[img_path], outputs=change_date_output + [sorted_button])
+ newest.click(newest_click, inputs=[img_path, date_to], outputs=change_date_output)
+ date_to.change(archive_images, inputs=[img_path, date_to], outputs=change_date_output)
+ date_to.change(fn=None, inputs=[tabname_box], outputs=None, _js="images_history_turnpage")
+ newest.click(fn=None, inputs=[tabname_box], outputs=None, _js="images_history_turnpage")
+
+ delete.click(delete_image, inputs=[delete_num, img_file_name, filenames, image_index, visible_img_num], outputs=[filenames, delete_num, visible_img_num])
+ delete.click(fn=None, _js="images_history_delete", inputs=[delete_num, tabname_box, image_index], outputs=None)
+
# turn pages
- gallery_inputs = [img_path, page_index, image_index, tabname_box, date_from, date_to]
- gallery_outputs = [history_gallery, page_index, filenames, img_file_name]
+ gallery_inputs = [page_index, filenames]
+ gallery_outputs = [page_index, history_gallery, img_file_name, visible_img_num]
+
+ first_page.click(first_page_click, inputs=gallery_inputs, outputs=gallery_outputs)
+ next_page.click(next_page_click, inputs=gallery_inputs, outputs=gallery_outputs)
+ prev_page.click(prev_page_click, inputs=gallery_inputs, outputs=gallery_outputs)
+ end_page.click(end_page_click, inputs=gallery_inputs, outputs=gallery_outputs)
+ page_index.submit(page_index_change, inputs=gallery_inputs, outputs=gallery_outputs)
- first_page.click(first_page_click, _js="images_history_turnpage", inputs=gallery_inputs, outputs=gallery_outputs)
- next_page.click(next_page_click, _js="images_history_turnpage", inputs=gallery_inputs, outputs=gallery_outputs)
- prev_page.click(prev_page_click, _js="images_history_turnpage", inputs=gallery_inputs, outputs=gallery_outputs)
- end_page.click(end_page_click, _js="images_history_turnpage", inputs=gallery_inputs, outputs=gallery_outputs)
- page_index.submit(page_index_change, _js="images_history_turnpage", inputs=gallery_inputs, outputs=gallery_outputs)
- renew_page.click(page_index_change, _js="images_history_turnpage", inputs=gallery_inputs, outputs=gallery_outputs)
- # page_index.change(page_index_change, inputs=[tabname_box, img_path, page_index], outputs=[history_gallery, page_index])
+ first_page.click(fn=None, inputs=[tabname_box], outputs=None, _js="images_history_turnpage")
+ next_page.click(fn=None, inputs=[tabname_box], outputs=None, _js="images_history_turnpage")
+ prev_page.click(fn=None, inputs=[tabname_box], outputs=None, _js="images_history_turnpage")
+ end_page.click(fn=None, inputs=[tabname_box], outputs=None, _js="images_history_turnpage")
+ page_index.submit(fn=None, inputs=[tabname_box], outputs=None, _js="images_history_turnpage")
# other funcitons
- set_index.click(show_image_info, _js="images_history_get_current_img", inputs=[tabname_box, image_index, filenames], outputs=[img_file_name, image_index, hidden])
- img_file_name.change(fn=None, _js="images_history_enable_del_buttons", inputs=None, outputs=None)
- delete.click(delete_image, _js="images_history_delete", inputs=[delete_num, tabname_box, img_file_name, page_index, filenames, image_index], outputs=[filenames, delete_num])
+ set_index.click(show_image_info, _js="images_history_get_current_img", inputs=[tabname_box, image_index, page_index, filenames], outputs=[img_file_name, image_index, hidden])
+ img_file_name.change(fn=None, _js="images_history_enable_del_buttons", inputs=None, outputs=None)
hidden.change(fn=run_pnginfo, inputs=[hidden], outputs=[info1, img_file_info, info2])
- date_to.change(date_to_change, _js="images_history_turnpage", inputs=gallery_inputs, outputs=gallery_outputs + [date_from])
- # pnginfo.click(fn=run_pnginfo, inputs=[hidden], outputs=[info1, img_file_info, info2])
+
switch_dict["fn"](pnginfo_send_to_txt2img, switch_dict["t2i"], img_file_info, 'switch_to_txt2img')
switch_dict["fn"](pnginfo_send_to_img2img, switch_dict["i2i"], img_file_info, 'switch_to_img2img_img2img')
- sorted_button.click(archive_images, inputs=[img_path], outputs=[init_warning, page_panel, date_to, date_from])
- newest.click(archive_images, inputs=[img_path], outputs=[init_warning, page_panel, date_to, date_from])
-
-
-
def create_history_tabs(gr, opts, run_pnginfo, switch_dict):
with gr.Blocks(analytics_enabled=False) as images_history:
with gr.Tabs() as tabs:
- with gr.Tab("txt2img history"):
- with gr.Blocks(analytics_enabled=False) as images_history_txt2img:
- show_images_history(gr, opts, "txt2img", run_pnginfo, switch_dict)
- with gr.Tab("img2img history"):
- with gr.Blocks(analytics_enabled=False) as images_history_img2img:
- show_images_history(gr, opts, "img2img", run_pnginfo, switch_dict)
- with gr.Tab("extras history"):
- with gr.Blocks(analytics_enabled=False) as images_history_img2img:
- show_images_history(gr, opts, "extras", run_pnginfo, switch_dict)
+ for tab in ["saved", "txt2img", "img2img", "extras"]:
+ with gr.Tab(tab):
+ with gr.Blocks(analytics_enabled=False) as images_history_img2img:
+ show_images_history(gr, opts, tab, run_pnginfo, switch_dict)
return images_history
--
cgit v1.2.1
From 91235d8008372862b1f232f7bf99da310a5955e4 Mon Sep 17 00:00:00 2001
From: CookieHCl
Date: Sun, 16 Oct 2022 20:50:24 +0900
Subject: Fix FileNotFoundError in history tab
Now only traverse images when directory exists
---
modules/images_history.py | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/modules/images_history.py b/modules/images_history.py
index 9260df8a..e6284142 100644
--- a/modules/images_history.py
+++ b/modules/images_history.py
@@ -1,6 +1,6 @@
import os
import shutil
-
+import sys
def traverse_all_files(output_dir, image_list, curr_dir=None):
curr_path = output_dir if curr_dir is None else os.path.join(output_dir, curr_dir)
@@ -24,10 +24,14 @@ def traverse_all_files(output_dir, image_list, curr_dir=None):
def get_recent_images(dir_name, page_index, step, image_index, tabname):
page_index = int(page_index)
- f_list = os.listdir(dir_name)
image_list = []
- image_list = traverse_all_files(dir_name, image_list)
- image_list = sorted(image_list, key=lambda file: -os.path.getctime(os.path.join(dir_name, file)))
+ if not os.path.exists(dir_name):
+ pass
+ elif os.path.isdir(dir_name):
+ image_list = traverse_all_files(dir_name, image_list)
+ image_list = sorted(image_list, key=lambda file: -os.path.getctime(os.path.join(dir_name, file)))
+ else:
+ print(f"ERROR: {dir_name} is not a directory. Check the path in the settings.", file=sys.stderr)
num = 48 if tabname != "extras" else 12
max_page_index = len(image_list) // num + 1
page_index = max_page_index if page_index == -1 else page_index + step
--
cgit v1.2.1
From c9836279f58461e04c1dda0a86e718f8bd3f41e4 Mon Sep 17 00:00:00 2001
From: CookieHCl
Date: Sun, 16 Oct 2022 21:59:05 +0900
Subject: Only make output dir when creating output
---
modules/processing.py | 6 ------
modules/ui.py | 5 ++++-
2 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/modules/processing.py b/modules/processing.py
index 833fed8a..deb6125e 100644
--- a/modules/processing.py
+++ b/modules/processing.py
@@ -334,12 +334,6 @@ def process_images(p: StableDiffusionProcessing) -> Processed:
seed = get_fixed_seed(p.seed)
subseed = get_fixed_seed(p.subseed)
- if p.outpath_samples is not None:
- os.makedirs(p.outpath_samples, exist_ok=True)
-
- if p.outpath_grids is not None:
- os.makedirs(p.outpath_grids, exist_ok=True)
-
modules.sd_hijack.model_hijack.apply_circular(p.tiling)
modules.sd_hijack.model_hijack.clear_comments()
diff --git a/modules/ui.py b/modules/ui.py
index ee3d0248..fa73627a 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -1394,7 +1394,10 @@ def create_ui(wrap_gradio_gpu_call):
component_dict = {}
def open_folder(f):
- if not os.path.isdir(f):
+ if not os.path.exists(f):
+ print(f"{f} doesn't exist. After you create an image, the folder will be created.")
+ return
+ elif not os.path.isdir(f):
print(f"""
WARNING
An open_folder request was made with an argument that is not a folder.
--
cgit v1.2.1
From adc0ea74e1ee9791f15c3a74bc6c5ad789e10d17 Mon Sep 17 00:00:00 2001
From: CookieHCl
Date: Sun, 16 Oct 2022 22:03:18 +0900
Subject: Better readablity of logs
---
modules/images_history.py | 2 +-
modules/ui.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules/images_history.py b/modules/images_history.py
index e6284142..e06e07bf 100644
--- a/modules/images_history.py
+++ b/modules/images_history.py
@@ -31,7 +31,7 @@ def get_recent_images(dir_name, page_index, step, image_index, tabname):
image_list = traverse_all_files(dir_name, image_list)
image_list = sorted(image_list, key=lambda file: -os.path.getctime(os.path.join(dir_name, file)))
else:
- print(f"ERROR: {dir_name} is not a directory. Check the path in the settings.", file=sys.stderr)
+ print(f'ERROR: "{dir_name}" is not a directory. Check the path in the settings.', file=sys.stderr)
num = 48 if tabname != "extras" else 12
max_page_index = len(image_list) // num + 1
page_index = max_page_index if page_index == -1 else page_index + step
diff --git a/modules/ui.py b/modules/ui.py
index fa73627a..7b0d5a92 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -1395,7 +1395,7 @@ def create_ui(wrap_gradio_gpu_call):
def open_folder(f):
if not os.path.exists(f):
- print(f"{f} doesn't exist. After you create an image, the folder will be created.")
+ print(f'Folder "{f}" does not exist. After you create an image, the folder will be created.')
return
elif not os.path.isdir(f):
print(f"""
--
cgit v1.2.1
From fc220a51cf5bb5bfca83322c16e907a18ec59f6b Mon Sep 17 00:00:00 2001
From: DancingSnow <1121149616@qq.com>
Date: Sun, 16 Oct 2022 10:49:21 +0800
Subject: fix dir_path in some path like `D:/Pic/outputs`
---
modules/images_history.py | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/modules/images_history.py b/modules/images_history.py
index e06e07bf..46b23e56 100644
--- a/modules/images_history.py
+++ b/modules/images_history.py
@@ -109,10 +109,8 @@ def show_images_history(gr, opts, tabname, run_pnginfo, switch_dict):
dir_name = opts.outdir_img2img_samples
elif tabname == "extras":
dir_name = opts.outdir_extras_samples
- d = dir_name.split("/")
- dir_name = "/" if dir_name.startswith("/") else d[0]
- for p in d[1:]:
- dir_name = os.path.join(dir_name, p)
+ else:
+ return
with gr.Row():
renew_page = gr.Button('Renew Page', elem_id=tabname + "_images_history_renew_page")
first_page = gr.Button('First Page')
--
cgit v1.2.1
From c57919ea2a8e4a23a05d21f28928e08bbf34c59e Mon Sep 17 00:00:00 2001
From: AUTOMATIC <16777216c@gmail.com>
Date: Sun, 16 Oct 2022 17:22:56 +0300
Subject: keep focus on current element when updating gallery
---
javascript/progressbar.js | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/javascript/progressbar.js b/javascript/progressbar.js
index 076f0a97..c7d0343f 100644
--- a/javascript/progressbar.js
+++ b/javascript/progressbar.js
@@ -34,7 +34,7 @@ function check_progressbar(id_part, id_progressbar, id_progressbar_span, id_skip
preview.style.height = gallery.clientHeight + "px"
//only watch gallery if there is a generation process going on
- check_gallery(id_gallery);
+ check_gallery(id_gallery);
var progressDiv = gradioApp().querySelectorAll('#' + id_progressbar_span).length > 0;
if(!progressDiv){
@@ -73,8 +73,10 @@ function check_gallery(id_gallery){
let galleryBtnSelected = gradioApp().querySelector('#'+id_gallery+' .gallery-item.\\!ring-2')
if (prevSelectedIndex !== -1 && galleryButtons.length>prevSelectedIndex && !galleryBtnSelected) {
//automatically re-open previously selected index (if exists)
+ activeElement = document.activeElement;
galleryButtons[prevSelectedIndex].click();
- showGalleryImage();
+ showGalleryImage();
+ if(activeElement) activeElement.focus()
}
})
galleryObservers[id_gallery].observe( gallery, { childList:true, subtree:false })
--
cgit v1.2.1
From a4de699e3c235d83b5a957d08779cb41cb0781bc Mon Sep 17 00:00:00 2001
From: yfszzx
Date: Sun, 16 Oct 2022 22:37:12 +0800
Subject: Images history speed up
---
javascript/images_history.js | 1 +
modules/images_history.py | 7 +++++--
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/javascript/images_history.js b/javascript/images_history.js
index fb1356d9..9d9d04fb 100644
--- a/javascript/images_history.js
+++ b/javascript/images_history.js
@@ -108,6 +108,7 @@ function images_history_delete(del_num, tabname, image_index){
});
var img_num = buttons.length / 2;
del_num = Math.min(img_num - image_index, del_num)
+ console.log(del_num, img_num)
if (img_num <= del_num){
setTimeout(function(tabname){
gradioApp().getElementById(tabname + '_images_history_renew_page').click();
diff --git a/modules/images_history.py b/modules/images_history.py
index ae0b4e40..94bd16a8 100644
--- a/modules/images_history.py
+++ b/modules/images_history.py
@@ -153,6 +153,7 @@ def delete_image(delete_num, name, filenames, image_index, visible_num):
if os.path.exists(name):
if visible_num == image_index:
new_file_list.append(name)
+ i += 1
continue
print(f"Delete file {name}")
os.remove(name)
@@ -221,7 +222,7 @@ def show_images_history(gr, opts, tabname, run_pnginfo, switch_dict):
with gr.Column(visible=sorted_flag) as page_panel:
with gr.Row():
- #renew_page = gr.Button('Refresh')
+ renew_page = gr.Button('Refresh page', elem_id=tabname + "_images_history_renew_page")
first_page = gr.Button('First Page')
prev_page = gr.Button('Prev Page')
page_index = gr.Number(value=1, label="Page Index")
@@ -231,7 +232,7 @@ def show_images_history(gr, opts, tabname, run_pnginfo, switch_dict):
with gr.Row(elem_id=tabname + "_images_history"):
with gr.Column(scale=2):
with gr.Row():
- newest = gr.Button('Refresh', elem_id=tabname + "_images_history_start")
+ newest = gr.Button('Reload', elem_id=tabname + "_images_history_start")
date_from = gr.Textbox(label="Date from", interactive=False)
date_to = gr.Dropdown(value="start" if not sorted_flag else None, label="Date to")
@@ -291,12 +292,14 @@ def show_images_history(gr, opts, tabname, run_pnginfo, switch_dict):
prev_page.click(prev_page_click, inputs=gallery_inputs, outputs=gallery_outputs)
end_page.click(end_page_click, inputs=gallery_inputs, outputs=gallery_outputs)
page_index.submit(page_index_change, inputs=gallery_inputs, outputs=gallery_outputs)
+ renew_page.click(page_index_change, inputs=gallery_inputs, outputs=gallery_outputs)
first_page.click(fn=None, inputs=[tabname_box], outputs=None, _js="images_history_turnpage")
next_page.click(fn=None, inputs=[tabname_box], outputs=None, _js="images_history_turnpage")
prev_page.click(fn=None, inputs=[tabname_box], outputs=None, _js="images_history_turnpage")
end_page.click(fn=None, inputs=[tabname_box], outputs=None, _js="images_history_turnpage")
page_index.submit(fn=None, inputs=[tabname_box], outputs=None, _js="images_history_turnpage")
+ renew_page.click(fn=None, inputs=[tabname_box], outputs=None, _js="images_history_turnpage")
# other funcitons
set_index.click(show_image_info, _js="images_history_get_current_img", inputs=[tabname_box, image_index, page_index, filenames], outputs=[img_file_name, image_index, hidden])
--
cgit v1.2.1
From 9324cdaa3199d65c182858785dd1eca42b192b8e Mon Sep 17 00:00:00 2001
From: MalumaDev
Date: Sun, 16 Oct 2022 17:53:56 +0200
Subject: ui fix, re organization of the code
---
modules/aesthetic_clip.py | 154 +++++++++++++++++++++++++++++++++--
modules/img2img.py | 14 +++-
modules/processing.py | 29 ++-----
modules/sd_hijack.py | 102 ++---------------------
modules/sd_models.py | 5 +-
modules/shared.py | 14 +++-
modules/textual_inversion/dataset.py | 2 +-
modules/txt2img.py | 18 ++--
modules/ui.py | 52 +++++++-----
9 files changed, 233 insertions(+), 157 deletions(-)
diff --git a/modules/aesthetic_clip.py b/modules/aesthetic_clip.py
index ccb35c73..34efa931 100644
--- a/modules/aesthetic_clip.py
+++ b/modules/aesthetic_clip.py
@@ -1,3 +1,4 @@
+import copy
import itertools
import os
from pathlib import Path
@@ -7,11 +8,12 @@ import gc
import gradio as gr
import torch
from PIL import Image
-from modules import shared
-from modules.shared import device
-from transformers import CLIPModel, CLIPProcessor
+from torch import optim
-from tqdm.auto import tqdm
+from modules import shared
+from transformers import CLIPModel, CLIPProcessor, CLIPTokenizer
+from tqdm.auto import tqdm, trange
+from modules.shared import opts, device
def get_all_images_in_folder(folder):
@@ -37,12 +39,39 @@ def iter_to_batched(iterable, n=1):
yield chunk
+def create_ui():
+ with gr.Group():
+ with gr.Accordion("Open for Clip Aesthetic!", open=False):
+ with gr.Row():
+ aesthetic_weight = gr.Slider(minimum=0, maximum=1, step=0.01, label="Aesthetic weight",
+ value=0.9)
+ aesthetic_steps = gr.Slider(minimum=0, maximum=50, step=1, label="Aesthetic steps", value=5)
+
+ with gr.Row():
+ aesthetic_lr = gr.Textbox(label='Aesthetic learning rate',
+ placeholder="Aesthetic learning rate", value="0.0001")
+ aesthetic_slerp = gr.Checkbox(label="Slerp interpolation", value=False)
+ aesthetic_imgs = gr.Dropdown(sorted(shared.aesthetic_embeddings.keys()),
+ label="Aesthetic imgs embedding",
+ value="None")
+
+ with gr.Row():
+ aesthetic_imgs_text = gr.Textbox(label='Aesthetic text for imgs',
+ placeholder="This text is used to rotate the feature space of the imgs embs",
+ value="")
+ aesthetic_slerp_angle = gr.Slider(label='Slerp angle', minimum=0, maximum=1, step=0.01,
+ value=0.1)
+ aesthetic_text_negative = gr.Checkbox(label="Is negative text", value=False)
+
+ return aesthetic_weight, aesthetic_steps, aesthetic_lr, aesthetic_slerp, aesthetic_imgs, aesthetic_imgs_text, aesthetic_slerp_angle, aesthetic_text_negative
+
+
def generate_imgs_embd(name, folder, batch_size):
# clipModel = CLIPModel.from_pretrained(
# shared.sd_model.cond_stage_model.clipModel.name_or_path
# )
- model = CLIPModel.from_pretrained(shared.sd_model.cond_stage_model.clipModel.name_or_path).to(device)
- processor = CLIPProcessor.from_pretrained(shared.sd_model.cond_stage_model.clipModel.name_or_path)
+ model = shared.clip_model.to(device)
+ processor = CLIPProcessor.from_pretrained(model.name_or_path)
with torch.no_grad():
embs = []
@@ -63,7 +92,6 @@ def generate_imgs_embd(name, folder, batch_size):
torch.save(embs, path)
model = model.cpu()
- del model
del processor
del embs
gc.collect()
@@ -74,4 +102,114 @@ def generate_imgs_embd(name, folder, batch_size):
"""
shared.update_aesthetic_embeddings()
return gr.Dropdown.update(choices=sorted(shared.aesthetic_embeddings.keys()), label="Imgs embedding",
- value="None"), res, ""
+ value="None"), \
+ gr.Dropdown.update(choices=sorted(shared.aesthetic_embeddings.keys()),
+ label="Imgs embedding",
+ value="None"), res, ""
+
+
+def slerp(low, high, val):
+ low_norm = low / torch.norm(low, dim=1, keepdim=True)
+ high_norm = high / torch.norm(high, dim=1, keepdim=True)
+ omega = torch.acos((low_norm * high_norm).sum(1))
+ so = torch.sin(omega)
+ res = (torch.sin((1.0 - val) * omega) / so).unsqueeze(1) * low + (torch.sin(val * omega) / so).unsqueeze(1) * high
+ return res
+
+
+class AestheticCLIP:
+ def __init__(self):
+ self.skip = False
+ self.aesthetic_steps = 0
+ self.aesthetic_weight = 0
+ self.aesthetic_lr = 0
+ self.slerp = False
+ self.aesthetic_text_negative = ""
+ self.aesthetic_slerp_angle = 0
+ self.aesthetic_imgs_text = ""
+
+ self.image_embs_name = None
+ self.image_embs = None
+ self.load_image_embs(None)
+
+ def set_aesthetic_params(self, aesthetic_lr=0, aesthetic_weight=0, aesthetic_steps=0, image_embs_name=None,
+ aesthetic_slerp=True, aesthetic_imgs_text="",
+ aesthetic_slerp_angle=0.15,
+ aesthetic_text_negative=False):
+ self.aesthetic_imgs_text = aesthetic_imgs_text
+ self.aesthetic_slerp_angle = aesthetic_slerp_angle
+ self.aesthetic_text_negative = aesthetic_text_negative
+ self.slerp = aesthetic_slerp
+ self.aesthetic_lr = aesthetic_lr
+ self.aesthetic_weight = aesthetic_weight
+ self.aesthetic_steps = aesthetic_steps
+ self.load_image_embs(image_embs_name)
+
+ def set_skip(self, skip):
+ self.skip = skip
+
+ def load_image_embs(self, image_embs_name):
+ if image_embs_name is None or len(image_embs_name) == 0 or image_embs_name == "None":
+ image_embs_name = None
+ self.image_embs_name = None
+ if image_embs_name is not None and self.image_embs_name != image_embs_name:
+ self.image_embs_name = image_embs_name
+ self.image_embs = torch.load(shared.aesthetic_embeddings[self.image_embs_name], map_location=device)
+ self.image_embs /= self.image_embs.norm(dim=-1, keepdim=True)
+ self.image_embs.requires_grad_(False)
+
+ def __call__(self, z, remade_batch_tokens):
+ if not self.skip and self.aesthetic_steps != 0 and self.aesthetic_lr != 0 and self.aesthetic_weight != 0 and self.image_embs_name is not None:
+ tokenizer = shared.sd_model.cond_stage_model.tokenizer
+ if not opts.use_old_emphasis_implementation:
+ remade_batch_tokens = [
+ [tokenizer.bos_token_id] + x[:75] + [tokenizer.eos_token_id] for x in
+ remade_batch_tokens]
+
+ tokens = torch.asarray(remade_batch_tokens).to(device)
+
+ model = copy.deepcopy(shared.clip_model).to(device)
+ model.requires_grad_(True)
+ if self.aesthetic_imgs_text is not None and len(self.aesthetic_imgs_text) > 0:
+ text_embs_2 = model.get_text_features(
+ **tokenizer([self.aesthetic_imgs_text], padding=True, return_tensors="pt").to(device))
+ if self.aesthetic_text_negative:
+ text_embs_2 = self.image_embs - text_embs_2
+ text_embs_2 /= text_embs_2.norm(dim=-1, keepdim=True)
+ img_embs = slerp(self.image_embs, text_embs_2, self.aesthetic_slerp_angle)
+ else:
+ img_embs = self.image_embs
+
+ with torch.enable_grad():
+
+ # We optimize the model to maximize the similarity
+ optimizer = optim.Adam(
+ model.text_model.parameters(), lr=self.aesthetic_lr
+ )
+
+ for _ in trange(self.aesthetic_steps, desc="Aesthetic optimization"):
+ text_embs = model.get_text_features(input_ids=tokens)
+ text_embs = text_embs / text_embs.norm(dim=-1, keepdim=True)
+ sim = text_embs @ img_embs.T
+ loss = -sim
+ optimizer.zero_grad()
+ loss.mean().backward()
+ optimizer.step()
+
+ zn = model.text_model(input_ids=tokens, output_hidden_states=-opts.CLIP_stop_at_last_layers)
+ if opts.CLIP_stop_at_last_layers > 1:
+ zn = zn.hidden_states[-opts.CLIP_stop_at_last_layers]
+ zn = model.text_model.final_layer_norm(zn)
+ else:
+ zn = zn.last_hidden_state
+ model.cpu()
+ del model
+ gc.collect()
+ torch.cuda.empty_cache()
+ zn = torch.concat([zn[77 * i:77 * (i + 1)] for i in range(max(z.shape[1] // 77, 1))], 1)
+ if self.slerp:
+ z = slerp(z, zn, self.aesthetic_weight)
+ else:
+ z = z * (1 - self.aesthetic_weight) + zn * self.aesthetic_weight
+
+ return z
diff --git a/modules/img2img.py b/modules/img2img.py
index 24126774..4ed80c4b 100644
--- a/modules/img2img.py
+++ b/modules/img2img.py
@@ -56,7 +56,14 @@ def process_batch(p, input_dir, output_dir, args):
processed_image.save(os.path.join(output_dir, filename))
-def img2img(mode: int, prompt: str, negative_prompt: str, prompt_style: str, prompt_style2: str, init_img, init_img_with_mask, init_img_inpaint, init_mask_inpaint, mask_mode, steps: int, sampler_index: int, mask_blur: int, inpainting_fill: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, resize_mode: int, inpaint_full_res: bool, inpaint_full_res_padding: int, inpainting_mask_invert: int, img2img_batch_input_dir: str, img2img_batch_output_dir: str, *args):
+def img2img(mode: int, prompt: str, negative_prompt: str, prompt_style: str, prompt_style2: str, init_img, init_img_with_mask, init_img_inpaint, init_mask_inpaint, mask_mode, steps: int, sampler_index: int, mask_blur: int, inpainting_fill: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, resize_mode: int, inpaint_full_res: bool, inpaint_full_res_padding: int, inpainting_mask_invert: int, img2img_batch_input_dir: str, img2img_batch_output_dir: str,
+ aesthetic_lr=0,
+ aesthetic_weight=0, aesthetic_steps=0,
+ aesthetic_imgs=None,
+ aesthetic_slerp=False,
+ aesthetic_imgs_text="",
+ aesthetic_slerp_angle=0.15,
+ aesthetic_text_negative=False, *args):
is_inpaint = mode == 1
is_batch = mode == 2
@@ -109,6 +116,11 @@ def img2img(mode: int, prompt: str, negative_prompt: str, prompt_style: str, pro
inpainting_mask_invert=inpainting_mask_invert,
)
+ shared.aesthetic_clip.set_aesthetic_params(float(aesthetic_lr), float(aesthetic_weight), int(aesthetic_steps),
+ aesthetic_imgs, aesthetic_slerp, aesthetic_imgs_text,
+ aesthetic_slerp_angle,
+ aesthetic_text_negative)
+
if shared.cmd_opts.enable_console_prompts:
print(f"\nimg2img: {prompt}", file=shared.progress_print_out)
diff --git a/modules/processing.py b/modules/processing.py
index 1db26c3e..685f9fcd 100644
--- a/modules/processing.py
+++ b/modules/processing.py
@@ -146,7 +146,8 @@ class Processed:
self.prompt = self.prompt if type(self.prompt) != list else self.prompt[0]
self.negative_prompt = self.negative_prompt if type(self.negative_prompt) != list else self.negative_prompt[0]
self.seed = int(self.seed if type(self.seed) != list else self.seed[0]) if self.seed is not None else -1
- self.subseed = int(self.subseed if type(self.subseed) != list else self.subseed[0]) if self.subseed is not None else -1
+ self.subseed = int(
+ self.subseed if type(self.subseed) != list else self.subseed[0]) if self.subseed is not None else -1
self.all_prompts = all_prompts or [self.prompt]
self.all_seeds = all_seeds or [self.seed]
@@ -332,16 +333,9 @@ def create_infotext(p, all_prompts, all_seeds, all_subseeds, comments, iteration
return f"{all_prompts[index]}{negative_prompt_text}\n{generation_params_text}".strip()
-def process_images(p: StableDiffusionProcessing, aesthetic_lr=0, aesthetic_weight=0, aesthetic_steps=0,
- aesthetic_imgs=None, aesthetic_slerp=False, aesthetic_imgs_text="",
- aesthetic_slerp_angle=0.15,
- aesthetic_text_negative=False) -> Processed:
+def process_images(p: StableDiffusionProcessing) -> Processed:
"""this is the main loop that both txt2img and img2img use; it calls func_init once inside all the scopes and func_sample once per batch"""
- aesthetic_lr = float(aesthetic_lr)
- aesthetic_weight = float(aesthetic_weight)
- aesthetic_steps = int(aesthetic_steps)
-
if type(p.prompt) == list:
assert (len(p.prompt) > 0)
else:
@@ -417,16 +411,10 @@ def process_images(p: StableDiffusionProcessing, aesthetic_lr=0, aesthetic_weigh
# uc = p.sd_model.get_learned_conditioning(len(prompts) * [p.negative_prompt])
# c = p.sd_model.get_learned_conditioning(prompts)
with devices.autocast():
- if hasattr(shared.sd_model.cond_stage_model, "set_aesthetic_params"):
- shared.sd_model.cond_stage_model.set_aesthetic_params()
+ shared.aesthetic_clip.set_skip(True)
uc = prompt_parser.get_learned_conditioning(shared.sd_model, len(prompts) * [p.negative_prompt],
p.steps)
- if hasattr(shared.sd_model.cond_stage_model, "set_aesthetic_params"):
- shared.sd_model.cond_stage_model.set_aesthetic_params(aesthetic_lr, aesthetic_weight,
- aesthetic_steps, aesthetic_imgs,
- aesthetic_slerp, aesthetic_imgs_text,
- aesthetic_slerp_angle,
- aesthetic_text_negative)
+ shared.aesthetic_clip.set_skip(False)
c = prompt_parser.get_multicond_learned_conditioning(shared.sd_model, prompts, p.steps)
if len(model_hijack.comments) > 0:
@@ -582,7 +570,6 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
self.truncate_x = int(self.firstphase_width - firstphase_width_truncated) // opt_f
self.truncate_y = int(self.firstphase_height - firstphase_height_truncated) // opt_f
-
def sample(self, conditioning, unconditional_conditioning, seeds, subseeds, subseed_strength):
self.sampler = sd_samplers.create_sampler_with_index(sd_samplers.samplers, self.sampler_index, self.sd_model)
@@ -600,10 +587,12 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
seed_resize_from_w=self.seed_resize_from_w, p=self)
samples = self.sampler.sample(self, x, conditioning, unconditional_conditioning)
- samples = samples[:, :, self.truncate_y//2:samples.shape[2]-self.truncate_y//2, self.truncate_x//2:samples.shape[3]-self.truncate_x//2]
+ samples = samples[:, :, self.truncate_y // 2:samples.shape[2] - self.truncate_y // 2,
+ self.truncate_x // 2:samples.shape[3] - self.truncate_x // 2]
if opts.use_scale_latent_for_hires_fix:
- samples = torch.nn.functional.interpolate(samples, size=(self.height // opt_f, self.width // opt_f), mode="bilinear")
+ samples = torch.nn.functional.interpolate(samples, size=(self.height // opt_f, self.width // opt_f),
+ mode="bilinear")
else:
decoded_samples = decode_first_stage(self.sd_model, samples)
lowres_samples = torch.clamp((decoded_samples + 1.0) / 2.0, min=0.0, max=1.0)
diff --git a/modules/sd_hijack.py b/modules/sd_hijack.py
index 5d0590af..227e7670 100644
--- a/modules/sd_hijack.py
+++ b/modules/sd_hijack.py
@@ -29,8 +29,8 @@ def apply_optimizations():
ldm.modules.diffusionmodules.model.nonlinearity = silu
-
- if cmd_opts.force_enable_xformers or (cmd_opts.xformers and shared.xformers_available and torch.version.cuda and (6, 0) <= torch.cuda.get_device_capability(shared.device) <= (9, 0)):
+ if cmd_opts.force_enable_xformers or (cmd_opts.xformers and shared.xformers_available and torch.version.cuda and (
+ 6, 0) <= torch.cuda.get_device_capability(shared.device) <= (9, 0)):
print("Applying xformers cross attention optimization.")
ldm.modules.attention.CrossAttention.forward = sd_hijack_optimizations.xformers_attention_forward
ldm.modules.diffusionmodules.model.AttnBlock.forward = sd_hijack_optimizations.xformers_attnblock_forward
@@ -118,33 +118,14 @@ class StableDiffusionModelHijack:
return remade_batch_tokens[0], token_count, get_target_prompt_token_count(token_count)
-def slerp(low, high, val):
- low_norm = low / torch.norm(low, dim=1, keepdim=True)
- high_norm = high / torch.norm(high, dim=1, keepdim=True)
- omega = torch.acos((low_norm * high_norm).sum(1))
- so = torch.sin(omega)
- res = (torch.sin((1.0 - val) * omega) / so).unsqueeze(1) * low + (torch.sin(val * omega) / so).unsqueeze(1) * high
- return res
-
-
class FrozenCLIPEmbedderWithCustomWords(torch.nn.Module):
def __init__(self, wrapped, hijack):
super().__init__()
self.wrapped = wrapped
- self.clipModel = CLIPModel.from_pretrained(
- self.wrapped.transformer.name_or_path
- )
- del self.clipModel.vision_model
- self.tokenizer = CLIPTokenizer.from_pretrained(self.wrapped.transformer.name_or_path)
- self.hijack: StableDiffusionModelHijack = hijack
- self.tokenizer = wrapped.tokenizer
- # self.vision = CLIPVisionModel.from_pretrained(self.wrapped.transformer.name_or_path).eval()
- self.image_embs_name = None
- self.image_embs = None
- self.load_image_embs(None)
self.token_mults = {}
-
+ self.hijack: StableDiffusionModelHijack = hijack
+ self.tokenizer = wrapped.tokenizer
self.comma_token = [v for k, v in self.tokenizer.get_vocab().items() if k == ','][0]
tokens_with_parens = [(k, v) for k, v in self.tokenizer.get_vocab().items() if
@@ -164,28 +145,6 @@ class FrozenCLIPEmbedderWithCustomWords(torch.nn.Module):
if mult != 1.0:
self.token_mults[ident] = mult
- def set_aesthetic_params(self, aesthetic_lr=0, aesthetic_weight=0, aesthetic_steps=0, image_embs_name=None,
- aesthetic_slerp=True, aesthetic_imgs_text="",
- aesthetic_slerp_angle=0.15,
- aesthetic_text_negative=False):
- self.aesthetic_imgs_text = aesthetic_imgs_text
- self.aesthetic_slerp_angle = aesthetic_slerp_angle
- self.aesthetic_text_negative = aesthetic_text_negative
- self.slerp = aesthetic_slerp
- self.aesthetic_lr = aesthetic_lr
- self.aesthetic_weight = aesthetic_weight
- self.aesthetic_steps = aesthetic_steps
- self.load_image_embs(image_embs_name)
-
- def load_image_embs(self, image_embs_name):
- if image_embs_name is None or len(image_embs_name) == 0 or image_embs_name == "None":
- image_embs_name = None
- if image_embs_name is not None and self.image_embs_name != image_embs_name:
- self.image_embs_name = image_embs_name
- self.image_embs = torch.load(shared.aesthetic_embeddings[self.image_embs_name], map_location=device)
- self.image_embs /= self.image_embs.norm(dim=-1, keepdim=True)
- self.image_embs.requires_grad_(False)
-
def tokenize_line(self, line, used_custom_terms, hijack_comments):
id_end = self.wrapped.tokenizer.eos_token_id
@@ -391,58 +350,7 @@ class FrozenCLIPEmbedderWithCustomWords(torch.nn.Module):
z1 = self.process_tokens(tokens, multipliers)
z = z1 if z is None else torch.cat((z, z1), axis=-2)
-
- if self.aesthetic_steps != 0 and self.aesthetic_lr != 0 and self.aesthetic_weight != 0 and self.image_embs_name != None:
- if not opts.use_old_emphasis_implementation:
- remade_batch_tokens = [
- [self.wrapped.tokenizer.bos_token_id] + x[:75] + [self.wrapped.tokenizer.eos_token_id] for x in
- remade_batch_tokens]
-
- tokens = torch.asarray(remade_batch_tokens).to(device)
-
- model = copy.deepcopy(self.clipModel).to(device)
- model.requires_grad_(True)
- if self.aesthetic_imgs_text is not None and len(self.aesthetic_imgs_text) > 0:
- text_embs_2 = model.get_text_features(
- **self.tokenizer([self.aesthetic_imgs_text], padding=True, return_tensors="pt").to(device))
- if self.aesthetic_text_negative:
- text_embs_2 = self.image_embs - text_embs_2
- text_embs_2 /= text_embs_2.norm(dim=-1, keepdim=True)
- img_embs = slerp(self.image_embs, text_embs_2, self.aesthetic_slerp_angle)
- else:
- img_embs = self.image_embs
-
- with torch.enable_grad():
-
- # We optimize the model to maximize the similarity
- optimizer = optim.Adam(
- model.text_model.parameters(), lr=self.aesthetic_lr
- )
-
- for i in trange(self.aesthetic_steps, desc="Aesthetic optimization"):
- text_embs = model.get_text_features(input_ids=tokens)
- text_embs = text_embs / text_embs.norm(dim=-1, keepdim=True)
- sim = text_embs @ img_embs.T
- loss = -sim
- optimizer.zero_grad()
- loss.mean().backward()
- optimizer.step()
-
- zn = model.text_model(input_ids=tokens, output_hidden_states=-opts.CLIP_stop_at_last_layers)
- if opts.CLIP_stop_at_last_layers > 1:
- zn = zn.hidden_states[-opts.CLIP_stop_at_last_layers]
- zn = model.text_model.final_layer_norm(zn)
- else:
- zn = zn.last_hidden_state
- model.cpu()
- del model
-
- zn = torch.concat([zn for i in range(z.shape[1] // 77)], 1)
- if self.slerp:
- z = slerp(z, zn, self.aesthetic_weight)
- else:
- z = z * (1 - self.aesthetic_weight) + zn * self.aesthetic_weight
-
+ z = shared.aesthetic_clip(z, remade_batch_tokens)
remade_batch_tokens = rem_tokens
batch_multipliers = rem_multipliers
i += 1
diff --git a/modules/sd_models.py b/modules/sd_models.py
index 3aa21ec1..8e4ee435 100644
--- a/modules/sd_models.py
+++ b/modules/sd_models.py
@@ -20,7 +20,7 @@ checkpoints_loaded = collections.OrderedDict()
try:
# this silences the annoying "Some weights of the model checkpoint were not used when initializing..." message at start.
- from transformers import logging
+ from transformers import logging, CLIPModel
logging.set_verbosity_error()
except Exception:
@@ -196,6 +196,9 @@ def load_model():
sd_hijack.model_hijack.hijack(sd_model)
+ if shared.clip_model is None or shared.clip_model.transformer.name_or_path != sd_model.cond_stage_model.wrapped.transformer.name_or_path:
+ shared.clip_model = CLIPModel.from_pretrained(sd_model.cond_stage_model.wrapped.transformer.name_or_path)
+
sd_model.eval()
print(f"Model loaded.")
diff --git a/modules/shared.py b/modules/shared.py
index e2c98b2d..e19ca779 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -3,6 +3,7 @@ import datetime
import json
import os
import sys
+from collections import OrderedDict
import gradio as gr
import tqdm
@@ -94,15 +95,15 @@ os.makedirs(cmd_opts.hypernetwork_dir, exist_ok=True)
hypernetworks = hypernetwork.list_hypernetworks(cmd_opts.hypernetwork_dir)
loaded_hypernetwork = None
-aesthetic_embeddings = {f.replace(".pt",""): os.path.join(cmd_opts.aesthetic_embeddings_dir, f) for f in
- os.listdir(cmd_opts.aesthetic_embeddings_dir) if f.endswith(".pt")}
-aesthetic_embeddings = aesthetic_embeddings | {"None": None}
+aesthetic_embeddings = {}
def update_aesthetic_embeddings():
global aesthetic_embeddings
aesthetic_embeddings = {f.replace(".pt",""): os.path.join(cmd_opts.aesthetic_embeddings_dir, f) for f in
os.listdir(cmd_opts.aesthetic_embeddings_dir) if f.endswith(".pt")}
- aesthetic_embeddings = aesthetic_embeddings | {"None": None}
+ aesthetic_embeddings = OrderedDict(**{"None": None}, **aesthetic_embeddings)
+
+update_aesthetic_embeddings()
def reload_hypernetworks():
global hypernetworks
@@ -381,6 +382,11 @@ sd_upscalers = []
sd_model = None
+clip_model = None
+
+from modules.aesthetic_clip import AestheticCLIP
+aesthetic_clip = AestheticCLIP()
+
progress_print_out = sys.stdout
diff --git a/modules/textual_inversion/dataset.py b/modules/textual_inversion/dataset.py
index 68ceffe3..23bb4b6a 100644
--- a/modules/textual_inversion/dataset.py
+++ b/modules/textual_inversion/dataset.py
@@ -49,7 +49,7 @@ class PersonalizedBase(Dataset):
print("Preparing dataset...")
for path in tqdm.tqdm(self.image_paths):
try:
- image = Image.open(path).convert('RGB').resize((self.width, self.height), PIL.Image.Resampling.BICUBIC)
+ image = Image.open(path).convert('RGB').resize((self.width, self.height), PIL.Image.BICUBIC)
except Exception:
continue
diff --git a/modules/txt2img.py b/modules/txt2img.py
index 8f394d05..6cbc50fc 100644
--- a/modules/txt2img.py
+++ b/modules/txt2img.py
@@ -1,12 +1,17 @@
import modules.scripts
-from modules.processing import StableDiffusionProcessing, Processed, StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img, process_images
+from modules.processing import StableDiffusionProcessing, Processed, StableDiffusionProcessingTxt2Img, \
+ StableDiffusionProcessingImg2Img, process_images
from modules.shared import opts, cmd_opts
import modules.shared as shared
import modules.processing as processing
from modules.ui import plaintext_to_html
-def txt2img(prompt: str, negative_prompt: str, prompt_style: str, prompt_style2: str, steps: int, sampler_index: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, enable_hr: bool, denoising_strength: float, firstphase_width: int, firstphase_height: int,aesthetic_lr=0,
+def txt2img(prompt: str, negative_prompt: str, prompt_style: str, prompt_style2: str, steps: int, sampler_index: int,
+ restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, seed: int, subseed: int,
+ subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool,
+ height: int, width: int, enable_hr: bool, denoising_strength: float, firstphase_width: int,
+ firstphase_height: int, aesthetic_lr=0,
aesthetic_weight=0, aesthetic_steps=0,
aesthetic_imgs=None,
aesthetic_slerp=False,
@@ -41,15 +46,17 @@ def txt2img(prompt: str, negative_prompt: str, prompt_style: str, prompt_style2:
firstphase_height=firstphase_height if enable_hr else None,
)
+ shared.aesthetic_clip.set_aesthetic_params(float(aesthetic_lr), float(aesthetic_weight), int(aesthetic_steps),
+ aesthetic_imgs, aesthetic_slerp, aesthetic_imgs_text, aesthetic_slerp_angle,
+ aesthetic_text_negative)
+
if cmd_opts.enable_console_prompts:
print(f"\ntxt2img: {prompt}", file=shared.progress_print_out)
processed = modules.scripts.scripts_txt2img.run(p, *args)
if processed is None:
- processed = process_images(p, aesthetic_lr, aesthetic_weight, aesthetic_steps, aesthetic_imgs, aesthetic_slerp,aesthetic_imgs_text,
- aesthetic_slerp_angle,
- aesthetic_text_negative)
+ processed = process_images(p)
shared.total_tqdm.clear()
@@ -61,4 +68,3 @@ def txt2img(prompt: str, negative_prompt: str, prompt_style: str, prompt_style2:
processed.images = []
return processed.images, generation_info_js, plaintext_to_html(processed.info)
-
diff --git a/modules/ui.py b/modules/ui.py
index 4069f0d2..0e5d73f0 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -43,7 +43,7 @@ from modules.images import save_image
import modules.textual_inversion.ui
import modules.hypernetworks.ui
-import modules.aesthetic_clip
+import modules.aesthetic_clip as aesthetic_clip
import modules.images_history as img_his
@@ -593,23 +593,25 @@ def create_ui(wrap_gradio_gpu_call):
width = gr.Slider(minimum=64, maximum=2048, step=64, label="Width", value=512)
height = gr.Slider(minimum=64, maximum=2048, step=64, label="Height", value=512)
- with gr.Group():
- with gr.Accordion("Open for Clip Aesthetic!",open=False):
- with gr.Row():
- aesthetic_weight = gr.Slider(minimum=0, maximum=1, step=0.01, label="Aesthetic weight", value=0.9)
- aesthetic_steps = gr.Slider(minimum=0, maximum=50, step=1, label="Aesthetic steps", value=5)
-
- with gr.Row():
- aesthetic_lr = gr.Textbox(label='Aesthetic learning rate', placeholder="Aesthetic learning rate", value="0.0001")
- aesthetic_slerp = gr.Checkbox(label="Slerp interpolation", value=False)
- aesthetic_imgs = gr.Dropdown(sorted(aesthetic_embeddings.keys()),
- label="Aesthetic imgs embedding",
- value="None")
-
- with gr.Row():
- aesthetic_imgs_text = gr.Textbox(label='Aesthetic text for imgs', placeholder="This text is used to rotate the feature space of the imgs embs", value="")
- aesthetic_slerp_angle = gr.Slider(label='Slerp angle',minimum=0, maximum=1, step=0.01, value=0.1)
- aesthetic_text_negative = gr.Checkbox(label="Is negative text", value=False)
+ # with gr.Group():
+ # with gr.Accordion("Open for Clip Aesthetic!",open=False):
+ # with gr.Row():
+ # aesthetic_weight = gr.Slider(minimum=0, maximum=1, step=0.01, label="Aesthetic weight", value=0.9)
+ # aesthetic_steps = gr.Slider(minimum=0, maximum=50, step=1, label="Aesthetic steps", value=5)
+ #
+ # with gr.Row():
+ # aesthetic_lr = gr.Textbox(label='Aesthetic learning rate', placeholder="Aesthetic learning rate", value="0.0001")
+ # aesthetic_slerp = gr.Checkbox(label="Slerp interpolation", value=False)
+ # aesthetic_imgs = gr.Dropdown(sorted(aesthetic_embeddings.keys()),
+ # label="Aesthetic imgs embedding",
+ # value="None")
+ #
+ # with gr.Row():
+ # aesthetic_imgs_text = gr.Textbox(label='Aesthetic text for imgs', placeholder="This text is used to rotate the feature space of the imgs embs", value="")
+ # aesthetic_slerp_angle = gr.Slider(label='Slerp angle',minimum=0, maximum=1, step=0.01, value=0.1)
+ # aesthetic_text_negative = gr.Checkbox(label="Is negative text", value=False)
+
+ aesthetic_weight, aesthetic_steps, aesthetic_lr, aesthetic_slerp, aesthetic_imgs, aesthetic_imgs_text, aesthetic_slerp_angle, aesthetic_text_negative = aesthetic_clip.create_ui()
with gr.Row():
@@ -840,6 +842,9 @@ def create_ui(wrap_gradio_gpu_call):
width = gr.Slider(minimum=64, maximum=2048, step=64, label="Width", value=512)
height = gr.Slider(minimum=64, maximum=2048, step=64, label="Height", value=512)
+ aesthetic_weight_im, aesthetic_steps_im, aesthetic_lr_im, aesthetic_slerp_im, aesthetic_imgs_im, aesthetic_imgs_text_im, aesthetic_slerp_angle_im, aesthetic_text_negative_im = aesthetic_clip.create_ui()
+
+
with gr.Row():
restore_faces = gr.Checkbox(label='Restore faces', value=False, visible=len(shared.face_restorers) > 1)
tiling = gr.Checkbox(label='Tiling', value=False)
@@ -944,6 +949,14 @@ def create_ui(wrap_gradio_gpu_call):
inpainting_mask_invert,
img2img_batch_input_dir,
img2img_batch_output_dir,
+ aesthetic_lr_im,
+ aesthetic_weight_im,
+ aesthetic_steps_im,
+ aesthetic_imgs_im,
+ aesthetic_slerp_im,
+ aesthetic_imgs_text_im,
+ aesthetic_slerp_angle_im,
+ aesthetic_text_negative_im,
] + custom_inputs,
outputs=[
img2img_gallery,
@@ -1283,7 +1296,7 @@ def create_ui(wrap_gradio_gpu_call):
)
create_embedding_ae.click(
- fn=modules.aesthetic_clip.generate_imgs_embd,
+ fn=aesthetic_clip.generate_imgs_embd,
inputs=[
new_embedding_name_ae,
process_src_ae,
@@ -1291,6 +1304,7 @@ def create_ui(wrap_gradio_gpu_call):
],
outputs=[
aesthetic_imgs,
+ aesthetic_imgs_im,
ti_output,
ti_outcome,
]
--
cgit v1.2.1
From 26a11776e4070af30b864ab0ddf25dcda21631a7 Mon Sep 17 00:00:00 2001
From: dvsilch <743422767@qq.com>
Date: Mon, 17 Oct 2022 00:51:10 +0800
Subject: fix: add null check when start running project the currentButton is
null
---
javascript/imageviewer.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/javascript/imageviewer.js b/javascript/imageviewer.js
index 65a33dd7..d4ab6984 100644
--- a/javascript/imageviewer.js
+++ b/javascript/imageviewer.js
@@ -31,7 +31,7 @@ function updateOnBackgroundChange() {
}
})
- if (modalImage.src != currentButton.children[0].src) {
+ if (currentButton?.children?.length > 0 && modalImage.src != currentButton.children[0].src) {
modalImage.src = currentButton.children[0].src;
if (modalImage.style.display === 'none') {
modal.style.setProperty('background-image', `url(${modalImage.src})`)
--
cgit v1.2.1
From c8045c5ad4f99deb3a19add06e0457de1df62b05 Mon Sep 17 00:00:00 2001
From: SGKoishi
Date: Sun, 16 Oct 2022 10:08:23 -0700
Subject: The hide_ui_dir_config flag also restrict write attempt to path
settings
---
modules/shared.py | 10 ++++++++++
modules/ui.py | 8 +++++++-
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/modules/shared.py b/modules/shared.py
index dcab0af9..c2775603 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -77,6 +77,16 @@ parser.add_argument("--disable-safe-unpickle", action='store_true', help="disabl
cmd_opts = parser.parse_args()
+restricted_opts = [
+ "samples_filename_pattern",
+ "outdir_samples",
+ "outdir_txt2img_samples",
+ "outdir_img2img_samples",
+ "outdir_extras_samples",
+ "outdir_grids",
+ "outdir_txt2img_grids",
+ "outdir_save",
+]
devices.device, devices.device_interrogate, devices.device_gfpgan, devices.device_bsrgan, devices.device_esrgan, devices.device_scunet, devices.device_codeformer = \
(devices.cpu if any(y in cmd_opts.use_cpu for y in [x, 'all']) else devices.get_optimal_device() for x in ['sd', 'interrogate', 'gfpgan', 'bsrgan', 'esrgan', 'scunet', 'codeformer'])
diff --git a/modules/ui.py b/modules/ui.py
index 7b0d5a92..43dc88fc 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -25,7 +25,7 @@ import gradio.routes
from modules import sd_hijack, sd_models
from modules.paths import script_path
-from modules.shared import opts, cmd_opts
+from modules.shared import opts, cmd_opts, restricted_opts
if cmd_opts.deepdanbooru:
from modules.deepbooru import get_deepbooru_tags
import modules.shared as shared
@@ -1430,6 +1430,9 @@ Requested path was: {f}
if comp_args and isinstance(comp_args, dict) and comp_args.get('visible') is False:
continue
+ if cmd_opts.hide_ui_dir_config and key in restricted_opts:
+ continue
+
oldval = opts.data.get(key, None)
opts.data[key] = value
@@ -1447,6 +1450,9 @@ Requested path was: {f}
if not opts.same_type(value, opts.data_labels[key].default):
return gr.update(visible=True), opts.dumpjson()
+ if cmd_opts.hide_ui_dir_config and key in restricted_opts:
+ return gr.update(value=oldval), opts.dumpjson()
+
oldval = opts.data.get(key, None)
opts.data[key] = value
--
cgit v1.2.1
From a1d3cbf92cfde6b3e02a9c795412d01cdc268934 Mon Sep 17 00:00:00 2001
From: fortypercnt <114840933+fortypercnt@users.noreply.github.com>
Date: Mon, 17 Oct 2022 05:25:34 +0200
Subject: Fix #2750
left / top alignment was necessary with gradio 3.4.1. In gradio 3.5 the parent div of the image mask is centered, so the left / top alignment put the mask in the wrong place as described in #2750 #2795 #2805. This fix was tested on Windows 10 / Chrome.
---
javascript/imageMaskFix.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/javascript/imageMaskFix.js b/javascript/imageMaskFix.js
index 3d77bfe9..9fe7a603 100644
--- a/javascript/imageMaskFix.js
+++ b/javascript/imageMaskFix.js
@@ -31,8 +31,8 @@ function imageMaskResize() {
wrapper.style.width = `${wW}px`;
wrapper.style.height = `${wH}px`;
- wrapper.style.left = `${(w-wW)/2}px`;
- wrapper.style.top = `${(h-wH)/2}px`;
+ wrapper.style.left = `0px`;
+ wrapper.style.top = `0px`;
canvases.forEach( c => {
c.style.width = c.style.height = '';
@@ -42,4 +42,4 @@ function imageMaskResize() {
});
}
- onUiUpdate(() => imageMaskResize());
\ No newline at end of file
+ onUiUpdate(() => imageMaskResize());
--
cgit v1.2.1
From 0fd130767102ebcf90e97c6c191ecf199a2d4091 Mon Sep 17 00:00:00 2001
From: MrCheeze
Date: Sun, 16 Oct 2022 18:44:39 -0400
Subject: improve performance of 3-way merge on machines with not enough ram,
by only accessing two of the models at a time
---
modules/extras.py | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/modules/extras.py b/modules/extras.py
index 0819ed37..340a45fd 100644
--- a/modules/extras.py
+++ b/modules/extras.py
@@ -175,11 +175,14 @@ def run_pnginfo(image):
def run_modelmerger(primary_model_name, secondary_model_name, teritary_model_name, interp_method, multiplier, save_as_half, custom_name):
- def weighted_sum(theta0, theta1, theta2, alpha):
+ def weighted_sum(theta0, theta1, alpha):
return ((1 - alpha) * theta0) + (alpha * theta1)
- def add_difference(theta0, theta1, theta2, alpha):
- return theta0 + (theta1 - theta2) * alpha
+ def get_difference(theta1, theta2):
+ return theta1 - theta2
+
+ def add_difference(theta0, theta1_2_diff, alpha):
+ return theta0 + (alpha * theta1_2_diff)
primary_model_info = sd_models.checkpoints_list[primary_model_name]
secondary_model_info = sd_models.checkpoints_list[secondary_model_name]
@@ -201,20 +204,24 @@ def run_modelmerger(primary_model_name, secondary_model_name, teritary_model_nam
theta_2 = None
theta_funcs = {
- "Weighted sum": weighted_sum,
- "Add difference": add_difference,
+ "Weighted sum": (None, weighted_sum),
+ "Add difference": (get_difference, add_difference),
}
- theta_func = theta_funcs[interp_method]
+ theta_func1, theta_func2 = theta_funcs[interp_method]
print(f"Merging...")
+ if theta_func1:
+ for key in tqdm.tqdm(theta_1.keys()):
+ if 'model' in key:
+ t2 = theta_2.get(key, torch.zeros_like(theta_1[key]))
+ theta_1[key] = theta_func1(theta_1[key], t2)
+ del theta_2, teritary_model
+
for key in tqdm.tqdm(theta_0.keys()):
if 'model' in key and key in theta_1:
- t2 = (theta_2 or {}).get(key)
- if t2 is None:
- t2 = torch.zeros_like(theta_0[key])
- theta_0[key] = theta_func(theta_0[key], theta_1[key], t2, multiplier)
+ theta_0[key] = theta_func2(theta_0[key], theta_1[key], multiplier)
if save_as_half:
theta_0[key] = theta_0[key].half()
--
cgit v1.2.1
From 6f7b7a3dcdc471ebe63baa8a7731952557859c5b Mon Sep 17 00:00:00 2001
From: AUTOMATIC <16777216c@gmail.com>
Date: Mon, 17 Oct 2022 07:56:08 +0300
Subject: only read files with .py extension from the scripts dir
---
modules/scripts.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/modules/scripts.py b/modules/scripts.py
index 45230f9a..ac66d448 100644
--- a/modules/scripts.py
+++ b/modules/scripts.py
@@ -58,6 +58,9 @@ def load_scripts(basedir):
for filename in sorted(os.listdir(basedir)):
path = os.path.join(basedir, filename)
+ if os.path.splitext(path)[1].lower() != '.py':
+ continue
+
if not os.path.isfile(path):
continue
--
cgit v1.2.1
From 8aaadf56b3d5f06b9bd86718d7518883d94d70a0 Mon Sep 17 00:00:00 2001
From: DancingSnow <1121149616@qq.com>
Date: Mon, 17 Oct 2022 09:34:18 +0800
Subject: add cache for workflow
---
.github/workflows/on_pull_request.yaml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/.github/workflows/on_pull_request.yaml b/.github/workflows/on_pull_request.yaml
index 5270cba4..b097d180 100644
--- a/.github/workflows/on_pull_request.yaml
+++ b/.github/workflows/on_pull_request.yaml
@@ -22,6 +22,12 @@ jobs:
uses: actions/setup-python@v3
with:
python-version: 3.10.6
+ - uses: actions/cache@v2
+ with:
+ path: ~/.cache/pip
+ key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
+ restore-keys: |
+ ${{ runner.os }}-pip-
- name: Install PyLint
run: |
python -m pip install --upgrade pip
--
cgit v1.2.1
From 58f3ef77336663bce2321f5b692cf2aeacd3ac1c Mon Sep 17 00:00:00 2001
From: DenkingOfficial
Date: Mon, 17 Oct 2022 03:10:59 +0500
Subject: Fix CLIP Interrogator and disable ranks for it
---
modules/interrogate.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules/interrogate.py b/modules/interrogate.py
index 9263d65a..d85d7dcc 100644
--- a/modules/interrogate.py
+++ b/modules/interrogate.py
@@ -157,9 +157,9 @@ class InterrogateModels:
matches = self.rank(image_features, items, top_count=topn)
for match, score in matches:
if include_ranks:
- res += ", " + match
- else:
res += f", ({match}:{score})"
+ else:
+ res += ", " + match
except Exception:
print(f"Error interrogating", file=sys.stderr)
--
cgit v1.2.1
From 5c94aaf290f8ad7bf4499a91c268ad0791b0432f Mon Sep 17 00:00:00 2001
From: AUTOMATIC <16777216c@gmail.com>
Date: Mon, 17 Oct 2022 08:28:18 +0300
Subject: fix bug for latest model merge RAM improvement
---
modules/extras.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/modules/extras.py b/modules/extras.py
index 340a45fd..8dbab240 100644
--- a/modules/extras.py
+++ b/modules/extras.py
@@ -201,6 +201,7 @@ def run_modelmerger(primary_model_name, secondary_model_name, teritary_model_nam
teritary_model = torch.load(teritary_model_info.filename, map_location='cpu')
theta_2 = sd_models.get_state_dict_from_checkpoint(teritary_model)
else:
+ teritary_model = None
theta_2 = None
theta_funcs = {
--
cgit v1.2.1
From b99d3cf6dd9bc817e51d0d0a6e8eb12c7c0ac6af Mon Sep 17 00:00:00 2001
From: AUTOMATIC <16777216c@gmail.com>
Date: Mon, 17 Oct 2022 08:41:02 +0300
Subject: make CLIP interrogate ranks output sane values
---
modules/interrogate.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/modules/interrogate.py b/modules/interrogate.py
index d85d7dcc..64b91eb4 100644
--- a/modules/interrogate.py
+++ b/modules/interrogate.py
@@ -123,7 +123,7 @@ class InterrogateModels:
return caption[0]
- def interrogate(self, pil_image, include_ranks=False):
+ def interrogate(self, pil_image):
res = None
try:
@@ -156,8 +156,8 @@ class InterrogateModels:
for name, topn, items in self.categories:
matches = self.rank(image_features, items, top_count=topn)
for match, score in matches:
- if include_ranks:
- res += f", ({match}:{score})"
+ if shared.opts.interrogate_return_ranks:
+ res += f", ({match}:{score/100:.3f})"
else:
res += ", " + match
--
cgit v1.2.1
From 62edfae257e8982cd620d03862c7bdd44159d18f Mon Sep 17 00:00:00 2001
From: DepFA <35278260+dfaker@users.noreply.github.com>
Date: Sun, 16 Oct 2022 20:28:15 +0100
Subject: print list of embeddings on reload
---
modules/textual_inversion/textual_inversion.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/modules/textual_inversion/textual_inversion.py b/modules/textual_inversion/textual_inversion.py
index 7ec75018..3be69562 100644
--- a/modules/textual_inversion/textual_inversion.py
+++ b/modules/textual_inversion/textual_inversion.py
@@ -137,6 +137,7 @@ class EmbeddingDatabase:
continue
print(f"Loaded a total of {len(self.word_embeddings)} textual inversion embeddings.")
+ print("Embeddings:", ', '.join(self.word_embeddings.keys()))
def find_embedding_at_position(self, tokens, offset):
token = tokens[offset]
--
cgit v1.2.1
From cccc5a20fce4bde9a4299f8790366790735f1d05 Mon Sep 17 00:00:00 2001
From: Greg Fuller
Date: Sun, 16 Oct 2022 12:10:07 -0700
Subject: Safeguard setting restore logic against exceptions
also useful for keeping settings cache and restore logic together, and nice for code reuse (other third party scripts can import this class)
---
scripts/xy_grid.py | 48 ++++++++++++++++++++++++++----------------------
1 file changed, 26 insertions(+), 22 deletions(-)
diff --git a/scripts/xy_grid.py b/scripts/xy_grid.py
index 88ad3bf7..5cca168a 100644
--- a/scripts/xy_grid.py
+++ b/scripts/xy_grid.py
@@ -233,6 +233,21 @@ def draw_xy_grid(p, xs, ys, x_labels, y_labels, cell, draw_legend, include_lone_
return processed_result
+class SharedSettingsStackHelper(object):
+ def __enter__(self):
+ self.CLIP_stop_at_last_layers = opts.CLIP_stop_at_last_layers
+ self.hypernetwork = opts.sd_hypernetwork
+ self.model = shared.sd_model
+
+ def __exit__(self, exc_type, exc_value, tb):
+ modules.sd_models.reload_model_weights(self.model)
+
+ hypernetwork.load_hypernetwork(self.hypernetwork)
+ hypernetwork.apply_strength()
+
+ opts.data["CLIP_stop_at_last_layers"] = self.CLIP_stop_at_last_layers
+
+
re_range = re.compile(r"\s*([+-]?\s*\d+)\s*-\s*([+-]?\s*\d+)(?:\s*\(([+-]\d+)\s*\))?\s*")
re_range_float = re.compile(r"\s*([+-]?\s*\d+(?:.\d*)?)\s*-\s*([+-]?\s*\d+(?:.\d*)?)(?:\s*\(([+-]\d+(?:.\d*)?)\s*\))?\s*")
@@ -267,9 +282,6 @@ class Script(scripts.Script):
if not opts.return_grid:
p.batch_size = 1
-
- CLIP_stop_at_last_layers = opts.CLIP_stop_at_last_layers
-
def process_axis(opt, vals):
if opt.label == 'Nothing':
return [0]
@@ -367,27 +379,19 @@ class Script(scripts.Script):
return process_images(pc)
- processed = draw_xy_grid(
- p,
- xs=xs,
- ys=ys,
- x_labels=[x_opt.format_value(p, x_opt, x) for x in xs],
- y_labels=[y_opt.format_value(p, y_opt, y) for y in ys],
- cell=cell,
- draw_legend=draw_legend,
- include_lone_images=include_lone_images
- )
+ with SharedSettingsStackHelper():
+ processed = draw_xy_grid(
+ p,
+ xs=xs,
+ ys=ys,
+ x_labels=[x_opt.format_value(p, x_opt, x) for x in xs],
+ y_labels=[y_opt.format_value(p, y_opt, y) for y in ys],
+ cell=cell,
+ draw_legend=draw_legend,
+ include_lone_images=include_lone_images
+ )
if opts.grid_save:
images.save_image(processed.images[0], p.outpath_grids, "xy_grid", prompt=p.prompt, seed=processed.seed, grid=True, p=p)
- # restore checkpoint in case it was changed by axes
- modules.sd_models.reload_model_weights(shared.sd_model)
-
- hypernetwork.load_hypernetwork(opts.sd_hypernetwork)
- hypernetwork.apply_strength()
-
-
- opts.data["CLIP_stop_at_last_layers"] = CLIP_stop_at_last_layers
-
return processed
--
cgit v1.2.1
From 9d702b16f01795c3af900e0ebd70faf4b25200f6 Mon Sep 17 00:00:00 2001
From: yfszzx
Date: Mon, 17 Oct 2022 16:11:03 +0800
Subject: fix two little bug
---
modules/images_history.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules/images_history.py b/modules/images_history.py
index 23045df1..1ae168ca 100644
--- a/modules/images_history.py
+++ b/modules/images_history.py
@@ -133,7 +133,7 @@ def archive_images(dir_name, date_to):
date = sort_array[loads_num][2]
filenames = [x[1] for x in sort_array]
else:
- date = sort_array[loads_num][2]
+ date = sort_array[-1][2]
filenames = [x[1] for x in sort_array]
filenames = [x[1] for x in sort_array if x[2]>= date]
_, image_list, _, visible_num = get_recent_images(1, 0, filenames)
@@ -334,6 +334,6 @@ def create_history_tabs(gr, sys_opts, run_pnginfo, switch_dict):
with gr.Tab(tab):
with gr.Blocks(analytics_enabled=False) as images_history_img2img:
show_images_history(gr, opts, tab, run_pnginfo, switch_dict)
- gradio.Checkbox(opts.images_history_reconstruct_directory, elem_id="images_history_reconstruct_directory") #, visible=False)
+ gradio.Checkbox(opts.images_history_reconstruct_directory, elem_id="images_history_reconstruct_directory", visible=False)
return images_history
--
cgit v1.2.1
From 60251c9456f5472784862896c2f97e38feb42482 Mon Sep 17 00:00:00 2001
From: arcticfaded
Date: Mon, 17 Oct 2022 06:58:42 +0000
Subject: initial prototype by borrowing contracts
---
modules/api/api.py | 60 ++++++++++++++++++++++++++++++++++++++++++++
modules/processing.py | 2 +-
modules/shared.py | 2 +-
webui.py | 69 +++++++++++++++++++++++++++++----------------------
4 files changed, 102 insertions(+), 31 deletions(-)
create mode 100644 modules/api/api.py
diff --git a/modules/api/api.py b/modules/api/api.py
new file mode 100644
index 00000000..9d7c699d
--- /dev/null
+++ b/modules/api/api.py
@@ -0,0 +1,60 @@
+from modules.api.processing import StableDiffusionProcessingAPI
+from modules.processing import StableDiffusionProcessingTxt2Img, process_images
+import modules.shared as shared
+import uvicorn
+from fastapi import FastAPI, Body, APIRouter
+from fastapi.responses import JSONResponse
+from pydantic import BaseModel, Field, Json
+import json
+import io
+import base64
+
+app = FastAPI()
+
+class TextToImageResponse(BaseModel):
+ images: list[str] = Field(default=None, title="Image", description="The generated image in base64 format.")
+ parameters: Json
+ info: Json
+
+
+class Api:
+ def __init__(self, txt2img, img2img, run_extras, run_pnginfo):
+ self.router = APIRouter()
+ app.add_api_route("/v1/txt2img", self.text2imgapi, methods=["POST"])
+
+ def text2imgapi(self, txt2imgreq: StableDiffusionProcessingAPI ):
+ print(txt2imgreq)
+ p = StableDiffusionProcessingTxt2Img(**vars(txt2imgreq))
+ p.sd_model = shared.sd_model
+ print(p)
+ processed = process_images(p)
+
+ b64images = []
+ for i in processed.images:
+ buffer = io.BytesIO()
+ i.save(buffer, format="png")
+ b64images.append(base64.b64encode(buffer.getvalue()))
+
+ response = {
+ "images": b64images,
+ "info": processed.js(),
+ "parameters": json.dumps(vars(txt2imgreq))
+ }
+
+
+ return TextToImageResponse(images=b64images, parameters=json.dumps(vars(txt2imgreq)), info=json.dumps(processed.info))
+
+
+
+ def img2imgendoint(self):
+ raise NotImplementedError
+
+ def extrasendoint(self):
+ raise NotImplementedError
+
+ def pnginfoendoint(self):
+ raise NotImplementedError
+
+ def launch(self, server_name, port):
+ app.include_router(self.router)
+ uvicorn.run(app, host=server_name, port=port)
\ No newline at end of file
diff --git a/modules/processing.py b/modules/processing.py
index deb6125e..4a7c6ccc 100644
--- a/modules/processing.py
+++ b/modules/processing.py
@@ -723,4 +723,4 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
del x
devices.torch_gc()
- return samples
+ return samples
\ No newline at end of file
diff --git a/modules/shared.py b/modules/shared.py
index c2775603..6c6405fd 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -74,7 +74,7 @@ parser.add_argument("--disable-console-progressbars", action='store_true', help=
parser.add_argument("--enable-console-prompts", action='store_true', help="print prompts to console when generating with txt2img and img2img", default=False)
parser.add_argument('--vae-path', type=str, help='Path to Variational Autoencoders model', default=None)
parser.add_argument("--disable-safe-unpickle", action='store_true', help="disable checking pytorch models for malicious code", default=False)
-
+parser.add_argument("--api", action='store_true', help="use api=True to launch the api instead of the webui")
cmd_opts = parser.parse_args()
restricted_opts = [
diff --git a/webui.py b/webui.py
index fe0ce321..cd8a99ea 100644
--- a/webui.py
+++ b/webui.py
@@ -97,40 +97,51 @@ def webui():
os._exit(0)
signal.signal(signal.SIGINT, sigint_handler)
+
+ if cmd_opts.api:
+ from modules.api.api import Api
+ api = Api(txt2img=modules.txt2img.txt2img,
+ img2img=modules.img2img.img2img,
+ run_extras=modules.extras.run_extras,
+ run_pnginfo=modules.extras.run_pnginfo)
- while 1:
-
- demo = modules.ui.create_ui(wrap_gradio_gpu_call=wrap_gradio_gpu_call)
-
- app, local_url, share_url = demo.launch(
- share=cmd_opts.share,
- server_name="0.0.0.0" if cmd_opts.listen else None,
- server_port=cmd_opts.port,
- debug=cmd_opts.gradio_debug,
- auth=[tuple(cred.split(':')) for cred in cmd_opts.gradio_auth.strip('"').split(',')] if cmd_opts.gradio_auth else None,
- inbrowser=cmd_opts.autolaunch,
- prevent_thread_lock=True
- )
-
- app.add_middleware(GZipMiddleware, minimum_size=1000)
+ api.launch(server_name="0.0.0.0" if cmd_opts.listen else "127.0.0.1",
+ port=cmd_opts.port if cmd_opts.port else 7861)
+ else:
while 1:
- time.sleep(0.5)
- if getattr(demo, 'do_restart', False):
- time.sleep(0.5)
- demo.close()
- time.sleep(0.5)
- break
- sd_samplers.set_samplers()
+ demo = modules.ui.create_ui(wrap_gradio_gpu_call=wrap_gradio_gpu_call)
- print('Reloading Custom Scripts')
- modules.scripts.reload_scripts(os.path.join(script_path, "scripts"))
- print('Reloading modules: modules.ui')
- importlib.reload(modules.ui)
- print('Refreshing Model List')
- modules.sd_models.list_models()
- print('Restarting Gradio')
+ app, local_url, share_url = demo.launch(
+ share=cmd_opts.share,
+ server_name="0.0.0.0" if cmd_opts.listen else None,
+ server_port=cmd_opts.port,
+ debug=cmd_opts.gradio_debug,
+ auth=[tuple(cred.split(':')) for cred in cmd_opts.gradio_auth.strip('"').split(',')] if cmd_opts.gradio_auth else None,
+ inbrowser=cmd_opts.autolaunch,
+ prevent_thread_lock=True
+ )
+
+ app.add_middleware(GZipMiddleware, minimum_size=1000)
+
+ while 1:
+ time.sleep(0.5)
+ if getattr(demo, 'do_restart', False):
+ time.sleep(0.5)
+ demo.close()
+ time.sleep(0.5)
+ break
+
+ sd_samplers.set_samplers()
+
+ print('Reloading Custom Scripts')
+ modules.scripts.reload_scripts(os.path.join(script_path, "scripts"))
+ print('Reloading modules: modules.ui')
+ importlib.reload(modules.ui)
+ print('Refreshing Model List')
+ modules.sd_models.list_models()
+ print('Restarting Gradio')
if __name__ == "__main__":
--
cgit v1.2.1
From 9e02812afd10582f00a7fbbfa63c8f9188678e26 Mon Sep 17 00:00:00 2001
From: arcticfaded
Date: Mon, 17 Oct 2022 07:02:08 +0000
Subject: pydantic instrumentation
---
modules/api/processing.py | 99 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 99 insertions(+)
create mode 100644 modules/api/processing.py
diff --git a/modules/api/processing.py b/modules/api/processing.py
new file mode 100644
index 00000000..459a8f49
--- /dev/null
+++ b/modules/api/processing.py
@@ -0,0 +1,99 @@
+from inflection import underscore
+from typing import Any, Dict, Optional
+from pydantic import BaseModel, Field, create_model
+from modules.processing import StableDiffusionProcessing, Processed, StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img, process_images
+import inspect
+
+
+class ModelDef(BaseModel):
+ """Assistance Class for Pydantic Dynamic Model Generation"""
+
+ field: str
+ field_alias: str
+ field_type: Any
+ field_value: Any
+
+
+class pydanticModelGenerator:
+ """
+ Takes source_data:Dict ( a single instance example of something like a JSON node) and self generates a pythonic data model with Alias to original source field names. This makes it easy to popuate or export to other systems yet handle the data in a pythonic way.
+ Being a pydantic datamodel all the richness of pydantic data validation is available and these models can easily be used in FastAPI and or a ORM
+
+ It does not process full JSON data structures but takes simple JSON document with basic elements
+
+ Provide a model_name, an example of JSON data and a dict of type overrides
+
+ Example:
+
+ source_data = {'Name': '48 Rainbow Rd',
+ 'GroupAddressStyle': 'ThreeLevel',
+ 'LastModified': '2020-12-21T07:02:51.2400232Z',
+ 'ProjectStart': '2020-12-03T07:36:03.324856Z',
+ 'Comment': '',
+ 'CompletionStatus': 'Editing',
+ 'LastUsedPuid': '955',
+ 'Guid': '0c85957b-c2ae-4985-9752-b300ab385b36'}
+
+ source_overrides = {'Guid':{'type':uuid.UUID},
+ 'LastModified':{'type':datetime },
+ 'ProjectStart':{'type':datetime },
+ }
+ source_optionals = {"Comment":True}
+
+ #create Model
+ model_Project=pydanticModelGenerator(
+ model_name="Project",
+ source_data=source_data,
+ overrides=source_overrides,
+ optionals=source_optionals).generate_model()
+
+ #create instance using DynamicModel
+ project_instance=model_Project(**project_info)
+
+ """
+
+ def __init__(
+ self,
+ model_name: str = None,
+ source_data: str = None,
+ params: Dict = {},
+ overrides: Dict = {},
+ optionals: Dict = {},
+ ):
+ def field_type_generator(k, v, overrides, optionals):
+ print(k, v)
+ field_type = str if not overrides.get(k) else overrides[k]["type"]
+ if v is None:
+ field_type = Any
+ else:
+ field_type = type(v)
+
+ return Optional[field_type]
+
+ self._model_name = model_name
+ self._json_data = source_data
+ self._model_def = [
+ ModelDef(
+ field=underscore(k),
+ field_alias=k,
+ field_type=field_type_generator(k, v, overrides, optionals),
+ field_value=v
+ )
+ for (k,v) in source_data.items() if k in params
+ ]
+
+ def generate_model(self):
+ """
+ Creates a pydantic BaseModel
+ from the json and overrides provided at initialization
+ """
+ fields = {
+ d.field: (d.field_type, Field(default=d.field_value, alias=d.field_alias)) for d in self._model_def
+ }
+ DynamicModel = create_model(self._model_name, **fields)
+ DynamicModel.__config__.allow_population_by_field_name = True
+ return DynamicModel
+
+StableDiffusionProcessingAPI = pydanticModelGenerator("StableDiffusionProcessing",
+ StableDiffusionProcessing().__dict__,
+ inspect.signature(StableDiffusionProcessing.__init__).parameters).generate_model()
\ No newline at end of file
--
cgit v1.2.1
From f3fe487e6340b1a2db5d2e2ddf5ae885b4eef54c Mon Sep 17 00:00:00 2001
From: Jonathan
Date: Mon, 17 Oct 2022 03:14:53 -0400
Subject: Update webui.py
---
webui.py | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/webui.py b/webui.py
index cd8a99ea..603a4ccd 100644
--- a/webui.py
+++ b/webui.py
@@ -100,10 +100,7 @@ def webui():
if cmd_opts.api:
from modules.api.api import Api
- api = Api(txt2img=modules.txt2img.txt2img,
- img2img=modules.img2img.img2img,
- run_extras=modules.extras.run_extras,
- run_pnginfo=modules.extras.run_pnginfo)
+ api = Api()
api.launch(server_name="0.0.0.0" if cmd_opts.listen else "127.0.0.1",
port=cmd_opts.port if cmd_opts.port else 7861)
--
cgit v1.2.1
From 832b490e5173f78c4d3aa7ca9ca9ac794d140664 Mon Sep 17 00:00:00 2001
From: Jonathan
Date: Mon, 17 Oct 2022 03:18:41 -0400
Subject: Update processing.py
---
modules/api/processing.py | 41 +++++------------------------------------
1 file changed, 5 insertions(+), 36 deletions(-)
diff --git a/modules/api/processing.py b/modules/api/processing.py
index 459a8f49..4c3d0bd0 100644
--- a/modules/api/processing.py
+++ b/modules/api/processing.py
@@ -16,46 +16,15 @@ class ModelDef(BaseModel):
class pydanticModelGenerator:
"""
- Takes source_data:Dict ( a single instance example of something like a JSON node) and self generates a pythonic data model with Alias to original source field names. This makes it easy to popuate or export to other systems yet handle the data in a pythonic way.
- Being a pydantic datamodel all the richness of pydantic data validation is available and these models can easily be used in FastAPI and or a ORM
-
- It does not process full JSON data structures but takes simple JSON document with basic elements
-
- Provide a model_name, an example of JSON data and a dict of type overrides
-
- Example:
-
- source_data = {'Name': '48 Rainbow Rd',
- 'GroupAddressStyle': 'ThreeLevel',
- 'LastModified': '2020-12-21T07:02:51.2400232Z',
- 'ProjectStart': '2020-12-03T07:36:03.324856Z',
- 'Comment': '',
- 'CompletionStatus': 'Editing',
- 'LastUsedPuid': '955',
- 'Guid': '0c85957b-c2ae-4985-9752-b300ab385b36'}
-
- source_overrides = {'Guid':{'type':uuid.UUID},
- 'LastModified':{'type':datetime },
- 'ProjectStart':{'type':datetime },
- }
- source_optionals = {"Comment":True}
-
- #create Model
- model_Project=pydanticModelGenerator(
- model_name="Project",
- source_data=source_data,
- overrides=source_overrides,
- optionals=source_optionals).generate_model()
-
- #create instance using DynamicModel
- project_instance=model_Project(**project_info)
-
+ Takes in created classes and stubs them out in a way FastAPI/Pydantic is happy about:
+ source_data is a snapshot of the default values produced by the class
+ params are the names of the actual keys required by __init__
"""
def __init__(
self,
model_name: str = None,
- source_data: str = None,
+ source_data: {} = {},
params: Dict = {},
overrides: Dict = {},
optionals: Dict = {},
@@ -96,4 +65,4 @@ class pydanticModelGenerator:
StableDiffusionProcessingAPI = pydanticModelGenerator("StableDiffusionProcessing",
StableDiffusionProcessing().__dict__,
- inspect.signature(StableDiffusionProcessing.__init__).parameters).generate_model()
\ No newline at end of file
+ inspect.signature(StableDiffusionProcessing.__init__).parameters).generate_model()
--
cgit v1.2.1
From 99013ba68a5fe1bde3621632e5539c03562a3ae8 Mon Sep 17 00:00:00 2001
From: Jonathan
Date: Mon, 17 Oct 2022 03:20:17 -0400
Subject: Update processing.py
---
modules/api/processing.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/modules/api/processing.py b/modules/api/processing.py
index 4c3d0bd0..e4df93c5 100644
--- a/modules/api/processing.py
+++ b/modules/api/processing.py
@@ -30,7 +30,6 @@ class pydanticModelGenerator:
optionals: Dict = {},
):
def field_type_generator(k, v, overrides, optionals):
- print(k, v)
field_type = str if not overrides.get(k) else overrides[k]["type"]
if v is None:
field_type = Any
--
cgit v1.2.1
From 71d42bb44b257f3fb274c3ad5075a195281ff915 Mon Sep 17 00:00:00 2001
From: Jonathan
Date: Mon, 17 Oct 2022 03:22:19 -0400
Subject: Update api.py
---
modules/api/api.py | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/modules/api/api.py b/modules/api/api.py
index 9d7c699d..4d9619a8 100644
--- a/modules/api/api.py
+++ b/modules/api/api.py
@@ -23,10 +23,8 @@ class Api:
app.add_api_route("/v1/txt2img", self.text2imgapi, methods=["POST"])
def text2imgapi(self, txt2imgreq: StableDiffusionProcessingAPI ):
- print(txt2imgreq)
p = StableDiffusionProcessingTxt2Img(**vars(txt2imgreq))
p.sd_model = shared.sd_model
- print(p)
processed = process_images(p)
b64images = []
@@ -34,13 +32,6 @@ class Api:
buffer = io.BytesIO()
i.save(buffer, format="png")
b64images.append(base64.b64encode(buffer.getvalue()))
-
- response = {
- "images": b64images,
- "info": processed.js(),
- "parameters": json.dumps(vars(txt2imgreq))
- }
-
return TextToImageResponse(images=b64images, parameters=json.dumps(vars(txt2imgreq)), info=json.dumps(processed.info))
@@ -57,4 +48,4 @@ class Api:
def launch(self, server_name, port):
app.include_router(self.router)
- uvicorn.run(app, host=server_name, port=port)
\ No newline at end of file
+ uvicorn.run(app, host=server_name, port=port)
--
cgit v1.2.1
From 964b63c0423a861bd67c40b59f767e7037051083 Mon Sep 17 00:00:00 2001
From: AUTOMATIC <16777216c@gmail.com>
Date: Mon, 17 Oct 2022 11:38:32 +0300
Subject: add api() function to return webui() to how it was
---
webui.py | 79 +++++++++++++++++++++++++++++++++-------------------------------
1 file changed, 41 insertions(+), 38 deletions(-)
diff --git a/webui.py b/webui.py
index 603a4ccd..16c862f0 100644
--- a/webui.py
+++ b/webui.py
@@ -87,59 +87,62 @@ def initialize():
shared.opts.onchange("sd_hypernetwork", wrap_queued_call(lambda: modules.hypernetworks.hypernetwork.load_hypernetwork(shared.opts.sd_hypernetwork)))
shared.opts.onchange("sd_hypernetwork_strength", modules.hypernetworks.hypernetwork.apply_strength)
-
-def webui():
- initialize()
-
# make the program just exit at ctrl+c without waiting for anything
def sigint_handler(sig, frame):
print(f'Interrupted with signal {sig} in {frame}')
os._exit(0)
signal.signal(signal.SIGINT, sigint_handler)
-
- if cmd_opts.api:
- from modules.api.api import Api
- api = Api()
- api.launch(server_name="0.0.0.0" if cmd_opts.listen else "127.0.0.1",
- port=cmd_opts.port if cmd_opts.port else 7861)
- else:
- while 1:
+def api()
+ initialize()
- demo = modules.ui.create_ui(wrap_gradio_gpu_call=wrap_gradio_gpu_call)
+ from modules.api.api import Api
+ api = Api()
+ api.launch(server_name="0.0.0.0" if cmd_opts.listen else "127.0.0.1", port=cmd_opts.port if cmd_opts.port else 7861)
- app, local_url, share_url = demo.launch(
- share=cmd_opts.share,
- server_name="0.0.0.0" if cmd_opts.listen else None,
- server_port=cmd_opts.port,
- debug=cmd_opts.gradio_debug,
- auth=[tuple(cred.split(':')) for cred in cmd_opts.gradio_auth.strip('"').split(',')] if cmd_opts.gradio_auth else None,
- inbrowser=cmd_opts.autolaunch,
- prevent_thread_lock=True
- )
- app.add_middleware(GZipMiddleware, minimum_size=1000)
+def webui():
+ initialize()
- while 1:
+ while 1:
+
+ demo = modules.ui.create_ui(wrap_gradio_gpu_call=wrap_gradio_gpu_call)
+
+ app, local_url, share_url = demo.launch(
+ share=cmd_opts.share,
+ server_name="0.0.0.0" if cmd_opts.listen else None,
+ server_port=cmd_opts.port,
+ debug=cmd_opts.gradio_debug,
+ auth=[tuple(cred.split(':')) for cred in cmd_opts.gradio_auth.strip('"').split(',')] if cmd_opts.gradio_auth else None,
+ inbrowser=cmd_opts.autolaunch,
+ prevent_thread_lock=True
+ )
+
+ app.add_middleware(GZipMiddleware, minimum_size=1000)
+
+ while 1:
+ time.sleep(0.5)
+ if getattr(demo, 'do_restart', False):
+ time.sleep(0.5)
+ demo.close()
time.sleep(0.5)
- if getattr(demo, 'do_restart', False):
- time.sleep(0.5)
- demo.close()
- time.sleep(0.5)
- break
+ break
- sd_samplers.set_samplers()
+ sd_samplers.set_samplers()
- print('Reloading Custom Scripts')
- modules.scripts.reload_scripts(os.path.join(script_path, "scripts"))
- print('Reloading modules: modules.ui')
- importlib.reload(modules.ui)
- print('Refreshing Model List')
- modules.sd_models.list_models()
- print('Restarting Gradio')
+ print('Reloading Custom Scripts')
+ modules.scripts.reload_scripts(os.path.join(script_path, "scripts"))
+ print('Reloading modules: modules.ui')
+ importlib.reload(modules.ui)
+ print('Refreshing Model List')
+ modules.sd_models.list_models()
+ print('Restarting Gradio')
if __name__ == "__main__":
- webui()
+ if cmd_opts.api:
+ api()
+ else:
+ webui()
--
cgit v1.2.1
From d42125baf62880854ad06af06c15c23e7e50cca6 Mon Sep 17 00:00:00 2001
From: AUTOMATIC <16777216c@gmail.com>
Date: Mon, 17 Oct 2022 11:50:20 +0300
Subject: add missing requirement for api and fix some typos
---
modules/api/api.py | 2 +-
requirements.txt | 1 +
requirements_versions.txt | 1 +
webui.py | 2 +-
4 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/modules/api/api.py b/modules/api/api.py
index 4d9619a8..fd09d352 100644
--- a/modules/api/api.py
+++ b/modules/api/api.py
@@ -18,7 +18,7 @@ class TextToImageResponse(BaseModel):
class Api:
- def __init__(self, txt2img, img2img, run_extras, run_pnginfo):
+ def __init__(self):
self.router = APIRouter()
app.add_api_route("/v1/txt2img", self.text2imgapi, methods=["POST"])
diff --git a/requirements.txt b/requirements.txt
index cf583de9..da1969cf 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -23,3 +23,4 @@ resize-right
torchdiffeq
kornia
lark
+inflection
diff --git a/requirements_versions.txt b/requirements_versions.txt
index abadcb58..72ccc5a3 100644
--- a/requirements_versions.txt
+++ b/requirements_versions.txt
@@ -22,3 +22,4 @@ resize-right==0.0.2
torchdiffeq==0.2.3
kornia==0.6.7
lark==1.1.2
+inflection==0.5.1
diff --git a/webui.py b/webui.py
index 16c862f0..eeee44c3 100644
--- a/webui.py
+++ b/webui.py
@@ -95,7 +95,7 @@ def initialize():
signal.signal(signal.SIGINT, sigint_handler)
-def api()
+def api():
initialize()
from modules.api.api import Api
--
cgit v1.2.1
From 8c6a981d5d9ef30381ac2327460285111550acbc Mon Sep 17 00:00:00 2001
From: Michoko
Date: Mon, 17 Oct 2022 11:05:05 +0200
Subject: Added dark mode switch
Launch the UI in dark mode with the --dark-mode switch
---
javascript/ui.js | 7 +++++++
modules/shared.py | 2 +-
modules/ui.py | 2 ++
3 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/javascript/ui.js b/javascript/ui.js
index 9e1bed4c..bfa72885 100644
--- a/javascript/ui.js
+++ b/javascript/ui.js
@@ -1,5 +1,12 @@
// various functions for interation with ui.py not large enough to warrant putting them in separate files
+function go_dark_mode(){
+ gradioURL = window.location.href
+ if (!gradioURL.endsWith('?__theme=dark')) {
+ window.location.replace(gradioURL + '?__theme=dark');
+ }
+}
+
function selected_gallery_index(){
var buttons = gradioApp().querySelectorAll('[style="display: block;"].tabitem .gallery-item')
var button = gradioApp().querySelector('[style="display: block;"].tabitem .gallery-item.\\!ring-2')
diff --git a/modules/shared.py b/modules/shared.py
index c2775603..cbf158e4 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -69,13 +69,13 @@ parser.add_argument("--gradio-img2img-tool", type=str, help='gradio image upload
parser.add_argument("--opt-channelslast", action='store_true', help="change memory type for stable diffusion to channels last")
parser.add_argument("--styles-file", type=str, help="filename to use for styles", default=os.path.join(script_path, 'styles.csv'))
parser.add_argument("--autolaunch", action='store_true', help="open the webui URL in the system's default browser upon launch", default=False)
+parser.add_argument("--dark-mode", action='store_true', help="launches the UI in dark mode", default=False)
parser.add_argument("--use-textbox-seed", action='store_true', help="use textbox for seeds in UI (no up/down, but possible to input long seeds)", default=False)
parser.add_argument("--disable-console-progressbars", action='store_true', help="do not output progressbars to console", default=False)
parser.add_argument("--enable-console-prompts", action='store_true', help="print prompts to console when generating with txt2img and img2img", default=False)
parser.add_argument('--vae-path', type=str, help='Path to Variational Autoencoders model', default=None)
parser.add_argument("--disable-safe-unpickle", action='store_true', help="disable checking pytorch models for malicious code", default=False)
-
cmd_opts = parser.parse_args()
restricted_opts = [
"samples_filename_pattern",
diff --git a/modules/ui.py b/modules/ui.py
index 43dc88fc..a0cd052e 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -1783,6 +1783,8 @@ for filename in sorted(os.listdir(jsdir)):
with open(os.path.join(jsdir, filename), "r", encoding="utf8") as jsfile:
javascript += f"\n"
+if cmd_opts.dark_mode:
+ javascript += "\n\n"
if 'gradio_routes_templates_response' not in globals():
def template_response(*args, **kwargs):
--
cgit v1.2.1
From af3f6489d3b229da4e688eaf439adb5d3e4f070b Mon Sep 17 00:00:00 2001
From: AUTOMATIC <16777216c@gmail.com>
Date: Mon, 17 Oct 2022 16:57:19 +0300
Subject: possibly defeat losing of focus for prompt when generating images
with gallery open
---
javascript/progressbar.js | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/javascript/progressbar.js b/javascript/progressbar.js
index c7d0343f..7a05726e 100644
--- a/javascript/progressbar.js
+++ b/javascript/progressbar.js
@@ -72,11 +72,17 @@ function check_gallery(id_gallery){
let galleryButtons = gradioApp().querySelectorAll('#'+id_gallery+' .gallery-item')
let galleryBtnSelected = gradioApp().querySelector('#'+id_gallery+' .gallery-item.\\!ring-2')
if (prevSelectedIndex !== -1 && galleryButtons.length>prevSelectedIndex && !galleryBtnSelected) {
- //automatically re-open previously selected index (if exists)
- activeElement = document.activeElement;
+ // automatically re-open previously selected index (if exists)
+ activeElement = gradioApp().activeElement;
+
galleryButtons[prevSelectedIndex].click();
showGalleryImage();
- if(activeElement) activeElement.focus()
+
+ if(activeElement){
+ // i fought this for about an hour; i don't know why the focus is lost or why this helps recover it
+ // if somenoe has a better solution please by all means
+ setTimeout(function() { activeElement.focus() }, 1);
+ }
}
})
galleryObservers[id_gallery].observe( gallery, { childList:true, subtree:false })
--
cgit v1.2.1
From c408a0b41cfffde184cad35b2d97346342947d83 Mon Sep 17 00:00:00 2001
From: yfszzx
Date: Mon, 17 Oct 2022 22:28:43 +0800
Subject: fix two bug
---
launch.py | 1 -
modules/images_history.py | 4 ++--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/launch.py b/launch.py
index 7520cfee..088eada1 100644
--- a/launch.py
+++ b/launch.py
@@ -11,7 +11,6 @@ python = sys.executable
git = os.environ.get('GIT', "git")
index_url = os.environ.get('INDEX_URL', "")
-
def extract_arg(args, name):
return [x for x in args if x != name], name in args
diff --git a/modules/images_history.py b/modules/images_history.py
index 1ae168ca..10e5b970 100644
--- a/modules/images_history.py
+++ b/modules/images_history.py
@@ -181,7 +181,8 @@ def delete_image(delete_num, name, filenames, image_index, visible_num):
return new_file_list, 1, visible_num
def save_image(file_name):
- shutil.copy2(file_name, opts.outdir_save)
+ if file_name is not None and os.path.exists(file_name):
+ shutil.copy2(file_name, opts.outdir_save)
def get_recent_images(page_index, step, filenames):
page_index = int(page_index)
@@ -327,7 +328,6 @@ def create_history_tabs(gr, sys_opts, run_pnginfo, switch_dict):
opts = sys_opts
loads_files_num = int(opts.images_history_num_per_page)
num_of_imgs_per_page = int(opts.images_history_num_per_page * opts.images_history_pages_num)
- backup_flag = opts.images_history_backup
with gr.Blocks(analytics_enabled=False) as images_history:
with gr.Tabs() as tabs:
for tab in ["txt2img", "img2img", "extras", "saved"]:
--
cgit v1.2.1
From de179cf8fd8191e1a6d288e7c29a16f53da1be88 Mon Sep 17 00:00:00 2001
From: yfszzx
Date: Mon, 17 Oct 2022 22:38:46 +0800
Subject: fix two bug
---
launch.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/launch.py b/launch.py
index 088eada1..7520cfee 100644
--- a/launch.py
+++ b/launch.py
@@ -11,6 +11,7 @@ python = sys.executable
git = os.environ.get('GIT', "git")
index_url = os.environ.get('INDEX_URL', "")
+
def extract_arg(args, name):
return [x for x in args if x != name], name in args
--
cgit v1.2.1
From 2272cf2f35fafd5cd486bfb4ee89df5bbc625b97 Mon Sep 17 00:00:00 2001
From: yfszzx
Date: Mon, 17 Oct 2022 23:04:42 +0800
Subject: fix two bug
---
modules/images_history.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/images_history.py b/modules/images_history.py
index 10e5b970..1c1790a4 100644
--- a/modules/images_history.py
+++ b/modules/images_history.py
@@ -133,7 +133,7 @@ def archive_images(dir_name, date_to):
date = sort_array[loads_num][2]
filenames = [x[1] for x in sort_array]
else:
- date = sort_array[-1][2]
+ date = None if len(sort_array) == 0 else sort_array[-1][2]
filenames = [x[1] for x in sort_array]
filenames = [x[1] for x in sort_array if x[2]>= date]
_, image_list, _, visible_num = get_recent_images(1, 0, filenames)
--
cgit v1.2.1
From 2b5b62e768d892773a7ec1d5e8d8cea23aae1254 Mon Sep 17 00:00:00 2001
From: yfszzx
Date: Mon, 17 Oct 2022 23:14:03 +0800
Subject: fix two bug
---
modules/images_history.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules/images_history.py b/modules/images_history.py
index 1c1790a4..20324557 100644
--- a/modules/images_history.py
+++ b/modules/images_history.py
@@ -44,7 +44,7 @@ def traverse_all_files(curr_path, image_list, all_type=False):
return image_list
for file in f_list:
file = os.path.join(curr_path, file)
- if (not all_type) and file[-4:] == ".txt":
+ if (not all_type) and (file[-4:] == ".txt" or file[-4:] == ".csv"):
pass
elif os.path.isfile(file) and file[-10:].rfind(".") > 0:
image_list.append(file)
@@ -182,7 +182,7 @@ def delete_image(delete_num, name, filenames, image_index, visible_num):
def save_image(file_name):
if file_name is not None and os.path.exists(file_name):
- shutil.copy2(file_name, opts.outdir_save)
+ shutil.copy(file_name, opts.outdir_save)
def get_recent_images(page_index, step, filenames):
page_index = int(page_index)
--
cgit v1.2.1
From 665beebc0825a6fad410c8252f27f6f6f0bd900b Mon Sep 17 00:00:00 2001
From: Michoko
Date: Mon, 17 Oct 2022 18:24:24 +0200
Subject: Use of a --theme argument for more flexibility
Added possibility to set the theme (light or dark)
---
javascript/ui.js | 6 +++---
modules/shared.py | 2 +-
modules/ui.py | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/javascript/ui.js b/javascript/ui.js
index bfa72885..cfd0dcd3 100644
--- a/javascript/ui.js
+++ b/javascript/ui.js
@@ -1,9 +1,9 @@
// various functions for interation with ui.py not large enough to warrant putting them in separate files
-function go_dark_mode(){
+function set_theme(theme){
gradioURL = window.location.href
- if (!gradioURL.endsWith('?__theme=dark')) {
- window.location.replace(gradioURL + '?__theme=dark');
+ if (!gradioURL.includes('?__theme=')) {
+ window.location.replace(gradioURL + '?__theme=' + theme);
}
}
diff --git a/modules/shared.py b/modules/shared.py
index cbf158e4..fa084c69 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -69,7 +69,7 @@ parser.add_argument("--gradio-img2img-tool", type=str, help='gradio image upload
parser.add_argument("--opt-channelslast", action='store_true', help="change memory type for stable diffusion to channels last")
parser.add_argument("--styles-file", type=str, help="filename to use for styles", default=os.path.join(script_path, 'styles.csv'))
parser.add_argument("--autolaunch", action='store_true', help="open the webui URL in the system's default browser upon launch", default=False)
-parser.add_argument("--dark-mode", action='store_true', help="launches the UI in dark mode", default=False)
+parser.add_argument("--theme", type=str, help="launches the UI with light or dark theme", default=None)
parser.add_argument("--use-textbox-seed", action='store_true', help="use textbox for seeds in UI (no up/down, but possible to input long seeds)", default=False)
parser.add_argument("--disable-console-progressbars", action='store_true', help="do not output progressbars to console", default=False)
parser.add_argument("--enable-console-prompts", action='store_true', help="print prompts to console when generating with txt2img and img2img", default=False)
diff --git a/modules/ui.py b/modules/ui.py
index a0cd052e..d41715fa 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -1783,8 +1783,8 @@ for filename in sorted(os.listdir(jsdir)):
with open(os.path.join(jsdir, filename), "r", encoding="utf8") as jsfile:
javascript += f"\n