Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a3ddf464a2 | |||
| 2c11e9009e | |||
| 1f26815dd3 | |||
| 8218f6cd37 | |||
| 23c947ab03 | |||
| 0e47c36a28 | |||
| 4334d25978 | |||
| 05ccb4d0e3 | |||
| d5c850aab5 | |||
| 0a334b447f | |||
| c2b9754857 | |||
| c8b55f29e2 | |||
| 6094310704 | |||
| 0c4ca5f43e | |||
| b010eea520 | |||
| 2b42f73e3d | |||
| 136c8859a4 |
+4
-4
@@ -29,7 +29,8 @@
|
||||
* speedup extra networks listing
|
||||
* added `[none]` filename token.
|
||||
* removed thumbs extra networks view mode (use settings tab to change width/height/scale to get thumbs)
|
||||
* add always_discard_next_to_last_sigma option to XYZ plot
|
||||
* add always_discard_next_to_last_sigma option to XYZ plot
|
||||
* automatically switch to 32-bit float VAE if the generated picture has NaNs without the need for `--no-half-vae` commandline flag.
|
||||
|
||||
### Extensions and API:
|
||||
* api endpoints: /sdapi/v1/server-kill, /sdapi/v1/server-restart, /sdapi/v1/server-stop
|
||||
@@ -58,9 +59,8 @@
|
||||
* fix: check fill size none zero when resize (fixes #11425)
|
||||
* use submit and blur for quick settings textbox
|
||||
* save img2img batch with images.save_image()
|
||||
*
|
||||
|
||||
|
||||
* prevent running preload.py for disabled extensions
|
||||
* fix: previously, model name was added together with directory name to infotext and to [model_name] filename pattern; directory name is now not included
|
||||
|
||||
|
||||
## 1.4.1
|
||||
|
||||
@@ -25,7 +25,7 @@ class ExtraNetworkLora(extra_networks.ExtraNetwork):
|
||||
te_multiplier = float(params.positional[1]) if len(params.positional) > 1 else 1.0
|
||||
te_multiplier = float(params.named.get("te", te_multiplier))
|
||||
|
||||
unet_multiplier = float(params.positional[2]) if len(params.positional) > 2 else 1.0
|
||||
unet_multiplier = float(params.positional[2]) if len(params.positional) > 2 else te_multiplier
|
||||
unet_multiplier = float(params.named.get("unet", unet_multiplier))
|
||||
|
||||
dyn_dim = int(params.positional[3]) if len(params.positional) > 3 else None
|
||||
|
||||
@@ -11,7 +11,7 @@ import network_full
|
||||
import torch
|
||||
from typing import Union
|
||||
|
||||
from modules import shared, devices, sd_models, errors, scripts, sd_hijack, paths
|
||||
from modules import shared, devices, sd_models, errors, scripts, sd_hijack
|
||||
|
||||
module_types = [
|
||||
network_lora.ModuleTypeLora(),
|
||||
@@ -399,7 +399,7 @@ def list_available_networks():
|
||||
os.makedirs(shared.cmd_opts.lora_dir, exist_ok=True)
|
||||
|
||||
candidates = list(shared.walk_files(shared.cmd_opts.lora_dir, allowed_extensions=[".pt", ".ckpt", ".safetensors"]))
|
||||
candidates += list(shared.walk_files(os.path.join(paths.models_path, "LyCORIS"), allowed_extensions=[".pt", ".ckpt", ".safetensors"]))
|
||||
candidates += list(shared.walk_files(shared.cmd_opts.lyco_dir_backcompat, allowed_extensions=[".pt", ".ckpt", ".safetensors"]))
|
||||
for filename in candidates:
|
||||
if os.path.isdir(filename):
|
||||
continue
|
||||
|
||||
@@ -4,3 +4,4 @@ from modules import paths
|
||||
|
||||
def preload(parser):
|
||||
parser.add_argument("--lora-dir", type=str, help="Path to directory with Lora networks.", default=os.path.join(paths.models_path, 'Lora'))
|
||||
parser.add_argument("--lyco-dir-backcompat", type=str, help="Path to directory with LyCORIS networks (for backawards compatibility; can also use --lyco-dir).", default=os.path.join(paths.models_path, 'LyCORIS'))
|
||||
|
||||
@@ -3,7 +3,7 @@ import os
|
||||
import network
|
||||
import networks
|
||||
|
||||
from modules import shared, ui_extra_networks, paths
|
||||
from modules import shared, ui_extra_networks
|
||||
from modules.ui_extra_networks import quote_js
|
||||
from ui_edit_user_metadata import LoraUserMetadataEditor
|
||||
|
||||
@@ -72,7 +72,7 @@ class ExtraNetworksPageLora(ui_extra_networks.ExtraNetworksPage):
|
||||
yield item
|
||||
|
||||
def allowed_directories_for_previews(self):
|
||||
return [shared.cmd_opts.lora_dir, os.path.join(paths.models_path, "LyCORIS")]
|
||||
return [shared.cmd_opts.lora_dir, shared.cmd_opts.lyco_dir_backcompat]
|
||||
|
||||
def create_user_metadata_editor(self, ui, tabname):
|
||||
return LoraUserMetadataEditor(ui, tabname, self)
|
||||
|
||||
@@ -18,6 +18,7 @@ run_pip = launch_utils.run_pip
|
||||
check_run_python = launch_utils.check_run_python
|
||||
git_clone = launch_utils.git_clone
|
||||
git_pull_recursive = launch_utils.git_pull_recursive
|
||||
list_extensions = launch_utils.list_extensions
|
||||
run_extension_installer = launch_utils.run_extension_installer
|
||||
prepare_environment = launch_utils.prepare_environment
|
||||
configure_for_tests = launch_utils.configure_for_tests
|
||||
|
||||
+1
-1
@@ -363,7 +363,7 @@ class FilenameGenerator:
|
||||
'styles': lambda self: self.p and sanitize_filename_part(", ".join([style for style in self.p.styles if not style == "None"]) or "None", replace_spaces=False),
|
||||
'sampler': lambda self: self.p and sanitize_filename_part(self.p.sampler_name, replace_spaces=False),
|
||||
'model_hash': lambda self: getattr(self.p, "sd_model_hash", shared.sd_model.sd_model_hash),
|
||||
'model_name': lambda self: sanitize_filename_part(shared.sd_model.sd_checkpoint_info.model_name, replace_spaces=False),
|
||||
'model_name': lambda self: sanitize_filename_part(shared.sd_model.sd_checkpoint_info.name_for_extra, replace_spaces=False),
|
||||
'date': lambda self: datetime.datetime.now().strftime('%Y-%m-%d'),
|
||||
'datetime': lambda self, *args: self.datetime(*args), # accepts formats: [datetime], [datetime<Format>], [datetime<Format><Time Zone>]
|
||||
'job_timestamp': lambda self: getattr(self.p, "job_timestamp", shared.state.job_timestamp),
|
||||
|
||||
+4
-3
@@ -90,8 +90,12 @@ def setup_for_low_vram(sd_model, use_medvram):
|
||||
sd_model.conditioner.register_forward_pre_hook(send_me_to_gpu)
|
||||
elif is_sd2:
|
||||
sd_model.cond_stage_model.model.register_forward_pre_hook(send_me_to_gpu)
|
||||
sd_model.cond_stage_model.model.token_embedding.register_forward_pre_hook(send_me_to_gpu)
|
||||
parents[sd_model.cond_stage_model.model] = sd_model.cond_stage_model
|
||||
parents[sd_model.cond_stage_model.model.token_embedding] = sd_model.cond_stage_model
|
||||
else:
|
||||
sd_model.cond_stage_model.transformer.register_forward_pre_hook(send_me_to_gpu)
|
||||
parents[sd_model.cond_stage_model.transformer] = sd_model.cond_stage_model
|
||||
|
||||
sd_model.first_stage_model.register_forward_pre_hook(send_me_to_gpu)
|
||||
sd_model.first_stage_model.encode = first_stage_model_encode_wrap
|
||||
@@ -101,9 +105,6 @@ def setup_for_low_vram(sd_model, use_medvram):
|
||||
if sd_model.embedder:
|
||||
sd_model.embedder.register_forward_pre_hook(send_me_to_gpu)
|
||||
|
||||
if hasattr(sd_model, 'cond_stage_model'):
|
||||
parents[sd_model.cond_stage_model.transformer] = sd_model.cond_stage_model
|
||||
|
||||
if use_medvram:
|
||||
sd_model.model.register_forward_pre_hook(send_me_to_gpu)
|
||||
else:
|
||||
|
||||
+38
-7
@@ -14,7 +14,7 @@ from skimage import exposure
|
||||
from typing import Any, Dict, List
|
||||
|
||||
import modules.sd_hijack
|
||||
from modules import devices, prompt_parser, masking, sd_samplers, lowvram, generation_parameters_copypaste, extra_networks, sd_vae_approx, scripts, sd_samplers_common, sd_unet
|
||||
from modules import devices, prompt_parser, masking, sd_samplers, lowvram, generation_parameters_copypaste, extra_networks, sd_vae_approx, scripts, sd_samplers_common, sd_unet, errors
|
||||
from modules.sd_hijack import model_hijack
|
||||
from modules.shared import opts, cmd_opts, state
|
||||
import modules.shared as shared
|
||||
@@ -538,6 +538,40 @@ def create_random_tensors(shape, seeds, subseeds=None, subseed_strength=0.0, see
|
||||
return x
|
||||
|
||||
|
||||
def decode_latent_batch(model, batch, target_device=None, check_for_nans=False):
|
||||
samples = []
|
||||
|
||||
for i in range(batch.shape[0]):
|
||||
sample = decode_first_stage(model, batch[i:i + 1])[0]
|
||||
|
||||
if check_for_nans:
|
||||
try:
|
||||
devices.test_for_nans(sample, "vae")
|
||||
except devices.NansException as e:
|
||||
if devices.dtype_vae == torch.float32 or not shared.opts.auto_vae_precision:
|
||||
raise e
|
||||
|
||||
errors.print_error_explanation(
|
||||
"A tensor with all NaNs was produced in VAE.\n"
|
||||
"Web UI will now convert VAE into 32-bit float and retry.\n"
|
||||
"To disable this behavior, disable the 'Automaticlly revert VAE to 32-bit floats' setting.\n"
|
||||
"To always start with 32-bit VAE, use --no-half-vae commandline flag."
|
||||
)
|
||||
|
||||
devices.dtype_vae = torch.float32
|
||||
model.first_stage_model.to(devices.dtype_vae)
|
||||
batch = batch.to(devices.dtype_vae)
|
||||
|
||||
sample = decode_first_stage(model, batch[i:i + 1])[0]
|
||||
|
||||
if target_device is not None:
|
||||
sample = sample.to(target_device)
|
||||
|
||||
samples.append(sample)
|
||||
|
||||
return samples
|
||||
|
||||
|
||||
def decode_first_stage(model, x):
|
||||
x = model.decode_first_stage(x.to(devices.dtype_vae))
|
||||
|
||||
@@ -587,7 +621,7 @@ def create_infotext(p, all_prompts, all_seeds, all_subseeds, comments=None, iter
|
||||
"Face restoration": (opts.face_restoration_model if p.restore_faces else None),
|
||||
"Size": f"{p.width}x{p.height}",
|
||||
"Model hash": getattr(p, 'sd_model_hash', None if not opts.add_model_hash_to_info or not shared.sd_model.sd_model_hash else shared.sd_model.sd_model_hash),
|
||||
"Model": (None if not opts.add_model_name_to_info or not shared.sd_model.sd_checkpoint_info.model_name else shared.sd_model.sd_checkpoint_info.model_name.replace(',', '').replace(':', '')),
|
||||
"Model": (None if not opts.add_model_name_to_info else shared.sd_model.sd_checkpoint_info.name_for_extra),
|
||||
"Variation seed": (None if p.subseed_strength == 0 else all_subseeds[index]),
|
||||
"Variation seed strength": (None if p.subseed_strength == 0 else p.subseed_strength),
|
||||
"Seed resize from": (None if p.seed_resize_from_w <= 0 or p.seed_resize_from_h <= 0 else f"{p.seed_resize_from_w}x{p.seed_resize_from_h}"),
|
||||
@@ -758,10 +792,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
|
||||
with devices.without_autocast() if devices.unet_needs_upcast else devices.autocast():
|
||||
samples_ddim = p.sample(conditioning=p.c, unconditional_conditioning=p.uc, seeds=p.seeds, subseeds=p.subseeds, subseed_strength=p.subseed_strength, prompts=p.prompts)
|
||||
|
||||
x_samples_ddim = [decode_first_stage(p.sd_model, samples_ddim[i:i+1].to(dtype=devices.dtype_vae))[0].cpu() for i in range(samples_ddim.size(0))]
|
||||
for x in x_samples_ddim:
|
||||
devices.test_for_nans(x, "vae")
|
||||
|
||||
x_samples_ddim = decode_latent_batch(p.sd_model, samples_ddim, target_device=devices.cpu, check_for_nans=True)
|
||||
x_samples_ddim = torch.stack(x_samples_ddim).float()
|
||||
x_samples_ddim = torch.clamp((x_samples_ddim + 1.0) / 2.0, min=0.0, max=1.0)
|
||||
|
||||
@@ -1029,7 +1060,7 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
|
||||
image = sd_samplers.sample_to_image(image, index, approximation=0)
|
||||
|
||||
info = create_infotext(self, self.all_prompts, self.all_seeds, self.all_subseeds, [], iteration=self.iteration, position_in_batch=index)
|
||||
images.save_image(image, self.outpath_samples, "", seeds[index], prompts[index], opts.samples_format, info=info, suffix="-before-highres-fix")
|
||||
images.save_image(image, self.outpath_samples, "", seeds[index], prompts[index], opts.samples_format, info=info, p=self, suffix="-before-highres-fix")
|
||||
|
||||
if latent_scale_mode is not None:
|
||||
for i in range(samples.shape[0]):
|
||||
|
||||
@@ -12,11 +12,12 @@ def load_module(path):
|
||||
return module
|
||||
|
||||
|
||||
def preload_extensions(extensions_dir, parser):
|
||||
def preload_extensions(extensions_dir, parser, extension_list=None):
|
||||
if not os.path.isdir(extensions_dir):
|
||||
return
|
||||
|
||||
for dirname in sorted(os.listdir(extensions_dir)):
|
||||
extensions = extension_list if extension_list is not None else os.listdir(extensions_dir)
|
||||
for dirname in sorted(extensions):
|
||||
preload_script = os.path.join(extensions_dir, dirname, "preload.py")
|
||||
if not os.path.isfile(preload_script):
|
||||
continue
|
||||
|
||||
@@ -32,7 +32,7 @@ class FrozenOpenCLIPEmbedderWithCustomWords(sd_hijack_clip.FrozenCLIPEmbedderWit
|
||||
def encode_embedding_init_text(self, init_text, nvpt):
|
||||
ids = tokenizer.encode(init_text)
|
||||
ids = torch.asarray([ids], device=devices.device, dtype=torch.int)
|
||||
embedded = self.wrapped.model.token_embedding.wrapped(ids.to(self.wrapped.model.token_embedding.wrapped.weight.device)).squeeze(0)
|
||||
embedded = self.wrapped.model.token_embedding.wrapped(ids).squeeze(0)
|
||||
|
||||
return embedded
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@ def get_learned_conditioning(self: sgm.models.diffusion.DiffusionEngine, batch:
|
||||
for embedder in self.conditioner.embedders:
|
||||
embedder.ucg_rate = 0.0
|
||||
|
||||
width = getattr(self, 'target_width', 1024)
|
||||
height = getattr(self, 'target_height', 1024)
|
||||
width = getattr(batch, 'width', 1024)
|
||||
height = getattr(batch, 'height', 1024)
|
||||
is_negative_prompt = getattr(batch, 'is_negative_prompt', False)
|
||||
aesthetic_score = shared.opts.sdxl_refiner_low_aesthetic_score if is_negative_prompt else shared.opts.sdxl_refiner_high_aesthetic_score
|
||||
|
||||
|
||||
+3
-1
@@ -11,6 +11,7 @@ import gradio as gr
|
||||
import torch
|
||||
import tqdm
|
||||
|
||||
import launch
|
||||
import modules.interrogate
|
||||
import modules.memmon
|
||||
import modules.styles
|
||||
@@ -26,7 +27,7 @@ demo = None
|
||||
|
||||
parser = cmd_args.parser
|
||||
|
||||
script_loading.preload_extensions(extensions_dir, parser)
|
||||
script_loading.preload_extensions(extensions_dir, parser, extension_list=launch.list_extensions(launch.args.ui_settings_file))
|
||||
script_loading.preload_extensions(extensions_builtin_dir, parser)
|
||||
|
||||
if os.environ.get('IGNORE_CMD_ARGS_ERRORS', None) is None:
|
||||
@@ -426,6 +427,7 @@ options_templates.update(options_section(('sd', "Stable Diffusion"), {
|
||||
"comma_padding_backtrack": OptionInfo(20, "Prompt word wrap length limit", gr.Slider, {"minimum": 0, "maximum": 74, "step": 1}).info("in tokens - for texts shorter than specified, if they don't fit into 75 token limit, move them to the next 75 token chunk"),
|
||||
"CLIP_stop_at_last_layers": OptionInfo(1, "Clip skip", gr.Slider, {"minimum": 1, "maximum": 12, "step": 1}).link("wiki", "https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Features#clip-skip").info("ignore last layers of CLIP network; 1 ignores none, 2 ignores one layer"),
|
||||
"upcast_attn": OptionInfo(False, "Upcast cross attention layer to float32"),
|
||||
"auto_vae_precision": OptionInfo(True, "Automaticlly revert VAE to 32-bit floats").info("triggers when a tensor with NaNs is produced in VAE; disabling the option in this case will result in a black square image"),
|
||||
"randn_source": OptionInfo("GPU", "Random number generator source.", gr.Radio, {"choices": ["GPU", "CPU"]}).info("changes seeds drastically; use CPU to produce the same picture across different videocard vendors"),
|
||||
}))
|
||||
|
||||
|
||||
@@ -4,8 +4,15 @@
|
||||
# change the variables in webui-user.sh instead #
|
||||
#################################################
|
||||
|
||||
|
||||
use_venv=1
|
||||
if [[ $venv_dir == "-" ]]; then
|
||||
use_venv=0
|
||||
fi
|
||||
|
||||
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||
|
||||
|
||||
# If run from macOS, load defaults from webui-macos-env.sh
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
if [[ -f "$SCRIPT_DIR"/webui-macos-env.sh ]]
|
||||
@@ -47,7 +54,7 @@ then
|
||||
fi
|
||||
|
||||
# python3 venv without trailing slash (defaults to ${install_dir}/${clone_dir}/venv)
|
||||
if [[ -z "${venv_dir}" ]]
|
||||
if [[ -z "${venv_dir}" ]] && [[ $use_venv -eq 1 ]]
|
||||
then
|
||||
venv_dir="venv"
|
||||
fi
|
||||
@@ -164,7 +171,7 @@ do
|
||||
fi
|
||||
done
|
||||
|
||||
if ! "${python_cmd}" -c "import venv" &>/dev/null
|
||||
if [[ $use_venv -eq 1 ]] && ! "${python_cmd}" -c "import venv" &>/dev/null
|
||||
then
|
||||
printf "\n%s\n" "${delimiter}"
|
||||
printf "\e[1m\e[31mERROR: python3-venv is not installed, aborting...\e[0m"
|
||||
@@ -184,7 +191,7 @@ else
|
||||
cd "${clone_dir}"/ || { printf "\e[1m\e[31mERROR: Can't cd to %s/%s/, aborting...\e[0m" "${install_dir}" "${clone_dir}"; exit 1; }
|
||||
fi
|
||||
|
||||
if [[ -z "${VIRTUAL_ENV}" ]];
|
||||
if [[ $use_venv -eq 1 ]] && [[ -z "${VIRTUAL_ENV}" ]];
|
||||
then
|
||||
printf "\n%s\n" "${delimiter}"
|
||||
printf "Create and activate python venv"
|
||||
@@ -207,7 +214,7 @@ then
|
||||
fi
|
||||
else
|
||||
printf "\n%s\n" "${delimiter}"
|
||||
printf "python venv already activate: ${VIRTUAL_ENV}"
|
||||
printf "python venv already activate or run without venv: ${VIRTUAL_ENV}"
|
||||
printf "\n%s\n" "${delimiter}"
|
||||
fi
|
||||
|
||||
|
||||
Reference in New Issue
Block a user