Skip to content

Commit

Permalink
Merge branch 'AUTOMATIC1111:master' into hide_ui_tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
vladmandic authored Feb 19, 2023
2 parents a320d15 + 076d624 commit 8affa42
Show file tree
Hide file tree
Showing 28 changed files with 306 additions and 82 deletions.
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,7 @@ Alternatively, use online services (like Google Colab):
1. Install [Python 3.10.6](https://www.python.org/downloads/windows/), checking "Add Python to PATH"
2. Install [git](https://git-scm.com/download/win).
3. Download the stable-diffusion-webui repository, for example by running `git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git`.
4. Place stable diffusion checkpoint (`model.ckpt`) in the `models/Stable-diffusion` directory (see [dependencies](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Dependencies) for where to get it).
5. Run `webui-user.bat` from Windows Explorer as normal, non-administrator, user.
4. Run `webui-user.bat` from Windows Explorer as normal, non-administrator, user.

### Automatic Installation on Linux
1. Install the dependencies:
Expand All @@ -121,7 +120,7 @@ sudo pacman -S wget git python3
```bash
bash <(wget -qO- https://raw.githubusercontent.com/AUTOMATIC1111/stable-diffusion-webui/master/webui.sh)
```

3. Run `webui.sh`.
### Installation on Apple Silicon

Find the instructions [here](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Installation-on-Apple-Silicon).
Expand Down
4 changes: 2 additions & 2 deletions javascript/hints.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ titles = {
"DDIM": "Denoising Diffusion Implicit Models - best at inpainting",
"DPM adaptive": "Ignores step count - uses a number of steps determined by the CFG and resolution",

"Batch count": "How many batches of images to create",
"Batch size": "How many image to create in a single batch",
"Batch count": "How many batches of images to create (has no impact on generation performance or VRAM usage)",
"Batch size": "How many image to create in a single batch (increases generation performance at cost of higher VRAM usage)",
"CFG Scale": "Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results",
"Seed": "A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result",
"\u{1f3b2}\ufe0f": "Set seed to -1, which will cause a new random number to be used every time",
Expand Down
2 changes: 1 addition & 1 deletion launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ def prepare_environment():

sys.argv += shlex.split(commandline_args)

parser = argparse.ArgumentParser()
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument("--ui-settings-file", type=str, help="filename to use for ui settings", default='config.json')
args, _ = parser.parse_known_args(sys.argv)

Expand Down
2 changes: 1 addition & 1 deletion modules/api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ def train_hypernetwork(self, args: dict):
if not apply_optimizations:
sd_hijack.undo_optimizations()
try:
hypernetwork, filename = train_hypernetwork(*args)
hypernetwork, filename = train_hypernetwork(**args)
except Exception as e:
error = e
finally:
Expand Down
1 change: 1 addition & 0 deletions modules/esrgan_model_arch.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# this file is adapted from https://github.com/victorca25/iNNfer

from collections import OrderedDict
import math
import functools
import torch
Expand Down
6 changes: 6 additions & 0 deletions modules/extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import sys
import traceback

import time
import git

from modules import paths, shared
Expand All @@ -25,6 +26,7 @@ def __init__(self, name, path, enabled=True, is_builtin=False):
self.status = ''
self.can_update = False
self.is_builtin = is_builtin
self.version = ''

repo = None
try:
Expand All @@ -40,6 +42,10 @@ def __init__(self, name, path, enabled=True, is_builtin=False):
try:
self.remote = next(repo.remote().urls, None)
self.status = 'unknown'
head = repo.head.commit
ts = time.asctime(time.gmtime(repo.head.commit.committed_date))
self.version = f'{head.hexsha[:8]} ({ts})'

except Exception:
self.remote = None

Expand Down
7 changes: 4 additions & 3 deletions modules/generation_parameters_copypaste.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ def image_from_url_text(filedata):
return image


def add_paste_fields(tabname, init_img, fields):
paste_fields[tabname] = {"init_img": init_img, "fields": fields}
def add_paste_fields(tabname, init_img, fields, override_settings_component=None):
paste_fields[tabname] = {"init_img": init_img, "fields": fields, "override_settings_component": override_settings_component}

# backwards compatibility for existing extensions
import modules.ui
Expand Down Expand Up @@ -110,6 +110,7 @@ def connect_paste_params_buttons():
for binding in registered_param_bindings:
destination_image_component = paste_fields[binding.tabname]["init_img"]
fields = paste_fields[binding.tabname]["fields"]
override_settings_component = binding.override_settings_component or paste_fields[binding.tabname]["override_settings_component"]

destination_width_component = next(iter([field for field, name in fields if name == "Size-1"] if fields else []), None)
destination_height_component = next(iter([field for field, name in fields if name == "Size-2"] if fields else []), None)
Expand All @@ -130,7 +131,7 @@ def connect_paste_params_buttons():
)

if binding.source_text_component is not None and fields is not None:
connect_paste(binding.paste_button, fields, binding.source_text_component, binding.override_settings_component, binding.tabname)
connect_paste(binding.paste_button, fields, binding.source_text_component, override_settings_component, binding.tabname)

if binding.source_tabname is not None and fields is not None:
paste_field_names = ['Prompt', 'Negative prompt', 'Steps', 'Face restoration'] + (["Seed"] if shared.opts.send_seed else [])
Expand Down
16 changes: 11 additions & 5 deletions modules/hypernetworks/hypernetwork.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,8 +380,8 @@ def apply_single_hypernetwork(hypernetwork, context_k, context_v, layer=None):
layer.hyper_k = hypernetwork_layers[0]
layer.hyper_v = hypernetwork_layers[1]

context_k = hypernetwork_layers[0](context_k)
context_v = hypernetwork_layers[1](context_v)
context_k = devices.cond_cast_unet(hypernetwork_layers[0](devices.cond_cast_float(context_k)))
context_v = devices.cond_cast_unet(hypernetwork_layers[1](devices.cond_cast_float(context_v)))
return context_k, context_v


Expand Down Expand Up @@ -496,7 +496,7 @@ def create_hypernetwork(name, enable_sizes, overwrite_old, layer_structure=None,
shared.reload_hypernetworks()


def train_hypernetwork(id_task, hypernetwork_name, learn_rate, batch_size, gradient_step, data_root, log_directory, training_width, training_height, varsize, steps, clip_grad_mode, clip_grad_value, shuffle_tags, tag_drop_out, latent_sampling_method, create_image_every, save_hypernetwork_every, template_filename, preview_from_txt2img, preview_prompt, preview_negative_prompt, preview_steps, preview_sampler_index, preview_cfg_scale, preview_seed, preview_width, preview_height):
def train_hypernetwork(id_task, hypernetwork_name, learn_rate, batch_size, gradient_step, data_root, log_directory, training_width, training_height, varsize, steps, clip_grad_mode, clip_grad_value, shuffle_tags, tag_drop_out, latent_sampling_method, use_weight, create_image_every, save_hypernetwork_every, template_filename, preview_from_txt2img, preview_prompt, preview_negative_prompt, preview_steps, preview_sampler_index, preview_cfg_scale, preview_seed, preview_width, preview_height):
# images allows training previews to have infotext. Importing it at the top causes a circular import problem.
from modules import images

Expand Down Expand Up @@ -554,7 +554,7 @@ def train_hypernetwork(id_task, hypernetwork_name, learn_rate, batch_size, gradi

pin_memory = shared.opts.pin_memory

ds = modules.textual_inversion.dataset.PersonalizedBase(data_root=data_root, width=training_width, height=training_height, repeats=shared.opts.training_image_repeats_per_epoch, placeholder_token=hypernetwork_name, model=shared.sd_model, cond_model=shared.sd_model.cond_stage_model, device=devices.device, template_file=template_file, include_cond=True, batch_size=batch_size, gradient_step=gradient_step, shuffle_tags=shuffle_tags, tag_drop_out=tag_drop_out, latent_sampling_method=latent_sampling_method, varsize=varsize)
ds = modules.textual_inversion.dataset.PersonalizedBase(data_root=data_root, width=training_width, height=training_height, repeats=shared.opts.training_image_repeats_per_epoch, placeholder_token=hypernetwork_name, model=shared.sd_model, cond_model=shared.sd_model.cond_stage_model, device=devices.device, template_file=template_file, include_cond=True, batch_size=batch_size, gradient_step=gradient_step, shuffle_tags=shuffle_tags, tag_drop_out=tag_drop_out, latent_sampling_method=latent_sampling_method, varsize=varsize, use_weight=use_weight)

if shared.opts.save_training_settings_to_txt:
saved_params = dict(
Expand Down Expand Up @@ -640,13 +640,19 @@ def train_hypernetwork(id_task, hypernetwork_name, learn_rate, batch_size, gradi

with devices.autocast():
x = batch.latent_sample.to(devices.device, non_blocking=pin_memory)
if use_weight:
w = batch.weight.to(devices.device, non_blocking=pin_memory)
if tag_drop_out != 0 or shuffle_tags:
shared.sd_model.cond_stage_model.to(devices.device)
c = shared.sd_model.cond_stage_model(batch.cond_text).to(devices.device, non_blocking=pin_memory)
shared.sd_model.cond_stage_model.to(devices.cpu)
else:
c = stack_conds(batch.cond).to(devices.device, non_blocking=pin_memory)
loss = shared.sd_model(x, c)[0] / gradient_step
if use_weight:
loss = shared.sd_model.weighted_forward(x, c, w)[0] / gradient_step
del w
else:
loss = shared.sd_model.forward(x, c)[0] / gradient_step
del x
del c

Expand Down
18 changes: 11 additions & 7 deletions modules/images.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import json
import hashlib

from modules import sd_samplers, shared, script_callbacks
from modules import sd_samplers, shared, script_callbacks, errors
from modules.shared import opts, cmd_opts

LANCZOS = (Image.Resampling.LANCZOS if hasattr(Image, 'Resampling') else Image.LANCZOS)
Expand Down Expand Up @@ -553,6 +553,8 @@ def _atomically_save_image(image_to_save, filename_without_extension, extension)
elif extension.lower() in (".jpg", ".jpeg", ".webp"):
if image_to_save.mode == 'RGBA':
image_to_save = image_to_save.convert("RGB")
elif image_to_save.mode == 'I;16':
image_to_save = image_to_save.point(lambda p: p * 0.0038910505836576).convert("RGB" if extension.lower() == ".webp" else "L")

image_to_save.save(temp_file_path, format=image_format, quality=opts.jpeg_quality)

Expand All @@ -575,17 +577,19 @@ def _atomically_save_image(image_to_save, filename_without_extension, extension)

image.already_saved_as = fullfn

target_side_length = 4000
oversize = image.width > target_side_length or image.height > target_side_length
if opts.export_for_4chan and (oversize or os.stat(fullfn).st_size > 4 * 1024 * 1024):
oversize = image.width > opts.target_side_length or image.height > opts.target_side_length
if opts.export_for_4chan and (oversize or os.stat(fullfn).st_size > opts.img_downscale_threshold * 1024 * 1024):
ratio = image.width / image.height

if oversize and ratio > 1:
image = image.resize((target_side_length, image.height * target_side_length // image.width), LANCZOS)
image = image.resize((opts.target_side_length, image.height * opts.target_side_length // image.width), LANCZOS)
elif oversize:
image = image.resize((image.width * target_side_length // image.height, target_side_length), LANCZOS)
image = image.resize((image.width * opts.target_side_length // image.height, opts.target_side_length), LANCZOS)

_atomically_save_image(image, fullfn_without_extension, ".jpg")
try:
_atomically_save_image(image, fullfn_without_extension, ".jpg")
except Exception as e:
errors.display(e, "saving image as downscaled JPG")

if opts.save_txt and info is not None:
txt_fullfn = f"{fullfn_without_extension}.txt"
Expand Down
2 changes: 2 additions & 0 deletions modules/img2img.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args):

if not save_normally:
os.makedirs(output_dir, exist_ok=True)
if processed_image.mode == 'RGBA':
processed_image = processed_image.convert("RGB")
processed_image.save(os.path.join(output_dir, filename))


Expand Down
24 changes: 14 additions & 10 deletions modules/processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -543,8 +543,6 @@ def infotext(iteration=0, position_in_batch=0):
if os.path.exists(cmd_opts.embeddings_dir) and not p.do_not_reload_embeddings:
model_hijack.embedding_db.load_textual_inversion_embeddings()

_, extra_network_data = extra_networks.parse_prompts(p.all_prompts[0:1])

if p.scripts is not None:
p.scripts.process(p)

Expand Down Expand Up @@ -582,13 +580,6 @@ def get_conds_with_caching(function, required_prompts, steps, cache):
if shared.opts.live_previews_enable and opts.show_progress_type == "Approx NN":
sd_vae_approx.model()

if not p.disable_extra_networks:
extra_networks.activate(p, extra_network_data)

with open(os.path.join(paths.data_path, "params.txt"), "w", encoding="utf8") as file:
processed = Processed(p, [], p.seed, "")
file.write(processed.infotext(p, 0))

if state.job_count == -1:
state.job_count = p.n_iter

Expand All @@ -609,11 +600,24 @@ def get_conds_with_caching(function, required_prompts, steps, cache):
if len(prompts) == 0:
break

prompts, _ = extra_networks.parse_prompts(prompts)
prompts, extra_network_data = extra_networks.parse_prompts(prompts)

if not p.disable_extra_networks:
with devices.autocast():
extra_networks.activate(p, extra_network_data)

if p.scripts is not None:
p.scripts.process_batch(p, batch_number=n, prompts=prompts, seeds=seeds, subseeds=subseeds)

# params.txt should be saved after scripts.process_batch, since the
# infotext could be modified by that callback
# Example: a wildcard processed by process_batch sets an extra model
# strength, which is saved as "Model Strength: 1.0" in the infotext
if n == 0:
with open(os.path.join(paths.data_path, "params.txt"), "w", encoding="utf8") as file:
processed = Processed(p, [], p.seed, "")
file.write(processed.infotext(p, 0))

uc = get_conds_with_caching(prompt_parser.get_learned_conditioning, negative_prompts, p.steps, cached_uc)
c = get_conds_with_caching(prompt_parser.get_multicond_learned_conditioning, prompts, p.steps, cached_c)

Expand Down
29 changes: 29 additions & 0 deletions modules/script_callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ def __init__(self, x, image_cond, sigma, sampling_step, total_sampling_steps):
"""Total number of sampling steps planned"""


class CFGDenoisedParams:
def __init__(self, x, sampling_step, total_sampling_steps):
self.x = x
"""Latent image representation in the process of being denoised"""

self.sampling_step = sampling_step
"""Current Sampling step number"""

self.total_sampling_steps = total_sampling_steps
"""Total number of sampling steps planned"""


class UiTrainTabParams:
def __init__(self, txt2img_preview_params):
self.txt2img_preview_params = txt2img_preview_params
Expand All @@ -68,6 +80,7 @@ def __init__(self, imgs, cols, rows):
callbacks_before_image_saved=[],
callbacks_image_saved=[],
callbacks_cfg_denoiser=[],
callbacks_cfg_denoised=[],
callbacks_before_component=[],
callbacks_after_component=[],
callbacks_image_grid=[],
Expand Down Expand Up @@ -150,6 +163,14 @@ def cfg_denoiser_callback(params: CFGDenoiserParams):
report_exception(c, 'cfg_denoiser_callback')


def cfg_denoised_callback(params: CFGDenoisedParams):
for c in callback_map['callbacks_cfg_denoised']:
try:
c.callback(params)
except Exception:
report_exception(c, 'cfg_denoised_callback')


def before_component_callback(component, **kwargs):
for c in callback_map['callbacks_before_component']:
try:
Expand Down Expand Up @@ -283,6 +304,14 @@ def on_cfg_denoiser(callback):
add_callback(callback_map['callbacks_cfg_denoiser'], callback)


def on_cfg_denoised(callback):
"""register a function to be called in the kdiffussion cfg_denoiser method after building the inner model inputs.
The callback is called with one argument:
- params: CFGDenoisedParams - parameters to be passed to the inner model and sampling state details.
"""
add_callback(callback_map['callbacks_cfg_denoised'], callback)


def on_before_component(callback):
"""register a function to be called before a component is created.
The callback is called with arguments:
Expand Down
Loading

0 comments on commit 8affa42

Please sign in to comment.