jumbo merge

This commit is contained in:
Vladimir Mandic
2023-06-13 11:58:14 -04:00
parent 0d101b9def
commit cb307399dd
72 changed files with 535 additions and 408 deletions
+9
View File
@@ -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
+1 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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
+3 -3
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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')
+2 -2
View File
@@ -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 () => {
+4
View File
@@ -405,6 +405,10 @@ div#extras_scale_to_tab div.form{
padding: 2em;
}
.ui-defaults-none{
color: #aaa !important;
}
/* fullpage image viewer */
#lightboxModal{
+1 -1
View File
@@ -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
View File
@@ -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)
+1 -1
View File
@@ -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
View File
@@ -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,
+2 -2
View File
@@ -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,
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -23,7 +23,7 @@ class DirectML():
else:
return UnknownOptimizer
return optimizer
except:
except Exception:
return UnknownOptimizer
def memory_stats(device: torch.device):
+1 -1
View File
@@ -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] = [
+2 -6
View File
@@ -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']
+2
View File
@@ -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':
+1 -1
View File
@@ -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):
+1 -1
View File
@@ -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
+3 -3
View File
@@ -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
+8 -8
View File
@@ -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
+2 -8
View File
@@ -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
View File
@@ -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
View File
@@ -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')
+2 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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
+6 -9
View File
@@ -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)
+18 -25
View File
@@ -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]
+2 -1
View File
@@ -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}")
+4 -4
View File
@@ -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
View File
@@ -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):
+3 -3
View File
@@ -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}"
+8 -8
View File
@@ -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))
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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 = {}
+1 -1
View File
@@ -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] = [
+2 -3
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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):
+8 -6
View File
@@ -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
+1 -1
View File
@@ -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:
+1 -1
View File
@@ -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:
+3 -6
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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:
+2 -2
View File
@@ -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'
+176
View File
@@ -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 -1
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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):
+40
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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)
-1
View File
@@ -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)
+12 -12
View File
@@ -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