mirror of
https://github.com/vladmandic/automatic
synced 2026-09-18 16:54:33 +02:00
upscaler caching and ti model detection
This commit is contained in:
+8
-3
@@ -72,9 +72,14 @@ Upgrades are still possible and supported, but above is recommended for best exp
|
||||
description file present in format of *[model].txt*
|
||||
- to enable search, make sure all models have set hash values
|
||||
*Models -> Valida -> Calculate hashes*
|
||||
- **Intel Arc/IPEX**:
|
||||
- more optimizations, built-in binary wheels for Windows
|
||||
thanks @Disty0 @Nuullll
|
||||
- **Compute**
|
||||
- **Intel Arc/IPEX**:
|
||||
- more optimizations, built-in binary wheels for Windows
|
||||
thanks @Disty0 @Nuullll
|
||||
- **AMD ROCm**:
|
||||
- updated installer to support detect `ROCm` *5.4/5.5/5.6/5.7*
|
||||
- **CUDA**:
|
||||
- testing moved to `torch` *2.2.0-dev/cu121*
|
||||
- **Startup**
|
||||
- All main CLI parameters can now be set as environment variable as well
|
||||
for example `--data-dir <path>` can be specified as `SD_DATADIR=<path>` before starting SD.Next
|
||||
|
||||
@@ -397,6 +397,9 @@ def check_torch():
|
||||
if rocm_ver in ['5.5', '5.6']:
|
||||
# install torch nightly via torchvision to avoid wasting bandwidth when torchvision depends on torch from yesterday
|
||||
torch_command = os.environ.get('TORCH_COMMAND', f'torchvision --pre --index-url https://download.pytorch.org/whl/nightly/rocm{rocm_ver}')
|
||||
elif rocm_ver in ['5.7']:
|
||||
# there is no torch nightly for rocm 5.7 yet
|
||||
torch_command = os.environ.get('TORCH_COMMAND', f'torchvision --pre --index-url https://download.pytorch.org/whl/nightly/rocm5.6')
|
||||
else:
|
||||
torch_command = os.environ.get('TORCH_COMMAND', 'torch==2.0.1 torchvision==0.15.2 --index-url https://download.pytorch.org/whl/rocm5.4.2')
|
||||
xformers_package = os.environ.get('XFORMERS_PACKAGE', 'none')
|
||||
|
||||
@@ -45,7 +45,6 @@ def setup_model(dirname):
|
||||
self.cmd_dir = dirname
|
||||
|
||||
def create_models(self):
|
||||
|
||||
if self.net is not None and self.face_helper is not None:
|
||||
self.net.to(devices.device_codeformer)
|
||||
return self.net, self.face_helper
|
||||
@@ -60,14 +59,11 @@ def setup_model(dirname):
|
||||
net.load_state_dict(checkpoint)
|
||||
net.eval()
|
||||
shared.log.info(f"Model loaded: type=CodeFormer model={ckpt_path}")
|
||||
|
||||
if hasattr(retinaface, 'device'):
|
||||
retinaface.device = devices.device_codeformer
|
||||
face_helper = FaceRestoreHelper(1, face_size=512, crop_ratio=(1, 1), det_model='retinaface_resnet50', save_ext='png', use_parse=True, device=devices.device_codeformer)
|
||||
|
||||
self.net = net
|
||||
self.face_helper = face_helper
|
||||
|
||||
return net, face_helper
|
||||
|
||||
def send_model_to(self, device):
|
||||
@@ -77,25 +73,19 @@ def setup_model(dirname):
|
||||
|
||||
def restore(self, np_image, w=None):
|
||||
np_image = np_image[:, :, ::-1]
|
||||
|
||||
original_resolution = np_image.shape[0:2]
|
||||
|
||||
self.create_models()
|
||||
if self.net is None or self.face_helper is None:
|
||||
return np_image
|
||||
|
||||
self.send_model_to(devices.device_codeformer)
|
||||
|
||||
self.face_helper.clean_all()
|
||||
self.face_helper.read_image(np_image)
|
||||
self.face_helper.get_face_landmarks_5(only_center_face=False, resize=640, eye_dist_threshold=5)
|
||||
self.face_helper.align_warp_face()
|
||||
|
||||
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)
|
||||
|
||||
try:
|
||||
with devices.inference_context():
|
||||
output = self.net(cropped_face_t, w=w if w is not None else shared.opts.code_former_weight, adain=True)[0]
|
||||
@@ -105,33 +95,23 @@ def setup_model(dirname):
|
||||
except Exception as e:
|
||||
shared.log.error(f'CodeForomer error: {e}')
|
||||
restored_face = tensor2img(cropped_face_t, rgb2bgr=True, min_max=(-1, 1))
|
||||
|
||||
restored_face = restored_face.astype('uint8')
|
||||
self.face_helper.add_restored_face(restored_face)
|
||||
|
||||
self.face_helper.get_inverse_affine(None)
|
||||
|
||||
restored_img = self.face_helper.paste_faces_to_input_image()
|
||||
restored_img = restored_img[:, :, ::-1]
|
||||
|
||||
if original_resolution != restored_img.shape[0:2]:
|
||||
restored_img = cv2.resize(restored_img, (0, 0), fx=original_resolution[1]/restored_img.shape[1], fy=original_resolution[0]/restored_img.shape[0], interpolation=cv2.INTER_LINEAR)
|
||||
|
||||
self.face_helper.clean_all()
|
||||
|
||||
if shared.opts.face_restoration_unload:
|
||||
self.send_model_to(devices.cpu)
|
||||
|
||||
return restored_img
|
||||
|
||||
global have_codeformer # pylint: disable=global-statement
|
||||
have_codeformer = True
|
||||
|
||||
global codeformer # pylint: disable=global-statement
|
||||
codeformer = FaceRestorerCodeFormer(dirname)
|
||||
shared.face_restorers.append(codeformer)
|
||||
|
||||
except Exception as e:
|
||||
errors.display(e, 'codeformer')
|
||||
|
||||
# sys.path = stored_sys_path
|
||||
|
||||
@@ -4,7 +4,7 @@ from PIL import Image
|
||||
from rich.progress import Progress, TextColumn, BarColumn, TaskProgressColumn, TimeRemainingColumn, TimeElapsedColumn
|
||||
import modules.postprocess.esrgan_model_arch as arch
|
||||
from modules import images, devices
|
||||
from modules.upscaler import Upscaler
|
||||
from modules.upscaler import Upscaler, UpscalerData
|
||||
from modules.shared import opts, log, console
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ class UpscalerESRGAN(Upscaler):
|
||||
self.user_path = dirname
|
||||
super().__init__()
|
||||
self.scalers = self.find_scalers()
|
||||
|
||||
self.models = {}
|
||||
|
||||
def do_upscale(self, img, selected_model):
|
||||
model = self.load_model(selected_model)
|
||||
@@ -130,12 +130,19 @@ class UpscalerESRGAN(Upscaler):
|
||||
return img
|
||||
model.to(devices.device_esrgan)
|
||||
img = esrgan_upscale(model, img)
|
||||
if opts.upscaler_unload and selected_model in self.models:
|
||||
del self.models[selected_model]
|
||||
log.debug(f"Upscaler unloaded: type={self.name} model={selected_model}")
|
||||
devices.torch_gc(force=True)
|
||||
return img
|
||||
|
||||
def load_model(self, path: str):
|
||||
info = self.find_model(path)
|
||||
info: UpscalerData = self.find_model(path)
|
||||
if info is None:
|
||||
return
|
||||
if self.models.get(info.local_data_path, None) is not None:
|
||||
log.debug(f"Upscaler cached: type={self.name} model={info.local_data_path}")
|
||||
return self.models[info.local_data_path]
|
||||
state_dict = torch.load(info.local_data_path, map_location='cpu' if devices.device_esrgan.type == 'mps' else None)
|
||||
log.info(f"Upscaler loaded: type={self.name} model={info.local_data_path}")
|
||||
|
||||
@@ -147,7 +154,9 @@ class UpscalerESRGAN(Upscaler):
|
||||
model = arch.SRVGGNetCompact(num_in_ch=3, num_out_ch=3, num_feat=64, num_conv=num_conv, upscale=4, act_type='prelu')
|
||||
model.load_state_dict(state_dict)
|
||||
model.eval()
|
||||
return model
|
||||
self.models[info.local_data_path] = model
|
||||
return self.models[info.local_data_path]
|
||||
|
||||
if "body.0.rdb1.conv1.weight" in state_dict and "conv_first.weight" in state_dict:
|
||||
nb = 6 if "RealESRGAN_x4plus_anime_6B" in info.local_data_path else 23
|
||||
state_dict = resrgan2normal(state_dict, nb)
|
||||
@@ -155,14 +164,12 @@ class UpscalerESRGAN(Upscaler):
|
||||
state_dict = mod2normal(state_dict)
|
||||
elif "model.0.weight" not in state_dict:
|
||||
raise TypeError("The file is not a recognized ESRGAN model.")
|
||||
|
||||
in_nc, out_nc, nf, nb, plus, mscale = infer_params(state_dict)
|
||||
|
||||
model = arch.RRDBNet(in_nc=in_nc, out_nc=out_nc, nf=nf, nb=nb, upscale=mscale, plus=plus)
|
||||
model.load_state_dict(state_dict)
|
||||
model.eval()
|
||||
|
||||
return model
|
||||
self.models[info.local_data_path] = model
|
||||
return self.models[info.local_data_path]
|
||||
|
||||
|
||||
def upscale_without_tiling(model, img):
|
||||
|
||||
@@ -5,7 +5,7 @@ from basicsr.archs.rrdbnet_arch import RRDBNet
|
||||
from modules.postprocess.realesrgan_model_arch import SRVGGNetCompact
|
||||
from modules.upscaler import Upscaler
|
||||
from modules.shared import opts, device, log
|
||||
|
||||
from modules import devices
|
||||
|
||||
class UpscalerRealESRGAN(Upscaler):
|
||||
def __init__(self, dirname):
|
||||
@@ -13,6 +13,7 @@ class UpscalerRealESRGAN(Upscaler):
|
||||
self.user_path = dirname
|
||||
super().__init__()
|
||||
self.scalers = self.find_scalers()
|
||||
self.models = {}
|
||||
for scaler in self.scalers:
|
||||
if scaler.name == 'RealESRGAN 2x+':
|
||||
scaler.model = lambda: RRDBNet(num_in_ch=3, num_out_ch=3, num_feat=64, num_block=23, num_grow_ch=32, scale=2)
|
||||
@@ -41,22 +42,29 @@ class UpscalerRealESRGAN(Upscaler):
|
||||
except Exception:
|
||||
log.error("Error importing Real-ESRGAN:")
|
||||
return img
|
||||
|
||||
info = self.find_model(selected_model)
|
||||
if info is None or not os.path.exists(info.local_data_path):
|
||||
return img
|
||||
|
||||
upsampler = RealESRGANer(
|
||||
scale=info.scale,
|
||||
model_path=info.local_data_path,
|
||||
model=info.model(),
|
||||
half=not opts.no_half and not opts.upcast_sampling,
|
||||
tile=opts.ESRGAN_tile,
|
||||
tile_pad=opts.ESRGAN_tile_overlap,
|
||||
device=device,
|
||||
)
|
||||
|
||||
if self.models.get(info.local_data_path, None) is not None:
|
||||
log.debug(f"Upscaler cached: type={self.name} model={info.local_data_path}")
|
||||
upsampler=self.models[info.local_data_path]
|
||||
else:
|
||||
upsampler = RealESRGANer(
|
||||
name=info.name,
|
||||
scale=info.scale,
|
||||
model_path=info.local_data_path,
|
||||
model=info.model(),
|
||||
half=not opts.no_half and not opts.upcast_sampling,
|
||||
tile=opts.ESRGAN_tile,
|
||||
tile_pad=opts.ESRGAN_tile_overlap,
|
||||
device=device,
|
||||
)
|
||||
self.models[info.local_data_path] = upsampler
|
||||
upsampled = upsampler.enhance(np.array(img), outscale=info.scale)[0]
|
||||
if opts.upscaler_unload and info.local_data_path in self.models:
|
||||
del self.models[info.local_data_path]
|
||||
log.debug(f"Upscaler unloaded: type={self.name} model={selected_model}")
|
||||
devices.torch_gc(force=True)
|
||||
|
||||
image = Image.fromarray(upsampled)
|
||||
return image
|
||||
|
||||
@@ -29,6 +29,7 @@ class RealESRGANer():
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
name,
|
||||
scale,
|
||||
model_path,
|
||||
dni_weight=None,
|
||||
@@ -39,6 +40,7 @@ class RealESRGANer():
|
||||
half=False,
|
||||
device=None,
|
||||
gpu_id=None):
|
||||
self.name = name
|
||||
self.scale = scale
|
||||
self.tile_size = tile
|
||||
self.tile_pad = tile_pad
|
||||
@@ -63,6 +65,7 @@ class RealESRGANer():
|
||||
from modules.modelloader import load_file_from_url
|
||||
model_path = load_file_from_url(url=model_path, model_dir=os.path.join(ROOT_DIR, 'weights'), progress=True, file_name=None)
|
||||
loadnet = torch.load(model_path, map_location=torch.device('cpu'))
|
||||
log.info(f"Upscaler loaded: type={self.name} model={model_path}")
|
||||
|
||||
# prefer to use params_ema
|
||||
if 'params_ema' in loadnet:
|
||||
|
||||
@@ -14,18 +14,24 @@ class UpscalerSCUNet(Upscaler):
|
||||
self.user_path = dirname
|
||||
super().__init__()
|
||||
self.scalers = self.find_scalers()
|
||||
self.models = {}
|
||||
|
||||
def load_model(self, path: str):
|
||||
info = self.find_model(path)
|
||||
if info is None:
|
||||
return
|
||||
model = net(in_nc=3, config=[4, 4, 4, 4, 4, 4, 4], dim=64)
|
||||
model.load_state_dict(torch.load(info.local_data_path), strict=True)
|
||||
model.eval()
|
||||
log.info(f"Upscaler loaded: type={self.name} model={info.local_data_path}")
|
||||
for _, v in model.named_parameters():
|
||||
v.requires_grad = False
|
||||
model = model.to(device)
|
||||
if self.models.get(info.local_data_path, None) is not None:
|
||||
log.debug(f"Upscaler cached: type={self.name} model={info.local_data_path}")
|
||||
model=self.models[info.local_data_path]
|
||||
else:
|
||||
model = net(in_nc=3, config=[4, 4, 4, 4, 4, 4, 4], dim=64)
|
||||
model.load_state_dict(torch.load(info.local_data_path), strict=True)
|
||||
model.eval()
|
||||
log.info(f"Upscaler loaded: type={self.name} model={info.local_data_path}")
|
||||
for _, v in model.named_parameters():
|
||||
v.requires_grad = False
|
||||
model = model.to(device)
|
||||
self.models[info.local_data_path] = model
|
||||
return model
|
||||
|
||||
@staticmethod
|
||||
@@ -83,7 +89,12 @@ class UpscalerSCUNet(Upscaler):
|
||||
devices.torch_gc()
|
||||
output = np_output.transpose((1, 2, 0)) # CHW to HWC
|
||||
output = output[:, :, ::-1] # BGR to RGB
|
||||
return PIL.Image.fromarray((output * 255).astype(np.uint8))
|
||||
img = PIL.Image.fromarray((output * 255).astype(np.uint8))
|
||||
if opts.upscaler_unload and selected_file in self.models:
|
||||
del self.models[selected_file]
|
||||
log.debug(f"Upscaler unloaded: type={self.name} model={selected_file}")
|
||||
devices.torch_gc(force=True)
|
||||
return img
|
||||
|
||||
|
||||
def on_ui_settings():
|
||||
|
||||
@@ -19,17 +19,22 @@ class UpscalerSD(Upscaler):
|
||||
None,
|
||||
None,
|
||||
]
|
||||
self.models = {}
|
||||
|
||||
def load_model(self, path: str):
|
||||
from modules.sd_models import set_diffuser_options
|
||||
scaler = [x for x in self.scalers if x.data_path == path][0]
|
||||
if scaler.model is None:
|
||||
scaler: UpscalerData = [x for x in self.scalers if x.data_path == path][0]
|
||||
if self.models.get(path, None) is not None:
|
||||
shared.log.debug(f"Upscaler cached: type={scaler.name} model={path}")
|
||||
return self.models[path]
|
||||
else:
|
||||
devices.set_cuda_params()
|
||||
scaler.model = diffusers.DiffusionPipeline.from_pretrained(path, cache_dir=shared.opts.diffusers_dir, torch_dtype=devices.dtype)
|
||||
if hasattr(scaler.model, "set_progress_bar_config"):
|
||||
scaler.model.set_progress_bar_config(bar_format='Progress {rate_fmt}{postfix} {bar} {percentage:3.0f}% {n_fmt}/{total_fmt} {elapsed} {remaining} ' + '\x1b[38;5;71m' + 'Upscale', ncols=80, colour='#327fba')
|
||||
model = diffusers.DiffusionPipeline.from_pretrained(path, cache_dir=shared.opts.diffusers_dir, torch_dtype=devices.dtype)
|
||||
if hasattr(model, "set_progress_bar_config"):
|
||||
model.set_progress_bar_config(bar_format='Progress {rate_fmt}{postfix} {bar} {percentage:3.0f}% {n_fmt}/{total_fmt} {elapsed} {remaining} ' + '\x1b[38;5;71m' + 'Upscale', ncols=80, colour='#327fba')
|
||||
set_diffuser_options(scaler.model, vae=None, op='upscaler')
|
||||
return scaler.model
|
||||
self.models[path] = model
|
||||
return self.models[path]
|
||||
|
||||
def callback(self, _step: int, _timestep: int, _latents: torch.FloatTensor):
|
||||
pass
|
||||
@@ -61,4 +66,8 @@ class UpscalerSD(Upscaler):
|
||||
model = model.to(devices.device)
|
||||
output = model(**args)
|
||||
image = output.images[0]
|
||||
if shared.opts.upscaler_unload and selected_model in self.models:
|
||||
del self.models[selected_model]
|
||||
shared.log.debug(f"Upscaler unloaded: type={self.name} model={selected_model}")
|
||||
devices.torch_gc(force=True)
|
||||
return image
|
||||
|
||||
@@ -14,11 +14,15 @@ class UpscalerSwinIR(Upscaler):
|
||||
self.user_path = dirname
|
||||
super().__init__()
|
||||
self.scalers = self.find_scalers()
|
||||
self.models = {}
|
||||
|
||||
def load_model(self, path, scale=4):
|
||||
info = self.find_model(path)
|
||||
if info is None:
|
||||
return
|
||||
if self.models.get(info.local_data_path, None) is not None:
|
||||
shared.log.debug(f"Upscaler cached: type={self.name} model={info.local_data_path}")
|
||||
return self.models[info.local_data_path]
|
||||
pretrained_model = torch.load(info.local_data_path)
|
||||
model_v2 = net2(
|
||||
upscale=scale,
|
||||
@@ -54,6 +58,7 @@ class UpscalerSwinIR(Upscaler):
|
||||
else:
|
||||
model.load_state_dict(pretrained_model, strict=True)
|
||||
shared.log.info(f"Upscaler loaded: type={self.name} model={info.local_data_path} param={param}")
|
||||
self.models[info.local_data_path] = model
|
||||
return model
|
||||
except Exception as e:
|
||||
shared.log.error(f'Upscaler invalid parameters: type={self.name} model={info.local_data_path} {e}')
|
||||
@@ -65,7 +70,10 @@ class UpscalerSwinIR(Upscaler):
|
||||
return img
|
||||
model = model.to(shared.device, dtype=devices.dtype)
|
||||
img = upscale(img, model)
|
||||
devices.torch_gc()
|
||||
if shared.opts.upscaler_unload and selected_model in self.models:
|
||||
del self.models[selected_model]
|
||||
shared.log.debug(f"Upscaler unloaded: type={self.name} model={selected_model}")
|
||||
devices.torch_gc(force=True)
|
||||
return img
|
||||
|
||||
|
||||
|
||||
+2
-1
@@ -613,7 +613,8 @@ options_templates.update(options_section(('postprocessing', "Postprocessing"), {
|
||||
"face_restoration_unload": OptionInfo(False, "Move face restoration model from VRAM into RAM after processing"),
|
||||
|
||||
"postprocessing_sep_upscalers": OptionInfo("<h2>Upscaling</h2>", "", gr.HTML),
|
||||
'upscaling_max_images_in_cache': OptionInfo(5, "Maximum number of images in upscaling cache", gr.Slider, {"minimum": 0, "maximum": 10, "step": 1}),
|
||||
"upscaler_unload": OptionInfo(False, "Unload upscaler after processing"),
|
||||
'upscaling_max_images_in_cache': OptionInfo(5, "Maximum number of images in upscaling cache", gr.Slider, {"minimum": 0, "maximum": 10, "step": 1, "visible": False}),
|
||||
"upscaler_for_img2img": OptionInfo("None", "Default upscaler for image resize operations", gr.Dropdown, lambda: {"choices": [x.name for x in sd_upscalers]}),
|
||||
# "realesrgan_enabled_models": OptionInfo(["R-ESRGAN 4x+", "R-ESRGAN 4x+ Anime6B"], "Real-ESRGAN available models", gr.CheckboxGroup, lambda: {"choices": shared_items.realesrgan_models_names()}),
|
||||
"ESRGAN_tile": OptionInfo(192, "Tile size for ESRGAN upscalers", gr.Slider, {"minimum": 0, "maximum": 512, "step": 16}),
|
||||
|
||||
@@ -128,52 +128,68 @@ class EmbeddingDatabase:
|
||||
if ext.lower() != ".pt" and ext.lower() != ".safetensors":
|
||||
return
|
||||
pipe = shared.sd_model
|
||||
if filename == "":
|
||||
pipe.tokenizer = pipe.tokenizer.__class__.from_pretrained(pipe.tokenizer.name_or_path)
|
||||
pipe.text_encoder.resize_token_embeddings(len(pipe.tokenizer))
|
||||
return
|
||||
name = os.path.basename(fn)
|
||||
embedding = Embedding(vec=None, name=name, filename=path)
|
||||
if not hasattr(pipe, "tokenizer") or not hasattr(pipe, 'text_encoder'):
|
||||
self.skipped_embeddings[name] = embedding
|
||||
return
|
||||
try:
|
||||
done = False
|
||||
if hasattr(pipe,"load_textual_inversion"):
|
||||
try:
|
||||
token_ids = pipe.tokenizer.convert_tokens_to_ids(name)
|
||||
if token_ids > 49407: # already loaded
|
||||
done = True
|
||||
else:
|
||||
pipe.load_textual_inversion(path, token=name, cache_dir=shared.opts.diffusers_dir, local_files_only=True)
|
||||
done = True
|
||||
is_xl = hasattr(pipe, 'text_encoder_2')
|
||||
try:
|
||||
if not is_xl: # only use for sd15/sd21
|
||||
pipe.load_textual_inversion(path, token=name, cache_dir=shared.opts.diffusers_dir, local_files_only=True)
|
||||
self.register_embedding(embedding, shared.sd_model)
|
||||
except Exception:
|
||||
pass
|
||||
if not done and "safetensors" in path:
|
||||
except Exception:
|
||||
pass
|
||||
is_loaded = pipe.tokenizer.convert_tokens_to_ids(name) > 49407
|
||||
if is_loaded:
|
||||
self.register_embedding(embedding, shared.sd_model)
|
||||
else:
|
||||
embeddings_dict = {}
|
||||
from safetensors.torch import safe_open
|
||||
with safe_open(path, framework="pt") as f:
|
||||
for k in f.keys():
|
||||
embeddings_dict[k] = f.get_tensor(k)
|
||||
if ext.lower() in ['.safetensors']:
|
||||
with safetensors.torch.safe_open(path, framework="pt") as f:
|
||||
for k in f.keys():
|
||||
embeddings_dict[k] = f.get_tensor(k)
|
||||
else:
|
||||
raise NotImplementedError
|
||||
"""
|
||||
# alternatively could disable load_textual_inversion and load everything here
|
||||
elif ext.lower() in ['.pt', '.bin']:
|
||||
data = torch.load(path, map_location="cpu")
|
||||
embedding.tag = data.get('name', None)
|
||||
embedding.step = data.get('step', None)
|
||||
embedding.sd_checkpoint = data.get('sd_checkpoint', None)
|
||||
embedding.sd_checkpoint_name = data.get('sd_checkpoint_name', None)
|
||||
param_dict = data.get('string_to_param', None)
|
||||
embeddings_dict['clip_l'] = []
|
||||
for tokens in param_dict.values():
|
||||
for vec in tokens:
|
||||
embeddings_dict['clip_l'].append(vec)
|
||||
"""
|
||||
clip_l = pipe.text_encoder.get_input_embeddings().weight if hasattr(pipe, 'text_encoder') and hasattr(pipe.text_encoder, "resize_token_embeddings") else None
|
||||
clip_g = pipe.text_encoder_2.get_input_embeddings().weight if hasattr(pipe, 'text_encoder_2') and hasattr(pipe.text_encoder_2, "resize_token_embeddings") else None
|
||||
is_sd = clip_l is not None and 'clip_l' in embeddings_dict and clip_g is None and 'clip_g' not in embeddings_dict
|
||||
is_xl = clip_l is not None and 'clip_l' in embeddings_dict and clip_g is not None and 'clip_g' in embeddings_dict
|
||||
tokens = []
|
||||
for i in range(len(embeddings_dict["clip_l"])):
|
||||
if clip_l is not None and len(clip_l.data[0]) == len(embeddings_dict["clip_l"][i]):
|
||||
if (is_sd or is_xl) and (len(clip_l.data[0]) == len(embeddings_dict["clip_l"][i])):
|
||||
tokens.append(name if i == 0 else f"{name}_{i}")
|
||||
num_added = pipe.tokenizer.add_tokens(tokens)
|
||||
if num_added > 0:
|
||||
token_ids = pipe.tokenizer.convert_tokens_to_ids(tokens)
|
||||
if clip_l is not None:
|
||||
if is_sd: # only used for sd15 if load_textual_inversion failed and format is safetensors
|
||||
pipe.text_encoder.resize_token_embeddings(len(pipe.tokenizer))
|
||||
for i in range(len(token_ids)):
|
||||
clip_l.data[token_ids[i]] = embeddings_dict["clip_l"][i]
|
||||
if clip_g is not None:
|
||||
elif is_xl:
|
||||
pipe.text_encoder.resize_token_embeddings(len(pipe.tokenizer))
|
||||
pipe.text_encoder_2.resize_token_embeddings(len(pipe.tokenizer))
|
||||
for i in range(len(token_ids)):
|
||||
clip_l.data[token_ids[i]] = embeddings_dict["clip_l"][i]
|
||||
clip_g.data[token_ids[i]] = embeddings_dict["clip_g"][i]
|
||||
self.register_embedding(embedding, shared.sd_model)
|
||||
else:
|
||||
raise NotImplementedError
|
||||
# self.word_embeddings[name] = embedding
|
||||
self.register_embedding(embedding, shared.sd_model)
|
||||
else:
|
||||
raise NotImplementedError
|
||||
except Exception:
|
||||
self.skipped_embeddings[name] = embedding
|
||||
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
from PIL import Image
|
||||
import numpy as np
|
||||
import gradio as gr
|
||||
from modules import scripts_postprocessing, shared
|
||||
from modules.ui_components import FormRow, ToolButton
|
||||
import modules.ui_symbols as symbols
|
||||
|
||||
|
||||
upscale_cache = {}
|
||||
|
||||
|
||||
class ScriptPostprocessingUpscale(scripts_postprocessing.ScriptPostprocessing):
|
||||
name = "Upscale"
|
||||
order = 1000
|
||||
@@ -58,25 +54,12 @@ class ScriptPostprocessingUpscale(scripts_postprocessing.ScriptPostprocessing):
|
||||
info["Postprocess upscale to"] = f"{upscale_to_width}x{upscale_to_height}"
|
||||
else:
|
||||
info["Postprocess upscale by"] = upscale_by
|
||||
|
||||
cache_key = (hash(np.array(image.getdata()).tobytes()), upscaler.name, upscale_mode, upscale_by, upscale_to_width, upscale_to_height, upscale_crop)
|
||||
cached_image = upscale_cache.pop(cache_key, None)
|
||||
|
||||
if cached_image is not None:
|
||||
image = cached_image
|
||||
else:
|
||||
image = upscaler.scaler.upscale(image, upscale_by, upscaler.data_path)
|
||||
|
||||
upscale_cache[cache_key] = image
|
||||
if len(upscale_cache) > shared.opts.upscaling_max_images_in_cache:
|
||||
upscale_cache.pop(next(iter(upscale_cache), None), None)
|
||||
|
||||
image = upscaler.scaler.upscale(image, upscale_by, upscaler.data_path)
|
||||
if upscale_mode == 1 and upscale_crop:
|
||||
cropped = Image.new("RGB", (upscale_to_width, upscale_to_height))
|
||||
cropped.paste(image, box=(upscale_to_width // 2 - image.width // 2, upscale_to_height // 2 - image.height // 2))
|
||||
image = cropped
|
||||
info["Postprocess crop to"] = f"{image.width}x{image.height}"
|
||||
|
||||
return image
|
||||
|
||||
def process(self, pp: scripts_postprocessing.PostprocessedImage, upscale_mode=1, upscale_by=2.0, upscale_to_width=None, upscale_to_height=None, upscale_crop=False, upscaler_1_name=None, upscaler_2_name=None, upscaler_2_visibility=0.0): # pylint: disable=arguments-differ
|
||||
@@ -104,7 +87,7 @@ class ScriptPostprocessingUpscale(scripts_postprocessing.ScriptPostprocessing):
|
||||
pp.image = upscaled_image
|
||||
|
||||
def image_changed(self):
|
||||
upscale_cache.clear()
|
||||
pass
|
||||
|
||||
|
||||
class ScriptPostprocessingUpscaleSimple(ScriptPostprocessingUpscale):
|
||||
|
||||
Reference in New Issue
Block a user