mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 01:04:32 +02:00
jumbo merge
This commit is contained in:
@@ -4,6 +4,15 @@
|
||||
|
||||
- new cache for models/lora/lyco metadata: `metadata.json`
|
||||
drastically reduces disk access on app startup
|
||||
- allow saving of **ui default values**
|
||||
settings -> ui defaults
|
||||
- ability to run server without loaded model
|
||||
default is to auto-load model on startup, can be changed in settings -> stable diffusion
|
||||
if disabled, model will be loaded on first request, e.g. when you click generate
|
||||
- updated `accelerate` and `xformers`
|
||||
- huge nubmer of changes ported from a1111 upstream
|
||||
hopefully this does not cause any regressions
|
||||
|
||||
|
||||
## Update for 06/12/2023
|
||||
|
||||
|
||||
@@ -23,11 +23,7 @@ Stuff to be investigated...
|
||||
|
||||
Pick & merge PRs from main repo...
|
||||
|
||||
- <https://github.com/AUTOMATIC1111/stable-diffusion-webui/compare/89f9faa...baf6946>
|
||||
- TODO:
|
||||
- ruff stuff from 05/10/2023
|
||||
- modules/sub_quadratic_attention.py
|
||||
- <https://github.com/AUTOMATIC1111/stable-diffusion-webui/commit/1332c46b71b169b889d7df420f3285d9022da5cc>
|
||||
- TODO: <https://github.com/AUTOMATIC1111/stable-diffusion-webui/compare/89f9faa...baf6946>
|
||||
- STATUS: up-to-date 05/13/2023
|
||||
|
||||
## Integration
|
||||
|
||||
+2
-2
@@ -278,7 +278,7 @@ def args(): # parse cmd arguments
|
||||
data = json.load(f)
|
||||
random = Map(data)
|
||||
log.debug({ 'random template': sd })
|
||||
except:
|
||||
except Exception:
|
||||
log.error({ 'random template error': params.random})
|
||||
exit()
|
||||
elif os.path.isfile(os.path.join(home, params.random)):
|
||||
@@ -287,7 +287,7 @@ def args(): # parse cmd arguments
|
||||
data = json.load(f)
|
||||
random = Map(data)
|
||||
log.debug({ 'random template': sd })
|
||||
except:
|
||||
except Exception:
|
||||
log.error({ 'random template error': params.random})
|
||||
exit()
|
||||
else:
|
||||
|
||||
+2
-2
@@ -31,7 +31,7 @@ class Exif: # pylint: disable=single-string-used-for-slots
|
||||
exif_dict = {}
|
||||
try:
|
||||
exif_dict = dict(img._getexif().items()) # pylint: disable=protected-access
|
||||
except:
|
||||
except Exception:
|
||||
exif_dict = dict(img.info.items())
|
||||
for key, val in exif_dict.items():
|
||||
if isinstance(val, bytes): # decode bytestring
|
||||
@@ -65,7 +65,7 @@ class Exif: # pylint: disable=single-string-used-for-slots
|
||||
if len(val) == 0: # remove empty strings
|
||||
val = None
|
||||
return val
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
@@ -26,13 +26,13 @@ def get_exif(image):
|
||||
for k, v in exif.items():
|
||||
key = list(vars(piexif.ExifIFD).keys())[list(vars(piexif.ExifIFD).values()).index(k)]
|
||||
res1[key] = piexif.helper.UserComment.load(v)
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
# using pillow
|
||||
res2 = {}
|
||||
try:
|
||||
res2 = { TAGS[k]: v for k, v in image.getexif().items() if k in TAGS }
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
return {**res1, **res2}
|
||||
|
||||
@@ -54,7 +54,7 @@ def get_watermark(image, params):
|
||||
decoded = decoder.decode(data, options.method)
|
||||
try:
|
||||
s = str(decoded, 'UTF-8').replace('\x00', '')
|
||||
except:
|
||||
except Exception:
|
||||
s = ''
|
||||
return s
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ async def txt2img():
|
||||
data = {}
|
||||
try:
|
||||
data = await sdapi.post('/sdapi/v1/txt2img', options)
|
||||
except:
|
||||
except Exception:
|
||||
return -1
|
||||
if 'error' in data:
|
||||
return -1
|
||||
|
||||
+2
-2
@@ -44,7 +44,7 @@ def setup_logging(clean=False):
|
||||
if clean and os.path.isfile(log_file):
|
||||
os.remove(log_file)
|
||||
time.sleep(0.1) # prevent race condition
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
from rich.theme import Theme
|
||||
from rich.logging import RichHandler
|
||||
@@ -128,7 +128,7 @@ def prepare_server():
|
||||
try:
|
||||
server_status = util.Map(sdapi.progresssync())
|
||||
server_state = server_status['state']
|
||||
except:
|
||||
except Exception:
|
||||
log.error(f'server error: {server_status}')
|
||||
exit(1)
|
||||
if server_state['job_count'] > 0:
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ def get_memory():
|
||||
'gpu-inactive': inactive,
|
||||
'events': events,
|
||||
})
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
return Map(mem)
|
||||
|
||||
|
||||
@@ -110,7 +110,6 @@ class LDSR:
|
||||
diffusion_steps = int(steps)
|
||||
eta = 1.0
|
||||
|
||||
|
||||
gc.collect()
|
||||
if torch.cuda.is_available:
|
||||
torch.cuda.empty_cache()
|
||||
|
||||
@@ -6,9 +6,7 @@ import torch
|
||||
import pytorch_lightning as pl
|
||||
import torch.nn.functional as F
|
||||
from contextlib import contextmanager
|
||||
|
||||
from torch.optim.lr_scheduler import LambdaLR
|
||||
|
||||
from ldm.modules.ema import LitEma
|
||||
from taming.modules.vqvae.quantize import VectorQuantizer2 as VectorQuantizer
|
||||
from ldm.modules.diffusionmodules.model import Encoder, Decoder
|
||||
|
||||
@@ -82,7 +82,7 @@ class LoraOnDisk:
|
||||
try:
|
||||
self.metadata = sd_models.read_metadata_from_safetensors(filename)
|
||||
except Exception as e:
|
||||
errors.display(e, f"reading lora {filename}")
|
||||
errors.display(e, f"reading lora metadata: {filename}")
|
||||
|
||||
if self.metadata:
|
||||
m = {}
|
||||
|
||||
+9
-9
@@ -53,7 +53,7 @@ def setup_logging(clean=False):
|
||||
if clean and os.path.isfile(log_file):
|
||||
os.remove(log_file)
|
||||
time.sleep(0.1) # prevent race condition
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
from rich.theme import Theme
|
||||
from rich.logging import RichHandler
|
||||
@@ -83,7 +83,7 @@ def setup_logging(clean=False):
|
||||
def print_profile(profile: cProfile.Profile, msg: str):
|
||||
try:
|
||||
from rich import print # pylint: disable=redefined-builtin
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
profile.disable()
|
||||
stream = io.StringIO()
|
||||
@@ -261,7 +261,7 @@ def check_torch():
|
||||
elif allow_cuda and (shutil.which('nvidia-smi') is not None or os.path.exists(os.path.join(os.environ.get('SystemRoot') or r'C:\Windows', 'System32', 'nvidia-smi.exe'))):
|
||||
log.info('nVidia CUDA toolkit detected')
|
||||
torch_command = os.environ.get('TORCH_COMMAND', 'torch torchvision --index-url https://download.pytorch.org/whl/cu118')
|
||||
xformers_package = os.environ.get('XFORMERS_PACKAGE', 'xformers==0.0.17' if opts.get('cross_attention_optimization', '') == 'xFormers' else 'none')
|
||||
xformers_package = os.environ.get('XFORMERS_PACKAGE', 'xformers==0.0.20' if opts.get('cross_attention_optimization', '') == 'xFormers' else 'none')
|
||||
elif allow_rocm and (shutil.which('rocminfo') is not None or os.path.exists('/opt/rocm/bin/rocminfo') or os.path.exists('/dev/kfd')):
|
||||
log.info('AMD ROCm toolkit detected')
|
||||
os.environ.setdefault('HSA_OVERRIDE_GFX_VERSION', '10.3.0')
|
||||
@@ -318,7 +318,7 @@ def check_torch():
|
||||
log.info(f'Torch backend: DirectML ({version})')
|
||||
for i in range(0, torch_directml.device_count()):
|
||||
log.info(f'Torch detected GPU: {torch_directml.device_name(i)}')
|
||||
except:
|
||||
except Exception:
|
||||
log.warning("Torch reports CUDA not available")
|
||||
except Exception as e:
|
||||
log.error(f'Could not load torch: {e}')
|
||||
@@ -359,7 +359,7 @@ def check_modified_files():
|
||||
files = [x for x in files if len(x) > 0 and not x.startswith('extensions') and not x.startswith('wiki') and not x.endswith('.json')]
|
||||
if len(files) > 0:
|
||||
log.warning(f'Modified files: {files}')
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
@@ -479,7 +479,7 @@ def install_extensions():
|
||||
if not args.skip_update:
|
||||
try:
|
||||
update(os.path.join(folder, ext))
|
||||
except:
|
||||
except Exception:
|
||||
log.error(f'Error updating extension: {os.path.join(folder, ext)}')
|
||||
if not args.skip_extensions:
|
||||
run_extension_installer(os.path.join(folder, ext))
|
||||
@@ -522,7 +522,7 @@ def install_submodules():
|
||||
try:
|
||||
name = submodule.split()[1].strip()
|
||||
update(name)
|
||||
except:
|
||||
except Exception:
|
||||
log.error(f'Error updating submodule: {submodule}')
|
||||
if args.profile:
|
||||
print_profile(pr, 'Submodule')
|
||||
@@ -656,7 +656,7 @@ def update_wiki():
|
||||
try:
|
||||
update(os.path.join(os.path.dirname(__file__), "wiki"))
|
||||
update(os.path.join(os.path.dirname(__file__), "wiki", "origin-wiki"))
|
||||
except:
|
||||
except Exception:
|
||||
log.error('Error updating wiki')
|
||||
|
||||
|
||||
@@ -745,7 +745,7 @@ def extensions_preload(parser):
|
||||
preload_extensions(ext_dir, parser)
|
||||
t1 = time.time()
|
||||
log.info(f'Extension preload: {round(t1 - t0, 1)}s {ext_dir}')
|
||||
except:
|
||||
except Exception:
|
||||
log.error('Error running extension preloading')
|
||||
if args.profile:
|
||||
print_profile(pr, 'Preload')
|
||||
|
||||
@@ -44,6 +44,7 @@ async function setHints() {
|
||||
if (!locale.el) tooltipCreate();
|
||||
let localized = 0;
|
||||
let hints = 0;
|
||||
locale.finished = true;
|
||||
for (el of elements) {
|
||||
const found = locale.data.find(l => l.label === el.textContent);
|
||||
if (found?.localized?.length > 0) {
|
||||
@@ -63,8 +64,7 @@ async function setHints() {
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log('set-hints', { type: locale.type, elements: elements.length, localized, hints, data: locale.data });
|
||||
locale.finished = true;
|
||||
console.log('set-hints', { type: locale.type, elements: elements.length, localized, hints, data: locale.data.length });
|
||||
}
|
||||
|
||||
onAfterUiUpdate(async () => {
|
||||
|
||||
@@ -405,6 +405,10 @@ div#extras_scale_to_tab div.form{
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
.ui-defaults-none{
|
||||
color: #aaa !important;
|
||||
}
|
||||
|
||||
/* fullpage image viewer */
|
||||
|
||||
#lightboxModal{
|
||||
|
||||
@@ -183,7 +183,7 @@ if __name__ == "__main__":
|
||||
while True:
|
||||
try:
|
||||
alive = instance.thread.is_alive()
|
||||
except:
|
||||
except Exception:
|
||||
alive = False
|
||||
if round(time.time()) % 120 == 0:
|
||||
installer.log.debug(f'Server alive: {alive} Memory {get_memory_stats()}')
|
||||
|
||||
+57
-57
@@ -2,7 +2,7 @@ import io
|
||||
import time
|
||||
import base64
|
||||
from io import BytesIO
|
||||
from typing import List
|
||||
from typing import List, Dict, Any
|
||||
from threading import Lock
|
||||
from secrets import compare_digest
|
||||
from fastapi import APIRouter, Depends, FastAPI
|
||||
@@ -14,7 +14,7 @@ import piexif.helper
|
||||
import uvicorn
|
||||
import gradio as gr
|
||||
from modules import errors, shared, sd_samplers, deepbooru, sd_hijack, images, scripts, ui, postprocessing
|
||||
from modules.api.models import * # pylint: disable=unused-wildcard-import, wildcard-import
|
||||
from modules.api import models
|
||||
from modules.processing import StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img, process_images
|
||||
from modules.textual_inversion.textual_inversion import create_embedding, train_embedding
|
||||
from modules.textual_inversion.preprocess import preprocess
|
||||
@@ -97,7 +97,7 @@ def encode_pil_to_base64(image):
|
||||
|
||||
class Api:
|
||||
def __init__(self, app: FastAPI, queue_lock: Lock):
|
||||
self.credentials = dict()
|
||||
self.credentials = {}
|
||||
if shared.cmd_opts.auth:
|
||||
for auth in shared.cmd_opts.auth.split(","):
|
||||
user, password = auth.split(":")
|
||||
@@ -111,37 +111,37 @@ class Api:
|
||||
self.router = APIRouter()
|
||||
self.app = app
|
||||
self.queue_lock = queue_lock
|
||||
self.add_api_route("/sdapi/v1/txt2img", self.text2imgapi, methods=["POST"], response_model=TextToImageResponse)
|
||||
self.add_api_route("/sdapi/v1/img2img", self.img2imgapi, methods=["POST"], response_model=ImageToImageResponse)
|
||||
self.add_api_route("/sdapi/v1/extra-single-image", self.extras_single_image_api, methods=["POST"], response_model=ExtrasSingleImageResponse)
|
||||
self.add_api_route("/sdapi/v1/extra-batch-images", self.extras_batch_images_api, methods=["POST"], response_model=ExtrasBatchImagesResponse)
|
||||
self.add_api_route("/sdapi/v1/png-info", self.pnginfoapi, methods=["POST"], response_model=PNGInfoResponse)
|
||||
self.add_api_route("/sdapi/v1/progress", self.progressapi, methods=["GET"], response_model=ProgressResponse)
|
||||
self.add_api_route("/sdapi/v1/txt2img", self.text2imgapi, methods=["POST"], response_model=models.TextToImageResponse)
|
||||
self.add_api_route("/sdapi/v1/img2img", self.img2imgapi, methods=["POST"], response_model=models.ImageToImageResponse)
|
||||
self.add_api_route("/sdapi/v1/extra-single-image", self.extras_single_image_api, methods=["POST"], response_model=models.ExtrasSingleImageResponse)
|
||||
self.add_api_route("/sdapi/v1/extra-batch-images", self.extras_batch_images_api, methods=["POST"], response_model=models.ExtrasBatchImagesResponse)
|
||||
self.add_api_route("/sdapi/v1/png-info", self.pnginfoapi, methods=["POST"], response_model=models.PNGInfoResponse)
|
||||
self.add_api_route("/sdapi/v1/progress", self.progressapi, methods=["GET"], response_model=models.ProgressResponse)
|
||||
self.add_api_route("/sdapi/v1/interrogate", self.interrogateapi, methods=["POST"])
|
||||
self.add_api_route("/sdapi/v1/interrupt", self.interruptapi, methods=["POST"])
|
||||
self.add_api_route("/sdapi/v1/skip", self.skip, methods=["POST"])
|
||||
self.add_api_route("/sdapi/v1/options", self.get_config, methods=["GET"], response_model=OptionsModel)
|
||||
self.add_api_route("/sdapi/v1/options", self.get_config, methods=["GET"], response_model=models.OptionsModel)
|
||||
self.add_api_route("/sdapi/v1/options", self.set_config, methods=["POST"])
|
||||
self.add_api_route("/sdapi/v1/cmd-flags", self.get_cmd_flags, methods=["GET"], response_model=FlagsModel)
|
||||
self.add_api_route("/sdapi/v1/samplers", self.get_samplers, methods=["GET"], response_model=List[SamplerItem])
|
||||
self.add_api_route("/sdapi/v1/upscalers", self.get_upscalers, methods=["GET"], response_model=List[UpscalerItem])
|
||||
self.add_api_route("/sdapi/v1/sd-models", self.get_sd_models, methods=["GET"], response_model=List[SDModelItem])
|
||||
self.add_api_route("/sdapi/v1/hypernetworks", self.get_hypernetworks, methods=["GET"], response_model=List[HypernetworkItem])
|
||||
self.add_api_route("/sdapi/v1/face-restorers", self.get_face_restorers, methods=["GET"], response_model=List[FaceRestorerItem])
|
||||
self.add_api_route("/sdapi/v1/realesrgan-models", self.get_realesrgan_models, methods=["GET"], response_model=List[RealesrganItem])
|
||||
self.add_api_route("/sdapi/v1/prompt-styles", self.get_prompt_styles, methods=["GET"], response_model=List[PromptStyleItem])
|
||||
self.add_api_route("/sdapi/v1/embeddings", self.get_embeddings, methods=["GET"], response_model=EmbeddingsResponse)
|
||||
self.add_api_route("/sdapi/v1/cmd-flags", self.get_cmd_flags, methods=["GET"], response_model=models.FlagsModel)
|
||||
self.add_api_route("/sdapi/v1/samplers", self.get_samplers, methods=["GET"], response_model=List[models.SamplerItem])
|
||||
self.add_api_route("/sdapi/v1/upscalers", self.get_upscalers, methods=["GET"], response_model=List[models.UpscalerItem])
|
||||
self.add_api_route("/sdapi/v1/sd-models", self.get_sd_models, methods=["GET"], response_model=List[models.SDModelItem])
|
||||
self.add_api_route("/sdapi/v1/hypernetworks", self.get_hypernetworks, methods=["GET"], response_model=List[models.HypernetworkItem])
|
||||
self.add_api_route("/sdapi/v1/face-restorers", self.get_face_restorers, methods=["GET"], response_model=List[models.FaceRestorerItem])
|
||||
self.add_api_route("/sdapi/v1/realesrgan-models", self.get_realesrgan_models, methods=["GET"], response_model=List[models.RealesrganItem])
|
||||
self.add_api_route("/sdapi/v1/prompt-styles", self.get_prompt_styles, methods=["GET"], response_model=List[models.PromptStyleItem])
|
||||
self.add_api_route("/sdapi/v1/embeddings", self.get_embeddings, methods=["GET"], response_model=models.EmbeddingsResponse)
|
||||
self.add_api_route("/sdapi/v1/refresh-checkpoints", self.refresh_checkpoints, methods=["POST"])
|
||||
self.add_api_route("/sdapi/v1/create/embedding", self.create_embedding, methods=["POST"], response_model=CreateResponse)
|
||||
self.add_api_route("/sdapi/v1/create/hypernetwork", self.create_hypernetwork, methods=["POST"], response_model=CreateResponse)
|
||||
self.add_api_route("/sdapi/v1/preprocess", self.preprocess, methods=["POST"], response_model=PreprocessResponse)
|
||||
self.add_api_route("/sdapi/v1/train/embedding", self.train_embedding, methods=["POST"], response_model=TrainResponse)
|
||||
self.add_api_route("/sdapi/v1/train/hypernetwork", self.train_hypernetwork, methods=["POST"], response_model=TrainResponse)
|
||||
self.add_api_route("/sdapi/v1/create/embedding", self.create_embedding, methods=["POST"], response_model=models.CreateResponse)
|
||||
self.add_api_route("/sdapi/v1/create/hypernetwork", self.create_hypernetwork, methods=["POST"], response_model=models.CreateResponse)
|
||||
self.add_api_route("/sdapi/v1/preprocess", self.preprocess, methods=["POST"], response_model=models.PreprocessResponse)
|
||||
self.add_api_route("/sdapi/v1/train/embedding", self.train_embedding, methods=["POST"], response_model=models.TrainResponse)
|
||||
self.add_api_route("/sdapi/v1/train/hypernetwork", self.train_hypernetwork, methods=["POST"], response_model=models.TrainResponse)
|
||||
self.add_api_route("/sdapi/v1/shutdown", self.shutdown, methods=["POST"])
|
||||
self.add_api_route("/sdapi/v1/memory", self.get_memory, methods=["GET"], response_model=MemoryResponse)
|
||||
self.add_api_route("/sdapi/v1/memory", self.get_memory, methods=["GET"], response_model=models.MemoryResponse)
|
||||
self.add_api_route("/sdapi/v1/unload-checkpoint", self.unloadapi, methods=["POST"])
|
||||
self.add_api_route("/sdapi/v1/reload-checkpoint", self.reloadapi, methods=["POST"])
|
||||
self.add_api_route("/sdapi/v1/scripts", self.get_scripts_list, methods=["GET"], response_model=ScriptsList)
|
||||
self.add_api_route("/sdapi/v1/scripts", self.get_scripts_list, methods=["GET"], response_model=models.ScriptsList)
|
||||
self.default_script_arg_txt2img = []
|
||||
self.default_script_arg_img2img = []
|
||||
|
||||
@@ -166,7 +166,7 @@ class Api:
|
||||
def get_scripts_list(self):
|
||||
t2ilist = [str(title.lower()) for title in scripts.scripts_txt2img.titles]
|
||||
i2ilist = [str(title.lower()) for title in scripts.scripts_img2img.titles]
|
||||
return ScriptsList(txt2img = t2ilist, img2img = i2ilist)
|
||||
return models.ScriptsList(txt2img = t2ilist, img2img = i2ilist)
|
||||
|
||||
def get_script(self, script_name, script_runner):
|
||||
if script_name is None or script_name == "":
|
||||
@@ -218,7 +218,7 @@ class Api:
|
||||
return script_args
|
||||
|
||||
|
||||
def text2imgapi(self, txt2imgreq: StableDiffusionTxt2ImgProcessingAPI):
|
||||
def text2imgapi(self, txt2imgreq: models.StableDiffusionTxt2ImgProcessingAPI):
|
||||
script_runner = scripts.scripts_txt2img
|
||||
if not script_runner.scripts:
|
||||
script_runner.initialize_scripts(False)
|
||||
@@ -255,9 +255,9 @@ class Api:
|
||||
shared.state.end()
|
||||
|
||||
b64images = list(map(encode_pil_to_base64, processed.images)) if send_images else []
|
||||
return TextToImageResponse(images=b64images, parameters=vars(txt2imgreq), info=processed.js())
|
||||
return models.TextToImageResponse(images=b64images, parameters=vars(txt2imgreq), info=processed.js())
|
||||
|
||||
def img2imgapi(self, img2imgreq: StableDiffusionImg2ImgProcessingAPI):
|
||||
def img2imgapi(self, img2imgreq: models.StableDiffusionImg2ImgProcessingAPI):
|
||||
init_images = img2imgreq.init_images
|
||||
if init_images is None:
|
||||
raise HTTPException(status_code=404, detail="Init image not found")
|
||||
@@ -306,16 +306,16 @@ class Api:
|
||||
if not img2imgreq.include_init_images:
|
||||
img2imgreq.init_images = None
|
||||
img2imgreq.mask = None
|
||||
return ImageToImageResponse(images=b64images, parameters=vars(img2imgreq), info=processed.js())
|
||||
return models.ImageToImageResponse(images=b64images, parameters=vars(img2imgreq), info=processed.js())
|
||||
|
||||
def extras_single_image_api(self, req: ExtrasSingleImageRequest):
|
||||
def extras_single_image_api(self, req: models.ExtrasSingleImageRequest):
|
||||
reqDict = setUpscalers(req)
|
||||
reqDict['image'] = decode_base64_to_image(reqDict['image'])
|
||||
with self.queue_lock:
|
||||
result = postprocessing.run_extras(extras_mode=0, image_folder="", input_dir="", output_dir="", save_output=False, **reqDict)
|
||||
return ExtrasSingleImageResponse(image=encode_pil_to_base64(result[0][0]), html_info=result[1])
|
||||
return models.ExtrasSingleImageResponse(image=encode_pil_to_base64(result[0][0]), html_info=result[1])
|
||||
|
||||
def extras_batch_images_api(self, req: ExtrasBatchImagesRequest):
|
||||
def extras_batch_images_api(self, req: models.ExtrasBatchImagesRequest):
|
||||
reqDict = setUpscalers(req)
|
||||
|
||||
image_list = reqDict.pop('imageList', [])
|
||||
@@ -324,15 +324,15 @@ class Api:
|
||||
with self.queue_lock:
|
||||
result = postprocessing.run_extras(extras_mode=1, image_folder=image_folder, image="", input_dir="", output_dir="", save_output=False, **reqDict)
|
||||
|
||||
return ExtrasBatchImagesResponse(images=list(map(encode_pil_to_base64, result[0])), html_info=result[1])
|
||||
return models.ExtrasBatchImagesResponse(images=list(map(encode_pil_to_base64, result[0])), html_info=result[1])
|
||||
|
||||
def pnginfoapi(self, req: PNGInfoRequest):
|
||||
def pnginfoapi(self, req: models.PNGInfoRequest):
|
||||
if not req.image.strip():
|
||||
return PNGInfoResponse(info="")
|
||||
return models.PNGInfoResponse(info="")
|
||||
|
||||
image = decode_base64_to_image(req.image.strip())
|
||||
if image is None:
|
||||
return PNGInfoResponse(info="")
|
||||
return models.PNGInfoResponse(info="")
|
||||
|
||||
geninfo, items = images.read_info_from_image(image)
|
||||
if geninfo is None:
|
||||
@@ -340,13 +340,13 @@ class Api:
|
||||
|
||||
items = {**{'parameters': geninfo}, **items}
|
||||
|
||||
return PNGInfoResponse(info=geninfo, items=items)
|
||||
return models.PNGInfoResponse(info=geninfo, items=items)
|
||||
|
||||
def progressapi(self, req: ProgressRequest = Depends()):
|
||||
def progressapi(self, req: models.ProgressRequest = Depends()):
|
||||
# copy from check_progress_call of ui.py
|
||||
|
||||
if shared.state.job_count == 0:
|
||||
return ProgressResponse(progress=0, eta_relative=0, state=shared.state.dict(), textinfo=shared.state.textinfo)
|
||||
return models.ProgressResponse(progress=0, eta_relative=0, state=shared.state.dict(), textinfo=shared.state.textinfo)
|
||||
|
||||
# avoid dividing zero
|
||||
progress = 0.01
|
||||
@@ -368,9 +368,9 @@ class Api:
|
||||
if shared.state.current_image and not req.skip_current_image:
|
||||
current_image = encode_pil_to_base64(shared.state.current_image)
|
||||
|
||||
return ProgressResponse(progress=progress, eta_relative=eta_relative, state=shared.state.dict(), current_image=current_image, textinfo=shared.state.textinfo)
|
||||
return models.ProgressResponse(progress=progress, eta_relative=eta_relative, state=shared.state.dict(), current_image=current_image, textinfo=shared.state.textinfo)
|
||||
|
||||
def interrogateapi(self, interrogatereq: InterrogateRequest):
|
||||
def interrogateapi(self, interrogatereq: models.InterrogateRequest):
|
||||
image_b64 = interrogatereq.image
|
||||
if image_b64 is None:
|
||||
raise HTTPException(status_code=404, detail="Image not found")
|
||||
@@ -387,7 +387,7 @@ class Api:
|
||||
else:
|
||||
raise HTTPException(status_code=404, detail="Model not found")
|
||||
|
||||
return InterrogateResponse(caption=processed)
|
||||
return models.InterrogateResponse(caption=processed)
|
||||
|
||||
def interruptapi(self):
|
||||
shared.state.interrupt()
|
||||
@@ -493,36 +493,36 @@ class Api:
|
||||
filename = create_embedding(**args) # create empty embedding
|
||||
sd_hijack.model_hijack.embedding_db.load_textual_inversion_embeddings() # reload embeddings so new one can be immediately used
|
||||
shared.state.end()
|
||||
return CreateResponse(info = f"create embedding filename: {filename}")
|
||||
return models.CreateResponse(info = f"create embedding filename: {filename}")
|
||||
except AssertionError as e:
|
||||
shared.state.end()
|
||||
return TrainResponse(info = f"create embedding error: {e}")
|
||||
return models.TrainResponse(info = f"create embedding error: {e}")
|
||||
|
||||
def create_hypernetwork(self, args: dict):
|
||||
try:
|
||||
shared.state.begin()
|
||||
filename = create_hypernetwork(**args) # create empty embedding # pylint: disable=E1111
|
||||
shared.state.end()
|
||||
return CreateResponse(info = f"create hypernetwork filename: {filename}")
|
||||
return models.CreateResponse(info = f"create hypernetwork filename: {filename}")
|
||||
except AssertionError as e:
|
||||
shared.state.end()
|
||||
return TrainResponse(info = f"create hypernetwork error: {e}")
|
||||
return models.TrainResponse(info = f"create hypernetwork error: {e}")
|
||||
|
||||
def preprocess(self, args: dict):
|
||||
try:
|
||||
shared.state.begin()
|
||||
preprocess(**args) # quick operation unless blip/booru interrogation is enabled
|
||||
shared.state.end()
|
||||
return PreprocessResponse(info = 'preprocess complete')
|
||||
return models.PreprocessResponse(info = 'preprocess complete')
|
||||
except KeyError as e:
|
||||
shared.state.end()
|
||||
return PreprocessResponse(info = f"preprocess error: invalid token: {e}")
|
||||
return models.PreprocessResponse(info = f"preprocess error: invalid token: {e}")
|
||||
except AssertionError as e:
|
||||
shared.state.end()
|
||||
return PreprocessResponse(info = f"preprocess error: {e}")
|
||||
return models.PreprocessResponse(info = f"preprocess error: {e}")
|
||||
except FileNotFoundError as e:
|
||||
shared.state.end()
|
||||
return PreprocessResponse(info = f'preprocess error: {e}')
|
||||
return models.PreprocessResponse(info = f'preprocess error: {e}')
|
||||
|
||||
def train_embedding(self, args: dict):
|
||||
try:
|
||||
@@ -540,10 +540,10 @@ class Api:
|
||||
if not apply_optimizations:
|
||||
sd_hijack.apply_optimizations()
|
||||
shared.state.end()
|
||||
return TrainResponse(info = f"train embedding complete: filename: {filename} error: {error}")
|
||||
return models.TrainResponse(info = f"train embedding complete: filename: {filename} error: {error}")
|
||||
except AssertionError as msg:
|
||||
shared.state.end()
|
||||
return TrainResponse(info = f"train embedding error: {msg}")
|
||||
return models.TrainResponse(info = f"train embedding error: {msg}")
|
||||
|
||||
def train_hypernetwork(self, args: dict):
|
||||
try:
|
||||
@@ -564,10 +564,10 @@ class Api:
|
||||
if not apply_optimizations:
|
||||
sd_hijack.apply_optimizations()
|
||||
shared.state.end()
|
||||
return TrainResponse(info=f"train embedding complete: filename: {filename} error: {error}")
|
||||
return models.TrainResponse(info=f"train embedding complete: filename: {filename} error: {error}")
|
||||
except AssertionError:
|
||||
shared.state.end()
|
||||
return TrainResponse(info=f"train embedding error: {error}")
|
||||
return models.TrainResponse(info=f"train embedding error: {error}")
|
||||
|
||||
def shutdown(self):
|
||||
shared.log.info('Shutdown request received')
|
||||
@@ -628,7 +628,7 @@ class Api:
|
||||
cuda = { 'error': 'unavailable' }
|
||||
except Exception as err:
|
||||
cuda = { 'error': f'{err}' }
|
||||
return MemoryResponse(ram = ram, cuda = cuda)
|
||||
return models.MemoryResponse(ram = ram, cuda = cuda)
|
||||
|
||||
def launch(self, server_name, port):
|
||||
self.app.include_router(self.router)
|
||||
|
||||
@@ -220,7 +220,7 @@ for key in _options:
|
||||
_type = str
|
||||
if _options[key].default is not None:
|
||||
_type = type(_options[key].default)
|
||||
flags.update({flag.dest: (_type,Field(default=flag.default, description=flag.help))})
|
||||
flags.update({flag.dest: (_type, Field(default=flag.default, description=flag.help))})
|
||||
|
||||
FlagsModel = create_model("Flags", **flags)
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ from torch import nn, Tensor
|
||||
import torch.nn.functional as F
|
||||
from typing import Optional, List
|
||||
|
||||
from modules.codeformer.vqgan_arch import *
|
||||
from modules.codeformer.vqgan_arch import VQAutoEncoder, ResBlock
|
||||
from basicsr.utils import get_root_logger
|
||||
from basicsr.utils.registry import ARCH_REGISTRY
|
||||
|
||||
@@ -160,12 +160,12 @@ class Fuse_sft_block(nn.Module):
|
||||
|
||||
@ARCH_REGISTRY.register()
|
||||
class CodeFormer(VQAutoEncoder):
|
||||
def __init__(self, dim_embd=512, n_head=8, n_layers=9,
|
||||
def __init__(self, dim_embd=512, n_head=8, n_layers=9,
|
||||
codebook_size=1024, latent_size=256,
|
||||
connect_list=['32', '64', '128', '256'],
|
||||
fix_modules=['quantize','generator']):
|
||||
connect_list=('32', '64', '128', '256'),
|
||||
fix_modules=('quantize', 'generator')):
|
||||
super(CodeFormer, self).__init__(512, 64, [1, 2, 2, 4, 4, 8], 'nearest',2, [16], codebook_size)
|
||||
|
||||
|
||||
if fix_modules is not None:
|
||||
for module in fix_modules:
|
||||
for param in getattr(self, module).parameters():
|
||||
@@ -180,14 +180,14 @@ class CodeFormer(VQAutoEncoder):
|
||||
self.feat_emb = nn.Linear(256, self.dim_embd)
|
||||
|
||||
# transformer
|
||||
self.ft_layers = nn.Sequential(*[TransformerSALayer(embed_dim=dim_embd, nhead=n_head, dim_mlp=self.dim_mlp, dropout=0.0)
|
||||
self.ft_layers = nn.Sequential(*[TransformerSALayer(embed_dim=dim_embd, nhead=n_head, dim_mlp=self.dim_mlp, dropout=0.0)
|
||||
for _ in range(self.n_layers)])
|
||||
|
||||
# logits_predict head
|
||||
self.idx_pred_layer = nn.Sequential(
|
||||
nn.LayerNorm(dim_embd),
|
||||
nn.Linear(dim_embd, codebook_size, bias=False))
|
||||
|
||||
|
||||
self.channels = {
|
||||
'16': 512,
|
||||
'32': 256,
|
||||
|
||||
@@ -328,7 +328,7 @@ class Generator(nn.Module):
|
||||
|
||||
@ARCH_REGISTRY.register()
|
||||
class VQAutoEncoder(nn.Module):
|
||||
def __init__(self, img_size, nf, ch_mult, quantizer="nearest", res_blocks=2, attn_resolutions=[16], codebook_size=1024, emb_dim=256,
|
||||
def __init__(self, img_size, nf, ch_mult, quantizer="nearest", res_blocks=2, attn_resolutions=None, codebook_size=1024, emb_dim=256,
|
||||
beta=0.25, gumbel_straight_through=False, gumbel_kl_weight=1e-8, model_path=None):
|
||||
super().__init__()
|
||||
logger = get_root_logger()
|
||||
@@ -339,7 +339,7 @@ class VQAutoEncoder(nn.Module):
|
||||
self.embed_dim = emb_dim
|
||||
self.ch_mult = ch_mult
|
||||
self.resolution = img_size
|
||||
self.attn_resolutions = attn_resolutions
|
||||
self.attn_resolutions = attn_resolutions or [16]
|
||||
self.quantizer_type = quantizer
|
||||
self.encoder = Encoder(
|
||||
self.in_channels,
|
||||
|
||||
@@ -91,7 +91,7 @@ def setup_model(dirname):
|
||||
self.face_helper.get_face_landmarks_5(only_center_face=False, resize=640, eye_dist_threshold=5)
|
||||
self.face_helper.align_warp_face()
|
||||
|
||||
for _idx, cropped_face in enumerate(self.face_helper.cropped_faces):
|
||||
for cropped_face in self.face_helper.cropped_faces:
|
||||
cropped_face_t = img2tensor(cropped_face / 255., bgr2rgb=True, float32=True)
|
||||
normalize(cropped_face_t, (0.5, 0.5, 0.5), (0.5, 0.5, 0.5), inplace=True)
|
||||
cropped_face_t = cropped_face_t.unsqueeze(0).to(devices.device_codeformer)
|
||||
|
||||
@@ -78,7 +78,7 @@ class DeepDanbooru:
|
||||
|
||||
res = []
|
||||
|
||||
filtertags = set([x.strip().replace(' ', '_') for x in shared.opts.deepbooru_filter_tags.split(",")])
|
||||
filtertags = {x.strip().replace(' ', '_') for x in shared.opts.deepbooru_filter_tags.split(",")}
|
||||
|
||||
for tag in [x for x in tags if x not in filtertags]:
|
||||
probability = probability_dict[tag]
|
||||
|
||||
+6
-6
@@ -68,14 +68,14 @@ def torch_gc(force=False):
|
||||
try:
|
||||
with torch.xpu.device(get_cuda_device_string()):
|
||||
torch.xpu.empty_cache()
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
elif cuda_ok:
|
||||
try:
|
||||
with torch.cuda.device(get_cuda_device_string()):
|
||||
torch.cuda.empty_cache()
|
||||
torch.cuda.ipc_collect()
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
shared.log.debug(f'gc: collected={collected} device={torch.device(get_optimal_device_name())} {memstats.memory_stats()}')
|
||||
|
||||
@@ -89,7 +89,7 @@ def test_fp16():
|
||||
_y = layerNorm(x)
|
||||
shared.log.debug('Torch FP16 test passed')
|
||||
return True
|
||||
except:
|
||||
except Exception:
|
||||
shared.log.warning('Torch FP16 test failed: Forcing FP32 operations')
|
||||
shared.opts.cuda_dtype = 'FP32'
|
||||
shared.opts.no_half = True
|
||||
@@ -104,7 +104,7 @@ def test_bf16():
|
||||
image = torch.randn(1, 4, 32, 32).to(device=device, dtype=torch.bfloat16)
|
||||
_out = F.interpolate(image, size=(64, 64), mode="nearest")
|
||||
return True
|
||||
except:
|
||||
except Exception:
|
||||
shared.log.warning('Torch BF16 test failed: Fallback to FP16 operations')
|
||||
return False
|
||||
|
||||
@@ -116,7 +116,7 @@ def set_cuda_params():
|
||||
torch.backends.cuda.matmul.allow_tf32 = shared.opts.cuda_allow_tf32
|
||||
torch.backends.cuda.matmul.allow_fp16_reduced_precision_reduction = shared.opts.cuda_allow_tf16_reduced
|
||||
torch.backends.cuda.matmul.allow_bf16_reduced_precision_reduction = shared.opts.cuda_allow_tf16_reduced
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
if torch.backends.cudnn.is_available():
|
||||
try:
|
||||
@@ -124,7 +124,7 @@ def set_cuda_params():
|
||||
if shared.opts.cudnn_benchmark:
|
||||
torch.backends.cudnn.benchmark_limit = 0
|
||||
torch.backends.cudnn.allow_tf32 = shared.opts.cuda_allow_tf32
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
global dtype, dtype_vae, dtype_unet, unet_needs_upcast # pylint: disable=global-statement
|
||||
if shared.cmd_opts.use_directml and not shared.cmd_opts.experimental: # TODO DirectML does not have full autocast capabilities
|
||||
|
||||
@@ -23,7 +23,7 @@ class DirectML():
|
||||
else:
|
||||
return UnknownOptimizer
|
||||
return optimizer
|
||||
except:
|
||||
except Exception:
|
||||
return UnknownOptimizer
|
||||
|
||||
def memory_stats(device: torch.device):
|
||||
|
||||
@@ -20,7 +20,7 @@ def p_sample_plms(self, x, c, t, index, repeat_noise=False, use_original_steps=F
|
||||
|
||||
if isinstance(c, dict):
|
||||
assert isinstance(unconditional_conditioning, dict)
|
||||
c_in = dict()
|
||||
c_in = {}
|
||||
for k in c:
|
||||
if isinstance(c[k], list):
|
||||
c_in[k] = [
|
||||
|
||||
@@ -16,9 +16,7 @@ def mod2normal(state_dict):
|
||||
# this code is copied from https://github.com/victorca25/iNNfer
|
||||
if 'conv_first.weight' in state_dict:
|
||||
crt_net = {}
|
||||
items = []
|
||||
for k, _v in state_dict.items():
|
||||
items.append(k)
|
||||
items = list(state_dict)
|
||||
|
||||
crt_net['model.0.weight'] = state_dict['conv_first.weight']
|
||||
crt_net['model.0.bias'] = state_dict['conv_first.bias']
|
||||
@@ -52,9 +50,7 @@ def resrgan2normal(state_dict, nb=23):
|
||||
if "conv_first.weight" in state_dict and "body.0.rdb1.conv1.weight" in state_dict:
|
||||
re8x = 0
|
||||
crt_net = {}
|
||||
items = []
|
||||
for k, _v in state_dict.items():
|
||||
items.append(k)
|
||||
items = list(state_dict)
|
||||
|
||||
crt_net['model.0.weight'] = state_dict['conv_first.weight']
|
||||
crt_net['model.0.bias'] = state_dict['conv_first.bias']
|
||||
|
||||
@@ -437,9 +437,11 @@ def conv_block(in_nc, out_nc, kernel_size, stride=1, dilation=1, groups=1, bias=
|
||||
padding = padding if pad_type == 'zero' else 0
|
||||
|
||||
if convtype=='PartialConv2D':
|
||||
from torchvision.ops import PartialConv2d
|
||||
c = PartialConv2d(in_nc, out_nc, kernel_size=kernel_size, stride=stride, padding=padding,
|
||||
dilation=dilation, bias=bias, groups=groups)
|
||||
elif convtype=='DeformConv2D':
|
||||
from torchvision.ops import DeformConv2d
|
||||
c = DeformConv2d(in_nc, out_nc, kernel_size=kernel_size, stride=stride, padding=padding,
|
||||
dilation=dilation, bias=bias, groups=groups)
|
||||
elif convtype=='Conv3D':
|
||||
|
||||
@@ -86,7 +86,7 @@ class Extension:
|
||||
def check_updates(self):
|
||||
try:
|
||||
repo = git.Repo(self.path)
|
||||
except:
|
||||
except Exception:
|
||||
self.can_update = False
|
||||
return
|
||||
for fetch in repo.remote().fetch(dry_run=True):
|
||||
|
||||
@@ -91,7 +91,7 @@ def deactivate(p, extra_network_data):
|
||||
"""call deactivate for extra networks in extra_network_data in specified order, then call
|
||||
deactivate for all remaining registered networks"""
|
||||
|
||||
for extra_network_name, _extra_network_args in extra_network_data.items():
|
||||
for extra_network_name in extra_network_data:
|
||||
extra_network = extra_network_registry.get(extra_network_name, None)
|
||||
if extra_network is None:
|
||||
continue
|
||||
|
||||
@@ -20,14 +20,14 @@ registered_param_bindings = []
|
||||
|
||||
|
||||
class ParamBinding:
|
||||
def __init__(self, paste_button, tabname, source_text_component=None, source_image_component=None, source_tabname=None, override_settings_component=None, paste_field_names=[]):
|
||||
def __init__(self, paste_button, tabname, source_text_component=None, source_image_component=None, source_tabname=None, override_settings_component=None, paste_field_names=None):
|
||||
self.paste_button = paste_button
|
||||
self.tabname = tabname
|
||||
self.source_text_component = source_text_component
|
||||
self.source_image_component = source_image_component
|
||||
self.source_tabname = source_tabname
|
||||
self.override_settings_component = override_settings_component
|
||||
self.paste_field_names = paste_field_names
|
||||
self.paste_field_names = paste_field_names or []
|
||||
|
||||
|
||||
def reset():
|
||||
@@ -254,7 +254,7 @@ Steps: 20, Sampler: Euler a, CFG scale: 7, Seed: 965400086, Size: 512x512, Model
|
||||
if len(re_param.findall(lastline)) < 3:
|
||||
lines.append(lastline)
|
||||
lastline = ''
|
||||
for _i, line in enumerate(lines):
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
if line.startswith("Negative prompt:"):
|
||||
done_with_prompt = True
|
||||
|
||||
@@ -174,34 +174,34 @@ class Hypernetwork:
|
||||
|
||||
def weights(self):
|
||||
res = []
|
||||
for k, layers in self.layers.items():
|
||||
for layers in self.layers.values():
|
||||
for layer in layers:
|
||||
res += layer.parameters()
|
||||
return res
|
||||
|
||||
def train(self, mode=True):
|
||||
for k, layers in self.layers.items():
|
||||
for layers in self.layers.values():
|
||||
for layer in layers:
|
||||
layer.train(mode=mode)
|
||||
for param in layer.parameters():
|
||||
param.requires_grad = mode
|
||||
|
||||
def to(self, device):
|
||||
for k, layers in self.layers.items():
|
||||
for layers in self.layers.values():
|
||||
for layer in layers:
|
||||
layer.to(device)
|
||||
|
||||
return self
|
||||
|
||||
def set_multiplier(self, multiplier):
|
||||
for k, layers in self.layers.items():
|
||||
for layers in self.layers.values():
|
||||
for layer in layers:
|
||||
layer.multiplier = multiplier
|
||||
|
||||
return self
|
||||
|
||||
def eval(self):
|
||||
for k, layers in self.layers.items():
|
||||
for layers in self.layers.values():
|
||||
for layer in layers:
|
||||
layer.eval()
|
||||
for param in layer.parameters():
|
||||
@@ -400,7 +400,7 @@ def attention_CrossAttention_forward(self, x, context=None, mask=None):
|
||||
k = self.to_k(context_k)
|
||||
v = self.to_v(context_v)
|
||||
|
||||
q, k, v = map(lambda t: rearrange(t, 'b n (h d) -> (b h) n d', h=h), (q, k, v))
|
||||
q, k, v = (rearrange(t, 'b n (h d) -> (b h) n d', h=h) for t in (q, k, v))
|
||||
|
||||
sim = einsum('b i d, b j d -> b i j', q, k) * self.scale
|
||||
|
||||
@@ -619,7 +619,7 @@ def train_hypernetwork(id_task, hypernetwork_name, learn_rate, batch_size, gradi
|
||||
try:
|
||||
sd_hijack_checkpoint.add()
|
||||
|
||||
for i in range((steps-initial_step) * gradient_step):
|
||||
for _i in range((steps-initial_step) * gradient_step):
|
||||
if scheduler.finished:
|
||||
break
|
||||
if shared.state.interrupted:
|
||||
@@ -811,7 +811,7 @@ def save_hypernetwork(hypernetwork, checkpoint, hypernetwork_name, filename):
|
||||
hypernetwork.sd_checkpoint_name = checkpoint.model_name
|
||||
hypernetwork.name = hypernetwork_name
|
||||
hypernetwork.save(filename)
|
||||
except:
|
||||
except Exception:
|
||||
hypernetwork.sd_checkpoint = old_sd_checkpoint
|
||||
hypernetwork.sd_checkpoint_name = old_sd_checkpoint_name
|
||||
hypernetwork.name = old_hypernetwork_name
|
||||
|
||||
@@ -7,25 +7,20 @@ import modules.hypernetworks.hypernetwork
|
||||
from modules import devices, sd_hijack, shared
|
||||
|
||||
not_available = ["hardswish", "multiheadattention"]
|
||||
keys = list(x for x in modules.hypernetworks.hypernetwork.HypernetworkModule.activation_dict if x not in not_available)
|
||||
keys = [x for x in modules.hypernetworks.hypernetwork.HypernetworkModule.activation_dict.keys() if x not in not_available]
|
||||
|
||||
|
||||
def create_hypernetwork(name, enable_sizes, overwrite_old, layer_structure=None, activation_func=None, weight_init=None, add_layer_norm=False, use_dropout=False, dropout_structure=None):
|
||||
filename = modules.hypernetworks.hypernetwork.create_hypernetwork(name, enable_sizes, overwrite_old, layer_structure, activation_func, weight_init, add_layer_norm, use_dropout, dropout_structure)
|
||||
|
||||
return gr.Dropdown.update(choices=sorted([x for x in shared.hypernetworks])), f"Created: {filename}", ""
|
||||
return gr.Dropdown.update(choices=sorted(shared.hypernetworks)), f"Created: {filename}", ""
|
||||
|
||||
|
||||
def train_hypernetwork(*args):
|
||||
shared.loaded_hypernetworks = []
|
||||
|
||||
assert not shared.cmd_opts.lowvram, 'Training models with lowvram is not possible'
|
||||
|
||||
try:
|
||||
sd_hijack.undo_optimizations()
|
||||
|
||||
hypernetwork, filename = modules.hypernetworks.hypernetwork.train_hypernetwork(*args)
|
||||
|
||||
res = f"""
|
||||
Training {'interrupted' if shared.state.interrupted else 'finished'} at {hypernetwork.step} steps.
|
||||
Hypernetwork saved to {html.escape(filename)}
|
||||
@@ -37,4 +32,3 @@ Hypernetwork saved to {html.escape(filename)}
|
||||
shared.sd_model.cond_stage_model.to(devices.device)
|
||||
shared.sd_model.first_stage_model.to(devices.device)
|
||||
sd_hijack.apply_optimizations()
|
||||
|
||||
|
||||
+5
-5
@@ -150,7 +150,7 @@ def draw_grid_annotations(im, width, height, hor_texts, ver_texts, margin=0):
|
||||
return ImageFont.truetype('html/roboto.ttf', fontsize)
|
||||
|
||||
def draw_texts(drawing, draw_x, draw_y, lines, initial_fnt, initial_fontsize):
|
||||
for _i, line in enumerate(lines):
|
||||
for line in lines:
|
||||
fnt = initial_fnt
|
||||
fontsize = initial_fontsize
|
||||
while drawing.multiline_textsize(line.text, font=fnt)[0] > line.allowed_width and fontsize > 0:
|
||||
@@ -373,7 +373,7 @@ class FilenameGenerator:
|
||||
time_zone_time = time_datetime.astimezone(time_zone)
|
||||
try:
|
||||
formatted_time = time_zone_time.strftime(time_format)
|
||||
except (ValueError, TypeError) as _:
|
||||
except (ValueError, TypeError):
|
||||
formatted_time = time_zone_time.strftime(self.default_time_format)
|
||||
return sanitize_filename_part(formatted_time, replace_spaces=False)
|
||||
|
||||
@@ -418,9 +418,9 @@ def get_next_sequence_number(path, basename):
|
||||
prefix_length = len(basename)
|
||||
for p in os.listdir(path):
|
||||
if p.startswith(basename):
|
||||
l = os.path.splitext(p[prefix_length:])[0].split('-') # splits the filename (removing the basename first if one is defined, so the sequence number is always the first element)
|
||||
parts = os.path.splitext(p[prefix_length:])[0].split('-') # splits the filename (removing the basename first if one is defined, so the sequence number is always the first element)
|
||||
try:
|
||||
result = max(int(l[0]), result)
|
||||
result = max(int(parts[0]), result)
|
||||
except ValueError:
|
||||
pass
|
||||
return result + 1
|
||||
@@ -600,7 +600,7 @@ def safe_decode_string(s: bytes):
|
||||
if len(val) == 0: # remove empty strings
|
||||
val = None
|
||||
return val
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
+5
-7
@@ -2,11 +2,9 @@ import os
|
||||
import numpy as np
|
||||
from PIL import Image, ImageOps, ImageFilter, ImageEnhance, ImageChops, UnidentifiedImageError
|
||||
import modules.scripts
|
||||
from modules import sd_samplers, shared
|
||||
from modules import sd_samplers, shared, processing
|
||||
from modules.generation_parameters_copypaste import create_override_settings_dict
|
||||
from modules.processing import Processed, StableDiffusionProcessingImg2Img, process_images
|
||||
from modules.ui import plaintext_to_html, infotext_to_html
|
||||
import modules.processing as processing
|
||||
from modules.memstats import memory_stats
|
||||
|
||||
|
||||
@@ -51,7 +49,7 @@ def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args):
|
||||
|
||||
proc = modules.scripts.scripts_img2img.run(p, *args)
|
||||
if proc is None:
|
||||
proc = process_images(p)
|
||||
proc = processing.process_images(p)
|
||||
for n, processed_image in enumerate(proc.images):
|
||||
filename = os.path.basename(image)
|
||||
if n > 0:
|
||||
@@ -126,7 +124,7 @@ def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_s
|
||||
|
||||
assert 0. <= denoising_strength <= 1., 'can only work with strength in [0.0, 1.0]'
|
||||
|
||||
p = StableDiffusionProcessingImg2Img(
|
||||
p = processing.StableDiffusionProcessingImg2Img(
|
||||
sd_model=shared.sd_model,
|
||||
outpath_samples=shared.opts.outdir_samples or shared.opts.outdir_img2img_samples,
|
||||
outpath_grids=shared.opts.outdir_grids or shared.opts.outdir_img2img_grids,
|
||||
@@ -167,11 +165,11 @@ def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_s
|
||||
p.extra_generation_params["Mask blur"] = mask_blur
|
||||
if is_batch:
|
||||
process_batch(p, img2img_batch_input_dir, img2img_batch_output_dir, img2img_batch_inpaint_mask_dir, args)
|
||||
processed = Processed(p, [], p.seed, "")
|
||||
processed = processing.Processed(p, [], p.seed, "")
|
||||
else:
|
||||
processed = modules.scripts.scripts_img2img.run(p, *args)
|
||||
if processed is None:
|
||||
processed = process_images(p)
|
||||
processed = processing.process_images(p)
|
||||
p.close()
|
||||
generation_info_js = processed.js()
|
||||
shared.log.debug(f'Processed: {len(processed.images)} Memory: {memory_stats()} img')
|
||||
|
||||
@@ -3,15 +3,13 @@ import sys
|
||||
from collections import namedtuple
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
import torch
|
||||
import torch.hub # pylint: disable=ungrouped-imports
|
||||
|
||||
from torchvision import transforms
|
||||
from torchvision.transforms.functional import InterpolationMode
|
||||
|
||||
from modules import devices, paths, shared, lowvram, modelloader, errors
|
||||
|
||||
|
||||
blip_image_eval_size = 384
|
||||
clip_model_name = 'ViT-L/14'
|
||||
|
||||
@@ -157,7 +155,7 @@ class InterrogateModels:
|
||||
text_array = text_array[0:int(shared.opts.interrogate_clip_dict_limit)]
|
||||
|
||||
top_count = min(top_count, len(text_array))
|
||||
text_tokens = clip.tokenize([text for text in text_array], truncate=True).to(devices.device_interrogate)
|
||||
text_tokens = clip.tokenize(list(text_array), truncate=True).to(devices.device_interrogate)
|
||||
text_features = self.clip_model.encode_text(text_tokens).type(self.dtype)
|
||||
text_features /= text_features.norm(dim=-1, keepdim=True)
|
||||
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ class MemUsageMonitor(threading.Thread):
|
||||
self.data["reserved"] = torch_stats["reserved_bytes.all.current"]
|
||||
self.data["reserved_peak"] = torch_stats["reserved_bytes.all.peak"]
|
||||
self.data["system_peak"] = total - self.data["min_free"]
|
||||
except:
|
||||
except Exception:
|
||||
self.disabled = True
|
||||
return self.data
|
||||
|
||||
|
||||
+2
-2
@@ -27,7 +27,7 @@ def memory_stats():
|
||||
'oom': s['num_ooms']
|
||||
})
|
||||
return mem
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
gpu = { 'used': gb(torch.xpu.memory_allocated()), 'total': gb(torch.xpu.get_device_properties(shared.device).total_memory) }
|
||||
@@ -40,6 +40,6 @@ def memory_stats():
|
||||
if s['num_ooms'] > 0:
|
||||
shared.state.oom = True
|
||||
return mem
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
return mem
|
||||
|
||||
@@ -79,7 +79,7 @@ def load_models(model_path: str, model_url: str = None, command_path: str = None
|
||||
if os.path.islink(full_path) and not os.path.exists(full_path):
|
||||
print(f"Skipping broken symlink: {full_path}")
|
||||
continue
|
||||
if ext_blacklist is not None and any([full_path.endswith(x) for x in ext_blacklist]):
|
||||
if ext_blacklist is not None and any(full_path.endswith(x) for x in ext_blacklist):
|
||||
continue
|
||||
if full_path not in output:
|
||||
output.append(full_path)
|
||||
@@ -147,19 +147,18 @@ def move_files(src_path: str, dest_path: str, ext_filter: str = None):
|
||||
print(f"Moving {file} from {src_path} to {dest_path}.")
|
||||
try:
|
||||
shutil.move(fullpath, dest_path)
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
if len(os.listdir(src_path)) == 0:
|
||||
print(f"Removing empty folder: {src_path}")
|
||||
shutil.rmtree(src_path, True)
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
def load_upscalers():
|
||||
# We can only do this 'magic' method to dynamically load upscalers if they are referenced,
|
||||
# so we'll try to import any _model.py files before looking in __subclasses__
|
||||
# We can only do this 'magic' method to dynamically load upscalers if they are referenced, so we'll try to import any _model.py files before looking in __subclasses__
|
||||
modules_dir = os.path.join(shared.script_path, "modules")
|
||||
for file in os.listdir(modules_dir):
|
||||
if "_model.py" in file:
|
||||
@@ -167,14 +166,12 @@ def load_upscalers():
|
||||
full_model = f"modules.{model_name}_model"
|
||||
try:
|
||||
importlib.import_module(full_model)
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
datas = []
|
||||
commandline_options = vars(shared.cmd_opts)
|
||||
# some of upscaler classes will not go away after reloading their modules, and we'll end
|
||||
# up with two copies of those classes. The newest copy will always be the last in the list,
|
||||
# so we go from end to beginning and ignore duplicates
|
||||
# some of upscaler classes will not go away after reloading their modules, and we'll end up with two copies of those classes. The newest copy will always be the last in the list, so we go from end to beginning and ignore duplicates
|
||||
used_classes = {}
|
||||
for cls in reversed(Upscaler.__subclasses__()):
|
||||
classname = str(cls)
|
||||
|
||||
@@ -52,7 +52,7 @@ class DDPM(pl.LightningModule):
|
||||
beta_schedule="linear",
|
||||
loss_type="l2",
|
||||
ckpt_path=None,
|
||||
ignore_keys=[],
|
||||
ignore_keys=None,
|
||||
load_only_unet=False,
|
||||
monitor="val/loss",
|
||||
use_ema=True,
|
||||
@@ -107,7 +107,7 @@ class DDPM(pl.LightningModule):
|
||||
print(f"Keeping EMAs of {len(list(self.model_ema.buffers()))}.")
|
||||
|
||||
if ckpt_path is not None:
|
||||
self.init_from_ckpt(ckpt_path, ignore_keys=ignore_keys, only_model=load_only_unet)
|
||||
self.init_from_ckpt(ckpt_path, ignore_keys=ignore_keys or [], only_model=load_only_unet)
|
||||
|
||||
# If initialing from EMA-only checkpoint, create EMA model after loading.
|
||||
if self.use_ema and not load_ema:
|
||||
@@ -194,7 +194,8 @@ class DDPM(pl.LightningModule):
|
||||
if context is not None:
|
||||
print(f"{context}: Restored training weights")
|
||||
|
||||
def init_from_ckpt(self, path, ignore_keys=list(), only_model=False):
|
||||
def init_from_ckpt(self, path, ignore_keys=None, only_model=False):
|
||||
ignore_keys = ignore_keys or []
|
||||
sd = torch.load(path, map_location="cpu")
|
||||
if "state_dict" in list(sd.keys()):
|
||||
sd = sd["state_dict"]
|
||||
@@ -403,7 +404,7 @@ class DDPM(pl.LightningModule):
|
||||
|
||||
@torch.no_grad()
|
||||
def log_images(self, batch, N=8, n_row=2, sample=True, return_keys=None, **kwargs):
|
||||
log = dict()
|
||||
log = {}
|
||||
x = self.get_input(batch, self.first_stage_key)
|
||||
N = min(x.shape[0], N)
|
||||
n_row = min(x.shape[0], n_row)
|
||||
@@ -411,7 +412,7 @@ class DDPM(pl.LightningModule):
|
||||
log["inputs"] = x
|
||||
|
||||
# get diffusion row
|
||||
diffusion_row = list()
|
||||
diffusion_row = []
|
||||
x_start = x[:n_row]
|
||||
|
||||
for t in range(self.num_timesteps):
|
||||
@@ -473,13 +474,13 @@ class LatentDiffusion(DDPM):
|
||||
conditioning_key = None
|
||||
ckpt_path = kwargs.pop("ckpt_path", None)
|
||||
ignore_keys = kwargs.pop("ignore_keys", [])
|
||||
super().__init__(conditioning_key=conditioning_key, *args, load_ema=load_ema, **kwargs)
|
||||
super().__init__(*args, conditioning_key=conditioning_key, load_ema=load_ema, **kwargs)
|
||||
self.concat_mode = concat_mode
|
||||
self.cond_stage_trainable = cond_stage_trainable
|
||||
self.cond_stage_key = cond_stage_key
|
||||
try:
|
||||
self.num_downs = len(first_stage_config.params.ddconfig.ch_mult) - 1
|
||||
except:
|
||||
except Exception:
|
||||
self.num_downs = 0
|
||||
if not scale_by_std:
|
||||
self.scale_factor = scale_factor
|
||||
@@ -891,16 +892,6 @@ class LatentDiffusion(DDPM):
|
||||
c = self.q_sample(x_start=c, t=tc, noise=torch.randn_like(c.float()))
|
||||
return self.p_losses(x, c, t, *args, **kwargs)
|
||||
|
||||
def _rescale_annotations(self, bboxes, crop_coordinates): # TODO: move to dataset
|
||||
def rescale_bbox(bbox):
|
||||
x0 = clamp((bbox[0] - crop_coordinates[0]) / crop_coordinates[2])
|
||||
y0 = clamp((bbox[1] - crop_coordinates[1]) / crop_coordinates[3])
|
||||
w = min(bbox[2] / crop_coordinates[2], 1 - x0)
|
||||
h = min(bbox[3] / crop_coordinates[3], 1 - y0)
|
||||
return x0, y0, w, h
|
||||
|
||||
return [rescale_bbox(b) for b in bboxes]
|
||||
|
||||
def apply_model(self, x_noisy, t, cond, return_ids=False):
|
||||
|
||||
if isinstance(cond, dict):
|
||||
@@ -1140,7 +1131,7 @@ class LatentDiffusion(DDPM):
|
||||
if cond is not None:
|
||||
if isinstance(cond, dict):
|
||||
cond = {key: cond[key][:batch_size] if not isinstance(cond[key], list) else
|
||||
list(map(lambda x: x[:batch_size], cond[key])) for key in cond}
|
||||
[x[:batch_size] for x in cond[key]] for key in cond}
|
||||
else:
|
||||
cond = [c[:batch_size] for c in cond] if isinstance(cond, list) else cond[:batch_size]
|
||||
|
||||
@@ -1171,8 +1162,10 @@ class LatentDiffusion(DDPM):
|
||||
|
||||
if i % log_every_t == 0 or i == timesteps - 1:
|
||||
intermediates.append(x0_partial)
|
||||
if callback: callback(i)
|
||||
if img_callback: img_callback(img, i)
|
||||
if callback:
|
||||
callback(i)
|
||||
if img_callback:
|
||||
img_callback(img, i)
|
||||
return img, intermediates
|
||||
|
||||
@torch.no_grad()
|
||||
@@ -1235,7 +1228,7 @@ class LatentDiffusion(DDPM):
|
||||
if cond is not None:
|
||||
if isinstance(cond, dict):
|
||||
cond = {key: cond[key][:batch_size] if not isinstance(cond[key], list) else
|
||||
list(map(lambda x: x[:batch_size], cond[key])) for key in cond}
|
||||
[x[:batch_size] for x in cond[key]] for key in cond}
|
||||
else:
|
||||
cond = [c[:batch_size] for c in cond] if isinstance(cond, list) else cond[:batch_size]
|
||||
return self.p_sample_loop(cond,
|
||||
@@ -1267,7 +1260,7 @@ class LatentDiffusion(DDPM):
|
||||
|
||||
use_ddim = False
|
||||
|
||||
log = dict()
|
||||
log = {}
|
||||
z, c, x, xrec, xc = self.get_input(batch, self.first_stage_key,
|
||||
return_first_stage_outputs=True,
|
||||
force_c_encode=True,
|
||||
@@ -1337,7 +1330,7 @@ class LatentDiffusion(DDPM):
|
||||
|
||||
if inpaint:
|
||||
# make a simple center square
|
||||
b, h, w = z.shape[0], z.shape[2], z.shape[3]
|
||||
h, w = z.shape[2], z.shape[3]
|
||||
mask = torch.ones(N, h, w).to(self.device)
|
||||
# zeros will be filled in
|
||||
mask[:, h // 4:3 * h // 4, w // 4:3 * w // 4] = 0.
|
||||
@@ -1439,10 +1432,10 @@ class Layout2ImgDiffusion(LatentDiffusion):
|
||||
# TODO: move all layout-specific hacks to this class
|
||||
def __init__(self, cond_stage_key, *args, **kwargs):
|
||||
assert cond_stage_key == 'coordinates_bbox', 'Layout2ImgDiffusion only for cond_stage_key="coordinates_bbox"'
|
||||
super().__init__(cond_stage_key=cond_stage_key, *args, **kwargs)
|
||||
super().__init__(*args, cond_stage_key=cond_stage_key, **kwargs)
|
||||
|
||||
def log_images(self, batch, N=8, *args, **kwargs):
|
||||
logs = super().log_images(batch=batch, N=N, *args, **kwargs)
|
||||
logs = super().log_images(*args, batch=batch, N=N, **kwargs)
|
||||
|
||||
key = 'train' if self.training else 'validation'
|
||||
dset = self.trainer.datamodule.datasets[key]
|
||||
|
||||
@@ -147,7 +147,8 @@ class UniPCSampler(object):
|
||||
if conditioning is not None:
|
||||
if isinstance(conditioning, dict):
|
||||
ctmp = conditioning[list(conditioning.keys())[0]]
|
||||
while isinstance(ctmp, list): ctmp = ctmp[0]
|
||||
while isinstance(ctmp, list):
|
||||
ctmp = ctmp[0]
|
||||
cbs = ctmp.shape[0]
|
||||
if cbs != batch_size:
|
||||
print(f"Warning: Got {cbs} conditionings but batch-size is {batch_size}")
|
||||
|
||||
@@ -181,13 +181,13 @@ def model_wrapper(
|
||||
model,
|
||||
noise_schedule,
|
||||
model_type="noise",
|
||||
model_kwargs={},
|
||||
model_kwargs=None,
|
||||
guidance_type="uncond",
|
||||
#condition=None,
|
||||
#unconditional_condition=None,
|
||||
guidance_scale=1.,
|
||||
classifier_fn=None,
|
||||
classifier_kwargs={},
|
||||
classifier_kwargs=None,
|
||||
):
|
||||
"""Create a wrapper function for the noise prediction model.
|
||||
|
||||
@@ -346,7 +346,7 @@ def model_wrapper(
|
||||
t_in = torch.cat([t_continuous] * 2)
|
||||
if isinstance(condition, dict):
|
||||
assert isinstance(unconditional_condition, dict)
|
||||
c_in = dict()
|
||||
c_in = {}
|
||||
for k in condition:
|
||||
if isinstance(condition[k], list):
|
||||
c_in[k] = [torch.cat([
|
||||
@@ -357,7 +357,7 @@ def model_wrapper(
|
||||
unconditional_condition[k],
|
||||
condition[k]])
|
||||
elif isinstance(condition, list):
|
||||
c_in = list()
|
||||
c_in = []
|
||||
assert isinstance(unconditional_condition, list)
|
||||
for i in range(len(condition)):
|
||||
c_in.append(torch.cat([unconditional_condition[i], condition[i]]))
|
||||
|
||||
+1
-2
@@ -57,8 +57,7 @@ def create_paths(opts):
|
||||
if not os.path.exists(folder):
|
||||
try:
|
||||
os.makedirs(folder, exist_ok=True)
|
||||
# print('Creating folder:', folder)
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def fix_path(folder):
|
||||
|
||||
@@ -471,7 +471,7 @@ def create_infotext(p: StableDiffusionProcessing, all_prompts, all_seeds, all_su
|
||||
def print_profile(profile, msg: str):
|
||||
try:
|
||||
from rich import print # pylint: disable=redefined-builtin
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
lines = profile.key_averages().table(sort_by="cuda_time_total", row_limit=20)
|
||||
lines = lines.split('\n')
|
||||
@@ -485,7 +485,7 @@ def print_profile(profile, msg: str):
|
||||
import pstats
|
||||
try:
|
||||
from rich import print # pylint: disable=redefined-builtin
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
profile.disable()
|
||||
stream = io.StringIO()
|
||||
@@ -645,7 +645,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
|
||||
if not shared.opts.dont_fix_second_order_samplers_schedule:
|
||||
try:
|
||||
step_multiplier = 2 if sd_samplers.all_samplers_map.get(p.sampler_name).aliases[0] in ['k_dpmpp_2s_a', 'k_dpmpp_2s_a_ka', 'k_dpmpp_sde', 'k_dpmpp_sde_ka', 'k_dpm_2', 'k_dpm_2_a', 'k_heun'] else 1
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
if p.n_iter > 1:
|
||||
shared.state.job = f"Batch {n+1} out of {p.n_iter}"
|
||||
|
||||
@@ -102,18 +102,18 @@ def get_learned_conditioning_prompt_schedules(prompts, steps):
|
||||
"""
|
||||
|
||||
def collect_steps(steps, tree):
|
||||
l = [steps]
|
||||
res = [steps]
|
||||
class CollectSteps(lark.Visitor):
|
||||
def scheduled(self, tree):
|
||||
tree.children[-1] = float(tree.children[-1])
|
||||
if tree.children[-1] < 1:
|
||||
tree.children[-1] *= steps
|
||||
tree.children[-1] = min(steps, int(tree.children[-1]))
|
||||
l.append(tree.children[-1])
|
||||
res.append(tree.children[-1])
|
||||
def alternate(self, tree): # pylint: disable=unused-argument
|
||||
l.extend(range(1, steps+1))
|
||||
res.extend(range(1, steps+1))
|
||||
CollectSteps().visit(tree)
|
||||
return sorted(set(l))
|
||||
return sorted(set(res))
|
||||
|
||||
def at_step(step, tree):
|
||||
class AtStep(lark.Transformer):
|
||||
@@ -243,12 +243,12 @@ def reconstruct_multicond_batch(c: MulticondLearnedConditioning, current_step):
|
||||
param = c.batch[0][0].schedules[0].cond
|
||||
tensors = []
|
||||
conds_list = []
|
||||
for _batch_no, composable_prompts in enumerate(c.batch):
|
||||
for composable_prompts in c.batch:
|
||||
conds_for_batch = []
|
||||
for _cond_index, composable_prompt in enumerate(composable_prompts):
|
||||
for composable_prompt in composable_prompts:
|
||||
target_index = 0
|
||||
for current, (end_at, _cond) in enumerate(composable_prompt.schedules):
|
||||
if current_step <= end_at:
|
||||
for current, entry in enumerate(composable_prompt.schedules):
|
||||
if current_step <= entry.end_at_step:
|
||||
target_index = current
|
||||
break
|
||||
conds_for_batch.append((len(tensors), composable_prompt.weight))
|
||||
|
||||
@@ -42,7 +42,7 @@ class UpscalerRealESRGAN(Upscaler):
|
||||
|
||||
try:
|
||||
from realesrgan import RealESRGANer
|
||||
except:
|
||||
except Exception:
|
||||
print("Error importing Real-ESRGAN:", file=sys.stderr)
|
||||
return img
|
||||
|
||||
|
||||
+1
-1
@@ -102,7 +102,7 @@ def check_pt(filename, extra_handler):
|
||||
|
||||
|
||||
def load(filename, *args, **kwargs):
|
||||
return load_with_extra(filename, extra_handler=global_extra_handler, *args, **kwargs)
|
||||
return load_with_extra(filename, *args, extra_handler=global_extra_handler, **kwargs)
|
||||
|
||||
|
||||
def load_with_extra(filename, extra_handler=None, *args, **kwargs): # pylint: disable=keyword-arg-before-vararg
|
||||
|
||||
+2
-2
@@ -222,7 +222,7 @@ def load_scripts():
|
||||
time_load = {}
|
||||
|
||||
def register_scripts_from_module(module, scriptfile):
|
||||
for _key, script_class in module.__dict__.items():
|
||||
for script_class in module.__dict__.values():
|
||||
if type(script_class) != type:
|
||||
continue
|
||||
# log.debug(f'Registering script: {scriptfile.path}')
|
||||
@@ -487,7 +487,7 @@ class ScriptRunner:
|
||||
if module is None:
|
||||
module = script_loading.load_module(script.filename)
|
||||
cache[filename] = module
|
||||
for _key, script_class in module.__dict__.items():
|
||||
for script_class in module.__dict__.values():
|
||||
if type(script_class) == type and issubclass(script_class, Script):
|
||||
self.scripts[si] = script_class()
|
||||
self.scripts[si].filename = filename
|
||||
|
||||
@@ -17,7 +17,7 @@ class ScriptPostprocessingForMainUI(scripts.Script):
|
||||
return self.postprocessing_controls.values()
|
||||
|
||||
def postprocess_image(self, p, script_pp, *args): # pylint: disable=arguments-differ
|
||||
args_dict = {k: v for k, v in zip(self.postprocessing_controls, args)}
|
||||
args_dict = dict(zip(self.postprocessing_controls, args))
|
||||
|
||||
pp = scripts_postprocessing.PostprocessedImage(script_pp.image)
|
||||
pp.info = {}
|
||||
|
||||
@@ -24,7 +24,7 @@ def p_sample_plms(self, x, c, t, index, repeat_noise=False, use_original_steps=F
|
||||
|
||||
if isinstance(c, dict):
|
||||
assert isinstance(unconditional_conditioning, dict)
|
||||
c_in = dict()
|
||||
c_in = {}
|
||||
for k in c:
|
||||
if isinstance(c[k], list):
|
||||
c_in[k] = [
|
||||
|
||||
@@ -44,7 +44,7 @@ def get_available_vram():
|
||||
mem_free_cuda, _ = torch.cuda.mem_get_info(torch.cuda.current_device())
|
||||
mem_free_torch = mem_reserved - mem_active
|
||||
mem_free_total = mem_free_cuda + mem_free_torch
|
||||
except:
|
||||
except Exception:
|
||||
mem_free_total = 1024 * 1024 * 1024
|
||||
|
||||
return mem_free_total
|
||||
@@ -206,7 +206,7 @@ def einsum_op_cuda(q, k, v):
|
||||
mem_free_cuda, _ = torch.cuda.mem_get_info(q.device)
|
||||
mem_free_torch = mem_reserved - mem_active
|
||||
mem_free_total = mem_free_cuda + mem_free_torch
|
||||
except:
|
||||
except Exception:
|
||||
mem_free_total = 1024 * 1024 * 1024
|
||||
# Divide factor of safety as there's copying and fragmentation
|
||||
return einsum_op_tensor_mem(q, k, v, mem_free_total / 3.3 / (1 << 20))
|
||||
@@ -319,7 +319,6 @@ def sub_quad_attention(q, k, v, q_chunk_size=1024, kv_chunk_size=None, kv_chunk_
|
||||
if chunk_threshold_bytes is not None and qk_matmul_size_bytes <= chunk_threshold_bytes:
|
||||
# the big matmul fits into our memory limit; do everything in 1 chunk,
|
||||
# i.e. send it down the unchunked fast-path
|
||||
query_chunk_size = q_tokens # pylint: disable=unused-variable
|
||||
kv_chunk_size = k_tokens
|
||||
|
||||
with devices.without_autocast(disable=q.dtype == v.dtype):
|
||||
|
||||
+52
-27
@@ -2,9 +2,11 @@ import collections
|
||||
import os.path
|
||||
import re
|
||||
import io
|
||||
import json
|
||||
import threading
|
||||
from os import mkdir
|
||||
from urllib import request
|
||||
import filelock
|
||||
from rich import progress # pylint: disable=redefined-builtin
|
||||
import torch
|
||||
import safetensors.torch
|
||||
@@ -28,6 +30,7 @@ checkpoints_loaded = collections.OrderedDict()
|
||||
skip_next_load = False
|
||||
sd_metadata_file = os.path.join(paths.data_path, "metadata.json")
|
||||
sd_metadata = None
|
||||
sd_metadata_pending = 0
|
||||
|
||||
|
||||
class CheckpointInfo:
|
||||
@@ -188,7 +191,7 @@ def model_hash(filename):
|
||||
return m.hexdigest()[0:8]
|
||||
except FileNotFoundError:
|
||||
return 'NOFILE'
|
||||
except:
|
||||
except Exception:
|
||||
return 'NOHASH'
|
||||
|
||||
|
||||
@@ -237,40 +240,62 @@ def get_state_dict_from_checkpoint(pl_sd):
|
||||
return pl_sd
|
||||
|
||||
|
||||
def write_metadata():
|
||||
def default(obj):
|
||||
shared.log.debug(f"Model metadata not a valid object: {obj}")
|
||||
return str(obj)
|
||||
|
||||
global sd_metadata_pending # pylint: disable=global-statement
|
||||
if sd_metadata_pending == 0:
|
||||
shared.log.debug(f"Model metadata: {sd_metadata_file} no changes")
|
||||
return
|
||||
with filelock.FileLock(f"{sd_metadata_file}.lock"):
|
||||
try:
|
||||
with open(sd_metadata_file, "w", encoding="utf8") as file:
|
||||
json.dump(sd_metadata, file, indent=4, skipkeys=True, ensure_ascii=True, check_circular=True, allow_nan=True, default=default)
|
||||
except Exception as e:
|
||||
shared.log.error(f"Model metadata save error: {sd_metadata_file} {e}")
|
||||
shared.log.info(f"Model metadata saved: {sd_metadata_file} {sd_metadata_pending}")
|
||||
sd_metadata_pending = 0
|
||||
|
||||
|
||||
def read_metadata_from_safetensors(filename):
|
||||
import json
|
||||
global sd_metadata # pylint: disable=global-statement
|
||||
if sd_metadata is None:
|
||||
if not os.path.isfile(sd_metadata_file):
|
||||
sd_metadata = {}
|
||||
else:
|
||||
try:
|
||||
with open(sd_metadata_file, "r", encoding="utf8") as file:
|
||||
sd_metadata = json.load(file)
|
||||
except:
|
||||
with filelock.FileLock(f"{sd_metadata_file}.lock"):
|
||||
if not os.path.isfile(sd_metadata_file):
|
||||
sd_metadata = {}
|
||||
else:
|
||||
try:
|
||||
with open(sd_metadata_file, "r", encoding="utf8") as file:
|
||||
sd_metadata = json.load(file)
|
||||
except Exception:
|
||||
sd_metadata = {}
|
||||
res = sd_metadata.get(filename, None)
|
||||
if res is not None:
|
||||
return res
|
||||
|
||||
res = {}
|
||||
with open(filename, mode="rb") as file:
|
||||
metadata_len = file.read(8)
|
||||
metadata_len = int.from_bytes(metadata_len, "little")
|
||||
json_start = file.read(2)
|
||||
assert metadata_len > 2 and json_start in (b'{"', b"{'"), f"{filename} is not a safetensors file"
|
||||
json_data = json_start + file.read(metadata_len-2)
|
||||
json_obj = json.loads(json_data)
|
||||
for k, v in json_obj.get("__metadata__", {}).items():
|
||||
res[k] = v
|
||||
if isinstance(v, str) and v[0:1] == '{':
|
||||
try:
|
||||
res[k] = json.loads(v)
|
||||
except Exception:
|
||||
pass
|
||||
sd_metadata[filename] = res
|
||||
with open(sd_metadata_file, "w", encoding="utf8") as file:
|
||||
json.dump(sd_metadata, file, indent=4)
|
||||
try:
|
||||
with open(filename, mode="rb") as file:
|
||||
metadata_len = file.read(8)
|
||||
metadata_len = int.from_bytes(metadata_len, "little")
|
||||
json_start = file.read(2)
|
||||
if metadata_len <= 2 or json_start not in (b'{"', b"{'"):
|
||||
shared.log.error(f"Not a valid safetensors file: {filename}")
|
||||
json_data = json_start + file.read(metadata_len-2)
|
||||
json_obj = json.loads(json_data)
|
||||
for k, v in json_obj.get("__metadata__", {}).items():
|
||||
res[k] = v
|
||||
if isinstance(v, str) and v[0:1] == '{':
|
||||
try:
|
||||
res[k] = json.loads(v)
|
||||
except Exception:
|
||||
pass
|
||||
sd_metadata[filename] = res
|
||||
global sd_metadata_pending # pylint: disable=global-statement
|
||||
sd_metadata_pending += 1
|
||||
except Exception as e:
|
||||
shared.log.error(f"Error reading metadata from: {filename} {e}")
|
||||
return res
|
||||
|
||||
|
||||
|
||||
@@ -329,7 +329,7 @@ class KDiffusionSampler:
|
||||
if cmd_opts.use_ipex: #Remove this after Intel adds support for torch.Generator()
|
||||
try:
|
||||
return BrownianTreeNoiseSampler(x.to("cpu"), sigma_min, sigma_max, seed=current_iter_seeds, transform=lambda x: x.to("cpu"), transform_last=lambda x: x.to(shared.device)) # pylint: disable=E1123
|
||||
except:
|
||||
except Exception:
|
||||
print("ERROR Please apply this patch to repositories/k-diffusion/k_diffusion/sampling.py: https://github.com/crowsonkb/k-diffusion/pull/68/files")
|
||||
return None
|
||||
else:
|
||||
|
||||
+8
-10
@@ -269,7 +269,7 @@ def refresh_themes():
|
||||
f.write(json.dumps(res))
|
||||
else:
|
||||
log.error('Error refreshing UI themes')
|
||||
except:
|
||||
except Exception:
|
||||
log.error('Exception refreshing UI themes')
|
||||
|
||||
|
||||
@@ -288,6 +288,7 @@ else: # cuda
|
||||
|
||||
options_templates.update(options_section(('sd', "Stable Diffusion"), {
|
||||
"sd_model_checkpoint": OptionInfo(default_checkpoint, "Stable Diffusion checkpoint", gr.Dropdown, lambda: {"choices": list_checkpoint_tiles()}, refresh=refresh_checkpoints),
|
||||
"sd_checkpoint_autoload": OptionInfo(True, "Stable Diffusion checkpoint autoload on server start"),
|
||||
"sd_checkpoint_cache": OptionInfo(0, "Number of cached model checkpoints", gr.Slider, {"minimum": 0, "maximum": 10, "step": 1}),
|
||||
"sd_vae_checkpoint_cache": OptionInfo(0, "Number of cached VAE checkpoints", gr.Slider, {"minimum": 0, "maximum": 10, "step": 1}),
|
||||
"sd_vae": OptionInfo("Automatic", "Select VAE", gr.Dropdown, lambda: {"choices": shared_items.sd_vae_items()}, refresh=shared_items.refresh_vae_list),
|
||||
@@ -660,10 +661,10 @@ class Options:
|
||||
"""reorder settings so that all items related to section always go together"""
|
||||
section_ids = {}
|
||||
settings_items = self.data_labels.items()
|
||||
for k, item in settings_items:
|
||||
for _k, item in settings_items:
|
||||
if item.section not in section_ids:
|
||||
section_ids[item.section] = len(section_ids)
|
||||
self.data_labels = {k: v for k, v in sorted(settings_items, key=lambda x: section_ids[x[1].section])}
|
||||
self.data_labels = dict(sorted(settings_items, key=lambda x: section_ids[x[1].section]))
|
||||
|
||||
def cast_value(self, key, value):
|
||||
"""casts an arbitrary to the same type as this setting's value with key
|
||||
@@ -719,7 +720,7 @@ def reload_gradio_theme(theme_name=None):
|
||||
try:
|
||||
req = urllib.request.Request("https://fonts.googleapis.com/css2?family=IBM+Plex+Mono", method="HEAD")
|
||||
res = urllib.request.urlopen(req, timeout=3.0).status
|
||||
except:
|
||||
except Exception:
|
||||
res = 0
|
||||
if res != 200:
|
||||
log.info('No internet access detected, using default fonts')
|
||||
@@ -743,7 +744,7 @@ def reload_gradio_theme(theme_name=None):
|
||||
else:
|
||||
try:
|
||||
gradio_theme = gr.themes.ThemeClass.from_hub(theme_name)
|
||||
except:
|
||||
except Exception:
|
||||
log.error("Theme download error accessing HuggingFace")
|
||||
gradio_theme = gr.themes.Default(**default_font_params)
|
||||
log.info(f'Loading UI theme: name={theme_name} style={opts.theme_style}')
|
||||
@@ -794,7 +795,7 @@ def restart_server(restart=True):
|
||||
demo.close(verbose=False)
|
||||
demo.server.close()
|
||||
demo.fns = []
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
if restart:
|
||||
log.info('Server will restart')
|
||||
@@ -804,9 +805,6 @@ def restore_defaults(restart=True):
|
||||
if os.path.exists(cmd_opts.config):
|
||||
log.info('Restoring server defaults')
|
||||
os.remove(cmd_opts.config)
|
||||
if os.path.exists(cmd_opts.ui_config):
|
||||
log.info('Restoring UI defaults')
|
||||
os.remove(cmd_opts.ui_config)
|
||||
restart_server(restart)
|
||||
|
||||
|
||||
@@ -859,7 +857,7 @@ def get_version():
|
||||
'hash': githash,
|
||||
'url': origin.replace('\n', '') + '/tree/' + branch.replace('\n', '')
|
||||
}
|
||||
except:
|
||||
except Exception:
|
||||
version = { 'app': 'sd.next' }
|
||||
return version
|
||||
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ class StyleDatabase:
|
||||
prompt = row["prompt"] if "prompt" in row else row["text"]
|
||||
negative_prompt = row.get("negative_prompt", "")
|
||||
self.styles[row["name"]] = PromptStyle(row["name"], prompt, negative_prompt)
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def get_style_prompts(self, styles):
|
||||
|
||||
@@ -16,6 +16,7 @@ from typing import Optional, NamedTuple, List
|
||||
import torch
|
||||
from torch import Tensor
|
||||
from torch.utils.checkpoint import checkpoint
|
||||
import numpy as np
|
||||
|
||||
|
||||
def narrow_trunc(
|
||||
@@ -201,13 +202,14 @@ def efficient_dot_product_attention(
|
||||
value=value,
|
||||
)
|
||||
|
||||
# maybe we should use torch.empty_like(query) to allocate storage in-advance,
|
||||
# and pass slices to be mutated, instead of torch.cat()ing the returned slices
|
||||
res = torch.cat([
|
||||
compute_query_chunk_attn(
|
||||
res = torch.zeros_like(query)
|
||||
for i in range(math.ceil(q_tokens / query_chunk_size)):
|
||||
attn_scores = compute_query_chunk_attn(
|
||||
query=get_query_chunk(i * query_chunk_size),
|
||||
key=key,
|
||||
value=value,
|
||||
) for i in range(math.ceil(q_tokens / query_chunk_size))
|
||||
], dim=1)
|
||||
)
|
||||
|
||||
res[:, i * query_chunk_size:i * query_chunk_size + attn_scores.shape[1], :] = attn_scores
|
||||
|
||||
return res
|
||||
|
||||
@@ -183,7 +183,7 @@ def image_face_points(im, settings):
|
||||
try:
|
||||
faces = classifier.detectMultiScale(gray, scaleFactor=1.1,
|
||||
minNeighbors=7, minSize=(minsize, minsize), flags=cv2.CASCADE_SCALE_IMAGE)
|
||||
except:
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
if len(faces) > 0:
|
||||
|
||||
@@ -16,7 +16,7 @@ class EmbeddingEncoder(json.JSONEncoder):
|
||||
|
||||
class EmbeddingDecoder(json.JSONDecoder):
|
||||
def __init__(self, *args, **kwargs):
|
||||
json.JSONDecoder.__init__(self, object_hook=self.object_hook, *args, **kwargs)
|
||||
json.JSONDecoder.__init__(self, *args, object_hook=self.object_hook, **kwargs)
|
||||
|
||||
def object_hook(self, d):
|
||||
if 'TORCHTENSOR' in d:
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
import tqdm
|
||||
|
||||
|
||||
class LearnScheduleIterator:
|
||||
def __init__(self, learn_rate, max_steps, cur_step=0):
|
||||
"""
|
||||
@@ -12,7 +9,7 @@ class LearnScheduleIterator:
|
||||
self.it = 0
|
||||
self.maxit = 0
|
||||
try:
|
||||
for i, pair in enumerate(pairs):
|
||||
for pair in pairs:
|
||||
if not pair.strip():
|
||||
continue
|
||||
tmp = pair.split(':')
|
||||
@@ -32,8 +29,8 @@ class LearnScheduleIterator:
|
||||
self.maxit += 1
|
||||
return
|
||||
assert self.rates
|
||||
except (ValueError, AssertionError):
|
||||
raise Exception('Invalid learning rate schedule. It should be a number or, for example, like "0.001:100, 0.00001:1000, 1e-5:10000" to have lr of 0.001 until step 100, 0.00001 until 1000, and 1e-5 until 10000.')
|
||||
except (ValueError, AssertionError) as e:
|
||||
raise Exception('Invalid learning rate schedule. It should be a number or, for example, like "0.001:100, 0.00001:1000, 1e-5:10000" to have lr of 0.001 until step 100, 0.00001 until 1000, and 1e-5 until 10000.') from e
|
||||
|
||||
|
||||
def __iter__(self):
|
||||
|
||||
@@ -210,7 +210,7 @@ class EmbeddingDatabase:
|
||||
return
|
||||
if not force_reload:
|
||||
need_reload = False
|
||||
for _path, embdir in self.embedding_dirs.items():
|
||||
for embdir in self.embedding_dirs.values():
|
||||
if embdir.has_changed():
|
||||
need_reload = True
|
||||
break
|
||||
@@ -223,7 +223,7 @@ class EmbeddingDatabase:
|
||||
self.skipped_embeddings.clear()
|
||||
self.expected_shape = self.get_expected_shape()
|
||||
|
||||
for _path, embdir in self.embedding_dirs.items():
|
||||
for embdir in self.embedding_dirs.values():
|
||||
self.load_from_dir(embdir)
|
||||
embdir.update()
|
||||
|
||||
@@ -620,7 +620,7 @@ def save_embedding(embedding, optimizer, checkpoint, embedding_name, filename, r
|
||||
embedding.name = embedding_name
|
||||
embedding.optimizer_state_dict = optimizer.state_dict()
|
||||
embedding.save(filename)
|
||||
except:
|
||||
except Exception:
|
||||
embedding.sd_checkpoint = old_sd_checkpoint
|
||||
embedding.sd_checkpoint_name = old_sd_checkpoint_name
|
||||
embedding.name = old_embedding_name
|
||||
|
||||
+3
-5
@@ -1,8 +1,6 @@
|
||||
import modules.scripts
|
||||
from modules import sd_samplers, shared
|
||||
from modules import sd_samplers, shared, processing
|
||||
from modules.generation_parameters_copypaste import create_override_settings_dict
|
||||
from modules.processing import StableDiffusionProcessingTxt2Img, process_images
|
||||
# from modules.shared import opts, sd_model, debug
|
||||
from modules.ui import plaintext_to_html, infotext_to_html
|
||||
from modules.memstats import memory_stats
|
||||
|
||||
@@ -19,7 +17,7 @@ def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, step
|
||||
shared.log.warning('Model not loaded')
|
||||
return
|
||||
|
||||
p = StableDiffusionProcessingTxt2Img(
|
||||
p = processing.StableDiffusionProcessingTxt2Img(
|
||||
sd_model=shared.sd_model,
|
||||
outpath_samples=shared.opts.outdir_samples or shared.opts.outdir_txt2img_samples,
|
||||
outpath_grids=shared.opts.outdir_grids or shared.opts.outdir_txt2img_grids,
|
||||
@@ -55,7 +53,7 @@ def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, step
|
||||
p.script_args = args
|
||||
processed = modules.scripts.scripts_txt2img.run(p, *args)
|
||||
if processed is None:
|
||||
processed = process_images(p)
|
||||
processed = processing.process_images(p)
|
||||
p.close()
|
||||
generation_info_js = processed.js()
|
||||
shared.log.debug(f'Processed: {len(processed.images)} Memory: {memory_stats()} txt')
|
||||
|
||||
+18
-107
@@ -10,7 +10,7 @@ import numpy as np
|
||||
from PIL import Image
|
||||
from modules.call_queue import wrap_gradio_gpu_call, wrap_queued_call, wrap_gradio_call
|
||||
|
||||
from modules import sd_hijack, sd_models, script_callbacks, ui_extensions, deepbooru, sd_vae, extra_networks, ui_common, ui_postprocessing
|
||||
from modules import sd_hijack, sd_models, script_callbacks, ui_extensions, deepbooru, sd_vae, extra_networks, ui_common, ui_postprocessing, ui_loadsave
|
||||
from modules.ui_components import FormRow, FormColumn, FormGroup, ToolButton, FormHTML # pylint: disable=unused-import
|
||||
from modules.paths import script_path, data_path
|
||||
from modules.shared import opts, cmd_opts, backend, Backend
|
||||
@@ -73,17 +73,6 @@ def send_gradio_gallery_to_image(x):
|
||||
return parameters_copypaste.image_from_url_text(x[0])
|
||||
|
||||
|
||||
def visit(x, func, path=""):
|
||||
if hasattr(x, 'children'):
|
||||
if isinstance(x, gr.Tabs) and x.elem_id is not None:
|
||||
# Tabs element can't have a label, have to use elem_id instead
|
||||
func(f"{path}/Tabs@{x.elem_id}", x)
|
||||
for c in x.children:
|
||||
visit(c, func, path)
|
||||
elif x.label is not None:
|
||||
func(f"{path}/{x.label}", x)
|
||||
|
||||
|
||||
def add_style(name: str, prompt: str, negative_prompt: str):
|
||||
if name is None:
|
||||
return [gr_show() for x in range(4)]
|
||||
@@ -599,7 +588,6 @@ def create_ui():
|
||||
img2img_batch_inpaint_mask_dir = gr.Textbox(label="Inpaint batch mask directory", **modules.shared.hide_dirs, elem_id="img2img_batch_inpaint_mask_dir")
|
||||
|
||||
img2img_tabs = [tab_img2img, tab_sketch, tab_inpaint, tab_inpaint_color, tab_inpaint_upload, tab_batch]
|
||||
img2img_image_inputs = [init_img, sketch, init_img_with_mask, inpaint_color_sketch] # pylint: disable=unused-variable
|
||||
|
||||
for i, tab in enumerate(img2img_tabs):
|
||||
tab.select(fn=lambda tabnum=i: tabnum, inputs=[], outputs=[img2img_selected_tab])
|
||||
@@ -900,7 +888,7 @@ def create_ui():
|
||||
with gr.Blocks(analytics_enabled=False) as train_interface:
|
||||
with gr.Column(elem_id='ti_train_container'):
|
||||
with gr.Tabs(elem_id="train_tabs"):
|
||||
with gr.Tab(label="Merge models") as modelmerger_interface:
|
||||
with gr.Tab(label="Merge models"):
|
||||
with gr.Row().style(equal_height=False):
|
||||
with gr.Column(variant='compact'):
|
||||
with FormRow(elem_id="modelmerger_models"):
|
||||
@@ -1040,7 +1028,7 @@ def create_ui():
|
||||
)
|
||||
|
||||
def get_textual_inversion_template_names():
|
||||
return sorted([x for x in textual_inversion.textual_inversion_templates])
|
||||
return sorted(textual_inversion.textual_inversion_templates)
|
||||
|
||||
with gr.Tab(label="Train", id="train"):
|
||||
gr.HTML(value="<p style='margin-bottom: 0.7em'>Train an embedding or Hypernetwork; you must specify a directory with a set of 1:1 ratio images</p>")
|
||||
@@ -1100,8 +1088,8 @@ def create_ui():
|
||||
|
||||
with gr.Column(elem_id='ti_gallery_container'):
|
||||
ti_output = gr.Text(elem_id="ti_output", value="", show_label=False)
|
||||
_ti_gallery = gr.Gallery(label='Output', show_label=False, elem_id='ti_gallery').style(columns=4)
|
||||
_ti_progress = gr.HTML(elem_id="ti_progress", value="")
|
||||
gr.Gallery(label='Output', show_label=False, elem_id='ti_gallery').style(columns=4)
|
||||
gr.HTML(elem_id="ti_progress", value="")
|
||||
ti_outcome = gr.HTML(elem_id="ti_error", value="")
|
||||
|
||||
create_embedding.click(
|
||||
@@ -1316,6 +1304,7 @@ def create_ui():
|
||||
indicator.click(fn=get_opt_values, outputs=elements_to_reset, show_progress=False)
|
||||
return indicator
|
||||
|
||||
loadsave = ui_loadsave.UiLoadsave(cmd_opts.ui_config)
|
||||
components = []
|
||||
component_dict = {}
|
||||
modules.shared.settings_components = component_dict
|
||||
@@ -1402,6 +1391,9 @@ def create_ui():
|
||||
current_tab.__exit__()
|
||||
|
||||
request_notifications = gr.Button(value='Request browser notifications', elem_id="request_notifications", visible=False)
|
||||
with gr.TabItem("User interface defaults", id="defaults", elem_id="settings_tab_defaults"):
|
||||
loadsave.create_ui()
|
||||
create_dirty_indicator("tab_defaults", [], interactive=False)
|
||||
with gr.TabItem("Licenses", id="licenses", elem_id="settings_tab_licenses"):
|
||||
gr.HTML(modules.shared.html("licenses.html"), elem_id="licenses")
|
||||
create_dirty_indicator("tab_licenses", [], interactive=False)
|
||||
@@ -1472,7 +1464,12 @@ def create_ui():
|
||||
continue
|
||||
with gr.TabItem(label, id=ifid, elem_id=f"tab_{ifid}"):
|
||||
interface.render()
|
||||
|
||||
for interface, _label, ifid in interfaces:
|
||||
if ifid in ["extensions", "settings"]:
|
||||
continue
|
||||
loadsave.add_block(interface, ifid)
|
||||
loadsave.add_component(f"webui/Tabs@{tabs.elem_id}", tabs)
|
||||
loadsave.setup_ui()
|
||||
if opts.notification_audio_enable and os.path.exists(os.path.join(script_path, opts.notification_audio_path)):
|
||||
gr.Audio(interactive=False, value=os.path.join(script_path, opts.notification_audio_path), elem_id="audio_notification", visible=False)
|
||||
|
||||
@@ -1561,95 +1558,9 @@ def create_ui():
|
||||
)
|
||||
model_checkhash.click(fn=sd_models.update_model_hashes, inputs=[], outputs=[modelmerger_result])
|
||||
|
||||
ui_config_file = cmd_opts.ui_config
|
||||
ui_settings = {}
|
||||
settings_count = len(ui_settings)
|
||||
error_loading = False
|
||||
|
||||
try:
|
||||
if os.path.exists(ui_config_file):
|
||||
with open(ui_config_file, "r", encoding="utf8") as file:
|
||||
ui_settings = json.load(file)
|
||||
except Exception as e:
|
||||
error_loading = True
|
||||
modules.errors.display(e, 'loading ui settings')
|
||||
|
||||
def loadsave(path, x):
|
||||
def apply_field(obj, field, condition=None, init_field=None):
|
||||
key = f"{path}/{field}"
|
||||
|
||||
if getattr(obj, 'custom_script_source', None) is not None:
|
||||
key = f"customscript/{obj.custom_script_source}/{key}"
|
||||
|
||||
if getattr(obj, 'do_not_save_to_config', False):
|
||||
return
|
||||
|
||||
saved_value = ui_settings.get(key, None)
|
||||
if saved_value is None:
|
||||
ui_settings[key] = getattr(obj, field)
|
||||
elif condition and not condition(saved_value):
|
||||
pass
|
||||
else:
|
||||
setattr(obj, field, saved_value)
|
||||
if init_field is not None:
|
||||
init_field(saved_value)
|
||||
|
||||
if type(x) in [gr.Slider, gr.Radio, gr.Checkbox, gr.Textbox, gr.Number, gr.Dropdown, ToolButton] and x.visible:
|
||||
apply_field(x, 'visible')
|
||||
|
||||
if type(x) == gr.Slider:
|
||||
apply_field(x, 'value')
|
||||
apply_field(x, 'minimum')
|
||||
apply_field(x, 'maximum')
|
||||
apply_field(x, 'step')
|
||||
|
||||
if type(x) == gr.Radio:
|
||||
apply_field(x, 'value', lambda val: val in x.choices)
|
||||
|
||||
if type(x) == gr.Checkbox:
|
||||
apply_field(x, 'value')
|
||||
|
||||
if type(x) == gr.Textbox:
|
||||
apply_field(x, 'value')
|
||||
|
||||
if type(x) == gr.Number:
|
||||
apply_field(x, 'value')
|
||||
|
||||
if type(x) == gr.Dropdown:
|
||||
def check_dropdown(val):
|
||||
if getattr(x, 'multiselect', False):
|
||||
return all([value in x.choices for value in val])
|
||||
else:
|
||||
return val in x.choices
|
||||
|
||||
apply_field(x, 'value', check_dropdown, getattr(x, 'init_field', None))
|
||||
|
||||
def check_tab_id(tab_id):
|
||||
tab_items = list(filter(lambda e: isinstance(e, gr.TabItem), x.children))
|
||||
if type(tab_id) == str:
|
||||
tab_ids = [t.id for t in tab_items]
|
||||
return tab_id in tab_ids
|
||||
elif type(tab_id) == int:
|
||||
return tab_id >= 0 and tab_id < len(tab_items)
|
||||
else:
|
||||
return False
|
||||
|
||||
if type(x) == gr.Tabs:
|
||||
apply_field(x, 'selected', check_tab_id)
|
||||
|
||||
visit(txt2img_interface, loadsave, "txt2img")
|
||||
visit(img2img_interface, loadsave, "img2img")
|
||||
visit(extras_interface, loadsave, "extras")
|
||||
visit(modelmerger_interface, loadsave, "modelmerger")
|
||||
visit(train_interface, loadsave, "train")
|
||||
loadsave(f"webui/Tabs@{tabs.elem_id}", tabs)
|
||||
|
||||
if not error_loading and (not os.path.exists(ui_config_file) or settings_count != len(ui_settings)):
|
||||
with open(ui_config_file, "w", encoding="utf8") as file:
|
||||
json.dump(ui_settings, file, indent=4)
|
||||
|
||||
# Required as a workaround for change() event not triggering when loading values from ui-config.json
|
||||
interp_description.value = update_interp_description(interp_method.value)
|
||||
loadsave.dump_defaults()
|
||||
demo.ui_loadsave = loadsave
|
||||
interp_description.value = update_interp_description(interp_method.value) # Required as a workaround for change() event not triggering when loading values from ui-config.json
|
||||
|
||||
return demo
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ def update_extension_list():
|
||||
with open(os.path.join(paths.script_path, "html", "extensions.json"), "r", encoding="utf-8") as f:
|
||||
extensions_list = json.loads(f.read())
|
||||
shared.log.debug(f'Extensions list loaded: {os.path.join(paths.script_path, "html", "extensions.json")}')
|
||||
except:
|
||||
except Exception:
|
||||
shared.log.debug(f'Extensions list failed to load: {os.path.join(paths.script_path, "html", "extensions.json")}')
|
||||
found = []
|
||||
for ext in extensions.extensions:
|
||||
|
||||
@@ -23,7 +23,7 @@ def register_page(page):
|
||||
|
||||
def fetch_file(filename: str = ""):
|
||||
from starlette.responses import FileResponse, JSONResponse
|
||||
if not any([Path(x).absolute() in Path(filename).absolute().parents for x in allowed_dirs]):
|
||||
if not any(Path(x).absolute() in Path(filename).absolute().parents for x in allowed_dirs):
|
||||
return JSONResponse({"error": f"File cannot be fetched: {filename}. Must be in one of directories registered by extra pages."})
|
||||
if os.path.splitext(filename)[1].lower() not in (".png", ".jpg", ".webp"):
|
||||
return JSONResponse({"error": f"File cannot be fetched: {filename}. Only png and jpg and webp."})
|
||||
@@ -284,7 +284,7 @@ def setup_ui(ui, gallery):
|
||||
image = image_from_url_text(img_info)
|
||||
is_allowed = False
|
||||
for extra_page in ui.stored_extra_pages:
|
||||
if any([path_is_parent(x, filename) for x in extra_page.allowed_directories_for_previews()]):
|
||||
if any(path_is_parent(x, filename) for x in extra_page.allowed_directories_for_previews()):
|
||||
is_allowed = True
|
||||
break
|
||||
assert is_allowed, f'writing to {filename} is not allowed'
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
import json
|
||||
import os
|
||||
|
||||
import gradio as gr
|
||||
|
||||
from modules import errors
|
||||
from modules.ui_components import ToolButton
|
||||
|
||||
|
||||
class UiLoadsave:
|
||||
"""allows saving and restorig default values for gradio components"""
|
||||
|
||||
def __init__(self, filename):
|
||||
self.filename = filename
|
||||
self.ui_settings = {}
|
||||
self.component_mapping = {}
|
||||
self.error_loading = False
|
||||
self.finalized_ui = False
|
||||
self.ui_defaults_view = None
|
||||
self.ui_defaults_apply = None
|
||||
self.ui_defaults_review = None
|
||||
self.ui_defaults_restore = None
|
||||
try:
|
||||
if os.path.exists(self.filename):
|
||||
self.ui_settings = self.read_from_file()
|
||||
except Exception as e:
|
||||
self.error_loading = True
|
||||
errors.display(e, "loading settings")
|
||||
|
||||
def add_component(self, path, x):
|
||||
"""adds component to the registry of tracked components"""
|
||||
assert not self.finalized_ui
|
||||
def apply_field(obj, field, condition=None, init_field=None):
|
||||
key = f"{path}/{field}"
|
||||
if getattr(obj, 'custom_script_source', None) is not None:
|
||||
key = f"customscript/{obj.custom_script_source}/{key}"
|
||||
if getattr(obj, 'do_not_save_to_config', False):
|
||||
return
|
||||
saved_value = self.ui_settings.get(key, None)
|
||||
if saved_value is None:
|
||||
self.ui_settings[key] = getattr(obj, field)
|
||||
elif condition and not condition(saved_value):
|
||||
pass
|
||||
else:
|
||||
setattr(obj, field, saved_value)
|
||||
if init_field is not None:
|
||||
init_field(saved_value)
|
||||
if field == 'value' and key not in self.component_mapping:
|
||||
self.component_mapping[key] = x
|
||||
if type(x) in [gr.Slider, gr.Radio, gr.Checkbox, gr.Textbox, gr.Number, gr.Dropdown, ToolButton, gr.Button] and x.visible:
|
||||
apply_field(x, 'visible')
|
||||
if type(x) == gr.Slider:
|
||||
apply_field(x, 'value')
|
||||
apply_field(x, 'minimum')
|
||||
apply_field(x, 'maximum')
|
||||
apply_field(x, 'step')
|
||||
if type(x) == gr.Radio:
|
||||
apply_field(x, 'value', lambda val: val in x.choices)
|
||||
if type(x) == gr.Checkbox:
|
||||
apply_field(x, 'value')
|
||||
if type(x) == gr.Textbox:
|
||||
apply_field(x, 'value')
|
||||
if type(x) == gr.Number:
|
||||
apply_field(x, 'value')
|
||||
if type(x) == gr.Dropdown:
|
||||
def check_dropdown(val):
|
||||
if getattr(x, 'multiselect', False):
|
||||
return all(value in x.choices for value in val)
|
||||
else:
|
||||
return val in x.choices
|
||||
apply_field(x, 'value', check_dropdown, getattr(x, 'init_field', None))
|
||||
|
||||
def check_tab_id(tab_id):
|
||||
tab_items = list(filter(lambda e: isinstance(e, gr.TabItem), x.children))
|
||||
if type(tab_id) == str:
|
||||
tab_ids = [t.id for t in tab_items]
|
||||
return tab_id in tab_ids
|
||||
elif type(tab_id) == int:
|
||||
return 0 <= tab_id < len(tab_items)
|
||||
else:
|
||||
return False
|
||||
|
||||
if type(x) == gr.Tabs:
|
||||
apply_field(x, 'selected', check_tab_id)
|
||||
|
||||
def add_block(self, x, path=""):
|
||||
"""adds all components inside a gradio block x to the registry of tracked components"""
|
||||
if hasattr(x, 'children'):
|
||||
if isinstance(x, gr.Tabs) and x.elem_id is not None:
|
||||
# Tabs element can't have a label, have to use elem_id instead
|
||||
self.add_component(f"{path}/Tabs@{x.elem_id}", x)
|
||||
for c in x.children:
|
||||
self.add_block(c, path)
|
||||
elif x.label is not None:
|
||||
self.add_component(f"{path}/{x.label}", x)
|
||||
elif isinstance(x, gr.Button) and x.value is not None:
|
||||
self.add_component(f"{path}/{x.value}", x)
|
||||
|
||||
def read_from_file(self):
|
||||
with open(self.filename, "r", encoding="utf8") as file:
|
||||
return json.load(file)
|
||||
|
||||
def write_to_file(self, current_ui_settings):
|
||||
with open(self.filename, "w", encoding="utf8") as file:
|
||||
json.dump(current_ui_settings, file, indent=4)
|
||||
|
||||
def dump_defaults(self):
|
||||
"""saves default values to a file unless tjhe file is present and there was an error loading default values at start"""
|
||||
if self.error_loading and os.path.exists(self.filename):
|
||||
return
|
||||
self.write_to_file(self.ui_settings)
|
||||
|
||||
def iter_changes(self, current_ui_settings, values):
|
||||
"""
|
||||
given a dictionary with defaults from a file and current values from gradio elements, returns
|
||||
an iterator over tuples of values that are not the same between the file and the current;
|
||||
tuple contents are: path, old value, new value
|
||||
"""
|
||||
for (path, component), new_value in zip(self.component_mapping.items(), values):
|
||||
old_value = current_ui_settings.get(path)
|
||||
choices = getattr(component, 'choices', None)
|
||||
if isinstance(new_value, int) and choices:
|
||||
if new_value >= len(choices):
|
||||
continue
|
||||
new_value = choices[new_value]
|
||||
if new_value == old_value:
|
||||
continue
|
||||
if old_value is None and new_value == '' or new_value == []:
|
||||
continue
|
||||
yield path, old_value, new_value
|
||||
|
||||
def ui_view(self, *values):
|
||||
text = ["<table><thead><tr><th>Path</th><th>Old value</th><th>New value</th></thead><tbody>"]
|
||||
for path, old_value, new_value in self.iter_changes(self.read_from_file(), values):
|
||||
if old_value is None:
|
||||
old_value = "<span class='ui-defaults-none'>None</span>"
|
||||
text.append(f"<tr><td>{path}</td><td>{old_value}</td><td>{new_value}</td></tr>")
|
||||
if len(text) == 1:
|
||||
text.append("<tr><td colspan=3>No changes</td></tr>")
|
||||
text.append("</tbody>")
|
||||
return "".join(text)
|
||||
|
||||
def ui_apply(self, *values):
|
||||
num_changed = 0
|
||||
current_ui_settings = self.read_from_file()
|
||||
for path, _, new_value in self.iter_changes(current_ui_settings.copy(), values):
|
||||
num_changed += 1
|
||||
current_ui_settings[path] = new_value
|
||||
if num_changed == 0:
|
||||
return "No changes"
|
||||
self.write_to_file(current_ui_settings)
|
||||
errors.log.info(f'UI defaults saved: {self.filename}')
|
||||
return f"Wrote {num_changed} changes"
|
||||
|
||||
def ui_restore(self):
|
||||
if os.path.exists(self.filename):
|
||||
os.remove(self.filename)
|
||||
errors.log.info(f'UI defaults reset: {self.filename}')
|
||||
return "Restored system defaults for user interface"
|
||||
|
||||
def create_ui(self):
|
||||
"""creates ui elements for editing defaults UI, without adding any logic to them"""
|
||||
gr.HTML(f"Review changed values and apply them as new user interface defaults<br>Config file: {self.filename}")
|
||||
with gr.Row():
|
||||
self.ui_defaults_view = gr.Button(value='View changes', elem_id="ui_defaults_view", variant="secondary")
|
||||
self.ui_defaults_apply = gr.Button(value='Set new defaults', elem_id="ui_defaults_apply", variant="primary")
|
||||
self.ui_defaults_restore = gr.Button(value='Restore system defaults', elem_id="ui_defaults_restore", variant="primary")
|
||||
self.ui_defaults_review = gr.HTML("")
|
||||
|
||||
def setup_ui(self):
|
||||
"""adds logic to elements created with create_ui; all add_block class must be made before this"""
|
||||
assert not self.finalized_ui
|
||||
self.finalized_ui = True
|
||||
self.ui_defaults_view.click(fn=self.ui_view, inputs=list(self.component_mapping.values()), outputs=[self.ui_defaults_review])
|
||||
self.ui_defaults_apply.click(fn=self.ui_apply, inputs=list(self.component_mapping.values()), outputs=[self.ui_defaults_review])
|
||||
self.ui_defaults_restore.click(fn=self.ui_restore, inputs=[], outputs=[self.ui_defaults_review])
|
||||
@@ -1,6 +1,6 @@
|
||||
import json
|
||||
import gradio as gr
|
||||
from modules import scripts_postprocessing, scripts, shared, gfpgan_model, codeformer_model, ui_common, postprocessing, call_queue # pylint: disable=unused-import
|
||||
from modules import scripts, shared, ui_common, postprocessing, call_queue
|
||||
import modules.generation_parameters_copypaste as parameters_copypaste
|
||||
from modules.call_queue import wrap_gradio_gpu_call, wrap_queued_call, wrap_gradio_call # pylint: disable=unused-import
|
||||
from modules.extras import run_pnginfo
|
||||
|
||||
@@ -18,7 +18,7 @@ def register_tmp_file(gradio, filename):
|
||||
def check_tmp_file(gradio, filename):
|
||||
ok = False
|
||||
if hasattr(gradio, 'temp_file_sets'):
|
||||
ok = ok or any([filename in fileset for fileset in gradio.temp_file_sets])
|
||||
ok = ok or any(filename in fileset for fileset in gradio.temp_file_sets)
|
||||
if shared.opts.outdir_samples != '':
|
||||
ok = ok or Path(shared.opts.outdir_samples).resolve() in Path(filename).resolve().parents
|
||||
else:
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
from typing import Optional
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
from transformers import XLMRobertaModel,XLMRobertaTokenizer, BertPreTrainedModel, BertModel, BertConfig # pylint: disable=unused-import
|
||||
from transformers import XLMRobertaModel,XLMRobertaTokenizer, BertPreTrainedModel, BertConfig
|
||||
from transformers.models.xlm_roberta.configuration_xlm_roberta import XLMRobertaConfig
|
||||
|
||||
class BertSeriesConfig(BertConfig):
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
[tool.ruff]
|
||||
|
||||
target-version = "py39"
|
||||
|
||||
extend-select = [
|
||||
"B",
|
||||
"C",
|
||||
"I",
|
||||
"W",
|
||||
]
|
||||
|
||||
exclude = [
|
||||
"extensions",
|
||||
"extensions-disabled",
|
||||
"extensions-builtin",
|
||||
"modules/lora",
|
||||
"modules/lycoris",
|
||||
"modules/dml",
|
||||
]
|
||||
|
||||
ignore = [
|
||||
"C408", # Rewrite as a literal
|
||||
"C901", # Function is too complex
|
||||
"E501", # Line too long
|
||||
"E731", # Do not assign a `lambda` expression, use a `def`
|
||||
"I001", # Import block is un-sorted or un-formatted
|
||||
"W605", # invalid escape sequence, messes with some docstrings
|
||||
"E402", # Module level import not at top of file
|
||||
"F401", # Imported but unused
|
||||
]
|
||||
|
||||
[tool.ruff.per-file-ignores]
|
||||
"webui.py" = ["E402"] # Module level import not at top of file
|
||||
|
||||
[tool.ruff.flake8-bugbear]
|
||||
# Allow default arguments like, e.g., `data: List[str] = fastapi.Query(None)`.
|
||||
extend-immutable-calls = ["fastapi.Depends", "fastapi.security.HTTPBasic"]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
base_url = "http://127.0.0.1:7860"
|
||||
+1
-3
@@ -11,8 +11,6 @@ easydev
|
||||
extcolors
|
||||
facexlib
|
||||
filetype
|
||||
font-roboto
|
||||
fonts
|
||||
future
|
||||
gdown
|
||||
gfpgan
|
||||
@@ -47,7 +45,7 @@ basicsr
|
||||
compel
|
||||
requests==2.31.0
|
||||
tqdm==4.65.0
|
||||
accelerate==0.18.0
|
||||
accelerate==0.20.3
|
||||
opencv-python==4.7.0.72
|
||||
diffusers==0.16.1
|
||||
einops==0.4.1
|
||||
|
||||
@@ -149,7 +149,7 @@ class Script(scripts.Script):
|
||||
images = []
|
||||
all_prompts = []
|
||||
infotexts = []
|
||||
for n, args in enumerate(jobs):
|
||||
for args in jobs:
|
||||
state.job = f"{state.job_no + 1} out of {state.job_count}"
|
||||
|
||||
copy_p = copy.copy(p)
|
||||
|
||||
@@ -319,7 +319,6 @@ def draw_xyz_grid(p, xs, ys, zs, x_labels, y_labels, z_labels, cell, draw_legend
|
||||
return Processed(p, [])
|
||||
|
||||
z_count = len(zs)
|
||||
# sub_grids = [None] * z_count
|
||||
for i in range(z_count):
|
||||
start_index = (i * len(xs) * len(ys)) + i
|
||||
end_index = start_index + len(xs) * len(ys)
|
||||
|
||||
@@ -15,7 +15,7 @@ errors.log.debug('Loading Torch')
|
||||
import torch # pylint: disable=C0411
|
||||
try:
|
||||
import intel_extension_for_pytorch as ipex # pylint: disable=import-error, unused-import
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
import torchvision # pylint: disable=W0611,C0411
|
||||
import pytorch_lightning # pytorch_lightning should be imported after torch, but it re-enables warnings on import so import once to disable them # pylint: disable=W0611,C0411
|
||||
@@ -153,18 +153,12 @@ def initialize():
|
||||
def load_model():
|
||||
shared.state.begin()
|
||||
shared.state.job = 'load model'
|
||||
Thread(target=lambda: shared.sd_model).start()
|
||||
# TODO delay load model
|
||||
"""
|
||||
if shared.sd_model is None:
|
||||
log.warning("No stable diffusion model loaded")
|
||||
# exit(1)
|
||||
else:
|
||||
shared.opts.data["sd_model_checkpoint"] = shared.sd_model.sd_checkpoint_info.title
|
||||
"""
|
||||
thread = Thread(target=lambda: shared.sd_model)
|
||||
thread.start()
|
||||
shared.opts.onchange("sd_model_checkpoint", wrap_queued_call(lambda: modules.sd_models.reload_model_weights()), call=False)
|
||||
shared.opts.onchange("sd_model_dict", wrap_queued_call(lambda: modules.sd_models.reload_model_weights()), call=False)
|
||||
shared.state.end()
|
||||
thread.join()
|
||||
startup_timer.record("checkpoint")
|
||||
|
||||
|
||||
@@ -284,7 +278,7 @@ def start_ui():
|
||||
setup_middleware(app, cmd_opts)
|
||||
|
||||
if cmd_opts.subpath:
|
||||
_mounted_app = gradio.mount_gradio_app(app, shared.demo, path=f"/{cmd_opts.subpath}")
|
||||
gradio.mount_gradio_app(app, shared.demo, path=f"/{cmd_opts.subpath}")
|
||||
shared.log.info(f'Redirector mounted: /{cmd_opts.subpath}')
|
||||
|
||||
startup_timer.record("launch")
|
||||
@@ -305,7 +299,12 @@ def start_ui():
|
||||
def webui():
|
||||
start_common()
|
||||
start_ui()
|
||||
load_model()
|
||||
modules.sd_models.write_metadata()
|
||||
if opts.sd_checkpoint_autoload:
|
||||
load_model()
|
||||
else:
|
||||
log.debug('Model auto load disabled')
|
||||
|
||||
log.info(f"Startup time: {startup_timer.summary()}")
|
||||
|
||||
# override all loggers to use the same handlers as the main logger
|
||||
@@ -329,6 +328,7 @@ def api_only():
|
||||
api = create_api(app)
|
||||
api.wants_restart = False
|
||||
modules.script_callbacks.app_started_callback(None, app)
|
||||
modules.sd_models.write_metadata()
|
||||
log.info(f"Startup time: {startup_timer.summary()}")
|
||||
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)
|
||||
return api
|
||||
|
||||
+1
-1
Submodule wiki updated: 383fa467c3...34913c8824
Reference in New Issue
Block a user