refactor backend detection

This commit is contained in:
Vladimir Mandic
2024-06-06 20:41:10 -04:00
parent c8d6f03209
commit 5574833f0d
55 changed files with 171 additions and 170 deletions
+3 -1
View File
@@ -9,7 +9,9 @@ from PIL import Image, ExifTags, TiffImagePlugin, PngImagePlugin
from rich import print # pylint: disable=redefined-builtin
module_spec = importlib.util.spec_from_file_location('infotext', os.path.join('modules', 'infotext.py'))
module_file = os.path.abspath(__file__)
module_dir = os.path.dirname(module_file)
module_spec = importlib.util.spec_from_file_location('infotext', os.path.join(module_dir, '..', 'modules', 'infotext.py'))
infotext = importlib.util.module_from_spec(module_spec)
module_spec.loader.exec_module(infotext)
@@ -104,7 +104,7 @@ class ExtraNetworkLora(extra_networks.ExtraNetwork):
self.active = False
def deactivate(self, p):
if shared.backend == shared.Backend.DIFFUSERS and hasattr(shared.sd_model, "unload_lora_weights") and hasattr(shared.sd_model, "text_encoder"):
if shared.native and hasattr(shared.sd_model, "unload_lora_weights") and hasattr(shared.sd_model, "text_encoder"):
if 'CLIP' in shared.sd_model.text_encoder.__class__.__name__ and not (shared.compiled_model_state is not None and shared.compiled_model_state.is_compiled is True):
if shared.opts.lora_fuse_diffusers:
shared.sd_model.unfuse_lora()
+1 -1
View File
@@ -106,7 +106,7 @@ def make_unet_conversion_map() -> Dict[str, str]:
class KeyConvert:
def __init__(self):
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
self.converter = self.original
self.is_sd2 = 'model_transformer_resblocks' in shared.sd_model.network_layer_mapping
else:
+4 -4
View File
@@ -47,7 +47,7 @@ convert_diffusers_name_to_compvis = lora_convert.convert_diffusers_name_to_compv
def assign_network_names_to_compvis_modules(sd_model):
network_layer_mapping = {}
if shared.backend == shared.Backend.DIFFUSERS:
if shared.native:
if not hasattr(shared.sd_model, 'text_encoder') or not hasattr(shared.sd_model, 'unet'):
return
for name, module in shared.sd_model.text_encoder.named_modules():
@@ -85,7 +85,7 @@ def load_diffusers(name, network_on_disk, lora_scale=1.0) -> network.Network:
shared.log.debug(f'LoRA load: name="{name}" file="{network_on_disk.filename}" type=diffusers {"cached" if cached else ""} fuse={shared.opts.lora_fuse_diffusers}')
if cached is not None:
return cached
if shared.backend != shared.Backend.DIFFUSERS:
if shared.native:
return None
shared.sd_model.load_lora_weights(network_on_disk.filename)
if shared.opts.lora_fuse_diffusers:
@@ -195,9 +195,9 @@ def load_networks(names, te_multipliers=None, unet_multipliers=None, dyn_dims=No
try:
if recompile_model:
shared.compiled_model_state.lora_model.append(f"{name}:{te_multipliers[i] if te_multipliers else 1.0}")
if shared.backend == shared.Backend.DIFFUSERS and shared.opts.lora_force_diffusers: # OpenVINO only works with Diffusers LoRa loading
if shared.native and shared.opts.lora_force_diffusers: # OpenVINO only works with Diffusers LoRa loading
net = load_diffusers(name, network_on_disk, lora_scale=te_multipliers[i] if te_multipliers else 1.0)
elif shared.backend == shared.Backend.DIFFUSERS and network_overrides.check_override(shorthash):
elif shared.native and network_overrides.check_override(shorthash):
net = load_diffusers(name, network_on_disk, lora_scale=te_multipliers[i] if te_multipliers else 1.0)
else:
net = load_network(name, network_on_disk)
@@ -19,10 +19,10 @@ class ExtraNetworksPageLora(ui_extra_networks.ExtraNetworksPage):
try:
# path, _ext = os.path.splitext(l.filename)
name = os.path.splitext(os.path.relpath(l.filename, shared.cmd_opts.lora_dir))[0]
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
if l.sd_version == network.SdVersion.SDXL:
return None
elif shared.backend == shared.Backend.DIFFUSERS:
elif shared.native:
if shared.sd_model_type == 'none': # return all when model is not loaded
pass
elif shared.sd_model_type == 'sdxl':
+2 -2
View File
@@ -12,7 +12,7 @@ class Script(scripts.Script):
return 'Face'
def show(self, is_img2img):
return True if shared.backend == shared.Backend.DIFFUSERS else False
return True if shared.native else False
def load_images(self, files):
init_images = []
@@ -90,7 +90,7 @@ class Script(scripts.Script):
return [mode, gallery, ip_model, ip_override, ip_cache, ip_strength, ip_structure, id_strength, id_conditioning, id_cache, pm_trigger, pm_strength, pm_start, fs_cache]
def run(self, p: processing.StableDiffusionProcessing, mode, input_images, ip_model, ip_override, ip_cache, ip_strength, ip_structure, id_strength, id_conditioning, id_cache, pm_trigger, pm_strength, pm_start, fs_cache): # pylint: disable=arguments-differ, unused-argument
if shared.backend != shared.Backend.DIFFUSERS:
if not shared.native:
return None
if mode == 'None':
return None
+1 -1
View File
@@ -70,7 +70,7 @@ def face_id(
if shared.opts.cuda_compile_backend == 'none':
sd_models.apply_token_merging(p.sd_model)
sd_hijack_freeu.apply_freeu(p, shared.backend == shared.Backend.ORIGINAL)
sd_hijack_freeu.apply_freeu(p, not shared.native)
script_callbacks.before_process_callback(p)
+2
View File
@@ -6,6 +6,8 @@ from modules.hidiffusion import hidiffusion
def apply_hidiffusion(p, model_type):
if not shared.native:
return
if model_type not in ['sd', 'sdxl'] and p.hidiffusion:
shared.log.warning(f'HiDiffusion: class={shared.sd_model.__class__.__name__} not supported')
return
+3 -3
View File
@@ -165,7 +165,7 @@ class InterrogateModels:
res = ""
shared.state.begin('Interrogate')
try:
if shared.backend == shared.Backend.ORIGINAL and (shared.cmd_opts.lowvram or shared.cmd_opts.medvram):
if not shared.native and (shared.cmd_opts.lowvram or shared.cmd_opts.medvram):
lowvram.send_everything_to_cpu()
devices.torch_gc()
self.load()
@@ -269,7 +269,7 @@ def interrogate(image, mode, caption=None):
def interrogate_image(image, model, mode):
shared.state.begin('Interrogate')
try:
if shared.backend == shared.Backend.ORIGINAL and (shared.cmd_opts.lowvram or shared.cmd_opts.medvram):
if not shared.native and (shared.cmd_opts.lowvram or shared.cmd_opts.medvram):
lowvram.send_everything_to_cpu()
devices.torch_gc()
load_interrogator(model)
@@ -297,7 +297,7 @@ def interrogate_batch(batch_files, batch_folder, batch_str, model, mode, write):
shared.state.begin('Batch interrogate')
prompts = []
try:
if shared.backend == shared.Backend.ORIGINAL and (shared.cmd_opts.lowvram or shared.cmd_opts.medvram):
if not shared.native and (shared.cmd_opts.lowvram or shared.cmd_opts.medvram):
lowvram.send_everything_to_cpu()
devices.torch_gc()
load_interrogator(model)
+1 -1
View File
@@ -138,7 +138,7 @@ def apply(pipe, p: processing.StableDiffusionProcessing, adapter_names=[], adapt
# init code
if pipe is None:
return False
if shared.backend != shared.Backend.DIFFUSERS:
if not shared.native:
shared.log.warning('IP adapter: not in diffusers mode')
return False
if len(adapter_images) == 0:
+2
View File
@@ -41,6 +41,8 @@ def apply_layerdiffuse_sdxl_conv(pipeline):
def apply_layerdiffuse():
if not shared.native:
return
try:
if shared.sd_model_type == 'sd':
shared.log.info(f'LayerDiffuse: class={shared.sd_model.__class__.__name__}')
+2 -2
View File
@@ -81,7 +81,7 @@ class Shared(sys.modules[__name__].__class__):
if modules.sd_models.model_data.sd_model is None:
model_type = 'none'
return model_type
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
model_type = 'ldm'
elif "StableDiffusionXL" in self.sd_model.__class__.__name__:
model_type = 'sdxl'
@@ -110,7 +110,7 @@ class Shared(sys.modules[__name__].__class__):
if modules.sd_models.model_data.sd_refiner is None:
model_type = 'none'
return model_type
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
model_type = 'ldm'
elif "StableDiffusionXL" in self.sd_refiner.__class__.__name__:
model_type = 'sdxl'
+2
View File
@@ -11,6 +11,8 @@ orig_pipeline = None
def apply(p: processing.StableDiffusionProcessing): # pylint: disable=arguments-differ
global orig_pipeline # pylint: disable=global-statement
c = shared.sd_model.__class__ if shared.sd_loaded else None
if not shared.native:
return None
if p.pag_scale == 0:
unapply()
return None
+1 -1
View File
@@ -8,7 +8,7 @@ class UpscalerSD(Upscaler):
def __init__(self, dirname): # pylint: disable=super-init-not-called
self.name = "SDUpscale"
self.user_path = dirname
if shared.backend != shared.Backend.DIFFUSERS:
if not shared.native:
super().__init__()
return
self.scalers = [
+9 -9
View File
@@ -161,7 +161,7 @@ def process_images(p: StableDiffusionProcessing) -> Processed:
pag.apply(p)
if shared.opts.cuda_compile_backend == 'none':
sd_models.apply_token_merging(p.sd_model)
sd_hijack_freeu.apply_freeu(p, shared.backend == shared.Backend.ORIGINAL)
sd_hijack_freeu.apply_freeu(p, not shared.native)
if p.width is not None:
p.width = 8 * int(p.width / 8)
@@ -247,7 +247,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
else:
assert p.prompt is not None
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
import modules.sd_hijack # pylint: disable=redefined-outer-name
modules.sd_hijack.model_hijack.apply_circular(p.tiling)
modules.sd_hijack.model_hijack.clear_comments()
@@ -256,7 +256,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
output_images = []
process_init(p)
if os.path.exists(shared.opts.embeddings_dir) and not p.do_not_reload_embeddings and shared.backend == shared.Backend.ORIGINAL:
if os.path.exists(shared.opts.embeddings_dir) and not p.do_not_reload_embeddings and not shared.native:
modules.sd_hijack.model_hijack.embedding_db.load_textual_inversion_embeddings(force_reload=False)
if p.scripts is not None and isinstance(p.scripts, scripts.ScriptRunner):
p.scripts.process(p)
@@ -264,7 +264,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
def infotext(_inxex=0): # dummy function overriden if there are iterations
return ''
ema_scope_context = p.sd_model.ema_scope if shared.backend == shared.Backend.ORIGINAL else nullcontext
ema_scope_context = p.sd_model.ema_scope if not shared.native else nullcontext
shared.state.job_count = p.n_iter
with devices.inference_context(), ema_scope_context():
t0 = time.time()
@@ -283,7 +283,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
shared.log.debug(f'Process interrupted: {n+1}/{p.n_iter}')
break
if shared.backend == shared.Backend.DIFFUSERS:
if shared.native:
from modules import ipadapter
ipadapter.apply(shared.sd_model, p)
p.prompts = p.all_prompts[n * p.batch_size:(n+1) * p.batch_size]
@@ -304,10 +304,10 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
if p.scripts is not None and isinstance(p.scripts, scripts.ScriptRunner):
x_samples_ddim = p.scripts.process_images(p)
if x_samples_ddim is None:
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
from modules.processing_original import process_original
x_samples_ddim = process_original(p)
elif shared.backend == shared.Backend.DIFFUSERS:
elif shared.native:
from modules.processing_diffusers import process_diffusers
x_samples_ddim = process_diffusers(p)
else:
@@ -316,7 +316,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
if not shared.opts.keep_incomplete and shared.state.interrupted:
x_samples_ddim = []
if shared.backend == shared.Backend.ORIGINAL and (shared.cmd_opts.lowvram or shared.cmd_opts.medvram):
if not shared.native and (shared.cmd_opts.lowvram or shared.cmd_opts.medvram):
lowvram.send_everything_to_cpu()
devices.torch_gc()
if p.scripts is not None and isinstance(p.scripts, scripts.ScriptRunner):
@@ -407,7 +407,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
if shared.opts.grid_save:
images.save_image(grid, p.outpath_grids, "", p.all_seeds[0], p.all_prompts[0], shared.opts.grid_format, info=infotext(-1), p=p, grid=True, suffix="-grid") # main save grid
if shared.backend == shared.Backend.DIFFUSERS:
if shared.native:
from modules import ipadapter
ipadapter.unapply(shared.sd_model)
+9 -9
View File
@@ -215,7 +215,7 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
self.script_args = []
def init(self, all_prompts=None, all_seeds=None, all_subseeds=None):
if shared.backend == shared.Backend.DIFFUSERS:
if shared.native:
shared.sd_model = sd_models.set_diffuser_pipe(self.sd_model, sd_models.DiffusersTaskType.TEXT_2_IMAGE)
self.width = self.width or 512
self.height = self.height or 512
@@ -252,7 +252,7 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
self.hr_upscale_to_y = self.hr_resize_y
self.truncate_x = (self.hr_upscale_to_x - target_w) // 8
self.truncate_y = (self.hr_upscale_to_y - target_h) // 8
if shared.backend == shared.Backend.ORIGINAL: # diffusers are handled in processing_diffusers
if not shared.native: # diffusers are handled in processing_diffusers
if (self.hr_upscale_to_x == self.width and self.hr_upscale_to_y == self.height) or upscaler is None or upscaler == 'None': # special case: the user has chosen to do nothing
self.is_hr_pass = False
return
@@ -303,9 +303,9 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
self.script_args = []
def init(self, all_prompts=None, all_seeds=None, all_subseeds=None):
if shared.backend == shared.Backend.DIFFUSERS and getattr(self, 'image_mask', None) is not None:
if shared.native and getattr(self, 'image_mask', None) is not None:
shared.sd_model = sd_models.set_diffuser_pipe(self.sd_model, sd_models.DiffusersTaskType.INPAINTING)
elif shared.backend == shared.Backend.DIFFUSERS and getattr(self, 'init_images', None) is not None:
elif shared.native and getattr(self, 'init_images', None) is not None:
shared.sd_model = sd_models.set_diffuser_pipe(self.sd_model, sd_models.DiffusersTaskType.IMAGE_2_IMAGE)
if all_prompts is not None:
@@ -317,7 +317,7 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
if self.sampler_name == "PLMS":
self.sampler_name = 'UniPC'
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
self.sampler = sd_samplers.create_sampler(self.sampler_name, self.sd_model)
if hasattr(self.sampler, "initialize"):
self.sampler.initialize(self)
@@ -331,7 +331,7 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
if self.image_mask is not None:
if type(self.image_mask) == list:
self.image_mask = self.image_mask[0]
if shared.backend == shared.Backend.ORIGINAL: # original way of processing mask
if not shared.native: # original way of processing mask
self.image_mask = processing_helpers.create_binary_mask(self.image_mask)
if self.inpainting_mask_invert:
self.image_mask = ImageOps.invert(self.image_mask)
@@ -341,7 +341,7 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
np_mask = cv2.GaussianBlur(np_mask, (kernel_size, 1), self.mask_blur)
np_mask = cv2.GaussianBlur(np_mask, (1, kernel_size), self.mask_blur)
self.image_mask = Image.fromarray(np_mask)
elif shared.backend == shared.Backend.DIFFUSERS:
elif shared.native:
if 'control' in self.ops:
self.image_mask = masking.run_mask(input_image=self.init_images, input_mask=self.image_mask, return_type='Grayscale', invert=self.inpainting_mask_invert==1) # blur/padding are handled in masking module
else:
@@ -411,9 +411,9 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
self.overlay_images = self.overlay_images * self.batch_size
if self.color_corrections is not None and len(self.color_corrections) == 1:
self.color_corrections = self.color_corrections * self.batch_size
if shared.backend == shared.Backend.DIFFUSERS:
if shared.native:
return # we've already set self.init_images and self.mask and we dont need any more processing
elif shared.backend == shared.Backend.ORIGINAL:
elif not shared.native:
self.init_images = [np.moveaxis((np.array(image).astype(np.float32) / 255.0), 2, 0) for image in self.init_images]
if len(self.init_images) == 1:
batch_images = np.expand_dims(self.init_images[0], axis=0).repeat(self.batch_size, axis=0)
+3 -3
View File
@@ -35,9 +35,9 @@ def apply_color_correction(correction, original_image):
def apply_overlay(image: Image, paste_loc, index, overlays):
debug(f'Apply overlay: image={image} loc={paste_loc} index={index} overlays={overlays}')
if overlays is None or index >= len(overlays):
return image
debug(f'Apply overlay: image={image} loc={paste_loc} index={index} overlays={overlays}')
overlay = overlays[index]
if paste_loc is not None:
x, y, w, h = paste_loc
@@ -321,7 +321,7 @@ def img2img_image_conditioning(p, source_image, latent_image, image_mask=None):
# HACK: Using introspection as the Depth2Image model doesn't appear to uniquely
# identify itself with a field common to all models. The conditioning_key is also hybrid.
if shared.backend == shared.Backend.DIFFUSERS:
if shared.native:
return diffusers_image_conditioning(source_image, latent_image, image_mask)
if isinstance(p.sd_model, LatentDepth2ImageDiffusion):
return depth2img_image_conditioning(source_image)
@@ -346,7 +346,7 @@ def validate_sample(tensor):
sample = tensor
else:
shared.log.warning(f'Unknown sample type: {type(tensor)}')
sample = 255.0 * np.moveaxis(sample, 0, 2) if shared.backend == shared.Backend.ORIGINAL else 255.0 * sample
sample = 255.0 * np.moveaxis(sample, 0, 2) if not shared.native else 255.0 * sample
with warnings.catch_warnings(record=True) as w:
cast = sample.astype(np.uint8)
if len(w) > 0:
+4 -4
View File
@@ -4,7 +4,7 @@ from modules import shared, sd_samplers_common, sd_vae, generation_parameters_co
from modules.processing_class import StableDiffusionProcessing
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
from modules import sd_hijack
else:
sd_hijack = None
@@ -57,7 +57,7 @@ def create_infotext(p: StableDiffusionProcessing, all_prompts=None, all_seeds=No
"Styles": "; ".join(p.styles) if p.styles is not None and len(p.styles) > 0 else None,
"Tiling": p.tiling if p.tiling else None,
# sdnext
"Backend": 'Diffusers' if shared.backend == shared.Backend.DIFFUSERS else 'Original',
"Backend": 'Diffusers' if shared.native else 'Original',
"App": 'SD.Next',
"Version": git_commit,
"Comment": comment,
@@ -109,12 +109,12 @@ def create_infotext(p: StableDiffusionProcessing, all_prompts=None, all_seeds=No
args["Sampler ENSD"] = shared.opts.eta_noise_seed_delta if shared.opts.eta_noise_seed_delta != 0 and sd_samplers_common.is_sampler_using_eta_noise_seed_delta(p) else None
args["Sampler ENSM"] = p.initial_noise_multiplier if getattr(p, 'initial_noise_multiplier', 1.0) != 1.0 else None
args['Sampler order'] = shared.opts.schedulers_solver_order if shared.opts.schedulers_solver_order != shared.opts.data_labels.get('schedulers_solver_order').default else None
if shared.backend == shared.Backend.DIFFUSERS:
if shared.native:
args['Sampler beta schedule'] = shared.opts.schedulers_beta_schedule if shared.opts.schedulers_beta_schedule != shared.opts.data_labels.get('schedulers_beta_schedule').default else None
args['Sampler beta start'] = shared.opts.schedulers_beta_start if shared.opts.schedulers_beta_start != shared.opts.data_labels.get('schedulers_beta_start').default else None
args['Sampler beta end'] = shared.opts.schedulers_beta_end if shared.opts.schedulers_beta_end != shared.opts.data_labels.get('schedulers_beta_end').default else None
args['Sampler DPM solver'] = shared.opts.schedulers_dpm_solver if shared.opts.schedulers_dpm_solver != shared.opts.data_labels.get('schedulers_dpm_solver').default else None
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
args['Sampler brownian'] = shared.opts.schedulers_brownian_noise if shared.opts.schedulers_brownian_noise != shared.opts.data_labels.get('schedulers_brownian_noise').default else None
args['Sampler discard'] = shared.opts.schedulers_discard_penultimate if shared.opts.schedulers_discard_penultimate != shared.opts.data_labels.get('schedulers_discard_penultimate').default else None
args['Sampler dyn threshold'] = shared.opts.schedulers_use_thresholding if shared.opts.schedulers_use_thresholding != shared.opts.data_labels.get('schedulers_use_thresholding').default else None
+2 -2
View File
@@ -14,7 +14,7 @@ from typing import List
import lark
import torch
from compel import Compel
from modules.shared import opts, log, backend, Backend
from modules.shared import opts, log, native
# a prompt like this: "fantasy landscape with a [mountain:lake:0.25] and [an oak:a christmas tree:0.75][ in foreground::0.6][ in background:0.25] [shoddy:masterful:0.5]"
# will be represented with prompt_schedule like this (assuming steps=100):
@@ -326,7 +326,7 @@ def parse_prompt_attention(text):
whitespace = ''
else:
re_attention = re_attention_v1
if backend == Backend.DIFFUSERS:
if native:
text = text.replace('\n', ' BREAK ')
else:
text = text.replace('\n', ' ')
+15 -23
View File
@@ -104,7 +104,7 @@ def get_prompt_schedule(prompt, steps):
def get_tokens(msg, prompt):
global token_dict, token_type # pylint: disable=global-statement
if shared.backend != shared.Backend.DIFFUSERS:
if not shared.native:
return
if shared.sd_loaded and hasattr(shared.sd_model, 'tokenizer') and shared.sd_model.tokenizer is not None:
if token_dict is None or token_type != shared.sd_model_type:
@@ -133,7 +133,7 @@ def encode_prompts(pipe, p, prompts: list, negative_prompts: list, steps: int, c
if 'StableDiffusion' not in pipe.__class__.__name__ and 'DemoFusion' not in pipe.__class__.__name__ and 'StableCascade' not in pipe.__class__.__name__:
shared.log.warning(f"Prompt parser not supported: {pipe.__class__.__name__}")
return
elif prompts == cache.get('prompts', None) and negative_prompts == cache.get('negative_prompts', None) and clip_skip == cache.get('clip_skip', None) and cache.get('model_type', None) == shared.sd_model_type:
elif prompts == cache.get('prompts', None) and negative_prompts == cache.get('negative_prompts', None) and clip_skip == cache.get('clip_skip', None) and cache.get('model_type', None) == shared.sd_model_type and steps == cache.get('steps', None):
p.prompt_embeds = cache.get('prompt_embeds', None)
p.positive_pooleds = cache.get('positive_pooleds', None)
p.negative_embeds = cache.get('negative_embeds', None)
@@ -154,36 +154,28 @@ def encode_prompts(pipe, p, prompts: list, negative_prompts: list, steps: int, c
for i in range(max(len(positive_schedule), len(negative_schedule))):
positive_prompt = positive_schedule[i % len(positive_schedule)]
negative_prompt = negative_schedule[i % len(negative_schedule)]
if cache.get('model_type', None) != shared.sd_model_type:
cache[positive_prompt + negative_prompt] = None
results = None
elif clip_skip == cache.get('clip_skip', None):
results = cache.get(positive_prompt + negative_prompt, None)
else:
results = None
if results is None:
results = get_weighted_text_embeddings(pipe, positive_prompt, negative_prompt, clip_skip)
cache[positive_prompt + negative_prompt] = results
prompt_embed, positive_pooled, negative_embed, negative_pooled = results
prompt_embed, positive_pooled, negative_embed, negative_pooled = get_weighted_text_embeddings(pipe, positive_prompt, negative_prompt, clip_skip)
if prompt_embed is not None:
p.prompt_embeds.append(torch.cat([prompt_embed] * len(prompts), dim=0))
cache['prompt_embeds'] = p.prompt_embeds
if negative_embed is not None:
p.negative_embeds.append(torch.cat([negative_embed] * len(negative_prompts), dim=0))
cache['negative_embeds'] = p.negative_embeds
if positive_pooled is not None:
p.positive_pooleds.append(torch.cat([positive_pooled] * len(prompts), dim=0))
cache['positive_pooleds'] = p.positive_pooleds
if negative_pooled is not None:
p.negative_pooleds.append(torch.cat([negative_pooled] * len(negative_prompts), dim=0))
cache['negative_pooleds'] = p.negative_pooleds
cache['prompts'] = prompts
cache['negative_prompts'] = negative_prompts
cache['clip_skip'] = clip_skip
cache['model_type'] = shared.sd_model_type
cache.update({
'prompt_embeds': p.prompt_embeds,
'negative_embeds': p.negative_embeds,
'positive_pooleds': p.positive_pooleds,
'negative_pooleds': p.negative_pooleds,
'scheduled_prompt': p.scheduled_prompt,
'prompts': prompts,
'negative_prompts': negative_prompts,
'clip_skip': clip_skip,
'steps': steps,
'model_type': shared.sd_model_type
})
if debug_enabled:
get_tokens('positive', prompts[0])
get_tokens('negative', negative_prompts[0])
+2 -2
View File
@@ -175,7 +175,7 @@ class StableDiffusionModelHijack:
if m.cond_stage_key == "edit":
sd_hijack_unet.hijack_ddpm_edit()
if "Model" in shared.opts.ipex_optimize and shared.backend == shared.Backend.ORIGINAL:
if "Model" in shared.opts.ipex_optimize and not shared.native:
try:
import intel_extension_for_pytorch as ipex # pylint: disable=import-error, unused-import
m.model.eval()
@@ -185,7 +185,7 @@ class StableDiffusionModelHijack:
except Exception as err:
shared.log.warning(f"IPEX Optimize not supported: {err}")
if "Model" in shared.opts.cuda_compile and shared.opts.cuda_compile_backend != 'none' and shared.backend == shared.Backend.ORIGINAL:
if "Model" in shared.opts.cuda_compile and shared.opts.cuda_compile_backend != 'none' and not shared.native:
try:
import logging
shared.log.info(f"Compiling pipeline={m.model.__class__.__name__} mode={shared.opts.cuda_compile_backend}")
+2 -2
View File
@@ -186,7 +186,7 @@ def context_hypertile_vae(p):
error_reported = False
height, width = p.height, p.width
max_h, max_w = 0, 0
vae = getattr(p.sd_model, "vae", None) if shared.backend == shared.Backend.DIFFUSERS else getattr(p.sd_model, "first_stage_model", None)
vae = getattr(p.sd_model, "vae", None) if shared.native else getattr(p.sd_model, "first_stage_model", None)
if height % 8 != 0 or width % 8 != 0:
log.warning(f'Hypertile VAE disabled: width={width} height={height} are not divisible by 8')
return nullcontext()
@@ -211,7 +211,7 @@ def context_hypertile_unet(p):
error_reported = False
height, width = p.height, p.width
max_h, max_w = 0, 0
unet = getattr(p.sd_model, "unet", None) if shared.backend == shared.Backend.DIFFUSERS else getattr(p.sd_model.model, "diffusion_model", None)
unet = getattr(p.sd_model, "unet", None) if shared.native else getattr(p.sd_model.model, "diffusion_model", None)
if height % 8 != 0 or width % 8 != 0:
log.warning(f'Hypertile UNet disabled: width={width} height={height} are not divisible by 8')
return nullcontext()
+25 -24
View File
@@ -127,7 +127,7 @@ def setup_model():
list_models()
sd_hijack_accelerate.hijack_hfhub()
# sd_hijack_accelerate.hijack_torch_conv()
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
enable_midas_autodownload()
@@ -144,19 +144,19 @@ def list_models():
global checkpoints_list # pylint: disable=global-statement
checkpoints_list.clear()
checkpoint_aliases.clear()
ext_filter = [".safetensors"] if shared.opts.sd_disable_ckpt or shared.backend == shared.Backend.DIFFUSERS else [".ckpt", ".safetensors"]
ext_filter = [".safetensors"] if shared.opts.sd_disable_ckpt or shared.native else [".ckpt", ".safetensors"]
model_list = list(modelloader.load_models(model_path=model_path, model_url=None, command_path=shared.opts.ckpt_dir, ext_filter=ext_filter, download_name=None, ext_blacklist=[".vae.ckpt", ".vae.safetensors"]))
for filename in sorted(model_list, key=str.lower):
checkpoint_info = CheckpointInfo(filename)
if checkpoint_info.name is not None:
checkpoint_info.register()
if shared.backend == shared.Backend.DIFFUSERS:
if shared.native:
for repo in modelloader.load_diffusers_models(clear=True):
checkpoint_info = CheckpointInfo(repo['name'], sha=repo['hash'])
if checkpoint_info.name is not None:
checkpoint_info.register()
if shared.cmd_opts.ckpt is not None:
if not os.path.exists(shared.cmd_opts.ckpt) and shared.backend == shared.Backend.ORIGINAL:
if not os.path.exists(shared.cmd_opts.ckpt) and not shared.native:
if shared.cmd_opts.ckpt.lower() != "none":
shared.log.warning(f"Requested checkpoint not found: {shared.cmd_opts.ckpt}")
else:
@@ -414,7 +414,7 @@ def get_checkpoint_state_dict(checkpoint_info: CheckpointInfo, timer):
checkpoints_loaded.move_to_end(checkpoint_info, last=True) # FIFO -> LRU cache
return checkpoints_loaded[checkpoint_info]
res = read_state_dict(checkpoint_info.filename)
if shared.opts.sd_checkpoint_cache > 0 and shared.backend == shared.Backend.ORIGINAL:
if shared.opts.sd_checkpoint_cache > 0 and not shared.native:
# cache newly loaded model
checkpoints_loaded[checkpoint_info] = res
# clean up cache if limit is reached
@@ -536,6 +536,7 @@ def change_backend():
shared.log.warning('Full server restart required to apply all changes')
unload_model_weights()
shared.backend = shared.Backend.ORIGINAL if shared.opts.sd_backend == 'original' else shared.Backend.DIFFUSERS
shared.native = shared.backend == shared.Backend.DIFFUSERS
checkpoints_loaded.clear()
from modules.sd_samplers import list_samplers
list_samplers(shared.backend)
@@ -564,29 +565,29 @@ def detect_pipeline(f: str, op: str = 'model', warning=True):
# elif size < 0: # unknown
# guess = 'Stable Diffusion 2B'
elif size >= 5791 and size <= 5799: # 5795
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
warn(f'Model detected as SD-XL refiner model, but attempting to load using backend=original: {op}={f} size={size} MB')
if op == 'model':
warn(f'Model detected as SD-XL refiner model, but attempting to load a base model: {op}={f} size={size} MB')
guess = 'Stable Diffusion XL Refiner'
elif (size >= 6611 and size <= 7220): # 6617, HassakuXL is 6776, monkrenRealisticINT_v10 is 7217
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
warn(f'Model detected as SD-XL base model, but attempting to load using backend=original: {op}={f} size={size} MB')
guess = 'Stable Diffusion XL'
elif size >= 3361 and size <= 3369: # 3368
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
warn(f'Model detected as SD upscale model, but attempting to load using backend=original: {op}={f} size={size} MB')
guess = 'Stable Diffusion Upscale'
elif size >= 4891 and size <= 4899: # 4897
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
warn(f'Model detected as SD XL inpaint model, but attempting to load using backend=original: {op}={f} size={size} MB')
guess = 'Stable Diffusion XL Inpaint'
elif size >= 9791 and size <= 9799: # 9794
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
warn(f'Model detected as SD XL instruct pix2pix model, but attempting to load using backend=original: {op}={f} size={size} MB')
guess = 'Stable Diffusion XL Instruct'
elif size > 3138 and size < 3142: #3140
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
warn(f'Model detected as Segmind Vega model, but attempting to load using backend=original: {op}={f} size={size} MB')
guess = 'Stable Diffusion XL'
# guess by name
@@ -597,29 +598,29 @@ def detect_pipeline(f: str, op: str = 'model', warning=True):
guess = 'Latent Consistency Model'
"""
if 'instaflow' in f.lower():
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
warn(f'Model detected as InstaFlow model, but attempting to load using backend=original: {op}={f} size={size} MB')
guess = 'InstaFlow'
if 'segmoe' in f.lower():
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
warn(f'Model detected as SegMoE model, but attempting to load using backend=original: {op}={f} size={size} MB')
guess = 'SegMoE'
if 'hunyuandit' in f.lower():
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
warn(f'Model detected as Tenecent HunyuanDiT model, but attempting to load using backend=original: {op}={f} size={size} MB')
guess = 'HunyuanDiT'
if 'pixart-xl' in f.lower():
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
warn(f'Model detected as PixArt Alpha model, but attempting to load using backend=original: {op}={f} size={size} MB')
guess = 'PixArt-Alpha'
if 'stable-cascade' in f.lower() or 'stablecascade' in f.lower() or 'wuerstchen3' in f.lower():
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
warn(f'Model detected as Stable Cascade model, but attempting to load using backend=original: {op}={f} size={size} MB')
if devices.dtype == torch.float16:
warn('Stable Cascade does not support Float16')
guess = 'Stable Cascade'
if 'pixart_sigma' in f.lower():
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
warn(f'Model detected as PixArt-Sigma model, but attempting to load using backend=original: {op}={f} size={size} MB')
guess = 'PixArt-Sigma'
# switch for specific variant
@@ -1415,7 +1416,7 @@ def load_model(checkpoint_info=None, already_loaded_state_dict=None, timer=None,
current_checkpoint_info = model_data.sd_refiner.sd_checkpoint_info
unload_model_weights(op=op)
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
from modules import sd_hijack_inpainting
sd_hijack_inpainting.do_inpainting_hijack()
@@ -1472,7 +1473,7 @@ def load_model(checkpoint_info=None, already_loaded_state_dict=None, timer=None,
else:
shared.log.debug(f'Model weights loaded: {memory_stats()}')
timer.record("load")
if shared.backend == shared.Backend.ORIGINAL and (shared.cmd_opts.lowvram or shared.cmd_opts.medvram):
if not shared.native and (shared.cmd_opts.lowvram or shared.cmd_opts.medvram):
lowvram.setup_for_low_vram(sd_model, shared.cmd_opts.medvram)
else:
move_model(sd_model, devices.device)
@@ -1519,7 +1520,7 @@ def reload_model_weights(sd_model=None, info=None, reuse_dict=False, op='model',
current_checkpoint_info = getattr(sd_model, 'sd_checkpoint_info', None)
if current_checkpoint_info is not None and checkpoint_info is not None and current_checkpoint_info.filename == checkpoint_info.filename and not force:
return None
if shared.backend == shared.Backend.ORIGINAL and (shared.cmd_opts.lowvram or shared.cmd_opts.medvram):
if not shared.native and (shared.cmd_opts.lowvram or shared.cmd_opts.medvram):
lowvram.send_everything_to_cpu()
else:
move_model(sd_model, devices.cpu)
@@ -1531,12 +1532,12 @@ def reload_model_weights(sd_model=None, info=None, reuse_dict=False, op='model',
sd_model = None
timer = Timer()
# TODO implement caching after diffusers implement state_dict loading
state_dict = get_checkpoint_state_dict(checkpoint_info, timer) if shared.backend == shared.Backend.ORIGINAL else None
state_dict = get_checkpoint_state_dict(checkpoint_info, timer) if not shared.native else None
checkpoint_config = sd_models_config.find_checkpoint_config(state_dict, checkpoint_info)
timer.record("config")
if sd_model is None or checkpoint_config != getattr(sd_model, 'used_config', None):
sd_model = None
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
load_model(checkpoint_info, already_loaded_state_dict=state_dict, timer=timer, op=op)
model_data.sd_dict = shared.opts.sd_model_dict
else:
@@ -1603,7 +1604,7 @@ def unload_model_weights(op='model'):
shared.compiled_model_state.partitioned_modules.clear()
if op == 'model' or op == 'dict':
if model_data.sd_model:
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
from modules import sd_hijack
move_model(model_data.sd_model, devices.cpu)
sd_hijack.model_hijack.undo_hijack(model_data.sd_model)
@@ -1615,7 +1616,7 @@ def unload_model_weights(op='model'):
shared.log.debug(f'Unload weights {op}: {memory_stats()}')
elif op == 'refiner':
if model_data.sd_refiner:
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
from modules import sd_hijack
move_model(model_data.sd_refiner, devices.cpu)
sd_hijack.model_hijack.undo_hijack(model_data.sd_refiner)
+3 -3
View File
@@ -20,7 +20,7 @@ def list_samplers(backend_name = shared.backend):
global samplers # pylint: disable=global-statement
global samplers_for_img2img # pylint: disable=global-statement
global samplers_map # pylint: disable=global-statement
if backend_name == shared.Backend.ORIGINAL:
if not shared.native:
from modules import sd_samplers_compvis, sd_samplers_kdiffusion
all_samplers = [*sd_samplers_compvis.samplers_data_compvis, *sd_samplers_kdiffusion.samplers_data_k_diffusion]
else:
@@ -57,14 +57,14 @@ def create_sampler(name, model):
if config is None or config.constructor is None:
# shared.log.warning(f'Sampler: sampler="{name}" not found')
return None
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
sampler = config.constructor(model)
sampler.config = config
sampler.name = name
sampler.initialize(p=None)
shared.log.debug(f'Sampler: sampler="{name}" config={config.options}')
return sampler
elif shared.backend == shared.Backend.DIFFUSERS:
elif shared.native:
sampler = config.constructor(model)
if not hasattr(model, 'scheduler_config'):
model.scheduler_config = sampler.sampler.config.copy()
+1 -1
View File
@@ -49,7 +49,7 @@ def single_sample_to_image(sample, approximation=None):
if len(sample.shape) == 4 and sample.shape[0]: # likely animatediff latent
sample = sample.permute(1, 0, 2, 3)[0]
if shared.backend == shared.Backend.DIFFUSERS: # [-x,x] to [-5,5]
if shared.native: # [-x,x] to [-5,5]
sample_max = torch.max(sample)
if sample_max > 5:
sample = sample * (5 / sample_max)
+5 -5
View File
@@ -54,7 +54,7 @@ def refresh_vae_list():
vae_path = shared.opts.vae_dir
vae_dict.clear()
vae_paths = []
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
if sd_models.model_path is not None and os.path.isdir(sd_models.model_path):
vae_paths += [
os.path.join(sd_models.model_path, 'VAE', '**/*.vae.ckpt'),
@@ -73,7 +73,7 @@ def refresh_vae_list():
os.path.join(shared.opts.vae_dir, '**/*.pt'),
os.path.join(shared.opts.vae_dir, '**/*.safetensors'),
]
elif shared.backend == shared.Backend.DIFFUSERS:
elif shared.native:
if sd_models.model_path is not None and os.path.isdir(sd_models.model_path):
vae_paths += [os.path.join(sd_models.model_path, 'VAE', '**/*.vae.safetensors')]
if shared.opts.ckpt_dir is not None and os.path.isdir(shared.opts.ckpt_dir):
@@ -92,7 +92,7 @@ def refresh_vae_list():
name = get_filename(filepath)
if name == 'VAE':
continue
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
vae_dict[name] = filepath
else:
if filepath.endswith(".json"):
@@ -243,12 +243,12 @@ def reload_vae_weights(sd_model=None, vae_file=unspecified):
vae_source = "function-argument"
if loaded_vae_file == vae_file:
return None
if shared.backend == shared.Backend.ORIGINAL and (shared.cmd_opts.lowvram or shared.cmd_opts.medvram):
if not shared.native and (shared.cmd_opts.lowvram or shared.cmd_opts.medvram):
lowvram.send_everything_to_cpu()
# else:
# sd_models.move_model(sd_model, devices.cpu)
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
sd_hijack.model_hijack.undo_hijack(sd_model)
if shared.cmd_opts.rollback_vae and devices.dtype_vae == torch.bfloat16:
devices.dtype_vae = torch.float16
+20 -20
View File
@@ -206,7 +206,7 @@ if cmd_opts.backend is not None: # override with args
if cmd_opts.use_openvino: # override for openvino
backend = Backend.DIFFUSERS
from modules.intel.openvino import get_device_list as get_openvino_device_list # pylint: disable=ungrouped-imports
native = backend == Backend.DIFFUSERS
class OptionInfo:
def __init__(self, default=None, label="", component=None, component_args=None, onchange=None, section=None, refresh=None, folder=None, submit=None, comment_before='', comment_after=''):
@@ -340,11 +340,11 @@ def temp_disable_extensions():
for ext in disable_safe:
if ext.lower() not in opts.disabled_extensions:
disabled.append(ext)
if backend == Backend.DIFFUSERS:
if native:
for ext in disable_diffusers:
if ext.lower() not in opts.disabled_extensions:
disabled.append(ext)
if backend == Backend.ORIGINAL:
if not native:
for ext in disable_original:
if ext.lower() not in opts.disabled_extensions:
disabled.append(ext)
@@ -366,13 +366,13 @@ if not (cmd_opts.lowvram or cmd_opts.medvram):
if devices.backend == "directml": # Force BMM for DirectML instead of SDP
cross_attention_optimization_default = "Dynamic Attention BMM" if backend == Backend.DIFFUSERS else "Sub-quadratic"
elif backend == Backend.DIFFUSERS and (cmd_opts.lowvram or cmd_opts.medvram):
cross_attention_optimization_default = "Dynamic Attention BMM" if native else "Sub-quadratic"
elif native and (cmd_opts.lowvram or cmd_opts.medvram):
cross_attention_optimization_default = "Dynamic Attention SDP"
elif devices.backend == "cpu":
cross_attention_optimization_default = "Scaled-Dot-Product" if backend == Backend.DIFFUSERS else "Doggettx's"
cross_attention_optimization_default = "Scaled-Dot-Product" if native else "Doggettx's"
elif devices.backend == "mps":
cross_attention_optimization_default = "Scaled-Dot-Product" if backend == Backend.DIFFUSERS else "Doggettx's"
cross_attention_optimization_default = "Scaled-Dot-Product" if native else "Doggettx's"
else: # cuda, rocm, ipex
cross_attention_optimization_default ="Scaled-Dot-Product"
@@ -392,12 +392,12 @@ options_templates.update(options_section(('sd', "Execution & Models"), {
"sd_unet": OptionInfo("None", "UNET model", gr.Dropdown, lambda: {"choices": shared_items.sd_unet_items()}, refresh=shared_items.refresh_unet_list),
"sd_checkpoint_autoload": OptionInfo(True, "Model autoload on start"),
"sd_model_dict": OptionInfo('None', "Use separate base dict", gr.Dropdown, lambda: {"choices": ['None'] + list_checkpoint_tiles()}, refresh=refresh_checkpoints),
"stream_load": OptionInfo(False, "Load models using stream loading method", gr.Checkbox, {"visible": backend == Backend.ORIGINAL }),
"stream_load": OptionInfo(False, "Load models using stream loading method", gr.Checkbox, {"visible": not native }),
"model_reuse_dict": OptionInfo(False, "Reuse loaded model dictionary", gr.Checkbox, {"visible": False}),
"prompt_attention": OptionInfo("Full parser", "Prompt attention parser", gr.Radio, {"choices": ["Full parser", "Compel parser", "A1111 parser", "Fixed attention"] }),
"prompt_mean_norm": OptionInfo(True, "Prompt attention normalization", gr.Checkbox, {"visible": backend == Backend.ORIGINAL }),
"comma_padding_backtrack": OptionInfo(20, "Prompt padding", gr.Slider, {"minimum": 0, "maximum": 74, "step": 1, "visible": backend == Backend.ORIGINAL }),
"sd_checkpoint_cache": OptionInfo(0, "Cached models", gr.Slider, {"minimum": 0, "maximum": 10, "step": 1, "visible": backend == Backend.ORIGINAL }),
"prompt_mean_norm": OptionInfo(True, "Prompt attention normalization", gr.Checkbox, {"visible": not native }),
"comma_padding_backtrack": OptionInfo(20, "Prompt padding", gr.Slider, {"minimum": 0, "maximum": 74, "step": 1, "visible": not native }),
"sd_checkpoint_cache": OptionInfo(0, "Cached models", gr.Slider, {"minimum": 0, "maximum": 10, "step": 1, "visible": not native }),
"sd_vae_checkpoint_cache": OptionInfo(0, "Cached VAEs", gr.Slider, {"minimum": 0, "maximum": 10, "step": 1, "visible": False}),
"sd_disable_ckpt": OptionInfo(False, "Disallow models in ckpt format", gr.Checkbox, {"visible": False}),
}))
@@ -416,14 +416,14 @@ options_templates.update(options_section(('cuda', "Compute Settings"), {
"rollback_vae": OptionInfo(False, "Attempt VAE roll back for NaN values"),
"cross_attention_sep": OptionInfo("<h2>Attention</h2>", "", gr.HTML),
"cross_attention_optimization": OptionInfo(cross_attention_optimization_default, "Attention optimization method", gr.Radio, lambda: {"choices": shared_items.list_crossattention(diffusers=backend == Backend.DIFFUSERS) }),
"cross_attention_optimization": OptionInfo(cross_attention_optimization_default, "Attention optimization method", gr.Radio, lambda: {"choices": shared_items.list_crossattention(native) }),
"sdp_options": OptionInfo(sdp_options_default, "SDP options", gr.CheckboxGroup, {"choices": ['Flash attention', 'Memory attention', 'Math attention'] }),
"xformers_options": OptionInfo(['Flash attention'], "xFormers options", gr.CheckboxGroup, {"choices": ['Flash attention'] }),
"dynamic_attention_slice_rate": OptionInfo(4, "Dynamic Attention slicing rate in GB", gr.Slider, {"minimum": 0.1, "maximum": 16, "step": 0.1, "visible": backend == Backend.DIFFUSERS}),
"sub_quad_sep": OptionInfo("<h3>Sub-quadratic options</h3>", "", gr.HTML, {"visible": backend == Backend.ORIGINAL}),
"sub_quad_q_chunk_size": OptionInfo(512, "Attention query chunk size", gr.Slider, {"minimum": 16, "maximum": 8192, "step": 8, "visible": backend == Backend.ORIGINAL}),
"sub_quad_kv_chunk_size": OptionInfo(512, "Attention kv chunk size", gr.Slider, {"minimum": 0, "maximum": 8192, "step": 8, "visible": backend == Backend.ORIGINAL}),
"sub_quad_chunk_threshold": OptionInfo(80, "Attention chunking threshold", gr.Slider, {"minimum": 0, "maximum": 100, "step": 1, "visible": backend == Backend.ORIGINAL}),
"dynamic_attention_slice_rate": OptionInfo(4, "Dynamic Attention slicing rate in GB", gr.Slider, {"minimum": 0.1, "maximum": 16, "step": 0.1, "visible": native}),
"sub_quad_sep": OptionInfo("<h3>Sub-quadratic options</h3>", "", gr.HTML, {"visible": not native}),
"sub_quad_q_chunk_size": OptionInfo(512, "Attention query chunk size", gr.Slider, {"minimum": 16, "maximum": 8192, "step": 8, "visible": not native}),
"sub_quad_kv_chunk_size": OptionInfo(512, "Attention kv chunk size", gr.Slider, {"minimum": 0, "maximum": 8192, "step": 8, "visible": not native}),
"sub_quad_chunk_threshold": OptionInfo(80, "Attention chunking threshold", gr.Slider, {"minimum": 0, "maximum": 100, "step": 1, "visible": not native}),
"other_sep": OptionInfo("<h2>Execution precision</h2>", "", gr.HTML),
"opt_channelslast": OptionInfo(False, "Use channels last "),
@@ -445,7 +445,7 @@ options_templates.update(options_section(('cuda', "Compute Settings"), {
"deep_cache_interval": OptionInfo(3, "DeepCache cache interval", gr.Slider, {"minimum": 1, "maximum": 10, "step": 1}),
"nncf_sep": OptionInfo("<h2>Model Compress</h2>", "", gr.HTML),
"nncf_compress_weights": OptionInfo([], "Compress Model weights with NNCF", gr.CheckboxGroup, {"choices": ["Model", "VAE", "Text Encoder"], "visible": backend == Backend.DIFFUSERS}),
"nncf_compress_weights": OptionInfo([], "Compress Model weights with NNCF", gr.CheckboxGroup, {"choices": ["Model", "VAE", "Text Encoder"], "visible": native}),
"ipex_sep": OptionInfo("<h2>IPEX</h2>", "", gr.HTML, {"visible": devices.backend == "ipex"}),
"ipex_optimize": OptionInfo([], "IPEX Optimize for Intel GPUs", gr.CheckboxGroup, {"choices": ["Model", "VAE", "Text Encoder", "Upscaler"], "visible": devices.backend == "ipex"}),
@@ -668,7 +668,7 @@ options_templates.update(options_section(('ui', "User Interface Options"), {
"keyedit_precision_attention": OptionInfo(0.1, "Ctrl+up/down precision when editing (attention:1.1)", gr.Slider, {"minimum": 0.01, "maximum": 0.2, "step": 0.001, "visible": False}),
"keyedit_precision_extra": OptionInfo(0.05, "Ctrl+up/down precision when editing <extra networks:0.9>", gr.Slider, {"minimum": 0.01, "maximum": 0.2, "step": 0.001, "visible": False}),
"keyedit_delimiters": OptionInfo(r".,\/!?%^*;:{}=`~()", "Ctrl+up/down word delimiters", gr.Textbox, { "visible": False }),
"quicksettings_list": OptionInfo(["sd_model_checkpoint"] if backend == Backend.ORIGINAL else ["sd_model_checkpoint", "sd_model_refiner"], "Quicksettings list", gr.Dropdown, lambda: {"multiselect":True, "choices": list(opts.data_labels.keys())}),
"quicksettings_list": OptionInfo(["sd_model_checkpoint"], "Quicksettings list", gr.Dropdown, lambda: {"multiselect":True, "choices": list(opts.data_labels.keys())}),
"ui_scripts_reorder": OptionInfo("", "UI scripts order", gr.Textbox, { "visible": False }),
}))
@@ -815,7 +815,7 @@ options_templates.update(options_section(('extra_networks', "Extra Networks"), {
"extra_network_reference": OptionInfo(False, "Use reference values when available", gr.Checkbox),
"extra_network_skip_indexing": OptionInfo(False, "Build info on first access", gr.Checkbox),
"extra_networks_default_multiplier": OptionInfo(1.0, "Default multiplier for extra networks", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}),
"diffusers_convert_embed": OptionInfo(False, "Auto-convert SD 1.5 embeddings to SDXL ", gr.Checkbox, {"visible": backend==Backend.DIFFUSERS}),
"diffusers_convert_embed": OptionInfo(False, "Auto-convert SD 1.5 embeddings to SDXL ", gr.Checkbox, {"visible": native}),
"extra_networks_sep3": OptionInfo("<h2>Extra networks settings</h2>", "", gr.HTML),
"extra_networks_styles": OptionInfo(True, "Show built-in styles"),
"lora_preferred_name": OptionInfo("filename", "LoRA preferred name", gr.Radio, {"choices": ["filename", "alias"]}),
@@ -27,7 +27,7 @@ def list_textual_inversion_templates():
def list_embeddings(*dirs):
is_ext = extension_filter(['.SAFETENSORS', '.PT' ] + ( ['.PNG', '.WEBP', '.JXL', '.AVIF', '.BIN' ] if shared.backend != shared.Backend.DIFFUSERS else [] ))
is_ext = extension_filter(['.SAFETENSORS', '.PT' ] + ( ['.PNG', '.WEBP', '.JXL', '.AVIF', '.BIN' ] if not shared.native else [] ))
is_not_preview = lambda fp: not next(iter(os.path.splitext(fp))).upper().endswith('.PREVIEW') # pylint: disable=unnecessary-lambda-assignment
return list(filter(lambda fp: is_ext(fp) and is_not_preview(fp) and os.stat(fp).st_size > 0, directory_files(*dirs)))
@@ -138,7 +138,7 @@ class EmbeddingDatabase:
return embedding
def get_expected_shape(self):
if shared.backend == shared.Backend.DIFFUSERS:
if shared.native:
return 0
if not shared.sd_loaded:
shared.log.error('Model not loaded')
@@ -302,7 +302,7 @@ class EmbeddingDatabase:
else:
raise RuntimeError(f"Couldn't identify {filename} as textual inversion embedding")
if shared.backend == shared.Backend.DIFFUSERS:
if shared.native:
return emb
vec = emb.detach().to(devices.device, dtype=torch.float32)
@@ -326,7 +326,7 @@ class EmbeddingDatabase:
if not os.path.isdir(embdir.path):
return
file_paths = list_embeddings(embdir.path)
if shared.backend == shared.Backend.DIFFUSERS:
if shared.native:
self.load_diffusers_embedding(file_paths)
else:
for file_path in file_paths:
+1 -1
View File
@@ -139,7 +139,7 @@ def create_ui(startup_timer = None):
modules.scripts.scripts_current = None
with gr.Blocks(analytics_enabled=False) as control_interface:
if shared.backend == shared.Backend.DIFFUSERS:
if shared.native:
from modules import ui_control
ui_control.create_ui()
timer.startup.record("ui-control")
+3 -3
View File
@@ -262,7 +262,7 @@ def create_output_panel(tabname, preview=True, prompt=None, height=None):
clip_files.click(fn=None, _js='clip_gallery_urls', inputs=[result_gallery], outputs=[])
save = gr.Button('Save', elem_id=f'save_{tabname}')
delete = gr.Button('Delete', elem_id=f'delete_{tabname}')
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
buttons = generation_parameters_copypaste.create_buttons(["img2img", "inpaint", "extras"])
else:
buttons = generation_parameters_copypaste.create_buttons(["txt2img", "img2img", "control", "extras"])
@@ -389,7 +389,7 @@ def update_token_counter(text, steps):
return f"<span class='gr-box gr-text-input'>{token_count}/{max_length}</span>"
from modules import extra_networks
prompt, _ = extra_networks.parse_prompt(text)
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
from modules import sd_hijack
try:
_, prompt_flat_list, _ = prompt_parser.get_multicond_prompt_list([text])
@@ -399,7 +399,7 @@ def update_token_counter(text, steps):
flat_prompts = reduce(lambda list1, list2: list1+list2, prompt_schedules)
prompts = [prompt_text for _step, prompt_text in flat_prompts]
token_count, max_length = max([sd_hijack.model_hijack.get_prompt_lengths(prompt) for prompt in prompts], key=lambda args: args[0])
elif shared.backend == shared.Backend.DIFFUSERS:
elif shared.native:
if shared.sd_loaded and hasattr(shared.sd_model, 'tokenizer') and shared.sd_model.tokenizer is not None:
has_bos_token = shared.sd_model.tokenizer.bos_token_id is not None
has_eos_token = shared.sd_model.tokenizer.eos_token_id is not None
+1 -1
View File
@@ -67,7 +67,7 @@ def generate_click(job_id: str, active_tab: str, *args):
def create_ui(_blocks: gr.Blocks=None):
helpers.initialize()
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
with gr.Blocks(analytics_enabled = False) as control_ui:
pass
return [(control_ui, 'Control', 'control')]
+1 -1
View File
@@ -224,7 +224,7 @@ class ExtraNetworksPage:
tgt = tgt.path
if os.path.join(paths.models_path, 'Reference') in tgt:
subdirs['Reference'] = 1
if shared.backend == shared.Backend.DIFFUSERS and shared.opts.diffusers_dir in tgt:
if shared.native and shared.opts.diffusers_dir in tgt:
subdirs[os.path.basename(shared.opts.diffusers_dir)] = 1
if 'models--' in tgt:
continue
+2 -2
View File
@@ -16,7 +16,7 @@ class ExtraNetworksPageCheckpoints(ui_extra_networks.ExtraNetworksPage):
def list_reference(self): # pylint: disable=inconsistent-return-statements
for k, v in shared.reference_models.items():
if shared.backend != shared.Backend.DIFFUSERS:
if not shared.native:
if not v.get('original', False):
continue
url = v.get('alt', None) or v['path']
@@ -82,7 +82,7 @@ class ExtraNetworksPageCheckpoints(ui_extra_networks.ExtraNetworksPage):
return items
def allowed_directories_for_previews(self):
if shared.backend == shared.Backend.DIFFUSERS:
if shared.native:
return [v for v in [shared.opts.ckpt_dir, shared.opts.diffusers_dir, reference_dir] if v is not None]
else:
return [v for v in [shared.opts.ckpt_dir, reference_dir, sd_models.model_path] if v is not None]
@@ -13,7 +13,7 @@ class ExtraNetworksPageTextualInversion(ui_extra_networks.ExtraNetworksPage):
def refresh(self):
if sd_models.model_data.sd_model is None:
return
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
sd_hijack.model_hijack.embedding_db.load_textual_inversion_embeddings(force_reload=True)
elif hasattr(sd_models.model_data.sd_model, 'embedding_db'):
sd_models.model_data.sd_model.embedding_db.load_textual_inversion_embeddings(force_reload=True)
@@ -48,7 +48,7 @@ class ExtraNetworksPageTextualInversion(ui_extra_networks.ExtraNetworksPage):
for embedding_path
in candidates
]
elif shared.backend == shared.Backend.ORIGINAL:
elif not shared.native:
self.embeddings = list(sd_hijack.model_hijack.embedding_db.word_embeddings.values())
elif hasattr(sd_models.model_data.sd_model, 'embedding_db'):
self.embeddings = list(sd_models.model_data.sd_model.embedding_db.word_embeddings.values())
+1 -1
View File
@@ -141,7 +141,7 @@ def create_ui():
with gr.Row():
inpainting_mask_invert = gr.Radio(label='Mode', choices=['masked', 'invert'], value='masked', type="index", elem_id="img2img_mask_mode")
inpaint_full_res = gr.Radio(label="Inpaint area", choices=["full", "masked"], type="index", value="full", elem_id="img2img_inpaint_full_res")
inpainting_fill = gr.Radio(label='Masked content', choices=['fill', 'original', 'noise', 'nothing'], value='original', type="index", elem_id="img2img_inpainting_fill", visible=shared.backend == shared.Backend.ORIGINAL)
inpainting_fill = gr.Radio(label='Masked content', choices=['fill', 'original', 'noise', 'nothing'], value='original', type="index", elem_id="img2img_inpainting_fill", visible=not shared.native)
def select_img2img_tab(tab):
return gr.update(visible=tab in [2, 3, 4]), gr.update(visible=tab == 3)
+7 -7
View File
@@ -166,18 +166,18 @@ def create_advanced_inputs(tab, base=True):
cfg_scale, cfg_end = None, None
with gr.Row():
image_cfg_scale = gr.Slider(minimum=0.0, maximum=30.0, step=0.1, label='Secondary guidance', value=6.0, elem_id=f"{tab}_image_cfg_scale")
diffusers_guidance_rescale = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Rescale guidance', value=0.7, elem_id=f"{tab}_image_cfg_rescale", visible=shared.backend == shared.Backend.DIFFUSERS)
diffusers_guidance_rescale = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Rescale guidance', value=0.7, elem_id=f"{tab}_image_cfg_rescale", visible=shared.native)
with gr.Row():
diffusers_pag_scale = gr.Slider(minimum=0.0, maximum=30.0, step=0.05, label='Attention guidance', value=0.0, elem_id=f"{tab}_pag_scale", visible=shared.backend == shared.Backend.DIFFUSERS)
diffusers_pag_adaptive = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Adaptive scaling', value=0.5, elem_id=f"{tab}_pag_adaptive", visible=shared.backend == shared.Backend.DIFFUSERS)
diffusers_pag_scale = gr.Slider(minimum=0.0, maximum=30.0, step=0.05, label='Attention guidance', value=0.0, elem_id=f"{tab}_pag_scale", visible=shared.native)
diffusers_pag_adaptive = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Adaptive scaling', value=0.5, elem_id=f"{tab}_pag_adaptive", visible=shared.native)
with gr.Row():
clip_skip = gr.Slider(label='CLIP skip', value=1, minimum=0, maximum=12, step=0.1, elem_id=f"{tab}_clip_skip", interactive=True)
return cfg_scale, clip_skip, image_cfg_scale, diffusers_guidance_rescale, diffusers_pag_scale, diffusers_pag_adaptive, cfg_end
def create_correction_inputs(tab):
with gr.Accordion(open=False, label="Corrections", elem_id=f"{tab}_corrections", elem_classes=["small-accordion"], visible=shared.backend == shared.Backend.DIFFUSERS):
with gr.Group(visible=shared.backend == shared.Backend.DIFFUSERS):
with gr.Accordion(open=False, label="Corrections", elem_id=f"{tab}_corrections", elem_classes=["small-accordion"], visible=shared.native):
with gr.Group(visible=shared.native):
with gr.Row(elem_id=f"{tab}_hdr_mode_row"):
hdr_mode = gr.Dropdown(label="Mode", choices=["Relative values", "Absolute values"], type="index", value="Relative values", elem_id=f"{tab}_hdr_mode", show_label=False)
gr.HTML('<br>')
@@ -243,7 +243,7 @@ def create_sampler_options(tabname):
return '999,845,730,587,443,310,193,116,53,13'
return ''
if shared.backend == shared.Backend.ORIGINAL:
if not shared.native:
with gr.Row(elem_classes=['flex-break']):
options = ['brownian noise', 'discard penultimate sigma']
values = []
@@ -292,7 +292,7 @@ def create_hires_inputs(tab):
with gr.Row(elem_id=f"{tab}_hires_row2"):
hr_second_pass_steps = gr.Slider(minimum=0, maximum=99, step=1, label='HiRes steps', elem_id=f"{tab}_steps_alt", value=20)
denoising_strength = gr.Slider(minimum=0.0, maximum=0.99, step=0.01, label='Strength', value=0.3, elem_id=f"{tab}_denoising_strength")
with gr.Group(visible=shared.backend == shared.Backend.DIFFUSERS):
with gr.Group(visible=shared.native):
with gr.Row(elem_id=f"{tab}_refiner_row1", variant="compact"):
refiner_start = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Refiner start', value=0.0, elem_id=f"{tab}_refiner_start")
refiner_steps = gr.Slider(minimum=0, maximum=99, step=1, label="Refiner steps", elem_id=f"{tab}_refiner_steps", value=10)
+2 -2
View File
@@ -50,7 +50,7 @@ orig_pipe = None # original sd_model pipeline
def set_adapter(adapter_name: str = 'None'):
if not shared.sd_loaded:
return
if shared.backend != shared.Backend.DIFFUSERS:
if not shared.native:
shared.log.warning('AnimateDiff: not in diffusers mode')
return
global motion_adapter, loaded_adapter, orig_pipe # pylint: disable=global-statement
@@ -135,7 +135,7 @@ class Script(scripts.Script):
return 'AnimateDiff'
def show(self, _is_img2img):
return scripts.AlwaysVisible if shared.backend == shared.Backend.DIFFUSERS else False
return scripts.AlwaysVisible if shared.native else False
def ui(self, _is_img2img):
+1 -1
View File
@@ -10,7 +10,7 @@ class Script(scripts.Script):
return title
def show(self, is_img2img):
return is_img2img if shared.backend == shared.Backend.DIFFUSERS else False
return is_img2img if shared.native else False
def ui(self, _is_img2img):
with gr.Row():
+1 -1
View File
@@ -1225,7 +1225,7 @@ class Script(scripts.Script):
return 'DemoFusion'
def show(self, is_img2img):
return not is_img2img if shared.backend == shared.Backend.DIFFUSERS else False
return not is_img2img if shared.native else False
# return signature is array of gradio components
def ui(self, _is_img2img):
+1 -1
View File
@@ -1875,7 +1875,7 @@ class Script(scripts.Script):
return 'Differential diffusion'
def show(self, is_img2img):
return is_img2img if shared.backend == shared.Backend.DIFFUSERS else False
return is_img2img if shared.native else False
def ui(self, _is_img2img):
with gr.Row():
+1 -1
View File
@@ -67,7 +67,7 @@ class Script(scripts.Script):
return title
def show(self, is_img2img):
if shared.backend == shared.Backend.DIFFUSERS:
if shared.native:
return img2img if is_img2img else txt2img
return False
+1 -1
View File
@@ -16,7 +16,7 @@ class Script(scripts.Script):
return 'Image-to-Video'
def show(self, is_img2img):
return is_img2img if shared.backend == shared.Backend.DIFFUSERS else False
return is_img2img if shared.native else False
# return False
# return signature is array of gradio components
+2 -2
View File
@@ -8,7 +8,7 @@ class Script(scripts.Script):
return 'Init Latents'
def show(self, is_img2img):
return scripts.AlwaysVisible if shared.backend == shared.Backend.DIFFUSERS else False
return scripts.AlwaysVisible if shared.native else False
@staticmethod
def get_latents(p):
@@ -31,7 +31,7 @@ class Script(scripts.Script):
def process_batch(self, p: processing.StableDiffusionProcessing, *args, **kwargs): # pylint: disable=arguments-differ
from modules.processing_helpers import create_random_tensors
if shared.backend != shared.Backend.DIFFUSERS:
if not shared.native:
return
args = list(args)
if p.subseed_strength != 0 and getattr(shared.sd_model, '_execution_device', None) is not None:
+2 -2
View File
@@ -14,7 +14,7 @@ class Script(scripts.Script):
return 'IP Adapters'
def show(self, is_img2img):
return scripts.AlwaysVisible if shared.backend == shared.Backend.DIFFUSERS else False
return scripts.AlwaysVisible if shared.native else False
def load_images(self, files):
init_images = []
@@ -83,7 +83,7 @@ class Script(scripts.Script):
return [num_adapters] + adapters + scales + files + starts + ends + masks + [layers_active] + [layers]
def process(self, p: processing.StableDiffusionProcessing, *args): # pylint: disable=arguments-differ
if shared.backend != shared.Backend.DIFFUSERS:
if not shared.native:
return
args = list(args) if args is not None else []
if len(args) == 0:
+1 -1
View File
@@ -8,7 +8,7 @@ class Script(scripts.Script):
return 'Kohya HiRes Fix'
def show(self, is_img2img):
return not is_img2img if shared.backend == shared.Backend.DIFFUSERS else False
return not is_img2img if shared.native else False
# return signature is array of gradio components
def ui(self, _is_img2img):
+1 -1
View File
@@ -8,7 +8,7 @@ class Script(scripts.Script):
return 'LayerDiffuse'
def show(self, is_img2img):
return True if shared.backend == shared.Backend.DIFFUSERS else False
return True if shared.native else False
def apply(self):
from modules import layerdiffuse
+1 -1
View File
@@ -8,7 +8,7 @@ class Script(scripts.Script):
return 'LEdits++'
def show(self, is_img2img):
return is_img2img if shared.backend == shared.Backend.DIFFUSERS else False
return is_img2img if shared.native else False
# return signature is array of gradio components
def ui(self, _is_img2img):
+1 -1
View File
@@ -29,7 +29,7 @@ class Script(scripts.Script):
return 'Mixture tiling'
def show(self, is_img2img):
return not is_img2img if shared.backend == shared.Backend.DIFFUSERS else False
return not is_img2img if shared.native else False
def ui(self, _is_img2img):
with gr.Row():
+1 -1
View File
@@ -50,7 +50,7 @@ class Script(scripts.Script):
def show(self, is_img2img):
if shared.cmd_opts.experimental:
return True if shared.backend == shared.Backend.DIFFUSERS else False
return True if shared.native else False
else:
return False
+1 -1
View File
@@ -24,7 +24,7 @@ class Script(scripts.Script):
return 'Regional prompting'
def show(self, is_img2img):
return not is_img2img if shared.backend == shared.Backend.DIFFUSERS else False
return not is_img2img if shared.native else False
def change(self, mode):
return [gr.update(visible='Col' in mode or 'Row' in mode), gr.update(visible='Prompt' in mode)]
+1 -1
View File
@@ -19,7 +19,7 @@ class Script(scripts.Script):
return 'Stable Video Diffusion'
def show(self, is_img2img):
return is_img2img if shared.backend == shared.Backend.DIFFUSERS else False
return is_img2img if shared.native else False
# return signature is array of gradio components
def ui(self, _is_img2img):
+1 -1
View File
@@ -8,7 +8,7 @@ class Script(scripts.Script):
return 'T-Gate'
def show(self, is_img2img):
return not is_img2img if shared.backend == shared.Backend.DIFFUSERS else False
return not is_img2img if shared.native else False
# return signature is array of gradio components
def ui(self, _is_img2img):
+1 -1
View File
@@ -26,7 +26,7 @@ class Script(scripts.Script):
return 'Text-to-Video'
def show(self, is_img2img):
return not is_img2img if shared.backend == shared.Backend.DIFFUSERS else False
return not is_img2img if shared.native else False
# return signature is array of gradio components
def ui(self, _is_img2img):
+1 -1
View File
@@ -16,7 +16,7 @@ class Script(scripts.Script):
def show(self, is_img2img):
return False
# return True if shared.backend == shared.Backend.DIFFUSERS else False
# return True if shared.native else False
def ui(self, _is_img2img):
with gr.Row():