Skip to content

Commit

Permalink
Merge pull request #1 from vladmandic/last-known-origin
Browse files Browse the repository at this point in the history
Last known origin
  • Loading branch information
vladmandic authored Jan 5, 2023
2 parents 8149078 + f8d0cf6 commit 646a36f
Show file tree
Hide file tree
Showing 21 changed files with 180 additions and 83 deletions.
4 changes: 4 additions & 0 deletions html/footer.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@
 • 
<a href="/" onclick="javascript:gradioApp().getElementById('settings_restart_gradio').click(); return false">Reload UI</a>
</div>
<br />
<div class="versions">
{versions}
</div>
4 changes: 2 additions & 2 deletions javascript/imageviewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ function showGalleryImage() {
if(e && e.parentElement.tagName == 'DIV'){
e.style.cursor='pointer'
e.style.userSelect='none'
e.addEventListener('click', function (evt) {
if(!opts.js_modal_lightbox) return;
e.addEventListener('mousedown', function (evt) {
if(!opts.js_modal_lightbox || evt.button != 0) return;
modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed)
showModal(evt)
}, true);
Expand Down
20 changes: 16 additions & 4 deletions launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,21 @@
python = sys.executable
git = os.environ.get('GIT', "git")
index_url = os.environ.get('INDEX_URL', "")
stored_commit_hash = None


def commit_hash():
global stored_commit_hash

if stored_commit_hash is not None:
return stored_commit_hash

try:
stored_commit_hash = run(f"{git} rev-parse HEAD").strip()
except Exception:
stored_commit_hash = "<none>"

return stored_commit_hash


def extract_arg(args, name):
Expand Down Expand Up @@ -194,10 +209,7 @@ def prepare_environment():
xformers = '--xformers' in sys.argv
ngrok = '--ngrok' in sys.argv

try:
commit = run(f"{git} rev-parse HEAD").strip()
except Exception:
commit = "<none>"
commit = commit_hash()

print(f"Python {sys.version}")
print(f"Commit hash: {commit}")
Expand Down
16 changes: 12 additions & 4 deletions modules/api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
from secrets import compare_digest

import modules.shared as shared
from modules import sd_samplers, deepbooru, sd_hijack
from modules import sd_samplers, deepbooru, sd_hijack, images
from modules.api.models import *
from modules.processing import StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img, process_images
from modules.extras import run_extras, run_pnginfo
from modules.extras import run_extras
from modules.textual_inversion.textual_inversion import create_embedding, train_embedding
from modules.textual_inversion.preprocess import preprocess
from modules.hypernetworks.hypernetwork import create_hypernetwork, train_hypernetwork
Expand Down Expand Up @@ -233,9 +233,17 @@ def pnginfoapi(self, req: PNGInfoRequest):
if(not req.image.strip()):
return PNGInfoResponse(info="")

result = run_pnginfo(decode_base64_to_image(req.image.strip()))
image = decode_base64_to_image(req.image.strip())
if image is None:
return PNGInfoResponse(info="")

geninfo, items = images.read_info_from_image(image)
if geninfo is None:
geninfo = ""

items = {**{'parameters': geninfo}, **items}

return PNGInfoResponse(info=result[1])
return PNGInfoResponse(info=geninfo, items=items)

def progressapi(self, req: ProgressRequest = Depends()):
# copy from check_progress_call of ui.py
Expand Down
5 changes: 3 additions & 2 deletions modules/api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ class PNGInfoRequest(BaseModel):
image: str = Field(title="Image", description="The base64 encoded PNG image")

class PNGInfoResponse(BaseModel):
info: str = Field(title="Image info", description="A string with all the info the image had")
info: str = Field(title="Image info", description="A string with the parameters used to generate the image")
items: dict = Field(title="Items", description="An object containing all the info the image had")

class ProgressRequest(BaseModel):
skip_current_image: bool = Field(default=False, title="Skip current image", description="Skip current image serialization")
Expand Down Expand Up @@ -258,4 +259,4 @@ class EmbeddingItem(BaseModel):

class EmbeddingsResponse(BaseModel):
loaded: Dict[str, EmbeddingItem] = Field(title="Loaded", description="Embeddings loaded for the current model")
skipped: Dict[str, EmbeddingItem] = Field(title="Skipped", description="Embeddings skipped for the current model (likely due to architecture incompatibility)")
skipped: Dict[str, EmbeddingItem] = Field(title="Skipped", description="Embeddings skipped for the current model (likely due to architecture incompatibility)")
38 changes: 28 additions & 10 deletions modules/processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ def apply_color_correction(correction, original_image):
correction,
channel_axis=2
), cv2.COLOR_LAB2RGB).astype("uint8"))

image = blendLayers(image, original_image, BlendType.LUMINOSITY)

return image


Expand Down Expand Up @@ -466,9 +466,15 @@ def process_images(p: StableDiffusionProcessing) -> Processed:
try:
for k, v in p.override_settings.items():
setattr(opts, k, v)
if k == 'sd_hypernetwork': shared.reload_hypernetworks() # make onchange call for changing hypernet
if k == 'sd_model_checkpoint': sd_models.reload_model_weights() # make onchange call for changing SD model
if k == 'sd_vae': sd_vae.reload_vae_weights() # make onchange call for changing VAE
if k == 'sd_hypernetwork':
shared.reload_hypernetworks() # make onchange call for changing hypernet

if k == 'sd_model_checkpoint':
sd_models.reload_model_weights() # make onchange call for changing SD model
p.sd_model = shared.sd_model

if k == 'sd_vae':
sd_vae.reload_vae_weights() # make onchange call for changing VAE

res = process_images_inner(p)

Expand Down Expand Up @@ -683,13 +689,9 @@ def __init__(self, enable_hr: bool = False, denoising_strength: float = 0.75, fi
self.truncate_x = 0
self.truncate_y = 0


def init(self, all_prompts, all_seeds, all_subseeds):
if self.enable_hr:
if state.job_count == -1:
state.job_count = self.n_iter * 2
else:
state.job_count = state.job_count * 2

if self.hr_resize_x == 0 and self.hr_resize_y == 0:
self.extra_generation_params["Hires upscale"] = self.hr_scale
self.hr_upscale_to_x = int(self.width * self.hr_scale)
Expand Down Expand Up @@ -719,6 +721,22 @@ def init(self, all_prompts, all_seeds, all_subseeds):
self.truncate_x = (self.hr_upscale_to_x - target_w) // opt_f
self.truncate_y = (self.hr_upscale_to_y - target_h) // opt_f

# special case: the user has chosen to do nothing
if self.hr_upscale_to_x == self.width and self.hr_upscale_to_y == self.height:
self.enable_hr = False
self.denoising_strength = None
self.extra_generation_params.pop("Hires upscale", None)
self.extra_generation_params.pop("Hires resize", None)
return

if not state.processing_has_refined_job_count:
if state.job_count == -1:
state.job_count = self.n_iter

shared.total_tqdm.updateTotal((self.steps + (self.hr_second_pass_steps or self.steps)) * state.job_count)
state.job_count = state.job_count * 2
state.processing_has_refined_job_count = True

if self.hr_second_pass_steps:
self.extra_generation_params["Hires steps"] = self.hr_second_pass_steps

Expand Down
10 changes: 10 additions & 0 deletions modules/scripts.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import re
import sys
import traceback
from collections import namedtuple
Expand Down Expand Up @@ -128,6 +129,15 @@ def describe(self):
"""unused"""
return ""

def elem_id(self, item_id):
"""helper function to generate id for a HTML element, constructs final id out of script name, tab and user-supplied item_id"""

need_tabname = self.show(True) == self.show(False)
tabname = ('img2img' if self.is_img2img else 'txt2txt') + "_" if need_tabname else ""
title = re.sub(r'[^a-z_0-9]', '', re.sub(r'\s', '_', self.title().lower()))

return f'script_{tabname}{title}_{item_id}'


current_basedir = paths.script_path

Expand Down
14 changes: 11 additions & 3 deletions modules/sd_samplers.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,9 @@ def set_samplers():

def setup_img2img_steps(p, steps=None):
if opts.img2img_fix_steps or steps is not None:
steps = int((steps or p.steps) / min(p.denoising_strength, 0.999)) if p.denoising_strength > 0 else 0
t_enc = p.steps - 1
requested_steps = (steps or p.steps)
steps = int(requested_steps / min(p.denoising_strength, 0.999)) if p.denoising_strength > 0 else 0
t_enc = requested_steps - 1
else:
steps = p.steps
t_enc = int(min(p.denoising_strength, 0.999) * steps)
Expand Down Expand Up @@ -462,6 +463,13 @@ def initialize(self, p):
return extra_params_kwargs

def get_sigmas(self, p, steps):
discard_next_to_last_sigma = self.config is not None and self.config.options.get('discard_next_to_last_sigma', False)
if opts.always_discard_next_to_last_sigma and not discard_next_to_last_sigma:
discard_next_to_last_sigma = True
p.extra_generation_params["Discard penultimate sigma"] = True

steps += 1 if discard_next_to_last_sigma else 0

if p.sampler_noise_scheduler_override:
sigmas = p.sampler_noise_scheduler_override(steps)
elif self.config is not None and self.config.options.get('scheduler', None) == 'karras':
Expand All @@ -471,7 +479,7 @@ def get_sigmas(self, p, steps):
else:
sigmas = self.model_wrap.get_sigmas(steps)

if self.config is not None and self.config.options.get('discard_next_to_last_sigma', False):
if discard_next_to_last_sigma:
sigmas = torch.cat([sigmas[:-2], sigmas[-1:]])

return sigmas
Expand Down
5 changes: 4 additions & 1 deletion modules/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ class State:
job = ""
job_no = 0
job_count = 0
processing_has_refined_job_count = False
job_timestamp = '0'
sampling_step = 0
sampling_steps = 0
Expand Down Expand Up @@ -194,6 +195,7 @@ def dict(self):
def begin(self):
self.sampling_step = 0
self.job_count = -1
self.processing_has_refined_job_count = False
self.job_no = 0
self.job_timestamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
self.current_latent = None
Expand Down Expand Up @@ -440,6 +442,7 @@ def list_samplers():
's_tmin': OptionInfo(0.0, "sigma tmin", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}),
's_noise': OptionInfo(1.0, "sigma noise", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}),
'eta_noise_seed_delta': OptionInfo(0, "Eta noise seed delta", gr.Number, {"precision": 0}),
'always_discard_next_to_last_sigma': OptionInfo(False, "Always discard next-to-last sigma"),
}))

options_templates.update(options_section((None, "Hidden options"), {
Expand Down Expand Up @@ -608,7 +611,7 @@ def updateTotal(self, new_total):
return
if self._tqdm is None:
self.reset()
self._tqdm.total=new_total
self._tqdm.total = new_total

def clear(self):
if self._tqdm is not None:
Expand Down
47 changes: 38 additions & 9 deletions modules/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ def open_folder(f):
generation_info = None
with gr.Column():
with gr.Row(elem_id=f"image_buttons_{tabname}"):
open_folder_button = gr.Button(folder_symbol, elem_id="hidden_element" if shared.cmd_opts.hide_ui_dir_config else 'open_folder')
open_folder_button = gr.Button(folder_symbol, elem_id="hidden_element" if shared.cmd_opts.hide_ui_dir_config else f'open_folder_{tabname}')

if tabname != "extras":
save = gr.Button('Save', elem_id=f'save_{tabname}')
Expand All @@ -576,13 +576,13 @@ def open_folder(f):

if tabname != "extras":
with gr.Row():
download_files = gr.File(None, file_count="multiple", interactive=False, show_label=False, visible=False)
download_files = gr.File(None, file_count="multiple", interactive=False, show_label=False, visible=False, elem_id=f'download_files_{tabname}')

with gr.Group():
html_info = gr.HTML()
html_log = gr.HTML()
html_info = gr.HTML(elem_id=f'html_info_{tabname}')
html_log = gr.HTML(elem_id=f'html_log_{tabname}')

generation_info = gr.Textbox(visible=False)
generation_info = gr.Textbox(visible=False, elem_id=f'generation_info_{tabname}')
if tabname == 'txt2img' or tabname == 'img2img':
generation_info_button = gr.Button(visible=False, elem_id=f"{tabname}_generation_info_button")
generation_info_button.click(
Expand Down Expand Up @@ -624,9 +624,9 @@ def open_folder(f):
)

else:
html_info_x = gr.HTML()
html_info = gr.HTML()
html_log = gr.HTML()
html_info_x = gr.HTML(elem_id=f'html_info_x_{tabname}')
html_info = gr.HTML(elem_id=f'html_info_{tabname}')
html_log = gr.HTML(elem_id=f'html_log_{tabname}')

parameters_copypaste.bind_buttons(buttons, result_gallery, "txt2img" if tabname == "txt2img" else None)
return result_gallery, generation_info if tabname != "extras" else html_info_x, html_info, html_log
Expand Down Expand Up @@ -1696,7 +1696,9 @@ def request_restart():

if os.path.exists("html/footer.html"):
with open("html/footer.html", encoding="utf8") as file:
gr.HTML(file.read(), elem_id="footer")
footer = file.read()
footer = footer.format(versions=versions_html())
gr.HTML(footer, elem_id="footer")

text_settings = gr.Textbox(elem_id="settings_json", value=lambda: opts.dumpjson(), visible=False)
settings_submit.click(
Expand Down Expand Up @@ -1857,3 +1859,30 @@ def template_response(*args, **kwargs):

if not hasattr(shared, 'GradioTemplateResponseOriginal'):
shared.GradioTemplateResponseOriginal = gradio.routes.templates.TemplateResponse


def versions_html():
import torch
import launch

python_version = ".".join([str(x) for x in sys.version_info[0:3]])
commit = launch.commit_hash()
short_commit = commit[0:8]

if shared.xformers_available:
import xformers
xformers_version = xformers.__version__
else:
xformers_version = "N/A"

return f"""
python: <span title="{sys.version}">{python_version}</span>
 • 
torch: {torch.__version__}
 • 
xformers: {xformers_version}
 • 
gradio: {gr.__version__}
 • 
commit: <a href="https://github.com/AUTOMATIC1111/stable-diffusion-webui/commit/{commit}">{short_commit}</a>
"""
3 changes: 1 addition & 2 deletions scripts/custom_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@ class Script(scripts.Script):
def title(self):
return "Custom code"


def show(self, is_img2img):
return cmd_opts.allow_code

def ui(self, is_img2img):
code = gr.Textbox(label="Python code", lines=1)
code = gr.Textbox(label="Python code", lines=1, elem_id=self.elem_id("code"))

return [code]

Expand Down
22 changes: 11 additions & 11 deletions scripts/img2imgalt.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,25 +125,25 @@ def title(self):
def show(self, is_img2img):
return is_img2img

def ui(self, is_img2img):
def ui(self, is_img2img):
info = gr.Markdown('''
* `CFG Scale` should be 2 or lower.
''')

override_sampler = gr.Checkbox(label="Override `Sampling method` to Euler?(this method is built for it)", value=True)
override_sampler = gr.Checkbox(label="Override `Sampling method` to Euler?(this method is built for it)", value=True, elem_id=self.elem_id("override_sampler"))

override_prompt = gr.Checkbox(label="Override `prompt` to the same value as `original prompt`?(and `negative prompt`)", value=True)
original_prompt = gr.Textbox(label="Original prompt", lines=1)
original_negative_prompt = gr.Textbox(label="Original negative prompt", lines=1)
override_prompt = gr.Checkbox(label="Override `prompt` to the same value as `original prompt`?(and `negative prompt`)", value=True, elem_id=self.elem_id("override_prompt"))
original_prompt = gr.Textbox(label="Original prompt", lines=1, elem_id=self.elem_id("original_prompt"))
original_negative_prompt = gr.Textbox(label="Original negative prompt", lines=1, elem_id=self.elem_id("original_negative_prompt"))

override_steps = gr.Checkbox(label="Override `Sampling Steps` to the same value as `Decode steps`?", value=True)
st = gr.Slider(label="Decode steps", minimum=1, maximum=150, step=1, value=50)
override_steps = gr.Checkbox(label="Override `Sampling Steps` to the same value as `Decode steps`?", value=True, elem_id=self.elem_id("override_steps"))
st = gr.Slider(label="Decode steps", minimum=1, maximum=150, step=1, value=50, elem_id=self.elem_id("st"))

override_strength = gr.Checkbox(label="Override `Denoising strength` to 1?", value=True)
override_strength = gr.Checkbox(label="Override `Denoising strength` to 1?", value=True, elem_id=self.elem_id("override_strength"))

cfg = gr.Slider(label="Decode CFG scale", minimum=0.0, maximum=15.0, step=0.1, value=1.0)
randomness = gr.Slider(label="Randomness", minimum=0.0, maximum=1.0, step=0.01, value=0.0)
sigma_adjustment = gr.Checkbox(label="Sigma adjustment for finding noise for image", value=False)
cfg = gr.Slider(label="Decode CFG scale", minimum=0.0, maximum=15.0, step=0.1, value=1.0, elem_id=self.elem_id("cfg"))
randomness = gr.Slider(label="Randomness", minimum=0.0, maximum=1.0, step=0.01, value=0.0, elem_id=self.elem_id("randomness"))
sigma_adjustment = gr.Checkbox(label="Sigma adjustment for finding noise for image", value=False, elem_id=self.elem_id("sigma_adjustment"))

return [
info,
Expand Down
Loading

0 comments on commit 646a36f

Please sign in to comment.