diff --git a/javascript/gallery.js b/javascript/gallery.js index d9945cd8d..1f3afd148 100644 --- a/javascript/gallery.js +++ b/javascript/gallery.js @@ -276,33 +276,34 @@ async function gallerySort(btn) { const arr = Array.from(el.files.children).filter((node) => node.name); // filter out separators const fragment = document.createDocumentFragment(); el.files.innerHTML = ''; + log('gallerySort', btn.charCodeAt(0)); switch (btn.charCodeAt(0)) { - case 61789: + case 61789: // name asc arr .sort((a, b) => a.name.localeCompare(b.name)) .forEach((node) => fragment.appendChild(node)); break; - case 61790: + case 61790: // name dsc arr .sort((b, a) => a.name.localeCompare(b.name)) .forEach((node) => fragment.appendChild(node)); break; - case 61792: + case 61792: // size asc arr .sort((a, b) => a.size - b.size) .forEach((node) => fragment.appendChild(node)); break; - case 61793: + case 61793: // size dsc arr .sort((b, a) => a.size - b.size) .forEach((node) => fragment.appendChild(node)); break; - case 61794: + case 61794: // resolution asc arr .sort((a, b) => a.width * a.height - b.width * b.height) .forEach((node) => fragment.appendChild(node)); break; - case 61795: + case 61795: // resolution dsc arr .sort((b, a) => a.width * a.height - b.width * b.height) .forEach((node) => fragment.appendChild(node)); diff --git a/modules/processing_args.py b/modules/processing_args.py index 7cb380ee7..1aebca869 100644 --- a/modules/processing_args.py +++ b/modules/processing_args.py @@ -99,6 +99,7 @@ def set_pipeline_args(p, model, prompts: list, negative_prompts: list, prompts_2 steps = kwargs.get("num_inference_steps", None) or len(getattr(p, 'timesteps', ['1'])) clip_skip = kwargs.pop("clip_skip", 1) + prompt_parser_diffusers.fix_position_ids(model) if shared.opts.prompt_attention != 'Fixed attention' and 'Onnx' not in model.__class__.__name__ and ( 'StableDiffusion' in model.__class__.__name__ or 'StableCascade' in model.__class__.__name__ or diff --git a/modules/processing_vae.py b/modules/processing_vae.py index 77f24711c..4ad77edae 100644 --- a/modules/processing_vae.py +++ b/modules/processing_vae.py @@ -60,8 +60,7 @@ def full_vae_decode(latents, model): model.vae.orig_dtype = model.vae.dtype model.vae = model.vae.to(dtype=torch.float32) latents = latents.to(torch.float32) - else: - latents = latents.to(devices.device) + latents = latents.to(devices.device) if getattr(model.vae, "post_quant_conv", None) is not None: latents = latents.to(next(iter(model.vae.post_quant_conv.parameters())).dtype) @@ -84,6 +83,7 @@ def full_vae_decode(latents, model): latents_stats = f'shape={latents.shape} dtype={latents.dtype} device={latents.device}' stats = f'vae {vae_stats} latents {latents_stats}' + log_debug(f'VAE config: {model.vae.config}') try: decoded = model.vae.decode(latents, return_dict=False)[0] except Exception as e: diff --git a/modules/prompt_parser_diffusers.py b/modules/prompt_parser_diffusers.py index 6ebba5e0a..75e9f5b32 100644 --- a/modules/prompt_parser_diffusers.py +++ b/modules/prompt_parser_diffusers.py @@ -34,10 +34,12 @@ def compel_hijack(self, token_ids: torch.Tensor, attention_mask: typing.Optional[torch.Tensor] = None) -> torch.Tensor: needs_hidden_states = self.returned_embeddings_type != 1 try: # can crash in ATen/native/cuda/Indexing since position_ids are corrupt so index lookup fails, but its not compel specific, happens with fixed attention as well + sd_models.move_model(self.text_encoder, devices.device) text_encoder_output = self.text_encoder(token_ids, attention_mask, output_hidden_states=needs_hidden_states, return_dict=True) except Exception as e: # its a non-recoverable error as cuda state is corrupt shared.log.error(f'TE: class={self.text_encoder.__class__} device={self.text_encoder.device} dtype={self.text_encoder.dtype} {e}') errors.display(e, 'TE:') + return None if not needs_hidden_states: return text_encoder_output.last_hidden_state @@ -174,7 +176,7 @@ def encode_prompts(pipe, p, prompts: list, negative_prompts: list, steps: int, c ): shared.log.warning(f"Prompt parser not supported: {pipe.__class__.__name__}") return - elif shared.opts.sd_textencoder_cache and cache.get('model_type', None) == shared.sd_model_type and params_match and False: + elif shared.opts.sd_textencoder_cache and cache.get('model_type', None) == shared.sd_model_type and params_match: p.prompt_embeds = cache.get('prompt_embeds', None) p.positive_pooleds = cache.get('positive_pooleds', None) p.negative_embeds = cache.get('negative_embeds', None) @@ -190,10 +192,14 @@ def encode_prompts(pipe, p, prompts: list, negative_prompts: list, steps: int, c pipe.maybe_free_model_hooks() devices.torch_gc() - fix_position_ids(pipe) - prompt_embeds, positive_pooleds, negative_embeds, negative_pooleds = [], [], [], [] + p.prompt_embeds = [] + p.positive_pooleds = [] + p.negative_embeds = [] + p.negative_pooleds = [] + p.scheduled_prompt = False last_prompt, last_negative = None, None for prompt, negative in zip(prompts, negative_prompts): + prompt_embeds, positive_pooleds, negative_embeds, negative_pooleds = [], [], [], [] prompt_embed, positive_pooled, negative_embed, negative_pooled = None, None, None, None if last_prompt == prompt and last_negative == negative: prompt_embeds.append(prompt_embeds[-1]) @@ -205,11 +211,7 @@ def encode_prompts(pipe, p, prompts: list, negative_prompts: list, steps: int, c continue positive_schedule, scheduled = get_prompt_schedule(prompt, steps) negative_schedule, neg_scheduled = get_prompt_schedule(negative, steps) - p.scheduled_prompt = scheduled or neg_scheduled - p.prompt_embeds = [] - p.positive_pooleds = [] - p.negative_embeds = [] - p.negative_pooleds = [] + p.scheduled_prompt = p.scheduled_prompt or scheduled or neg_scheduled for i in range(max(len(positive_schedule), len(negative_schedule))): positive_prompt = positive_schedule[i % len(positive_schedule)] @@ -228,25 +230,25 @@ def encode_prompts(pipe, p, prompts: list, negative_prompts: list, steps: int, c negative_pooleds.append(negative_pooled) last_prompt, last_negative = prompt, negative - def fix_length(embeds): - max_len = max([e.shape[1] for e in embeds if e is not None]) - for i, e in enumerate(embeds): - if e is not None and e.shape[1] < max_len: - expanded = torch.zeros((e.shape[0], max_len, e.shape[2]), device=e.device, dtype=e.dtype) - expanded[:, :e.shape[1], :] = e - embeds[i] = expanded - return torch.cat(embeds, dim=0).to(devices.device, dtype=devices.dtype) + def fix_length(embeds): + max_len = max([e.shape[1] for e in embeds if e is not None]) + for i, e in enumerate(embeds): + if e is not None and e.shape[1] < max_len: + expanded = torch.zeros((e.shape[0], max_len, e.shape[2]), device=e.device, dtype=e.dtype) + expanded[:, :e.shape[1], :] = e + embeds[i] = expanded + return torch.cat(embeds, dim=0).to(devices.device, dtype=devices.dtype) - if len(prompt_embeds) > 0: - p.prompt_embeds.append(fix_length(prompt_embeds)) - if len(negative_embeds) > 0: - p.negative_embeds.append(fix_length(negative_embeds)) - if len(positive_pooleds) > 0: - p.positive_pooleds.append(fix_length(positive_pooleds)) - if len(negative_pooleds) > 0: - p.negative_pooleds.append(fix_length(negative_pooleds)) + if len(prompt_embeds) > 0: + p.prompt_embeds.append(fix_length(prompt_embeds)) + if len(negative_embeds) > 0: + p.negative_embeds.append(fix_length(negative_embeds)) + if len(positive_pooleds) > 0: + p.positive_pooleds.append(fix_length(positive_pooleds)) + if len(negative_pooleds) > 0: + p.negative_pooleds.append(fix_length(negative_pooleds)) - if shared.opts.sd_textencoder_cache and p.batch_size == 1: + if p.batch_size == 1: cache.update({ 'prompt_embeds': p.prompt_embeds, 'negative_embeds': p.negative_embeds, diff --git a/modules/sd_models.py b/modules/sd_models.py index 613a33bfa..577a74ff5 100644 --- a/modules/sd_models.py +++ b/modules/sd_models.py @@ -1035,8 +1035,6 @@ def load_diffuser(checkpoint_info=None, already_loaded_state_dict=None, timer=No if shared.opts.diffusers_pipeline == 'Custom Diffusers Pipeline' and len(shared.opts.custom_diffusers_pipeline) > 0: shared.log.debug(f'Model pipeline: pipeline="{shared.opts.custom_diffusers_pipeline}"') diffusers_load_config['custom_pipeline'] = shared.opts.custom_diffusers_pipeline - # if 'LCM' in checkpoint_info.path: - # diffusers_load_config['custom_pipeline'] = 'latent_consistency_txt2img' if shared.opts.data.get('sd_model_checkpoint', '') == 'model.ckpt' or shared.opts.data.get('sd_model_checkpoint', '') == '': shared.opts.data['sd_model_checkpoint'] = "stabilityai/stable-diffusion-xl-base-1.0" @@ -1737,7 +1735,6 @@ def reload_text_encoder(initial=False): def reload_model_weights(sd_model=None, info=None, reuse_dict=False, op='model', force=False): - devices.set_cuda_params() load_dict = shared.opts.sd_model_dict != model_data.sd_dict from modules import lowvram, sd_hijack checkpoint_info = info or select_checkpoint(op=op) # are we selecting model or dictionary @@ -1749,10 +1746,10 @@ def reload_model_weights(sd_model=None, info=None, reuse_dict=False, op='model', shared.state = shared_state.State() shared.state.begin('Load') if load_dict: - shared.log.debug(f'Model dict: existing={sd_model is not None} target={checkpoint_info.filename} info={info}') + shared.log.debug(f'Load {op} dict: target="{checkpoint_info.filename}" existing={sd_model is not None} info={info}') else: model_data.sd_dict = 'None' - shared.log.debug(f'Load model: existing={sd_model is not None} target={checkpoint_info.filename} info={info}') + shared.log.debug(f'Load {op}: target="{checkpoint_info.filename}" existing={sd_model is not None} info={info}') if sd_model is None: sd_model = model_data.sd_model if op == 'model' or op == 'dict' else model_data.sd_refiner if sd_model is None: # previous model load failed @@ -1766,7 +1763,7 @@ def reload_model_weights(sd_model=None, info=None, reuse_dict=False, op='model', else: move_model(sd_model, devices.cpu) if (reuse_dict or shared.opts.model_reuse_dict) and not getattr(sd_model, 'has_accelerate', False): - shared.log.info('Reusing previous model dictionary') + shared.log.info(f'Load {op}: reusing dictionary') sd_hijack.model_hijack.undo_hijack(sd_model) else: unload_model_weights(op=op) diff --git a/modules/shared.py b/modules/shared.py index 597b72079..6e377be57 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -1081,9 +1081,11 @@ cmd_opts.disable_extension_access = (cmd_opts.share or cmd_opts.listen or (cmd_o devices.backend = devices.get_backend(cmd_opts, opts) devices.device = devices.get_optimal_device() devices.onnx = [opts.onnx_execution_provider] +devices.set_cuda_params() if opts.onnx_cpu_fallback and 'CPUExecutionProvider' not in devices.onnx: devices.onnx.append('CPUExecutionProvider') device = devices.device + batch_cond_uncond = opts.always_batch_cond_uncond or not (cmd_opts.lowvram or cmd_opts.medvram) parallel_processing_allowed = not cmd_opts.lowvram mem_mon = modules.memmon.MemUsageMonitor("MemMon", devices.device) diff --git a/scripts/xyz_grid_on.py b/scripts/xyz_grid_on.py index cb13acf10..ac1bc4c2f 100644 --- a/scripts/xyz_grid_on.py +++ b/scripts/xyz_grid_on.py @@ -143,9 +143,9 @@ class Script(scripts.Script): def process(self, p, enabled, x_type, x_values, x_values_dropdown, y_type, y_values, y_values_dropdown, z_type, z_values, z_values_dropdown, csv_mode, draw_legend, no_fixed_seeds, include_grid, include_subgrids, include_images, margin_size): # pylint: disable=W0221 global active, cache # pylint: disable=W0603 + cache = None if not enabled or active: return - cache = None active = True if not no_fixed_seeds: processing.fix_seed(p) diff --git a/scripts/xyz_grid_shared.py b/scripts/xyz_grid_shared.py index 972e1d2a4..b182a4e80 100644 --- a/scripts/xyz_grid_shared.py +++ b/scripts/xyz_grid_shared.py @@ -196,6 +196,10 @@ def apply_lora(p, x, xs): return x = os.path.basename(x) p.prompt = p.prompt + f" " + if p.all_prompts is not None: + p.all_prompts = len(p.all_prompts) * [p.prompt] + if p.all_negative_prompts is not None: + p.all_negative_prompts = len(p.all_negative_prompts) * [p.prompt] shared.log.debug(f'XYZ grid apply LoRA: "{x}"')