Compare commits

...

13 Commits

Author SHA1 Message Date
AUTOMATIC1111 99ef3b6c52 update readme 2023-07-25 16:31:01 +03:00
AUTOMATIC1111 65b6f8d3d5 fix for #11963 2023-07-25 16:20:55 +03:00
AUTOMATIC1111 b57a816038 Merge pull request #11963 from catboxanon/fix/lora-te
Fix parsing text encoder blocks in some LoRAs
2023-07-25 16:20:52 +03:00
AUTOMATIC1111 11f996a096 Merge pull request #11979 from AUTOMATIC1111/catch-exception-for-non-git-extensions
catch exception for non git extensions
2023-07-25 16:20:49 +03:00
AUTOMATIC1111 ce0aab3643 Merge pull request #11984 from AUTOMATIC1111/api-only-subpath-(root_path)
api only subpath (rootpath)
2023-07-25 16:20:46 +03:00
AUTOMATIC1111 c251e8db8d Merge pull request #11957 from ljleb/pp-batch-list
Add postprocess_batch_list script callback
2023-07-25 16:20:33 +03:00
AUTOMATIC1111 284822323a restyle Startup profile for black users 2023-07-25 16:20:16 +03:00
AUTOMATIC1111 1f59be5188 Merge pull request #11926 from wfjsw/fix-env-get-1
fix 11291#issuecomment-1646547908
2023-07-25 16:20:07 +03:00
AUTOMATIC1111 cad87bf4e3 Merge pull request #11927 from ljleb/fix-AND
Fix composable diffusion weight parsing
2023-07-25 16:20:01 +03:00
AUTOMATIC1111 704628b903 Merge pull request #11923 from AnyISalIn/dev
[bug] If txt2img/img2img raises an exception, finally call state.end()
2023-07-25 16:19:36 +03:00
AUTOMATIC1111 636ff513b0 Merge pull request #11920 from wfjsw/typo-fix-1
typo fix
2023-07-25 16:19:22 +03:00
AUTOMATIC1111 51206edb62 Merge pull request #11921 from wfjsw/prepend-pythonpath
prepend the pythonpath instead of overriding it
2023-07-25 16:19:08 +03:00
AUTOMATIC1111 c5934fb6e3 Merge pull request #11878 from Bourne-M/patch-1
【bug】reload altclip model error
2023-07-25 16:18:55 +03:00
11 changed files with 121 additions and 34 deletions
+19
View File
@@ -1,3 +1,22 @@
## 1.5.1
### Minor:
* support parsing text encoder blocks in some new LoRAs
### Extensions and API:
* add postprocess_batch_list script callback
### Bug Fixes:
* fix reload altclip model error
* prepend the pythonpath instead of overriding it
* fix typo in SD_WEBUI_RESTARTING
* if txt2img/img2img raises an exception, finally call state.end()
* fix composable diffusion weight parsing
* restyle Startup profile for black users
* fix webui not launching with --nowebui
* catch exception for non git extensions
## 1.5.0
### Features:
+5
View File
@@ -163,6 +163,11 @@ def load_network(name, network_on_disk):
key = key_network_without_network_parts.replace("lora_te1_text_model", "0_transformer_text_model")
sd_module = shared.sd_model.network_layer_mapping.get(key, None)
# some SD1 Loras also have correct compvis keys
if sd_module is None:
key = key_network_without_network_parts.replace("lora_te1_text_model", "transformer_text_model")
sd_module = shared.sd_model.network_layer_mapping.get(key, None)
if sd_module is None:
keys_failed_to_match[key_network] = key
continue
+22 -18
View File
@@ -333,14 +333,16 @@ class Api:
p.outpath_grids = opts.outdir_txt2img_grids
p.outpath_samples = opts.outdir_txt2img_samples
shared.state.begin(job="scripts_txt2img")
if selectable_scripts is not None:
p.script_args = script_args
processed = scripts.scripts_txt2img.run(p, *p.script_args) # Need to pass args as list here
else:
p.script_args = tuple(script_args) # Need to pass args as tuple here
processed = process_images(p)
shared.state.end()
try:
shared.state.begin(job="scripts_txt2img")
if selectable_scripts is not None:
p.script_args = script_args
processed = scripts.scripts_txt2img.run(p, *p.script_args) # Need to pass args as list here
else:
p.script_args = tuple(script_args) # Need to pass args as tuple here
processed = process_images(p)
finally:
shared.state.end()
b64images = list(map(encode_pil_to_base64, processed.images)) if send_images else []
@@ -390,14 +392,16 @@ class Api:
p.outpath_grids = opts.outdir_img2img_grids
p.outpath_samples = opts.outdir_img2img_samples
shared.state.begin(job="scripts_img2img")
if selectable_scripts is not None:
p.script_args = script_args
processed = scripts.scripts_img2img.run(p, *p.script_args) # Need to pass args as list here
else:
p.script_args = tuple(script_args) # Need to pass args as tuple here
processed = process_images(p)
shared.state.end()
try:
shared.state.begin(job="scripts_img2img")
if selectable_scripts is not None:
p.script_args = script_args
processed = scripts.scripts_img2img.run(p, *p.script_args) # Need to pass args as list here
else:
p.script_args = tuple(script_args) # Need to pass args as tuple here
processed = process_images(p)
finally:
shared.state.end()
b64images = list(map(encode_pil_to_base64, processed.images)) if send_images else []
@@ -720,9 +724,9 @@ class Api:
cuda = {'error': f'{err}'}
return models.MemoryResponse(ram=ram, cuda=cuda)
def launch(self, server_name, port):
def launch(self, server_name, port, root_path):
self.app.include_router(self.router)
uvicorn.run(self.app, host=server_name, port=port, timeout_keep_alive=shared.cmd_opts.timeout_keep_alive)
uvicorn.run(self.app, host=server_name, port=port, timeout_keep_alive=shared.cmd_opts.timeout_keep_alive, root_path=root_path)
def kill_webui(self):
restart.stop_program()
+5 -3
View File
@@ -56,9 +56,11 @@ class Extension:
self.do_read_info_from_repo()
return self.to_dict()
d = cache.cached_data_for_file('extensions-git', self.name, os.path.join(self.path, ".git"), read_from_repo)
self.from_dict(d)
try:
d = cache.cached_data_for_file('extensions-git', self.name, os.path.join(self.path, ".git"), read_from_repo)
self.from_dict(d)
except FileNotFoundError:
pass
self.status = 'unknown'
def do_read_info_from_repo(self):
+4 -4
View File
@@ -196,7 +196,7 @@ def run_extension_installer(extension_dir):
try:
env = os.environ.copy()
env['PYTHONPATH'] = os.path.abspath(".")
env['PYTHONPATH'] = f"{os.path.abspath('.')}{os.pathsep}{env.get('PYTHONPATH', '')}"
print(run(f'"{python}" "{path_installer}"', errdesc=f"Error running install.py for extension {extension_dir}", custom_env=env))
except Exception as e:
@@ -233,7 +233,7 @@ def run_extensions_installers(settings_file):
re_requirement = re.compile(r"\s*([-_a-zA-Z0-9]+)\s*(?:==\s*([-+_.a-zA-Z0-9]+))?\s*")
def requrements_met(requirements_file):
def requirements_met(requirements_file):
"""
Does a simple parse of a requirements.txt file to determine if all rerqirements in it
are already installed. Returns True if so, False if not installed or parsing fails.
@@ -293,7 +293,7 @@ def prepare_environment():
try:
# the existance of this file is a signal to webui.sh/bat that webui needs to be restarted when it stops execution
os.remove(os.path.join(script_path, "tmp", "restart"))
os.environ.setdefault('SD_WEBUI_RESTARTING ', '1')
os.environ.setdefault('SD_WEBUI_RESTARTING', '1')
except OSError:
pass
@@ -354,7 +354,7 @@ def prepare_environment():
if not os.path.isfile(requirements_file):
requirements_file = os.path.join(script_path, requirements_file)
if not requrements_met(requirements_file):
if not requirements_met(requirements_file):
run_pip(f"install -r \"{requirements_file}\"", "requirements")
run_extensions_installers(settings_file=args.ui_settings_file)
+25 -1
View File
@@ -717,7 +717,27 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
p.all_subseeds = [int(subseed) + x for x in range(len(p.all_prompts))]
def infotext(iteration=0, position_in_batch=0, use_main_prompt=False):
return create_infotext(p, p.all_prompts, p.all_seeds, p.all_subseeds, comments, iteration, position_in_batch, use_main_prompt)
all_prompts = p.all_prompts[:]
all_negative_prompts = p.all_negative_prompts[:]
all_seeds = p.all_seeds[:]
all_subseeds = p.all_subseeds[:]
# apply changes to generation data
all_prompts[iteration * p.batch_size:(iteration + 1) * p.batch_size] = p.prompts
all_negative_prompts[iteration * p.batch_size:(iteration + 1) * p.batch_size] = p.negative_prompts
all_seeds[iteration * p.batch_size:(iteration + 1) * p.batch_size] = p.seeds
all_subseeds[iteration * p.batch_size:(iteration + 1) * p.batch_size] = p.subseeds
# update p.all_negative_prompts in case extensions changed the size of the batch
# create_infotext below uses it
old_negative_prompts = p.all_negative_prompts
p.all_negative_prompts = all_negative_prompts
try:
return create_infotext(p, all_prompts, all_seeds, all_subseeds, comments, iteration, position_in_batch, use_main_prompt)
finally:
# restore p.all_negative_prompts in case extensions changed the size of the batch
p.all_negative_prompts = old_negative_prompts
if os.path.exists(cmd_opts.embeddings_dir) and not p.do_not_reload_embeddings:
model_hijack.embedding_db.load_textual_inversion_embeddings()
@@ -806,6 +826,10 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
if p.scripts is not None:
p.scripts.postprocess_batch(p, x_samples_ddim, batch_number=n)
postprocess_batch_list_args = scripts.PostprocessBatchListArgs(list(x_samples_ddim))
p.scripts.postprocess_batch_list(p, postprocess_batch_list_args, batch_number=n)
x_samples_ddim = postprocess_batch_list_args.images
for i, x_sample in enumerate(x_samples_ddim):
p.batch_index = i
+1 -1
View File
@@ -178,7 +178,7 @@ def get_learned_conditioning(model, prompts: SdConditioning | list[str], steps):
re_AND = re.compile(r"\bAND\b")
re_weight = re.compile(r"^(.*?)(?:\s*:\s*([-+]?(?:\d+\.?|\d*\.\d+)))?\s*$")
re_weight = re.compile(r"^((?:\s|.)*?)(?:\s*:\s*([-+]?(?:\d+\.?|\d*\.\d+)))?\s*$")
def get_multicond_prompt_list(prompts: SdConditioning | list[str]):
+33 -1
View File
@@ -16,6 +16,11 @@ class PostprocessImageArgs:
self.image = image
class PostprocessBatchListArgs:
def __init__(self, images):
self.images = images
class Script:
name = None
"""script's internal name derived from title"""
@@ -119,7 +124,7 @@ class Script:
def after_extra_networks_activate(self, p, *args, **kwargs):
"""
Calledafter extra networks activation, before conds calculation
Called after extra networks activation, before conds calculation
allow modification of the network after extra networks activation been applied
won't be call if p.disable_extra_networks
@@ -156,6 +161,25 @@ class Script:
pass
def postprocess_batch_list(self, p, pp: PostprocessBatchListArgs, *args, **kwargs):
"""
Same as postprocess_batch(), but receives batch images as a list of 3D tensors instead of a 4D tensor.
This is useful when you want to update the entire batch instead of individual images.
You can modify the postprocessing object (pp) to update the images in the batch, remove images, add images, etc.
If the number of images is different from the batch size when returning,
then the script has the responsibility to also update the following attributes in the processing object (p):
- p.prompts
- p.negative_prompts
- p.seeds
- p.subseeds
**kwargs will have same items as process_batch, and also:
- batch_number - index of current batch, from 0 to number of batches-1
"""
pass
def postprocess_image(self, p, pp: PostprocessImageArgs, *args):
"""
Called for every image after it has been generated.
@@ -536,6 +560,14 @@ class ScriptRunner:
except Exception:
errors.report(f"Error running postprocess_batch: {script.filename}", exc_info=True)
def postprocess_batch_list(self, p, pp: PostprocessBatchListArgs, **kwargs):
for script in self.alwayson_scripts:
try:
script_args = p.script_args[script.args_from:script.args_to]
script.postprocess_batch_list(p, pp, *script_args, **kwargs)
except Exception:
errors.report(f"Error running postprocess_batch_list: {script.filename}", exc_info=True)
def postprocess_image(self, p, pp: PostprocessImageArgs):
for script in self.alwayson_scripts:
try:
+1 -1
View File
@@ -243,7 +243,7 @@ class StableDiffusionModelHijack:
ldm.modules.diffusionmodules.openaimodel.UNetModel.forward = sd_unet.UNetModel_forward
def undo_hijack(self, m):
if type(m.cond_stage_model) == xlmr.BertSeriesModelWithTransformation:
if type(m.cond_stage_model) == sd_hijack_xlmr.FrozenXLMREmbedderWithCustomWords:
m.cond_stage_model = m.cond_stage_model.wrapped
elif type(m.cond_stage_model) == sd_hijack_clip.FrozenCLIPEmbedderWithCustomWords:
+4 -3
View File
@@ -423,15 +423,16 @@ div#extras_scale_to_tab div.form{
}
table.popup-table{
background: white;
background: var(--body-background-fill);
color: var(--body-text-color);
border-collapse: collapse;
margin: 1em;
border: 4px solid white;
border: 4px solid var(--body-background-fill);
}
table.popup-table td{
padding: 0.4em;
border: 1px solid #ccc;
border: 1px solid rgba(128, 128, 128, 0.5);
max-width: 36em;
}
+2 -2
View File
@@ -374,7 +374,7 @@ def api_only():
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,
root_path = f"/{cmd_opts.subpath}"
root_path=f"/{cmd_opts.subpath}" if cmd_opts.subpath else ""
)
@@ -407,7 +407,7 @@ def webui():
ssl_verify=cmd_opts.disable_tls_verify,
debug=cmd_opts.gradio_debug,
auth=gradio_auth_creds,
inbrowser=cmd_opts.autolaunch and os.getenv('SD_WEBUI_RESTARTING ') != '1',
inbrowser=cmd_opts.autolaunch and os.getenv('SD_WEBUI_RESTARTING') != '1',
prevent_thread_lock=True,
allowed_paths=cmd_opts.gradio_allowed_path,
app_kwargs={