From bfc2db95bc2e302087d8e5fda81ececdb1fffbca Mon Sep 17 00:00:00 2001 From: gabe56f Date: Fri, 21 Jul 2023 22:45:00 +0200 Subject: [PATCH 001/143] feat: SDXL --- core/files.py | 21 + core/inference/functions.py | 35 +- core/inference/pytorch/lwp.py | 10 +- core/inference/pytorch/lwp_sdxl.py | 675 ++++++ core/inference/pytorch/pytorch.py | 162 +- core/optimizations/pytorch_optimizations.py | 16 +- core/types.py | 11 +- frontend/dist/assets/AccelerateView.js | 2 +- frontend/dist/assets/DescriptionsItem.js | 2 +- frontend/dist/assets/ExtraView.js | 2 +- ...ion.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/GridOutline.js | 92 + frontend/dist/assets/Image2ImageView.js | 5 +- frontend/dist/assets/ImageBrowserView.js | 91 +- ...put.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/ImageUpload.js | 2 +- frontend/dist/assets/InputNumber.js | 2 +- frontend/dist/assets/ModelsView.css | 21 + frontend/dist/assets/ModelsView.js | 2068 ++++++++++++++++- ...ats.vue_vue_type_script_setup_true_lang.js | 43 + ...tTo.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/SettingsView.js | 23 +- frontend/dist/assets/Slider.js | 2 +- frontend/dist/assets/Switch.js | 2 +- frontend/dist/assets/TestView.js | 23 +- frontend/dist/assets/TextToImageView.js | 3 +- frontend/dist/assets/TrashBin.js | 2 +- frontend/dist/assets/clock.js | 73 +- frontend/dist/assets/index.css | 20 +- frontend/dist/assets/index.js | 789 +++++-- frontend/src/components/TopBar.vue | 47 + frontend/src/core/interfaces.ts | 1 + frontend/src/views/TestView.vue | 4 - 33 files changed, 3668 insertions(+), 587 deletions(-) create mode 100644 core/inference/pytorch/lwp_sdxl.py create mode 100644 frontend/dist/assets/GridOutline.js create mode 100644 frontend/dist/assets/OutputStats.vue_vue_type_script_setup_true_lang.js diff --git a/core/files.py b/core/files.py index c15eb21f7..e9e2bc668 100644 --- a/core/files.py +++ b/core/files.py @@ -69,6 +69,27 @@ def pytorch(self) -> List[ModelResponse]: if self.checkpoint_converted_path.joinpath(model_name).is_dir(): # Assuming that model is in Diffusers format + file = self.checkpoint_converted_path / model_name / "model_index.json" + try: + with open(file, "r", encoding="UTF-8") as content: + sdxl = "StableDiffusionXL" in content.readlines()[1] + if sdxl: + if not (file.parent / "sdxl.txt").exists(): + open(file.parent / "sdxl.txt", "x") + models.append( + ModelResponse( + name=model_name, + path=model_name, + backend="SDXL", + vae="default", + valid=True, + loras=[], + state="not loaded", + ) + ) + continue + except Exception: # pylint: disable=broad-except + pass models.append( ModelResponse( name=model_name, diff --git a/core/inference/functions.py b/core/inference/functions.py index 461761060..ca4343cbe 100644 --- a/core/inference/functions.py +++ b/core/inference/functions.py @@ -413,19 +413,32 @@ def load_pytorch_pipeline( with console.status( f"[bold green]Loading model from {'HuggingFace Hub' if '/' in model_id_or_path else 'HuggingFace model'}..." ): - pipe = StableDiffusionPipeline.from_pretrained( - pretrained_model_name_or_path=get_full_model_path(model_id_or_path), - torch_dtype=config.api.dtype, - safety_checker=None, - requires_safety_checker=False, - feature_extractor=None, - low_cpu_mem_usage=True, - ) - assert isinstance(pipe, StableDiffusionPipeline) + if (get_full_model_path(model_id_or_path) / "sdxl.txt").exists(): + from diffusers import StableDiffusionXLPipeline + + pipe = StableDiffusionXLPipeline.from_pretrained( + pretrained_model_name_or_path=get_full_model_path(model_id_or_path), + torch_dtype=config.api.dtype, + use_safetensors=True, + safety_checker=None, + requires_safety_checker=False, + feature_extractor=None, + low_cpu_mem_usage=True, + ) + else: + pipe = StableDiffusionPipeline.from_pretrained( + pretrained_model_name_or_path=get_full_model_path(model_id_or_path), + torch_dtype=config.api.dtype, + safety_checker=None, + requires_safety_checker=False, + feature_extractor=None, + low_cpu_mem_usage=True, + ) + # assert isinstance(pipe, StableDiffusionPipeline) logger.debug(f"Loaded {model_id_or_path} with {config.api.data_type}") - assert isinstance(pipe, StableDiffusionPipeline) + # assert isinstance(pipe, StableDiffusionPipeline) conf = pipe.text_encoder.config conf.num_hidden_layers = 13 - config.api.clip_skip @@ -442,7 +455,7 @@ def load_pytorch_pipeline( is_for_aitemplate=is_for_aitemplate, ) else: - pipe.to(device) + pipe.to(device, config.api.dtype) return pipe diff --git a/core/inference/pytorch/lwp.py b/core/inference/pytorch/lwp.py index fff29179e..8f331a042 100644 --- a/core/inference/pytorch/lwp.py +++ b/core/inference/pytorch/lwp.py @@ -239,6 +239,7 @@ def get_unweighted_text_embeddings( it should be split into chunks and sent to the text encoder individually. """ max_embeddings_multiples = (text_input.shape[1] - 2) // (chunk_length - 2) + hidden_states = None if max_embeddings_multiples > 1: text_embeddings = [] @@ -254,7 +255,9 @@ def get_unweighted_text_embeddings( if hasattr(pipe, "clip_inference"): text_embedding = pipe.clip_inference(text_input_chunk) else: - text_embedding = pipe.text_encoder(text_input_chunk)[0] # type: ignore + text_embedding = pipe.text_encoder(text_input_chunk, output_hidden_states=True) # type: ignore + hidden_states = text_embedding.hidden_states[-2] + text_embedding = text_embedding[0] # type: ignore if no_boseos_middle: if i == 0: @@ -273,7 +276,10 @@ def get_unweighted_text_embeddings( if hasattr(pipe, "clip_inference"): text_embeddings = pipe.clip_inference(text_input) else: - text_embeddings = pipe.text_encoder(text_input)[0] # type: ignore + text_embeddings = pipe.text_encoder(text_input, output_hidden_states=True) # type: ignore + hidden_states = text_embeddings.hidden_states[-2] + text_embeddings = text_embeddings[0] # type: ignore + text_embeddings.hidden_states = hidden_states return text_embeddings diff --git a/core/inference/pytorch/lwp_sdxl.py b/core/inference/pytorch/lwp_sdxl.py new file mode 100644 index 000000000..a3251001b --- /dev/null +++ b/core/inference/pytorch/lwp_sdxl.py @@ -0,0 +1,675 @@ +# HuggingFace example pipeline taken from https://github.com/huggingface/diffusers/blob/main/examples/community/lpw_stable_diffusion.py + +import inspect +from contextlib import ExitStack +from typing import Callable, List, Literal, Optional, Union + +import numpy as np +import PIL +import torch +from diffusers import LMSDiscreteScheduler, SchedulerMixin, StableDiffusionPipeline +from diffusers.models import AutoencoderKL, UNet2DConditionModel +from diffusers.pipelines.stable_diffusion import ( + StableDiffusionPipelineOutput, + StableDiffusionSafetyChecker, +) +from diffusers.utils import PIL_INTERPOLATION, logging +from transformers.models.clip import CLIPFeatureExtractor, CLIPTextModel, CLIPTokenizer + +from core.config import config +from core.inference.pytorch.latents import prepare_latents +from core.inference.pytorch.lwp import get_weighted_text_embeddings +from core.inference.pytorch.sag import ( + CrossAttnStoreProcessor, + pred_epsilon, + pred_x0, + sag_masking, +) +from core.optimizations import autocast + +# ------------------------------------------------------------------------------ + +logger = logging.get_logger(__name__) # pylint: disable=invalid-name + + +def preprocess_image(image): + w, h = image.size + w, h = map(lambda x: x - x % 32, (w, h)) # resize to integer multiple of 32 + image = image.resize((w, h), resample=PIL_INTERPOLATION["lanczos"]) + image = np.array(image).astype(np.float32) / 255.0 + image = image[None].transpose(0, 3, 1, 2) + image = torch.from_numpy(image) + return 2.0 * image - 1.0 + + +def preprocess_mask(mask, scale_factor=8): + mask = mask.convert("L") + w, h = mask.size + w, h = map(lambda x: x - x % 32, (w, h)) # resize to integer multiple of 32 + mask = mask.resize( + (w // scale_factor, h // scale_factor), resample=PIL_INTERPOLATION["nearest"] + ) + mask = np.array(mask).astype(np.float32) / 255.0 + mask = np.tile(mask, (4, 1, 1)) + mask = mask[None].transpose(0, 1, 2, 3) # what does this step do? + mask = 1 - mask # repaint white, keep black + mask = torch.from_numpy(mask) + return mask + + +class StableDiffusionLongPromptWeightingPipeline(StableDiffusionPipeline): + r""" + Pipeline for text-to-image generation using Stable Diffusion without tokens length limit, and support parsing + weighting in prompt. + + This model inherits from [`DiffusionPipeline`]. Check the superclass documentation for the generic methods the + library implements for all the pipelines (such as downloading or saving, running on a particular device, etc.) + + Args: + vae ([`AutoencoderKL`]): + Variational Auto-Encoder (VAE) Model to encode and decode images to and from latent representations. + text_encoder ([`CLIPTextModel`]): + Frozen text-encoder. Stable Diffusion uses the text portion of + [CLIP](https://huggingface.co/docs/transformers/model_doc/clip#transformers.CLIPTextModel), specifically + the [clip-vit-large-patch14](https://huggingface.co/openai/clip-vit-large-patch14) variant. + tokenizer (`CLIPTokenizer`): + Tokenizer of class + [CLIPTokenizer](https://huggingface.co/docs/transformers/v4.21.0/en/model_doc/clip#transformers.CLIPTokenizer). + unet ([`UNet2DConditionModel`]): Conditional U-Net architecture to denoise the encoded image latents. + scheduler ([`SchedulerMixin`]): + A scheduler to be used in combination with `unet` to denoise the encoded image latents. Can be one of + [`DDIMScheduler`], [`LMSDiscreteScheduler`], or [`PNDMScheduler`]. + safety_checker ([`StableDiffusionSafetyChecker`]): + Classification module that estimates whether generated images could be considered offensive or harmful. + Please, refer to the [model card](https://huggingface.co/CompVis/stable-diffusion-v1-4) for details. + feature_extractor ([`CLIPFeatureExtractor`]): + Model that extracts features from generated images to be used as inputs for the `safety_checker`. + """ + + def __init__( + self, + parent, + vae: AutoencoderKL, + text_encoder: CLIPTextModel, + tokenizer: CLIPTokenizer, + unet: UNet2DConditionModel, + scheduler: SchedulerMixin, + safety_checker: StableDiffusionSafetyChecker, + feature_extractor: CLIPFeatureExtractor, + requires_safety_checker: bool = False, + ): + super().__init__( + vae=vae, + text_encoder=text_encoder, + tokenizer=tokenizer, + unet=unet, + scheduler=scheduler, # type: ignore + safety_checker=safety_checker, + feature_extractor=feature_extractor, + requires_safety_checker=requires_safety_checker, + ) + self.__init__additional__() + + self.parent = parent + self.vae: AutoencoderKL + self.text_encoder: CLIPTextModel + self.tokenizer: CLIPTokenizer + self.unet: UNet2DConditionModel + self.scheduler: LMSDiscreteScheduler + self.safety_checker: StableDiffusionSafetyChecker + self.feature_extractor: CLIPFeatureExtractor + self.requires_safety_checker: bool + + def __init__additional__(self): + if not hasattr(self, "vae_scale_factor"): + setattr( + self, + "vae_scale_factor", + 2 ** (len(self.vae.config.block_out_channels) - 1), # type: ignore + ) + + @property + def _execution_device(self): + r""" + Returns the device on which the pipeline's models will be executed. After calling + `pipeline.enable_sequential_cpu_offload()` the execution device can only be inferred from Accelerate's module + hooks. + """ + if self.device != torch.device("meta") or not hasattr(self.unet, "_hf_hook"): # type: ignore + return self.device + for module in self.unet.modules(): # type: ignore + if ( + hasattr(module, "_hf_hook") + and hasattr( + module._hf_hook, # pylint: disable=protected-access + "execution_device", + ) + and module._hf_hook.execution_device # pylint: disable=protected-access # type: ignore + is not None + ): + return torch.device( + module._hf_hook.execution_device # pylint: disable=protected-access # type: ignore + ) + return self.device + + def upcast_vae(self): + from diffusers.models.attention_processor import ( + XFormersAttnProcessor, + AttnProcessor2_0, + ) + + dtype = self.vae.dtype + self.vae.to(dtype=torch.float32) + use_torch_2_0_or_xformers = isinstance( + self.vae.decoder.mid_block.attentions[0].processor, # type: ignore + ( + AttnProcessor2_0, + XFormersAttnProcessor, + ), + ) + # if xformers or torch_2_0 is used attention block does not need + # to be in float32 which can save lots of memory + if use_torch_2_0_or_xformers: + self.vae.post_quant_conv.to(dtype) + self.vae.decoder.conv_in.to(dtype) + self.vae.decoder.mid_block.to(dtype) # type: ignore + + def _encode_prompt( + self, + prompt, + device, + num_images_per_prompt, + negative_prompt, + max_embeddings_multiples, + ): + batch_size = len(prompt) if isinstance(prompt, list) else 1 + + prompts = [prompt, prompt] + negative_prompts = [negative_prompt, negative_prompt] + tokenizers = ( + [self.tokenizer, self.tokenizer_2] + if self.tokenizer is not None + else [self.tokenizer_2] + ) + text_encoders = ( + [self.text_encoder, self.text_encoder_2] + if self.text_encoder is not None + else [self.text_encoder_2] + ) + + prompt_embeds_list = [] + uncond_embeds_list = [] + for prompt, negative_prompt, tokenizer, text_encoder in zip( + prompts, negative_prompts, tokenizers, text_encoders + ): + prompt = self.maybe_convert_prompt(prompt, tokenizer) + logger.debug(f"Post textual prompt: {prompt}") + + if negative_prompt is not None: + negative_prompt = self.maybe_convert_prompt(negative_prompt, tokenizer) + logger.debug(f"Post textual negative_prompt: {negative_prompt}") + + obj = object() + obj.text_encoder = text_encoder # type: ignore + obj.tokenizer = tokenizer # type: ignore + obj.loras = [] # type: ignore + + text_embeddings, uncond_embeddings = get_weighted_text_embeddings( + pipe=obj, # type: ignore + prompt=prompt, + uncond_prompt=None if negative_prompt is None else [negative_prompt] * batch_size, # type: ignore + max_embeddings_multiples=max_embeddings_multiples, + ) + pooled_embeddings = text_embeddings.hidden_states + if negative_prompt is None: + uncond_embeddings = torch.zeros_like(text_embeddings) + uncond_pooled_embeddings = torch.zeros_like(pooled_embeddings) + else: + uncond_pooled_embeddings = uncond_embeddings.hidden_states # type: ignore + prompt_embeds_list.append(pooled_embeddings) + uncond_embeds_list.append(uncond_pooled_embeddings) + + pooled_embeddings = torch.concat(prompt_embeds_list, dim=-1) + uncond_pooled_embeddings = torch.concat(uncond_embeds_list, dim=-1) + + bs_embed = pooled_embeddings.shape[0] + pooled_embeddings = pooled_embeddings.repeat(1, num_images_per_prompt) + pooled_embeddings = pooled_embeddings.view(bs_embed * num_images_per_prompt, -1) + + bs_embed = uncond_pooled_embeddings.shape[0] # type: ignore + uncond_pooled_embeddings = uncond_pooled_embeddings.repeat(1, num_images_per_prompt) # type: ignore + uncond_pooled_embeddings = uncond_pooled_embeddings.view( + bs_embed * num_images_per_prompt, -1 + ) + + # Only the last one is necessary + return pooled_embeddings.to(device), uncond_pooled_embeddings.to(device), text_embeddings.to(device), uncond_embeddings.to(device) # type: ignore + + def check_inputs(self, prompt, height, width, strength, callback_steps): + if not isinstance(prompt, str) and not isinstance(prompt, list): + raise ValueError( + f"`prompt` has to be of type `str` or `list` but is {type(prompt)}" + ) + + if strength < 0 or strength > 1: + raise ValueError( + f"The value of strength should in [0.0, 1.0] but is {strength}" + ) + + if height % 8 != 0 or width % 8 != 0: + raise ValueError( + f"`height` and `width` have to be divisible by 8 but are {height} and {width}." + ) + + if (callback_steps is None) or ( + callback_steps is not None + and (not isinstance(callback_steps, int) or callback_steps <= 0) + ): + raise ValueError( + f"`callback_steps` has to be a positive integer but is {callback_steps} of type" + f" {type(callback_steps)}." + ) + + def get_timesteps(self, num_inference_steps, strength, device, is_text2img): + if is_text2img: + return self.scheduler.timesteps.to(device), num_inference_steps # type: ignore + else: + # get the original timestep using init_timestep + offset = self.scheduler.config.get("steps_offset", 0) # type: ignore + init_timestep = int(num_inference_steps * strength) + offset + init_timestep = min(init_timestep, num_inference_steps) + + t_start = max(num_inference_steps - init_timestep + offset, 0) + timesteps = self.scheduler.timesteps[t_start:].to(device) # type: ignore + return timesteps, num_inference_steps - t_start + + def _get_add_time_ids( + self, original_size, crops_coords_top_left, target_size, dtype + ): + add_time_ids = list(original_size + crops_coords_top_left + target_size) + + passed_add_embed_dim = ( + self.unet.config.addition_time_embed_dim * len(add_time_ids) + self.text_encoder_2.config.projection_dim # type: ignore + ) + expected_add_embed_dim = self.unet.add_embedding.linear_1.in_features # type: ignore + + if expected_add_embed_dim != passed_add_embed_dim: + raise ValueError( + f"Model expects an added time embedding vector of length {expected_add_embed_dim}, but a vector of {passed_add_embed_dim} was created. The model has an incorrect config. Please check `unet.config.time_embedding_type` and `text_encoder_2.config.projection_dim`." + ) + + add_time_ids = torch.tensor([add_time_ids], dtype=dtype) + return add_time_ids + + def decode_latents(self, latents): + latents = 1 / 0.18215 * latents + image = self.vae.decode(latents).sample # type: ignore + image = (image / 2 + 0.5).clamp(0, 1) + # we always cast to float32 as this does not cause significant overhead and is compatible with bfloat16 + image = image.cpu().permute(0, 2, 3, 1).float().numpy() + return image + + def prepare_extra_step_kwargs(self, generator, eta): + # prepare extra kwargs for the scheduler step, since not all schedulers have the same signature + # eta (η) is only used with the DDIMScheduler, it will be ignored for other schedulers. + # eta corresponds to η in DDIM paper: https://arxiv.org/abs/2010.02502 + # and should be between [0, 1] + + accepts_eta = "eta" in set( + inspect.signature(self.scheduler.step).parameters.keys() # type: ignore + ) + extra_step_kwargs = {} + if accepts_eta: + extra_step_kwargs["eta"] = eta + + # check if the scheduler accepts generator + accepts_generator = "generator" in set( + inspect.signature(self.scheduler.step).parameters.keys() # type: ignore + ) + if accepts_generator: + extra_step_kwargs["generator"] = generator + return extra_step_kwargs + + @torch.no_grad() + def __call__( + self, + prompt: str, + negative_prompt: Optional[str] = None, + image: Union[torch.FloatTensor, PIL.Image.Image] = None, # type: ignore + mask_image: Union[torch.FloatTensor, PIL.Image.Image] = None, # type: ignore + height: int = 1024, + width: int = 1024, + num_inference_steps: int = 50, + guidance_scale: float = 7.5, + self_attention_scale: float = 0.0, + strength: float = 0.8, + num_images_per_prompt: Optional[int] = 1, + eta: float = 0.0, + generator: Optional[torch.Generator] = None, + latents: Optional[torch.FloatTensor] = None, + max_embeddings_multiples: Optional[int] = 100, + output_type: Literal["pil", "latent"] = "pil", + return_dict: bool = True, + callback: Optional[Callable[[int, int, torch.FloatTensor], None]] = None, + is_cancelled_callback: Optional[Callable[[], bool]] = None, + callback_steps: int = 1, + ): + if config.api.torch_compile: + self.unet = torch.compile( + self.unet, + fullgraph=config.api.torch_compile_fullgraph, + dynamic=config.api.torch_compile_dynamic, + mode=config.api.torch_compile_mode, + ) # type: ignore + + # 0. Default height and width to unet + with autocast( + dtype=self.unet.dtype, + disable=not config.api.autocast, + ): + height = height or self.unet.config.sample_size * self.vae_scale_factor # type: ignore + width = width or self.unet.config.sample_size * self.vae_scale_factor # type: ignore + + # 1. Check inputs. Raise error if not correct + self.check_inputs(prompt, height, width, strength, callback_steps) + + # 2. Define call parameters + batch_size = 1 if isinstance(prompt, str) else len(prompt) + device = self._execution_device + # here `guidance_scale` is defined analog to the guidance weight `w` of equation (2) + # of the Imagen paper: https://arxiv.org/pdf/2205.11487.pdf . `guidance_scale = 1` + # corresponds to doing no classifier free guidance. + do_classifier_free_guidance = guidance_scale > 1.0 + do_self_attention_guidance = self_attention_scale > 0.0 + + # 3. Encode input prompt + ( + prompt_embeds, + negative_prompt_embeds, + pooled_prompt_embeds, + negative_pooled_prompt_embeds, + ) = self._encode_prompt( + prompt, + device, + num_images_per_prompt, + negative_prompt, + max_embeddings_multiples, + ) + dtype = prompt_embeds.dtype + + # 4. Preprocess image and mask + if isinstance(image, PIL.Image.Image): # type: ignore + image = preprocess_image(image) + if image is not None: + image = image.to(device=self.device, dtype=dtype) + if isinstance(mask_image, PIL.Image.Image): # type: ignore + mask_image = preprocess_mask(mask_image, self.vae_scale_factor) + if mask_image is not None: + mask = mask_image.to(device=self.device, dtype=dtype) + mask = torch.cat([mask] * batch_size * num_images_per_prompt) # type: ignore + else: + mask = None + + # 5. set timesteps + self.scheduler.set_timesteps(num_inference_steps, device=device) # type: ignore + timesteps, num_inference_steps = self.get_timesteps( + num_inference_steps, strength, device, image is None + ) + latent_timestep = timesteps[:1].repeat(batch_size * num_images_per_prompt) # type: ignore + + # 6. Prepare latent variables + latents, init_latents_orig, noise = prepare_latents( + self, + image, + latent_timestep, + batch_size * num_images_per_prompt, # type: ignore + height, + width, + dtype, + device, + generator, + latents, + ) + + # 7. Prepare extra step kwargs. TODO: Logic should ideally just be moved out of the pipeline + extra_step_kwargs = self.prepare_extra_step_kwargs(generator, eta) + + if do_self_attention_guidance: + store_processor = CrossAttnStoreProcessor() + self.unet.mid_block.attentions[0].transformer_blocks[0].attn1.processor = store_processor # type: ignore + + map_size = None + + def get_map_size(_, __, output): + nonlocal map_size + map_size = output[0].shape[ + -2: + ] # output.sample.shape[-2:] in older diffusers + + # 8. Denoising loop + with ExitStack() as gs: + if do_self_attention_guidance: + gs.enter_context(self.unet.mid_block.attentions[0].register_forward_hook(get_map_size)) # type: ignore + + for i, t in enumerate(self.progress_bar(timesteps)): + # expand the latents if we are doing classifier free guidance + latent_model_input = ( + torch.cat([latents] * 2) if do_classifier_free_guidance else latents # type: ignore + ) + latent_model_input = self.scheduler.scale_model_input(latent_model_input, t) # type: ignore + + # predict the noise residual + noise_pred = self.unet( # type: ignore + latent_model_input, t, encoder_hidden_states=text_embeddings + ).sample + + # perform guidance + if do_classifier_free_guidance: + noise_pred_uncond, noise_pred_text = noise_pred.chunk(2) + noise_pred = noise_pred_uncond + guidance_scale * ( + noise_pred_text - noise_pred_uncond + ) + + if do_self_attention_guidance: + if do_classifier_free_guidance: + pred = pred_x0(self, latents, noise_pred_uncond, t) # type: ignore + uncond_attn, cond_attn = store_processor.attention_probs.chunk(2) # type: ignore + degraded_latents = sag_masking( + self, pred, uncond_attn, map_size, t, pred_epsilon(self, latents, noise_pred_uncond, t) # type: ignore + ) + uncond_emb, _ = text_embeddings.chunk(2) + # predict the noise residual + # this probably could have been done better but honestly fuck this + degraded_prep = self.unet( # type: ignore + degraded_latents, + t, + encoder_hidden_states=uncond_emb, + ).sample + noise_pred += self_attention_scale * (noise_pred_uncond - degraded_prep) # type: ignore + else: + pred = pred_x0(self, latents, noise_pred, t) + cond_attn = store_processor.attention_probs # type: ignore + degraded_latents = sag_masking( + self, + pred, + cond_attn, + map_size, + t, + pred_epsilon(self, latents, noise_pred, t), + ) + # predict the noise residual + degraded_prep = self.unet( # type: ignore + degraded_latents, + t, + encoder_hidden_states=text_embeddings, + ).sample + noise_pred += self_attention_scale * (noise_pred - degraded_prep) # type: ignore + + # compute the previous noisy sample x_t -> x_t-1 + latents = self.scheduler.step( # type: ignore + noise_pred, t.to(noise_pred.device), latents.to(noise_pred.device), **extra_step_kwargs # type: ignore + ).prev_sample # type: ignore + + if mask is not None: + # masking + init_latents_proper = self.scheduler.add_noise( # type: ignore + init_latents_orig, noise, torch.tensor([t]) # type: ignore + ) + latents = (init_latents_proper * mask) + (latents * (1 - mask)) # type: ignore + + # call the callback, if provided + if i % callback_steps == 0: + if callback is not None: + callback(i, t, latents) # type: ignore + if ( + is_cancelled_callback is not None + and is_cancelled_callback() + ): + return None + + # 9. Post-processing + if output_type == "latent": + return latents, False + + image = self.decode_latents(latents) + + # 10. Run safety checker + image, has_nsfw_concept = self.run_safety_checker( + image, device, text_embeddings.dtype + ) + + # 11. Convert to PIL + if output_type == "pil": + image = self.numpy_to_pil(image) + + if hasattr(self, "final_offload_hook"): + self.final_offload_hook.offload() # type: ignore + + if not return_dict: + return image, has_nsfw_concept + + return StableDiffusionPipelineOutput( + images=image, nsfw_content_detected=has_nsfw_concept # type: ignore + ) + + def text2img( + self, + prompt: Union[str, List[str]], + negative_prompt: Optional[Union[str, List[str]]] = None, + height: int = 512, + width: int = 512, + num_inference_steps: int = 50, + guidance_scale: float = 7.5, + self_attention_scale: float = 0.0, + num_images_per_prompt: Optional[int] = 1, + eta: float = 0.0, + generator: Optional[torch.Generator] = None, + latents: Optional[torch.FloatTensor] = None, + max_embeddings_multiples: Optional[int] = 100, + output_type: Literal["pil", "latent"] = "pil", + return_dict: bool = True, + callback: Optional[Callable[[int, int, torch.FloatTensor], None]] = None, + is_cancelled_callback: Optional[Callable[[], bool]] = None, + callback_steps: int = 1, + ): + return self.__call__( + prompt=prompt, + negative_prompt=negative_prompt, + height=height, + width=width, + num_inference_steps=num_inference_steps, + guidance_scale=guidance_scale, + self_attention_scale=self_attention_scale, + num_images_per_prompt=num_images_per_prompt, + eta=eta, + generator=generator, + latents=latents, + max_embeddings_multiples=max_embeddings_multiples, + output_type=output_type, + return_dict=return_dict, + callback=callback, + is_cancelled_callback=is_cancelled_callback, + callback_steps=callback_steps, + ) + + def img2img( + self, + image: Union[torch.FloatTensor, PIL.Image.Image], # type: ignore + prompt: Union[str, List[str]], + negative_prompt: Optional[Union[str, List[str]]] = None, + strength: float = 0.8, + num_inference_steps: Optional[int] = 50, + guidance_scale: Optional[float] = 7.5, + self_attention_scale: float = 0.0, + num_images_per_prompt: Optional[int] = 1, + eta: Optional[float] = 0.0, + generator: Optional[torch.Generator] = None, + max_embeddings_multiples: Optional[int] = 100, + output_type: Literal["pil", "latent"] = "pil", + return_dict: bool = True, + callback: Optional[Callable[[int, int, torch.FloatTensor], None]] = None, + is_cancelled_callback: Optional[Callable[[], bool]] = None, + callback_steps: int = 1, + ): + return self.__call__( + prompt=prompt, + negative_prompt=negative_prompt, + image=image, + num_inference_steps=num_inference_steps, # type: ignore + guidance_scale=guidance_scale, # type: ignore + self_attention_scale=self_attention_scale, + strength=strength, + num_images_per_prompt=num_images_per_prompt, + eta=eta, # type: ignore + generator=generator, + max_embeddings_multiples=max_embeddings_multiples, + output_type=output_type, + return_dict=return_dict, + callback=callback, + is_cancelled_callback=is_cancelled_callback, + callback_steps=callback_steps, + ) + + def inpaint( + self, + image: Union[torch.FloatTensor, PIL.Image.Image], # type: ignore + mask_image: Union[torch.FloatTensor, PIL.Image.Image], # type: ignore + prompt: Union[str, List[str]], + negative_prompt: Optional[Union[str, List[str]]] = None, + strength: float = 0.8, + num_inference_steps: Optional[int] = 50, + guidance_scale: Optional[float] = 7.5, + self_attention_scale: float = 0.0, + num_images_per_prompt: Optional[int] = 1, + eta: Optional[float] = 0.0, + generator: Optional[torch.Generator] = None, + max_embeddings_multiples: Optional[int] = 100, + output_type: Literal["pil", "latent"] = "pil", + return_dict: bool = True, + callback: Optional[Callable[[int, int, torch.FloatTensor], None]] = None, + is_cancelled_callback: Optional[Callable[[], bool]] = None, + callback_steps: int = 1, + width: int = 512, + height: int = 512, + ): + return self.__call__( + prompt=prompt, + negative_prompt=negative_prompt, + image=image, + mask_image=mask_image, + num_inference_steps=num_inference_steps, # type: ignore + guidance_scale=guidance_scale, # type: ignore + self_attention_scale=self_attention_scale, + strength=strength, + num_images_per_prompt=num_images_per_prompt, + eta=eta, # type: ignore + generator=generator, + max_embeddings_multiples=max_embeddings_multiples, + output_type=output_type, + return_dict=return_dict, + callback=callback, + is_cancelled_callback=is_cancelled_callback, + callback_steps=callback_steps, + width=width, + height=height, + ) diff --git a/core/inference/pytorch/pytorch.py b/core/inference/pytorch/pytorch.py index 4b7c1be0a..8e34e371a 100755 --- a/core/inference/pytorch/pytorch.py +++ b/core/inference/pytorch/pytorch.py @@ -9,10 +9,14 @@ StableDiffusionControlNetPipeline, StableDiffusionInpaintPipeline, StableDiffusionPipeline, + StableDiffusionXLPipeline, UNet2DConditionModel, ) from PIL import Image, ImageOps -from transformers.models.clip.modeling_clip import CLIPTextModel +from transformers.models.clip.modeling_clip import ( + CLIPTextModel, + CLIPTextModelWithProjection, +) from transformers.models.clip.tokenization_clip import CLIPTokenizer from api import websocket_manager @@ -64,11 +68,13 @@ def __init__( self.vae: AutoencoderKL self.unet: UNet2DConditionModel self.text_encoder: CLIPTextModel + self.text_encoder_2: CLIPTextModelWithProjection = None # type: ignore self.tokenizer: CLIPTokenizer + self.tokenizer_2: CLIPTokenizer = None # type: ignore self.scheduler: Any - self.feature_extractor: Any + self.feature_extractor: Any = None self.requires_safety_checker: bool - self.safety_checker: Any + self.safety_checker: Any = None self.image_encoder: Any self.controlnet: Optional[ControlNetModel] @@ -96,11 +102,17 @@ def load(self): self.vae = pipe.vae # type: ignore self.unet = pipe.unet # type: ignore self.text_encoder = pipe.text_encoder # type: ignore + if hasattr(pipe, "text_encoder_2"): + self.text_encoder_2 = pipe.text_encoder_2 # type: ignore self.tokenizer = pipe.tokenizer # type: ignore + if hasattr(pipe, "tokenizer_2"): + self.tokenizer_2 = pipe.tokenizer_2 # type: ignore self.scheduler = pipe.scheduler # type: ignore - self.feature_extractor = pipe.feature_extractor # type: ignore + if hasattr(pipe, "feature_extractor"): + self.feature_extractor = pipe.feature_extractor # type: ignore self.requires_safety_checker = False # type: ignore - self.safety_checker = pipe.safety_checker # type: ignore + if hasattr(pipe, "safety_checker"): + self.safety_checker = pipe.safety_checker # type: ignore if not self.bare: # Autoload textual inversions @@ -233,84 +245,118 @@ def txt2img(self, job: Txt2ImgQueueEntry) -> List[Image.Image]: self.manage_optional_components() - pipe = StableDiffusionLongPromptWeightingPipeline( - parent=self, - vae=self.vae, - unet=self.unet, # type: ignore - text_encoder=self.text_encoder, - tokenizer=self.tokenizer, - scheduler=self.scheduler, - feature_extractor=self.feature_extractor, - safety_checker=self.safety_checker, - ) + total_images: List[Image.Image] = [] if config.api.device_type == "directml": generator = torch.Generator().manual_seed(job.data.seed) else: generator = torch.Generator(config.api.device).manual_seed(job.data.seed) - if job.data.scheduler: - change_scheduler( - model=pipe, - scheduler=job.data.scheduler, - use_karras_sigmas=job.data.use_karras_sigmas, + if self.text_encoder_2 is None: + pipe = StableDiffusionLongPromptWeightingPipeline( + parent=self, + vae=self.vae, + unet=self.unet, # type: ignore + text_encoder=self.text_encoder, + tokenizer=self.tokenizer, + scheduler=self.scheduler, + feature_extractor=self.feature_extractor, + safety_checker=self.safety_checker, ) - total_images: List[Image.Image] = [] + if job.data.scheduler: + change_scheduler( + model=pipe, + scheduler=job.data.scheduler, + use_karras_sigmas=job.data.use_karras_sigmas, + ) - for _ in range(job.data.batch_count): - output_type = "pil" + for _ in range(job.data.batch_count): + output_type = "pil" - if "highres_fix" in job.flags: - output_type = "latent" + if "highres_fix" in job.flags: + output_type = "latent" - data = pipe.text2img( - prompt=job.data.prompt, - height=job.data.height, - width=job.data.width, - num_inference_steps=job.data.steps, - guidance_scale=job.data.guidance_scale, - self_attention_scale=job.data.self_attention_scale, - negative_prompt=job.data.negative_prompt, - output_type=output_type, - generator=generator, - callback=txt2img_callback, - num_images_per_prompt=job.data.batch_size, - ) + data = pipe.text2img( + prompt=job.data.prompt, + height=job.data.height, + width=job.data.width, + num_inference_steps=job.data.steps, + guidance_scale=job.data.guidance_scale, + self_attention_scale=job.data.self_attention_scale, + negative_prompt=job.data.negative_prompt, + output_type=output_type, + generator=generator, + callback=txt2img_callback, + num_images_per_prompt=job.data.batch_size, + ) - if output_type == "latent": - latents = data[0] # type: ignore - assert isinstance(latents, (torch.Tensor, torch.FloatTensor)) + if output_type == "latent": + latents = data[0] # type: ignore + assert isinstance(latents, (torch.Tensor, torch.FloatTensor)) - flag = job.flags["highres_fix"] - flag = HighResFixFlag.from_dict(flag) + flag = job.flags["highres_fix"] + flag = HighResFixFlag.from_dict(flag) - latents = scale_latents( - latents=latents, - scale=flag.scale, - latent_scale_mode=flag.latent_scale_mode, - ) + latents = scale_latents( + latents=latents, + scale=flag.scale, + latent_scale_mode=flag.latent_scale_mode, + ) + + self.memory_cleanup() + + data = pipe.img2img( + prompt=job.data.prompt, + image=latents, + num_inference_steps=flag.steps, + guidance_scale=job.data.guidance_scale, + self_attention_scale=job.data.self_attention_scale, + negative_prompt=job.data.negative_prompt, + output_type="pil", + generator=generator, + callback=txt2img_callback, + strength=flag.strength, + return_dict=False, + num_images_per_prompt=job.data.batch_size, + ) - self.memory_cleanup() + images: list[Image.Image] = data[0] # type: ignore - data = pipe.img2img( + total_images.extend(images) + else: + pipe = StableDiffusionXLPipeline( + vae=self.vae, + text_encoder=self.text_encoder, + text_encoder_2=self.text_encoder_2, + tokenizer=self.tokenizer, + tokenizer_2=self.tokenizer_2, + unet=self.unet, + scheduler=self.scheduler, + ) + if job.data.scheduler: + change_scheduler( + model=pipe, + scheduler=job.data.scheduler, + use_karras_sigmas=job.data.use_karras_sigmas, + ) + for _ in range(job.data.batch_count): + data = pipe( prompt=job.data.prompt, - image=latents, - num_inference_steps=flag.steps, + height=job.data.height, + width=job.data.width, + num_inference_steps=job.data.steps, guidance_scale=job.data.guidance_scale, - self_attention_scale=job.data.self_attention_scale, negative_prompt=job.data.negative_prompt, output_type="pil", generator=generator, callback=txt2img_callback, - strength=flag.strength, - return_dict=False, num_images_per_prompt=job.data.batch_size, + return_dict=False, ) - images: list[Image.Image] = data[0] # type: ignore - - total_images.extend(images) + images: list[Image.Image] = data[0] # type: ignore + total_images.extend(images) websocket_manager.broadcast_sync( data=Data( diff --git a/core/optimizations/pytorch_optimizations.py b/core/optimizations/pytorch_optimizations.py index cee083a77..97f7eb8e6 100644 --- a/core/optimizations/pytorch_optimizations.py +++ b/core/optimizations/pytorch_optimizations.py @@ -65,6 +65,14 @@ def optimize_model( "mps", ] and (offload != "disabled" and offload is not None) + if hasattr(pipe, "text_encoder_2"): + from diffusers import AutoencoderKL + + vae = AutoencoderKL.from_pretrained( + "madebyollin/sdxl-vae-fp16-fix", torch_dtype=torch.float16 + ) + pipe.vae = vae + # Took me an hour to understand why CPU stopped working... # Turns out AMD just lacks support for BF16... # Not mad, not mad at all... to be fair, I'm just disappointed @@ -146,12 +154,14 @@ def optimize_model( for cpu_offloaded_model in [ pipe.text_encoder, + pipe.text_encoder_2, pipe.unet, pipe.vae, ]: - _, hook = cpu_offload_with_hook( - cpu_offloaded_model, device, prev_module_hook=hook - ) + if cpu_offloaded_model is not None: + _, hook = cpu_offload_with_hook( + cpu_offloaded_model, device, prev_module_hook=hook + ) pipe.final_offload_hook = hook setattr(pipe.vae, "main_device", True) setattr(pipe.unet, "main_device", True) diff --git a/core/types.py b/core/types.py index b0c43ae05..e071be0f5 100644 --- a/core/types.py +++ b/core/types.py @@ -15,9 +15,16 @@ ) from diffusers.schedulers.scheduling_utils import KarrasDiffusionSchedulers -InferenceBackend = Literal["PyTorch", "AITemplate", "ONNX"] +InferenceBackend = Literal["PyTorch", "SDXL", "AITemplate", "ONNX"] Backend = Literal[ - "PyTorch", "AITemplate", "unknown", "LoRA", "Textual Inversion", "ONNX", "VAE" + "PyTorch", + "SDXL", + "AITemplate", + "unknown", + "LoRA", + "Textual Inversion", + "ONNX", + "VAE", ] diff --git a/frontend/dist/assets/AccelerateView.js b/frontend/dist/assets/AccelerateView.js index 97bdaccee..884e111a0 100644 --- a/frontend/dist/assets/AccelerateView.js +++ b/frontend/dist/assets/AccelerateView.js @@ -1,4 +1,4 @@ -import { Y as cB, $ as cM, X as c, Z as cE, a0 as iconSwitchTransition, aq as cNotM, d as defineComponent, Q as useConfig, a7 as useRtl, a5 as useTheme, T as provide, D as h, aC as flatten, aD as getSlot, V as createInjectionKey, bb as stepsLight, a3 as inject, aZ as throwError, c as computed, a9 as useThemeClass, aB as resolveWrappedSlot, at as resolveSlot, ab as NIconSwitchTransition, a8 as createKey, W as call, au as NBaseIcon, bc as FinishedIcon, bd as ErrorIcon, b as useMessage, u as useState, E as ref, e as openBlock, f as createElementBlock, g as createVNode, w as withCtx, h as unref, j as NSpace, i as NCard, n as createBaseVNode, r as NSelect, F as NButton, m as createTextVNode, b9 as NModal, s as serverUrl, a as useSettings, v as createBlock, H as NTabPane, I as NTabs } from "./index.js"; +import { a1 as cB, a4 as cM, a3 as c, a2 as cE, ar as iconSwitchTransition, aL as cNotM, d as defineComponent, X as useConfig, aw as useRtl, aa as useTheme, T as provide, D as h, ac as flatten, aW as getSlot, U as createInjectionKey, bt as stepsLight, V as inject, W as throwError, c as computed, ab as useThemeClass, aV as resolveWrappedSlot, aN as resolveSlot, az as NIconSwitchTransition, ax as createKey, aq as call, aO as NBaseIcon, bu as FinishedIcon, bv as ErrorIcon, b as useMessage, u as useState, E as ref, e as openBlock, f as createElementBlock, g as createVNode, w as withCtx, h as unref, j as NSpace, i as NCard, n as createBaseVNode, r as NSelect, F as NButton, m as createTextVNode, bp as NModal, s as serverUrl, a as useSettings, v as createBlock, H as NTabPane, I as NTabs } from "./index.js"; import { N as NSlider } from "./Slider.js"; import { N as NInputNumber } from "./InputNumber.js"; import { N as NSwitch } from "./Switch.js"; diff --git a/frontend/dist/assets/DescriptionsItem.js b/frontend/dist/assets/DescriptionsItem.js index badc570a3..22bb1b138 100644 --- a/frontend/dist/assets/DescriptionsItem.js +++ b/frontend/dist/assets/DescriptionsItem.js @@ -1,4 +1,4 @@ -import { X as c, Y as cB, aq as cNotM, $ as cM, Z as cE, a1 as insideModal, a2 as insidePopover, d as defineComponent, Q as useConfig, a5 as useTheme, c as computed, a9 as useThemeClass, bn as useCompitable, aC as flatten, D as h, aD as getSlot, bo as descriptionsLight, a8 as createKey } from "./index.js"; +import { a3 as c, a1 as cB, aL as cNotM, a4 as cM, a2 as cE, as as insideModal, at as insidePopover, d as defineComponent, X as useConfig, aa as useTheme, c as computed, ab as useThemeClass, bE as useCompitable, ac as flatten, D as h, aW as getSlot, bF as descriptionsLight, ax as createKey } from "./index.js"; function getVNodeChildren(vNode, slotName = "default", fallback = []) { const { children } = vNode; if (children !== null && typeof children === "object" && !Array.isArray(children)) { diff --git a/frontend/dist/assets/ExtraView.js b/frontend/dist/assets/ExtraView.js index 113dfd307..adb452496 100644 --- a/frontend/dist/assets/ExtraView.js +++ b/frontend/dist/assets/ExtraView.js @@ -1,7 +1,7 @@ import { _ as _sfc_main$2 } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; import { _ as _sfc_main$3 } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; import { I as ImageUpload } from "./ImageUpload.js"; -import { d as defineComponent, u as useState, a as useSettings, b as useMessage, e as openBlock, f as createElementBlock, g as createVNode, w as withCtx, h as unref, N as NGi, i as NCard, j as NSpace, n as createBaseVNode, r as NSelect, K as upscalerOptions, q as NTooltip, m as createTextVNode, y as NGrid, s as serverUrl, A as pushScopeId, B as popScopeId, _ as _export_sfc, v as createBlock, H as NTabPane, I as NTabs } from "./index.js"; +import { d as defineComponent, u as useState, a as useSettings, b as useMessage, e as openBlock, f as createElementBlock, g as createVNode, w as withCtx, h as unref, N as NGi, i as NCard, j as NSpace, n as createBaseVNode, r as NSelect, J as upscalerOptions, q as NTooltip, m as createTextVNode, y as NGrid, s as serverUrl, A as pushScopeId, B as popScopeId, _ as _export_sfc, v as createBlock, H as NTabPane, I as NTabs } from "./index.js"; import { N as NSlider } from "./Slider.js"; import { N as NInputNumber } from "./InputNumber.js"; import "./SendOutputTo.vue_vue_type_script_setup_true_lang.js"; diff --git a/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js index 18677889a..adf5b7132 100644 --- a/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { d as defineComponent, e as openBlock, f as createElementBlock, n as createBaseVNode, u as useState, a as useSettings, E as ref, bi as onMounted, o as onUnmounted, s as serverUrl, v as createBlock, w as withCtx, g as createVNode, h as unref, N as NGi, F as NButton, G as NIcon, m as createTextVNode, y as NGrid, bA as NAlert, x as createCommentVNode, i as NCard } from "./index.js"; +import { d as defineComponent, e as openBlock, f as createElementBlock, n as createBaseVNode, u as useState, a as useSettings, E as ref, $ as onMounted, o as onUnmounted, s as serverUrl, v as createBlock, w as withCtx, g as createVNode, h as unref, N as NGi, F as NButton, G as NIcon, m as createTextVNode, y as NGrid, bN as NAlert, x as createCommentVNode, i as NCard } from "./index.js"; const _hoisted_1$1 = { xmlns: "http://www.w3.org/2000/svg", "xmlns:xlink": "http://www.w3.org/1999/xlink", diff --git a/frontend/dist/assets/GridOutline.js b/frontend/dist/assets/GridOutline.js new file mode 100644 index 000000000..76aca14a0 --- /dev/null +++ b/frontend/dist/assets/GridOutline.js @@ -0,0 +1,92 @@ +import { d as defineComponent, e as openBlock, f as createElementBlock, n as createBaseVNode } from "./index.js"; +const _hoisted_1 = { + xmlns: "http://www.w3.org/2000/svg", + "xmlns:xlink": "http://www.w3.org/1999/xlink", + viewBox: "0 0 512 512" +}; +const _hoisted_2 = /* @__PURE__ */ createBaseVNode( + "rect", + { + x: "48", + y: "48", + width: "176", + height: "176", + rx: "20", + ry: "20", + fill: "none", + stroke: "currentColor", + "stroke-linecap": "round", + "stroke-linejoin": "round", + "stroke-width": "32" + }, + null, + -1 + /* HOISTED */ +); +const _hoisted_3 = /* @__PURE__ */ createBaseVNode( + "rect", + { + x: "288", + y: "48", + width: "176", + height: "176", + rx: "20", + ry: "20", + fill: "none", + stroke: "currentColor", + "stroke-linecap": "round", + "stroke-linejoin": "round", + "stroke-width": "32" + }, + null, + -1 + /* HOISTED */ +); +const _hoisted_4 = /* @__PURE__ */ createBaseVNode( + "rect", + { + x: "48", + y: "288", + width: "176", + height: "176", + rx: "20", + ry: "20", + fill: "none", + stroke: "currentColor", + "stroke-linecap": "round", + "stroke-linejoin": "round", + "stroke-width": "32" + }, + null, + -1 + /* HOISTED */ +); +const _hoisted_5 = /* @__PURE__ */ createBaseVNode( + "rect", + { + x: "288", + y: "288", + width: "176", + height: "176", + rx: "20", + ry: "20", + fill: "none", + stroke: "currentColor", + "stroke-linecap": "round", + "stroke-linejoin": "round", + "stroke-width": "32" + }, + null, + -1 + /* HOISTED */ +); +const _hoisted_6 = [_hoisted_2, _hoisted_3, _hoisted_4, _hoisted_5]; +const GridOutline = defineComponent({ + name: "GridOutline", + render: function render(_ctx, _cache) { + return openBlock(), createElementBlock("svg", _hoisted_1, _hoisted_6); + } +}); +export { + GridOutline as G +}; diff --git a/frontend/dist/assets/Image2ImageView.js b/frontend/dist/assets/Image2ImageView.js index 6e2b27fa8..49d267225 100644 --- a/frontend/dist/assets/Image2ImageView.js +++ b/frontend/dist/assets/Image2ImageView.js @@ -1,16 +1,17 @@ import { _ as _sfc_main$4 } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; -import { B as BurnerClock, _ as _sfc_main$6 } from "./clock.js"; +import { B as BurnerClock } from "./clock.js"; import { _ as _sfc_main$5 } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; import { I as ImageUpload } from "./ImageUpload.js"; +import { _ as _sfc_main$6 } from "./OutputStats.vue_vue_type_script_setup_true_lang.js"; import { d as defineComponent, e as openBlock, f as createElementBlock, n as createBaseVNode, u as useState, a as useSettings, b as useMessage, c as computed, o as onUnmounted, g as createVNode, w as withCtx, h as unref, N as NGi, i as NCard, j as NSpace, k as NInput, p as promptHandleKeyUp, l as promptHandleKeyDown, m as createTextVNode, t as toDisplayString, q as NTooltip, r as NSelect, y as NGrid, z as spaceRegex, s as serverUrl, A as pushScopeId, B as popScopeId, _ as _export_sfc, C as resolveComponent, D as h, E as ref, F as NButton, G as NIcon, v as createBlock, H as NTabPane, I as NTabs } from "./index.js"; import { v as v4 } from "./v4.js"; import { N as NSwitch } from "./Switch.js"; import { N as NSlider } from "./Slider.js"; import { N as NInputNumber } from "./InputNumber.js"; -import "./DescriptionsItem.js"; import "./SendOutputTo.vue_vue_type_script_setup_true_lang.js"; import "./TrashBin.js"; import "./CloudUpload.js"; +import "./DescriptionsItem.js"; const _hoisted_1$6 = { xmlns: "http://www.w3.org/2000/svg", "xmlns:xlink": "http://www.w3.org/1999/xlink", diff --git a/frontend/dist/assets/ImageBrowserView.js b/frontend/dist/assets/ImageBrowserView.js index ff8751c31..d8198b6e9 100644 --- a/frontend/dist/assets/ImageBrowserView.js +++ b/frontend/dist/assets/ImageBrowserView.js @@ -1,96 +1,9 @@ -import { d as defineComponent, e as openBlock, f as createElementBlock, n as createBaseVNode, bl as useCssVars, u as useState, a as useSettings, E as ref, c as computed, b7 as reactive, bi as onMounted, o as onUnmounted, g as createVNode, h as unref, w as withCtx, L as Fragment, M as renderList, s as serverUrl, k as NInput, G as NIcon, b9 as NModal, y as NGrid, N as NGi, F as NButton, m as createTextVNode, O as NScrollbar, v as createBlock, t as toDisplayString, x as createCommentVNode, bm as urlFromPath, _ as _export_sfc } from "./index.js"; +import { d as defineComponent, bq as useCssVars, u as useState, a as useSettings, E as ref, c as computed, bn as reactive, $ as onMounted, o as onUnmounted, e as openBlock, f as createElementBlock, n as createBaseVNode, g as createVNode, h as unref, w as withCtx, K as Fragment, L as renderList, s as serverUrl, k as NInput, G as NIcon, bp as NModal, y as NGrid, N as NGi, F as NButton, m as createTextVNode, M as NScrollbar, v as createBlock, t as toDisplayString, x as createCommentVNode, bC as urlFromPath, _ as _export_sfc } from "./index.js"; import { D as Download, _ as _sfc_main$1 } from "./SendOutputTo.vue_vue_type_script_setup_true_lang.js"; +import { G as GridOutline } from "./GridOutline.js"; import { N as NImage, T as TrashBin } from "./TrashBin.js"; import { N as NSlider } from "./Slider.js"; import { N as NDescriptionsItem, a as NDescriptions } from "./DescriptionsItem.js"; -const _hoisted_1$1 = { - xmlns: "http://www.w3.org/2000/svg", - "xmlns:xlink": "http://www.w3.org/1999/xlink", - viewBox: "0 0 512 512" -}; -const _hoisted_2$1 = /* @__PURE__ */ createBaseVNode( - "rect", - { - x: "48", - y: "48", - width: "176", - height: "176", - rx: "20", - ry: "20", - fill: "none", - stroke: "currentColor", - "stroke-linecap": "round", - "stroke-linejoin": "round", - "stroke-width": "32" - }, - null, - -1 - /* HOISTED */ -); -const _hoisted_3$1 = /* @__PURE__ */ createBaseVNode( - "rect", - { - x: "288", - y: "48", - width: "176", - height: "176", - rx: "20", - ry: "20", - fill: "none", - stroke: "currentColor", - "stroke-linecap": "round", - "stroke-linejoin": "round", - "stroke-width": "32" - }, - null, - -1 - /* HOISTED */ -); -const _hoisted_4$1 = /* @__PURE__ */ createBaseVNode( - "rect", - { - x: "48", - y: "288", - width: "176", - height: "176", - rx: "20", - ry: "20", - fill: "none", - stroke: "currentColor", - "stroke-linecap": "round", - "stroke-linejoin": "round", - "stroke-width": "32" - }, - null, - -1 - /* HOISTED */ -); -const _hoisted_5 = /* @__PURE__ */ createBaseVNode( - "rect", - { - x: "288", - y: "288", - width: "176", - height: "176", - rx: "20", - ry: "20", - fill: "none", - stroke: "currentColor", - "stroke-linecap": "round", - "stroke-linejoin": "round", - "stroke-width": "32" - }, - null, - -1 - /* HOISTED */ -); -const _hoisted_6 = [_hoisted_2$1, _hoisted_3$1, _hoisted_4$1, _hoisted_5]; -const GridOutline = defineComponent({ - name: "GridOutline", - render: function render(_ctx, _cache) { - return openBlock(), createElementBlock("svg", _hoisted_1$1, _hoisted_6); - } -}); const _hoisted_1 = { style: { "width": "calc(100vw - 98px)", "height": "48px", "border-bottom": "#505050 1px solid", "margin-top": "53px", "display": "flex", "justify-content": "end", "align-items": "center", "padding-right": "24px", "position": "fixed", "top": "0", "z-index": "1" }, class: "top-bar" diff --git a/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js index 2961f10c2..bf668606f 100644 --- a/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { d as defineComponent, E as ref, u as useState, e as openBlock, v as createBlock, w as withCtx, h as unref, N as NGi, g as createVNode, G as NIcon, m as createTextVNode, F as NButton, x as createCommentVNode, y as NGrid, c as computed, n as createBaseVNode, f as createElementBlock, L as Fragment, M as renderList, O as NScrollbar, i as NCard } from "./index.js"; +import { d as defineComponent, E as ref, u as useState, e as openBlock, v as createBlock, w as withCtx, h as unref, N as NGi, g as createVNode, G as NIcon, m as createTextVNode, F as NButton, x as createCommentVNode, y as NGrid, c as computed, n as createBaseVNode, f as createElementBlock, K as Fragment, L as renderList, M as NScrollbar, i as NCard } from "./index.js"; import { D as Download, _ as _sfc_main$2 } from "./SendOutputTo.vue_vue_type_script_setup_true_lang.js"; import { T as TrashBin, N as NImage } from "./TrashBin.js"; const _sfc_main$1 = /* @__PURE__ */ defineComponent({ diff --git a/frontend/dist/assets/ImageUpload.js b/frontend/dist/assets/ImageUpload.js index 2d80b754f..630a5d7f2 100644 --- a/frontend/dist/assets/ImageUpload.js +++ b/frontend/dist/assets/ImageUpload.js @@ -1,4 +1,4 @@ -import { d as defineComponent, E as ref, c as computed, bi as onMounted, e as openBlock, v as createBlock, w as withCtx, n as createBaseVNode, bz as withModifiers, f as createElementBlock, g as createVNode, h as unref, G as NIcon, t as toDisplayString, i as NCard, A as pushScopeId, B as popScopeId, _ as _export_sfc } from "./index.js"; +import { d as defineComponent, E as ref, c as computed, $ as onMounted, e as openBlock, v as createBlock, w as withCtx, n as createBaseVNode, bM as withModifiers, f as createElementBlock, g as createVNode, h as unref, G as NIcon, t as toDisplayString, i as NCard, A as pushScopeId, B as popScopeId, _ as _export_sfc } from "./index.js"; import { C as CloudUpload } from "./CloudUpload.js"; const _withScopeId = (n) => (pushScopeId("data-v-4f5be896"), n = n(), popScopeId(), n); const _hoisted_1 = { class: "image-container" }; diff --git a/frontend/dist/assets/InputNumber.js b/frontend/dist/assets/InputNumber.js index 7339753a3..f0779d8ff 100644 --- a/frontend/dist/assets/InputNumber.js +++ b/frontend/dist/assets/InputNumber.js @@ -1,4 +1,4 @@ -import { d as defineComponent, D as h, X as c, Y as cB, Q as useConfig, a5 as useTheme, ar as useLocale, R as useFormItem, E as ref, U as toRef, S as useMergedState, a4 as useMemo, J as watch, a7 as useRtl, c as computed, k as NInput, aB as resolveWrappedSlot, bB as inputNumberLight, ac as on, bC as rgba, at as resolveSlot, au as NBaseIcon, bD as XButton, a$ as AddIcon, W as call, ah as nextTick } from "./index.js"; +import { d as defineComponent, D as h, a3 as c, a1 as cB, X as useConfig, aa as useTheme, aM as useLocale, ap as useFormItem, E as ref, a6 as toRef, a5 as useMergedState, au as useMemo, a9 as watch, aw as useRtl, c as computed, k as NInput, aV as resolveWrappedSlot, bO as inputNumberLight, an as on, bP as rgba, aN as resolveSlot, aO as NBaseIcon, bQ as XButton, bg as AddIcon, aq as call, ao as nextTick } from "./index.js"; const RemoveIcon = defineComponent({ name: "Remove", render() { diff --git a/frontend/dist/assets/ModelsView.css b/frontend/dist/assets/ModelsView.css index 0963a92de..ccadecd81 100644 --- a/frontend/dist/assets/ModelsView.css +++ b/frontend/dist/assets/ModelsView.css @@ -1,4 +1,25 @@ +.img-slider[data-v-30671504] { + aspect-ratio: 1/1; + height: 182px; + width: auto; +} +.image-grid[data-v-30671504] { + display: grid; + grid-template-columns: repeat( + var(--3e32aafb), + 1fr + ); + grid-gap: 8px; +} +.top-bar[data-v-30671504] { + background-color: var(--46aceb59); +} +.image-column[data-v-30671504] { + display: flex; + flex-direction: column; +} + .install[data-v-6a6fb4b4] { width: 100%; padding: 10px 0px; diff --git a/frontend/dist/assets/ModelsView.js b/frontend/dist/assets/ModelsView.js index ce111c608..ad58c591d 100644 --- a/frontend/dist/assets/ModelsView.js +++ b/frontend/dist/assets/ModelsView.js @@ -1,4 +1,7 @@ -import { d as defineComponent, D as h, P as replaceable, Q as useConfig, R as useFormItem, E as ref, c as computed, S as useMergedState, T as provide, U as toRef, V as createInjectionKey, W as call, X as c, Y as cB, Z as cE, $ as cM, a0 as iconSwitchTransition, a1 as insideModal, a2 as insidePopover, a3 as inject, a4 as useMemo, a5 as useTheme, a6 as checkboxLight, a7 as useRtl, a8 as createKey, a9 as useThemeClass, aa as createId, ab as NIconSwitchTransition, ac as on, ad as popselectLight, J as watch, ae as NInternalSelectMenu, af as createTreeMate, ag as happensIn, ah as nextTick, ai as keysOf, aj as createTmOptions, ak as keep, al as createRefSetter, am as mergeEventHandlers, an as omit, ao as NPopover, ap as popoverBaseProps, aq as cNotM, ar as useLocale, as as watchEffect, at as resolveSlot, k as NInput, r as NSelect, L as Fragment, au as NBaseIcon, av as useAdjustedTo, aw as paginationLight, ax as ellipsisLight, ay as onDeactivated, q as NTooltip, az as mergeProps, aA as radioLight, aB as resolveWrappedSlot, aC as flatten$1, aD as getSlot, aE as depx, aF as formatLength, F as NButton, aG as NScrollbar, aH as onBeforeUnmount, aI as off, aJ as ChevronDownIcon, aK as NDropdown, aL as pxfy, aM as get, aN as NBaseLoading, aO as ChevronRightIcon, o as onUnmounted, aP as VResizeObserver, aQ as warn, aR as VVirtualList, aS as NEmpty, aT as cssrAnchorMetaName, aU as repeat, aV as beforeNextFrameOnce, aW as fadeInScaleUpTransition, aX as Transition, aY as dataTableLight, aZ as throwError, a_ as isBrowser, a$ as AddIcon, b0 as NProgress, b1 as NFadeInExpandTransition, b2 as EyeIcon, b3 as fadeInHeightExpandTransition, b4 as Teleport, b5 as uploadLight, e as openBlock, f as createElementBlock, n as createBaseVNode, v as createBlock, w as withCtx, g as createVNode, h as unref, G as NIcon, b6 as NResult, u as useState, b as useMessage, b7 as reactive, b8 as huggingfaceModelsFile, m as createTextVNode, i as NCard, s as serverUrl, A as pushScopeId, B as popScopeId, _ as _export_sfc, j as NSpace, b9 as NModal, N as NGi, ba as NText, M as renderList, t as toDisplayString, y as NGrid, H as NTabPane, I as NTabs } from "./index.js"; +import { O as upperFirst, P as toString, Q as createCompounder, d as defineComponent, D as h, R as replaceable, S as cloneVNode, T as provide, U as createInjectionKey, V as inject, W as throwError, X as useConfig, E as ref, Y as onBeforeUpdate, Z as indexMap, c as computed, $ as onMounted, a0 as onBeforeUnmount, a1 as cB, a2 as cE, a3 as c, a4 as cM, a5 as useMergedState, a6 as toRef, a7 as watchEffect, a8 as onUpdated, a9 as watch, aa as useTheme, ab as useThemeClass, ac as flatten$1, ad as VResizeObserver, ae as resolveSlotWithProps, af as withDirectives, ag as vShow, ah as Transition, ai as keep, aj as off, ak as carouselLight, al as normalizeStyle, am as getPreciseEventTarget, an as on, ao as nextTick, ap as useFormItem, aq as call, ar as iconSwitchTransition, as as insideModal, at as insidePopover, au as useMemo, av as checkboxLight, aw as useRtl, ax as createKey, ay as createId, az as NIconSwitchTransition, aA as popselectLight, aB as NInternalSelectMenu, aC as createTreeMate, aD as happensIn, aE as keysOf, aF as createTmOptions, aG as createRefSetter, aH as mergeEventHandlers, aI as omit, aJ as NPopover, aK as popoverBaseProps, aL as cNotM, aM as useLocale, aN as resolveSlot, k as NInput, r as NSelect, K as Fragment, aO as NBaseIcon, aP as useAdjustedTo, aQ as paginationLight, aR as ellipsisLight, aS as onDeactivated, q as NTooltip, aT as mergeProps, aU as radioLight, aV as resolveWrappedSlot, aW as getSlot, aX as depx, aY as formatLength, F as NButton, aZ as NScrollbar, a_ as ChevronDownIcon, a$ as NDropdown, b0 as pxfy, b1 as get, b2 as NBaseLoading, b3 as ChevronRightIcon, o as onUnmounted, b4 as warn, b5 as VVirtualList, b6 as NEmpty, b7 as cssrAnchorMetaName, b8 as repeat, b9 as beforeNextFrameOnce, ba as fadeInScaleUpTransition, bb as dataTableLight, bc as loadingBarApiInjectionKey, L as renderList, bd as rateLight, be as color2Class, bf as isBrowser, bg as AddIcon, bh as NProgress, bi as NFadeInExpandTransition, bj as EyeIcon, bk as fadeInHeightExpandTransition, bl as Teleport, bm as uploadLight, e as openBlock, f as createElementBlock, n as createBaseVNode, b as useMessage, bn as reactive, v as createBlock, w as withCtx, g as createVNode, h as unref, H as NTabPane, y as NGrid, N as NGi, i as NCard, bo as NTag, m as createTextVNode, t as toDisplayString, I as NTabs, bp as NModal, bq as useCssVars, a as useSettings, G as NIcon, _ as _export_sfc, u as useState, br as huggingfaceModelsFile, s as serverUrl, A as pushScopeId, B as popScopeId, j as NSpace, bs as NText } from "./index.js"; +import { a as NDescriptions, N as NDescriptionsItem } from "./DescriptionsItem.js"; +import { G as GridOutline } from "./GridOutline.js"; +import { N as NSlider } from "./Slider.js"; import { N as NSwitch } from "./Switch.js"; import { N as NImage, a as NImageGroup, T as TrashBin } from "./TrashBin.js"; import { C as CloudUpload } from "./CloudUpload.js"; @@ -17,6 +20,14 @@ function smallerSize(size) { } throw Error(`${size} has no smaller size.`); } +function capitalize(string) { + return upperFirst(toString(string).toLowerCase()); +} +var camelCase = createCompounder(function(result, word, index) { + word = word.toLowerCase(); + return result + (index ? capitalize(word) : word); +}); +const camelCase$1 = camelCase; const ArrowDownIcon = defineComponent({ name: "ArrowDown", render() { @@ -147,39 +158,1272 @@ const MoreIcon = defineComponent({ name: "More", render() { return h( - "svg", - { viewBox: "0 0 16 16", version: "1.1", xmlns: "http://www.w3.org/2000/svg" }, - h( - "g", - { stroke: "none", "stroke-width": "1", fill: "none", "fill-rule": "evenodd" }, - h( - "g", - { fill: "currentColor", "fill-rule": "nonzero" }, - h("path", { d: "M4,7 C4.55228,7 5,7.44772 5,8 C5,8.55229 4.55228,9 4,9 C3.44772,9 3,8.55229 3,8 C3,7.44772 3.44772,7 4,7 Z M8,7 C8.55229,7 9,7.44772 9,8 C9,8.55229 8.55229,9 8,9 C7.44772,9 7,8.55229 7,8 C7,7.44772 7.44772,7 8,7 Z M12,7 C12.5523,7 13,7.44772 13,8 C13,8.55229 12.5523,9 12,9 C11.4477,9 11,8.55229 11,8 C11,7.44772 11.4477,7 12,7 Z" }) - ) - ) + "svg", + { viewBox: "0 0 16 16", version: "1.1", xmlns: "http://www.w3.org/2000/svg" }, + h( + "g", + { stroke: "none", "stroke-width": "1", fill: "none", "fill-rule": "evenodd" }, + h( + "g", + { fill: "currentColor", "fill-rule": "nonzero" }, + h("path", { d: "M4,7 C4.55228,7 5,7.44772 5,8 C5,8.55229 4.55228,9 4,9 C3.44772,9 3,8.55229 3,8 C3,7.44772 3.44772,7 4,7 Z M8,7 C8.55229,7 9,7.44772 9,8 C9,8.55229 8.55229,9 8,9 C7.44772,9 7,8.55229 7,8 C7,7.44772 7.44772,7 8,7 Z M12,7 C12.5523,7 13,7.44772 13,8 C13,8.55229 12.5523,9 12,9 C11.4477,9 11,8.55229 11,8 C11,7.44772 11.4477,7 12,7 Z" }) + ) + ) + ); + } +}); +const CancelIcon = replaceable("cancel", h( + "svg", + { viewBox: "0 0 16 16", version: "1.1", xmlns: "http://www.w3.org/2000/svg" }, + h( + "g", + { stroke: "none", "stroke-width": "1", fill: "none", "fill-rule": "evenodd" }, + h( + "g", + { fill: "currentColor", "fill-rule": "nonzero" }, + h("path", { d: "M2.58859116,2.7156945 L2.64644661,2.64644661 C2.82001296,2.47288026 3.08943736,2.45359511 3.2843055,2.58859116 L3.35355339,2.64644661 L8,7.293 L12.6464466,2.64644661 C12.8417088,2.45118446 13.1582912,2.45118446 13.3535534,2.64644661 C13.5488155,2.84170876 13.5488155,3.15829124 13.3535534,3.35355339 L8.707,8 L13.3535534,12.6464466 C13.5271197,12.820013 13.5464049,13.0894374 13.4114088,13.2843055 L13.3535534,13.3535534 C13.179987,13.5271197 12.9105626,13.5464049 12.7156945,13.4114088 L12.6464466,13.3535534 L8,8.707 L3.35355339,13.3535534 C3.15829124,13.5488155 2.84170876,13.5488155 2.64644661,13.3535534 C2.45118446,13.1582912 2.45118446,12.8417088 2.64644661,12.6464466 L7.293,8 L2.64644661,3.35355339 C2.47288026,3.17998704 2.45359511,2.91056264 2.58859116,2.7156945 L2.64644661,2.64644661 L2.58859116,2.7156945 Z" }) + ) + ) +)); +const RetryIcon = replaceable("retry", h( + "svg", + { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 512 512" }, + h("path", { d: "M320,146s24.36-12-64-12A160,160,0,1,0,416,294", style: "fill: none; stroke: currentcolor; stroke-linecap: round; stroke-miterlimit: 10; stroke-width: 32px;" }), + h("polyline", { points: "256 58 336 138 256 218", style: "fill: none; stroke: currentcolor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 32px;" }) +)); +function addDuplicateSlides(slides) { + const { length } = slides; + if (length > 1) { + slides.push(duplicateSlide(slides[0], 0, "append")); + slides.unshift(duplicateSlide(slides[length - 1], length - 1, "prepend")); + return slides; + } + return slides; +} +function duplicateSlide(child, index, position) { + return cloneVNode(child, { + // for patch + key: `carousel-item-duplicate-${index}-${position}` + }); +} +function getDisplayIndex(current, length, duplicatedable) { + return !duplicatedable ? current : current === 0 ? length - 3 : current === length - 1 ? 0 : current - 1; +} +function getRealIndex(current, duplicatedable) { + return !duplicatedable ? current : current + 1; +} +function getPrevIndex(current, length, duplicatedable) { + if (current < 0) + return null; + return current === 0 ? duplicatedable ? length - 1 : null : current - 1; +} +function getNextIndex(current, length, duplicatedable) { + if (current > length - 1) + return null; + return current === length - 1 ? duplicatedable ? 0 : null : current + 1; +} +function getDisplayTotalView(total, duplicatedable) { + return duplicatedable && total > 3 ? total - 2 : total; +} +function isTouchEvent(e) { + return window.TouchEvent && e instanceof window.TouchEvent; +} +function calculateSize(element, innerOnly) { + let { offsetWidth: width, offsetHeight: height } = element; + if (innerOnly) { + const style2 = getComputedStyle(element); + width = width - parseFloat(style2.getPropertyValue("padding-left")) - parseFloat(style2.getPropertyValue("padding-right")); + height = height - parseFloat(style2.getPropertyValue("padding-top")) - parseFloat(style2.getPropertyValue("padding-bottom")); + } + return { width, height }; +} +function clampValue(value, min, max) { + return value < min ? min : value > max ? max : value; +} +function resolveSpeed(value) { + if (value === void 0) + return 0; + if (typeof value === "number") + return value; + const timeRE = /^((\d+)?\.?\d+?)(ms|s)?$/; + const match = value.match(timeRE); + if (match) { + const [, number, , unit = "ms"] = match; + return Number(number) * (unit === "ms" ? 1 : 1e3); + } + return 0; +} +const carouselMethodsInjectionKey = createInjectionKey("n-carousel-methods"); +const provideCarouselContext = (contextValue) => { + provide(carouselMethodsInjectionKey, contextValue); +}; +const useCarouselContext = (location = "unknown", component = "component") => { + const CarouselContext = inject(carouselMethodsInjectionKey); + if (!CarouselContext) { + throwError(location, `\`${component}\` must be placed inside \`n-carousel\`.`); + } + return CarouselContext; +}; +const carouselDotsProps = { + total: { + type: Number, + default: 0 + }, + currentIndex: { + type: Number, + default: 0 + }, + dotType: { + type: String, + default: "dot" + }, + trigger: { + type: String, + default: "click" + }, + keyboard: Boolean +}; +const NCarouselDots = defineComponent({ + name: "CarouselDots", + props: carouselDotsProps, + setup(props) { + const { mergedClsPrefixRef } = useConfig(props); + const dotElsRef = ref([]); + const NCarousel2 = useCarouselContext(); + function handleKeydown(e, current) { + switch (e.key) { + case "Enter": + case " ": + e.preventDefault(); + NCarousel2.to(current); + return; + } + if (props.keyboard) { + handleKeyboard(e); + } + } + function handleMouseenter(current) { + if (props.trigger === "hover") { + NCarousel2.to(current); + } + } + function handleClick(current) { + if (props.trigger === "click") { + NCarousel2.to(current); + } + } + function handleKeyboard(e) { + var _a; + if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) { + return; + } + const nodeName = (_a = document.activeElement) === null || _a === void 0 ? void 0 : _a.nodeName.toLowerCase(); + if (nodeName === "input" || nodeName === "textarea") { + return; + } + const { code: keycode } = e; + const isVerticalNext = keycode === "PageUp" || keycode === "ArrowUp"; + const isVerticalPrev = keycode === "PageDown" || keycode === "ArrowDown"; + const isHorizontalNext = keycode === "PageUp" || keycode === "ArrowRight"; + const isHorizontalPrev = keycode === "PageDown" || keycode === "ArrowLeft"; + const vertical = NCarousel2.isVertical(); + const wantToNext = vertical ? isVerticalNext : isHorizontalNext; + const wantToPrev = vertical ? isVerticalPrev : isHorizontalPrev; + if (!wantToNext && !wantToPrev) { + return; + } + e.preventDefault(); + if (wantToNext && !NCarousel2.isNextDisabled()) { + NCarousel2.next(); + focusDot(NCarousel2.currentIndexRef.value); + } else if (wantToPrev && !NCarousel2.isPrevDisabled()) { + NCarousel2.prev(); + focusDot(NCarousel2.currentIndexRef.value); + } + } + function focusDot(index) { + var _a; + (_a = dotElsRef.value[index]) === null || _a === void 0 ? void 0 : _a.focus(); + } + onBeforeUpdate(() => dotElsRef.value.length = 0); + return { + mergedClsPrefix: mergedClsPrefixRef, + dotEls: dotElsRef, + handleKeydown, + handleMouseenter, + handleClick + }; + }, + render() { + const { mergedClsPrefix, dotEls } = this; + return h("div", { class: [ + `${mergedClsPrefix}-carousel__dots`, + `${mergedClsPrefix}-carousel__dots--${this.dotType}` + ], role: "tablist" }, indexMap(this.total, (i) => { + const selected = i === this.currentIndex; + return h("div", { "aria-selected": selected, ref: (el) => dotEls.push(el), role: "button", tabindex: "0", class: [ + `${mergedClsPrefix}-carousel__dot`, + selected && `${mergedClsPrefix}-carousel__dot--active` + ], key: i, onClick: () => { + this.handleClick(i); + }, onMouseenter: () => { + this.handleMouseenter(i); + }, onKeydown: (e) => { + this.handleKeydown(e, i); + } }); + })); + } +}); +const backwardIcon = h( + "svg", + { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16" }, + h( + "g", + { fill: "none" }, + h("path", { d: "M10.26 3.2a.75.75 0 0 1 .04 1.06L6.773 8l3.527 3.74a.75.75 0 1 1-1.1 1.02l-4-4.25a.75.75 0 0 1 0-1.02l4-4.25a.75.75 0 0 1 1.06-.04z", fill: "currentColor" }) + ) +); +const forwardIcon = h( + "svg", + { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16" }, + h( + "g", + { fill: "none" }, + h("path", { d: "M5.74 3.2a.75.75 0 0 0-.04 1.06L9.227 8L5.7 11.74a.75.75 0 1 0 1.1 1.02l4-4.25a.75.75 0 0 0 0-1.02l-4-4.25a.75.75 0 0 0-1.06-.04z", fill: "currentColor" }) + ) +); +const NCarouselArrow = defineComponent({ + name: "CarouselArrow", + setup(props) { + const { mergedClsPrefixRef } = useConfig(props); + const { isVertical, isPrevDisabled, isNextDisabled, prev, next } = useCarouselContext(); + return { + mergedClsPrefix: mergedClsPrefixRef, + isVertical, + isPrevDisabled, + isNextDisabled, + prev, + next + }; + }, + render() { + const { mergedClsPrefix } = this; + return h( + "div", + { class: `${mergedClsPrefix}-carousel__arrow-group` }, + h("div", { class: [ + `${mergedClsPrefix}-carousel__arrow`, + this.isPrevDisabled() && `${mergedClsPrefix}-carousel__arrow--disabled` + ], role: "button", onClick: this.prev }, backwardIcon), + h("div", { class: [ + `${mergedClsPrefix}-carousel__arrow`, + this.isNextDisabled() && `${mergedClsPrefix}-carousel__arrow--disabled` + ], role: "button", onClick: this.next }, forwardIcon) + ); + } +}); +const CarouselItemName = "CarouselItem"; +const isCarouselItem = (child) => { + var _a; + return ((_a = child.type) === null || _a === void 0 ? void 0 : _a.name) === CarouselItemName; +}; +const NCarouselItem = defineComponent({ + name: CarouselItemName, + setup(props) { + const { mergedClsPrefixRef } = useConfig(props); + const NCarousel2 = useCarouselContext(camelCase$1(CarouselItemName), `n-${camelCase$1(CarouselItemName)}`); + const selfElRef = ref(); + const indexRef = computed(() => { + const { value: selfEl } = selfElRef; + return selfEl ? NCarousel2.getSlideIndex(selfEl) : -1; + }); + const isPrevRef = computed(() => NCarousel2.isPrev(indexRef.value)); + const isNextRef = computed(() => NCarousel2.isNext(indexRef.value)); + const isActiveRef = computed(() => NCarousel2.isActive(indexRef.value)); + const styleRef = computed(() => NCarousel2.getSlideStyle(indexRef.value)); + onMounted(() => { + NCarousel2.addSlide(selfElRef.value); + }); + onBeforeUnmount(() => { + NCarousel2.removeSlide(selfElRef.value); + }); + function handleClick(event) { + const { value: index } = indexRef; + if (index !== void 0) { + NCarousel2 === null || NCarousel2 === void 0 ? void 0 : NCarousel2.onCarouselItemClick(index, event); + } + } + return { + mergedClsPrefix: mergedClsPrefixRef, + selfElRef, + isPrev: isPrevRef, + isNext: isNextRef, + isActive: isActiveRef, + index: indexRef, + style: styleRef, + handleClick + }; + }, + render() { + var _a; + const { $slots: slots, mergedClsPrefix, isPrev, isNext, isActive, index, style: style2 } = this; + const className = [ + `${mergedClsPrefix}-carousel__slide`, + { + [`${mergedClsPrefix}-carousel__slide--current`]: isActive, + [`${mergedClsPrefix}-carousel__slide--prev`]: isPrev, + [`${mergedClsPrefix}-carousel__slide--next`]: isNext + } + ]; + return h("div", { + ref: "selfElRef", + class: className, + role: "option", + tabindex: "-1", + "data-index": index, + "aria-hidden": !isActive, + style: style2, + // We use ts-ignore for vue-tsc, since it seems to patch native event + // for vue components + // @ts-expect-error vue's tsx has type for capture events + onClickCapture: this.handleClick + }, (_a = slots.default) === null || _a === void 0 ? void 0 : _a.call(slots, { + isPrev, + isNext, + isActive, + index + })); + } +}); +const style$9 = cB("carousel", ` + position: relative; + width: 100%; + height: 100%; + touch-action: pan-y; + overflow: hidden; +`, [cE("slides", ` + display: flex; + width: 100%; + height: 100%; + transition-timing-function: var(--n-bezier); + transition-property: transform; + `, [cE("slide", ` + flex-shrink: 0; + position: relative; + width: 100%; + height: 100%; + outline: none; + overflow: hidden; + `, [c("> img", ` + display: block; + `)])]), cE("dots", ` + position: absolute; + display: flex; + flex-wrap: nowrap; + `, [cM("dot", [cE("dot", ` + height: var(--n-dot-size); + width: var(--n-dot-size); + background-color: var(--n-dot-color); + border-radius: 50%; + cursor: pointer; + transition: + box-shadow .3s var(--n-bezier), + background-color .3s var(--n-bezier); + outline: none; + `, [c("&:focus", ` + background-color: var(--n-dot-color-focus); + `), cM("active", ` + background-color: var(--n-dot-color-active); + `)])]), cM("line", [cE("dot", ` + border-radius: 9999px; + width: var(--n-dot-line-width); + height: 4px; + background-color: var(--n-dot-color); + cursor: pointer; + transition: + width .3s var(--n-bezier), + box-shadow .3s var(--n-bezier), + background-color .3s var(--n-bezier); + outline: none; + `, [c("&:focus", ` + background-color: var(--n-dot-color-focus); + `), cM("active", ` + width: var(--n-dot-line-width-active); + background-color: var(--n-dot-color-active); + `)])])]), cE("arrow", ` + transition: background-color .3s var(--n-bezier); + cursor: pointer; + height: 28px; + width: 28px; + display: flex; + align-items: center; + justify-content: center; + background-color: rgba(255, 255, 255, .2); + color: var(--n-arrow-color); + border-radius: 8px; + user-select: none; + -webkit-user-select: none; + font-size: 18px; + `, [c("svg", ` + height: 1em; + width: 1em; + `), c("&:hover", ` + background-color: rgba(255, 255, 255, .3); + `)]), cM("vertical", ` + touch-action: pan-x; + `, [cE("slides", ` + flex-direction: column; + `), cM("fade", [cE("slide", ` + top: 50%; + left: unset; + transform: translateY(-50%); + `)]), cM("card", [cE("slide", ` + top: 50%; + left: unset; + transform: translateY(-50%) translateZ(-400px); + `, [cM("current", ` + transform: translateY(-50%) translateZ(0); + `), cM("prev", ` + transform: translateY(-100%) translateZ(-200px); + `), cM("next", ` + transform: translateY(0%) translateZ(-200px); + `)])])]), cM("usercontrol", [cE("slides", [c(">", [c("div", ` + position: absolute; + top: 50%; + left: 50%; + width: 100%; + height: 100%; + transform: translate(-50%, -50%); + `)])])]), cM("left", [cE("dots", ` + transform: translateY(-50%); + top: 50%; + left: 12px; + flex-direction: column; + `, [cM("line", [cE("dot", ` + width: 4px; + height: var(--n-dot-line-width); + margin: 4px 0; + transition: + height .3s var(--n-bezier), + box-shadow .3s var(--n-bezier), + background-color .3s var(--n-bezier); + outline: none; + `, [cM("active", ` + height: var(--n-dot-line-width-active); + `)])])]), cE("dot", ` + margin: 4px 0; + `)]), cE("arrow-group", ` + position: absolute; + display: flex; + flex-wrap: nowrap; + `), cM("vertical", [cE("arrow", ` + transform: rotate(90deg); + `)]), cM("show-arrow", [cM("bottom", [cE("dots", ` + transform: translateX(0); + bottom: 18px; + left: 18px; + `)]), cM("top", [cE("dots", ` + transform: translateX(0); + top: 18px; + left: 18px; + `)]), cM("left", [cE("dots", ` + transform: translateX(0); + top: 18px; + left: 18px; + `)]), cM("right", [cE("dots", ` + transform: translateX(0); + top: 18px; + right: 18px; + `)])]), cM("left", [cE("arrow-group", ` + bottom: 12px; + left: 12px; + flex-direction: column; + `, [c("> *:first-child", ` + margin-bottom: 12px; + `)])]), cM("right", [cE("dots", ` + transform: translateY(-50%); + top: 50%; + right: 12px; + flex-direction: column; + `, [cM("line", [cE("dot", ` + width: 4px; + height: var(--n-dot-line-width); + margin: 4px 0; + transition: + height .3s var(--n-bezier), + box-shadow .3s var(--n-bezier), + background-color .3s var(--n-bezier); + outline: none; + `, [cM("active", ` + height: var(--n-dot-line-width-active); + `)])])]), cE("dot", ` + margin: 4px 0; + `), cE("arrow-group", ` + bottom: 12px; + right: 12px; + flex-direction: column; + `, [c("> *:first-child", ` + margin-bottom: 12px; + `)])]), cM("top", [cE("dots", ` + transform: translateX(-50%); + top: 12px; + left: 50%; + `, [cM("line", [cE("dot", ` + margin: 0 4px; + `)])]), cE("dot", ` + margin: 0 4px; + `), cE("arrow-group", ` + top: 12px; + right: 12px; + `, [c("> *:first-child", ` + margin-right: 12px; + `)])]), cM("bottom", [cE("dots", ` + transform: translateX(-50%); + bottom: 12px; + left: 50%; + `, [cM("line", [cE("dot", ` + margin: 0 4px; + `)])]), cE("dot", ` + margin: 0 4px; + `), cE("arrow-group", ` + bottom: 12px; + right: 12px; + `, [c("> *:first-child", ` + margin-right: 12px; + `)])]), cM("fade", [cE("slide", ` + position: absolute; + opacity: 0; + transition-property: opacity; + pointer-events: none; + `, [cM("current", ` + opacity: 1; + pointer-events: auto; + `)])]), cM("card", [cE("slides", ` + perspective: 1000px; + `), cE("slide", ` + position: absolute; + left: 50%; + opacity: 0; + transform: translateX(-50%) translateZ(-400px); + transition-property: opacity, transform; + `, [cM("current", ` + opacity: 1; + transform: translateX(-50%) translateZ(0); + z-index: 1; + `), cM("prev", ` + opacity: 0.4; + transform: translateX(-100%) translateZ(-200px); + `), cM("next", ` + opacity: 0.4; + transform: translateX(0%) translateZ(-200px); + `)])])]); +const transitionProperties = [ + "transitionDuration", + "transitionTimingFunction" +]; +const carouselProps = Object.assign(Object.assign({}, useTheme.props), { defaultIndex: { + type: Number, + default: 0 +}, currentIndex: Number, showArrow: Boolean, dotType: { + type: String, + default: "dot" +}, dotPlacement: { + type: String, + default: "bottom" +}, slidesPerView: { + type: [Number, String], + default: 1 +}, spaceBetween: { + type: Number, + default: 0 +}, centeredSlides: Boolean, direction: { + type: String, + default: "horizontal" +}, autoplay: Boolean, interval: { + type: Number, + default: 5e3 +}, loop: { + type: Boolean, + default: true +}, effect: { + type: String, + default: "slide" +}, showDots: { + type: Boolean, + default: true +}, trigger: { + type: String, + default: "click" +}, transitionStyle: { + type: Object, + default: () => ({ + transitionDuration: "300ms" + }) +}, transitionProps: Object, draggable: Boolean, prevSlideStyle: [Object, String], nextSlideStyle: [Object, String], touchable: { + type: Boolean, + default: true +}, mousewheel: Boolean, keyboard: Boolean, "onUpdate:currentIndex": Function, onUpdateCurrentIndex: Function }); +let globalDragging = false; +const NCarousel = defineComponent({ + name: "Carousel", + props: carouselProps, + setup(props) { + const { mergedClsPrefixRef, inlineThemeDisabled } = useConfig(props); + const selfElRef = ref(null); + const slidesElRef = ref(null); + const slideElsRef = ref([]); + const slideVNodesRef = { value: [] }; + const verticalRef = computed(() => props.direction === "vertical"); + const sizeAxisRef = computed(() => verticalRef.value ? "height" : "width"); + const spaceAxisRef = computed(() => verticalRef.value ? "bottom" : "right"); + const sequenceLayoutRef = computed(() => props.effect === "slide"); + const duplicatedableRef = computed( + // duplicate the copy operation in `slide` mode, + // because only its DOM is sequence layout + () => props.loop && props.slidesPerView === 1 && sequenceLayoutRef.value + ); + const userWantsControlRef = computed(() => props.effect === "custom"); + const displaySlidesPerViewRef = computed(() => !sequenceLayoutRef.value || props.centeredSlides ? 1 : props.slidesPerView); + const realSlidesPerViewRef = computed(() => userWantsControlRef.value ? 1 : props.slidesPerView); + const autoSlideSizeRef = computed(() => displaySlidesPerViewRef.value === "auto" || props.slidesPerView === "auto" && props.centeredSlides); + const perViewSizeRef = ref({ width: 0, height: 0 }); + const slideSizesRef = computed(() => { + const { value: slidesEls } = slideElsRef; + if (!slidesEls.length) + return []; + const { value: autoSlideSize } = autoSlideSizeRef; + if (autoSlideSize) { + return slidesEls.map((slide) => calculateSize(slide)); + } + const { value: slidesPerView } = realSlidesPerViewRef; + const { value: perViewSize } = perViewSizeRef; + const { value: axis } = sizeAxisRef; + let axisSize = perViewSize[axis]; + if (slidesPerView !== "auto") { + const { spaceBetween } = props; + const remaining = axisSize - (slidesPerView - 1) * spaceBetween; + const percentage = 1 / Math.max(1, slidesPerView); + axisSize = remaining * percentage; + } + const slideSize = Object.assign(Object.assign({}, perViewSize), { [axis]: axisSize }); + return slidesEls.map(() => slideSize); + }); + const slideTranlatesRef = computed(() => { + const { value: slideSizes } = slideSizesRef; + if (!slideSizes.length) + return []; + const { centeredSlides, spaceBetween } = props; + const { value: axis } = sizeAxisRef; + const { [axis]: perViewSize } = perViewSizeRef.value; + let previousTranslate2 = 0; + return slideSizes.map(({ [axis]: slideSize }) => { + let translate = previousTranslate2; + if (centeredSlides) { + translate += (slideSize - perViewSize) / 2; + } + previousTranslate2 += slideSize + spaceBetween; + return translate; + }); + }); + const isMountedRef = ref(false); + const transitionStyleRef = computed(() => { + const { transitionStyle } = props; + return transitionStyle ? keep(transitionStyle, transitionProperties) : {}; + }); + const speedRef = computed(() => userWantsControlRef.value ? 0 : resolveSpeed(transitionStyleRef.value.transitionDuration)); + const slideStylesRef = computed(() => { + const { value: slidesEls } = slideElsRef; + if (!slidesEls.length) + return []; + const useComputedSize = !(autoSlideSizeRef.value || realSlidesPerViewRef.value === 1); + const getSlideSize = (index) => { + if (useComputedSize) { + const { value: axis } = sizeAxisRef; + return { + [axis]: `${slideSizesRef.value[index][axis]}px` + }; + } + }; + if (userWantsControlRef.value) { + return slidesEls.map((_, i) => getSlideSize(i)); + } + const { effect, spaceBetween } = props; + const { value: spaceAxis } = spaceAxisRef; + return slidesEls.reduce((styles, _, i) => { + const style2 = Object.assign(Object.assign({}, getSlideSize(i)), { [`margin-${spaceAxis}`]: `${spaceBetween}px` }); + styles.push(style2); + if (isMountedRef.value && (effect === "fade" || effect === "card")) { + Object.assign(style2, transitionStyleRef.value); + } + return styles; + }, []); + }); + const totalViewRef = computed(() => { + const { value: slidesPerView } = displaySlidesPerViewRef; + const { length: totalSlides } = slideElsRef.value; + if (slidesPerView !== "auto") { + return Math.max(totalSlides - slidesPerView, 0) + 1; + } else { + const { value: slideSizes } = slideSizesRef; + const { length } = slideSizes; + if (!length) + return totalSlides; + const { value: translates } = slideTranlatesRef; + const { value: axis } = sizeAxisRef; + const perViewSize = perViewSizeRef.value[axis]; + let lastViewSize = slideSizes[slideSizes.length - 1][axis]; + let i = length; + while (i > 1 && lastViewSize < perViewSize) { + i--; + lastViewSize += translates[i] - translates[i - 1]; + } + return clampValue(i + 1, 1, length); + } + }); + const displayTotalViewRef = computed(() => getDisplayTotalView(totalViewRef.value, duplicatedableRef.value)); + const defaultRealIndex = getRealIndex(props.defaultIndex, duplicatedableRef.value); + const uncontrolledDisplayIndexRef = ref(getDisplayIndex(defaultRealIndex, totalViewRef.value, duplicatedableRef.value)); + const mergedDisplayIndexRef = useMergedState(toRef(props, "currentIndex"), uncontrolledDisplayIndexRef); + const realIndexRef = computed(() => getRealIndex(mergedDisplayIndexRef.value, duplicatedableRef.value)); + function toRealIndex(index) { + var _a, _b; + index = clampValue(index, 0, totalViewRef.value - 1); + const displayIndex = getDisplayIndex(index, totalViewRef.value, duplicatedableRef.value); + const { value: lastDisplayIndex } = mergedDisplayIndexRef; + if (displayIndex !== mergedDisplayIndexRef.value) { + uncontrolledDisplayIndexRef.value = displayIndex; + (_a = props["onUpdate:currentIndex"]) === null || _a === void 0 ? void 0 : _a.call(props, displayIndex, lastDisplayIndex); + (_b = props.onUpdateCurrentIndex) === null || _b === void 0 ? void 0 : _b.call(props, displayIndex, lastDisplayIndex); + } + } + function getRealPrevIndex(index = realIndexRef.value) { + return getPrevIndex(index, totalViewRef.value, props.loop); + } + function getRealNextIndex(index = realIndexRef.value) { + return getNextIndex(index, totalViewRef.value, props.loop); + } + function isRealPrev(slideOrIndex) { + const index = getSlideIndex(slideOrIndex); + return index !== null && getRealPrevIndex() === index; + } + function isRealNext(slideOrIndex) { + const index = getSlideIndex(slideOrIndex); + return index !== null && getRealNextIndex() === index; + } + function isRealActive(slideOrIndex) { + return realIndexRef.value === getSlideIndex(slideOrIndex); + } + function isDisplayActive(index) { + return mergedDisplayIndexRef.value === index; + } + function isPrevDisabled() { + return getRealPrevIndex() === null; + } + function isNextDisabled() { + return getRealNextIndex() === null; + } + function to(index) { + const realIndex = clampValue(getRealIndex(index, duplicatedableRef.value), 0, totalViewRef.value); + if (index !== mergedDisplayIndexRef.value || realIndex !== realIndexRef.value) { + toRealIndex(realIndex); + } + } + function prev() { + const prevIndex = getRealPrevIndex(); + if (prevIndex !== null) + toRealIndex(prevIndex); + } + function next() { + const nextIndex = getRealNextIndex(); + if (nextIndex !== null) + toRealIndex(nextIndex); + } + function prevIfSlideTransitionEnd() { + if (!inTransition || !duplicatedableRef.value) + prev(); + } + function nextIfSlideTransitionEnd() { + if (!inTransition || !duplicatedableRef.value) + next(); + } + let inTransition = false; + let previousTranslate = 0; + const translateStyleRef = ref({}); + function updateTranslate(translate, speed = 0) { + translateStyleRef.value = Object.assign({}, transitionStyleRef.value, { + transform: verticalRef.value ? `translateY(${-translate}px)` : `translateX(${-translate}px)`, + transitionDuration: `${speed}ms` + }); + } + function fixTranslate(speed = 0) { + if (sequenceLayoutRef.value) { + translateTo(realIndexRef.value, speed); + } else if (previousTranslate !== 0) { + if (!inTransition && speed > 0) { + inTransition = true; + } + updateTranslate(previousTranslate = 0, speed); + } + } + function translateTo(index, speed) { + const translate = getTranslate(index); + if (translate !== previousTranslate && speed > 0) { + inTransition = true; + } + previousTranslate = getTranslate(realIndexRef.value); + updateTranslate(translate, speed); + } + function getTranslate(index) { + let translate; + if (index >= totalViewRef.value - 1) { + translate = getLastViewTranslate(); + } else { + translate = slideTranlatesRef.value[index] || 0; + } + return translate; + } + function getLastViewTranslate() { + if (displaySlidesPerViewRef.value === "auto") { + const { value: axis } = sizeAxisRef; + const { [axis]: perViewSize } = perViewSizeRef.value; + const { value: translates } = slideTranlatesRef; + const lastTranslate = translates[translates.length - 1]; + let overallSize; + if (lastTranslate === void 0) { + overallSize = perViewSize; + } else { + const { value: slideSizes } = slideSizesRef; + overallSize = lastTranslate + slideSizes[slideSizes.length - 1][axis]; + } + return overallSize - perViewSize; + } else { + const { value: translates } = slideTranlatesRef; + return translates[totalViewRef.value - 1] || 0; + } + } + const carouselContext = { + currentIndexRef: mergedDisplayIndexRef, + to, + prev: prevIfSlideTransitionEnd, + next: nextIfSlideTransitionEnd, + isVertical: () => verticalRef.value, + isHorizontal: () => !verticalRef.value, + isPrev: isRealPrev, + isNext: isRealNext, + isActive: isRealActive, + isPrevDisabled, + isNextDisabled, + getSlideIndex, + getSlideStyle, + addSlide, + removeSlide, + onCarouselItemClick + }; + provideCarouselContext(carouselContext); + function addSlide(slide) { + if (!slide) + return; + slideElsRef.value.push(slide); + } + function removeSlide(slide) { + if (!slide) + return; + const index = getSlideIndex(slide); + if (index !== -1) { + slideElsRef.value.splice(index, 1); + } + } + function getSlideIndex(slideOrIndex) { + return typeof slideOrIndex === "number" ? slideOrIndex : slideOrIndex ? slideElsRef.value.indexOf(slideOrIndex) : -1; + } + function getSlideStyle(slide) { + const index = getSlideIndex(slide); + if (index !== -1) { + const styles = [slideStylesRef.value[index]]; + const isPrev = carouselContext.isPrev(index); + const isNext = carouselContext.isNext(index); + if (isPrev) { + styles.push(props.prevSlideStyle || ""); + } + if (isNext) { + styles.push(props.nextSlideStyle || ""); + } + return normalizeStyle(styles); + } + } + function onCarouselItemClick(index, event) { + let allowClick = !inTransition && !dragging && !isEffectiveDrag; + if (props.effect === "card" && allowClick && !isRealActive(index)) { + to(index); + allowClick = false; + } + if (!allowClick) { + event.preventDefault(); + event.stopPropagation(); + } + } + let autoplayTimer = null; + function stopAutoplay() { + if (autoplayTimer) { + clearInterval(autoplayTimer); + autoplayTimer = null; + } + } + function resetAutoplay() { + stopAutoplay(); + const disabled = !props.autoplay || displayTotalViewRef.value < 2; + if (!disabled) { + autoplayTimer = window.setInterval(next, props.interval); + } + } + let dragStartX = 0; + let dragStartY = 0; + let dragOffset = 0; + let dragStartTime = 0; + let dragging = false; + let isEffectiveDrag = false; + function handleTouchstart(event) { + var _a; + if (globalDragging) + return; + if (!((_a = slidesElRef.value) === null || _a === void 0 ? void 0 : _a.contains(getPreciseEventTarget(event)))) { + return; + } + globalDragging = true; + dragging = true; + isEffectiveDrag = false; + dragStartTime = Date.now(); + stopAutoplay(); + if (event.type !== "touchstart" && !event.target.isContentEditable) { + event.preventDefault(); + } + const touchEvent = isTouchEvent(event) ? event.touches[0] : event; + if (verticalRef.value) { + dragStartY = touchEvent.clientY; + } else { + dragStartX = touchEvent.clientX; + } + if (props.touchable) { + on("touchmove", document, handleTouchmove, { passive: true }); + on("touchend", document, handleTouchend); + on("touchcancel", document, handleTouchend); + } + if (props.draggable) { + on("mousemove", document, handleTouchmove); + on("mouseup", document, handleTouchend); + } + } + function handleTouchmove(event) { + const { value: vertical } = verticalRef; + const { value: axis } = sizeAxisRef; + const touchEvent = isTouchEvent(event) ? event.touches[0] : event; + const offset = vertical ? touchEvent.clientY - dragStartY : touchEvent.clientX - dragStartX; + const perViewSize = perViewSizeRef.value[axis]; + dragOffset = clampValue(offset, -perViewSize, perViewSize); + if (event.cancelable) { + event.preventDefault(); + } + if (sequenceLayoutRef.value) { + updateTranslate(previousTranslate - dragOffset, 0); + } + } + function handleTouchend() { + const { value: realIndex } = realIndexRef; + let currentIndex = realIndex; + if (!inTransition && dragOffset !== 0 && sequenceLayoutRef.value) { + const currentTranslate = previousTranslate - dragOffset; + const translates = [ + ...slideTranlatesRef.value.slice(0, totalViewRef.value - 1), + getLastViewTranslate() + ]; + let prevOffset = null; + for (let i = 0; i < translates.length; i++) { + const offset = Math.abs(translates[i] - currentTranslate); + if (prevOffset !== null && prevOffset < offset) { + break; + } + prevOffset = offset; + currentIndex = i; + } + } + if (currentIndex === realIndex) { + const timeElapsed = Date.now() - dragStartTime; + const { value: axis } = sizeAxisRef; + const perViewSize = perViewSizeRef.value[axis]; + if (dragOffset > perViewSize / 2 || dragOffset / timeElapsed > 0.4) { + currentIndex = getRealPrevIndex(realIndex); + } else if (dragOffset < -perViewSize / 2 || dragOffset / timeElapsed < -0.4) { + currentIndex = getRealNextIndex(realIndex); + } + } + if (currentIndex !== null && currentIndex !== realIndex) { + isEffectiveDrag = true; + toRealIndex(currentIndex); + void nextTick(() => { + if (!duplicatedableRef.value || uncontrolledDisplayIndexRef.value !== mergedDisplayIndexRef.value) { + fixTranslate(speedRef.value); + } + }); + } else { + fixTranslate(speedRef.value); + } + resetDragStatus(); + resetAutoplay(); + } + function resetDragStatus() { + if (dragging) { + globalDragging = false; + } + dragging = false; + dragStartX = 0; + dragStartY = 0; + dragOffset = 0; + dragStartTime = 0; + off("touchmove", document, handleTouchmove); + off("touchend", document, handleTouchend); + off("touchcancel", document, handleTouchend); + off("mousemove", document, handleTouchmove); + off("mouseup", document, handleTouchend); + } + function handleTransitionEnd() { + if (sequenceLayoutRef.value && inTransition) { + const { value: realIndex } = realIndexRef; + translateTo(realIndex, 0); + } else { + resetAutoplay(); + } + if (sequenceLayoutRef.value) { + translateStyleRef.value.transitionDuration = "0ms"; + } + inTransition = false; + } + function handleMousewheel(event) { + event.preventDefault(); + if (inTransition) + return; + let { deltaX, deltaY } = event; + if (event.shiftKey && !deltaX) { + deltaX = deltaY; + } + const prevMultiplier = -1; + const nextMultiplier = 1; + const m = (deltaX || deltaY) > 0 ? nextMultiplier : prevMultiplier; + let rx = 0; + let ry = 0; + if (verticalRef.value) { + ry = m; + } else { + rx = m; + } + const responseStep = 10; + if (ry * deltaY >= responseStep || rx * deltaX >= responseStep) { + if (m === nextMultiplier && !isNextDisabled()) { + next(); + } else if (m === prevMultiplier && !isPrevDisabled()) { + prev(); + } + } + } + function handleResize() { + perViewSizeRef.value = calculateSize(selfElRef.value, true); + resetAutoplay(); + } + function handleSlideResize() { + var _a, _b; + if (autoSlideSizeRef.value) { + (_b = (_a = slideSizesRef.effect).scheduler) === null || _b === void 0 ? void 0 : _b.call(_a); + slideSizesRef.effect.run(); + } + } + function handleMouseenter() { + if (props.autoplay) { + stopAutoplay(); + } + } + function handleMouseleave() { + if (props.autoplay) { + resetAutoplay(); + } + } + onMounted(() => { + watchEffect(resetAutoplay); + requestAnimationFrame(() => isMountedRef.value = true); + }); + onBeforeUnmount(() => { + resetDragStatus(); + stopAutoplay(); + }); + onUpdated(() => { + const { value: slidesEls } = slideElsRef; + const { value: slideVNodes } = slideVNodesRef; + const indexMap2 = /* @__PURE__ */ new Map(); + const getDisplayIndex2 = (el) => ( + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + indexMap2.has(el) ? indexMap2.get(el) : -1 + ); + let isChanged = false; + for (let i = 0; i < slidesEls.length; i++) { + const index = slideVNodes.findIndex((v) => v.el === slidesEls[i]); + if (index !== i) { + isChanged = true; + } + indexMap2.set(slidesEls[i], index); + } + if (isChanged) { + slidesEls.sort((a, b) => getDisplayIndex2(a) - getDisplayIndex2(b)); + } + }); + watch(realIndexRef, (realIndex, lastRealIndex) => { + if (realIndex === lastRealIndex) + return; + resetAutoplay(); + if (sequenceLayoutRef.value) { + if (duplicatedableRef.value && displayTotalViewRef.value > 2) { + const { value: length } = totalViewRef; + if (realIndex === length - 2 && lastRealIndex === 1) { + realIndex = 0; + } else if (realIndex === 1 && lastRealIndex === length - 2) { + realIndex = length - 1; + } + } + translateTo(realIndex, speedRef.value); + } else { + fixTranslate(); + } + }, { immediate: true }); + watch([duplicatedableRef, displaySlidesPerViewRef], () => void nextTick(() => { + toRealIndex(realIndexRef.value); + })); + watch(slideTranlatesRef, () => { + sequenceLayoutRef.value && fixTranslate(); + }, { + deep: true + }); + watch(sequenceLayoutRef, (value) => { + if (!value) { + inTransition = false; + updateTranslate(previousTranslate = 0); + } else { + fixTranslate(); + } + }); + const slidesControlListenersRef = computed(() => { + return { + onTouchstartPassive: props.touchable ? handleTouchstart : void 0, + onMousedown: props.draggable ? handleTouchstart : void 0, + onWheel: props.mousewheel ? handleMousewheel : void 0 + }; + }); + const arrowSlotPropsRef = computed(() => Object.assign(Object.assign({}, keep(carouselContext, [ + "to", + "prev", + "next", + "isPrevDisabled", + "isNextDisabled" + ])), { total: displayTotalViewRef.value, currentIndex: mergedDisplayIndexRef.value })); + const dotSlotPropsRef = computed(() => ({ + total: displayTotalViewRef.value, + currentIndex: mergedDisplayIndexRef.value, + to: carouselContext.to + })); + const caroulseExposedMethod = { + getCurrentIndex: () => mergedDisplayIndexRef.value, + to, + prev, + next + }; + const themeRef = useTheme("Carousel", "-carousel", style$9, carouselLight, props, mergedClsPrefixRef); + const cssVarsRef = computed(() => { + const { common: { cubicBezierEaseInOut }, self: { dotSize, dotColor, dotColorActive, dotColorFocus, dotLineWidth, dotLineWidthActive, arrowColor } } = themeRef.value; + return { + "--n-bezier": cubicBezierEaseInOut, + "--n-dot-color": dotColor, + "--n-dot-color-focus": dotColorFocus, + "--n-dot-color-active": dotColorActive, + "--n-dot-size": dotSize, + "--n-dot-line-width": dotLineWidth, + "--n-dot-line-width-active": dotLineWidthActive, + "--n-arrow-color": arrowColor + }; + }); + const themeClassHandle = inlineThemeDisabled ? useThemeClass("carousel", void 0, cssVarsRef, props) : void 0; + return Object.assign(Object.assign({ + mergedClsPrefix: mergedClsPrefixRef, + selfElRef, + slidesElRef, + slideVNodes: slideVNodesRef, + duplicatedable: duplicatedableRef, + userWantsControl: userWantsControlRef, + autoSlideSize: autoSlideSizeRef, + displayIndex: mergedDisplayIndexRef, + realIndex: realIndexRef, + slideStyles: slideStylesRef, + translateStyle: translateStyleRef, + slidesControlListeners: slidesControlListenersRef, + handleTransitionEnd, + handleResize, + handleSlideResize, + handleMouseenter, + handleMouseleave, + isActive: isDisplayActive, + arrowSlotProps: arrowSlotPropsRef, + dotSlotProps: dotSlotPropsRef + }, caroulseExposedMethod), { cssVars: inlineThemeDisabled ? void 0 : cssVarsRef, themeClass: themeClassHandle === null || themeClassHandle === void 0 ? void 0 : themeClassHandle.themeClass, onRender: themeClassHandle === null || themeClassHandle === void 0 ? void 0 : themeClassHandle.onRender }); + }, + render() { + var _a; + const { mergedClsPrefix, showArrow, userWantsControl, slideStyles, dotType, dotPlacement, slidesControlListeners, transitionProps = {}, arrowSlotProps, dotSlotProps, $slots: { default: defaultSlot, dots: dotsSlot, arrow: arrowSlot } } = this; + const children = defaultSlot && flatten$1(defaultSlot()) || []; + let slides = filterCarouselItem(children); + if (!slides.length) { + slides = children.map((ch) => h(NCarouselItem, null, { + default: () => cloneVNode(ch) + })); + } + if (this.duplicatedable) { + slides = addDuplicateSlides(slides); + } + this.slideVNodes.value = slides; + if (this.autoSlideSize) { + slides = slides.map((slide) => h(VResizeObserver, { onResize: this.handleSlideResize }, { + default: () => slide + })); + } + (_a = this.onRender) === null || _a === void 0 ? void 0 : _a.call(this); + return h( + "div", + Object.assign({ ref: "selfElRef", class: [ + this.themeClass, + `${mergedClsPrefix}-carousel`, + this.direction === "vertical" && `${mergedClsPrefix}-carousel--vertical`, + this.showArrow && `${mergedClsPrefix}-carousel--show-arrow`, + `${mergedClsPrefix}-carousel--${dotPlacement}`, + `${mergedClsPrefix}-carousel--${this.direction}`, + `${mergedClsPrefix}-carousel--${this.effect}`, + userWantsControl && `${mergedClsPrefix}-carousel--usercontrol` + ], style: this.cssVars }, slidesControlListeners, { onMouseenter: this.handleMouseenter, onMouseleave: this.handleMouseleave }), + h(VResizeObserver, { onResize: this.handleResize }, { + default: () => h("div", { ref: "slidesElRef", class: `${mergedClsPrefix}-carousel__slides`, role: "listbox", style: this.translateStyle, onTransitionend: this.handleTransitionEnd }, userWantsControl ? slides.map((slide, i) => h("div", { style: slideStyles[i], key: i }, withDirectives(h(Transition, Object.assign({}, transitionProps), { + default: () => slide + }), [[vShow, this.isActive(i)]]))) : slides) + }), + this.showDots && dotSlotProps.total > 1 && resolveSlotWithProps(dotsSlot, dotSlotProps, () => [ + h(NCarouselDots, { key: dotType + dotPlacement, total: dotSlotProps.total, currentIndex: dotSlotProps.currentIndex, dotType, trigger: this.trigger, keyboard: this.keyboard }) + ]), + showArrow && resolveSlotWithProps(arrowSlot, arrowSlotProps, () => [ + h(NCarouselArrow, null) + ]) ); } }); -const CancelIcon = replaceable("cancel", h( - "svg", - { viewBox: "0 0 16 16", version: "1.1", xmlns: "http://www.w3.org/2000/svg" }, - h( - "g", - { stroke: "none", "stroke-width": "1", fill: "none", "fill-rule": "evenodd" }, - h( - "g", - { fill: "currentColor", "fill-rule": "nonzero" }, - h("path", { d: "M2.58859116,2.7156945 L2.64644661,2.64644661 C2.82001296,2.47288026 3.08943736,2.45359511 3.2843055,2.58859116 L3.35355339,2.64644661 L8,7.293 L12.6464466,2.64644661 C12.8417088,2.45118446 13.1582912,2.45118446 13.3535534,2.64644661 C13.5488155,2.84170876 13.5488155,3.15829124 13.3535534,3.35355339 L8.707,8 L13.3535534,12.6464466 C13.5271197,12.820013 13.5464049,13.0894374 13.4114088,13.2843055 L13.3535534,13.3535534 C13.179987,13.5271197 12.9105626,13.5464049 12.7156945,13.4114088 L12.6464466,13.3535534 L8,8.707 L3.35355339,13.3535534 C3.15829124,13.5488155 2.84170876,13.5488155 2.64644661,13.3535534 C2.45118446,13.1582912 2.45118446,12.8417088 2.64644661,12.6464466 L7.293,8 L2.64644661,3.35355339 C2.47288026,3.17998704 2.45359511,2.91056264 2.58859116,2.7156945 L2.64644661,2.64644661 L2.58859116,2.7156945 Z" }) - ) - ) -)); -const RetryIcon = replaceable("retry", h( - "svg", - { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 512 512" }, - h("path", { d: "M320,146s24.36-12-64-12A160,160,0,1,0,416,294", style: "fill: none; stroke: currentcolor; stroke-linecap: round; stroke-miterlimit: 10; stroke-width: 32px;" }), - h("polyline", { points: "256 58 336 138 256 218", style: "fill: none; stroke: currentcolor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 32px;" }) -)); +function filterCarouselItem(vnodes) { + return vnodes.reduce((carouselItems, vnode) => { + if (isCarouselItem(vnode)) { + carouselItems.push(vnode); + } + return carouselItems; + }, []); +} const CheckMark = h( "svg", { viewBox: "0 0 64 64", class: "check-icon" }, @@ -335,7 +1579,7 @@ const NCheckboxGroup = defineComponent({ return h("div", { class: `${this.mergedClsPrefix}-checkbox-group`, role: "group" }, this.$slots); } }); -const style$7 = c([ +const style$8 = c([ cB("checkbox", ` line-height: var(--n-label-line-height); font-size: var(--n-font-size); @@ -562,7 +1806,7 @@ const NCheckbox = defineComponent({ return mergedCheckedRef.value === props.checkedValue; } }); - const themeRef = useTheme("Checkbox", "-checkbox", style$7, checkboxLight, props, mergedClsPrefixRef); + const themeRef = useTheme("Checkbox", "-checkbox", style$8, checkboxLight, props, mergedClsPrefixRef); function toggle(e) { if (NCheckboxGroup2 && props.value !== void 0) { NCheckboxGroup2.toggleCheckbox(!renderedCheckedRef.value, props.value); @@ -701,7 +1945,7 @@ const NCheckbox = defineComponent({ } }); const popselectInjectionKey = createInjectionKey("n-popselect"); -const style$6 = cB("popselect-menu", ` +const style$7 = cB("popselect-menu", ` box-shadow: var(--n-menu-box-shadow); `); const panelProps = { @@ -741,7 +1985,7 @@ const NPopselectPanel = defineComponent({ setup(props) { const NPopselect2 = inject(popselectInjectionKey); const { mergedClsPrefixRef, inlineThemeDisabled } = useConfig(props); - const themeRef = useTheme("Popselect", "-pop-select", style$6, popselectLight, NPopselect2.props, mergedClsPrefixRef); + const themeRef = useTheme("Popselect", "-pop-select", style$7, popselectLight, NPopselect2.props, mergedClsPrefixRef); const treeMateRef = computed(() => { return createTreeMate(props.options, createTmOptions("value", "children")); }); @@ -1070,7 +2314,7 @@ const hoverStyleChildren = [cM("button", ` border: var(--n-button-border-hover); color: var(--n-button-icon-color-hover); `)]; -const style$5 = cB("pagination", ` +const style$6 = cB("pagination", ` display: flex; vertical-align: middle; font-size: var(--n-item-font-size); @@ -1215,7 +2459,7 @@ const NPagination = defineComponent({ props: paginationProps, setup(props) { const { mergedComponentPropsRef, mergedClsPrefixRef, inlineThemeDisabled, mergedRtlRef } = useConfig(props); - const themeRef = useTheme("Pagination", "-pagination", style$5, paginationLight, props, mergedClsPrefixRef); + const themeRef = useTheme("Pagination", "-pagination", style$6, paginationLight, props, mergedClsPrefixRef); const { localeRef } = useLocale("Pagination"); const selfRef = ref(null); const uncontrolledPageRef = ref(props.defaultPage); @@ -1706,7 +2950,7 @@ const NPagination = defineComponent({ ); } }); -const style$4 = cB("ellipsis", { +const style$5 = cB("ellipsis", { overflow: "hidden" }, [cNotM("line-clamp", ` white-space: nowrap; @@ -1735,7 +2979,7 @@ const NEllipsis = defineComponent({ props: ellipsisProps, setup(props, { slots, attrs }) { const { mergedClsPrefixRef } = useConfig(props); - const mergedTheme = useTheme("Ellipsis", "-ellipsis", style$4, ellipsisLight, props, mergedClsPrefixRef); + const mergedTheme = useTheme("Ellipsis", "-ellipsis", style$5, ellipsisLight, props, mergedClsPrefixRef); const triggerRef = ref(null); const triggerInnerRef = ref(null); const tooltipRef = ref(null); @@ -1875,8 +3119,8 @@ const RenderSorter = defineComponent({ } }, render() { - const { render: render5, order } = this; - return render5({ + const { render: render4, order } = this; + return render4({ order }); } @@ -2052,8 +3296,8 @@ const RenderFilter = defineComponent({ } }, render() { - const { render: render5, active, show } = this; - return render5({ + const { render: render4, active, show } = this; + return render4({ active, show }); @@ -2180,7 +3424,7 @@ function setup(props) { handleRadioInputFocus }; } -const style$3 = cB("radio", ` +const style$4 = cB("radio", ` line-height: var(--n-label-line-height); outline: none; position: relative; @@ -2273,7 +3517,7 @@ const NRadio = defineComponent({ props: Object.assign(Object.assign({}, useTheme.props), radioProps), setup(props) { const radio = setup(props); - const themeRef = useTheme("Radio", "-radio", style$3, radioLight, props, radio.mergedClsPrefix); + const themeRef = useTheme("Radio", "-radio", style$4, radioLight, props, radio.mergedClsPrefix); const cssVarsRef = computed(() => { const { mergedSize: { value: size } } = radio; const { common: { cubicBezierEaseInOut }, self: { boxShadow, boxShadowActive, boxShadowDisabled, boxShadowFocus, boxShadowHover, color, colorDisabled, colorActive, textColor, textColorDisabled, dotColorActive, dotColorDisabled, labelPadding, labelLineHeight, labelFontWeight, [createKey("fontSize", size)]: fontSize, [createKey("radioSize", size)]: radioSize } } = themeRef.value; @@ -2341,7 +3585,7 @@ const NRadio = defineComponent({ ); } }); -const style$2 = cB("radio-group", ` +const style$3 = cB("radio-group", ` display: inline-block; font-size: var(--n-font-size); `, [cE("splitor", ` @@ -2492,7 +3736,7 @@ const NRadioGroup = defineComponent({ const selfElRef = ref(null); const { mergedSizeRef, mergedDisabledRef, nTriggerFormChange, nTriggerFormInput, nTriggerFormBlur, nTriggerFormFocus } = useFormItem(props); const { mergedClsPrefixRef, inlineThemeDisabled, mergedRtlRef } = useConfig(props); - const themeRef = useTheme("Radio", "-radio-group", style$2, radioLight, props, mergedClsPrefixRef); + const themeRef = useTheme("Radio", "-radio-group", style$3, radioLight, props, mergedClsPrefixRef); const uncontrolledValueRef = ref(props.defaultValue); const controlledValueRef = toRef(props, "value"); const mergedValueRef = useMergedState(controlledValueRef, uncontrolledValueRef); @@ -3270,9 +4514,9 @@ const Cell = defineComponent({ render() { const { isSummary, column, row, renderCell } = this; let cell; - const { render: render5, key, ellipsis } = column; - if (render5 && !isSummary) { - cell = render5(row, this.index); + const { render: render4, key, ellipsis } = column; + if (render4 && !isSummary) { + cell = render4(row, this.index); } else { if (isSummary) { cell = row[key].value; @@ -5030,7 +6274,7 @@ function useExpand(props, treeMateRef) { }; } const fixedColumnStyle = createFixedColumnStyle(); -const style$1 = c([cB("data-table", ` +const style$2 = c([cB("data-table", ` width: 100%; font-size: var(--n-font-size); display: flex; @@ -5432,7 +6676,7 @@ const NDataTable = defineComponent({ return bottomBordered; return true; }); - const themeRef = useTheme("DataTable", "-data-table", style$1, dataTableLight, props, mergedClsPrefixRef); + const themeRef = useTheme("DataTable", "-data-table", style$2, dataTableLight, props, mergedClsPrefixRef); const bodyWidthRef = ref(null); const scrollPartRef = ref("body"); onDeactivated(() => { @@ -5657,6 +6901,205 @@ const NDataTable = defineComponent({ ); } }); +function useLoadingBar() { + const loadingBar = inject(loadingBarApiInjectionKey, null); + if (loadingBar === null) { + throwError("use-loading-bar", "No outer founded."); + } + return loadingBar; +} +const StarIcon = h( + "svg", + { viewBox: "0 0 512 512" }, + h("path", { d: "M394 480a16 16 0 01-9.39-3L256 383.76 127.39 477a16 16 0 01-24.55-18.08L153 310.35 23 221.2a16 16 0 019-29.2h160.38l48.4-148.95a16 16 0 0130.44 0l48.4 149H480a16 16 0 019.05 29.2L359 310.35l50.13 148.53A16 16 0 01394 480z" }) +); +const style$1 = cB("rate", { + display: "inline-flex", + flexWrap: "nowrap" +}, [c("&:hover", [cE("item", ` + transition: + transform .1s var(--n-bezier), + color .3s var(--n-bezier); + `)]), cE("item", ` + position: relative; + display: flex; + transition: + transform .1s var(--n-bezier), + color .3s var(--n-bezier); + transform: scale(1); + font-size: var(--n-item-size); + color: var(--n-item-color); + `, [c("&:not(:first-child)", ` + margin-left: 6px; + `), cM("active", ` + color: var(--n-item-color-active); + `)]), cNotM("readonly", ` + cursor: pointer; + `, [cE("item", [c("&:hover", ` + transform: scale(1.05); + `), c("&:active", ` + transform: scale(0.96); + `)])]), cE("half", ` + display: flex; + transition: inherit; + position: absolute; + top: 0; + left: 0; + bottom: 0; + width: 50%; + overflow: hidden; + color: rgba(255, 255, 255, 0); + `, [cM("active", ` + color: var(--n-item-color-active); + `)])]); +const rateProps = Object.assign(Object.assign({}, useTheme.props), { allowHalf: Boolean, count: { + type: Number, + default: 5 +}, value: Number, defaultValue: { + type: Number, + default: null +}, readonly: Boolean, size: { + type: [String, Number], + default: "medium" +}, clearable: Boolean, color: String, onClear: Function, "onUpdate:value": [Function, Array], onUpdateValue: [Function, Array] }); +const NRate = defineComponent({ + name: "Rate", + props: rateProps, + setup(props) { + const { mergedClsPrefixRef, inlineThemeDisabled } = useConfig(props); + const themeRef = useTheme("Rate", "-rate", style$1, rateLight, props, mergedClsPrefixRef); + const controlledValueRef = toRef(props, "value"); + const uncontrolledValueRef = ref(props.defaultValue); + const hoverIndexRef = ref(null); + const formItem = useFormItem(props); + const mergedValue = useMergedState(controlledValueRef, uncontrolledValueRef); + function doUpdateValue(value) { + const { "onUpdate:value": _onUpdateValue, onUpdateValue } = props; + const { nTriggerFormChange, nTriggerFormInput } = formItem; + if (_onUpdateValue) { + call(_onUpdateValue, value); + } + if (onUpdateValue) { + call(onUpdateValue, value); + } + uncontrolledValueRef.value = value; + nTriggerFormChange(); + nTriggerFormInput(); + } + function getDerivedValue(index, e) { + if (props.allowHalf) { + if (e.offsetX >= Math.floor(e.currentTarget.offsetWidth / 2)) { + return index + 1; + } else { + return index + 0.5; + } + } else { + return index + 1; + } + } + let cleared = false; + function handleMouseMove(index, e) { + if (cleared) + return; + hoverIndexRef.value = getDerivedValue(index, e); + } + function handleMouseLeave() { + hoverIndexRef.value = null; + } + function handleClick(index, e) { + var _a; + const { clearable } = props; + const derivedValue = getDerivedValue(index, e); + if (clearable && derivedValue === mergedValue.value) { + cleared = true; + (_a = props.onClear) === null || _a === void 0 ? void 0 : _a.call(props); + hoverIndexRef.value = null; + doUpdateValue(null); + } else { + doUpdateValue(derivedValue); + } + } + function handleMouseEnterSomeStar() { + cleared = false; + } + const mergedSizeRef = computed(() => { + const { size } = props; + const { self } = themeRef.value; + if (typeof size === "number") { + return `${size}px`; + } else { + return self[createKey("size", size)]; + } + }); + const cssVarsRef = computed(() => { + const { common: { cubicBezierEaseInOut }, self } = themeRef.value; + const { itemColor, itemColorActive } = self; + const { color } = props; + return { + "--n-bezier": cubicBezierEaseInOut, + "--n-item-color": itemColor, + "--n-item-color-active": color || itemColorActive, + "--n-item-size": mergedSizeRef.value + }; + }); + const themeClassHandle = inlineThemeDisabled ? useThemeClass("rate", computed(() => { + const size = mergedSizeRef.value; + const { color } = props; + let hash = ""; + if (size) { + hash += size[0]; + } + if (color) { + hash += color2Class(color); + } + return hash; + }), cssVarsRef, props) : void 0; + return { + mergedClsPrefix: mergedClsPrefixRef, + mergedValue, + hoverIndex: hoverIndexRef, + handleMouseMove, + handleClick, + handleMouseLeave, + handleMouseEnterSomeStar, + cssVars: inlineThemeDisabled ? void 0 : cssVarsRef, + themeClass: themeClassHandle === null || themeClassHandle === void 0 ? void 0 : themeClassHandle.themeClass, + onRender: themeClassHandle === null || themeClassHandle === void 0 ? void 0 : themeClassHandle.onRender + }; + }, + render() { + const { readonly, hoverIndex, mergedValue, mergedClsPrefix, onRender, $slots: { default: defaultSlot } } = this; + onRender === null || onRender === void 0 ? void 0 : onRender(); + return h("div", { class: [ + `${mergedClsPrefix}-rate`, + { + [`${mergedClsPrefix}-rate--readonly`]: readonly + }, + this.themeClass + ], style: this.cssVars, onMouseleave: this.handleMouseLeave }, renderList(this.count, (_, index) => { + const icon = defaultSlot ? defaultSlot({ index }) : h(NBaseIcon, { clsPrefix: mergedClsPrefix }, { default: () => StarIcon }); + const entireStarActive = hoverIndex !== null ? index + 1 <= hoverIndex : index + 1 <= (mergedValue || 0); + return h( + "div", + { key: index, class: [ + `${mergedClsPrefix}-rate__item`, + entireStarActive && `${mergedClsPrefix}-rate__item--active` + ], onClick: readonly ? void 0 : (e) => { + this.handleClick(index, e); + }, onMouseenter: this.handleMouseEnterSomeStar, onMousemove: readonly ? void 0 : (e) => { + this.handleMouseMove(index, e); + } }, + icon, + this.allowHalf ? h("div", { class: [ + `${mergedClsPrefix}-rate__half`, + { + [`${mergedClsPrefix}-rate__half--active`]: !entireStarActive && hoverIndex !== null ? index + 0.5 <= hoverIndex : index + 0.5 <= (mergedValue || 0) + } + ] }, icon) : null + ); + })); + } +}); const uploadInjectionKey = createInjectionKey("n-upload"); const uploadDraggerKey = "__UPLOAD_DRAGGER__"; const NUploadDragger = defineComponent({ @@ -7035,50 +8478,12 @@ const NUpload = defineComponent({ ); } }); -const _hoisted_1$6 = { - xmlns: "http://www.w3.org/2000/svg", - "xmlns:xlink": "http://www.w3.org/1999/xlink", - viewBox: "0 0 512 512" -}; -const _hoisted_2$6 = /* @__PURE__ */ createBaseVNode( - "path", - { - d: "M393.87 190a32.1 32.1 0 0 1-45.25 0l-26.57-26.57a32.09 32.09 0 0 1 0-45.26L382.19 58a1 1 0 0 0-.3-1.64c-38.82-16.64-89.15-8.16-121.11 23.57c-30.58 30.35-32.32 76-21.12 115.84a31.93 31.93 0 0 1-9.06 32.08L64 380a48.17 48.17 0 1 0 68 68l153.86-167a31.93 31.93 0 0 1 31.6-9.13c39.54 10.59 84.54 8.6 114.72-21.19c32.49-32 39.5-88.56 23.75-120.93a1 1 0 0 0-1.6-.26z", - fill: "none", - stroke: "currentColor", - "stroke-linecap": "round", - "stroke-miterlimit": "10", - "stroke-width": "32" - }, - null, - -1 - /* HOISTED */ -); -const _hoisted_3$6 = /* @__PURE__ */ createBaseVNode( - "circle", - { - cx: "96", - cy: "416", - r: "16", - fill: "currentColor" - }, - null, - -1 - /* HOISTED */ -); -const _hoisted_4$6 = [_hoisted_2$6, _hoisted_3$6]; -const BuildOutline = defineComponent({ - name: "BuildOutline", - render: function render(_ctx, _cache) { - return openBlock(), createElementBlock("svg", _hoisted_1$6, _hoisted_4$6); - } -}); -const _hoisted_1$5 = { +const _hoisted_1$7 = { xmlns: "http://www.w3.org/2000/svg", "xmlns:xlink": "http://www.w3.org/1999/xlink", viewBox: "0 0 512 512" }; -const _hoisted_2$5 = /* @__PURE__ */ createBaseVNode( +const _hoisted_2$7 = /* @__PURE__ */ createBaseVNode( "path", { d: "M261.56 101.28a8 8 0 0 0-11.06 0L66.4 277.15a8 8 0 0 0-2.47 5.79L63.9 448a32 32 0 0 0 32 32H192a16 16 0 0 0 16-16V328a8 8 0 0 1 8-8h80a8 8 0 0 1 8 8v136a16 16 0 0 0 16 16h96.06a32 32 0 0 0 32-32V282.94a8 8 0 0 0-2.47-5.79z", @@ -7088,7 +8493,7 @@ const _hoisted_2$5 = /* @__PURE__ */ createBaseVNode( -1 /* HOISTED */ ); -const _hoisted_3$5 = /* @__PURE__ */ createBaseVNode( +const _hoisted_3$7 = /* @__PURE__ */ createBaseVNode( "path", { d: "M490.91 244.15l-74.8-71.56V64a16 16 0 0 0-16-16h-48a16 16 0 0 0-16 16v32l-57.92-55.38C272.77 35.14 264.71 32 256 32c-8.68 0-16.72 3.14-22.14 8.63l-212.7 203.5c-6.22 6-7 15.87-1.34 22.37A16 16 0 0 0 43 267.56L250.5 69.28a8 8 0 0 1 11.06 0l207.52 198.28a16 16 0 0 0 22.59-.44c6.14-6.36 5.63-16.86-.76-22.97z", @@ -7098,19 +8503,19 @@ const _hoisted_3$5 = /* @__PURE__ */ createBaseVNode( -1 /* HOISTED */ ); -const _hoisted_4$5 = [_hoisted_2$5, _hoisted_3$5]; +const _hoisted_4$7 = [_hoisted_2$7, _hoisted_3$7]; const Home = defineComponent({ name: "Home", - render: function render2(_ctx, _cache) { - return openBlock(), createElementBlock("svg", _hoisted_1$5, _hoisted_4$5); + render: function render(_ctx, _cache) { + return openBlock(), createElementBlock("svg", _hoisted_1$7, _hoisted_4$7); } }); -const _hoisted_1$4 = { +const _hoisted_1$6 = { xmlns: "http://www.w3.org/2000/svg", "xmlns:xlink": "http://www.w3.org/1999/xlink", viewBox: "0 0 512 512" }; -const _hoisted_2$4 = /* @__PURE__ */ createBaseVNode( +const _hoisted_2$6 = /* @__PURE__ */ createBaseVNode( "path", { fill: "none", @@ -7124,7 +8529,7 @@ const _hoisted_2$4 = /* @__PURE__ */ createBaseVNode( -1 /* HOISTED */ ); -const _hoisted_3$4 = /* @__PURE__ */ createBaseVNode( +const _hoisted_3$6 = /* @__PURE__ */ createBaseVNode( "path", { fill: "none", @@ -7138,7 +8543,7 @@ const _hoisted_3$4 = /* @__PURE__ */ createBaseVNode( -1 /* HOISTED */ ); -const _hoisted_4$4 = /* @__PURE__ */ createBaseVNode( +const _hoisted_4$6 = /* @__PURE__ */ createBaseVNode( "path", { fill: "none", @@ -7152,19 +8557,19 @@ const _hoisted_4$4 = /* @__PURE__ */ createBaseVNode( -1 /* HOISTED */ ); -const _hoisted_5$2 = [_hoisted_2$4, _hoisted_3$4, _hoisted_4$4]; +const _hoisted_5$3 = [_hoisted_2$6, _hoisted_3$6, _hoisted_4$6]; const Menu = defineComponent({ name: "Menu", - render: function render3(_ctx, _cache) { - return openBlock(), createElementBlock("svg", _hoisted_1$4, _hoisted_5$2); + render: function render2(_ctx, _cache) { + return openBlock(), createElementBlock("svg", _hoisted_1$6, _hoisted_5$3); } }); -const _hoisted_1$3 = { +const _hoisted_1$5 = { xmlns: "http://www.w3.org/2000/svg", "xmlns:xlink": "http://www.w3.org/1999/xlink", viewBox: "0 0 512 512" }; -const _hoisted_2$3 = /* @__PURE__ */ createBaseVNode( +const _hoisted_2$5 = /* @__PURE__ */ createBaseVNode( "circle", { cx: "256", @@ -7176,7 +8581,7 @@ const _hoisted_2$3 = /* @__PURE__ */ createBaseVNode( -1 /* HOISTED */ ); -const _hoisted_3$3 = /* @__PURE__ */ createBaseVNode( +const _hoisted_3$5 = /* @__PURE__ */ createBaseVNode( "path", { d: "M470.39 300l-.47-.38l-31.56-24.75a16.11 16.11 0 0 1-6.1-13.33v-11.56a16 16 0 0 1 6.11-13.22L469.92 212l.47-.38a26.68 26.68 0 0 0 5.9-34.06l-42.71-73.9a1.59 1.59 0 0 1-.13-.22A26.86 26.86 0 0 0 401 92.14l-.35.13l-37.1 14.93a15.94 15.94 0 0 1-14.47-1.29q-4.92-3.1-10-5.86a15.94 15.94 0 0 1-8.19-11.82l-5.59-39.59l-.12-.72A27.22 27.22 0 0 0 298.76 26h-85.52a26.92 26.92 0 0 0-26.45 22.39l-.09.56l-5.57 39.67a16 16 0 0 1-8.13 11.82a175.21 175.21 0 0 0-10 5.82a15.92 15.92 0 0 1-14.43 1.27l-37.13-15l-.35-.14a26.87 26.87 0 0 0-32.48 11.34l-.13.22l-42.77 73.95a26.71 26.71 0 0 0 5.9 34.1l.47.38l31.56 24.75a16.11 16.11 0 0 1 6.1 13.33v11.56a16 16 0 0 1-6.11 13.22L42.08 300l-.47.38a26.68 26.68 0 0 0-5.9 34.06l42.71 73.9a1.59 1.59 0 0 1 .13.22a26.86 26.86 0 0 0 32.45 11.3l.35-.13l37.07-14.93a15.94 15.94 0 0 1 14.47 1.29q4.92 3.11 10 5.86a15.94 15.94 0 0 1 8.19 11.82l5.56 39.59l.12.72A27.22 27.22 0 0 0 213.24 486h85.52a26.92 26.92 0 0 0 26.45-22.39l.09-.56l5.57-39.67a16 16 0 0 1 8.18-11.82c3.42-1.84 6.76-3.79 10-5.82a15.92 15.92 0 0 1 14.43-1.27l37.13 14.95l.35.14a26.85 26.85 0 0 0 32.48-11.34a2.53 2.53 0 0 1 .13-.22l42.71-73.89a26.7 26.7 0 0 0-5.89-34.11zm-134.48-40.24a80 80 0 1 1-83.66-83.67a80.21 80.21 0 0 1 83.66 83.67z", @@ -7186,43 +8591,458 @@ const _hoisted_3$3 = /* @__PURE__ */ createBaseVNode( -1 /* HOISTED */ ); -const _hoisted_4$3 = [_hoisted_2$3, _hoisted_3$3]; +const _hoisted_4$5 = [_hoisted_2$5, _hoisted_3$5]; const Settings = defineComponent({ name: "Settings", - render: function render4(_ctx, _cache) { - return openBlock(), createElementBlock("svg", _hoisted_1$3, _hoisted_4$3); + render: function render3(_ctx, _cache) { + return openBlock(), createElementBlock("svg", _hoisted_1$5, _hoisted_4$5); } }); +const _hoisted_1$4 = ["src"]; +const _hoisted_2$4 = /* @__PURE__ */ createBaseVNode("i", null, [ + /* @__PURE__ */ createTextVNode("Data provided by "), + /* @__PURE__ */ createBaseVNode("a", { href: "https://civitai.com" }, "CivitAI"), + /* @__PURE__ */ createTextVNode(", go and support them") +], -1); +const _hoisted_3$4 = { style: { "height": "90%" } }; +const _hoisted_4$4 = { style: { "line-height": "32px" } }; +const _hoisted_5$2 = { style: { "width": "100%", "display": "inline-flex", "height": "40px", "align-items": "center", "margin-top": "8px" } }; const _sfc_main$5 = /* @__PURE__ */ defineComponent({ - __name: "WIP", - setup(__props) { + __name: "ModelPopup", + props: { + model: {}, + showModal: { type: Boolean } + }, + emits: ["update:showModal"], + setup(__props, { emit }) { + const props = __props; + const message = useMessage(); + const tabValue = ref(""); + const tabsInstRef = ref(null); + const selectedModel = reactive(/* @__PURE__ */ new Map()); + const dateFormat = new Intl.DateTimeFormat(navigator.language, { + year: "numeric", + month: "long", + day: "numeric", + minute: "numeric", + hour: "numeric" + }); + watch(props, (newProps) => { + if (newProps.model) { + tabValue.value = newProps.model.modelVersions[0].name; + } + nextTick(() => { + var _a; + (_a = tabsInstRef.value) == null ? void 0 : _a.syncBarPosition(); + }); + }); + function generateDownloadOptions(submodel) { + return submodel.map((file) => ({ + label: `${file.metadata.format} ${file.metadata.size} ${file.metadata.fp} [${(file.sizeKB / 1024 / 1024).toFixed(2)} GB]`, + value: file.downloadUrl + })); + } return (_ctx, _cache) => { - return openBlock(), createBlock(unref(NResult), { - title: "Work in progress", - description: "This page is still under development.", - style: { "height": "70vh", "display": "flex", "align-items": "center", "justify-content": "center" } + var _a, _b; + return openBlock(), createBlock(unref(NModal), { + show: _ctx.showModal, + title: ((_a = _ctx.model) == null ? void 0 : _a.name) + " (by " + ((_b = _ctx.model) == null ? void 0 : _b.creator.username) + ")" || "Loading...", + preset: "card", + style: { "width": "90vw" }, + "onUpdate:show": _cache[1] || (_cache[1] = ($event) => emit("update:showModal", $event)) }, { - icon: withCtx(() => [ - createVNode(unref(NIcon), { size: "250" }, { - default: withCtx(() => [ - createVNode(unref(BuildOutline)) - ]), + default: withCtx(() => [ + createVNode(unref(NTabs), { + "justify-content": "start", + type: "bar", + value: tabValue.value, + "onUpdate:value": _cache[0] || (_cache[0] = ($event) => tabValue.value = $event), + animated: "" + }, { + default: withCtx(() => { + var _a2; + return [ + (openBlock(true), createElementBlock(Fragment, null, renderList((_a2 = props.model) == null ? void 0 : _a2.modelVersions, (subModel) => { + return openBlock(), createBlock(unref(NTabPane), { + name: subModel.name, + key: subModel.id, + style: { "display": "flex", "flex-direction": "column" } + }, { + default: withCtx(() => [ + createVNode(unref(NGrid), { cols: "1 850:2" }, { + default: withCtx(() => [ + createVNode(unref(NGi), null, { + default: withCtx(() => [ + createVNode(unref(NCarousel), { + style: { "height": "70vh", "width": "100%" }, + draggable: "", + "slides-per-view": 2, + effect: "card", + "dot-type": "line", + "centered-slides": "", + keyboard: "", + mousewheel: "" + }, { + default: withCtx(() => [ + (openBlock(true), createElementBlock(Fragment, null, renderList(subModel.images, (image) => { + return openBlock(), createElementBlock("div", { + key: image.hash, + style: { "border-radius": "20px", "overflow": "hidden" } + }, [ + createBaseVNode("img", { + src: image.url, + style: normalizeStyle({ + width: "100%" + // filter: image.nsfw !== 'None' ? 'blur(4px)' : 'none', + }) + }, null, 12, _hoisted_1$4) + ]); + }), 128)) + ]), + _: 2 + }, 1024) + ]), + _: 2 + }, 1024), + createVNode(unref(NGi), null, { + default: withCtx(() => [ + createVNode(unref(NCard), { + title: subModel.name, + style: { "height": "auto" }, + segmented: "", + hoverable: "", + "content-style": { + paddingBottom: "8px" + } + }, { + footer: withCtx(() => [ + _hoisted_2$4 + ]), + default: withCtx(() => { + var _a3; + return [ + createBaseVNode("div", _hoisted_3$4, [ + createVNode(unref(NRate), { + value: subModel.stats.rating, + "allow-half": "", + readonly: "" + }, null, 8, ["value"]), + createBaseVNode("div", _hoisted_4$4, [ + (openBlock(true), createElementBlock(Fragment, null, renderList((_a3 = _ctx.model) == null ? void 0 : _a3.tags, (tag) => { + return openBlock(), createBlock(unref(NTag), { + key: tag, + style: { "margin-right": "4px" } + }, { + default: withCtx(() => [ + createTextVNode(toDisplayString(tag), 1) + ]), + _: 2 + }, 1024); + }), 128)) + ]), + createVNode(unref(NDescriptions), { + "label-placement": "left", + "label-align": "left", + bordered: "", + columns: 1, + style: { "margin-top": "8px" } + }, { + default: withCtx(() => [ + createVNode(unref(NDescriptionsItem), { label: "Base Model" }, { + default: withCtx(() => [ + createTextVNode(toDisplayString(subModel.baseModel), 1) + ]), + _: 2 + }, 1024), + createVNode(unref(NDescriptionsItem), { label: "Downloads" }, { + default: withCtx(() => [ + createTextVNode(toDisplayString(subModel.stats.downloadCount.toLocaleString()), 1) + ]), + _: 2 + }, 1024), + createVNode(unref(NDescriptionsItem), { label: "Keywords" }, { + default: withCtx(() => [ + createTextVNode(toDisplayString(subModel.trainedWords.length !== 0 ? subModel.trainedWords : "No keywords"), 1) + ]), + _: 2 + }, 1024), + createVNode(unref(NDescriptionsItem), { label: "Last Updated" }, { + default: withCtx(() => [ + createTextVNode(toDisplayString(unref(dateFormat).format(new Date(subModel.updatedAt))), 1) + ]), + _: 2 + }, 1024), + createVNode(unref(NDescriptionsItem), { label: "Created" }, { + default: withCtx(() => [ + createTextVNode(toDisplayString(unref(dateFormat).format(new Date(subModel.createdAt))), 1) + ]), + _: 2 + }, 1024) + ]), + _: 2 + }, 1024) + ]), + createBaseVNode("div", _hoisted_5$2, [ + createVNode(unref(NSelect), { + options: generateDownloadOptions(subModel.files), + onUpdateValue: (value) => selectedModel.set(subModel.name, value) + }, null, 8, ["options", "onUpdateValue"]), + createVNode(unref(NButton), { + style: { "margin-left": "4px" }, + type: "primary", + ghost: "", + disabled: !selectedModel.get(subModel.name), + onClick: ($event) => unref(message).success("Test: " + selectedModel.get(subModel.name)) + }, { + default: withCtx(() => [ + createTextVNode(" Download ") + ]), + _: 2 + }, 1032, ["disabled", "onClick"]) + ]) + ]; + }), + _: 2 + }, 1032, ["title"]) + ]), + _: 2 + }, 1024) + ]), + _: 2 + }, 1024) + ]), + _: 2 + }, 1032, ["name"]); + }), 128)) + ]; + }), _: 1 - }) + }, 8, ["value"]) ]), _: 1 - }); + }, 8, ["show", "title"]); }; } }); +const _hoisted_1$3 = { + style: { "width": "calc(100vw - 98px)", "height": "48px", "border-bottom": "#505050 1px solid", "display": "flex", "justify-content": "end", "align-items": "center", "padding-right": "24px", "position": "sticky", "top": "52px", "z-index": "1" }, + class: "top-bar" +}; +const _hoisted_2$3 = { + class: "main-container", + style: { "margin": "12px", "margin-top": "52px" } +}; +const _hoisted_3$3 = { class: "image-grid" }; +const _hoisted_4$3 = ["src", "onClick"]; const _sfc_main$4 = /* @__PURE__ */ defineComponent({ __name: "CivitAIDownload", setup(__props) { + useCssVars((_ctx) => ({ + "3e32aafb": unref(conf).data.settings.frontend.image_browser_columns, + "46aceb59": backgroundColor.value + })); + const conf = useSettings(); + const loadingLock = ref(false); + const currentPage = ref(1); + const currentModel = ref(null); + const showModal = ref(false); + const scrollComponent = ref(null); + const itemFilter = ref(""); + const gridColumnRefs = ref([]); + const currentColumn = ref(0); + const currentRowIndex = ref(0); + const loadingBar = useLoadingBar(); + function imgClick(column_index, item_index) { + currentRowIndex.value = item_index; + currentColumn.value = column_index; + const item = columns.value[column_index][item_index]; + currentModel.value = item; + showModal.value = true; + } + const modelData = reactive([]); + const columns = computed(() => { + const cols = []; + for (let i = 0; i < conf.data.settings.frontend.image_browser_columns; i++) { + cols.push([]); + } + for (let i = 0; i < modelData.length; i++) { + cols[i % conf.data.settings.frontend.image_browser_columns].push( + modelData[i] + ); + } + return cols; + }); + async function refreshImages() { + modelData.splice(0, modelData.length); + const url = new URL("https://civitai.com/api/v1/models"); + url.searchParams.append("sort", "Most Downloaded"); + await fetch(url).then((res) => res.json()).then((data) => { + data.items.forEach((item) => { + modelData.push(item); + }); + }); + } + const handleScroll = (e) => { + let element = scrollComponent.value; + if (element === null) { + return; + } + let minBox = 0; + for (const col of gridColumnRefs.value) { + const lastImg = col.childNodes.item( + col.childNodes.length - 2 + ); + const bottombbox = lastImg.getBoundingClientRect().bottom; + if (minBox === 0) { + minBox = bottombbox; + } else if (bottombbox < minBox) { + minBox = bottombbox; + } + } + if (minBox - 50 < window.innerHeight) { + if (loadingLock.value) { + return; + } + loadingLock.value = true; + currentPage.value++; + loadingBar.start(); + const pageToFetch = currentPage.value.toString(); + const url = new URL("https://civitai.com/api/v1/models"); + url.searchParams.append("sort", "Most Downloaded"); + url.searchParams.append("page", pageToFetch); + console.log("Fetching page: " + url.toString()); + fetch(url).then((res) => res.json()).then((data) => { + data.items.forEach((item) => { + modelData.push(item); + }); + loadingBar.finish(); + loadingLock.value = false; + }).catch((err) => { + console.error(err); + loadingBar.error(); + loadingLock.value = false; + }); + } + }; + function moveImage(direction) { + const numColumns = conf.data.settings.frontend.image_browser_columns; + if (direction === -1) { + if (currentColumn.value > 0) { + imgClick(currentColumn.value - 1, currentRowIndex.value); + } else { + imgClick(numColumns - 1, currentRowIndex.value - 1); + } + } else if (direction === 1) { + if (currentColumn.value < numColumns - 1) { + imgClick(currentColumn.value + 1, currentRowIndex.value); + } else { + imgClick(0, currentRowIndex.value + 1); + } + } + } + onMounted(() => { + window.addEventListener("scroll", handleScroll); + window.addEventListener("keydown", (e) => { + if (e.key === "ArrowLeft") { + moveImage(-1); + } else if (e.key === "ArrowRight") { + moveImage(1); + } + }); + }); + onUnmounted(() => { + window.removeEventListener("scroll", handleScroll); + window.removeEventListener("keydown", (e) => { + if (e.key === "ArrowLeft") { + moveImage(-1); + } else if (e.key === "ArrowRight") { + moveImage(1); + } + }); + }); + refreshImages(); + const backgroundColor = computed(() => { + if (conf.data.settings.frontend.theme === "dark") { + return "#121215"; + } else { + return "#fff"; + } + }); return (_ctx, _cache) => { - return openBlock(), createBlock(_sfc_main$5); + return openBlock(), createElementBlock(Fragment, null, [ + createVNode(_sfc_main$5, { + model: currentModel.value, + "show-modal": showModal.value, + "onUpdate:showModal": _cache[0] || (_cache[0] = ($event) => showModal.value = $event) + }, null, 8, ["model", "show-modal"]), + createBaseVNode("div", _hoisted_1$3, [ + createVNode(unref(NInput), { + value: itemFilter.value, + "onUpdate:value": _cache[1] || (_cache[1] = ($event) => itemFilter.value = $event), + style: { "margin": "0 12px" }, + placeholder: "Filter" + }, null, 8, ["value"]), + createVNode(unref(NIcon), { + style: { "margin-right": "12px" }, + size: "22" + }, { + default: withCtx(() => [ + createVNode(unref(GridOutline)) + ]), + _: 1 + }), + createVNode(unref(NSlider), { + style: { "width": "50vw" }, + min: 1, + max: 10, + value: unref(conf).data.settings.frontend.image_browser_columns, + "onUpdate:value": _cache[2] || (_cache[2] = ($event) => unref(conf).data.settings.frontend.image_browser_columns = $event) + }, null, 8, ["value"]) + ]), + createBaseVNode("div", _hoisted_2$3, [ + createBaseVNode("div", { + ref_key: "scrollComponent", + ref: scrollComponent + }, [ + createBaseVNode("div", _hoisted_3$3, [ + (openBlock(true), createElementBlock(Fragment, null, renderList(columns.value, (column, column_index) => { + return openBlock(), createElementBlock("div", { + key: column_index, + class: "image-column", + ref_for: true, + ref_key: "gridColumnRefs", + ref: gridColumnRefs + }, [ + (openBlock(true), createElementBlock(Fragment, null, renderList(column, (item, item_index) => { + return openBlock(), createElementBlock("div", { + key: item_index, + style: { "border-radius": "20px", "overflow": "hidden" } + }, [ + createBaseVNode("img", { + src: item.modelVersions[0].images[0].url, + style: normalizeStyle({ + width: "100%", + height: "auto", + borderRadius: "8px", + cursor: "pointer", + marginBottom: "6px", + filter: item.modelVersions[0].images[0].nsfw !== "None" ? "blur(12px)" : "none" + }), + onClick: ($event) => imgClick(column_index, item_index) + }, null, 12, _hoisted_4$3) + ]); + }), 128)) + ]); + }), 128)) + ]) + ], 512) + ]) + ], 64); }; } }); +const CivitAIDownload_vue_vue_type_style_index_0_scoped_30671504_lang = ""; +const CivitAIDownload = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-30671504"]]); const _withScopeId = (n) => (pushScopeId("data-v-6a6fb4b4"), n = n(), popScopeId(), n); const _hoisted_1$2 = { style: { "margin": "18px" } }; const _hoisted_2$2 = { style: { "width": "100%", "display": "inline-flex", "justify-content": "space-between", "align-items": "center" } }; @@ -7914,7 +9734,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({ }), createVNode(unref(NTabPane), { name: "CivitAI" }, { default: withCtx(() => [ - createVNode(_sfc_main$4) + createVNode(CivitAIDownload) ]), _: 1 }), diff --git a/frontend/dist/assets/OutputStats.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/OutputStats.vue_vue_type_script_setup_true_lang.js new file mode 100644 index 000000000..d17793bdc --- /dev/null +++ b/frontend/dist/assets/OutputStats.vue_vue_type_script_setup_true_lang.js @@ -0,0 +1,43 @@ +import { N as NDescriptionsItem, a as NDescriptions } from "./DescriptionsItem.js"; +import { d as defineComponent, e as openBlock, v as createBlock, w as withCtx, g as createVNode, h as unref, m as createTextVNode, t as toDisplayString, i as NCard, x as createCommentVNode } from "./index.js"; +const _sfc_main = /* @__PURE__ */ defineComponent({ + __name: "OutputStats", + props: { + genData: { + type: Object, + required: true + } + }, + setup(__props) { + return (_ctx, _cache) => { + return __props.genData.time_taken || __props.genData.seed ? (openBlock(), createBlock(unref(NCard), { + key: 0, + title: "Stats" + }, { + default: withCtx(() => [ + createVNode(unref(NDescriptions), null, { + default: withCtx(() => [ + createVNode(unref(NDescriptionsItem), { label: "Total Time" }, { + default: withCtx(() => [ + createTextVNode(toDisplayString(__props.genData.time_taken) + "s ", 1) + ]), + _: 1 + }), + createVNode(unref(NDescriptionsItem), { label: "Seed" }, { + default: withCtx(() => [ + createTextVNode(toDisplayString(__props.genData.seed), 1) + ]), + _: 1 + }) + ]), + _: 1 + }) + ]), + _: 1 + })) : createCommentVNode("", true); + }; + } +}); +export { + _sfc_main as _ +}; diff --git a/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js index f2d3e12f9..5f0c31833 100644 --- a/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { d as defineComponent, e as openBlock, f as createElementBlock, n as createBaseVNode, bp as useRouter, a as useSettings, u as useState, v as createBlock, w as withCtx, g as createVNode, h as unref, N as NGi, F as NButton, m as createTextVNode, y as NGrid, i as NCard, x as createCommentVNode } from "./index.js"; +import { d as defineComponent, e as openBlock, f as createElementBlock, n as createBaseVNode, bD as useRouter, a as useSettings, u as useState, v as createBlock, w as withCtx, g as createVNode, h as unref, N as NGi, F as NButton, m as createTextVNode, y as NGrid, i as NCard, x as createCommentVNode } from "./index.js"; const _hoisted_1 = { xmlns: "http://www.w3.org/2000/svg", "xmlns:xlink": "http://www.w3.org/1999/xlink", diff --git a/frontend/dist/assets/SettingsView.js b/frontend/dist/assets/SettingsView.js index be04f8dc3..c3a364b6a 100644 --- a/frontend/dist/assets/SettingsView.js +++ b/frontend/dist/assets/SettingsView.js @@ -1,4 +1,5 @@ -import { a3 as inject, be as getCurrentInstance, J as watch, aH as onBeforeUnmount, Y as cB, $ as cM, X as c, V as createInjectionKey, d as defineComponent, Q as useConfig, a5 as useTheme, E as ref, T as provide, D as h, bf as formLight, ai as keysOf, c as computed, aF as formatLength, aM as get, bg as commonVariables, Z as cE, U as toRef, aa as createId, bh as formItemInjectionKey, bi as onMounted, a9 as useThemeClass, aX as Transition, aB as resolveWrappedSlot, a8 as createKey, aQ as warn, a as useSettings, u as useState, e as openBlock, v as createBlock, w as withCtx, g as createVNode, h as unref, k as NInput, r as NSelect, f as createElementBlock, x as createCommentVNode, n as createBaseVNode, i as NCard, H as NTabPane, I as NTabs, b as useMessage, bj as useNotification, F as NButton, m as createTextVNode, bk as defaultSettings, s as serverUrl } from "./index.js"; +import { B as BurnerClock } from "./clock.js"; +import { V as inject, bw as getCurrentInstance, a9 as watch, a0 as onBeforeUnmount, a1 as cB, a4 as cM, a3 as c, U as createInjectionKey, d as defineComponent, X as useConfig, aa as useTheme, E as ref, T as provide, D as h, bx as formLight, aE as keysOf, c as computed, aY as formatLength, b1 as get, by as commonVariables, a2 as cE, a6 as toRef, ay as createId, bz as formItemInjectionKey, $ as onMounted, ab as useThemeClass, ah as Transition, aV as resolveWrappedSlot, ax as createKey, b4 as warn, a as useSettings, u as useState, e as openBlock, v as createBlock, w as withCtx, g as createVNode, h as unref, k as NInput, r as NSelect, f as createElementBlock, x as createCommentVNode, n as createBaseVNode, i as NCard, H as NTabPane, I as NTabs, b as useMessage, bA as useNotification, o as onUnmounted, s as serverUrl, F as NButton, m as createTextVNode, bB as defaultSettings } from "./index.js"; import { N as NSwitch } from "./Switch.js"; import { N as NInputNumber } from "./InputNumber.js"; import { N as NSlider } from "./Slider.js"; @@ -3188,6 +3189,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({ const message = useMessage(); const settings = useSettings(); const notification = useNotification(); + const saving = ref(false); function resetSettings() { Object.assign( settings.defaultSettings, @@ -3198,7 +3200,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({ ); } function saveSettings() { - console.log(settings.defaultSettings); + saving.value = true; fetch(`${serverUrl}/api/settings/save`, { method: "POST", headers: { @@ -3218,8 +3220,20 @@ const _sfc_main = /* @__PURE__ */ defineComponent({ }); }); } + saving.value = false; }); } + const conf = useSettings(); + const burner = new BurnerClock( + conf.defaultSettings, + conf, + saveSettings, + 3e3, + false + ); + onUnmounted(() => { + burner.cleanup(); + }); return (_ctx, _cache) => { return openBlock(), createElementBlock("div", _hoisted_1, [ createVNode(unref(NCard), null, { @@ -3240,13 +3254,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({ createVNode(unref(NButton), { type: "success", ghost: "", - onClick: saveSettings + onClick: saveSettings, + loading: saving.value }, { default: withCtx(() => [ createTextVNode("Save Settings") ]), _: 1 - }) + }, 8, ["loading"]) ]), default: withCtx(() => [ createVNode(unref(NTabPane), { name: "Frontend" }, { diff --git a/frontend/dist/assets/Slider.js b/frontend/dist/assets/Slider.js index 9263f3fa1..2b4afe8c1 100644 --- a/frontend/dist/assets/Slider.js +++ b/frontend/dist/assets/Slider.js @@ -1,4 +1,4 @@ -import { E as ref, bG as onBeforeUpdate, X as c, Y as cB, $ as cM, Z as cE, aW as fadeInScaleUpTransition, a1 as insideModal, a2 as insidePopover, d as defineComponent, Q as useConfig, a5 as useTheme, R as useFormItem, c as computed, U as toRef, S as useMergedState, J as watch, aH as onBeforeUnmount, a9 as useThemeClass, bs as isMounted, av as useAdjustedTo, D as h, bH as VBinder, bI as VTarget, at as resolveSlot, bJ as VFollower, aX as Transition, bK as sliderLight, ac as on, aI as off, ah as nextTick, W as call } from "./index.js"; +import { E as ref, Y as onBeforeUpdate, a3 as c, a1 as cB, a4 as cM, a2 as cE, ba as fadeInScaleUpTransition, as as insideModal, at as insidePopover, d as defineComponent, X as useConfig, aa as useTheme, ap as useFormItem, c as computed, a6 as toRef, a5 as useMergedState, a9 as watch, a0 as onBeforeUnmount, ab as useThemeClass, bI as isMounted, aP as useAdjustedTo, D as h, bT as VBinder, bU as VTarget, aN as resolveSlot, bV as VFollower, ah as Transition, bW as sliderLight, an as on, aj as off, ao as nextTick, aq as call } from "./index.js"; function isTouchEvent(e) { return window.TouchEvent && e instanceof window.TouchEvent; } diff --git a/frontend/dist/assets/Switch.js b/frontend/dist/assets/Switch.js index 968c72dee..cfc46fe29 100644 --- a/frontend/dist/assets/Switch.js +++ b/frontend/dist/assets/Switch.js @@ -1,4 +1,4 @@ -import { Y as cB, Z as cE, a0 as iconSwitchTransition, X as c, $ as cM, aq as cNotM, d as defineComponent, Q as useConfig, a5 as useTheme, R as useFormItem, E as ref, U as toRef, S as useMergedState, c as computed, a9 as useThemeClass, bE as isSlotEmpty, D as h, aB as resolveWrappedSlot, bF as switchLight, a8 as createKey, aL as pxfy, aE as depx, ab as NIconSwitchTransition, aN as NBaseLoading, W as call } from "./index.js"; +import { a1 as cB, a2 as cE, ar as iconSwitchTransition, a3 as c, a4 as cM, aL as cNotM, d as defineComponent, X as useConfig, aa as useTheme, ap as useFormItem, E as ref, a6 as toRef, a5 as useMergedState, c as computed, ab as useThemeClass, bR as isSlotEmpty, D as h, aV as resolveWrappedSlot, bS as switchLight, ax as createKey, b0 as pxfy, aX as depx, az as NIconSwitchTransition, b2 as NBaseLoading, aq as call } from "./index.js"; const style = cB("switch", ` height: var(--n-height); min-width: var(--n-width); diff --git a/frontend/dist/assets/TestView.js b/frontend/dist/assets/TestView.js index f6248ba5b..da8935a36 100644 --- a/frontend/dist/assets/TestView.js +++ b/frontend/dist/assets/TestView.js @@ -1,10 +1,17 @@ -import { _ as _export_sfc, e as openBlock, f as createElementBlock } from "./index.js"; -const _sfc_main = {}; -const _hoisted_1 = { class: "main-container" }; -function _sfc_render(_ctx, _cache) { - return openBlock(), createElementBlock("div", _hoisted_1); -} -const TestView = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]); +import { d as defineComponent, E as ref } from "./index.js"; +const _sfc_main = /* @__PURE__ */ defineComponent({ + __name: "TestView", + setup(__props) { + const model = ref(null); + fetch("https://civitai.com/api/v1/models/7240").then((res) => { + res.json().then((data) => { + model.value = data; + }); + }); + return () => { + }; + } +}); export { - TestView as default + _sfc_main as default }; diff --git a/frontend/dist/assets/TextToImageView.js b/frontend/dist/assets/TextToImageView.js index 59619a655..bc8250db4 100644 --- a/frontend/dist/assets/TextToImageView.js +++ b/frontend/dist/assets/TextToImageView.js @@ -1,7 +1,8 @@ import { _ as _sfc_main$1 } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; import { _ as _sfc_main$2 } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; -import { B as BurnerClock, _ as _sfc_main$3 } from "./clock.js"; +import { _ as _sfc_main$3 } from "./OutputStats.vue_vue_type_script_setup_true_lang.js"; import { d as defineComponent, u as useState, a as useSettings, b as useMessage, c as computed, o as onUnmounted, e as openBlock, f as createElementBlock, g as createVNode, w as withCtx, h as unref, s as serverUrl, N as NGi, i as NCard, j as NSpace, k as NInput, p as promptHandleKeyUp, l as promptHandleKeyDown, m as createTextVNode, t as toDisplayString, n as createBaseVNode, q as NTooltip, r as NSelect, v as createBlock, x as createCommentVNode, y as NGrid, z as spaceRegex } from "./index.js"; +import { B as BurnerClock } from "./clock.js"; import { v as v4 } from "./v4.js"; import { N as NSwitch } from "./Switch.js"; import { N as NSlider } from "./Slider.js"; diff --git a/frontend/dist/assets/TrashBin.js b/frontend/dist/assets/TrashBin.js index fb55ac4cf..255b8460f 100644 --- a/frontend/dist/assets/TrashBin.js +++ b/frontend/dist/assets/TrashBin.js @@ -1,4 +1,4 @@ -import { P as replaceable, D as h, d as defineComponent, a_ as isBrowser, a5 as useTheme, V as createInjectionKey, X as c, Y as cB, bq as fadeInTransition, aW as fadeInScaleUpTransition, aq as cNotM, U as toRef, br as imageLight, E as ref, ar as useLocale, J as watch, aH as onBeforeUnmount, aI as off, a3 as inject, c as computed, Q as useConfig, a9 as useThemeClass, bs as isMounted, bt as LazyTeleport, bu as withDirectives, bv as zindexable, aX as Transition, L as Fragment, au as NBaseIcon, bw as vShow, ac as on, bx as normalizeStyle, by as kebabCase, q as NTooltip, aV as beforeNextFrameOnce, aa as createId, T as provide, be as getCurrentInstance, bi as onMounted, as as watchEffect, e as openBlock, f as createElementBlock, n as createBaseVNode } from "./index.js"; +import { R as replaceable, D as h, d as defineComponent, bf as isBrowser, aa as useTheme, U as createInjectionKey, a3 as c, a1 as cB, bG as fadeInTransition, ba as fadeInScaleUpTransition, aL as cNotM, a6 as toRef, bH as imageLight, E as ref, aM as useLocale, a9 as watch, a0 as onBeforeUnmount, aj as off, V as inject, c as computed, X as useConfig, ab as useThemeClass, bI as isMounted, bJ as LazyTeleport, af as withDirectives, bK as zindexable, ah as Transition, K as Fragment, aO as NBaseIcon, ag as vShow, an as on, al as normalizeStyle, bL as kebabCase, q as NTooltip, b9 as beforeNextFrameOnce, ay as createId, T as provide, bw as getCurrentInstance, $ as onMounted, a7 as watchEffect, e as openBlock, f as createElementBlock, n as createBaseVNode } from "./index.js"; const RotateClockwiseIcon = replaceable("rotateClockwise", h( "svg", { viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, diff --git a/frontend/dist/assets/clock.js b/frontend/dist/assets/clock.js index 70edd312a..770687252 100644 --- a/frontend/dist/assets/clock.js +++ b/frontend/dist/assets/clock.js @@ -4,55 +4,18 @@ var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; -import { N as NDescriptionsItem, a as NDescriptions } from "./DescriptionsItem.js"; -import { d as defineComponent, e as openBlock, v as createBlock, w as withCtx, g as createVNode, h as unref, m as createTextVNode, t as toDisplayString, i as NCard, x as createCommentVNode, J as watch, E as ref, s as serverUrl } from "./index.js"; -const _sfc_main = /* @__PURE__ */ defineComponent({ - __name: "OutputStats", - props: { - genData: { - type: Object, - required: true - } - }, - setup(__props) { - return (_ctx, _cache) => { - return __props.genData.time_taken || __props.genData.seed ? (openBlock(), createBlock(unref(NCard), { - key: 0, - title: "Stats" - }, { - default: withCtx(() => [ - createVNode(unref(NDescriptions), null, { - default: withCtx(() => [ - createVNode(unref(NDescriptionsItem), { label: "Total Time" }, { - default: withCtx(() => [ - createTextVNode(toDisplayString(__props.genData.time_taken) + "s ", 1) - ]), - _: 1 - }), - createVNode(unref(NDescriptionsItem), { label: "Seed" }, { - default: withCtx(() => [ - createTextVNode(toDisplayString(__props.genData.seed), 1) - ]), - _: 1 - }) - ]), - _: 1 - }) - ]), - _: 1 - })) : createCommentVNode("", true); - }; - } -}); +import { a9 as watch, E as ref, s as serverUrl } from "./index.js"; class BurnerClock { - constructor(observed_value, settings, callback) { + constructor(observed_value, settings, callback, timerOverrride = 0, sendInterrupt = true) { __publicField(this, "isChanging", ref(false)); __publicField(this, "timer", null); __publicField(this, "timeoutDuration"); this.observed_value = observed_value; this.settings = settings; this.callback = callback; - this.timeoutDuration = this.settings.data.settings.frontend.on_change_timer; + this.timerOverrride = timerOverrride; + this.sendInterrupt = sendInterrupt; + this.timeoutDuration = this.timerOverrride !== 0 ? this.timerOverrride : this.settings.data.settings.frontend.on_change_timer; watch(this.observed_value, () => { this.handleChange(); }); @@ -68,17 +31,22 @@ class BurnerClock { if (this.timeoutDuration > 0) { this.isChanging.value = true; this.timer = setTimeout(() => { - fetch(`${serverUrl}/api/general/interrupt`, { - method: "POST" - }).then((res) => { - if (res.status === 200) { - this.callback(); + if (this.sendInterrupt) { + fetch(`${serverUrl}/api/general/interrupt`, { + method: "POST" + }).then((res) => { + if (res.status === 200) { + this.callback(); + this.isChanging.value = false; + } + }).catch((err) => { this.isChanging.value = false; - } - }).catch((err) => { + console.error(err); + }); + } else { + this.callback(); this.isChanging.value = false; - console.error(err); - }); + } }, this.timeoutDuration); } } @@ -107,6 +75,5 @@ class BurnerClock { } } export { - BurnerClock as B, - _sfc_main as _ + BurnerClock as B }; diff --git a/frontend/dist/assets/index.css b/frontend/dist/assets/index.css index 5c9ebcef4..39222f7f5 100644 --- a/frontend/dist/assets/index.css +++ b/frontend/dist/assets/index.css @@ -7,12 +7,12 @@ z-index: 2; } -.progress-container[data-v-37b1913e] { +.progress-container[data-v-18a00c0d] { margin: 12px; flex-grow: 1; width: 400px; } -.top-bar[data-v-37b1913e] { +.top-bar[data-v-18a00c0d] { display: inline-flex; align-items: center; border-bottom: #505050 1px solid; @@ -23,15 +23,15 @@ position: fixed; top: 0; z-index: 1; - background-color: var(--2ac8c8e2); + background-color: var(--7ea1c782); } -.logo[data-v-37b1913e] { +.logo[data-v-18a00c0d] { margin-right: 16px; margin-left: 16px; } .main { - background-color: var(--1d19c67b); + background-color: var(--29cef8cc); } .autocomplete { position: relative; @@ -40,18 +40,18 @@ .autocomplete-items { position: absolute; z-index: 99; - background-color: var(--12b62b62); - border-radius: var(--753630fc); + background-color: var(--4a43647e); + border-radius: var(--e4e5ec3e); padding: 2px; } .autocomplete-items div { padding: 8px; cursor: pointer; - border-radius: var(--753630fc); + border-radius: var(--e4e5ec3e); } .autocomplete-active { - background-color: var(--53c6c405) !important; - color: var(--e7594bd2) !important; + background-color: var(--1beee664) !important; + color: var(--440cdb18) !important; } body { min-height: 100vh; diff --git a/frontend/dist/assets/index.js b/frontend/dist/assets/index.js index 16df5892c..24bb0b949 100644 --- a/frontend/dist/assets/index.js +++ b/frontend/dist/assets/index.js @@ -7385,6 +7385,19 @@ function repeat(count, v) { } return ret; } +function indexMap(count, createValue) { + const ret = []; + if (!createValue) { + for (let i = 0; i < count; ++i) { + ret.push(i); + } + return ret; + } + for (let i = 0; i < count; ++i) { + ret.push(createValue(i)); + } + return ret; +} function getSlot$1(instance, slotName = "default", fallback = []) { const slots = instance.$slots; const slot = slots[slotName]; @@ -9811,7 +9824,7 @@ function getOffset(placement, offsetRect, targetRect, offsetTopToStandardPlaceme }; } } -const style$z = c([ +const style$A = c([ c(".v-binder-follower-container", { position: "absolute", left: "0", @@ -9893,7 +9906,7 @@ const VFollower = defineComponent({ } }); const ssrAdapter2 = useSsrAdapter(); - style$z.mount({ + style$A.mount({ id: "vueuc/binder", head: true, anchorMetaName: cssrAnchorMetaName$1, @@ -11088,7 +11101,7 @@ const VXScroll = defineComponent({ } }); const hiddenAttr = "v-hidden"; -const style$y = c("[v-hidden]", { +const style$z = c("[v-hidden]", { display: "none!important" }); const VOverflow = defineComponent({ @@ -11178,7 +11191,7 @@ const VOverflow = defineComponent({ } } const ssrAdapter2 = useSsrAdapter(); - style$y.mount({ + style$z.mount({ id: "vueuc/overflow", head: true, anchorMetaName: cssrAnchorMetaName$1, @@ -14738,7 +14751,7 @@ const NFadeInExpandTransition = defineComponent({ }; } }); -const style$x = cB("base-icon", ` +const style$y = cB("base-icon", ` height: 1em; width: 1em; line-height: 1em; @@ -14773,13 +14786,13 @@ const NBaseIcon = defineComponent({ onMouseup: Function }, setup(props) { - useStyle("-base-icon", style$x, toRef(props, "clsPrefix")); + useStyle("-base-icon", style$y, toRef(props, "clsPrefix")); }, render() { return h("i", { class: `${this.clsPrefix}-base-icon`, onClick: this.onClick, onMousedown: this.onMousedown, onMouseup: this.onMouseup, role: this.role, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, "aria-disabled": this.ariaDisabled }, this.$slots); } }); -const style$w = cB("base-close", ` +const style$x = cB("base-close", ` display: flex; align-items: center; justify-content: center; @@ -14848,7 +14861,7 @@ const NBaseClose = defineComponent({ absolute: Boolean }, setup(props) { - useStyle("-base-close", style$w, toRef(props, "clsPrefix")); + useStyle("-base-close", style$x, toRef(props, "clsPrefix")); return () => { const { clsPrefix, disabled, absolute, round, isButtonTag } = props; const Tag = isButtonTag ? "button" : "div"; @@ -14907,7 +14920,7 @@ function iconSwitchTransition({ transition })]; } -const style$v = c$1([c$1("@keyframes loading-container-rotate", ` +const style$w = c$1([c$1("@keyframes loading-container-rotate", ` to { -webkit-transform: rotate(360deg); transform: rotate(360deg); @@ -15070,7 +15083,7 @@ const NBaseLoading = defineComponent({ default: 100 } }, exposedLoadingProps), setup(props) { - useStyle("-base-loading", style$v, toRef(props, "clsPrefix")); + useStyle("-base-loading", style$w, toRef(props, "clsPrefix")); }, render() { const { clsPrefix, radius, strokeWidth, stroke, scale } = this; @@ -16100,7 +16113,7 @@ const emptyDark = { self: self$1d }; const emptyDark$1 = emptyDark; -const style$u = cB("empty", ` +const style$v = cB("empty", ` display: flex; flex-direction: column; align-items: center; @@ -16139,7 +16152,7 @@ const NEmpty = defineComponent({ props: emptyProps, setup(props) { const { mergedClsPrefixRef, inlineThemeDisabled } = useConfig(props); - const themeRef = useTheme("Empty", "-empty", style$u, emptyLight$1, props, mergedClsPrefixRef); + const themeRef = useTheme("Empty", "-empty", style$v, emptyLight$1, props, mergedClsPrefixRef); const { localeRef } = useLocale("Empty"); const NConfigProvider2 = inject(configProviderInjectionKey, null); const mergedDescriptionRef = computed(() => { @@ -16230,7 +16243,7 @@ function fadeInTransition({ opacity: 1 })]; } -const style$t = cB("scrollbar", ` +const style$u = cB("scrollbar", ` overflow: hidden; position: relative; z-index: auto; @@ -16753,7 +16766,7 @@ const Scrollbar$1 = defineComponent({ off("mousemove", window, handleYScrollMouseMove, true); off("mouseup", window, handleYScrollMouseUp, true); }); - const themeRef = useTheme("Scrollbar", "-scrollbar", style$t, scrollbarLight$1, props, mergedClsPrefixRef); + const themeRef = useTheme("Scrollbar", "-scrollbar", style$u, scrollbarLight$1, props, mergedClsPrefixRef); const cssVarsRef = computed(() => { const { common: { cubicBezierEaseInOut: cubicBezierEaseInOut2, scrollbarBorderRadius, scrollbarHeight, scrollbarWidth }, self: { color, colorHover } } = themeRef.value; return { @@ -17099,7 +17112,7 @@ function fadeInScaleUpTransition({ transform: `${originalTransform} scale(1)` })]; } -const style$s = cB("base-select-menu", ` +const style$t = cB("base-select-menu", ` line-height: 1.5; outline: none; z-index: 0; @@ -17268,7 +17281,7 @@ const NInternalSelectMenu = defineComponent({ onToggle: Function }), setup(props) { - const themeRef = useTheme("InternalSelectMenu", "-internal-select-menu", style$s, internalSelectMenuLight$1, props, toRef(props, "clsPrefix")); + const themeRef = useTheme("InternalSelectMenu", "-internal-select-menu", style$t, internalSelectMenuLight$1, props, toRef(props, "clsPrefix")); const selfRef = ref(null); const virtualListRef = ref(null); const scrollbarRef = ref(null); @@ -17567,7 +17580,7 @@ const NInternalSelectMenu = defineComponent({ ); } }); -const style$r = cB("base-wave", ` +const style$s = cB("base-wave", ` position: absolute; left: 0; right: 0; @@ -17584,7 +17597,7 @@ const NBaseWave = defineComponent({ } }, setup(props) { - useStyle("-base-wave", style$r, toRef(props, "clsPrefix")); + useStyle("-base-wave", style$s, toRef(props, "clsPrefix")); const selfRef = ref(null); const activeRef = ref(false); let animationTimerId = null; @@ -17660,7 +17673,7 @@ const oppositePlacement = { right: "left" }; const arrowSize = "var(--n-arrow-height) * 1.414"; -const style$q = c$1([cB("popover", ` +const style$r = c$1([cB("popover", ` transition: box-shadow .3s var(--n-bezier), background-color .3s var(--n-bezier), @@ -17852,7 +17865,7 @@ const NPopoverBody = defineComponent({ props: popoverBodyProps, setup(props, { slots, attrs }) { const { namespaceRef, mergedClsPrefixRef, inlineThemeDisabled } = useConfig(props); - const themeRef = useTheme("Popover", "-popover", style$q, popoverLight$1, props, mergedClsPrefixRef); + const themeRef = useTheme("Popover", "-popover", style$r, popoverLight$1, props, mergedClsPrefixRef); const followerRef = ref(null); const NPopover2 = inject("NPopover"); const bodyRef = ref(null); @@ -18734,7 +18747,7 @@ const commonProps = { default: void 0 } }; -const style$p = cB("tag", ` +const style$q = cB("tag", ` white-space: nowrap; position: relative; box-sizing: border-box; @@ -18837,7 +18850,7 @@ const NTag = defineComponent({ setup(props) { const contentRef = ref(null); const { mergedBorderedRef, mergedClsPrefixRef, inlineThemeDisabled, mergedRtlRef } = useConfig(props); - const themeRef = useTheme("Tag", "-tag", style$p, tagLight$1, props, mergedClsPrefixRef); + const themeRef = useTheme("Tag", "-tag", style$q, tagLight$1, props, mergedClsPrefixRef); provide(tagInjectionKey, { roundRef: toRef(props, "round") }); @@ -18968,7 +18981,7 @@ const NTag = defineComponent({ ); } }); -const style$o = cB("base-clear", ` +const style$p = cB("base-clear", ` flex-shrink: 0; height: 1em; width: 1em; @@ -19008,7 +19021,7 @@ const NBaseClear = defineComponent({ onClear: Function }, setup(props) { - useStyle("-base-clear", style$o, toRef(props, "clsPrefix")); + useStyle("-base-clear", style$p, toRef(props, "clsPrefix")); return { handleMouseDown(e) { e.preventDefault(); @@ -19228,7 +19241,7 @@ const internalSelectionDark = { } }; const internalSelectionDark$1 = internalSelectionDark; -const style$n = c$1([cB("base-selection", ` +const style$o = c$1([cB("base-selection", ` position: relative; z-index: auto; box-shadow: none; @@ -19468,7 +19481,7 @@ const NInternalSelection = defineComponent({ const showTagsPopoverRef = ref(false); const patternInputFocusedRef = ref(false); const hoverRef = ref(false); - const themeRef = useTheme("InternalSelection", "-internal-selection", style$n, internalSelectionLight$1, props, toRef(props, "clsPrefix")); + const themeRef = useTheme("InternalSelection", "-internal-selection", style$o, internalSelectionLight$1, props, toRef(props, "clsPrefix")); const mergedClearableRef = computed(() => { return props.clearable && !props.disabled && (hoverRef.value || props.active); }); @@ -20273,7 +20286,7 @@ function fadeInHeightExpandTransition({ ${originalTransition ? "," + originalTransition : ""} `)]; } -const style$m = cB("alert", ` +const style$n = cB("alert", ` line-height: var(--n-line-height); border-radius: var(--n-border-radius); position: relative; @@ -20372,7 +20385,7 @@ const NAlert = defineComponent({ props: alertProps, setup(props) { const { mergedClsPrefixRef, mergedBorderedRef, inlineThemeDisabled, mergedRtlRef } = useConfig(props); - const themeRef = useTheme("Alert", "-alert", style$m, alertLight$1, props, mergedClsPrefixRef); + const themeRef = useTheme("Alert", "-alert", style$n, alertLight$1, props, mergedClsPrefixRef); const rtlEnabledRef = useRtl("Alert", mergedRtlRef, mergedClsPrefixRef); const cssVarsRef = computed(() => { const { common: { cubicBezierEaseInOut: cubicBezierEaseInOut2 }, self: self2 } = themeRef.value; @@ -20839,7 +20852,7 @@ const WordCount = defineComponent({ }; } }); -const style$l = cB("input", ` +const style$m = cB("input", ` max-width: 100%; cursor: text; line-height: 1.5; @@ -21194,7 +21207,7 @@ const NInput = defineComponent({ props: inputProps, setup(props) { const { mergedClsPrefixRef, mergedBorderedRef, inlineThemeDisabled, mergedRtlRef } = useConfig(props); - const themeRef = useTheme("Input", "-input", style$l, inputLight$1, props, mergedClsPrefixRef); + const themeRef = useTheme("Input", "-input", style$m, inputLight$1, props, mergedClsPrefixRef); if (isSafari) { useStyle("-input-safari", safariStyle, mergedClsPrefixRef); } @@ -22039,7 +22052,7 @@ const NInput = defineComponent({ ); } }); -const style$k = cB("input-group", ` +const style$l = cB("input-group", ` display: inline-flex; width: 100%; flex-wrap: nowrap; @@ -22101,7 +22114,7 @@ const NInputGroup = defineComponent({ props: inputGroupProps, setup(props) { const { mergedClsPrefixRef } = useConfig(props); - useStyle("-input-group", style$k, mergedClsPrefixRef); + useStyle("-input-group", style$l, mergedClsPrefixRef); return { mergedClsPrefix: mergedClsPrefixRef }; @@ -22511,7 +22524,7 @@ const buttonDark = { } }; const buttonDark$1 = buttonDark; -const style$j = c$1([cB("button", ` +const style$k = c$1([cB("button", ` margin: 0; font-weight: var(--n-font-weight); line-height: 1; @@ -22768,7 +22781,7 @@ const Button = defineComponent({ enterPressedRef.value = false; }; const { inlineThemeDisabled, mergedClsPrefixRef, mergedRtlRef } = useConfig(props); - const themeRef = useTheme("Button", "-button", style$j, buttonLight$1, props, mergedClsPrefixRef); + const themeRef = useTheme("Button", "-button", style$k, buttonLight$1, props, mergedClsPrefixRef); const rtlEnabledRef = useRtl("Button", mergedRtlRef, mergedClsPrefixRef); const cssVarsRef = computed(() => { const theme = themeRef.value; @@ -23936,7 +23949,7 @@ const ColorPreview = defineComponent({ ); } }); -const style$i = c$1([cB("color-picker", ` +const style$j = c$1([cB("color-picker", ` display: inline-block; box-sizing: border-box; height: var(--n-height); @@ -24147,7 +24160,7 @@ const NColorPicker = defineComponent({ const { mergedSizeRef, mergedDisabledRef } = formItem; const { localeRef } = useLocale("global"); const { mergedClsPrefixRef, namespaceRef, inlineThemeDisabled } = useConfig(props); - const themeRef = useTheme("ColorPicker", "-color-picker", style$i, colorPickerLight$1, props, mergedClsPrefixRef); + const themeRef = useTheme("ColorPicker", "-color-picker", style$j, colorPickerLight$1, props, mergedClsPrefixRef); provide(colorPickerInjectionKey, { themeRef, renderLabelRef: toRef(props, "renderLabel"), @@ -24605,7 +24618,7 @@ const cardDark = { } }; const cardDark$1 = cardDark; -const style$h = c$1([cB("card", ` +const style$i = c$1([cB("card", ` font-size: var(--n-font-size); line-height: var(--n-line-height); display: flex; @@ -24750,7 +24763,7 @@ const NCard = defineComponent({ call(onClose); }; const { inlineThemeDisabled, mergedClsPrefixRef, mergedRtlRef } = useConfig(props); - const themeRef = useTheme("Card", "-card", style$h, cardLight$1, props, mergedClsPrefixRef); + const themeRef = useTheme("Card", "-card", style$i, cardLight$1, props, mergedClsPrefixRef); const rtlEnabledRef = useRtl("Card", mergedRtlRef, mergedClsPrefixRef); const cssVarsRef = computed(() => { const { size: size2 } = props; @@ -25039,7 +25052,7 @@ const collapseDark = { self: self$S }; const collapseDark$1 = collapseDark; -const style$g = cB("collapse", "width: 100%;", [cB("collapse-item", ` +const style$h = cB("collapse", "width: 100%;", [cB("collapse-item", ` font-size: var(--n-font-size); color: var(--n-text-color); transition: @@ -25122,7 +25135,7 @@ const NCollapse = defineComponent({ const uncontrolledExpandedNamesRef = ref(props.defaultExpandedNames); const controlledExpandedNamesRef = computed(() => props.expandedNames); const mergedExpandedNamesRef = useMergedState(controlledExpandedNamesRef, uncontrolledExpandedNamesRef); - const themeRef = useTheme("Collapse", "-collapse", style$g, collapseLight$1, props, mergedClsPrefixRef); + const themeRef = useTheme("Collapse", "-collapse", style$h, collapseLight$1, props, mergedClsPrefixRef); function doUpdateExpandedNames(names) { const { "onUpdate:expandedNames": _onUpdateExpandedNames, onUpdateExpandedNames, onExpandedNamesChange } = props; if (onUpdateExpandedNames) { @@ -25593,7 +25606,7 @@ const selectDark = { self: self$P }; const selectDark$1 = selectDark; -const style$f = c$1([cB("select", ` +const style$g = c$1([cB("select", ` z-index: auto; outline: none; width: 100%; @@ -25722,7 +25735,7 @@ const NSelect = defineComponent({ props: selectProps, setup(props) { const { mergedClsPrefixRef, mergedBorderedRef, namespaceRef, inlineThemeDisabled } = useConfig(props); - const themeRef = useTheme("Select", "-select", style$f, selectLight$1, props, mergedClsPrefixRef); + const themeRef = useTheme("Select", "-select", style$g, selectLight$1, props, mergedClsPrefixRef); const uncontrolledValueRef = ref(props.defaultValue); const controlledValueRef = toRef(props, "value"); const mergedValueRef = useMergedState(controlledValueRef, uncontrolledValueRef); @@ -26800,7 +26813,7 @@ const iconDark$1 = { self: self$J }; const iconDark$2 = iconDark$1; -const style$e = cB("icon", ` +const style$f = cB("icon", ` height: 1em; width: 1em; line-height: 1em; @@ -26828,7 +26841,7 @@ const NIcon = defineComponent({ props: iconProps, setup(props) { const { mergedClsPrefixRef, inlineThemeDisabled } = useConfig(props); - const themeRef = useTheme("Icon", "-icon", style$e, iconLight$1, props, mergedClsPrefixRef); + const themeRef = useTheme("Icon", "-icon", style$f, iconLight$1, props, mergedClsPrefixRef); const cssVarsRef = computed(() => { const { depth } = props; const { common: { cubicBezierEaseInOut: cubicBezierEaseInOut2 }, self: self2 } = themeRef.value; @@ -27322,7 +27335,7 @@ const NDropdownMenu = defineComponent({ ); } }); -const style$d = cB("dropdown-menu", ` +const style$e = cB("dropdown-menu", ` transform-origin: var(--v-transform-origin); background-color: var(--n-color); border-radius: var(--n-border-radius); @@ -27550,7 +27563,7 @@ const NDropdown = defineComponent({ } }, keyboardEnabledRef); const { mergedClsPrefixRef, inlineThemeDisabled } = useConfig(props); - const themeRef = useTheme("Dropdown", "-dropdown", style$d, dropdownLight$1, props, mergedClsPrefixRef); + const themeRef = useTheme("Dropdown", "-dropdown", style$e, dropdownLight$1, props, mergedClsPrefixRef); provide(dropdownInjectionKey, { labelFieldRef: toRef(props, "labelField"), childrenFieldRef: toRef(props, "childrenField"), @@ -28036,7 +28049,7 @@ const dialogProps = { onClose: Function }; const dialogPropKeys = keysOf(dialogProps); -const style$c = c$1([cB("dialog", ` +const style$d = c$1([cB("dialog", ` word-break: break-word; line-height: var(--n-line-height); position: relative; @@ -28144,7 +28157,7 @@ const NDialog = defineComponent({ if (onClose) onClose(); } - const themeRef = useTheme("Dialog", "-dialog", style$c, dialogLight$1, props, mergedClsPrefixRef); + const themeRef = useTheme("Dialog", "-dialog", style$d, dialogLight$1, props, mergedClsPrefixRef); const cssVarsRef = computed(() => { const { type } = props; const iconPlacement = mergedIconPlacementRef.value; @@ -28470,7 +28483,7 @@ const NModalBodyWrapper = defineComponent({ ]) : null; } }); -const style$b = c$1([cB("modal-container", ` +const style$c = c$1([cB("modal-container", ` position: fixed; left: 0; top: 0; @@ -28562,7 +28575,7 @@ const NModal = defineComponent({ setup(props) { const containerRef = ref(null); const { mergedClsPrefixRef, namespaceRef, inlineThemeDisabled } = useConfig(props); - const themeRef = useTheme("Modal", "-modal", style$b, modalLight$1, props, mergedClsPrefixRef); + const themeRef = useTheme("Modal", "-modal", style$c, modalLight$1, props, mergedClsPrefixRef); const clickedRef = useClicked(64); const clickedPositionRef = useClickPosition(); const isMountedRef = isMounted(); @@ -28752,7 +28765,7 @@ const dividerDark = { self: self$D }; const dividerDark$1 = dividerDark; -const style$a = cB("divider", ` +const style$b = cB("divider", ` position: relative; display: flex; width: 100%; @@ -28813,7 +28826,7 @@ const NDivider = defineComponent({ props: dividerProps, setup(props) { const { mergedClsPrefixRef, inlineThemeDisabled } = useConfig(props); - const themeRef = useTheme("Divider", "-divider", style$a, dividerLight$1, props, mergedClsPrefixRef); + const themeRef = useTheme("Divider", "-divider", style$b, dividerLight$1, props, mergedClsPrefixRef); const cssVarsRef = computed(() => { const { common: { cubicBezierEaseInOut: cubicBezierEaseInOut2 }, self: { color, textColor, fontWeight } } = themeRef.value; return { @@ -29209,7 +29222,7 @@ function slideInFromBottomTransition({ duration = "0.3s", leaveDuration = "0.2s" }) ]; } -const style$9 = c$1([cB("drawer", ` +const style$a = c$1([cB("drawer", ` word-break: break-word; line-height: var(--n-line-height); position: absolute; @@ -29419,7 +29432,7 @@ const NDrawer = defineComponent({ setup(props) { const { mergedClsPrefixRef, namespaceRef, inlineThemeDisabled } = useConfig(props); const isMountedRef = isMounted(); - const themeRef = useTheme("Drawer", "-drawer", style$9, drawerLight$1, props, mergedClsPrefixRef); + const themeRef = useTheme("Drawer", "-drawer", style$a, drawerLight$1, props, mergedClsPrefixRef); const uncontrolledWidthRef = ref(props.defaultWidth); const uncontrolledHeightRef = ref(props.defaultHeight); const mergedWidthRef = useMergedState(toRef(props, "width"), uncontrolledWidthRef); @@ -31623,7 +31636,7 @@ const positionProp = { type: String, default: "static" }; -const style$8 = cB("layout", ` +const style$9 = cB("layout", ` color: var(--n-text-color); background-color: var(--n-color); box-sizing: border-box; @@ -31674,7 +31687,7 @@ function createLayoutComponent(isContent) { const scrollableElRef = ref(null); const scrollbarInstRef = ref(null); const { mergedClsPrefixRef, inlineThemeDisabled } = useConfig(props); - const themeRef = useTheme("Layout", "-layout", style$8, layoutLight$1, props, mergedClsPrefixRef); + const themeRef = useTheme("Layout", "-layout", style$9, layoutLight$1, props, mergedClsPrefixRef); function scrollTo(options, y) { if (props.nativeScrollbar) { const { value: scrollableEl } = scrollableElRef; @@ -31759,7 +31772,7 @@ function createLayoutComponent(isContent) { }); } const NLayout = createLayoutComponent(false); -const style$7 = cB("layout-sider", ` +const style$8 = cB("layout-sider", ` flex-shrink: 0; box-sizing: border-box; position: relative; @@ -32063,7 +32076,7 @@ const NLayoutSider = defineComponent({ collapseModeRef: toRef(props, "collapseMode") }); const { mergedClsPrefixRef, inlineThemeDisabled } = useConfig(props); - const themeRef = useTheme("Layout", "-layout-sider", style$7, layoutLight$1, props, mergedClsPrefixRef); + const themeRef = useTheme("Layout", "-layout-sider", style$8, layoutLight$1, props, mergedClsPrefixRef); function handleTransitionend(e) { var _a2, _b; if (e.propertyName === "max-width") { @@ -32245,6 +32258,298 @@ const transferLight = createTheme({ self: self$3 }); const legacyTransferLight = transferLight; +const loadingBarProviderInjectionKey = createInjectionKey("n-loading-bar"); +const loadingBarApiInjectionKey = createInjectionKey("n-loading-bar-api"); +const style$7 = cB("loading-bar-container", ` + z-index: 5999; + position: fixed; + top: 0; + left: 0; + right: 0; + height: 2px; +`, [fadeInTransition({ + enterDuration: "0.3s", + leaveDuration: "0.8s" +}), cB("loading-bar", ` + width: 100%; + transition: + max-width 4s linear, + background .2s linear; + height: var(--n-height); + `, [cM("starting", ` + background: var(--n-color-loading); + `), cM("finishing", ` + background: var(--n-color-loading); + transition: + max-width .2s linear, + background .2s linear; + `), cM("error", ` + background: var(--n-color-error); + transition: + max-width .2s linear, + background .2s linear; + `)])]); +var __awaiter = globalThis && globalThis.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve2) { + resolve2(value); + }); + } + return new (P || (P = Promise))(function(resolve2, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve2(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +function createClassName(status, clsPrefix) { + return `${clsPrefix}-loading-bar ${clsPrefix}-loading-bar--${status}`; +} +const NLoadingBar = defineComponent({ + name: "LoadingBar", + props: { + containerStyle: [String, Object] + }, + setup() { + const { inlineThemeDisabled } = useConfig(); + const { + props: providerProps, + mergedClsPrefixRef + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + } = inject(loadingBarProviderInjectionKey); + const loadingBarRef = ref(null); + const enteringRef = ref(false); + const startedRef = ref(false); + const loadingRef = ref(false); + const transitionDisabledRef = ref(false); + let finishing = false; + const erroringRef = ref(false); + const mergedLoadingBarStyle = computed(() => { + const { loadingBarStyle } = providerProps; + if (!loadingBarStyle) + return ""; + return loadingBarStyle[erroringRef.value ? "error" : "loading"]; + }); + function init2() { + return __awaiter(this, void 0, void 0, function* () { + enteringRef.value = false; + loadingRef.value = false; + finishing = false; + erroringRef.value = false; + transitionDisabledRef.value = true; + yield nextTick(); + transitionDisabledRef.value = false; + }); + } + function start(fromProgress = 0, toProgress = 80, status = "starting") { + return __awaiter(this, void 0, void 0, function* () { + yield init2(); + loadingRef.value = true; + startedRef.value = true; + yield nextTick(); + const el = loadingBarRef.value; + if (!el) + return; + el.style.maxWidth = `${fromProgress}%`; + el.style.transition = "none"; + void el.offsetWidth; + el.className = createClassName(status, mergedClsPrefixRef.value); + el.style.transition = ""; + el.style.maxWidth = `${toProgress}%`; + }); + } + function finish() { + if (finishing || erroringRef.value || !loadingRef.value) + return; + finishing = true; + const el = loadingBarRef.value; + if (!el) + return; + el.className = createClassName("finishing", mergedClsPrefixRef.value); + el.style.maxWidth = "100%"; + void el.offsetWidth; + loadingRef.value = false; + } + function error() { + if (finishing || erroringRef.value) + return; + if (!loadingRef.value) { + void start(100, 100, "error").then(() => { + erroringRef.value = true; + const el = loadingBarRef.value; + if (!el) + return; + el.className = createClassName("error", mergedClsPrefixRef.value); + void el.offsetWidth; + loadingRef.value = false; + }); + } else { + erroringRef.value = true; + const el = loadingBarRef.value; + if (!el) + return; + el.className = createClassName("error", mergedClsPrefixRef.value); + el.style.maxWidth = "100%"; + void el.offsetWidth; + loadingRef.value = false; + } + } + function handleEnter() { + enteringRef.value = true; + } + function handleAfterEnter() { + enteringRef.value = false; + } + function handleAfterLeave() { + return __awaiter(this, void 0, void 0, function* () { + yield init2(); + }); + } + const themeRef = useTheme("LoadingBar", "-loading-bar", style$7, loadingBarLight$1, providerProps, mergedClsPrefixRef); + const cssVarsRef = computed(() => { + const { self: { height, colorError, colorLoading } } = themeRef.value; + return { + "--n-height": height, + "--n-color-loading": colorLoading, + "--n-color-error": colorError + }; + }); + const themeClassHandle = inlineThemeDisabled ? useThemeClass("loading-bar", void 0, cssVarsRef, providerProps) : void 0; + return { + mergedClsPrefix: mergedClsPrefixRef, + loadingBarRef, + started: startedRef, + loading: loadingRef, + entering: enteringRef, + transitionDisabled: transitionDisabledRef, + start, + error, + finish, + handleEnter, + handleAfterEnter, + handleAfterLeave, + mergedLoadingBarStyle, + cssVars: inlineThemeDisabled ? void 0 : cssVarsRef, + themeClass: themeClassHandle === null || themeClassHandle === void 0 ? void 0 : themeClassHandle.themeClass, + onRender: themeClassHandle === null || themeClassHandle === void 0 ? void 0 : themeClassHandle.onRender + }; + }, + render() { + if (!this.started) + return null; + const { mergedClsPrefix } = this; + return h(Transition, { + name: "fade-in-transition", + appear: true, + onEnter: this.handleEnter, + onAfterEnter: this.handleAfterEnter, + // eslint-disable-next-line @typescript-eslint/no-misused-promises + onAfterLeave: this.handleAfterLeave, + css: !this.transitionDisabled + }, { + default: () => { + var _a2; + (_a2 = this.onRender) === null || _a2 === void 0 ? void 0 : _a2.call(this); + return withDirectives(h( + "div", + { class: [ + `${mergedClsPrefix}-loading-bar-container`, + this.themeClass + ], style: this.containerStyle }, + h("div", { ref: "loadingBarRef", class: [`${mergedClsPrefix}-loading-bar`], style: [ + this.cssVars, + this.mergedLoadingBarStyle + ] }) + ), [[vShow, this.loading || !this.loading && this.entering]]); + } + }); + } +}); +const loadingBarProviderProps = Object.assign(Object.assign({}, useTheme.props), { to: { + type: [String, Object, Boolean], + default: void 0 +}, containerStyle: [String, Object], loadingBarStyle: { + type: Object +} }); +const NLoadingBarProvider = defineComponent({ + name: "LoadingBarProvider", + props: loadingBarProviderProps, + setup(props) { + const isMountedRef = isMounted(); + const loadingBarRef = ref(null); + const methods = { + start() { + var _a2; + if (isMountedRef.value) { + (_a2 = loadingBarRef.value) === null || _a2 === void 0 ? void 0 : _a2.start(); + } else { + void nextTick(() => { + var _a3; + (_a3 = loadingBarRef.value) === null || _a3 === void 0 ? void 0 : _a3.start(); + }); + } + }, + error() { + var _a2; + if (isMountedRef.value) { + (_a2 = loadingBarRef.value) === null || _a2 === void 0 ? void 0 : _a2.error(); + } else { + void nextTick(() => { + var _a3; + (_a3 = loadingBarRef.value) === null || _a3 === void 0 ? void 0 : _a3.error(); + }); + } + }, + finish() { + var _a2; + if (isMountedRef.value) { + (_a2 = loadingBarRef.value) === null || _a2 === void 0 ? void 0 : _a2.finish(); + } else { + void nextTick(() => { + var _a3; + (_a3 = loadingBarRef.value) === null || _a3 === void 0 ? void 0 : _a3.finish(); + }); + } + } + }; + const { mergedClsPrefixRef } = useConfig(props); + provide(loadingBarApiInjectionKey, methods); + provide(loadingBarProviderInjectionKey, { + props, + mergedClsPrefixRef + }); + return Object.assign(methods, { + loadingBarRef + }); + }, + render() { + var _a2, _b; + return h( + Fragment, + null, + h( + Teleport, + { disabled: this.to === false, to: this.to || "body" }, + h(NLoadingBar, { ref: "loadingBarRef", containerStyle: this.containerStyle }) + ), + (_b = (_a2 = this.$slots).default) === null || _b === void 0 ? void 0 : _b.call(_a2) + ); + } +}); const menuInjectionKey = createInjectionKey("n-menu"); const submenuInjectionKey = createInjectionKey("n-submenu"); const menuItemGroupInjectionKey = createInjectionKey("n-menu-item-group"); @@ -40575,7 +40880,7 @@ const useSettings = defineStore("settings", () => { resetSettings }; }); -const _withScopeId = (n) => (pushScopeId("data-v-37b1913e"), n = n(), popScopeId(), n); +const _withScopeId = (n) => (pushScopeId("data-v-18a00c0d"), n = n(), popScopeId(), n); const _hoisted_1 = { class: "top-bar" }; const _hoisted_2 = { key: 0 }; const _hoisted_3 = { key: 1 }; @@ -40595,7 +40900,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ __name: "TopBar", setup(__props) { useCssVars((_ctx) => ({ - "2ac8c8e2": backgroundColor.value + "7ea1c782": backgroundColor.value })); const router2 = useRouter(); const websocketState = useWebsocket(); @@ -40615,6 +40920,13 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ return a.name.localeCompare(b.name); }); }); + const sdxlModels = computed(() => { + return filteredModels.value.filter((model) => { + return model.backend === "SDXL"; + }).sort((a, b) => { + return a.name.localeCompare(b.name); + }); + }); const aitModels = computed(() => { return filteredModels.value.filter((model) => { return model.backend === "AITemplate"; @@ -41358,6 +41670,56 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ ]), _: 1 }), + createVNode(unref(NTabPane), { name: "SDXL" }, { + default: withCtx(() => [ + createVNode(unref(NScrollbar), { style: { "height": "70vh" } }, { + default: withCtx(() => [ + createVNode(unref(NCard), { + title: "Models", + style: { "height": "100%" } + }, { + default: withCtx(() => [ + (openBlock(true), createElementBlock(Fragment, null, renderList(sdxlModels.value, (model) => { + return openBlock(), createElementBlock("div", { + style: { "display": "inline-flex", "width": "100%", "align-items": "center", "justify-content": "space-between", "border-bottom": "1px solid rgb(66, 66, 71)" }, + key: model.path + }, [ + createBaseVNode("p", null, toDisplayString(model.name), 1), + createBaseVNode("div", null, [ + model.state === "loaded" ? (openBlock(), createBlock(unref(NButton), { + key: 0, + type: "error", + ghost: "", + onClick: ($event) => unloadModel(model) + }, { + default: withCtx(() => [ + createTextVNode("Unload ") + ]), + _: 2 + }, 1032, ["onClick"])) : (openBlock(), createBlock(unref(NButton), { + key: 1, + type: "success", + ghost: "", + onClick: ($event) => loadModel(model), + loading: model.state === "loading" + }, { + default: withCtx(() => [ + createTextVNode(" Load") + ]), + _: 2 + }, 1032, ["onClick", "loading"])) + ]) + ]); + }), 128)) + ]), + _: 1 + }) + ]), + _: 1 + }) + ]), + _: 1 + }), createVNode(unref(NTabPane), { name: "ONNX" }, { default: withCtx(() => [ createVNode(unref(NScrollbar), { style: { "height": "70vh" } }, { @@ -41480,7 +41842,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ }; } }); -const TopBar_vue_vue_type_style_index_0_scoped_37b1913e_lang = ""; +const TopBar_vue_vue_type_style_index_0_scoped_18a00c0d_lang = ""; const _export_sfc = (sfc, props) => { const target = sfc.__vccOpts || sfc; for (const [key, val] of props) { @@ -41488,7 +41850,7 @@ const _export_sfc = (sfc, props) => { } return target; }; -const TopBarVue = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-37b1913e"]]); +const TopBarVue = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-18a00c0d"]]); const _sfc_main$1 = {}; function _sfc_render(_ctx, _cache) { const _component_RouterView = resolveComponent("RouterView"); @@ -41499,11 +41861,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({ __name: "App", setup(__props) { useCssVars((_ctx) => ({ - "1d19c67b": backgroundColor.value, - "12b62b62": theme.value.common.popoverColor, - "753630fc": theme.value.common.borderRadius, - "53c6c405": theme.value.common.pressedColor, - "e7594bd2": theme.value.common.primaryColorHover + "29cef8cc": backgroundColor.value, + "4a43647e": theme.value.common.popoverColor, + "e4e5ec3e": theme.value.common.borderRadius, + "1beee664": theme.value.common.pressedColor, + "440cdb18": theme.value.common.primaryColorHover })); const settings = useSettings(); const theme = computed(() => { @@ -41541,13 +41903,18 @@ const _sfc_main = /* @__PURE__ */ defineComponent({ max: 3 }, { default: withCtx(() => [ - createVNode(unref(NMessageProvider), null, { + createVNode(unref(NLoadingBarProvider), null, { default: withCtx(() => [ - createVNode(_sfc_main$3), - createVNode(_sfc_main$5), - createVNode(TopBarVue), - createVNode(routerContainerVue, { style: { "margin-top": "52px" } }), - createVNode(_sfc_main$4) + createVNode(unref(NMessageProvider), null, { + default: withCtx(() => [ + createVNode(_sfc_main$3), + createVNode(_sfc_main$5), + createVNode(TopBarVue), + createVNode(routerContainerVue, { style: { "margin-top": "52px" } }), + createVNode(_sfc_main$4) + ]), + _: 1 + }) ]), _: 1 }) @@ -41611,12 +41978,12 @@ const router = createRouter({ { path: "/", name: "text2image", - component: () => __vitePreload(() => import("./TextToImageView.js"), true ? ["assets/TextToImageView.js","assets/GenerateSection.vue_vue_type_script_setup_true_lang.js","assets/GenerateSection.css","assets/ImageOutput.vue_vue_type_script_setup_true_lang.js","assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js","assets/TrashBin.js","assets/clock.js","assets/DescriptionsItem.js","assets/v4.js","assets/Switch.js","assets/Slider.js","assets/InputNumber.js"] : void 0) + component: () => __vitePreload(() => import("./TextToImageView.js"), true ? ["assets/TextToImageView.js","assets/GenerateSection.vue_vue_type_script_setup_true_lang.js","assets/GenerateSection.css","assets/ImageOutput.vue_vue_type_script_setup_true_lang.js","assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js","assets/TrashBin.js","assets/OutputStats.vue_vue_type_script_setup_true_lang.js","assets/DescriptionsItem.js","assets/clock.js","assets/v4.js","assets/Switch.js","assets/Slider.js","assets/InputNumber.js"] : void 0) }, { path: "/image2image", name: "image2image", - component: () => __vitePreload(() => import("./Image2ImageView.js"), true ? ["assets/Image2ImageView.js","assets/GenerateSection.vue_vue_type_script_setup_true_lang.js","assets/GenerateSection.css","assets/clock.js","assets/DescriptionsItem.js","assets/ImageOutput.vue_vue_type_script_setup_true_lang.js","assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js","assets/TrashBin.js","assets/ImageUpload.js","assets/CloudUpload.js","assets/ImageUpload.css","assets/v4.js","assets/Switch.js","assets/Slider.js","assets/InputNumber.js","assets/Image2ImageView.css"] : void 0) + component: () => __vitePreload(() => import("./Image2ImageView.js"), true ? ["assets/Image2ImageView.js","assets/GenerateSection.vue_vue_type_script_setup_true_lang.js","assets/GenerateSection.css","assets/clock.js","assets/ImageOutput.vue_vue_type_script_setup_true_lang.js","assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js","assets/TrashBin.js","assets/ImageUpload.js","assets/CloudUpload.js","assets/ImageUpload.css","assets/OutputStats.vue_vue_type_script_setup_true_lang.js","assets/DescriptionsItem.js","assets/v4.js","assets/Switch.js","assets/Slider.js","assets/InputNumber.js","assets/Image2ImageView.css"] : void 0) }, { path: "/extra", @@ -41626,7 +41993,7 @@ const router = createRouter({ { path: "/models", name: "models", - component: () => __vitePreload(() => import("./ModelsView.js"), true ? ["assets/ModelsView.js","assets/Switch.js","assets/TrashBin.js","assets/CloudUpload.js","assets/ModelsView.css"] : void 0) + component: () => __vitePreload(() => import("./ModelsView.js"), true ? ["assets/ModelsView.js","assets/DescriptionsItem.js","assets/GridOutline.js","assets/Slider.js","assets/Switch.js","assets/TrashBin.js","assets/CloudUpload.js","assets/ModelsView.css"] : void 0) }, { path: "/about", @@ -41646,12 +42013,12 @@ const router = createRouter({ { path: "/settings", name: "settings", - component: () => __vitePreload(() => import("./SettingsView.js"), true ? ["assets/SettingsView.js","assets/Switch.js","assets/InputNumber.js","assets/Slider.js"] : void 0) + component: () => __vitePreload(() => import("./SettingsView.js"), true ? ["assets/SettingsView.js","assets/clock.js","assets/Switch.js","assets/InputNumber.js","assets/Slider.js"] : void 0) }, { path: "/imageBrowser", name: "imageBrowser", - component: () => __vitePreload(() => import("./ImageBrowserView.js"), true ? ["assets/ImageBrowserView.js","assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js","assets/TrashBin.js","assets/Slider.js","assets/DescriptionsItem.js","assets/ImageBrowserView.css"] : void 0) + component: () => __vitePreload(() => import("./ImageBrowserView.js"), true ? ["assets/ImageBrowserView.js","assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js","assets/GridOutline.js","assets/TrashBin.js","assets/Slider.js","assets/DescriptionsItem.js","assets/ImageBrowserView.css"] : void 0) }, { path: "/tagger", @@ -41667,7 +42034,7 @@ app.use(pinia); app.use(router); app.mount("#app"); export { - cM as $, + onMounted as $, pushScopeId as A, popScopeId as B, resolveComponent as C, @@ -41677,137 +42044,149 @@ export { NIcon as G, NTabPane as H, NTabs as I, - watch as J, - upscalerOptions as K, - Fragment as L, - renderList as M, + upscalerOptions as J, + Fragment as K, + renderList as L, + NScrollbar as M, NGi as N, - NScrollbar as O, - replaceable as P, - useConfig as Q, - useFormItem as R, - useMergedState as S, + upperFirst$1 as O, + toString as P, + createCompounder as Q, + replaceable as R, + cloneVNode as S, provide as T, - toRef as U, - createInjectionKey as V, - call as W, - c$1 as X, - cB as Y, - cE as Z, + createInjectionKey as U, + inject as V, + throwError as W, + useConfig as X, + onBeforeUpdate as Y, + indexMap as Z, _export_sfc as _, useSettings as a, - AddIcon as a$, - iconSwitchTransition as a0, - insideModal as a1, - insidePopover as a2, - inject as a3, - useMemo as a4, - useTheme as a5, - checkboxLight$1 as a6, - useRtl as a7, - createKey as a8, - useThemeClass as a9, - radioLight$1 as aA, - resolveWrappedSlot as aB, - flatten$2 as aC, - getSlot$1 as aD, - depx as aE, - formatLength as aF, - NScrollbar$1 as aG, - onBeforeUnmount as aH, - off as aI, - ChevronDownIcon as aJ, - NDropdown as aK, - pxfy as aL, - get as aM, - NBaseLoading as aN, - ChevronRightIcon as aO, - VResizeObserver as aP, - warn$2 as aQ, - VVirtualList as aR, - NEmpty as aS, - cssrAnchorMetaName as aT, - repeat as aU, - beforeNextFrameOnce as aV, - fadeInScaleUpTransition as aW, - Transition as aX, - dataTableLight$1 as aY, - throwError as aZ, - isBrowser$3 as a_, - createId as aa, - NIconSwitchTransition as ab, - on as ac, - popselectLight$1 as ad, - NInternalSelectMenu as ae, - createTreeMate as af, - happensIn as ag, - nextTick as ah, - keysOf as ai, - createTmOptions as aj, - keep as ak, - createRefSetter as al, - mergeEventHandlers as am, - omit as an, - NPopover as ao, - popoverBaseProps as ap, - cNotM as aq, - useLocale as ar, - watchEffect as as, - resolveSlot as at, - NBaseIcon as au, - useAdjustedTo as av, - paginationLight$1 as aw, - ellipsisLight$1 as ax, - onDeactivated as ay, - mergeProps as az, + NDropdown as a$, + onBeforeUnmount as a0, + cB as a1, + cE as a2, + c$1 as a3, + cM as a4, + useMergedState as a5, + toRef as a6, + watchEffect as a7, + onUpdated as a8, + watch as a9, + popselectLight$1 as aA, + NInternalSelectMenu as aB, + createTreeMate as aC, + happensIn as aD, + keysOf as aE, + createTmOptions as aF, + createRefSetter as aG, + mergeEventHandlers as aH, + omit as aI, + NPopover as aJ, + popoverBaseProps as aK, + cNotM as aL, + useLocale as aM, + resolveSlot as aN, + NBaseIcon as aO, + useAdjustedTo as aP, + paginationLight$1 as aQ, + ellipsisLight$1 as aR, + onDeactivated as aS, + mergeProps as aT, + radioLight$1 as aU, + resolveWrappedSlot as aV, + getSlot$1 as aW, + depx as aX, + formatLength as aY, + NScrollbar$1 as aZ, + ChevronDownIcon as a_, + useTheme as aa, + useThemeClass as ab, + flatten$2 as ac, + VResizeObserver as ad, + resolveSlotWithProps as ae, + withDirectives as af, + vShow as ag, + Transition as ah, + keep as ai, + off as aj, + carouselLight$1 as ak, + normalizeStyle as al, + getPreciseEventTarget as am, + on as an, + nextTick as ao, + useFormItem as ap, + call as aq, + iconSwitchTransition as ar, + insideModal as as, + insidePopover as at, + useMemo as au, + checkboxLight$1 as av, + useRtl as aw, + createKey as ax, + createId as ay, + NIconSwitchTransition as az, useMessage as b, - NProgress as b0, - NFadeInExpandTransition as b1, - EyeIcon as b2, - fadeInHeightExpandTransition as b3, - Teleport as b4, - uploadLight$1 as b5, - NResult as b6, - reactive as b7, - huggingfaceModelsFile as b8, - NModal as b9, - NAlert as bA, - inputNumberLight$1 as bB, - rgba as bC, - XButton as bD, - isSlotEmpty as bE, - switchLight$1 as bF, - onBeforeUpdate as bG, - VBinder as bH, - VTarget as bI, - VFollower as bJ, - sliderLight$1 as bK, - NText as ba, - stepsLight$1 as bb, - FinishedIcon as bc, - ErrorIcon$1 as bd, - getCurrentInstance as be, - formLight$1 as bf, - commonVariables$m as bg, - formItemInjectionKey as bh, - onMounted as bi, - useNotification as bj, - defaultSettings as bk, - useCssVars as bl, - urlFromPath as bm, - useCompitable as bn, - descriptionsLight$1 as bo, - useRouter as bp, - fadeInTransition as bq, - imageLight as br, - isMounted as bs, - LazyTeleport as bt, - withDirectives as bu, - zindexable$1 as bv, - vShow as bw, - normalizeStyle as bx, - kebabCase$1 as by, - withModifiers as bz, + pxfy as b0, + get as b1, + NBaseLoading as b2, + ChevronRightIcon as b3, + warn$2 as b4, + VVirtualList as b5, + NEmpty as b6, + cssrAnchorMetaName as b7, + repeat as b8, + beforeNextFrameOnce as b9, + useNotification as bA, + defaultSettings as bB, + urlFromPath as bC, + useRouter as bD, + useCompitable as bE, + descriptionsLight$1 as bF, + fadeInTransition as bG, + imageLight as bH, + isMounted as bI, + LazyTeleport as bJ, + zindexable$1 as bK, + kebabCase$1 as bL, + withModifiers as bM, + NAlert as bN, + inputNumberLight$1 as bO, + rgba as bP, + XButton as bQ, + isSlotEmpty as bR, + switchLight$1 as bS, + VBinder as bT, + VTarget as bU, + VFollower as bV, + sliderLight$1 as bW, + fadeInScaleUpTransition as ba, + dataTableLight$1 as bb, + loadingBarApiInjectionKey as bc, + rateLight as bd, + color2Class as be, + isBrowser$3 as bf, + AddIcon as bg, + NProgress as bh, + NFadeInExpandTransition as bi, + EyeIcon as bj, + fadeInHeightExpandTransition as bk, + Teleport as bl, + uploadLight$1 as bm, + reactive as bn, + NTag as bo, + NModal as bp, + useCssVars as bq, + huggingfaceModelsFile as br, + NText as bs, + stepsLight$1 as bt, + FinishedIcon as bu, + ErrorIcon$1 as bv, + getCurrentInstance as bw, + formLight$1 as bx, + commonVariables$m as by, + formItemInjectionKey as bz, computed as c, defineComponent as d, openBlock as e, diff --git a/frontend/src/components/TopBar.vue b/frontend/src/components/TopBar.vue index 1fbc30118..c7d6fb904 100644 --- a/frontend/src/components/TopBar.vue +++ b/frontend/src/components/TopBar.vue @@ -283,6 +283,43 @@ + + + +
+

{{ model.name }}

+
+ Unload + + + Load +
+
+
+
+
@@ -438,6 +475,16 @@ const pyTorchModels = computed(() => { }); }); +const sdxlModels = computed(() => { + return filteredModels.value + .filter((model) => { + return model.backend === "SDXL"; + }) + .sort((a, b) => { + return a.name.localeCompare(b.name); + }); +}); + const aitModels = computed(() => { return filteredModels.value .filter((model) => { diff --git a/frontend/src/core/interfaces.ts b/frontend/src/core/interfaces.ts index c44758707..332cdf0a2 100644 --- a/frontend/src/core/interfaces.ts +++ b/frontend/src/core/interfaces.ts @@ -20,6 +20,7 @@ export interface ModelEntry { path: string; backend: | "PyTorch" + | "SDXL" | "AITemplate" | "ONNX" | "unknown" diff --git a/frontend/src/views/TestView.vue b/frontend/src/views/TestView.vue index 52830d27f..595fa8f0c 100644 --- a/frontend/src/views/TestView.vue +++ b/frontend/src/views/TestView.vue @@ -1,7 +1,3 @@ - - diff --git a/frontend/src/views/TextToImageView.vue b/frontend/src/views/TextToImageView.vue index 9d5c1a0cc..24026270d 100644 --- a/frontend/src/views/TextToImageView.vue +++ b/frontend/src/views/TextToImageView.vue @@ -1,588 +1,7 @@ From e822f21233ee56aea41da3f00b65564524efb103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Kissik?= Date: Thu, 9 Nov 2023 09:44:33 +0100 Subject: [PATCH 029/143] Reload-less more feature-proof clip skip --- core/inference/functions.py | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/core/inference/functions.py b/core/inference/functions.py index 0cfb142ee..88edf99eb 100644 --- a/core/inference/functions.py +++ b/core/inference/functions.py @@ -393,19 +393,20 @@ def load_pytorch_pipeline( for name, text_encoder in [x for x in vars(pipe).items() if "text_encoder" in x[0]]: text_encoder: CLIPTextModel if text_encoder is not None: - conf = text_encoder.config - conf.num_hidden_layers = conf.num_hidden_layers - ( - config.api.clip_skip - * (2 if text_encoder is CLIPTextModelWithProjection else 1) - ) - logger.debug(f"Replacing {name}s layers to {conf.num_hidden_layers}.") - setattr( - pipe, - name, - text_encoder.__class__.from_pretrained( - None, config=conf, state_dict=text_encoder.state_dict() - ), - ) + def new_forward( + self, + inputs_embeds, + attention_mask: Optional[torch.Tensor] = None, + causal_attention_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + ): + n = [] + original = self.old_forward(inputs_embeds, attention_mask=attention_mask, causal_attention_mask=causal_attention_mask, output_attentions=output_attentions, output_hidden_states=True, return_dict=return_dict) + n.append(original.hidden_states[-config.api.clip_skip]) + return n + if config.api.clip_quantization != "full": from transformers import BitsAndBytesConfig from transformers.utils.bitsandbytes import ( @@ -435,7 +436,10 @@ def load_pytorch_pipeline( set_module_quantized_tensor_to_device(nt, k, config.api.device, v) setattr(pipe, name, nt) del state_dict, dont_convert - del conf + + text_encoder.text_model.encoder.old_forward = text_encoder.text_model.encoder.forward # type: ignore + text_encoder.text_model.encoder.forward = new_forward # type: ignore + logger.debug(f"Overwritten {name}s final_layer_norm.") if optimize: from core.optimizations import optimize_model From 270caa33b49b12430c5f567b02febe4cdef01ef0 Mon Sep 17 00:00:00 2001 From: gabe56f Date: Thu, 9 Nov 2023 16:01:53 +0100 Subject: [PATCH 030/143] T2I --- core/flags.py | 15 ++- core/inference/pytorch/pipeline.py | 171 +++++++++++++++++++++----- core/inference/sdxl/pipeline.py | 175 +++++++++++++++++++++++---- core/inference/sdxl/sdxl.py | 38 +++++- core/inference/utilities/__init__.py | 1 + core/inference/utilities/latents.py | 30 +++++ 6 files changed, 368 insertions(+), 62 deletions(-) diff --git a/core/flags.py b/core/flags.py index cb649d0b8..f65a68f7e 100644 --- a/core/flags.py +++ b/core/flags.py @@ -1,5 +1,5 @@ -from dataclasses import dataclass -from typing import Literal +from dataclasses import dataclass, field +from typing import List, Literal from dataclasses_json.api import DataClassJsonMixin @@ -30,7 +30,16 @@ class HighResFixFlag(Flag, DataClassJsonMixin): @dataclass -class RefinerFlag(Flag, DataClassJsonMixin): +class XLFlag(Flag, DataClassJsonMixin): + "Flag for SDXL settings" + + aesthetic_score: float = 6.0 + negative_aesthetic_score: float = 2.5 + original_size: List[int] = field(default_factory=lambda: [1024, 1024]) + + +@dataclass +class XLRefinerFlag(Flag, DataClassJsonMixin): "Flag for SDXL refiners" steps: int = 50 diff --git a/core/inference/pytorch/pipeline.py b/core/inference/pytorch/pipeline.py index f621257ab..9018204ae 100644 --- a/core/inference/pytorch/pipeline.py +++ b/core/inference/pytorch/pipeline.py @@ -4,9 +4,16 @@ from typing import Any, Callable, Dict, List, Literal, Optional, Union import PIL +from PIL import Image import torch from diffusers import LMSDiscreteScheduler, SchedulerMixin, StableDiffusionPipeline -from diffusers.models import AutoencoderKL, ControlNetModel, UNet2DConditionModel +from diffusers.models import ( + AutoencoderKL, + ControlNetModel, + UNet2DConditionModel, + T2IAdapter, + MultiAdapter, +) from diffusers.pipelines.stable_diffusion import StableDiffusionPipelineOutput from diffusers.utils import logging from tqdm import tqdm @@ -25,6 +32,7 @@ prepare_mask_and_masked_image, prepare_mask_latents, preprocess_image, + preprocess_adapter_image, ) from core.optimizations import upcast_vae, ensure_correct_device, unload_all from core.inference.utilities.philox import PhiloxGenerator @@ -119,6 +127,42 @@ def _execution_device(self): return self.device return getattr(self.unet, "offload_device", self.device) + def _default_height_width(self, height, width, image): + if image is None: + return height, width + + # NOTE: It is possible that a list of images have different + # dimensions for each image, so just checking the first image + # is not _exactly_ correct, but it is simple. + while isinstance(image, list): + image = image[0] + + if height is None: + if isinstance(image, Image.Image): + height = image.height + elif isinstance(image, torch.Tensor): + height = image.shape[-2] + + # round down to nearest multiple of `self.adapter.downscale_factor` + if hasattr(self, "adapter") and self.adapter is not None: + height = ( + height // self.adapter.downscale_factor + ) * self.adapter.downscale_factor + + if width is None: + if isinstance(image, Image.Image): + width = image.width + elif isinstance(image, torch.Tensor): + width = image.shape[-1] + + # round down to nearest multiple of `self.adapter.downscale_factor` + if hasattr(self, "adapter") and self.adapter is not None: + width = ( + width // self.adapter.downscale_factor + ) * self.adapter.downscale_factor + + return height, width + def _encode_prompt( self, prompt, @@ -256,6 +300,8 @@ def __call__( callback_steps: int = 1, seed: int = 0, prompt_expansion_settings: Optional[Dict] = None, + adapter_conditioning_scale: Union[float, List[float]] = 1.0, + adapter_conditioning_factor: float = 1.0, ): r""" Function invoked when calling the pipeline for generation. @@ -337,6 +383,8 @@ def __call__( self.unet = inf.unet # type: ignore self.vae = inf.vae # type: ignore + height, width = self._default_height_width(height, width, image) + # 1. Check inputs. Raise error if not correct self._check_inputs(prompt, strength, callback_steps) if hasattr(self, "controlnet"): @@ -372,6 +420,26 @@ def __call__( ).to(device) dtype = text_embeddings.dtype + adapter_input = None # type: ignore + if hasattr(self, "adapter"): + if isinstance(self.adapter, MultiAdapter): + adapter_input: list = [] # type: ignore + + if not isinstance(adapter_conditioning_scale, list): + adapter_conditioning_scale = [ + adapter_conditioning_scale * len(image) + ] + + for oi in image: + oi = preprocess_adapter_image(oi, height, width) + oi = oi.to(device, dtype) + adapter_input.append(oi) # type: ignore + else: + adapter_input: torch.Tensor = preprocess_adapter_image( # type: ignore + adapter_input, height, width + ) + adapter_input.to(device, dtype) + # 4. Preprocess image and mask if isinstance(image, PIL.Image.Image): # type: ignore width, height = image.size # type: ignore @@ -442,6 +510,24 @@ def __call__( # 7. Prepare extra step kwargs. TODO: Logic should ideally just be moved out of the pipeline extra_step_kwargs = prepare_extra_step_kwargs(self.scheduler, eta, generator) # type: ignore + if hasattr(self, "adapter"): + if isinstance(self.adapter, MultiAdapter): + adapter_state = self.adapter( + adapter_input, adapter_conditioning_scale + ) + for k, v in enumerate(adapter_state): + adapter_state[k] = v + else: + adapter_state = self.adapter(adapter_input) + for k, v in enumerate(adapter_state): + adapter_state[k] = v * adapter_conditioning_scale + if num_images_per_prompt > 1: # type: ignore + for k, v in enumerate(adapter_state): + adapter_state[k] = v.repeat(num_images_per_prompt, 1, 1, 1) + if do_classifier_free_guidance: + for k, v in enumerate(adapter_state): + adapter_state[k] = torch.cat([v] * 2, dim=0) + controlnet_keep = [] if hasattr(self, "controlnet"): for i in range(len(timesteps)): @@ -464,12 +550,17 @@ def get_map_size(_, __, output): -2: ] # output.sample.shape[-2:] in older diffusers + cutoff = num_inference_steps * adapter_conditioning_factor + # 8. Denoising loop + j = 0 + def do_denoise( x: torch.Tensor, t: torch.IntTensor, call: Callable[..., torch.Tensor], change_source: Callable[[Callable], None], ): + nonlocal j # expand the latents if we are doing classifier free guidance latent_model_input = ( torch.cat([x] * 2) if do_classifier_free_guidance and not split_latents_into_two else x # type: ignore @@ -480,20 +571,16 @@ def do_denoise( latent_model_input = torch.cat([latent_model_input, mask, masked_image_latents], dim=1) # type: ignore # predict the noise residual - if not hasattr(self, "controlnet"): - if split_latents_into_two: - uncond, cond = text_embeddings.chunk(2) - noise_pred_text = call(latent_model_input, t, cond=cond) - noise_pred_uncond = call(latent_model_input, t, cond=uncond) - else: - noise_pred = call( # type: ignore - latent_model_input, - t, - cond=text_embeddings, - ) - else: - assert self.controlnet is not None + down_intrablock_additional_residuals = None + if hasattr(self, "adapter") and self.adapter is not None: + if j < cutoff: + assert adapter_state is not None + down_intrablock_additional_residuals = [ + state.clone() for state in adapter_state + ] + down_block_res_samples, mid_block_res_sample = None, None + if hasattr(self, "controlnet") and self.controlnet is not None: if guess_mode and do_classifier_free_guidance: # Infer ControlNet only for the conditional batch. control_model_input = x @@ -534,25 +621,43 @@ def do_denoise( ] ) - change_source(self.unet) - if split_latents_into_two: - uncond, cond = text_embeddings.chunk(2) - noise_pred_text = call( - latent_model_input, - t, - cond=cond, - down_block_additional_residuals=down_block_res_samples, - mid_block_additional_residual=mid_block_res_sample, - ) - noise_pred_uncond = call(latent_model_input, t, cond=uncond) - else: - noise_pred = call( # type: ignore - latent_model_input, - t, - cond=text_embeddings, - down_block_additional_residuals=down_block_res_samples, - mid_block_additional_residual=mid_block_res_sample, - ) + change_source(self.unet) + if split_latents_into_two and do_classifier_free_guidance: + uncond, cond = text_embeddings.chunk(2) + uncond_down, cond_down = down_block_res_samples.chunk(2) + uncond_mid, cond_mid = mid_block_res_sample.chunk(2) + uncond_intra, cond_intra = None, None + if down_intrablock_additional_residuals is not None: + uncond_intra, cond_intra = [], [] + for s in down_intrablock_additional_residuals: + unc, cnd = s.chunk(2) + uncond_intra.append(unc) + cond_intra.append(cnd) + noise_pred_text = call( + latent_model_input, + t, + cond=cond, + down_block_additional_residuals=cond_down, + mid_block_additional_residual=cond_mid, + down_intrablock_additional_residuals=cond_intra, + ) + noise_pred_uncond = call( + latent_model_input, + t, + cond=uncond, + down_block_additional_residuals=uncond_down, + mid_block_additional_residual=uncond_mid, + down_intrablock_additional_residuals=uncond_intra, + ) + else: + noise_pred = call( # type: ignore + latent_model_input, + t, + cond=text_embeddings, + down_block_additional_residuals=down_block_res_samples, + mid_block_additional_residual=mid_block_res_sample, + down_intrablock_additional_residuals=down_intrablock_additional_residuals, + ) # perform guidance if do_classifier_free_guidance: diff --git a/core/inference/sdxl/pipeline.py b/core/inference/sdxl/pipeline.py index 2c7b65d8d..402d2a2e6 100644 --- a/core/inference/sdxl/pipeline.py +++ b/core/inference/sdxl/pipeline.py @@ -1,11 +1,17 @@ -from typing import Callable, Literal, Optional, Union +from typing import Callable, List, Literal, Optional, Union import logging import PIL +from PIL import Image import torch from tqdm import tqdm from diffusers import LMSDiscreteScheduler, SchedulerMixin, StableDiffusionXLPipeline -from diffusers.models import AutoencoderKL, UNet2DConditionModel +from diffusers.models import ( + AutoencoderKL, + MultiAdapter, + T2IAdapter, + UNet2DConditionModel, +) from diffusers.pipelines.stable_diffusion import ( StableDiffusionPipelineOutput, ) @@ -18,6 +24,7 @@ from core.config import config from core.inference.utilities import ( prepare_latents, + preprocess_adapter_image, preprocess_image, preprocess_mask, prepare_mask_latents, @@ -28,7 +35,6 @@ full_vae, numpy_to_pil, philox, - Placebo, ) from core.scheduling import KdiffusionSchedulerAdapter from core.optimizations import ( @@ -86,6 +92,42 @@ def __init__additional__(self): 2 ** (len(self.vae.config.block_out_channels) - 1), # type: ignore ) + def _default_height_width(self, height, width, image): + if image is None: + return height, width + + # NOTE: It is possible that a list of images have different + # dimensions for each image, so just checking the first image + # is not _exactly_ correct, but it is simple. + while isinstance(image, list): + image = image[0] + + if height is None: + if isinstance(image, Image.Image): + height = image.height + elif isinstance(image, torch.Tensor): + height = image.shape[-2] + + # round down to nearest multiple of `self.adapter.downscale_factor` + if hasattr(self, "adapter") and self.adapter is not None: + height = ( + height // self.adapter.downscale_factor + ) * self.adapter.downscale_factor + + if width is None: + if isinstance(image, Image.Image): + width = image.width + elif isinstance(image, torch.Tensor): + width = image.shape[-1] + + # round down to nearest multiple of `self.adapter.downscale_factor` + if hasattr(self, "adapter") and self.adapter is not None: + width = ( + width // self.adapter.downscale_factor + ) * self.adapter.downscale_factor + + return height, width + @property def _execution_device(self): r""" @@ -126,9 +168,11 @@ def _encode_prompt( for prompt, negative_prompt, tokenizer, text_encoder in zip( prompts, negative_prompts, tokenizers, text_encoders ): + prompt = self.maybe_convert_prompt(prompt, tokenizer) logger.debug(f"Post textual prompt: {prompt}") if negative_prompt is not None: + negative_prompt = self.maybe_convert_prompt(negative_prompt, tokenizer) logger.debug(f"Post textual negative_prompt: {negative_prompt}") ensure_correct_device(text_encoder) @@ -237,6 +281,9 @@ def __call__( prompt: str, generator: Union[torch.Generator, philox.PhiloxGenerator], seed: int, + aesthetic_score: float = 6.0, + negative_aesthetic_score: float = 2.5, + original_size: List[int] = [1024, 1024], negative_prompt: Optional[str] = None, image: Union[torch.FloatTensor, PIL.Image.Image] = None, # type: ignore mask_image: Union[torch.FloatTensor, PIL.Image.Image] = None, # type: ignore @@ -245,7 +292,7 @@ def __call__( num_inference_steps: int = 50, guidance_scale: float = 7.5, strength: float = 0.8, - num_images_per_prompt: Optional[int] = 1, + num_images_per_prompt: int = 1, eta: float = 0.0, latents: Optional[torch.FloatTensor] = None, max_embeddings_multiples: Optional[int] = 100, @@ -255,10 +302,9 @@ def __call__( is_cancelled_callback: Optional[Callable[[], bool]] = None, callback_steps: int = 1, prompt_expansion_settings=None, + adapter_conditioning_scale: Union[float, List[float]] = 1.0, + adapter_conditioning_factor: float = 1.0, ): - aesthetic_score = 6.0 - negative_aesthetic_score = 2.5 - if config.api.torch_compile: self.unet = torch.compile( self.unet, @@ -272,6 +318,8 @@ def __call__( self.unet = context.unet # type: ignore self.vae = context.vae # type: ignore + height, width = self._default_height_width(height, width, image) + # 2. Define call parameters batch_size = 1 if isinstance(prompt, str) else len(prompt) device = self._execution_device @@ -300,12 +348,32 @@ def __call__( ) dtype = prompt_embeds.dtype + adapter_input = None # type: ignore + if hasattr(self, "adapter"): + if isinstance(self.adapter, MultiAdapter): + adapter_input: list = [] # type: ignore + + if not isinstance(adapter_conditioning_scale, list): + adapter_conditioning_scale = [ + adapter_conditioning_scale * len(image) + ] + + for oi in image: + oi = preprocess_adapter_image(oi, height, width) + oi = oi.to(device, dtype) + adapter_input.append(oi) # type: ignore + else: + adapter_input: torch.Tensor = preprocess_adapter_image( # type: ignore + adapter_input, height, width + ) + adapter_input.to(device, dtype) + # 4. Preprocess image and mask - if isinstance(image, PIL.Image.Image): # type: ignore + if isinstance(image, Image.Image): image = preprocess_image(image) if image is not None: image = image.to(device=device, dtype=dtype) - if isinstance(mask_image, PIL.Image.Image): # type: ignore + if isinstance(mask_image, Image.Image): mask_image = preprocess_mask(mask_image) if mask_image is not None: mask, masked_image, _ = prepare_mask_and_masked_image( @@ -314,7 +382,7 @@ def __call__( mask, _ = prepare_mask_latents( mask, masked_image, - batch_size * num_images_per_prompt, # type: ignore + batch_size * num_images_per_prompt, height, width, dtype, @@ -340,14 +408,14 @@ def __call__( if isinstance(self.scheduler, KdiffusionSchedulerAdapter): self.scheduler.timesteps = timesteps self.scheduler.steps = num_inference_steps - latent_timestep = timesteps[:1].repeat(batch_size * num_images_per_prompt) # type: ignore + latent_timestep = timesteps[:1].repeat(batch_size * num_images_per_prompt) # 6. Prepare latent variables latents, init_latents_orig, noise = prepare_latents( self, # type: ignore image, latent_timestep, - batch_size * num_images_per_prompt, # type: ignore + batch_size * num_images_per_prompt, height, width, dtype, @@ -361,9 +429,26 @@ def __call__( scheduler=self.scheduler, generator=generator, eta=eta ) + if hasattr(self, "adapter"): + if isinstance(self.adapter, MultiAdapter): + adapter_state = self.adapter( + adapter_input, adapter_conditioning_scale + ) + for k, v in enumerate(adapter_state): + adapter_state[k] = v + else: + adapter_state = self.adapter(adapter_input) + for k, v in enumerate(adapter_state): + adapter_state[k] = v * adapter_conditioning_scale + if num_images_per_prompt > 1: + for k, v in enumerate(adapter_state): + adapter_state[k] = v.repeat(num_images_per_prompt, 1, 1, 1) + if do_classifier_free_guidance: + for k, v in enumerate(adapter_state): + adapter_state[k] = torch.cat([v] * 2, dim=0) add_text_embeds = pooled_prompt_embeds add_time_ids, add_neg_time_ids = self._get_add_time_ids( - (height, width), + original_size, (0, 0), (height, width), aesthetic_score, @@ -383,44 +468,67 @@ def __call__( add_text_embeds = add_text_embeds.to(device) add_time_ids = add_time_ids.to(device).repeat(batch_size * num_images_per_prompt, 1) # type: ignore + cutoff = num_inference_steps * adapter_conditioning_factor # 8. Denoising loop + j = 0 + def do_denoise( x: torch.Tensor, t: torch.IntTensor, call: Callable[..., torch.Tensor], change_source: Callable[[Callable], None], ) -> torch.Tensor: + nonlocal j + # expand the latents if we are doing classifier free guidance latent_model_input = ( torch.cat([x] * 2) if do_classifier_free_guidance and not split_latents_into_two else x # type: ignore ) latent_model_input = self.scheduler.scale_model_input(latent_model_input, t) # type: ignore + down_intrablock_additional_residuals = None + if hasattr(self, "adapter") and self.adapter is not None: + if j < cutoff: + assert adapter_state is not None + down_intrablock_additional_residuals = [ + state.clone() for state in adapter_state + ] + if split_latents_into_two: uncond, cond = prompt_embeds.chunk(2) uncond_text, cond_text = add_text_embeds.chunk(2) uncond_time, cond_time = add_time_ids.chunk(2) + uncond_intra, cond_intra = None, None + if down_intrablock_additional_residuals is not None: + uncond_intra, cond_intra = [], [] + for s in down_intrablock_additional_residuals: + unc, cnd = s.chunk(2) + uncond_intra.append(unc) + cond_intra.append(cnd) added_cond_kwargs = { "text_embeds": cond_text, "time_ids": cond_time, } + added_uncond_kwargs = { + "text_embeds": uncond_text, + "time_ids": uncond_time, + } + noise_pred_text = call( latent_model_input, t, cond=cond, added_cond_kwargs=added_cond_kwargs, + down_intrablock_additional_residuals=cond_intra, ) - added_cond_kwargs = { - "text_embeds": uncond_text, - "time_ids": uncond_time, - } noise_pred_uncond = call( latent_model_input, t, cond=uncond, - added_cond_kwargs=added_cond_kwargs, + added_cond_kwargs=added_uncond_kwargs, + down_intrablock_additional_residuals=uncond_intra, ) else: added_cond_kwargs = { @@ -432,6 +540,7 @@ def do_denoise( t, cond=prompt_embeds, added_cond_kwargs=added_cond_kwargs, + down_intrablock_additional_residuals=down_intrablock_additional_residuals, ) # perform guidance @@ -442,7 +551,6 @@ def do_denoise( noise_pred_text - noise_pred_uncond # type: ignore ) # type: ignore - # compute the previous noisy sample x_t -> x_t-1 if not isinstance(self.scheduler, KdiffusionSchedulerAdapter): # compute the previous noisy sample x_t -> x_t-1 x = self.scheduler.step( # type: ignore @@ -457,6 +565,7 @@ def do_denoise( init_latents_orig, noise, torch.tensor([t]) # type: ignore ) x = (init_latents_proper * mask) + (x * (1 - mask)) # type: ignore + j += 1 return x ensure_correct_device(self.unet) @@ -524,12 +633,15 @@ def text2img( generator: Union[torch.Generator, philox.PhiloxGenerator], prompt: str, seed: int, + aesthetic_score: float = 6.0, + negative_aesthetic_score: float = 2.5, + original_size: List[int] = [1024, 1024], negative_prompt: Optional[str] = None, height: int = 512, width: int = 512, num_inference_steps: int = 50, guidance_scale: float = 7.5, - num_images_per_prompt: Optional[int] = 1, + num_images_per_prompt: int = 1, eta: float = 0.0, latents: Optional[torch.FloatTensor] = None, max_embeddings_multiples: Optional[int] = 100, @@ -541,6 +653,9 @@ def text2img( prompt_expansion_settings=None, ): return self.__call__( + aesthetic_score=aesthetic_score, + negative_aesthetic_score=negative_aesthetic_score, + original_size=original_size, prompt=prompt, negative_prompt=negative_prompt, seed=seed, @@ -563,15 +678,18 @@ def text2img( def img2img( self, - image: Union[torch.FloatTensor, PIL.Image.Image], # type: ignore + image: Union[torch.FloatTensor, Image.Image], prompt: str, seed: int, generator: Union[torch.Generator, philox.PhiloxGenerator], + aesthetic_score: float = 6.0, + negative_aesthetic_score: float = 2.5, + original_size: List[int] = [1024, 1024], negative_prompt: Optional[str] = None, strength: float = 0.8, - num_inference_steps: Optional[int] = 50, + num_inference_steps: int = 50, guidance_scale: Optional[float] = 7.5, - num_images_per_prompt: Optional[int] = 1, + num_images_per_prompt: int = 1, eta: Optional[float] = 0.0, max_embeddings_multiples: Optional[int] = 100, output_type: Literal["pil", "latent"] = "pil", @@ -582,6 +700,9 @@ def img2img( prompt_expansion_settings=None, ): return self.__call__( + aesthetic_score=aesthetic_score, + negative_aesthetic_score=negative_aesthetic_score, + original_size=original_size, prompt=prompt, seed=seed, negative_prompt=negative_prompt, @@ -608,11 +729,14 @@ def inpaint( prompt: str, seed: int, generator: Union[torch.Generator, philox.PhiloxGenerator], + aesthetic_score: float = 6.0, + negative_aesthetic_score: float = 2.5, + original_size: List[int] = [1024, 1024], negative_prompt: Optional[str] = None, strength: float = 0.8, num_inference_steps: Optional[int] = 50, guidance_scale: Optional[float] = 7.5, - num_images_per_prompt: Optional[int] = 1, + num_images_per_prompt: int = 1, eta: Optional[float] = 0.0, max_embeddings_multiples: Optional[int] = 100, output_type: Literal["pil", "latent"] = "pil", @@ -625,6 +749,9 @@ def inpaint( prompt_expansion_settings=None, ): return self.__call__( + aesthetic_score=aesthetic_score, + negative_aesthetic_score=negative_aesthetic_score, + original_size=original_size, prompt=prompt, seed=seed, negative_prompt=negative_prompt, diff --git a/core/inference/sdxl/sdxl.py b/core/inference/sdxl/sdxl.py index 1894d8b02..c202d6d33 100644 --- a/core/inference/sdxl/sdxl.py +++ b/core/inference/sdxl/sdxl.py @@ -19,8 +19,9 @@ from api import websocket_manager from api.websockets import Data +from core import shared from core.config import config -from core.flags import RefinerFlag +from core.flags import XLRefinerFlag, XLFlag from core.inference.base_model import InferenceModel from core.inference.functions import convert_vaept_to_diffusers, load_pytorch_pipeline from core.inference.utilities import change_scheduler, create_generator @@ -158,14 +159,24 @@ def txt2img(self, job: Txt2ImgQueueEntry) -> List[Image.Image]: sampler_settings=job.data.sampler_settings, ) generator = create_generator(job.data.seed) + shared.current_method = "txt2img" for _ in tqdm(range(job.data.batch_count), desc="Queue", position=1): output_type = "pil" + xl_flag: XLFlag + if "sdxl" in job.flags: + xl_flag = XLFlag.from_dict(job.flags["sdxl"]) + else: + xl_flag = XLFlag() + if "refiner" in job.flags: output_type = "latent" data = pipe.text2img( + aesthetic_score=xl_flag.aesthetic_score, + negative_aesthetic_score=xl_flag.negative_aesthetic_score, + original_size=xl_flag.original_size, generator=generator, prompt=job.data.prompt, height=job.data.height, @@ -182,7 +193,7 @@ def txt2img(self, job: Txt2ImgQueueEntry) -> List[Image.Image]: if output_type == "latent": latents: torch.FloatTensor = data[0] # type: ignore - flags = RefinerFlag.from_dict(job.flags["refiner"]) + flags = XLRefinerFlag.from_dict(job.flags["refiner"]) from core.shared_dependent import gpu @@ -198,6 +209,9 @@ def txt2img(self, job: Txt2ImgQueueEntry) -> List[Image.Image]: sampler_settings=job.data.sampler_settings, ) data = pipe( + aesthetic_score=xl_flag.aesthetic_score, + negative_aesthetic_score=xl_flag.negative_aesthetic_score, + original_size=xl_flag.original_size, image=latents, generator=generator, prompt=job.data.prompt, @@ -284,9 +298,19 @@ def img2img(self, job: Img2ImgQueueEntry) -> List[Image.Image]: input_image = resize(input_image, job.data.width, job.data.height) total_images: List[Image.Image] = [] + shared.current_method = "img2img" + + xl_flag: XLFlag + if "sdxl" in job.flags: + xl_flag = XLFlag.from_dict(job.flags["sdxl"]) + else: + xl_flag = XLFlag() for _ in tqdm(range(job.data.batch_count), desc="Queue", position=1): data = pipe.img2img( + aesthetic_score=xl_flag.aesthetic_score, + negative_aesthetic_score=xl_flag.negative_aesthetic_score, + original_size=xl_flag.original_size, generator=generator, prompt=job.data.prompt, image=input_image, @@ -344,9 +368,19 @@ def inpaint(self, job: InpaintQueueEntry) -> List[Image.Image]: input_mask_image = resize(input_mask_image, job.data.width, job.data.height) total_images: List[Image.Image] = [] + shared.current_method = "inpainting" + + xl_flag: XLFlag + if "sdxl" in job.flags: + xl_flag = XLFlag.from_dict(job.flags["sdxl"]) + else: + xl_flag = XLFlag() for _ in tqdm(range(job.data.batch_count), desc="Queue", position=1): data = pipe.inpaint( + aesthetic_score=xl_flag.aesthetic_score, + negative_aesthetic_score=xl_flag.negative_aesthetic_score, + original_size=xl_flag.original_size, generator=generator, prompt=job.data.prompt, image=input_image, diff --git a/core/inference/utilities/__init__.py b/core/inference/utilities/__init__.py index 6cbfb7fc0..fbe76f149 100644 --- a/core/inference/utilities/__init__.py +++ b/core/inference/utilities/__init__.py @@ -6,6 +6,7 @@ prepare_latents, prepare_mask_and_masked_image, prepare_mask_latents, + preprocess_adapter_image, preprocess_image, preprocess_mask, scale_latents, diff --git a/core/inference/utilities/latents.py b/core/inference/utilities/latents.py index 8f372be69..7d30f2a7f 100644 --- a/core/inference/utilities/latents.py +++ b/core/inference/utilities/latents.py @@ -214,6 +214,36 @@ def prepare_image( return image +def preprocess_adapter_image(image, height, width): + if isinstance(image, torch.Tensor): + return image + elif isinstance(image, Image.Image): + image = [image] + + if isinstance(image[0], Image.Image): + image = [ + np.array(i.resize((width, height), resample=PIL_INTERPOLATION["lanczos"])) + for i in image + ] + image = [ + i[None, ..., None] if i.ndim == 2 else i[None, ...] for i in image + ] # expand [h, w] or [h, w, c] to [b, h, w, c] + image = np.concatenate(image, axis=0) + image = np.array(image).astype(np.float32) / 255.0 + image = image.transpose(0, 3, 1, 2) + image = torch.from_numpy(image) + elif isinstance(image[0], torch.Tensor): + if image[0].ndim == 3: + image = torch.stack(image, dim=0) + elif image[0].ndim == 4: + image = torch.cat(image, dim=0) + else: + raise ValueError( + f"Invalid image tensor! Expecting image tensor with 3 or 4 dimension, but recive: {image[0].ndim}" + ) + return image + + def preprocess_mask(mask): mask = mask.convert("L") # w, h = mask.size From 7a523e1757d18098b0e7e347126d4a55381225c3 Mon Sep 17 00:00:00 2001 From: gabe56f Date: Thu, 9 Nov 2023 21:28:18 +0100 Subject: [PATCH 031/143] Fix loading --- core/flags.py | 4 +- core/inference/functions.py | 39 +++- core/inference/sdxl/pipeline.py | 4 +- core/inference/sdxl/sdxl.py | 10 +- core/inference/utilities/lwp.py | 5 + core/optimizations/offload.py | 3 + frontend/dist/assets/TextToImageView.js | 197 ++++++++++++------ frontend/dist/assets/index.js | 5 + frontend/src/components/inference/Txt2Img.vue | 124 ++++++++--- frontend/src/settings.ts | 10 + 10 files changed, 287 insertions(+), 114 deletions(-) diff --git a/core/flags.py b/core/flags.py index f65a68f7e..e1f9488f4 100644 --- a/core/flags.py +++ b/core/flags.py @@ -33,8 +33,6 @@ class HighResFixFlag(Flag, DataClassJsonMixin): class XLFlag(Flag, DataClassJsonMixin): "Flag for SDXL settings" - aesthetic_score: float = 6.0 - negative_aesthetic_score: float = 2.5 original_size: List[int] = field(default_factory=lambda: [1024, 1024]) @@ -45,3 +43,5 @@ class XLRefinerFlag(Flag, DataClassJsonMixin): steps: int = 50 strength: float = 0.3 model: str = "" + aesthetic_score: float = 6.0 + negative_aesthetic_score: float = 2.5 diff --git a/core/inference/functions.py b/core/inference/functions.py index 88edf99eb..d75b8c13a 100644 --- a/core/inference/functions.py +++ b/core/inference/functions.py @@ -5,6 +5,7 @@ from importlib.util import find_spec from pathlib import Path from typing import Any, Dict, Tuple, Union, Optional +from functools import partial import requests import torch @@ -43,7 +44,7 @@ from omegaconf import OmegaConf from packaging import version from requests import HTTPError -from transformers import CLIPTextModel, CLIPTextModelWithProjection +from transformers.models.clip.modeling_clip import BaseModelOutput from core.config import config from core.files import get_full_model_path @@ -391,22 +392,40 @@ def load_pytorch_pipeline( logger.debug(f"Loaded {model_id_or_path} with {config.api.data_type}") for name, text_encoder in [x for x in vars(pipe).items() if "text_encoder" in x[0]]: - text_encoder: CLIPTextModel if text_encoder is not None: + def new_forward( - self, inputs_embeds, attention_mask: Optional[torch.Tensor] = None, causal_attention_mask: Optional[torch.Tensor] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, return_dict: Optional[bool] = None, + bober=None, ): - n = [] - original = self.old_forward(inputs_embeds, attention_mask=attention_mask, causal_attention_mask=causal_attention_mask, output_attentions=output_attentions, output_hidden_states=True, return_dict=return_dict) - n.append(original.hidden_states[-config.api.clip_skip]) - return n - + output_hidden_states = True + original = bober.old_forward( # type: ignore + inputs_embeds, + attention_mask=attention_mask, + causal_attention_mask=causal_attention_mask, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + ) + + hidden_states = (_ := original[1])[: len(_) - config.api.clip_skip] + last_hidden_state = hidden_states[-1] + + attentions = original[2] if output_attentions else None + + if not return_dict: + return last_hidden_state, hidden_states, attentions + return BaseModelOutput( + last_hidden_state=last_hidden_state, + hidden_states=hidden_states, + attentions=attentions, + ) + if config.api.clip_quantization != "full": from transformers import BitsAndBytesConfig from transformers.utils.bitsandbytes import ( @@ -438,7 +457,9 @@ def new_forward( del state_dict, dont_convert text_encoder.text_model.encoder.old_forward = text_encoder.text_model.encoder.forward # type: ignore - text_encoder.text_model.encoder.forward = new_forward # type: ignore + # fuck you python + # enjoy bober + text_encoder.text_model.encoder.forward = partial(new_forward, bober=text_encoder.text_model.encoder) # type: ignore logger.debug(f"Overwritten {name}s final_layer_norm.") if optimize: diff --git a/core/inference/sdxl/pipeline.py b/core/inference/sdxl/pipeline.py index 402d2a2e6..97a335c15 100644 --- a/core/inference/sdxl/pipeline.py +++ b/core/inference/sdxl/pipeline.py @@ -168,6 +168,7 @@ def _encode_prompt( for prompt, negative_prompt, tokenizer, text_encoder in zip( prompts, negative_prompts, tokenizers, text_encoders ): + ensure_correct_device(text_encoder) prompt = self.maybe_convert_prompt(prompt, tokenizer) logger.debug(f"Post textual prompt: {prompt}") @@ -175,8 +176,6 @@ def _encode_prompt( negative_prompt = self.maybe_convert_prompt(negative_prompt, tokenizer) logger.debug(f"Post textual negative_prompt: {negative_prompt}") - ensure_correct_device(text_encoder) - ( text_embeddings, pooled_embeddings, @@ -318,6 +317,7 @@ def __call__( self.unet = context.unet # type: ignore self.vae = context.vae # type: ignore + original_size = tuple(original_size) # type: ignore height, width = self._default_height_width(height, width, image) # 2. Define call parameters diff --git a/core/inference/sdxl/sdxl.py b/core/inference/sdxl/sdxl.py index c202d6d33..52add6a0d 100644 --- a/core/inference/sdxl/sdxl.py +++ b/core/inference/sdxl/sdxl.py @@ -174,8 +174,6 @@ def txt2img(self, job: Txt2ImgQueueEntry) -> List[Image.Image]: output_type = "latent" data = pipe.text2img( - aesthetic_score=xl_flag.aesthetic_score, - negative_aesthetic_score=xl_flag.negative_aesthetic_score, original_size=xl_flag.original_size, generator=generator, prompt=job.data.prompt, @@ -209,8 +207,8 @@ def txt2img(self, job: Txt2ImgQueueEntry) -> List[Image.Image]: sampler_settings=job.data.sampler_settings, ) data = pipe( - aesthetic_score=xl_flag.aesthetic_score, - negative_aesthetic_score=xl_flag.negative_aesthetic_score, + aesthetic_score=flags.aesthetic_score, + negative_aesthetic_score=flags.negative_aesthetic_score, original_size=xl_flag.original_size, image=latents, generator=generator, @@ -308,8 +306,6 @@ def img2img(self, job: Img2ImgQueueEntry) -> List[Image.Image]: for _ in tqdm(range(job.data.batch_count), desc="Queue", position=1): data = pipe.img2img( - aesthetic_score=xl_flag.aesthetic_score, - negative_aesthetic_score=xl_flag.negative_aesthetic_score, original_size=xl_flag.original_size, generator=generator, prompt=job.data.prompt, @@ -378,8 +374,6 @@ def inpaint(self, job: InpaintQueueEntry) -> List[Image.Image]: for _ in tqdm(range(job.data.batch_count), desc="Queue", position=1): data = pipe.inpaint( - aesthetic_score=xl_flag.aesthetic_score, - negative_aesthetic_score=xl_flag.negative_aesthetic_score, original_size=xl_flag.original_size, generator=generator, prompt=job.data.prompt, diff --git a/core/inference/utilities/lwp.py b/core/inference/utilities/lwp.py index 1e398b12e..556f5436e 100644 --- a/core/inference/utilities/lwp.py +++ b/core/inference/utilities/lwp.py @@ -11,6 +11,7 @@ from ...config import config from ...files import get_full_model_path +from ...optimizations import ensure_correct_device from .prompt_expansion import expand logger = logging.getLogger(__name__) @@ -279,6 +280,7 @@ def get_unweighted_text_embeddings( if hasattr(pipe, "clip_inference"): text_embedding = pipe.clip_inference(text_input_chunk) else: + ensure_correct_device(pipe.text_encoder) text_embedding = pipe.text_encoder(text_input_chunk)[0] # type: ignore if no_boseos_middle: @@ -298,6 +300,7 @@ def get_unweighted_text_embeddings( if hasattr(pipe, "clip_inference"): text_embeddings = pipe.clip_inference(text_input) else: + ensure_correct_device(pipe.text_encoder) text_embeddings = pipe.text_encoder(text_input)[0] # type: ignore return text_embeddings, None # type: ignore else: @@ -311,6 +314,7 @@ def get_unweighted_text_embeddings( text_input_chunk[:, 0] = text_input[0, 0] text_input_chunk[:, -1] = text_input[0, -1] + ensure_correct_device(text_encoder) text_embedding = text_encoder( # type: ignore text_input_chunk, output_hidden_states=True ) @@ -335,6 +339,7 @@ def get_unweighted_text_embeddings( hidden_states = text_embeddings[-1][0].unsqueeze(0) # type: ignore # text_embeddings = torch.Tensor(hidden_states.shape[0]) else: + ensure_correct_device(text_encoder) text_embeddings = text_encoder(text_input, output_hidden_states=True) # type: ignore hidden_states = text_embeddings[0] text_embeddings = text_embeddings.hidden_states[-2] diff --git a/core/optimizations/offload.py b/core/optimizations/offload.py index 2348410bd..3ce67dc11 100644 --- a/core/optimizations/offload.py +++ b/core/optimizations/offload.py @@ -22,6 +22,9 @@ def ensure_correct_device(module: torch.nn.Module): if hasattr(module, "offload_device"): global _module + if module.__class__.__name__ == _module.__class__.__name__: + return + device = getattr(module, "offload_device", config.api.device) logger.debug(f"Transferring {module.__class__.__name__} to {str(device)}.") diff --git a/frontend/dist/assets/TextToImageView.js b/frontend/dist/assets/TextToImageView.js index b7bb7db1d..bb29e1125 100644 --- a/frontend/dist/assets/TextToImageView.js +++ b/frontend/dist/assets/TextToImageView.js @@ -38,22 +38,28 @@ const _hoisted_20 = { class: "flex-container" }; const _hoisted_21 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Steps", -1); const _hoisted_22 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "We recommend using 20-50 steps for most images.", -1); const _hoisted_23 = { class: "flex-container" }; -const _hoisted_24 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Strength", -1); -const _hoisted_25 = { class: "flex-container" }; -const _hoisted_26 = /* @__PURE__ */ createBaseVNode("div", { class: "slider-label" }, [ +const _hoisted_24 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Aesthetic Score", -1); +const _hoisted_25 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "Generally best to keep it around 6.", -1); +const _hoisted_26 = { class: "flex-container" }; +const _hoisted_27 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Negative Aesthetic Score", -1); +const _hoisted_28 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "Generally best to keep it around 3.", -1); +const _hoisted_29 = { class: "flex-container" }; +const _hoisted_30 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Strength", -1); +const _hoisted_31 = { class: "flex-container" }; +const _hoisted_32 = /* @__PURE__ */ createBaseVNode("div", { class: "slider-label" }, [ /* @__PURE__ */ createBaseVNode("p", null, "Enabled") ], -1); -const _hoisted_27 = { class: "flex-container" }; -const _hoisted_28 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Steps", -1); -const _hoisted_29 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "We recommend using 20-50 steps for most images.", -1); -const _hoisted_30 = { class: "flex-container" }; -const _hoisted_31 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Scale", -1); -const _hoisted_32 = { class: "flex-container" }; -const _hoisted_33 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Strength", -1); -const _hoisted_34 = { class: "flex-container" }; -const _hoisted_35 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Antialiased", -1); +const _hoisted_33 = { class: "flex-container" }; +const _hoisted_34 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Steps", -1); +const _hoisted_35 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "We recommend using 20-50 steps for most images.", -1); const _hoisted_36 = { class: "flex-container" }; -const _hoisted_37 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Latent Mode", -1); +const _hoisted_37 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Scale", -1); +const _hoisted_38 = { class: "flex-container" }; +const _hoisted_39 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Strength", -1); +const _hoisted_40 = { class: "flex-container" }; +const _hoisted_41 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Antialiased", -1); +const _hoisted_42 = { class: "flex-container" }; +const _hoisted_43 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Latent Mode", -1); const _sfc_main$1 = /* @__PURE__ */ defineComponent({ __name: "Txt2Img", setup(__props) { @@ -121,21 +127,30 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ model: (_a = settings.data.settings.model) == null ? void 0 : _a.name, backend: "PyTorch", autoload: false, - flags: global.state.txt2img.highres ? { - highres_fix: { - scale: settings.data.settings.extra.highres.scale, - latent_scale_mode: settings.data.settings.extra.highres.latent_scale_mode, - strength: settings.data.settings.extra.highres.strength, - steps: settings.data.settings.extra.highres.steps, - antialiased: settings.data.settings.extra.highres.antialiased - } - } : global.state.txt2img.refiner ? { - refiner: { - model: settings.data.settings.extra.refiner.model, - steps: settings.data.settings.extra.refiner.steps, - strength: settings.data.settings.extra.refiner.strength - } - } : {} + flags: { + ...isSelectedModelSDXL.value ? { + sdxl: { + original_size: settings.data.settings.extra.sdxl.original_size + } + } : {}, + ...global.state.txt2img.highres ? { + highres_fix: { + scale: settings.data.settings.extra.highres.scale, + latent_scale_mode: settings.data.settings.extra.highres.latent_scale_mode, + strength: settings.data.settings.extra.highres.strength, + steps: settings.data.settings.extra.highres.steps, + antialiased: settings.data.settings.extra.highres.antialiased + } + } : global.state.txt2img.refiner ? { + refiner: { + model: settings.data.settings.extra.refiner.model, + aesthetic_score: settings.data.settings.extra.refiner.aesthetic_score, + negative_aesthetic_score: settings.data.settings.extra.refiner.negative_aesthetic_score, + steps: settings.data.settings.extra.refiner.steps, + strength: settings.data.settings.extra.refiner.strength + } + } : {} + } }) }).then((res) => { if (!res.ok) { @@ -383,10 +398,68 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ }, null, 8, ["value"]) ]), createBaseVNode("div", _hoisted_23, [ - _hoisted_24, + createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { + trigger: withCtx(() => [ + _hoisted_24 + ]), + default: withCtx(() => [ + createTextVNode(' Generally higher numbers will produce "more professional" images. '), + _hoisted_25 + ]), + _: 1 + }), + createVNode(unref(NSlider), { + value: unref(settings).data.settings.extra.refiner.aesthetic_score, + "onUpdate:value": _cache[12] || (_cache[12] = ($event) => unref(settings).data.settings.extra.refiner.aesthetic_score = $event), + min: 0, + max: 10, + step: 0.5, + style: { "margin-right": "12px" } + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: unref(settings).data.settings.extra.refiner.aesthetic_score, + "onUpdate:value": _cache[13] || (_cache[13] = ($event) => unref(settings).data.settings.extra.refiner.aesthetic_score = $event), + min: 0, + max: 10, + step: 0.25, + size: "small", + style: { "min-width": "96px", "width": "96px" } + }, null, 8, ["value"]) + ]), + createBaseVNode("div", _hoisted_26, [ + createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { + trigger: withCtx(() => [ + _hoisted_27 + ]), + default: withCtx(() => [ + createTextVNode(" Makes sense to keep this lower than aesthetic score. "), + _hoisted_28 + ]), + _: 1 + }), + createVNode(unref(NSlider), { + value: unref(settings).data.settings.extra.refiner.negative_aesthetic_score, + "onUpdate:value": _cache[14] || (_cache[14] = ($event) => unref(settings).data.settings.extra.refiner.negative_aesthetic_score = $event), + min: 0, + max: 10, + step: 0.5, + style: { "margin-right": "12px" } + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: unref(settings).data.settings.extra.refiner.negative_aesthetic_score, + "onUpdate:value": _cache[15] || (_cache[15] = ($event) => unref(settings).data.settings.extra.refiner.negative_aesthetic_score = $event), + min: 0, + max: 10, + step: 0.25, + size: "small", + style: { "min-width": "96px", "width": "96px" } + }, null, 8, ["value"]) + ]), + createBaseVNode("div", _hoisted_29, [ + _hoisted_30, createVNode(unref(NSlider), { value: unref(settings).data.settings.extra.refiner.strength, - "onUpdate:value": _cache[12] || (_cache[12] = ($event) => unref(settings).data.settings.extra.refiner.strength = $event), + "onUpdate:value": _cache[16] || (_cache[16] = ($event) => unref(settings).data.settings.extra.refiner.strength = $event), min: 0.1, max: 0.9, step: 0.05, @@ -394,7 +467,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ }, null, 8, ["value"]), createVNode(unref(NInputNumber), { value: unref(settings).data.settings.extra.refiner.strength, - "onUpdate:value": _cache[13] || (_cache[13] = ($event) => unref(settings).data.settings.extra.refiner.strength = $event), + "onUpdate:value": _cache[17] || (_cache[17] = ($event) => unref(settings).data.settings.extra.refiner.strength = $event), size: "small", style: { "min-width": "96px", "width": "96px" }, min: 0.1, @@ -408,16 +481,17 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ ]), _: 1 })) : createCommentVNode("", true), - createVNode(unref(NCard), { + !isSelectedModelSDXL.value ? (openBlock(), createBlock(unref(NCard), { + key: 1, title: "Highres fix", style: { "margin-top": "12px", "margin-bottom": "12px" } }, { default: withCtx(() => [ - createBaseVNode("div", _hoisted_25, [ - _hoisted_26, + createBaseVNode("div", _hoisted_31, [ + _hoisted_32, createVNode(unref(NSwitch), { value: unref(global).state.txt2img.highres, - "onUpdate:value": _cache[14] || (_cache[14] = ($event) => unref(global).state.txt2img.highres = $event) + "onUpdate:value": _cache[18] || (_cache[18] = ($event) => unref(global).state.txt2img.highres = $event) }, null, 8, ["value"]) ]), unref(global).state.txt2img.highres ? (openBlock(), createBlock(unref(NSpace), { @@ -426,36 +500,36 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ class: "left-container" }, { default: withCtx(() => [ - createBaseVNode("div", _hoisted_27, [ + createBaseVNode("div", _hoisted_33, [ createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { trigger: withCtx(() => [ - _hoisted_28 + _hoisted_34 ]), default: withCtx(() => [ createTextVNode(" Number of steps to take in the diffusion process. Higher values will result in more detailed images but will take longer to generate. There is also a point of diminishing returns around 100 steps. "), - _hoisted_29 + _hoisted_35 ]), _: 1 }), createVNode(unref(NSlider), { value: unref(settings).data.settings.extra.highres.steps, - "onUpdate:value": _cache[15] || (_cache[15] = ($event) => unref(settings).data.settings.extra.highres.steps = $event), + "onUpdate:value": _cache[19] || (_cache[19] = ($event) => unref(settings).data.settings.extra.highres.steps = $event), min: 5, max: 300, style: { "margin-right": "12px" } }, null, 8, ["value"]), createVNode(unref(NInputNumber), { value: unref(settings).data.settings.extra.highres.steps, - "onUpdate:value": _cache[16] || (_cache[16] = ($event) => unref(settings).data.settings.extra.highres.steps = $event), + "onUpdate:value": _cache[20] || (_cache[20] = ($event) => unref(settings).data.settings.extra.highres.steps = $event), size: "small", style: { "min-width": "96px", "width": "96px" } }, null, 8, ["value"]) ]), - createBaseVNode("div", _hoisted_30, [ - _hoisted_31, + createBaseVNode("div", _hoisted_36, [ + _hoisted_37, createVNode(unref(NSlider), { value: unref(settings).data.settings.extra.highres.scale, - "onUpdate:value": _cache[17] || (_cache[17] = ($event) => unref(settings).data.settings.extra.highres.scale = $event), + "onUpdate:value": _cache[21] || (_cache[21] = ($event) => unref(settings).data.settings.extra.highres.scale = $event), min: 1, max: 8, step: 0.1, @@ -463,17 +537,17 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ }, null, 8, ["value"]), createVNode(unref(NInputNumber), { value: unref(settings).data.settings.extra.highres.scale, - "onUpdate:value": _cache[18] || (_cache[18] = ($event) => unref(settings).data.settings.extra.highres.scale = $event), + "onUpdate:value": _cache[22] || (_cache[22] = ($event) => unref(settings).data.settings.extra.highres.scale = $event), size: "small", style: { "min-width": "96px", "width": "96px" }, step: 0.1 }, null, 8, ["value"]) ]), - createBaseVNode("div", _hoisted_32, [ - _hoisted_33, + createBaseVNode("div", _hoisted_38, [ + _hoisted_39, createVNode(unref(NSlider), { value: unref(settings).data.settings.extra.highres.strength, - "onUpdate:value": _cache[19] || (_cache[19] = ($event) => unref(settings).data.settings.extra.highres.strength = $event), + "onUpdate:value": _cache[23] || (_cache[23] = ($event) => unref(settings).data.settings.extra.highres.strength = $event), min: 0.1, max: 0.9, step: 0.05, @@ -481,7 +555,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ }, null, 8, ["value"]), createVNode(unref(NInputNumber), { value: unref(settings).data.settings.extra.highres.strength, - "onUpdate:value": _cache[20] || (_cache[20] = ($event) => unref(settings).data.settings.extra.highres.strength = $event), + "onUpdate:value": _cache[24] || (_cache[24] = ($event) => unref(settings).data.settings.extra.highres.strength = $event), size: "small", style: { "min-width": "96px", "width": "96px" }, min: 0.1, @@ -489,18 +563,18 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ step: 0.05 }, null, 8, ["value"]) ]), - createBaseVNode("div", _hoisted_34, [ - _hoisted_35, + createBaseVNode("div", _hoisted_40, [ + _hoisted_41, createVNode(unref(NSwitch), { value: unref(settings).data.settings.extra.highres.antialiased, - "onUpdate:value": _cache[21] || (_cache[21] = ($event) => unref(settings).data.settings.extra.highres.antialiased = $event) + "onUpdate:value": _cache[25] || (_cache[25] = ($event) => unref(settings).data.settings.extra.highres.antialiased = $event) }, null, 8, ["value"]) ]), - createBaseVNode("div", _hoisted_36, [ - _hoisted_37, + createBaseVNode("div", _hoisted_42, [ + _hoisted_43, createVNode(unref(NSelect), { value: unref(settings).data.settings.extra.highres.latent_scale_mode, - "onUpdate:value": _cache[22] || (_cache[22] = ($event) => unref(settings).data.settings.extra.highres.latent_scale_mode = $event), + "onUpdate:value": _cache[26] || (_cache[26] = ($event) => unref(settings).data.settings.extra.highres.latent_scale_mode = $event), size: "small", style: { "flex-grow": "1" }, options: [ @@ -509,23 +583,16 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ { label: "Area", value: "area" }, { label: "Bilinear", value: "bilinear" }, { label: "Bicubic", value: "bicubic" }, - { - label: "Bislerp (Original, slow)", - value: "bislerp-original" - }, - { - label: "Bislerp (Tortured, fast)", - value: "bislerp-tortured" - } + { label: "Bislerp", value: "bislerp" } ] - }, null, 8, ["value", "options"]) + }, null, 8, ["value"]) ]) ]), _: 1 })) : createCommentVNode("", true) ]), _: 1 - }) + })) : createCommentVNode("", true) ]), _: 1 }), @@ -536,7 +603,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ "current-image": unref(global).state.txt2img.currentImage, images: unref(global).state.txt2img.images, data: unref(settings).data.settings.txt2img, - onImageClicked: _cache[23] || (_cache[23] = ($event) => unref(global).state.txt2img.currentImage = $event) + onImageClicked: _cache[27] || (_cache[27] = ($event) => unref(global).state.txt2img.currentImage = $event) }, null, 8, ["current-image", "images", "data"]), createVNode(unref(_sfc_main$7), { style: { "margin-top": "12px" }, diff --git a/frontend/dist/assets/index.js b/frontend/dist/assets/index.js index 6640fb9ae..95d58bb1f 100644 --- a/frontend/dist/assets/index.js +++ b/frontend/dist/assets/index.js @@ -40680,6 +40680,9 @@ const defaultSettings = { backend: "PyTorch", model: null, extra: { + sdxl: { + original_size: [1024, 1024] + }, highres: { scale: 2, latent_scale_mode: "bilinear", @@ -40689,6 +40692,8 @@ const defaultSettings = { }, refiner: { model: void 0, + aesthetic_score: 6, + negative_aesthetic_score: 2.5, steps: 50, strength: 0.3 } diff --git a/frontend/src/components/inference/Txt2Img.vue b/frontend/src/components/inference/Txt2Img.vue index ffc69dd07..2af29299e 100644 --- a/frontend/src/components/inference/Txt2Img.vue +++ b/frontend/src/components/inference/Txt2Img.vue @@ -221,6 +221,67 @@ /> + +
+ + + Generally higher numbers will produce "more professional" + images. + Generally best to keep it around 6. + + + +
+ + +
+ + + Makes sense to keep this lower than aesthetic score. + Generally best to keep it around 3. + + + +
+

Strength

@@ -344,14 +406,7 @@ { label: 'Area', value: 'area' }, { label: 'Bilinear', value: 'bilinear' }, { label: 'Bicubic', value: 'bicubic' }, - { - label: 'Bislerp (Original, slow)', - value: 'bislerp-original', - }, - { - label: 'Bislerp (Tortured, fast)', - value: 'bislerp-tortured', - }, + { label: 'Bislerp', value: 'bislerp' }, ]" />
@@ -490,26 +545,39 @@ const generate = () => { model: settings.data.settings.model?.name, backend: "PyTorch", autoload: false, - flags: global.state.txt2img.highres - ? { - highres_fix: { - scale: settings.data.settings.extra.highres.scale, - latent_scale_mode: - settings.data.settings.extra.highres.latent_scale_mode, - strength: settings.data.settings.extra.highres.strength, - steps: settings.data.settings.extra.highres.steps, - antialiased: settings.data.settings.extra.highres.antialiased, - }, - } - : global.state.txt2img.refiner - ? { - refiner: { - model: settings.data.settings.extra.refiner.model, - steps: settings.data.settings.extra.refiner.steps, - strength: settings.data.settings.extra.refiner.strength, - }, - } - : {}, + flags: { + ...(isSelectedModelSDXL.value + ? { + sdxl: { + original_size: settings.data.settings.extra.sdxl.original_size, + }, + } + : {}), + ...(global.state.txt2img.highres + ? { + highres_fix: { + scale: settings.data.settings.extra.highres.scale, + latent_scale_mode: + settings.data.settings.extra.highres.latent_scale_mode, + strength: settings.data.settings.extra.highres.strength, + steps: settings.data.settings.extra.highres.steps, + antialiased: settings.data.settings.extra.highres.antialiased, + }, + } + : global.state.txt2img.refiner + ? { + refiner: { + model: settings.data.settings.extra.refiner.model, + aesthetic_score: + settings.data.settings.extra.refiner.aesthetic_score, + negative_aesthetic_score: + settings.data.settings.extra.refiner.negative_aesthetic_score, + steps: settings.data.settings.extra.refiner.steps, + strength: settings.data.settings.extra.refiner.strength, + }, + } + : {}), + }, }), }) .then((res) => { diff --git a/frontend/src/settings.ts b/frontend/src/settings.ts index c20f4d004..af7722f02 100644 --- a/frontend/src/settings.ts +++ b/frontend/src/settings.ts @@ -37,6 +37,9 @@ export interface ISettings { backend: "PyTorch" | "AITemplate" | "ONNX" | "unknown"; model: ModelEntry | null; extra: { + sdxl: { + original_size: number[]; + }; highres: { scale: number; latent_scale_mode: @@ -52,6 +55,8 @@ export interface ISettings { }; refiner: { model: string | undefined; + aesthetic_score: number; + negative_aesthetic_score: number; steps: 50; strength: number; }; @@ -251,6 +256,9 @@ export const defaultSettings: ISettings = { backend: "PyTorch", model: null, extra: { + sdxl: { + original_size: [1024, 1024], + }, highres: { scale: 2, latent_scale_mode: "bilinear", @@ -260,6 +268,8 @@ export const defaultSettings: ISettings = { }, refiner: { model: undefined, + aesthetic_score: 6.0, + negative_aesthetic_score: 2.5, steps: 50, strength: 0.3, }, From 7f8522948503d233814e9313a5a25dae0b9d0a0e Mon Sep 17 00:00:00 2001 From: Stax124 Date: Thu, 9 Nov 2023 21:56:47 +0100 Subject: [PATCH 032/143] Merge SDXL and SD model loader tabs, few config typing changes, rebuild frontend, remove async from some functions --- api/routes/models.py | 10 +- core/config/default_settings.py | 20 +- core/config/frontend_settings.py | 4 +- frontend/dist/assets/SettingsView.js | 10 +- frontend/dist/assets/index.css | 6 +- frontend/dist/assets/index.js | 312 ++++++------------ frontend/src/components/TopBar.vue | 250 +++++--------- .../src/components/settings/FlagsSettings.vue | 8 +- 8 files changed, 203 insertions(+), 417 deletions(-) diff --git a/api/routes/models.py b/api/routes/models.py index 2de295b5b..5d76d091d 100644 --- a/api/routes/models.py +++ b/api/routes/models.py @@ -104,7 +104,7 @@ def load_model( @router.post("/unload") -async def unload_model(model: str): +def unload_model(model: str): "Unloads a model from memory" gpu.unload(model) @@ -123,7 +123,7 @@ def unload_all_models(): @router.post("/load-vae") -async def load_vae(req: VaeLoadRequest): +def load_vae(req: VaeLoadRequest): "Load a VAE into a model" gpu.load_vae(req) @@ -132,7 +132,7 @@ async def load_vae(req: VaeLoadRequest): @router.post("/load-textual-inversion") -async def load_textual_inversion(req: TextualInversionLoadRequest): +def load_textual_inversion(req: TextualInversionLoadRequest): "Load a LoRA model into a model" gpu.load_textual_inversion(req) @@ -141,7 +141,7 @@ async def load_textual_inversion(req: TextualInversionLoadRequest): @router.post("/memory-cleanup") -async def cleanup(): +def cleanup(): "Free up memory manually" gpu.memory_cleanup() @@ -149,7 +149,7 @@ async def cleanup(): @router.post("/download") -async def download_model(model: str): +def download_model(model: str): "Download a model to the cache" gpu.download_huggingface_model(model) diff --git a/core/config/default_settings.py b/core/config/default_settings.py index a8a2b2503..844ca172a 100644 --- a/core/config/default_settings.py +++ b/core/config/default_settings.py @@ -1,6 +1,6 @@ -from dataclasses import dataclass, field import multiprocessing -from typing import Optional +from dataclasses import dataclass, field +from typing import Optional, Union from diffusers.schedulers.scheduling_utils import KarrasDiffusionSchedulers @@ -23,7 +23,9 @@ class Txt2ImgConfig: height: int = 512 seed: int = -1 cfg_scale: int = 7 - sampler: int = KarrasDiffusionSchedulers.DPMSolverSinglestepScheduler.value + sampler: Union[ + int, str + ] = KarrasDiffusionSchedulers.DPMSolverSinglestepScheduler.value prompt: str = "" negative_prompt: str = "" steps: int = 40 @@ -40,7 +42,9 @@ class Img2ImgConfig: height: int = 512 seed: int = -1 cfg_scale: int = 7 - sampler: int = KarrasDiffusionSchedulers.DPMSolverSinglestepScheduler.value + sampler: Union[ + int, str + ] = KarrasDiffusionSchedulers.DPMSolverSinglestepScheduler.value prompt: str = "" negative_prompt: str = "" steps: int = 40 @@ -64,7 +68,9 @@ class InpaintingConfig: seed: int = -1 batch_count: int = 1 batch_size: int = 1 - sampler: int = KarrasDiffusionSchedulers.DPMSolverSinglestepScheduler.value + sampler: Union[ + int, str + ] = KarrasDiffusionSchedulers.DPMSolverSinglestepScheduler.value self_attention_scale: float = 0.0 @@ -81,7 +87,9 @@ class ControlNetConfig: steps: int = 40 batch_count: int = 1 batch_size: int = 1 - sampler: int = KarrasDiffusionSchedulers.DPMSolverSinglestepScheduler.value + sampler: Union[ + int, str + ] = KarrasDiffusionSchedulers.DPMSolverSinglestepScheduler.value controlnet: str = "lllyasviel/sd-controlnet-canny" controlnet_conditioning_scale: float = 1.0 detection_resolution: int = 512 diff --git a/core/config/frontend_settings.py b/core/config/frontend_settings.py index 36d44bfd7..5103aae44 100644 --- a/core/config/frontend_settings.py +++ b/core/config/frontend_settings.py @@ -1,12 +1,12 @@ from dataclasses import dataclass -from typing import Literal +from typing import Literal, Union @dataclass class FrontendConfig: "Configuration for the frontend" - theme: Literal["dark", "light"] = "dark" + theme: Union[Literal["dark", "light"], str] = "dark" enable_theme_editor: bool = False image_browser_columns: int = 5 on_change_timer: int = 0 diff --git a/frontend/dist/assets/SettingsView.js b/frontend/dist/assets/SettingsView.js index 379da1e77..1727b5008 100644 --- a/frontend/dist/assets/SettingsView.js +++ b/frontend/dist/assets/SettingsView.js @@ -1015,12 +1015,8 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({ value: "bicubic" }, { - label: "Bislerp (Original, slow)", - value: "bislerp-original" - }, - { - label: "Bislerp (Tortured, fast)", - value: "bislerp-tortured" + label: "Bislerp", + value: "bislerp" }, { label: "Nearest Exact", @@ -1029,7 +1025,7 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({ ], value: unref(settings).defaultSettings.flags.highres.latent_scale_mode, "onUpdate:value": _cache[1] || (_cache[1] = ($event) => unref(settings).defaultSettings.flags.highres.latent_scale_mode = $event) - }, null, 8, ["options", "value"]) + }, null, 8, ["value"]) ]), _: 1 }), diff --git a/frontend/dist/assets/index.css b/frontend/dist/assets/index.css index 27b32f39c..2f1d0e053 100644 --- a/frontend/dist/assets/index.css +++ b/frontend/dist/assets/index.css @@ -50,12 +50,12 @@ justify-content: center; } -.progress-container[data-v-e207b7ed] { +.progress-container[data-v-e0808386] { margin: 12px; flex-grow: 1; width: 400px; } -.top-bar[data-v-e207b7ed] { +.top-bar[data-v-e0808386] { display: inline-flex; align-items: center; padding-top: 10px; @@ -66,7 +66,7 @@ top: 0; z-index: 1; } -.logo[data-v-e207b7ed] { +.logo[data-v-e0808386] { margin-right: 16px; margin-left: 16px; } diff --git a/frontend/dist/assets/index.js b/frontend/dist/assets/index.js index 53b971025..afcea18be 100644 --- a/frontend/dist/assets/index.js +++ b/frontend/dist/assets/index.js @@ -42064,7 +42064,7 @@ function urlFromPath(path) { const url = new URL(path, serverUrl); return url.href; } -const _withScopeId = (n) => (pushScopeId("data-v-e207b7ed"), n = n(), popScopeId(), n); +const _withScopeId = (n) => (pushScopeId("data-v-e0808386"), n = n(), popScopeId(), n); const _hoisted_1$1 = { class: "top-bar" }; const _hoisted_2 = { key: 0 }; const _hoisted_3 = { key: 1 }; @@ -42074,20 +42074,17 @@ const _hoisted_4 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBase }, null, -1)); const _hoisted_5 = { key: 2 }; const _hoisted_6 = { style: { "display": "inline-flex", "width": "100%", "margin-bottom": "12px" } }; -const _hoisted_7 = { style: { "display": "inline-flex" } }; -const _hoisted_8 = { key: 0 }; -const _hoisted_9 = { style: { "display": "inline-flex" } }; -const _hoisted_10 = { key: 1 }; -const _hoisted_11 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("b", null, "Ignore the tokens on CivitAI", -1)); -const _hoisted_12 = { key: 0 }; -const _hoisted_13 = { style: { "display": "inline-flex" } }; -const _hoisted_14 = { key: 1 }; -const _hoisted_15 = { style: { "display": "inline-flex" } }; -const _hoisted_16 = { key: 0 }; -const _hoisted_17 = { style: { "display": "inline-flex" } }; -const _hoisted_18 = { key: 1 }; -const _hoisted_19 = { class: "progress-container" }; -const _hoisted_20 = { style: { "display": "inline-flex", "align-items": "center" } }; +const _hoisted_7 = { style: { "display": "flex", "flex-direction": "row", "align-items": "center" } }; +const _hoisted_8 = { style: { "display": "inline-flex" } }; +const _hoisted_9 = { key: 0 }; +const _hoisted_10 = { style: { "display": "inline-flex" } }; +const _hoisted_11 = { key: 1 }; +const _hoisted_12 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("b", null, "Ignore the tokens on CivitAI", -1)); +const _hoisted_13 = { key: 0 }; +const _hoisted_14 = { style: { "display": "inline-flex" } }; +const _hoisted_15 = { key: 1 }; +const _hoisted_16 = { class: "progress-container" }; +const _hoisted_17 = { style: { "display": "inline-flex", "align-items": "center" } }; const _sfc_main$3 = /* @__PURE__ */ defineComponent({ __name: "TopBar", setup(__props) { @@ -42104,7 +42101,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ }); const pyTorchModels = computed(() => { return filteredModels.value.filter((model) => { - return model.backend === "PyTorch" && model.valid === true; + return (model.backend === "PyTorch" || model.backend === "SDXL") && model.valid === true; }).sort((a, b) => { if (a.state === "loaded" && b.state !== "loaded") { return -1; @@ -42115,13 +42112,6 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ } }); }); - const sdxlModels = computed(() => { - return filteredModels.value.filter((model) => { - return model.backend === "SDXL"; - }).sort((a, b) => { - return a.name.localeCompare(b.name); - }); - }); const aitModels = computed(() => { return filteredModels.value.filter((model) => { return model.backend === "AITemplate"; @@ -42148,62 +42138,64 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ } }); }); - const vaeModels = computed(() => { - return [ - { - name: "Default VAE", - path: "default", - backend: "VAE", - valid: true, - state: "not loaded", - vae: "default", - textual_inversions: [] - }, - { - name: "Tiny VAE (fast)", - path: "madebyollin/taesd", - backend: "VAE", - valid: true, - state: "not loaded", - vae: "madebyollin/taesd", - textual_inversions: [] - }, - { - name: "Asymmetric VAE", - path: "cross-attention/asymmetric-autoencoder-kl-x-1-5", - backend: "VAE", - valid: true, - state: "not loaded", - vae: "cross-attention/asymmetric-autoencoder-kl-x-1-5", - textual_inversions: [] - }, - ...filteredModels.value.filter((model) => { - return model.backend === "VAE"; - }).sort((a, b) => { - return a.name.localeCompare(b.name); - }) - ]; + const manualVAEModels = computed(() => { + const selectedModel = global2.state.selected_model; + if ((selectedModel == null ? void 0 : selectedModel.backend) === "SDXL") { + return [ + { + name: "Default VAE (fp32)", + path: "default", + backend: "VAE", + valid: true, + state: "not loaded", + vae: "default", + textual_inversions: [] + }, + { + name: "FP16 VAE", + path: "madebyollin/sdxl-vae-fp16-fix", + backend: "VAE", + valid: true, + state: "not loaded", + vae: "fp16", + textual_inversions: [] + } + ]; + } else { + return [ + { + name: "Default VAE", + path: "default", + backend: "VAE", + valid: true, + state: "not loaded", + vae: "default", + textual_inversions: [] + }, + { + name: "Tiny VAE (fast)", + path: "madebyollin/taesd", + backend: "VAE", + valid: true, + state: "not loaded", + vae: "madebyollin/taesd", + textual_inversions: [] + }, + { + name: "Asymmetric VAE", + path: "cross-attention/asymmetric-autoencoder-kl-x-1-5", + backend: "VAE", + valid: true, + state: "not loaded", + vae: "cross-attention/asymmetric-autoencoder-kl-x-1-5", + textual_inversions: [] + } + ]; + } }); - const sdxlVaeModels = computed(() => { + const vaeModels = computed(() => { return [ - { - name: "Default VAE (fp32)", - path: "default", - backend: "VAE", - valid: true, - state: "not loaded", - vae: "default", - textual_inversions: [] - }, - { - name: "FP16 VAE", - path: "madebyollin/sdxl-vae-fp16-fix", - backend: "VAE", - valid: true, - state: "not loaded", - vae: "fp16", - textual_inversions: [] - }, + ...manualVAEModels.value, ...filteredModels.value.filter((model) => { return model.backend === "VAE"; }).sort((a, b) => { @@ -42746,8 +42738,20 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ style: { "display": "inline-flex", "width": "100%", "align-items": "center", "justify-content": "space-between", "border-bottom": "1px solid rgb(66, 66, 71)" }, key: model.path }, [ - createBaseVNode("p", null, toDisplayString(model.name), 1), createBaseVNode("div", _hoisted_7, [ + createVNode(unref(NTag), { + type: model.backend === "SDXL" ? "warning" : "info", + ghost: "", + style: { "margin-right": "8px" } + }, { + default: withCtx(() => [ + createTextVNode(toDisplayString(model.backend === "SDXL" ? "SDXL" : "SD"), 1) + ]), + _: 2 + }, 1032, ["type"]), + createBaseVNode("p", null, toDisplayString(model.name), 1) + ]), + createBaseVNode("div", _hoisted_8, [ model.state === "loaded" ? (openBlock(), createBlock(unref(NButton), { key: 0, type: "error", @@ -42795,7 +42799,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ default: withCtx(() => [ createVNode(unref(NCard), { title: vae_title.value }, { default: withCtx(() => [ - unref(global2).state.selected_model !== null ? (openBlock(), createElementBlock("div", _hoisted_8, [ + unref(global2).state.selected_model !== null ? (openBlock(), createElementBlock("div", _hoisted_9, [ (openBlock(true), createElementBlock(Fragment, null, renderList(vaeModels.value, (vae) => { var _a3; return openBlock(), createElementBlock("div", { @@ -42803,7 +42807,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ key: vae.path }, [ createBaseVNode("p", null, toDisplayString(vae.name), 1), - createBaseVNode("div", _hoisted_9, [ + createBaseVNode("div", _hoisted_10, [ ((_a3 = unref(global2).state.selected_model) == null ? void 0 : _a3.vae) == vae.path ? (openBlock(), createBlock(unref(NButton), { key: 0, type: "error", @@ -42830,7 +42834,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ ]) ]); }), 128)) - ])) : (openBlock(), createElementBlock("div", _hoisted_10, [ + ])) : (openBlock(), createElementBlock("div", _hoisted_11, [ createVNode(unref(NAlert), { type: "warning", "show-icon": "", @@ -42859,12 +42863,12 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ title: "Usage of textual inversion" }, { default: withCtx(() => [ - _hoisted_11, + _hoisted_12, createTextVNode(". The name of the inversion that is displayed here will be the actual token (easynegative.pt -> easynegative) ") ]), _: 1 }), - unref(global2).state.selected_model !== null ? (openBlock(), createElementBlock("div", _hoisted_12, [ + unref(global2).state.selected_model !== null ? (openBlock(), createElementBlock("div", _hoisted_13, [ (openBlock(true), createElementBlock(Fragment, null, renderList(textualInversionModels.value, (textualInversion) => { var _a3; return openBlock(), createElementBlock("div", { @@ -42872,7 +42876,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ key: textualInversion.path }, [ createBaseVNode("p", null, toDisplayString(textualInversion.name), 1), - createBaseVNode("div", _hoisted_13, [ + createBaseVNode("div", _hoisted_14, [ ((_a3 = unref(global2).state.selected_model) == null ? void 0 : _a3.textual_inversions.includes( textualInversion.path )) ? (openBlock(), createBlock(unref(NButton), { @@ -42901,7 +42905,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ ]) ]); }), 128)) - ])) : (openBlock(), createElementBlock("div", _hoisted_14, [ + ])) : (openBlock(), createElementBlock("div", _hoisted_15, [ createVNode(unref(NAlert), { type: "warning", "show-icon": "", @@ -42976,136 +42980,6 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ ]), _: 1 }), - createVNode(unref(NTabPane), { name: "SDXL" }, { - default: withCtx(() => [ - createVNode(unref(NGrid), { - cols: "1 900:2", - "x-gap": 8, - "y-gap": 8, - style: { "height": "100%" } - }, { - default: withCtx(() => [ - createVNode(unref(NGi), null, { - default: withCtx(() => [ - createVNode(unref(NCard), { - title: "Models", - style: { "height": "100%" } - }, { - default: withCtx(() => [ - (openBlock(true), createElementBlock(Fragment, null, renderList(sdxlModels.value, (model) => { - return openBlock(), createElementBlock("div", { - style: { "display": "inline-flex", "width": "100%", "align-items": "center", "justify-content": "space-between", "border-bottom": "1px solid rgb(66, 66, 71)" }, - key: model.path - }, [ - createBaseVNode("p", null, toDisplayString(model.name), 1), - createBaseVNode("div", _hoisted_15, [ - model.state === "loaded" ? (openBlock(), createBlock(unref(NButton), { - key: 0, - type: "error", - ghost: "", - onClick: ($event) => unloadModel(model) - }, { - default: withCtx(() => [ - createTextVNode("Unload ") - ]), - _: 2 - }, 1032, ["onClick"])) : (openBlock(), createBlock(unref(NButton), { - key: 1, - type: "success", - ghost: "", - onClick: ($event) => loadModel(model), - loading: model.state === "loading" - }, { - default: withCtx(() => [ - createTextVNode("Load") - ]), - _: 2 - }, 1032, ["onClick", "loading"])), - createVNode(unref(NButton), { - type: "info", - style: { "margin-left": "4px" }, - ghost: "", - onClick: ($event) => unref(global2).state.selected_model = model, - disabled: model.state !== "loaded" - }, { - default: withCtx(() => [ - createTextVNode("Select") - ]), - _: 2 - }, 1032, ["onClick", "disabled"]) - ]) - ]); - }), 128)) - ]), - _: 1 - }) - ]), - _: 1 - }), - createVNode(unref(NGi), null, { - default: withCtx(() => [ - createVNode(unref(NCard), { title: vae_title.value }, { - default: withCtx(() => [ - unref(global2).state.selected_model !== null ? (openBlock(), createElementBlock("div", _hoisted_16, [ - (openBlock(true), createElementBlock(Fragment, null, renderList(sdxlVaeModels.value, (vae) => { - var _a3; - return openBlock(), createElementBlock("div", { - style: { "display": "inline-flex", "width": "100%", "align-items": "center", "justify-content": "space-between", "border-bottom": "1px solid rgb(66, 66, 71)" }, - key: vae.path - }, [ - createBaseVNode("p", null, toDisplayString(vae.name), 1), - createBaseVNode("div", _hoisted_17, [ - ((_a3 = unref(global2).state.selected_model) == null ? void 0 : _a3.vae) == vae.path ? (openBlock(), createBlock(unref(NButton), { - key: 0, - type: "error", - ghost: "", - disabled: "" - }, { - default: withCtx(() => [ - createTextVNode("Loaded ") - ]), - _: 1 - })) : (openBlock(), createBlock(unref(NButton), { - key: 1, - type: "success", - ghost: "", - onClick: ($event) => loadVAE(vae), - disabled: unref(global2).state.selected_model === void 0, - loading: vae.state === "loading" - }, { - default: withCtx(() => [ - createTextVNode("Load") - ]), - _: 2 - }, 1032, ["onClick", "disabled", "loading"])) - ]) - ]); - }), 128)) - ])) : (openBlock(), createElementBlock("div", _hoisted_18, [ - createVNode(unref(NAlert), { - type: "warning", - "show-icon": "", - title: "No model selected", - style: { "margin-top": "4px" } - }, { - default: withCtx(() => [ - createTextVNode(" Please select a model first ") - ]), - _: 1 - }) - ])) - ]), - _: 1 - }, 8, ["title"]) - ]), - _: 1 - }) - ]), - _: 1 - }) - ]), - _: 1 - }), createVNode(unref(NTabPane), { name: "ONNX" }, { default: withCtx(() => [ createVNode(unref(NScrollbar), { style: { "height": "70vh" } }, { @@ -43166,7 +43040,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ ]), _: 1 }, 8, ["show"]), - createBaseVNode("div", _hoisted_19, [ + createBaseVNode("div", _hoisted_16, [ createVNode(unref(NProgress), { type: "line", percentage: unref(global2).state.progress, @@ -43186,7 +43060,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ _: 1 }, 8, ["percentage", "processing"]) ]), - createBaseVNode("div", _hoisted_20, [ + createBaseVNode("div", _hoisted_17, [ createVNode(unref(NDropdown), { options: dropdownOptions, onSelect: dropdownSelected @@ -43208,8 +43082,8 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ }; } }); -const TopBar_vue_vue_type_style_index_0_scoped_e207b7ed_lang = ""; -const TopBar = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-e207b7ed"]]); +const TopBar_vue_vue_type_style_index_0_scoped_e0808386_lang = ""; +const TopBar = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-e0808386"]]); const Prompt_vue_vue_type_style_index_0_lang = ""; const Prompt_vue_vue_type_style_index_1_scoped_780680bc_lang = ""; const Upscale_vue_vue_type_style_index_0_scoped_5358ed01_lang = ""; diff --git a/frontend/src/components/TopBar.vue b/frontend/src/components/TopBar.vue index 0b7f057f8..e26f04a83 100644 --- a/frontend/src/components/TopBar.vue +++ b/frontend/src/components/TopBar.vue @@ -119,7 +119,22 @@ v-for="model in pyTorchModels" v-bind:key="model.path" > -

{{ model.name }}

+
+ + {{ model.backend === "SDXL" ? "SDXL" : "SD" }} + +

{{ model.name }}

+
- - - - - -
-

{{ model.name }}

-
- Unload - - Load - Select -
-
-
-
- - - -
-
-

{{ vae.name }}

-
- Loaded - - Load -
-
-
-
- - Please select a model first - -
-
-
-
-
@@ -486,6 +404,7 @@ import { NSelect, NTabPane, NTabs, + NTag, NText, type DropdownOption, } from "naive-ui"; @@ -523,7 +442,7 @@ const settings = useSettings(); const modelsLoading = ref(false); const filter = ref(""); -const filteredModels = computed(() => { +const filteredModels = computed(() => { return global.state.models.filter((model) => { return ( model.path.toLowerCase().includes(filter.value.toLowerCase()) || @@ -532,10 +451,13 @@ const filteredModels = computed(() => { }); }); -const pyTorchModels = computed(() => { +const pyTorchModels = computed(() => { return filteredModels.value .filter((model) => { - return model.backend === "PyTorch" && model.valid === true; + return ( + (model.backend === "PyTorch" || model.backend === "SDXL") && + model.valid === true + ); }) .sort((a, b) => { if (a.state === "loaded" && b.state !== "loaded") { @@ -549,17 +471,7 @@ const pyTorchModels = computed(() => { }); }); -const sdxlModels = computed(() => { - return filteredModels.value - .filter((model) => { - return model.backend === "SDXL"; - }) - .sort((a, b) => { - return a.name.localeCompare(b.name); - }); -}); - -const aitModels = computed(() => { +const aitModels = computed(() => { return filteredModels.value .filter((model) => { return model.backend === "AITemplate"; @@ -576,7 +488,7 @@ const aitModels = computed(() => { }); }); -const onnxModels = computed(() => { +const onnxModels = computed(() => { return filteredModels.value .filter((model) => { return model.backend === "ONNX"; @@ -593,65 +505,65 @@ const onnxModels = computed(() => { }); }); -const vaeModels = computed(() => { - return [ - { - name: "Default VAE", - path: "default", - backend: "VAE", - valid: true, - state: "not loaded", - vae: "default", - textual_inversions: [], - } as ModelEntry, - { - name: "Tiny VAE (fast)", - path: "madebyollin/taesd", - backend: "VAE", - valid: true, - state: "not loaded", - vae: "madebyollin/taesd", - textual_inversions: [], - } as ModelEntry, - { - name: "Asymmetric VAE", - path: "cross-attention/asymmetric-autoencoder-kl-x-1-5", - backend: "VAE", - valid: true, - state: "not loaded", - vae: "cross-attention/asymmetric-autoencoder-kl-x-1-5", - textual_inversions: [], - } as ModelEntry, - ...filteredModels.value - .filter((model) => { - return model.backend === "VAE"; - }) - .sort((a, b) => { - return a.name.localeCompare(b.name); - }), - ]; +const manualVAEModels = computed(() => { + const selectedModel = global.state.selected_model; + if (selectedModel?.backend === "SDXL") { + return [ + { + name: "Default VAE (fp32)", + path: "default", + backend: "VAE", + valid: true, + state: "not loaded", + vae: "default", + textual_inversions: [], + } as ModelEntry, + { + name: "FP16 VAE", + path: "madebyollin/sdxl-vae-fp16-fix", + backend: "VAE", + valid: true, + state: "not loaded", + vae: "fp16", + textual_inversions: [], + } as ModelEntry, + ]; + } else { + return [ + { + name: "Default VAE", + path: "default", + backend: "VAE", + valid: true, + state: "not loaded", + vae: "default", + textual_inversions: [], + } as ModelEntry, + { + name: "Tiny VAE (fast)", + path: "madebyollin/taesd", + backend: "VAE", + valid: true, + state: "not loaded", + vae: "madebyollin/taesd", + textual_inversions: [], + } as ModelEntry, + { + name: "Asymmetric VAE", + path: "cross-attention/asymmetric-autoencoder-kl-x-1-5", + backend: "VAE", + valid: true, + state: "not loaded", + vae: "cross-attention/asymmetric-autoencoder-kl-x-1-5", + textual_inversions: [], + } as ModelEntry, + ]; + } }); -const sdxlVaeModels = computed(() => { +const vaeModels = computed(() => { return [ - { - name: "Default VAE (fp32)", - path: "default", - backend: "VAE", - valid: true, - state: "not loaded", - vae: "default", - textual_inversions: [], - } as ModelEntry, - { - name: "FP16 VAE", - path: "madebyollin/sdxl-vae-fp16-fix", - backend: "VAE", - valid: true, - state: "not loaded", - vae: "fp16", - textual_inversions: [], - } as ModelEntry, + ...manualVAEModels.value, ...filteredModels.value .filter((model) => { return model.backend === "VAE"; diff --git a/frontend/src/components/settings/FlagsSettings.vue b/frontend/src/components/settings/FlagsSettings.vue index 5fa9b97ec..390384572 100644 --- a/frontend/src/components/settings/FlagsSettings.vue +++ b/frontend/src/components/settings/FlagsSettings.vue @@ -26,12 +26,8 @@ value: 'bicubic', }, { - label: 'Bislerp (Original, slow)', - value: 'bislerp-original', - }, - { - label: 'Bislerp (Tortured, fast)', - value: 'bislerp-tortured', + label: 'Bislerp', + value: 'bislerp', }, { label: 'Nearest Exact', From 66b350d7f8e128c819f8c93d301033abadfa3354 Mon Sep 17 00:00:00 2001 From: gabe56f Date: Thu, 9 Nov 2023 22:21:09 +0100 Subject: [PATCH 033/143] Completely broken module offload --- core/config/api_settings.py | 2 +- core/inference/pytorch/pipeline.py | 4 +--- core/optimizations/offload.py | 14 +++++++++----- core/optimizations/pytorch_optimizations.py | 6 +++++- frontend/dist/assets/SettingsView.js | 16 +++++++++++++++- frontend/dist/assets/TextToImageView.js | 2 +- frontend/dist/assets/index.js | 2 +- frontend/src/components/inference/Txt2Img.vue | 2 +- .../settings/OptimizationSettings.vue | 19 ++++++++++++++++++- frontend/src/settings.ts | 4 ++-- 10 files changed, 54 insertions(+), 17 deletions(-) diff --git a/core/config/api_settings.py b/core/config/api_settings.py index d75b4e83c..9b07ee359 100644 --- a/core/config/api_settings.py +++ b/core/config/api_settings.py @@ -33,7 +33,7 @@ class APIConfig: channels_last: bool = True trace_model: bool = False clear_memory_policy: Literal["always", "after_disconnect", "never"] = "always" - offload: bool = False + offload: Literal["disabled", "model", "module"] = "disabled" data_type: Literal["float32", "float16", "bfloat16"] = "float16" dont_merge_latents: bool = ( False # Will drop performance, but could help with some VRAM issues diff --git a/core/inference/pytorch/pipeline.py b/core/inference/pytorch/pipeline.py index 3a3ae3d8b..6c2932c9f 100644 --- a/core/inference/pytorch/pipeline.py +++ b/core/inference/pytorch/pipeline.py @@ -130,9 +130,7 @@ def _execution_device(self): `pipeline.enable_sequential_cpu_offload()` the execution device can only be inferred from Accelerate's module hooks. """ - if self.device != torch.device("meta") and not hasattr(self.unet, "offload_device"): # type: ignore - return self.device - return getattr(self.unet, "offload_device", self.device) + return torch.device(config.api.device) def _default_height_width(self, height, width, image): if image is None: diff --git a/core/optimizations/offload.py b/core/optimizations/offload.py index 70d3feac5..391701163 100644 --- a/core/optimizations/offload.py +++ b/core/optimizations/offload.py @@ -2,6 +2,7 @@ import logging +from accelerate import cpu_offload import torch from core.config import config @@ -18,24 +19,27 @@ def unload_all(): def ensure_correct_device(module: torch.nn.Module): - if hasattr(module, "offload_device"): + if hasattr(module, "v_offload_device"): global _module if module.__class__.__name__ == _module.__class__.__name__: return - device = getattr(module, "offload_device", config.api.device) - logger.debug(f"Transferring {module.__class__.__name__} to {str(device)}.") + device = getattr(module, "v_offload_device", config.api.device) if _module is not None: logger.debug(f"Transferring {_module.__class__.__name__} to cpu.") _module.cpu() + logger.debug(f"Transferring {module.__class__.__name__} to {str(device)}.") module.to(device=torch.device(device)) _module = module else: logger.debug(f"Don't need to do anything with {module.__class__.__name__}.") -def set_offload(module, device: torch.device): - setattr(module, "offload_device", device) +def set_offload(module: torch.nn.Module, device: torch.device): + if config.api.offload == "module": + cpu_offload(module, device, offload_buffers=len(module._parameters) > 0) + else: + setattr(module, "v_offload_device", device) diff --git a/core/optimizations/pytorch_optimizations.py b/core/optimizations/pytorch_optimizations.py index 2d19ef6ca..48d1c2a36 100644 --- a/core/optimizations/pytorch_optimizations.py +++ b/core/optimizations/pytorch_optimizations.py @@ -46,7 +46,11 @@ def optimize_model( 'You can disable it by going inside Graphics Settings → "Default Graphics Settings" and disabling "Hardware-accelerated GPU Scheduling"' ) - offload = config.api.offload and is_pytorch_pipe(pipe) and not is_for_aitemplate + offload = ( + config.api.offload != "disabled" + and is_pytorch_pipe(pipe) + and not is_for_aitemplate + ) can_offload = ( any(map(lambda x: x not in config.api.device, ["cpu", "vulkan", "mps"])) and offload diff --git a/frontend/dist/assets/SettingsView.js b/frontend/dist/assets/SettingsView.js index 379da1e77..d078d3fb0 100644 --- a/frontend/dist/assets/SettingsView.js +++ b/frontend/dist/assets/SettingsView.js @@ -1594,7 +1594,21 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ "label-placement": "left" }, { default: withCtx(() => [ - createVNode(unref(NSwitch), { + createVNode(unref(NSelect), { + options: [ + { + value: "disabled", + label: "Disabled" + }, + { + value: "model", + label: "Offload the whole model to RAM when not used" + }, + { + value: "module", + label: "Offload individual modules to RAM when not used" + } + ], value: unref(settings).defaultSettings.api.offload, "onUpdate:value": _cache[22] || (_cache[22] = ($event) => unref(settings).defaultSettings.api.offload = $event) }, null, 8, ["value"]) diff --git a/frontend/dist/assets/TextToImageView.js b/frontend/dist/assets/TextToImageView.js index 990b63ed4..df606f5e7 100644 --- a/frontend/dist/assets/TextToImageView.js +++ b/frontend/dist/assets/TextToImageView.js @@ -298,7 +298,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ flags: { ...isSelectedModelSDXL.value ? { sdxl: { - original_size: settings.data.settings.flags.sdxl.original_size + original_size: [1024, 1024] } } : {}, ...global.state.txt2img.highres ? { diff --git a/frontend/dist/assets/index.js b/frontend/dist/assets/index.js index 5f4718e9b..a23bc5fd7 100644 --- a/frontend/dist/assets/index.js +++ b/frontend/dist/assets/index.js @@ -40798,7 +40798,7 @@ const defaultSettings = { vae_tiling: false, trace_model: false, cudnn_benchmark: false, - offload: false, + offload: "disabled", dont_merge_latents: false, device: "cuda:0", data_type: "float16", diff --git a/frontend/src/components/inference/Txt2Img.vue b/frontend/src/components/inference/Txt2Img.vue index 5cbd0fcfd..551b35737 100644 --- a/frontend/src/components/inference/Txt2Img.vue +++ b/frontend/src/components/inference/Txt2Img.vue @@ -440,7 +440,7 @@ const generate = () => { ...(isSelectedModelSDXL.value ? { sdxl: { - original_size: settings.data.settings.flags.sdxl.original_size, + original_size: [1024, 1024], }, } : {}), diff --git a/frontend/src/components/settings/OptimizationSettings.vue b/frontend/src/components/settings/OptimizationSettings.vue index 6a1b4ee59..118bee800 100644 --- a/frontend/src/components/settings/OptimizationSettings.vue +++ b/frontend/src/components/settings/OptimizationSettings.vue @@ -158,7 +158,24 @@ - + +
diff --git a/frontend/src/settings.ts b/frontend/src/settings.ts index f6dc0e25c..3a9d4d8fe 100644 --- a/frontend/src/settings.ts +++ b/frontend/src/settings.ts @@ -179,7 +179,7 @@ export interface ISettings { vae_slicing: boolean; vae_tiling: boolean; trace_model: boolean; - offload: boolean; + offload: "disabled" | "model" | "module"; device: string; data_type: "float16" | "float32" | "bfloat16"; deterministic_generation: boolean; @@ -381,7 +381,7 @@ export const defaultSettings: ISettings = { vae_tiling: false, trace_model: false, cudnn_benchmark: false, - offload: false, + offload: "disabled", dont_merge_latents: false, device: "cuda:0", From 6582e73e5c47b337487f4008e25c26494d1dfff2 Mon Sep 17 00:00:00 2001 From: gabe56f Date: Fri, 10 Nov 2023 01:27:59 +0100 Subject: [PATCH 034/143] Tag expansion, improved offload --- api/routes/models.py | 5 +- core/files.py | 118 +++++------------- core/gpu.py | 8 +- core/inference/functions.py | 2 +- core/inference/pytorch/pytorch.py | 23 ++-- core/inference/sdxl/sdxl.py | 17 ++- core/inference/utilities/vae.py | 5 +- core/install_requirements.py | 17 ++- core/optimizations/offload.py | 22 ++-- core/optimizations/pytorch_optimizations.py | 2 +- core/shared.py | 8 +- core/types.py | 1 - frontend/dist/assets/TextToImageView.js | 4 +- frontend/dist/assets/index.css | 6 +- frontend/dist/assets/index.js | 75 ++++++----- frontend/src/components/TopBar.vue | 66 +++++----- frontend/src/components/inference/Txt2Img.vue | 4 +- frontend/src/core/interfaces.ts | 4 + frontend/src/types.ts | 11 ++ requirements/api.txt | 14 +-- requirements/dev.txt | 6 +- requirements/interrogation.txt | 2 +- requirements/onnx.txt | 4 +- requirements/pytorch.txt | 25 ++-- requirements/tests.txt | 4 +- 25 files changed, 229 insertions(+), 224 deletions(-) diff --git a/api/routes/models.py b/api/routes/models.py index 5d76d091d..402b1efc5 100644 --- a/api/routes/models.py +++ b/api/routes/models.py @@ -22,6 +22,7 @@ ModelResponse, TextualInversionLoadRequest, VaeLoadRequest, + PyTorchModelBase, ) from core.utils import download_file @@ -73,6 +74,7 @@ def list_loaded_models() -> List[ModelResponse]: "textual_inversions", [] ), valid=True, + type=gpu.loaded_models[model_id].__dict__.get("type", "SD1.x"), ) ) @@ -90,11 +92,12 @@ def list_available_models() -> List[ModelResponse]: def load_model( model: str, backend: InferenceBackend, + type: PyTorchModelBase, ): "Loads a model into memory" try: - gpu.load_model(model, backend) + gpu.load_model(model, backend, type) websocket_manager.broadcast_sync(data=Data(data_type="refresh_models", data={})) except torch.cuda.OutOfMemoryError: # type: ignore diff --git a/core/files.py b/core/files.py index 110181a4b..22be977e0 100644 --- a/core/files.py +++ b/core/files.py @@ -7,6 +7,7 @@ from huggingface_hub.file_download import repo_folder_name from core.types import ModelResponse +from core.utils import determine_model_type logger = logging.getLogger(__name__) @@ -53,100 +54,45 @@ def pytorch(self) -> List[ModelResponse]: # Skip if it is not a huggingface model if "model" not in model_name: continue + model_name: str = "/".join(model_name.split("--")[1:3]) + name, base, stage = determine_model_type(self.paths["pytorch"] / model_name) - name: str = "/".join(model_name.split("--")[1:3]) - try: - file = get_full_model_path(name) / "model_index.json" - with open(file, "r", encoding="UTF-8") as content: - sdxl = "StableDiffusionXL" in content.readlines()[1] - if sdxl: - models.append( - ModelResponse( - name=name, - path=name, - backend="SDXL", - vae="default", - valid=True, - state="not loaded", - ) - ) - continue - except Exception: # pylint: disable=broad-except - pass - try: - models.append( - ModelResponse( - name=name, - path=name, - backend="PyTorch", - vae="default", - valid=is_valid_diffusers_model(get_full_model_path(name)), - state="not loaded", - ) + models.append( + ModelResponse( + name=name, + path=name, + backend="PyTorch", + type=base, + stage=stage, + vae="default", + valid=is_valid_diffusers_model(get_full_model_path(model_name)), + state="not loaded", ) - except ValueError: - logger.debug(f"Invalid model {name}, skipping...") - continue + ) - # Localy stored models + # Locally stored models logger.debug(f"Looking for local models in {self.paths['checkpoints']}") for model_name in os.listdir(self.paths["checkpoints"]): logger.debug(f"Found model {model_name}") - - if self.paths["checkpoints"].joinpath(model_name).is_dir(): - # Assuming that model is in Diffusers format - file = self.paths["checkpoints"] / model_name / "model_index.json" - try: - with open(file, "r", encoding="UTF-8") as content: - sdxl = "StableDiffusionXL" in content.readlines()[1] - if sdxl: - models.append( - ModelResponse( - name=model_name, - path=model_name, - backend="SDXL", - vae="default", - valid=True, - state="not loaded", - ) - ) - continue - except Exception: # pylint: disable=broad-except - pass - models.append( - ModelResponse( - name=model_name, - path=model_name, - backend="PyTorch", - vae="default", - valid=is_valid_diffusers_model( - self.paths["checkpoints"].joinpath(model_name) - ), - state="not loaded", - ) - ) - elif (self.paths["checkpoints"] / model_name).suffix in [ - ".ckpt", - ".safetensors", - ]: - # Assuming that model is in Checkpoint / Safetensors format - models.append( - ModelResponse( - name=model_name, - path=model_name, - backend="PyTorch" - if "xl" not in model_name.casefold() - else "SDXL", - vae="default", - valid=True, - state="not loaded", - ) - ) + if model_name.endswith(".ckpt"): + name, base, stage = model_name, "SD1.x", "first_stage" else: - # Junk file, notify user - logger.debug( - f"Found junk file {model_name} in {self.paths['checkpoints']}, skipping..." + name, base, stage = determine_model_type( + self.paths["checkpoints"] / model_name + ) + + models.append( + ModelResponse( + name=name, + path=model_name, + backend="PyTorch", + vae="default", + valid=True, + state="not loaded", + type=base, + stage=stage, ) + ) return models diff --git a/core/gpu.py b/core/gpu.py index 55a9dfc43..c72de6efc 100644 --- a/core/gpu.py +++ b/core/gpu.py @@ -38,6 +38,7 @@ TextualInversionLoadRequest, UpscaleQueueEntry, VaeLoadRequest, + PyTorchModelBase, ) from core.utils import convert_to_image, image_grid, preprocess_job @@ -221,13 +222,13 @@ def generate_thread_call(job: Job) -> List[Image.Image]: shared_dependent.cached_controlnet_preprocessor = None self.memory_cleanup() - # shared.current_model = model - if isinstance(model, PyTorchStableDiffusion): logger.debug("Generating with PyTorch") + shared.current_model = "SD1.x" images: List[Image.Image] = model.generate(job) elif isinstance(model, SDXLStableDiffusion): logger.debug("Generating with SDXL (PyTorch)") + shared.current_model = "SDXL" images: List[Image.Image] = model.generate(job) elif isinstance(model, AITemplateStableDiffusion): logger.debug("Generating with AITemplate") @@ -333,6 +334,7 @@ def load_model( self, model: str, backend: InferenceBackend, + type: PyTorchModelBase, ): "Load a model into memory" @@ -397,7 +399,7 @@ def load_model_thread_call( pt_model = OnnxStableDiffusion(model_id=model) self.loaded_models[model] = pt_model - elif backend == "SDXL": + elif type == "SDXL": logger.debug("Selecting SDXL") websocket_manager.broadcast_sync( diff --git a/core/inference/functions.py b/core/inference/functions.py index 4874d955f..e1fae83be 100644 --- a/core/inference/functions.py +++ b/core/inference/functions.py @@ -363,7 +363,7 @@ def load_pytorch_pipeline( type = determine_model_type(get_full_model_path(model_id_or_path)) cl = StableDiffusionXLPipeline if type[1] == "SDXL" else StableDiffusionPipeline # I never knew this existed, but this is pretty handy :) - # cl.__init__ = partialmethod(cl.__init__, requires_safety_checker=False) # type: ignore + # cl.__init__ = partialmethod(cl.__init__, low_cpu_mem_usage=True) # type: ignore try: pipe = download_from_original_stable_diffusion_ckpt( str(get_full_model_path(model_id_or_path)), diff --git a/core/inference/pytorch/pytorch.py b/core/inference/pytorch/pytorch.py index f271a6d93..8fdfaeab3 100755 --- a/core/inference/pytorch/pytorch.py +++ b/core/inference/pytorch/pytorch.py @@ -139,8 +139,12 @@ def change_vae(self, vae: str) -> None: old_vae = getattr(self, "original_vae") # Not sure what I needed this for, but whatever - # dtype = self.unet.dtype - # device = self.unet.device + dtype = self.unet.dtype + device = self.unet.device + + if hasattr(self.text_encoder, "v_offload_device"): + device = torch.device("cpu") + if vae == "default": self.vae = old_vae else: @@ -149,9 +153,7 @@ def change_vae(self, vae: str) -> None: f"https://huggingface.co/{vae}/raw/main/config.json" ).json()["_class_name"] cont = getattr(importlib.import_module("diffusers"), cont) - self.vae = cont.from_pretrained(vae).to( - device=old_vae.device, dtype=old_vae.dtype - ) + self.vae = cont.from_pretrained(vae).to(device, dtype) if not hasattr(self.vae.config, "block_out_channels"): setattr( self.vae.config, @@ -168,12 +170,17 @@ def change_vae(self, vae: str) -> None: if Path(vae).is_dir(): self.vae = ModelMixin.from_pretrained(vae) # type: ignore else: - self.vae = convert_vaept_to_diffusers(vae).to( - device=old_vae.device, dtype=old_vae.dtype - ) + self.vae = convert_vaept_to_diffusers(vae).to(device, dtype) else: raise FileNotFoundError(f"{vae} is not a valid path") + # Check if text_encoder has v_offload_device, because it always + # gets wholly offloaded instead of being sequentially offloaded + if hasattr(self.text_encoder, "v_offload_device"): + from core.optimizations.offload import set_offload + + self.vae = set_offload(self.vae, torch.device(config.api.device)) # type: ignore + logger.info(f"Successfully changed vae to {vae} of type {type(self.vae)}") # This is at the end 'cause I've read horror stories about pythons prefetch system diff --git a/core/inference/sdxl/sdxl.py b/core/inference/sdxl/sdxl.py index f6940c648..8c0606c33 100644 --- a/core/inference/sdxl/sdxl.py +++ b/core/inference/sdxl/sdxl.py @@ -52,7 +52,8 @@ def __init__( ) -> None: super().__init__(model_id, device) - self.backend: Backend = "SDXL" + self.backend: Backend = "PyTorch" + self.type = "SDXL" self.bare: bool = bare # Components @@ -113,6 +114,10 @@ def change_vae(self, vae: str) -> None: old_vae = getattr(self, "original_vae") dtype = self.unet.dtype device = self.unet.device + + if hasattr(self.text_encoder, "v_offload_device"): + device = torch.device("cpu") + if vae == "default": self.vae = old_vae else: @@ -124,8 +129,12 @@ def change_vae(self, vae: str) -> None: self.vae = convert_vaept_to_diffusers(vae).to( device=device, dtype=dtype ) - if hasattr(old_vae, "offload_device"): - setattr(self.vae, "offload_device", getattr(old_vae, "offload_device")) + # Check if text_encoder has v_offload_device, because it always + # gets wholly offloaded instead of being sequentially offloaded + if hasattr(self.text_encoder, "v_offload_device"): + from core.optimizations.offload import set_offload + + self.vae = set_offload(self.vae, torch.device(config.api.device)) # type: ignore self.vae_path = vae def unload(self) -> None: @@ -196,7 +205,7 @@ def txt2img(self, job: Txt2ImgQueueEntry) -> List[Image.Image]: unload = False if flags.model not in gpu.loaded_models: - gpu.load_model(flags.model, "SDXL") + gpu.load_model(flags.model, "PyTorch", "SDXL") unload = True model: SDXLStableDiffusion = gpu.loaded_models[flags.model] # type: ignore if config.api.clear_memory_policy == "always": diff --git a/core/inference/utilities/vae.py b/core/inference/utilities/vae.py index ab6cf8b5c..1023246c0 100644 --- a/core/inference/utilities/vae.py +++ b/core/inference/utilities/vae.py @@ -5,6 +5,7 @@ from PIL import Image from core.config import config +from core import shared taesd_model = None @@ -18,7 +19,7 @@ def taesd( from diffusers.models.autoencoder_tiny import AutoencoderTiny model = "madebyollin/taesd" - if False: # TODO: if is_sdxl: + if shared.current_model == "SDXL": model = "madebyollin/taesdxl" taesd_model = AutoencoderTiny.from_pretrained( model, torch_dtype=torch.float16 @@ -46,7 +47,7 @@ def cheap_approximation(sample: torch.Tensor) -> Image.Image: [-0.158, 0.189, 0.264], [-0.184, -0.271, -0.473], ] - if False: # TODO: if is_sdxl: + if shared.current_model == "SDXL": coeffs = [ [0.3448, 0.4168, 0.4395], [-0.1953, -0.0290, 0.0250], diff --git a/core/install_requirements.py b/core/install_requirements.py index b56e47050..8383d40e0 100644 --- a/core/install_requirements.py +++ b/core/install_requirements.py @@ -160,9 +160,9 @@ class PytorchDistribution: "-m", "pip", "install", - "torch==1.13.0a0", - "torchvision==0.14.1a0", - "intel_extension_for_pytorch==1.13.120+xpu", + "torch==2.0.1a0", + "torchvision==0.15.2a0", + "intel_extension_for_pytorch==2.0.110+xpu", "-f", "https://developer.intel.com/ipex-whl-stable-xpu", ], @@ -239,7 +239,7 @@ def install_deps(force_distribution: int = -1): logger.info("Installing PyTorch") if platform.system() == "Darwin": subprocess.check_call( - [sys.executable, "-m", "pip", "install", "torch==2.0.0", "torchvision"] + [sys.executable, "-m", "pip", "install", "torch==2.1.0", "torchvision"] ) else: for c in _pytorch_distributions: @@ -410,8 +410,13 @@ def check_valid_python_version(): print("Please consider switching to an older release to use volta!") raise RuntimeError("Unsupported Python version") elif minor < 9: - print("The python release you are currently using is older than our") - print("official supported version! Please consider updating to Python 3.11!") + print("--------------------------------------------------------") + print("| The python release you are currently using is older |") + print("| than our official supported version! Please consider |") + print("| updating to Python 3.11! |") + print("| |") + print("| Issues will most likely be IGNORED! |") + print("--------------------------------------------------------") def is_up_to_date(): diff --git a/core/optimizations/offload.py b/core/optimizations/offload.py index 391701163..3e0b46d49 100644 --- a/core/optimizations/offload.py +++ b/core/optimizations/offload.py @@ -19,18 +19,15 @@ def unload_all(): def ensure_correct_device(module: torch.nn.Module): - if hasattr(module, "v_offload_device"): - global _module - + global _module + if _module is not None: if module.__class__.__name__ == _module.__class__.__name__: return - + logger.debug(f"Transferring {_module.__class__.__name__} to cpu.") + _module.cpu() + if hasattr(module, "v_offload_device"): device = getattr(module, "v_offload_device", config.api.device) - if _module is not None: - logger.debug(f"Transferring {_module.__class__.__name__} to cpu.") - _module.cpu() - logger.debug(f"Transferring {module.__class__.__name__} to {str(device)}.") module.to(device=torch.device(device)) _module = module @@ -40,6 +37,9 @@ def ensure_correct_device(module: torch.nn.Module): def set_offload(module: torch.nn.Module, device: torch.device): if config.api.offload == "module": - cpu_offload(module, device, offload_buffers=len(module._parameters) > 0) - else: - setattr(module, "v_offload_device", device) + if "CLIP" not in module.__class__.__name__: + return cpu_offload( + module, device, offload_buffers=len(module._parameters) > 0 + ) + setattr(module, "v_offload_device", device) + return module diff --git a/core/optimizations/pytorch_optimizations.py b/core/optimizations/pytorch_optimizations.py index 48d1c2a36..0f83e73c6 100644 --- a/core/optimizations/pytorch_optimizations.py +++ b/core/optimizations/pytorch_optimizations.py @@ -132,7 +132,7 @@ def optimize_model( ]: cpu_offloaded_model = getattr(pipe, model_name, None) if cpu_offloaded_model is not None: - set_offload(cpu_offloaded_model, device) + cpu_offloaded_model = set_offload(cpu_offloaded_model, device) setattr(pipe, model_name, cpu_offloaded_model) logger.info("Optimization: Offloaded model parts to CPU.") diff --git a/core/shared.py b/core/shared.py index 8530d61b6..579b045dd 100644 --- a/core/shared.py +++ b/core/shared.py @@ -1,15 +1,15 @@ import asyncio from concurrent.futures import ThreadPoolExecutor -from typing import TYPE_CHECKING, List, Optional, Union, Literal +from typing import TYPE_CHECKING, List, Optional, Literal + +from .types import PyTorchModelBase if TYPE_CHECKING: from uvicorn import Server - from core.inference.pytorch import PyTorchStableDiffusion - amd: bool = False all_gpus: List = [] -current_model: Union["PyTorchStableDiffusion", None] = None +current_model: Optional[PyTorchModelBase] = None current_method: Literal[None, "txt2img", "img2img", "inpainting", "controlnet"] = None current_steps: int = 50 current_done_steps: int = 0 diff --git a/core/types.py b/core/types.py index 72d11d9f6..53af57d08 100644 --- a/core/types.py +++ b/core/types.py @@ -21,7 +21,6 @@ SigmaScheduler = Literal["automatic", "karras", "exponential", "polyexponential", "vp"] Backend = Literal[ "PyTorch", - "SDXL", "AITemplate", "unknown", "LoRA", diff --git a/frontend/dist/assets/TextToImageView.js b/frontend/dist/assets/TextToImageView.js index df606f5e7..892829448 100644 --- a/frontend/dist/assets/TextToImageView.js +++ b/frontend/dist/assets/TextToImageView.js @@ -236,11 +236,11 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ const messageHandler = useMessage(); const isSelectedModelSDXL = computed(() => { var _a; - return ((_a = settings.data.settings.model) == null ? void 0 : _a.backend) === "SDXL"; + return ((_a = settings.data.settings.model) == null ? void 0 : _a.type) === "SDXL"; }); const refinerModels = computed(() => { return global.state.models.filter( - (model) => model.backend === "SDXL" && model.name.toLowerCase().includes("refiner") + (model) => model.type === "SDXL" && model.name.toLowerCase().includes("refiner") ).map((model) => { return { label: model.name, diff --git a/frontend/dist/assets/index.css b/frontend/dist/assets/index.css index 2f1d0e053..bc04a78b4 100644 --- a/frontend/dist/assets/index.css +++ b/frontend/dist/assets/index.css @@ -50,12 +50,12 @@ justify-content: center; } -.progress-container[data-v-e0808386] { +.progress-container[data-v-ab2d5f77] { margin: 12px; flex-grow: 1; width: 400px; } -.top-bar[data-v-e0808386] { +.top-bar[data-v-ab2d5f77] { display: inline-flex; align-items: center; padding-top: 10px; @@ -66,7 +66,7 @@ top: 0; z-index: 1; } -.logo[data-v-e0808386] { +.logo[data-v-ab2d5f77] { margin-right: 16px; margin-left: 16px; } diff --git a/frontend/dist/assets/index.js b/frontend/dist/assets/index.js index c70219d35..a1d41fd5e 100644 --- a/frontend/dist/assets/index.js +++ b/frontend/dist/assets/index.js @@ -42069,7 +42069,7 @@ function urlFromPath(path) { const url = new URL(path, serverUrl); return url.href; } -const _withScopeId = (n) => (pushScopeId("data-v-e0808386"), n = n(), popScopeId(), n); +const _withScopeId = (n) => (pushScopeId("data-v-ab2d5f77"), n = n(), popScopeId(), n); const _hoisted_1$1 = { class: "top-bar" }; const _hoisted_2 = { key: 0 }; const _hoisted_3 = { key: 1 }; @@ -42106,7 +42106,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ }); const pyTorchModels = computed(() => { return filteredModels.value.filter((model) => { - return (model.backend === "PyTorch" || model.backend === "SDXL") && model.valid === true; + return model.backend === "PyTorch" && model.valid === true; }).sort((a, b) => { if (a.state === "loaded" && b.state !== "loaded") { return -1; @@ -42145,7 +42145,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ }); const manualVAEModels = computed(() => { const selectedModel = global2.state.selected_model; - if ((selectedModel == null ? void 0 : selectedModel.backend) === "SDXL") { + if ((selectedModel == null ? void 0 : selectedModel.type) === "SDXL") { return [ { name: "Default VAE (fp32)", @@ -42154,7 +42154,9 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ valid: true, state: "not loaded", vae: "default", - textual_inversions: [] + textual_inversions: [], + type: "SDXL", + stage: "last_stage" }, { name: "FP16 VAE", @@ -42163,7 +42165,9 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ valid: true, state: "not loaded", vae: "fp16", - textual_inversions: [] + textual_inversions: [], + type: "SDXL", + stage: "last_stage" } ]; } else { @@ -42175,7 +42179,9 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ valid: true, state: "not loaded", vae: "default", - textual_inversions: [] + textual_inversions: [], + type: "SD1.x", + stage: "last_stage" }, { name: "Tiny VAE (fast)", @@ -42184,7 +42190,9 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ valid: true, state: "not loaded", vae: "madebyollin/taesd", - textual_inversions: [] + textual_inversions: [], + type: "SD1.x", + stage: "last_stage" }, { name: "Asymmetric VAE", @@ -42193,7 +42201,9 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ valid: true, state: "not loaded", vae: "cross-attention/asymmetric-autoencoder-kl-x-1-5", - textual_inversions: [] + textual_inversions: [], + type: "SD1.x", + stage: "last_stage" } ]; } @@ -42260,7 +42270,6 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ ...loadedPyTorchModels.value, ...loadedAitModels.value, ...loadedOnnxModels.value, - ...loadedSdxlModels.value, ...loadedExtraModels.value ]; console.log("All loaded models: ", allLoaded); @@ -42316,7 +42325,11 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ model.state = "loading"; modelsLoading.value = true; const load_url = new URL(`${serverUrl}/api/models/load`); - const params = { model: model.path, backend: model.backend }; + const params = { + model: model.path, + backend: model.backend, + type: model.type + }; load_url.search = new URLSearchParams(params).toString(); fetch(load_url, { method: "POST" @@ -42432,6 +42445,21 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ global2.state.models.splice(0, global2.state.models.length); console.log("Reset models"); } + function getModelTag(type) { + switch (type) { + case "SD1.x": + return [type, "primary"]; + case "SD2.x": + return [type, "info"]; + case "SDXL": + return [type, "warning"]; + case "Kandinsky 2.1": + case "Kandinsky 2.2": + return ["Kandinsky", "success"]; + default: + return [type, "error"]; + } + } websocketState.onConnectedCallbacks.push(() => { refreshModels(); }); @@ -42459,11 +42487,6 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ return model.backend === "ONNX" && model.state === "loaded"; }); }); - const loadedSdxlModels = computed(() => { - return global2.state.models.filter((model) => { - return model.backend === "SDXL" && model.state === "loaded"; - }); - }); const loadedExtraModels = computed(() => { return global2.state.models.filter((model) => { return model.backend === "unknown" && model.state === "loaded"; @@ -42521,24 +42544,10 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ }) }; }); - const sdxlOptions = computed(() => { - return { - type: "group", - label: "SDXL", - key: "sdxl", - children: loadedSdxlModels.value.map((model) => { - return { - label: model.name, - value: `${model.path}:SDXL` - }; - }) - }; - }); const generatedModelOptions = computed(() => { return [ pyTorchOptions.value, aitOptions.value, - sdxlOptions.value, onnxOptions.value, extraOptions.value ]; @@ -42745,12 +42754,12 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ }, [ createBaseVNode("div", _hoisted_7, [ createVNode(unref(NTag), { - type: model.backend === "SDXL" ? "warning" : "info", + type: getModelTag(model.type)[1], ghost: "", style: { "margin-right": "8px" } }, { default: withCtx(() => [ - createTextVNode(toDisplayString(model.backend === "SDXL" ? "SDXL" : "SD"), 1) + createTextVNode(toDisplayString(getModelTag(model.type)[0]), 1) ]), _: 2 }, 1032, ["type"]), @@ -43087,8 +43096,8 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ }; } }); -const TopBar_vue_vue_type_style_index_0_scoped_e0808386_lang = ""; -const TopBar = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-e0808386"]]); +const TopBar_vue_vue_type_style_index_0_scoped_ab2d5f77_lang = ""; +const TopBar = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-ab2d5f77"]]); const Prompt_vue_vue_type_style_index_0_lang = ""; const Prompt_vue_vue_type_style_index_1_scoped_780680bc_lang = ""; const Upscale_vue_vue_type_style_index_0_scoped_5358ed01_lang = ""; diff --git a/frontend/src/components/TopBar.vue b/frontend/src/components/TopBar.vue index e26f04a83..17865ad6a 100644 --- a/frontend/src/components/TopBar.vue +++ b/frontend/src/components/TopBar.vue @@ -127,11 +127,11 @@ " > - {{ model.backend === "SDXL" ? "SDXL" : "SD" }} + {{ getModelTag(model.type)[0] }}

{{ model.name }}

@@ -454,10 +454,7 @@ const filteredModels = computed(() => { const pyTorchModels = computed(() => { return filteredModels.value .filter((model) => { - return ( - (model.backend === "PyTorch" || model.backend === "SDXL") && - model.valid === true - ); + return model.backend === "PyTorch" && model.valid === true; }) .sort((a, b) => { if (a.state === "loaded" && b.state !== "loaded") { @@ -507,7 +504,7 @@ const onnxModels = computed(() => { const manualVAEModels = computed(() => { const selectedModel = global.state.selected_model; - if (selectedModel?.backend === "SDXL") { + if (selectedModel?.type === "SDXL") { return [ { name: "Default VAE (fp32)", @@ -517,6 +514,8 @@ const manualVAEModels = computed(() => { state: "not loaded", vae: "default", textual_inversions: [], + type: "SDXL", + stage: "last_stage", } as ModelEntry, { name: "FP16 VAE", @@ -526,6 +525,8 @@ const manualVAEModels = computed(() => { state: "not loaded", vae: "fp16", textual_inversions: [], + type: "SDXL", + stage: "last_stage", } as ModelEntry, ]; } else { @@ -538,6 +539,8 @@ const manualVAEModels = computed(() => { state: "not loaded", vae: "default", textual_inversions: [], + type: "SD1.x", + stage: "last_stage", } as ModelEntry, { name: "Tiny VAE (fast)", @@ -547,6 +550,8 @@ const manualVAEModels = computed(() => { state: "not loaded", vae: "madebyollin/taesd", textual_inversions: [], + type: "SD1.x", + stage: "last_stage", } as ModelEntry, { name: "Asymmetric VAE", @@ -556,6 +561,8 @@ const manualVAEModels = computed(() => { state: "not loaded", vae: "cross-attention/asymmetric-autoencoder-kl-x-1-5", textual_inversions: [], + type: "SD1.x", + stage: "last_stage", } as ModelEntry, ]; } @@ -640,7 +647,6 @@ function refreshModels() { ...loadedPyTorchModels.value, ...loadedAitModels.value, ...loadedOnnxModels.value, - ...loadedSdxlModels.value, ...loadedExtraModels.value, ]; @@ -710,7 +716,11 @@ async function loadModel(model: ModelEntry) { model.state = "loading"; modelsLoading.value = true; const load_url = new URL(`${serverUrl}/api/models/load`); - const params = { model: model.path, backend: model.backend }; + const params = { + model: model.path, + backend: model.backend, + type: model.type, + }; load_url.search = new URLSearchParams(params).toString(); fetch(load_url, { @@ -844,6 +854,24 @@ function resetModels() { console.log("Reset models"); } +function getModelTag( + type: string +): [string, "info" | "warning" | "success" | "error" | "primary"] { + switch (type) { + case "SD1.x": + return [type, "primary"]; + case "SD2.x": + return [type, "info"]; + case "SDXL": + return [type, "warning"]; + case "Kandinsky 2.1": + case "Kandinsky 2.2": + return ["Kandinsky", "success"]; + default: + return [type, "error"]; + } +} + websocketState.onConnectedCallbacks.push(() => { refreshModels(); }); @@ -872,11 +900,6 @@ const loadedOnnxModels = computed(() => { return model.backend === "ONNX" && model.state === "loaded"; }); }); -const loadedSdxlModels = computed(() => { - return global.state.models.filter((model) => { - return model.backend === "SDXL" && model.state === "loaded"; - }); -}); const loadedExtraModels = computed(() => { return global.state.models.filter((model) => { return model.backend === "unknown" && model.state === "loaded"; @@ -939,25 +962,10 @@ const extraOptions: ComputedRef = computed(() => { }; }); -const sdxlOptions: ComputedRef = computed(() => { - return { - type: "group", - label: "SDXL", - key: "sdxl", - children: loadedSdxlModels.value.map((model) => { - return { - label: model.name, - value: `${model.path}:SDXL`, - }; - }), - }; -}); - const generatedModelOptions: ComputedRef = computed(() => { return [ pyTorchOptions.value, aitOptions.value, - sdxlOptions.value, onnxOptions.value, extraOptions.value, ]; diff --git a/frontend/src/components/inference/Txt2Img.vue b/frontend/src/components/inference/Txt2Img.vue index 551b35737..0c8f26122 100644 --- a/frontend/src/components/inference/Txt2Img.vue +++ b/frontend/src/components/inference/Txt2Img.vue @@ -361,14 +361,14 @@ const settings = useSettings(); const messageHandler = useMessage(); const isSelectedModelSDXL = computed(() => { - return settings.data.settings.model?.backend === "SDXL"; + return settings.data.settings.model?.type === "SDXL"; }); const refinerModels = computed(() => { return global.state.models .filter( (model) => - model.backend === "SDXL" && model.name.toLowerCase().includes("refiner") + model.type === "SDXL" && model.name.toLowerCase().includes("refiner") ) .map((model) => { return { diff --git a/frontend/src/core/interfaces.ts b/frontend/src/core/interfaces.ts index 05d26680b..4f71a3446 100644 --- a/frontend/src/core/interfaces.ts +++ b/frontend/src/core/interfaces.ts @@ -1,3 +1,5 @@ +import type { PyTorchModelBase, PyTorchModelStage } from "@/types"; + export interface imgData { id: string; path: string; @@ -38,6 +40,8 @@ export interface ModelEntry { vae: string; state: "loading" | "loaded" | "not loaded"; textual_inversions: string[]; + type: PyTorchModelBase; + stage: PyTorchModelStage; } export interface Capabilities { diff --git a/frontend/src/types.ts b/frontend/src/types.ts index b6519e61e..e16e4a2b8 100644 --- a/frontend/src/types.ts +++ b/frontend/src/types.ts @@ -8,4 +8,15 @@ export type ExtendedThemeOverrides = GlobalThemeOverrides & { }; }; +export type PyTorchModelBase = + | "SD1.x" + | "SD2.x" + | "SDXL" + | "Kandinsky 2.1" + | "Kandinsky 2.2" + | "Wuerstchen" + | "IF"; + +export type PyTorchModelStage = "text_encoding" | "first_stage" | "last_stage"; + export type InferenceTabs = "txt2img" | "img2img" | "inpainting" | "controlnet"; diff --git a/requirements/api.txt b/requirements/api.txt index fd4a56b29..6c9cfb61f 100644 --- a/requirements/api.txt +++ b/requirements/api.txt @@ -1,11 +1,11 @@ requests==2.31.0 fastapi==0.95.0 -websockets==11.0 -uvicorn==0.22.0 -pyngrok==6.0.0 -nest_asyncio==1.5.6 -fastapi-analytics==1.1.4 +websockets==12.0 +uvicorn==0.24.0.post1 +pyngrok==7.0.0 +nest_asyncio==1.5.8 +fastapi-analytics==1.1.5 fastapi-simple-cachecontrol==0.1.0 python-multipart==0.0.6 -streaming_form_data==1.12.0 -rich==13.4.2 +streaming-form-data==1.13.0 +rich==13.6.0 diff --git a/requirements/dev.txt b/requirements/dev.txt index aeaa5763a..6ef463822 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -1,3 +1,3 @@ -pre-commit==3.3.3 -black==23.3.0 -pylint==2.17.4 \ No newline at end of file +pre-commit==3.5.0 +black==23.11.0 +ruff==0.1.5 \ No newline at end of file diff --git a/requirements/interrogation.txt b/requirements/interrogation.txt index 87964d3ff..68b1b0918 100644 --- a/requirements/interrogation.txt +++ b/requirements/interrogation.txt @@ -1,2 +1,2 @@ -open_clip_torch==2.20.0 +open-clip-torch==2.23.0 git+https://github.com/dhansmair/flamingo-mini@3f2234da433cad5aae07d5fee12c6c61cda9cca0 # 0.0.2 \ No newline at end of file diff --git a/requirements/onnx.txt b/requirements/onnx.txt index f74331e45..cce1ed67c 100644 --- a/requirements/onnx.txt +++ b/requirements/onnx.txt @@ -1,2 +1,2 @@ -onnxruntime==1.14.1 -onnx==1.13.1 \ No newline at end of file +onnxruntime==1.16.2 +onnx==1.15.0 \ No newline at end of file diff --git a/requirements/pytorch.txt b/requirements/pytorch.txt index 2ae1c55ef..14b87e89b 100644 --- a/requirements/pytorch.txt +++ b/requirements/pytorch.txt @@ -1,25 +1,26 @@ --extra-index-url https://pypi.ngc.nvidia.com coloredlogs==15.0.1 -dataclasses-json==0.5.8 -diffusers==0.22.2 -huggingface_hub==0.17.3 +dataclasses-json==0.6.1 +diffusers==0.23.0 +huggingface-hub==0.17.3 +tokenizers==0.14.1 scipy==1.10.1 -transformers==4.31.0 -accelerate==0.21.0 +transformers==4.35.0 +accelerate==0.24.1 ftfy==6.1.1 OmegaConf==2.3.0 -safetensors==0.3.1 -pytorch-lightning==2.0.3 -gpustat==1.1 +safetensors==0.4.0 +pytorch-lightning==2.1.1 +gpustat==1.1.1 opencv-contrib-python-headless==4.7.0.72 -controlnet-aux==0.0.6 +controlnet-aux==0.0.7 realesrgan==0.3.0 -timm==0.9.2 -boto3==1.26.153 +timm==0.9.10 +boto3==1.28.83 tomesd==0.1.3 invisible-watermark==0.2.0 cpufeature==0.2.1; platform_system != "Darwin" -pyamdgpuinfo; platform_system == "Linux" +pyamdgpuinfo==2.1.6; platform_system == "Linux" piexif==1.1.3 git+https://github.com/tfernd/HyperTile@2ef64b2800d007d305755c33550537410310d7df # 0.1.5 k-diffusion==0.1.1 diff --git a/requirements/tests.txt b/requirements/tests.txt index 23433a3a4..a313ed169 100644 --- a/requirements/tests.txt +++ b/requirements/tests.txt @@ -1,4 +1,4 @@ -httpx==0.24.1 -pytest==7.3.2 +httpx==0.25.1 +pytest==7.4.3 pytest-optional-tests==0.1.1 pytest-cov==4.1.0 \ No newline at end of file From cad5969368efbd75597affd4642e49d37bded5e5 Mon Sep 17 00:00:00 2001 From: Stax124 Date: Fri, 10 Nov 2023 14:50:51 +0100 Subject: [PATCH 035/143] Hardcode gpu load model for now, better error handling when searching for models, rename requirement to stop install loop --- api/app.py | 4 +++- core/files.py | 10 ++++++++-- core/install_requirements.py | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/api/app.py b/api/app.py index 8260c8905..29ccffe32 100644 --- a/api/app.py +++ b/api/app.py @@ -130,7 +130,9 @@ async def startup_event(): for model in config.api.autoloaded_models: if model in [i.path for i in all_models]: backend: InferenceBackend = [i.backend for i in all_models if i.path == model][0] # type: ignore - gpu.load_model(model, backend) + gpu.load_model( + model, backend, type="SD1.x" + ) # TODO: this is hardcoded now, we need something dynamic here else: logger.warning(f"Autoloaded model {model} not found, skipping") diff --git a/core/files.py b/core/files.py index 22be977e0..10350b0ab 100644 --- a/core/files.py +++ b/core/files.py @@ -57,6 +57,12 @@ def pytorch(self) -> List[ModelResponse]: model_name: str = "/".join(model_name.split("--")[1:3]) name, base, stage = determine_model_type(self.paths["pytorch"] / model_name) + try: + full_path = get_full_model_path(model_name) + except ValueError as e: + logger.debug(f"Model {model_name} is not valid: {e}") + continue + models.append( ModelResponse( name=name, @@ -65,7 +71,7 @@ def pytorch(self) -> List[ModelResponse]: type=base, stage=stage, vae="default", - valid=is_valid_diffusers_model(get_full_model_path(model_name)), + valid=is_valid_diffusers_model(full_path), state="not loaded", ) ) @@ -453,7 +459,7 @@ def get_full_model_path( ref = current_diffusers_ref(storage, revision) if not ref: - raise ValueError("No ref found") + raise ValueError(f"No ref found for {repo_id}") if diffusers_skip_ref_follow: return Path(storage) diff --git a/core/install_requirements.py b/core/install_requirements.py index 8383d40e0..169b242f1 100644 --- a/core/install_requirements.py +++ b/core/install_requirements.py @@ -14,7 +14,7 @@ "opencv-contrib-python-headless": "cv2", "fastapi-analytics": "api_analytics", "cuda-python": "cuda", - "open_clip_torch": "open_clip", + "open-clip-torch": "open_clip", "python-multipart": "multipart", "invisible-watermark": "imwatermark", "discord.py": "discord", From 1d63a68b26a82bd775528ec790a869654518c126 Mon Sep 17 00:00:00 2001 From: Stax124 Date: Fri, 10 Nov 2023 18:37:29 +0100 Subject: [PATCH 036/143] add few cases to determine_model_type, hook it up to autoloader --- api/app.py | 8 +++++--- core/files.py | 13 +++++++++---- core/utils.py | 12 +++++++++--- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/api/app.py b/api/app.py index 29ccffe32..ed4ce8157 100644 --- a/api/app.py +++ b/api/app.py @@ -19,7 +19,9 @@ from api.websockets.data import Data from api.websockets.notification import Notification from core import shared +from core.files import get_full_model_path from core.types import InferenceBackend +from core.utils import determine_model_type logger = logging.getLogger(__name__) @@ -130,9 +132,9 @@ async def startup_event(): for model in config.api.autoloaded_models: if model in [i.path for i in all_models]: backend: InferenceBackend = [i.backend for i in all_models if i.path == model][0] # type: ignore - gpu.load_model( - model, backend, type="SD1.x" - ) # TODO: this is hardcoded now, we need something dynamic here + model_type = determine_model_type(get_full_model_path(model))[1] + + gpu.load_model(model, backend, type=model_type) else: logger.warning(f"Autoloaded model {model} not found, skipping") diff --git a/core/files.py b/core/files.py index 10350b0ab..cc2c735ef 100644 --- a/core/files.py +++ b/core/files.py @@ -1,7 +1,7 @@ import logging import os from pathlib import Path -from typing import List, Optional, Union +from typing import List, Union from diffusers.utils.constants import DIFFUSERS_CACHE from huggingface_hub.file_download import repo_folder_name @@ -406,17 +406,18 @@ def diffusers_storage_name(repo_id: str, repo_type: str = "model") -> str: ) -def current_diffusers_ref(path: str, revision: str = "main") -> Optional[str]: +def current_diffusers_ref(path: str, revision: str = "main") -> str: "Return the current ref of the diffusers model" rev_path = os.path.join(path, "refs", revision) snapshot_path = os.path.join(path, "snapshots") if not os.path.exists(rev_path) or not os.path.exists(snapshot_path): - return None + raise ValueError( + f"Ref path {rev_path} or snapshot path {snapshot_path} not found" + ) snapshots = os.listdir(snapshot_path) - ref = "" with open(os.path.join(path, "refs", revision), "r", encoding="utf-8") as f: ref = f.read().strip().split(":")[0] @@ -425,6 +426,10 @@ def current_diffusers_ref(path: str, revision: str = "main") -> Optional[str]: if ref.startswith(snapshot): return snapshot + raise ValueError( + f"Ref {ref} found in {snapshot_path} for revision {revision}, but ref path does not exist" + ) + def get_full_model_path( repo_id: str, diff --git a/core/utils.py b/core/utils.py index 1f9d89eb4..8d624b9a0 100644 --- a/core/utils.py +++ b/core/utils.py @@ -1,15 +1,15 @@ import asyncio import base64 +import json import logging import math import os import re +import struct from enum import Enum from io import BytesIO from pathlib import Path from typing import Any, Callable, Coroutine, Dict, List, Optional, Tuple, Union -import struct -import json import requests from PIL import Image @@ -22,9 +22,9 @@ ImageFormats, Img2ImgQueueEntry, InpaintQueueEntry, - Txt2ImgQueueEntry, PyTorchModelBase, PyTorchModelStage, + Txt2ImgQueueEntry, ) logger = logging.getLogger(__name__) @@ -153,6 +153,12 @@ def determine_model_type( elif class_name == "KandinskyPriorPipeline": model_type = "Kandinsky 2.1" model_stage = "text_encoding" + elif class_name == "StableDiffusionPipeline": + # Either SD1.x or SD2.x + model_type = "SD1.x" + elif class_name == "StableDiffusionXLPipeline": + model_type = "SDXL" + return (name, model_type, model_stage) From 26e2b7aa4a1dd5ecb0179f89c8616aac78ebc5bd Mon Sep 17 00:00:00 2001 From: Stax124 Date: Fri, 10 Nov 2023 18:38:47 +0100 Subject: [PATCH 037/143] Update docstring for CachedModelList --- core/files.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/files.py b/core/files.py index cc2c735ef..12f2f5a53 100644 --- a/core/files.py +++ b/core/files.py @@ -13,7 +13,7 @@ class CachedModelList: - "List of models downloaded for PyTorch and (or) converted to TRT" + "List of models that user has downloaded" def __init__(self): self.paths = { From 3a8c8f817cd371172782b1b6a4b4906f9f86907c Mon Sep 17 00:00:00 2001 From: Stax124 Date: Fri, 10 Nov 2023 19:52:10 +0100 Subject: [PATCH 038/143] Fix Diffusers model loading --- core/files.py | 17 +++++++---- core/types.py | 9 +++++- core/utils.py | 47 ++++++++++++++++-------------- frontend/dist/assets/index.css | 6 ++-- frontend/dist/assets/index.js | 6 ++-- frontend/src/components/TopBar.vue | 14 ++++----- frontend/src/types.ts | 3 +- 7 files changed, 58 insertions(+), 44 deletions(-) diff --git a/core/files.py b/core/files.py index 12f2f5a53..9efe11175 100644 --- a/core/files.py +++ b/core/files.py @@ -54,19 +54,19 @@ def pytorch(self) -> List[ModelResponse]: # Skip if it is not a huggingface model if "model" not in model_name: continue - model_name: str = "/".join(model_name.split("--")[1:3]) - name, base, stage = determine_model_type(self.paths["pytorch"] / model_name) + parsed_model_name: str = "/".join(model_name.split("--")[1:3]) try: - full_path = get_full_model_path(model_name) + full_path = get_full_model_path(parsed_model_name) except ValueError as e: - logger.debug(f"Model {model_name} is not valid: {e}") + logger.debug(f"Model {parsed_model_name} is not valid: {e}") continue + _name, base, stage = determine_model_type(full_path) models.append( ModelResponse( - name=name, - path=name, + name=parsed_model_name, + path=parsed_model_name, backend="PyTorch", type=base, stage=stage, @@ -79,6 +79,11 @@ def pytorch(self) -> List[ModelResponse]: # Locally stored models logger.debug(f"Looking for local models in {self.paths['checkpoints']}") for model_name in os.listdir(self.paths["checkpoints"]): + if not ( + model_name.endswith(".ckpt") or model_name.endswith(".safetensors") + ): + continue + logger.debug(f"Found model {model_name}") if model_name.endswith(".ckpt"): name, base, stage = model_name, "SD1.x", "first_stage" diff --git a/core/types.py b/core/types.py index 53af57d08..2bd054a46 100644 --- a/core/types.py +++ b/core/types.py @@ -32,7 +32,14 @@ "GPT", # for prompt-expansion ] PyTorchModelBase = Literal[ - "SD1.x", "SD2.x", "SDXL", "Kandinsky 2.1", "Kandinsky 2.2", "Wuerstchen", "IF" + "SD1.x", + "SD2.x", + "SDXL", + "Kandinsky 2.1", + "Kandinsky 2.2", + "Wuerstchen", + "IF", + "Unknown", ] PyTorchModelStage = Literal["text_encoding", "first_stage", "last_stage"] ImageFormats = Literal["png", "jpeg", "webp"] diff --git a/core/utils.py b/core/utils.py index 8d624b9a0..4a7cccfcd 100644 --- a/core/utils.py +++ b/core/utils.py @@ -97,7 +97,7 @@ def determine_model_type( file: Path, ) -> Tuple[str, PyTorchModelBase, PyTorchModelStage]: name = file.name - model_type: PyTorchModelBase = "SD1.x" + model_type: PyTorchModelBase = "Unknown" model_stage: PyTorchModelStage = "last_stage" if file.suffix == ".safetensors": with open(file, "rb") as f: @@ -137,27 +137,30 @@ def determine_model_type( if "class_embedding.linear_1.bias" not in _metadata: model_stage = "first_stage" elif file.is_dir(): - with open(file / "model_index.json", "r") as f: - metadata: Dict[str, str] = json.loads(f.read()) - class_name = metadata.get("_class_name") - if class_name == "KandinskyV22PriorPipeline": - model_type = "Kandinsky 2.2" - model_stage = "text_encoding" - elif ( - class_name == "KandinskyV22ControlnetPipeline" - or class_name == "KandinskyV22Pipeline" - ): - model_type = "Kandinsky 2.2" - elif class_name == "KandinskyPipeline": - model_type = "Kandinsky 2.1" - elif class_name == "KandinskyPriorPipeline": - model_type = "Kandinsky 2.1" - model_stage = "text_encoding" - elif class_name == "StableDiffusionPipeline": - # Either SD1.x or SD2.x - model_type = "SD1.x" - elif class_name == "StableDiffusionXLPipeline": - model_type = "SDXL" + if file.joinpath("model_index.json").exists(): + with open(file / "model_index.json", "r") as f: + metadata: Dict[str, str] = json.loads(f.read()) + class_name = metadata.get("_class_name") + if class_name == "KandinskyV22PriorPipeline": + model_type = "Kandinsky 2.2" + model_stage = "text_encoding" + elif ( + class_name == "KandinskyV22ControlnetPipeline" + or class_name == "KandinskyV22Pipeline" + ): + model_type = "Kandinsky 2.2" + elif class_name == "KandinskyPipeline": + model_type = "Kandinsky 2.1" + elif class_name == "KandinskyPriorPipeline": + model_type = "Kandinsky 2.1" + model_stage = "text_encoding" + elif class_name == "StableDiffusionPipeline": + # Either SD1.x or SD2.x + model_type = "SD1.x" + elif class_name == "StableDiffusionXLPipeline": + model_type = "SDXL" + else: + model_type = "Unknown" return (name, model_type, model_stage) diff --git a/frontend/dist/assets/index.css b/frontend/dist/assets/index.css index bc04a78b4..f16e74b41 100644 --- a/frontend/dist/assets/index.css +++ b/frontend/dist/assets/index.css @@ -50,12 +50,12 @@ justify-content: center; } -.progress-container[data-v-ab2d5f77] { +.progress-container[data-v-fc8ab602] { margin: 12px; flex-grow: 1; width: 400px; } -.top-bar[data-v-ab2d5f77] { +.top-bar[data-v-fc8ab602] { display: inline-flex; align-items: center; padding-top: 10px; @@ -66,7 +66,7 @@ top: 0; z-index: 1; } -.logo[data-v-ab2d5f77] { +.logo[data-v-fc8ab602] { margin-right: 16px; margin-left: 16px; } diff --git a/frontend/dist/assets/index.js b/frontend/dist/assets/index.js index a1d41fd5e..244e94309 100644 --- a/frontend/dist/assets/index.js +++ b/frontend/dist/assets/index.js @@ -42069,7 +42069,7 @@ function urlFromPath(path) { const url = new URL(path, serverUrl); return url.href; } -const _withScopeId = (n) => (pushScopeId("data-v-ab2d5f77"), n = n(), popScopeId(), n); +const _withScopeId = (n) => (pushScopeId("data-v-fc8ab602"), n = n(), popScopeId(), n); const _hoisted_1$1 = { class: "top-bar" }; const _hoisted_2 = { key: 0 }; const _hoisted_3 = { key: 1 }; @@ -43096,8 +43096,8 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ }; } }); -const TopBar_vue_vue_type_style_index_0_scoped_ab2d5f77_lang = ""; -const TopBar = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-ab2d5f77"]]); +const TopBar_vue_vue_type_style_index_0_scoped_fc8ab602_lang = ""; +const TopBar = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-fc8ab602"]]); const Prompt_vue_vue_type_style_index_0_lang = ""; const Prompt_vue_vue_type_style_index_1_scoped_780680bc_lang = ""; const Upscale_vue_vue_type_style_index_0_scoped_5358ed01_lang = ""; diff --git a/frontend/src/components/TopBar.vue b/frontend/src/components/TopBar.vue index 17865ad6a..f11d2dd71 100644 --- a/frontend/src/components/TopBar.vue +++ b/frontend/src/components/TopBar.vue @@ -393,6 +393,8 @@ diff --git a/frontend/src/components/generate/XLRefiner.vue b/frontend/src/components/generate/XLRefiner.vue new file mode 100644 index 000000000..7ae31984d --- /dev/null +++ b/frontend/src/components/generate/XLRefiner.vue @@ -0,0 +1,169 @@ + + + diff --git a/frontend/src/components/generate/index.ts b/frontend/src/components/generate/index.ts index 0566441bc..d244dc177 100644 --- a/frontend/src/components/generate/index.ts +++ b/frontend/src/components/generate/index.ts @@ -3,3 +3,4 @@ export { default as DimensionsInput } from "./DimensionsInput.vue"; export { default as HighResFix } from "./HighResFix.vue"; export { default as Prompt } from "./Prompt.vue"; export { default as SamplerPicker } from "./SamplerPicker.vue"; +export { default as XLRefiner } from "./XLRefiner.vue"; diff --git a/frontend/src/components/inference/Txt2Img.vue b/frontend/src/components/inference/Txt2Img.vue index 0c8f26122..94c781fa9 100644 --- a/frontend/src/components/inference/Txt2Img.vue +++ b/frontend/src/components/inference/Txt2Img.vue @@ -154,156 +154,14 @@
- -
-
-

Enabled

-
- -
- - -
- - - The SDXL-Refiner model to use for this step of diffusion. - - Generally, the refiner that came with your model is bound to - generate the best results. - - - -
- - -
- - - Number of steps to take in the diffusion process. Higher values - will result in more detailed images but will take longer to - generate. There is also a point of diminishing returns around - 100 steps. - We recommend using 20-50 steps for most images. - - - -
- - -
- - - Generally higher numbers will produce "more professional" - images. - Generally best to keep it around 6. - - - -
- - -
- - - Makes sense to keep this lower than aesthetic score. - Generally best to keep it around 3. - - - -
- -
-

Strength

- - -
-
-
- - + /> + @@ -338,6 +196,7 @@ import { OutputStats, Prompt, SamplerPicker, + XLRefiner, } from "@/components"; import { serverUrl } from "@/env"; import { @@ -364,24 +223,6 @@ const isSelectedModelSDXL = computed(() => { return settings.data.settings.model?.type === "SDXL"; }); -const refinerModels = computed(() => { - return global.state.models - .filter( - (model) => - model.type === "SDXL" && model.name.toLowerCase().includes("refiner") - ) - .map((model) => { - return { - label: model.name, - value: model.name, - }; - }); -}); - -async function onRefinerChange(modelStr: string) { - settings.data.settings.flags.refiner.model = modelStr; -} - const checkSeed = (seed: number) => { // If -1 create random seed if (seed === -1) { From 196df8ff1afcf5171e6f97e83af02cdce687144c Mon Sep 17 00:00:00 2001 From: Stax124 Date: Sat, 11 Nov 2023 12:08:54 +0100 Subject: [PATCH 040/143] Temporary ResizeFromDimensionsInput --- .../components/generate/DimensionsInput.vue | 1 + .../generate/ResizeFromDimensionsInput.vue | 62 +++++++++++++++++++ frontend/src/components/generate/index.ts | 1 + frontend/src/components/inference/Txt2Img.vue | 7 +++ 4 files changed, 71 insertions(+) create mode 100644 frontend/src/components/generate/ResizeFromDimensionsInput.vue diff --git a/frontend/src/components/generate/DimensionsInput.vue b/frontend/src/components/generate/DimensionsInput.vue index ad45d72d2..88cee393e 100644 --- a/frontend/src/components/generate/DimensionsInput.vue +++ b/frontend/src/components/generate/DimensionsInput.vue @@ -1,3 +1,4 @@ + diff --git a/frontend/src/settings.ts b/frontend/src/settings.ts index 3a9d4d8fe..a74c59c6f 100644 --- a/frontend/src/settings.ts +++ b/frontend/src/settings.ts @@ -176,8 +176,6 @@ export interface ISettings { subquadratic_size: number; attention_slicing: "auto" | number | "disabled"; channels_last: boolean; - vae_slicing: boolean; - vae_tiling: boolean; trace_model: boolean; offload: "disabled" | "model" | "module"; device: string; @@ -217,9 +215,16 @@ export interface ISettings { sgm_noise_multiplier: boolean; kdiffusers_quantization: boolean; + xl_refiner: "joint" | "separate"; + generator: "device" | "cpu" | "philox"; live_preview_method: "disabled" | "approximation" | "taesd"; live_preview_delay: number; + upcast_vae: boolean; + vae_slicing: boolean; + vae_tiling: boolean; + apply_unsharp_mask: boolean; + cfg_rescale_threshold: number; prompt_to_prompt: boolean; prompt_to_prompt_model: string; @@ -377,8 +382,6 @@ export const defaultSettings: ISettings = { subquadratic_size: 512, attention_slicing: "disabled", channels_last: true, - vae_slicing: false, - vae_tiling: false, trace_model: false, cudnn_benchmark: false, offload: "disabled", @@ -423,9 +426,16 @@ export const defaultSettings: ISettings = { sgm_noise_multiplier: false, kdiffusers_quantization: true, + xl_refiner: "joint", + generator: "device", live_preview_method: "approximation", live_preview_delay: 2.0, + upcast_vae: false, + vae_slicing: false, + vae_tiling: false, + apply_unsharp_mask: false, + cfg_rescale_threshold: 10.0, prompt_to_prompt: false, prompt_to_prompt_model: "lllyasviel/Fooocus-Expansion", From db9bda50a6acda1e479b88f96ee709115926efed Mon Sep 17 00:00:00 2001 From: gabe56f Date: Sat, 11 Nov 2023 20:07:37 +0100 Subject: [PATCH 042/143] rebuild --- frontend/dist/assets/AccelerateView.js | 2 +- frontend/dist/assets/DescriptionsItem.js | 2 +- ...ion.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/Image2ImageView.js | 2 +- frontend/dist/assets/ImageBrowserView.js | 2 +- ...put.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/ImageProcessingView.js | 2 +- frontend/dist/assets/ImageUpload.js | 2 +- frontend/dist/assets/InputNumber.js | 2 +- ...pup.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/ModelsView.js | 2 +- ...ker.vue_vue_type_script_setup_true_lang.js | 2 +- ...tTo.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/Settings.js | 2 +- frontend/dist/assets/SettingsView.js | 2 +- frontend/dist/assets/Switch.js | 2 +- frontend/dist/assets/TaggerView.js | 2 +- frontend/dist/assets/TestView.js | 2 +- frontend/dist/assets/TextToImageView.js | 133 ++++++++++++++---- frontend/dist/assets/TrashBin.js | 2 +- frontend/dist/assets/clock.js | 2 +- frontend/dist/assets/index.js | 14 +- 22 files changed, 130 insertions(+), 57 deletions(-) diff --git a/frontend/dist/assets/AccelerateView.js b/frontend/dist/assets/AccelerateView.js index c10dc0930..2f6d77834 100644 --- a/frontend/dist/assets/AccelerateView.js +++ b/frontend/dist/assets/AccelerateView.js @@ -1,4 +1,4 @@ -import { Q as cB, ab as cM, aa as c, at as cE, aT as iconSwitchTransition, ac as cNotM, d as defineComponent, S as useConfig, ag as useRtl, T as useTheme, a3 as provide, y as h, aw as flatten, ax as getSlot, P as createInjectionKey, bg as stepsLight, R as inject, a_ as throwError, c as computed, ah as createKey, Y as useThemeClass, a1 as call, av as resolveWrappedSlot, ai as resolveSlot, aI as NIconSwitchTransition, aj as NBaseIcon, bh as FinishedIcon, bi as ErrorIcon, p as useMessage, a as useState, z as ref, o as openBlock, j as createElementBlock, g as createVNode, w as withCtx, h as unref, N as NSpace, n as NCard, f as createBaseVNode, i as NSelect, A as NButton, k as createTextVNode, bd as NModal, t as serverUrl, u as useSettings, e as createBlock, D as NTabPane, E as NTabs } from "./index.js"; +import { Q as cB, ab as cM, aa as c, at as cE, aT as iconSwitchTransition, ac as cNotM, d as defineComponent, S as useConfig, ag as useRtl, T as useTheme, a3 as provide, z as h, aw as flatten, ax as getSlot, P as createInjectionKey, bg as stepsLight, R as inject, a_ as throwError, c as computed, ah as createKey, Y as useThemeClass, a1 as call, av as resolveWrappedSlot, ai as resolveSlot, aI as NIconSwitchTransition, aj as NBaseIcon, bh as FinishedIcon, bi as ErrorIcon, p as useMessage, a as useState, r as ref, o as openBlock, j as createElementBlock, g as createVNode, w as withCtx, h as unref, N as NSpace, n as NCard, f as createBaseVNode, i as NSelect, A as NButton, k as createTextVNode, bd as NModal, v as serverUrl, u as useSettings, e as createBlock, D as NTabPane, E as NTabs } from "./index.js"; import { a as NSlider, N as NSwitch } from "./Switch.js"; import { N as NInputNumber } from "./InputNumber.js"; const style = cB("steps", ` diff --git a/frontend/dist/assets/DescriptionsItem.js b/frontend/dist/assets/DescriptionsItem.js index 27c00366e..505e80b82 100644 --- a/frontend/dist/assets/DescriptionsItem.js +++ b/frontend/dist/assets/DescriptionsItem.js @@ -1,4 +1,4 @@ -import { aa as c, Q as cB, ac as cNotM, ab as cM, at as cE, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, c as computed, ah as createKey, Y as useThemeClass, bS as useCompitable, aw as flatten, y as h, aQ as repeat, ax as getSlot, bT as descriptionsLight } from "./index.js"; +import { aa as c, Q as cB, ac as cNotM, ab as cM, at as cE, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, c as computed, ah as createKey, Y as useThemeClass, bS as useCompitable, aw as flatten, z as h, aQ as repeat, ax as getSlot, bT as descriptionsLight } from "./index.js"; function getVNodeChildren(vNode, slotName = "default", fallback = []) { const { children } = vNode; if (children !== null && typeof children === "object" && !Array.isArray(children)) { diff --git a/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js index a3d8d99d5..b7bae85e5 100644 --- a/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { d as defineComponent, o as openBlock, j as createElementBlock, f as createBaseVNode, a as useState, u as useSettings, z as ref, b9 as onMounted, q as onUnmounted, t as serverUrl, e as createBlock, w as withCtx, g as createVNode, h as unref, r as NGi, A as NButton, B as NIcon, k as createTextVNode, s as NGrid, bV as NAlert, m as createCommentVNode, n as NCard } from "./index.js"; +import { d as defineComponent, o as openBlock, j as createElementBlock, f as createBaseVNode, a as useState, u as useSettings, r as ref, b9 as onMounted, q as onUnmounted, v as serverUrl, e as createBlock, w as withCtx, g as createVNode, h as unref, s as NGi, A as NButton, B as NIcon, k as createTextVNode, t as NGrid, bV as NAlert, m as createCommentVNode, n as NCard } from "./index.js"; const _hoisted_1$1 = { xmlns: "http://www.w3.org/2000/svg", "xmlns:xlink": "http://www.w3.org/1999/xlink", diff --git a/frontend/dist/assets/Image2ImageView.js b/frontend/dist/assets/Image2ImageView.js index ceb712769..d13b7316c 100644 --- a/frontend/dist/assets/Image2ImageView.js +++ b/frontend/dist/assets/Image2ImageView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, o as openBlock, j as createElementBlock, f as createBaseVNode, a as useState, u as useSettings, p as useMessage, q as onUnmounted, g as createVNode, w as withCtx, h as unref, r as NGi, n as NCard, N as NSpace, l as NTooltip, k as createTextVNode, i as NSelect, s as NGrid, t as serverUrl, v as pushScopeId, x as popScopeId, _ as _export_sfc, m as createCommentVNode, y as h, z as ref, A as NButton, B as NIcon, e as createBlock, C as toDisplayString, D as NTabPane, E as NTabs } from "./index.js"; +import { d as defineComponent, o as openBlock, j as createElementBlock, f as createBaseVNode, a as useState, u as useSettings, p as useMessage, q as onUnmounted, g as createVNode, w as withCtx, h as unref, s as NGi, n as NCard, N as NSpace, l as NTooltip, k as createTextVNode, i as NSelect, t as NGrid, v as serverUrl, x as pushScopeId, y as popScopeId, _ as _export_sfc, m as createCommentVNode, z as h, r as ref, A as NButton, B as NIcon, e as createBlock, C as toDisplayString, D as NTabPane, E as NTabs } from "./index.js"; import { B as BurnerClock, P as Prompt, _ as _sfc_main$5, a as _sfc_main$6, b as _sfc_main$9 } from "./clock.js"; import { _ as _sfc_main$7 } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; import { _ as _sfc_main$8 } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; diff --git a/frontend/dist/assets/ImageBrowserView.js b/frontend/dist/assets/ImageBrowserView.js index 0ef71fd6b..928783129 100644 --- a/frontend/dist/assets/ImageBrowserView.js +++ b/frontend/dist/assets/ImageBrowserView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, b6 as useCssVars, a as useState, u as useSettings, R as inject, z as ref, c as computed, bI as urlFromPath, b8 as reactive, b9 as onMounted, q as onUnmounted, o as openBlock, j as createElementBlock, f as createBaseVNode, g as createVNode, h as unref, w as withCtx, F as Fragment, L as renderList, b7 as themeOverridesKey, t as serverUrl, J as NInput, B as NIcon, bd as NModal, s as NGrid, r as NGi, A as NButton, k as createTextVNode, M as NScrollbar, e as createBlock, by as convertToTextString, C as toDisplayString, m as createCommentVNode, bJ as diffusersSchedulerTuple, _ as _export_sfc } from "./index.js"; +import { d as defineComponent, b6 as useCssVars, a as useState, u as useSettings, R as inject, r as ref, c as computed, bI as urlFromPath, b8 as reactive, b9 as onMounted, q as onUnmounted, o as openBlock, j as createElementBlock, f as createBaseVNode, g as createVNode, h as unref, w as withCtx, F as Fragment, L as renderList, b7 as themeOverridesKey, v as serverUrl, J as NInput, B as NIcon, bd as NModal, t as NGrid, s as NGi, A as NButton, k as createTextVNode, M as NScrollbar, e as createBlock, by as convertToTextString, C as toDisplayString, m as createCommentVNode, bJ as diffusersSchedulerTuple, _ as _export_sfc } from "./index.js"; import { D as Download, _ as _sfc_main$1 } from "./SendOutputTo.vue_vue_type_script_setup_true_lang.js"; import { G as GridOutline } from "./GridOutline.js"; import { N as NImage, T as TrashBin } from "./TrashBin.js"; diff --git a/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js index 57bc1e1e5..24190edca 100644 --- a/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { d as defineComponent, z as ref, a as useState, o as openBlock, e as createBlock, w as withCtx, h as unref, r as NGi, g as createVNode, B as NIcon, k as createTextVNode, A as NButton, m as createCommentVNode, s as NGrid, c as computed, f as createBaseVNode, j as createElementBlock, F as Fragment, L as renderList, M as NScrollbar, n as NCard } from "./index.js"; +import { d as defineComponent, r as ref, a as useState, o as openBlock, e as createBlock, w as withCtx, h as unref, s as NGi, g as createVNode, B as NIcon, k as createTextVNode, A as NButton, m as createCommentVNode, t as NGrid, c as computed, f as createBaseVNode, j as createElementBlock, F as Fragment, L as renderList, M as NScrollbar, n as NCard } from "./index.js"; import { D as Download, _ as _sfc_main$2 } from "./SendOutputTo.vue_vue_type_script_setup_true_lang.js"; import { T as TrashBin, N as NImage } from "./TrashBin.js"; const _sfc_main$1 = /* @__PURE__ */ defineComponent({ diff --git a/frontend/dist/assets/ImageProcessingView.js b/frontend/dist/assets/ImageProcessingView.js index 413029b4f..c48eb5f22 100644 --- a/frontend/dist/assets/ImageProcessingView.js +++ b/frontend/dist/assets/ImageProcessingView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, a as useState, u as useSettings, p as useMessage, c as computed, b as upscalerOptions, o as openBlock, j as createElementBlock, g as createVNode, w as withCtx, h as unref, r as NGi, n as NCard, N as NSpace, f as createBaseVNode, i as NSelect, l as NTooltip, k as createTextVNode, s as NGrid, t as serverUrl, v as pushScopeId, x as popScopeId, _ as _export_sfc, e as createBlock, D as NTabPane, E as NTabs } from "./index.js"; +import { d as defineComponent, a as useState, u as useSettings, p as useMessage, c as computed, b as upscalerOptions, o as openBlock, j as createElementBlock, g as createVNode, w as withCtx, h as unref, s as NGi, n as NCard, N as NSpace, f as createBaseVNode, i as NSelect, l as NTooltip, k as createTextVNode, t as NGrid, v as serverUrl, x as pushScopeId, y as popScopeId, _ as _export_sfc, e as createBlock, D as NTabPane, E as NTabs } from "./index.js"; import { _ as _sfc_main$2 } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; import { _ as _sfc_main$3 } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; import { I as ImageUpload } from "./ImageUpload.js"; diff --git a/frontend/dist/assets/ImageUpload.js b/frontend/dist/assets/ImageUpload.js index 892dc106b..6a1a80317 100644 --- a/frontend/dist/assets/ImageUpload.js +++ b/frontend/dist/assets/ImageUpload.js @@ -1,4 +1,4 @@ -import { d as defineComponent, z as ref, c as computed, b9 as onMounted, o as openBlock, e as createBlock, w as withCtx, f as createBaseVNode, bU as withModifiers, j as createElementBlock, g as createVNode, h as unref, B as NIcon, C as toDisplayString, n as NCard, v as pushScopeId, x as popScopeId, _ as _export_sfc } from "./index.js"; +import { d as defineComponent, r as ref, c as computed, b9 as onMounted, o as openBlock, e as createBlock, w as withCtx, f as createBaseVNode, bU as withModifiers, j as createElementBlock, g as createVNode, h as unref, B as NIcon, C as toDisplayString, n as NCard, x as pushScopeId, y as popScopeId, _ as _export_sfc } from "./index.js"; import { C as CloudUpload } from "./CloudUpload.js"; const _withScopeId = (n) => (pushScopeId("data-v-9ed1514f"), n = n(), popScopeId(), n); const _hoisted_1 = { class: "image-container" }; diff --git a/frontend/dist/assets/InputNumber.js b/frontend/dist/assets/InputNumber.js index 65f5be9cc..0792ef26c 100644 --- a/frontend/dist/assets/InputNumber.js +++ b/frontend/dist/assets/InputNumber.js @@ -1,4 +1,4 @@ -import { d as defineComponent, y as h, aa as c, Q as cB, S as useConfig, T as useTheme, ad as useLocale, ar as useFormItem, z as ref, X as toRef, ae as useMergedState, as as useMemo, K as watch, ag as useRtl, c as computed, bW as rgba, J as NInput, av as resolveWrappedSlot, bX as inputNumberLight, aD as on, ai as resolveSlot, aj as NBaseIcon, bY as XButton, a$ as AddIcon, a1 as call, W as nextTick } from "./index.js"; +import { d as defineComponent, z as h, aa as c, Q as cB, S as useConfig, T as useTheme, ad as useLocale, ar as useFormItem, r as ref, X as toRef, ae as useMergedState, as as useMemo, K as watch, ag as useRtl, c as computed, bW as rgba, J as NInput, av as resolveWrappedSlot, bX as inputNumberLight, aD as on, ai as resolveSlot, aj as NBaseIcon, bY as XButton, a$ as AddIcon, a1 as call, W as nextTick } from "./index.js"; const RemoveIcon = defineComponent({ name: "Remove", render() { diff --git a/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js index d63e0de48..28e13a328 100644 --- a/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { bj as upperFirst, bk as toString, bl as createCompounder, bm as cloneVNode, a3 as provide, P as createInjectionKey, R as inject, a_ as throwError, d as defineComponent, S as useConfig, z as ref, bn as onBeforeUpdate, y as h, bo as indexMap, c as computed, b9 as onMounted, aB as onBeforeUnmount, Q as cB, at as cE, aa as c, ab as cM, a4 as keep, ae as useMergedState, X as toRef, af as watchEffect, bp as onUpdated, K as watch, W as nextTick, T as useTheme, Y as useThemeClass, aw as flatten, aL as VResizeObserver, bq as resolveSlotWithProps, br as withDirectives, bs as vShow, aX as Transition, ba as normalizeStyle, bt as getPreciseEventTarget, aD as on, aC as off, bu as carouselLight, ac as cNotM, ar as useFormItem, ah as createKey, bv as color2Class, L as renderList, aj as NBaseIcon, bw as rateLight, a1 as call, p as useMessage, u as useSettings, b8 as reactive, o as openBlock, e as createBlock, w as withCtx, g as createVNode, j as createElementBlock, h as unref, D as NTabPane, s as NGrid, r as NGi, F as Fragment, f as createBaseVNode, n as NCard, k as createTextVNode, C as toDisplayString, bx as NTag, i as NSelect, A as NButton, E as NTabs, bd as NModal, t as serverUrl } from "./index.js"; +import { bj as upperFirst, bk as toString, bl as createCompounder, bm as cloneVNode, a3 as provide, P as createInjectionKey, R as inject, a_ as throwError, d as defineComponent, S as useConfig, r as ref, bn as onBeforeUpdate, z as h, bo as indexMap, c as computed, b9 as onMounted, aB as onBeforeUnmount, Q as cB, at as cE, aa as c, ab as cM, a4 as keep, ae as useMergedState, X as toRef, af as watchEffect, bp as onUpdated, K as watch, W as nextTick, T as useTheme, Y as useThemeClass, aw as flatten, aL as VResizeObserver, bq as resolveSlotWithProps, br as withDirectives, bs as vShow, aX as Transition, ba as normalizeStyle, bt as getPreciseEventTarget, aD as on, aC as off, bu as carouselLight, ac as cNotM, ar as useFormItem, ah as createKey, bv as color2Class, L as renderList, aj as NBaseIcon, bw as rateLight, a1 as call, p as useMessage, u as useSettings, b8 as reactive, o as openBlock, e as createBlock, w as withCtx, g as createVNode, j as createElementBlock, h as unref, D as NTabPane, t as NGrid, s as NGi, F as Fragment, f as createBaseVNode, n as NCard, k as createTextVNode, C as toDisplayString, bx as NTag, i as NSelect, A as NButton, E as NTabs, bd as NModal, v as serverUrl } from "./index.js"; import { a as NDescriptions, N as NDescriptionsItem } from "./DescriptionsItem.js"; function capitalize(string) { return upperFirst(toString(string).toLowerCase()); diff --git a/frontend/dist/assets/ModelsView.js b/frontend/dist/assets/ModelsView.js index 0356485f0..6afeeb364 100644 --- a/frontend/dist/assets/ModelsView.js +++ b/frontend/dist/assets/ModelsView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, y as h, O as replaceable, P as createInjectionKey, Q as cB, R as inject, S as useConfig, T as useTheme, U as popselectLight, c as computed, V as createTreeMate, K as watch, W as nextTick, X as toRef, Y as useThemeClass, Z as NInternalSelectMenu, $ as createTmOptions, a0 as happensIn, a1 as call, a2 as keysOf, z as ref, a3 as provide, a4 as keep, a5 as createRefSetter, a6 as mergeEventHandlers, a7 as omit, a8 as NPopover, a9 as popoverBaseProps, aa as c, ab as cM, ac as cNotM, ad as useLocale, ae as useMergedState, af as watchEffect, ag as useRtl, ah as createKey, ai as resolveSlot, J as NInput, i as NSelect, F as Fragment, aj as NBaseIcon, ak as useAdjustedTo, al as paginationLight, am as useMergedClsPrefix, an as ellipsisLight, ao as onDeactivated, l as NTooltip, ap as mergeProps, aq as useStyle, ar as useFormItem, as as useMemo, at as cE, au as radioLight, av as resolveWrappedSlot, aw as flatten$1, ax as getSlot, ay as depx, az as formatLength, A as NButton, aA as NScrollbar, aB as onBeforeUnmount, aC as off, aD as on, aE as ChevronDownIcon, aF as NDropdown, aG as pxfy, aH as get, aI as NIconSwitchTransition, aJ as NBaseLoading, aK as ChevronRightIcon, q as onUnmounted, aL as VResizeObserver, aM as warn, aN as cssrAnchorMetaName, aO as VVirtualList, aP as NEmpty, aQ as repeat, aR as beforeNextFrameOnce, aS as fadeInScaleUpTransition, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, aW as createId, aX as Transition, aY as dataTableLight, aZ as loadingBarApiInjectionKey, a_ as throwError, a$ as AddIcon, b0 as NProgress, b1 as NFadeInExpandTransition, b2 as EyeIcon, b3 as fadeInHeightExpandTransition, b4 as Teleport, b5 as uploadLight, o as openBlock, j as createElementBlock, f as createBaseVNode, b6 as useCssVars, h as unref, u as useSettings, b7 as themeOverridesKey, b8 as reactive, b9 as onMounted, g as createVNode, w as withCtx, B as NIcon, L as renderList, ba as normalizeStyle, k as createTextVNode, C as toDisplayString, bb as NText, m as createCommentVNode, _ as _export_sfc, a as useState, p as useMessage, bc as huggingfaceModelsFile, n as NCard, t as serverUrl, v as pushScopeId, x as popScopeId, N as NSpace, bd as NModal, e as createBlock, r as NGi, s as NGrid, be as NDivider, bf as Backends, D as NTabPane, E as NTabs } from "./index.js"; +import { d as defineComponent, z as h, O as replaceable, P as createInjectionKey, Q as cB, R as inject, S as useConfig, T as useTheme, U as popselectLight, c as computed, V as createTreeMate, K as watch, W as nextTick, X as toRef, Y as useThemeClass, Z as NInternalSelectMenu, $ as createTmOptions, a0 as happensIn, a1 as call, a2 as keysOf, r as ref, a3 as provide, a4 as keep, a5 as createRefSetter, a6 as mergeEventHandlers, a7 as omit, a8 as NPopover, a9 as popoverBaseProps, aa as c, ab as cM, ac as cNotM, ad as useLocale, ae as useMergedState, af as watchEffect, ag as useRtl, ah as createKey, ai as resolveSlot, J as NInput, i as NSelect, F as Fragment, aj as NBaseIcon, ak as useAdjustedTo, al as paginationLight, am as useMergedClsPrefix, an as ellipsisLight, ao as onDeactivated, l as NTooltip, ap as mergeProps, aq as useStyle, ar as useFormItem, as as useMemo, at as cE, au as radioLight, av as resolveWrappedSlot, aw as flatten$1, ax as getSlot, ay as depx, az as formatLength, A as NButton, aA as NScrollbar, aB as onBeforeUnmount, aC as off, aD as on, aE as ChevronDownIcon, aF as NDropdown, aG as pxfy, aH as get, aI as NIconSwitchTransition, aJ as NBaseLoading, aK as ChevronRightIcon, q as onUnmounted, aL as VResizeObserver, aM as warn, aN as cssrAnchorMetaName, aO as VVirtualList, aP as NEmpty, aQ as repeat, aR as beforeNextFrameOnce, aS as fadeInScaleUpTransition, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, aW as createId, aX as Transition, aY as dataTableLight, aZ as loadingBarApiInjectionKey, a_ as throwError, a$ as AddIcon, b0 as NProgress, b1 as NFadeInExpandTransition, b2 as EyeIcon, b3 as fadeInHeightExpandTransition, b4 as Teleport, b5 as uploadLight, o as openBlock, j as createElementBlock, f as createBaseVNode, b6 as useCssVars, h as unref, u as useSettings, b7 as themeOverridesKey, b8 as reactive, b9 as onMounted, g as createVNode, w as withCtx, B as NIcon, L as renderList, ba as normalizeStyle, k as createTextVNode, C as toDisplayString, bb as NText, m as createCommentVNode, _ as _export_sfc, a as useState, p as useMessage, bc as huggingfaceModelsFile, n as NCard, v as serverUrl, x as pushScopeId, y as popScopeId, N as NSpace, bd as NModal, e as createBlock, s as NGi, t as NGrid, be as NDivider, bf as Backends, D as NTabPane, E as NTabs } from "./index.js"; import { _ as _sfc_main$5, n as nsfwIndex } from "./ModelPopup.vue_vue_type_script_setup_true_lang.js"; import { G as GridOutline } from "./GridOutline.js"; import { a as NSlider, N as NSwitch } from "./Switch.js"; diff --git a/frontend/dist/assets/SamplerPicker.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/SamplerPicker.vue_vue_type_script_setup_true_lang.js index d3120ca90..8f92b4052 100644 --- a/frontend/dist/assets/SamplerPicker.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/SamplerPicker.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { R as inject, bC as getCurrentInstance, K as watch, aB as onBeforeUnmount, Q as cB, ab as cM, aa as c, P as createInjectionKey, d as defineComponent, S as useConfig, T as useTheme, z as ref, a3 as provide, y as h, bD as formLight, a2 as keysOf, c as computed, az as formatLength, aH as get, bE as commonVariables, at as cE, X as toRef, aW as createId, bF as formItemInjectionKey, b9 as onMounted, ah as createKey, Y as useThemeClass, aX as Transition, av as resolveWrappedSlot, aM as warn, u as useSettings, o as openBlock, j as createElementBlock, f as createBaseVNode, g as createVNode, w as withCtx, h as unref, n as NCard, F as Fragment, L as renderList, A as NButton, k as createTextVNode, C as toDisplayString, by as convertToTextString, e as createBlock, bG as resolveDynamicComponent, bd as NModal, l as NTooltip, i as NSelect, B as NIcon } from "./index.js"; +import { R as inject, bC as getCurrentInstance, K as watch, aB as onBeforeUnmount, Q as cB, ab as cM, aa as c, P as createInjectionKey, d as defineComponent, S as useConfig, T as useTheme, r as ref, a3 as provide, z as h, bD as formLight, a2 as keysOf, c as computed, az as formatLength, aH as get, bE as commonVariables, at as cE, X as toRef, aW as createId, bF as formItemInjectionKey, b9 as onMounted, ah as createKey, Y as useThemeClass, aX as Transition, av as resolveWrappedSlot, aM as warn, u as useSettings, o as openBlock, j as createElementBlock, f as createBaseVNode, g as createVNode, w as withCtx, h as unref, n as NCard, F as Fragment, L as renderList, A as NButton, k as createTextVNode, C as toDisplayString, by as convertToTextString, e as createBlock, bG as resolveDynamicComponent, bd as NModal, l as NTooltip, i as NSelect, B as NIcon } from "./index.js"; import { S as Settings, a as NCheckbox } from "./Settings.js"; import { N as NInputNumber } from "./InputNumber.js"; import { a as NSlider } from "./Switch.js"; diff --git a/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js index beac36b50..216b00ec0 100644 --- a/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { d as defineComponent, o as openBlock, j as createElementBlock, f as createBaseVNode, bK as useRouter, u as useSettings, a as useState, z as ref, b8 as reactive, K as watch, c as computed, g as createVNode, w as withCtx, h as unref, n as NCard, A as NButton, k as createTextVNode, M as NScrollbar, F as Fragment, L as renderList, C as toDisplayString, be as NDivider, bd as NModal, e as createBlock, r as NGi, s as NGrid, m as createCommentVNode } from "./index.js"; +import { d as defineComponent, o as openBlock, j as createElementBlock, f as createBaseVNode, bK as useRouter, u as useSettings, a as useState, r as ref, b8 as reactive, K as watch, c as computed, g as createVNode, w as withCtx, h as unref, n as NCard, A as NButton, k as createTextVNode, M as NScrollbar, F as Fragment, L as renderList, C as toDisplayString, be as NDivider, bd as NModal, e as createBlock, s as NGi, t as NGrid, m as createCommentVNode } from "./index.js"; import { N as NSwitch } from "./Switch.js"; const _hoisted_1$3 = { xmlns: "http://www.w3.org/2000/svg", diff --git a/frontend/dist/assets/Settings.js b/frontend/dist/assets/Settings.js index a780d5357..d1d197dc9 100644 --- a/frontend/dist/assets/Settings.js +++ b/frontend/dist/assets/Settings.js @@ -1,4 +1,4 @@ -import { y as h, d as defineComponent, S as useConfig, ar as useFormItem, z as ref, c as computed, ae as useMergedState, a3 as provide, X as toRef, P as createInjectionKey, a1 as call, aa as c, Q as cB, ab as cM, at as cE, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, R as inject, as as useMemo, T as useTheme, bH as checkboxLight, ag as useRtl, ah as createKey, Y as useThemeClass, aW as createId, av as resolveWrappedSlot, aI as NIconSwitchTransition, aD as on, o as openBlock, j as createElementBlock, f as createBaseVNode } from "./index.js"; +import { z as h, d as defineComponent, S as useConfig, ar as useFormItem, r as ref, c as computed, ae as useMergedState, a3 as provide, X as toRef, P as createInjectionKey, a1 as call, aa as c, Q as cB, ab as cM, at as cE, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, R as inject, as as useMemo, T as useTheme, bH as checkboxLight, ag as useRtl, ah as createKey, Y as useThemeClass, aW as createId, av as resolveWrappedSlot, aI as NIconSwitchTransition, aD as on, o as openBlock, j as createElementBlock, f as createBaseVNode } from "./index.js"; const CheckMark = h( "svg", { viewBox: "0 0 64 64", class: "check-icon" }, diff --git a/frontend/dist/assets/SettingsView.js b/frontend/dist/assets/SettingsView.js index 3c0a05b26..b4c5f2d9d 100644 --- a/frontend/dist/assets/SettingsView.js +++ b/frontend/dist/assets/SettingsView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, u as useSettings, o as openBlock, e as createBlock, w as withCtx, g as createVNode, h as unref, J as NInput, i as NSelect, n as NCard, b8 as reactive, c as computed, by as convertToTextString, z as ref, t as serverUrl, K as watch, a as useState, f as createBaseVNode, j as createElementBlock, L as renderList, bb as NText, k as createTextVNode, C as toDisplayString, F as Fragment, m as createCommentVNode, D as NTabPane, E as NTabs, R as inject, bz as themeKey, A as NButton, l as NTooltip, p as useMessage, bA as useNotification, q as onUnmounted, bB as defaultSettings } from "./index.js"; +import { d as defineComponent, u as useSettings, o as openBlock, e as createBlock, w as withCtx, g as createVNode, h as unref, J as NInput, i as NSelect, n as NCard, b8 as reactive, c as computed, by as convertToTextString, r as ref, v as serverUrl, K as watch, a as useState, f as createBaseVNode, j as createElementBlock, L as renderList, bb as NText, k as createTextVNode, C as toDisplayString, F as Fragment, m as createCommentVNode, D as NTabPane, E as NTabs, R as inject, bz as themeKey, A as NButton, l as NTooltip, p as useMessage, bA as useNotification, q as onUnmounted, bB as defaultSettings } from "./index.js"; import { a as NFormItem, _ as _sfc_main$h, N as NForm } from "./SamplerPicker.vue_vue_type_script_setup_true_lang.js"; import { N as NSwitch, a as NSlider } from "./Switch.js"; import { N as NInputNumber } from "./InputNumber.js"; diff --git a/frontend/dist/assets/Switch.js b/frontend/dist/assets/Switch.js index 27efe4dec..e7687d04d 100644 --- a/frontend/dist/assets/Switch.js +++ b/frontend/dist/assets/Switch.js @@ -1,4 +1,4 @@ -import { z as ref, bn as onBeforeUpdate, aa as c, Q as cB, ab as cM, at as cE, aS as fadeInScaleUpTransition, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, ar as useFormItem, c as computed, X as toRef, ae as useMergedState, K as watch, W as nextTick, aB as onBeforeUnmount, Y as useThemeClass, bO as isMounted, ak as useAdjustedTo, y as h, bZ as VBinder, b_ as VTarget, ai as resolveSlot, b$ as VFollower, aX as Transition, c0 as sliderLight, aD as on, aC as off, a1 as call, aT as iconSwitchTransition, ac as cNotM, ah as createKey, aG as pxfy, ay as depx, c1 as isSlotEmpty, av as resolveWrappedSlot, c2 as switchLight, aI as NIconSwitchTransition, aJ as NBaseLoading } from "./index.js"; +import { r as ref, bn as onBeforeUpdate, aa as c, Q as cB, ab as cM, at as cE, aS as fadeInScaleUpTransition, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, ar as useFormItem, c as computed, X as toRef, ae as useMergedState, K as watch, W as nextTick, aB as onBeforeUnmount, Y as useThemeClass, bO as isMounted, ak as useAdjustedTo, z as h, bZ as VBinder, b_ as VTarget, ai as resolveSlot, b$ as VFollower, aX as Transition, c0 as sliderLight, aD as on, aC as off, a1 as call, aT as iconSwitchTransition, ac as cNotM, ah as createKey, aG as pxfy, ay as depx, c1 as isSlotEmpty, av as resolveWrappedSlot, c2 as switchLight, aI as NIconSwitchTransition, aJ as NBaseLoading } from "./index.js"; function isTouchEvent(e) { return window.TouchEvent && e instanceof window.TouchEvent; } diff --git a/frontend/dist/assets/TaggerView.js b/frontend/dist/assets/TaggerView.js index 154f4dc90..aff7bc63c 100644 --- a/frontend/dist/assets/TaggerView.js +++ b/frontend/dist/assets/TaggerView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, a as useState, u as useSettings, p as useMessage, z as ref, c as computed, G as spaceRegex, o as openBlock, j as createElementBlock, g as createVNode, w as withCtx, h as unref, r as NGi, n as NCard, N as NSpace, f as createBaseVNode, i as NSelect, l as NTooltip, k as createTextVNode, J as NInput, C as toDisplayString, s as NGrid, t as serverUrl, v as pushScopeId, x as popScopeId, _ as _export_sfc } from "./index.js"; +import { d as defineComponent, a as useState, u as useSettings, p as useMessage, r as ref, c as computed, G as spaceRegex, o as openBlock, j as createElementBlock, g as createVNode, w as withCtx, h as unref, s as NGi, n as NCard, N as NSpace, f as createBaseVNode, i as NSelect, l as NTooltip, k as createTextVNode, J as NInput, C as toDisplayString, t as NGrid, v as serverUrl, x as pushScopeId, y as popScopeId, _ as _export_sfc } from "./index.js"; import { _ as _sfc_main$1 } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; import { I as ImageUpload } from "./ImageUpload.js"; import { v as v4 } from "./v4.js"; diff --git a/frontend/dist/assets/TestView.js b/frontend/dist/assets/TestView.js index ff8c3ffbd..c938d7409 100644 --- a/frontend/dist/assets/TestView.js +++ b/frontend/dist/assets/TestView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, z as ref, o as openBlock, e as createBlock, h as unref } from "./index.js"; +import { d as defineComponent, r as ref, o as openBlock, e as createBlock, h as unref } from "./index.js"; import { _ as _sfc_main$1 } from "./ModelPopup.vue_vue_type_script_setup_true_lang.js"; import "./DescriptionsItem.js"; const _sfc_main = /* @__PURE__ */ defineComponent({ diff --git a/frontend/dist/assets/TextToImageView.js b/frontend/dist/assets/TextToImageView.js index 3a75e12f4..e1b131cc8 100644 --- a/frontend/dist/assets/TextToImageView.js +++ b/frontend/dist/assets/TextToImageView.js @@ -1,26 +1,26 @@ -import { d as defineComponent, u as useSettings, a as useState, c as computed, b as upscalerOptions, o as openBlock, e as createBlock, w as withCtx, f as createBaseVNode, g as createVNode, h as unref, N as NSpace, i as NSelect, j as createElementBlock, k as createTextVNode, l as NTooltip, m as createCommentVNode, n as NCard, p as useMessage, q as onUnmounted, r as NGi, s as NGrid, t as serverUrl } from "./index.js"; -import { _ as _sfc_main$7 } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; -import { _ as _sfc_main$8 } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; -import { B as BurnerClock, P as Prompt, _ as _sfc_main$5, a as _sfc_main$6, b as _sfc_main$9 } from "./clock.js"; +import { d as defineComponent, u as useSettings, a as useState, c as computed, b as upscalerOptions, o as openBlock, e as createBlock, w as withCtx, f as createBaseVNode, g as createVNode, h as unref, N as NSpace, i as NSelect, j as createElementBlock, k as createTextVNode, l as NTooltip, m as createCommentVNode, n as NCard, r as ref, F as Fragment, p as useMessage, q as onUnmounted, s as NGi, t as NGrid, v as serverUrl } from "./index.js"; +import { _ as _sfc_main$8 } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; +import { _ as _sfc_main$9 } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; +import { B as BurnerClock, P as Prompt, _ as _sfc_main$6, a as _sfc_main$7, b as _sfc_main$a } from "./clock.js"; import { N as NSwitch, a as NSlider } from "./Switch.js"; import { N as NInputNumber } from "./InputNumber.js"; -import { _ as _sfc_main$4 } from "./SamplerPicker.vue_vue_type_script_setup_true_lang.js"; +import { _ as _sfc_main$5 } from "./SamplerPicker.vue_vue_type_script_setup_true_lang.js"; import { v as v4 } from "./v4.js"; import "./SendOutputTo.vue_vue_type_script_setup_true_lang.js"; import "./TrashBin.js"; import "./DescriptionsItem.js"; import "./Settings.js"; -const _hoisted_1$2 = { class: "flex-container" }; -const _hoisted_2$2 = /* @__PURE__ */ createBaseVNode("div", { class: "slider-label" }, [ +const _hoisted_1$3 = { class: "flex-container" }; +const _hoisted_2$3 = /* @__PURE__ */ createBaseVNode("div", { class: "slider-label" }, [ /* @__PURE__ */ createBaseVNode("p", null, "Enabled") ], -1); -const _hoisted_3$2 = { class: "flex-container" }; -const _hoisted_4$2 = /* @__PURE__ */ createBaseVNode("div", { class: "slider-label" }, [ +const _hoisted_3$3 = { class: "flex-container" }; +const _hoisted_4$3 = /* @__PURE__ */ createBaseVNode("div", { class: "slider-label" }, [ /* @__PURE__ */ createBaseVNode("p", null, "Mode") ], -1); -const _hoisted_5$2 = { key: 0 }; -const _hoisted_6$2 = { class: "flex-container" }; -const _hoisted_7$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Upscaler", -1); +const _hoisted_5$3 = { key: 0 }; +const _hoisted_6$3 = { class: "flex-container" }; +const _hoisted_7$3 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Upscaler", -1); const _hoisted_8$2 = { key: 1 }; const _hoisted_9$2 = { class: "flex-container" }; const _hoisted_10$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Antialiased", -1); @@ -33,7 +33,7 @@ const _hoisted_16$1 = { class: "flex-container" }; const _hoisted_17 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Scale", -1); const _hoisted_18 = { class: "flex-container" }; const _hoisted_19 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Strength", -1); -const _sfc_main$3 = /* @__PURE__ */ defineComponent({ +const _sfc_main$4 = /* @__PURE__ */ defineComponent({ __name: "HighResFix", setup(__props) { const settings = useSettings(); @@ -58,8 +58,8 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ return (_ctx, _cache) => { return openBlock(), createBlock(unref(NCard), { title: "Highres fix" }, { default: withCtx(() => [ - createBaseVNode("div", _hoisted_1$2, [ - _hoisted_2$2, + createBaseVNode("div", _hoisted_1$3, [ + _hoisted_2$3, createVNode(unref(NSwitch), { value: unref(global).state.txt2img.highres, "onUpdate:value": _cache[0] || (_cache[0] = ($event) => unref(global).state.txt2img.highres = $event) @@ -71,8 +71,8 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ class: "left-container" }, { default: withCtx(() => [ - createBaseVNode("div", _hoisted_3$2, [ - _hoisted_4$2, + createBaseVNode("div", _hoisted_3$3, [ + _hoisted_4$3, createVNode(unref(NSelect), { value: unref(settings).data.settings.flags.highres.mode, "onUpdate:value": _cache[1] || (_cache[1] = ($event) => unref(settings).data.settings.flags.highres.mode = $event), @@ -82,9 +82,9 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ ] }, null, 8, ["value"]) ]), - unref(settings).data.settings.flags.highres.mode === "image" ? (openBlock(), createElementBlock("div", _hoisted_5$2, [ - createBaseVNode("div", _hoisted_6$2, [ - _hoisted_7$2, + unref(settings).data.settings.flags.highres.mode === "image" ? (openBlock(), createElementBlock("div", _hoisted_5$3, [ + createBaseVNode("div", _hoisted_6$3, [ + _hoisted_7$3, createVNode(unref(NSelect), { value: unref(settings).data.settings.flags.highres.image_upscaler, "onUpdate:value": _cache[2] || (_cache[2] = ($event) => unref(settings).data.settings.flags.highres.image_upscaler = $event), @@ -186,6 +186,75 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ }; } }); +const _hoisted_1$2 = { class: "flex-container" }; +const _hoisted_2$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Resize From (temporary placement)", -1); +const _hoisted_3$2 = { key: 0 }; +const _hoisted_4$2 = { class: "flex-container" }; +const _hoisted_5$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Resize From Width", -1); +const _hoisted_6$2 = { class: "flex-container" }; +const _hoisted_7$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Resize From Height", -1); +const _sfc_main$3 = /* @__PURE__ */ defineComponent({ + __name: "ResizeFromDimensionsInput", + props: { + dimensionsObject: { + type: Object, + required: true + } + }, + setup(__props) { + const props = __props; + const show = ref(false); + return (_ctx, _cache) => { + return openBlock(), createElementBlock(Fragment, null, [ + createBaseVNode("div", _hoisted_1$2, [ + _hoisted_2$2, + createVNode(unref(NSwitch), { + value: show.value, + "onUpdate:value": _cache[0] || (_cache[0] = ($event) => show.value = $event) + }, null, 8, ["value"]) + ]), + show.value ? (openBlock(), createElementBlock("div", _hoisted_3$2, [ + createBaseVNode("div", _hoisted_4$2, [ + _hoisted_5$2, + createVNode(unref(NSlider), { + value: props.dimensionsObject.width, + "onUpdate:value": _cache[1] || (_cache[1] = ($event) => props.dimensionsObject.width = $event), + min: 128, + max: 2048, + step: 1, + style: { "margin-right": "12px" } + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: props.dimensionsObject.width, + "onUpdate:value": _cache[2] || (_cache[2] = ($event) => props.dimensionsObject.width = $event), + size: "small", + style: { "min-width": "96px", "width": "96px" }, + step: 1 + }, null, 8, ["value"]) + ]), + createBaseVNode("div", _hoisted_6$2, [ + _hoisted_7$2, + createVNode(unref(NSlider), { + value: props.dimensionsObject.height, + "onUpdate:value": _cache[3] || (_cache[3] = ($event) => props.dimensionsObject.height = $event), + min: 128, + max: 2048, + step: 1, + style: { "margin-right": "12px" } + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: props.dimensionsObject.height, + "onUpdate:value": _cache[4] || (_cache[4] = ($event) => props.dimensionsObject.height = $event), + size: "small", + style: { "min-width": "96px", "width": "96px" }, + step: 1 + }, null, 8, ["value"]) + ]) + ])) : createCommentVNode("", true) + ], 64); + }; + } +}); const _hoisted_1$1 = { class: "flex-container" }; const _hoisted_2$1 = /* @__PURE__ */ createBaseVNode("div", { class: "slider-label" }, [ /* @__PURE__ */ createBaseVNode("p", null, "Enabled") @@ -374,7 +443,7 @@ const _hoisted_5 = { class: "flex-container" }; const _hoisted_6 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "CFG Scale", -1); const _hoisted_7 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "We recommend using 3-15 for most images.", -1); const _hoisted_8 = { - key: 0, + key: 1, class: "flex-container" }; const _hoisted_9 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Self Attention Scale", -1); @@ -510,13 +579,17 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ class: "left-container" }, { default: withCtx(() => { - var _a; + var _a, _b; return [ createVNode(unref(Prompt), { tab: "txt2img" }), - createVNode(unref(_sfc_main$4), { type: "txt2img" }), - createVNode(unref(_sfc_main$5), { + createVNode(unref(_sfc_main$5), { type: "txt2img" }), + createVNode(unref(_sfc_main$6), { "dimensions-object": unref(settings).data.settings.txt2img }, null, 8, ["dimensions-object"]), + ((_a = unref(settings).data.settings.model) == null ? void 0 : _a.type) === "SDXL" ? (openBlock(), createBlock(unref(_sfc_main$3), { + key: 0, + "dimensions-object": unref(settings).data.settings.txt2img + }, null, 8, ["dimensions-object"])) : createCommentVNode("", true), createBaseVNode("div", _hoisted_2, [ createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { trigger: withCtx(() => [ @@ -569,7 +642,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ step: 0.5 }, null, 8, ["value"]) ]), - Number.isInteger(unref(settings).data.settings.txt2img.sampler) && ((_a = unref(settings).data.settings.model) == null ? void 0 : _a.backend) === "PyTorch" ? (openBlock(), createElementBlock("div", _hoisted_8, [ + Number.isInteger(unref(settings).data.settings.txt2img.sampler) && ((_b = unref(settings).data.settings.model) == null ? void 0 : _b.backend) === "PyTorch" ? (openBlock(), createElementBlock("div", _hoisted_8, [ createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { trigger: withCtx(() => [ _hoisted_9 @@ -619,7 +692,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ style: { "min-width": "96px", "width": "96px" } }, null, 8, ["value"]) ]), - createVNode(unref(_sfc_main$6), { + createVNode(unref(_sfc_main$7), { "batch-size-object": unref(settings).data.settings.txt2img }, null, 8, ["batch-size-object"]), createBaseVNode("div", _hoisted_12, [ @@ -651,7 +724,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ key: 0, style: { "margin-top": "12px", "margin-bottom": "12px" } })) : createCommentVNode("", true), - !isSelectedModelSDXL.value ? (openBlock(), createBlock(unref(_sfc_main$3), { + !isSelectedModelSDXL.value ? (openBlock(), createBlock(unref(_sfc_main$4), { key: 1, style: { "margin-top": "12px", "margin-bottom": "12px" } })) : createCommentVNode("", true) @@ -660,14 +733,14 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ }), createVNode(unref(NGi), null, { default: withCtx(() => [ - createVNode(unref(_sfc_main$7), { generate }), - createVNode(unref(_sfc_main$8), { + createVNode(unref(_sfc_main$8), { generate }), + createVNode(unref(_sfc_main$9), { "current-image": unref(global).state.txt2img.currentImage, images: unref(global).state.txt2img.images, data: unref(settings).data.settings.txt2img, onImageClicked: _cache[9] || (_cache[9] = ($event) => unref(global).state.txt2img.currentImage = $event) }, null, 8, ["current-image", "images", "data"]), - createVNode(unref(_sfc_main$9), { + createVNode(unref(_sfc_main$a), { style: { "margin-top": "12px" }, "gen-data": unref(global).state.txt2img.genData }, null, 8, ["gen-data"]) diff --git a/frontend/dist/assets/TrashBin.js b/frontend/dist/assets/TrashBin.js index 8f894ef91..595b067af 100644 --- a/frontend/dist/assets/TrashBin.js +++ b/frontend/dist/assets/TrashBin.js @@ -1,4 +1,4 @@ -import { O as replaceable, y as h, d as defineComponent, bL as isBrowser, T as useTheme, P as createInjectionKey, aa as c, Q as cB, bM as fadeInTransition, aS as fadeInScaleUpTransition, ac as cNotM, X as toRef, bN as imageLight, z as ref, ad as useLocale, K as watch, aD as on, aC as off, aB as onBeforeUnmount, R as inject, c as computed, S as useConfig, Y as useThemeClass, bO as isMounted, bP as LazyTeleport, br as withDirectives, bQ as zindexable, aX as Transition, F as Fragment, aj as NBaseIcon, bs as vShow, ba as normalizeStyle, bR as kebabCase, l as NTooltip, aR as beforeNextFrameOnce, aW as createId, a3 as provide, bC as getCurrentInstance, b9 as onMounted, af as watchEffect, o as openBlock, j as createElementBlock, f as createBaseVNode } from "./index.js"; +import { O as replaceable, z as h, d as defineComponent, bL as isBrowser, T as useTheme, P as createInjectionKey, aa as c, Q as cB, bM as fadeInTransition, aS as fadeInScaleUpTransition, ac as cNotM, X as toRef, bN as imageLight, r as ref, ad as useLocale, K as watch, aD as on, aC as off, aB as onBeforeUnmount, R as inject, c as computed, S as useConfig, Y as useThemeClass, bO as isMounted, bP as LazyTeleport, br as withDirectives, bQ as zindexable, aX as Transition, F as Fragment, aj as NBaseIcon, bs as vShow, ba as normalizeStyle, bR as kebabCase, l as NTooltip, aR as beforeNextFrameOnce, aW as createId, a3 as provide, bC as getCurrentInstance, b9 as onMounted, af as watchEffect, o as openBlock, j as createElementBlock, f as createBaseVNode } from "./index.js"; const RotateClockwiseIcon = replaceable("rotateClockwise", h( "svg", { viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, diff --git a/frontend/dist/assets/clock.js b/frontend/dist/assets/clock.js index 7deffb759..5b2000c5a 100644 --- a/frontend/dist/assets/clock.js +++ b/frontend/dist/assets/clock.js @@ -5,7 +5,7 @@ var __publicField = (obj, key, value) => { return value; }; import { N as NDescriptionsItem, a as NDescriptions } from "./DescriptionsItem.js"; -import { d as defineComponent, o as openBlock, j as createElementBlock, f as createBaseVNode, e as createBlock, w as withCtx, g as createVNode, h as unref, k as createTextVNode, C as toDisplayString, n as NCard, m as createCommentVNode, u as useSettings, l as NTooltip, F as Fragment, a as useState, c as computed, G as spaceRegex, B as NIcon, i as NSelect, H as promptHandleKeyUp, I as promptHandleKeyDown, J as NInput, _ as _export_sfc, K as watch, z as ref, t as serverUrl } from "./index.js"; +import { d as defineComponent, o as openBlock, j as createElementBlock, f as createBaseVNode, e as createBlock, w as withCtx, g as createVNode, h as unref, k as createTextVNode, C as toDisplayString, n as NCard, m as createCommentVNode, u as useSettings, l as NTooltip, F as Fragment, a as useState, c as computed, G as spaceRegex, B as NIcon, i as NSelect, H as promptHandleKeyUp, I as promptHandleKeyDown, J as NInput, _ as _export_sfc, K as watch, r as ref, v as serverUrl } from "./index.js"; import { a as NSlider, N as NSwitch } from "./Switch.js"; import { N as NInputNumber } from "./InputNumber.js"; import { N as NForm, a as NFormItem } from "./SamplerPicker.vue_vue_type_script_setup_true_lang.js"; diff --git a/frontend/dist/assets/index.js b/frontend/dist/assets/index.js index b92794fb5..264c43f65 100644 --- a/frontend/dist/assets/index.js +++ b/frontend/dist/assets/index.js @@ -43539,13 +43539,13 @@ export { openBlock as o, useMessage as p, onUnmounted as q, - NGi as r, - NGrid as s, - serverUrl as t, + ref as r, + NGi as s, + NGrid as t, useSettings as u, - pushScopeId as v, + serverUrl as v, withCtx as w, - popScopeId as x, - h as y, - ref as z + pushScopeId as x, + popScopeId as y, + h as z }; From 6b5bae4b66e6accc5dbbc8127c55683c8872b7dd Mon Sep 17 00:00:00 2001 From: Stax124 Date: Sat, 11 Nov 2023 20:35:30 +0100 Subject: [PATCH 043/143] Resize from frontend and config --- core/config/flags_settings.py | 6 +- core/flags.py | 14 +- core/inference/functions.py | 4 +- core/inference/sdxl/pipeline.py | 17 +- core/inference/sdxl/sdxl.py | 51 +- frontend/dist/assets/AccelerateView.js | 2 +- frontend/dist/assets/DescriptionsItem.js | 2 +- ...ion.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/Image2ImageView.js | 2 +- frontend/dist/assets/ImageBrowserView.js | 2 +- ...put.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/ImageProcessingView.js | 2 +- frontend/dist/assets/ImageUpload.js | 2 +- frontend/dist/assets/InputNumber.js | 2 +- ...pup.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/ModelsView.js | 2 +- ...ker.vue_vue_type_script_setup_true_lang.js | 2 +- ...tTo.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/Settings.js | 2 +- frontend/dist/assets/SettingsView.js | 2 +- frontend/dist/assets/Switch.js | 2 +- frontend/dist/assets/TaggerView.js | 2 +- frontend/dist/assets/TestView.js | 2 +- frontend/dist/assets/TextToImageView.js | 446 +++++++++--------- frontend/dist/assets/TrashBin.js | 2 +- frontend/dist/assets/clock.js | 2 +- frontend/dist/assets/index.css | 8 + frontend/dist/assets/index.js | 20 +- frontend/src/assets/2img.css | 8 + .../src/components/generate/HighResFix.vue | 2 +- .../generate/ResizeFromDimensionsInput.vue | 95 ++-- .../src/components/generate/XLRefiner.vue | 2 +- frontend/src/components/inference/Txt2Img.vue | 26 +- frontend/src/settings.ts | 10 +- frontend/src/store/state.ts | 2 + 35 files changed, 399 insertions(+), 352 deletions(-) diff --git a/core/config/flags_settings.py b/core/config/flags_settings.py index 65f24d678..f95bb7124 100644 --- a/core/config/flags_settings.py +++ b/core/config/flags_settings.py @@ -1,6 +1,6 @@ from dataclasses import dataclass, field -from core.flags import HighResFixFlag, XLFlag, XLRefinerFlag +from core.flags import HighResFixFlag, SDXLFlag, SDXLRefinerFlag @dataclass @@ -8,5 +8,5 @@ class FlagsConfig: "Configuration for flags" highres: HighResFixFlag = field(default_factory=HighResFixFlag) - refiner: XLRefinerFlag = field(default_factory=XLRefinerFlag) - xl: XLFlag = field(default_factory=XLFlag) + refiner: SDXLRefinerFlag = field(default_factory=SDXLRefinerFlag) + sdxl: SDXLFlag = field(default_factory=SDXLFlag) diff --git a/core/flags.py b/core/flags.py index 1a1edf2a2..3bbf25cc8 100644 --- a/core/flags.py +++ b/core/flags.py @@ -1,5 +1,5 @@ from dataclasses import dataclass, field -from typing import List, Literal +from typing import Literal from dataclasses_json.api import DataClassJsonMixin @@ -39,14 +39,20 @@ class HighResFixFlag(Flag, DataClassJsonMixin): @dataclass -class XLFlag(Flag, DataClassJsonMixin): +class XLOriginalSize: + width: int = 1024 + height: int = 1024 + + +@dataclass +class SDXLFlag(Flag, DataClassJsonMixin): "Flag for SDXL settings" - original_size: List[int] = field(default_factory=lambda: [1024, 1024]) + original_size: XLOriginalSize = field(default_factory=XLOriginalSize) @dataclass -class XLRefinerFlag(Flag, DataClassJsonMixin): +class SDXLRefinerFlag(Flag, DataClassJsonMixin): "Flag for SDXL refiners" steps: int = 50 diff --git a/core/inference/functions.py b/core/inference/functions.py index e1fae83be..1462192c6 100644 --- a/core/inference/functions.py +++ b/core/inference/functions.py @@ -2,10 +2,10 @@ import json import logging import os +from functools import partial from importlib.util import find_spec from pathlib import Path -from typing import Any, Dict, Tuple, Union, Optional -from functools import partial +from typing import Any, Dict, Optional, Tuple, Union import requests import torch diff --git a/core/inference/sdxl/pipeline.py b/core/inference/sdxl/pipeline.py index da1ee094c..42d5dc783 100644 --- a/core/inference/sdxl/pipeline.py +++ b/core/inference/sdxl/pipeline.py @@ -23,6 +23,7 @@ ) from core.config import config +from core.flags import SDXLRefinerFlag from core.inference.utilities import ( calculate_cfg, full_vae, @@ -40,7 +41,6 @@ ) from core.optimizations import ensure_correct_device, inference_context, unload_all from core.scheduling import KdiffusionSchedulerAdapter -from core.flags import XLRefinerFlag # ------------------------------------------------------------------------------ @@ -281,7 +281,7 @@ def __call__( seed: int, aesthetic_score: float = 6.0, negative_aesthetic_score: float = 2.5, - original_size: List[int] = [1024, 1024], + original_size: Optional[List[int]] = [1024, 1024], negative_prompt: Optional[str] = None, image: Union[torch.FloatTensor, PIL.Image.Image] = None, # type: ignore mask_image: Union[torch.FloatTensor, PIL.Image.Image] = None, # type: ignore @@ -302,9 +302,12 @@ def __call__( prompt_expansion_settings=None, adapter_conditioning_scale: Union[float, List[float]] = 1.0, adapter_conditioning_factor: float = 1.0, - refiner: Optional[XLRefinerFlag] = None, + refiner: Optional[SDXLRefinerFlag] = None, refiner_model: Optional["StableDiffusionXLLongPromptWeightingPipeline"] = None, ): + if original_size is None: + original_size = [height, width] + if config.api.torch_compile: self.unet = torch.compile( self.unet, @@ -653,7 +656,7 @@ def text2img( seed: int, aesthetic_score: float = 6.0, negative_aesthetic_score: float = 2.5, - original_size: List[int] = [1024, 1024], + original_size: Optional[List[int]] = None, negative_prompt: Optional[str] = None, height: int = 512, width: int = 512, @@ -669,7 +672,7 @@ def text2img( is_cancelled_callback: Optional[Callable[[], bool]] = None, callback_steps: int = 1, prompt_expansion_settings=None, - refiner: Optional[XLRefinerFlag] = None, + refiner: Optional[SDXLRefinerFlag] = None, refiner_model: Optional["StableDiffusionXLLongPromptWeightingPipeline"] = None, ): return self.__call__( @@ -706,7 +709,7 @@ def img2img( generator: Union[torch.Generator, philox.PhiloxGenerator], aesthetic_score: float = 6.0, negative_aesthetic_score: float = 2.5, - original_size: List[int] = [1024, 1024], + original_size: Optional[List[int]] = None, negative_prompt: Optional[str] = None, strength: float = 0.8, num_inference_steps: int = 50, @@ -753,7 +756,7 @@ def inpaint( generator: Union[torch.Generator, philox.PhiloxGenerator], aesthetic_score: float = 6.0, negative_aesthetic_score: float = 2.5, - original_size: List[int] = [1024, 1024], + original_size: Optional[List[int]] = None, negative_prompt: Optional[str] = None, strength: float = 0.8, num_inference_steps: Optional[int] = 50, diff --git a/core/inference/sdxl/sdxl.py b/core/inference/sdxl/sdxl.py index 82f71a1dd..689e862df 100644 --- a/core/inference/sdxl/sdxl.py +++ b/core/inference/sdxl/sdxl.py @@ -20,7 +20,7 @@ from api.websockets import Data from core import shared from core.config import config -from core.flags import XLFlag, XLRefinerFlag +from core.flags import SDXLFlag, SDXLRefinerFlag from core.inference.base_model import InferenceModel from core.inference.functions import convert_vaept_to_diffusers, load_pytorch_pipeline from core.inference.utilities import change_scheduler, create_generator @@ -157,7 +157,7 @@ def unload(self) -> None: self.memory_cleanup() - def load_refiner(self, refiner: XLRefinerFlag, job) -> Tuple[Any, Any]: + def load_refiner(self, refiner: SDXLRefinerFlag, job) -> Tuple[Any, Any]: from core.shared_dependent import gpu unload = False @@ -200,21 +200,28 @@ def txt2img(self, job: Txt2ImgQueueEntry) -> List[Image.Image]: for _ in tqdm(range(job.data.batch_count), desc="Queue", position=1): output_type = "pil" - xl_flag = XLFlag() + xl_flag = None if "sdxl" in job.flags: - xl_flag = XLFlag.from_dict(job.flags["sdxl"]) + xl_flag = SDXLFlag.from_dict(job.flags["sdxl"]) refiner = None if "refiner" in job.flags: output_type = "latent" - refiner = XLRefinerFlag.from_dict(job.flags["refiner"]) + refiner = SDXLRefinerFlag.from_dict(job.flags["refiner"]) refiner_model, unload = None, lambda: "" if config.api.sdxl_refiner == "joint" and refiner is not None: refiner_model, unload = self.load_refiner(refiner, job) + original_size = None + if xl_flag: + original_size = [ + xl_flag.original_size.height, + xl_flag.original_size.width, + ] + data = pipe.text2img( - original_size=xl_flag.original_size, + original_size=original_size, generator=generator, prompt=job.data.prompt, height=job.data.height, @@ -239,7 +246,7 @@ def txt2img(self, job: Txt2ImgQueueEntry) -> List[Image.Image]: data = pipe( aesthetic_score=refiner.aesthetic_score, negative_aesthetic_score=refiner.negative_aesthetic_score, - original_size=xl_flag.original_size, + original_size=original_size, image=latents, generator=generator, prompt=job.data.prompt, @@ -326,15 +333,20 @@ def img2img(self, job: Img2ImgQueueEntry) -> List[Image.Image]: total_images: List[Image.Image] = [] shared.current_method = "img2img" - xl_flag: XLFlag + xl_flag = None if "sdxl" in job.flags: - xl_flag = XLFlag.from_dict(job.flags["sdxl"]) - else: - xl_flag = XLFlag() + xl_flag = SDXLFlag.from_dict(job.flags["sdxl"]) + + original_size = None + if xl_flag: + original_size = [ + xl_flag.original_size.height, + xl_flag.original_size.width, + ] for _ in tqdm(range(job.data.batch_count), desc="Queue", position=1): data = pipe.img2img( - original_size=xl_flag.original_size, + original_size=original_size, generator=generator, prompt=job.data.prompt, image=input_image, @@ -394,15 +406,20 @@ def inpaint(self, job: InpaintQueueEntry) -> List[Image.Image]: total_images: List[Image.Image] = [] shared.current_method = "inpainting" - xl_flag: XLFlag + xl_flag = None if "sdxl" in job.flags: - xl_flag = XLFlag.from_dict(job.flags["sdxl"]) - else: - xl_flag = XLFlag() + xl_flag = SDXLFlag.from_dict(job.flags["sdxl"]) + + original_size = None + if xl_flag: + original_size = [ + xl_flag.original_size.height, + xl_flag.original_size.width, + ] for _ in tqdm(range(job.data.batch_count), desc="Queue", position=1): data = pipe.inpaint( - original_size=xl_flag.original_size, + original_size=original_size, generator=generator, prompt=job.data.prompt, image=input_image, diff --git a/frontend/dist/assets/AccelerateView.js b/frontend/dist/assets/AccelerateView.js index 2f6d77834..c10dc0930 100644 --- a/frontend/dist/assets/AccelerateView.js +++ b/frontend/dist/assets/AccelerateView.js @@ -1,4 +1,4 @@ -import { Q as cB, ab as cM, aa as c, at as cE, aT as iconSwitchTransition, ac as cNotM, d as defineComponent, S as useConfig, ag as useRtl, T as useTheme, a3 as provide, z as h, aw as flatten, ax as getSlot, P as createInjectionKey, bg as stepsLight, R as inject, a_ as throwError, c as computed, ah as createKey, Y as useThemeClass, a1 as call, av as resolveWrappedSlot, ai as resolveSlot, aI as NIconSwitchTransition, aj as NBaseIcon, bh as FinishedIcon, bi as ErrorIcon, p as useMessage, a as useState, r as ref, o as openBlock, j as createElementBlock, g as createVNode, w as withCtx, h as unref, N as NSpace, n as NCard, f as createBaseVNode, i as NSelect, A as NButton, k as createTextVNode, bd as NModal, v as serverUrl, u as useSettings, e as createBlock, D as NTabPane, E as NTabs } from "./index.js"; +import { Q as cB, ab as cM, aa as c, at as cE, aT as iconSwitchTransition, ac as cNotM, d as defineComponent, S as useConfig, ag as useRtl, T as useTheme, a3 as provide, y as h, aw as flatten, ax as getSlot, P as createInjectionKey, bg as stepsLight, R as inject, a_ as throwError, c as computed, ah as createKey, Y as useThemeClass, a1 as call, av as resolveWrappedSlot, ai as resolveSlot, aI as NIconSwitchTransition, aj as NBaseIcon, bh as FinishedIcon, bi as ErrorIcon, p as useMessage, a as useState, z as ref, o as openBlock, j as createElementBlock, g as createVNode, w as withCtx, h as unref, N as NSpace, n as NCard, f as createBaseVNode, i as NSelect, A as NButton, k as createTextVNode, bd as NModal, t as serverUrl, u as useSettings, e as createBlock, D as NTabPane, E as NTabs } from "./index.js"; import { a as NSlider, N as NSwitch } from "./Switch.js"; import { N as NInputNumber } from "./InputNumber.js"; const style = cB("steps", ` diff --git a/frontend/dist/assets/DescriptionsItem.js b/frontend/dist/assets/DescriptionsItem.js index 505e80b82..27c00366e 100644 --- a/frontend/dist/assets/DescriptionsItem.js +++ b/frontend/dist/assets/DescriptionsItem.js @@ -1,4 +1,4 @@ -import { aa as c, Q as cB, ac as cNotM, ab as cM, at as cE, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, c as computed, ah as createKey, Y as useThemeClass, bS as useCompitable, aw as flatten, z as h, aQ as repeat, ax as getSlot, bT as descriptionsLight } from "./index.js"; +import { aa as c, Q as cB, ac as cNotM, ab as cM, at as cE, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, c as computed, ah as createKey, Y as useThemeClass, bS as useCompitable, aw as flatten, y as h, aQ as repeat, ax as getSlot, bT as descriptionsLight } from "./index.js"; function getVNodeChildren(vNode, slotName = "default", fallback = []) { const { children } = vNode; if (children !== null && typeof children === "object" && !Array.isArray(children)) { diff --git a/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js index b7bae85e5..a3d8d99d5 100644 --- a/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { d as defineComponent, o as openBlock, j as createElementBlock, f as createBaseVNode, a as useState, u as useSettings, r as ref, b9 as onMounted, q as onUnmounted, v as serverUrl, e as createBlock, w as withCtx, g as createVNode, h as unref, s as NGi, A as NButton, B as NIcon, k as createTextVNode, t as NGrid, bV as NAlert, m as createCommentVNode, n as NCard } from "./index.js"; +import { d as defineComponent, o as openBlock, j as createElementBlock, f as createBaseVNode, a as useState, u as useSettings, z as ref, b9 as onMounted, q as onUnmounted, t as serverUrl, e as createBlock, w as withCtx, g as createVNode, h as unref, r as NGi, A as NButton, B as NIcon, k as createTextVNode, s as NGrid, bV as NAlert, m as createCommentVNode, n as NCard } from "./index.js"; const _hoisted_1$1 = { xmlns: "http://www.w3.org/2000/svg", "xmlns:xlink": "http://www.w3.org/1999/xlink", diff --git a/frontend/dist/assets/Image2ImageView.js b/frontend/dist/assets/Image2ImageView.js index d13b7316c..ceb712769 100644 --- a/frontend/dist/assets/Image2ImageView.js +++ b/frontend/dist/assets/Image2ImageView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, o as openBlock, j as createElementBlock, f as createBaseVNode, a as useState, u as useSettings, p as useMessage, q as onUnmounted, g as createVNode, w as withCtx, h as unref, s as NGi, n as NCard, N as NSpace, l as NTooltip, k as createTextVNode, i as NSelect, t as NGrid, v as serverUrl, x as pushScopeId, y as popScopeId, _ as _export_sfc, m as createCommentVNode, z as h, r as ref, A as NButton, B as NIcon, e as createBlock, C as toDisplayString, D as NTabPane, E as NTabs } from "./index.js"; +import { d as defineComponent, o as openBlock, j as createElementBlock, f as createBaseVNode, a as useState, u as useSettings, p as useMessage, q as onUnmounted, g as createVNode, w as withCtx, h as unref, r as NGi, n as NCard, N as NSpace, l as NTooltip, k as createTextVNode, i as NSelect, s as NGrid, t as serverUrl, v as pushScopeId, x as popScopeId, _ as _export_sfc, m as createCommentVNode, y as h, z as ref, A as NButton, B as NIcon, e as createBlock, C as toDisplayString, D as NTabPane, E as NTabs } from "./index.js"; import { B as BurnerClock, P as Prompt, _ as _sfc_main$5, a as _sfc_main$6, b as _sfc_main$9 } from "./clock.js"; import { _ as _sfc_main$7 } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; import { _ as _sfc_main$8 } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; diff --git a/frontend/dist/assets/ImageBrowserView.js b/frontend/dist/assets/ImageBrowserView.js index 928783129..0ef71fd6b 100644 --- a/frontend/dist/assets/ImageBrowserView.js +++ b/frontend/dist/assets/ImageBrowserView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, b6 as useCssVars, a as useState, u as useSettings, R as inject, r as ref, c as computed, bI as urlFromPath, b8 as reactive, b9 as onMounted, q as onUnmounted, o as openBlock, j as createElementBlock, f as createBaseVNode, g as createVNode, h as unref, w as withCtx, F as Fragment, L as renderList, b7 as themeOverridesKey, v as serverUrl, J as NInput, B as NIcon, bd as NModal, t as NGrid, s as NGi, A as NButton, k as createTextVNode, M as NScrollbar, e as createBlock, by as convertToTextString, C as toDisplayString, m as createCommentVNode, bJ as diffusersSchedulerTuple, _ as _export_sfc } from "./index.js"; +import { d as defineComponent, b6 as useCssVars, a as useState, u as useSettings, R as inject, z as ref, c as computed, bI as urlFromPath, b8 as reactive, b9 as onMounted, q as onUnmounted, o as openBlock, j as createElementBlock, f as createBaseVNode, g as createVNode, h as unref, w as withCtx, F as Fragment, L as renderList, b7 as themeOverridesKey, t as serverUrl, J as NInput, B as NIcon, bd as NModal, s as NGrid, r as NGi, A as NButton, k as createTextVNode, M as NScrollbar, e as createBlock, by as convertToTextString, C as toDisplayString, m as createCommentVNode, bJ as diffusersSchedulerTuple, _ as _export_sfc } from "./index.js"; import { D as Download, _ as _sfc_main$1 } from "./SendOutputTo.vue_vue_type_script_setup_true_lang.js"; import { G as GridOutline } from "./GridOutline.js"; import { N as NImage, T as TrashBin } from "./TrashBin.js"; diff --git a/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js index 24190edca..57bc1e1e5 100644 --- a/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { d as defineComponent, r as ref, a as useState, o as openBlock, e as createBlock, w as withCtx, h as unref, s as NGi, g as createVNode, B as NIcon, k as createTextVNode, A as NButton, m as createCommentVNode, t as NGrid, c as computed, f as createBaseVNode, j as createElementBlock, F as Fragment, L as renderList, M as NScrollbar, n as NCard } from "./index.js"; +import { d as defineComponent, z as ref, a as useState, o as openBlock, e as createBlock, w as withCtx, h as unref, r as NGi, g as createVNode, B as NIcon, k as createTextVNode, A as NButton, m as createCommentVNode, s as NGrid, c as computed, f as createBaseVNode, j as createElementBlock, F as Fragment, L as renderList, M as NScrollbar, n as NCard } from "./index.js"; import { D as Download, _ as _sfc_main$2 } from "./SendOutputTo.vue_vue_type_script_setup_true_lang.js"; import { T as TrashBin, N as NImage } from "./TrashBin.js"; const _sfc_main$1 = /* @__PURE__ */ defineComponent({ diff --git a/frontend/dist/assets/ImageProcessingView.js b/frontend/dist/assets/ImageProcessingView.js index c48eb5f22..413029b4f 100644 --- a/frontend/dist/assets/ImageProcessingView.js +++ b/frontend/dist/assets/ImageProcessingView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, a as useState, u as useSettings, p as useMessage, c as computed, b as upscalerOptions, o as openBlock, j as createElementBlock, g as createVNode, w as withCtx, h as unref, s as NGi, n as NCard, N as NSpace, f as createBaseVNode, i as NSelect, l as NTooltip, k as createTextVNode, t as NGrid, v as serverUrl, x as pushScopeId, y as popScopeId, _ as _export_sfc, e as createBlock, D as NTabPane, E as NTabs } from "./index.js"; +import { d as defineComponent, a as useState, u as useSettings, p as useMessage, c as computed, b as upscalerOptions, o as openBlock, j as createElementBlock, g as createVNode, w as withCtx, h as unref, r as NGi, n as NCard, N as NSpace, f as createBaseVNode, i as NSelect, l as NTooltip, k as createTextVNode, s as NGrid, t as serverUrl, v as pushScopeId, x as popScopeId, _ as _export_sfc, e as createBlock, D as NTabPane, E as NTabs } from "./index.js"; import { _ as _sfc_main$2 } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; import { _ as _sfc_main$3 } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; import { I as ImageUpload } from "./ImageUpload.js"; diff --git a/frontend/dist/assets/ImageUpload.js b/frontend/dist/assets/ImageUpload.js index 6a1a80317..892dc106b 100644 --- a/frontend/dist/assets/ImageUpload.js +++ b/frontend/dist/assets/ImageUpload.js @@ -1,4 +1,4 @@ -import { d as defineComponent, r as ref, c as computed, b9 as onMounted, o as openBlock, e as createBlock, w as withCtx, f as createBaseVNode, bU as withModifiers, j as createElementBlock, g as createVNode, h as unref, B as NIcon, C as toDisplayString, n as NCard, x as pushScopeId, y as popScopeId, _ as _export_sfc } from "./index.js"; +import { d as defineComponent, z as ref, c as computed, b9 as onMounted, o as openBlock, e as createBlock, w as withCtx, f as createBaseVNode, bU as withModifiers, j as createElementBlock, g as createVNode, h as unref, B as NIcon, C as toDisplayString, n as NCard, v as pushScopeId, x as popScopeId, _ as _export_sfc } from "./index.js"; import { C as CloudUpload } from "./CloudUpload.js"; const _withScopeId = (n) => (pushScopeId("data-v-9ed1514f"), n = n(), popScopeId(), n); const _hoisted_1 = { class: "image-container" }; diff --git a/frontend/dist/assets/InputNumber.js b/frontend/dist/assets/InputNumber.js index 0792ef26c..65f5be9cc 100644 --- a/frontend/dist/assets/InputNumber.js +++ b/frontend/dist/assets/InputNumber.js @@ -1,4 +1,4 @@ -import { d as defineComponent, z as h, aa as c, Q as cB, S as useConfig, T as useTheme, ad as useLocale, ar as useFormItem, r as ref, X as toRef, ae as useMergedState, as as useMemo, K as watch, ag as useRtl, c as computed, bW as rgba, J as NInput, av as resolveWrappedSlot, bX as inputNumberLight, aD as on, ai as resolveSlot, aj as NBaseIcon, bY as XButton, a$ as AddIcon, a1 as call, W as nextTick } from "./index.js"; +import { d as defineComponent, y as h, aa as c, Q as cB, S as useConfig, T as useTheme, ad as useLocale, ar as useFormItem, z as ref, X as toRef, ae as useMergedState, as as useMemo, K as watch, ag as useRtl, c as computed, bW as rgba, J as NInput, av as resolveWrappedSlot, bX as inputNumberLight, aD as on, ai as resolveSlot, aj as NBaseIcon, bY as XButton, a$ as AddIcon, a1 as call, W as nextTick } from "./index.js"; const RemoveIcon = defineComponent({ name: "Remove", render() { diff --git a/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js index 28e13a328..d63e0de48 100644 --- a/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { bj as upperFirst, bk as toString, bl as createCompounder, bm as cloneVNode, a3 as provide, P as createInjectionKey, R as inject, a_ as throwError, d as defineComponent, S as useConfig, r as ref, bn as onBeforeUpdate, z as h, bo as indexMap, c as computed, b9 as onMounted, aB as onBeforeUnmount, Q as cB, at as cE, aa as c, ab as cM, a4 as keep, ae as useMergedState, X as toRef, af as watchEffect, bp as onUpdated, K as watch, W as nextTick, T as useTheme, Y as useThemeClass, aw as flatten, aL as VResizeObserver, bq as resolveSlotWithProps, br as withDirectives, bs as vShow, aX as Transition, ba as normalizeStyle, bt as getPreciseEventTarget, aD as on, aC as off, bu as carouselLight, ac as cNotM, ar as useFormItem, ah as createKey, bv as color2Class, L as renderList, aj as NBaseIcon, bw as rateLight, a1 as call, p as useMessage, u as useSettings, b8 as reactive, o as openBlock, e as createBlock, w as withCtx, g as createVNode, j as createElementBlock, h as unref, D as NTabPane, t as NGrid, s as NGi, F as Fragment, f as createBaseVNode, n as NCard, k as createTextVNode, C as toDisplayString, bx as NTag, i as NSelect, A as NButton, E as NTabs, bd as NModal, v as serverUrl } from "./index.js"; +import { bj as upperFirst, bk as toString, bl as createCompounder, bm as cloneVNode, a3 as provide, P as createInjectionKey, R as inject, a_ as throwError, d as defineComponent, S as useConfig, z as ref, bn as onBeforeUpdate, y as h, bo as indexMap, c as computed, b9 as onMounted, aB as onBeforeUnmount, Q as cB, at as cE, aa as c, ab as cM, a4 as keep, ae as useMergedState, X as toRef, af as watchEffect, bp as onUpdated, K as watch, W as nextTick, T as useTheme, Y as useThemeClass, aw as flatten, aL as VResizeObserver, bq as resolveSlotWithProps, br as withDirectives, bs as vShow, aX as Transition, ba as normalizeStyle, bt as getPreciseEventTarget, aD as on, aC as off, bu as carouselLight, ac as cNotM, ar as useFormItem, ah as createKey, bv as color2Class, L as renderList, aj as NBaseIcon, bw as rateLight, a1 as call, p as useMessage, u as useSettings, b8 as reactive, o as openBlock, e as createBlock, w as withCtx, g as createVNode, j as createElementBlock, h as unref, D as NTabPane, s as NGrid, r as NGi, F as Fragment, f as createBaseVNode, n as NCard, k as createTextVNode, C as toDisplayString, bx as NTag, i as NSelect, A as NButton, E as NTabs, bd as NModal, t as serverUrl } from "./index.js"; import { a as NDescriptions, N as NDescriptionsItem } from "./DescriptionsItem.js"; function capitalize(string) { return upperFirst(toString(string).toLowerCase()); diff --git a/frontend/dist/assets/ModelsView.js b/frontend/dist/assets/ModelsView.js index 6afeeb364..0356485f0 100644 --- a/frontend/dist/assets/ModelsView.js +++ b/frontend/dist/assets/ModelsView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, z as h, O as replaceable, P as createInjectionKey, Q as cB, R as inject, S as useConfig, T as useTheme, U as popselectLight, c as computed, V as createTreeMate, K as watch, W as nextTick, X as toRef, Y as useThemeClass, Z as NInternalSelectMenu, $ as createTmOptions, a0 as happensIn, a1 as call, a2 as keysOf, r as ref, a3 as provide, a4 as keep, a5 as createRefSetter, a6 as mergeEventHandlers, a7 as omit, a8 as NPopover, a9 as popoverBaseProps, aa as c, ab as cM, ac as cNotM, ad as useLocale, ae as useMergedState, af as watchEffect, ag as useRtl, ah as createKey, ai as resolveSlot, J as NInput, i as NSelect, F as Fragment, aj as NBaseIcon, ak as useAdjustedTo, al as paginationLight, am as useMergedClsPrefix, an as ellipsisLight, ao as onDeactivated, l as NTooltip, ap as mergeProps, aq as useStyle, ar as useFormItem, as as useMemo, at as cE, au as radioLight, av as resolveWrappedSlot, aw as flatten$1, ax as getSlot, ay as depx, az as formatLength, A as NButton, aA as NScrollbar, aB as onBeforeUnmount, aC as off, aD as on, aE as ChevronDownIcon, aF as NDropdown, aG as pxfy, aH as get, aI as NIconSwitchTransition, aJ as NBaseLoading, aK as ChevronRightIcon, q as onUnmounted, aL as VResizeObserver, aM as warn, aN as cssrAnchorMetaName, aO as VVirtualList, aP as NEmpty, aQ as repeat, aR as beforeNextFrameOnce, aS as fadeInScaleUpTransition, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, aW as createId, aX as Transition, aY as dataTableLight, aZ as loadingBarApiInjectionKey, a_ as throwError, a$ as AddIcon, b0 as NProgress, b1 as NFadeInExpandTransition, b2 as EyeIcon, b3 as fadeInHeightExpandTransition, b4 as Teleport, b5 as uploadLight, o as openBlock, j as createElementBlock, f as createBaseVNode, b6 as useCssVars, h as unref, u as useSettings, b7 as themeOverridesKey, b8 as reactive, b9 as onMounted, g as createVNode, w as withCtx, B as NIcon, L as renderList, ba as normalizeStyle, k as createTextVNode, C as toDisplayString, bb as NText, m as createCommentVNode, _ as _export_sfc, a as useState, p as useMessage, bc as huggingfaceModelsFile, n as NCard, v as serverUrl, x as pushScopeId, y as popScopeId, N as NSpace, bd as NModal, e as createBlock, s as NGi, t as NGrid, be as NDivider, bf as Backends, D as NTabPane, E as NTabs } from "./index.js"; +import { d as defineComponent, y as h, O as replaceable, P as createInjectionKey, Q as cB, R as inject, S as useConfig, T as useTheme, U as popselectLight, c as computed, V as createTreeMate, K as watch, W as nextTick, X as toRef, Y as useThemeClass, Z as NInternalSelectMenu, $ as createTmOptions, a0 as happensIn, a1 as call, a2 as keysOf, z as ref, a3 as provide, a4 as keep, a5 as createRefSetter, a6 as mergeEventHandlers, a7 as omit, a8 as NPopover, a9 as popoverBaseProps, aa as c, ab as cM, ac as cNotM, ad as useLocale, ae as useMergedState, af as watchEffect, ag as useRtl, ah as createKey, ai as resolveSlot, J as NInput, i as NSelect, F as Fragment, aj as NBaseIcon, ak as useAdjustedTo, al as paginationLight, am as useMergedClsPrefix, an as ellipsisLight, ao as onDeactivated, l as NTooltip, ap as mergeProps, aq as useStyle, ar as useFormItem, as as useMemo, at as cE, au as radioLight, av as resolveWrappedSlot, aw as flatten$1, ax as getSlot, ay as depx, az as formatLength, A as NButton, aA as NScrollbar, aB as onBeforeUnmount, aC as off, aD as on, aE as ChevronDownIcon, aF as NDropdown, aG as pxfy, aH as get, aI as NIconSwitchTransition, aJ as NBaseLoading, aK as ChevronRightIcon, q as onUnmounted, aL as VResizeObserver, aM as warn, aN as cssrAnchorMetaName, aO as VVirtualList, aP as NEmpty, aQ as repeat, aR as beforeNextFrameOnce, aS as fadeInScaleUpTransition, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, aW as createId, aX as Transition, aY as dataTableLight, aZ as loadingBarApiInjectionKey, a_ as throwError, a$ as AddIcon, b0 as NProgress, b1 as NFadeInExpandTransition, b2 as EyeIcon, b3 as fadeInHeightExpandTransition, b4 as Teleport, b5 as uploadLight, o as openBlock, j as createElementBlock, f as createBaseVNode, b6 as useCssVars, h as unref, u as useSettings, b7 as themeOverridesKey, b8 as reactive, b9 as onMounted, g as createVNode, w as withCtx, B as NIcon, L as renderList, ba as normalizeStyle, k as createTextVNode, C as toDisplayString, bb as NText, m as createCommentVNode, _ as _export_sfc, a as useState, p as useMessage, bc as huggingfaceModelsFile, n as NCard, t as serverUrl, v as pushScopeId, x as popScopeId, N as NSpace, bd as NModal, e as createBlock, r as NGi, s as NGrid, be as NDivider, bf as Backends, D as NTabPane, E as NTabs } from "./index.js"; import { _ as _sfc_main$5, n as nsfwIndex } from "./ModelPopup.vue_vue_type_script_setup_true_lang.js"; import { G as GridOutline } from "./GridOutline.js"; import { a as NSlider, N as NSwitch } from "./Switch.js"; diff --git a/frontend/dist/assets/SamplerPicker.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/SamplerPicker.vue_vue_type_script_setup_true_lang.js index 8f92b4052..d3120ca90 100644 --- a/frontend/dist/assets/SamplerPicker.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/SamplerPicker.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { R as inject, bC as getCurrentInstance, K as watch, aB as onBeforeUnmount, Q as cB, ab as cM, aa as c, P as createInjectionKey, d as defineComponent, S as useConfig, T as useTheme, r as ref, a3 as provide, z as h, bD as formLight, a2 as keysOf, c as computed, az as formatLength, aH as get, bE as commonVariables, at as cE, X as toRef, aW as createId, bF as formItemInjectionKey, b9 as onMounted, ah as createKey, Y as useThemeClass, aX as Transition, av as resolveWrappedSlot, aM as warn, u as useSettings, o as openBlock, j as createElementBlock, f as createBaseVNode, g as createVNode, w as withCtx, h as unref, n as NCard, F as Fragment, L as renderList, A as NButton, k as createTextVNode, C as toDisplayString, by as convertToTextString, e as createBlock, bG as resolveDynamicComponent, bd as NModal, l as NTooltip, i as NSelect, B as NIcon } from "./index.js"; +import { R as inject, bC as getCurrentInstance, K as watch, aB as onBeforeUnmount, Q as cB, ab as cM, aa as c, P as createInjectionKey, d as defineComponent, S as useConfig, T as useTheme, z as ref, a3 as provide, y as h, bD as formLight, a2 as keysOf, c as computed, az as formatLength, aH as get, bE as commonVariables, at as cE, X as toRef, aW as createId, bF as formItemInjectionKey, b9 as onMounted, ah as createKey, Y as useThemeClass, aX as Transition, av as resolveWrappedSlot, aM as warn, u as useSettings, o as openBlock, j as createElementBlock, f as createBaseVNode, g as createVNode, w as withCtx, h as unref, n as NCard, F as Fragment, L as renderList, A as NButton, k as createTextVNode, C as toDisplayString, by as convertToTextString, e as createBlock, bG as resolveDynamicComponent, bd as NModal, l as NTooltip, i as NSelect, B as NIcon } from "./index.js"; import { S as Settings, a as NCheckbox } from "./Settings.js"; import { N as NInputNumber } from "./InputNumber.js"; import { a as NSlider } from "./Switch.js"; diff --git a/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js index 216b00ec0..beac36b50 100644 --- a/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { d as defineComponent, o as openBlock, j as createElementBlock, f as createBaseVNode, bK as useRouter, u as useSettings, a as useState, r as ref, b8 as reactive, K as watch, c as computed, g as createVNode, w as withCtx, h as unref, n as NCard, A as NButton, k as createTextVNode, M as NScrollbar, F as Fragment, L as renderList, C as toDisplayString, be as NDivider, bd as NModal, e as createBlock, s as NGi, t as NGrid, m as createCommentVNode } from "./index.js"; +import { d as defineComponent, o as openBlock, j as createElementBlock, f as createBaseVNode, bK as useRouter, u as useSettings, a as useState, z as ref, b8 as reactive, K as watch, c as computed, g as createVNode, w as withCtx, h as unref, n as NCard, A as NButton, k as createTextVNode, M as NScrollbar, F as Fragment, L as renderList, C as toDisplayString, be as NDivider, bd as NModal, e as createBlock, r as NGi, s as NGrid, m as createCommentVNode } from "./index.js"; import { N as NSwitch } from "./Switch.js"; const _hoisted_1$3 = { xmlns: "http://www.w3.org/2000/svg", diff --git a/frontend/dist/assets/Settings.js b/frontend/dist/assets/Settings.js index d1d197dc9..a780d5357 100644 --- a/frontend/dist/assets/Settings.js +++ b/frontend/dist/assets/Settings.js @@ -1,4 +1,4 @@ -import { z as h, d as defineComponent, S as useConfig, ar as useFormItem, r as ref, c as computed, ae as useMergedState, a3 as provide, X as toRef, P as createInjectionKey, a1 as call, aa as c, Q as cB, ab as cM, at as cE, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, R as inject, as as useMemo, T as useTheme, bH as checkboxLight, ag as useRtl, ah as createKey, Y as useThemeClass, aW as createId, av as resolveWrappedSlot, aI as NIconSwitchTransition, aD as on, o as openBlock, j as createElementBlock, f as createBaseVNode } from "./index.js"; +import { y as h, d as defineComponent, S as useConfig, ar as useFormItem, z as ref, c as computed, ae as useMergedState, a3 as provide, X as toRef, P as createInjectionKey, a1 as call, aa as c, Q as cB, ab as cM, at as cE, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, R as inject, as as useMemo, T as useTheme, bH as checkboxLight, ag as useRtl, ah as createKey, Y as useThemeClass, aW as createId, av as resolveWrappedSlot, aI as NIconSwitchTransition, aD as on, o as openBlock, j as createElementBlock, f as createBaseVNode } from "./index.js"; const CheckMark = h( "svg", { viewBox: "0 0 64 64", class: "check-icon" }, diff --git a/frontend/dist/assets/SettingsView.js b/frontend/dist/assets/SettingsView.js index b4c5f2d9d..3c0a05b26 100644 --- a/frontend/dist/assets/SettingsView.js +++ b/frontend/dist/assets/SettingsView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, u as useSettings, o as openBlock, e as createBlock, w as withCtx, g as createVNode, h as unref, J as NInput, i as NSelect, n as NCard, b8 as reactive, c as computed, by as convertToTextString, r as ref, v as serverUrl, K as watch, a as useState, f as createBaseVNode, j as createElementBlock, L as renderList, bb as NText, k as createTextVNode, C as toDisplayString, F as Fragment, m as createCommentVNode, D as NTabPane, E as NTabs, R as inject, bz as themeKey, A as NButton, l as NTooltip, p as useMessage, bA as useNotification, q as onUnmounted, bB as defaultSettings } from "./index.js"; +import { d as defineComponent, u as useSettings, o as openBlock, e as createBlock, w as withCtx, g as createVNode, h as unref, J as NInput, i as NSelect, n as NCard, b8 as reactive, c as computed, by as convertToTextString, z as ref, t as serverUrl, K as watch, a as useState, f as createBaseVNode, j as createElementBlock, L as renderList, bb as NText, k as createTextVNode, C as toDisplayString, F as Fragment, m as createCommentVNode, D as NTabPane, E as NTabs, R as inject, bz as themeKey, A as NButton, l as NTooltip, p as useMessage, bA as useNotification, q as onUnmounted, bB as defaultSettings } from "./index.js"; import { a as NFormItem, _ as _sfc_main$h, N as NForm } from "./SamplerPicker.vue_vue_type_script_setup_true_lang.js"; import { N as NSwitch, a as NSlider } from "./Switch.js"; import { N as NInputNumber } from "./InputNumber.js"; diff --git a/frontend/dist/assets/Switch.js b/frontend/dist/assets/Switch.js index e7687d04d..27efe4dec 100644 --- a/frontend/dist/assets/Switch.js +++ b/frontend/dist/assets/Switch.js @@ -1,4 +1,4 @@ -import { r as ref, bn as onBeforeUpdate, aa as c, Q as cB, ab as cM, at as cE, aS as fadeInScaleUpTransition, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, ar as useFormItem, c as computed, X as toRef, ae as useMergedState, K as watch, W as nextTick, aB as onBeforeUnmount, Y as useThemeClass, bO as isMounted, ak as useAdjustedTo, z as h, bZ as VBinder, b_ as VTarget, ai as resolveSlot, b$ as VFollower, aX as Transition, c0 as sliderLight, aD as on, aC as off, a1 as call, aT as iconSwitchTransition, ac as cNotM, ah as createKey, aG as pxfy, ay as depx, c1 as isSlotEmpty, av as resolveWrappedSlot, c2 as switchLight, aI as NIconSwitchTransition, aJ as NBaseLoading } from "./index.js"; +import { z as ref, bn as onBeforeUpdate, aa as c, Q as cB, ab as cM, at as cE, aS as fadeInScaleUpTransition, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, ar as useFormItem, c as computed, X as toRef, ae as useMergedState, K as watch, W as nextTick, aB as onBeforeUnmount, Y as useThemeClass, bO as isMounted, ak as useAdjustedTo, y as h, bZ as VBinder, b_ as VTarget, ai as resolveSlot, b$ as VFollower, aX as Transition, c0 as sliderLight, aD as on, aC as off, a1 as call, aT as iconSwitchTransition, ac as cNotM, ah as createKey, aG as pxfy, ay as depx, c1 as isSlotEmpty, av as resolveWrappedSlot, c2 as switchLight, aI as NIconSwitchTransition, aJ as NBaseLoading } from "./index.js"; function isTouchEvent(e) { return window.TouchEvent && e instanceof window.TouchEvent; } diff --git a/frontend/dist/assets/TaggerView.js b/frontend/dist/assets/TaggerView.js index aff7bc63c..154f4dc90 100644 --- a/frontend/dist/assets/TaggerView.js +++ b/frontend/dist/assets/TaggerView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, a as useState, u as useSettings, p as useMessage, r as ref, c as computed, G as spaceRegex, o as openBlock, j as createElementBlock, g as createVNode, w as withCtx, h as unref, s as NGi, n as NCard, N as NSpace, f as createBaseVNode, i as NSelect, l as NTooltip, k as createTextVNode, J as NInput, C as toDisplayString, t as NGrid, v as serverUrl, x as pushScopeId, y as popScopeId, _ as _export_sfc } from "./index.js"; +import { d as defineComponent, a as useState, u as useSettings, p as useMessage, z as ref, c as computed, G as spaceRegex, o as openBlock, j as createElementBlock, g as createVNode, w as withCtx, h as unref, r as NGi, n as NCard, N as NSpace, f as createBaseVNode, i as NSelect, l as NTooltip, k as createTextVNode, J as NInput, C as toDisplayString, s as NGrid, t as serverUrl, v as pushScopeId, x as popScopeId, _ as _export_sfc } from "./index.js"; import { _ as _sfc_main$1 } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; import { I as ImageUpload } from "./ImageUpload.js"; import { v as v4 } from "./v4.js"; diff --git a/frontend/dist/assets/TestView.js b/frontend/dist/assets/TestView.js index c938d7409..ff8c3ffbd 100644 --- a/frontend/dist/assets/TestView.js +++ b/frontend/dist/assets/TestView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, r as ref, o as openBlock, e as createBlock, h as unref } from "./index.js"; +import { d as defineComponent, z as ref, o as openBlock, e as createBlock, h as unref } from "./index.js"; import { _ as _sfc_main$1 } from "./ModelPopup.vue_vue_type_script_setup_true_lang.js"; import "./DescriptionsItem.js"; const _sfc_main = /* @__PURE__ */ defineComponent({ diff --git a/frontend/dist/assets/TextToImageView.js b/frontend/dist/assets/TextToImageView.js index e1b131cc8..f586adcbc 100644 --- a/frontend/dist/assets/TextToImageView.js +++ b/frontend/dist/assets/TextToImageView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, u as useSettings, a as useState, c as computed, b as upscalerOptions, o as openBlock, e as createBlock, w as withCtx, f as createBaseVNode, g as createVNode, h as unref, N as NSpace, i as NSelect, j as createElementBlock, k as createTextVNode, l as NTooltip, m as createCommentVNode, n as NCard, r as ref, F as Fragment, p as useMessage, q as onUnmounted, s as NGi, t as NGrid, v as serverUrl } from "./index.js"; +import { d as defineComponent, u as useSettings, a as useState, c as computed, b as upscalerOptions, o as openBlock, e as createBlock, w as withCtx, f as createBaseVNode, g as createVNode, h as unref, N as NSpace, i as NSelect, j as createElementBlock, k as createTextVNode, l as NTooltip, m as createCommentVNode, n as NCard, p as useMessage, q as onUnmounted, r as NGi, s as NGrid, t as serverUrl } from "./index.js"; import { _ as _sfc_main$8 } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; import { _ as _sfc_main$9 } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; import { B as BurnerClock, P as Prompt, _ as _sfc_main$6, a as _sfc_main$7, b as _sfc_main$a } from "./clock.js"; @@ -56,7 +56,10 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({ { label: "Bislerp", value: "bislerp" } ]; return (_ctx, _cache) => { - return openBlock(), createBlock(unref(NCard), { title: "Highres fix" }, { + return openBlock(), createBlock(unref(NCard), { + title: "Highres fix", + class: "generate-extra-card" + }, { default: withCtx(() => [ createBaseVNode("div", _hoisted_1$3, [ _hoisted_2$3, @@ -187,71 +190,71 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({ } }); const _hoisted_1$2 = { class: "flex-container" }; -const _hoisted_2$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Resize From (temporary placement)", -1); +const _hoisted_2$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Enabled", -1); const _hoisted_3$2 = { key: 0 }; const _hoisted_4$2 = { class: "flex-container" }; -const _hoisted_5$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Resize From Width", -1); +const _hoisted_5$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Width", -1); const _hoisted_6$2 = { class: "flex-container" }; -const _hoisted_7$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Resize From Height", -1); +const _hoisted_7$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Height", -1); const _sfc_main$3 = /* @__PURE__ */ defineComponent({ __name: "ResizeFromDimensionsInput", - props: { - dimensionsObject: { - type: Object, - required: true - } - }, setup(__props) { - const props = __props; - const show = ref(false); + const settings = useSettings(); + const global = useState(); return (_ctx, _cache) => { - return openBlock(), createElementBlock(Fragment, null, [ - createBaseVNode("div", _hoisted_1$2, [ - _hoisted_2$2, - createVNode(unref(NSwitch), { - value: show.value, - "onUpdate:value": _cache[0] || (_cache[0] = ($event) => show.value = $event) - }, null, 8, ["value"]) - ]), - show.value ? (openBlock(), createElementBlock("div", _hoisted_3$2, [ - createBaseVNode("div", _hoisted_4$2, [ - _hoisted_5$2, - createVNode(unref(NSlider), { - value: props.dimensionsObject.width, - "onUpdate:value": _cache[1] || (_cache[1] = ($event) => props.dimensionsObject.width = $event), - min: 128, - max: 2048, - step: 1, - style: { "margin-right": "12px" } - }, null, 8, ["value"]), - createVNode(unref(NInputNumber), { - value: props.dimensionsObject.width, - "onUpdate:value": _cache[2] || (_cache[2] = ($event) => props.dimensionsObject.width = $event), - size: "small", - style: { "min-width": "96px", "width": "96px" }, - step: 1 + return openBlock(), createBlock(unref(NCard), { + title: "Resize from", + class: "generate-extra-card" + }, { + default: withCtx(() => [ + createBaseVNode("div", _hoisted_1$2, [ + _hoisted_2$2, + createVNode(unref(NSwitch), { + value: unref(global).state.txt2img.sdxl_resize, + "onUpdate:value": _cache[0] || (_cache[0] = ($event) => unref(global).state.txt2img.sdxl_resize = $event) }, null, 8, ["value"]) ]), - createBaseVNode("div", _hoisted_6$2, [ - _hoisted_7$2, - createVNode(unref(NSlider), { - value: props.dimensionsObject.height, - "onUpdate:value": _cache[3] || (_cache[3] = ($event) => props.dimensionsObject.height = $event), - min: 128, - max: 2048, - step: 1, - style: { "margin-right": "12px" } - }, null, 8, ["value"]), - createVNode(unref(NInputNumber), { - value: props.dimensionsObject.height, - "onUpdate:value": _cache[4] || (_cache[4] = ($event) => props.dimensionsObject.height = $event), - size: "small", - style: { "min-width": "96px", "width": "96px" }, - step: 1 - }, null, 8, ["value"]) - ]) - ])) : createCommentVNode("", true) - ], 64); + unref(global).state.txt2img.sdxl_resize ? (openBlock(), createElementBlock("div", _hoisted_3$2, [ + createBaseVNode("div", _hoisted_4$2, [ + _hoisted_5$2, + createVNode(unref(NSlider), { + value: unref(settings).data.settings.flags.sdxl.original_size.width, + "onUpdate:value": _cache[1] || (_cache[1] = ($event) => unref(settings).data.settings.flags.sdxl.original_size.width = $event), + min: 128, + max: 2048, + step: 1, + style: { "margin-right": "12px" } + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: unref(settings).data.settings.flags.sdxl.original_size.width, + "onUpdate:value": _cache[2] || (_cache[2] = ($event) => unref(settings).data.settings.flags.sdxl.original_size.width = $event), + size: "small", + style: { "min-width": "96px", "width": "96px" }, + step: 1 + }, null, 8, ["value"]) + ]), + createBaseVNode("div", _hoisted_6$2, [ + _hoisted_7$2, + createVNode(unref(NSlider), { + value: unref(settings).data.settings.flags.sdxl.original_size.height, + "onUpdate:value": _cache[3] || (_cache[3] = ($event) => unref(settings).data.settings.flags.sdxl.original_size.height = $event), + min: 128, + max: 2048, + step: 1, + style: { "margin-right": "12px" } + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: unref(settings).data.settings.flags.sdxl.original_size.height, + "onUpdate:value": _cache[4] || (_cache[4] = ($event) => unref(settings).data.settings.flags.sdxl.original_size.height = $event), + size: "small", + style: { "min-width": "96px", "width": "96px" }, + step: 1 + }, null, 8, ["value"]) + ]) + ])) : createCommentVNode("", true) + ]), + _: 1 + }); }; } }); @@ -290,7 +293,10 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ settings.data.settings.flags.refiner.model = modelStr; } return (_ctx, _cache) => { - return openBlock(), createBlock(unref(NCard), { title: "SDXL Refiner" }, { + return openBlock(), createBlock(unref(NCard), { + title: "SDXL Refiner", + class: "generate-extra-card" + }, { default: withCtx(() => [ createBaseVNode("div", _hoisted_1$1, [ _hoisted_2$1, @@ -443,7 +449,7 @@ const _hoisted_5 = { class: "flex-container" }; const _hoisted_6 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "CFG Scale", -1); const _hoisted_7 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "We recommend using 3-15 for most images.", -1); const _hoisted_8 = { - key: 1, + key: 0, class: "flex-container" }; const _hoisted_9 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Self Attention Scale", -1); @@ -507,9 +513,12 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ backend: "PyTorch", autoload: false, flags: { - ...isSelectedModelSDXL.value ? { + ...isSelectedModelSDXL.value && global.state.txt2img.sdxl_resize ? { sdxl: { - original_size: [1024, 1024] + original_size: { + width: settings.data.settings.flags.sdxl.original_size.width, + height: settings.data.settings.flags.sdxl.original_size.height + } } } : {}, ...global.state.txt2img.highres ? { @@ -571,164 +580,161 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ }, { default: withCtx(() => [ createVNode(unref(NGi), null, { - default: withCtx(() => [ - createVNode(unref(NCard), { title: "Settings" }, { - default: withCtx(() => [ - createVNode(unref(NSpace), { - vertical: "", - class: "left-container" - }, { - default: withCtx(() => { - var _a, _b; - return [ - createVNode(unref(Prompt), { tab: "txt2img" }), - createVNode(unref(_sfc_main$5), { type: "txt2img" }), - createVNode(unref(_sfc_main$6), { - "dimensions-object": unref(settings).data.settings.txt2img - }, null, 8, ["dimensions-object"]), - ((_a = unref(settings).data.settings.model) == null ? void 0 : _a.type) === "SDXL" ? (openBlock(), createBlock(unref(_sfc_main$3), { - key: 0, - "dimensions-object": unref(settings).data.settings.txt2img - }, null, 8, ["dimensions-object"])) : createCommentVNode("", true), - createBaseVNode("div", _hoisted_2, [ - createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { - trigger: withCtx(() => [ - _hoisted_3 - ]), - default: withCtx(() => [ - createTextVNode(" Number of steps to take in the diffusion process. Higher values will result in more detailed images but will take longer to generate. There is also a point of diminishing returns around 100 steps. "), - _hoisted_4 - ]), - _: 1 - }), - createVNode(unref(NSlider), { - value: unref(settings).data.settings.txt2img.steps, - "onUpdate:value": _cache[0] || (_cache[0] = ($event) => unref(settings).data.settings.txt2img.steps = $event), - min: 5, - max: 300, - style: { "margin-right": "12px" } - }, null, 8, ["value"]), - createVNode(unref(NInputNumber), { - value: unref(settings).data.settings.txt2img.steps, - "onUpdate:value": _cache[1] || (_cache[1] = ($event) => unref(settings).data.settings.txt2img.steps = $event), - size: "small", - style: { "min-width": "96px", "width": "96px" } - }, null, 8, ["value"]) - ]), - createBaseVNode("div", _hoisted_5, [ - createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { - trigger: withCtx(() => [ - _hoisted_6 - ]), - default: withCtx(() => [ - createTextVNode(' Guidance scale indicates how much should model stay close to the prompt. Higher values might be exactly what you want, but generated images might have some artefacts. Lower values indicates that model can "dream" about this prompt more. '), - _hoisted_7 - ]), - _: 1 - }), - createVNode(unref(NSlider), { - value: unref(settings).data.settings.txt2img.cfg_scale, - "onUpdate:value": _cache[2] || (_cache[2] = ($event) => unref(settings).data.settings.txt2img.cfg_scale = $event), - min: 1, - max: 30, - step: 0.5, - style: { "margin-right": "12px" } - }, null, 8, ["value"]), - createVNode(unref(NInputNumber), { - value: unref(settings).data.settings.txt2img.cfg_scale, - "onUpdate:value": _cache[3] || (_cache[3] = ($event) => unref(settings).data.settings.txt2img.cfg_scale = $event), - size: "small", - style: { "min-width": "96px", "width": "96px" }, - step: 0.5 - }, null, 8, ["value"]) - ]), - Number.isInteger(unref(settings).data.settings.txt2img.sampler) && ((_b = unref(settings).data.settings.model) == null ? void 0 : _b.backend) === "PyTorch" ? (openBlock(), createElementBlock("div", _hoisted_8, [ - createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { - trigger: withCtx(() => [ - _hoisted_9 - ]), - default: withCtx(() => [ - createTextVNode(" If self attention is >0, SAG will guide the model and improve the quality of the image at the cost of speed. Higher values will follow the guidance more closely, which can lead to better, more sharp and detailed outputs. ") - ]), - _: 1 - }), - createVNode(unref(NSlider), { - value: unref(settings).data.settings.txt2img.self_attention_scale, - "onUpdate:value": _cache[4] || (_cache[4] = ($event) => unref(settings).data.settings.txt2img.self_attention_scale = $event), - min: 0, - max: 1, - step: 0.05, - style: { "margin-right": "12px" } - }, null, 8, ["value"]), - createVNode(unref(NInputNumber), { - value: unref(settings).data.settings.txt2img.self_attention_scale, - "onUpdate:value": _cache[5] || (_cache[5] = ($event) => unref(settings).data.settings.txt2img.self_attention_scale = $event), - size: "small", - style: { "min-width": "96px", "width": "96px" }, - step: 0.05 - }, null, 8, ["value"]) - ])) : createCommentVNode("", true), - createBaseVNode("div", _hoisted_10, [ - createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { - trigger: withCtx(() => [ - _hoisted_11 - ]), - default: withCtx(() => [ - createTextVNode(" Number of images to generate after each other. ") - ]), - _: 1 - }), - createVNode(unref(NSlider), { - value: unref(settings).data.settings.txt2img.batch_count, - "onUpdate:value": _cache[6] || (_cache[6] = ($event) => unref(settings).data.settings.txt2img.batch_count = $event), - min: 1, - max: 9, - style: { "margin-right": "12px" } - }, null, 8, ["value"]), - createVNode(unref(NInputNumber), { - value: unref(settings).data.settings.txt2img.batch_count, - "onUpdate:value": _cache[7] || (_cache[7] = ($event) => unref(settings).data.settings.txt2img.batch_count = $event), - size: "small", - style: { "min-width": "96px", "width": "96px" } - }, null, 8, ["value"]) - ]), - createVNode(unref(_sfc_main$7), { - "batch-size-object": unref(settings).data.settings.txt2img - }, null, 8, ["batch-size-object"]), - createBaseVNode("div", _hoisted_12, [ - createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { - trigger: withCtx(() => [ - _hoisted_13 - ]), - default: withCtx(() => [ - createTextVNode(" Seed is a number that represents the starting canvas of your image. If you want to create the same image as your friend, you can use the same settings and seed to do so. "), - _hoisted_14 - ]), - _: 1 - }), - createVNode(unref(NInputNumber), { - value: unref(settings).data.settings.txt2img.seed, - "onUpdate:value": _cache[8] || (_cache[8] = ($event) => unref(settings).data.settings.txt2img.seed = $event), - size: "small", - style: { "flex-grow": "1" } - }, null, 8, ["value"]) - ]) - ]; - }), - _: 1 - }) - ]), - _: 1 - }), - isSelectedModelSDXL.value ? (openBlock(), createBlock(unref(_sfc_main$2), { - key: 0, - style: { "margin-top": "12px", "margin-bottom": "12px" } - })) : createCommentVNode("", true), - !isSelectedModelSDXL.value ? (openBlock(), createBlock(unref(_sfc_main$4), { - key: 1, - style: { "margin-top": "12px", "margin-bottom": "12px" } - })) : createCommentVNode("", true) - ]), + default: withCtx(() => { + var _a; + return [ + createVNode(unref(NCard), { title: "Settings" }, { + default: withCtx(() => [ + createVNode(unref(NSpace), { + vertical: "", + class: "left-container" + }, { + default: withCtx(() => { + var _a2; + return [ + createVNode(unref(Prompt), { tab: "txt2img" }), + createVNode(unref(_sfc_main$5), { type: "txt2img" }), + createVNode(unref(_sfc_main$6), { + "dimensions-object": unref(settings).data.settings.txt2img + }, null, 8, ["dimensions-object"]), + createBaseVNode("div", _hoisted_2, [ + createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { + trigger: withCtx(() => [ + _hoisted_3 + ]), + default: withCtx(() => [ + createTextVNode(" Number of steps to take in the diffusion process. Higher values will result in more detailed images but will take longer to generate. There is also a point of diminishing returns around 100 steps. "), + _hoisted_4 + ]), + _: 1 + }), + createVNode(unref(NSlider), { + value: unref(settings).data.settings.txt2img.steps, + "onUpdate:value": _cache[0] || (_cache[0] = ($event) => unref(settings).data.settings.txt2img.steps = $event), + min: 5, + max: 300, + style: { "margin-right": "12px" } + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: unref(settings).data.settings.txt2img.steps, + "onUpdate:value": _cache[1] || (_cache[1] = ($event) => unref(settings).data.settings.txt2img.steps = $event), + size: "small", + style: { "min-width": "96px", "width": "96px" } + }, null, 8, ["value"]) + ]), + createBaseVNode("div", _hoisted_5, [ + createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { + trigger: withCtx(() => [ + _hoisted_6 + ]), + default: withCtx(() => [ + createTextVNode(' Guidance scale indicates how much should model stay close to the prompt. Higher values might be exactly what you want, but generated images might have some artefacts. Lower values indicates that model can "dream" about this prompt more. '), + _hoisted_7 + ]), + _: 1 + }), + createVNode(unref(NSlider), { + value: unref(settings).data.settings.txt2img.cfg_scale, + "onUpdate:value": _cache[2] || (_cache[2] = ($event) => unref(settings).data.settings.txt2img.cfg_scale = $event), + min: 1, + max: 30, + step: 0.5, + style: { "margin-right": "12px" } + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: unref(settings).data.settings.txt2img.cfg_scale, + "onUpdate:value": _cache[3] || (_cache[3] = ($event) => unref(settings).data.settings.txt2img.cfg_scale = $event), + size: "small", + style: { "min-width": "96px", "width": "96px" }, + step: 0.5 + }, null, 8, ["value"]) + ]), + Number.isInteger(unref(settings).data.settings.txt2img.sampler) && ((_a2 = unref(settings).data.settings.model) == null ? void 0 : _a2.backend) === "PyTorch" ? (openBlock(), createElementBlock("div", _hoisted_8, [ + createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { + trigger: withCtx(() => [ + _hoisted_9 + ]), + default: withCtx(() => [ + createTextVNode(" If self attention is >0, SAG will guide the model and improve the quality of the image at the cost of speed. Higher values will follow the guidance more closely, which can lead to better, more sharp and detailed outputs. ") + ]), + _: 1 + }), + createVNode(unref(NSlider), { + value: unref(settings).data.settings.txt2img.self_attention_scale, + "onUpdate:value": _cache[4] || (_cache[4] = ($event) => unref(settings).data.settings.txt2img.self_attention_scale = $event), + min: 0, + max: 1, + step: 0.05, + style: { "margin-right": "12px" } + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: unref(settings).data.settings.txt2img.self_attention_scale, + "onUpdate:value": _cache[5] || (_cache[5] = ($event) => unref(settings).data.settings.txt2img.self_attention_scale = $event), + size: "small", + style: { "min-width": "96px", "width": "96px" }, + step: 0.05 + }, null, 8, ["value"]) + ])) : createCommentVNode("", true), + createBaseVNode("div", _hoisted_10, [ + createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { + trigger: withCtx(() => [ + _hoisted_11 + ]), + default: withCtx(() => [ + createTextVNode(" Number of images to generate after each other. ") + ]), + _: 1 + }), + createVNode(unref(NSlider), { + value: unref(settings).data.settings.txt2img.batch_count, + "onUpdate:value": _cache[6] || (_cache[6] = ($event) => unref(settings).data.settings.txt2img.batch_count = $event), + min: 1, + max: 9, + style: { "margin-right": "12px" } + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: unref(settings).data.settings.txt2img.batch_count, + "onUpdate:value": _cache[7] || (_cache[7] = ($event) => unref(settings).data.settings.txt2img.batch_count = $event), + size: "small", + style: { "min-width": "96px", "width": "96px" } + }, null, 8, ["value"]) + ]), + createVNode(unref(_sfc_main$7), { + "batch-size-object": unref(settings).data.settings.txt2img + }, null, 8, ["batch-size-object"]), + createBaseVNode("div", _hoisted_12, [ + createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { + trigger: withCtx(() => [ + _hoisted_13 + ]), + default: withCtx(() => [ + createTextVNode(" Seed is a number that represents the starting canvas of your image. If you want to create the same image as your friend, you can use the same settings and seed to do so. "), + _hoisted_14 + ]), + _: 1 + }), + createVNode(unref(NInputNumber), { + value: unref(settings).data.settings.txt2img.seed, + "onUpdate:value": _cache[8] || (_cache[8] = ($event) => unref(settings).data.settings.txt2img.seed = $event), + size: "small", + style: { "flex-grow": "1" } + }, null, 8, ["value"]) + ]) + ]; + }), + _: 1 + }) + ]), + _: 1 + }), + ((_a = unref(settings).data.settings.model) == null ? void 0 : _a.type) === "SDXL" ? (openBlock(), createBlock(unref(_sfc_main$3), { + key: 0, + "dimensions-object": unref(settings).data.settings.txt2img + }, null, 8, ["dimensions-object"])) : createCommentVNode("", true), + isSelectedModelSDXL.value ? (openBlock(), createBlock(unref(_sfc_main$2), { key: 1 })) : createCommentVNode("", true), + !isSelectedModelSDXL.value ? (openBlock(), createBlock(unref(_sfc_main$4), { key: 2 })) : createCommentVNode("", true) + ]; + }), _: 1 }), createVNode(unref(NGi), null, { diff --git a/frontend/dist/assets/TrashBin.js b/frontend/dist/assets/TrashBin.js index 595b067af..8f894ef91 100644 --- a/frontend/dist/assets/TrashBin.js +++ b/frontend/dist/assets/TrashBin.js @@ -1,4 +1,4 @@ -import { O as replaceable, z as h, d as defineComponent, bL as isBrowser, T as useTheme, P as createInjectionKey, aa as c, Q as cB, bM as fadeInTransition, aS as fadeInScaleUpTransition, ac as cNotM, X as toRef, bN as imageLight, r as ref, ad as useLocale, K as watch, aD as on, aC as off, aB as onBeforeUnmount, R as inject, c as computed, S as useConfig, Y as useThemeClass, bO as isMounted, bP as LazyTeleport, br as withDirectives, bQ as zindexable, aX as Transition, F as Fragment, aj as NBaseIcon, bs as vShow, ba as normalizeStyle, bR as kebabCase, l as NTooltip, aR as beforeNextFrameOnce, aW as createId, a3 as provide, bC as getCurrentInstance, b9 as onMounted, af as watchEffect, o as openBlock, j as createElementBlock, f as createBaseVNode } from "./index.js"; +import { O as replaceable, y as h, d as defineComponent, bL as isBrowser, T as useTheme, P as createInjectionKey, aa as c, Q as cB, bM as fadeInTransition, aS as fadeInScaleUpTransition, ac as cNotM, X as toRef, bN as imageLight, z as ref, ad as useLocale, K as watch, aD as on, aC as off, aB as onBeforeUnmount, R as inject, c as computed, S as useConfig, Y as useThemeClass, bO as isMounted, bP as LazyTeleport, br as withDirectives, bQ as zindexable, aX as Transition, F as Fragment, aj as NBaseIcon, bs as vShow, ba as normalizeStyle, bR as kebabCase, l as NTooltip, aR as beforeNextFrameOnce, aW as createId, a3 as provide, bC as getCurrentInstance, b9 as onMounted, af as watchEffect, o as openBlock, j as createElementBlock, f as createBaseVNode } from "./index.js"; const RotateClockwiseIcon = replaceable("rotateClockwise", h( "svg", { viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, diff --git a/frontend/dist/assets/clock.js b/frontend/dist/assets/clock.js index 5b2000c5a..7deffb759 100644 --- a/frontend/dist/assets/clock.js +++ b/frontend/dist/assets/clock.js @@ -5,7 +5,7 @@ var __publicField = (obj, key, value) => { return value; }; import { N as NDescriptionsItem, a as NDescriptions } from "./DescriptionsItem.js"; -import { d as defineComponent, o as openBlock, j as createElementBlock, f as createBaseVNode, e as createBlock, w as withCtx, g as createVNode, h as unref, k as createTextVNode, C as toDisplayString, n as NCard, m as createCommentVNode, u as useSettings, l as NTooltip, F as Fragment, a as useState, c as computed, G as spaceRegex, B as NIcon, i as NSelect, H as promptHandleKeyUp, I as promptHandleKeyDown, J as NInput, _ as _export_sfc, K as watch, r as ref, v as serverUrl } from "./index.js"; +import { d as defineComponent, o as openBlock, j as createElementBlock, f as createBaseVNode, e as createBlock, w as withCtx, g as createVNode, h as unref, k as createTextVNode, C as toDisplayString, n as NCard, m as createCommentVNode, u as useSettings, l as NTooltip, F as Fragment, a as useState, c as computed, G as spaceRegex, B as NIcon, i as NSelect, H as promptHandleKeyUp, I as promptHandleKeyDown, J as NInput, _ as _export_sfc, K as watch, z as ref, t as serverUrl } from "./index.js"; import { a as NSlider, N as NSwitch } from "./Switch.js"; import { N as NInputNumber } from "./InputNumber.js"; import { N as NForm, a as NFormItem } from "./SamplerPicker.vue_vue_type_script_setup_true_lang.js"; diff --git a/frontend/dist/assets/index.css b/frontend/dist/assets/index.css index f16e74b41..46c43775d 100644 --- a/frontend/dist/assets/index.css +++ b/frontend/dist/assets/index.css @@ -26,6 +26,14 @@ color: #63e2b7; } +.generate-extra-card { + margin-top: 12px; +} + +.generate-extra-card:last-child { + margin-bottom: 12px; +} + .navbar { position: fixed; top: 0; diff --git a/frontend/dist/assets/index.js b/frontend/dist/assets/index.js index 264c43f65..338e96712 100644 --- a/frontend/dist/assets/index.js +++ b/frontend/dist/assets/index.js @@ -40551,6 +40551,7 @@ const useState2 = defineStore("state", () => { images: [], highres: false, refiner: false, + sdxl_resize: false, currentImage: "", genData: { time_taken: null, @@ -40681,7 +40682,10 @@ const defaultSettings = { model: null, flags: { sdxl: { - original_size: [1024, 1024] + original_size: { + width: 1024, + height: 1024 + } }, highres: { image_upscaler: "RealESRGAN_x4plus_anime_6B", @@ -43539,13 +43543,13 @@ export { openBlock as o, useMessage as p, onUnmounted as q, - ref as r, - NGi as s, - NGrid as t, + NGi as r, + NGrid as s, + serverUrl as t, useSettings as u, - serverUrl as v, + pushScopeId as v, withCtx as w, - pushScopeId as x, - popScopeId as y, - h as z + popScopeId as x, + h as y, + ref as z }; diff --git a/frontend/src/assets/2img.css b/frontend/src/assets/2img.css index 4fbcf468e..a6fc0dcef 100644 --- a/frontend/src/assets/2img.css +++ b/frontend/src/assets/2img.css @@ -25,3 +25,11 @@ .highlight { color: #63e2b7; } + +.generate-extra-card { + margin-top: 12px; +} + +.generate-extra-card:last-child { + margin-bottom: 12px; +} diff --git a/frontend/src/components/generate/HighResFix.vue b/frontend/src/components/generate/HighResFix.vue index d6963ee41..9a5fa785d 100644 --- a/frontend/src/components/generate/HighResFix.vue +++ b/frontend/src/components/generate/HighResFix.vue @@ -1,5 +1,5 @@ diff --git a/frontend/src/components/models/index.ts b/frontend/src/components/models/index.ts index 54946f188..f56a8412c 100644 --- a/frontend/src/components/models/index.ts +++ b/frontend/src/components/models/index.ts @@ -1,4 +1,5 @@ export { default as CivitAIDownload } from "./CivitAIDownload.vue"; +export { default as CivitAIModelImage } from "./CivitAIModelImage.vue"; export { default as HuggingfaceDownload } from "./HuggingfaceDownload.vue"; export { default as ModelConvert } from "./ModelConvert.vue"; export { default as ModelManager } from "./ModelManager.vue"; From 7b5713be58ab89e3cb6511f02b118e206eb4bc07 Mon Sep 17 00:00:00 2001 From: Stax124 Date: Fri, 1 Dec 2023 21:00:26 +0100 Subject: [PATCH 084/143] Fix CivitAI model image grouping --- frontend/dist/assets/ModelsView.js | 116 ++++++----------- frontend/dist/assets/index.css | 15 +-- frontend/dist/assets/index.js | 2 +- .../src/components/models/CivitAIDownload.vue | 122 +++++------------- .../components/models/CivitAIModelImage.vue | 6 +- 5 files changed, 79 insertions(+), 182 deletions(-) diff --git a/frontend/dist/assets/ModelsView.js b/frontend/dist/assets/ModelsView.js index b0f3bd9ef..050c90ad3 100644 --- a/frontend/dist/assets/ModelsView.js +++ b/frontend/dist/assets/ModelsView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, y as h, O as replaceable, P as createInjectionKey, Q as cB, R as inject, S as useConfig, T as useTheme, U as popselectLight, c as computed, V as createTreeMate, K as watch, W as nextTick, X as toRef, Y as useThemeClass, Z as NInternalSelectMenu, $ as createTmOptions, a0 as happensIn, a1 as call, a2 as keysOf, z as ref, a3 as provide, a4 as keep, a5 as createRefSetter, a6 as mergeEventHandlers, a7 as omit, a8 as NPopover, a9 as popoverBaseProps, aa as c, ab as cM, ac as cNotM, ad as useLocale, ae as useMergedState, af as watchEffect, ag as useRtl, ah as createKey, ai as resolveSlot, J as NInput, i as NSelect, F as Fragment, aj as NBaseIcon, ak as useAdjustedTo, al as paginationLight, am as useMergedClsPrefix, an as ellipsisLight, ao as onDeactivated, l as NTooltip, ap as mergeProps, aq as useStyle, ar as useFormItem, as as useMemo, at as cE, au as radioLight, av as resolveWrappedSlot, aw as flatten$1, ax as getSlot, ay as depx, az as formatLength, A as NButton, aA as NScrollbar, aB as onBeforeUnmount, aC as off, aD as on, aE as ChevronDownIcon, aF as NDropdown, aG as pxfy, aH as get, aI as NIconSwitchTransition, aJ as NBaseLoading, aK as ChevronRightIcon, q as onUnmounted, aL as VResizeObserver, aM as warn, aN as cssrAnchorMetaName, aO as VVirtualList, aP as NEmpty, aQ as repeat, aR as beforeNextFrameOnce, aS as fadeInScaleUpTransition, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, aW as createId, aX as Transition, aY as dataTableLight, aZ as loadingBarApiInjectionKey, a_ as throwError, a$ as AddIcon, b0 as NProgress, b1 as NFadeInExpandTransition, b2 as EyeIcon, b3 as fadeInHeightExpandTransition, b4 as Teleport, b5 as uploadLight, o as openBlock, j as createElementBlock, b6 as createStaticVNode, f as createBaseVNode, b7 as useCssVars, h as unref, u as useSettings, b8 as themeOverridesKey, b9 as reactive, ba as onMounted, g as createVNode, w as withCtx, B as NIcon, L as renderList, _ as _export_sfc, m as createCommentVNode, bb as normalizeStyle, k as createTextVNode, C as toDisplayString, bc as NText, e as createBlock, bd as withModifiers, a as useState, p as useMessage, be as huggingfaceModelsFile, n as NCard, t as serverUrl, v as pushScopeId, x as popScopeId, N as NSpace, bf as NModal, r as NGi, s as NGrid, bg as NDivider, bh as Backends, D as NTabPane, E as NTabs } from "./index.js"; +import { d as defineComponent, y as h, O as replaceable, P as createInjectionKey, Q as cB, R as inject, S as useConfig, T as useTheme, U as popselectLight, c as computed, V as createTreeMate, K as watch, W as nextTick, X as toRef, Y as useThemeClass, Z as NInternalSelectMenu, $ as createTmOptions, a0 as happensIn, a1 as call, a2 as keysOf, z as ref, a3 as provide, a4 as keep, a5 as createRefSetter, a6 as mergeEventHandlers, a7 as omit, a8 as NPopover, a9 as popoverBaseProps, aa as c, ab as cM, ac as cNotM, ad as useLocale, ae as useMergedState, af as watchEffect, ag as useRtl, ah as createKey, ai as resolveSlot, J as NInput, i as NSelect, F as Fragment, aj as NBaseIcon, ak as useAdjustedTo, al as paginationLight, am as useMergedClsPrefix, an as ellipsisLight, ao as onDeactivated, l as NTooltip, ap as mergeProps, aq as useStyle, ar as useFormItem, as as useMemo, at as cE, au as radioLight, av as resolveWrappedSlot, aw as flatten$1, ax as getSlot, ay as depx, az as formatLength, A as NButton, aA as NScrollbar, aB as onBeforeUnmount, aC as off, aD as on, aE as ChevronDownIcon, aF as NDropdown, aG as pxfy, aH as get, aI as NIconSwitchTransition, aJ as NBaseLoading, aK as ChevronRightIcon, q as onUnmounted, aL as VResizeObserver, aM as warn, aN as cssrAnchorMetaName, aO as VVirtualList, aP as NEmpty, aQ as repeat, aR as beforeNextFrameOnce, aS as fadeInScaleUpTransition, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, aW as createId, aX as Transition, aY as dataTableLight, aZ as loadingBarApiInjectionKey, a_ as throwError, a$ as AddIcon, b0 as NProgress, b1 as NFadeInExpandTransition, b2 as EyeIcon, b3 as fadeInHeightExpandTransition, b4 as Teleport, b5 as uploadLight, o as openBlock, j as createElementBlock, b6 as createStaticVNode, f as createBaseVNode, b7 as useCssVars, h as unref, b8 as themeOverridesKey, b9 as reactive, ba as onMounted, g as createVNode, w as withCtx, B as NIcon, L as renderList, _ as _export_sfc, u as useSettings, m as createCommentVNode, bb as normalizeStyle, k as createTextVNode, C as toDisplayString, bc as NText, e as createBlock, bd as withModifiers, a as useState, p as useMessage, be as huggingfaceModelsFile, n as NCard, t as serverUrl, v as pushScopeId, x as popScopeId, N as NSpace, bf as NModal, r as NGi, s as NGrid, bg as NDivider, bh as Backends, D as NTabPane, E as NTabs } from "./index.js"; import { _ as _sfc_main$6, n as nsfwIndex } from "./ModelPopup.vue_vue_type_script_setup_true_lang.js"; import { N as NCheckboxGroup, a as NCheckbox, S as Settings } from "./Settings.js"; import { N as NSwitch } from "./Switch.js"; @@ -6425,7 +6425,7 @@ const _hoisted_2$7 = /* @__PURE__ */ createBaseVNode( -1 /* HOISTED */ ); -const _hoisted_3$6 = /* @__PURE__ */ createBaseVNode( +const _hoisted_3$5 = /* @__PURE__ */ createBaseVNode( "path", { d: "M490.91 244.15l-74.8-71.56V64a16 16 0 0 0-16-16h-48a16 16 0 0 0-16 16v32l-57.92-55.38C272.77 35.14 264.71 32 256 32c-8.68 0-16.72 3.14-22.14 8.63l-212.7 203.5c-6.22 6-7 15.87-1.34 22.37A16 16 0 0 0 43 267.56L250.5 69.28a8 8 0 0 1 11.06 0l207.52 198.28a16 16 0 0 0 22.59-.44c6.14-6.36 5.63-16.86-.76-22.97z", @@ -6435,7 +6435,7 @@ const _hoisted_3$6 = /* @__PURE__ */ createBaseVNode( -1 /* HOISTED */ ); -const _hoisted_4$4 = [_hoisted_2$7, _hoisted_3$6]; +const _hoisted_4$4 = [_hoisted_2$7, _hoisted_3$5]; const Home = defineComponent({ name: "Home", render: function render2(_ctx, _cache) { @@ -6461,7 +6461,7 @@ const _hoisted_2$6 = /* @__PURE__ */ createBaseVNode( -1 /* HOISTED */ ); -const _hoisted_3$5 = /* @__PURE__ */ createBaseVNode( +const _hoisted_3$4 = /* @__PURE__ */ createBaseVNode( "path", { fill: "none", @@ -6489,7 +6489,7 @@ const _hoisted_4$3 = /* @__PURE__ */ createBaseVNode( -1 /* HOISTED */ ); -const _hoisted_5$1 = [_hoisted_2$6, _hoisted_3$5, _hoisted_4$3]; +const _hoisted_5$1 = [_hoisted_2$6, _hoisted_3$4, _hoisted_4$3]; const Menu = defineComponent({ name: "Menu", render: function render3(_ctx, _cache) { @@ -6514,7 +6514,7 @@ const _hoisted_2$5 = /* @__PURE__ */ createBaseVNode( -1 /* HOISTED */ ); -const _hoisted_3$4 = /* @__PURE__ */ createBaseVNode( +const _hoisted_3$3 = /* @__PURE__ */ createBaseVNode( "path", { fill: "none", @@ -6528,7 +6528,7 @@ const _hoisted_3$4 = /* @__PURE__ */ createBaseVNode( -1 /* HOISTED */ ); -const _hoisted_4$2 = [_hoisted_2$5, _hoisted_3$4]; +const _hoisted_4$2 = [_hoisted_2$5, _hoisted_3$3]; const SearchOutline = defineComponent({ name: "SearchOutline", render: function render4(_ctx, _cache) { @@ -6543,17 +6543,15 @@ const _hoisted_2$4 = { class: "main-container", style: { "margin": "12px", "margin-top": "8px" } }; -const _hoisted_3$3 = { class: "image-grid" }; const _sfc_main$5 = /* @__PURE__ */ defineComponent({ __name: "CivitAIDownload", setup(__props) { useCssVars((_ctx) => { var _a, _b; return { - "5ae1a71d": (_b = (_a = unref(theme)) == null ? void 0 : _a.Card) == null ? void 0 : _b.color + "3d50ed98": (_b = (_a = unref(theme)) == null ? void 0 : _a.Card) == null ? void 0 : _b.color }; }); - const settings = useSettings(); const theme = inject(themeOverridesKey); const loadingLock = ref(false); const currentPage = ref(1); @@ -6561,32 +6559,18 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({ const types = ref(""); const currentModel = ref(null); const showModal = ref(false); + const gridRef = ref(null); const scrollComponent = ref(null); const itemFilter = ref(""); - const gridColumnRefs = ref([]); - const currentColumn = ref(0); - const currentRowIndex = ref(0); + const currentIndex = ref(0); const loadingBar = useLoadingBar(); - function imgClick(column_index, item_index) { - currentRowIndex.value = item_index; - currentColumn.value = column_index; - const item = columns.value[column_index][item_index]; + function imgClick(item_index) { + const item = modelData[item_index]; + currentIndex.value = item_index; currentModel.value = item; showModal.value = true; } const modelData = reactive([]); - const columns = computed(() => { - const cols = []; - for (let i = 0; i < settings.data.settings.frontend.image_browser_columns; i++) { - cols.push([]); - } - for (let i = 0; i < modelData.length; i++) { - cols[i % settings.data.settings.frontend.image_browser_columns].push( - modelData[i] - ); - } - return cols; - }); async function refreshImages() { currentPage.value = 1; modelData.splice(0, modelData.length); @@ -6612,16 +6596,11 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({ return; } let minBox = 0; - for (const col of gridColumnRefs.value) { - const lastImg = col.childNodes.item( - col.childNodes.length - 2 - ); - const bottombbox = lastImg.getBoundingClientRect().bottom; - if (minBox === 0) { - minBox = bottombbox; - } else if (bottombbox < minBox) { - minBox = bottombbox; - } + const bottombbox = gridRef.value.getBoundingClientRect().bottom; + if (minBox === 0) { + minBox = bottombbox; + } else if (bottombbox < minBox) { + minBox = bottombbox; } if (minBox - 50 < window.innerHeight) { if (loadingLock.value) { @@ -6654,18 +6633,16 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({ } }; function moveImage(direction) { - const numColumns = settings.data.settings.frontend.image_browser_columns; + if (currentModel.value === null) { + return; + } if (direction === -1) { - if (currentColumn.value > 0) { - imgClick(currentColumn.value - 1, currentRowIndex.value); - } else { - imgClick(numColumns - 1, currentRowIndex.value - 1); + if (currentIndex.value > 0) { + imgClick(currentIndex.value - 1); } } else if (direction === 1) { - if (currentColumn.value < numColumns - 1) { - imgClick(currentColumn.value + 1, currentRowIndex.value); - } else { - imgClick(0, currentRowIndex.value + 1); + if (currentIndex.value < modelData.length - 1) { + imgClick(currentIndex.value + 1); } } } @@ -6777,38 +6754,31 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({ ref_key: "scrollComponent", ref: scrollComponent }, [ - createBaseVNode("div", _hoisted_3$3, [ - (openBlock(true), createElementBlock(Fragment, null, renderList(columns.value, (column, column_index) => { + createBaseVNode("div", { + class: "image-grid", + ref_key: "gridRef", + ref: gridRef + }, [ + (openBlock(true), createElementBlock(Fragment, null, renderList(modelData, (item, item_index) => { return openBlock(), createElementBlock("div", { - key: column_index, - class: "image-column", - ref_for: true, - ref_key: "gridColumnRefs", - ref: gridColumnRefs + key: item_index, + style: { "border-radius": "20px", "position": "relative", "border": "1px solid #505050", "overflow": "hidden", "margin-bottom": "8px" } }, [ - (openBlock(true), createElementBlock(Fragment, null, renderList(column, (item, item_index) => { - return openBlock(), createElementBlock("div", { - key: item_index, - style: { "border-radius": "20px", "position": "relative", "border": "1px solid #505050", "overflow": "hidden", "margin-bottom": "8px" } - }, [ - createVNode(unref(_sfc_main$4), { - item, - column_index, - item_index, - onImgClick: imgClick - }, null, 8, ["item", "column_index", "item_index"]) - ]); - }), 128)) + createVNode(unref(_sfc_main$4), { + item, + item_index, + onImgClick: imgClick + }, null, 8, ["item", "item_index"]) ]); }), 128)) - ]) + ], 512) ], 512) ]) ], 64); }; } }); -const CivitAIDownload = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-aac1a1fc"]]); +const CivitAIDownload = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-241a4664"]]); const _hoisted_1$3 = ["src"]; const _hoisted_2$3 = { style: { "position": "absolute", "width": "100%", "bottom": "0", "padding": "0 8px 0 12px", "min-height": "32px", "overflow": "hidden", "box-sizing": "border-box", "backdrop-filter": "blur(12px)", "background-color": "rgba(0, 0, 0, 0.3)" } }; const _sfc_main$4 = /* @__PURE__ */ defineComponent({ @@ -6818,10 +6788,6 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({ type: Object, required: true }, - column_index: { - type: Number, - required: true - }, item_index: { type: Number, required: true @@ -6836,7 +6802,7 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({ var _a; return openBlock(), createElementBlock("div", { style: { "height": "500px", "cursor": "pointer" }, - onClick: _cache[1] || (_cache[1] = ($event) => emit("imgClick", props.column_index, props.item_index)) + onClick: _cache[1] || (_cache[1] = ($event) => emit("imgClick", props.item_index)) }, [ createBaseVNode("div", { style: normalizeStyle({ diff --git a/frontend/dist/assets/index.css b/frontend/dist/assets/index.css index 96d4129e0..89024e3b7 100644 --- a/frontend/dist/assets/index.css +++ b/frontend/dist/assets/index.css @@ -170,22 +170,13 @@ justify-content: center; } -.img-slider[data-v-aac1a1fc] { - aspect-ratio: 1/1; - height: 182px; - width: auto; -} -.image-grid[data-v-aac1a1fc] { +.image-grid[data-v-241a4664] { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); grid-gap: 8px; } -.top-bar[data-v-aac1a1fc] { - background-color: var(--5ae1a71d); -} -.image-column[data-v-aac1a1fc] { - display: flex; - flex-direction: column; +.top-bar[data-v-241a4664] { + background-color: var(--3d50ed98); } .install[data-v-b405f046] { diff --git a/frontend/dist/assets/index.js b/frontend/dist/assets/index.js index ab45cde91..212d1b142 100644 --- a/frontend/dist/assets/index.js +++ b/frontend/dist/assets/index.js @@ -43150,7 +43150,7 @@ const Upscale_vue_vue_type_style_index_0_scoped_5358ed01_lang = ""; const ControlNet_vue_vue_type_style_index_0_scoped_95a354be_lang = ""; const Img2Img_vue_vue_type_style_index_0_scoped_116492bf_lang = ""; const Inpainting_vue_vue_type_style_index_0_scoped_6961892e_lang = ""; -const CivitAIDownload_vue_vue_type_style_index_0_scoped_aac1a1fc_lang = ""; +const CivitAIDownload_vue_vue_type_style_index_0_scoped_241a4664_lang = ""; const HuggingfaceDownload_vue_vue_type_style_index_0_scoped_b405f046_lang = ""; const _hoisted_1$1 = { style: { "margin": "16px 0" } }; const _hoisted_2 = /* @__PURE__ */ createBaseVNode("b", null, "Key in question:", -1); diff --git a/frontend/src/components/models/CivitAIDownload.vue b/frontend/src/components/models/CivitAIDownload.vue index 50f139b32..71680ab82 100644 --- a/frontend/src/components/models/CivitAIDownload.vue +++ b/frontend/src/components/models/CivitAIDownload.vue @@ -77,31 +77,23 @@
-
+
-
- -
+
@@ -113,19 +105,9 @@ import { CivitAIModelImage, ModelPopup } from "@/components"; import { themeOverridesKey } from "@/injectionKeys"; import { SearchOutline } from "@vicons/ionicons5"; import { NButton, NIcon, NInput, NSelect, useLoadingBar } from "naive-ui"; -import { - computed, - inject, - onMounted, - onUnmounted, - reactive, - ref, - type Ref, -} from "vue"; +import { inject, onMounted, onUnmounted, reactive, ref, type Ref } from "vue"; import type { ICivitAIModel, ICivitAIModels } from "../../civitai"; -import { useSettings } from "../../store/settings"; -const settings = useSettings(); const theme = inject(themeOverridesKey); const loadingLock = ref(false); @@ -135,46 +117,26 @@ const types: Ref<"Checkpoint" | "TextualInversion" | "LORA" | ""> = ref(""); const currentModel = ref(null); const showModal = ref(false); +const gridRef = ref(null); const scrollComponent = ref(null); const itemFilter = ref(""); -const gridColumnRefs = ref([]); - -const currentColumn = ref(0); -const currentRowIndex = ref(0); +const currentIndex = ref(0); const loadingBar = useLoadingBar(); -function imgClick(column_index: number, item_index: number) { - currentRowIndex.value = item_index; - currentColumn.value = column_index; - const item = columns.value[column_index][item_index]; +function imgClick(item_index: number) { + const item = modelData[item_index]; + currentIndex.value = item_index; currentModel.value = item; showModal.value = true; } const modelData: ICivitAIModel[] = reactive([]); -const columns = computed(() => { - const cols: ICivitAIModel[][] = []; - for ( - let i = 0; - i < settings.data.settings.frontend.image_browser_columns; - i++ - ) { - cols.push([]); - } - for (let i = 0; i < modelData.length; i++) { - cols[i % settings.data.settings.frontend.image_browser_columns].push( - modelData[i] - ); - } - return cols; -}); - async function refreshImages() { // Clear the data currentPage.value = 1; @@ -212,16 +174,11 @@ const handleScroll = (e: Event) => { // Get the smallest possible value of the bottom of the images columns let minBox = 0; - for (const col of gridColumnRefs.value) { - const lastImg = col.childNodes.item( - col.childNodes.length - 2 - ) as HTMLElement; - const bottombbox = lastImg.getBoundingClientRect().bottom; - if (minBox === 0) { - minBox = bottombbox; - } else if (bottombbox < minBox) { - minBox = bottombbox; - } + const bottombbox = gridRef.value!.getBoundingClientRect().bottom; + if (minBox === 0) { + minBox = bottombbox; + } else if (bottombbox < minBox) { + minBox = bottombbox; } // Extend the image limit if the bottom of the images is less than 50px from the bottom of the screen @@ -263,21 +220,19 @@ const handleScroll = (e: Event) => { }; function moveImage(direction: number) { - const numColumns = settings.data.settings.frontend.image_browser_columns; + if (currentModel.value === null) { + return; + } if (direction === -1) { // Traverse all the columns before removing one from the currentIndexOfColumn - if (currentColumn.value > 0) { - imgClick(currentColumn.value - 1, currentRowIndex.value); - } else { - imgClick(numColumns - 1, currentRowIndex.value - 1); + if (currentIndex.value > 0) { + imgClick(currentIndex.value - 1); } } else if (direction === 1) { // Traverse all the columns before adding one from the currentIndexOfColumn - if (currentColumn.value < numColumns - 1) { - imgClick(currentColumn.value + 1, currentRowIndex.value); - } else { - imgClick(0, currentRowIndex.value + 1); + if (currentIndex.value < modelData.length - 1) { + imgClick(currentIndex.value + 1); } } } @@ -326,12 +281,6 @@ refreshImages(); diff --git a/frontend/src/components/models/CivitAIModelImage.vue b/frontend/src/components/models/CivitAIModelImage.vue index 4aebbc91f..934eaf454 100644 --- a/frontend/src/components/models/CivitAIModelImage.vue +++ b/frontend/src/components/models/CivitAIModelImage.vue @@ -1,7 +1,7 @@ From bdd599baf9ff8c0d10b6258d724d580a84dbc2ef Mon Sep 17 00:00:00 2001 From: gabe56f Date: Sat, 2 Dec 2023 19:35:37 +0100 Subject: [PATCH 086/143] More CODEOWNERS stuff --- .github/CODEOWNERS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 3172a9608..496f08f8a 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,13 +2,16 @@ # core is somewhat general * @Stax124 /core/ @Stax124 @gabe56f +/frontend/ @Stax124 @gabe56f # Stax-specific /core/* @Stax124 /core/inference/esrgan/ @Stax124 # Gabe-specific stuff +/libs/ @gabe56f /core/scheduling/ @gabe56f +/core/optimizations/ @gabe56f /core/inference/injectables/ @gabe56f /core/inference/utilities/kohya_hires.py @gabe56f /core/inference/utilities/anisotropic.py @gabe56f From c3e4cf2189da98512689a3377fb63c4aaf304581 Mon Sep 17 00:00:00 2001 From: Stax124 Date: Sun, 3 Dec 2023 13:40:49 +0100 Subject: [PATCH 087/143] Update Docker compose templates, yarn commands for docker --- .gitignore | 4 ++-- docker/ait-no-mount.docker-compose.yml | 29 ++++++++++++++++++++++ docker/ait.docker-compose.yml | 32 +++++++++++++++++++++++++ docker/ait/dockerfile | 25 +++++++++++++------ docker/cuda-no-mount.docker-compose.yml | 29 ++++++++++++++++++++++ docker/cuda.docker-compose.yml | 32 +++++++++++++++++++++++++ package.json | 9 +++---- 7 files changed, 147 insertions(+), 13 deletions(-) create mode 100644 docker/ait-no-mount.docker-compose.yml create mode 100644 docker/ait.docker-compose.yml create mode 100644 docker/cuda-no-mount.docker-compose.yml create mode 100644 docker/cuda.docker-compose.yml diff --git a/.gitignore b/.gitignore index a56685ed3..c9d9b40b5 100644 --- a/.gitignore +++ b/.gitignore @@ -52,8 +52,8 @@ traced_unet/ converted # Docker -test.docker-compose.yml -test-no-mount.docker-compose.yml +*test.docker-compose.yml +*test-no-mount.docker-compose.yml # Docs node_modules/ diff --git a/docker/ait-no-mount.docker-compose.yml b/docker/ait-no-mount.docker-compose.yml new file mode 100644 index 000000000..022e51513 --- /dev/null +++ b/docker/ait-no-mount.docker-compose.yml @@ -0,0 +1,29 @@ +version: "3.7" + +services: + voltaml: + image: stax124/volta:experimental-ait + environment: + # General + - HUGGINGFACE_TOKEN=${HUGGINGFACE_TOKEN:-} + - LOG_LEVEL=${LOG_LEVEL:-INFO} + - EXTRA_ARGS=${EXTRA_ARGS:-} + + # Extra api keys + - FASTAPI_ANALYTICS_KEY=${FASTAPI_ANALYTICS_KEY:-} + - DISCORD_BOT_TOKEN=${DISCORD_BOT_TOKEN:-} + + # R2 + - R2_ENDPOINT=${R2_ENDPOINT:-} + - R2_BUCKET_NAME=${R2_BUCKET_NAME:-} + - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-} + - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-} + - R2_DEV_ADDRESS=${R2_DEV_ADDRESS:-} + ports: + - "5003:5003" + deploy: + resources: + reservations: + devices: + - driver: nvidia + capabilities: ["gpu"] diff --git a/docker/ait.docker-compose.yml b/docker/ait.docker-compose.yml new file mode 100644 index 000000000..c8ccac7c0 --- /dev/null +++ b/docker/ait.docker-compose.yml @@ -0,0 +1,32 @@ +version: "3.7" + +services: + voltaml: + image: stax124/volta:experimental-ait + environment: + # General + - HUGGINGFACE_TOKEN=${HUGGINGFACE_TOKEN:-} + - LOG_LEVEL=${LOG_LEVEL:-INFO} + - EXTRA_ARGS=${EXTRA_ARGS:-} + + # Extra api keys + - FASTAPI_ANALYTICS_KEY=${FASTAPI_ANALYTICS_KEY:-} + - DISCORD_BOT_TOKEN=${DISCORD_BOT_TOKEN:-} + + # R2 + - R2_ENDPOINT=${R2_ENDPOINT:-} + - R2_BUCKET_NAME=${R2_BUCKET_NAME:-} + - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-} + - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-} + - R2_DEV_ADDRESS=${R2_DEV_ADDRESS:-} + volumes: + - ${HOME}/voltaML/data:/app/data # XXX is the path to the folder where all the outputs will be saved + - ${HOME}/.cache/huggingface:/root/.cache/huggingface # YYY is path to your home folder (you may need to change the YYY/.cache/huggingface to YYY\.cache\huggingface on Windows) + ports: + - "5003:5003" + deploy: + resources: + reservations: + devices: + - driver: nvidia + capabilities: ["gpu"] diff --git a/docker/ait/dockerfile b/docker/ait/dockerfile index bd42c1d43..09ff746ca 100644 --- a/docker/ait/dockerfile +++ b/docker/ait/dockerfile @@ -1,28 +1,39 @@ -FROM stax124/aitemplate:latest +FROM stax124/ait:torch2.1.1-cuda11.8-ubuntu22.04-devel ENV DEBIAN_FRONTEND=noninteractive +# Basic dependencies RUN apt update && apt install curl -y -RUN curl -sL https://deb.nodesource.com/setup_18.x | bash +RUN apt install time git -y +RUN apt install python3 python3-pip -y +RUN pip install --upgrade pip +RUN apt install -y ca-certificates curl gnupg +# Set up Node.js and Yarn +RUN mkdir -p /etc/apt/keyrings +RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +RUN echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list +RUN apt update RUN apt install nodejs -y - RUN npm i -g yarn -RUN apt install time git -y -RUN pip install --upgrade pip +# Set up working directory and copy requirement definitions WORKDIR /app - COPY requirements /app/requirements +# PyTorch goes first to avoid redownloads +RUN --mount=type=cache,mode=0755,target=/root/.cache/pip pip install torch torchvision torchaudio + +# Other Python dependencies +RUN --mount=type=cache,mode=0755,target=/root/.cache/pip pip install python-dotenv requests RUN --mount=type=cache,mode=0755,target=/root/.cache/pip pip install -r requirements/api.txt RUN --mount=type=cache,mode=0755,target=/root/.cache/pip pip install -r requirements/bot.txt RUN --mount=type=cache,mode=0755,target=/root/.cache/pip pip install -r requirements/pytorch.txt RUN --mount=type=cache,mode=0755,target=/root/.cache/pip pip install -r requirements/interrogation.txt -RUN --mount=type=cache,mode=0755,target=/root/.cache/pip pip install python-dotenv COPY . /app +# Install frontend dependencies and build the frontend RUN --mount=type=cache,mode=0755,target=/app/frontend/node_modules cd frontend && yarn install && yarn build RUN rm -rf frontend/node_modules diff --git a/docker/cuda-no-mount.docker-compose.yml b/docker/cuda-no-mount.docker-compose.yml new file mode 100644 index 000000000..fe8aa9753 --- /dev/null +++ b/docker/cuda-no-mount.docker-compose.yml @@ -0,0 +1,29 @@ +version: "3.7" + +services: + voltaml: + image: stax124/volta:experimental-cuda + environment: + # General + - HUGGINGFACE_TOKEN=${HUGGINGFACE_TOKEN:-} + - LOG_LEVEL=${LOG_LEVEL:-INFO} + - EXTRA_ARGS=${EXTRA_ARGS:-} + + # Extra api keys + - FASTAPI_ANALYTICS_KEY=${FASTAPI_ANALYTICS_KEY:-} + - DISCORD_BOT_TOKEN=${DISCORD_BOT_TOKEN:-} + + # R2 + - R2_ENDPOINT=${R2_ENDPOINT:-} + - R2_BUCKET_NAME=${R2_BUCKET_NAME:-} + - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-} + - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-} + - R2_DEV_ADDRESS=${R2_DEV_ADDRESS:-} + ports: + - "5003:5003" + deploy: + resources: + reservations: + devices: + - driver: nvidia + capabilities: ["gpu"] diff --git a/docker/cuda.docker-compose.yml b/docker/cuda.docker-compose.yml new file mode 100644 index 000000000..f71744385 --- /dev/null +++ b/docker/cuda.docker-compose.yml @@ -0,0 +1,32 @@ +version: "3.7" + +services: + voltaml: + image: stax124/volta:experimental-cuda + environment: + # General + - HUGGINGFACE_TOKEN=${HUGGINGFACE_TOKEN:-} + - LOG_LEVEL=${LOG_LEVEL:-INFO} + - EXTRA_ARGS=${EXTRA_ARGS:-} + + # Extra api keys + - FASTAPI_ANALYTICS_KEY=${FASTAPI_ANALYTICS_KEY:-} + - DISCORD_BOT_TOKEN=${DISCORD_BOT_TOKEN:-} + + # R2 + - R2_ENDPOINT=${R2_ENDPOINT:-} + - R2_BUCKET_NAME=${R2_BUCKET_NAME:-} + - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-} + - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-} + - R2_DEV_ADDRESS=${R2_DEV_ADDRESS:-} + volumes: + - ${HOME}/voltaML/data:/app/data # XXX is the path to the folder where all the outputs will be saved + - ${HOME}/.cache/huggingface:/root/.cache/huggingface # YYY is path to your home folder (you may need to change the YYY/.cache/huggingface to YYY\.cache\huggingface on Windows) + ports: + - "5003:5003" + deploy: + resources: + reservations: + devices: + - driver: nvidia + capabilities: ["gpu"] diff --git a/package.json b/package.json index b64865a4e..ad175ba9a 100644 --- a/package.json +++ b/package.json @@ -33,10 +33,11 @@ "docker:build-ait": "docker build -t volta:ait -f docker/ait/dockerfile . && docker tag volta:ait stax124/volta:experimental-ait && docker rmi $(docker images --filter \"dangling=true\" -q --no-trunc)", "docker:build-cuda": "docker build -t volta:cuda -f docker/cuda/dockerfile . && docker tag volta:cuda stax124/volta:experimental-cuda && docker tag volta:cuda stax124/volta:experimental && docker rmi $(docker images --filter \"dangling=true\" -q --no-trunc)", "docker:clean": "docker rm $(docker ps -aq) -f && docker rmi $(docker images --filter \"dangling=true\" -q --no-trunc)", - "docker:test-compose": "docker compose -f docker/test.docker-compose.yml up --force-recreate --remove-orphans", - "docker:test-compose-no-mount": "docker compose -f docker/test-no-mount.docker-compose.yml up --force-recreate --remove-orphans", + "docker:cuda": "docker compose -f docker/cuda.docker-compose.yml up --force-recreate --remove-orphans", + "docker:ait": "docker compose -f docker/ait.docker-compose.yml up --force-recreate --remove-orphans", + "docker:cuda-no-mount": "docker compose -f docker/cuda-no-mount.docker-compose.yml up --force-recreate --remove-orphans", + "docker:ait-no-mount": "docker compose -f docker/ait-no-mount.docker-compose.yml up --force-recreate --remove-orphans", "docker:run": "docker compose run --service-ports --rm voltaml", "docker:push": "docker push stax124/volta:experimental" - }, - "dependencies": {} + } } \ No newline at end of file From 707065ee8016576c93d17e8b295929ccef5fa48b Mon Sep 17 00:00:00 2001 From: Stax124 Date: Sun, 3 Dec 2023 15:03:17 +0100 Subject: [PATCH 088/143] Try to fix Intel Arc install issues, fix types --- core/inference/functions.py | 2 +- core/inference/onnx/pipeline.py | 2 +- core/inference/sdxl/pipeline.py | 8 ++++---- core/inference/utilities/prompt_expansion/expand.py | 2 +- core/inference/utilities/vae.py | 2 +- core/install_requirements.py | 10 +++++----- core/interrogation/flamingo.py | 2 +- core/optimizations/dtype.py | 6 +++++- core/optimizations/pytorch_optimizations.py | 7 +++++-- core/scheduling/adapter/unipc_adapter.py | 2 +- core/scheduling/denoiser.py | 2 +- 11 files changed, 26 insertions(+), 19 deletions(-) diff --git a/core/inference/functions.py b/core/inference/functions.py index b30ad33f3..50779e646 100644 --- a/core/inference/functions.py +++ b/core/inference/functions.py @@ -663,7 +663,7 @@ def convert_vaept_to_diffusers(path: str) -> AutoencoderKL: from safetensors import safe_open checkpoint = {} - with safe_open(path, framework="pt", device="cpu") as f: + with safe_open(path, framework="pt", device="cpu") as f: # type: ignore # weird import structure, seems to be replaced at runtime in the lib for key in f.keys(): checkpoint[key] = f.get_tensor(key) else: diff --git a/core/inference/onnx/pipeline.py b/core/inference/onnx/pipeline.py index 2de12096a..00e2173b3 100644 --- a/core/inference/onnx/pipeline.py +++ b/core/inference/onnx/pipeline.py @@ -609,7 +609,7 @@ def convert_text_encoder( main_folder / "text_encoder" ) assert isinstance(text_encoder, CLIPTextModelWrapper) - text_encoder.to(dtype=dtype, device=device) + text_encoder.to(dtype=dtype, device=device) # type: ignore text_encoder.eval() num_tokens = text_encoder.config.max_position_embeddings diff --git a/core/inference/sdxl/pipeline.py b/core/inference/sdxl/pipeline.py index dff185c66..3aa033bde 100644 --- a/core/inference/sdxl/pipeline.py +++ b/core/inference/sdxl/pipeline.py @@ -680,19 +680,19 @@ def _call(*args, **kwargs): return None # 9. Post-processing - image = full_vae(latents, self.vae, height=height, width=width) # type: ignore + converted_image = full_vae(latents, self.vae, height=height, width=width) # type: ignore # 11. Convert to PIL if output_type == "pil": - image = numpy_to_pil(image) + converted_image = numpy_to_pil(converted_image) unload_all() if not return_dict: - return image, False + return converted_image, False return StableDiffusionPipelineOutput( - images=image, nsfw_content_detected=False # type: ignore + images=converted_image, nsfw_content_detected=False # type: ignore ) def text2img( diff --git a/core/inference/utilities/prompt_expansion/expand.py b/core/inference/utilities/prompt_expansion/expand.py index a55177dc1..7416ef0f9 100644 --- a/core/inference/utilities/prompt_expansion/expand.py +++ b/core/inference/utilities/prompt_expansion/expand.py @@ -128,7 +128,7 @@ def _load(prompt_to_prompt_model, prompt_to_prompt_device): _GPT.eval() device, dtype = _device_dtype(prompt_to_prompt_device) - _GPT = _GPT.to(device=device, dtype=dtype) + _GPT = _GPT.to(device=device, dtype=dtype) # type: ignore @torch.inference_mode() diff --git a/core/inference/utilities/vae.py b/core/inference/utilities/vae.py index b232fcd22..6e7d1093a 100644 --- a/core/inference/utilities/vae.py +++ b/core/inference/utilities/vae.py @@ -14,7 +14,7 @@ def taesd( samples: torch.Tensor, height: Optional[int] = None, width: Optional[int] = None -) -> torch.Tensor: +) -> np.ndarray: global taesd_model if taesd_model is None: diff --git a/core/install_requirements.py b/core/install_requirements.py index 169b242f1..4763e5c51 100644 --- a/core/install_requirements.py +++ b/core/install_requirements.py @@ -160,11 +160,11 @@ class PytorchDistribution: "-m", "pip", "install", - "torch==2.0.1a0", - "torchvision==0.15.2a0", - "intel_extension_for_pytorch==2.0.110+xpu", - "-f", - "https://developer.intel.com/ipex-whl-stable-xpu", + "torch==2.0.0a0+gitc6a572f", + "torchvision==0.14.1a0+5e8e2f1", + "intel-extension-for-pytorch==2.0.110+gitba7f6c1", + "--extra-index-url", + "https://pytorch-extension.intel.com/release-whl/stable/xpu/us/", ], ), PytorchDistribution( diff --git a/core/interrogation/flamingo.py b/core/interrogation/flamingo.py index 1b0bf0f70..7fc1f2749 100644 --- a/core/interrogation/flamingo.py +++ b/core/interrogation/flamingo.py @@ -25,7 +25,7 @@ def load(self): model = FlamingoModel.from_pretrained(config.interrogator.flamingo_model) assert isinstance(model, FlamingoModel) self.model = model - self.model.to(self.device, dtype=self.dtype) + self.model.to(self.device, dtype=self.dtype) # type: ignore self.model.eval() self.processor = FlamingoProcessor(self.model.config) diff --git a/core/optimizations/dtype.py b/core/optimizations/dtype.py index 280797362..ea68dd19c 100644 --- a/core/optimizations/dtype.py +++ b/core/optimizations/dtype.py @@ -1,9 +1,13 @@ import logging +from typing import Union import torch from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion import ( StableDiffusionPipeline, ) +from diffusers.pipelines.stable_diffusion_xl.pipeline_stable_diffusion_xl import ( + StableDiffusionXLPipeline, +) from core.config import config @@ -16,7 +20,7 @@ def cast( - pipe: StableDiffusionPipeline, + pipe: Union[StableDiffusionPipeline, StableDiffusionXLPipeline], device: str, dtype: torch.dtype, offload: bool, diff --git a/core/optimizations/pytorch_optimizations.py b/core/optimizations/pytorch_optimizations.py index 85a90e384..fe5ab3a01 100644 --- a/core/optimizations/pytorch_optimizations.py +++ b/core/optimizations/pytorch_optimizations.py @@ -1,11 +1,14 @@ import logging -from typing import Optional, Tuple +from typing import Optional, Tuple, Union import torch from diffusers.pipelines.pipeline_utils import DiffusionPipeline from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion import ( StableDiffusionPipeline, ) +from diffusers.pipelines.stable_diffusion_xl.pipeline_stable_diffusion_xl import ( + StableDiffusionXLPipeline, +) from core.config import config @@ -22,7 +25,7 @@ def optimize_model( - pipe: StableDiffusionPipeline, + pipe: Union[StableDiffusionPipeline, StableDiffusionXLPipeline], device, is_for_aitemplate: bool = False, ) -> None: diff --git a/core/scheduling/adapter/unipc_adapter.py b/core/scheduling/adapter/unipc_adapter.py index a5a521ee6..f9b6c8074 100644 --- a/core/scheduling/adapter/unipc_adapter.py +++ b/core/scheduling/adapter/unipc_adapter.py @@ -1,8 +1,8 @@ import functools from typing import Any, Callable, Optional, Union -from diffusers import UNet2DConditionModel import torch +from diffusers.models.unet_2d_condition import UNet2DConditionModel from core.inference.utilities.philox import PhiloxGenerator diff --git a/core/scheduling/denoiser.py b/core/scheduling/denoiser.py index d407baed6..b5ad46abd 100644 --- a/core/scheduling/denoiser.py +++ b/core/scheduling/denoiser.py @@ -1,5 +1,5 @@ -from diffusers import UNet2DConditionModel import torch +from diffusers.models.unet_2d_condition import UNet2DConditionModel from k_diffusion.external import CompVisDenoiser, CompVisVDenoiser from .types import Denoiser From 960523cc20089bc36242c28a67f95a2a531b7c4b Mon Sep 17 00:00:00 2001 From: Stax124 Date: Sun, 3 Dec 2023 15:42:52 +0100 Subject: [PATCH 089/143] Fix dependencies for intel part 2 --- core/install_requirements.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/core/install_requirements.py b/core/install_requirements.py index 4763e5c51..4d123a308 100644 --- a/core/install_requirements.py +++ b/core/install_requirements.py @@ -167,6 +167,21 @@ class PytorchDistribution: "https://pytorch-extension.intel.com/release-whl/stable/xpu/us/", ], ), + PytorchDistribution( + windows_supported=True, + name="intel", + check_command=["test", "-f", '"/etc/OpenCL/vendors/intel.icd"'], + success_message="Intel check success, assuming user has an Intel (i)GPU", + install_command=[ + sys.executable, + "-m", + "pip", + "install", + "https://github.com/Nuullll/intel-extension-for-pytorch/releases/download/v2.0.110%2Bxpu-master%2Bdll-bundle/torch-2.0.0a0+gite9ebda2-cp310-cp310-win_amd64.whl", + "https://github.com/Nuullll/intel-extension-for-pytorch/releases/download/v2.0.110%2Bxpu-master%2Bdll-bundle/torchvision-0.15.2a0+fa99a53-cp310-cp310-win_amd64.whl", + "https://github.com/Nuullll/intel-extension-for-pytorch/releases/download/v2.0.110%2Bxpu-master%2Bdll-bundle/intel_extension_for_pytorch-2.0.110+gitc6ea20b-cp310-cp310-win_amd64.whl", + ], + ), PytorchDistribution( windows_supported=False, name="cpu", From e1b58093286e180d991440806f40c507635448e6 Mon Sep 17 00:00:00 2001 From: Stax124 Date: Sun, 3 Dec 2023 17:49:28 +0100 Subject: [PATCH 090/143] Fix Intel Arc install part 3 --- .vscode/launch.json | 20 +++++++++--------- core/install_requirements.py | 40 +++++++++++++++++++++++------------- pyrightconfig.json | 1 + 3 files changed, 37 insertions(+), 24 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 4f1708097..07b6e4776 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,12 +1,12 @@ { - "configurations": [ - { - "name": "VoltaML API Debug", - "type": "python", - "request": "launch", - "program": "main.py", - "args": ["--log-level=DEBUG"], - "justMyCode": false - } - ] + "configurations": [ + { + "name": "VoltaML API Debug", + "type": "python", + "request": "launch", + "program": "main.py", + "args": ["--log-level=DEBUG"], + "justMyCode": false + } + ] } diff --git a/core/install_requirements.py b/core/install_requirements.py index 4d123a308..ad9979efb 100644 --- a/core/install_requirements.py +++ b/core/install_requirements.py @@ -234,7 +234,7 @@ class PytorchDistribution: ] -def install_deps(force_distribution: int = -1): +def install_deps(force_distribution: Union[int, str] = -1): "Install necessary requirements for inference" # Install pytorch @@ -250,6 +250,7 @@ def install_deps(force_distribution: int = -1): x for x in _pytorch_distributions if x.name == force_distribution.lower() + and (x.windows_supported if platform.system() == "Windows" else True) ][0] logger.info("Installing PyTorch") if platform.system() == "Darwin": @@ -257,10 +258,22 @@ def install_deps(force_distribution: int = -1): [sys.executable, "-m", "pip", "install", "torch==2.1.0", "torchvision"] ) else: - for c in _pytorch_distributions: - if ( - (c.windows_supported if platform.system() == "Windows" else True) - and ( + if forced_distribution is not None: + # User forced a specific distribution + + logger.info(forced_distribution.success_message) + if isinstance(forced_distribution.install_command[0], list): + for cmd in forced_distribution.install_command: + subprocess.check_call(cmd) + else: + subprocess.check_call(forced_distribution.install_command) # type: ignore + else: + # Automatically detect pytorch distribution + + for c in _pytorch_distributions: + if ( + c.windows_supported if platform.system() == "Windows" else True + ) and ( ( subprocess.run( c.check_command, @@ -270,15 +283,14 @@ def install_deps(force_distribution: int = -1): ).returncode == 0 ) - ) - ) or c == forced_distribution: - logger.info(c.success_message) - if isinstance(c.install_command[0], list): - for cmd in c.install_command: - subprocess.check_call(cmd) - else: - subprocess.check_call(c.install_command) # type: ignore - break + ): + logger.info(c.success_message) + if isinstance(c.install_command[0], list): + for cmd in c.install_command: + subprocess.check_call(cmd) + else: + subprocess.check_call(c.install_command) # type: ignore + break # Install other requirements install_requirements("requirements/pytorch.txt") diff --git a/pyrightconfig.json b/pyrightconfig.json index e5a1cbaac..a7a8e8d4c 100644 --- a/pyrightconfig.json +++ b/pyrightconfig.json @@ -2,6 +2,7 @@ "exclude": [ "core/hijack/diffusers/", "venv/", + "venv-intel/", "core/submodules/", "typings/", "AITemplate" From ea65063c3f844d0af5bcd005efdfaa44e3b124f4 Mon Sep 17 00:00:00 2001 From: Stax124 Date: Sun, 3 Dec 2023 18:13:10 +0100 Subject: [PATCH 091/143] Fix get_capabilities for non-CUDA users --- core/gpu.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/gpu.py b/core/gpu.py index 649a2b496..f0a5fb5a6 100644 --- a/core/gpu.py +++ b/core/gpu.py @@ -101,10 +101,10 @@ def _get_capabilities(self) -> Capabilities: for device in [torch.device("cpu"), torch.device(config.api.device)]: support_map[device.type] = [] for dt in test_suite: - dtype = getattr(torch, dt) - a = torch.tensor([1.0], device=device, dtype=dtype) - b = torch.tensor([2.0], device=device, dtype=dtype) try: + dtype = getattr(torch, dt) + a = torch.tensor([1.0], device=device, dtype=dtype) + b = torch.tensor([2.0], device=device, dtype=dtype) torch.matmul(a, b) support_map[device.type].append(dt) except RuntimeError: From 39b078b417565c8c111847743ed18ba3f36805a9 Mon Sep 17 00:00:00 2001 From: Stax124 Date: Sun, 3 Dec 2023 19:04:51 +0100 Subject: [PATCH 092/143] Fix get_capabilities for Arc users pt2 --- core/gpu.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/gpu.py b/core/gpu.py index f0a5fb5a6..1cd2924b4 100644 --- a/core/gpu.py +++ b/core/gpu.py @@ -109,6 +109,8 @@ def _get_capabilities(self) -> Capabilities: support_map[device.type].append(dt) except RuntimeError: pass + except AssertionError: + pass for t, s in support_map.items(): if t == "cpu": cap.supported_precisions_cpu = ( From d6daeb56964261a67330454035d085f2ba5be7ea Mon Sep 17 00:00:00 2001 From: gabe56f Date: Wed, 6 Dec 2023 15:45:30 +0100 Subject: [PATCH 093/143] Experimental custom TI impl. --- .../injectables/textual_inversion.py | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 core/inference/injectables/textual_inversion.py diff --git a/core/inference/injectables/textual_inversion.py b/core/inference/injectables/textual_inversion.py new file mode 100644 index 000000000..e6976a3ca --- /dev/null +++ b/core/inference/injectables/textual_inversion.py @@ -0,0 +1,92 @@ +from copy import deepcopy + +from diffusers.loaders import ( + TextualInversionLoaderMixin, + load_textual_inversion_state_dicts, +) +import torch +from transformers import PreTrainedTokenizer, PreTrainedModel + + +def maybe_convert_prompt(prompt: str, tokenizer: PreTrainedTokenizer) -> str: + tokens = tokenizer.tokenize(prompt) + unique_tokens = set(tokens) + for token in unique_tokens: + if token in tokenizer.added_tokens_encoder: + replacement = token + i = 1 + while f"{token}_{i}" in tokenizer.added_tokens_encoder: + replacement += f" {token}_{i}" + i += 1 + prompt = prompt.replace(token, replacement) + return prompt + + +def unload(token: str, tokenizer: PreTrainedTokenizer, text_encoder: PreTrainedModel): + load_map = text_encoder.change_map if hasattr(text_encoder, "change_map") else [] + input_embedding: torch.Tensor = text_encoder.get_input_embeddings().weight + device, dtype = text_encoder.device, text_encoder.dtype + + if token in load_map: + token_id: int = tokenizer.convert_tokens_to_ids(token) # type: ignore + tokenizer.added_tokens_encoder.pop(token) + input_embedding.data = torch.cat( + (input_embedding.data[:token_id], input_embedding.data[token_id + 1 :]) + ) + text_encoder.resize_token_embeddings(len(tokenizer)) + load_map.remove(token) + + input_embedding.to(device, dtype) + setattr(text_encoder, "change_map", load_map) + + +def unload_all(tokenizer: PreTrainedTokenizer, text_encoder: PreTrainedModel): + load_map = text_encoder.change_map if hasattr(text_encoder, "change_map") else [] + input_embedding: torch.Tensor = text_encoder.get_input_embeddings().weight + device, dtype = text_encoder.device, text_encoder.dtype + + for token in deepcopy(load_map): + token_id: int = tokenizer.convert_tokens_to_ids(token) # type: ignore + tokenizer.added_tokens_encoder.pop(token) + input_embedding.data = torch.cat( + (input_embedding.data[:token_id], input_embedding.data[token_id + 1 :]) + ) + text_encoder.resize_token_embeddings(len(tokenizer)) + load_map.remove(token) + + input_embedding.to(device, dtype) + setattr(text_encoder, "change_map", load_map) + + +def load( + model: str, + token: str, + tokenizer: PreTrainedTokenizer, + text_encoder: PreTrainedModel, +): + state_dicts = load_textual_inversion_state_dicts(model) + + token, embeddings = TextualInversionLoaderMixin._retrieve_tokens_and_embeddings( + [token], state_dicts, tokenizer # type: ignore + ) + tokens, embeddings = TextualInversionLoaderMixin._retrieve_tokens_and_embeddings( + token, embeddings, tokenizer + ) + + device, dtype = text_encoder.device, text_encoder.dtype + + load_map = text_encoder.change_map if hasattr(text_encoder, "change_map") else [] + input_embedding: torch.Tensor = text_encoder.get_input_embeddings().weight + + def load(token, embedding): + tokenizer.add_tokens(token) + token_id = tokenizer.convert_tokens_to_ids(token) + input_embedding.data[token_id] = embedding + text_encoder.resize_token_embeddings(len(tokenizer)) + load_map.append(token) + + for _token, embedding in zip(tokens, embeddings): + load(_token, embedding) + + input_embedding.to(device, dtype) + setattr(text_encoder, "change_map", load_map) From c0a319f6db4c1714cfecc4515ece7e46aed3e66a Mon Sep 17 00:00:00 2001 From: Stax124 Date: Wed, 6 Dec 2023 17:33:46 +0100 Subject: [PATCH 094/143] Enable Upscale everywhere, prep for highres everywhere --- core/config/default_settings.py | 5 + core/flags.py | 15 +- core/gpu.py | 35 + frontend/dist/assets/404View.js | 2 +- frontend/dist/assets/AboutView.js | 2 +- frontend/dist/assets/AccelerateView.js | 2 +- frontend/dist/assets/CloudUpload.js | 2 +- frontend/dist/assets/DescriptionsItem.js | 2 +- frontend/dist/assets/ExtraView.js | 2 +- ...ion.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/Image2ImageView.js | 142 +- frontend/dist/assets/ImageBrowserView.js | 2 +- ...put.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/ImageProcessingView.js | 16 +- frontend/dist/assets/ImageUpload.js | 2 +- frontend/dist/assets/InputNumber.js | 2 +- ...pup.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/ModelsView.js | 2 +- ...tTo.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/Settings.js | 2 +- frontend/dist/assets/SettingsView.js | 190 +- frontend/dist/assets/Slider.js | 2 +- frontend/dist/assets/Switch.js | 2 +- frontend/dist/assets/TaggerView.js | 2 +- frontend/dist/assets/TestView.js | 2 +- frontend/dist/assets/TextToImageView.js | 233 +-- frontend/dist/assets/TrashBin.js | 2 +- ...le.vue_vue_type_script_setup_true_lang.js} | 397 +++- frontend/dist/assets/clock.js | 134 +- frontend/dist/assets/index.css | 35 +- frontend/dist/assets/index.js | 1646 +++++++++-------- .../src/components/generate/HighResFix.vue | 57 +- frontend/src/components/generate/Upscale.vue | 156 ++ frontend/src/components/generate/index.ts | 5 +- .../{Upscale.vue => ESRGAN.vue} | 15 - .../src/components/imageProcessing/index.ts | 2 +- .../src/components/inference/ControlNet.vue | 45 +- frontend/src/components/inference/Img2Img.vue | 44 +- .../src/components/inference/Inpainting.vue | 45 +- frontend/src/components/inference/Txt2Img.vue | 36 +- .../src/components/settings/FlagsSettings.vue | 73 - .../defaultSettings/ControlNetSettings.vue | 5 +- .../defaultSettings/ImageToImageSettings.vue | 5 +- .../defaultSettings/InpaintingSettings.vue | 5 +- .../defaultSettings/TextToImageSettings.vue | 5 +- frontend/src/components/settings/index.ts | 1 - frontend/src/functions.ts | 4 + frontend/src/settings.ts | 88 +- frontend/src/views/ImageProcessingView.vue | 4 +- frontend/src/views/SettingsView.vue | 4 - 50 files changed, 2005 insertions(+), 1482 deletions(-) rename frontend/dist/assets/{SamplerPicker.vue_vue_type_script_setup_true_lang.js => Upscale.vue_vue_type_script_setup_true_lang.js} (80%) create mode 100644 frontend/src/components/generate/Upscale.vue rename frontend/src/components/imageProcessing/{Upscale.vue => ESRGAN.vue} (96%) delete mode 100644 frontend/src/components/settings/FlagsSettings.vue diff --git a/core/config/default_settings.py b/core/config/default_settings.py index d8282436e..3e601ca1b 100644 --- a/core/config/default_settings.py +++ b/core/config/default_settings.py @@ -4,6 +4,7 @@ from diffusers.schedulers.scheduling_utils import KarrasDiffusionSchedulers +from core.flags import HighResFixFlag, UpscaleFlag from core.types import SigmaScheduler @@ -33,6 +34,10 @@ class BaseDiffusionMixin: ] = KarrasDiffusionSchedulers.DPMSolverSinglestepScheduler.value sigmas: SigmaScheduler = "automatic" + # Flags + highres: HighResFixFlag = field(default_factory=HighResFixFlag) + upscale: UpscaleFlag = field(default_factory=UpscaleFlag) + @dataclass class Txt2ImgConfig(BaseDiffusionMixin): diff --git a/core/flags.py b/core/flags.py index 3bbf25cc8..016180366 100644 --- a/core/flags.py +++ b/core/flags.py @@ -22,6 +22,8 @@ class Flag: class HighResFixFlag(Flag, DataClassJsonMixin): "Flag to fix high resolution images" + enabled: bool = False # For storing in json + scale: float = 2 mode: Literal["latent", "image"] = "latent" @@ -35,7 +37,6 @@ class HighResFixFlag(Flag, DataClassJsonMixin): # Img2img strength: float = 0.7 steps: int = 50 - antialiased: bool = False @dataclass @@ -60,3 +61,15 @@ class SDXLRefinerFlag(Flag, DataClassJsonMixin): model: str = "" aesthetic_score: float = 6.0 negative_aesthetic_score: float = 2.5 + + +@dataclass +class UpscaleFlag(Flag, DataClassJsonMixin): + "Flag for upscaling" + + enabled: bool = False # For storing in json + + upscale_factor: float = field(default=4) + tile_size: int = field(default=128) + tile_padding: int = field(default=10) + model: str = field(default="RealESRGAN_x4plus_anime_6B") diff --git a/core/gpu.py b/core/gpu.py index 1cd2924b4..2a6a52fac 100644 --- a/core/gpu.py +++ b/core/gpu.py @@ -16,6 +16,7 @@ from core import shared from core.config import config from core.errors import InferenceInterruptedError, ModelNotLoadedError +from core.flags import UpscaleFlag from core.inference.ait import AITemplateStableDiffusion from core.inference.esrgan import RealESRGAN, Upscaler from core.inference.functions import is_ipex_available @@ -37,6 +38,7 @@ ONNXBuildRequest, PyTorchModelBase, TextualInversionLoadRequest, + UpscaleData, UpscaleQueueEntry, VaeLoadRequest, ) @@ -180,6 +182,36 @@ def vram_used(self) -> float: index = torch.device(config.api.device).index return torch.cuda.memory_allocated(index) / 1024**2 + def postprocess(self, job: Job, images: List[Image.Image]) -> List[Image.Image]: + "Postprocess images" + + logger.debug(f"Postprocessing flags: {job.flags}") + + # TODO: Move highres fix here instead of relying on the individual generate function + + if "upscale" in job.flags: + logger.debug("Upscaling image") + + flag = UpscaleFlag(**job.flags["upscale"]) + + final_images = [] + for image in images: + upscale_job = UpscaleQueueEntry( + data=UpscaleData( + image=image, # type: ignore # Pydantic would cry if we extend the union + upscale_factor=flag.upscale_factor, + tile_padding=flag.tile_padding, + tile_size=flag.tile_size, + ), + model=flag.model, + ) + + final_images.append(self.upscale(upscale_job)[0]) + + images = final_images + + return images + def generate( self, job: InferenceJob, @@ -249,6 +281,9 @@ def generate_thread_call(job: Job) -> List[Image.Image]: raise NotImplementedError("Unknown model type") self.memory_cleanup() + + # Run postprocessing + images = self.postprocess(job, images) return images try: diff --git a/frontend/dist/assets/404View.js b/frontend/dist/assets/404View.js index 6e34371e9..867fb51f9 100644 --- a/frontend/dist/assets/404View.js +++ b/frontend/dist/assets/404View.js @@ -1,4 +1,4 @@ -import { d as defineComponent, o as openBlock, j as createElementBlock, g as createVNode, w as withCtx, h as unref, c4 as NResult, n as NCard } from "./index.js"; +import { d as defineComponent, o as openBlock, g as createElementBlock, e as createVNode, w as withCtx, f as unref, c4 as NResult, N as NCard } from "./index.js"; const _hoisted_1 = { style: { "width": "100vw", "height": "100vh", "display": "flex", "align-items": "center", "justify-content": "center", "backdrop-filter": "blur(4px)" } }; const _sfc_main = /* @__PURE__ */ defineComponent({ __name: "404View", diff --git a/frontend/dist/assets/AboutView.js b/frontend/dist/assets/AboutView.js index fee3296e9..f0a9c505e 100644 --- a/frontend/dist/assets/AboutView.js +++ b/frontend/dist/assets/AboutView.js @@ -1,4 +1,4 @@ -import { _ as _export_sfc, j as createElementBlock, o as openBlock, f as createBaseVNode } from "./index.js"; +import { _ as _export_sfc, g as createElementBlock, o as openBlock, b as createBaseVNode } from "./index.js"; const _sfc_main = {}; const _hoisted_1 = { class: "about" }; const _hoisted_2 = /* @__PURE__ */ createBaseVNode("h1", null, "This is an about page", -1); diff --git a/frontend/dist/assets/AccelerateView.js b/frontend/dist/assets/AccelerateView.js index 23b863c8d..3dd08490d 100644 --- a/frontend/dist/assets/AccelerateView.js +++ b/frontend/dist/assets/AccelerateView.js @@ -1,4 +1,4 @@ -import { Q as cB, ab as cM, aa as c, at as cE, aT as iconSwitchTransition, ac as cNotM, d as defineComponent, S as useConfig, ag as useRtl, T as useTheme, a3 as provide, y as h, aw as flatten, ax as getSlot, P as createInjectionKey, bi as stepsLight, R as inject, a_ as throwError, c as computed, ah as createKey, Y as useThemeClass, a1 as call, av as resolveWrappedSlot, ai as resolveSlot, aI as NIconSwitchTransition, aj as NBaseIcon, bj as FinishedIcon, bk as ErrorIcon, p as useMessage, a as useState, z as ref, o as openBlock, j as createElementBlock, g as createVNode, w as withCtx, h as unref, N as NSpace, n as NCard, f as createBaseVNode, i as NSelect, A as NButton, k as createTextVNode, bf as NModal, t as serverUrl, u as useSettings, e as createBlock, D as NTabPane, E as NTabs } from "./index.js"; +import { Q as cB, ab as cM, aa as c, at as cE, aT as iconSwitchTransition, ac as cNotM, d as defineComponent, S as useConfig, ag as useRtl, T as useTheme, a3 as provide, x as h, aw as flatten, ax as getSlot, P as createInjectionKey, bi as stepsLight, R as inject, a_ as throwError, i as computed, ah as createKey, Y as useThemeClass, a1 as call, av as resolveWrappedSlot, ai as resolveSlot, aI as NIconSwitchTransition, aj as NBaseIcon, bj as FinishedIcon, bk as ErrorIcon, n as useMessage, a as useState, y as ref, o as openBlock, g as createElementBlock, e as createVNode, w as withCtx, f as unref, j as NSpace, N as NCard, b as createBaseVNode, m as NSelect, z as NButton, k as createTextVNode, bf as NModal, s as serverUrl, u as useSettings, c as createBlock, C as NTabPane, D as NTabs } from "./index.js"; import { N as NSlider } from "./Slider.js"; import { N as NInputNumber } from "./InputNumber.js"; import { N as NSwitch } from "./Switch.js"; diff --git a/frontend/dist/assets/CloudUpload.js b/frontend/dist/assets/CloudUpload.js index 78a6dea82..f46de648a 100644 --- a/frontend/dist/assets/CloudUpload.js +++ b/frontend/dist/assets/CloudUpload.js @@ -1,4 +1,4 @@ -import { d as defineComponent, o as openBlock, j as createElementBlock, f as createBaseVNode } from "./index.js"; +import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode } from "./index.js"; const _hoisted_1 = { xmlns: "http://www.w3.org/2000/svg", "xmlns:xlink": "http://www.w3.org/1999/xlink", diff --git a/frontend/dist/assets/DescriptionsItem.js b/frontend/dist/assets/DescriptionsItem.js index cb8aa85ed..830ad75f1 100644 --- a/frontend/dist/assets/DescriptionsItem.js +++ b/frontend/dist/assets/DescriptionsItem.js @@ -1,4 +1,4 @@ -import { aa as c, Q as cB, ac as cNotM, ab as cM, at as cE, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, c as computed, ah as createKey, Y as useThemeClass, bU as useCompitable, aw as flatten, y as h, aQ as repeat, ax as getSlot, bV as descriptionsLight } from "./index.js"; +import { aa as c, Q as cB, ac as cNotM, ab as cM, at as cE, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, i as computed, ah as createKey, Y as useThemeClass, bU as useCompitable, aw as flatten, x as h, aQ as repeat, ax as getSlot, bV as descriptionsLight } from "./index.js"; function getVNodeChildren(vNode, slotName = "default", fallback = []) { const { children } = vNode; if (children !== null && typeof children === "object" && !Array.isArray(children)) { diff --git a/frontend/dist/assets/ExtraView.js b/frontend/dist/assets/ExtraView.js index 51509edbf..1c56eef7b 100644 --- a/frontend/dist/assets/ExtraView.js +++ b/frontend/dist/assets/ExtraView.js @@ -1,4 +1,4 @@ -import { _ as _export_sfc, d as defineComponent, a as useState, o as openBlock, e as createBlock, w as withCtx, h as unref, g as createVNode, D as NTabPane, E as NTabs } from "./index.js"; +import { _ as _export_sfc, d as defineComponent, a as useState, o as openBlock, c as createBlock, w as withCtx, f as unref, e as createVNode, C as NTabPane, D as NTabs } from "./index.js"; const _sfc_main$2 = {}; function _sfc_render$1(_ctx, _cache) { return "Autofill manager"; diff --git a/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js index b805090d3..5170594ec 100644 --- a/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { d as defineComponent, o as openBlock, j as createElementBlock, f as createBaseVNode, a as useState, u as useSettings, z as ref, ba as onMounted, q as onUnmounted, t as serverUrl, e as createBlock, w as withCtx, g as createVNode, h as unref, r as NGi, A as NButton, B as NIcon, k as createTextVNode, s as NGrid, bW as NAlert, m as createCommentVNode, n as NCard } from "./index.js"; +import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, a as useState, u as useSettings, y as ref, ba as onMounted, p as onUnmounted, s as serverUrl, c as createBlock, w as withCtx, e as createVNode, f as unref, q as NGi, z as NButton, A as NIcon, k as createTextVNode, r as NGrid, bW as NAlert, h as createCommentVNode, N as NCard } from "./index.js"; const _hoisted_1$1 = { xmlns: "http://www.w3.org/2000/svg", "xmlns:xlink": "http://www.w3.org/1999/xlink", diff --git a/frontend/dist/assets/Image2ImageView.js b/frontend/dist/assets/Image2ImageView.js index c7a6217a0..883e54deb 100644 --- a/frontend/dist/assets/Image2ImageView.js +++ b/frontend/dist/assets/Image2ImageView.js @@ -1,9 +1,9 @@ -import { d as defineComponent, o as openBlock, j as createElementBlock, f as createBaseVNode, a as useState, u as useSettings, p as useMessage, q as onUnmounted, g as createVNode, w as withCtx, h as unref, r as NGi, n as NCard, N as NSpace, l as NTooltip, k as createTextVNode, i as NSelect, s as NGrid, t as serverUrl, v as pushScopeId, x as popScopeId, _ as _export_sfc, y as h, z as ref, A as NButton, B as NIcon, e as createBlock, C as toDisplayString, D as NTabPane, E as NTabs } from "./index.js"; -import { B as BurnerClock, P as Prompt, _ as _sfc_main$5, a as _sfc_main$6, b as _sfc_main$7, c as _sfc_main$8, d as _sfc_main$b } from "./clock.js"; -import { _ as _sfc_main$9 } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; -import { _ as _sfc_main$a } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; +import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, a as useState, u as useSettings, n as useMessage, i as computed, p as onUnmounted, e as createVNode, w as withCtx, f as unref, q as NGi, N as NCard, j as NSpace, l as NTooltip, k as createTextVNode, m as NSelect, c as createBlock, h as createCommentVNode, r as NGrid, s as serverUrl, t as pushScopeId, v as popScopeId, _ as _export_sfc, x as h, y as ref, z as NButton, A as NIcon, B as toDisplayString, C as NTabPane, D as NTabs } from "./index.js"; +import { B as BurnerClock, P as Prompt, _ as _sfc_main$5, a as _sfc_main$6, b as _sfc_main$7, c as _sfc_main$8, d as _sfc_main$d } from "./clock.js"; +import { _ as _sfc_main$b } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; +import { _ as _sfc_main$c } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; import { I as ImageUpload } from "./ImageUpload.js"; -import { _ as _sfc_main$4 } from "./SamplerPicker.vue_vue_type_script_setup_true_lang.js"; +import { _ as _sfc_main$4, a as _sfc_main$9, b as _sfc_main$a } from "./Upscale.vue_vue_type_script_setup_true_lang.js"; import { v as v4 } from "./v4.js"; import { N as NSlider } from "./Slider.js"; import { N as NInputNumber } from "./InputNumber.js"; @@ -146,7 +146,7 @@ const TrashBinSharp = defineComponent({ return openBlock(), createElementBlock("svg", _hoisted_1$3, _hoisted_6$3); } }); -const _withScopeId$2 = (n) => (pushScopeId("data-v-95a354be"), n = n(), popScopeId(), n); +const _withScopeId$2 = (n) => (pushScopeId("data-v-97c56df6"), n = n(), popScopeId(), n); const _hoisted_1$2 = { style: { "margin": "0 12px" } }; const _hoisted_2$2 = { class: "flex-container" }; const _hoisted_3$2 = /* @__PURE__ */ _withScopeId$2(() => /* @__PURE__ */ createBaseVNode("p", { style: { "margin-right": "12px", "width": "150px" } }, "ControlNet", -1)); @@ -175,6 +175,10 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ const global = useState(); const settings = useSettings(); const messageHandler = useMessage(); + const isSelectedModelSDXL = computed(() => { + var _a; + return ((_a = settings.data.settings.model) == null ? void 0 : _a.type) === "SDXL"; + }); const checkSeed = (seed) => { if (seed === -1) { seed = Math.floor(Math.random() * 999999999999); @@ -229,7 +233,28 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ save_preprocessed: settings.data.settings.controlnet.save_preprocessed, return_preprocessed: settings.data.settings.controlnet.return_preprocessed }, - model: (_a = settings.data.settings.model) == null ? void 0 : _a.path + model: (_a = settings.data.settings.model) == null ? void 0 : _a.path, + flags: { + ...settings.data.settings.controlnet.highres.enabled ? { + highres_fix: { + mode: settings.data.settings.controlnet.highres.mode, + image_upscaler: settings.data.settings.controlnet.highres.image_upscaler, + scale: settings.data.settings.controlnet.highres.scale, + latent_scale_mode: settings.data.settings.controlnet.highres.latent_scale_mode, + strength: settings.data.settings.controlnet.highres.strength, + steps: settings.data.settings.controlnet.highres.steps, + antialiased: settings.data.settings.controlnet.highres.antialiased + } + } : {}, + ...settings.data.settings.controlnet.upscale.enabled ? { + upscale: { + upscale_factor: settings.data.settings.controlnet.upscale.upscale_factor, + tile_size: settings.data.settings.controlnet.upscale.tile_size, + tile_padding: settings.data.settings.controlnet.upscale.tile_padding, + model: settings.data.settings.controlnet.upscale.model + } + } : {} + } }) }).then((res) => { if (!res.ok) { @@ -471,20 +496,25 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ }) ]), _: 1 - }) + }), + !isSelectedModelSDXL.value ? (openBlock(), createBlock(unref(_sfc_main$9), { + key: 0, + tab: "controlnet" + })) : createCommentVNode("", true), + createVNode(unref(_sfc_main$a), { tab: "controlnet" }) ]), _: 1 }), createVNode(unref(NGi), null, { default: withCtx(() => [ - createVNode(unref(_sfc_main$9), { generate }), - createVNode(unref(_sfc_main$a), { + createVNode(unref(_sfc_main$b), { generate }), + createVNode(unref(_sfc_main$c), { "current-image": unref(global).state.controlnet.currentImage, images: unref(global).state.controlnet.images, data: unref(settings).data.settings.controlnet, onImageClicked: _cache[14] || (_cache[14] = ($event) => unref(global).state.controlnet.currentImage = $event) }, null, 8, ["current-image", "images", "data"]), - createVNode(unref(_sfc_main$b), { + createVNode(unref(_sfc_main$d), { style: { "margin-top": "12px" }, "gen-data": unref(global).state.controlnet.genData }, null, 8, ["gen-data"]) @@ -498,8 +528,8 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ }; } }); -const ControlNet = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-95a354be"]]); -const _withScopeId$1 = (n) => (pushScopeId("data-v-116492bf"), n = n(), popScopeId(), n); +const ControlNet = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-97c56df6"]]); +const _withScopeId$1 = (n) => (pushScopeId("data-v-bfd46a0a"), n = n(), popScopeId(), n); const _hoisted_1$1 = { style: { "margin": "0 12px" } }; const _hoisted_2$1 = { class: "flex-container" }; const _hoisted_3$1 = /* @__PURE__ */ _withScopeId$1(() => /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Steps", -1)); @@ -523,6 +553,10 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ } return seed; }; + const isSelectedModelSDXL = computed(() => { + var _a; + return ((_a = settings.data.settings.model) == null ? void 0 : _a.type) === "SDXL"; + }); const imageSelectCallback = (base64Image) => { settings.data.settings.img2img.image = base64Image; }; @@ -563,7 +597,28 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ prompt_to_prompt: settings.data.settings.api.prompt_to_prompt } }, - model: (_a = settings.data.settings.model) == null ? void 0 : _a.path + model: (_a = settings.data.settings.model) == null ? void 0 : _a.path, + flags: { + ...settings.data.settings.img2img.highres.enabled ? { + highres_fix: { + mode: settings.data.settings.img2img.highres.mode, + image_upscaler: settings.data.settings.img2img.highres.image_upscaler, + scale: settings.data.settings.img2img.highres.scale, + latent_scale_mode: settings.data.settings.img2img.highres.latent_scale_mode, + strength: settings.data.settings.img2img.highres.strength, + steps: settings.data.settings.img2img.highres.steps, + antialiased: settings.data.settings.img2img.highres.antialiased + } + } : {}, + ...settings.data.settings.img2img.upscale.enabled ? { + upscale: { + upscale_factor: settings.data.settings.img2img.upscale.upscale_factor, + tile_size: settings.data.settings.img2img.upscale.tile_size, + tile_padding: settings.data.settings.img2img.upscale.tile_padding, + model: settings.data.settings.img2img.upscale.model + } + } : {} + } }) }).then((res) => { if (!res.ok) { @@ -736,20 +791,25 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ }) ]), _: 1 - }) + }), + !isSelectedModelSDXL.value ? (openBlock(), createBlock(unref(_sfc_main$9), { + key: 0, + tab: "img2img" + })) : createCommentVNode("", true), + createVNode(unref(_sfc_main$a), { tab: "img2img" }) ]), _: 1 }), createVNode(unref(NGi), null, { default: withCtx(() => [ - createVNode(unref(_sfc_main$9), { generate }), - createVNode(unref(_sfc_main$a), { + createVNode(unref(_sfc_main$b), { generate }), + createVNode(unref(_sfc_main$c), { "current-image": unref(global).state.img2img.currentImage, images: unref(global).state.img2img.images, data: unref(settings).data.settings.img2img, onImageClicked: _cache[8] || (_cache[8] = ($event) => unref(global).state.img2img.currentImage = $event) }, null, 8, ["current-image", "images", "data"]), - createVNode(unref(_sfc_main$b), { + createVNode(unref(_sfc_main$d), { style: { "margin-top": "12px" }, "gen-data": unref(global).state.img2img.genData }, null, 8, ["gen-data"]) @@ -763,7 +823,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ }; } }); -const ImageToImage = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-116492bf"]]); +const ImageToImage = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-bfd46a0a"]]); var VueDrawingCanvas = /* @__PURE__ */ defineComponent({ name: "VueDrawingCanvas", props: { @@ -1339,7 +1399,7 @@ var VueDrawingCanvas = /* @__PURE__ */ defineComponent({ }); } }); -const _withScopeId = (n) => (pushScopeId("data-v-6961892e"), n = n(), popScopeId(), n); +const _withScopeId = (n) => (pushScopeId("data-v-1193df1f"), n = n(), popScopeId(), n); const _hoisted_1 = { style: { "margin": "0 12px" } }; const _hoisted_2 = { style: { "display": "inline-flex", "align-items": "center" } }; const _hoisted_3 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("svg", { @@ -1375,6 +1435,10 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ const global = useState(); const settings = useSettings(); const messageHandler = useMessage(); + const isSelectedModelSDXL = computed(() => { + var _a; + return ((_a = settings.data.settings.model) == null ? void 0 : _a.type) === "SDXL"; + }); const checkSeed = (seed) => { if (seed === -1) { seed = Math.floor(Math.random() * 999999999999); @@ -1419,7 +1483,28 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ prompt_to_prompt: settings.data.settings.api.prompt_to_prompt } }, - model: (_a = settings.data.settings.model) == null ? void 0 : _a.path + model: (_a = settings.data.settings.model) == null ? void 0 : _a.path, + flags: { + ...settings.data.settings.inpainting.highres.enabled ? { + highres_fix: { + mode: settings.data.settings.inpainting.highres.mode, + image_upscaler: settings.data.settings.inpainting.highres.image_upscaler, + scale: settings.data.settings.inpainting.highres.scale, + latent_scale_mode: settings.data.settings.inpainting.highres.latent_scale_mode, + strength: settings.data.settings.inpainting.highres.strength, + steps: settings.data.settings.inpainting.highres.steps, + antialiased: settings.data.settings.inpainting.highres.antialiased + } + } : {}, + ...settings.data.settings.inpainting.upscale.enabled ? { + upscale: { + upscale_factor: settings.data.settings.inpainting.upscale.upscale_factor, + tile_size: settings.data.settings.inpainting.upscale.tile_size, + tile_padding: settings.data.settings.inpainting.upscale.tile_padding, + model: settings.data.settings.inpainting.upscale.model + } + } : {} + } }) }).then((res) => { if (!res.ok) { @@ -1825,20 +1910,25 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ }) ]), _: 1 - }) + }), + !isSelectedModelSDXL.value ? (openBlock(), createBlock(unref(_sfc_main$9), { + key: 0, + tab: "inpainting" + })) : createCommentVNode("", true), + createVNode(unref(_sfc_main$a), { tab: "inpainting" }) ]), _: 1 }), createVNode(unref(NGi), null, { default: withCtx(() => [ - createVNode(unref(_sfc_main$9), { generate }), - createVNode(unref(_sfc_main$a), { + createVNode(unref(_sfc_main$b), { generate }), + createVNode(unref(_sfc_main$c), { "current-image": unref(global).state.inpainting.currentImage, images: unref(global).state.inpainting.images, data: unref(settings).data.settings.inpainting, onImageClicked: _cache[13] || (_cache[13] = ($event) => unref(global).state.inpainting.currentImage = $event) }, null, 8, ["current-image", "images", "data"]), - createVNode(unref(_sfc_main$b), { + createVNode(unref(_sfc_main$d), { style: { "margin-top": "12px" }, "gen-data": unref(global).state.inpainting.genData }, null, 8, ["gen-data"]) @@ -1852,7 +1942,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ }; } }); -const Inpainting = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-6961892e"]]); +const Inpainting = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-1193df1f"]]); const _sfc_main = /* @__PURE__ */ defineComponent({ __name: "Image2ImageView", setup(__props) { diff --git a/frontend/dist/assets/ImageBrowserView.js b/frontend/dist/assets/ImageBrowserView.js index 8fff76b05..cd0eb27dd 100644 --- a/frontend/dist/assets/ImageBrowserView.js +++ b/frontend/dist/assets/ImageBrowserView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, o as openBlock, j as createElementBlock, f as createBaseVNode, b7 as useCssVars, a as useState, u as useSettings, R as inject, z as ref, c as computed, bK as urlFromPath, b9 as reactive, ba as onMounted, q as onUnmounted, g as createVNode, h as unref, w as withCtx, F as Fragment, L as renderList, b8 as themeOverridesKey, t as serverUrl, J as NInput, B as NIcon, bf as NModal, s as NGrid, r as NGi, A as NButton, k as createTextVNode, M as NScrollbar, e as createBlock, bA as convertToTextString, C as toDisplayString, m as createCommentVNode, bL as diffusersSchedulerTuple, _ as _export_sfc } from "./index.js"; +import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, b7 as useCssVars, a as useState, u as useSettings, R as inject, y as ref, i as computed, bK as urlFromPath, b9 as reactive, ba as onMounted, p as onUnmounted, e as createVNode, f as unref, w as withCtx, F as Fragment, L as renderList, b8 as themeOverridesKey, s as serverUrl, I as NInput, A as NIcon, bf as NModal, r as NGrid, q as NGi, z as NButton, k as createTextVNode, M as NScrollbar, c as createBlock, bA as convertToTextString, B as toDisplayString, h as createCommentVNode, bL as diffusersSchedulerTuple, _ as _export_sfc } from "./index.js"; import { D as Download, _ as _sfc_main$1 } from "./SendOutputTo.vue_vue_type_script_setup_true_lang.js"; import { N as NImage, T as TrashBin } from "./TrashBin.js"; import { N as NSlider } from "./Slider.js"; diff --git a/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js index 57bc1e1e5..f5b4f964a 100644 --- a/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { d as defineComponent, z as ref, a as useState, o as openBlock, e as createBlock, w as withCtx, h as unref, r as NGi, g as createVNode, B as NIcon, k as createTextVNode, A as NButton, m as createCommentVNode, s as NGrid, c as computed, f as createBaseVNode, j as createElementBlock, F as Fragment, L as renderList, M as NScrollbar, n as NCard } from "./index.js"; +import { d as defineComponent, y as ref, a as useState, o as openBlock, c as createBlock, w as withCtx, f as unref, q as NGi, e as createVNode, A as NIcon, k as createTextVNode, z as NButton, h as createCommentVNode, r as NGrid, i as computed, b as createBaseVNode, g as createElementBlock, F as Fragment, L as renderList, M as NScrollbar, N as NCard } from "./index.js"; import { D as Download, _ as _sfc_main$2 } from "./SendOutputTo.vue_vue_type_script_setup_true_lang.js"; import { T as TrashBin, N as NImage } from "./TrashBin.js"; const _sfc_main$1 = /* @__PURE__ */ defineComponent({ diff --git a/frontend/dist/assets/ImageProcessingView.js b/frontend/dist/assets/ImageProcessingView.js index cb11234cb..081f5a5f2 100644 --- a/frontend/dist/assets/ImageProcessingView.js +++ b/frontend/dist/assets/ImageProcessingView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, a as useState, u as useSettings, p as useMessage, c as computed, b as upscalerOptions, o as openBlock, j as createElementBlock, g as createVNode, w as withCtx, h as unref, r as NGi, n as NCard, N as NSpace, f as createBaseVNode, i as NSelect, l as NTooltip, k as createTextVNode, s as NGrid, t as serverUrl, v as pushScopeId, x as popScopeId, _ as _export_sfc, e as createBlock, D as NTabPane, E as NTabs } from "./index.js"; +import { d as defineComponent, a as useState, u as useSettings, n as useMessage, i as computed, K as upscalerOptions, o as openBlock, g as createElementBlock, e as createVNode, w as withCtx, f as unref, q as NGi, N as NCard, j as NSpace, b as createBaseVNode, m as NSelect, l as NTooltip, k as createTextVNode, r as NGrid, s as serverUrl, c as createBlock, C as NTabPane, D as NTabs } from "./index.js"; import { _ as _sfc_main$2 } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; import { _ as _sfc_main$3 } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; import { I as ImageUpload } from "./ImageUpload.js"; @@ -8,18 +8,17 @@ import "./SendOutputTo.vue_vue_type_script_setup_true_lang.js"; import "./Switch.js"; import "./TrashBin.js"; import "./CloudUpload.js"; -const _withScopeId = (n) => (pushScopeId("data-v-5358ed01"), n = n(), popScopeId(), n); const _hoisted_1 = { style: { "margin": "0 12px" } }; const _hoisted_2 = { class: "flex-container" }; -const _hoisted_3 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Model", -1)); +const _hoisted_3 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Model", -1); const _hoisted_4 = { class: "flex-container" }; -const _hoisted_5 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Scale Factor", -1)); +const _hoisted_5 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Scale Factor", -1); const _hoisted_6 = { class: "flex-container" }; -const _hoisted_7 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Tile Size", -1)); +const _hoisted_7 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Tile Size", -1); const _hoisted_8 = { class: "flex-container" }; -const _hoisted_9 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Tile Padding", -1)); +const _hoisted_9 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Tile Padding", -1); const _sfc_main$1 = /* @__PURE__ */ defineComponent({ - __name: "Upscale", + __name: "ESRGAN", setup(__props) { const global = useState(); const settings = useSettings(); @@ -209,7 +208,6 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ }; } }); -const Upscale = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-5358ed01"]]); const _sfc_main = /* @__PURE__ */ defineComponent({ __name: "ImageProcessingView", setup(__props) { @@ -226,7 +224,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({ name: "upscale" }, { default: withCtx(() => [ - createVNode(unref(Upscale)) + createVNode(unref(_sfc_main$1)) ]), _: 1 }) diff --git a/frontend/dist/assets/ImageUpload.js b/frontend/dist/assets/ImageUpload.js index 9ee35c29e..62a763014 100644 --- a/frontend/dist/assets/ImageUpload.js +++ b/frontend/dist/assets/ImageUpload.js @@ -1,4 +1,4 @@ -import { d as defineComponent, z as ref, c as computed, ba as onMounted, o as openBlock, e as createBlock, w as withCtx, f as createBaseVNode, bd as withModifiers, j as createElementBlock, g as createVNode, h as unref, B as NIcon, C as toDisplayString, n as NCard, v as pushScopeId, x as popScopeId, _ as _export_sfc } from "./index.js"; +import { d as defineComponent, y as ref, i as computed, ba as onMounted, o as openBlock, c as createBlock, w as withCtx, b as createBaseVNode, bd as withModifiers, g as createElementBlock, e as createVNode, f as unref, A as NIcon, B as toDisplayString, N as NCard, t as pushScopeId, v as popScopeId, _ as _export_sfc } from "./index.js"; import { C as CloudUpload } from "./CloudUpload.js"; const _withScopeId = (n) => (pushScopeId("data-v-9ed1514f"), n = n(), popScopeId(), n); const _hoisted_1 = { class: "image-container" }; diff --git a/frontend/dist/assets/InputNumber.js b/frontend/dist/assets/InputNumber.js index 581770766..dcf6aae8d 100644 --- a/frontend/dist/assets/InputNumber.js +++ b/frontend/dist/assets/InputNumber.js @@ -1,4 +1,4 @@ -import { d as defineComponent, y as h, aa as c, Q as cB, S as useConfig, T as useTheme, ad as useLocale, ar as useFormItem, z as ref, X as toRef, ae as useMergedState, as as useMemo, K as watch, ag as useRtl, c as computed, bX as rgba, J as NInput, av as resolveWrappedSlot, bY as inputNumberLight, aD as on, ai as resolveSlot, aj as NBaseIcon, bZ as XButton, a$ as AddIcon, a1 as call, W as nextTick } from "./index.js"; +import { d as defineComponent, x as h, aa as c, Q as cB, S as useConfig, T as useTheme, ad as useLocale, ar as useFormItem, y as ref, X as toRef, ae as useMergedState, as as useMemo, J as watch, ag as useRtl, i as computed, bX as rgba, I as NInput, av as resolveWrappedSlot, bY as inputNumberLight, aD as on, ai as resolveSlot, aj as NBaseIcon, bZ as XButton, a$ as AddIcon, a1 as call, W as nextTick } from "./index.js"; const RemoveIcon = defineComponent({ name: "Remove", render() { diff --git a/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js index f436ecd51..56f631aaa 100644 --- a/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { bl as upperFirst, bm as toString, bn as createCompounder, bo as cloneVNode, a3 as provide, P as createInjectionKey, R as inject, a_ as throwError, d as defineComponent, S as useConfig, z as ref, bp as onBeforeUpdate, y as h, bq as indexMap, c as computed, ba as onMounted, aB as onBeforeUnmount, Q as cB, at as cE, aa as c, ab as cM, a4 as keep, ae as useMergedState, X as toRef, af as watchEffect, br as onUpdated, K as watch, W as nextTick, T as useTheme, Y as useThemeClass, aw as flatten, aL as VResizeObserver, bs as resolveSlotWithProps, bt as withDirectives, bu as vShow, aX as Transition, bb as normalizeStyle, bv as getPreciseEventTarget, aD as on, aC as off, bw as carouselLight, ac as cNotM, ar as useFormItem, ah as createKey, bx as color2Class, L as renderList, aj as NBaseIcon, by as rateLight, a1 as call, p as useMessage, u as useSettings, b9 as reactive, o as openBlock, e as createBlock, w as withCtx, g as createVNode, j as createElementBlock, h as unref, D as NTabPane, s as NGrid, r as NGi, F as Fragment, f as createBaseVNode, n as NCard, k as createTextVNode, C as toDisplayString, bz as NTag, i as NSelect, A as NButton, E as NTabs, bf as NModal, t as serverUrl } from "./index.js"; +import { bl as upperFirst, bm as toString, bn as createCompounder, bo as cloneVNode, a3 as provide, P as createInjectionKey, R as inject, a_ as throwError, d as defineComponent, S as useConfig, y as ref, bp as onBeforeUpdate, x as h, bq as indexMap, i as computed, ba as onMounted, aB as onBeforeUnmount, Q as cB, at as cE, aa as c, ab as cM, a4 as keep, ae as useMergedState, X as toRef, af as watchEffect, br as onUpdated, J as watch, W as nextTick, T as useTheme, Y as useThemeClass, aw as flatten, aL as VResizeObserver, bs as resolveSlotWithProps, bt as withDirectives, bu as vShow, aX as Transition, bb as normalizeStyle, bv as getPreciseEventTarget, aD as on, aC as off, bw as carouselLight, ac as cNotM, ar as useFormItem, ah as createKey, bx as color2Class, L as renderList, aj as NBaseIcon, by as rateLight, a1 as call, n as useMessage, u as useSettings, b9 as reactive, o as openBlock, c as createBlock, w as withCtx, e as createVNode, g as createElementBlock, f as unref, C as NTabPane, r as NGrid, q as NGi, F as Fragment, b as createBaseVNode, N as NCard, k as createTextVNode, B as toDisplayString, bz as NTag, m as NSelect, z as NButton, D as NTabs, bf as NModal, s as serverUrl } from "./index.js"; import { a as NDescriptions, N as NDescriptionsItem } from "./DescriptionsItem.js"; function capitalize(string) { return upperFirst(toString(string).toLowerCase()); diff --git a/frontend/dist/assets/ModelsView.js b/frontend/dist/assets/ModelsView.js index feae7a3d6..20cc0dd55 100644 --- a/frontend/dist/assets/ModelsView.js +++ b/frontend/dist/assets/ModelsView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, y as h, O as replaceable, P as createInjectionKey, Q as cB, R as inject, S as useConfig, T as useTheme, U as popselectLight, c as computed, V as createTreeMate, K as watch, W as nextTick, X as toRef, Y as useThemeClass, Z as NInternalSelectMenu, $ as createTmOptions, a0 as happensIn, a1 as call, a2 as keysOf, z as ref, a3 as provide, a4 as keep, a5 as createRefSetter, a6 as mergeEventHandlers, a7 as omit, a8 as NPopover, a9 as popoverBaseProps, aa as c, ab as cM, ac as cNotM, ad as useLocale, ae as useMergedState, af as watchEffect, ag as useRtl, ah as createKey, ai as resolveSlot, J as NInput, i as NSelect, F as Fragment, aj as NBaseIcon, ak as useAdjustedTo, al as paginationLight, am as useMergedClsPrefix, an as ellipsisLight, ao as onDeactivated, l as NTooltip, ap as mergeProps, aq as useStyle, ar as useFormItem, as as useMemo, at as cE, au as radioLight, av as resolveWrappedSlot, aw as flatten$1, ax as getSlot, ay as depx, az as formatLength, A as NButton, aA as NScrollbar, aB as onBeforeUnmount, aC as off, aD as on, aE as ChevronDownIcon, aF as NDropdown, aG as pxfy, aH as get, aI as NIconSwitchTransition, aJ as NBaseLoading, aK as ChevronRightIcon, q as onUnmounted, aL as VResizeObserver, aM as warn, aN as cssrAnchorMetaName, aO as VVirtualList, aP as NEmpty, aQ as repeat, aR as beforeNextFrameOnce, aS as fadeInScaleUpTransition, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, aW as createId, aX as Transition, aY as dataTableLight, aZ as loadingBarApiInjectionKey, a_ as throwError, a$ as AddIcon, b0 as NProgress, b1 as NFadeInExpandTransition, b2 as EyeIcon, b3 as fadeInHeightExpandTransition, b4 as Teleport, b5 as uploadLight, o as openBlock, j as createElementBlock, f as createBaseVNode, b6 as createStaticVNode, b7 as useCssVars, h as unref, b8 as themeOverridesKey, b9 as reactive, ba as onMounted, g as createVNode, w as withCtx, B as NIcon, L as renderList, _ as _export_sfc, u as useSettings, m as createCommentVNode, bb as normalizeStyle, k as createTextVNode, C as toDisplayString, bc as NText, e as createBlock, bd as withModifiers, a as useState, p as useMessage, be as huggingfaceModelsFile, n as NCard, t as serverUrl, v as pushScopeId, x as popScopeId, N as NSpace, bf as NModal, r as NGi, s as NGrid, bg as NDivider, bh as Backends, D as NTabPane, E as NTabs } from "./index.js"; +import { d as defineComponent, x as h, O as replaceable, P as createInjectionKey, Q as cB, R as inject, S as useConfig, T as useTheme, U as popselectLight, i as computed, V as createTreeMate, J as watch, W as nextTick, X as toRef, Y as useThemeClass, Z as NInternalSelectMenu, $ as createTmOptions, a0 as happensIn, a1 as call, a2 as keysOf, y as ref, a3 as provide, a4 as keep, a5 as createRefSetter, a6 as mergeEventHandlers, a7 as omit, a8 as NPopover, a9 as popoverBaseProps, aa as c, ab as cM, ac as cNotM, ad as useLocale, ae as useMergedState, af as watchEffect, ag as useRtl, ah as createKey, ai as resolveSlot, I as NInput, m as NSelect, F as Fragment, aj as NBaseIcon, ak as useAdjustedTo, al as paginationLight, am as useMergedClsPrefix, an as ellipsisLight, ao as onDeactivated, l as NTooltip, ap as mergeProps, aq as useStyle, ar as useFormItem, as as useMemo, at as cE, au as radioLight, av as resolveWrappedSlot, aw as flatten$1, ax as getSlot, ay as depx, az as formatLength, z as NButton, aA as NScrollbar, aB as onBeforeUnmount, aC as off, aD as on, aE as ChevronDownIcon, aF as NDropdown, aG as pxfy, aH as get, aI as NIconSwitchTransition, aJ as NBaseLoading, aK as ChevronRightIcon, p as onUnmounted, aL as VResizeObserver, aM as warn, aN as cssrAnchorMetaName, aO as VVirtualList, aP as NEmpty, aQ as repeat, aR as beforeNextFrameOnce, aS as fadeInScaleUpTransition, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, aW as createId, aX as Transition, aY as dataTableLight, aZ as loadingBarApiInjectionKey, a_ as throwError, a$ as AddIcon, b0 as NProgress, b1 as NFadeInExpandTransition, b2 as EyeIcon, b3 as fadeInHeightExpandTransition, b4 as Teleport, b5 as uploadLight, o as openBlock, g as createElementBlock, b as createBaseVNode, b6 as createStaticVNode, b7 as useCssVars, f as unref, b8 as themeOverridesKey, b9 as reactive, ba as onMounted, e as createVNode, w as withCtx, A as NIcon, L as renderList, _ as _export_sfc, u as useSettings, h as createCommentVNode, bb as normalizeStyle, k as createTextVNode, B as toDisplayString, bc as NText, c as createBlock, bd as withModifiers, a as useState, n as useMessage, be as huggingfaceModelsFile, N as NCard, s as serverUrl, t as pushScopeId, v as popScopeId, j as NSpace, bf as NModal, q as NGi, r as NGrid, bg as NDivider, bh as Backends, C as NTabPane, D as NTabs } from "./index.js"; import { _ as _sfc_main$6, n as nsfwIndex, N as NRate } from "./ModelPopup.vue_vue_type_script_setup_true_lang.js"; import { N as NCheckboxGroup, a as NCheckbox, S as Settings } from "./Settings.js"; import { N as NSwitch } from "./Switch.js"; diff --git a/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js index 204327628..3a5c9d964 100644 --- a/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { d as defineComponent, o as openBlock, j as createElementBlock, f as createBaseVNode, bM as useRouter, u as useSettings, a as useState, z as ref, b9 as reactive, K as watch, c as computed, g as createVNode, w as withCtx, h as unref, n as NCard, A as NButton, k as createTextVNode, M as NScrollbar, F as Fragment, L as renderList, C as toDisplayString, bg as NDivider, bf as NModal, e as createBlock, r as NGi, s as NGrid, m as createCommentVNode } from "./index.js"; +import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, bM as useRouter, u as useSettings, a as useState, y as ref, b9 as reactive, J as watch, i as computed, e as createVNode, w as withCtx, f as unref, N as NCard, z as NButton, k as createTextVNode, M as NScrollbar, F as Fragment, L as renderList, B as toDisplayString, bg as NDivider, bf as NModal, c as createBlock, q as NGi, r as NGrid, h as createCommentVNode } from "./index.js"; import { N as NSwitch } from "./Switch.js"; const _hoisted_1$3 = { xmlns: "http://www.w3.org/2000/svg", diff --git a/frontend/dist/assets/Settings.js b/frontend/dist/assets/Settings.js index 43644bf2f..e939932b6 100644 --- a/frontend/dist/assets/Settings.js +++ b/frontend/dist/assets/Settings.js @@ -1,4 +1,4 @@ -import { y as h, d as defineComponent, S as useConfig, ar as useFormItem, z as ref, c as computed, ae as useMergedState, a3 as provide, X as toRef, P as createInjectionKey, a1 as call, aa as c, Q as cB, ab as cM, at as cE, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, R as inject, as as useMemo, T as useTheme, bJ as checkboxLight, ag as useRtl, ah as createKey, Y as useThemeClass, aW as createId, av as resolveWrappedSlot, aI as NIconSwitchTransition, aD as on, o as openBlock, j as createElementBlock, f as createBaseVNode } from "./index.js"; +import { x as h, d as defineComponent, S as useConfig, ar as useFormItem, y as ref, i as computed, ae as useMergedState, a3 as provide, X as toRef, P as createInjectionKey, a1 as call, aa as c, Q as cB, ab as cM, at as cE, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, R as inject, as as useMemo, T as useTheme, bJ as checkboxLight, ag as useRtl, ah as createKey, Y as useThemeClass, aW as createId, av as resolveWrappedSlot, aI as NIconSwitchTransition, aD as on, o as openBlock, g as createElementBlock, b as createBaseVNode } from "./index.js"; const CheckMark = h( "svg", { viewBox: "0 0 64 64", class: "check-icon" }, diff --git a/frontend/dist/assets/SettingsView.js b/frontend/dist/assets/SettingsView.js index bcd651134..3c607222f 100644 --- a/frontend/dist/assets/SettingsView.js +++ b/frontend/dist/assets/SettingsView.js @@ -1,10 +1,10 @@ -import { d as defineComponent, u as useSettings, o as openBlock, e as createBlock, w as withCtx, g as createVNode, h as unref, J as NInput, i as NSelect, n as NCard, b9 as reactive, c as computed, bA as convertToTextString, z as ref, t as serverUrl, K as watch, a as useState, f as createBaseVNode, j as createElementBlock, L as renderList, bc as NText, k as createTextVNode, C as toDisplayString, F as Fragment, m as createCommentVNode, D as NTabPane, E as NTabs, R as inject, bB as themeKey, A as NButton, l as NTooltip, p as useMessage, bC as useNotification, q as onUnmounted, bD as defaultSettings } from "./index.js"; -import { a as NFormItem, _ as _sfc_main$h, N as NForm } from "./SamplerPicker.vue_vue_type_script_setup_true_lang.js"; +import { d as defineComponent, u as useSettings, o as openBlock, c as createBlock, w as withCtx, e as createVNode, f as unref, I as NInput, m as NSelect, N as NCard, b9 as reactive, i as computed, bA as convertToTextString, y as ref, s as serverUrl, J as watch, a as useState, b as createBaseVNode, g as createElementBlock, L as renderList, bc as NText, k as createTextVNode, B as toDisplayString, F as Fragment, h as createCommentVNode, C as NTabPane, D as NTabs, R as inject, bB as themeKey, z as NButton, l as NTooltip, n as useMessage, bC as useNotification, p as onUnmounted, bD as defaultSettings } from "./index.js"; +import { c as NFormItem, _ as _sfc_main$g, b as _sfc_main$h, a as _sfc_main$i, N as NForm } from "./Upscale.vue_vue_type_script_setup_true_lang.js"; import { N as NSwitch } from "./Switch.js"; import { N as NInputNumber } from "./InputNumber.js"; import { N as NSlider } from "./Slider.js"; import "./Settings.js"; -const _sfc_main$g = /* @__PURE__ */ defineComponent({ +const _sfc_main$f = /* @__PURE__ */ defineComponent({ __name: "ControlNetSettings", setup(__props) { const settings = useSettings(); @@ -178,9 +178,17 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({ ]), _: 1 }), - createVNode(_sfc_main$h, { + createVNode(unref(_sfc_main$g), { type: "controlnet", target: "defaultSettings" + }), + createVNode(unref(_sfc_main$h), { + tab: "controlnet", + target: "defaultSettings" + }), + createVNode(unref(_sfc_main$i), { + tab: "controlnet", + target: "defaultSettings" }) ]), _: 1 @@ -191,7 +199,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({ }; } }); -const _sfc_main$f = /* @__PURE__ */ defineComponent({ +const _sfc_main$e = /* @__PURE__ */ defineComponent({ __name: "ImageBrowserSettings", setup(__props) { const settings = useSettings(); @@ -221,7 +229,7 @@ const _sfc_main$f = /* @__PURE__ */ defineComponent({ }; } }); -const _sfc_main$e = /* @__PURE__ */ defineComponent({ +const _sfc_main$d = /* @__PURE__ */ defineComponent({ __name: "ImageToImageSettings", setup(__props) { const settings = useSettings(); @@ -355,9 +363,17 @@ const _sfc_main$e = /* @__PURE__ */ defineComponent({ ]), _: 1 }), - createVNode(_sfc_main$h, { + createVNode(unref(_sfc_main$g), { type: "img2img", target: "defaultSettings" + }), + createVNode(unref(_sfc_main$h), { + tab: "img2img", + target: "defaultSettings" + }), + createVNode(unref(_sfc_main$i), { + tab: "img2img", + target: "defaultSettings" }) ]), _: 1 @@ -368,7 +384,7 @@ const _sfc_main$e = /* @__PURE__ */ defineComponent({ }; } }); -const _sfc_main$d = /* @__PURE__ */ defineComponent({ +const _sfc_main$c = /* @__PURE__ */ defineComponent({ __name: "InpaintingSettings", setup(__props) { const settings = useSettings(); @@ -489,9 +505,17 @@ const _sfc_main$d = /* @__PURE__ */ defineComponent({ ]), _: 1 }), - createVNode(_sfc_main$h, { + createVNode(unref(_sfc_main$g), { type: "inpainting", target: "defaultSettings" + }), + createVNode(unref(_sfc_main$h), { + tab: "inpainting", + target: "defaultSettings" + }), + createVNode(unref(_sfc_main$i), { + tab: "inpainting", + target: "defaultSettings" }) ]), _: 1 @@ -502,7 +526,7 @@ const _sfc_main$d = /* @__PURE__ */ defineComponent({ }; } }); -const _sfc_main$c = /* @__PURE__ */ defineComponent({ +const _sfc_main$b = /* @__PURE__ */ defineComponent({ __name: "TextToImageSettings", setup(__props) { const settings = useSettings(); @@ -623,9 +647,17 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({ ]), _: 1 }), - createVNode(_sfc_main$h, { + createVNode(unref(_sfc_main$g), { type: "txt2img", target: "defaultSettings" + }), + createVNode(unref(_sfc_main$h), { + tab: "txt2img", + target: "defaultSettings" + }), + createVNode(unref(_sfc_main$i), { + tab: "txt2img", + target: "defaultSettings" }) ]), _: 1 @@ -636,7 +668,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({ }; } }); -const _sfc_main$b = /* @__PURE__ */ defineComponent({ +const _sfc_main$a = /* @__PURE__ */ defineComponent({ __name: "ThemeSettings", setup(__props) { const settings = useSettings(); @@ -712,7 +744,7 @@ const _sfc_main$b = /* @__PURE__ */ defineComponent({ } }); const _hoisted_1$3 = { style: { "width": "100%" } }; -const _sfc_main$a = /* @__PURE__ */ defineComponent({ +const _sfc_main$9 = /* @__PURE__ */ defineComponent({ __name: "AutoloadSettings", setup(__props) { const settings = useSettings(); @@ -837,7 +869,7 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({ }; } }); -const _sfc_main$9 = /* @__PURE__ */ defineComponent({ +const _sfc_main$8 = /* @__PURE__ */ defineComponent({ __name: "BotSettings", setup(__props) { const settings = useSettings(); @@ -892,7 +924,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({ }; } }); -const _sfc_main$8 = /* @__PURE__ */ defineComponent({ +const _sfc_main$7 = /* @__PURE__ */ defineComponent({ __name: "FilesSettings", setup(__props) { const settings = useSettings(); @@ -971,110 +1003,6 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({ }; } }); -const _sfc_main$7 = /* @__PURE__ */ defineComponent({ - __name: "FlagsSettings", - setup(__props) { - const settings = useSettings(); - return (_ctx, _cache) => { - return openBlock(), createBlock(unref(NCard), { title: "Hi-res fix" }, { - default: withCtx(() => [ - createVNode(unref(NForm), null, { - default: withCtx(() => [ - createVNode(unref(NFormItem), { - label: "Scale", - "label-placement": "left" - }, { - default: withCtx(() => [ - createVNode(unref(NInputNumber), { - value: unref(settings).defaultSettings.flags.highres.scale, - "onUpdate:value": _cache[0] || (_cache[0] = ($event) => unref(settings).defaultSettings.flags.highres.scale = $event) - }, null, 8, ["value"]) - ]), - _: 1 - }), - createVNode(unref(NFormItem), { - label: "Scaling Mode", - "label-placement": "left" - }, { - default: withCtx(() => [ - createVNode(unref(NSelect), { - options: [ - { - label: "Nearest", - value: "nearest" - }, - { - label: "Linear", - value: "linear" - }, - { - label: "Bilinear", - value: "bilinear" - }, - { - label: "Bicubic", - value: "bicubic" - }, - { - label: "Bislerp", - value: "bislerp" - }, - { - label: "Nearest Exact", - value: "nearest-exact" - } - ], - value: unref(settings).defaultSettings.flags.highres.latent_scale_mode, - "onUpdate:value": _cache[1] || (_cache[1] = ($event) => unref(settings).defaultSettings.flags.highres.latent_scale_mode = $event) - }, null, 8, ["value"]) - ]), - _: 1 - }), - createVNode(unref(NFormItem), { - label: "Strength", - "label-placement": "left" - }, { - default: withCtx(() => [ - createVNode(unref(NInputNumber), { - value: unref(settings).defaultSettings.flags.highres.strength, - "onUpdate:value": _cache[2] || (_cache[2] = ($event) => unref(settings).defaultSettings.flags.highres.strength = $event) - }, null, 8, ["value"]) - ]), - _: 1 - }), - createVNode(unref(NFormItem), { - label: "Steps", - "label-placement": "left" - }, { - default: withCtx(() => [ - createVNode(unref(NInputNumber), { - value: unref(settings).defaultSettings.flags.highres.steps, - "onUpdate:value": _cache[3] || (_cache[3] = ($event) => unref(settings).defaultSettings.flags.highres.steps = $event) - }, null, 8, ["value"]) - ]), - _: 1 - }), - createVNode(unref(NFormItem), { - label: "Antialiased", - "label-placement": "left" - }, { - default: withCtx(() => [ - createVNode(unref(NSwitch), { - value: unref(settings).defaultSettings.flags.highres.antialiased, - "onUpdate:value": _cache[4] || (_cache[4] = ($event) => unref(settings).defaultSettings.flags.highres.antialiased = $event) - }, null, 8, ["value"]) - ]), - _: 1 - }) - ]), - _: 1 - }) - ]), - _: 1 - }); - }; - } -}); const _sfc_main$6 = /* @__PURE__ */ defineComponent({ __name: "FrontendSettings", setup(__props) { @@ -1083,31 +1011,31 @@ const _sfc_main$6 = /* @__PURE__ */ defineComponent({ default: withCtx(() => [ createVNode(unref(NTabPane), { name: "Text to Image" }, { default: withCtx(() => [ - createVNode(unref(_sfc_main$c)) + createVNode(unref(_sfc_main$b)) ]), _: 1 }), createVNode(unref(NTabPane), { name: "Image to Image" }, { default: withCtx(() => [ - createVNode(unref(_sfc_main$e)) + createVNode(unref(_sfc_main$d)) ]), _: 1 }), createVNode(unref(NTabPane), { name: "ControlNet" }, { default: withCtx(() => [ - createVNode(unref(_sfc_main$g)) + createVNode(unref(_sfc_main$f)) ]), _: 1 }), createVNode(unref(NTabPane), { name: "Inpainting" }, { default: withCtx(() => [ - createVNode(unref(_sfc_main$d)) + createVNode(unref(_sfc_main$c)) ]), _: 1 }), createVNode(unref(NTabPane), { name: "Image Browser" }, { default: withCtx(() => [ - createVNode(unref(_sfc_main$f)) + createVNode(unref(_sfc_main$e)) ]), _: 1 }) @@ -2278,13 +2206,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({ default: withCtx(() => [ createVNode(unref(NTabPane), { name: "Autoload" }, { default: withCtx(() => [ - createVNode(unref(_sfc_main$a)) + createVNode(unref(_sfc_main$9)) ]), _: 1 }), createVNode(unref(NTabPane), { name: "Files & Saving" }, { default: withCtx(() => [ - createVNode(unref(_sfc_main$8)) + createVNode(unref(_sfc_main$7)) ]), _: 1 }), @@ -2314,7 +2242,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({ }), createVNode(unref(NTabPane), { name: "Bot" }, { default: withCtx(() => [ - createVNode(unref(_sfc_main$9)) + createVNode(unref(_sfc_main$8)) ]), _: 1 }), @@ -2324,15 +2252,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({ ]), _: 1 }), - createVNode(unref(NTabPane), { name: "Flags" }, { - default: withCtx(() => [ - createVNode(unref(_sfc_main$7)) - ]), - _: 1 - }), createVNode(unref(NTabPane), { name: "Theme" }, { default: withCtx(() => [ - createVNode(unref(_sfc_main$b)) + createVNode(unref(_sfc_main$a)) ]), _: 1 }), diff --git a/frontend/dist/assets/Slider.js b/frontend/dist/assets/Slider.js index 35d233583..2d318b072 100644 --- a/frontend/dist/assets/Slider.js +++ b/frontend/dist/assets/Slider.js @@ -1,4 +1,4 @@ -import { z as ref, bp as onBeforeUpdate, aa as c, Q as cB, ab as cM, at as cE, aS as fadeInScaleUpTransition, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, ar as useFormItem, c as computed, X as toRef, ae as useMergedState, K as watch, W as nextTick, aB as onBeforeUnmount, Y as useThemeClass, bQ as isMounted, ak as useAdjustedTo, y as h, b_ as VBinder, b$ as VTarget, ai as resolveSlot, c0 as VFollower, aX as Transition, c1 as sliderLight, aD as on, aC as off, a1 as call } from "./index.js"; +import { y as ref, bp as onBeforeUpdate, aa as c, Q as cB, ab as cM, at as cE, aS as fadeInScaleUpTransition, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, ar as useFormItem, i as computed, X as toRef, ae as useMergedState, J as watch, W as nextTick, aB as onBeforeUnmount, Y as useThemeClass, bQ as isMounted, ak as useAdjustedTo, x as h, b_ as VBinder, b$ as VTarget, ai as resolveSlot, c0 as VFollower, aX as Transition, c1 as sliderLight, aD as on, aC as off, a1 as call } from "./index.js"; function isTouchEvent(e) { return window.TouchEvent && e instanceof window.TouchEvent; } diff --git a/frontend/dist/assets/Switch.js b/frontend/dist/assets/Switch.js index fb9768669..762abd2de 100644 --- a/frontend/dist/assets/Switch.js +++ b/frontend/dist/assets/Switch.js @@ -1,4 +1,4 @@ -import { Q as cB, at as cE, aT as iconSwitchTransition, aa as c, ab as cM, ac as cNotM, d as defineComponent, S as useConfig, T as useTheme, ar as useFormItem, z as ref, X as toRef, ae as useMergedState, c as computed, ah as createKey, aG as pxfy, ay as depx, Y as useThemeClass, c2 as isSlotEmpty, y as h, av as resolveWrappedSlot, c3 as switchLight, aI as NIconSwitchTransition, aJ as NBaseLoading, a1 as call } from "./index.js"; +import { Q as cB, at as cE, aT as iconSwitchTransition, aa as c, ab as cM, ac as cNotM, d as defineComponent, S as useConfig, T as useTheme, ar as useFormItem, y as ref, X as toRef, ae as useMergedState, i as computed, ah as createKey, aG as pxfy, ay as depx, Y as useThemeClass, c2 as isSlotEmpty, x as h, av as resolveWrappedSlot, c3 as switchLight, aI as NIconSwitchTransition, aJ as NBaseLoading, a1 as call } from "./index.js"; const style = cB("switch", ` height: var(--n-height); min-width: var(--n-width); diff --git a/frontend/dist/assets/TaggerView.js b/frontend/dist/assets/TaggerView.js index 39a48c7ad..ec5a7444a 100644 --- a/frontend/dist/assets/TaggerView.js +++ b/frontend/dist/assets/TaggerView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, a as useState, u as useSettings, p as useMessage, z as ref, c as computed, G as spaceRegex, o as openBlock, j as createElementBlock, g as createVNode, w as withCtx, h as unref, r as NGi, n as NCard, N as NSpace, f as createBaseVNode, i as NSelect, l as NTooltip, k as createTextVNode, J as NInput, C as toDisplayString, s as NGrid, t as serverUrl, v as pushScopeId, x as popScopeId, _ as _export_sfc } from "./index.js"; +import { d as defineComponent, a as useState, u as useSettings, n as useMessage, y as ref, i as computed, E as spaceRegex, o as openBlock, g as createElementBlock, e as createVNode, w as withCtx, f as unref, q as NGi, N as NCard, j as NSpace, b as createBaseVNode, m as NSelect, l as NTooltip, k as createTextVNode, I as NInput, B as toDisplayString, r as NGrid, s as serverUrl, t as pushScopeId, v as popScopeId, _ as _export_sfc } from "./index.js"; import { _ as _sfc_main$1 } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; import { I as ImageUpload } from "./ImageUpload.js"; import { v as v4 } from "./v4.js"; diff --git a/frontend/dist/assets/TestView.js b/frontend/dist/assets/TestView.js index ff8c3ffbd..b38d6910d 100644 --- a/frontend/dist/assets/TestView.js +++ b/frontend/dist/assets/TestView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, z as ref, o as openBlock, e as createBlock, h as unref } from "./index.js"; +import { d as defineComponent, y as ref, o as openBlock, c as createBlock, f as unref } from "./index.js"; import { _ as _sfc_main$1 } from "./ModelPopup.vue_vue_type_script_setup_true_lang.js"; import "./DescriptionsItem.js"; const _sfc_main = /* @__PURE__ */ defineComponent({ diff --git a/frontend/dist/assets/TextToImageView.js b/frontend/dist/assets/TextToImageView.js index 2b5dffa1a..abc3b7a3d 100644 --- a/frontend/dist/assets/TextToImageView.js +++ b/frontend/dist/assets/TextToImageView.js @@ -1,195 +1,16 @@ -import { d as defineComponent, u as useSettings, a as useState, c as computed, b as upscalerOptions, o as openBlock, e as createBlock, w as withCtx, f as createBaseVNode, g as createVNode, h as unref, N as NSpace, i as NSelect, j as createElementBlock, k as createTextVNode, l as NTooltip, m as createCommentVNode, n as NCard, p as useMessage, q as onUnmounted, r as NGi, s as NGrid, t as serverUrl } from "./index.js"; -import { _ as _sfc_main$a } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; -import { _ as _sfc_main$b } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; -import { B as BurnerClock, P as Prompt, _ as _sfc_main$6, a as _sfc_main$7, b as _sfc_main$8, c as _sfc_main$9, d as _sfc_main$c } from "./clock.js"; +import { d as defineComponent, u as useSettings, a as useState, o as openBlock, c as createBlock, w as withCtx, b as createBaseVNode, e as createVNode, f as unref, g as createElementBlock, h as createCommentVNode, N as NCard, i as computed, j as NSpace, k as createTextVNode, l as NTooltip, m as NSelect, n as useMessage, p as onUnmounted, q as NGi, r as NGrid, s as serverUrl } from "./index.js"; +import { _ as _sfc_main$b } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; +import { _ as _sfc_main$c } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; +import { B as BurnerClock, P as Prompt, _ as _sfc_main$5, a as _sfc_main$6, b as _sfc_main$7, c as _sfc_main$8, d as _sfc_main$d } from "./clock.js"; +import { _ as _sfc_main$4, a as _sfc_main$9, b as _sfc_main$a } from "./Upscale.vue_vue_type_script_setup_true_lang.js"; import { N as NSwitch } from "./Switch.js"; import { N as NSlider } from "./Slider.js"; import { N as NInputNumber } from "./InputNumber.js"; -import { _ as _sfc_main$5 } from "./SamplerPicker.vue_vue_type_script_setup_true_lang.js"; import { v as v4 } from "./v4.js"; import "./SendOutputTo.vue_vue_type_script_setup_true_lang.js"; import "./TrashBin.js"; import "./DescriptionsItem.js"; import "./Settings.js"; -const _hoisted_1$3 = { class: "flex-container" }; -const _hoisted_2$3 = /* @__PURE__ */ createBaseVNode("div", { class: "slider-label" }, [ - /* @__PURE__ */ createBaseVNode("p", null, "Enabled") -], -1); -const _hoisted_3$3 = { class: "flex-container" }; -const _hoisted_4$3 = /* @__PURE__ */ createBaseVNode("div", { class: "slider-label" }, [ - /* @__PURE__ */ createBaseVNode("p", null, "Mode") -], -1); -const _hoisted_5$3 = { key: 0 }; -const _hoisted_6$3 = { class: "flex-container" }; -const _hoisted_7$3 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Upscaler", -1); -const _hoisted_8$2 = { key: 1 }; -const _hoisted_9$2 = { class: "flex-container" }; -const _hoisted_10$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Antialiased", -1); -const _hoisted_11$1 = { class: "flex-container" }; -const _hoisted_12$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Latent Mode", -1); -const _hoisted_13$1 = { class: "flex-container" }; -const _hoisted_14$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Steps", -1); -const _hoisted_15$1 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "We recommend using 20-50 steps for most images.", -1); -const _hoisted_16$1 = { class: "flex-container" }; -const _hoisted_17 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Scale", -1); -const _hoisted_18 = { class: "flex-container" }; -const _hoisted_19 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Strength", -1); -const _sfc_main$4 = /* @__PURE__ */ defineComponent({ - __name: "HighResFix", - setup(__props) { - const settings = useSettings(); - const global = useState(); - const imageUpscalerOptions = computed(() => { - const localModels = global.state.models.filter( - (model) => model.backend === "Upscaler" && !(upscalerOptions.map((option) => option.label).indexOf(model.name) !== -1) - ).map((model) => ({ - label: model.name, - value: model.path - })); - return [...upscalerOptions, ...localModels]; - }); - const latentUpscalerOptions = [ - { label: "Nearest", value: "nearest" }, - { label: "Nearest exact", value: "nearest-exact" }, - { label: "Area", value: "area" }, - { label: "Bilinear", value: "bilinear" }, - { label: "Bicubic", value: "bicubic" }, - { label: "Bislerp", value: "bislerp" } - ]; - return (_ctx, _cache) => { - return openBlock(), createBlock(unref(NCard), { - title: "Highres fix", - class: "generate-extra-card" - }, { - default: withCtx(() => [ - createBaseVNode("div", _hoisted_1$3, [ - _hoisted_2$3, - createVNode(unref(NSwitch), { - value: unref(global).state.txt2img.highres, - "onUpdate:value": _cache[0] || (_cache[0] = ($event) => unref(global).state.txt2img.highres = $event) - }, null, 8, ["value"]) - ]), - unref(global).state.txt2img.highres ? (openBlock(), createBlock(unref(NSpace), { - key: 0, - vertical: "", - class: "left-container" - }, { - default: withCtx(() => [ - createBaseVNode("div", _hoisted_3$3, [ - _hoisted_4$3, - createVNode(unref(NSelect), { - value: unref(settings).data.settings.flags.highres.mode, - "onUpdate:value": _cache[1] || (_cache[1] = ($event) => unref(settings).data.settings.flags.highres.mode = $event), - options: [ - { label: "Latent", value: "latent" }, - { label: "Image", value: "image" } - ] - }, null, 8, ["value"]) - ]), - unref(settings).data.settings.flags.highres.mode === "image" ? (openBlock(), createElementBlock("div", _hoisted_5$3, [ - createBaseVNode("div", _hoisted_6$3, [ - _hoisted_7$3, - createVNode(unref(NSelect), { - value: unref(settings).data.settings.flags.highres.image_upscaler, - "onUpdate:value": _cache[2] || (_cache[2] = ($event) => unref(settings).data.settings.flags.highres.image_upscaler = $event), - size: "small", - style: { "flex-grow": "1" }, - filterable: "", - options: imageUpscalerOptions.value - }, null, 8, ["value", "options"]) - ]) - ])) : (openBlock(), createElementBlock("div", _hoisted_8$2, [ - createBaseVNode("div", _hoisted_9$2, [ - _hoisted_10$1, - createVNode(unref(NSwitch), { - value: unref(settings).data.settings.flags.highres.antialiased, - "onUpdate:value": _cache[3] || (_cache[3] = ($event) => unref(settings).data.settings.flags.highres.antialiased = $event) - }, null, 8, ["value"]) - ]), - createBaseVNode("div", _hoisted_11$1, [ - _hoisted_12$1, - createVNode(unref(NSelect), { - value: unref(settings).data.settings.flags.highres.latent_scale_mode, - "onUpdate:value": _cache[4] || (_cache[4] = ($event) => unref(settings).data.settings.flags.highres.latent_scale_mode = $event), - size: "small", - style: { "flex-grow": "1" }, - filterable: "", - options: latentUpscalerOptions - }, null, 8, ["value"]) - ]) - ])), - createBaseVNode("div", _hoisted_13$1, [ - createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { - trigger: withCtx(() => [ - _hoisted_14$1 - ]), - default: withCtx(() => [ - createTextVNode(" Number of steps to take in the diffusion process. Higher values will result in more detailed images but will take longer to generate. There is also a point of diminishing returns around 100 steps. "), - _hoisted_15$1 - ]), - _: 1 - }), - createVNode(unref(NSlider), { - value: unref(settings).data.settings.flags.highres.steps, - "onUpdate:value": _cache[5] || (_cache[5] = ($event) => unref(settings).data.settings.flags.highres.steps = $event), - min: 5, - max: 300, - style: { "margin-right": "12px" } - }, null, 8, ["value"]), - createVNode(unref(NInputNumber), { - value: unref(settings).data.settings.flags.highres.steps, - "onUpdate:value": _cache[6] || (_cache[6] = ($event) => unref(settings).data.settings.flags.highres.steps = $event), - size: "small", - style: { "min-width": "96px", "width": "96px" } - }, null, 8, ["value"]) - ]), - createBaseVNode("div", _hoisted_16$1, [ - _hoisted_17, - createVNode(unref(NSlider), { - value: unref(settings).data.settings.flags.highres.scale, - "onUpdate:value": _cache[7] || (_cache[7] = ($event) => unref(settings).data.settings.flags.highres.scale = $event), - min: 1, - max: 8, - step: 0.1, - style: { "margin-right": "12px" } - }, null, 8, ["value"]), - createVNode(unref(NInputNumber), { - value: unref(settings).data.settings.flags.highres.scale, - "onUpdate:value": _cache[8] || (_cache[8] = ($event) => unref(settings).data.settings.flags.highres.scale = $event), - size: "small", - style: { "min-width": "96px", "width": "96px" }, - step: 0.1 - }, null, 8, ["value"]) - ]), - createBaseVNode("div", _hoisted_18, [ - _hoisted_19, - createVNode(unref(NSlider), { - value: unref(settings).data.settings.flags.highres.strength, - "onUpdate:value": _cache[9] || (_cache[9] = ($event) => unref(settings).data.settings.flags.highres.strength = $event), - min: 0.1, - max: 0.9, - step: 0.05, - style: { "margin-right": "12px" } - }, null, 8, ["value"]), - createVNode(unref(NInputNumber), { - value: unref(settings).data.settings.flags.highres.strength, - "onUpdate:value": _cache[10] || (_cache[10] = ($event) => unref(settings).data.settings.flags.highres.strength = $event), - size: "small", - style: { "min-width": "96px", "width": "96px" }, - min: 0.1, - max: 0.9, - step: 0.05 - }, null, 8, ["value"]) - ]) - ]), - _: 1 - })) : createCommentVNode("", true) - ]), - _: 1 - }); - }; - } -}); const _hoisted_1$2 = { class: "flex-container" }; const _hoisted_2$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Enabled", -1); const _hoisted_3$2 = { key: 0 }; @@ -514,15 +335,15 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ } } } : {}, - ...global.state.txt2img.highres ? { + ...settings.data.settings.txt2img.highres.enabled ? { highres_fix: { - mode: settings.data.settings.flags.highres.mode, - image_upscaler: settings.data.settings.flags.highres.image_upscaler, - scale: settings.data.settings.flags.highres.scale, - latent_scale_mode: settings.data.settings.flags.highres.latent_scale_mode, - strength: settings.data.settings.flags.highres.strength, - steps: settings.data.settings.flags.highres.steps, - antialiased: settings.data.settings.flags.highres.antialiased + mode: settings.data.settings.txt2img.highres.mode, + image_upscaler: settings.data.settings.txt2img.highres.image_upscaler, + scale: settings.data.settings.txt2img.highres.scale, + latent_scale_mode: settings.data.settings.txt2img.highres.latent_scale_mode, + strength: settings.data.settings.txt2img.highres.strength, + steps: settings.data.settings.txt2img.highres.steps, + antialiased: settings.data.settings.txt2img.highres.antialiased } } : global.state.txt2img.refiner ? { refiner: { @@ -532,6 +353,14 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ steps: settings.data.settings.flags.refiner.steps, strength: settings.data.settings.flags.refiner.strength } + } : {}, + ...settings.data.settings.txt2img.upscale.enabled ? { + upscale: { + upscale_factor: settings.data.settings.txt2img.upscale.upscale_factor, + tile_size: settings.data.settings.txt2img.upscale.tile_size, + tile_padding: settings.data.settings.txt2img.upscale.tile_padding, + model: settings.data.settings.txt2img.upscale.model + } } : {} } }) @@ -584,8 +413,8 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ }, { default: withCtx(() => [ createVNode(unref(Prompt), { tab: "txt2img" }), - createVNode(unref(_sfc_main$5), { type: "txt2img" }), - createVNode(unref(_sfc_main$6), { + createVNode(unref(_sfc_main$4), { type: "txt2img" }), + createVNode(unref(_sfc_main$5), { "dimensions-object": unref(settings).data.settings.txt2img }, null, 8, ["dimensions-object"]), createBaseVNode("div", _hoisted_2, [ @@ -613,8 +442,8 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ style: { "min-width": "96px", "width": "96px" } }, null, 8, ["value"]) ]), + createVNode(unref(_sfc_main$6), { tab: "txt2img" }), createVNode(unref(_sfc_main$7), { tab: "txt2img" }), - createVNode(unref(_sfc_main$8), { tab: "txt2img" }), createBaseVNode("div", _hoisted_5, [ createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { trigger: withCtx(() => [ @@ -639,7 +468,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ style: { "min-width": "96px", "width": "96px" } }, null, 8, ["value"]) ]), - createVNode(unref(_sfc_main$9), { + createVNode(unref(_sfc_main$8), { "batch-size-object": unref(settings).data.settings.txt2img }, null, 8, ["batch-size-object"]), createBaseVNode("div", _hoisted_7, [ @@ -671,21 +500,25 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ "dimensions-object": unref(settings).data.settings.txt2img }, null, 8, ["dimensions-object"])) : createCommentVNode("", true), isSelectedModelSDXL.value ? (openBlock(), createBlock(unref(_sfc_main$2), { key: 1 })) : createCommentVNode("", true), - !isSelectedModelSDXL.value ? (openBlock(), createBlock(unref(_sfc_main$4), { key: 2 })) : createCommentVNode("", true) + !isSelectedModelSDXL.value ? (openBlock(), createBlock(unref(_sfc_main$9), { + key: 2, + tab: "txt2img" + })) : createCommentVNode("", true), + createVNode(unref(_sfc_main$a), { tab: "txt2img" }) ]; }), _: 1 }), createVNode(unref(NGi), null, { default: withCtx(() => [ - createVNode(unref(_sfc_main$a), { generate }), - createVNode(unref(_sfc_main$b), { + createVNode(unref(_sfc_main$b), { generate }), + createVNode(unref(_sfc_main$c), { "current-image": unref(global).state.txt2img.currentImage, images: unref(global).state.txt2img.images, data: unref(settings).data.settings.txt2img, onImageClicked: _cache[5] || (_cache[5] = ($event) => unref(global).state.txt2img.currentImage = $event) }, null, 8, ["current-image", "images", "data"]), - createVNode(unref(_sfc_main$c), { + createVNode(unref(_sfc_main$d), { style: { "margin-top": "12px" }, "gen-data": unref(global).state.txt2img.genData }, null, 8, ["gen-data"]) diff --git a/frontend/dist/assets/TrashBin.js b/frontend/dist/assets/TrashBin.js index 74401731f..4a22a2783 100644 --- a/frontend/dist/assets/TrashBin.js +++ b/frontend/dist/assets/TrashBin.js @@ -1,4 +1,4 @@ -import { O as replaceable, y as h, d as defineComponent, bN as isBrowser, T as useTheme, P as createInjectionKey, aa as c, Q as cB, bO as fadeInTransition, aS as fadeInScaleUpTransition, ac as cNotM, X as toRef, bP as imageLight, z as ref, ad as useLocale, K as watch, aD as on, aC as off, aB as onBeforeUnmount, R as inject, c as computed, S as useConfig, Y as useThemeClass, bQ as isMounted, bR as LazyTeleport, bt as withDirectives, bS as zindexable, aX as Transition, F as Fragment, aj as NBaseIcon, bu as vShow, bb as normalizeStyle, bT as kebabCase, l as NTooltip, aR as beforeNextFrameOnce, aW as createId, a3 as provide, bE as getCurrentInstance, ba as onMounted, af as watchEffect, o as openBlock, j as createElementBlock, f as createBaseVNode } from "./index.js"; +import { O as replaceable, x as h, d as defineComponent, bN as isBrowser, T as useTheme, P as createInjectionKey, aa as c, Q as cB, bO as fadeInTransition, aS as fadeInScaleUpTransition, ac as cNotM, X as toRef, bP as imageLight, y as ref, ad as useLocale, J as watch, aD as on, aC as off, aB as onBeforeUnmount, R as inject, i as computed, S as useConfig, Y as useThemeClass, bQ as isMounted, bR as LazyTeleport, bt as withDirectives, bS as zindexable, aX as Transition, F as Fragment, aj as NBaseIcon, bu as vShow, bb as normalizeStyle, bT as kebabCase, l as NTooltip, aR as beforeNextFrameOnce, aW as createId, a3 as provide, bE as getCurrentInstance, ba as onMounted, af as watchEffect, o as openBlock, g as createElementBlock, b as createBaseVNode } from "./index.js"; const RotateClockwiseIcon = replaceable("rotateClockwise", h( "svg", { viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, diff --git a/frontend/dist/assets/SamplerPicker.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/Upscale.vue_vue_type_script_setup_true_lang.js similarity index 80% rename from frontend/dist/assets/SamplerPicker.vue_vue_type_script_setup_true_lang.js rename to frontend/dist/assets/Upscale.vue_vue_type_script_setup_true_lang.js index 834fca788..b31241fa6 100644 --- a/frontend/dist/assets/SamplerPicker.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/Upscale.vue_vue_type_script_setup_true_lang.js @@ -1,7 +1,8 @@ -import { R as inject, bE as getCurrentInstance, K as watch, aB as onBeforeUnmount, Q as cB, ab as cM, aa as c, P as createInjectionKey, d as defineComponent, S as useConfig, T as useTheme, z as ref, a3 as provide, y as h, bF as formLight, a2 as keysOf, c as computed, az as formatLength, aH as get, bG as commonVariables, at as cE, X as toRef, aW as createId, bH as formItemInjectionKey, ba as onMounted, ah as createKey, Y as useThemeClass, aX as Transition, av as resolveWrappedSlot, aM as warn, u as useSettings, o as openBlock, j as createElementBlock, f as createBaseVNode, g as createVNode, w as withCtx, h as unref, n as NCard, F as Fragment, L as renderList, A as NButton, k as createTextVNode, C as toDisplayString, bA as convertToTextString, e as createBlock, bI as resolveDynamicComponent, bf as NModal, l as NTooltip, i as NSelect, B as NIcon } from "./index.js"; -import { S as Settings, a as NCheckbox } from "./Settings.js"; -import { N as NInputNumber } from "./InputNumber.js"; +import { R as inject, bE as getCurrentInstance, J as watch, aB as onBeforeUnmount, Q as cB, ab as cM, aa as c, P as createInjectionKey, d as defineComponent, S as useConfig, T as useTheme, y as ref, a3 as provide, x as h, bF as formLight, a2 as keysOf, i as computed, az as formatLength, aH as get, bG as commonVariables, at as cE, X as toRef, aW as createId, bH as formItemInjectionKey, ba as onMounted, ah as createKey, Y as useThemeClass, aX as Transition, av as resolveWrappedSlot, aM as warn, u as useSettings, a as useState, K as upscalerOptions, o as openBlock, c as createBlock, w as withCtx, b as createBaseVNode, e as createVNode, f as unref, j as NSpace, m as NSelect, g as createElementBlock, k as createTextVNode, l as NTooltip, h as createCommentVNode, N as NCard, F as Fragment, L as renderList, z as NButton, B as toDisplayString, bA as convertToTextString, bI as resolveDynamicComponent, bf as NModal, A as NIcon } from "./index.js"; +import { N as NSwitch } from "./Switch.js"; import { N as NSlider } from "./Slider.js"; +import { N as NInputNumber } from "./InputNumber.js"; +import { S as Settings, a as NCheckbox } from "./Settings.js"; function useInjectionInstanceCollection(injectionName, collectionKey, registerKeyRef) { var _a; const injection = inject(injectionName, null); @@ -1839,17 +1840,214 @@ const NFormItem = defineComponent({ ); } }); -const _hoisted_1 = { class: "flex-container" }; -const _hoisted_2 = { style: { "margin-left": "12px", "margin-right": "12px", "white-space": "nowrap" } }; -const _hoisted_3 = /* @__PURE__ */ createBaseVNode("p", { style: { "margin-right": "12px", "width": "100px" } }, "Sampler", -1); -const _hoisted_4 = /* @__PURE__ */ createBaseVNode("a", { +const _hoisted_1$2 = { class: "flex-container" }; +const _hoisted_2$2 = /* @__PURE__ */ createBaseVNode("div", { class: "slider-label" }, [ + /* @__PURE__ */ createBaseVNode("p", null, "Enabled") +], -1); +const _hoisted_3$2 = { class: "flex-container" }; +const _hoisted_4$2 = /* @__PURE__ */ createBaseVNode("div", { class: "slider-label" }, [ + /* @__PURE__ */ createBaseVNode("p", null, "Mode") +], -1); +const _hoisted_5$2 = { key: 0 }; +const _hoisted_6$2 = { class: "flex-container" }; +const _hoisted_7$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Upscaler", -1); +const _hoisted_8$1 = { key: 1 }; +const _hoisted_9$1 = { class: "flex-container" }; +const _hoisted_10$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Antialiased", -1); +const _hoisted_11 = { class: "flex-container" }; +const _hoisted_12 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Latent Mode", -1); +const _hoisted_13 = { class: "flex-container" }; +const _hoisted_14 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Steps", -1); +const _hoisted_15 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "We recommend using 20-50 steps for most images.", -1); +const _hoisted_16 = { class: "flex-container" }; +const _hoisted_17 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Scale", -1); +const _hoisted_18 = { class: "flex-container" }; +const _hoisted_19 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Strength", -1); +const _sfc_main$2 = /* @__PURE__ */ defineComponent({ + __name: "HighResFix", + props: { + tab: { + type: String, + required: true + }, + target: { + type: String, + required: false, + default: "settings" + } + }, + setup(__props) { + const props = __props; + const settings = useSettings(); + const global = useState(); + const target = computed(() => { + if (props.target === "settings") { + return settings.data.settings; + } + return settings.defaultSettings; + }); + const imageUpscalerOptions = computed(() => { + const localModels = global.state.models.filter( + (model) => model.backend === "Upscaler" && !(upscalerOptions.map((option) => option.label).indexOf(model.name) !== -1) + ).map((model) => ({ + label: model.name, + value: model.path + })); + return [...upscalerOptions, ...localModels]; + }); + const latentUpscalerOptions = [ + { label: "Nearest", value: "nearest" }, + { label: "Nearest exact", value: "nearest-exact" }, + { label: "Area", value: "area" }, + { label: "Bilinear", value: "bilinear" }, + { label: "Bicubic", value: "bicubic" }, + { label: "Bislerp", value: "bislerp" } + ]; + return (_ctx, _cache) => { + return openBlock(), createBlock(unref(NCard), { + title: "Highres fix", + class: "generate-extra-card" + }, { + default: withCtx(() => [ + createBaseVNode("div", _hoisted_1$2, [ + _hoisted_2$2, + createVNode(unref(NSwitch), { + value: target.value[props.tab].highres.enabled, + "onUpdate:value": _cache[0] || (_cache[0] = ($event) => target.value[props.tab].highres.enabled = $event) + }, null, 8, ["value"]) + ]), + target.value[props.tab].highres.enabled ? (openBlock(), createBlock(unref(NSpace), { + key: 0, + vertical: "", + class: "left-container" + }, { + default: withCtx(() => [ + createBaseVNode("div", _hoisted_3$2, [ + _hoisted_4$2, + createVNode(unref(NSelect), { + value: target.value[props.tab].highres.mode, + "onUpdate:value": _cache[1] || (_cache[1] = ($event) => target.value[props.tab].highres.mode = $event), + options: [ + { label: "Latent", value: "latent" }, + { label: "Image", value: "image" } + ] + }, null, 8, ["value"]) + ]), + target.value[props.tab].highres.mode === "image" ? (openBlock(), createElementBlock("div", _hoisted_5$2, [ + createBaseVNode("div", _hoisted_6$2, [ + _hoisted_7$2, + createVNode(unref(NSelect), { + value: target.value[props.tab].highres.image_upscaler, + "onUpdate:value": _cache[2] || (_cache[2] = ($event) => target.value[props.tab].highres.image_upscaler = $event), + size: "small", + style: { "flex-grow": "1" }, + filterable: "", + options: imageUpscalerOptions.value + }, null, 8, ["value", "options"]) + ]) + ])) : (openBlock(), createElementBlock("div", _hoisted_8$1, [ + createBaseVNode("div", _hoisted_9$1, [ + _hoisted_10$1, + createVNode(unref(NSwitch), { + value: target.value[props.tab].highres.antialiased, + "onUpdate:value": _cache[3] || (_cache[3] = ($event) => target.value[props.tab].highres.antialiased = $event) + }, null, 8, ["value"]) + ]), + createBaseVNode("div", _hoisted_11, [ + _hoisted_12, + createVNode(unref(NSelect), { + value: target.value[props.tab].highres.latent_scale_mode, + "onUpdate:value": _cache[4] || (_cache[4] = ($event) => target.value[props.tab].highres.latent_scale_mode = $event), + size: "small", + style: { "flex-grow": "1" }, + filterable: "", + options: latentUpscalerOptions + }, null, 8, ["value"]) + ]) + ])), + createBaseVNode("div", _hoisted_13, [ + createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { + trigger: withCtx(() => [ + _hoisted_14 + ]), + default: withCtx(() => [ + createTextVNode(" Number of steps to take in the diffusion process. Higher values will result in more detailed images but will take longer to generate. There is also a point of diminishing returns around 100 steps. "), + _hoisted_15 + ]), + _: 1 + }), + createVNode(unref(NSlider), { + value: target.value[props.tab].highres.steps, + "onUpdate:value": _cache[5] || (_cache[5] = ($event) => target.value[props.tab].highres.steps = $event), + min: 5, + max: 300, + style: { "margin-right": "12px" } + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: target.value[props.tab].highres.steps, + "onUpdate:value": _cache[6] || (_cache[6] = ($event) => target.value[props.tab].highres.steps = $event), + size: "small", + style: { "min-width": "96px", "width": "96px" } + }, null, 8, ["value"]) + ]), + createBaseVNode("div", _hoisted_16, [ + _hoisted_17, + createVNode(unref(NSlider), { + value: target.value[props.tab].highres.scale, + "onUpdate:value": _cache[7] || (_cache[7] = ($event) => target.value[props.tab].highres.scale = $event), + min: 1, + max: 8, + step: 0.1, + style: { "margin-right": "12px" } + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: target.value[props.tab].highres.scale, + "onUpdate:value": _cache[8] || (_cache[8] = ($event) => target.value[props.tab].highres.scale = $event), + size: "small", + style: { "min-width": "96px", "width": "96px" }, + step: 0.1 + }, null, 8, ["value"]) + ]), + createBaseVNode("div", _hoisted_18, [ + _hoisted_19, + createVNode(unref(NSlider), { + value: target.value[props.tab].highres.strength, + "onUpdate:value": _cache[9] || (_cache[9] = ($event) => target.value[props.tab].highres.strength = $event), + min: 0.1, + max: 0.9, + step: 0.05, + style: { "margin-right": "12px" } + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: target.value[props.tab].highres.strength, + "onUpdate:value": _cache[10] || (_cache[10] = ($event) => target.value[props.tab].highres.strength = $event), + size: "small", + style: { "min-width": "96px", "width": "96px" }, + min: 0.1, + max: 0.9, + step: 0.05 + }, null, 8, ["value"]) + ]) + ]), + _: 1 + })) : createCommentVNode("", true) + ]), + _: 1 + }); + }; + } +}); +const _hoisted_1$1 = { class: "flex-container" }; +const _hoisted_2$1 = { style: { "margin-left": "12px", "margin-right": "12px", "white-space": "nowrap" } }; +const _hoisted_3$1 = /* @__PURE__ */ createBaseVNode("p", { style: { "margin-right": "12px", "width": "100px" } }, "Sampler", -1); +const _hoisted_4$1 = /* @__PURE__ */ createBaseVNode("a", { target: "_blank", href: "https://docs.google.com/document/d/1n0YozLAUwLJWZmbsx350UD_bwAx3gZMnRuleIZt_R1w" }, "Learn more", -1); -const _hoisted_5 = { class: "flex-container" }; -const _hoisted_6 = /* @__PURE__ */ createBaseVNode("p", { style: { "margin-right": "12px", "width": "94px" } }, "Sigmas", -1); -const _hoisted_7 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, 'Only "Default" and "Karras" sigmas work on diffusers samplers (and "Karras" are only applied to KDPM samplers)', -1); -const _sfc_main = /* @__PURE__ */ defineComponent({ +const _hoisted_5$1 = { class: "flex-container" }; +const _hoisted_6$1 = /* @__PURE__ */ createBaseVNode("p", { style: { "margin-right": "12px", "width": "94px" } }, "Sigmas", -1); +const _hoisted_7$1 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, 'Only "Default" and "Karras" sigmas work on diffusers samplers (and "Karras" are only applied to KDPM samplers)', -1); +const _sfc_main$1 = /* @__PURE__ */ defineComponent({ __name: "SamplerPicker", props: { type: { @@ -1953,7 +2151,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({ }); return (_ctx, _cache) => { return openBlock(), createElementBlock(Fragment, null, [ - createBaseVNode("div", _hoisted_1, [ + createBaseVNode("div", _hoisted_1$1, [ createVNode(unref(NModal), { show: showModal.value, "onUpdate:show": _cache[1] || (_cache[1] = ($event) => showModal.value = $event), @@ -1985,7 +2183,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({ ]), _: 2 }, 1032, ["type", "disabled", "onClick"]), - createBaseVNode("p", _hoisted_2, toDisplayString(unref(convertToTextString)(param)), 1), + createBaseVNode("p", _hoisted_2$1, toDisplayString(unref(convertToTextString)(param)), 1), (openBlock(), createBlock(resolveDynamicComponent( resolveComponent( target.value.sampler_config["ui_settings"][param], @@ -2002,11 +2200,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({ }, 8, ["show"]), createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { trigger: withCtx(() => [ - _hoisted_3 + _hoisted_3$1 ]), default: withCtx(() => [ createTextVNode(" The sampler is the method used to generate the image. Your result may vary drastically depending on the sampler you choose. "), - _hoisted_4 + _hoisted_4$1 ]), _: 1 }), @@ -2032,14 +2230,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({ _: 1 }) ]), - createBaseVNode("div", _hoisted_5, [ + createBaseVNode("div", _hoisted_5$1, [ createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { trigger: withCtx(() => [ - _hoisted_6 + _hoisted_6$1 ]), default: withCtx(() => [ createTextVNode(" Changes the sigmas used in the diffusion process. Can change the quality of the output. "), - _hoisted_7 + _hoisted_7$1 ]), _: 1 }), @@ -2054,8 +2252,167 @@ const _sfc_main = /* @__PURE__ */ defineComponent({ }; } }); +const _hoisted_1 = { class: "flex-container" }; +const _hoisted_2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Enabled", -1); +const _hoisted_3 = { class: "flex-container" }; +const _hoisted_4 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Model", -1); +const _hoisted_5 = { class: "flex-container" }; +const _hoisted_6 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Scale Factor", -1); +const _hoisted_7 = { class: "flex-container" }; +const _hoisted_8 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Tile Size", -1); +const _hoisted_9 = { class: "flex-container" }; +const _hoisted_10 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Tile Padding", -1); +const _sfc_main = /* @__PURE__ */ defineComponent({ + __name: "Upscale", + props: { + tab: { + type: String, + required: true + }, + target: { + type: String, + required: false, + default: "settings" + } + }, + setup(__props) { + const props = __props; + const global = useState(); + const settings = useSettings(); + const target = computed(() => { + if (props.target === "settings") { + return settings.data.settings; + } + return settings.defaultSettings; + }); + const upscalerOptionsFull = computed(() => { + const localModels = global.state.models.filter( + (model) => model.backend === "Upscaler" && !(upscalerOptions.map((option) => option.label).indexOf(model.name) !== -1) + ).map((model) => ({ + label: model.name, + value: model.path + })); + return [...upscalerOptions, ...localModels]; + }); + return (_ctx, _cache) => { + return openBlock(), createBlock(unref(NCard), { + title: "Upscale", + class: "generate-extra-card" + }, { + default: withCtx(() => [ + createBaseVNode("div", _hoisted_1, [ + _hoisted_2, + createVNode(unref(NSwitch), { + value: target.value[props.tab].upscale.enabled, + "onUpdate:value": _cache[0] || (_cache[0] = ($event) => target.value[props.tab].upscale.enabled = $event) + }, null, 8, ["value"]) + ]), + target.value[props.tab].upscale.enabled ? (openBlock(), createBlock(unref(NSpace), { + key: 0, + vertical: "", + class: "left-container" + }, { + default: withCtx(() => [ + createBaseVNode("div", _hoisted_3, [ + _hoisted_4, + createVNode(unref(NSelect), { + value: target.value[props.tab].upscale.model, + "onUpdate:value": _cache[1] || (_cache[1] = ($event) => target.value[props.tab].upscale.model = $event), + style: { "margin-right": "12px" }, + filterable: "", + tag: "", + options: upscalerOptionsFull.value + }, null, 8, ["value", "options"]) + ]), + createBaseVNode("div", _hoisted_5, [ + createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { + trigger: withCtx(() => [ + _hoisted_6 + ]), + default: withCtx(() => [ + createTextVNode(" TODO ") + ]), + _: 1 + }), + createVNode(unref(NSlider), { + value: target.value[props.tab].upscale.upscale_factor, + "onUpdate:value": _cache[2] || (_cache[2] = ($event) => target.value[props.tab].upscale.upscale_factor = $event), + min: 1, + max: 4, + step: 0.1, + style: { "margin-right": "12px" } + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: target.value[props.tab].upscale.upscale_factor, + "onUpdate:value": _cache[3] || (_cache[3] = ($event) => target.value[props.tab].upscale.upscale_factor = $event), + size: "small", + style: { "min-width": "96px", "width": "96px" }, + min: 1, + max: 4, + step: 0.1 + }, null, 8, ["value"]) + ]), + createBaseVNode("div", _hoisted_7, [ + createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { + trigger: withCtx(() => [ + _hoisted_8 + ]), + default: withCtx(() => [ + createTextVNode(" How large each tile should be. Larger tiles will use more memory. 0 will disable tiling. ") + ]), + _: 1 + }), + createVNode(unref(NSlider), { + value: target.value[props.tab].upscale.tile_size, + "onUpdate:value": _cache[4] || (_cache[4] = ($event) => target.value[props.tab].upscale.tile_size = $event), + min: 32, + max: 2048, + style: { "margin-right": "12px" } + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: target.value[props.tab].upscale.tile_size, + "onUpdate:value": _cache[5] || (_cache[5] = ($event) => target.value[props.tab].upscale.tile_size = $event), + size: "small", + min: 32, + max: 2048, + style: { "min-width": "96px", "width": "96px" } + }, null, 8, ["value"]) + ]), + createBaseVNode("div", _hoisted_9, [ + createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { + trigger: withCtx(() => [ + _hoisted_10 + ]), + default: withCtx(() => [ + createTextVNode(" How much should tiles overlap. Larger padding will use more memory, but image should not have visible seams. ") + ]), + _: 1 + }), + createVNode(unref(NSlider), { + value: target.value[props.tab].upscale.tile_padding, + "onUpdate:value": _cache[6] || (_cache[6] = ($event) => target.value[props.tab].upscale.tile_padding = $event), + style: { "margin-right": "12px" } + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: target.value[props.tab].upscale.tile_padding, + "onUpdate:value": _cache[7] || (_cache[7] = ($event) => target.value[props.tab].upscale.tile_padding = $event), + size: "small", + style: { "min-width": "96px", "width": "96px" } + }, null, 8, ["value"]) + ]) + ]), + _: 1 + })) : createCommentVNode("", true) + ]), + _: 1 + }); + }; + } +}); export { NForm as N, - _sfc_main as _, - NFormItem as a + _sfc_main$1 as _, + _sfc_main$2 as a, + _sfc_main as b, + NFormItem as c }; diff --git a/frontend/dist/assets/clock.js b/frontend/dist/assets/clock.js index 06e27eb87..22e746768 100644 --- a/frontend/dist/assets/clock.js +++ b/frontend/dist/assets/clock.js @@ -5,10 +5,10 @@ var __publicField = (obj, key, value) => { return value; }; import { N as NDescriptionsItem, a as NDescriptions } from "./DescriptionsItem.js"; -import { d as defineComponent, o as openBlock, j as createElementBlock, f as createBaseVNode, e as createBlock, w as withCtx, g as createVNode, h as unref, k as createTextVNode, C as toDisplayString, n as NCard, m as createCommentVNode, u as useSettings, l as NTooltip, F as Fragment, a as useState, c as computed, G as spaceRegex, B as NIcon, i as NSelect, H as promptHandleKeyUp, I as promptHandleKeyDown, J as NInput, _ as _export_sfc, K as watch, z as ref, t as serverUrl } from "./index.js"; +import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, c as createBlock, w as withCtx, e as createVNode, f as unref, k as createTextVNode, B as toDisplayString, N as NCard, h as createCommentVNode, u as useSettings, l as NTooltip, i as computed, F as Fragment, a as useState, E as spaceRegex, A as NIcon, m as NSelect, G as promptHandleKeyUp, H as promptHandleKeyDown, I as NInput, _ as _export_sfc, J as watch, y as ref, s as serverUrl } from "./index.js"; import { N as NSlider } from "./Slider.js"; import { N as NInputNumber } from "./InputNumber.js"; -import { N as NForm, a as NFormItem } from "./SamplerPicker.vue_vue_type_script_setup_true_lang.js"; +import { N as NForm, c as NFormItem } from "./Upscale.vue_vue_type_script_setup_true_lang.js"; import { N as NSwitch } from "./Switch.js"; const _hoisted_1$4 = { xmlns: "http://www.w3.org/2000/svg", @@ -148,12 +148,66 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({ }; } }); -const _hoisted_1$2 = { +const _hoisted_1$2 = { class: "flex-container" }; +const _hoisted_2$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "CFG Scale", -1); +const _hoisted_3$1 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "We recommend using 3-15 for most images.", -1); +const _sfc_main$3 = /* @__PURE__ */ defineComponent({ + __name: "CFGScaleInput", + props: { + tab: { + type: String, + required: true + } + }, + setup(__props) { + const props = __props; + const settings = useSettings(); + const cfgMax = computed(() => { + var scale = 30; + return scale + Math.max( + settings.defaultSettings.api.apply_unsharp_mask ? 15 : 0, + settings.defaultSettings.api.cfg_rescale_threshold == "off" ? 0 : 30 + ); + }); + return (_ctx, _cache) => { + return openBlock(), createElementBlock("div", _hoisted_1$2, [ + createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { + trigger: withCtx(() => [ + _hoisted_2$2 + ]), + default: withCtx(() => [ + createTextVNode(" Guidance scale indicates how close should the model stay to the prompt. Higher values might be exactly what you want, but generated images might have some artifacts. Lower values give the model more freedom, and therefore might produce more coherent/less-artifacty images, but wouldn't follow the prompt as closely. "), + _hoisted_3$1 + ]), + _: 1 + }), + createVNode(unref(NSlider), { + value: unref(settings).data.settings[props.tab].cfg_scale, + "onUpdate:value": _cache[0] || (_cache[0] = ($event) => unref(settings).data.settings[props.tab].cfg_scale = $event), + min: 1, + max: cfgMax.value, + step: 0.5, + style: { "margin-right": "12px" } + }, null, 8, ["value", "max"]), + createVNode(unref(NInputNumber), { + value: unref(settings).data.settings[props.tab].cfg_scale, + "onUpdate:value": _cache[1] || (_cache[1] = ($event) => unref(settings).data.settings[props.tab].cfg_scale = $event), + size: "small", + style: { "min-width": "96px", "width": "96px" }, + min: 1, + max: cfgMax.value, + step: 0.5 + }, null, 8, ["value", "max"]) + ]); + }; + } +}); +const _hoisted_1$1 = { key: 0, class: "flex-container" }; -const _hoisted_2$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Width", -1); -const _hoisted_3$1 = { +const _hoisted_2$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Width", -1); +const _hoisted_3 = { key: 1, class: "flex-container" }; @@ -168,7 +222,7 @@ const _hoisted_7 = { class: "flex-container" }; const _hoisted_8 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Height", -1); -const _sfc_main$3 = /* @__PURE__ */ defineComponent({ +const _sfc_main$2 = /* @__PURE__ */ defineComponent({ __name: "DimensionsInput", props: { dimensionsObject: { @@ -181,8 +235,8 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ const settings = useSettings(); return (_ctx, _cache) => { return openBlock(), createElementBlock(Fragment, null, [ - unref(settings).data.settings.aitDim.width ? (openBlock(), createElementBlock("div", _hoisted_1$2, [ - _hoisted_2$2, + unref(settings).data.settings.aitDim.width ? (openBlock(), createElementBlock("div", _hoisted_1$1, [ + _hoisted_2$1, createVNode(unref(NSlider), { value: props.dimensionsObject.width, "onUpdate:value": _cache[0] || (_cache[0] = ($event) => props.dimensionsObject.width = $event), @@ -200,7 +254,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ max: unref(settings).data.settings.aitDim.width[1], step: 64 }, null, 8, ["value", "min", "max"]) - ])) : (openBlock(), createElementBlock("div", _hoisted_3$1, [ + ])) : (openBlock(), createElementBlock("div", _hoisted_3, [ _hoisted_4, createVNode(unref(NSlider), { value: props.dimensionsObject.width, @@ -259,7 +313,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ }; } }); -const _sfc_main$2 = /* @__PURE__ */ defineComponent({ +const _sfc_main$1 = /* @__PURE__ */ defineComponent({ __name: "Prompt", props: { tab: { @@ -412,61 +466,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ }; } }); -const Prompt = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-780680bc"]]); -const _hoisted_1$1 = { class: "flex-container" }; -const _hoisted_2$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "CFG Scale", -1); -const _hoisted_3 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "We recommend using 3-15 for most images.", -1); -const _sfc_main$1 = /* @__PURE__ */ defineComponent({ - __name: "CFGScaleInput", - props: { - tab: { - type: String, - required: true - } - }, - setup(__props) { - const props = __props; - const settings = useSettings(); - const cfgMax = computed(() => { - var scale = 30; - return scale + Math.max( - settings.defaultSettings.api.apply_unsharp_mask ? 15 : 0, - settings.defaultSettings.api.cfg_rescale_threshold == "off" ? 0 : 30 - ); - }); - return (_ctx, _cache) => { - return openBlock(), createElementBlock("div", _hoisted_1$1, [ - createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { - trigger: withCtx(() => [ - _hoisted_2$1 - ]), - default: withCtx(() => [ - createTextVNode(" Guidance scale indicates how close should the model stay to the prompt. Higher values might be exactly what you want, but generated images might have some artifacts. Lower values give the model more freedom, and therefore might produce more coherent/less-artifacty images, but wouldn't follow the prompt as closely. "), - _hoisted_3 - ]), - _: 1 - }), - createVNode(unref(NSlider), { - value: unref(settings).data.settings[props.tab].cfg_scale, - "onUpdate:value": _cache[0] || (_cache[0] = ($event) => unref(settings).data.settings[props.tab].cfg_scale = $event), - min: 1, - max: cfgMax.value, - step: 0.5, - style: { "margin-right": "12px" } - }, null, 8, ["value", "max"]), - createVNode(unref(NInputNumber), { - value: unref(settings).data.settings[props.tab].cfg_scale, - "onUpdate:value": _cache[1] || (_cache[1] = ($event) => unref(settings).data.settings[props.tab].cfg_scale = $event), - size: "small", - style: { "min-width": "96px", "width": "96px" }, - min: 1, - max: cfgMax.value, - step: 0.5 - }, null, 8, ["value", "max"]) - ]); - }; - } -}); +const Prompt = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-780680bc"]]); const _hoisted_1 = { key: 0, class: "flex-container" @@ -586,8 +586,8 @@ class BurnerClock { export { BurnerClock as B, Prompt as P, - _sfc_main$3 as _, - _sfc_main$1 as a, + _sfc_main$2 as _, + _sfc_main$3 as a, _sfc_main as b, _sfc_main$4 as c, _sfc_main$5 as d diff --git a/frontend/dist/assets/index.css b/frontend/dist/assets/index.css index 89024e3b7..4da72df34 100644 --- a/frontend/dist/assets/index.css +++ b/frontend/dist/assets/index.css @@ -85,52 +85,39 @@ margin-bottom: 10px; } -.image-container img[data-v-5358ed01] { +.image-container img[data-v-97c56df6] { width: 100%; height: 100%; object-fit: contain; overflow: hidden; } -.image-container[data-v-5358ed01] { +.image-container[data-v-97c56df6] { height: 70vh; width: 100%; display: flex; justify-content: center; } -.image-container img[data-v-95a354be] { +.image-container img[data-v-bfd46a0a] { width: 100%; height: 100%; object-fit: contain; overflow: hidden; } -.image-container[data-v-95a354be] { +.image-container[data-v-bfd46a0a] { height: 70vh; width: 100%; display: flex; justify-content: center; } -.image-container img[data-v-116492bf] { - width: 100%; - height: 100%; - object-fit: contain; - overflow: hidden; -} -.image-container[data-v-116492bf] { - height: 70vh; - width: 100%; - display: flex; - justify-content: center; -} - -.hidden-input[data-v-6961892e] { +.hidden-input[data-v-1193df1f] { display: none; } -.utility-button[data-v-6961892e] { +.utility-button[data-v-1193df1f] { margin-right: 8px; } -.file-upload[data-v-6961892e] { +.file-upload[data-v-1193df1f] { appearance: none; background-color: transparent; border: 1px solid #63e2b7; @@ -150,21 +137,21 @@ vertical-align: middle; white-space: nowrap; } -.file-upload[data-v-6961892e]:focus:not(:focus-visible):not(.focus-visible) { +.file-upload[data-v-1193df1f]:focus:not(:focus-visible):not(.focus-visible) { box-shadow: none; outline: none; } -.file-upload[data-v-6961892e]:focus { +.file-upload[data-v-1193df1f]:focus { box-shadow: rgba(46, 164, 79, 0.4) 0 0 0 3px; outline: none; } -.file-upload[data-v-6961892e]:disabled { +.file-upload[data-v-1193df1f]:disabled { background-color: #94d3a2; border-color: rgba(27, 31, 35, 0.1); color: rgba(255, 255, 255, 0.8); cursor: default; } -.image-container[data-v-6961892e] { +.image-container[data-v-1193df1f] { width: 100%; display: flex; justify-content: center; diff --git a/frontend/dist/assets/index.js b/frontend/dist/assets/index.js index 212d1b142..4834cc80e 100644 --- a/frontend/dist/assets/index.js +++ b/frontend/dist/assets/index.js @@ -40687,665 +40687,6 @@ var ControlNetType = /* @__PURE__ */ ((ControlNetType2) => { ControlNetType2["SEGMENTATION"] = "lllyasviel/sd-controlnet-seg"; return ControlNetType2; })(ControlNetType || {}); -const defaultSettings = { - $schema: "./schema/ui_data/settings.json", - backend: "PyTorch", - model: null, - flags: { - sdxl: { - original_size: { - width: 1024, - height: 1024 - } - }, - highres: { - image_upscaler: "RealESRGAN_x4plus_anime_6B", - mode: "latent", - scale: 2, - latent_scale_mode: "bislerp", - strength: 0.7, - steps: 50, - antialiased: false - }, - refiner: { - model: void 0, - aesthetic_score: 6, - negative_aesthetic_score: 2.5, - steps: 50, - strength: 0.3 - } - }, - aitDim: { - width: void 0, - height: void 0, - batch_size: void 0 - }, - txt2img: { - width: 512, - height: 512, - seed: -1, - cfg_scale: 7, - sampler: 8, - prompt: "", - steps: 25, - batch_count: 1, - batch_size: 1, - negative_prompt: "", - self_attention_scale: 0, - sigmas: "automatic" - }, - img2img: { - width: 512, - height: 512, - seed: -1, - cfg_scale: 7, - sampler: 8, - prompt: "", - steps: 25, - batch_count: 1, - batch_size: 1, - negative_prompt: "", - denoising_strength: 0.6, - image: "", - self_attention_scale: 0, - sigmas: "automatic" - }, - inpainting: { - prompt: "", - negative_prompt: "", - image: "", - mask_image: "", - width: 512, - height: 512, - steps: 25, - cfg_scale: 7, - seed: -1, - batch_count: 1, - batch_size: 1, - sampler: 8, - self_attention_scale: 0, - sigmas: "automatic" - }, - controlnet: { - prompt: "", - image: "", - sampler: 8, - controlnet: ControlNetType.CANNY, - negative_prompt: "", - width: 512, - height: 512, - steps: 25, - cfg_scale: 7, - seed: -1, - batch_size: 1, - batch_count: 1, - controlnet_conditioning_scale: 1, - detection_resolution: 512, - is_preprocessed: false, - save_preprocessed: false, - return_preprocessed: true, - self_attention_scale: 0, - sigmas: "automatic" - }, - upscale: { - image: "", - upscale_factor: 4, - model: "RealESRGAN_x4plus_anime_6B", - tile_size: 128, - tile_padding: 10 - }, - tagger: { - image: "", - model: "deepdanbooru", - threshold: 0.5 - }, - api: { - websocket_sync_interval: 0.02, - websocket_perf_interval: 1, - enable_websocket_logging: true, - clip_skip: 1, - clip_quantization: "full", - autocast: true, - attention_processor: "xformers", - subquadratic_size: 512, - attention_slicing: "disabled", - channels_last: true, - trace_model: false, - cudnn_benchmark: false, - offload: "disabled", - dont_merge_latents: false, - device: "cuda:0", - data_type: "float16", - use_tomesd: true, - tomesd_ratio: 0.4, - tomesd_downsample_layers: 1, - deterministic_generation: false, - reduced_precision: false, - clear_memory_policy: "always", - huggingface_style_parsing: false, - autoloaded_textual_inversions: [], - autoloaded_models: [], - autoloaded_vae: {}, - save_path_template: "{folder}/{prompt}/{id}-{index}.{extension}", - image_extension: "png", - image_quality: 95, - disable_grid: false, - torch_compile: false, - torch_compile_fullgraph: false, - torch_compile_dynamic: false, - torch_compile_backend: "inductor", - torch_compile_mode: "default", - sfast_compile: false, - sfast_xformers: true, - sfast_triton: true, - sfast_cuda_graph: false, - hypertile: false, - hypertile_unet_chunk: 256, - sgm_noise_multiplier: false, - kdiffusers_quantization: true, - xl_refiner: "joint", - generator: "device", - live_preview_method: "approximation", - live_preview_delay: 2, - upcast_vae: false, - vae_slicing: false, - vae_tiling: false, - apply_unsharp_mask: false, - cfg_rescale_threshold: 10, - prompt_to_prompt: false, - prompt_to_prompt_model: "lllyasviel/Fooocus-Expansion", - prompt_to_prompt_device: "gpu", - free_u: false, - free_u_s1: 0.9, - free_u_s2: 0.2, - free_u_b1: 1.2, - free_u_b2: 1.4 - }, - aitemplate: { - num_threads: 8 - }, - onnx: { - quant_dict: { - text_encoder: null, - unet: null, - vae_decoder: null, - vae_encoder: null - }, - convert_to_fp16: true, - simplify_unet: false - }, - bot: { - default_scheduler: 8, - verbose: false, - use_default_negative_prompt: true - }, - frontend: { - theme: "dark", - enable_theme_editor: false, - image_browser_columns: 5, - on_change_timer: 2e3, - nsfw_ok_threshold: 0, - background_image_override: "", - disable_analytics: true - }, - sampler_config: {} -}; -let rSettings = JSON.parse(JSON.stringify(defaultSettings)); -try { - const req = new XMLHttpRequest(); - req.open("GET", `${serverUrl}/api/settings/`, false); - req.send(); - rSettings = { ...rSettings, ...JSON.parse(req.responseText) }; -} catch (e) { - console.error(e); -} -console.log("Settings:", rSettings); -const recievedSettings = rSettings; -class Settings { - constructor(settings_override) { - __publicField(this, "settings"); - this.settings = { ...defaultSettings, ...settings_override }; - } - to_json() { - return JSON.stringify(this.settings); - } -} -const diffusersSchedulerTuple = { - DDIM: 1, - DDPM: 2, - PNDM: 3, - LMSD: 4, - EulerDiscrete: 5, - HeunDiscrete: 6, - EulerAncestralDiscrete: 7, - DPMSolverMultistep: 8, - DPMSolverSinglestep: 9, - KDPM2Discrete: 10, - KDPM2AncestralDiscrete: 11, - DEISMultistep: 12, - UniPCMultistep: 13, - DPMSolverSDEScheduler: 14 -}; -const upscalerOptions = [ - { - label: "RealESRGAN_x4plus", - value: "RealESRGAN_x4plus" - }, - { - label: "RealESRNet_x4plus", - value: "RealESRNet_x4plus" - }, - { - label: "RealESRGAN_x4plus_anime_6B", - value: "RealESRGAN_x4plus_anime_6B" - }, - { - label: "RealESRGAN_x2plus", - value: "RealESRGAN_x2plus" - }, - { - label: "RealESR-general-x4v3", - value: "RealESR-general-x4v3" - } -]; -function getSchedulerOptions() { - const scheduler_options = [ - { - type: "group", - label: "k-diffusion", - key: "K-Diffusion", - children: [ - { label: "Euler a", value: "euler_a" }, - { label: "Euler", value: "euler" }, - { label: "LMS", value: "lms" }, - { label: "Heun", value: "heun" }, - { label: "Heun++", value: "heunpp" }, - { label: "DPM Fast", value: "dpm_fast" }, - { label: "DPM Adaptive", value: "dpm_adaptive" }, - { label: "DPM2", value: "dpm2" }, - { label: "DPM2 a", value: "dpm2_a" }, - { label: "DPM++ 2S a", value: "dpmpp_2s_a" }, - { label: "DPM++ 2M", value: "dpmpp_2m" }, - { label: "DPM++ 2M Sharp", value: "dpmpp_2m_sharp" }, - { label: "DPM++ SDE", value: "dpmpp_sde" }, - { label: "DPM++ 2M SDE", value: "dpmpp_2m_sde" }, - { label: "DPM++ 3M SDE", value: "dpmpp_3m_sde" }, - { label: "UniPC Multistep", value: "unipc_multistep" }, - { label: "Restart", value: "restart" } - ] - }, - { - type: "group", - label: "Diffusers", - key: "diffusers", - children: Object.keys(diffusersSchedulerTuple).map((key) => { - return { - label: key, - value: diffusersSchedulerTuple[key] - }; - }) - } - ]; - return scheduler_options; -} -function getControlNetOptions() { - const controlnet_options = [ - { - type: "group", - label: "ControlNet 1.1", - key: "ControlNet 1.1", - children: [ - { - label: "lllyasviel/control_v11p_sd15_canny", - value: "lllyasviel/control_v11p_sd15_canny" - }, - { - label: "lllyasviel/control_v11f1p_sd15_depth", - value: "lllyasviel/control_v11f1p_sd15_depth" - }, - { - label: "lllyasviel/control_v11e_sd15_ip2p", - value: "lllyasviel/control_v11e_sd15_ip2p" - }, - { - label: "lllyasviel/control_v11p_sd15_softedge", - value: "lllyasviel/control_v11p_sd15_softedge" - }, - { - label: "lllyasviel/control_v11p_sd15_openpose", - value: "lllyasviel/control_v11p_sd15_openpose" - }, - { - label: "lllyasviel/control_v11f1e_sd15_tile", - value: "lllyasviel/control_v11f1e_sd15_tile" - }, - { - label: "lllyasviel/control_v11p_sd15_mlsd", - value: "lllyasviel/control_v11p_sd15_mlsd" - }, - { - label: "lllyasviel/control_v11p_sd15_scribble", - value: "lllyasviel/control_v11p_sd15_scribble" - }, - { - label: "lllyasviel/control_v11p_sd15_seg", - value: "lllyasviel/control_v11p_sd15_seg" - } - ] - }, - { - type: "group", - label: "Special", - key: "Special", - children: [ - { - label: "DionTimmer/controlnet_qrcode", - value: "DionTimmer/controlnet_qrcode" - }, - { - label: "CrucibleAI/ControlNetMediaPipeFace", - value: "CrucibleAI/ControlNetMediaPipeFace" - } - ] - }, - { - type: "group", - label: "Original", - key: "Original", - children: [ - { - label: "lllyasviel/sd-controlnet-canny", - value: "lllyasviel/sd-controlnet-canny" - }, - { - label: "lllyasviel/sd-controlnet-depth", - value: "lllyasviel/sd-controlnet-depth" - }, - { - label: "lllyasviel/sd-controlnet-hed", - value: "lllyasviel/sd-controlnet-hed" - }, - { - label: "lllyasviel/sd-controlnet-mlsd", - value: "lllyasviel/sd-controlnet-mlsd" - }, - { - label: "lllyasviel/sd-controlnet-normal", - value: "lllyasviel/sd-controlnet-normal" - }, - { - label: "lllyasviel/sd-controlnet-openpose", - value: "lllyasviel/sd-controlnet-openpose" - }, - { - label: "lllyasviel/sd-controlnet-scribble", - value: "lllyasviel/sd-controlnet-scribble" - }, - { - label: "lllyasviel/sd-controlnet-seg", - value: "lllyasviel/sd-controlnet-seg" - } - ] - } - ]; - return controlnet_options; -} -const deepcopiedSettings = JSON.parse(JSON.stringify(recievedSettings)); -const useSettings = defineStore("settings", () => { - const data = reactive(new Settings(recievedSettings)); - const scheduler_options = computed(() => { - return getSchedulerOptions(); - }); - const controlnet_options = computed(() => { - return getControlNetOptions(); - }); - function resetSettings() { - console.log("Resetting settings to default"); - Object.assign(defaultSettings$1, defaultSettings); - } - async function saveSettings() { - fetch(`${serverUrl}/api/settings/save`, { - method: "POST", - headers: { - "Content-Type": "application/json" - }, - body: JSON.stringify(defaultSettings$1) - }).then((res) => { - if (res.status === 200) { - console.log("Settings saved successfully"); - } else { - throw new Error("Failed to save settings"); - } - }); - } - const defaultSettings$1 = reactive(deepcopiedSettings); - return { - data, - scheduler_options, - controlnet_options, - defaultSettings: defaultSettings$1, - resetSettings, - saveSettings - }; -}); -const ImageUpload_vue_vue_type_style_index_0_scoped_9ed1514f_lang = ""; -const _export_sfc = (sfc, props) => { - const target = sfc.__vccOpts || sfc; - for (const [key, val] of props) { - target[key] = val; - } - return target; -}; -const _sfc_main$8 = /* @__PURE__ */ defineComponent({ - __name: "InitHandler", - setup(__props) { - console.log( - ` - ██╗ ██╗ █████╗ ██╗ ████████╗ █████╗ ███╗ ███╗██╗ - ██║ ██║██╔══██╗██║ ╚══██╔══╝██╔══██╗████╗ ████║██║ - ╚██╗ ██╔╝██║ ██║██║ ██║ ███████║██╔████╔██║██║ - ╚████╔╝ ██║ ██║██║ ██║ ██╔══██║██║╚██╔╝██║██║ - ╚██╔╝ ╚█████╔╝███████╗ ██║ ██║ ██║██║ ╚═╝ ██║███████╗ - ╚═╝ ╚════╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ - ` - ); - const global2 = useState2(); - global2.fetchCapabilites().then(() => { - console.log("Capabilities successfully fetched from the server"); - }); - global2.fetchAutofill(); - return (_ctx, _cache) => { - return null; - }; - } -}); -const _sfc_main$7 = /* @__PURE__ */ defineComponent({ - __name: "LogDrawer", - setup(__props) { - const glob = useState2(); - const log = computed(() => glob.state.log_drawer.logs.join("\n")); - return (_ctx, _cache) => { - return openBlock(), createBlock(unref(NDrawer), { - placement: "bottom", - show: unref(glob).state.log_drawer.enabled, - "onUpdate:show": _cache[0] || (_cache[0] = ($event) => unref(glob).state.log_drawer.enabled = $event), - "auto-focus": false, - "show-mask": true, - height: "70vh" - }, { - default: withCtx(() => [ - createVNode(unref(NDrawerContent), { - closable: "", - title: "Log - 500 latest messages" - }, { - default: withCtx(() => [ - createVNode(unref(NLog), { - ref: "logRef", - log: log.value, - trim: "", - style: { "height": "100%" } - }, null, 8, ["log"]) - ]), - _: 1 - }) - ]), - _: 1 - }, 8, ["show"]); - }; - } -}); -const _hoisted_1$4 = { style: { "width": "100%", "display": "inline-flex", "align-items": "center" } }; -const _hoisted_2$3 = /* @__PURE__ */ createBaseVNode("p", { style: { "width": "108px" } }, "Utilization", -1); -const _hoisted_3$2 = { style: { "width": "100%", "display": "inline-flex", "align-items": "center" } }; -const _hoisted_4$2 = /* @__PURE__ */ createBaseVNode("p", { style: { "width": "108px" } }, "Memory", -1); -const _hoisted_5$2 = { style: { "align-self": "flex-end", "margin-left": "12px" } }; -const _sfc_main$6 = /* @__PURE__ */ defineComponent({ - __name: "PerformanceDrawer", - setup(__props) { - const global2 = useState2(); - const glob = useState2(); - return (_ctx, _cache) => { - return openBlock(), createBlock(unref(NDrawer), { - placement: "bottom", - show: unref(glob).state.perf_drawer.enabled, - "onUpdate:show": _cache[0] || (_cache[0] = ($event) => unref(glob).state.perf_drawer.enabled = $event), - "auto-focus": false, - "show-mask": true, - height: "70vh" - }, { - default: withCtx(() => [ - createVNode(unref(NDrawerContent), { - closable: "", - title: "Performance statistics" - }, { - default: withCtx(() => [ - (openBlock(true), createElementBlock(Fragment, null, renderList(unref(global2).state.perf_drawer.gpus, (gpu) => { - return openBlock(), createBlock(unref(NCard), { - key: gpu.uuid, - style: { "margin-bottom": "12px" } - }, { - default: withCtx(() => [ - createVNode(unref(NSpace), { - inline: "", - justify: "space-between", - style: { "width": "100%" } - }, { - default: withCtx(() => [ - createBaseVNode("h3", null, "[" + toDisplayString(gpu.index) + "] " + toDisplayString(gpu.name), 1), - createBaseVNode("h4", null, toDisplayString(gpu.power_draw) + " / " + toDisplayString(gpu.power_limit) + "W ─ " + toDisplayString(gpu.temperature) + "°C ", 1) - ]), - _: 2 - }, 1024), - createBaseVNode("div", _hoisted_1$4, [ - _hoisted_2$3, - createVNode(unref(NProgress), { - percentage: gpu.utilization, - type: "line", - "indicator-placement": "inside", - style: { "flex-grow": "1", "width": "400px" } - }, null, 8, ["percentage"]) - ]), - createBaseVNode("div", _hoisted_3$2, [ - _hoisted_4$2, - createVNode(unref(NProgress), { - percentage: gpu.memory_usage, - type: "line", - style: { "flex-grow": "1", "width": "400px" }, - color: "#63e2b7", - "indicator-placement": "inside" - }, null, 8, ["percentage"]), - createBaseVNode("p", _hoisted_5$2, toDisplayString(gpu.memory_used) + " / " + toDisplayString(gpu.memory_total) + " MB ", 1) - ]) - ]), - _: 2 - }, 1024); - }), 128)) - ]), - _: 1 - }) - ]), - _: 1 - }, 8, ["show"]); - }; - } -}); -const _hoisted_1$3 = /* @__PURE__ */ createBaseVNode("a", { - target: "_blank", - href: "https://huggingface.co/settings/tokens" -}, "this page", -1); -const _hoisted_2$2 = { style: { "margin-top": "8px", "width": "100%", "display": "flex", "justify-content": "end" } }; -const _sfc_main$5 = /* @__PURE__ */ defineComponent({ - __name: "SecretsHandler", - setup(__props) { - const message = useMessage(); - const global2 = useState2(); - const hf_loading = ref(false); - const hf_token = ref(""); - function noSideSpace(value) { - return !/ /g.test(value); - } - function setHuggingfaceToken() { - hf_loading.value = true; - const url = new URL(`${serverUrl}/api/settings/inject-var-into-dotenv`); - url.searchParams.append("key", "HUGGINGFACE_TOKEN"); - url.searchParams.append("value", hf_token.value); - fetch(url, { method: "POST" }).then((res) => { - if (res.status !== 200) { - message.create("Failed to set HuggingFace token", { type: "error" }); - return; - } - global2.state.secrets.huggingface = "ok"; - message.create("HuggingFace token set successfully", { type: "success" }); - }).catch((e) => { - message.create(`Failed to set HuggingFace token: ${e.message}`, { - type: "error" - }); - }); - hf_loading.value = false; - } - return (_ctx, _cache) => { - return openBlock(), createBlock(unref(NModal), { - show: unref(global2).state.secrets.huggingface !== "ok", - preset: "card", - title: "Missing HuggingFace Token", - style: { "width": "80vw" }, - closable: false - }, { - default: withCtx(() => [ - createVNode(unref(NText), null, { - default: withCtx(() => [ - createTextVNode(" API does not have a HuggingFace token. Please enter a valid token to continue. You can get a token from "), - _hoisted_1$3 - ]), - _: 1 - }), - createVNode(unref(NInput), { - type: "password", - placeholder: "hf_123...", - style: { "margin-top": "8px" }, - "allow-input": noSideSpace, - value: hf_token.value, - "onUpdate:value": _cache[0] || (_cache[0] = ($event) => hf_token.value = $event) - }, null, 8, ["value"]), - createBaseVNode("div", _hoisted_2$2, [ - createVNode(unref(NButton), { - ghost: "", - type: "primary", - loading: hf_loading.value, - onClick: setHuggingfaceToken - }, { - default: withCtx(() => [ - createTextVNode("Set Token") - ]), - _: 1 - }, 8, ["loading"]) - ]) - ]), - _: 1 - }, 8, ["show"]); - }; - } -}); var _a; const isClient = typeof window !== "undefined"; const isFunction = (val) => typeof val === "function"; @@ -41884,6 +41225,9 @@ function convertToTextString(str) { const upper = str.charAt(0).toUpperCase() + str.slice(1); return upper.replace(/_/g, " "); } +function cloneObj(obj) { + return window.structuredClone(obj); +} function addActive(x) { if (!x) return false; @@ -41986,135 +41330,810 @@ function promptHandleKeyUp(e, data, key, globalState) { console.log("No selection, cannot parse for weighting"); } } - if (e.key === "ArrowDown" && e.ctrlKey) { - const values = getTextBoundaries( - document.activeElement - ); - const boundaryIndexStart = values[0]; - const boundaryIndexEnd = values[1]; + if (e.key === "ArrowDown" && e.ctrlKey) { + const values = getTextBoundaries( + document.activeElement + ); + const boundaryIndexStart = values[0]; + const boundaryIndexEnd = values[1]; + e.preventDefault(); + const elem = document.activeElement; + const current_selection = elem.value.substring( + boundaryIndexStart, + boundaryIndexEnd + ); + const regex = /\(([^:]+([:]?[\s]?)([\d.\d]+))\)/; + const matches = regex.exec(current_selection); + if (matches) { + if (matches) { + const value = parseFloat(matches[3]); + const new_value = Math.max(value - 0.1, 0).toFixed(1); + const beforeString = elem.value.substring(0, boundaryIndexStart); + const afterString = elem.value.substring(boundaryIndexEnd); + const newString = `${beforeString}${current_selection.replace( + matches[3], + new_value + )}${afterString}`; + elem.value = newString; + data[key] = newString; + elem.setSelectionRange(boundaryIndexStart, boundaryIndexEnd); + } + } else if (boundaryIndexStart !== boundaryIndexEnd) { + const new_inner_string = `(${current_selection}:0.9)`; + const beforeString = elem.value.substring(0, boundaryIndexStart); + const afterString = elem.value.substring(boundaryIndexEnd); + elem.value = `${beforeString}${new_inner_string}${afterString}`; + data[key] = `${beforeString}${new_inner_string}${afterString}`; + elem.setSelectionRange(boundaryIndexStart, boundaryIndexEnd + 6); + } else { + console.log("No selection, cannot parse for weighting"); + } + } + const input = e.target; + if (input) { + const text = input.value; + const currentTokenStripped = (_a2 = text.split(",").pop()) == null ? void 0 : _a2.trim(); + closeAllLists(void 0, input); + if (!currentTokenStripped) { + return false; + } + const toAppend = []; + for (let i = 0; i < globalState.state.autofill_special.length; i++) { + if (globalState.state.autofill_special[i].toLowerCase().includes(currentTokenStripped.toLowerCase())) { + const b = document.createElement("DIV"); + b.innerText = globalState.state.autofill_special[i]; + b.innerHTML += ""; + b.addEventListener("click", function() { + input.value = text.substring(0, text.lastIndexOf(",") + 1) + globalState.state.autofill_special[i]; + data[key] = input.value; + closeAllLists(void 0, input); + }); + toAppend.push(b); + } + } + const lowercaseStrippedToken = currentTokenStripped.toLowerCase(); + if (lowercaseStrippedToken.length >= 3) { + for (let i = 0; i < globalState.state.autofill.length; i++) { + if (globalState.state.autofill[i].toLowerCase().includes(lowercaseStrippedToken)) { + if (toAppend.length >= 30) { + break; + } + const b = document.createElement("DIV"); + b.innerText = globalState.state.autofill[i]; + b.innerHTML += ""; + b.addEventListener("click", function() { + input.value = text.substring(0, text.lastIndexOf(",") + 1) + globalState.state.autofill[i]; + data[key] = input.value; + closeAllLists(void 0, input); + }); + toAppend.push(b); + } + } + } + if (toAppend.length === 0) { + return false; + } + const div = document.createElement("DIV"); + div.setAttribute("id", "autocomplete-list"); + div.setAttribute("class", "autocomplete-items"); + (_e = (_d = (_c = (_b = input.parentNode) == null ? void 0 : _b.parentNode) == null ? void 0 : _c.parentNode) == null ? void 0 : _d.parentNode) == null ? void 0 : _e.appendChild(div); + for (let i = 0; i < toAppend.length; i++) { + div.appendChild(toAppend[i]); + } + onClickOutside(div, () => { + closeAllLists(void 0, input); + }); + const autocompleteList = document.getElementById("autocomplete-list"); + const x = autocompleteList == null ? void 0 : autocompleteList.getElementsByTagName("div"); + if (e.key === "ArrowDown") { + currentFocus++; + addActive(x); + e.preventDefault(); + } else if (e.key === "ArrowUp") { + currentFocus--; + addActive(x); + e.preventDefault(); + } else if (e.key === "Enter" || e.key === "Tab") { + e.stopImmediatePropagation(); + e.preventDefault(); + if (currentFocus > -1) { + if (x) + x[currentFocus].click(); + } + } else if (e.key === "Escape") { + closeAllLists(void 0, input); + } + } +} +function promptHandleKeyDown(e) { + if (arrowKeys.includes(e.keyCode) && e.ctrlKey) { e.preventDefault(); - const elem = document.activeElement; - const current_selection = elem.value.substring( - boundaryIndexStart, - boundaryIndexEnd - ); - const regex = /\(([^:]+([:]?[\s]?)([\d.\d]+))\)/; - const matches = regex.exec(current_selection); - if (matches) { - if (matches) { - const value = parseFloat(matches[3]); - const new_value = Math.max(value - 0.1, 0).toFixed(1); - const beforeString = elem.value.substring(0, boundaryIndexStart); - const afterString = elem.value.substring(boundaryIndexEnd); - const newString = `${beforeString}${current_selection.replace( - matches[3], - new_value - )}${afterString}`; - elem.value = newString; - data[key] = newString; - elem.setSelectionRange(boundaryIndexStart, boundaryIndexEnd); + } + if (document.getElementById("autocomplete-list")) { + if (e.key === "Enter" || e.key === "Tab" || e.key === "ArrowDown" || e.key === "ArrowUp") { + e.preventDefault(); + } + } +} +function urlFromPath(path) { + const url = new URL(path, serverUrl); + return url.href; +} +const highresFixFlagDefault = { + enabled: false, + scale: 2, + mode: "image", + image_upscaler: "RealESRGAN_x4plus_anime_6B", + latent_scale_mode: "bislerp", + antialiased: false, + strength: 0.65, + steps: 50 +}; +const upscaleFlagDefault = { + enabled: false, + upscale_factor: 4, + tile_size: 128, + tile_padding: 10, + model: "RealESRGAN_x4plus_anime_6B" +}; +const defaultSettings = { + $schema: "./schema/ui_data/settings.json", + backend: "PyTorch", + model: null, + flags: { + sdxl: { + original_size: { + width: 1024, + height: 1024 } - } else if (boundaryIndexStart !== boundaryIndexEnd) { - const new_inner_string = `(${current_selection}:0.9)`; - const beforeString = elem.value.substring(0, boundaryIndexStart); - const afterString = elem.value.substring(boundaryIndexEnd); - elem.value = `${beforeString}${new_inner_string}${afterString}`; - data[key] = `${beforeString}${new_inner_string}${afterString}`; - elem.setSelectionRange(boundaryIndexStart, boundaryIndexEnd + 6); - } else { - console.log("No selection, cannot parse for weighting"); + }, + refiner: { + model: void 0, + aesthetic_score: 6, + negative_aesthetic_score: 2.5, + steps: 50, + strength: 0.3 } + }, + aitDim: { + width: void 0, + height: void 0, + batch_size: void 0 + }, + txt2img: { + width: 512, + height: 512, + seed: -1, + cfg_scale: 7, + sampler: 8, + prompt: "", + steps: 25, + batch_count: 1, + batch_size: 1, + negative_prompt: "", + self_attention_scale: 0, + sigmas: "automatic", + highres: cloneObj(highresFixFlagDefault), + upscale: cloneObj(upscaleFlagDefault) + }, + img2img: { + width: 512, + height: 512, + seed: -1, + cfg_scale: 7, + sampler: 8, + prompt: "", + steps: 25, + batch_count: 1, + batch_size: 1, + negative_prompt: "", + denoising_strength: 0.6, + image: "", + self_attention_scale: 0, + sigmas: "automatic", + highres: cloneObj(highresFixFlagDefault), + upscale: cloneObj(upscaleFlagDefault) + }, + inpainting: { + prompt: "", + negative_prompt: "", + image: "", + mask_image: "", + width: 512, + height: 512, + steps: 25, + cfg_scale: 7, + seed: -1, + batch_count: 1, + batch_size: 1, + sampler: 8, + self_attention_scale: 0, + sigmas: "automatic", + highres: cloneObj(highresFixFlagDefault), + upscale: cloneObj(upscaleFlagDefault) + }, + controlnet: { + prompt: "", + image: "", + sampler: 8, + controlnet: ControlNetType.CANNY, + negative_prompt: "", + width: 512, + height: 512, + steps: 25, + cfg_scale: 7, + seed: -1, + batch_size: 1, + batch_count: 1, + controlnet_conditioning_scale: 1, + detection_resolution: 512, + is_preprocessed: false, + save_preprocessed: false, + return_preprocessed: true, + self_attention_scale: 0, + sigmas: "automatic", + highres: cloneObj(highresFixFlagDefault), + upscale: cloneObj(upscaleFlagDefault) + }, + upscale: { + image: "", + upscale_factor: 4, + model: "RealESRGAN_x4plus_anime_6B", + tile_size: 128, + tile_padding: 10 + }, + tagger: { + image: "", + model: "deepdanbooru", + threshold: 0.5 + }, + api: { + websocket_sync_interval: 0.02, + websocket_perf_interval: 1, + enable_websocket_logging: true, + clip_skip: 1, + clip_quantization: "full", + autocast: true, + attention_processor: "xformers", + subquadratic_size: 512, + attention_slicing: "disabled", + channels_last: true, + trace_model: false, + cudnn_benchmark: false, + offload: "disabled", + dont_merge_latents: false, + device: "cuda:0", + data_type: "float16", + use_tomesd: true, + tomesd_ratio: 0.4, + tomesd_downsample_layers: 1, + deterministic_generation: false, + reduced_precision: false, + clear_memory_policy: "always", + huggingface_style_parsing: false, + autoloaded_textual_inversions: [], + autoloaded_models: [], + autoloaded_vae: {}, + save_path_template: "{folder}/{prompt}/{id}-{index}.{extension}", + image_extension: "png", + image_quality: 95, + disable_grid: false, + torch_compile: false, + torch_compile_fullgraph: false, + torch_compile_dynamic: false, + torch_compile_backend: "inductor", + torch_compile_mode: "default", + sfast_compile: false, + sfast_xformers: true, + sfast_triton: true, + sfast_cuda_graph: false, + hypertile: false, + hypertile_unet_chunk: 256, + sgm_noise_multiplier: false, + kdiffusers_quantization: true, + xl_refiner: "joint", + generator: "device", + live_preview_method: "approximation", + live_preview_delay: 2, + upcast_vae: false, + vae_slicing: false, + vae_tiling: false, + apply_unsharp_mask: false, + cfg_rescale_threshold: 10, + prompt_to_prompt: false, + prompt_to_prompt_model: "lllyasviel/Fooocus-Expansion", + prompt_to_prompt_device: "gpu", + free_u: false, + free_u_s1: 0.9, + free_u_s2: 0.2, + free_u_b1: 1.2, + free_u_b2: 1.4 + }, + aitemplate: { + num_threads: 8 + }, + onnx: { + quant_dict: { + text_encoder: null, + unet: null, + vae_decoder: null, + vae_encoder: null + }, + convert_to_fp16: true, + simplify_unet: false + }, + bot: { + default_scheduler: 8, + verbose: false, + use_default_negative_prompt: true + }, + frontend: { + theme: "dark", + enable_theme_editor: false, + image_browser_columns: 5, + on_change_timer: 2e3, + nsfw_ok_threshold: 0, + background_image_override: "", + disable_analytics: true + }, + sampler_config: {} +}; +let rSettings = JSON.parse(JSON.stringify(defaultSettings)); +try { + const req = new XMLHttpRequest(); + req.open("GET", `${serverUrl}/api/settings/`, false); + req.send(); + rSettings = { ...rSettings, ...JSON.parse(req.responseText) }; +} catch (e) { + console.error(e); +} +console.log("Settings:", rSettings); +const recievedSettings = rSettings; +class Settings { + constructor(settings_override) { + __publicField(this, "settings"); + this.settings = { ...defaultSettings, ...settings_override }; + } + to_json() { + return JSON.stringify(this.settings); } - const input = e.target; - if (input) { - const text = input.value; - const currentTokenStripped = (_a2 = text.split(",").pop()) == null ? void 0 : _a2.trim(); - closeAllLists(void 0, input); - if (!currentTokenStripped) { - return false; - } - const toAppend = []; - for (let i = 0; i < globalState.state.autofill_special.length; i++) { - if (globalState.state.autofill_special[i].toLowerCase().includes(currentTokenStripped.toLowerCase())) { - const b = document.createElement("DIV"); - b.innerText = globalState.state.autofill_special[i]; - b.innerHTML += ""; - b.addEventListener("click", function() { - input.value = text.substring(0, text.lastIndexOf(",") + 1) + globalState.state.autofill_special[i]; - data[key] = input.value; - closeAllLists(void 0, input); - }); - toAppend.push(b); - } +} +const diffusersSchedulerTuple = { + DDIM: 1, + DDPM: 2, + PNDM: 3, + LMSD: 4, + EulerDiscrete: 5, + HeunDiscrete: 6, + EulerAncestralDiscrete: 7, + DPMSolverMultistep: 8, + DPMSolverSinglestep: 9, + KDPM2Discrete: 10, + KDPM2AncestralDiscrete: 11, + DEISMultistep: 12, + UniPCMultistep: 13, + DPMSolverSDEScheduler: 14 +}; +const upscalerOptions = [ + { + label: "RealESRGAN_x4plus", + value: "RealESRGAN_x4plus" + }, + { + label: "RealESRNet_x4plus", + value: "RealESRNet_x4plus" + }, + { + label: "RealESRGAN_x4plus_anime_6B", + value: "RealESRGAN_x4plus_anime_6B" + }, + { + label: "RealESRGAN_x2plus", + value: "RealESRGAN_x2plus" + }, + { + label: "RealESR-general-x4v3", + value: "RealESR-general-x4v3" + } +]; +function getSchedulerOptions() { + const scheduler_options = [ + { + type: "group", + label: "k-diffusion", + key: "K-Diffusion", + children: [ + { label: "Euler a", value: "euler_a" }, + { label: "Euler", value: "euler" }, + { label: "LMS", value: "lms" }, + { label: "Heun", value: "heun" }, + { label: "Heun++", value: "heunpp" }, + { label: "DPM Fast", value: "dpm_fast" }, + { label: "DPM Adaptive", value: "dpm_adaptive" }, + { label: "DPM2", value: "dpm2" }, + { label: "DPM2 a", value: "dpm2_a" }, + { label: "DPM++ 2S a", value: "dpmpp_2s_a" }, + { label: "DPM++ 2M", value: "dpmpp_2m" }, + { label: "DPM++ 2M Sharp", value: "dpmpp_2m_sharp" }, + { label: "DPM++ SDE", value: "dpmpp_sde" }, + { label: "DPM++ 2M SDE", value: "dpmpp_2m_sde" }, + { label: "DPM++ 3M SDE", value: "dpmpp_3m_sde" }, + { label: "UniPC Multistep", value: "unipc_multistep" }, + { label: "Restart", value: "restart" } + ] + }, + { + type: "group", + label: "Diffusers", + key: "diffusers", + children: Object.keys(diffusersSchedulerTuple).map((key) => { + return { + label: key, + value: diffusersSchedulerTuple[key] + }; + }) } - const lowercaseStrippedToken = currentTokenStripped.toLowerCase(); - if (lowercaseStrippedToken.length >= 3) { - for (let i = 0; i < globalState.state.autofill.length; i++) { - if (globalState.state.autofill[i].toLowerCase().includes(lowercaseStrippedToken)) { - if (toAppend.length >= 30) { - break; - } - const b = document.createElement("DIV"); - b.innerText = globalState.state.autofill[i]; - b.innerHTML += ""; - b.addEventListener("click", function() { - input.value = text.substring(0, text.lastIndexOf(",") + 1) + globalState.state.autofill[i]; - data[key] = input.value; - closeAllLists(void 0, input); - }); - toAppend.push(b); + ]; + return scheduler_options; +} +function getControlNetOptions() { + const controlnet_options = [ + { + type: "group", + label: "ControlNet 1.1", + key: "ControlNet 1.1", + children: [ + { + label: "lllyasviel/control_v11p_sd15_canny", + value: "lllyasviel/control_v11p_sd15_canny" + }, + { + label: "lllyasviel/control_v11f1p_sd15_depth", + value: "lllyasviel/control_v11f1p_sd15_depth" + }, + { + label: "lllyasviel/control_v11e_sd15_ip2p", + value: "lllyasviel/control_v11e_sd15_ip2p" + }, + { + label: "lllyasviel/control_v11p_sd15_softedge", + value: "lllyasviel/control_v11p_sd15_softedge" + }, + { + label: "lllyasviel/control_v11p_sd15_openpose", + value: "lllyasviel/control_v11p_sd15_openpose" + }, + { + label: "lllyasviel/control_v11f1e_sd15_tile", + value: "lllyasviel/control_v11f1e_sd15_tile" + }, + { + label: "lllyasviel/control_v11p_sd15_mlsd", + value: "lllyasviel/control_v11p_sd15_mlsd" + }, + { + label: "lllyasviel/control_v11p_sd15_scribble", + value: "lllyasviel/control_v11p_sd15_scribble" + }, + { + label: "lllyasviel/control_v11p_sd15_seg", + value: "lllyasviel/control_v11p_sd15_seg" } - } - } - if (toAppend.length === 0) { - return false; - } - const div = document.createElement("DIV"); - div.setAttribute("id", "autocomplete-list"); - div.setAttribute("class", "autocomplete-items"); - (_e = (_d = (_c = (_b = input.parentNode) == null ? void 0 : _b.parentNode) == null ? void 0 : _c.parentNode) == null ? void 0 : _d.parentNode) == null ? void 0 : _e.appendChild(div); - for (let i = 0; i < toAppend.length; i++) { - div.appendChild(toAppend[i]); + ] + }, + { + type: "group", + label: "Special", + key: "Special", + children: [ + { + label: "DionTimmer/controlnet_qrcode", + value: "DionTimmer/controlnet_qrcode" + }, + { + label: "CrucibleAI/ControlNetMediaPipeFace", + value: "CrucibleAI/ControlNetMediaPipeFace" + } + ] + }, + { + type: "group", + label: "Original", + key: "Original", + children: [ + { + label: "lllyasviel/sd-controlnet-canny", + value: "lllyasviel/sd-controlnet-canny" + }, + { + label: "lllyasviel/sd-controlnet-depth", + value: "lllyasviel/sd-controlnet-depth" + }, + { + label: "lllyasviel/sd-controlnet-hed", + value: "lllyasviel/sd-controlnet-hed" + }, + { + label: "lllyasviel/sd-controlnet-mlsd", + value: "lllyasviel/sd-controlnet-mlsd" + }, + { + label: "lllyasviel/sd-controlnet-normal", + value: "lllyasviel/sd-controlnet-normal" + }, + { + label: "lllyasviel/sd-controlnet-openpose", + value: "lllyasviel/sd-controlnet-openpose" + }, + { + label: "lllyasviel/sd-controlnet-scribble", + value: "lllyasviel/sd-controlnet-scribble" + }, + { + label: "lllyasviel/sd-controlnet-seg", + value: "lllyasviel/sd-controlnet-seg" + } + ] } - onClickOutside(div, () => { - closeAllLists(void 0, input); - }); - const autocompleteList = document.getElementById("autocomplete-list"); - const x = autocompleteList == null ? void 0 : autocompleteList.getElementsByTagName("div"); - if (e.key === "ArrowDown") { - currentFocus++; - addActive(x); - e.preventDefault(); - } else if (e.key === "ArrowUp") { - currentFocus--; - addActive(x); - e.preventDefault(); - } else if (e.key === "Enter" || e.key === "Tab") { - e.stopImmediatePropagation(); - e.preventDefault(); - if (currentFocus > -1) { - if (x) - x[currentFocus].click(); + ]; + return controlnet_options; +} +const deepcopiedSettings = JSON.parse(JSON.stringify(recievedSettings)); +const useSettings = defineStore("settings", () => { + const data = reactive(new Settings(recievedSettings)); + const scheduler_options = computed(() => { + return getSchedulerOptions(); + }); + const controlnet_options = computed(() => { + return getControlNetOptions(); + }); + function resetSettings() { + console.log("Resetting settings to default"); + Object.assign(defaultSettings$1, defaultSettings); + } + async function saveSettings() { + fetch(`${serverUrl}/api/settings/save`, { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify(defaultSettings$1) + }).then((res) => { + if (res.status === 200) { + console.log("Settings saved successfully"); + } else { + throw new Error("Failed to save settings"); } - } else if (e.key === "Escape") { - closeAllLists(void 0, input); - } + }); } -} -function promptHandleKeyDown(e) { - if (arrowKeys.includes(e.keyCode) && e.ctrlKey) { - e.preventDefault(); + const defaultSettings$1 = reactive(deepcopiedSettings); + return { + data, + scheduler_options, + controlnet_options, + defaultSettings: defaultSettings$1, + resetSettings, + saveSettings + }; +}); +const ImageUpload_vue_vue_type_style_index_0_scoped_9ed1514f_lang = ""; +const _export_sfc = (sfc, props) => { + const target = sfc.__vccOpts || sfc; + for (const [key, val] of props) { + target[key] = val; } - if (document.getElementById("autocomplete-list")) { - if (e.key === "Enter" || e.key === "Tab" || e.key === "ArrowDown" || e.key === "ArrowUp") { - e.preventDefault(); + return target; +}; +const _sfc_main$8 = /* @__PURE__ */ defineComponent({ + __name: "InitHandler", + setup(__props) { + console.log( + ` + ██╗ ██╗ █████╗ ██╗ ████████╗ █████╗ ███╗ ███╗██╗ + ██║ ██║██╔══██╗██║ ╚══██╔══╝██╔══██╗████╗ ████║██║ + ╚██╗ ██╔╝██║ ██║██║ ██║ ███████║██╔████╔██║██║ + ╚████╔╝ ██║ ██║██║ ██║ ██╔══██║██║╚██╔╝██║██║ + ╚██╔╝ ╚█████╔╝███████╗ ██║ ██║ ██║██║ ╚═╝ ██║███████╗ + ╚═╝ ╚════╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ + ` + ); + const global2 = useState2(); + global2.fetchCapabilites().then(() => { + console.log("Capabilities successfully fetched from the server"); + }); + global2.fetchAutofill(); + return (_ctx, _cache) => { + return null; + }; + } +}); +const _sfc_main$7 = /* @__PURE__ */ defineComponent({ + __name: "LogDrawer", + setup(__props) { + const glob = useState2(); + const log = computed(() => glob.state.log_drawer.logs.join("\n")); + return (_ctx, _cache) => { + return openBlock(), createBlock(unref(NDrawer), { + placement: "bottom", + show: unref(glob).state.log_drawer.enabled, + "onUpdate:show": _cache[0] || (_cache[0] = ($event) => unref(glob).state.log_drawer.enabled = $event), + "auto-focus": false, + "show-mask": true, + height: "70vh" + }, { + default: withCtx(() => [ + createVNode(unref(NDrawerContent), { + closable: "", + title: "Log - 500 latest messages" + }, { + default: withCtx(() => [ + createVNode(unref(NLog), { + ref: "logRef", + log: log.value, + trim: "", + style: { "height": "100%" } + }, null, 8, ["log"]) + ]), + _: 1 + }) + ]), + _: 1 + }, 8, ["show"]); + }; + } +}); +const _hoisted_1$4 = { style: { "width": "100%", "display": "inline-flex", "align-items": "center" } }; +const _hoisted_2$3 = /* @__PURE__ */ createBaseVNode("p", { style: { "width": "108px" } }, "Utilization", -1); +const _hoisted_3$2 = { style: { "width": "100%", "display": "inline-flex", "align-items": "center" } }; +const _hoisted_4$2 = /* @__PURE__ */ createBaseVNode("p", { style: { "width": "108px" } }, "Memory", -1); +const _hoisted_5$2 = { style: { "align-self": "flex-end", "margin-left": "12px" } }; +const _sfc_main$6 = /* @__PURE__ */ defineComponent({ + __name: "PerformanceDrawer", + setup(__props) { + const global2 = useState2(); + const glob = useState2(); + return (_ctx, _cache) => { + return openBlock(), createBlock(unref(NDrawer), { + placement: "bottom", + show: unref(glob).state.perf_drawer.enabled, + "onUpdate:show": _cache[0] || (_cache[0] = ($event) => unref(glob).state.perf_drawer.enabled = $event), + "auto-focus": false, + "show-mask": true, + height: "70vh" + }, { + default: withCtx(() => [ + createVNode(unref(NDrawerContent), { + closable: "", + title: "Performance statistics" + }, { + default: withCtx(() => [ + (openBlock(true), createElementBlock(Fragment, null, renderList(unref(global2).state.perf_drawer.gpus, (gpu) => { + return openBlock(), createBlock(unref(NCard), { + key: gpu.uuid, + style: { "margin-bottom": "12px" } + }, { + default: withCtx(() => [ + createVNode(unref(NSpace), { + inline: "", + justify: "space-between", + style: { "width": "100%" } + }, { + default: withCtx(() => [ + createBaseVNode("h3", null, "[" + toDisplayString(gpu.index) + "] " + toDisplayString(gpu.name), 1), + createBaseVNode("h4", null, toDisplayString(gpu.power_draw) + " / " + toDisplayString(gpu.power_limit) + "W ─ " + toDisplayString(gpu.temperature) + "°C ", 1) + ]), + _: 2 + }, 1024), + createBaseVNode("div", _hoisted_1$4, [ + _hoisted_2$3, + createVNode(unref(NProgress), { + percentage: gpu.utilization, + type: "line", + "indicator-placement": "inside", + style: { "flex-grow": "1", "width": "400px" } + }, null, 8, ["percentage"]) + ]), + createBaseVNode("div", _hoisted_3$2, [ + _hoisted_4$2, + createVNode(unref(NProgress), { + percentage: gpu.memory_usage, + type: "line", + style: { "flex-grow": "1", "width": "400px" }, + color: "#63e2b7", + "indicator-placement": "inside" + }, null, 8, ["percentage"]), + createBaseVNode("p", _hoisted_5$2, toDisplayString(gpu.memory_used) + " / " + toDisplayString(gpu.memory_total) + " MB ", 1) + ]) + ]), + _: 2 + }, 1024); + }), 128)) + ]), + _: 1 + }) + ]), + _: 1 + }, 8, ["show"]); + }; + } +}); +const _hoisted_1$3 = /* @__PURE__ */ createBaseVNode("a", { + target: "_blank", + href: "https://huggingface.co/settings/tokens" +}, "this page", -1); +const _hoisted_2$2 = { style: { "margin-top": "8px", "width": "100%", "display": "flex", "justify-content": "end" } }; +const _sfc_main$5 = /* @__PURE__ */ defineComponent({ + __name: "SecretsHandler", + setup(__props) { + const message = useMessage(); + const global2 = useState2(); + const hf_loading = ref(false); + const hf_token = ref(""); + function noSideSpace(value) { + return !/ /g.test(value); + } + function setHuggingfaceToken() { + hf_loading.value = true; + const url = new URL(`${serverUrl}/api/settings/inject-var-into-dotenv`); + url.searchParams.append("key", "HUGGINGFACE_TOKEN"); + url.searchParams.append("value", hf_token.value); + fetch(url, { method: "POST" }).then((res) => { + if (res.status !== 200) { + message.create("Failed to set HuggingFace token", { type: "error" }); + return; + } + global2.state.secrets.huggingface = "ok"; + message.create("HuggingFace token set successfully", { type: "success" }); + }).catch((e) => { + message.create(`Failed to set HuggingFace token: ${e.message}`, { + type: "error" + }); + }); + hf_loading.value = false; } + return (_ctx, _cache) => { + return openBlock(), createBlock(unref(NModal), { + show: unref(global2).state.secrets.huggingface !== "ok", + preset: "card", + title: "Missing HuggingFace Token", + style: { "width": "80vw" }, + closable: false + }, { + default: withCtx(() => [ + createVNode(unref(NText), null, { + default: withCtx(() => [ + createTextVNode(" API does not have a HuggingFace token. Please enter a valid token to continue. You can get a token from "), + _hoisted_1$3 + ]), + _: 1 + }), + createVNode(unref(NInput), { + type: "password", + placeholder: "hf_123...", + style: { "margin-top": "8px" }, + "allow-input": noSideSpace, + value: hf_token.value, + "onUpdate:value": _cache[0] || (_cache[0] = ($event) => hf_token.value = $event) + }, null, 8, ["value"]), + createBaseVNode("div", _hoisted_2$2, [ + createVNode(unref(NButton), { + ghost: "", + type: "primary", + loading: hf_loading.value, + onClick: setHuggingfaceToken + }, { + default: withCtx(() => [ + createTextVNode("Set Token") + ]), + _: 1 + }, 8, ["loading"]) + ]) + ]), + _: 1 + }, 8, ["show"]); + }; } -} -function urlFromPath(path) { - const url = new URL(path, serverUrl); - return url.href; -} +}); const _withScopeId = (n) => (pushScopeId("data-v-91ace41f"), n = n(), popScopeId(), n); const _hoisted_1$2 = { class: "top-bar" }; const _hoisted_2$1 = { key: 0 }; @@ -43146,10 +43165,9 @@ const TopBar_vue_vue_type_style_index_0_scoped_91ace41f_lang = ""; const TopBar = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-91ace41f"]]); const Prompt_vue_vue_type_style_index_0_lang = ""; const Prompt_vue_vue_type_style_index_1_scoped_780680bc_lang = ""; -const Upscale_vue_vue_type_style_index_0_scoped_5358ed01_lang = ""; -const ControlNet_vue_vue_type_style_index_0_scoped_95a354be_lang = ""; -const Img2Img_vue_vue_type_style_index_0_scoped_116492bf_lang = ""; -const Inpainting_vue_vue_type_style_index_0_scoped_6961892e_lang = ""; +const ControlNet_vue_vue_type_style_index_0_scoped_97c56df6_lang = ""; +const Img2Img_vue_vue_type_style_index_0_scoped_bfd46a0a_lang = ""; +const Inpainting_vue_vue_type_style_index_0_scoped_1193df1f_lang = ""; const CivitAIDownload_vue_vue_type_style_index_0_scoped_241a4664_lang = ""; const HuggingfaceDownload_vue_vue_type_style_index_0_scoped_b405f046_lang = ""; const _hoisted_1$1 = { style: { "margin": "16px 0" } }; @@ -43438,17 +43456,17 @@ const router = createRouter({ { path: "/", name: "home", - component: () => __vitePreload(() => import("./TextToImageView.js"), true ? ["assets/TextToImageView.js","assets/GenerateSection.vue_vue_type_script_setup_true_lang.js","assets/ImageOutput.vue_vue_type_script_setup_true_lang.js","assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js","assets/Switch.js","assets/TrashBin.js","assets/clock.js","assets/DescriptionsItem.js","assets/Slider.js","assets/InputNumber.js","assets/SamplerPicker.vue_vue_type_script_setup_true_lang.js","assets/Settings.js","assets/v4.js"] : void 0) + component: () => __vitePreload(() => import("./TextToImageView.js"), true ? ["assets/TextToImageView.js","assets/GenerateSection.vue_vue_type_script_setup_true_lang.js","assets/ImageOutput.vue_vue_type_script_setup_true_lang.js","assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js","assets/Switch.js","assets/TrashBin.js","assets/clock.js","assets/DescriptionsItem.js","assets/Slider.js","assets/InputNumber.js","assets/Upscale.vue_vue_type_script_setup_true_lang.js","assets/Settings.js","assets/v4.js"] : void 0) }, { path: "/txt2img", name: "txt2img", - component: () => __vitePreload(() => import("./TextToImageView.js"), true ? ["assets/TextToImageView.js","assets/GenerateSection.vue_vue_type_script_setup_true_lang.js","assets/ImageOutput.vue_vue_type_script_setup_true_lang.js","assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js","assets/Switch.js","assets/TrashBin.js","assets/clock.js","assets/DescriptionsItem.js","assets/Slider.js","assets/InputNumber.js","assets/SamplerPicker.vue_vue_type_script_setup_true_lang.js","assets/Settings.js","assets/v4.js"] : void 0) + component: () => __vitePreload(() => import("./TextToImageView.js"), true ? ["assets/TextToImageView.js","assets/GenerateSection.vue_vue_type_script_setup_true_lang.js","assets/ImageOutput.vue_vue_type_script_setup_true_lang.js","assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js","assets/Switch.js","assets/TrashBin.js","assets/clock.js","assets/DescriptionsItem.js","assets/Slider.js","assets/InputNumber.js","assets/Upscale.vue_vue_type_script_setup_true_lang.js","assets/Settings.js","assets/v4.js"] : void 0) }, { path: "/img2img", name: "img2img", - component: () => __vitePreload(() => import("./Image2ImageView.js"), true ? ["assets/Image2ImageView.js","assets/clock.js","assets/DescriptionsItem.js","assets/Slider.js","assets/InputNumber.js","assets/SamplerPicker.vue_vue_type_script_setup_true_lang.js","assets/Settings.js","assets/Switch.js","assets/GenerateSection.vue_vue_type_script_setup_true_lang.js","assets/ImageOutput.vue_vue_type_script_setup_true_lang.js","assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js","assets/TrashBin.js","assets/ImageUpload.js","assets/CloudUpload.js","assets/v4.js"] : void 0) + component: () => __vitePreload(() => import("./Image2ImageView.js"), true ? ["assets/Image2ImageView.js","assets/clock.js","assets/DescriptionsItem.js","assets/Slider.js","assets/InputNumber.js","assets/Upscale.vue_vue_type_script_setup_true_lang.js","assets/Switch.js","assets/Settings.js","assets/GenerateSection.vue_vue_type_script_setup_true_lang.js","assets/ImageOutput.vue_vue_type_script_setup_true_lang.js","assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js","assets/TrashBin.js","assets/ImageUpload.js","assets/CloudUpload.js","assets/v4.js"] : void 0) }, { path: "/imageProcessing", @@ -43483,7 +43501,7 @@ const router = createRouter({ { path: "/settings", name: "settings", - component: () => __vitePreload(() => import("./SettingsView.js"), true ? ["assets/SettingsView.js","assets/SamplerPicker.vue_vue_type_script_setup_true_lang.js","assets/Settings.js","assets/InputNumber.js","assets/Slider.js","assets/Switch.js"] : void 0) + component: () => __vitePreload(() => import("./SettingsView.js"), true ? ["assets/SettingsView.js","assets/Upscale.vue_vue_type_script_setup_true_lang.js","assets/Switch.js","assets/Slider.js","assets/InputNumber.js","assets/Settings.js"] : void 0) }, { path: "/imageBrowser", @@ -43516,20 +43534,20 @@ app.use(index, { app.mount("#app"); export { createTmOptions as $, - NButton as A, - NIcon as B, - toDisplayString as C, - NTabPane as D, - NTabs as E, + NIcon as A, + toDisplayString as B, + NTabPane as C, + NTabs as D, + spaceRegex as E, Fragment as F, - spaceRegex as G, - promptHandleKeyUp as H, - promptHandleKeyDown as I, - NInput as J, - watch as K, + promptHandleKeyUp as G, + promptHandleKeyDown as H, + NInput as I, + watch as J, + upscalerOptions as K, renderList as L, NScrollbar as M, - NSpace as N, + NCard as N, replaceable as O, createInjectionKey as P, cB as Q, @@ -43608,7 +43626,7 @@ export { getSlot$1 as ax, depx as ay, formatLength as az, - upscalerOptions as b, + createBaseVNode as b, VTarget as b$, NProgress as b0, NFadeInExpandTransition as b1, @@ -43673,33 +43691,33 @@ export { color2Class as bx, rateLight as by, NTag as bz, - computed as c, + createBlock as c, VFollower as c0, sliderLight$1 as c1, isSlotEmpty as c2, switchLight$1 as c3, NResult as c4, defineComponent as d, - createBlock as e, - createBaseVNode as f, - createVNode as g, - unref as h, - NSelect as i, - createElementBlock as j, + createVNode as e, + unref as f, + createElementBlock as g, + createCommentVNode as h, + computed as i, + NSpace as j, createTextVNode as k, NTooltip as l, - createCommentVNode as m, - NCard as n, + NSelect as m, + useMessage as n, openBlock as o, - useMessage as p, - onUnmounted as q, - NGi as r, - NGrid as s, - serverUrl as t, + onUnmounted as p, + NGi as q, + NGrid as r, + serverUrl as s, + pushScopeId as t, useSettings as u, - pushScopeId as v, + popScopeId as v, withCtx as w, - popScopeId as x, - h as y, - ref as z + h as x, + ref as y, + NButton as z }; diff --git a/frontend/src/components/generate/HighResFix.vue b/frontend/src/components/generate/HighResFix.vue index 9a5fa785d..85121cf92 100644 --- a/frontend/src/components/generate/HighResFix.vue +++ b/frontend/src/components/generate/HighResFix.vue @@ -4,17 +4,21 @@

Enabled

- +
- +

Mode

+

Upscaler

Antialiased

- +

Latent Mode

@@ -87,14 +87,14 @@

Scale

Strength

diff --git a/frontend/src/components/generate/index.ts b/frontend/src/components/generate/index.ts index 9a6acc202..fe53ac538 100644 --- a/frontend/src/components/generate/index.ts +++ b/frontend/src/components/generate/index.ts @@ -1,9 +1,10 @@ export { default as BatchSizeInput } from "./BatchSizeInput.vue"; +export { default as CFGScale } from "./CFGScaleInput.vue"; export { default as DimensionsInput } from "./DimensionsInput.vue"; export { default as HighResFix } from "./HighResFix.vue"; export { default as Prompt } from "./Prompt.vue"; export { default as ResizeFromDimensionsInput } from "./ResizeFromDimensionsInput.vue"; +export { default as SAGInput } from "./SAGInput.vue"; export { default as SamplerPicker } from "./SamplerPicker.vue"; +export { default as Upscale } from "./Upscale.vue"; export { default as XLRefiner } from "./XLRefiner.vue"; -export { default as CFGScale } from "./CFGScaleInput.vue"; -export { default as SAGInput } from "./SAGInput.vue"; diff --git a/frontend/src/components/imageProcessing/Upscale.vue b/frontend/src/components/imageProcessing/ESRGAN.vue similarity index 96% rename from frontend/src/components/imageProcessing/Upscale.vue rename to frontend/src/components/imageProcessing/ESRGAN.vue index 185246e45..e3b938e11 100644 --- a/frontend/src/components/imageProcessing/Upscale.vue +++ b/frontend/src/components/imageProcessing/ESRGAN.vue @@ -193,18 +193,3 @@ const generate = () => { }); }; - diff --git a/frontend/src/components/imageProcessing/index.ts b/frontend/src/components/imageProcessing/index.ts index b35cd812b..c27a8a325 100644 --- a/frontend/src/components/imageProcessing/index.ts +++ b/frontend/src/components/imageProcessing/index.ts @@ -1 +1 @@ -export { default as Upscale } from "./Upscale.vue"; +export { default as ESRGAN } from "./ESRGAN.vue"; diff --git a/frontend/src/components/inference/ControlNet.vue b/frontend/src/components/inference/ControlNet.vue index d54d9467f..c71636b13 100644 --- a/frontend/src/components/inference/ControlNet.vue +++ b/frontend/src/components/inference/ControlNet.vue @@ -221,6 +221,9 @@
+ + + @@ -250,15 +253,17 @@ import "@/assets/2img.css"; import { BurnerClock } from "@/clock"; import { BatchSizeInput, + CFGScale, DimensionsInput, GenerateSection, + HighResFix, ImageOutput, ImageUpload, OutputStats, Prompt, - SamplerPicker, - CFGScale, SAGInput, + SamplerPicker, + Upscale, } from "@/components"; import { serverUrl } from "@/env"; import { @@ -274,7 +279,7 @@ import { useMessage, } from "naive-ui"; import { v4 as uuidv4 } from "uuid"; -import { onUnmounted } from "vue"; +import { computed, onUnmounted } from "vue"; import { useSettings } from "../../store/settings"; import { useState } from "../../store/state"; @@ -282,6 +287,10 @@ const global = useState(); const settings = useSettings(); const messageHandler = useMessage(); +const isSelectedModelSDXL = computed(() => { + return settings.data.settings.model?.type === "SDXL"; +}); + const checkSeed = (seed: number) => { // If -1 create random seed if (seed === -1) { @@ -351,6 +360,36 @@ const generate = () => { settings.data.settings.controlnet.return_preprocessed, }, model: settings.data.settings.model?.path, + flags: { + ...(settings.data.settings.controlnet.highres.enabled + ? { + highres_fix: { + mode: settings.data.settings.controlnet.highres.mode, + image_upscaler: + settings.data.settings.controlnet.highres.image_upscaler, + scale: settings.data.settings.controlnet.highres.scale, + latent_scale_mode: + settings.data.settings.controlnet.highres.latent_scale_mode, + strength: settings.data.settings.controlnet.highres.strength, + steps: settings.data.settings.controlnet.highres.steps, + antialiased: + settings.data.settings.controlnet.highres.antialiased, + }, + } + : {}), + ...(settings.data.settings.controlnet.upscale.enabled + ? { + upscale: { + upscale_factor: + settings.data.settings.controlnet.upscale.upscale_factor, + tile_size: settings.data.settings.controlnet.upscale.tile_size, + tile_padding: + settings.data.settings.controlnet.upscale.tile_padding, + model: settings.data.settings.controlnet.upscale.model, + }, + } + : {}), + }, }), }) .then((res) => { diff --git a/frontend/src/components/inference/Img2Img.vue b/frontend/src/components/inference/Img2Img.vue index a9c999528..48478e66a 100644 --- a/frontend/src/components/inference/Img2Img.vue +++ b/frontend/src/components/inference/Img2Img.vue @@ -133,6 +133,9 @@
+ + + @@ -162,15 +165,17 @@ import "@/assets/2img.css"; import { BurnerClock } from "@/clock"; import { BatchSizeInput, + CFGScale, DimensionsInput, GenerateSection, + HighResFix, ImageOutput, ImageUpload, OutputStats, Prompt, - SamplerPicker, - CFGScale, SAGInput, + SamplerPicker, + Upscale, } from "@/components"; import { serverUrl } from "@/env"; import { @@ -184,7 +189,7 @@ import { useMessage, } from "naive-ui"; import { v4 as uuidv4 } from "uuid"; -import { onUnmounted } from "vue"; +import { computed, onUnmounted } from "vue"; import { useSettings } from "../../store/settings"; import { useState } from "../../store/state"; @@ -201,6 +206,10 @@ const checkSeed = (seed: number) => { return seed; }; +const isSelectedModelSDXL = computed(() => { + return settings.data.settings.model?.type === "SDXL"; +}); + const imageSelectCallback = (base64Image: string) => { settings.data.settings.img2img.image = base64Image; }; @@ -250,6 +259,35 @@ const generate = () => { }, }, model: settings.data.settings.model?.path, + flags: { + ...(settings.data.settings.img2img.highres.enabled + ? { + highres_fix: { + mode: settings.data.settings.img2img.highres.mode, + image_upscaler: + settings.data.settings.img2img.highres.image_upscaler, + scale: settings.data.settings.img2img.highres.scale, + latent_scale_mode: + settings.data.settings.img2img.highres.latent_scale_mode, + strength: settings.data.settings.img2img.highres.strength, + steps: settings.data.settings.img2img.highres.steps, + antialiased: settings.data.settings.img2img.highres.antialiased, + }, + } + : {}), + ...(settings.data.settings.img2img.upscale.enabled + ? { + upscale: { + upscale_factor: + settings.data.settings.img2img.upscale.upscale_factor, + tile_size: settings.data.settings.img2img.upscale.tile_size, + tile_padding: + settings.data.settings.img2img.upscale.tile_padding, + model: settings.data.settings.img2img.upscale.model, + }, + } + : {}), + }, }), }) .then((res) => { diff --git a/frontend/src/components/inference/Inpainting.vue b/frontend/src/components/inference/Inpainting.vue index b28f5b324..88b227d65 100644 --- a/frontend/src/components/inference/Inpainting.vue +++ b/frontend/src/components/inference/Inpainting.vue @@ -239,6 +239,9 @@
+ + + @@ -267,13 +270,15 @@ import "@/assets/2img.css"; import { BurnerClock } from "@/clock"; import { + CFGScale, GenerateSection, + HighResFix, ImageOutput, OutputStats, Prompt, - SamplerPicker, - CFGScale, SAGInput, + SamplerPicker, + Upscale, } from "@/components"; import { serverUrl } from "@/env"; import { @@ -295,7 +300,7 @@ import { useMessage, } from "naive-ui"; import { v4 as uuidv4 } from "uuid"; -import { onUnmounted, ref } from "vue"; +import { computed, onUnmounted, ref } from "vue"; import VueDrawingCanvas from "vue-drawing-canvas"; import { useSettings } from "../../store/settings"; import { useState } from "../../store/state"; @@ -304,6 +309,10 @@ const global = useState(); const settings = useSettings(); const messageHandler = useMessage(); +const isSelectedModelSDXL = computed(() => { + return settings.data.settings.model?.type === "SDXL"; +}); + const checkSeed = (seed: number) => { // If -1 create random seed if (seed === -1) { @@ -361,6 +370,36 @@ const generate = () => { }, }, model: settings.data.settings.model?.path, + flags: { + ...(settings.data.settings.inpainting.highres.enabled + ? { + highres_fix: { + mode: settings.data.settings.inpainting.highres.mode, + image_upscaler: + settings.data.settings.inpainting.highres.image_upscaler, + scale: settings.data.settings.inpainting.highres.scale, + latent_scale_mode: + settings.data.settings.inpainting.highres.latent_scale_mode, + strength: settings.data.settings.inpainting.highres.strength, + steps: settings.data.settings.inpainting.highres.steps, + antialiased: + settings.data.settings.inpainting.highres.antialiased, + }, + } + : {}), + ...(settings.data.settings.inpainting.upscale.enabled + ? { + upscale: { + upscale_factor: + settings.data.settings.inpainting.upscale.upscale_factor, + tile_size: settings.data.settings.inpainting.upscale.tile_size, + tile_padding: + settings.data.settings.inpainting.upscale.tile_padding, + model: settings.data.settings.inpainting.upscale.model, + }, + } + : {}), + }, }), }) .then((res) => { diff --git a/frontend/src/components/inference/Txt2Img.vue b/frontend/src/components/inference/Txt2Img.vue index 11b964e48..c6a51b135 100644 --- a/frontend/src/components/inference/Txt2Img.vue +++ b/frontend/src/components/inference/Txt2Img.vue @@ -97,7 +97,8 @@ v-if="settings.data.settings.model?.type === 'SDXL'" /> - + + @@ -125,6 +126,7 @@ diff --git a/frontend/src/components/settings/defaultSettings/ControlNetSettings.vue b/frontend/src/components/settings/defaultSettings/ControlNetSettings.vue index eec3dbaa0..fdeaea95b 100644 --- a/frontend/src/components/settings/defaultSettings/ControlNetSettings.vue +++ b/frontend/src/components/settings/defaultSettings/ControlNetSettings.vue @@ -77,13 +77,16 @@ :step="8" /> + + + diff --git a/frontend/src/components/generate/index.ts b/frontend/src/components/generate/index.ts index 9a6acc202..94ce900d9 100644 --- a/frontend/src/components/generate/index.ts +++ b/frontend/src/components/generate/index.ts @@ -7,3 +7,4 @@ export { default as SamplerPicker } from "./SamplerPicker.vue"; export { default as XLRefiner } from "./XLRefiner.vue"; export { default as CFGScale } from "./CFGScaleInput.vue"; export { default as SAGInput } from "./SAGInput.vue"; +export { default as Scalecrafter } from "./Scalecrafter.vue"; diff --git a/frontend/src/components/inference/Txt2Img.vue b/frontend/src/components/inference/Txt2Img.vue index 60b5063de..86b72d645 100644 --- a/frontend/src/components/inference/Txt2Img.vue +++ b/frontend/src/components/inference/Txt2Img.vue @@ -94,10 +94,11 @@ + @@ -136,6 +137,7 @@ import { XLRefiner, CFGScale, SAGInput, + Scalecrafter, } from "@/components"; import { serverUrl } from "@/env"; import { @@ -269,6 +271,17 @@ const generate = () => { }, } : {}), + ...(settings.defaultSettings.flags.scalecrafter.enabled + ? { + scalecrafter: { + unsafe_resolutions: + settings.defaultSettings.flags.scalecrafter + .unsafe_resolutions, + base: settings.data.settings.model?.type, + disperse: settings.defaultSettings.flags.scalecrafter.disperse, + }, + } + : {}), }, }), }) diff --git a/frontend/src/settings.ts b/frontend/src/settings.ts index 3f9713b77..1f70c1345 100644 --- a/frontend/src/settings.ts +++ b/frontend/src/settings.ts @@ -78,6 +78,12 @@ export interface ISettings { scaler: string; early_out: boolean; }; + scalecrafter: { + enabled: boolean; + base: string; + unsafe_resolutions: boolean; + disperse: boolean; + }; }; aitDim: { width: number[] | undefined; @@ -312,6 +318,12 @@ export const defaultSettings: ISettings = { base_scale: 0.5, scaler: "bislerp", }, + scalecrafter: { + enabled: false, + base: "sd15", + unsafe_resolutions: true, + disperse: false, + }, }, aitDim: { width: undefined, From 97c960912b3eda87353fdb3b4c7da9a44a8849ef Mon Sep 17 00:00:00 2001 From: gabe56f Date: Sat, 9 Dec 2023 17:34:40 +0100 Subject: [PATCH 097/143] format --- core/scheduling/custom/sasolver.py | 632 ++++++++++++++++++++--------- 1 file changed, 438 insertions(+), 194 deletions(-) diff --git a/core/scheduling/custom/sasolver.py b/core/scheduling/custom/sasolver.py index a1510b23b..3a2afc25a 100644 --- a/core/scheduling/custom/sasolver.py +++ b/core/scheduling/custom/sasolver.py @@ -25,14 +25,18 @@ from diffusers.configuration_utils import ConfigMixin, register_to_config from diffusers.utils.torch_utils import randn_tensor -from diffusers.schedulers.scheduling_utils import KarrasDiffusionSchedulers, SchedulerMixin, SchedulerOutput +from diffusers.schedulers.scheduling_utils import ( + KarrasDiffusionSchedulers, + SchedulerMixin, + SchedulerOutput, +) # Copied from diffusers.schedulers.scheduling_ddpm.betas_for_alpha_bar def betas_for_alpha_bar( - num_diffusion_timesteps, - max_beta=0.999, - alpha_transform_type="cosine", + num_diffusion_timesteps, + max_beta=0.999, + alpha_transform_type="cosine", ): """ Create a beta schedule that discretizes the given alpha_t_bar function, which defines the cumulative product of @@ -141,42 +145,52 @@ class SASolverScheduler(SchedulerMixin, ConfigMixin): @register_to_config def __init__( - self, - num_train_timesteps: int = 1000, - beta_start: float = 0.0001, - beta_end: float = 0.02, - beta_schedule: str = "linear", - trained_betas: Optional[Union[np.ndarray, List[float]]] = None, - predictor_order: int = 2, - corrector_order: int = 2, - predictor_corrector_mode: str = 'PEC', - prediction_type: str = "epsilon", - tau_func: Callable = lambda t: 1 if t >= 200 and t <= 800 else 0, - thresholding: bool = False, - dynamic_thresholding_ratio: float = 0.995, - sample_max_value: float = 1.0, - algorithm_type: str = "data_prediction", - lower_order_final: bool = True, - use_karras_sigmas: Optional[bool] = False, - lambda_min_clipped: float = -float("inf"), - variance_type: Optional[str] = None, - timestep_spacing: str = "linspace", - steps_offset: int = 0, + self, + num_train_timesteps: int = 1000, + beta_start: float = 0.0001, + beta_end: float = 0.02, + beta_schedule: str = "linear", + trained_betas: Optional[Union[np.ndarray, List[float]]] = None, + predictor_order: int = 2, + corrector_order: int = 2, + predictor_corrector_mode: str = "PEC", + prediction_type: str = "epsilon", + tau_func: Callable = lambda t: 1 if t >= 200 and t <= 800 else 0, + thresholding: bool = False, + dynamic_thresholding_ratio: float = 0.995, + sample_max_value: float = 1.0, + algorithm_type: str = "data_prediction", + lower_order_final: bool = True, + use_karras_sigmas: Optional[bool] = False, + lambda_min_clipped: float = -float("inf"), + variance_type: Optional[str] = None, + timestep_spacing: str = "linspace", + steps_offset: int = 0, ): if trained_betas is not None: self.betas = torch.tensor(trained_betas, dtype=torch.float32) elif beta_schedule == "linear": - self.betas = torch.linspace(beta_start, beta_end, num_train_timesteps, dtype=torch.float32) + self.betas = torch.linspace( + beta_start, beta_end, num_train_timesteps, dtype=torch.float32 + ) elif beta_schedule == "scaled_linear": # this schedule is very specific to the latent diffusion model. self.betas = ( - torch.linspace(beta_start ** 0.5, beta_end ** 0.5, num_train_timesteps, dtype=torch.float32) ** 2 + torch.linspace( + beta_start**0.5, + beta_end**0.5, + num_train_timesteps, + dtype=torch.float32, + ) + ** 2 ) elif beta_schedule == "squaredcos_cap_v2": # Glide cosine schedule self.betas = betas_for_alpha_bar(num_train_timesteps) else: - raise NotImplementedError(f"{beta_schedule} does is not implemented for {self.__class__}") + raise NotImplementedError( + f"{beta_schedule} does is not implemented for {self.__class__}" + ) self.alphas = 1.0 - self.betas self.alphas_cumprod = torch.cumprod(self.alphas, dim=0) @@ -189,11 +203,15 @@ def __init__( self.init_noise_sigma = 1.0 if algorithm_type not in ["data_prediction", "noise_prediction"]: - raise NotImplementedError(f"{algorithm_type} does is not implemented for {self.__class__}") + raise NotImplementedError( + f"{algorithm_type} does is not implemented for {self.__class__}" + ) # setable values self.num_inference_steps = None - timesteps = np.linspace(0, num_train_timesteps - 1, num_train_timesteps, dtype=np.float32)[::-1].copy() + timesteps = np.linspace( + 0, num_train_timesteps - 1, num_train_timesteps, dtype=np.float32 + )[::-1].copy() self.timesteps = torch.from_numpy(timesteps) self.timestep_list = [None] * max(predictor_order, corrector_order - 1) self.model_outputs = [None] * max(predictor_order, corrector_order - 1) @@ -203,7 +221,9 @@ def __init__( self.lower_order_nums = 0 self.last_sample = None - def set_timesteps(self, num_inference_steps: int = None, device: Union[str, torch.device] = None): + def set_timesteps( + self, num_inference_steps: int = None, device: Union[str, torch.device] = None + ): """ Sets the discrete timesteps used for the diffusion chain (to be run before inference). @@ -215,26 +235,38 @@ def set_timesteps(self, num_inference_steps: int = None, device: Union[str, torc """ # Clipping the minimum of all lambda(t) for numerical stability. # This is critical for cosine (squaredcos_cap_v2) noise schedule. - clipped_idx = torch.searchsorted(torch.flip(self.lambda_t, [0]), self.config.lambda_min_clipped) + clipped_idx = torch.searchsorted( + torch.flip(self.lambda_t, [0]), self.config.lambda_min_clipped + ) last_timestep = ((self.config.num_train_timesteps - clipped_idx).numpy()).item() # "linspace", "leading", "trailing" corresponds to annotation of Table 2. of https://arxiv.org/abs/2305.08891 if self.config.timestep_spacing == "linspace": timesteps = ( - np.linspace(0, last_timestep - 1, num_inference_steps + 1).round()[::-1][:-1].copy().astype(np.int64) + np.linspace(0, last_timestep - 1, num_inference_steps + 1) + .round()[::-1][:-1] + .copy() + .astype(np.int64) ) elif self.config.timestep_spacing == "leading": step_ratio = last_timestep // (num_inference_steps + 1) # creates integer timesteps by multiplying by ratio # casting to int to avoid issues when num_inference_step is power of 3 - timesteps = (np.arange(0, num_inference_steps + 1) * step_ratio).round()[::-1][:-1].copy().astype(np.int64) + timesteps = ( + (np.arange(0, num_inference_steps + 1) * step_ratio) + .round()[::-1][:-1] + .copy() + .astype(np.int64) + ) timesteps += self.config.steps_offset elif self.config.timestep_spacing == "trailing": step_ratio = self.config.num_train_timesteps / num_inference_steps # creates integer timesteps by multiplying by ratio # casting to int to avoid issues when num_inference_step is power of 3 - timesteps = np.arange(last_timestep, 0, -step_ratio).round().copy().astype(np.int64) + timesteps = ( + np.arange(last_timestep, 0, -step_ratio).round().copy().astype(np.int64) + ) timesteps -= 1 else: raise ValueError( @@ -244,8 +276,12 @@ def set_timesteps(self, num_inference_steps: int = None, device: Union[str, torc sigmas = np.array(((1 - self.alphas_cumprod) / self.alphas_cumprod) ** 0.5) if self.config.use_karras_sigmas: log_sigmas = np.log(sigmas) - sigmas = self._convert_to_karras(in_sigmas=sigmas, num_inference_steps=num_inference_steps) - timesteps = np.array([self._sigma_to_t(sigma, log_sigmas) for sigma in sigmas]).round() + sigmas = self._convert_to_karras( + in_sigmas=sigmas, num_inference_steps=num_inference_steps + ) + timesteps = np.array( + [self._sigma_to_t(sigma, log_sigmas) for sigma in sigmas] + ).round() timesteps = np.flip(timesteps).copy().astype(np.int64) self.sigmas = torch.from_numpy(sigmas) @@ -260,8 +296,8 @@ def set_timesteps(self, num_inference_steps: int = None, device: Union[str, torc self.num_inference_steps = len(timesteps) self.model_outputs = [ - None, - ] * max(self.config.predictor_order, self.config.corrector_order - 1) + None, + ] * max(self.config.predictor_order, self.config.corrector_order - 1) self.lower_order_nums = 0 self.last_sample = None @@ -280,7 +316,9 @@ def _threshold_sample(self, sample: torch.FloatTensor) -> torch.FloatTensor: batch_size, channels, height, width = sample.shape if dtype not in (torch.float32, torch.float64): - sample = sample.float() # upcast for quantile calculation, and clamp not implemented for cpu half + sample = ( + sample.float() + ) # upcast for quantile calculation, and clamp not implemented for cpu half # Flatten sample for doing quantile calculation along each image sample = sample.reshape(batch_size, channels * height * width) @@ -293,7 +331,9 @@ def _threshold_sample(self, sample: torch.FloatTensor) -> torch.FloatTensor: ) # When clamped to min=1, equivalent to standard clipping to [-1, 1] s = s.unsqueeze(1) # (batch_size, 1) because clamp will broadcast along dim=0 - sample = torch.clamp(sample, -s, s) / s # "we threshold xt0 to the range [-s, s] and then divide by s" + sample = ( + torch.clamp(sample, -s, s) / s + ) # "we threshold xt0 to the range [-s, s] and then divide by s" sample = sample.reshape(batch_size, channels, height, width) sample = sample.to(dtype) @@ -309,7 +349,11 @@ def _sigma_to_t(self, sigma, log_sigmas): dists = log_sigma - log_sigmas[:, np.newaxis] # get sigmas range - low_idx = np.cumsum((dists >= 0), axis=0).argmax(axis=0).clip(max=log_sigmas.shape[0] - 2) + low_idx = ( + np.cumsum((dists >= 0), axis=0) + .argmax(axis=0) + .clip(max=log_sigmas.shape[0] - 2) + ) high_idx = low_idx + 1 low = log_sigmas[low_idx] @@ -325,7 +369,9 @@ def _sigma_to_t(self, sigma, log_sigmas): return t # Copied from diffusers.schedulers.scheduling_euler_discrete.EulerDiscreteScheduler._convert_to_karras - def _convert_to_karras(self, in_sigmas: torch.FloatTensor, num_inference_steps) -> torch.FloatTensor: + def _convert_to_karras( + self, in_sigmas: torch.FloatTensor, num_inference_steps + ) -> torch.FloatTensor: """Constructs the noise schedule of Karras et al. (2022).""" sigma_min: float = in_sigmas[-1].item() @@ -339,7 +385,7 @@ def _convert_to_karras(self, in_sigmas: torch.FloatTensor, num_inference_steps) return sigmas def convert_model_output( - self, model_output: torch.FloatTensor, timestep: int, sample: torch.FloatTensor + self, model_output: torch.FloatTensor, timestep: int, sample: torch.FloatTensor ) -> torch.FloatTensor: """ Convert the model output to the corresponding type the DPMSolver/DPMSolver++ algorithm needs. DPM-Solver is @@ -418,51 +464,94 @@ def convert_model_output( return epsilon - def get_coefficients_exponential_negative(self, order, interval_start, interval_end): + def get_coefficients_exponential_negative( + self, order, interval_start, interval_end + ): """ Calculate the integral of exp(-x) * x^order dx from interval_start to interval_end """ assert order in [0, 1, 2, 3], "order is only supported for 0, 1, 2 and 3" if order == 0: - return torch.exp(-interval_end) * (torch.exp(interval_end - interval_start) - 1) + return torch.exp(-interval_end) * ( + torch.exp(interval_end - interval_start) - 1 + ) elif order == 1: return torch.exp(-interval_end) * ( - (interval_start + 1) * torch.exp(interval_end - interval_start) - (interval_end + 1)) + (interval_start + 1) * torch.exp(interval_end - interval_start) + - (interval_end + 1) + ) elif order == 2: return torch.exp(-interval_end) * ( - (interval_start ** 2 + 2 * interval_start + 2) * torch.exp(interval_end - interval_start) - ( - interval_end ** 2 + 2 * interval_end + 2)) + (interval_start**2 + 2 * interval_start + 2) + * torch.exp(interval_end - interval_start) + - (interval_end**2 + 2 * interval_end + 2) + ) elif order == 3: return torch.exp(-interval_end) * ( - (interval_start ** 3 + 3 * interval_start ** 2 + 6 * interval_start + 6) * torch.exp( - interval_end - interval_start) - (interval_end ** 3 + 3 * interval_end ** 2 + 6 * interval_end + 6)) + (interval_start**3 + 3 * interval_start**2 + 6 * interval_start + 6) + * torch.exp(interval_end - interval_start) + - (interval_end**3 + 3 * interval_end**2 + 6 * interval_end + 6) + ) - def get_coefficients_exponential_positive(self, order, interval_start, interval_end, tau): + def get_coefficients_exponential_positive( + self, order, interval_start, interval_end, tau + ): """ Calculate the integral of exp(x(1+tau^2)) * x^order dx from interval_start to interval_end """ assert order in [0, 1, 2, 3], "order is only supported for 0, 1, 2 and 3" # after change of variable(cov) - interval_end_cov = (1 + tau ** 2) * interval_end - interval_start_cov = (1 + tau ** 2) * interval_start + interval_end_cov = (1 + tau**2) * interval_end + interval_start_cov = (1 + tau**2) * interval_start if order == 0: - return torch.exp(interval_end_cov) * (1 - torch.exp(-(interval_end_cov - interval_start_cov))) / ( - (1 + tau ** 2)) + return ( + torch.exp(interval_end_cov) + * (1 - torch.exp(-(interval_end_cov - interval_start_cov))) + / ((1 + tau**2)) + ) elif order == 1: - return torch.exp(interval_end_cov) * ((interval_end_cov - 1) - (interval_start_cov - 1) * torch.exp( - -(interval_end_cov - interval_start_cov))) / ((1 + tau ** 2) ** 2) + return ( + torch.exp(interval_end_cov) + * ( + (interval_end_cov - 1) + - (interval_start_cov - 1) + * torch.exp(-(interval_end_cov - interval_start_cov)) + ) + / ((1 + tau**2) ** 2) + ) elif order == 2: - return torch.exp(interval_end_cov) * ((interval_end_cov ** 2 - 2 * interval_end_cov + 2) - ( - interval_start_cov ** 2 - 2 * interval_start_cov + 2) * torch.exp( - -(interval_end_cov - interval_start_cov))) / ((1 + tau ** 2) ** 3) + return ( + torch.exp(interval_end_cov) + * ( + (interval_end_cov**2 - 2 * interval_end_cov + 2) + - (interval_start_cov**2 - 2 * interval_start_cov + 2) + * torch.exp(-(interval_end_cov - interval_start_cov)) + ) + / ((1 + tau**2) ** 3) + ) elif order == 3: - return torch.exp(interval_end_cov) * ( - (interval_end_cov ** 3 - 3 * interval_end_cov ** 2 + 6 * interval_end_cov - 6) - ( - interval_start_cov ** 3 - 3 * interval_start_cov ** 2 + 6 * interval_start_cov - 6) * torch.exp( - -(interval_end_cov - interval_start_cov))) / ((1 + tau ** 2) ** 4) + return ( + torch.exp(interval_end_cov) + * ( + ( + interval_end_cov**3 + - 3 * interval_end_cov**2 + + 6 * interval_end_cov + - 6 + ) + - ( + interval_start_cov**3 + - 3 * interval_start_cov**2 + + 6 * interval_start_cov + - 6 + ) + * torch.exp(-(interval_end_cov - interval_start_cov)) + ) + / ((1 + tau**2) ** 4) + ) def lagrange_polynomial_coefficient(self, order, lambda_list): """ @@ -474,86 +563,151 @@ def lagrange_polynomial_coefficient(self, order, lambda_list): if order == 0: return [[1]] elif order == 1: - return [[1 / (lambda_list[0] - lambda_list[1]), -lambda_list[1] / (lambda_list[0] - lambda_list[1])], - [1 / (lambda_list[1] - lambda_list[0]), -lambda_list[0] / (lambda_list[1] - lambda_list[0])]] + return [ + [ + 1 / (lambda_list[0] - lambda_list[1]), + -lambda_list[1] / (lambda_list[0] - lambda_list[1]), + ], + [ + 1 / (lambda_list[1] - lambda_list[0]), + -lambda_list[0] / (lambda_list[1] - lambda_list[0]), + ], + ] elif order == 2: - denominator1 = (lambda_list[0] - lambda_list[1]) * (lambda_list[0] - lambda_list[2]) - denominator2 = (lambda_list[1] - lambda_list[0]) * (lambda_list[1] - lambda_list[2]) - denominator3 = (lambda_list[2] - lambda_list[0]) * (lambda_list[2] - lambda_list[1]) - return [[1 / denominator1, - (-lambda_list[1] - lambda_list[2]) / denominator1, - lambda_list[1] * lambda_list[2] / denominator1], - - [1 / denominator2, - (-lambda_list[0] - lambda_list[2]) / denominator2, - lambda_list[0] * lambda_list[2] / denominator2], - - [1 / denominator3, - (-lambda_list[0] - lambda_list[1]) / denominator3, - lambda_list[0] * lambda_list[1] / denominator3] - ] + denominator1 = (lambda_list[0] - lambda_list[1]) * ( + lambda_list[0] - lambda_list[2] + ) + denominator2 = (lambda_list[1] - lambda_list[0]) * ( + lambda_list[1] - lambda_list[2] + ) + denominator3 = (lambda_list[2] - lambda_list[0]) * ( + lambda_list[2] - lambda_list[1] + ) + return [ + [ + 1 / denominator1, + (-lambda_list[1] - lambda_list[2]) / denominator1, + lambda_list[1] * lambda_list[2] / denominator1, + ], + [ + 1 / denominator2, + (-lambda_list[0] - lambda_list[2]) / denominator2, + lambda_list[0] * lambda_list[2] / denominator2, + ], + [ + 1 / denominator3, + (-lambda_list[0] - lambda_list[1]) / denominator3, + lambda_list[0] * lambda_list[1] / denominator3, + ], + ] elif order == 3: - denominator1 = (lambda_list[0] - lambda_list[1]) * (lambda_list[0] - lambda_list[2]) * ( - lambda_list[0] - lambda_list[3]) - denominator2 = (lambda_list[1] - lambda_list[0]) * (lambda_list[1] - lambda_list[2]) * ( - lambda_list[1] - lambda_list[3]) - denominator3 = (lambda_list[2] - lambda_list[0]) * (lambda_list[2] - lambda_list[1]) * ( - lambda_list[2] - lambda_list[3]) - denominator4 = (lambda_list[3] - lambda_list[0]) * (lambda_list[3] - lambda_list[1]) * ( - lambda_list[3] - lambda_list[2]) - return [[1 / denominator1, - (-lambda_list[1] - lambda_list[2] - lambda_list[3]) / denominator1, - (lambda_list[1] * lambda_list[2] + lambda_list[1] * lambda_list[3] + lambda_list[2] * lambda_list[ - 3]) / denominator1, - (-lambda_list[1] * lambda_list[2] * lambda_list[3]) / denominator1], - - [1 / denominator2, - (-lambda_list[0] - lambda_list[2] - lambda_list[3]) / denominator2, - (lambda_list[0] * lambda_list[2] + lambda_list[0] * lambda_list[3] + lambda_list[2] * lambda_list[ - 3]) / denominator2, - (-lambda_list[0] * lambda_list[2] * lambda_list[3]) / denominator2], - - [1 / denominator3, - (-lambda_list[0] - lambda_list[1] - lambda_list[3]) / denominator3, - (lambda_list[0] * lambda_list[1] + lambda_list[0] * lambda_list[3] + lambda_list[1] * lambda_list[ - 3]) / denominator3, - (-lambda_list[0] * lambda_list[1] * lambda_list[3]) / denominator3], - - [1 / denominator4, - (-lambda_list[0] - lambda_list[1] - lambda_list[2]) / denominator4, - (lambda_list[0] * lambda_list[1] + lambda_list[0] * lambda_list[2] + lambda_list[1] * lambda_list[ - 2]) / denominator4, - (-lambda_list[0] * lambda_list[1] * lambda_list[2]) / denominator4] - - ] - - def get_coefficients_fn(self, order, interval_start, interval_end, lambda_list, tau): + denominator1 = ( + (lambda_list[0] - lambda_list[1]) + * (lambda_list[0] - lambda_list[2]) + * (lambda_list[0] - lambda_list[3]) + ) + denominator2 = ( + (lambda_list[1] - lambda_list[0]) + * (lambda_list[1] - lambda_list[2]) + * (lambda_list[1] - lambda_list[3]) + ) + denominator3 = ( + (lambda_list[2] - lambda_list[0]) + * (lambda_list[2] - lambda_list[1]) + * (lambda_list[2] - lambda_list[3]) + ) + denominator4 = ( + (lambda_list[3] - lambda_list[0]) + * (lambda_list[3] - lambda_list[1]) + * (lambda_list[3] - lambda_list[2]) + ) + return [ + [ + 1 / denominator1, + (-lambda_list[1] - lambda_list[2] - lambda_list[3]) / denominator1, + ( + lambda_list[1] * lambda_list[2] + + lambda_list[1] * lambda_list[3] + + lambda_list[2] * lambda_list[3] + ) + / denominator1, + (-lambda_list[1] * lambda_list[2] * lambda_list[3]) / denominator1, + ], + [ + 1 / denominator2, + (-lambda_list[0] - lambda_list[2] - lambda_list[3]) / denominator2, + ( + lambda_list[0] * lambda_list[2] + + lambda_list[0] * lambda_list[3] + + lambda_list[2] * lambda_list[3] + ) + / denominator2, + (-lambda_list[0] * lambda_list[2] * lambda_list[3]) / denominator2, + ], + [ + 1 / denominator3, + (-lambda_list[0] - lambda_list[1] - lambda_list[3]) / denominator3, + ( + lambda_list[0] * lambda_list[1] + + lambda_list[0] * lambda_list[3] + + lambda_list[1] * lambda_list[3] + ) + / denominator3, + (-lambda_list[0] * lambda_list[1] * lambda_list[3]) / denominator3, + ], + [ + 1 / denominator4, + (-lambda_list[0] - lambda_list[1] - lambda_list[2]) / denominator4, + ( + lambda_list[0] * lambda_list[1] + + lambda_list[0] * lambda_list[2] + + lambda_list[1] * lambda_list[2] + ) + / denominator4, + (-lambda_list[0] * lambda_list[1] * lambda_list[2]) / denominator4, + ], + ] + + def get_coefficients_fn( + self, order, interval_start, interval_end, lambda_list, tau + ): assert order in [1, 2, 3, 4] - assert order == len(lambda_list), 'the length of lambda list must be equal to the order' + assert order == len( + lambda_list + ), "the length of lambda list must be equal to the order" coefficients = [] - lagrange_coefficient = self.lagrange_polynomial_coefficient(order - 1, lambda_list) + lagrange_coefficient = self.lagrange_polynomial_coefficient( + order - 1, lambda_list + ) for i in range(order): coefficient = 0 for j in range(order): if self.predict_x0: - - coefficient += lagrange_coefficient[i][j] * self.get_coefficients_exponential_positive( - order - 1 - j, interval_start, interval_end, tau) + coefficient += lagrange_coefficient[i][ + j + ] * self.get_coefficients_exponential_positive( + order - 1 - j, interval_start, interval_end, tau + ) else: - coefficient += lagrange_coefficient[i][j] * self.get_coefficients_exponential_negative( - order - 1 - j, interval_start, interval_end) + coefficient += lagrange_coefficient[i][ + j + ] * self.get_coefficients_exponential_negative( + order - 1 - j, interval_start, interval_end + ) coefficients.append(coefficient) - assert len(coefficients) == order, 'the length of coefficients does not match the order' + assert ( + len(coefficients) == order + ), "the length of coefficients does not match the order" return coefficients def stochastic_adams_bashforth_update( - self, - model_output: torch.FloatTensor, - prev_timestep: int, - sample: torch.FloatTensor, - noise: torch.FloatTensor, - order: int, - tau: torch.FloatTensor, + self, + model_output: torch.FloatTensor, + prev_timestep: int, + sample: torch.FloatTensor, + noise: torch.FloatTensor, + order: int, + tau: torch.FloatTensor, ) -> torch.FloatTensor: """ One step for the SA-Predictor. @@ -587,40 +741,75 @@ def stochastic_adams_bashforth_update( for i in range(order): lambda_list.append(self.lambda_t[timestep_list[-(i + 1)]]) - gradient_coefficients = self.get_coefficients_fn(order, lambda_s0, lambda_t, lambda_list, tau) + gradient_coefficients = self.get_coefficients_fn( + order, lambda_s0, lambda_t, lambda_list, tau + ) x = sample if self.predict_x0: - if order == 2: ## if order = 2 we do a modification that does not influence the convergence order similar to unipc. Note: This is used only for few steps sampling. + if ( + order == 2 + ): ## if order = 2 we do a modification that does not influence the convergence order similar to unipc. Note: This is used only for few steps sampling. # The added term is O(h^3). Empirically we find it will slightly improve the image quality. # ODE case # gradient_coefficients[0] += 1.0 * torch.exp(lambda_t) * (h ** 2 / 2 - (h - 1 + torch.exp(-h))) / (ns.marginal_lambda(t_prev_list[-1]) - ns.marginal_lambda(t_prev_list[-2])) # gradient_coefficients[1] -= 1.0 * torch.exp(lambda_t) * (h ** 2 / 2 - (h - 1 + torch.exp(-h))) / (ns.marginal_lambda(t_prev_list[-1]) - ns.marginal_lambda(t_prev_list[-2])) - gradient_coefficients[0] += 1.0 * torch.exp((1 + tau ** 2) * lambda_t) * ( - h ** 2 / 2 - (h * (1 + tau ** 2) - 1 + torch.exp((1 + tau ** 2) * (-h))) / ( - (1 + tau ** 2) ** 2)) / (self.lambda_t[timestep_list[-1]] - self.lambda_t[ - timestep_list[-2]]) - gradient_coefficients[1] -= 1.0 * torch.exp((1 + tau ** 2) * lambda_t) * ( - h ** 2 / 2 - (h * (1 + tau ** 2) - 1 + torch.exp((1 + tau ** 2) * (-h))) / ( - (1 + tau ** 2) ** 2)) / (self.lambda_t[timestep_list[-1]] - self.lambda_t[ - timestep_list[-2]]) + gradient_coefficients[0] += ( + 1.0 + * torch.exp((1 + tau**2) * lambda_t) + * ( + h**2 / 2 + - (h * (1 + tau**2) - 1 + torch.exp((1 + tau**2) * (-h))) + / ((1 + tau**2) ** 2) + ) + / ( + self.lambda_t[timestep_list[-1]] + - self.lambda_t[timestep_list[-2]] + ) + ) + gradient_coefficients[1] -= ( + 1.0 + * torch.exp((1 + tau**2) * lambda_t) + * ( + h**2 / 2 + - (h * (1 + tau**2) - 1 + torch.exp((1 + tau**2) * (-h))) + / ((1 + tau**2) ** 2) + ) + / ( + self.lambda_t[timestep_list[-1]] + - self.lambda_t[timestep_list[-2]] + ) + ) for i in range(order): if self.predict_x0: - - gradient_part += (1 + tau ** 2) * sigma_t * torch.exp(- tau ** 2 * lambda_t) * gradient_coefficients[ - i] * model_output_list[-(i + 1)] + gradient_part += ( + (1 + tau**2) + * sigma_t + * torch.exp(-(tau**2) * lambda_t) + * gradient_coefficients[i] + * model_output_list[-(i + 1)] + ) else: - gradient_part += -(1 + tau ** 2) * alpha_t * gradient_coefficients[i] * model_output_list[-(i + 1)] + gradient_part += ( + -(1 + tau**2) + * alpha_t + * gradient_coefficients[i] + * model_output_list[-(i + 1)] + ) if self.predict_x0: - noise_part = sigma_t * torch.sqrt(1 - torch.exp(-2 * tau ** 2 * h)) * noise + noise_part = sigma_t * torch.sqrt(1 - torch.exp(-2 * tau**2 * h)) * noise else: noise_part = tau * sigma_t * torch.sqrt(torch.exp(2 * h) - 1) * noise if self.predict_x0: - x_t = torch.exp(-tau ** 2 * h) * (sigma_t / sigma_s0) * x + gradient_part + noise_part + x_t = ( + torch.exp(-(tau**2) * h) * (sigma_t / sigma_s0) * x + + gradient_part + + noise_part + ) else: x_t = (alpha_t / alpha_s0) * x + gradient_part + noise_part @@ -628,14 +817,14 @@ def stochastic_adams_bashforth_update( return x_t def stochastic_adams_moulton_update( - self, - this_model_output: torch.FloatTensor, - this_timestep: int, - last_sample: torch.FloatTensor, - last_noise: torch.FloatTensor, - this_sample: torch.FloatTensor, - order: int, - tau: torch.FloatTensor, + self, + this_model_output: torch.FloatTensor, + this_timestep: int, + last_sample: torch.FloatTensor, + last_noise: torch.FloatTensor, + this_sample: torch.FloatTensor, + order: int, + tau: torch.FloatTensor, ) -> torch.FloatTensor: """ One step for the SA-Corrector. @@ -673,37 +862,69 @@ def stochastic_adams_moulton_update( model_prev_list = model_output_list + [this_model_output] - gradient_coefficients = self.get_coefficients_fn(order, lambda_s0, lambda_t, lambda_list, tau) + gradient_coefficients = self.get_coefficients_fn( + order, lambda_s0, lambda_t, lambda_list, tau + ) x = last_sample if self.predict_x0: - if order == 2: ## if order = 2 we do a modification that does not influence the convergence order similar to UniPC. Note: This is used only for few steps sampling. + if ( + order == 2 + ): ## if order = 2 we do a modification that does not influence the convergence order similar to UniPC. Note: This is used only for few steps sampling. # The added term is O(h^3). Empirically we find it will slightly improve the image quality. # ODE case # gradient_coefficients[0] += 1.0 * torch.exp(lambda_t) * (h / 2 - (h - 1 + torch.exp(-h)) / h) # gradient_coefficients[1] -= 1.0 * torch.exp(lambda_t) * (h / 2 - (h - 1 + torch.exp(-h)) / h) - gradient_coefficients[0] += 1.0 * torch.exp((1 + tau ** 2) * lambda_t) * ( - h / 2 - (h * (1 + tau ** 2) - 1 + torch.exp((1 + tau ** 2) * (-h))) / ( - (1 + tau ** 2) ** 2 * h)) - gradient_coefficients[1] -= 1.0 * torch.exp((1 + tau ** 2) * lambda_t) * ( - h / 2 - (h * (1 + tau ** 2) - 1 + torch.exp((1 + tau ** 2) * (-h))) / ( - (1 + tau ** 2) ** 2 * h)) + gradient_coefficients[0] += ( + 1.0 + * torch.exp((1 + tau**2) * lambda_t) + * ( + h / 2 + - (h * (1 + tau**2) - 1 + torch.exp((1 + tau**2) * (-h))) + / ((1 + tau**2) ** 2 * h) + ) + ) + gradient_coefficients[1] -= ( + 1.0 + * torch.exp((1 + tau**2) * lambda_t) + * ( + h / 2 + - (h * (1 + tau**2) - 1 + torch.exp((1 + tau**2) * (-h))) + / ((1 + tau**2) ** 2 * h) + ) + ) for i in range(order): if self.predict_x0: - gradient_part += (1 + tau ** 2) * sigma_t * torch.exp(- tau ** 2 * lambda_t) * gradient_coefficients[ - i] * model_prev_list[-(i + 1)] + gradient_part += ( + (1 + tau**2) + * sigma_t + * torch.exp(-(tau**2) * lambda_t) + * gradient_coefficients[i] + * model_prev_list[-(i + 1)] + ) else: - gradient_part += -(1 + tau ** 2) * alpha_t * gradient_coefficients[i] * model_prev_list[-(i + 1)] + gradient_part += ( + -(1 + tau**2) + * alpha_t + * gradient_coefficients[i] + * model_prev_list[-(i + 1)] + ) if self.predict_x0: - noise_part = sigma_t * torch.sqrt(1 - torch.exp(-2 * tau ** 2 * h)) * last_noise + noise_part = ( + sigma_t * torch.sqrt(1 - torch.exp(-2 * tau**2 * h)) * last_noise + ) else: noise_part = tau * sigma_t * torch.sqrt(torch.exp(2 * h) - 1) * last_noise if self.predict_x0: - x_t = torch.exp(-tau ** 2 * h) * (sigma_t / sigma_s0) * x + gradient_part + noise_part + x_t = ( + torch.exp(-(tau**2) * h) * (sigma_t / sigma_s0) * x + + gradient_part + + noise_part + ) else: x_t = (alpha_t / alpha_s0) * x + gradient_part + noise_part @@ -711,12 +932,12 @@ def stochastic_adams_moulton_update( return x_t def step( - self, - model_output: torch.FloatTensor, - timestep: int, - sample: torch.FloatTensor, - generator=None, - return_dict: bool = True, + self, + model_output: torch.FloatTensor, + timestep: int, + sample: torch.FloatTensor, + generator=None, + return_dict: bool = True, ) -> Union[SchedulerOutput, Tuple]: """ Predict the sample from the previous timestep by reversing the SDE. This function propagates the sample with @@ -753,9 +974,7 @@ def step( else: step_index = step_index.item() - use_corrector = ( - step_index > 0 and self.last_sample is not None - ) + use_corrector = step_index > 0 and self.last_sample is not None model_output_convert = self.convert_model_output(model_output, timestep, sample) @@ -771,9 +990,15 @@ def step( tau=current_tau, ) - prev_timestep = 0 if step_index == len(self.timesteps) - 1 else self.timesteps[step_index + 1] + prev_timestep = ( + 0 + if step_index == len(self.timesteps) - 1 + else self.timesteps[step_index + 1] + ) - for i in range(max(self.config.predictor_order, self.config.corrector_order - 1) - 1): + for i in range( + max(self.config.predictor_order, self.config.corrector_order - 1) - 1 + ): self.model_outputs[i] = self.model_outputs[i + 1] self.timestep_list[i] = self.timestep_list[i + 1] @@ -781,18 +1006,29 @@ def step( self.timestep_list[-1] = timestep noise = randn_tensor( - model_output.shape, generator=generator, device=model_output.device, dtype=model_output.dtype + model_output.shape, + generator=generator, + device=model_output.device, + dtype=model_output.dtype, ) if self.config.lower_order_final: - this_predictor_order = min(self.config.predictor_order, len(self.timesteps) - step_index) - this_corrector_order = min(self.config.corrector_order, len(self.timesteps) - step_index + 1) + this_predictor_order = min( + self.config.predictor_order, len(self.timesteps) - step_index + ) + this_corrector_order = min( + self.config.corrector_order, len(self.timesteps) - step_index + 1 + ) else: this_predictor_order = self.config.predictor_order this_corrector_order = self.config.corrector_order - self.this_predictor_order = min(this_predictor_order, self.lower_order_nums + 1) # warmup for multistep - self.this_corrector_order = min(this_corrector_order, self.lower_order_nums + 2) # warmup for multistep + self.this_predictor_order = min( + this_predictor_order, self.lower_order_nums + 1 + ) # warmup for multistep + self.this_corrector_order = min( + this_corrector_order, self.lower_order_nums + 2 + ) # warmup for multistep assert self.this_predictor_order > 0 assert self.this_corrector_order > 0 @@ -809,7 +1045,9 @@ def step( tau=current_tau, ) - if self.lower_order_nums < max(self.config.predictor_order, self.config.corrector_order - 1): + if self.lower_order_nums < max( + self.config.predictor_order, self.config.corrector_order - 1 + ): self.lower_order_nums += 1 if not return_dict: @@ -817,7 +1055,9 @@ def step( return SchedulerOutput(prev_sample=prev_sample) - def scale_model_input(self, sample: torch.FloatTensor, *args, **kwargs) -> torch.FloatTensor: + def scale_model_input( + self, sample: torch.FloatTensor, *args, **kwargs + ) -> torch.FloatTensor: """ Ensures interchangeability with schedulers that need to scale the denoising model input depending on the current timestep. @@ -834,13 +1074,15 @@ def scale_model_input(self, sample: torch.FloatTensor, *args, **kwargs) -> torch # Copied from diffusers.schedulers.scheduling_ddpm.DDPMScheduler.add_noise def add_noise( - self, - original_samples: torch.FloatTensor, - noise: torch.FloatTensor, - timesteps: torch.IntTensor, + self, + original_samples: torch.FloatTensor, + noise: torch.FloatTensor, + timesteps: torch.IntTensor, ) -> torch.FloatTensor: # Make sure alphas_cumprod and timestep have same device and dtype as original_samples - alphas_cumprod = self.alphas_cumprod.to(device=original_samples.device, dtype=original_samples.dtype) + alphas_cumprod = self.alphas_cumprod.to( + device=original_samples.device, dtype=original_samples.dtype + ) timesteps = timesteps.to(original_samples.device) sqrt_alpha_prod = alphas_cumprod[timesteps] ** 0.5 @@ -853,8 +1095,10 @@ def add_noise( while len(sqrt_one_minus_alpha_prod.shape) < len(original_samples.shape): sqrt_one_minus_alpha_prod = sqrt_one_minus_alpha_prod.unsqueeze(-1) - noisy_samples = sqrt_alpha_prod * original_samples + sqrt_one_minus_alpha_prod * noise + noisy_samples = ( + sqrt_alpha_prod * original_samples + sqrt_one_minus_alpha_prod * noise + ) return noisy_samples def __len__(self): - return self.config.num_train_timesteps \ No newline at end of file + return self.config.num_train_timesteps From c3c62e1ac09537ed8c4feed87f824ecf55555f09 Mon Sep 17 00:00:00 2001 From: gabe56f Date: Sat, 9 Dec 2023 17:37:09 +0100 Subject: [PATCH 098/143] Forgot something --- frontend/dist/assets/TextToImageView.js | 94 ++++--------------- .../src/components/generate/Scalecrafter.vue | 58 +----------- 2 files changed, 21 insertions(+), 131 deletions(-) diff --git a/frontend/dist/assets/TextToImageView.js b/frontend/dist/assets/TextToImageView.js index 5ead51dc3..f1af61d48 100644 --- a/frontend/dist/assets/TextToImageView.js +++ b/frontend/dist/assets/TextToImageView.js @@ -22,11 +22,11 @@ const _hoisted_4$4 = /* @__PURE__ */ createBaseVNode("div", { class: "slider-lab const _hoisted_5$4 = { key: 0 }; const _hoisted_6$4 = { class: "flex-container" }; const _hoisted_7$4 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Upscaler", -1); -const _hoisted_8$3 = { key: 1 }; -const _hoisted_9$3 = { class: "flex-container" }; -const _hoisted_10$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Antialiased", -1); -const _hoisted_11$2 = { class: "flex-container" }; -const _hoisted_12$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Latent Mode", -1); +const _hoisted_8$2 = { key: 1 }; +const _hoisted_9$2 = { class: "flex-container" }; +const _hoisted_10$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Antialiased", -1); +const _hoisted_11$1 = { class: "flex-container" }; +const _hoisted_12$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Latent Mode", -1); const _hoisted_13$1 = { class: "flex-container" }; const _hoisted_14$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Steps", -1); const _hoisted_15$1 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "We recommend using 20-50 steps for most images.", -1); @@ -98,16 +98,16 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({ options: imageUpscalerOptions.value }, null, 8, ["value", "options"]) ]) - ])) : (openBlock(), createElementBlock("div", _hoisted_8$3, [ - createBaseVNode("div", _hoisted_9$3, [ - _hoisted_10$2, + ])) : (openBlock(), createElementBlock("div", _hoisted_8$2, [ + createBaseVNode("div", _hoisted_9$2, [ + _hoisted_10$1, createVNode(unref(NSwitch), { value: unref(settings).data.settings.flags.highres.antialiased, "onUpdate:value": _cache[3] || (_cache[3] = ($event) => unref(settings).data.settings.flags.highres.antialiased = $event) }, null, 8, ["value"]) ]), - createBaseVNode("div", _hoisted_11$2, [ - _hoisted_12$2, + createBaseVNode("div", _hoisted_11$1, [ + _hoisted_12$1, createVNode(unref(NSelect), { value: unref(settings).data.settings.flags.highres.latent_scale_mode, "onUpdate:value": _cache[4] || (_cache[4] = ($event) => unref(settings).data.settings.flags.highres.latent_scale_mode = $event), @@ -268,11 +268,11 @@ const _hoisted_4$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label const _hoisted_5$2 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, " Generally, the refiner that came with your model is bound to generate the best results. ", -1); const _hoisted_6$2 = { class: "flex-container" }; const _hoisted_7$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Steps", -1); -const _hoisted_8$2 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "We recommend using 20-50 steps for most images.", -1); -const _hoisted_9$2 = { class: "flex-container" }; -const _hoisted_10$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Aesthetic Score", -1); -const _hoisted_11$1 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "Generally best to keep it around 6.", -1); -const _hoisted_12$1 = { class: "flex-container" }; +const _hoisted_8$1 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "We recommend using 20-50 steps for most images.", -1); +const _hoisted_9$1 = { class: "flex-container" }; +const _hoisted_10 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Aesthetic Score", -1); +const _hoisted_11 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "Generally best to keep it around 6.", -1); +const _hoisted_12 = { class: "flex-container" }; const _hoisted_13 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Negative Aesthetic Score", -1); const _hoisted_14 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "Generally best to keep it around 3.", -1); const _hoisted_15 = { class: "flex-container" }; @@ -337,7 +337,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ ]), default: withCtx(() => [ createTextVNode(" Number of steps to take in the diffusion process. Higher values will result in more detailed images but will take longer to generate. There is also a point of diminishing returns around 100 steps. "), - _hoisted_8$2 + _hoisted_8$1 ]), _: 1 }), @@ -355,14 +355,14 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ style: { "min-width": "96px", "width": "96px" } }, null, 8, ["value"]) ]), - createBaseVNode("div", _hoisted_9$2, [ + createBaseVNode("div", _hoisted_9$1, [ createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { trigger: withCtx(() => [ - _hoisted_10$1 + _hoisted_10 ]), default: withCtx(() => [ createTextVNode(' Generally higher numbers will produce "more professional" images. '), - _hoisted_11$1 + _hoisted_11 ]), _: 1 }), @@ -384,7 +384,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ style: { "min-width": "96px", "width": "96px" } }, null, 8, ["value"]) ]), - createBaseVNode("div", _hoisted_12$1, [ + createBaseVNode("div", _hoisted_12, [ createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { trigger: withCtx(() => [ _hoisted_13 @@ -451,11 +451,6 @@ const _hoisted_4$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label const _hoisted_5$1 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, " However, this comes at the cost of increased vram usage, generally in the range of 3-4x. ", -1); const _hoisted_6$1 = { class: "flex-container" }; const _hoisted_7$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Unsafe resolutions", -1); -const _hoisted_8$1 = { class: "flex-container" }; -const _hoisted_9$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Negative Aesthetic Score", -1); -const _hoisted_10 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "Generally best to keep it around 3.", -1); -const _hoisted_11 = { class: "flex-container" }; -const _hoisted_12 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Strength", -1); const _sfc_main$2 = /* @__PURE__ */ defineComponent({ __name: "Scalecrafter", setup(__props) { @@ -509,55 +504,6 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ value: unref(settings).defaultSettings.flags.scalecrafter.unsafe_resolutions, "onUpdate:value": _cache[2] || (_cache[2] = ($event) => unref(settings).defaultSettings.flags.scalecrafter.unsafe_resolutions = $event) }, null, 8, ["value"]) - ]), - createBaseVNode("div", _hoisted_8$1, [ - createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { - trigger: withCtx(() => [ - _hoisted_9$1 - ]), - default: withCtx(() => [ - createTextVNode(" Makes sense to keep this lower than aesthetic score. "), - _hoisted_10 - ]), - _: 1 - }), - createVNode(unref(NSlider), { - value: unref(settings).data.settings.flags.refiner.negative_aesthetic_score, - "onUpdate:value": _cache[3] || (_cache[3] = ($event) => unref(settings).data.settings.flags.refiner.negative_aesthetic_score = $event), - min: 0, - max: 10, - step: 0.5, - style: { "margin-right": "12px" } - }, null, 8, ["value"]), - createVNode(unref(NInputNumber), { - value: unref(settings).data.settings.flags.refiner.negative_aesthetic_score, - "onUpdate:value": _cache[4] || (_cache[4] = ($event) => unref(settings).data.settings.flags.refiner.negative_aesthetic_score = $event), - min: 0, - max: 10, - step: 0.25, - size: "small", - style: { "min-width": "96px", "width": "96px" } - }, null, 8, ["value"]) - ]), - createBaseVNode("div", _hoisted_11, [ - _hoisted_12, - createVNode(unref(NSlider), { - value: unref(settings).data.settings.flags.refiner.strength, - "onUpdate:value": _cache[5] || (_cache[5] = ($event) => unref(settings).data.settings.flags.refiner.strength = $event), - min: 0.1, - max: 0.9, - step: 0.05, - style: { "margin-right": "12px" } - }, null, 8, ["value"]), - createVNode(unref(NInputNumber), { - value: unref(settings).data.settings.flags.refiner.strength, - "onUpdate:value": _cache[6] || (_cache[6] = ($event) => unref(settings).data.settings.flags.refiner.strength = $event), - size: "small", - style: { "min-width": "96px", "width": "96px" }, - min: 0.1, - max: 0.9, - step: 0.05 - }, null, 8, ["value"]) ]) ]), _: 1 diff --git a/frontend/src/components/generate/Scalecrafter.vue b/frontend/src/components/generate/Scalecrafter.vue index affd84a63..f607349a6 100644 --- a/frontend/src/components/generate/Scalecrafter.vue +++ b/frontend/src/components/generate/Scalecrafter.vue @@ -45,69 +45,13 @@ " />
- - -
- - - Makes sense to keep this lower than aesthetic score. - Generally best to keep it around 3. - - - -
- -
-

Strength

- - -
From e0b1f1dcf43f7f96750e13e42dbc030903b5a276 Mon Sep 17 00:00:00 2001 From: Stax124 Date: Sat, 9 Dec 2023 19:08:58 +0100 Subject: [PATCH 099/143] Global postprocessing (Hires, Upscale, more to come) --- core/gpu.py | 256 +++++++++----- core/inference/ait/aitemplate.py | 197 +++++------ core/inference/functions.py | 13 + core/inference/pytorch/pytorch.py | 312 +++++++----------- core/inference/sdxl/pipeline.py | 8 + core/inference/sdxl/sdxl.py | 234 +++++++------ core/types.py | 1 + frontend/dist/assets/TextToImageView.js | 5 +- frontend/src/components/inference/Txt2Img.vue | 2 +- 9 files changed, 538 insertions(+), 490 deletions(-) diff --git a/core/gpu.py b/core/gpu.py index 2a6a52fac..00d180266 100644 --- a/core/gpu.py +++ b/core/gpu.py @@ -16,12 +16,13 @@ from core import shared from core.config import config from core.errors import InferenceInterruptedError, ModelNotLoadedError -from core.flags import UpscaleFlag +from core.flags import HighResFixFlag, UpscaleFlag from core.inference.ait import AITemplateStableDiffusion from core.inference.esrgan import RealESRGAN, Upscaler from core.inference.functions import is_ipex_available from core.inference.pytorch import PyTorchStableDiffusion from core.inference.sdxl import SDXLStableDiffusion +from core.inference.utilities.latents import scale_latents from core.interrogation.base_interrogator import InterrogationResult from core.optimizations import is_hypertile_available from core.png_metadata import save_images @@ -31,13 +32,17 @@ AITemplateDynamicBuildRequest, Capabilities, ControlNetQueueEntry, + Img2imgData, + Img2ImgQueueEntry, InferenceBackend, InferenceJob, + InpaintQueueEntry, InterrogatorQueueEntry, Job, ONNXBuildRequest, PyTorchModelBase, TextualInversionLoadRequest, + Txt2ImgQueueEntry, UpscaleData, UpscaleQueueEntry, VaeLoadRequest, @@ -182,109 +187,205 @@ def vram_used(self) -> float: index = torch.device(config.api.device).index return torch.cuda.memory_allocated(index) / 1024**2 - def postprocess(self, job: Job, images: List[Image.Image]) -> List[Image.Image]: - "Postprocess images" + def highres_flag( + self, job: Job, images: Union[List[Image.Image], torch.Tensor] + ) -> List[Image.Image]: + flag = job.flags["highres_fix"] + flag = HighResFixFlag.from_dict(flag) - logger.debug(f"Postprocessing flags: {job.flags}") + if flag.mode == "latent": + assert isinstance(images, (torch.Tensor, torch.FloatTensor)) + latents = images - # TODO: Move highres fix here instead of relying on the individual generate function + latents = scale_latents( + latents=latents, + scale=flag.scale, + latent_scale_mode=flag.latent_scale_mode, + ) - if "upscale" in job.flags: - logger.debug("Upscaling image") + height = latents.shape[2] * 8 + width = latents.shape[3] * 8 + output_images = latents + else: + from core.shared_dependent import gpu - flag = UpscaleFlag(**job.flags["upscale"]) + assert isinstance(images, List) + output_images = [] - final_images = [] for image in images: - upscale_job = UpscaleQueueEntry( - data=UpscaleData( - image=image, # type: ignore # Pydantic would cry if we extend the union - upscale_factor=flag.upscale_factor, - tile_padding=flag.tile_padding, - tile_size=flag.tile_size, - ), - model=flag.model, + output: tuple[Image.Image, float] = gpu.upscale( + UpscaleQueueEntry( + data=UpscaleData( + id=job.data.id, + # FastAPI validation error, we need to do this so that we can pass in a PIL image + image=image, # type: ignore + upscale_factor=flag.scale, + ), + model=flag.image_upscaler, + save_image=False, + ) ) + output_images.append(output[0]) + + output_images = output_images[0] # type: ignore + height = int(flag.scale * job.data.height) + width = int(flag.scale * job.data.width) + + data = Img2imgData( + prompt=job.data.prompt, + negative_prompt=job.data.negative_prompt, + image=output_images, # type: ignore + scheduler=job.data.scheduler, + batch_count=job.data.batch_count, + batch_size=job.data.batch_size, + strength=flag.strength, + steps=flag.steps, + guidance_scale=job.data.guidance_scale, + prompt_to_prompt_settings=job.data.prompt_to_prompt_settings, + seed=job.data.seed, + self_attention_scale=job.data.self_attention_scale, + sigmas=job.data.sigmas, + sampler_settings=job.data.sampler_settings, + height=height, + width=width, + ) + + img2img_job = Img2ImgQueueEntry( + data=data, + model=job.model, + ) + + result: List[Image.Image] = self.run_inference(img2img_job) + return result + + def upscale_flag(self, job: Job, images: List[Image.Image]) -> List[Image.Image]: + logger.debug("Upscaling image") + + flag = UpscaleFlag(**job.flags["upscale"]) + + final_images = [] + for image in images: + upscale_job = UpscaleQueueEntry( + data=UpscaleData( + image=image, # type: ignore # Pydantic would cry if we extend the union + upscale_factor=flag.upscale_factor, + tile_padding=flag.tile_padding, + tile_size=flag.tile_size, + ), + model=flag.model, + ) + + final_images.append(self.upscale(upscale_job)[0]) + + return final_images + + def postprocess( + self, job: Job, images: Union[List[Image.Image], torch.Tensor] + ) -> List[Image.Image]: + "Postprocess images" + + logger.debug(f"Postprocessing flags: {job.flags}") - final_images.append(self.upscale(upscale_job)[0]) + if "highres_fix" in job.flags: + images = self.highres_flag(job, images) - images = final_images + if "upscale" in job.flags: + assert isinstance(images, list) + images = self.upscale_flag(job, images) + assert isinstance(images, list) return images - def generate( - self, - job: InferenceJob, - ): - "Generate images from the queue" + def set_callback_target(self, job: Job): + "Set the callback target for the job, updates the shared object and also returns the target" + + if isinstance(job, Txt2ImgQueueEntry): + target = "txt2img" + elif isinstance(job, Img2ImgQueueEntry): + target = "img2img" + elif isinstance(job, ControlNetQueueEntry): + target = "controlnet" + elif isinstance(job, InpaintQueueEntry): + target = "inpaint" + else: + raise ValueError("Unknown job type") - job = preprocess_job(job) + shared.current_method = target + return target - def generate_thread_call(job: Job) -> List[Image.Image]: - try: - model: Union[ - PyTorchStableDiffusion, - AITemplateStableDiffusion, - SDXLStableDiffusion, - "OnnxStableDiffusion", - ] = self.loaded_models[job.model] - except KeyError as err: - websocket_manager.broadcast_sync( - Notification( - "error", - "Model not loaded", - f"Model {job.model} is not loaded, please load it first", - ) + def run_inference(self, job: Job) -> List[Image.Image]: + try: + model: Union[ + PyTorchStableDiffusion, + AITemplateStableDiffusion, + SDXLStableDiffusion, + "OnnxStableDiffusion", + ] = self.loaded_models[job.model] + except KeyError as err: + websocket_manager.broadcast_sync( + Notification( + "error", + "Model not loaded", + f"Model {job.model} is not loaded, please load it first", ) + ) - logger.debug("Model not loaded on any GPU. Raising error") - raise ModelNotLoadedError(f"Model {job.model} is not loaded") from err + logger.debug("Model not loaded on any GPU. Raising error") + raise ModelNotLoadedError(f"Model {job.model} is not loaded") from err - shared.interrupt = False + shared.interrupt = False - if job.flags: - logger.debug(f"Job flags: {job.flags}") + if job.flags: + logger.debug(f"Job flags: {job.flags}") - steps = job.data.steps + steps = job.data.steps - strength: float = getattr(job.data, "strength", 1.0) - steps = math.floor(steps * strength) + strength: float = getattr(job.data, "strength", 1.0) + steps = math.floor(steps * strength) - shared.current_done_steps = 0 + shared.current_done_steps = 0 - if not isinstance(job, ControlNetQueueEntry): - from core import shared_dependent + if not isinstance(job, ControlNetQueueEntry): + from core import shared_dependent - if shared_dependent.cached_controlnet_preprocessor is not None: - # Wipe cached controlnet preprocessor - shared_dependent.cached_controlnet_preprocessor = None - self.memory_cleanup() + if shared_dependent.cached_controlnet_preprocessor is not None: + # Wipe cached controlnet preprocessor + shared_dependent.cached_controlnet_preprocessor = None + self.memory_cleanup() + + if isinstance(model, PyTorchStableDiffusion): + logger.debug("Generating with SD PyTorch") + shared.current_model = "SD1.x" + images: Union[List[Image.Image], torch.Tensor] = model.generate(job) + elif isinstance(model, SDXLStableDiffusion): + logger.debug("Generating with SDXL (PyTorch)") + shared.current_model = "SDXL" + images: Union[List[Image.Image], torch.Tensor] = model.generate(job) + elif isinstance(model, AITemplateStableDiffusion): + logger.debug("Generating with SD AITemplate") + images: Union[List[Image.Image], torch.Tensor] = model.generate(job) + else: + from core.inference.onnx import OnnxStableDiffusion - if isinstance(model, PyTorchStableDiffusion): - logger.debug("Generating with PyTorch") - shared.current_model = "SD1.x" - images: List[Image.Image] = model.generate(job) - elif isinstance(model, SDXLStableDiffusion): - logger.debug("Generating with SDXL (PyTorch)") - shared.current_model = "SDXL" - images: List[Image.Image] = model.generate(job) - elif isinstance(model, AITemplateStableDiffusion): - logger.debug("Generating with AITemplate") - images: List[Image.Image] = model.generate(job) + if isinstance(model, OnnxStableDiffusion): + logger.debug("Generating with SD ONNX") + images: Union[List[Image.Image], torch.Tensor] = model.generate(job) else: - from core.inference.onnx import OnnxStableDiffusion + raise NotImplementedError("Unknown model type") - if isinstance(model, OnnxStableDiffusion): - logger.debug("Generating with ONNX") - images: List[Image.Image] = model.generate(job) - else: - raise NotImplementedError("Unknown model type") + self.memory_cleanup() - self.memory_cleanup() + # Run postprocessing + images = self.postprocess(job, images) + return images + + def generate( + self, + job: InferenceJob, + ): + "Generate images from the queue" - # Run postprocessing - images = self.postprocess(job, images) - return images + job = preprocess_job(job) try: # Wait for turn in the queue @@ -294,7 +395,8 @@ def generate_thread_call(job: Job) -> List[Image.Image]: # Generate images try: - generated_images = generate_thread_call(job) + self.set_callback_target(job) + generated_images = self.run_inference(job) assert generated_images is not None diff --git a/core/inference/ait/aitemplate.py b/core/inference/ait/aitemplate.py index e95de38fd..8546ecda7 100644 --- a/core/inference/ait/aitemplate.py +++ b/core/inference/ait/aitemplate.py @@ -14,13 +14,10 @@ from api import websocket_manager from api.websockets.data import Data -from core import shared from core.config import config -from core.flags import HighResFixFlag from core.inference.ait.pipeline import StableDiffusionAITPipeline from core.inference.base_model import InferenceModel -from core.inference.functions import load_pytorch_pipeline -from core.inference.utilities.latents import scale_latents +from core.inference.functions import get_output_type, load_pytorch_pipeline from core.inference_callbacks import callback from core.types import ( Backend, @@ -267,7 +264,7 @@ def create_pipe( ) return pipe - def generate(self, job: Job) -> List[Image.Image]: + def generate(self, job: Job) -> Union[List[Image.Image], torch.Tensor]: logging.info(f"Adding job {job.data.id} to queue") if isinstance(job, Txt2ImgQueueEntry): @@ -286,7 +283,7 @@ def generate(self, job: Job) -> List[Image.Image]: def txt2img( self, job: Txt2ImgQueueEntry, - ) -> List[Image.Image]: + ) -> Union[List[Image.Image], torch.Tensor]: "Generates images from text" pipe = self.create_pipe( scheduler=(job.data.scheduler, job.data.sigmas), @@ -295,15 +292,10 @@ def txt2img( generator = create_generator(seed=job.data.seed) - total_images: List[Image.Image] = [] - shared.current_method = "txt2img" + total_images: Union[List[Image.Image], torch.Tensor] = [] + output_type = get_output_type(job) for _ in tqdm(range(job.data.batch_count), desc="Queue", position=1): - output_type = "pil" - - if "highres_fix" in job.flags: - output_type = "latent" - data = pipe( generator=generator, prompt=job.data.prompt, @@ -317,62 +309,37 @@ def txt2img( num_images_per_prompt=job.data.batch_size, ) - if output_type == "latent": - latents = data[0] # type: ignore - assert isinstance(latents, (torch.Tensor, torch.FloatTensor)) - - flag = job.flags["highres_fix"] - flag = HighResFixFlag.from_dict(flag) + images: Union[List[Image.Image], torch.Tensor] = data[0] # type: ignore - latents = scale_latents( - latents=latents, - scale=flag.scale, - latent_scale_mode=flag.latent_scale_mode, - ) - - data = pipe( - generator=generator, - prompt=job.data.prompt, - image=latents, - height=latents.shape[2] * 8, - width=latents.shape[3] * 8, - num_inference_steps=flag.steps, - guidance_scale=job.data.guidance_scale, - self_attention_scale=job.data.self_attention_scale, - negative_prompt=job.data.negative_prompt, - output_type="pil", - callback=callback, - strength=flag.strength, - return_dict=False, - num_images_per_prompt=job.data.batch_size, + if not isinstance(images, List): + total_images = images + else: + assert isinstance(total_images, List) + total_images.extend(images) + + if isinstance(total_images, List): + websocket_manager.broadcast_sync( + data=Data( + data_type="txt2img", + data={ + "progress": 0, + "current_step": 0, + "total_steps": 0, + "image": convert_images_to_base64_grid( + total_images, + quality=config.api.image_quality, + image_format=config.api.image_extension, + ), + }, ) - - images: list[Image.Image] = data[0] # type: ignore - - total_images.extend(images) - - websocket_manager.broadcast_sync( - data=Data( - data_type="txt2img", - data={ - "progress": 0, - "current_step": 0, - "total_steps": 0, - "image": convert_images_to_base64_grid( - total_images, - quality=config.api.image_quality, - image_format=config.api.image_extension, - ), - }, ) - ) return total_images def img2img( self, job: Img2ImgQueueEntry, - ) -> List[Image.Image]: + ) -> Union[List[Image.Image], torch.Tensor]: "Generates images from images" pipe = self.create_pipe( scheduler=(job.data.scheduler, job.data.sigmas), @@ -381,11 +348,15 @@ def img2img( generator = create_generator(seed=job.data.seed) - input_image = convert_to_image(job.data.image) - input_image = resize(input_image, job.data.width, job.data.height) + # Preprocess the image + if isinstance(job.data.image, (str, bytes, Image.Image)): + input_image = convert_to_image(job.data.image) + input_image = resize(input_image, job.data.width, job.data.height) + else: + input_image = job.data.image - total_images: List[Image.Image] = [] - shared.current_method = "img2img" + total_images: Union[List[Image.Image], torch.Tensor] = [] + output_type = get_output_type(job) for _ in tqdm(range(job.data.batch_count), desc="Queue", position=1): data = pipe( @@ -395,40 +366,44 @@ def img2img( image=input_image, # type: ignore num_inference_steps=job.data.steps, guidance_scale=job.data.guidance_scale, - output_type="pil", + output_type=output_type, callback=callback, strength=job.data.strength, # type: ignore return_dict=False, num_images_per_prompt=job.data.batch_size, ) - images = data[0] - assert isinstance(images, List) - - total_images.extend(images) - - websocket_manager.broadcast_sync( - data=Data( - data_type="img2img", - data={ - "progress": 0, - "current_step": 0, - "total_steps": 0, - "image": convert_images_to_base64_grid( - total_images, - quality=config.api.image_quality, - image_format=config.api.image_extension, - ), - }, + images: Union[List[Image.Image], torch.Tensor] = data[0] # type: ignore + + if not isinstance(images, List): + total_images = images + else: + assert isinstance(total_images, List) + total_images.extend(images) + + if isinstance(total_images, List): + websocket_manager.broadcast_sync( + data=Data( + data_type="img2img", + data={ + "progress": 0, + "current_step": 0, + "total_steps": 0, + "image": convert_images_to_base64_grid( + total_images, + quality=config.api.image_quality, + image_format=config.api.image_extension, + ), + }, + ) ) - ) return total_images def controlnet2img( self, job: ControlNetQueueEntry, - ) -> List[Image.Image]: + ) -> Union[List[Image.Image], torch.Tensor]: "Generates images from images" pipe = self.create_pipe( controlnet=job.data.controlnet, @@ -445,8 +420,8 @@ def controlnet2img( if not job.data.is_preprocessed: input_image = image_to_controlnet_input(input_image, job.data) - total_images: List[Image.Image] = [input_image] - shared.current_method = "controlnet" + total_images: Union[List[Image.Image], torch.Tensor] = [] + output_type = get_output_type(job) for _ in tqdm(range(job.data.batch_count), desc="Queue", position=1): data = pipe( @@ -456,7 +431,7 @@ def controlnet2img( image=input_image, # type: ignore num_inference_steps=job.data.steps, guidance_scale=job.data.guidance_scale, - output_type="pil", + output_type=output_type, callback=callback, return_dict=False, num_images_per_prompt=job.data.batch_size, @@ -465,27 +440,31 @@ def controlnet2img( width=job.data.width, ) - images = data[0] - assert isinstance(images, List) - - total_images.extend(images) - - websocket_manager.broadcast_sync( - data=Data( - data_type="controlnet", - data={ - "progress": 0, - "current_step": 0, - "total_steps": 0, - "image": convert_images_to_base64_grid( - total_images - if job.data.return_preprocessed - else total_images[1:], - quality=config.api.image_quality, - image_format=config.api.image_extension, - ), - }, + images: Union[List[Image.Image], torch.Tensor] = data[0] # type: ignore + + if not isinstance(images, List): + total_images = images + else: + assert isinstance(total_images, List) + total_images.extend(images) + + if isinstance(total_images, List): + websocket_manager.broadcast_sync( + data=Data( + data_type="controlnet", + data={ + "progress": 0, + "current_step": 0, + "total_steps": 0, + "image": convert_images_to_base64_grid( + total_images + if job.data.return_preprocessed + else total_images[1:], + quality=config.api.image_quality, + image_format=config.api.image_extension, + ), + }, + ) ) - ) return total_images diff --git a/core/inference/functions.py b/core/inference/functions.py index 50779e646..737b19c53 100644 --- a/core/inference/functions.py +++ b/core/inference/functions.py @@ -49,7 +49,9 @@ from core.config import config from core.files import get_full_model_path +from core.flags import HighResFixFlag from core.optimizations import compile_sfast +from core.types import Job from core.utils import determine_model_type logger = logging.getLogger(__name__) @@ -678,3 +680,14 @@ def convert_vaept_to_diffusers(path: str) -> AutoencoderKL: vae = AutoencoderKL(**vae_config) vae.load_state_dict(converted_vae_checkpoint) return vae + + +def get_output_type(job: Job): + return ( + "latent" + if ( + "highres_fix" in job.flags + and HighResFixFlag(**job.flags["highres_fix"]).mode == "latent" + ) + else "pil" + ) diff --git a/core/inference/pytorch/pytorch.py b/core/inference/pytorch/pytorch.py index 2bef67990..54c31fc55 100755 --- a/core/inference/pytorch/pytorch.py +++ b/core/inference/pytorch/pytorch.py @@ -20,19 +20,21 @@ from api import websocket_manager from api.websockets import Data from api.websockets.notification import Notification -from core import shared from core.config import config -from core.flags import HighResFixFlag from core.inference.base_model import InferenceModel -from core.inference.functions import convert_vaept_to_diffusers, load_pytorch_pipeline +from core.inference.functions import ( + convert_vaept_to_diffusers, + get_output_type, + load_pytorch_pipeline, +) from core.inference.pytorch.pipeline import StableDiffusionLongPromptWeightingPipeline from core.inference.utilities import ( change_scheduler, create_generator, image_to_controlnet_input, - scale_latents, ) from core.inference_callbacks import callback +from core.optimizations import optimize_vae from core.types import ( Backend, ControlNetQueueEntry, @@ -41,10 +43,7 @@ Job, SigmaScheduler, Txt2ImgQueueEntry, - UpscaleData, - UpscaleQueueEntry, ) -from core.optimizations import optimize_vae from core.utils import convert_images_to_base64_grid, convert_to_image, resize logger = logging.getLogger(__name__) @@ -294,7 +293,7 @@ def create_pipe( return pipe - def txt2img(self, job: Txt2ImgQueueEntry) -> List[Image.Image]: + def txt2img(self, job: Txt2ImgQueueEntry) -> Union[List[Image.Image], torch.Tensor]: "Generate an image from a prompt" pipe = self.create_pipe( @@ -304,19 +303,10 @@ def txt2img(self, job: Txt2ImgQueueEntry) -> List[Image.Image]: generator = create_generator(job.data.seed) - total_images: List[Image.Image] = [] - shared.current_method = "txt2img" + total_images: Union[List[Image.Image], torch.Tensor] = [] + output_type = get_output_type(job) for _ in tqdm(range(job.data.batch_count), desc="Queue", position=1): - output_type = ( - "latent" - if ( - "highres_fix" in job.flags - and HighResFixFlag(**job.flags["highres_fix"]).mode == "latent" - ) - else "pil" - ) - data = pipe.text2img( generator=generator, prompt=job.data.prompt, @@ -333,103 +323,34 @@ def txt2img(self, job: Txt2ImgQueueEntry) -> List[Image.Image]: prompt_expansion_settings=job.data.prompt_to_prompt_settings, ) - if "highres_fix" in job.flags: - flag = job.flags["highres_fix"] - flag = HighResFixFlag.from_dict(flag) - - if flag.mode == "latent": - latents = data[0] # type: ignore - assert isinstance(latents, (torch.Tensor, torch.FloatTensor)) - - latents = scale_latents( - latents=latents, - scale=flag.scale, - latent_scale_mode=flag.latent_scale_mode, - ) - - data = pipe.img2img( - generator=generator, - prompt=job.data.prompt, - image=latents, - height=latents.shape[2] * 8, - width=latents.shape[3] * 8, - num_inference_steps=flag.steps, - guidance_scale=job.data.guidance_scale, - self_attention_scale=job.data.self_attention_scale, - negative_prompt=job.data.negative_prompt, - output_type="pil", - callback=callback, - strength=flag.strength, - return_dict=False, - num_images_per_prompt=job.data.batch_size, - seed=job.data.seed, - prompt_expansion_settings=job.data.prompt_to_prompt_settings, - ) - - else: - from core.shared_dependent import gpu - - images = data[0] # type: ignore - assert isinstance(images, List) - - upscaled_images = [] - for image in images: - output: tuple[Image.Image, float] = gpu.upscale( - UpscaleQueueEntry( - data=UpscaleData( - id=job.data.id, - # FastAPI validation error, we need to do this so that we can pass in a PIL image - image=image, # type: ignore - upscale_factor=flag.scale, - ), - model=flag.image_upscaler, - save_image=False, - ) - ) - upscaled_images.append(output[0]) - - data = pipe.img2img( - generator=generator, - prompt=job.data.prompt, - image=upscaled_images[0], - height=int(flag.scale * job.data.height), - width=int(flag.scale * job.data.width), - num_inference_steps=flag.steps, - guidance_scale=job.data.guidance_scale, - self_attention_scale=job.data.self_attention_scale, - negative_prompt=job.data.negative_prompt, - output_type="pil", - callback=callback, - strength=flag.strength, - return_dict=False, - num_images_per_prompt=job.data.batch_size, - seed=job.data.seed, - prompt_expansion_settings=job.data.prompt_to_prompt_settings, - ) + images: Union[List[Image.Image], torch.Tensor] = data[0] # type: ignore - images: list[Image.Image] = data[0] # type: ignore - - total_images.extend(images) - - websocket_manager.broadcast_sync( - data=Data( - data_type="txt2img", - data={ - "progress": 0, - "current_step": 0, - "total_steps": 0, - "image": convert_images_to_base64_grid( - total_images, - quality=config.api.image_quality, - image_format=config.api.image_extension, - ), - }, + if not isinstance(images, List): + total_images = images + else: + assert isinstance(total_images, List) + total_images.extend(images) + + if isinstance(total_images, List): + websocket_manager.broadcast_sync( + data=Data( + data_type="txt2img", + data={ + "progress": 0, + "current_step": 0, + "total_steps": 0, + "image": convert_images_to_base64_grid( + total_images, + quality=config.api.image_quality, + image_format=config.api.image_extension, + ), + }, + ) ) - ) return total_images - def img2img(self, job: Img2ImgQueueEntry) -> List[Image.Image]: + def img2img(self, job: Img2ImgQueueEntry) -> Union[List[Image.Image], torch.Tensor]: "Generate an image from an image" pipe = self.create_pipe( @@ -440,11 +361,14 @@ def img2img(self, job: Img2ImgQueueEntry) -> List[Image.Image]: generator = create_generator(job.data.seed) # Preprocess the image - input_image = convert_to_image(job.data.image) - input_image = resize(input_image, job.data.width, job.data.height) + if isinstance(job.data.image, (str, bytes, Image.Image)): + input_image = convert_to_image(job.data.image) + input_image = resize(input_image, job.data.width, job.data.height) + else: + input_image = job.data.image - total_images: List[Image.Image] = [] - shared.current_method = "img2img" + total_images: Union[List[Image.Image], torch.Tensor] = [] + output_type = get_output_type(job) for _ in tqdm(range(job.data.batch_count), desc="Queue", position=1): data = pipe.img2img( @@ -457,7 +381,7 @@ def img2img(self, job: Img2ImgQueueEntry) -> List[Image.Image]: guidance_scale=job.data.guidance_scale, self_attention_scale=job.data.self_attention_scale, negative_prompt=job.data.negative_prompt, - output_type="pil", + output_type=output_type, callback=callback, strength=job.data.strength, return_dict=False, @@ -466,33 +390,34 @@ def img2img(self, job: Img2ImgQueueEntry) -> List[Image.Image]: prompt_expansion_settings=job.data.prompt_to_prompt_settings, ) - if not data: - raise ValueError("No data returned from pipeline") - - images = data[0] - assert isinstance(images, List) - - total_images.extend(images) - - websocket_manager.broadcast_sync( - data=Data( - data_type="img2img", - data={ - "progress": 0, - "current_step": 0, - "total_steps": 0, - "image": convert_images_to_base64_grid( - total_images, - quality=config.api.image_quality, - image_format=config.api.image_extension, - ), - }, + images: Union[List[Image.Image], torch.Tensor] = data[0] # type: ignore + + if not isinstance(images, List): + total_images = images + else: + assert isinstance(total_images, List) + total_images.extend(images) + + if isinstance(total_images, List): + websocket_manager.broadcast_sync( + data=Data( + data_type="img2img", + data={ + "progress": 0, + "current_step": 0, + "total_steps": 0, + "image": convert_images_to_base64_grid( + total_images, + quality=config.api.image_quality, + image_format=config.api.image_extension, + ), + }, + ) ) - ) return total_images - def inpaint(self, job: InpaintQueueEntry) -> List[Image.Image]: + def inpaint(self, job: InpaintQueueEntry) -> Union[List[Image.Image], torch.Tensor]: "Generate an image from an image" pipe = self.create_pipe( @@ -510,8 +435,8 @@ def inpaint(self, job: InpaintQueueEntry) -> List[Image.Image]: input_mask_image = ImageOps.invert(input_mask_image) input_mask_image = resize(input_mask_image, job.data.width, job.data.height) - total_images: List[Image.Image] = [] - shared.current_method = "inpainting" + total_images: Union[List[Image.Image], torch.Tensor] = [] + output_type = get_output_type(job) for _ in tqdm(range(job.data.batch_count), desc="Queue", position=1): data = pipe.inpaint( @@ -523,7 +448,7 @@ def inpaint(self, job: InpaintQueueEntry) -> List[Image.Image]: guidance_scale=job.data.guidance_scale, self_attention_scale=job.data.self_attention_scale, negative_prompt=job.data.negative_prompt, - output_type="pil", + output_type=output_type, callback=callback, return_dict=False, num_images_per_prompt=job.data.batch_size, @@ -533,33 +458,36 @@ def inpaint(self, job: InpaintQueueEntry) -> List[Image.Image]: prompt_expansion_settings=job.data.prompt_to_prompt_settings, ) - if not data: - raise ValueError("No data returned from pipeline") - - images = data[0] - assert isinstance(images, List) - - total_images.extend(images) - - websocket_manager.broadcast_sync( - data=Data( - data_type="inpainting", - data={ - "progress": 0, - "current_step": 0, - "total_steps": 0, - "image": convert_images_to_base64_grid( - total_images, - quality=config.api.image_quality, - image_format=config.api.image_extension, - ), - }, + images: Union[List[Image.Image], torch.Tensor] = data[0] # type: ignore + + if not isinstance(images, List): + total_images = images + else: + assert isinstance(total_images, List) + total_images.extend(images) + + if isinstance(total_images, List): + websocket_manager.broadcast_sync( + data=Data( + data_type="inpainting", + data={ + "progress": 0, + "current_step": 0, + "total_steps": 0, + "image": convert_images_to_base64_grid( + total_images, + quality=config.api.image_quality, + image_format=config.api.image_extension, + ), + }, + ) ) - ) return total_images - def controlnet2img(self, job: ControlNetQueueEntry) -> List[Image.Image]: + def controlnet2img( + self, job: ControlNetQueueEntry + ) -> Union[List[Image.Image], torch.Tensor]: "Generate an image from an image and controlnet conditioning" if config.api.trace_model is True: @@ -585,8 +513,8 @@ def controlnet2img(self, job: ControlNetQueueEntry) -> List[Image.Image]: input_image = image_to_controlnet_input(input_image, job.data) logger.debug(f"Preprocessed image size: {input_image.size}") - total_images: List[Image.Image] = [input_image] - shared.current_method = "controlnet" + total_images: Union[List[Image.Image], torch.Tensor] = [] + output_type = get_output_type(job) for _ in tqdm(range(job.data.batch_count), desc="Queue", position=1): data = pipe( @@ -596,7 +524,7 @@ def controlnet2img(self, job: ControlNetQueueEntry) -> List[Image.Image]: image=input_image, num_inference_steps=job.data.steps, guidance_scale=job.data.guidance_scale, - output_type="pil", + output_type=output_type, callback=callback, return_dict=False, num_images_per_prompt=job.data.batch_size, @@ -607,32 +535,36 @@ def controlnet2img(self, job: ControlNetQueueEntry) -> List[Image.Image]: prompt_expansion_settings=job.data.prompt_to_prompt_settings, ) - images = data[0] # type: ignore - assert isinstance(images, List) - - total_images.extend(images) # type: ignore - - websocket_manager.broadcast_sync( - data=Data( - data_type="controlnet", - data={ - "progress": 0, - "current_step": 0, - "total_steps": 0, - "image": convert_images_to_base64_grid( - total_images - if job.data.return_preprocessed - else total_images[1:], - quality=config.api.image_quality, - image_format=config.api.image_extension, - ), - }, + images: Union[List[Image.Image], torch.Tensor] = data[0] # type: ignore + + if not isinstance(images, List): + total_images = images + else: + assert isinstance(total_images, List) + total_images.extend(images) + + if isinstance(total_images, List): + websocket_manager.broadcast_sync( + data=Data( + data_type="controlnet", + data={ + "progress": 0, + "current_step": 0, + "total_steps": 0, + "image": convert_images_to_base64_grid( + total_images + if job.data.return_preprocessed + else total_images[1:], + quality=config.api.image_quality, + image_format=config.api.image_extension, + ), + }, + ) ) - ) return total_images - def generate(self, job: Job): + def generate(self, job: Job) -> Union[List[Image.Image], torch.Tensor]: "Generate images from the queue" logging.info(f"Adding job {job.data.id} to queue") diff --git a/core/inference/sdxl/pipeline.py b/core/inference/sdxl/pipeline.py index 3aa033bde..a8ec6cc07 100644 --- a/core/inference/sdxl/pipeline.py +++ b/core/inference/sdxl/pipeline.py @@ -680,6 +680,10 @@ def _call(*args, **kwargs): return None # 9. Post-processing + if output_type == "latent": + unload_all() + return latents, False + converted_image = full_vae(latents, self.vae, height=height, width=width) # type: ignore # 11. Convert to PIL @@ -759,6 +763,8 @@ def img2img( negative_aesthetic_score: float = 2.5, original_size: Optional[List[int]] = None, negative_prompt: Optional[str] = None, + height: int = 512, + width: int = 512, strength: float = 0.8, num_inference_steps: int = 50, guidance_scale: Optional[float] = 7.5, @@ -781,6 +787,8 @@ def img2img( prompt=prompt, seed=seed, negative_prompt=negative_prompt, + width=width, + height=height, image=image, num_inference_steps=num_inference_steps, # type: ignore guidance_scale=guidance_scale, # type: ignore diff --git a/core/inference/sdxl/sdxl.py b/core/inference/sdxl/sdxl.py index ad4261e88..c50d5f980 100644 --- a/core/inference/sdxl/sdxl.py +++ b/core/inference/sdxl/sdxl.py @@ -1,6 +1,6 @@ import logging from pathlib import Path -from typing import Any, List, Optional, Tuple +from typing import Any, List, Optional, Tuple, Union import torch from diffusers.models.autoencoder_kl import AutoencoderKL @@ -20,12 +20,15 @@ from api import websocket_manager from api.websockets import Data from api.websockets.notification import Notification -from core import shared from core.config import config from core.files import get_full_model_path from core.flags import SDXLFlag, SDXLRefinerFlag from core.inference.base_model import InferenceModel -from core.inference.functions import convert_vaept_to_diffusers, load_pytorch_pipeline +from core.inference.functions import ( + convert_vaept_to_diffusers, + get_output_type, + load_pytorch_pipeline, +) from core.inference.utilities import change_scheduler, create_generator from core.inference_callbacks import callback from core.optimizations import optimize_vae @@ -211,21 +214,53 @@ def unll(): return pipe, unl - def txt2img(self, job: Txt2ImgQueueEntry) -> List[Image.Image]: - "Generate an image from a prompt" + def create_pipe( + self, + controlnet: Optional[str] = "", + scheduler: Optional[Tuple[Any, SigmaScheduler]] = None, + sampler_settings: Optional[dict] = None, + ) -> StableDiffusionXLLongPromptWeightingPipeline: + "Create an LWP-XL pipeline" + + # self.manage_optional_components(target_controlnet=controlnet or "") + + pipe = StableDiffusionXLLongPromptWeightingPipeline( + parent=self, + vae=self.vae, + unet=self.unet, # type: ignore + text_encoder=self.text_encoder, + text_encoder_2=self.text_encoder_2, + tokenizer=self.tokenizer, + tokenizer_2=self.tokenizer_2, + scheduler=self.scheduler, + force_zeros=self.force_zeros, + aesthetic_score=self.aesthetic_score, + ) + pipe.parent = self + + if scheduler: + change_scheduler( + model=pipe, + scheduler=scheduler[0], # type: ignore + sigma_type=scheduler[1], + sampler_settings=sampler_settings, + ) - total_images: List[Image.Image] = [] + return pipe + + def txt2img(self, job: Txt2ImgQueueEntry) -> Union[List[Image.Image], torch.Tensor]: + "Generate an image from a prompt" pipe = self.create_pipe( scheduler=(job.data.scheduler, job.data.sigmas), sampler_settings=job.data.sampler_settings, ) generator = create_generator(job.data.seed) - shared.current_method = "txt2img" - for _ in tqdm(range(job.data.batch_count), desc="Queue", position=1): - output_type = "pil" + total_images: Union[List[Image.Image], torch.Tensor] = [] + output_type = get_output_type(job) + for _ in tqdm(range(job.data.batch_count), desc="Queue", position=1): xl_flag = None if "sdxl" in job.flags: xl_flag = SDXLFlag.from_dict(job.flags["sdxl"]) @@ -286,66 +321,40 @@ def txt2img(self, job: Txt2ImgQueueEntry) -> List[Image.Image]: callback=callback, num_images_per_prompt=job.data.batch_size, return_dict=False, - output_type="pil", + output_type=output_type, seed=job.data.seed, self_attention_scale=job.data.self_attention_scale, prompt_expansion_settings=job.data.prompt_to_prompt_settings, ) - images: list[Image.Image] = data[0] # type: ignore - total_images.extend(images) - unload() - websocket_manager.broadcast_sync( - data=Data( - data_type="txt2img", - data={ - "progress": 0, - "current_step": 0, - "total_steps": 0, - "image": convert_images_to_base64_grid( - total_images, quality=90, image_format="webp" - ), - }, - ) - ) + images: Union[List[Image.Image], torch.Tensor] = data[0] # type: ignore - return total_images - - def create_pipe( - self, - controlnet: Optional[str] = "", - scheduler: Optional[Tuple[Any, SigmaScheduler]] = None, - sampler_settings: Optional[dict] = None, - ) -> StableDiffusionXLLongPromptWeightingPipeline: - "Create an LWP-XL pipeline" - - # self.manage_optional_components(target_controlnet=controlnet or "") + if not isinstance(images, List): + total_images = images + else: + assert isinstance(total_images, List) + total_images.extend(images) - pipe = StableDiffusionXLLongPromptWeightingPipeline( - parent=self, - vae=self.vae, - unet=self.unet, # type: ignore - text_encoder=self.text_encoder, - text_encoder_2=self.text_encoder_2, - tokenizer=self.tokenizer, - tokenizer_2=self.tokenizer_2, - scheduler=self.scheduler, - force_zeros=self.force_zeros, - aesthetic_score=self.aesthetic_score, - ) - pipe.parent = self + unload() - if scheduler: - change_scheduler( - model=pipe, - scheduler=scheduler[0], # type: ignore - sigma_type=scheduler[1], - sampler_settings=sampler_settings, + if isinstance(total_images, List): + websocket_manager.broadcast_sync( + data=Data( + data_type="txt2img", + data={ + "progress": 0, + "current_step": 0, + "total_steps": 0, + "image": convert_images_to_base64_grid( + total_images, quality=90, image_format="webp" + ), + }, + ) ) - return pipe + return total_images - def img2img(self, job: Img2ImgQueueEntry) -> List[Image.Image]: + def img2img(self, job: Img2ImgQueueEntry) -> Union[List[Image.Image], torch.Tensor]: "Generate an image from an image" pipe = self.create_pipe( @@ -355,11 +364,14 @@ def img2img(self, job: Img2ImgQueueEntry) -> List[Image.Image]: generator = create_generator(job.data.seed) # Preprocess the image - input_image = convert_to_image(job.data.image) - input_image = resize(input_image, job.data.width, job.data.height) + if isinstance(job.data.image, (str, bytes, Image.Image)): + input_image = convert_to_image(job.data.image) + input_image = resize(input_image, job.data.width, job.data.height) + else: + input_image = job.data.image - total_images: List[Image.Image] = [] - shared.current_method = "img2img" + total_images: Union[List[Image.Image], torch.Tensor] = [] + output_type = get_output_type(job) xl_flag = None if "sdxl" in job.flags: @@ -377,11 +389,13 @@ def img2img(self, job: Img2ImgQueueEntry) -> List[Image.Image]: original_size=original_size, generator=generator, prompt=job.data.prompt, - image=input_image, + image=input_image, # type: ignore num_inference_steps=job.data.steps, guidance_scale=job.data.guidance_scale, negative_prompt=job.data.negative_prompt, - output_type="pil", + width=job.data.width, + height=job.data.height, + output_type=output_type, callback=callback, strength=job.data.strength, return_dict=False, @@ -391,31 +405,32 @@ def img2img(self, job: Img2ImgQueueEntry) -> List[Image.Image]: prompt_expansion_settings=job.data.prompt_to_prompt_settings, ) - if not data: - raise ValueError("No data returned from pipeline") - - images = data[0] - assert isinstance(images, List) - - total_images.extend(images) - - websocket_manager.broadcast_sync( - data=Data( - data_type="img2img", - data={ - "progress": 0, - "current_step": 0, - "total_steps": 0, - "image": convert_images_to_base64_grid( - total_images, quality=90, image_format="webp" - ), - }, + images: Union[List[Image.Image], torch.Tensor] = data[0] # type: ignore + + if not isinstance(images, List): + total_images = images + else: + assert isinstance(total_images, List) + total_images.extend(images) + + if isinstance(total_images, List): + websocket_manager.broadcast_sync( + data=Data( + data_type="img2img", + data={ + "progress": 0, + "current_step": 0, + "total_steps": 0, + "image": convert_images_to_base64_grid( + total_images, quality=90, image_format="webp" + ), + }, + ) ) - ) return total_images - def inpaint(self, job: InpaintQueueEntry) -> List[Image.Image]: + def inpaint(self, job: InpaintQueueEntry) -> Union[List[Image.Image], torch.Tensor]: "Generate an image from an image" pipe = self.create_pipe( @@ -432,8 +447,8 @@ def inpaint(self, job: InpaintQueueEntry) -> List[Image.Image]: input_mask_image = ImageOps.invert(input_mask_image) input_mask_image = resize(input_mask_image, job.data.width, job.data.height) - total_images: List[Image.Image] = [] - shared.current_method = "inpainting" + total_images: Union[List[Image.Image], torch.Tensor] = [] + output_type = get_output_type(job) xl_flag = None if "sdxl" in job.flags: @@ -456,7 +471,7 @@ def inpaint(self, job: InpaintQueueEntry) -> List[Image.Image]: num_inference_steps=job.data.steps, guidance_scale=job.data.guidance_scale, negative_prompt=job.data.negative_prompt, - output_type="pil", + output_type=output_type, callback=callback, return_dict=False, num_images_per_prompt=job.data.batch_size, @@ -467,31 +482,32 @@ def inpaint(self, job: InpaintQueueEntry) -> List[Image.Image]: prompt_expansion_settings=job.data.prompt_to_prompt_settings, ) - if not data: - raise ValueError("No data returned from pipeline") - - images = data[0] - assert isinstance(images, List) - - total_images.extend(images) - - websocket_manager.broadcast_sync( - data=Data( - data_type="inpainting", - data={ - "progress": 0, - "current_step": 0, - "total_steps": 0, - "image": convert_images_to_base64_grid( - total_images, quality=90, image_format="webp" - ), - }, + images: Union[List[Image.Image], torch.Tensor] = data[0] # type: ignore + + if not isinstance(images, List): + total_images = images + else: + assert isinstance(total_images, List) + total_images.extend(images) + + if isinstance(total_images, List): + websocket_manager.broadcast_sync( + data=Data( + data_type="inpainting", + data={ + "progress": 0, + "current_step": 0, + "total_steps": 0, + "image": convert_images_to_base64_grid( + total_images, quality=90, image_format="webp" + ), + }, + ) ) - ) return total_images - def generate(self, job: Job): + def generate(self, job: Job) -> Union[List[Image.Image], torch.Tensor]: "Generate images from the queue" logging.info(f"Adding job {job.data.id} to queue") diff --git a/core/types.py b/core/types.py index 2bd054a46..cf14ecf42 100644 --- a/core/types.py +++ b/core/types.py @@ -147,6 +147,7 @@ class ControlNetData: height: int = field(default=512) steps: int = field(default=25) guidance_scale: float = field(default=7) + self_attention_scale: float = field(default=0.0) sigmas: SigmaScheduler = field(default="automatic") seed: int = field(default=0) batch_size: int = field(default=1) diff --git a/frontend/dist/assets/TextToImageView.js b/frontend/dist/assets/TextToImageView.js index abc3b7a3d..b3c5d4d42 100644 --- a/frontend/dist/assets/TextToImageView.js +++ b/frontend/dist/assets/TextToImageView.js @@ -500,10 +500,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ "dimensions-object": unref(settings).data.settings.txt2img }, null, 8, ["dimensions-object"])) : createCommentVNode("", true), isSelectedModelSDXL.value ? (openBlock(), createBlock(unref(_sfc_main$2), { key: 1 })) : createCommentVNode("", true), - !isSelectedModelSDXL.value ? (openBlock(), createBlock(unref(_sfc_main$9), { - key: 2, - tab: "txt2img" - })) : createCommentVNode("", true), + createVNode(unref(_sfc_main$9), { tab: "txt2img" }), createVNode(unref(_sfc_main$a), { tab: "txt2img" }) ]; }), diff --git a/frontend/src/components/inference/Txt2Img.vue b/frontend/src/components/inference/Txt2Img.vue index c6a51b135..3ec4e7774 100644 --- a/frontend/src/components/inference/Txt2Img.vue +++ b/frontend/src/components/inference/Txt2Img.vue @@ -97,7 +97,7 @@ v-if="settings.data.settings.model?.type === 'SDXL'" /> - + From c5288d1714daf96773453912fefbf58c6c45d0d0 Mon Sep 17 00:00:00 2001 From: gabe56f Date: Sat, 9 Dec 2023 19:20:19 +0100 Subject: [PATCH 100/143] merge --- frontend/dist/assets/AccelerateView.js | 2 +- frontend/dist/assets/DescriptionsItem.js | 2 +- ...ion.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/Image2ImageView.js | 35 +- frontend/dist/assets/ImageBrowserView.js | 2 +- ...put.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/ImageProcessingView.js | 2 +- frontend/dist/assets/ImageUpload.js | 2 +- frontend/dist/assets/InputNumber.js | 2 +- ...pup.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/ModelsView.js | 2 +- ...tTo.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/Settings.js | 2 +- frontend/dist/assets/SettingsView.js | 2 +- frontend/dist/assets/Slider.js | 2 +- frontend/dist/assets/Switch.js | 2 +- frontend/dist/assets/TaggerView.js | 2 +- frontend/dist/assets/TextToImageView.js | 508 ++++-------------- frontend/dist/assets/TrashBin.js | 2 +- ...ale.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/clock.js | 15 +- frontend/dist/assets/index.css | 57 +- frontend/dist/assets/index.js | 25 +- 23 files changed, 142 insertions(+), 534 deletions(-) diff --git a/frontend/dist/assets/AccelerateView.js b/frontend/dist/assets/AccelerateView.js index 3dd08490d..0c1c16501 100644 --- a/frontend/dist/assets/AccelerateView.js +++ b/frontend/dist/assets/AccelerateView.js @@ -1,4 +1,4 @@ -import { Q as cB, ab as cM, aa as c, at as cE, aT as iconSwitchTransition, ac as cNotM, d as defineComponent, S as useConfig, ag as useRtl, T as useTheme, a3 as provide, x as h, aw as flatten, ax as getSlot, P as createInjectionKey, bi as stepsLight, R as inject, a_ as throwError, i as computed, ah as createKey, Y as useThemeClass, a1 as call, av as resolveWrappedSlot, ai as resolveSlot, aI as NIconSwitchTransition, aj as NBaseIcon, bj as FinishedIcon, bk as ErrorIcon, n as useMessage, a as useState, y as ref, o as openBlock, g as createElementBlock, e as createVNode, w as withCtx, f as unref, j as NSpace, N as NCard, b as createBaseVNode, m as NSelect, z as NButton, k as createTextVNode, bf as NModal, s as serverUrl, u as useSettings, c as createBlock, C as NTabPane, D as NTabs } from "./index.js"; +import { Q as cB, ab as cM, aa as c, at as cE, aT as iconSwitchTransition, ac as cNotM, d as defineComponent, S as useConfig, ag as useRtl, T as useTheme, a3 as provide, x as h, aw as flatten, ax as getSlot, P as createInjectionKey, bi as stepsLight, R as inject, a_ as throwError, l as computed, ah as createKey, Y as useThemeClass, a1 as call, av as resolveWrappedSlot, ai as resolveSlot, aI as NIconSwitchTransition, aj as NBaseIcon, bj as FinishedIcon, bk as ErrorIcon, n as useMessage, a as useState, y as ref, o as openBlock, g as createElementBlock, e as createVNode, w as withCtx, f as unref, i as NSpace, N as NCard, b as createBaseVNode, m as NSelect, z as NButton, j as createTextVNode, bf as NModal, s as serverUrl, u as useSettings, c as createBlock, C as NTabPane, D as NTabs } from "./index.js"; import { N as NSlider } from "./Slider.js"; import { N as NInputNumber } from "./InputNumber.js"; import { N as NSwitch } from "./Switch.js"; diff --git a/frontend/dist/assets/DescriptionsItem.js b/frontend/dist/assets/DescriptionsItem.js index 830ad75f1..9aabff443 100644 --- a/frontend/dist/assets/DescriptionsItem.js +++ b/frontend/dist/assets/DescriptionsItem.js @@ -1,4 +1,4 @@ -import { aa as c, Q as cB, ac as cNotM, ab as cM, at as cE, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, i as computed, ah as createKey, Y as useThemeClass, bU as useCompitable, aw as flatten, x as h, aQ as repeat, ax as getSlot, bV as descriptionsLight } from "./index.js"; +import { aa as c, Q as cB, ac as cNotM, ab as cM, at as cE, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, l as computed, ah as createKey, Y as useThemeClass, bU as useCompitable, aw as flatten, x as h, aQ as repeat, ax as getSlot, bV as descriptionsLight } from "./index.js"; function getVNodeChildren(vNode, slotName = "default", fallback = []) { const { children } = vNode; if (children !== null && typeof children === "object" && !Array.isArray(children)) { diff --git a/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js index 5170594ec..ea4cd77fb 100644 --- a/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, a as useState, u as useSettings, y as ref, ba as onMounted, p as onUnmounted, s as serverUrl, c as createBlock, w as withCtx, e as createVNode, f as unref, q as NGi, z as NButton, A as NIcon, k as createTextVNode, r as NGrid, bW as NAlert, h as createCommentVNode, N as NCard } from "./index.js"; +import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, a as useState, u as useSettings, y as ref, ba as onMounted, p as onUnmounted, s as serverUrl, c as createBlock, w as withCtx, e as createVNode, f as unref, q as NGi, z as NButton, A as NIcon, j as createTextVNode, r as NGrid, bW as NAlert, h as createCommentVNode, N as NCard } from "./index.js"; const _hoisted_1$1 = { xmlns: "http://www.w3.org/2000/svg", "xmlns:xlink": "http://www.w3.org/1999/xlink", diff --git a/frontend/dist/assets/Image2ImageView.js b/frontend/dist/assets/Image2ImageView.js index eb405b3e9..6fb16f486 100644 --- a/frontend/dist/assets/Image2ImageView.js +++ b/frontend/dist/assets/Image2ImageView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, a as useState, u as useSettings, n as useMessage, i as computed, p as onUnmounted, e as createVNode, w as withCtx, f as unref, q as NGi, N as NCard, j as NSpace, l as NTooltip, k as createTextVNode, m as NSelect, c as createBlock, h as createCommentVNode, r as NGrid, s as serverUrl, t as pushScopeId, v as popScopeId, _ as _export_sfc, x as h, y as ref, z as NButton, A as NIcon, B as toDisplayString, C as NTabPane, D as NTabs } from "./index.js"; +import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, a as useState, u as useSettings, n as useMessage, l as computed, p as onUnmounted, e as createVNode, w as withCtx, f as unref, q as NGi, N as NCard, i as NSpace, k as NTooltip, j as createTextVNode, m as NSelect, c as createBlock, h as createCommentVNode, r as NGrid, s as serverUrl, t as pushScopeId, v as popScopeId, _ as _export_sfc, x as h, y as ref, z as NButton, A as NIcon, B as toDisplayString, C as NTabPane, D as NTabs } from "./index.js"; import { B as BurnerClock, P as Prompt, _ as _sfc_main$5, a as _sfc_main$6, b as _sfc_main$7, c as _sfc_main$8, d as _sfc_main$d } from "./clock.js"; import { _ as _sfc_main$b } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; import { _ as _sfc_main$c } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; @@ -528,13 +528,8 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ }; } }); -<<<<<<< HEAD -const ControlNet = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-95a354be"]]); -const _withScopeId$1 = (n) => (pushScopeId("data-v-4fae0a93"), n = n(), popScopeId(), n); -======= const ControlNet = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-97c56df6"]]); -const _withScopeId$1 = (n) => (pushScopeId("data-v-bfd46a0a"), n = n(), popScopeId(), n); ->>>>>>> origin/experimental +const _withScopeId$1 = (n) => (pushScopeId("data-v-8c5af50f"), n = n(), popScopeId(), n); const _hoisted_1$1 = { style: { "margin": "0 12px" } }; const _hoisted_2$1 = { class: "flex-container" }; const _hoisted_3$1 = /* @__PURE__ */ _withScopeId$1(() => /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Steps", -1)); @@ -602,7 +597,6 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ prompt_to_prompt: settings.data.settings.api.prompt_to_prompt } }, -<<<<<<< HEAD ...settings.defaultSettings.flags.deepshrink.enabled ? { flags: { deepshrink: { @@ -616,8 +610,6 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ } } } : {}, - model: (_a = settings.data.settings.model) == null ? void 0 : _a.path -======= model: (_a = settings.data.settings.model) == null ? void 0 : _a.path, flags: { ...settings.data.settings.img2img.highres.enabled ? { @@ -640,7 +632,6 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ } } : {} } ->>>>>>> origin/experimental }) }).then((res) => { if (!res.ok) { @@ -845,11 +836,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ }; } }); -<<<<<<< HEAD -const ImageToImage = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-4fae0a93"]]); -======= -const ImageToImage = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-bfd46a0a"]]); ->>>>>>> origin/experimental +const ImageToImage = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-8c5af50f"]]); var VueDrawingCanvas = /* @__PURE__ */ defineComponent({ name: "VueDrawingCanvas", props: { @@ -1425,11 +1412,7 @@ var VueDrawingCanvas = /* @__PURE__ */ defineComponent({ }); } }); -<<<<<<< HEAD -const _withScopeId = (n) => (pushScopeId("data-v-0d0f8c9e"), n = n(), popScopeId(), n); -======= -const _withScopeId = (n) => (pushScopeId("data-v-1193df1f"), n = n(), popScopeId(), n); ->>>>>>> origin/experimental +const _withScopeId = (n) => (pushScopeId("data-v-124be5cd"), n = n(), popScopeId(), n); const _hoisted_1 = { style: { "margin": "0 12px" } }; const _hoisted_2 = { style: { "display": "inline-flex", "align-items": "center" } }; const _hoisted_3 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("svg", { @@ -1513,7 +1496,6 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ prompt_to_prompt: settings.data.settings.api.prompt_to_prompt } }, -<<<<<<< HEAD ...settings.defaultSettings.flags.deepshrink.enabled ? { flags: { deepshrink: { @@ -1527,8 +1509,6 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ } } } : {}, - model: (_a = settings.data.settings.model) == null ? void 0 : _a.path -======= model: (_a = settings.data.settings.model) == null ? void 0 : _a.path, flags: { ...settings.data.settings.inpainting.highres.enabled ? { @@ -1551,7 +1531,6 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ } } : {} } ->>>>>>> origin/experimental }) }).then((res) => { if (!res.ok) { @@ -1989,11 +1968,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ }; } }); -<<<<<<< HEAD -const Inpainting = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-0d0f8c9e"]]); -======= -const Inpainting = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-1193df1f"]]); ->>>>>>> origin/experimental +const Inpainting = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-124be5cd"]]); const _sfc_main = /* @__PURE__ */ defineComponent({ __name: "Image2ImageView", setup(__props) { diff --git a/frontend/dist/assets/ImageBrowserView.js b/frontend/dist/assets/ImageBrowserView.js index cd0eb27dd..852d74630 100644 --- a/frontend/dist/assets/ImageBrowserView.js +++ b/frontend/dist/assets/ImageBrowserView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, b7 as useCssVars, a as useState, u as useSettings, R as inject, y as ref, i as computed, bK as urlFromPath, b9 as reactive, ba as onMounted, p as onUnmounted, e as createVNode, f as unref, w as withCtx, F as Fragment, L as renderList, b8 as themeOverridesKey, s as serverUrl, I as NInput, A as NIcon, bf as NModal, r as NGrid, q as NGi, z as NButton, k as createTextVNode, M as NScrollbar, c as createBlock, bA as convertToTextString, B as toDisplayString, h as createCommentVNode, bL as diffusersSchedulerTuple, _ as _export_sfc } from "./index.js"; +import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, b7 as useCssVars, a as useState, u as useSettings, R as inject, y as ref, l as computed, bK as urlFromPath, b9 as reactive, ba as onMounted, p as onUnmounted, e as createVNode, f as unref, w as withCtx, F as Fragment, L as renderList, b8 as themeOverridesKey, s as serverUrl, I as NInput, A as NIcon, bf as NModal, r as NGrid, q as NGi, z as NButton, j as createTextVNode, M as NScrollbar, c as createBlock, bA as convertToTextString, B as toDisplayString, h as createCommentVNode, bL as diffusersSchedulerTuple, _ as _export_sfc } from "./index.js"; import { D as Download, _ as _sfc_main$1 } from "./SendOutputTo.vue_vue_type_script_setup_true_lang.js"; import { N as NImage, T as TrashBin } from "./TrashBin.js"; import { N as NSlider } from "./Slider.js"; diff --git a/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js index f5b4f964a..d4468dc5e 100644 --- a/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { d as defineComponent, y as ref, a as useState, o as openBlock, c as createBlock, w as withCtx, f as unref, q as NGi, e as createVNode, A as NIcon, k as createTextVNode, z as NButton, h as createCommentVNode, r as NGrid, i as computed, b as createBaseVNode, g as createElementBlock, F as Fragment, L as renderList, M as NScrollbar, N as NCard } from "./index.js"; +import { d as defineComponent, y as ref, a as useState, o as openBlock, c as createBlock, w as withCtx, f as unref, q as NGi, e as createVNode, A as NIcon, j as createTextVNode, z as NButton, h as createCommentVNode, r as NGrid, l as computed, b as createBaseVNode, g as createElementBlock, F as Fragment, L as renderList, M as NScrollbar, N as NCard } from "./index.js"; import { D as Download, _ as _sfc_main$2 } from "./SendOutputTo.vue_vue_type_script_setup_true_lang.js"; import { T as TrashBin, N as NImage } from "./TrashBin.js"; const _sfc_main$1 = /* @__PURE__ */ defineComponent({ diff --git a/frontend/dist/assets/ImageProcessingView.js b/frontend/dist/assets/ImageProcessingView.js index 081f5a5f2..a38cf670b 100644 --- a/frontend/dist/assets/ImageProcessingView.js +++ b/frontend/dist/assets/ImageProcessingView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, a as useState, u as useSettings, n as useMessage, i as computed, K as upscalerOptions, o as openBlock, g as createElementBlock, e as createVNode, w as withCtx, f as unref, q as NGi, N as NCard, j as NSpace, b as createBaseVNode, m as NSelect, l as NTooltip, k as createTextVNode, r as NGrid, s as serverUrl, c as createBlock, C as NTabPane, D as NTabs } from "./index.js"; +import { d as defineComponent, a as useState, u as useSettings, n as useMessage, l as computed, K as upscalerOptions, o as openBlock, g as createElementBlock, e as createVNode, w as withCtx, f as unref, q as NGi, N as NCard, i as NSpace, b as createBaseVNode, m as NSelect, k as NTooltip, j as createTextVNode, r as NGrid, s as serverUrl, c as createBlock, C as NTabPane, D as NTabs } from "./index.js"; import { _ as _sfc_main$2 } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; import { _ as _sfc_main$3 } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; import { I as ImageUpload } from "./ImageUpload.js"; diff --git a/frontend/dist/assets/ImageUpload.js b/frontend/dist/assets/ImageUpload.js index 62a763014..f8f5e390a 100644 --- a/frontend/dist/assets/ImageUpload.js +++ b/frontend/dist/assets/ImageUpload.js @@ -1,4 +1,4 @@ -import { d as defineComponent, y as ref, i as computed, ba as onMounted, o as openBlock, c as createBlock, w as withCtx, b as createBaseVNode, bd as withModifiers, g as createElementBlock, e as createVNode, f as unref, A as NIcon, B as toDisplayString, N as NCard, t as pushScopeId, v as popScopeId, _ as _export_sfc } from "./index.js"; +import { d as defineComponent, y as ref, l as computed, ba as onMounted, o as openBlock, c as createBlock, w as withCtx, b as createBaseVNode, bd as withModifiers, g as createElementBlock, e as createVNode, f as unref, A as NIcon, B as toDisplayString, N as NCard, t as pushScopeId, v as popScopeId, _ as _export_sfc } from "./index.js"; import { C as CloudUpload } from "./CloudUpload.js"; const _withScopeId = (n) => (pushScopeId("data-v-9ed1514f"), n = n(), popScopeId(), n); const _hoisted_1 = { class: "image-container" }; diff --git a/frontend/dist/assets/InputNumber.js b/frontend/dist/assets/InputNumber.js index dcf6aae8d..be417d0e4 100644 --- a/frontend/dist/assets/InputNumber.js +++ b/frontend/dist/assets/InputNumber.js @@ -1,4 +1,4 @@ -import { d as defineComponent, x as h, aa as c, Q as cB, S as useConfig, T as useTheme, ad as useLocale, ar as useFormItem, y as ref, X as toRef, ae as useMergedState, as as useMemo, J as watch, ag as useRtl, i as computed, bX as rgba, I as NInput, av as resolveWrappedSlot, bY as inputNumberLight, aD as on, ai as resolveSlot, aj as NBaseIcon, bZ as XButton, a$ as AddIcon, a1 as call, W as nextTick } from "./index.js"; +import { d as defineComponent, x as h, aa as c, Q as cB, S as useConfig, T as useTheme, ad as useLocale, ar as useFormItem, y as ref, X as toRef, ae as useMergedState, as as useMemo, J as watch, ag as useRtl, l as computed, bX as rgba, I as NInput, av as resolveWrappedSlot, bY as inputNumberLight, aD as on, ai as resolveSlot, aj as NBaseIcon, bZ as XButton, a$ as AddIcon, a1 as call, W as nextTick } from "./index.js"; const RemoveIcon = defineComponent({ name: "Remove", render() { diff --git a/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js index 56f631aaa..17e8282ef 100644 --- a/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { bl as upperFirst, bm as toString, bn as createCompounder, bo as cloneVNode, a3 as provide, P as createInjectionKey, R as inject, a_ as throwError, d as defineComponent, S as useConfig, y as ref, bp as onBeforeUpdate, x as h, bq as indexMap, i as computed, ba as onMounted, aB as onBeforeUnmount, Q as cB, at as cE, aa as c, ab as cM, a4 as keep, ae as useMergedState, X as toRef, af as watchEffect, br as onUpdated, J as watch, W as nextTick, T as useTheme, Y as useThemeClass, aw as flatten, aL as VResizeObserver, bs as resolveSlotWithProps, bt as withDirectives, bu as vShow, aX as Transition, bb as normalizeStyle, bv as getPreciseEventTarget, aD as on, aC as off, bw as carouselLight, ac as cNotM, ar as useFormItem, ah as createKey, bx as color2Class, L as renderList, aj as NBaseIcon, by as rateLight, a1 as call, n as useMessage, u as useSettings, b9 as reactive, o as openBlock, c as createBlock, w as withCtx, e as createVNode, g as createElementBlock, f as unref, C as NTabPane, r as NGrid, q as NGi, F as Fragment, b as createBaseVNode, N as NCard, k as createTextVNode, B as toDisplayString, bz as NTag, m as NSelect, z as NButton, D as NTabs, bf as NModal, s as serverUrl } from "./index.js"; +import { bl as upperFirst, bm as toString, bn as createCompounder, bo as cloneVNode, a3 as provide, P as createInjectionKey, R as inject, a_ as throwError, d as defineComponent, S as useConfig, y as ref, bp as onBeforeUpdate, x as h, bq as indexMap, l as computed, ba as onMounted, aB as onBeforeUnmount, Q as cB, at as cE, aa as c, ab as cM, a4 as keep, ae as useMergedState, X as toRef, af as watchEffect, br as onUpdated, J as watch, W as nextTick, T as useTheme, Y as useThemeClass, aw as flatten, aL as VResizeObserver, bs as resolveSlotWithProps, bt as withDirectives, bu as vShow, aX as Transition, bb as normalizeStyle, bv as getPreciseEventTarget, aD as on, aC as off, bw as carouselLight, ac as cNotM, ar as useFormItem, ah as createKey, bx as color2Class, L as renderList, aj as NBaseIcon, by as rateLight, a1 as call, n as useMessage, u as useSettings, b9 as reactive, o as openBlock, c as createBlock, w as withCtx, e as createVNode, g as createElementBlock, f as unref, C as NTabPane, r as NGrid, q as NGi, F as Fragment, b as createBaseVNode, N as NCard, j as createTextVNode, B as toDisplayString, bz as NTag, m as NSelect, z as NButton, D as NTabs, bf as NModal, s as serverUrl } from "./index.js"; import { a as NDescriptions, N as NDescriptionsItem } from "./DescriptionsItem.js"; function capitalize(string) { return upperFirst(toString(string).toLowerCase()); diff --git a/frontend/dist/assets/ModelsView.js b/frontend/dist/assets/ModelsView.js index 20cc0dd55..e70a5f55e 100644 --- a/frontend/dist/assets/ModelsView.js +++ b/frontend/dist/assets/ModelsView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, x as h, O as replaceable, P as createInjectionKey, Q as cB, R as inject, S as useConfig, T as useTheme, U as popselectLight, i as computed, V as createTreeMate, J as watch, W as nextTick, X as toRef, Y as useThemeClass, Z as NInternalSelectMenu, $ as createTmOptions, a0 as happensIn, a1 as call, a2 as keysOf, y as ref, a3 as provide, a4 as keep, a5 as createRefSetter, a6 as mergeEventHandlers, a7 as omit, a8 as NPopover, a9 as popoverBaseProps, aa as c, ab as cM, ac as cNotM, ad as useLocale, ae as useMergedState, af as watchEffect, ag as useRtl, ah as createKey, ai as resolveSlot, I as NInput, m as NSelect, F as Fragment, aj as NBaseIcon, ak as useAdjustedTo, al as paginationLight, am as useMergedClsPrefix, an as ellipsisLight, ao as onDeactivated, l as NTooltip, ap as mergeProps, aq as useStyle, ar as useFormItem, as as useMemo, at as cE, au as radioLight, av as resolveWrappedSlot, aw as flatten$1, ax as getSlot, ay as depx, az as formatLength, z as NButton, aA as NScrollbar, aB as onBeforeUnmount, aC as off, aD as on, aE as ChevronDownIcon, aF as NDropdown, aG as pxfy, aH as get, aI as NIconSwitchTransition, aJ as NBaseLoading, aK as ChevronRightIcon, p as onUnmounted, aL as VResizeObserver, aM as warn, aN as cssrAnchorMetaName, aO as VVirtualList, aP as NEmpty, aQ as repeat, aR as beforeNextFrameOnce, aS as fadeInScaleUpTransition, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, aW as createId, aX as Transition, aY as dataTableLight, aZ as loadingBarApiInjectionKey, a_ as throwError, a$ as AddIcon, b0 as NProgress, b1 as NFadeInExpandTransition, b2 as EyeIcon, b3 as fadeInHeightExpandTransition, b4 as Teleport, b5 as uploadLight, o as openBlock, g as createElementBlock, b as createBaseVNode, b6 as createStaticVNode, b7 as useCssVars, f as unref, b8 as themeOverridesKey, b9 as reactive, ba as onMounted, e as createVNode, w as withCtx, A as NIcon, L as renderList, _ as _export_sfc, u as useSettings, h as createCommentVNode, bb as normalizeStyle, k as createTextVNode, B as toDisplayString, bc as NText, c as createBlock, bd as withModifiers, a as useState, n as useMessage, be as huggingfaceModelsFile, N as NCard, s as serverUrl, t as pushScopeId, v as popScopeId, j as NSpace, bf as NModal, q as NGi, r as NGrid, bg as NDivider, bh as Backends, C as NTabPane, D as NTabs } from "./index.js"; +import { d as defineComponent, x as h, O as replaceable, P as createInjectionKey, Q as cB, R as inject, S as useConfig, T as useTheme, U as popselectLight, l as computed, V as createTreeMate, J as watch, W as nextTick, X as toRef, Y as useThemeClass, Z as NInternalSelectMenu, $ as createTmOptions, a0 as happensIn, a1 as call, a2 as keysOf, y as ref, a3 as provide, a4 as keep, a5 as createRefSetter, a6 as mergeEventHandlers, a7 as omit, a8 as NPopover, a9 as popoverBaseProps, aa as c, ab as cM, ac as cNotM, ad as useLocale, ae as useMergedState, af as watchEffect, ag as useRtl, ah as createKey, ai as resolveSlot, I as NInput, m as NSelect, F as Fragment, aj as NBaseIcon, ak as useAdjustedTo, al as paginationLight, am as useMergedClsPrefix, an as ellipsisLight, ao as onDeactivated, k as NTooltip, ap as mergeProps, aq as useStyle, ar as useFormItem, as as useMemo, at as cE, au as radioLight, av as resolveWrappedSlot, aw as flatten$1, ax as getSlot, ay as depx, az as formatLength, z as NButton, aA as NScrollbar, aB as onBeforeUnmount, aC as off, aD as on, aE as ChevronDownIcon, aF as NDropdown, aG as pxfy, aH as get, aI as NIconSwitchTransition, aJ as NBaseLoading, aK as ChevronRightIcon, p as onUnmounted, aL as VResizeObserver, aM as warn, aN as cssrAnchorMetaName, aO as VVirtualList, aP as NEmpty, aQ as repeat, aR as beforeNextFrameOnce, aS as fadeInScaleUpTransition, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, aW as createId, aX as Transition, aY as dataTableLight, aZ as loadingBarApiInjectionKey, a_ as throwError, a$ as AddIcon, b0 as NProgress, b1 as NFadeInExpandTransition, b2 as EyeIcon, b3 as fadeInHeightExpandTransition, b4 as Teleport, b5 as uploadLight, o as openBlock, g as createElementBlock, b as createBaseVNode, b6 as createStaticVNode, b7 as useCssVars, f as unref, b8 as themeOverridesKey, b9 as reactive, ba as onMounted, e as createVNode, w as withCtx, A as NIcon, L as renderList, _ as _export_sfc, u as useSettings, h as createCommentVNode, bb as normalizeStyle, j as createTextVNode, B as toDisplayString, bc as NText, c as createBlock, bd as withModifiers, a as useState, n as useMessage, be as huggingfaceModelsFile, N as NCard, s as serverUrl, t as pushScopeId, v as popScopeId, i as NSpace, bf as NModal, q as NGi, r as NGrid, bg as NDivider, bh as Backends, C as NTabPane, D as NTabs } from "./index.js"; import { _ as _sfc_main$6, n as nsfwIndex, N as NRate } from "./ModelPopup.vue_vue_type_script_setup_true_lang.js"; import { N as NCheckboxGroup, a as NCheckbox, S as Settings } from "./Settings.js"; import { N as NSwitch } from "./Switch.js"; diff --git a/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js index 3a5c9d964..29407f6b3 100644 --- a/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, bM as useRouter, u as useSettings, a as useState, y as ref, b9 as reactive, J as watch, i as computed, e as createVNode, w as withCtx, f as unref, N as NCard, z as NButton, k as createTextVNode, M as NScrollbar, F as Fragment, L as renderList, B as toDisplayString, bg as NDivider, bf as NModal, c as createBlock, q as NGi, r as NGrid, h as createCommentVNode } from "./index.js"; +import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, bM as useRouter, u as useSettings, a as useState, y as ref, b9 as reactive, J as watch, l as computed, e as createVNode, w as withCtx, f as unref, N as NCard, z as NButton, j as createTextVNode, M as NScrollbar, F as Fragment, L as renderList, B as toDisplayString, bg as NDivider, bf as NModal, c as createBlock, q as NGi, r as NGrid, h as createCommentVNode } from "./index.js"; import { N as NSwitch } from "./Switch.js"; const _hoisted_1$3 = { xmlns: "http://www.w3.org/2000/svg", diff --git a/frontend/dist/assets/Settings.js b/frontend/dist/assets/Settings.js index e939932b6..ae341017c 100644 --- a/frontend/dist/assets/Settings.js +++ b/frontend/dist/assets/Settings.js @@ -1,4 +1,4 @@ -import { x as h, d as defineComponent, S as useConfig, ar as useFormItem, y as ref, i as computed, ae as useMergedState, a3 as provide, X as toRef, P as createInjectionKey, a1 as call, aa as c, Q as cB, ab as cM, at as cE, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, R as inject, as as useMemo, T as useTheme, bJ as checkboxLight, ag as useRtl, ah as createKey, Y as useThemeClass, aW as createId, av as resolveWrappedSlot, aI as NIconSwitchTransition, aD as on, o as openBlock, g as createElementBlock, b as createBaseVNode } from "./index.js"; +import { x as h, d as defineComponent, S as useConfig, ar as useFormItem, y as ref, l as computed, ae as useMergedState, a3 as provide, X as toRef, P as createInjectionKey, a1 as call, aa as c, Q as cB, ab as cM, at as cE, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, R as inject, as as useMemo, T as useTheme, bJ as checkboxLight, ag as useRtl, ah as createKey, Y as useThemeClass, aW as createId, av as resolveWrappedSlot, aI as NIconSwitchTransition, aD as on, o as openBlock, g as createElementBlock, b as createBaseVNode } from "./index.js"; const CheckMark = h( "svg", { viewBox: "0 0 64 64", class: "check-icon" }, diff --git a/frontend/dist/assets/SettingsView.js b/frontend/dist/assets/SettingsView.js index 3c607222f..65f836ede 100644 --- a/frontend/dist/assets/SettingsView.js +++ b/frontend/dist/assets/SettingsView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, u as useSettings, o as openBlock, c as createBlock, w as withCtx, e as createVNode, f as unref, I as NInput, m as NSelect, N as NCard, b9 as reactive, i as computed, bA as convertToTextString, y as ref, s as serverUrl, J as watch, a as useState, b as createBaseVNode, g as createElementBlock, L as renderList, bc as NText, k as createTextVNode, B as toDisplayString, F as Fragment, h as createCommentVNode, C as NTabPane, D as NTabs, R as inject, bB as themeKey, z as NButton, l as NTooltip, n as useMessage, bC as useNotification, p as onUnmounted, bD as defaultSettings } from "./index.js"; +import { d as defineComponent, u as useSettings, o as openBlock, c as createBlock, w as withCtx, e as createVNode, f as unref, I as NInput, m as NSelect, N as NCard, b9 as reactive, l as computed, bA as convertToTextString, y as ref, s as serverUrl, J as watch, a as useState, b as createBaseVNode, g as createElementBlock, L as renderList, bc as NText, j as createTextVNode, B as toDisplayString, F as Fragment, h as createCommentVNode, C as NTabPane, D as NTabs, R as inject, bB as themeKey, z as NButton, k as NTooltip, n as useMessage, bC as useNotification, p as onUnmounted, bD as defaultSettings } from "./index.js"; import { c as NFormItem, _ as _sfc_main$g, b as _sfc_main$h, a as _sfc_main$i, N as NForm } from "./Upscale.vue_vue_type_script_setup_true_lang.js"; import { N as NSwitch } from "./Switch.js"; import { N as NInputNumber } from "./InputNumber.js"; diff --git a/frontend/dist/assets/Slider.js b/frontend/dist/assets/Slider.js index 2d318b072..4922bd369 100644 --- a/frontend/dist/assets/Slider.js +++ b/frontend/dist/assets/Slider.js @@ -1,4 +1,4 @@ -import { y as ref, bp as onBeforeUpdate, aa as c, Q as cB, ab as cM, at as cE, aS as fadeInScaleUpTransition, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, ar as useFormItem, i as computed, X as toRef, ae as useMergedState, J as watch, W as nextTick, aB as onBeforeUnmount, Y as useThemeClass, bQ as isMounted, ak as useAdjustedTo, x as h, b_ as VBinder, b$ as VTarget, ai as resolveSlot, c0 as VFollower, aX as Transition, c1 as sliderLight, aD as on, aC as off, a1 as call } from "./index.js"; +import { y as ref, bp as onBeforeUpdate, aa as c, Q as cB, ab as cM, at as cE, aS as fadeInScaleUpTransition, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, ar as useFormItem, l as computed, X as toRef, ae as useMergedState, J as watch, W as nextTick, aB as onBeforeUnmount, Y as useThemeClass, bQ as isMounted, ak as useAdjustedTo, x as h, b_ as VBinder, b$ as VTarget, ai as resolveSlot, c0 as VFollower, aX as Transition, c1 as sliderLight, aD as on, aC as off, a1 as call } from "./index.js"; function isTouchEvent(e) { return window.TouchEvent && e instanceof window.TouchEvent; } diff --git a/frontend/dist/assets/Switch.js b/frontend/dist/assets/Switch.js index 762abd2de..bc72d175f 100644 --- a/frontend/dist/assets/Switch.js +++ b/frontend/dist/assets/Switch.js @@ -1,4 +1,4 @@ -import { Q as cB, at as cE, aT as iconSwitchTransition, aa as c, ab as cM, ac as cNotM, d as defineComponent, S as useConfig, T as useTheme, ar as useFormItem, y as ref, X as toRef, ae as useMergedState, i as computed, ah as createKey, aG as pxfy, ay as depx, Y as useThemeClass, c2 as isSlotEmpty, x as h, av as resolveWrappedSlot, c3 as switchLight, aI as NIconSwitchTransition, aJ as NBaseLoading, a1 as call } from "./index.js"; +import { Q as cB, at as cE, aT as iconSwitchTransition, aa as c, ab as cM, ac as cNotM, d as defineComponent, S as useConfig, T as useTheme, ar as useFormItem, y as ref, X as toRef, ae as useMergedState, l as computed, ah as createKey, aG as pxfy, ay as depx, Y as useThemeClass, c2 as isSlotEmpty, x as h, av as resolveWrappedSlot, c3 as switchLight, aI as NIconSwitchTransition, aJ as NBaseLoading, a1 as call } from "./index.js"; const style = cB("switch", ` height: var(--n-height); min-width: var(--n-width); diff --git a/frontend/dist/assets/TaggerView.js b/frontend/dist/assets/TaggerView.js index ec5a7444a..71e4573c5 100644 --- a/frontend/dist/assets/TaggerView.js +++ b/frontend/dist/assets/TaggerView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, a as useState, u as useSettings, n as useMessage, y as ref, i as computed, E as spaceRegex, o as openBlock, g as createElementBlock, e as createVNode, w as withCtx, f as unref, q as NGi, N as NCard, j as NSpace, b as createBaseVNode, m as NSelect, l as NTooltip, k as createTextVNode, I as NInput, B as toDisplayString, r as NGrid, s as serverUrl, t as pushScopeId, v as popScopeId, _ as _export_sfc } from "./index.js"; +import { d as defineComponent, a as useState, u as useSettings, n as useMessage, y as ref, l as computed, E as spaceRegex, o as openBlock, g as createElementBlock, e as createVNode, w as withCtx, f as unref, q as NGi, N as NCard, i as NSpace, b as createBaseVNode, m as NSelect, k as NTooltip, j as createTextVNode, I as NInput, B as toDisplayString, r as NGrid, s as serverUrl, t as pushScopeId, v as popScopeId, _ as _export_sfc } from "./index.js"; import { _ as _sfc_main$1 } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; import { I as ImageUpload } from "./ImageUpload.js"; import { v as v4 } from "./v4.js"; diff --git a/frontend/dist/assets/TextToImageView.js b/frontend/dist/assets/TextToImageView.js index bdbd176a2..21cab42b0 100644 --- a/frontend/dist/assets/TextToImageView.js +++ b/frontend/dist/assets/TextToImageView.js @@ -1,207 +1,16 @@ -<<<<<<< HEAD -import { d as defineComponent, u as useSettings, a as useState, c as computed, b as upscalerOptions, o as openBlock, e as createBlock, w as withCtx, f as createBaseVNode, g as createVNode, h as unref, N as NSpace, i as NSelect, j as createElementBlock, k as createTextVNode, l as NTooltip, m as createCommentVNode, n as NCard, p as useMessage, q as onUnmounted, r as NGi, s as NGrid, t as serverUrl } from "./index.js"; -import { _ as _sfc_main$b } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; -import { _ as _sfc_main$c } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; -import { B as BurnerClock, P as Prompt, _ as _sfc_main$7, a as _sfc_main$8, b as _sfc_main$9, c as _sfc_main$a, d as _sfc_main$d } from "./clock.js"; +import { d as defineComponent, u as useSettings, a as useState, o as openBlock, c as createBlock, w as withCtx, b as createBaseVNode, e as createVNode, f as unref, g as createElementBlock, h as createCommentVNode, N as NCard, i as NSpace, j as createTextVNode, k as NTooltip, l as computed, m as NSelect, n as useMessage, p as onUnmounted, q as NGi, r as NGrid, s as serverUrl } from "./index.js"; +import { _ as _sfc_main$c } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; +import { _ as _sfc_main$d } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; +import { B as BurnerClock, P as Prompt, _ as _sfc_main$6, a as _sfc_main$7, b as _sfc_main$8, c as _sfc_main$9, d as _sfc_main$e } from "./clock.js"; +import { _ as _sfc_main$5, a as _sfc_main$a, b as _sfc_main$b } from "./Upscale.vue_vue_type_script_setup_true_lang.js"; import { N as NSwitch } from "./Switch.js"; import { N as NSlider } from "./Slider.js"; import { N as NInputNumber } from "./InputNumber.js"; -import { _ as _sfc_main$6 } from "./SamplerPicker.vue_vue_type_script_setup_true_lang.js"; -======= -import { d as defineComponent, u as useSettings, a as useState, o as openBlock, c as createBlock, w as withCtx, b as createBaseVNode, e as createVNode, f as unref, g as createElementBlock, h as createCommentVNode, N as NCard, i as computed, j as NSpace, k as createTextVNode, l as NTooltip, m as NSelect, n as useMessage, p as onUnmounted, q as NGi, r as NGrid, s as serverUrl } from "./index.js"; -import { _ as _sfc_main$b } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; -import { _ as _sfc_main$c } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; -import { B as BurnerClock, P as Prompt, _ as _sfc_main$5, a as _sfc_main$6, b as _sfc_main$7, c as _sfc_main$8, d as _sfc_main$d } from "./clock.js"; -import { _ as _sfc_main$4, a as _sfc_main$9, b as _sfc_main$a } from "./Upscale.vue_vue_type_script_setup_true_lang.js"; -import { N as NSwitch } from "./Switch.js"; -import { N as NSlider } from "./Slider.js"; -import { N as NInputNumber } from "./InputNumber.js"; ->>>>>>> origin/experimental import { v as v4 } from "./v4.js"; import "./SendOutputTo.vue_vue_type_script_setup_true_lang.js"; import "./TrashBin.js"; import "./DescriptionsItem.js"; import "./Settings.js"; -<<<<<<< HEAD -const _hoisted_1$4 = { class: "flex-container" }; -const _hoisted_2$4 = /* @__PURE__ */ createBaseVNode("div", { class: "slider-label" }, [ - /* @__PURE__ */ createBaseVNode("p", null, "Enabled") -], -1); -const _hoisted_3$4 = { class: "flex-container" }; -const _hoisted_4$4 = /* @__PURE__ */ createBaseVNode("div", { class: "slider-label" }, [ - /* @__PURE__ */ createBaseVNode("p", null, "Mode") -], -1); -const _hoisted_5$4 = { key: 0 }; -const _hoisted_6$4 = { class: "flex-container" }; -const _hoisted_7$4 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Upscaler", -1); -const _hoisted_8$2 = { key: 1 }; -const _hoisted_9$2 = { class: "flex-container" }; -const _hoisted_10$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Antialiased", -1); -const _hoisted_11$1 = { class: "flex-container" }; -const _hoisted_12$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Latent Mode", -1); -const _hoisted_13$1 = { class: "flex-container" }; -const _hoisted_14$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Steps", -1); -const _hoisted_15$1 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "We recommend using 20-50 steps for most images.", -1); -const _hoisted_16$1 = { class: "flex-container" }; -const _hoisted_17 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Scale", -1); -const _hoisted_18 = { class: "flex-container" }; -const _hoisted_19 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Strength", -1); -const _sfc_main$5 = /* @__PURE__ */ defineComponent({ - __name: "HighResFix", - setup(__props) { - const settings = useSettings(); - const global = useState(); - const imageUpscalerOptions = computed(() => { - const localModels = global.state.models.filter( - (model) => model.backend === "Upscaler" && !(upscalerOptions.map((option) => option.label).indexOf(model.name) !== -1) - ).map((model) => ({ - label: model.name, - value: model.path - })); - return [...upscalerOptions, ...localModels]; - }); - const latentUpscalerOptions = [ - { label: "Nearest", value: "nearest" }, - { label: "Nearest exact", value: "nearest-exact" }, - { label: "Area", value: "area" }, - { label: "Bilinear", value: "bilinear" }, - { label: "Bicubic", value: "bicubic" }, - { label: "Bislerp", value: "bislerp" } - ]; - return (_ctx, _cache) => { - return openBlock(), createBlock(unref(NCard), { - title: "Highres fix", - class: "generate-extra-card" - }, { - default: withCtx(() => [ - createBaseVNode("div", _hoisted_1$4, [ - _hoisted_2$4, - createVNode(unref(NSwitch), { - value: unref(global).state.txt2img.highres, - "onUpdate:value": _cache[0] || (_cache[0] = ($event) => unref(global).state.txt2img.highres = $event) - }, null, 8, ["value"]) - ]), - unref(global).state.txt2img.highres ? (openBlock(), createBlock(unref(NSpace), { - key: 0, - vertical: "", - class: "left-container" - }, { - default: withCtx(() => [ - createBaseVNode("div", _hoisted_3$4, [ - _hoisted_4$4, - createVNode(unref(NSelect), { - value: unref(settings).data.settings.flags.highres.mode, - "onUpdate:value": _cache[1] || (_cache[1] = ($event) => unref(settings).data.settings.flags.highres.mode = $event), - options: [ - { label: "Latent", value: "latent" }, - { label: "Image", value: "image" } - ] - }, null, 8, ["value"]) - ]), - unref(settings).data.settings.flags.highres.mode === "image" ? (openBlock(), createElementBlock("div", _hoisted_5$4, [ - createBaseVNode("div", _hoisted_6$4, [ - _hoisted_7$4, - createVNode(unref(NSelect), { - value: unref(settings).data.settings.flags.highres.image_upscaler, - "onUpdate:value": _cache[2] || (_cache[2] = ($event) => unref(settings).data.settings.flags.highres.image_upscaler = $event), - size: "small", - style: { "flex-grow": "1" }, - filterable: "", - options: imageUpscalerOptions.value - }, null, 8, ["value", "options"]) - ]) - ])) : (openBlock(), createElementBlock("div", _hoisted_8$2, [ - createBaseVNode("div", _hoisted_9$2, [ - _hoisted_10$1, - createVNode(unref(NSwitch), { - value: unref(settings).data.settings.flags.highres.antialiased, - "onUpdate:value": _cache[3] || (_cache[3] = ($event) => unref(settings).data.settings.flags.highres.antialiased = $event) - }, null, 8, ["value"]) - ]), - createBaseVNode("div", _hoisted_11$1, [ - _hoisted_12$1, - createVNode(unref(NSelect), { - value: unref(settings).data.settings.flags.highres.latent_scale_mode, - "onUpdate:value": _cache[4] || (_cache[4] = ($event) => unref(settings).data.settings.flags.highres.latent_scale_mode = $event), - size: "small", - style: { "flex-grow": "1" }, - filterable: "", - options: latentUpscalerOptions - }, null, 8, ["value"]) - ]) - ])), - createBaseVNode("div", _hoisted_13$1, [ - createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { - trigger: withCtx(() => [ - _hoisted_14$1 - ]), - default: withCtx(() => [ - createTextVNode(" Number of steps to take in the diffusion process. Higher values will result in more detailed images but will take longer to generate. There is also a point of diminishing returns around 100 steps. "), - _hoisted_15$1 - ]), - _: 1 - }), - createVNode(unref(NSlider), { - value: unref(settings).data.settings.flags.highres.steps, - "onUpdate:value": _cache[5] || (_cache[5] = ($event) => unref(settings).data.settings.flags.highres.steps = $event), - min: 5, - max: 300, - style: { "margin-right": "12px" } - }, null, 8, ["value"]), - createVNode(unref(NInputNumber), { - value: unref(settings).data.settings.flags.highres.steps, - "onUpdate:value": _cache[6] || (_cache[6] = ($event) => unref(settings).data.settings.flags.highres.steps = $event), - size: "small", - style: { "min-width": "96px", "width": "96px" } - }, null, 8, ["value"]) - ]), - createBaseVNode("div", _hoisted_16$1, [ - _hoisted_17, - createVNode(unref(NSlider), { - value: unref(settings).data.settings.flags.highres.scale, - "onUpdate:value": _cache[7] || (_cache[7] = ($event) => unref(settings).data.settings.flags.highres.scale = $event), - min: 1, - max: 8, - step: 0.1, - style: { "margin-right": "12px" } - }, null, 8, ["value"]), - createVNode(unref(NInputNumber), { - value: unref(settings).data.settings.flags.highres.scale, - "onUpdate:value": _cache[8] || (_cache[8] = ($event) => unref(settings).data.settings.flags.highres.scale = $event), - size: "small", - style: { "min-width": "96px", "width": "96px" }, - step: 0.1 - }, null, 8, ["value"]) - ]), - createBaseVNode("div", _hoisted_18, [ - _hoisted_19, - createVNode(unref(NSlider), { - value: unref(settings).data.settings.flags.highres.strength, - "onUpdate:value": _cache[9] || (_cache[9] = ($event) => unref(settings).data.settings.flags.highres.strength = $event), - min: 0.1, - max: 0.9, - step: 0.05, - style: { "margin-right": "12px" } - }, null, 8, ["value"]), - createVNode(unref(NInputNumber), { - value: unref(settings).data.settings.flags.highres.strength, - "onUpdate:value": _cache[10] || (_cache[10] = ($event) => unref(settings).data.settings.flags.highres.strength = $event), - size: "small", - style: { "min-width": "96px", "width": "96px" }, - min: 0.1, - max: 0.9, - step: 0.05 - }, null, 8, ["value"]) - ]) - ]), - _: 1 - })) : createCommentVNode("", true) - ]), - _: 1 - }); - }; - } -}); const _hoisted_1$3 = { class: "flex-container" }; const _hoisted_2$3 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Enabled", -1); const _hoisted_3$3 = { key: 0 }; @@ -210,16 +19,6 @@ const _hoisted_5$3 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label const _hoisted_6$3 = { class: "flex-container" }; const _hoisted_7$3 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Height", -1); const _sfc_main$4 = /* @__PURE__ */ defineComponent({ -======= -const _hoisted_1$2 = { class: "flex-container" }; -const _hoisted_2$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Enabled", -1); -const _hoisted_3$2 = { key: 0 }; -const _hoisted_4$2 = { class: "flex-container" }; -const _hoisted_5$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Width", -1); -const _hoisted_6$2 = { class: "flex-container" }; -const _hoisted_7$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Height", -1); -const _sfc_main$3 = /* @__PURE__ */ defineComponent({ ->>>>>>> origin/experimental __name: "ResizeFromDimensionsInput", setup(__props) { const settings = useSettings(); @@ -286,10 +85,82 @@ const _hoisted_2$2 = /* @__PURE__ */ createBaseVNode("div", { class: "slider-lab /* @__PURE__ */ createBaseVNode("p", null, "Enabled") ], -1); const _hoisted_3$2 = { class: "flex-container" }; -const _hoisted_4$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Refiner model", -1); -const _hoisted_5$2 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, " Generally, the refiner that came with your model is bound to generate the best results. ", -1); +const _hoisted_4$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Disperse", -1); +const _hoisted_5$2 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, " However, this comes at the cost of increased vram usage, generally in the range of 3-4x. ", -1); const _hoisted_6$2 = { class: "flex-container" }; -const _hoisted_7$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Steps", -1); +const _hoisted_7$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Unsafe resolutions", -1); +const _sfc_main$3 = /* @__PURE__ */ defineComponent({ + __name: "Scalecrafter", + setup(__props) { + const settings = useSettings(); + return (_ctx, _cache) => { + return openBlock(), createBlock(unref(NCard), { + title: "Scalecrafter", + class: "generate-extra-card" + }, { + default: withCtx(() => [ + createBaseVNode("div", _hoisted_1$2, [ + _hoisted_2$2, + createVNode(unref(NSwitch), { + value: unref(settings).defaultSettings.flags.scalecrafter.enabled, + "onUpdate:value": _cache[0] || (_cache[0] = ($event) => unref(settings).defaultSettings.flags.scalecrafter.enabled = $event) + }, null, 8, ["value"]) + ]), + unref(settings).defaultSettings.flags.scalecrafter.enabled ? (openBlock(), createBlock(unref(NSpace), { + key: 0, + vertical: "", + class: "left-container" + }, { + default: withCtx(() => [ + createBaseVNode("div", _hoisted_3$2, [ + createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { + trigger: withCtx(() => [ + _hoisted_4$2 + ]), + default: withCtx(() => [ + createTextVNode(" May generate more unique images. "), + _hoisted_5$2 + ]), + _: 1 + }), + createVNode(unref(NSwitch), { + value: unref(settings).defaultSettings.flags.scalecrafter.disperse, + "onUpdate:value": _cache[1] || (_cache[1] = ($event) => unref(settings).defaultSettings.flags.scalecrafter.disperse = $event) + }, null, 8, ["value"]) + ]), + createBaseVNode("div", _hoisted_6$2, [ + createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { + trigger: withCtx(() => [ + _hoisted_7$2 + ]), + default: withCtx(() => [ + createTextVNode(" Allow generating with unique resolutions that don't have configs ready for them, or clamp them (really, force them) to the closest resolution. ") + ]), + _: 1 + }), + createVNode(unref(NSwitch), { + value: unref(settings).defaultSettings.flags.scalecrafter.unsafe_resolutions, + "onUpdate:value": _cache[2] || (_cache[2] = ($event) => unref(settings).defaultSettings.flags.scalecrafter.unsafe_resolutions = $event) + }, null, 8, ["value"]) + ]) + ]), + _: 1 + })) : createCommentVNode("", true) + ]), + _: 1 + }); + }; + } +}); +const _hoisted_1$1 = { class: "flex-container" }; +const _hoisted_2$1 = /* @__PURE__ */ createBaseVNode("div", { class: "slider-label" }, [ + /* @__PURE__ */ createBaseVNode("p", null, "Enabled") +], -1); +const _hoisted_3$1 = { class: "flex-container" }; +const _hoisted_4$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Refiner model", -1); +const _hoisted_5$1 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, " Generally, the refiner that came with your model is bound to generate the best results. ", -1); +const _hoisted_6$1 = { class: "flex-container" }; +const _hoisted_7$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Steps", -1); const _hoisted_8$1 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "We recommend using 20-50 steps for most images.", -1); const _hoisted_9$1 = { class: "flex-container" }; const _hoisted_10 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Aesthetic Score", -1); @@ -299,7 +170,7 @@ const _hoisted_13 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" const _hoisted_14 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "Generally best to keep it around 3.", -1); const _hoisted_15 = { class: "flex-container" }; const _hoisted_16 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Strength", -1); -const _sfc_main$3 = /* @__PURE__ */ defineComponent({ +const _sfc_main$2 = /* @__PURE__ */ defineComponent({ __name: "XLRefiner", setup(__props) { const settings = useSettings(); @@ -321,8 +192,8 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ class: "generate-extra-card" }, { default: withCtx(() => [ - createBaseVNode("div", _hoisted_1$2, [ - _hoisted_2$2, + createBaseVNode("div", _hoisted_1$1, [ + _hoisted_2$1, createVNode(unref(NSwitch), { value: unref(global).state.txt2img.refiner, "onUpdate:value": _cache[0] || (_cache[0] = ($event) => unref(global).state.txt2img.refiner = $event) @@ -334,14 +205,14 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ class: "left-container" }, { default: withCtx(() => [ - createBaseVNode("div", _hoisted_3$2, [ + createBaseVNode("div", _hoisted_3$1, [ createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { trigger: withCtx(() => [ - _hoisted_4$2 + _hoisted_4$1 ]), default: withCtx(() => [ createTextVNode(" The SDXL-Refiner model to use for this step of diffusion. "), - _hoisted_5$2 + _hoisted_5$1 ]), _: 1 }), @@ -352,10 +223,10 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ value: unref(settings).data.settings.flags.refiner.model !== null ? unref(settings).data.settings.flags.refiner.model : "" }, null, 8, ["options", "value"]) ]), - createBaseVNode("div", _hoisted_6$2, [ + createBaseVNode("div", _hoisted_6$1, [ createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { trigger: withCtx(() => [ - _hoisted_7$2 + _hoisted_7$1 ]), default: withCtx(() => [ createTextVNode(" Number of steps to take in the diffusion process. Higher values will result in more detailed images but will take longer to generate. There is also a point of diminishing returns around 100 steps. "), @@ -464,78 +335,6 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ }; } }); -const _hoisted_1$1 = { class: "flex-container" }; -const _hoisted_2$1 = /* @__PURE__ */ createBaseVNode("div", { class: "slider-label" }, [ - /* @__PURE__ */ createBaseVNode("p", null, "Enabled") -], -1); -const _hoisted_3$1 = { class: "flex-container" }; -const _hoisted_4$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Disperse", -1); -const _hoisted_5$1 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, " However, this comes at the cost of increased vram usage, generally in the range of 3-4x. ", -1); -const _hoisted_6$1 = { class: "flex-container" }; -const _hoisted_7$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Unsafe resolutions", -1); -const _sfc_main$2 = /* @__PURE__ */ defineComponent({ - __name: "Scalecrafter", - setup(__props) { - const settings = useSettings(); - return (_ctx, _cache) => { - return openBlock(), createBlock(unref(NCard), { - title: "Scalecrafter", - class: "generate-extra-card" - }, { - default: withCtx(() => [ - createBaseVNode("div", _hoisted_1$1, [ - _hoisted_2$1, - createVNode(unref(NSwitch), { - value: unref(settings).defaultSettings.flags.scalecrafter.enabled, - "onUpdate:value": _cache[0] || (_cache[0] = ($event) => unref(settings).defaultSettings.flags.scalecrafter.enabled = $event) - }, null, 8, ["value"]) - ]), - unref(settings).defaultSettings.flags.scalecrafter.enabled ? (openBlock(), createBlock(unref(NSpace), { - key: 0, - vertical: "", - class: "left-container" - }, { - default: withCtx(() => [ - createBaseVNode("div", _hoisted_3$1, [ - createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { - trigger: withCtx(() => [ - _hoisted_4$1 - ]), - default: withCtx(() => [ - createTextVNode(" May generate more unique images. "), - _hoisted_5$1 - ]), - _: 1 - }), - createVNode(unref(NSwitch), { - value: unref(settings).defaultSettings.flags.scalecrafter.disperse, - "onUpdate:value": _cache[1] || (_cache[1] = ($event) => unref(settings).defaultSettings.flags.scalecrafter.disperse = $event) - }, null, 8, ["value"]) - ]), - createBaseVNode("div", _hoisted_6$1, [ - createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { - trigger: withCtx(() => [ - _hoisted_7$1 - ]), - default: withCtx(() => [ - createTextVNode(" Allow generating with unique resolutions that don't have configs ready for them, or clamp them (really, force them) to the closest resolution. ") - ]), - _: 1 - }), - createVNode(unref(NSwitch), { - value: unref(settings).defaultSettings.flags.scalecrafter.unsafe_resolutions, - "onUpdate:value": _cache[2] || (_cache[2] = ($event) => unref(settings).defaultSettings.flags.scalecrafter.unsafe_resolutions = $event) - }, null, 8, ["value"]) - ]) - ]), - _: 1 - })) : createCommentVNode("", true) - ]), - _: 1 - }); - }; - } -}); const _hoisted_1 = { class: "main-container" }; const _hoisted_2 = { class: "flex-container" }; const _hoisted_3 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Steps", -1); @@ -627,7 +426,6 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ strength: settings.data.settings.flags.refiner.strength } } : {}, -<<<<<<< HEAD ...settings.defaultSettings.flags.deepshrink.enabled ? { deepshrink: { early_out: settings.defaultSettings.flags.deepshrink.early_out, @@ -644,14 +442,14 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ unsafe_resolutions: settings.defaultSettings.flags.scalecrafter.unsafe_resolutions, base: (_b = settings.data.settings.model) == null ? void 0 : _b.type, disperse: settings.defaultSettings.flags.scalecrafter.disperse -======= + } + } : {}, ...settings.data.settings.txt2img.upscale.enabled ? { upscale: { upscale_factor: settings.data.settings.txt2img.upscale.upscale_factor, tile_size: settings.data.settings.txt2img.upscale.tile_size, tile_padding: settings.data.settings.txt2img.upscale.tile_padding, model: settings.data.settings.txt2img.upscale.model ->>>>>>> origin/experimental } } : {} } @@ -694,7 +492,6 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ }, { default: withCtx(() => [ createVNode(unref(NGi), null, { -<<<<<<< HEAD default: withCtx(() => [ createVNode(unref(NCard), { title: "Settings" }, { default: withCtx(() => [ @@ -704,8 +501,8 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ }, { default: withCtx(() => [ createVNode(unref(Prompt), { tab: "txt2img" }), - createVNode(unref(_sfc_main$6), { type: "txt2img" }), - createVNode(unref(_sfc_main$7), { + createVNode(unref(_sfc_main$5), { type: "txt2img" }), + createVNode(unref(_sfc_main$6), { "dimensions-object": unref(settings).data.settings.txt2img }, null, 8, ["dimensions-object"]), createBaseVNode("div", _hoisted_2, [ @@ -733,8 +530,8 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ style: { "min-width": "96px", "width": "96px" } }, null, 8, ["value"]) ]), + createVNode(unref(_sfc_main$7), { tab: "txt2img" }), createVNode(unref(_sfc_main$8), { tab: "txt2img" }), - createVNode(unref(_sfc_main$9), { tab: "txt2img" }), createBaseVNode("div", _hoisted_5, [ createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { trigger: withCtx(() => [ @@ -759,7 +556,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ style: { "min-width": "96px", "width": "96px" } }, null, 8, ["value"]) ]), - createVNode(unref(_sfc_main$a), { + createVNode(unref(_sfc_main$9), { "batch-size-object": unref(settings).data.settings.txt2img }, null, 8, ["batch-size-object"]), createBaseVNode("div", _hoisted_7, [ @@ -790,126 +587,23 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ key: 0, "dimensions-object": unref(settings).data.settings.txt2img }, null, 8, ["dimensions-object"])) : createCommentVNode("", true), - isSelectedModelSDXL.value ? (openBlock(), createBlock(unref(_sfc_main$3), { key: 1 })) : createCommentVNode("", true), - !isSelectedModelSDXL.value ? (openBlock(), createBlock(unref(_sfc_main$5), { key: 2 })) : createCommentVNode("", true), - createVNode(unref(_sfc_main$2)) + isSelectedModelSDXL.value ? (openBlock(), createBlock(unref(_sfc_main$2), { key: 1 })) : createCommentVNode("", true), + createVNode(unref(_sfc_main$3)), + createVNode(unref(_sfc_main$a), { tab: "txt2img" }), + createVNode(unref(_sfc_main$b), { tab: "txt2img" }) ]), -======= - default: withCtx(() => { - var _a; - return [ - createVNode(unref(NCard), { title: "Settings" }, { - default: withCtx(() => [ - createVNode(unref(NSpace), { - vertical: "", - class: "left-container" - }, { - default: withCtx(() => [ - createVNode(unref(Prompt), { tab: "txt2img" }), - createVNode(unref(_sfc_main$4), { type: "txt2img" }), - createVNode(unref(_sfc_main$5), { - "dimensions-object": unref(settings).data.settings.txt2img - }, null, 8, ["dimensions-object"]), - createBaseVNode("div", _hoisted_2, [ - createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { - trigger: withCtx(() => [ - _hoisted_3 - ]), - default: withCtx(() => [ - createTextVNode(" Number of steps to take in the diffusion process. Higher values will result in more detailed images but will take longer to generate. There is also a point of diminishing returns around 100 steps. "), - _hoisted_4 - ]), - _: 1 - }), - createVNode(unref(NSlider), { - value: unref(settings).data.settings.txt2img.steps, - "onUpdate:value": _cache[0] || (_cache[0] = ($event) => unref(settings).data.settings.txt2img.steps = $event), - min: 5, - max: 300, - style: { "margin-right": "12px" } - }, null, 8, ["value"]), - createVNode(unref(NInputNumber), { - value: unref(settings).data.settings.txt2img.steps, - "onUpdate:value": _cache[1] || (_cache[1] = ($event) => unref(settings).data.settings.txt2img.steps = $event), - size: "small", - style: { "min-width": "96px", "width": "96px" } - }, null, 8, ["value"]) - ]), - createVNode(unref(_sfc_main$6), { tab: "txt2img" }), - createVNode(unref(_sfc_main$7), { tab: "txt2img" }), - createBaseVNode("div", _hoisted_5, [ - createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { - trigger: withCtx(() => [ - _hoisted_6 - ]), - default: withCtx(() => [ - createTextVNode(" Number of images to generate after each other. ") - ]), - _: 1 - }), - createVNode(unref(NSlider), { - value: unref(settings).data.settings.txt2img.batch_count, - "onUpdate:value": _cache[2] || (_cache[2] = ($event) => unref(settings).data.settings.txt2img.batch_count = $event), - min: 1, - max: 9, - style: { "margin-right": "12px" } - }, null, 8, ["value"]), - createVNode(unref(NInputNumber), { - value: unref(settings).data.settings.txt2img.batch_count, - "onUpdate:value": _cache[3] || (_cache[3] = ($event) => unref(settings).data.settings.txt2img.batch_count = $event), - size: "small", - style: { "min-width": "96px", "width": "96px" } - }, null, 8, ["value"]) - ]), - createVNode(unref(_sfc_main$8), { - "batch-size-object": unref(settings).data.settings.txt2img - }, null, 8, ["batch-size-object"]), - createBaseVNode("div", _hoisted_7, [ - createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { - trigger: withCtx(() => [ - _hoisted_8 - ]), - default: withCtx(() => [ - createTextVNode(" Seed is a number that represents the starting canvas of your image. If you want to create the same image as your friend, you can use the same settings and seed to do so. "), - _hoisted_9 - ]), - _: 1 - }), - createVNode(unref(NInputNumber), { - value: unref(settings).data.settings.txt2img.seed, - "onUpdate:value": _cache[4] || (_cache[4] = ($event) => unref(settings).data.settings.txt2img.seed = $event), - size: "small", - style: { "flex-grow": "1" } - }, null, 8, ["value"]) - ]) - ]), - _: 1 - }) - ]), - _: 1 - }), - ((_a = unref(settings).data.settings.model) == null ? void 0 : _a.type) === "SDXL" ? (openBlock(), createBlock(unref(_sfc_main$3), { - key: 0, - "dimensions-object": unref(settings).data.settings.txt2img - }, null, 8, ["dimensions-object"])) : createCommentVNode("", true), - isSelectedModelSDXL.value ? (openBlock(), createBlock(unref(_sfc_main$2), { key: 1 })) : createCommentVNode("", true), - createVNode(unref(_sfc_main$9), { tab: "txt2img" }), - createVNode(unref(_sfc_main$a), { tab: "txt2img" }) - ]; - }), ->>>>>>> origin/experimental _: 1 }), createVNode(unref(NGi), null, { default: withCtx(() => [ - createVNode(unref(_sfc_main$b), { generate }), - createVNode(unref(_sfc_main$c), { + createVNode(unref(_sfc_main$c), { generate }), + createVNode(unref(_sfc_main$d), { "current-image": unref(global).state.txt2img.currentImage, images: unref(global).state.txt2img.images, data: unref(settings).data.settings.txt2img, onImageClicked: _cache[5] || (_cache[5] = ($event) => unref(global).state.txt2img.currentImage = $event) }, null, 8, ["current-image", "images", "data"]), - createVNode(unref(_sfc_main$d), { + createVNode(unref(_sfc_main$e), { style: { "margin-top": "12px" }, "gen-data": unref(global).state.txt2img.genData }, null, 8, ["gen-data"]) diff --git a/frontend/dist/assets/TrashBin.js b/frontend/dist/assets/TrashBin.js index 4a22a2783..e43631603 100644 --- a/frontend/dist/assets/TrashBin.js +++ b/frontend/dist/assets/TrashBin.js @@ -1,4 +1,4 @@ -import { O as replaceable, x as h, d as defineComponent, bN as isBrowser, T as useTheme, P as createInjectionKey, aa as c, Q as cB, bO as fadeInTransition, aS as fadeInScaleUpTransition, ac as cNotM, X as toRef, bP as imageLight, y as ref, ad as useLocale, J as watch, aD as on, aC as off, aB as onBeforeUnmount, R as inject, i as computed, S as useConfig, Y as useThemeClass, bQ as isMounted, bR as LazyTeleport, bt as withDirectives, bS as zindexable, aX as Transition, F as Fragment, aj as NBaseIcon, bu as vShow, bb as normalizeStyle, bT as kebabCase, l as NTooltip, aR as beforeNextFrameOnce, aW as createId, a3 as provide, bE as getCurrentInstance, ba as onMounted, af as watchEffect, o as openBlock, g as createElementBlock, b as createBaseVNode } from "./index.js"; +import { O as replaceable, x as h, d as defineComponent, bN as isBrowser, T as useTheme, P as createInjectionKey, aa as c, Q as cB, bO as fadeInTransition, aS as fadeInScaleUpTransition, ac as cNotM, X as toRef, bP as imageLight, y as ref, ad as useLocale, J as watch, aD as on, aC as off, aB as onBeforeUnmount, R as inject, l as computed, S as useConfig, Y as useThemeClass, bQ as isMounted, bR as LazyTeleport, bt as withDirectives, bS as zindexable, aX as Transition, F as Fragment, aj as NBaseIcon, bu as vShow, bb as normalizeStyle, bT as kebabCase, k as NTooltip, aR as beforeNextFrameOnce, aW as createId, a3 as provide, bE as getCurrentInstance, ba as onMounted, af as watchEffect, o as openBlock, g as createElementBlock, b as createBaseVNode } from "./index.js"; const RotateClockwiseIcon = replaceable("rotateClockwise", h( "svg", { viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, diff --git a/frontend/dist/assets/Upscale.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/Upscale.vue_vue_type_script_setup_true_lang.js index b31241fa6..656e35bfe 100644 --- a/frontend/dist/assets/Upscale.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/Upscale.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { R as inject, bE as getCurrentInstance, J as watch, aB as onBeforeUnmount, Q as cB, ab as cM, aa as c, P as createInjectionKey, d as defineComponent, S as useConfig, T as useTheme, y as ref, a3 as provide, x as h, bF as formLight, a2 as keysOf, i as computed, az as formatLength, aH as get, bG as commonVariables, at as cE, X as toRef, aW as createId, bH as formItemInjectionKey, ba as onMounted, ah as createKey, Y as useThemeClass, aX as Transition, av as resolveWrappedSlot, aM as warn, u as useSettings, a as useState, K as upscalerOptions, o as openBlock, c as createBlock, w as withCtx, b as createBaseVNode, e as createVNode, f as unref, j as NSpace, m as NSelect, g as createElementBlock, k as createTextVNode, l as NTooltip, h as createCommentVNode, N as NCard, F as Fragment, L as renderList, z as NButton, B as toDisplayString, bA as convertToTextString, bI as resolveDynamicComponent, bf as NModal, A as NIcon } from "./index.js"; +import { R as inject, bE as getCurrentInstance, J as watch, aB as onBeforeUnmount, Q as cB, ab as cM, aa as c, P as createInjectionKey, d as defineComponent, S as useConfig, T as useTheme, y as ref, a3 as provide, x as h, bF as formLight, a2 as keysOf, l as computed, az as formatLength, aH as get, bG as commonVariables, at as cE, X as toRef, aW as createId, bH as formItemInjectionKey, ba as onMounted, ah as createKey, Y as useThemeClass, aX as Transition, av as resolveWrappedSlot, aM as warn, u as useSettings, a as useState, K as upscalerOptions, o as openBlock, c as createBlock, w as withCtx, b as createBaseVNode, e as createVNode, f as unref, i as NSpace, m as NSelect, g as createElementBlock, j as createTextVNode, k as NTooltip, h as createCommentVNode, N as NCard, F as Fragment, L as renderList, z as NButton, B as toDisplayString, bA as convertToTextString, bI as resolveDynamicComponent, bf as NModal, A as NIcon } from "./index.js"; import { N as NSwitch } from "./Switch.js"; import { N as NSlider } from "./Slider.js"; import { N as NInputNumber } from "./InputNumber.js"; diff --git a/frontend/dist/assets/clock.js b/frontend/dist/assets/clock.js index 9e95a27eb..92f4884f5 100644 --- a/frontend/dist/assets/clock.js +++ b/frontend/dist/assets/clock.js @@ -5,18 +5,11 @@ var __publicField = (obj, key, value) => { return value; }; import { N as NDescriptionsItem, a as NDescriptions } from "./DescriptionsItem.js"; -<<<<<<< HEAD -import { d as defineComponent, o as openBlock, j as createElementBlock, f as createBaseVNode, e as createBlock, w as withCtx, g as createVNode, h as unref, k as createTextVNode, C as toDisplayString, n as NCard, m as createCommentVNode, u as useSettings, l as NTooltip, i as NSelect, F as Fragment, a as useState, c as computed, G as spaceRegex, B as NIcon, H as promptHandleKeyUp, I as promptHandleKeyDown, J as NInput, _ as _export_sfc, K as watch, z as ref, t as serverUrl } from "./index.js"; +import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, c as createBlock, w as withCtx, e as createVNode, f as unref, j as createTextVNode, B as toDisplayString, N as NCard, h as createCommentVNode, u as useSettings, k as NTooltip, l as computed, m as NSelect, F as Fragment, a as useState, E as spaceRegex, A as NIcon, G as promptHandleKeyUp, H as promptHandleKeyDown, I as NInput, _ as _export_sfc, J as watch, y as ref, s as serverUrl } from "./index.js"; import { N as NSlider } from "./Slider.js"; import { N as NInputNumber } from "./InputNumber.js"; -======= -import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, c as createBlock, w as withCtx, e as createVNode, f as unref, k as createTextVNode, B as toDisplayString, N as NCard, h as createCommentVNode, u as useSettings, l as NTooltip, i as computed, F as Fragment, a as useState, E as spaceRegex, A as NIcon, m as NSelect, G as promptHandleKeyUp, H as promptHandleKeyDown, I as NInput, _ as _export_sfc, J as watch, y as ref, s as serverUrl } from "./index.js"; -import { N as NSlider } from "./Slider.js"; -import { N as NInputNumber } from "./InputNumber.js"; -import { N as NForm, c as NFormItem } from "./Upscale.vue_vue_type_script_setup_true_lang.js"; ->>>>>>> origin/experimental import { N as NSwitch } from "./Switch.js"; -import { N as NForm, a as NFormItem } from "./SamplerPicker.vue_vue_type_script_setup_true_lang.js"; +import { N as NForm, c as NFormItem } from "./Upscale.vue_vue_type_script_setup_true_lang.js"; const _hoisted_1$4 = { xmlns: "http://www.w3.org/2000/svg", "xmlns:xlink": "http://www.w3.org/1999/xlink", @@ -229,7 +222,6 @@ const _hoisted_7 = { class: "flex-container" }; const _hoisted_8 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Height", -1); -<<<<<<< HEAD const _hoisted_9 = { key: 4 }; const _hoisted_10 = { class: "flex-container" }; const _hoisted_11 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Enable Deepshrink", -1); @@ -251,10 +243,7 @@ const _hoisted_26 = { class: "flex-container" }; const _hoisted_27 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Latent scaler", -1); const _hoisted_28 = { class: "flex-container" }; const _hoisted_29 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Early out", -1); -const _sfc_main$3 = /* @__PURE__ */ defineComponent({ -======= const _sfc_main$2 = /* @__PURE__ */ defineComponent({ ->>>>>>> origin/experimental __name: "DimensionsInput", props: { dimensionsObject: { diff --git a/frontend/dist/assets/index.css b/frontend/dist/assets/index.css index 6a493c37a..3497ad1c6 100644 --- a/frontend/dist/assets/index.css +++ b/frontend/dist/assets/index.css @@ -98,49 +98,26 @@ justify-content: center; } -.image-container img[data-v-bfd46a0a] { +.image-container img[data-v-8c5af50f] { width: 100%; height: 100%; object-fit: contain; overflow: hidden; } -.image-container[data-v-bfd46a0a] { +.image-container[data-v-8c5af50f] { height: 70vh; width: 100%; display: flex; justify-content: center; } -<<<<<<< HEAD -.image-container img[data-v-4fae0a93] { - width: 100%; - height: 100%; - object-fit: contain; - overflow: hidden; -} -.image-container[data-v-4fae0a93] { - height: 70vh; - width: 100%; - display: flex; - justify-content: center; -} - -.hidden-input[data-v-0d0f8c9e] { +.hidden-input[data-v-124be5cd] { display: none; } -.utility-button[data-v-0d0f8c9e] { +.utility-button[data-v-124be5cd] { margin-right: 8px; } -.file-upload[data-v-0d0f8c9e] { -======= -.hidden-input[data-v-1193df1f] { - display: none; -} -.utility-button[data-v-1193df1f] { - margin-right: 8px; -} -.file-upload[data-v-1193df1f] { ->>>>>>> origin/experimental +.file-upload[data-v-124be5cd] { appearance: none; background-color: transparent; border: 1px solid #63e2b7; @@ -160,37 +137,21 @@ vertical-align: middle; white-space: nowrap; } -<<<<<<< HEAD -.file-upload[data-v-0d0f8c9e]:focus:not(:focus-visible):not(.focus-visible) { - box-shadow: none; - outline: none; -} -.file-upload[data-v-0d0f8c9e]:focus { - box-shadow: rgba(46, 164, 79, 0.4) 0 0 0 3px; - outline: none; -} -.file-upload[data-v-0d0f8c9e]:disabled { -======= -.file-upload[data-v-1193df1f]:focus:not(:focus-visible):not(.focus-visible) { +.file-upload[data-v-124be5cd]:focus:not(:focus-visible):not(.focus-visible) { box-shadow: none; outline: none; } -.file-upload[data-v-1193df1f]:focus { +.file-upload[data-v-124be5cd]:focus { box-shadow: rgba(46, 164, 79, 0.4) 0 0 0 3px; outline: none; } -.file-upload[data-v-1193df1f]:disabled { ->>>>>>> origin/experimental +.file-upload[data-v-124be5cd]:disabled { background-color: #94d3a2; border-color: rgba(27, 31, 35, 0.1); color: rgba(255, 255, 255, 0.8); cursor: default; } -<<<<<<< HEAD -.image-container[data-v-0d0f8c9e] { -======= -.image-container[data-v-1193df1f] { ->>>>>>> origin/experimental +.image-container[data-v-124be5cd] { width: 100%; display: flex; justify-content: center; diff --git a/frontend/dist/assets/index.js b/frontend/dist/assets/index.js index d0ed4212b..a3f71c14c 100644 --- a/frontend/dist/assets/index.js +++ b/frontend/dist/assets/index.js @@ -43184,16 +43184,9 @@ const TopBar_vue_vue_type_style_index_0_scoped_91ace41f_lang = ""; const TopBar = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-91ace41f"]]); const Prompt_vue_vue_type_style_index_0_lang = ""; const Prompt_vue_vue_type_style_index_1_scoped_780680bc_lang = ""; -<<<<<<< HEAD -const Upscale_vue_vue_type_style_index_0_scoped_5358ed01_lang = ""; -const ControlNet_vue_vue_type_style_index_0_scoped_95a354be_lang = ""; -const Img2Img_vue_vue_type_style_index_0_scoped_4fae0a93_lang = ""; -const Inpainting_vue_vue_type_style_index_0_scoped_0d0f8c9e_lang = ""; -======= const ControlNet_vue_vue_type_style_index_0_scoped_97c56df6_lang = ""; -const Img2Img_vue_vue_type_style_index_0_scoped_bfd46a0a_lang = ""; -const Inpainting_vue_vue_type_style_index_0_scoped_1193df1f_lang = ""; ->>>>>>> origin/experimental +const Img2Img_vue_vue_type_style_index_0_scoped_8c5af50f_lang = ""; +const Inpainting_vue_vue_type_style_index_0_scoped_124be5cd_lang = ""; const CivitAIDownload_vue_vue_type_style_index_0_scoped_241a4664_lang = ""; const HuggingfaceDownload_vue_vue_type_style_index_0_scoped_b405f046_lang = ""; const _hoisted_1$1 = { style: { "margin": "16px 0" } }; @@ -43492,11 +43485,7 @@ const router = createRouter({ { path: "/img2img", name: "img2img", -<<<<<<< HEAD - component: () => __vitePreload(() => import("./Image2ImageView.js"), true ? ["assets/Image2ImageView.js","assets/clock.js","assets/DescriptionsItem.js","assets/Slider.js","assets/InputNumber.js","assets/Switch.js","assets/SamplerPicker.vue_vue_type_script_setup_true_lang.js","assets/Settings.js","assets/GenerateSection.vue_vue_type_script_setup_true_lang.js","assets/ImageOutput.vue_vue_type_script_setup_true_lang.js","assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js","assets/TrashBin.js","assets/ImageUpload.js","assets/CloudUpload.js","assets/v4.js"] : void 0) -======= - component: () => __vitePreload(() => import("./Image2ImageView.js"), true ? ["assets/Image2ImageView.js","assets/clock.js","assets/DescriptionsItem.js","assets/Slider.js","assets/InputNumber.js","assets/Upscale.vue_vue_type_script_setup_true_lang.js","assets/Switch.js","assets/Settings.js","assets/GenerateSection.vue_vue_type_script_setup_true_lang.js","assets/ImageOutput.vue_vue_type_script_setup_true_lang.js","assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js","assets/TrashBin.js","assets/ImageUpload.js","assets/CloudUpload.js","assets/v4.js"] : void 0) ->>>>>>> origin/experimental + component: () => __vitePreload(() => import("./Image2ImageView.js"), true ? ["assets/Image2ImageView.js","assets/clock.js","assets/DescriptionsItem.js","assets/Slider.js","assets/InputNumber.js","assets/Switch.js","assets/Upscale.vue_vue_type_script_setup_true_lang.js","assets/Settings.js","assets/GenerateSection.vue_vue_type_script_setup_true_lang.js","assets/ImageOutput.vue_vue_type_script_setup_true_lang.js","assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js","assets/TrashBin.js","assets/ImageUpload.js","assets/CloudUpload.js","assets/v4.js"] : void 0) }, { path: "/imageProcessing", @@ -43732,10 +43721,10 @@ export { unref as f, createElementBlock as g, createCommentVNode as h, - computed as i, - NSpace as j, - createTextVNode as k, - NTooltip as l, + NSpace as i, + createTextVNode as j, + NTooltip as k, + computed as l, NSelect as m, useMessage as n, openBlock as o, From c5152cfabcf8d1f07e5a60b3aedfda47c12b2b83 Mon Sep 17 00:00:00 2001 From: Stax124 Date: Sun, 10 Dec 2023 21:54:43 +0100 Subject: [PATCH 101/143] WIP: Frontend for deepshrink and scalecrafter --- core/config/default_settings.py | 4 +- frontend/dist/assets/AccelerateView.js | 2 +- frontend/dist/assets/DescriptionsItem.js | 2 +- frontend/dist/assets/ExtraView.js | 2 +- ...ion.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/Image2ImageView.js | 42 +-- frontend/dist/assets/ImageBrowserView.js | 2 +- ...put.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/ImageProcessingView.js | 2 +- frontend/dist/assets/ImageUpload.js | 2 +- frontend/dist/assets/InputNumber.js | 2 +- ...pup.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/ModelsView.js | 2 +- ...tTo.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/Settings.js | 2 +- frontend/dist/assets/SettingsView.js | 2 +- frontend/dist/assets/Slider.js | 2 +- frontend/dist/assets/Switch.js | 2 +- frontend/dist/assets/TaggerView.js | 2 +- frontend/dist/assets/TestView.js | 2 +- frontend/dist/assets/TextToImageView.js | 277 +++++++++++++++--- frontend/dist/assets/TrashBin.js | 2 +- ...ale.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/clock.js | 146 +-------- frontend/dist/assets/index.css | 27 +- frontend/dist/assets/index.js | 70 +++-- frontend/src/assets/2img.css | 9 +- .../src/components/generate/DeepShrink.vue | 140 +++++++++ .../components/generate/DimensionsInput.vue | 109 +------ .../src/components/generate/Scalecrafter.vue | 37 ++- frontend/src/components/generate/index.ts | 3 +- frontend/src/components/inference/Img2Img.vue | 16 +- .../src/components/inference/Inpainting.vue | 19 +- frontend/src/components/inference/Txt2Img.vue | 32 +- frontend/src/settings.ts | 92 ++++-- 35 files changed, 620 insertions(+), 443 deletions(-) create mode 100644 frontend/src/components/generate/DeepShrink.vue diff --git a/core/config/default_settings.py b/core/config/default_settings.py index 3e601ca1b..1c33da11b 100644 --- a/core/config/default_settings.py +++ b/core/config/default_settings.py @@ -4,7 +4,7 @@ from diffusers.schedulers.scheduling_utils import KarrasDiffusionSchedulers -from core.flags import HighResFixFlag, UpscaleFlag +from core.flags import DeepshrinkFlag, HighResFixFlag, ScalecrafterFlag, UpscaleFlag from core.types import SigmaScheduler @@ -37,6 +37,8 @@ class BaseDiffusionMixin: # Flags highres: HighResFixFlag = field(default_factory=HighResFixFlag) upscale: UpscaleFlag = field(default_factory=UpscaleFlag) + deepshrink: DeepshrinkFlag = field(default_factory=DeepshrinkFlag) + scalecrafter: ScalecrafterFlag = field(default_factory=ScalecrafterFlag) @dataclass diff --git a/frontend/dist/assets/AccelerateView.js b/frontend/dist/assets/AccelerateView.js index 0c1c16501..f75c598cc 100644 --- a/frontend/dist/assets/AccelerateView.js +++ b/frontend/dist/assets/AccelerateView.js @@ -1,4 +1,4 @@ -import { Q as cB, ab as cM, aa as c, at as cE, aT as iconSwitchTransition, ac as cNotM, d as defineComponent, S as useConfig, ag as useRtl, T as useTheme, a3 as provide, x as h, aw as flatten, ax as getSlot, P as createInjectionKey, bi as stepsLight, R as inject, a_ as throwError, l as computed, ah as createKey, Y as useThemeClass, a1 as call, av as resolveWrappedSlot, ai as resolveSlot, aI as NIconSwitchTransition, aj as NBaseIcon, bj as FinishedIcon, bk as ErrorIcon, n as useMessage, a as useState, y as ref, o as openBlock, g as createElementBlock, e as createVNode, w as withCtx, f as unref, i as NSpace, N as NCard, b as createBaseVNode, m as NSelect, z as NButton, j as createTextVNode, bf as NModal, s as serverUrl, u as useSettings, c as createBlock, C as NTabPane, D as NTabs } from "./index.js"; +import { Q as cB, ab as cM, aa as c, at as cE, aT as iconSwitchTransition, ac as cNotM, d as defineComponent, S as useConfig, ag as useRtl, T as useTheme, a3 as provide, x as h, aw as flatten, ax as getSlot, P as createInjectionKey, bi as stepsLight, R as inject, a_ as throwError, c as computed, ah as createKey, Y as useThemeClass, a1 as call, av as resolveWrappedSlot, ai as resolveSlot, aI as NIconSwitchTransition, aj as NBaseIcon, bj as FinishedIcon, bk as ErrorIcon, n as useMessage, j as useState, y as ref, o as openBlock, g as createElementBlock, e as createVNode, w as withCtx, f as unref, k as NSpace, N as NCard, b as createBaseVNode, h as NSelect, z as NButton, l as createTextVNode, bf as NModal, s as serverUrl, u as useSettings, a as createBlock, C as NTabPane, D as NTabs } from "./index.js"; import { N as NSlider } from "./Slider.js"; import { N as NInputNumber } from "./InputNumber.js"; import { N as NSwitch } from "./Switch.js"; diff --git a/frontend/dist/assets/DescriptionsItem.js b/frontend/dist/assets/DescriptionsItem.js index 9aabff443..640125c63 100644 --- a/frontend/dist/assets/DescriptionsItem.js +++ b/frontend/dist/assets/DescriptionsItem.js @@ -1,4 +1,4 @@ -import { aa as c, Q as cB, ac as cNotM, ab as cM, at as cE, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, l as computed, ah as createKey, Y as useThemeClass, bU as useCompitable, aw as flatten, x as h, aQ as repeat, ax as getSlot, bV as descriptionsLight } from "./index.js"; +import { aa as c, Q as cB, ac as cNotM, ab as cM, at as cE, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, c as computed, ah as createKey, Y as useThemeClass, bU as useCompitable, aw as flatten, x as h, aQ as repeat, ax as getSlot, bV as descriptionsLight } from "./index.js"; function getVNodeChildren(vNode, slotName = "default", fallback = []) { const { children } = vNode; if (children !== null && typeof children === "object" && !Array.isArray(children)) { diff --git a/frontend/dist/assets/ExtraView.js b/frontend/dist/assets/ExtraView.js index 1c56eef7b..34e03be17 100644 --- a/frontend/dist/assets/ExtraView.js +++ b/frontend/dist/assets/ExtraView.js @@ -1,4 +1,4 @@ -import { _ as _export_sfc, d as defineComponent, a as useState, o as openBlock, c as createBlock, w as withCtx, f as unref, e as createVNode, C as NTabPane, D as NTabs } from "./index.js"; +import { _ as _export_sfc, d as defineComponent, j as useState, o as openBlock, a as createBlock, w as withCtx, f as unref, e as createVNode, C as NTabPane, D as NTabs } from "./index.js"; const _sfc_main$2 = {}; function _sfc_render$1(_ctx, _cache) { return "Autofill manager"; diff --git a/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js index ea4cd77fb..2bfa8ef52 100644 --- a/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, a as useState, u as useSettings, y as ref, ba as onMounted, p as onUnmounted, s as serverUrl, c as createBlock, w as withCtx, e as createVNode, f as unref, q as NGi, z as NButton, A as NIcon, j as createTextVNode, r as NGrid, bW as NAlert, h as createCommentVNode, N as NCard } from "./index.js"; +import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, j as useState, u as useSettings, y as ref, ba as onMounted, p as onUnmounted, s as serverUrl, a as createBlock, w as withCtx, e as createVNode, f as unref, q as NGi, z as NButton, A as NIcon, l as createTextVNode, r as NGrid, bW as NAlert, i as createCommentVNode, N as NCard } from "./index.js"; const _hoisted_1$1 = { xmlns: "http://www.w3.org/2000/svg", "xmlns:xlink": "http://www.w3.org/1999/xlink", diff --git a/frontend/dist/assets/Image2ImageView.js b/frontend/dist/assets/Image2ImageView.js index 6fb16f486..19023db00 100644 --- a/frontend/dist/assets/Image2ImageView.js +++ b/frontend/dist/assets/Image2ImageView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, a as useState, u as useSettings, n as useMessage, l as computed, p as onUnmounted, e as createVNode, w as withCtx, f as unref, q as NGi, N as NCard, i as NSpace, k as NTooltip, j as createTextVNode, m as NSelect, c as createBlock, h as createCommentVNode, r as NGrid, s as serverUrl, t as pushScopeId, v as popScopeId, _ as _export_sfc, x as h, y as ref, z as NButton, A as NIcon, B as toDisplayString, C as NTabPane, D as NTabs } from "./index.js"; +import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, j as useState, u as useSettings, n as useMessage, c as computed, p as onUnmounted, e as createVNode, w as withCtx, f as unref, q as NGi, N as NCard, k as NSpace, m as NTooltip, l as createTextVNode, h as NSelect, a as createBlock, i as createCommentVNode, r as NGrid, s as serverUrl, t as pushScopeId, v as popScopeId, _ as _export_sfc, x as h, y as ref, z as NButton, A as NIcon, B as toDisplayString, C as NTabPane, D as NTabs } from "./index.js"; import { B as BurnerClock, P as Prompt, _ as _sfc_main$5, a as _sfc_main$6, b as _sfc_main$7, c as _sfc_main$8, d as _sfc_main$d } from "./clock.js"; import { _ as _sfc_main$b } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; import { _ as _sfc_main$c } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; @@ -529,7 +529,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ } }); const ControlNet = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-97c56df6"]]); -const _withScopeId$1 = (n) => (pushScopeId("data-v-8c5af50f"), n = n(), popScopeId(), n); +const _withScopeId$1 = (n) => (pushScopeId("data-v-0af5331f"), n = n(), popScopeId(), n); const _hoisted_1$1 = { style: { "margin": "0 12px" } }; const _hoisted_2$1 = { class: "flex-container" }; const _hoisted_3$1 = /* @__PURE__ */ _withScopeId$1(() => /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Steps", -1)); @@ -597,16 +597,16 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ prompt_to_prompt: settings.data.settings.api.prompt_to_prompt } }, - ...settings.defaultSettings.flags.deepshrink.enabled ? { + ...settings.data.settings.img2img.deepshrink.enabled ? { flags: { deepshrink: { - early_out: settings.defaultSettings.flags.deepshrink.early_out, - depth_1: settings.defaultSettings.flags.deepshrink.depth_1, - stop_at_1: settings.defaultSettings.flags.deepshrink.stop_at_1, - depth_2: settings.defaultSettings.flags.deepshrink.depth_2, - stop_at_2: settings.defaultSettings.flags.deepshrink.stop_at_2, - scaler: settings.defaultSettings.flags.deepshrink.scaler, - base_scale: settings.defaultSettings.flags.deepshrink.base_scale + early_out: settings.data.settings.img2img.deepshrink.early_out, + depth_1: settings.data.settings.img2img.deepshrink.depth_1, + stop_at_1: settings.data.settings.img2img.deepshrink.stop_at_1, + depth_2: settings.data.settings.img2img.deepshrink.depth_2, + stop_at_2: settings.data.settings.img2img.deepshrink.stop_at_2, + scaler: settings.data.settings.img2img.deepshrink.scaler, + base_scale: settings.data.settings.img2img.deepshrink.base_scale } } } : {}, @@ -836,7 +836,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ }; } }); -const ImageToImage = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-8c5af50f"]]); +const ImageToImage = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-0af5331f"]]); var VueDrawingCanvas = /* @__PURE__ */ defineComponent({ name: "VueDrawingCanvas", props: { @@ -1412,7 +1412,7 @@ var VueDrawingCanvas = /* @__PURE__ */ defineComponent({ }); } }); -const _withScopeId = (n) => (pushScopeId("data-v-124be5cd"), n = n(), popScopeId(), n); +const _withScopeId = (n) => (pushScopeId("data-v-58a6e728"), n = n(), popScopeId(), n); const _hoisted_1 = { style: { "margin": "0 12px" } }; const _hoisted_2 = { style: { "display": "inline-flex", "align-items": "center" } }; const _hoisted_3 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createBaseVNode("svg", { @@ -1496,16 +1496,16 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ prompt_to_prompt: settings.data.settings.api.prompt_to_prompt } }, - ...settings.defaultSettings.flags.deepshrink.enabled ? { + ...settings.data.settings.inpainting.deepshrink.enabled ? { flags: { deepshrink: { - early_out: settings.defaultSettings.flags.deepshrink.early_out, - depth_1: settings.defaultSettings.flags.deepshrink.depth_1, - stop_at_1: settings.defaultSettings.flags.deepshrink.stop_at_1, - depth_2: settings.defaultSettings.flags.deepshrink.depth_2, - stop_at_2: settings.defaultSettings.flags.deepshrink.stop_at_2, - scaler: settings.defaultSettings.flags.deepshrink.scaler, - base_scale: settings.defaultSettings.flags.deepshrink.base_scale + early_out: settings.data.settings.inpainting.deepshrink.early_out, + depth_1: settings.data.settings.inpainting.deepshrink.depth_1, + stop_at_1: settings.data.settings.inpainting.deepshrink.stop_at_1, + depth_2: settings.data.settings.inpainting.deepshrink.depth_2, + stop_at_2: settings.data.settings.inpainting.deepshrink.stop_at_2, + scaler: settings.data.settings.inpainting.deepshrink.scaler, + base_scale: settings.data.settings.inpainting.deepshrink.base_scale } } } : {}, @@ -1968,7 +1968,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ }; } }); -const Inpainting = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-124be5cd"]]); +const Inpainting = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-58a6e728"]]); const _sfc_main = /* @__PURE__ */ defineComponent({ __name: "Image2ImageView", setup(__props) { diff --git a/frontend/dist/assets/ImageBrowserView.js b/frontend/dist/assets/ImageBrowserView.js index 852d74630..f64024d37 100644 --- a/frontend/dist/assets/ImageBrowserView.js +++ b/frontend/dist/assets/ImageBrowserView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, b7 as useCssVars, a as useState, u as useSettings, R as inject, y as ref, l as computed, bK as urlFromPath, b9 as reactive, ba as onMounted, p as onUnmounted, e as createVNode, f as unref, w as withCtx, F as Fragment, L as renderList, b8 as themeOverridesKey, s as serverUrl, I as NInput, A as NIcon, bf as NModal, r as NGrid, q as NGi, z as NButton, j as createTextVNode, M as NScrollbar, c as createBlock, bA as convertToTextString, B as toDisplayString, h as createCommentVNode, bL as diffusersSchedulerTuple, _ as _export_sfc } from "./index.js"; +import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, b7 as useCssVars, j as useState, u as useSettings, R as inject, y as ref, c as computed, bK as urlFromPath, b9 as reactive, ba as onMounted, p as onUnmounted, e as createVNode, f as unref, w as withCtx, F as Fragment, L as renderList, b8 as themeOverridesKey, s as serverUrl, I as NInput, A as NIcon, bf as NModal, r as NGrid, q as NGi, z as NButton, l as createTextVNode, M as NScrollbar, a as createBlock, bA as convertToTextString, B as toDisplayString, i as createCommentVNode, bL as diffusersSchedulerTuple, _ as _export_sfc } from "./index.js"; import { D as Download, _ as _sfc_main$1 } from "./SendOutputTo.vue_vue_type_script_setup_true_lang.js"; import { N as NImage, T as TrashBin } from "./TrashBin.js"; import { N as NSlider } from "./Slider.js"; diff --git a/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js index d4468dc5e..55e8d61c2 100644 --- a/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { d as defineComponent, y as ref, a as useState, o as openBlock, c as createBlock, w as withCtx, f as unref, q as NGi, e as createVNode, A as NIcon, j as createTextVNode, z as NButton, h as createCommentVNode, r as NGrid, l as computed, b as createBaseVNode, g as createElementBlock, F as Fragment, L as renderList, M as NScrollbar, N as NCard } from "./index.js"; +import { d as defineComponent, y as ref, j as useState, o as openBlock, a as createBlock, w as withCtx, f as unref, q as NGi, e as createVNode, A as NIcon, l as createTextVNode, z as NButton, i as createCommentVNode, r as NGrid, c as computed, b as createBaseVNode, g as createElementBlock, F as Fragment, L as renderList, M as NScrollbar, N as NCard } from "./index.js"; import { D as Download, _ as _sfc_main$2 } from "./SendOutputTo.vue_vue_type_script_setup_true_lang.js"; import { T as TrashBin, N as NImage } from "./TrashBin.js"; const _sfc_main$1 = /* @__PURE__ */ defineComponent({ diff --git a/frontend/dist/assets/ImageProcessingView.js b/frontend/dist/assets/ImageProcessingView.js index a38cf670b..9792ea445 100644 --- a/frontend/dist/assets/ImageProcessingView.js +++ b/frontend/dist/assets/ImageProcessingView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, a as useState, u as useSettings, n as useMessage, l as computed, K as upscalerOptions, o as openBlock, g as createElementBlock, e as createVNode, w as withCtx, f as unref, q as NGi, N as NCard, i as NSpace, b as createBaseVNode, m as NSelect, k as NTooltip, j as createTextVNode, r as NGrid, s as serverUrl, c as createBlock, C as NTabPane, D as NTabs } from "./index.js"; +import { d as defineComponent, j as useState, u as useSettings, n as useMessage, c as computed, K as upscalerOptions, o as openBlock, g as createElementBlock, e as createVNode, w as withCtx, f as unref, q as NGi, N as NCard, k as NSpace, b as createBaseVNode, h as NSelect, m as NTooltip, l as createTextVNode, r as NGrid, s as serverUrl, a as createBlock, C as NTabPane, D as NTabs } from "./index.js"; import { _ as _sfc_main$2 } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; import { _ as _sfc_main$3 } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; import { I as ImageUpload } from "./ImageUpload.js"; diff --git a/frontend/dist/assets/ImageUpload.js b/frontend/dist/assets/ImageUpload.js index f8f5e390a..4f71b434f 100644 --- a/frontend/dist/assets/ImageUpload.js +++ b/frontend/dist/assets/ImageUpload.js @@ -1,4 +1,4 @@ -import { d as defineComponent, y as ref, l as computed, ba as onMounted, o as openBlock, c as createBlock, w as withCtx, b as createBaseVNode, bd as withModifiers, g as createElementBlock, e as createVNode, f as unref, A as NIcon, B as toDisplayString, N as NCard, t as pushScopeId, v as popScopeId, _ as _export_sfc } from "./index.js"; +import { d as defineComponent, y as ref, c as computed, ba as onMounted, o as openBlock, a as createBlock, w as withCtx, b as createBaseVNode, bd as withModifiers, g as createElementBlock, e as createVNode, f as unref, A as NIcon, B as toDisplayString, N as NCard, t as pushScopeId, v as popScopeId, _ as _export_sfc } from "./index.js"; import { C as CloudUpload } from "./CloudUpload.js"; const _withScopeId = (n) => (pushScopeId("data-v-9ed1514f"), n = n(), popScopeId(), n); const _hoisted_1 = { class: "image-container" }; diff --git a/frontend/dist/assets/InputNumber.js b/frontend/dist/assets/InputNumber.js index be417d0e4..70465022a 100644 --- a/frontend/dist/assets/InputNumber.js +++ b/frontend/dist/assets/InputNumber.js @@ -1,4 +1,4 @@ -import { d as defineComponent, x as h, aa as c, Q as cB, S as useConfig, T as useTheme, ad as useLocale, ar as useFormItem, y as ref, X as toRef, ae as useMergedState, as as useMemo, J as watch, ag as useRtl, l as computed, bX as rgba, I as NInput, av as resolveWrappedSlot, bY as inputNumberLight, aD as on, ai as resolveSlot, aj as NBaseIcon, bZ as XButton, a$ as AddIcon, a1 as call, W as nextTick } from "./index.js"; +import { d as defineComponent, x as h, aa as c, Q as cB, S as useConfig, T as useTheme, ad as useLocale, ar as useFormItem, y as ref, X as toRef, ae as useMergedState, as as useMemo, J as watch, ag as useRtl, c as computed, bX as rgba, I as NInput, av as resolveWrappedSlot, bY as inputNumberLight, aD as on, ai as resolveSlot, aj as NBaseIcon, bZ as XButton, a$ as AddIcon, a1 as call, W as nextTick } from "./index.js"; const RemoveIcon = defineComponent({ name: "Remove", render() { diff --git a/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js index 17e8282ef..22abeae2a 100644 --- a/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { bl as upperFirst, bm as toString, bn as createCompounder, bo as cloneVNode, a3 as provide, P as createInjectionKey, R as inject, a_ as throwError, d as defineComponent, S as useConfig, y as ref, bp as onBeforeUpdate, x as h, bq as indexMap, l as computed, ba as onMounted, aB as onBeforeUnmount, Q as cB, at as cE, aa as c, ab as cM, a4 as keep, ae as useMergedState, X as toRef, af as watchEffect, br as onUpdated, J as watch, W as nextTick, T as useTheme, Y as useThemeClass, aw as flatten, aL as VResizeObserver, bs as resolveSlotWithProps, bt as withDirectives, bu as vShow, aX as Transition, bb as normalizeStyle, bv as getPreciseEventTarget, aD as on, aC as off, bw as carouselLight, ac as cNotM, ar as useFormItem, ah as createKey, bx as color2Class, L as renderList, aj as NBaseIcon, by as rateLight, a1 as call, n as useMessage, u as useSettings, b9 as reactive, o as openBlock, c as createBlock, w as withCtx, e as createVNode, g as createElementBlock, f as unref, C as NTabPane, r as NGrid, q as NGi, F as Fragment, b as createBaseVNode, N as NCard, j as createTextVNode, B as toDisplayString, bz as NTag, m as NSelect, z as NButton, D as NTabs, bf as NModal, s as serverUrl } from "./index.js"; +import { bl as upperFirst, bm as toString, bn as createCompounder, bo as cloneVNode, a3 as provide, P as createInjectionKey, R as inject, a_ as throwError, d as defineComponent, S as useConfig, y as ref, bp as onBeforeUpdate, x as h, bq as indexMap, c as computed, ba as onMounted, aB as onBeforeUnmount, Q as cB, at as cE, aa as c, ab as cM, a4 as keep, ae as useMergedState, X as toRef, af as watchEffect, br as onUpdated, J as watch, W as nextTick, T as useTheme, Y as useThemeClass, aw as flatten, aL as VResizeObserver, bs as resolveSlotWithProps, bt as withDirectives, bu as vShow, aX as Transition, bb as normalizeStyle, bv as getPreciseEventTarget, aD as on, aC as off, bw as carouselLight, ac as cNotM, ar as useFormItem, ah as createKey, bx as color2Class, L as renderList, aj as NBaseIcon, by as rateLight, a1 as call, n as useMessage, u as useSettings, b9 as reactive, o as openBlock, a as createBlock, w as withCtx, e as createVNode, g as createElementBlock, f as unref, C as NTabPane, r as NGrid, q as NGi, F as Fragment, b as createBaseVNode, N as NCard, l as createTextVNode, B as toDisplayString, bz as NTag, h as NSelect, z as NButton, D as NTabs, bf as NModal, s as serverUrl } from "./index.js"; import { a as NDescriptions, N as NDescriptionsItem } from "./DescriptionsItem.js"; function capitalize(string) { return upperFirst(toString(string).toLowerCase()); diff --git a/frontend/dist/assets/ModelsView.js b/frontend/dist/assets/ModelsView.js index e70a5f55e..c60b9dc1c 100644 --- a/frontend/dist/assets/ModelsView.js +++ b/frontend/dist/assets/ModelsView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, x as h, O as replaceable, P as createInjectionKey, Q as cB, R as inject, S as useConfig, T as useTheme, U as popselectLight, l as computed, V as createTreeMate, J as watch, W as nextTick, X as toRef, Y as useThemeClass, Z as NInternalSelectMenu, $ as createTmOptions, a0 as happensIn, a1 as call, a2 as keysOf, y as ref, a3 as provide, a4 as keep, a5 as createRefSetter, a6 as mergeEventHandlers, a7 as omit, a8 as NPopover, a9 as popoverBaseProps, aa as c, ab as cM, ac as cNotM, ad as useLocale, ae as useMergedState, af as watchEffect, ag as useRtl, ah as createKey, ai as resolveSlot, I as NInput, m as NSelect, F as Fragment, aj as NBaseIcon, ak as useAdjustedTo, al as paginationLight, am as useMergedClsPrefix, an as ellipsisLight, ao as onDeactivated, k as NTooltip, ap as mergeProps, aq as useStyle, ar as useFormItem, as as useMemo, at as cE, au as radioLight, av as resolveWrappedSlot, aw as flatten$1, ax as getSlot, ay as depx, az as formatLength, z as NButton, aA as NScrollbar, aB as onBeforeUnmount, aC as off, aD as on, aE as ChevronDownIcon, aF as NDropdown, aG as pxfy, aH as get, aI as NIconSwitchTransition, aJ as NBaseLoading, aK as ChevronRightIcon, p as onUnmounted, aL as VResizeObserver, aM as warn, aN as cssrAnchorMetaName, aO as VVirtualList, aP as NEmpty, aQ as repeat, aR as beforeNextFrameOnce, aS as fadeInScaleUpTransition, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, aW as createId, aX as Transition, aY as dataTableLight, aZ as loadingBarApiInjectionKey, a_ as throwError, a$ as AddIcon, b0 as NProgress, b1 as NFadeInExpandTransition, b2 as EyeIcon, b3 as fadeInHeightExpandTransition, b4 as Teleport, b5 as uploadLight, o as openBlock, g as createElementBlock, b as createBaseVNode, b6 as createStaticVNode, b7 as useCssVars, f as unref, b8 as themeOverridesKey, b9 as reactive, ba as onMounted, e as createVNode, w as withCtx, A as NIcon, L as renderList, _ as _export_sfc, u as useSettings, h as createCommentVNode, bb as normalizeStyle, j as createTextVNode, B as toDisplayString, bc as NText, c as createBlock, bd as withModifiers, a as useState, n as useMessage, be as huggingfaceModelsFile, N as NCard, s as serverUrl, t as pushScopeId, v as popScopeId, i as NSpace, bf as NModal, q as NGi, r as NGrid, bg as NDivider, bh as Backends, C as NTabPane, D as NTabs } from "./index.js"; +import { d as defineComponent, x as h, O as replaceable, P as createInjectionKey, Q as cB, R as inject, S as useConfig, T as useTheme, U as popselectLight, c as computed, V as createTreeMate, J as watch, W as nextTick, X as toRef, Y as useThemeClass, Z as NInternalSelectMenu, $ as createTmOptions, a0 as happensIn, a1 as call, a2 as keysOf, y as ref, a3 as provide, a4 as keep, a5 as createRefSetter, a6 as mergeEventHandlers, a7 as omit, a8 as NPopover, a9 as popoverBaseProps, aa as c, ab as cM, ac as cNotM, ad as useLocale, ae as useMergedState, af as watchEffect, ag as useRtl, ah as createKey, ai as resolveSlot, I as NInput, h as NSelect, F as Fragment, aj as NBaseIcon, ak as useAdjustedTo, al as paginationLight, am as useMergedClsPrefix, an as ellipsisLight, ao as onDeactivated, m as NTooltip, ap as mergeProps, aq as useStyle, ar as useFormItem, as as useMemo, at as cE, au as radioLight, av as resolveWrappedSlot, aw as flatten$1, ax as getSlot, ay as depx, az as formatLength, z as NButton, aA as NScrollbar, aB as onBeforeUnmount, aC as off, aD as on, aE as ChevronDownIcon, aF as NDropdown, aG as pxfy, aH as get, aI as NIconSwitchTransition, aJ as NBaseLoading, aK as ChevronRightIcon, p as onUnmounted, aL as VResizeObserver, aM as warn, aN as cssrAnchorMetaName, aO as VVirtualList, aP as NEmpty, aQ as repeat, aR as beforeNextFrameOnce, aS as fadeInScaleUpTransition, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, aW as createId, aX as Transition, aY as dataTableLight, aZ as loadingBarApiInjectionKey, a_ as throwError, a$ as AddIcon, b0 as NProgress, b1 as NFadeInExpandTransition, b2 as EyeIcon, b3 as fadeInHeightExpandTransition, b4 as Teleport, b5 as uploadLight, o as openBlock, g as createElementBlock, b as createBaseVNode, b6 as createStaticVNode, b7 as useCssVars, f as unref, b8 as themeOverridesKey, b9 as reactive, ba as onMounted, e as createVNode, w as withCtx, A as NIcon, L as renderList, _ as _export_sfc, u as useSettings, i as createCommentVNode, bb as normalizeStyle, l as createTextVNode, B as toDisplayString, bc as NText, a as createBlock, bd as withModifiers, j as useState, n as useMessage, be as huggingfaceModelsFile, N as NCard, s as serverUrl, t as pushScopeId, v as popScopeId, k as NSpace, bf as NModal, q as NGi, r as NGrid, bg as NDivider, bh as Backends, C as NTabPane, D as NTabs } from "./index.js"; import { _ as _sfc_main$6, n as nsfwIndex, N as NRate } from "./ModelPopup.vue_vue_type_script_setup_true_lang.js"; import { N as NCheckboxGroup, a as NCheckbox, S as Settings } from "./Settings.js"; import { N as NSwitch } from "./Switch.js"; diff --git a/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js index 29407f6b3..e649932af 100644 --- a/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, bM as useRouter, u as useSettings, a as useState, y as ref, b9 as reactive, J as watch, l as computed, e as createVNode, w as withCtx, f as unref, N as NCard, z as NButton, j as createTextVNode, M as NScrollbar, F as Fragment, L as renderList, B as toDisplayString, bg as NDivider, bf as NModal, c as createBlock, q as NGi, r as NGrid, h as createCommentVNode } from "./index.js"; +import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, bM as useRouter, u as useSettings, j as useState, y as ref, b9 as reactive, J as watch, c as computed, e as createVNode, w as withCtx, f as unref, N as NCard, z as NButton, l as createTextVNode, M as NScrollbar, F as Fragment, L as renderList, B as toDisplayString, bg as NDivider, bf as NModal, a as createBlock, q as NGi, r as NGrid, i as createCommentVNode } from "./index.js"; import { N as NSwitch } from "./Switch.js"; const _hoisted_1$3 = { xmlns: "http://www.w3.org/2000/svg", diff --git a/frontend/dist/assets/Settings.js b/frontend/dist/assets/Settings.js index ae341017c..d2e509a9c 100644 --- a/frontend/dist/assets/Settings.js +++ b/frontend/dist/assets/Settings.js @@ -1,4 +1,4 @@ -import { x as h, d as defineComponent, S as useConfig, ar as useFormItem, y as ref, l as computed, ae as useMergedState, a3 as provide, X as toRef, P as createInjectionKey, a1 as call, aa as c, Q as cB, ab as cM, at as cE, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, R as inject, as as useMemo, T as useTheme, bJ as checkboxLight, ag as useRtl, ah as createKey, Y as useThemeClass, aW as createId, av as resolveWrappedSlot, aI as NIconSwitchTransition, aD as on, o as openBlock, g as createElementBlock, b as createBaseVNode } from "./index.js"; +import { x as h, d as defineComponent, S as useConfig, ar as useFormItem, y as ref, c as computed, ae as useMergedState, a3 as provide, X as toRef, P as createInjectionKey, a1 as call, aa as c, Q as cB, ab as cM, at as cE, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, R as inject, as as useMemo, T as useTheme, bJ as checkboxLight, ag as useRtl, ah as createKey, Y as useThemeClass, aW as createId, av as resolveWrappedSlot, aI as NIconSwitchTransition, aD as on, o as openBlock, g as createElementBlock, b as createBaseVNode } from "./index.js"; const CheckMark = h( "svg", { viewBox: "0 0 64 64", class: "check-icon" }, diff --git a/frontend/dist/assets/SettingsView.js b/frontend/dist/assets/SettingsView.js index 65f836ede..7431ed37b 100644 --- a/frontend/dist/assets/SettingsView.js +++ b/frontend/dist/assets/SettingsView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, u as useSettings, o as openBlock, c as createBlock, w as withCtx, e as createVNode, f as unref, I as NInput, m as NSelect, N as NCard, b9 as reactive, l as computed, bA as convertToTextString, y as ref, s as serverUrl, J as watch, a as useState, b as createBaseVNode, g as createElementBlock, L as renderList, bc as NText, j as createTextVNode, B as toDisplayString, F as Fragment, h as createCommentVNode, C as NTabPane, D as NTabs, R as inject, bB as themeKey, z as NButton, k as NTooltip, n as useMessage, bC as useNotification, p as onUnmounted, bD as defaultSettings } from "./index.js"; +import { d as defineComponent, u as useSettings, o as openBlock, a as createBlock, w as withCtx, e as createVNode, f as unref, I as NInput, h as NSelect, N as NCard, b9 as reactive, c as computed, bA as convertToTextString, y as ref, s as serverUrl, J as watch, j as useState, b as createBaseVNode, g as createElementBlock, L as renderList, bc as NText, l as createTextVNode, B as toDisplayString, F as Fragment, i as createCommentVNode, C as NTabPane, D as NTabs, R as inject, bB as themeKey, z as NButton, m as NTooltip, n as useMessage, bC as useNotification, p as onUnmounted, bD as defaultSettings } from "./index.js"; import { c as NFormItem, _ as _sfc_main$g, b as _sfc_main$h, a as _sfc_main$i, N as NForm } from "./Upscale.vue_vue_type_script_setup_true_lang.js"; import { N as NSwitch } from "./Switch.js"; import { N as NInputNumber } from "./InputNumber.js"; diff --git a/frontend/dist/assets/Slider.js b/frontend/dist/assets/Slider.js index 4922bd369..931ecb9b3 100644 --- a/frontend/dist/assets/Slider.js +++ b/frontend/dist/assets/Slider.js @@ -1,4 +1,4 @@ -import { y as ref, bp as onBeforeUpdate, aa as c, Q as cB, ab as cM, at as cE, aS as fadeInScaleUpTransition, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, ar as useFormItem, l as computed, X as toRef, ae as useMergedState, J as watch, W as nextTick, aB as onBeforeUnmount, Y as useThemeClass, bQ as isMounted, ak as useAdjustedTo, x as h, b_ as VBinder, b$ as VTarget, ai as resolveSlot, c0 as VFollower, aX as Transition, c1 as sliderLight, aD as on, aC as off, a1 as call } from "./index.js"; +import { y as ref, bp as onBeforeUpdate, aa as c, Q as cB, ab as cM, at as cE, aS as fadeInScaleUpTransition, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, ar as useFormItem, c as computed, X as toRef, ae as useMergedState, J as watch, W as nextTick, aB as onBeforeUnmount, Y as useThemeClass, bQ as isMounted, ak as useAdjustedTo, x as h, b_ as VBinder, b$ as VTarget, ai as resolveSlot, c0 as VFollower, aX as Transition, c1 as sliderLight, aD as on, aC as off, a1 as call } from "./index.js"; function isTouchEvent(e) { return window.TouchEvent && e instanceof window.TouchEvent; } diff --git a/frontend/dist/assets/Switch.js b/frontend/dist/assets/Switch.js index bc72d175f..8988e74bb 100644 --- a/frontend/dist/assets/Switch.js +++ b/frontend/dist/assets/Switch.js @@ -1,4 +1,4 @@ -import { Q as cB, at as cE, aT as iconSwitchTransition, aa as c, ab as cM, ac as cNotM, d as defineComponent, S as useConfig, T as useTheme, ar as useFormItem, y as ref, X as toRef, ae as useMergedState, l as computed, ah as createKey, aG as pxfy, ay as depx, Y as useThemeClass, c2 as isSlotEmpty, x as h, av as resolveWrappedSlot, c3 as switchLight, aI as NIconSwitchTransition, aJ as NBaseLoading, a1 as call } from "./index.js"; +import { Q as cB, at as cE, aT as iconSwitchTransition, aa as c, ab as cM, ac as cNotM, d as defineComponent, S as useConfig, T as useTheme, ar as useFormItem, y as ref, X as toRef, ae as useMergedState, c as computed, ah as createKey, aG as pxfy, ay as depx, Y as useThemeClass, c2 as isSlotEmpty, x as h, av as resolveWrappedSlot, c3 as switchLight, aI as NIconSwitchTransition, aJ as NBaseLoading, a1 as call } from "./index.js"; const style = cB("switch", ` height: var(--n-height); min-width: var(--n-width); diff --git a/frontend/dist/assets/TaggerView.js b/frontend/dist/assets/TaggerView.js index 71e4573c5..17fdb1624 100644 --- a/frontend/dist/assets/TaggerView.js +++ b/frontend/dist/assets/TaggerView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, a as useState, u as useSettings, n as useMessage, y as ref, l as computed, E as spaceRegex, o as openBlock, g as createElementBlock, e as createVNode, w as withCtx, f as unref, q as NGi, N as NCard, i as NSpace, b as createBaseVNode, m as NSelect, k as NTooltip, j as createTextVNode, I as NInput, B as toDisplayString, r as NGrid, s as serverUrl, t as pushScopeId, v as popScopeId, _ as _export_sfc } from "./index.js"; +import { d as defineComponent, j as useState, u as useSettings, n as useMessage, y as ref, c as computed, E as spaceRegex, o as openBlock, g as createElementBlock, e as createVNode, w as withCtx, f as unref, q as NGi, N as NCard, k as NSpace, b as createBaseVNode, h as NSelect, m as NTooltip, l as createTextVNode, I as NInput, B as toDisplayString, r as NGrid, s as serverUrl, t as pushScopeId, v as popScopeId, _ as _export_sfc } from "./index.js"; import { _ as _sfc_main$1 } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; import { I as ImageUpload } from "./ImageUpload.js"; import { v as v4 } from "./v4.js"; diff --git a/frontend/dist/assets/TestView.js b/frontend/dist/assets/TestView.js index b38d6910d..d9fbaff73 100644 --- a/frontend/dist/assets/TestView.js +++ b/frontend/dist/assets/TestView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, y as ref, o as openBlock, c as createBlock, f as unref } from "./index.js"; +import { d as defineComponent, y as ref, o as openBlock, a as createBlock, f as unref } from "./index.js"; import { _ as _sfc_main$1 } from "./ModelPopup.vue_vue_type_script_setup_true_lang.js"; import "./DescriptionsItem.js"; const _sfc_main = /* @__PURE__ */ defineComponent({ diff --git a/frontend/dist/assets/TextToImageView.js b/frontend/dist/assets/TextToImageView.js index 21cab42b0..64410867f 100644 --- a/frontend/dist/assets/TextToImageView.js +++ b/frontend/dist/assets/TextToImageView.js @@ -1,16 +1,206 @@ -import { d as defineComponent, u as useSettings, a as useState, o as openBlock, c as createBlock, w as withCtx, b as createBaseVNode, e as createVNode, f as unref, g as createElementBlock, h as createCommentVNode, N as NCard, i as NSpace, j as createTextVNode, k as NTooltip, l as computed, m as NSelect, n as useMessage, p as onUnmounted, q as NGi, r as NGrid, s as serverUrl } from "./index.js"; -import { _ as _sfc_main$c } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; -import { _ as _sfc_main$d } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; -import { B as BurnerClock, P as Prompt, _ as _sfc_main$6, a as _sfc_main$7, b as _sfc_main$8, c as _sfc_main$9, d as _sfc_main$e } from "./clock.js"; -import { _ as _sfc_main$5, a as _sfc_main$a, b as _sfc_main$b } from "./Upscale.vue_vue_type_script_setup_true_lang.js"; +import { d as defineComponent, u as useSettings, c as computed, o as openBlock, a as createBlock, w as withCtx, b as createBaseVNode, e as createVNode, f as unref, g as createElementBlock, N as NCard, h as NSelect, i as createCommentVNode, j as useState, k as NSpace, l as createTextVNode, m as NTooltip, n as useMessage, p as onUnmounted, q as NGi, r as NGrid, s as serverUrl } from "./index.js"; +import { _ as _sfc_main$d } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; +import { _ as _sfc_main$e } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; +import { B as BurnerClock, P as Prompt, _ as _sfc_main$7, a as _sfc_main$8, b as _sfc_main$9, c as _sfc_main$a, d as _sfc_main$f } from "./clock.js"; import { N as NSwitch } from "./Switch.js"; -import { N as NSlider } from "./Slider.js"; import { N as NInputNumber } from "./InputNumber.js"; +import { N as NSlider } from "./Slider.js"; +import { _ as _sfc_main$6, a as _sfc_main$b, b as _sfc_main$c } from "./Upscale.vue_vue_type_script_setup_true_lang.js"; import { v as v4 } from "./v4.js"; import "./SendOutputTo.vue_vue_type_script_setup_true_lang.js"; import "./TrashBin.js"; import "./DescriptionsItem.js"; import "./Settings.js"; +const _hoisted_1$4 = { class: "flex-container" }; +const _hoisted_2$4 = /* @__PURE__ */ createBaseVNode("div", { class: "slider-label" }, [ + /* @__PURE__ */ createBaseVNode("p", null, "Enabled") +], -1); +const _hoisted_3$4 = { key: 0 }; +const _hoisted_4$4 = { class: "flex-container space-between" }; +const _hoisted_5$4 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Depth", -1); +const _hoisted_6$4 = { class: "flex-container" }; +const _hoisted_7$4 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Stop at", -1); +const _hoisted_8$2 = { class: "flex-container space-between" }; +const _hoisted_9$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Depth", -1); +const _hoisted_10$1 = { class: "flex-container" }; +const _hoisted_11$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Stop at", -1); +const _hoisted_12$1 = { class: "flex-container" }; +const _hoisted_13$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Scale", -1); +const _hoisted_14$1 = { class: "flex-container" }; +const _hoisted_15$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Latent scaler", -1); +const _hoisted_16$1 = { class: "flex-container" }; +const _hoisted_17 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Early out", -1); +const _sfc_main$5 = /* @__PURE__ */ defineComponent({ + __name: "DeepShrink", + props: { + tab: { + type: String, + required: true + }, + target: { + type: String, + required: false, + default: "settings" + } + }, + setup(__props) { + const props = __props; + const settings = useSettings(); + const latentUpscalerOptions = [ + { label: "Nearest", value: "nearest" }, + { label: "Nearest exact", value: "nearest-exact" }, + { label: "Area", value: "area" }, + { label: "Bilinear", value: "bilinear" }, + { label: "Bicubic", value: "bicubic" }, + { label: "Bislerp", value: "bislerp" } + ]; + const target = computed(() => { + if (props.target === "settings") { + return settings.data.settings; + } + return settings.defaultSettings; + }); + return (_ctx, _cache) => { + return openBlock(), createBlock(unref(NCard), { + title: "Deepshrink", + class: "generate-extra-card" + }, { + default: withCtx(() => [ + createBaseVNode("div", _hoisted_1$4, [ + _hoisted_2$4, + createVNode(unref(NSwitch), { + value: target.value[props.tab].deepshrink.enabled, + "onUpdate:value": _cache[0] || (_cache[0] = ($event) => target.value[props.tab].deepshrink.enabled = $event) + }, null, 8, ["value"]) + ]), + target.value[props.tab].deepshrink.enabled ? (openBlock(), createElementBlock("div", _hoisted_3$4, [ + createVNode(unref(NCard), { + bordered: false, + title: "First layer" + }, { + default: withCtx(() => [ + createBaseVNode("div", _hoisted_4$4, [ + _hoisted_5$4, + createVNode(unref(NInputNumber), { + value: target.value[props.tab].deepshrink.depth_1, + "onUpdate:value": _cache[1] || (_cache[1] = ($event) => target.value[props.tab].deepshrink.depth_1 = $event), + max: 4, + min: 1, + step: 1 + }, null, 8, ["value"]) + ]), + createBaseVNode("div", _hoisted_6$4, [ + _hoisted_7$4, + createVNode(unref(NSlider), { + value: target.value[props.tab].deepshrink.stop_at_1, + "onUpdate:value": _cache[2] || (_cache[2] = ($event) => target.value[props.tab].deepshrink.stop_at_1 = $event), + min: 0.05, + max: 1, + step: 0.05, + style: { "margin-right": "12px" } + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: target.value[props.tab].deepshrink.stop_at_1, + "onUpdate:value": _cache[3] || (_cache[3] = ($event) => target.value[props.tab].deepshrink.stop_at_1 = $event), + max: 1, + min: 0.05, + step: 0.05 + }, null, 8, ["value"]) + ]) + ]), + _: 1 + }), + createVNode(unref(NCard), { + bordered: false, + title: "Second layer" + }, { + default: withCtx(() => [ + createBaseVNode("div", _hoisted_8$2, [ + _hoisted_9$2, + createVNode(unref(NInputNumber), { + value: target.value[props.tab].deepshrink.depth_2, + "onUpdate:value": _cache[4] || (_cache[4] = ($event) => target.value[props.tab].deepshrink.depth_2 = $event), + max: 4, + min: 1, + step: 1 + }, null, 8, ["value"]) + ]), + createBaseVNode("div", _hoisted_10$1, [ + _hoisted_11$1, + createVNode(unref(NSlider), { + value: target.value[props.tab].deepshrink.stop_at_2, + "onUpdate:value": _cache[5] || (_cache[5] = ($event) => target.value[props.tab].deepshrink.stop_at_2 = $event), + min: 0.05, + max: 1, + step: 0.05 + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: target.value[props.tab].deepshrink.stop_at_2, + "onUpdate:value": _cache[6] || (_cache[6] = ($event) => target.value[props.tab].deepshrink.stop_at_2 = $event), + max: 1, + min: 0.05, + step: 0.05 + }, null, 8, ["value"]) + ]) + ]), + _: 1 + }), + createVNode(unref(NCard), { + bordered: false, + title: "Scale" + }, { + default: withCtx(() => [ + createBaseVNode("div", _hoisted_12$1, [ + _hoisted_13$1, + createVNode(unref(NSlider), { + value: target.value[props.tab].deepshrink.base_scale, + "onUpdate:value": _cache[7] || (_cache[7] = ($event) => target.value[props.tab].deepshrink.base_scale = $event), + min: 0.05, + max: 1, + step: 0.05 + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: target.value[props.tab].deepshrink.base_scale, + "onUpdate:value": _cache[8] || (_cache[8] = ($event) => target.value[props.tab].deepshrink.base_scale = $event), + max: 1, + min: 0.05, + step: 0.05 + }, null, 8, ["value"]) + ]), + createBaseVNode("div", _hoisted_14$1, [ + _hoisted_15$1, + createVNode(unref(NSelect), { + value: target.value[props.tab].deepshrink.scaler, + "onUpdate:value": _cache[9] || (_cache[9] = ($event) => target.value[props.tab].deepshrink.scaler = $event), + filterable: "", + options: latentUpscalerOptions + }, null, 8, ["value"]) + ]) + ]), + _: 1 + }), + createVNode(unref(NCard), { + bordered: false, + title: "Other" + }, { + default: withCtx(() => [ + createBaseVNode("div", _hoisted_16$1, [ + _hoisted_17, + createVNode(unref(NSwitch), { + value: target.value[props.tab].deepshrink.early_out, + "onUpdate:value": _cache[10] || (_cache[10] = ($event) => target.value[props.tab].deepshrink.early_out = $event) + }, null, 8, ["value"]) + ]) + ]), + _: 1 + }) + ])) : createCommentVNode("", true) + ]), + _: 1 + }); + }; + } +}); const _hoisted_1$3 = { class: "flex-container" }; const _hoisted_2$3 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Enabled", -1); const _hoisted_3$3 = { key: 0 }; @@ -91,8 +281,26 @@ const _hoisted_6$2 = { class: "flex-container" }; const _hoisted_7$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Unsafe resolutions", -1); const _sfc_main$3 = /* @__PURE__ */ defineComponent({ __name: "Scalecrafter", + props: { + tab: { + type: String, + required: true + }, + target: { + type: String, + required: false, + default: "settings" + } + }, setup(__props) { + const props = __props; const settings = useSettings(); + const target = computed(() => { + if (props.target === "settings") { + return settings.data.settings; + } + return settings.defaultSettings; + }); return (_ctx, _cache) => { return openBlock(), createBlock(unref(NCard), { title: "Scalecrafter", @@ -102,11 +310,11 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ createBaseVNode("div", _hoisted_1$2, [ _hoisted_2$2, createVNode(unref(NSwitch), { - value: unref(settings).defaultSettings.flags.scalecrafter.enabled, - "onUpdate:value": _cache[0] || (_cache[0] = ($event) => unref(settings).defaultSettings.flags.scalecrafter.enabled = $event) + value: target.value[props.tab].scalecrafter.enabled, + "onUpdate:value": _cache[0] || (_cache[0] = ($event) => target.value[props.tab].scalecrafter.enabled = $event) }, null, 8, ["value"]) ]), - unref(settings).defaultSettings.flags.scalecrafter.enabled ? (openBlock(), createBlock(unref(NSpace), { + target.value[props.tab].scalecrafter.enabled ? (openBlock(), createBlock(unref(NSpace), { key: 0, vertical: "", class: "left-container" @@ -124,8 +332,8 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ _: 1 }), createVNode(unref(NSwitch), { - value: unref(settings).defaultSettings.flags.scalecrafter.disperse, - "onUpdate:value": _cache[1] || (_cache[1] = ($event) => unref(settings).defaultSettings.flags.scalecrafter.disperse = $event) + value: target.value[props.tab].scalecrafter.disperse, + "onUpdate:value": _cache[1] || (_cache[1] = ($event) => target.value[props.tab].scalecrafter.disperse = $event) }, null, 8, ["value"]) ]), createBaseVNode("div", _hoisted_6$2, [ @@ -139,8 +347,8 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({ _: 1 }), createVNode(unref(NSwitch), { - value: unref(settings).defaultSettings.flags.scalecrafter.unsafe_resolutions, - "onUpdate:value": _cache[2] || (_cache[2] = ($event) => unref(settings).defaultSettings.flags.scalecrafter.unsafe_resolutions = $event) + value: target.value[props.tab].scalecrafter.unsafe_resolutions, + "onUpdate:value": _cache[2] || (_cache[2] = ($event) => target.value[props.tab].scalecrafter.unsafe_resolutions = $event) }, null, 8, ["value"]) ]) ]), @@ -426,22 +634,22 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ strength: settings.data.settings.flags.refiner.strength } } : {}, - ...settings.defaultSettings.flags.deepshrink.enabled ? { + ...settings.data.settings.txt2img.deepshrink.enabled ? { deepshrink: { - early_out: settings.defaultSettings.flags.deepshrink.early_out, - depth_1: settings.defaultSettings.flags.deepshrink.depth_1, - stop_at_1: settings.defaultSettings.flags.deepshrink.stop_at_1, - depth_2: settings.defaultSettings.flags.deepshrink.depth_2, - stop_at_2: settings.defaultSettings.flags.deepshrink.stop_at_2, - scaler: settings.defaultSettings.flags.deepshrink.scaler, - base_scale: settings.defaultSettings.flags.deepshrink.base_scale + early_out: settings.data.settings.txt2img.deepshrink.early_out, + depth_1: settings.data.settings.txt2img.deepshrink.depth_1, + stop_at_1: settings.data.settings.txt2img.deepshrink.stop_at_1, + depth_2: settings.data.settings.txt2img.deepshrink.depth_2, + stop_at_2: settings.data.settings.txt2img.deepshrink.stop_at_2, + scaler: settings.data.settings.txt2img.deepshrink.scaler, + base_scale: settings.data.settings.txt2img.deepshrink.base_scale } } : {}, - ...settings.defaultSettings.flags.scalecrafter.enabled ? { + ...settings.data.settings.txt2img.scalecrafter.enabled ? { scalecrafter: { - unsafe_resolutions: settings.defaultSettings.flags.scalecrafter.unsafe_resolutions, + unsafe_resolutions: settings.data.settings.txt2img.scalecrafter.unsafe_resolutions, base: (_b = settings.data.settings.model) == null ? void 0 : _b.type, - disperse: settings.defaultSettings.flags.scalecrafter.disperse + disperse: settings.data.settings.txt2img.scalecrafter.disperse } } : {}, ...settings.data.settings.txt2img.upscale.enabled ? { @@ -501,8 +709,8 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ }, { default: withCtx(() => [ createVNode(unref(Prompt), { tab: "txt2img" }), - createVNode(unref(_sfc_main$5), { type: "txt2img" }), - createVNode(unref(_sfc_main$6), { + createVNode(unref(_sfc_main$6), { type: "txt2img" }), + createVNode(unref(_sfc_main$7), { "dimensions-object": unref(settings).data.settings.txt2img }, null, 8, ["dimensions-object"]), createBaseVNode("div", _hoisted_2, [ @@ -530,8 +738,8 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ style: { "min-width": "96px", "width": "96px" } }, null, 8, ["value"]) ]), - createVNode(unref(_sfc_main$7), { tab: "txt2img" }), createVNode(unref(_sfc_main$8), { tab: "txt2img" }), + createVNode(unref(_sfc_main$9), { tab: "txt2img" }), createBaseVNode("div", _hoisted_5, [ createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { trigger: withCtx(() => [ @@ -556,7 +764,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ style: { "min-width": "96px", "width": "96px" } }, null, 8, ["value"]) ]), - createVNode(unref(_sfc_main$9), { + createVNode(unref(_sfc_main$a), { "batch-size-object": unref(settings).data.settings.txt2img }, null, 8, ["batch-size-object"]), createBaseVNode("div", _hoisted_7, [ @@ -588,22 +796,23 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ "dimensions-object": unref(settings).data.settings.txt2img }, null, 8, ["dimensions-object"])) : createCommentVNode("", true), isSelectedModelSDXL.value ? (openBlock(), createBlock(unref(_sfc_main$2), { key: 1 })) : createCommentVNode("", true), - createVNode(unref(_sfc_main$3)), - createVNode(unref(_sfc_main$a), { tab: "txt2img" }), - createVNode(unref(_sfc_main$b), { tab: "txt2img" }) + createVNode(unref(_sfc_main$b), { tab: "txt2img" }), + createVNode(unref(_sfc_main$c), { tab: "txt2img" }), + createVNode(unref(_sfc_main$5), { tab: "txt2img" }), + createVNode(unref(_sfc_main$3), { tab: "txt2img" }) ]), _: 1 }), createVNode(unref(NGi), null, { default: withCtx(() => [ - createVNode(unref(_sfc_main$c), { generate }), - createVNode(unref(_sfc_main$d), { + createVNode(unref(_sfc_main$d), { generate }), + createVNode(unref(_sfc_main$e), { "current-image": unref(global).state.txt2img.currentImage, images: unref(global).state.txt2img.images, data: unref(settings).data.settings.txt2img, onImageClicked: _cache[5] || (_cache[5] = ($event) => unref(global).state.txt2img.currentImage = $event) }, null, 8, ["current-image", "images", "data"]), - createVNode(unref(_sfc_main$e), { + createVNode(unref(_sfc_main$f), { style: { "margin-top": "12px" }, "gen-data": unref(global).state.txt2img.genData }, null, 8, ["gen-data"]) diff --git a/frontend/dist/assets/TrashBin.js b/frontend/dist/assets/TrashBin.js index e43631603..72fa42813 100644 --- a/frontend/dist/assets/TrashBin.js +++ b/frontend/dist/assets/TrashBin.js @@ -1,4 +1,4 @@ -import { O as replaceable, x as h, d as defineComponent, bN as isBrowser, T as useTheme, P as createInjectionKey, aa as c, Q as cB, bO as fadeInTransition, aS as fadeInScaleUpTransition, ac as cNotM, X as toRef, bP as imageLight, y as ref, ad as useLocale, J as watch, aD as on, aC as off, aB as onBeforeUnmount, R as inject, l as computed, S as useConfig, Y as useThemeClass, bQ as isMounted, bR as LazyTeleport, bt as withDirectives, bS as zindexable, aX as Transition, F as Fragment, aj as NBaseIcon, bu as vShow, bb as normalizeStyle, bT as kebabCase, k as NTooltip, aR as beforeNextFrameOnce, aW as createId, a3 as provide, bE as getCurrentInstance, ba as onMounted, af as watchEffect, o as openBlock, g as createElementBlock, b as createBaseVNode } from "./index.js"; +import { O as replaceable, x as h, d as defineComponent, bN as isBrowser, T as useTheme, P as createInjectionKey, aa as c, Q as cB, bO as fadeInTransition, aS as fadeInScaleUpTransition, ac as cNotM, X as toRef, bP as imageLight, y as ref, ad as useLocale, J as watch, aD as on, aC as off, aB as onBeforeUnmount, R as inject, c as computed, S as useConfig, Y as useThemeClass, bQ as isMounted, bR as LazyTeleport, bt as withDirectives, bS as zindexable, aX as Transition, F as Fragment, aj as NBaseIcon, bu as vShow, bb as normalizeStyle, bT as kebabCase, m as NTooltip, aR as beforeNextFrameOnce, aW as createId, a3 as provide, bE as getCurrentInstance, ba as onMounted, af as watchEffect, o as openBlock, g as createElementBlock, b as createBaseVNode } from "./index.js"; const RotateClockwiseIcon = replaceable("rotateClockwise", h( "svg", { viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, diff --git a/frontend/dist/assets/Upscale.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/Upscale.vue_vue_type_script_setup_true_lang.js index 656e35bfe..269970ced 100644 --- a/frontend/dist/assets/Upscale.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/Upscale.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { R as inject, bE as getCurrentInstance, J as watch, aB as onBeforeUnmount, Q as cB, ab as cM, aa as c, P as createInjectionKey, d as defineComponent, S as useConfig, T as useTheme, y as ref, a3 as provide, x as h, bF as formLight, a2 as keysOf, l as computed, az as formatLength, aH as get, bG as commonVariables, at as cE, X as toRef, aW as createId, bH as formItemInjectionKey, ba as onMounted, ah as createKey, Y as useThemeClass, aX as Transition, av as resolveWrappedSlot, aM as warn, u as useSettings, a as useState, K as upscalerOptions, o as openBlock, c as createBlock, w as withCtx, b as createBaseVNode, e as createVNode, f as unref, i as NSpace, m as NSelect, g as createElementBlock, j as createTextVNode, k as NTooltip, h as createCommentVNode, N as NCard, F as Fragment, L as renderList, z as NButton, B as toDisplayString, bA as convertToTextString, bI as resolveDynamicComponent, bf as NModal, A as NIcon } from "./index.js"; +import { R as inject, bE as getCurrentInstance, J as watch, aB as onBeforeUnmount, Q as cB, ab as cM, aa as c, P as createInjectionKey, d as defineComponent, S as useConfig, T as useTheme, y as ref, a3 as provide, x as h, bF as formLight, a2 as keysOf, c as computed, az as formatLength, aH as get, bG as commonVariables, at as cE, X as toRef, aW as createId, bH as formItemInjectionKey, ba as onMounted, ah as createKey, Y as useThemeClass, aX as Transition, av as resolveWrappedSlot, aM as warn, u as useSettings, j as useState, K as upscalerOptions, o as openBlock, a as createBlock, w as withCtx, b as createBaseVNode, e as createVNode, f as unref, k as NSpace, h as NSelect, g as createElementBlock, l as createTextVNode, m as NTooltip, i as createCommentVNode, N as NCard, F as Fragment, L as renderList, z as NButton, B as toDisplayString, bA as convertToTextString, bI as resolveDynamicComponent, bf as NModal, A as NIcon } from "./index.js"; import { N as NSwitch } from "./Switch.js"; import { N as NSlider } from "./Slider.js"; import { N as NInputNumber } from "./InputNumber.js"; diff --git a/frontend/dist/assets/clock.js b/frontend/dist/assets/clock.js index 92f4884f5..d80c85bd8 100644 --- a/frontend/dist/assets/clock.js +++ b/frontend/dist/assets/clock.js @@ -5,11 +5,11 @@ var __publicField = (obj, key, value) => { return value; }; import { N as NDescriptionsItem, a as NDescriptions } from "./DescriptionsItem.js"; -import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, c as createBlock, w as withCtx, e as createVNode, f as unref, j as createTextVNode, B as toDisplayString, N as NCard, h as createCommentVNode, u as useSettings, k as NTooltip, l as computed, m as NSelect, F as Fragment, a as useState, E as spaceRegex, A as NIcon, G as promptHandleKeyUp, H as promptHandleKeyDown, I as NInput, _ as _export_sfc, J as watch, y as ref, s as serverUrl } from "./index.js"; +import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, a as createBlock, w as withCtx, e as createVNode, f as unref, l as createTextVNode, B as toDisplayString, N as NCard, i as createCommentVNode, u as useSettings, m as NTooltip, c as computed, F as Fragment, j as useState, E as spaceRegex, A as NIcon, h as NSelect, G as promptHandleKeyUp, H as promptHandleKeyDown, I as NInput, _ as _export_sfc, J as watch, y as ref, s as serverUrl } from "./index.js"; import { N as NSlider } from "./Slider.js"; import { N as NInputNumber } from "./InputNumber.js"; -import { N as NSwitch } from "./Switch.js"; import { N as NForm, c as NFormItem } from "./Upscale.vue_vue_type_script_setup_true_lang.js"; +import { N as NSwitch } from "./Switch.js"; const _hoisted_1$4 = { xmlns: "http://www.w3.org/2000/svg", "xmlns:xlink": "http://www.w3.org/1999/xlink", @@ -222,27 +222,6 @@ const _hoisted_7 = { class: "flex-container" }; const _hoisted_8 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Height", -1); -const _hoisted_9 = { key: 4 }; -const _hoisted_10 = { class: "flex-container" }; -const _hoisted_11 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Enable Deepshrink", -1); -const _hoisted_12 = { key: 0 }; -const _hoisted_13 = { class: "flex-container" }; -const _hoisted_14 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "First layer", -1); -const _hoisted_15 = /* @__PURE__ */ createBaseVNode("div", null, null, -1); -const _hoisted_16 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Stop at", -1); -const _hoisted_17 = /* @__PURE__ */ createBaseVNode("div", null, null, -1); -const _hoisted_18 = { class: "flex-container" }; -const _hoisted_19 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Second layer", -1); -const _hoisted_20 = /* @__PURE__ */ createBaseVNode("div", null, null, -1); -const _hoisted_21 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Stop at", -1); -const _hoisted_22 = /* @__PURE__ */ createBaseVNode("div", null, null, -1); -const _hoisted_23 = { class: "flex-container" }; -const _hoisted_24 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Scale", -1); -const _hoisted_25 = /* @__PURE__ */ createBaseVNode("div", null, null, -1); -const _hoisted_26 = { class: "flex-container" }; -const _hoisted_27 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Latent scaler", -1); -const _hoisted_28 = { class: "flex-container" }; -const _hoisted_29 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Early out", -1); const _sfc_main$2 = /* @__PURE__ */ defineComponent({ __name: "DimensionsInput", props: { @@ -253,14 +232,6 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ }, setup(__props) { const props = __props; - const latentUpscalerOptions = [ - { label: "Nearest", value: "nearest" }, - { label: "Nearest exact", value: "nearest-exact" }, - { label: "Area", value: "area" }, - { label: "Bilinear", value: "bilinear" }, - { label: "Bicubic", value: "bicubic" }, - { label: "Bislerp", value: "bislerp" } - ]; const settings = useSettings(); return (_ctx, _cache) => { return openBlock(), createElementBlock(Fragment, null, [ @@ -271,8 +242,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ "onUpdate:value": _cache[0] || (_cache[0] = ($event) => props.dimensionsObject.width = $event), min: unref(settings).data.settings.aitDim.width[0], max: unref(settings).data.settings.aitDim.width[1], - step: 64, - style: { "margin-right": "12px" } + step: 64 }, null, 8, ["value", "min", "max"]), createVNode(unref(NInputNumber), { value: props.dimensionsObject.width, @@ -290,8 +260,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ "onUpdate:value": _cache[2] || (_cache[2] = ($event) => props.dimensionsObject.width = $event), min: 128, max: 2048, - step: 1, - style: { "margin-right": "12px" } + step: 1 }, null, 8, ["value"]), createVNode(unref(NInputNumber), { value: props.dimensionsObject.width, @@ -308,8 +277,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ "onUpdate:value": _cache[4] || (_cache[4] = ($event) => props.dimensionsObject.height = $event), min: unref(settings).data.settings.aitDim.height[0], max: unref(settings).data.settings.aitDim.height[1], - step: 64, - style: { "margin-right": "12px" } + step: 64 }, null, 8, ["value", "min", "max"]), createVNode(unref(NInputNumber), { value: props.dimensionsObject.height, @@ -327,8 +295,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ "onUpdate:value": _cache[6] || (_cache[6] = ($event) => props.dimensionsObject.height = $event), min: 128, max: 2048, - step: 1, - style: { "margin-right": "12px" } + step: 1 }, null, 8, ["value"]), createVNode(unref(NInputNumber), { value: props.dimensionsObject.height, @@ -337,106 +304,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ style: { "min-width": "96px", "width": "96px" }, step: 1 }, null, 8, ["value"]) - ])), - props.dimensionsObject.width * props.dimensionsObject.height >= 768 * 768 || unref(settings).defaultSettings.flags.deepshrink.enabled ? (openBlock(), createElementBlock("div", _hoisted_9, [ - createBaseVNode("div", _hoisted_10, [ - _hoisted_11, - createVNode(unref(NSwitch), { - value: unref(settings).defaultSettings.flags.deepshrink.enabled, - "onUpdate:value": _cache[8] || (_cache[8] = ($event) => unref(settings).defaultSettings.flags.deepshrink.enabled = $event) - }, null, 8, ["value"]) - ]), - unref(settings).defaultSettings.flags.deepshrink.enabled ? (openBlock(), createElementBlock("div", _hoisted_12, [ - createBaseVNode("div", _hoisted_13, [ - _hoisted_14, - createVNode(unref(NInputNumber), { - value: unref(settings).defaultSettings.flags.deepshrink.depth_1, - "onUpdate:value": _cache[9] || (_cache[9] = ($event) => unref(settings).defaultSettings.flags.deepshrink.depth_1 = $event), - max: 4, - min: 1, - step: 1 - }, null, 8, ["value"]), - _hoisted_15, - _hoisted_16, - createVNode(unref(NSlider), { - value: unref(settings).defaultSettings.flags.deepshrink.stop_at_1, - "onUpdate:value": _cache[10] || (_cache[10] = ($event) => unref(settings).defaultSettings.flags.deepshrink.stop_at_1 = $event), - min: 0.05, - max: 1, - step: 0.05 - }, null, 8, ["value"]), - _hoisted_17, - createVNode(unref(NInputNumber), { - value: unref(settings).defaultSettings.flags.deepshrink.stop_at_1, - "onUpdate:value": _cache[11] || (_cache[11] = ($event) => unref(settings).defaultSettings.flags.deepshrink.stop_at_1 = $event), - max: 1, - min: 0.05, - step: 0.05 - }, null, 8, ["value"]) - ]), - createBaseVNode("div", _hoisted_18, [ - _hoisted_19, - createVNode(unref(NInputNumber), { - value: unref(settings).defaultSettings.flags.deepshrink.depth_2, - "onUpdate:value": _cache[12] || (_cache[12] = ($event) => unref(settings).defaultSettings.flags.deepshrink.depth_2 = $event), - max: 4, - min: 1, - step: 1 - }, null, 8, ["value"]), - _hoisted_20, - _hoisted_21, - createVNode(unref(NSlider), { - value: unref(settings).defaultSettings.flags.deepshrink.stop_at_2, - "onUpdate:value": _cache[13] || (_cache[13] = ($event) => unref(settings).defaultSettings.flags.deepshrink.stop_at_2 = $event), - min: 0.05, - max: 1, - step: 0.05 - }, null, 8, ["value"]), - _hoisted_22, - createVNode(unref(NInputNumber), { - value: unref(settings).defaultSettings.flags.deepshrink.stop_at_2, - "onUpdate:value": _cache[14] || (_cache[14] = ($event) => unref(settings).defaultSettings.flags.deepshrink.stop_at_2 = $event), - max: 1, - min: 0.05, - step: 0.05 - }, null, 8, ["value"]) - ]), - createBaseVNode("div", _hoisted_23, [ - _hoisted_24, - createVNode(unref(NSlider), { - value: unref(settings).defaultSettings.flags.deepshrink.base_scale, - "onUpdate:value": _cache[15] || (_cache[15] = ($event) => unref(settings).defaultSettings.flags.deepshrink.base_scale = $event), - min: 0.05, - max: 1, - step: 0.05 - }, null, 8, ["value"]), - _hoisted_25, - createVNode(unref(NInputNumber), { - value: unref(settings).defaultSettings.flags.deepshrink.base_scale, - "onUpdate:value": _cache[16] || (_cache[16] = ($event) => unref(settings).defaultSettings.flags.deepshrink.base_scale = $event), - max: 1, - min: 0.05, - step: 0.05 - }, null, 8, ["value"]) - ]), - createBaseVNode("div", _hoisted_26, [ - _hoisted_27, - createVNode(unref(NSelect), { - value: unref(settings).defaultSettings.flags.deepshrink.scaler, - "onUpdate:value": _cache[17] || (_cache[17] = ($event) => unref(settings).defaultSettings.flags.deepshrink.scaler = $event), - filterable: "", - options: latentUpscalerOptions - }, null, 8, ["value"]) - ]), - createBaseVNode("div", _hoisted_28, [ - _hoisted_29, - createVNode(unref(NSwitch), { - value: unref(settings).defaultSettings.flags.deepshrink.early_out, - "onUpdate:value": _cache[18] || (_cache[18] = ($event) => unref(settings).defaultSettings.flags.deepshrink.early_out = $event) - }, null, 8, ["value"]) - ]) - ])) : createCommentVNode("", true) - ])) : createCommentVNode("", true) + ])) ], 64); }; } diff --git a/frontend/dist/assets/index.css b/frontend/dist/assets/index.css index 3497ad1c6..7b2cd3c82 100644 --- a/frontend/dist/assets/index.css +++ b/frontend/dist/assets/index.css @@ -2,14 +2,15 @@ margin: 0 12px; } -.split { - width: 50%; -} - .flex-container { width: 100%; display: inline-flex; align-items: center; + gap: 0 8px; +} + +.flex-container.space-between { + justify-content: space-between; } .slider-label { @@ -98,26 +99,26 @@ justify-content: center; } -.image-container img[data-v-8c5af50f] { +.image-container img[data-v-0af5331f] { width: 100%; height: 100%; object-fit: contain; overflow: hidden; } -.image-container[data-v-8c5af50f] { +.image-container[data-v-0af5331f] { height: 70vh; width: 100%; display: flex; justify-content: center; } -.hidden-input[data-v-124be5cd] { +.hidden-input[data-v-58a6e728] { display: none; } -.utility-button[data-v-124be5cd] { +.utility-button[data-v-58a6e728] { margin-right: 8px; } -.file-upload[data-v-124be5cd] { +.file-upload[data-v-58a6e728] { appearance: none; background-color: transparent; border: 1px solid #63e2b7; @@ -137,21 +138,21 @@ vertical-align: middle; white-space: nowrap; } -.file-upload[data-v-124be5cd]:focus:not(:focus-visible):not(.focus-visible) { +.file-upload[data-v-58a6e728]:focus:not(:focus-visible):not(.focus-visible) { box-shadow: none; outline: none; } -.file-upload[data-v-124be5cd]:focus { +.file-upload[data-v-58a6e728]:focus { box-shadow: rgba(46, 164, 79, 0.4) 0 0 0 3px; outline: none; } -.file-upload[data-v-124be5cd]:disabled { +.file-upload[data-v-58a6e728]:disabled { background-color: #94d3a2; border-color: rgba(27, 31, 35, 0.1); color: rgba(255, 255, 255, 0.8); cursor: default; } -.image-container[data-v-124be5cd] { +.image-container[data-v-58a6e728] { width: 100%; display: flex; justify-content: center; diff --git a/frontend/dist/assets/index.js b/frontend/dist/assets/index.js index a3f71c14c..282e949db 100644 --- a/frontend/dist/assets/index.js +++ b/frontend/dist/assets/index.js @@ -41476,6 +41476,22 @@ const upscaleFlagDefault = { tile_padding: 10, model: "RealESRGAN_x4plus_anime_6B" }; +const deepShrinkFlagDefault = { + enabled: false, + depth_1: 3, + stop_at_1: 0.15, + depth_2: 4, + stop_at_2: 0.3, + scaler: "bislerp", + base_scale: 0.5, + early_out: false +}; +const scaleCrafterFlagDefault = { + enabled: false, + base: "sd15", + unsafe_resolutions: true, + disperse: false +}; const defaultSettings = { $schema: "./schema/ui_data/settings.json", backend: "PyTorch", @@ -41493,22 +41509,6 @@ const defaultSettings = { negative_aesthetic_score: 2.5, steps: 50, strength: 0.3 - }, - deepshrink: { - enabled: false, - depth_1: 3, - depth_2: 4, - stop_at_1: 0.15, - stop_at_2: 0.3, - early_out: false, - base_scale: 0.5, - scaler: "bislerp" - }, - scalecrafter: { - enabled: false, - base: "sd15", - unsafe_resolutions: true, - disperse: false } }, aitDim: { @@ -41530,7 +41530,9 @@ const defaultSettings = { self_attention_scale: 0, sigmas: "automatic", highres: cloneObj(highresFixFlagDefault), - upscale: cloneObj(upscaleFlagDefault) + upscale: cloneObj(upscaleFlagDefault), + deepshrink: cloneObj(deepShrinkFlagDefault), + scalecrafter: cloneObj(scaleCrafterFlagDefault) }, img2img: { width: 512, @@ -41548,7 +41550,9 @@ const defaultSettings = { self_attention_scale: 0, sigmas: "automatic", highres: cloneObj(highresFixFlagDefault), - upscale: cloneObj(upscaleFlagDefault) + upscale: cloneObj(upscaleFlagDefault), + deepshrink: cloneObj(deepShrinkFlagDefault), + scalecrafter: cloneObj(scaleCrafterFlagDefault) }, inpainting: { prompt: "", @@ -41566,7 +41570,9 @@ const defaultSettings = { self_attention_scale: 0, sigmas: "automatic", highres: cloneObj(highresFixFlagDefault), - upscale: cloneObj(upscaleFlagDefault) + upscale: cloneObj(upscaleFlagDefault), + deepshrink: cloneObj(deepShrinkFlagDefault), + scalecrafter: cloneObj(scaleCrafterFlagDefault) }, controlnet: { prompt: "", @@ -41589,7 +41595,9 @@ const defaultSettings = { self_attention_scale: 0, sigmas: "automatic", highres: cloneObj(highresFixFlagDefault), - upscale: cloneObj(upscaleFlagDefault) + upscale: cloneObj(upscaleFlagDefault), + deepshrink: cloneObj(deepShrinkFlagDefault), + scalecrafter: cloneObj(scaleCrafterFlagDefault) }, upscale: { image: "", @@ -43185,8 +43193,8 @@ const TopBar = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-9 const Prompt_vue_vue_type_style_index_0_lang = ""; const Prompt_vue_vue_type_style_index_1_scoped_780680bc_lang = ""; const ControlNet_vue_vue_type_style_index_0_scoped_97c56df6_lang = ""; -const Img2Img_vue_vue_type_style_index_0_scoped_8c5af50f_lang = ""; -const Inpainting_vue_vue_type_style_index_0_scoped_124be5cd_lang = ""; +const Img2Img_vue_vue_type_style_index_0_scoped_0af5331f_lang = ""; +const Inpainting_vue_vue_type_style_index_0_scoped_58a6e728_lang = ""; const CivitAIDownload_vue_vue_type_style_index_0_scoped_241a4664_lang = ""; const HuggingfaceDownload_vue_vue_type_style_index_0_scoped_b405f046_lang = ""; const _hoisted_1$1 = { style: { "margin": "16px 0" } }; @@ -43485,7 +43493,7 @@ const router = createRouter({ { path: "/img2img", name: "img2img", - component: () => __vitePreload(() => import("./Image2ImageView.js"), true ? ["assets/Image2ImageView.js","assets/clock.js","assets/DescriptionsItem.js","assets/Slider.js","assets/InputNumber.js","assets/Switch.js","assets/Upscale.vue_vue_type_script_setup_true_lang.js","assets/Settings.js","assets/GenerateSection.vue_vue_type_script_setup_true_lang.js","assets/ImageOutput.vue_vue_type_script_setup_true_lang.js","assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js","assets/TrashBin.js","assets/ImageUpload.js","assets/CloudUpload.js","assets/v4.js"] : void 0) + component: () => __vitePreload(() => import("./Image2ImageView.js"), true ? ["assets/Image2ImageView.js","assets/clock.js","assets/DescriptionsItem.js","assets/Slider.js","assets/InputNumber.js","assets/Upscale.vue_vue_type_script_setup_true_lang.js","assets/Switch.js","assets/Settings.js","assets/GenerateSection.vue_vue_type_script_setup_true_lang.js","assets/ImageOutput.vue_vue_type_script_setup_true_lang.js","assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js","assets/TrashBin.js","assets/ImageUpload.js","assets/CloudUpload.js","assets/v4.js"] : void 0) }, { path: "/imageProcessing", @@ -43580,7 +43588,7 @@ export { useThemeClass as Y, NInternalSelectMenu as Z, _export_sfc as _, - useState2 as a, + createBlock as a, AddIcon as a$, happensIn as a0, call as a1, @@ -43710,7 +43718,7 @@ export { color2Class as bx, rateLight as by, NTag as bz, - createBlock as c, + computed as c, VFollower as c0, sliderLight$1 as c1, isSlotEmpty as c2, @@ -43720,12 +43728,12 @@ export { createVNode as e, unref as f, createElementBlock as g, - createCommentVNode as h, - NSpace as i, - createTextVNode as j, - NTooltip as k, - computed as l, - NSelect as m, + NSelect as h, + createCommentVNode as i, + useState2 as j, + NSpace as k, + createTextVNode as l, + NTooltip as m, useMessage as n, openBlock as o, onUnmounted as p, diff --git a/frontend/src/assets/2img.css b/frontend/src/assets/2img.css index a6fc0dcef..34bd76b06 100644 --- a/frontend/src/assets/2img.css +++ b/frontend/src/assets/2img.css @@ -2,14 +2,15 @@ margin: 0 12px; } -.split { - width: 50%; -} - .flex-container { width: 100%; display: inline-flex; align-items: center; + gap: 0 8px; +} + +.flex-container.space-between { + justify-content: space-between; } .slider-label { diff --git a/frontend/src/components/generate/DeepShrink.vue b/frontend/src/components/generate/DeepShrink.vue new file mode 100644 index 000000000..1a278a940 --- /dev/null +++ b/frontend/src/components/generate/DeepShrink.vue @@ -0,0 +1,140 @@ + + + diff --git a/frontend/src/components/generate/DimensionsInput.vue b/frontend/src/components/generate/DimensionsInput.vue index 62d63be8e..f251c6b0f 100644 --- a/frontend/src/components/generate/DimensionsInput.vue +++ b/frontend/src/components/generate/DimensionsInput.vue @@ -7,7 +7,6 @@ :min="settings.data.settings.aitDim.width[0]" :max="settings.data.settings.aitDim.width[1]" :step="64" - style="margin-right: 12px" />
-
-
-

Enable Deepshrink

- -
-
-
-

First layer

- -
-

Stop at

- -
- -
-
-

Second layer

- -
-

Stop at

- -
- -
-
-

Scale

- -
- -
-
-

Latent scaler

- -
-
-

Early out

- -
-
-
diff --git a/frontend/src/components/generate/index.ts b/frontend/src/components/generate/index.ts index 0aabb310c..e4ff554ff 100644 --- a/frontend/src/components/generate/index.ts +++ b/frontend/src/components/generate/index.ts @@ -1,11 +1,12 @@ export { default as BatchSizeInput } from "./BatchSizeInput.vue"; export { default as CFGScale } from "./CFGScaleInput.vue"; +export { default as DeepShrink } from "./DeepShrink.vue"; export { default as DimensionsInput } from "./DimensionsInput.vue"; export { default as HighResFix } from "./HighResFix.vue"; export { default as Prompt } from "./Prompt.vue"; export { default as ResizeFromDimensionsInput } from "./ResizeFromDimensionsInput.vue"; export { default as SAGInput } from "./SAGInput.vue"; -export { default as Scalecrafter } from "./Scalecrafter.vue"; export { default as SamplerPicker } from "./SamplerPicker.vue"; +export { default as Scalecrafter } from "./Scalecrafter.vue"; export { default as Upscale } from "./Upscale.vue"; export { default as XLRefiner } from "./XLRefiner.vue"; diff --git a/frontend/src/components/inference/Img2Img.vue b/frontend/src/components/inference/Img2Img.vue index 4ccb4dceb..cace34b17 100644 --- a/frontend/src/components/inference/Img2Img.vue +++ b/frontend/src/components/inference/Img2Img.vue @@ -258,18 +258,18 @@ const generate = () => { prompt_to_prompt: settings.data.settings.api.prompt_to_prompt, }, }, - ...(settings.defaultSettings.flags.deepshrink.enabled + ...(settings.data.settings.img2img.deepshrink.enabled ? { flags: { deepshrink: { - early_out: settings.defaultSettings.flags.deepshrink.early_out, - depth_1: settings.defaultSettings.flags.deepshrink.depth_1, - stop_at_1: settings.defaultSettings.flags.deepshrink.stop_at_1, - depth_2: settings.defaultSettings.flags.deepshrink.depth_2, - stop_at_2: settings.defaultSettings.flags.deepshrink.stop_at_2, - scaler: settings.defaultSettings.flags.deepshrink.scaler, + early_out: settings.data.settings.img2img.deepshrink.early_out, + depth_1: settings.data.settings.img2img.deepshrink.depth_1, + stop_at_1: settings.data.settings.img2img.deepshrink.stop_at_1, + depth_2: settings.data.settings.img2img.deepshrink.depth_2, + stop_at_2: settings.data.settings.img2img.deepshrink.stop_at_2, + scaler: settings.data.settings.img2img.deepshrink.scaler, base_scale: - settings.defaultSettings.flags.deepshrink.base_scale, + settings.data.settings.img2img.deepshrink.base_scale, }, }, } diff --git a/frontend/src/components/inference/Inpainting.vue b/frontend/src/components/inference/Inpainting.vue index 3b526efff..45f2863ed 100644 --- a/frontend/src/components/inference/Inpainting.vue +++ b/frontend/src/components/inference/Inpainting.vue @@ -369,18 +369,21 @@ const generate = () => { prompt_to_prompt: settings.data.settings.api.prompt_to_prompt, }, }, - ...(settings.defaultSettings.flags.deepshrink.enabled + ...(settings.data.settings.inpainting.deepshrink.enabled ? { flags: { deepshrink: { - early_out: settings.defaultSettings.flags.deepshrink.early_out, - depth_1: settings.defaultSettings.flags.deepshrink.depth_1, - stop_at_1: settings.defaultSettings.flags.deepshrink.stop_at_1, - depth_2: settings.defaultSettings.flags.deepshrink.depth_2, - stop_at_2: settings.defaultSettings.flags.deepshrink.stop_at_2, - scaler: settings.defaultSettings.flags.deepshrink.scaler, + early_out: + settings.data.settings.inpainting.deepshrink.early_out, + depth_1: settings.data.settings.inpainting.deepshrink.depth_1, + stop_at_1: + settings.data.settings.inpainting.deepshrink.stop_at_1, + depth_2: settings.data.settings.inpainting.deepshrink.depth_2, + stop_at_2: + settings.data.settings.inpainting.deepshrink.stop_at_2, + scaler: settings.data.settings.inpainting.deepshrink.scaler, base_scale: - settings.defaultSettings.flags.deepshrink.base_scale, + settings.data.settings.inpainting.deepshrink.base_scale, }, }, } diff --git a/frontend/src/components/inference/Txt2Img.vue b/frontend/src/components/inference/Txt2Img.vue index a6423780a..e4d293fea 100644 --- a/frontend/src/components/inference/Txt2Img.vue +++ b/frontend/src/components/inference/Txt2Img.vue @@ -97,9 +97,14 @@ v-if="isSelectedModelSDXL" /> - + + + + + + @@ -128,6 +133,7 @@ import { BatchSizeInput, CFGScale, + DeepShrink, DimensionsInput, GenerateSection, HighResFix, @@ -136,8 +142,8 @@ import { Prompt, ResizeFromDimensionsInput, SAGInput, - Scalecrafter, SamplerPicker, + Scalecrafter, Upscale, XLRefiner, } from "@/components"; @@ -259,28 +265,28 @@ const generate = () => { }, } : {}), - ...(settings.defaultSettings.flags.deepshrink.enabled + ...(settings.data.settings.txt2img.deepshrink.enabled ? { deepshrink: { - early_out: settings.defaultSettings.flags.deepshrink.early_out, - depth_1: settings.defaultSettings.flags.deepshrink.depth_1, - stop_at_1: settings.defaultSettings.flags.deepshrink.stop_at_1, - depth_2: settings.defaultSettings.flags.deepshrink.depth_2, - stop_at_2: settings.defaultSettings.flags.deepshrink.stop_at_2, - scaler: settings.defaultSettings.flags.deepshrink.scaler, + early_out: settings.data.settings.txt2img.deepshrink.early_out, + depth_1: settings.data.settings.txt2img.deepshrink.depth_1, + stop_at_1: settings.data.settings.txt2img.deepshrink.stop_at_1, + depth_2: settings.data.settings.txt2img.deepshrink.depth_2, + stop_at_2: settings.data.settings.txt2img.deepshrink.stop_at_2, + scaler: settings.data.settings.txt2img.deepshrink.scaler, base_scale: - settings.defaultSettings.flags.deepshrink.base_scale, + settings.data.settings.txt2img.deepshrink.base_scale, }, } : {}), - ...(settings.defaultSettings.flags.scalecrafter.enabled + ...(settings.data.settings.txt2img.scalecrafter.enabled ? { scalecrafter: { unsafe_resolutions: - settings.defaultSettings.flags.scalecrafter + settings.data.settings.txt2img.scalecrafter .unsafe_resolutions, base: settings.data.settings.model?.type, - disperse: settings.defaultSettings.flags.scalecrafter.disperse, + disperse: settings.data.settings.txt2img.scalecrafter.disperse, }, } : {}), diff --git a/frontend/src/settings.ts b/frontend/src/settings.ts index f4f770500..044ff508d 100644 --- a/frontend/src/settings.ts +++ b/frontend/src/settings.ts @@ -63,6 +63,50 @@ const upscaleFlagDefault: UpscaleFlag = { model: "RealESRGAN_x4plus_anime_6B", }; +export interface DeepShrinkFlag { + enabled: boolean; + + depth_1: number; + stop_at_1: number; + + depth_2: number; + stop_at_2: number; + + scaler: string; + base_scale: number; + early_out: boolean; +} + +const deepShrinkFlagDefault: DeepShrinkFlag = { + enabled: false, + + depth_1: 3, + stop_at_1: 0.15, + + depth_2: 4, + stop_at_2: 0.3, + + scaler: "bislerp", + base_scale: 0.5, + early_out: false, +}; + +export interface ScaleCrafterFlag { + enabled: boolean; + + base: string; + unsafe_resolutions: boolean; + disperse: boolean; +} + +const scaleCrafterFlagDefault: ScaleCrafterFlag = { + enabled: false, + + base: "sd15", + unsafe_resolutions: true, + disperse: false, +}; + export type SigmaType = | "automatic" | "karras" @@ -95,22 +139,6 @@ export interface ISettings { steps: 50; strength: number; }; - deepshrink: { - enabled: boolean; - depth_1: number; - stop_at_1: number; - depth_2: number; - stop_at_2: number; - base_scale: number; - scaler: string; - early_out: boolean; - }; - scalecrafter: { - enabled: boolean; - base: string; - unsafe_resolutions: boolean; - disperse: boolean; - }; }; aitDim: { width: number[] | undefined; @@ -132,6 +160,8 @@ export interface ISettings { sigmas: SigmaType; highres: HighResFixFlag; upscale: UpscaleFlag; + deepshrink: DeepShrinkFlag; + scalecrafter: ScaleCrafterFlag; }; img2img: { prompt: string; @@ -150,6 +180,8 @@ export interface ISettings { sigmas: SigmaType; highres: HighResFixFlag; upscale: UpscaleFlag; + deepshrink: DeepShrinkFlag; + scalecrafter: ScaleCrafterFlag; }; inpainting: { prompt: string; @@ -168,6 +200,8 @@ export interface ISettings { sigmas: SigmaType; highres: HighResFixFlag; upscale: UpscaleFlag; + deepshrink: DeepShrinkFlag; + scalecrafter: ScaleCrafterFlag; }; controlnet: { prompt: string; @@ -191,6 +225,8 @@ export interface ISettings { sigmas: SigmaType; highres: HighResFixFlag; upscale: UpscaleFlag; + deepshrink: DeepShrinkFlag; + scalecrafter: ScaleCrafterFlag; }; upscale: { image: string; @@ -334,22 +370,6 @@ export const defaultSettings: ISettings = { steps: 50, strength: 0.3, }, - deepshrink: { - enabled: false, - depth_1: 3, - depth_2: 4, - stop_at_1: 0.15, - stop_at_2: 0.3, - early_out: false, - base_scale: 0.5, - scaler: "bislerp", - }, - scalecrafter: { - enabled: false, - base: "sd15", - unsafe_resolutions: true, - disperse: false, - }, }, aitDim: { width: undefined, @@ -371,6 +391,8 @@ export const defaultSettings: ISettings = { sigmas: "automatic", highres: cloneObj(highresFixFlagDefault), upscale: cloneObj(upscaleFlagDefault), + deepshrink: cloneObj(deepShrinkFlagDefault), + scalecrafter: cloneObj(scaleCrafterFlagDefault), }, img2img: { width: 512, @@ -389,6 +411,8 @@ export const defaultSettings: ISettings = { sigmas: "automatic", highres: cloneObj(highresFixFlagDefault), upscale: cloneObj(upscaleFlagDefault), + deepshrink: cloneObj(deepShrinkFlagDefault), + scalecrafter: cloneObj(scaleCrafterFlagDefault), }, inpainting: { prompt: "", @@ -407,6 +431,8 @@ export const defaultSettings: ISettings = { sigmas: "automatic", highres: cloneObj(highresFixFlagDefault), upscale: cloneObj(upscaleFlagDefault), + deepshrink: cloneObj(deepShrinkFlagDefault), + scalecrafter: cloneObj(scaleCrafterFlagDefault), }, controlnet: { prompt: "", @@ -430,6 +456,8 @@ export const defaultSettings: ISettings = { sigmas: "automatic", highres: cloneObj(highresFixFlagDefault), upscale: cloneObj(upscaleFlagDefault), + deepshrink: cloneObj(deepShrinkFlagDefault), + scalecrafter: cloneObj(scaleCrafterFlagDefault), }, upscale: { image: "", From 4c0c1edf0b27dd26bebd2d95fa119e003fe8833d Mon Sep 17 00:00:00 2001 From: gabe56f Date: Mon, 11 Dec 2023 02:18:23 +0100 Subject: [PATCH 102/143] Animatediff --- core/flags.py | 20 +++++- core/inference/pytorch/pipeline.py | 84 ++++++++++++++++------- core/inference/utilities/animatediff.py | 1 + core/inference/utilities/latents.py | 22 +++++-- core/inference/utilities/vae.py | 88 ++++++++++++++++++++----- core/inference_callbacks.py | 7 +- core/optimizations/context_manager.py | 40 ++++++++++- core/png_metadata.py | 52 ++++++++------- core/types.py | 2 +- core/utils.py | 26 ++++++-- 10 files changed, 262 insertions(+), 80 deletions(-) create mode 100644 core/inference/utilities/animatediff.py diff --git a/core/flags.py b/core/flags.py index 3bbf25cc8..7dd47d61d 100644 --- a/core/flags.py +++ b/core/flags.py @@ -1,5 +1,5 @@ from dataclasses import dataclass, field -from typing import Literal +from typing import Literal, List from dataclasses_json.api import DataClassJsonMixin @@ -60,3 +60,21 @@ class SDXLRefinerFlag(Flag, DataClassJsonMixin): model: str = "" aesthetic_score: float = 6.0 negative_aesthetic_score: float = 2.5 + + +@dataclass +class AnimateDiffFlag(Flag, DataClassJsonMixin): + "Flag for AnimateDiff" + + motion_model: str = "" + frames: int = 16 + fps: int = 10 + + # only active when frames > 16 --> sliding context window. + frame_overlap: int = 4 # not working + + # increase processing time for decreased memory usage + chunk_feed_forward: bool = True # probably not working + + input_video: str = "" # not working + video_controlnets: List[str] = field(default_factory=list) # not working diff --git a/core/inference/pytorch/pipeline.py b/core/inference/pytorch/pipeline.py index f1027ec94..d1422dfed 100644 --- a/core/inference/pytorch/pipeline.py +++ b/core/inference/pytorch/pipeline.py @@ -2,6 +2,7 @@ from contextlib import ExitStack from typing import Any, Callable, Dict, List, Literal, Optional, Union +import inspect import PIL import torch @@ -39,6 +40,7 @@ preprocess_image, ) from core.inference.utilities.philox import PhiloxGenerator +from core.flags import AnimateDiffFlag from core.optimizations import ensure_correct_device, inference_context, unload_all from core.scheduling import KdiffusionSchedulerAdapter @@ -287,6 +289,7 @@ def __call__( prompt_expansion_settings: Optional[Dict] = None, adapter_conditioning_scale: Union[float, List[float]] = 1.0, adapter_conditioning_factor: float = 1.0, + animatediff: Optional[AnimateDiffFlag] = None, ): r""" Function invoked when calling the pipeline for generation. @@ -363,7 +366,15 @@ def __call__( (nsfw) content, according to the `safety_checker`. """ - with inference_context(self.unet, self.vae, height, width) as inf: + animatediff = AnimateDiffFlag( + motion_model="guoyww/animatediff-motion-adapter-v1-5-2", + frames=16, + chunk_feed_forward=True, + ) + + with inference_context( + self.unet, self.vae, height, width, [animatediff] + ) as inf: # 0. Modify unet and vae to the (optionally) modified versions from inf self.unet = inf.unet # type: ignore self.vae = inf.vae # type: ignore @@ -486,8 +497,9 @@ def __call__( dtype, device, generator, - latents, + latents=latents, latent_channels=None if mask is None else self.vae.config.latent_channels, # type: ignore + frames=None if animatediff is None else animatediff.frames, ) # 7. Prepare extra step kwargs. TODO: Logic should ideally just be moved out of the pipeline @@ -601,10 +613,20 @@ def do_denoise( ) change_source(self.unet) + kwargs = set( + inspect.signature(self.unet.forward).parameters.keys() # type: ignore + ) if split_latents_into_two and do_classifier_free_guidance: uncond, cond = text_embeddings.chunk(2) - uncond_down, cond_down = down_block_res_samples.chunk(2) # type: ignore - uncond_mid, cond_mid = mid_block_res_sample.chunk(2) # type: ignore + uncond_down, uncond_mid, cond_down, cond_mid = ( + None, + None, + None, + None, + ) + if down_block_res_samples is not None: + uncond_down, cond_down = down_block_res_samples.chunk(2) # type: ignore + uncond_mid, cond_mid = mid_block_res_sample.chunk(2) # type: ignore uncond_intra, cond_intra = None, None if down_intrablock_additional_residuals is not None: uncond_intra, cond_intra = [], [] @@ -612,36 +634,50 @@ def do_denoise( unc, cnd = s.chunk(2) uncond_intra.append(unc) cond_intra.append(cnd) - noise_pred_text = call( - latent_model_input, - t, - cond=cond, - down_block_additional_residuals=cond_down, - mid_block_additional_residual=cond_mid, - down_intrablock_additional_residuals=cond_intra, - ) + _kwargs = { + "down_block_additional_residuals": cond_down, + "mid_block_additional_residual": cond_mid, + "down_intrablock_additional_residuals": cond_intra, + } + for kw, _ in _kwargs.copy().items(): + if kw not in kwargs: + del _kwargs[kw] + noise_pred_text = call(latent_model_input, t, cond=cond, **_kwargs) + + _kwargs = { + "down_block_additional_residuals": uncond_down, + "mid_block_additional_residual": uncond_mid, + "down_intrablock_additional_residuals": uncond_intra, + } + for kw, _ in _kwargs.copy().items(): + if kw not in kwargs: + del _kwargs[kw] noise_pred_uncond = call( - latent_model_input, - t, - cond=uncond, - down_block_additional_residuals=uncond_down, - mid_block_additional_residual=uncond_mid, - down_intrablock_additional_residuals=uncond_intra, + latent_model_input, t, cond=uncond, **_kwargs ) else: + _kwargs = { + "down_block_additional_residuals": down_block_res_samples, + "mid_block_additional_residual": mid_block_res_sample, + "down_intrablock_additional_residuals": down_intrablock_additional_residuals, + } + for kw, _ in _kwargs.copy().items(): + if kw not in kwargs: + del _kwargs[kw] noise_pred = call( # type: ignore - latent_model_input, - t, - cond=text_embeddings, - down_block_additional_residuals=down_block_res_samples, - mid_block_additional_residual=mid_block_res_sample, - down_intrablock_additional_residuals=down_intrablock_additional_residuals, + latent_model_input, t, cond=text_embeddings, **_kwargs ) # perform guidance if do_classifier_free_guidance: if not split_latents_into_two: + if isinstance(noise_pred, tuple): # type: ignore + noise_pred = noise_pred[0] noise_pred_uncond, noise_pred_text = noise_pred.chunk(2) # type: ignore + if isinstance(noise_pred_text, tuple): # type: ignore + noise_pred_text = noise_pred_text[0] + if isinstance(noise_pred_uncond, tuple): # type: ignore + noise_pred_uncond = noise_pred_uncond[0] noise_pred = calculate_cfg( noise_pred_text, noise_pred_uncond, guidance_scale, t # type: ignore ) diff --git a/core/inference/utilities/animatediff.py b/core/inference/utilities/animatediff.py new file mode 100644 index 000000000..a7cf3d302 --- /dev/null +++ b/core/inference/utilities/animatediff.py @@ -0,0 +1 @@ +# AnimateDiff is NCFHW (batch, channels, frames, height, width) diff --git a/core/inference/utilities/latents.py b/core/inference/utilities/latents.py index e437793fa..f0716561a 100644 --- a/core/inference/utilities/latents.py +++ b/core/inference/utilities/latents.py @@ -272,17 +272,27 @@ def prepare_latents( dtype: torch.dtype, device: torch.device, generator: Union[PhiloxGenerator, torch.Generator], + frames: Optional[int] = None, latents=None, latent_channels: Optional[int] = None, align_to: int = 1, ): if image is None: - shape = ( - batch_size, - pipe.unet.config.in_channels, # type: ignore - (math.ceil(height / align_to) * align_to) // pipe.vae_scale_factor, # type: ignore - (math.ceil(width / align_to) * align_to) // pipe.vae_scale_factor, # type: ignore - ) + if frames is not None: + shape = ( + batch_size, + pipe.unet.config.in_channels, + frames, + (math.ceil(height / align_to) * align_to) // pipe.vae_scale_factor, # type: ignore + (math.ceil(width / align_to) * align_to) // pipe.vae_scale_factor, # type: ignore + ) + else: + shape = ( + batch_size, + pipe.unet.config.in_channels, # type: ignore + (math.ceil(height / align_to) * align_to) // pipe.vae_scale_factor, # type: ignore + (math.ceil(width / align_to) * align_to) // pipe.vae_scale_factor, # type: ignore + ) if latents is None: # randn does not work reproducibly on mps diff --git a/core/inference/utilities/vae.py b/core/inference/utilities/vae.py index b232fcd22..d48b92104 100644 --- a/core/inference/utilities/vae.py +++ b/core/inference/utilities/vae.py @@ -1,5 +1,6 @@ from contextlib import ExitStack -from typing import Callable, Optional +from typing import Callable, Optional, Union, List +from io import BytesIO import numpy as np import torch @@ -37,12 +38,11 @@ def taesd( ) -def cheap_approximation(sample: torch.Tensor) -> Image.Image: +def cheap_approximation(sample: torch.Tensor) -> Union[BytesIO, Image.Image]: "Convert a tensor of latents to RGB" # Credit to Automatic111 stable-diffusion-webui # https://discuss.huggingface.co/t/decoding-latents-to-rgb-without-upscaling/23204/2 - coeffs = [ [0.298, 0.207, 0.208], [0.187, 0.286, 0.173], @@ -57,7 +57,27 @@ def cheap_approximation(sample: torch.Tensor) -> Image.Image: [-0.3730, -0.2499, -0.2088], ] coeffs = torch.tensor(coeffs, dtype=torch.float32, device="cpu") - + if sample.dim() == 4: + decoded_rgb = torch.einsum( + "lfxy,lr -> frxy", sample.to(torch.float32).to("cpu"), coeffs + ) + decoded_rgb = torch.clamp((decoded_rgb + 1.0) / 2.0, min=0.0, max=1.0) + + decoded_rgb = 255.0 * np.moveaxis(decoded_rgb.cpu().numpy(), 1, -1) + decoded_rgb = decoded_rgb.astype(np.uint8) + + buffer = BytesIO() + images = [Image.fromarray(frame) for frame in decoded_rgb] + images[0].save( + buffer, + "gif", + save_all=True, + append_images=images[1:], + loop=0, + optimize=True, + subrectangles=True, + ) + return buffer decoded_rgb = torch.einsum( "lxy,lr -> rxy", sample.to(torch.float32).to("cpu"), coeffs ) @@ -74,7 +94,7 @@ def full_vae( height: Optional[int] = None, width: Optional[int] = None, ) -> np.ndarray: - ensure_correct_device(vae) + ensure_correct_device(vae) # type: ignore def decode(sample): with ExitStack() as gs: @@ -82,12 +102,27 @@ def decode(sample): gs.enter_context(autocast(dtype=torch.float32)) return vae.decode(sample, return_dict=False)[0] - return decode_latents( - decode, # type: ignore - samples, - height or samples[0].shape[1] * 8, - width or samples[0].shape[2] * 8, - ) + if samples.dim() == 5: + return torch.tensor( + np.array( # this is here since torch thinks itll be faster like this + [ + decode_latents( + decode, # type: ignore + samples[x].permute(1, 0, 2, 3), + height or samples[0].shape[1] * 8, + width or samples[0].shape[2] * 8, + ) + for x in range(samples.shape[0]) + ] + ) + ).numpy() + else: + return decode_latents( + decode, # type: ignore + samples, + height or samples[0].shape[1] * 8, + width or samples[0].shape[2] * 8, + ) def decode_latents( @@ -107,13 +142,34 @@ def decode_latents( return img -def numpy_to_pil(images: np.ndarray): +def numpy_to_pil(images: np.ndarray) -> List[Union[BytesIO, Image.Image]]: """ Convert a numpy image or a batch of images to a PIL image. """ - if images.ndim == 3: - images = images[None, ...] - images = (images * 255).round().astype(np.uint8) - pil_images = [Image.fromarray(image) for image in images] + pil_images: List[Union[BytesIO, Image.Image]] = [] + if images.ndim == 5: + for image in images: + frames_done: List[Image.Image] = [] + for frame in image: + frame: np.ndarray = (frame * 255).round().astype(np.uint8) + frames_done.append(Image.fromarray(frame)) + + buffer = BytesIO() + frames_done[0].save( + buffer, + "gif", + save_all=True, + append_images=frames_done[1:], + loop=0, + optimize=True, + subrectangles=True, + ) + + pil_images.append(buffer) + else: + if images.ndim == 3: + images = images[None, ...] + images = (images * 255).round().astype(np.uint8) + pil_images = [Image.fromarray(image) for image in images] return pil_images diff --git a/core/inference_callbacks.py b/core/inference_callbacks.py index bf73938db..14130da92 100644 --- a/core/inference_callbacks.py +++ b/core/inference_callbacks.py @@ -1,5 +1,6 @@ import time -from typing import List +from typing import Union, List +from io import BytesIO import torch from PIL import Image @@ -31,14 +32,14 @@ def callback(step: int, _timestep: int, tensor: torch.Tensor): (time.time() - last_image_time > config.api.live_preview_delay) ) - images: List[Image.Image] = [] + images: List[Union[BytesIO, Image.Image]] = [] if send_image: last_image_time = time.time() if config.api.live_preview_method == "approximation": for t in range(tensor.shape[0]): images.append(cheap_approximation(tensor[t])) else: - for img in numpy_to_pil(taesd(tensor)): + for img in numpy_to_pil(taesd(tensor)): # type: ignore images.append(img) websocket_manager.broadcast_sync( diff --git a/core/optimizations/context_manager.py b/core/optimizations/context_manager.py index e1cccc4f4..d975d0d64 100644 --- a/core/optimizations/context_manager.py +++ b/core/optimizations/context_manager.py @@ -1,9 +1,15 @@ from contextlib import ExitStack +from typing import List, Optional import torch +from diffusers.models.autoencoder_kl import AutoencoderKL +from diffusers.models.unet_2d_condition import UNet2DConditionModel +from diffusers.models.unet_motion_model import UNetMotionModel, MotionAdapter from core.config import config +from core.flags import AnimateDiffFlag, Flag from .autocast_utils import autocast +from .dtype import cast from .hypertile import is_hypertile_available, hypertile @@ -12,19 +18,51 @@ class InferenceContext(ExitStack): unet: torch.nn.Module vae: torch.nn.Module + components: dict = {} + def to(self, device: str, dtype: torch.dtype): + self.unet.to(device=device, dtype=dtype) + self.vae.to(device=device, dtype=dtype) -def inference_context(unet, vae, height, width) -> InferenceContext: + +def inference_context( + unet: UNet2DConditionModel, + vae: AutoencoderKL, + height: int, + width: int, + flags: List[Optional[Flag]] = [], +) -> InferenceContext: "Helper function for centralizing context management" s = InferenceContext() s.unet = unet s.vae = vae + s.components = {"unet": unet, "vae": vae} s.enter_context( autocast( config.api.load_dtype, disable=config.api.autocast and not unet.force_autocast, ) ) + animatediff = [x for x in flags if isinstance(x, AnimateDiffFlag)] + print(len(flags) - len(animatediff)) + if len(animatediff) != 0: + flag: AnimateDiffFlag = animatediff[0] + motion_adapter: MotionAdapter = MotionAdapter.from_pretrained(flag.motion_model) # type: ignore + motion_adapter.to(dtype=config.api.load_dtype, device=config.api.device) + + offload = s.unet.device.type == "cpu" + + s.unet = UNetMotionModel.from_unet2d( # type: ignore + s.unet, motion_adapter # type: ignore + ) + + if flag.chunk_feed_forward: + s.unet.enable_forward_chunking() # type: ignore + + s.components.update({"unet": s.unet}) + cast(s, device=config.api.device, dtype=config.api.dtype, offload=offload) # type: ignore + + s.unet.to(dtype=config.api.load_dtype, device=config.api.device) # type: ignore if is_hypertile_available() and config.api.hypertile: s.enter_context(hypertile(unet, height, width)) if config.api.torch_compile: diff --git a/core/png_metadata.py b/core/png_metadata.py index 51c426e19..0c7f13bac 100644 --- a/core/png_metadata.py +++ b/core/png_metadata.py @@ -34,6 +34,7 @@ def create_metadata( UpscaleQueueEntry, ], index: int, + extension: str, ): "Return image with metadata burned into it" @@ -51,7 +52,7 @@ def write_metadata_text(key: str): def write_metadata_exif(key: str): exif_meta_dict[key] = str(unwrap_enum_name(data.__dict__.get(key, ""))) - if config.api.image_extension == "png": + if extension == "png": for key in fields(data): if key.name not in ("image", "mask_image"): write_metadata_text(key.name) @@ -73,7 +74,7 @@ def write_metadata_exif(key: str): else: procedure = "unknown" - if config.api.image_extension == "png": + if extension == "png": text_metadata.add_text("procedure", procedure) text_metadata.add_text("model", job.model) user_comment: bytes = b"" # for type checking @@ -85,7 +86,7 @@ def write_metadata_exif(key: str): json.dumps(exif_meta_dict, ensure_ascii=False), encoding="unicode" ) - return text_metadata if config.api.image_extension == "png" else user_comment + return text_metadata if extension == "png" else user_comment def save_images( @@ -138,7 +139,8 @@ def save_images( else: folder = "img2img" - metadata = create_metadata(job, i) + extension = "gif" if isinstance(image, BytesIO) else config.api.image_extension + metadata = create_metadata(job, i, extension=extension) if job.save_image == "r2": # Save into Cloudflare R2 bucket @@ -148,7 +150,7 @@ def save_images( filename = f"{job.data.id}-{i}.png" image_bytes = BytesIO() - image.save(image_bytes, pnginfo=metadata, format=config.api.image_extension) + image.save(image_bytes, pnginfo=metadata, format=extension) image_bytes.seek(0) url = r2.upload_file(file=image_bytes, filename=filename) @@ -168,7 +170,7 @@ def save_images( if not isinstance(job, UpscaleQueueEntry) else "0", "index": i, - "extension": config.api.image_extension, + "extension": extension, } ) @@ -179,24 +181,30 @@ def save_images( with path.open("wb") as f: logger.debug(f"Saving image to {path.as_posix()}") - if config.api.image_extension == "png": + if extension == "png": image.save(f, pnginfo=metadata) else: - # ! This is using 2 filesystem calls, find a way to save directly to disk with metadata properly inserted - # Save the image - image.save(f, quality=config.api.image_quality) - - # Insert metadata - exif_metadata = { - "0th": {}, - "Exif": Image.Exif(), - "GPS": {}, - "Interop": {}, - "1st": {}, - } - exif_metadata["Exif"][piexif.ExifIFD.UserComment] = metadata - exif_bytes = piexif.dump(exif_metadata) - piexif.insert(exif_bytes, path.as_posix()) + buffer = BytesIO() + if extension == "gif": + buffer: BytesIO = image + else: + image.save(buffer, quality=config.api.image_quality) + + if extension == "gif": + buffer.seek(0) + f.write(buffer.getbuffer()) + else: + # Insert metadata + exif_metadata = { + "0th": {}, + "Exif": Image.Exif(), + "GPS": {}, + "Interop": {}, + "1st": {}, + } + exif_metadata["Exif"][piexif.ExifIFD.UserComment] = metadata + exif_bytes = piexif.dump(exif_metadata) + piexif.insert(exif_bytes, buffer, f) return urls diff --git a/core/types.py b/core/types.py index 2bd054a46..da86ebbb9 100644 --- a/core/types.py +++ b/core/types.py @@ -42,7 +42,7 @@ "Unknown", ] PyTorchModelStage = Literal["text_encoding", "first_stage", "last_stage"] -ImageFormats = Literal["png", "jpeg", "webp"] +ImageFormats = Literal["png", "jpeg", "webp", "gif"] @dataclass diff --git a/core/utils.py b/core/utils.py index 355042d9a..5330e54a5 100644 --- a/core/utils.py +++ b/core/utils.py @@ -56,10 +56,16 @@ def get_grid_dimension(length: int) -> Tuple[int, int]: def convert_image_to_stream( - image: Image.Image, quality: int = 95, _format: ImageFormats = "webp" + image: Union[BytesIO, Image.Image], + quality: int = 95, + _format: ImageFormats = "webp", ) -> BytesIO: "Convert an image to a stream of bytes" + if isinstance(image, BytesIO): + image.seek(0) + return image + assert image is Image.Image stream = BytesIO() image.save(stream, format=_format, quality=quality) stream.seek(0) @@ -173,7 +179,7 @@ def determine_model_type( def convert_image_to_base64( - image: Image.Image, + image: Union[BytesIO, Image.Image], quality: int = 95, image_format: ImageFormats = "webp", prefix_js: bool = True, @@ -220,6 +226,9 @@ async def run_in_thread_async( def image_grid(imgs: List[Image.Image]): "Make a grid of images" + if isinstance(imgs[0], BytesIO): + return imgs[0] + landscape: bool = imgs[0].size[1] >= imgs[0].size[0] dim = get_grid_dimension(len(imgs)) if landscape: @@ -236,15 +245,20 @@ def image_grid(imgs: List[Image.Image]): def convert_images_to_base64_grid( - images: List[Image.Image], + images: List[Union[BytesIO, Image.Image]], quality: int = 95, image_format: ImageFormats = "png", ) -> str: "Convert a list of images to a list of base64 strings" - return convert_image_to_base64( - image_grid(images), quality=quality, image_format=image_format - ) + if isinstance(images[0], BytesIO): + quality = max(quality - 20, 20) + return convert_image_to_base64(images[0], quality=quality, image_format="gif") + else: + assert images is List[Image.Image] + return convert_image_to_base64( + image_grid(images), quality=quality, image_format=image_format + ) def resize(image: Image.Image, w: int, h: int): From 0f2b7f45b0134b685aba9d95bf4f0db719cd4e8e Mon Sep 17 00:00:00 2001 From: gabe56f Date: Mon, 11 Dec 2023 22:21:31 +0100 Subject: [PATCH 103/143] AnimateDiff v2 --- core/flags.py | 7 + core/inference/pytorch/pipeline.py | 287 +++--- core/inference/utilities/animatediff.py | 1 - .../utilities/animatediff/__init__.py | 209 +++++ .../utilities/animatediff/models/__init__.py | 1 + .../utilities/animatediff/models/attention.py | 357 ++++++++ .../animatediff/models/motion_module.py | 339 +++++++ .../utilities/animatediff/models/resnet.py | 235 +++++ .../utilities/animatediff/models/unet.py | 614 +++++++++++++ .../animatediff/models/unet_blocks.py | 851 ++++++++++++++++++ core/optimizations/context_manager.py | 37 +- core/png_metadata.py | 2 +- data/motion-models/.gitkeep | 0 13 files changed, 2813 insertions(+), 127 deletions(-) delete mode 100644 core/inference/utilities/animatediff.py create mode 100644 core/inference/utilities/animatediff/__init__.py create mode 100644 core/inference/utilities/animatediff/models/__init__.py create mode 100644 core/inference/utilities/animatediff/models/attention.py create mode 100644 core/inference/utilities/animatediff/models/motion_module.py create mode 100644 core/inference/utilities/animatediff/models/resnet.py create mode 100644 core/inference/utilities/animatediff/models/unet.py create mode 100644 core/inference/utilities/animatediff/models/unet_blocks.py create mode 100644 data/motion-models/.gitkeep diff --git a/core/flags.py b/core/flags.py index 7dd47d61d..e1629a1fb 100644 --- a/core/flags.py +++ b/core/flags.py @@ -71,7 +71,14 @@ class AnimateDiffFlag(Flag, DataClassJsonMixin): fps: int = 10 # only active when frames > 16 --> sliding context window. + context_size: int = 16 + frame_stride: int = 1 frame_overlap: int = 4 # not working + context_scheduler: Literal[ + "uniform", "uniform_constant", "uniform_v2" + ] = "uniform_v2" + + closed_loop: bool = True # increase processing time for decreased memory usage chunk_feed_forward: bool = True # probably not working diff --git a/core/inference/pytorch/pipeline.py b/core/inference/pytorch/pipeline.py index d1422dfed..5f001a8e0 100644 --- a/core/inference/pytorch/pipeline.py +++ b/core/inference/pytorch/pipeline.py @@ -39,6 +39,7 @@ preprocess_adapter_image, preprocess_image, ) +from core.inference.utilities.animatediff import get_context_scheduler, nil_scheduler from core.inference.utilities.philox import PhiloxGenerator from core.flags import AnimateDiffFlag from core.optimizations import ensure_correct_device, inference_context, unload_all @@ -367,8 +368,9 @@ def __call__( """ animatediff = AnimateDiffFlag( - motion_model="guoyww/animatediff-motion-adapter-v1-5-2", - frames=16, + motion_model="data/motion-models/mm_sd_v15_v2.ckpt", + frames=64, + context_scheduler="uniform_v2", chunk_feed_forward=True, ) @@ -549,6 +551,26 @@ def get_map_size(_, __, output): # 8. Denoising loop j = 0 + context_scheduler = ( + get_context_scheduler(animatediff.context_scheduler) + if animatediff is not None + else nil_scheduler + ) + context_args = [] + if animatediff is not None: + if split_latents_into_two: + logger.warn( + "AnimateDiff doesn't work with non-merged latents! Disabling." + ) + split_latents_into_two = False + context_args = [ + animatediff.frames, + animatediff.context_size, + animatediff.frame_stride, + animatediff.frame_overlap, + animatediff.closed_loop, + ] + def do_denoise( x: torch.Tensor, t: torch.IntTensor, @@ -557,127 +579,170 @@ def do_denoise( ): nonlocal j # expand the latents if we are doing classifier free guidance - latent_model_input = ( - torch.cat([x] * 2) if do_classifier_free_guidance and not split_latents_into_two else x # type: ignore - ) - latent_model_input = self.scheduler.scale_model_input(latent_model_input, t) # type: ignore - - if num_channels_unet == 9: - latent_model_input = torch.cat([latent_model_input, mask, masked_image_latents], dim=1) # type: ignore - - # predict the noise residual - down_intrablock_additional_residuals = None - if hasattr(self, "adapter") and self.adapter is not None: - if j < cutoff: - assert adapter_state is not None - down_intrablock_additional_residuals = [ - state.clone() for state in adapter_state - ] + assert context_scheduler is not None + + noise_pred, counter = None, None + if animatediff is not None: + noise_pred = torch.zeros( + ( + x.shape[0] * (2 if do_classifier_free_guidance else 1), + *x.shape[1:], + ), + device=config.api.device, + dtype=config.api.load_dtype, + ) + counter = torch.zeros( + (1, 1, animatediff.frames, 1, 1), + device=config.api.device, + dtype=config.api.load_dtype, + ) - down_block_res_samples, mid_block_res_sample = None, None - if hasattr(self, "controlnet") and self.controlnet is not None: - if guess_mode and do_classifier_free_guidance: - # Infer ControlNet only for the conditional batch. - control_model_input = x - control_model_input = self.scheduler.scale_model_input(control_model_input, t).half() # type: ignore - controlnet_prompt_embeds = text_embeddings.chunk(2)[1] + for context in context_scheduler(j, *context_args): + if animatediff is not None: + latent_model_input = ( + x[:, :, context] + .to(device=self.unet.device) + .repeat(2 if do_classifier_free_guidance else 1, 1, 1, 1, 1) + ) else: - control_model_input = latent_model_input - controlnet_prompt_embeds = text_embeddings + latent_model_input = ( + torch.cat([x] * 2) if do_classifier_free_guidance and not split_latents_into_two else x # type: ignore + ) + latent_model_input = self.scheduler.scale_model_input(latent_model_input, t) # type: ignore + + if num_channels_unet == 9: + latent_model_input = torch.cat([latent_model_input, mask, masked_image_latents], dim=1) # type: ignore + + # predict the noise residual + down_intrablock_additional_residuals = None + if hasattr(self, "adapter") and self.adapter is not None: + if j < cutoff: + assert adapter_state is not None + down_intrablock_additional_residuals = [ + state.clone() for state in adapter_state + ] - cond_scale = controlnet_conditioning_scale * controlnet_keep[i] + down_block_res_samples, mid_block_res_sample = None, None + if hasattr(self, "controlnet") and self.controlnet is not None: + if guess_mode and do_classifier_free_guidance: + # Infer ControlNet only for the conditional batch. + control_model_input = x + control_model_input = self.scheduler.scale_model_input(control_model_input, t).half() # type: ignore + controlnet_prompt_embeds = text_embeddings.chunk(2)[1] + else: + control_model_input = latent_model_input + controlnet_prompt_embeds = text_embeddings + + cond_scale = controlnet_conditioning_scale * controlnet_keep[i] + + change_source(self.controlnet) + down_block_res_samples, mid_block_res_sample = call( + control_model_input, + t, + cond=controlnet_prompt_embeds, + controlnet_cond=image, + conditioning_scale=cond_scale, + guess_mode=guess_mode, + ) - change_source(self.controlnet) - down_block_res_samples, mid_block_res_sample = call( - control_model_input, - t, - cond=controlnet_prompt_embeds, - controlnet_cond=image, - conditioning_scale=cond_scale, - guess_mode=guess_mode, + if guess_mode and do_classifier_free_guidance: + # Infered ControlNet only for the conditional batch. + # To apply the output of ControlNet to both the unconditional and conditional batches, + # add 0 to the unconditional batch to keep it unchanged. + down_block_res_samples = [ + torch.cat([torch.zeros_like(d), d]) + for d in down_block_res_samples + ] + mid_block_res_sample = torch.cat( + [ + torch.zeros_like(mid_block_res_sample), + mid_block_res_sample, + ] + ) + + change_source(self.unet) + kwargs = set( + inspect.signature(self.unet.forward).parameters.keys() # type: ignore ) - if guess_mode and do_classifier_free_guidance: - # Infered ControlNet only for the conditional batch. - # To apply the output of ControlNet to both the unconditional and conditional batches, - # add 0 to the unconditional batch to keep it unchanged. - down_block_res_samples = [ - torch.cat([torch.zeros_like(d), d]) - for d in down_block_res_samples - ] - mid_block_res_sample = torch.cat( - [ - torch.zeros_like(mid_block_res_sample), - mid_block_res_sample, - ] + if split_latents_into_two and do_classifier_free_guidance: + uncond, cond = text_embeddings.chunk(2) + uncond_down, uncond_mid, cond_down, cond_mid = ( + None, + None, + None, + None, + ) + if down_block_res_samples is not None: + uncond_down, cond_down = down_block_res_samples.chunk(2) # type: ignore + uncond_mid, cond_mid = mid_block_res_sample.chunk(2) # type: ignore + uncond_intra, cond_intra = None, None + if down_intrablock_additional_residuals is not None: + uncond_intra, cond_intra = [], [] + for s in down_intrablock_additional_residuals: + unc, cnd = s.chunk(2) + uncond_intra.append(unc) + cond_intra.append(cnd) + _kwargs = { + "down_block_additional_residuals": cond_down, + "mid_block_additional_residual": cond_mid, + "down_intrablock_additional_residuals": cond_intra, + } + for kw, _ in _kwargs.copy().items(): + if kw not in kwargs: + del _kwargs[kw] + noise_pred_text = call( + latent_model_input, t, cond=cond, **_kwargs ) - change_source(self.unet) - kwargs = set( - inspect.signature(self.unet.forward).parameters.keys() # type: ignore - ) - if split_latents_into_two and do_classifier_free_guidance: - uncond, cond = text_embeddings.chunk(2) - uncond_down, uncond_mid, cond_down, cond_mid = ( - None, - None, - None, - None, - ) - if down_block_res_samples is not None: - uncond_down, cond_down = down_block_res_samples.chunk(2) # type: ignore - uncond_mid, cond_mid = mid_block_res_sample.chunk(2) # type: ignore - uncond_intra, cond_intra = None, None - if down_intrablock_additional_residuals is not None: - uncond_intra, cond_intra = [], [] - for s in down_intrablock_additional_residuals: - unc, cnd = s.chunk(2) - uncond_intra.append(unc) - cond_intra.append(cnd) - _kwargs = { - "down_block_additional_residuals": cond_down, - "mid_block_additional_residual": cond_mid, - "down_intrablock_additional_residuals": cond_intra, - } - for kw, _ in _kwargs.copy().items(): - if kw not in kwargs: - del _kwargs[kw] - noise_pred_text = call(latent_model_input, t, cond=cond, **_kwargs) - - _kwargs = { - "down_block_additional_residuals": uncond_down, - "mid_block_additional_residual": uncond_mid, - "down_intrablock_additional_residuals": uncond_intra, - } - for kw, _ in _kwargs.copy().items(): - if kw not in kwargs: - del _kwargs[kw] - noise_pred_uncond = call( - latent_model_input, t, cond=uncond, **_kwargs - ) - else: - _kwargs = { - "down_block_additional_residuals": down_block_res_samples, - "mid_block_additional_residual": mid_block_res_sample, - "down_intrablock_additional_residuals": down_intrablock_additional_residuals, - } - for kw, _ in _kwargs.copy().items(): - if kw not in kwargs: - del _kwargs[kw] - noise_pred = call( # type: ignore - latent_model_input, t, cond=text_embeddings, **_kwargs - ) + _kwargs = { + "down_block_additional_residuals": uncond_down, + "mid_block_additional_residual": uncond_mid, + "down_intrablock_additional_residuals": uncond_intra, + } + for kw, _ in _kwargs.copy().items(): + if kw not in kwargs: + del _kwargs[kw] + noise_pred_uncond = call( + latent_model_input, t, cond=uncond, **_kwargs + ) + else: + _kwargs = { + "down_block_additional_residuals": down_block_res_samples, + "mid_block_additional_residual": mid_block_res_sample, + "down_intrablock_additional_residuals": down_intrablock_additional_residuals, + } + for kw, _ in _kwargs.copy().items(): + if kw not in kwargs: + del _kwargs[kw] + + if animatediff is not None: + assert noise_pred is not None + assert counter is not None + noise_pred[:, :, context] = ( + noise_pred[:, :, context] + + call( + latent_model_input, + t, + cond=text_embeddings, + **_kwargs, + )[0] + ) + counter[:, :, context] = counter[:, :, context] + 1 + else: + noise_pred = call( # type: ignore + latent_model_input, t, cond=text_embeddings, **_kwargs + ) # perform guidance if do_classifier_free_guidance: if not split_latents_into_two: - if isinstance(noise_pred, tuple): # type: ignore - noise_pred = noise_pred[0] - noise_pred_uncond, noise_pred_text = noise_pred.chunk(2) # type: ignore - if isinstance(noise_pred_text, tuple): # type: ignore - noise_pred_text = noise_pred_text[0] - if isinstance(noise_pred_uncond, tuple): # type: ignore - noise_pred_uncond = noise_pred_uncond[0] + if animatediff is not None: + assert noise_pred is not None + assert counter is not None + noise_pred_uncond, noise_pred_text = (noise_pred / counter).chunk(2) # type: ignore + else: + noise_pred_uncond, noise_pred_text = noise_pred.chunk(2) # type: ignore noise_pred = calculate_cfg( noise_pred_text, noise_pred_uncond, guidance_scale, t # type: ignore ) diff --git a/core/inference/utilities/animatediff.py b/core/inference/utilities/animatediff.py deleted file mode 100644 index a7cf3d302..000000000 --- a/core/inference/utilities/animatediff.py +++ /dev/null @@ -1 +0,0 @@ -# AnimateDiff is NCFHW (batch, channels, frames, height, width) diff --git a/core/inference/utilities/animatediff/__init__.py b/core/inference/utilities/animatediff/__init__.py new file mode 100644 index 000000000..c560d178c --- /dev/null +++ b/core/inference/utilities/animatediff/__init__.py @@ -0,0 +1,209 @@ +# AnimateDiff is NCFHW (batch, channels, frames, height, width) + +from typing import Callable, Optional + +import torch +import einops +import numpy as np + +from core.config import config +from core.optimizations import InferenceContext +from core.flags import AnimateDiffFlag + + +def memory_required(input_shape: tuple): + area = input_shape[1] * input_shape[2] * input_shape[3] + if any([config.api.attention_processor == x for x in ["xformers", "sdpa"]]): + dtype_size = ( + 2 + if any( + [config.api.load_dtype == x for x in [torch.float16, torch.bfloat16]] + ) + else 4 + ) + return (area * dtype_size / 50) * (1024 * 1024) + else: + return (((area * 0.6) / 0.9) + 1024) * (1024 * 1024) + + +def groupnorm_factory(flag: AnimateDiffFlag): + def groupnorm_mm_forward(self, input: torch.Tensor) -> torch.Tensor: + # axes_factor normalizes batch based on total conds and unconds passed in batch; + # the conds and unconds per batch can change based on VRAM optimizations that may kick in + if not flag.frames > 16: + axes_factor = input.size(0) // flag.frames + else: + axes_factor = input.size(0) // flag.context_size + + input = einops.rearrange(input, "(b f) c h w -> b c f h w", b=axes_factor) + input = torch.nn.functional.group_norm( + input, self.num_groups, self.weight, self.bias, self.eps + ) + input = einops.rearrange(input, "b c f h w -> (b f) c h w", b=axes_factor) + return input + + return groupnorm_mm_forward + + +def ordered_halving(val): + "Returns fraction that has denominator that is a power of 2" + + bin_str = f"{val:064b}" + bin_flip = bin_str[::-1] + as_int = int(bin_flip, 2) + final = as_int / (1 << 64) + return final + + +# Generator that returns lists of latent indeces to diffuse on +def uniform( + step: int = 0, + num_frames: int = 0, + context_size: Optional[int] = None, + context_stride: int = 3, + context_overlap: int = 4, + closed_loop: bool = True, +): + if num_frames <= context_size: # type: ignore + yield list(range(num_frames)) + return + + context_stride = min( + context_stride, int(np.ceil(np.log2(num_frames / context_size))) + 1 # type: ignore + ) + + for context_step in 1 << np.arange(context_stride): + pad = int(round(num_frames * ordered_halving(step))) + for j in range( + int(ordered_halving(step) * context_step) + pad, + num_frames + pad + (0 if closed_loop else -context_overlap), + (context_size * context_step - context_overlap), + ): + yield [ + e % num_frames + for e in range(j, j + context_size * context_step, context_step) + ] + + +def uniform_v2( + step: int = 0, + num_frames: int = 0, + context_size: Optional[int] = None, + context_stride: int = 3, + context_overlap: int = 4, + closed_loop: bool = True, +): + if num_frames <= context_size: # type: ignore + yield list(range(num_frames)) + return + + context_stride = min( + context_stride, int(np.ceil(np.log2(num_frames / context_size))) + 1 # type: ignore + ) + + pad = int(round(num_frames * ordered_halving(step))) + for context_step in 1 << np.arange(context_stride): + j_initial = int(ordered_halving(step) * context_step) + pad + for j in range( + j_initial, + num_frames + pad - context_overlap, + (context_size * context_step - context_overlap), + ): + if context_size * context_step > num_frames: + # On the final context_step, + # ensure no frame appears in the window twice + yield [e % num_frames for e in range(j, j + num_frames, context_step)] + continue + j = j % num_frames + if j > (j + context_size * context_step) % num_frames and not closed_loop: + yield [e for e in range(j, num_frames, context_step)] + j_stop = (j + context_size * context_step) % num_frames + # When ((num_frames % (context_size - context_overlap)+context_overlap) % context_size != 0, + # This can cause 'superflous' runs where all frames in + # a context window have already been processed during + # the first context window of this stride and step. + # While the following commented if should prevent this, + # I believe leaving it in is more correct as it maintains + # the total conditional passes per frame over a large total steps + # if j_stop > context_overlap: + yield [e for e in range(0, j_stop, context_step)] + continue + yield [ + e % num_frames + for e in range(j, j + context_size * context_step, context_step) + ] + + +def uniform_constant( + step: int = 0, + num_frames: int = 0, + context_size: Optional[int] = None, + context_stride: int = 3, + context_overlap: int = 4, + closed_loop: bool = True, +): + if num_frames <= context_size: # type: ignore + yield list(range(num_frames)) + return + + context_stride = min(context_stride, int(np.ceil(np.log2(num_frames / context_size))) + 1) # type: ignore + + for context_step in 1 << np.arange(context_stride): + pad = int(round(num_frames * ordered_halving(step))) + for j in range( + int(ordered_halving(step) * context_step) + pad, + num_frames + pad + (0 if closed_loop else -context_overlap), + (context_size * context_step - context_overlap), + ): + skip_this_window = False + prev_val = -1 + to_yield = [] + for e in range(j, j + context_size * context_step, context_step): + e = e % num_frames + if not closed_loop and e < prev_val: + skip_this_window = True + break + to_yield.append(e) + prev_val = e + if skip_this_window: + continue + yield to_yield + + +UNIFORM_CONTEXT_MAPPING = { + "uniform": uniform, + "uniform_constant": uniform_constant, + "uniform_v2": uniform_v2, +} + + +def get_context_scheduler(name: str): + context_func = UNIFORM_CONTEXT_MAPPING.get(name, None) + assert context_func is not None + return context_func + + +def nil_scheduler(*args, **kwargs): + yield 0 + + +def patch(context: InferenceContext) -> InferenceContext: + global n + + n = None + + flag: AnimateDiffFlag | None = context.get_flag(AnimateDiffFlag) # type: ignore + assert flag is not None + + # def replace_groupnorm_forward(module): + # if isinstance(module, torch.nn.GroupNorm): + # module.forward = groupnorm_factory(module, flag) + # for m in module.modules(): + # replace_groupnorm_forward(m) + # + # for module in context.unet.modules(): + # replace_groupnorm_forward(module) + + # torch.nn.GroupNorm.forward = groupnorm_factory(flag) + + return context diff --git a/core/inference/utilities/animatediff/models/__init__.py b/core/inference/utilities/animatediff/models/__init__.py new file mode 100644 index 000000000..752607f84 --- /dev/null +++ b/core/inference/utilities/animatediff/models/__init__.py @@ -0,0 +1 @@ +MMV2_DIM_KEY = "up_blocks.0.motion_modules.1.temporal_transformer.transformer_blocks.0.attention_blocks.0.pos_encoder.pe" diff --git a/core/inference/utilities/animatediff/models/attention.py b/core/inference/utilities/animatediff/models/attention.py new file mode 100644 index 000000000..4e6a66e3b --- /dev/null +++ b/core/inference/utilities/animatediff/models/attention.py @@ -0,0 +1,357 @@ +# Adapted from https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/attention.py + +from dataclasses import dataclass +from typing import Any, Dict, Optional + +import torch +from diffusers.configuration_utils import ConfigMixin, register_to_config +from diffusers.models import ModelMixin # type: ignore +from diffusers.models.attention import AdaLayerNorm, Attention, FeedForward # type: ignore +from diffusers.utils import BaseOutput # type: ignore +from einops import rearrange, repeat +from torch import Tensor, nn +from torch._dynamo import allow_in_graph as maybe_allow_in_graph + + +@dataclass +class Transformer3DModelOutput(BaseOutput): + sample: torch.FloatTensor + + +@maybe_allow_in_graph +class Transformer3DModel(ModelMixin, ConfigMixin): + @register_to_config + def __init__( + self, + num_attention_heads: int = 16, + attention_head_dim: int = 88, + in_channels: Optional[int] = None, + num_layers: int = 1, + dropout: float = 0.0, + norm_num_groups: int = 32, + cross_attention_dim: Optional[int] = None, + attention_bias: bool = False, + activation_fn: str = "geglu", + num_embeds_ada_norm: Optional[int] = None, + use_linear_projection: bool = False, + only_cross_attention: bool = False, + upcast_attention: bool = False, + unet_use_cross_frame_attention=None, + unet_use_temporal_attention=None, + ): + super().__init__() + self.use_linear_projection = use_linear_projection + self.num_attention_heads = num_attention_heads + self.attention_head_dim = attention_head_dim + inner_dim = num_attention_heads * attention_head_dim + + # Define input layers + self.in_channels = in_channels + + self.norm = torch.nn.GroupNorm( + num_groups=norm_num_groups, num_channels=in_channels, eps=1e-6, affine=True # type: ignore + ) + if use_linear_projection: + self.proj_in = nn.Linear(in_channels, inner_dim) # type: ignore + else: + self.proj_in = nn.Conv2d( + in_channels, inner_dim, kernel_size=1, stride=1, padding=0 # type: ignore + ) + + # Define transformers blocks + self.transformer_blocks = nn.ModuleList( + [ + BasicTransformerBlock( + inner_dim, + num_attention_heads, + attention_head_dim, + dropout=dropout, + cross_attention_dim=cross_attention_dim, + activation_fn=activation_fn, + num_embeds_ada_norm=num_embeds_ada_norm, + attention_bias=attention_bias, + only_cross_attention=only_cross_attention, + upcast_attention=upcast_attention, + unet_use_cross_frame_attention=unet_use_cross_frame_attention, # type: ignore + unet_use_temporal_attention=unet_use_temporal_attention, # type: ignore + ) + for d in range(num_layers) + ] + ) + + # 4. Define output layers + if use_linear_projection: + self.proj_out = nn.Linear(in_channels, inner_dim) # type: ignore + else: + self.proj_out = nn.Conv2d( + inner_dim, in_channels, kernel_size=1, stride=1, padding=0 # type: ignore + ) + + def forward( + self, + hidden_states: torch.Tensor, + encoder_hidden_states: Optional[torch.Tensor] = None, + timestep: Optional[torch.LongTensor] = None, + cross_attention_kwargs: Dict[str, Any] = None, # type: ignore + attention_mask: Optional[torch.Tensor] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + return_dict: bool = True, + ) -> tuple[Tensor] | Transformer3DModelOutput: + # validate input dim + if hidden_states.dim() != 5: + raise ValueError( + f"Expected hidden_states to have ndim=5, but got ndim={hidden_states.dim()}." + ) + + # ensure attention_mask is a bias, and give it a singleton query_tokens dimension. + # we may have done this conversion already, e.g. if we came here via UNet2DConditionModel#forward. + # we can tell by counting dims; if ndim == 2: it's a mask rather than a bias. + # expects mask of shape: + # [batch, key_tokens] + # adds singleton query_tokens dimension: + # [batch, 1, key_tokens] + # this helps to broadcast it as a bias over attention scores, which will be in one of the following shapes: + # [batch, heads, query_tokens, key_tokens] (e.g. torch sdp attn) + # [batch * heads, query_tokens, key_tokens] (e.g. xformers or classic attn) + if attention_mask is not None and attention_mask.ndim == 2: + # assume that mask is expressed as: + # (1 = keep, 0 = discard) + # convert mask into a bias that can be added to attention scores: + # (keep = +0, discard = -10000.0) + attention_mask = (1 - attention_mask.to(hidden_states.dtype)) * -10000.0 + attention_mask = attention_mask.unsqueeze(1) + + # convert encoder_attention_mask to a bias the same way we do for attention_mask + if encoder_attention_mask is not None and encoder_attention_mask.ndim == 2: + encoder_attention_mask = ( + 1 - encoder_attention_mask.to(hidden_states.dtype) + ) * -10000.0 + encoder_attention_mask = encoder_attention_mask.unsqueeze(1) + + # shenanigans for motion module + video_length = hidden_states.shape[2] + hidden_states = rearrange(hidden_states, "b c f h w -> (b f) c h w") + encoder_hidden_states = repeat( + encoder_hidden_states, "b n c -> (b f) n c", f=video_length + ) + + # 1. Input + batch, _, height, width = hidden_states.shape + residual = hidden_states + + hidden_states = self.norm(hidden_states) + if not self.use_linear_projection: + hidden_states = self.proj_in(hidden_states) + inner_dim = hidden_states.shape[1] + hidden_states = hidden_states.permute(0, 2, 3, 1).reshape( + batch, height * width, inner_dim + ) + else: + inner_dim = hidden_states.shape[1] + hidden_states = hidden_states.permute(0, 2, 3, 1).reshape( + batch, height * width, inner_dim + ) + hidden_states = self.proj_in(hidden_states) + + # 2. Blocks + for block in self.transformer_blocks: + hidden_states = block( + hidden_states, + attention_mask=attention_mask, + encoder_hidden_states=encoder_hidden_states, + timestep=timestep, + video_length=video_length, + encoder_attention_mask=encoder_attention_mask, + cross_attention_kwargs=cross_attention_kwargs, + ) + + # 3. Output + if not self.use_linear_projection: + hidden_states = ( + hidden_states.reshape(batch, height, width, inner_dim) + .permute(0, 3, 1, 2) + .contiguous() + ) + hidden_states = self.proj_out(hidden_states) + else: + hidden_states = self.proj_out(hidden_states) + hidden_states = ( + hidden_states.reshape(batch, height, width, inner_dim) + .permute(0, 3, 1, 2) + .contiguous() + ) + + output = hidden_states + residual + + output = rearrange(output, "(b f) c h w -> b c f h w", f=video_length) + if not return_dict: + return (output,) + + return Transformer3DModelOutput(sample=output) # type: ignore + + +@maybe_allow_in_graph +class BasicTransformerBlock(nn.Module): + def __init__( + self, + dim: int, + num_attention_heads: int, + attention_head_dim: int, + dropout: float = 0.0, + cross_attention_dim: Optional[int] = None, + activation_fn: str = "geglu", + num_embeds_ada_norm: Optional[int] = None, + attention_bias: bool = False, + only_cross_attention: bool = False, + upcast_attention: bool = False, + norm_elementwise_affine: bool = True, + unet_use_cross_frame_attention: bool = False, + unet_use_temporal_attention: bool = False, + final_dropout: bool = False, + ) -> None: + super().__init__() + self.only_cross_attention = only_cross_attention + self.use_ada_layer_norm = num_embeds_ada_norm is not None + self.unet_use_cross_frame_attention = unet_use_cross_frame_attention + self.unet_use_temporal_attention = unet_use_temporal_attention + + # Define 3 blocks. Each block has its own normalization layer. + # 1. Self-Attn / SC-Attn + if self.use_ada_layer_norm: + self.norm1 = AdaLayerNorm(dim, num_embeds_ada_norm) # type: ignore + else: + self.norm1 = nn.LayerNorm(dim, elementwise_affine=norm_elementwise_affine) + + if unet_use_cross_frame_attention: + # this isn't actually implemented anywhere in the AnimateDiff codebase or in Diffusers... + raise NotImplementedError("SC-Attn is not implemented yet.") + else: + self.attn1 = Attention( + query_dim=dim, + cross_attention_dim=cross_attention_dim + if only_cross_attention + else None, + heads=num_attention_heads, + dim_head=attention_head_dim, + dropout=dropout, + bias=attention_bias, + upcast_attention=upcast_attention, + ) + + # 2. Cross-Attn + if cross_attention_dim is not None: + self.norm2 = ( + AdaLayerNorm(dim, num_embeds_ada_norm) # type: ignore + if self.use_ada_layer_norm + else nn.LayerNorm(dim, elementwise_affine=norm_elementwise_affine) + ) + self.attn2 = Attention( + query_dim=dim, + cross_attention_dim=cross_attention_dim, + heads=num_attention_heads, + dim_head=attention_head_dim, + dropout=dropout, + bias=attention_bias, + upcast_attention=upcast_attention, + ) # is self-attn if encoder_hidden_states is none + else: + self.norm2 = None + self.attn2 = None + + # 3. Feed-forward + self.norm3 = nn.LayerNorm(dim, elementwise_affine=norm_elementwise_affine) + self.ff = FeedForward( + dim, + dropout=dropout, + activation_fn=activation_fn, + final_dropout=final_dropout, + ) + + # 4. Temporal Attn + assert unet_use_temporal_attention is not None + if unet_use_temporal_attention: + self.attn_temp = Attention( + query_dim=dim, + heads=num_attention_heads, + dim_head=attention_head_dim, + dropout=dropout, + bias=attention_bias, + upcast_attention=upcast_attention, + ) + nn.init.zeros_(self.attn_temp.to_out[0].weight.data) + if self.use_ada_layer_norm: + self.norm1 = AdaLayerNorm(dim, num_embeds_ada_norm) # type: ignore + else: + self.norm1 = nn.LayerNorm( + dim, elementwise_affine=norm_elementwise_affine + ) + + def forward( + self, + hidden_states: torch.FloatTensor, + attention_mask: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + timestep: Optional[torch.LongTensor] = None, + cross_attention_kwargs: Dict[str, Any] = None, # type: ignore + video_length=None, + ): + # SparseCausal-Attention + # Notice that normalization is always applied before the real computation in the following blocks. + # 1. Self-Attention + if self.use_ada_layer_norm: + norm_hidden_states = self.norm1(hidden_states, timestep) + else: + norm_hidden_states = self.norm1(hidden_states) + + cross_attention_kwargs = ( + cross_attention_kwargs if cross_attention_kwargs is not None else {} + ) + if self.unet_use_cross_frame_attention: + cross_attention_kwargs["video_length"] = video_length + + attn_output = self.attn1( + norm_hidden_states, + encoder_hidden_states=encoder_hidden_states + if self.only_cross_attention + else None, + attention_mask=attention_mask, + **cross_attention_kwargs, + ) + + hidden_states = attn_output + hidden_states + + # 2. Cross-Attention + if self.attn2 is not None: + norm_hidden_states = ( + self.norm2(hidden_states, timestep) # type: ignore + if self.use_ada_layer_norm + else self.norm2(hidden_states) # type: ignore + ) + + attn_output = self.attn2( + norm_hidden_states, + encoder_hidden_states=encoder_hidden_states, + attention_mask=encoder_attention_mask, + **cross_attention_kwargs, + ) + hidden_states = attn_output + hidden_states + + # 3. Feed-forward + hidden_states = self.ff(self.norm3(hidden_states)) + hidden_states + + # 4. Temporal-Attention + if self.unet_use_temporal_attention: + d = hidden_states.shape[1] + hidden_states = rearrange( + hidden_states, "(b f) d c -> (b d) f c", f=video_length + ) + norm_hidden_states = ( + self.norm_temp(hidden_states, timestep) + if self.use_ada_layer_norm + else self.norm_temp(hidden_states) + ) + hidden_states = self.attn_temp(norm_hidden_states) + hidden_states + hidden_states = rearrange(hidden_states, "(b d) f c -> (b f) d c", d=d) + + return hidden_states diff --git a/core/inference/utilities/animatediff/models/motion_module.py b/core/inference/utilities/animatediff/models/motion_module.py new file mode 100644 index 000000000..95849de20 --- /dev/null +++ b/core/inference/utilities/animatediff/models/motion_module.py @@ -0,0 +1,339 @@ +import math +from dataclasses import dataclass +from typing import Optional + +import torch +from diffusers.models.attention import Attention, FeedForward # type: ignore +from diffusers.utils import BaseOutput # type: ignore +from einops import rearrange, repeat +from torch import Tensor, nn +from torch._dynamo import allow_in_graph as maybe_allow_in_graph + + +def zero_module(module): + # Zero out the parameters of a module and return it. + for p in module.parameters(): + p.detach().zero_() + return module + + +@dataclass +class TemporalTransformer3DModelOutput(BaseOutput): + sample: torch.FloatTensor + + +def get_motion_module(in_channels, motion_module_type: str, motion_module_kwargs: dict): + if motion_module_type == "Vanilla": + return VanillaTemporalModule( + in_channels=in_channels, + **motion_module_kwargs, + ) + else: + raise ValueError + + +class VanillaTemporalModule(nn.Module): + def __init__( + self, + in_channels, + num_attention_heads=8, + num_transformer_block=2, + attention_block_types=("Temporal_Self", "Temporal_Self"), + cross_frame_attention_mode=None, + temporal_position_encoding=False, + temporal_position_encoding_max_len=24, + temporal_attention_dim_div=1, + zero_initialize=True, + ): + super().__init__() + + self.temporal_transformer = TemporalTransformer3DModel( + in_channels=in_channels, + num_attention_heads=num_attention_heads, + attention_head_dim=in_channels + // num_attention_heads + // temporal_attention_dim_div, + num_layers=num_transformer_block, + attention_block_types=attention_block_types, + cross_frame_attention_mode=cross_frame_attention_mode, + temporal_position_encoding=temporal_position_encoding, + temporal_position_encoding_max_len=temporal_position_encoding_max_len, + ) + + if zero_initialize: + self.temporal_transformer.proj_out = zero_module( + self.temporal_transformer.proj_out + ) + + def forward( + self, + input_tensor, + temb, + encoder_hidden_states, + attention_mask=None, + anchor_frame_idx=None, + ): + hidden_states = input_tensor + hidden_states = self.temporal_transformer( + hidden_states, encoder_hidden_states, attention_mask + ) + + output = hidden_states + return output + + +@maybe_allow_in_graph +class TemporalTransformer3DModel(nn.Module): + def __init__( + self, + in_channels, + num_attention_heads, + attention_head_dim, + num_layers, + attention_block_types=( + "Temporal_Self", + "Temporal_Self", + ), + dropout=0.0, + norm_num_groups=32, + cross_attention_dim=768, + activation_fn="geglu", + attention_bias=False, + upcast_attention=False, + cross_frame_attention_mode=None, + temporal_position_encoding=False, + temporal_position_encoding_max_len=24, + ): + super().__init__() + + inner_dim = num_attention_heads * attention_head_dim + + self.norm = torch.nn.GroupNorm( + num_groups=norm_num_groups, num_channels=in_channels, eps=1e-6, affine=True + ) + self.proj_in = nn.Linear(in_channels, inner_dim) + + self.transformer_blocks = nn.ModuleList( + [ + TemporalTransformerBlock( + dim=inner_dim, + num_attention_heads=num_attention_heads, + attention_head_dim=attention_head_dim, + attention_block_types=attention_block_types, + dropout=dropout, + norm_num_groups=norm_num_groups, + cross_attention_dim=cross_attention_dim, + activation_fn=activation_fn, + attention_bias=attention_bias, + upcast_attention=upcast_attention, + cross_frame_attention_mode=cross_frame_attention_mode, + temporal_position_encoding=temporal_position_encoding, + temporal_position_encoding_max_len=temporal_position_encoding_max_len, + ) + for d in range(num_layers) + ] + ) + self.proj_out = nn.Linear(inner_dim, in_channels) + + def forward( + self, + hidden_states: Tensor, + encoder_hidden_states: Optional[Tensor] = None, + attention_mask: Optional[Tensor] = None, + ): + assert ( + hidden_states.dim() == 5 + ), f"Expected hidden_states to have ndim=5, but got ndim={hidden_states.dim()}." + video_length = hidden_states.shape[2] + hidden_states = rearrange(hidden_states, "b c f h w -> (b f) c h w") + + batch, channel, height, weight = hidden_states.shape + residual = hidden_states + + hidden_states = self.norm(hidden_states) + inner_dim = hidden_states.shape[1] + hidden_states = hidden_states.permute(0, 2, 3, 1).reshape( + batch, height * weight, inner_dim + ) + hidden_states = self.proj_in(hidden_states) + + # Transformer Blocks + for block in self.transformer_blocks: + hidden_states = block( + hidden_states, + encoder_hidden_states=encoder_hidden_states, + video_length=video_length, + ) + + # output + hidden_states = self.proj_out(hidden_states) + hidden_states = ( + hidden_states.reshape(batch, height, weight, inner_dim) + .permute(0, 3, 1, 2) + .contiguous() + ) + + output = hidden_states + residual + output = rearrange(output, "(b f) c h w -> b c f h w", f=video_length) + + return output + + +@maybe_allow_in_graph +class TemporalTransformerBlock(nn.Module): + def __init__( + self, + dim: int, + num_attention_heads: int, + attention_head_dim: int, + attention_block_types=( + "Temporal_Self", + "Temporal_Self", + ), + dropout=0.0, + norm_num_groups: int = 32, + cross_attention_dim: int = 768, + activation_fn: str = "geglu", + attention_bias: bool = False, + upcast_attention: bool = False, + cross_frame_attention_mode=None, + temporal_position_encoding: bool = False, + temporal_position_encoding_max_len: int = 24, + ): + super().__init__() + + attention_blocks = [] + norms = [] + + for block_name in attention_block_types: + attention_blocks.append( + VersatileAttention( + attention_mode=block_name.split("_")[0], + cross_attention_dim=cross_attention_dim + if block_name.endswith("_Cross") + else None, + query_dim=dim, + heads=num_attention_heads, + dim_head=attention_head_dim, + dropout=dropout, + bias=attention_bias, + upcast_attention=upcast_attention, + cross_frame_attention_mode=cross_frame_attention_mode, + temporal_position_encoding=temporal_position_encoding, + temporal_position_encoding_max_len=temporal_position_encoding_max_len, + ) + ) + norms.append(nn.LayerNorm(dim)) + + self.attention_blocks = nn.ModuleList(attention_blocks) + self.norms = nn.ModuleList(norms) + + self.ff = FeedForward(dim, dropout=dropout, activation_fn=activation_fn) + self.ff_norm = nn.LayerNorm(dim) + + def forward( + self, + hidden_states, + encoder_hidden_states=None, + attention_mask=None, + video_length=None, + ): + for attention_block, norm in zip(self.attention_blocks, self.norms): + norm_hidden_states = norm(hidden_states) + hidden_states = ( + attention_block( + norm_hidden_states, + encoder_hidden_states=encoder_hidden_states + if attention_block.is_cross_attention + else None, + video_length=video_length, + ) + + hidden_states + ) + + hidden_states = self.ff(self.ff_norm(hidden_states)) + hidden_states + + output = hidden_states + return output + + +class PositionalEncoding(nn.Module): + def __init__(self, d_model, dropout: float = 0.0, max_len: int = 24): + super().__init__() + self.dropout: nn.Module = nn.Dropout(p=dropout) + position = torch.arange(max_len).unsqueeze(1) + div_term = torch.exp( + torch.arange(0, d_model, 2) * (-math.log(10000.0) / d_model) + ) + pe: Tensor = torch.zeros(1, max_len, d_model) + pe[0, :, 0::2] = torch.sin(position * div_term) + pe[0, :, 1::2] = torch.cos(position * div_term) + self.register_buffer("pe", pe) + + def forward(self, x: Tensor): + x = x + self.pe[:, : x.size(1)] + return self.dropout(x) + + +@maybe_allow_in_graph +class VersatileAttention(Attention): + def __init__( + self, + attention_mode: str = None, # type: ignore + cross_frame_attention_mode: Optional[str] = None, + temporal_position_encoding: bool = False, + temporal_position_encoding_max_len: int = 24, + *args, + **kwargs, + ): + super().__init__(*args, **kwargs) + if attention_mode.lower() != "temporal": + raise ValueError(f"Attention mode {attention_mode} is not supported.") + + self.attention_mode = attention_mode + self.is_cross_attention = kwargs["cross_attention_dim"] is not None + + self.pos_encoder = ( + PositionalEncoding( + kwargs["query_dim"], + dropout=0.0, + max_len=temporal_position_encoding_max_len, + ) + if (temporal_position_encoding and attention_mode == "Temporal") + else None + ) + + def extra_repr(self): + return f"(Module Info) Attention_Mode: {self.attention_mode}, Is_Cross_Attention: {self.is_cross_attention}" + + def forward( + self, + hidden_states: Tensor, + encoder_hidden_states=None, + attention_mask=None, + video_length=None, + ): + if self.attention_mode == "Temporal": + d = hidden_states.shape[1] + hidden_states = rearrange( + hidden_states, "(b f) d c -> (b d) f c", f=video_length + ) + + if self.pos_encoder is not None: + hidden_states = self.pos_encoder(hidden_states) + + encoder_hidden_states = ( + repeat(encoder_hidden_states, "b n c -> (b d) n c", d=d) + if encoder_hidden_states is not None + else encoder_hidden_states + ) + else: + raise NotImplementedError + + # attention processor makes this easy so that's nice + hidden_states = self.processor(self, hidden_states, encoder_hidden_states, attention_mask) # type: ignore + + if self.attention_mode == "Temporal": + hidden_states = rearrange(hidden_states, "(b d) f c -> (b f) d c", d=d) + + return hidden_states diff --git a/core/inference/utilities/animatediff/models/resnet.py b/core/inference/utilities/animatediff/models/resnet.py new file mode 100644 index 000000000..18ff1b526 --- /dev/null +++ b/core/inference/utilities/animatediff/models/resnet.py @@ -0,0 +1,235 @@ +# Adapted from https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/resnet.py + +from typing import Optional + +import torch +import torch.nn.functional as F +from einops import rearrange +from torch import Tensor, nn + + +class InflatedConv3d(nn.Conv2d): + def forward(self, x: Tensor) -> Tensor: + frames = x.shape[2] + + x = rearrange(x, "b c f h w -> (b f) c h w") + x = F.conv2d( + x, + self.weight, + self.bias, + self.stride, + self.padding, + self.dilation, + self.groups, + ) + x = rearrange(x, "(b f) c h w -> b c f h w", f=frames) + return x + + +class Upsample3D(nn.Module): + def __init__( + self, + channels: int, + use_conv: bool = False, + use_conv_transpose: bool = False, + out_channels: Optional[int] = None, + name="conv", + ): + super().__init__() + self.channels = channels + self.out_channels = out_channels or channels + self.use_conv = use_conv + self.use_conv_transpose = use_conv_transpose + self.name = name + + if use_conv_transpose: + raise NotImplementedError + elif use_conv: + self.conv = InflatedConv3d(self.channels, self.out_channels, 3, padding=1) + + def forward(self, hidden_states: Tensor, output_size=None): + assert hidden_states.shape[1] == self.channels + + if self.use_conv_transpose: + raise NotImplementedError + + # Cast to float32 to as 'upsample_nearest2d_out_frame' op does not support bfloat16 + dtype = hidden_states.dtype + if dtype == torch.bfloat16: + hidden_states = hidden_states.to(torch.float32) + + # upsample_nearest_nhwc fails with large batch sizes. see https://github.com/huggingface/diffusers/issues/984 + if hidden_states.shape[0] >= 64: + hidden_states = hidden_states.contiguous() + + # if `output_size` is passed we force the interpolation output + # size and do not make use of `scale_factor=2` + if output_size is None: + hidden_states = F.interpolate( + hidden_states, scale_factor=[1.0, 2.0, 2.0], mode="nearest" + ) + else: + hidden_states = F.interpolate( + hidden_states, size=output_size, mode="nearest" + ) + + # If the input is bfloat16, we cast back to bfloat16 + if dtype == torch.bfloat16: + hidden_states = hidden_states.to(dtype) + + hidden_states = self.conv(hidden_states) + + return hidden_states + + +class Downsample3D(nn.Module): + def __init__( + self, + channels: int, + use_conv: bool = False, + out_channels: Optional[int] = None, + padding: int = 1, + name="conv", + ): + super().__init__() + self.channels = channels + self.out_channels = out_channels or channels + self.use_conv = use_conv + self.padding = padding + stride = 2 + self.name = name + + if use_conv: + self.conv = InflatedConv3d( + self.channels, self.out_channels, 3, stride=stride, padding=padding + ) + else: + raise NotImplementedError + + def forward(self, hidden_states): + assert hidden_states.shape[1] == self.channels + if self.use_conv and self.padding == 0: + raise NotImplementedError + + assert hidden_states.shape[1] == self.channels + hidden_states = self.conv(hidden_states) + + return hidden_states + + +class ResnetBlock3D(nn.Module): + def __init__( + self, + *, + in_channels, + out_channels=None, + conv_shortcut=False, + dropout=0.0, + temb_channels=512, + groups=32, + groups_out=None, + pre_norm=True, + eps=1e-6, + non_linearity="swish", + time_embedding_norm="default", + output_scale_factor=1.0, + use_in_shortcut=None, + ): + super().__init__() + self.pre_norm = pre_norm + self.pre_norm = True + self.in_channels = in_channels + out_channels = in_channels if out_channels is None else out_channels + self.out_channels = out_channels + self.use_conv_shortcut = conv_shortcut + self.time_embedding_norm = time_embedding_norm + self.output_scale_factor = output_scale_factor + + if groups_out is None: + groups_out = groups + + self.norm1 = nn.GroupNorm( + num_groups=groups, num_channels=in_channels, eps=eps, affine=True + ) + + self.conv1 = InflatedConv3d( + in_channels, out_channels, kernel_size=3, stride=1, padding=1 + ) + + if temb_channels is not None: + if self.time_embedding_norm == "default": + time_emb_proj_out_channels = out_channels + elif self.time_embedding_norm == "scale_shift": + time_emb_proj_out_channels = out_channels * 2 + else: + raise ValueError( + f"unknown time_embedding_norm : {self.time_embedding_norm} " + ) + + self.time_emb_proj = nn.Linear(temb_channels, time_emb_proj_out_channels) + else: + self.time_emb_proj = None + + self.norm2 = nn.GroupNorm( + num_groups=groups_out, num_channels=out_channels, eps=eps, affine=True + ) + self.dropout = nn.Dropout(dropout) + self.conv2 = InflatedConv3d( + out_channels, out_channels, kernel_size=3, stride=1, padding=1 + ) + + if non_linearity == "swish": + self.nonlinearity = lambda x: F.silu(x) + elif non_linearity == "mish": + self.nonlinearity = Mish() + elif non_linearity == "silu": + self.nonlinearity = nn.SiLU() + + self.use_in_shortcut = ( + self.in_channels != self.out_channels + if use_in_shortcut is None + else use_in_shortcut + ) + + self.conv_shortcut = None + if self.use_in_shortcut: + self.conv_shortcut = InflatedConv3d( + in_channels, out_channels, kernel_size=1, stride=1, padding=0 + ) + + def forward(self, input_tensor, temb): + hidden_states = input_tensor + + hidden_states = self.norm1(hidden_states) + hidden_states = self.nonlinearity(hidden_states) + + hidden_states = self.conv1(hidden_states) + + if temb is not None: + temb = self.time_emb_proj(self.nonlinearity(temb))[:, :, None, None, None] # type: ignore + + if temb is not None and self.time_embedding_norm == "default": + hidden_states = hidden_states + temb + + hidden_states = self.norm2(hidden_states) + + if temb is not None and self.time_embedding_norm == "scale_shift": + scale, shift = torch.chunk(temb, 2, dim=1) + hidden_states = hidden_states * (1 + scale) + shift + + hidden_states = self.nonlinearity(hidden_states) + + hidden_states = self.dropout(hidden_states) + hidden_states = self.conv2(hidden_states) + + if self.conv_shortcut is not None: + input_tensor = self.conv_shortcut(input_tensor) + + output_tensor = (input_tensor + hidden_states) / self.output_scale_factor + + return output_tensor + + +class Mish(nn.Module): + def forward(self, hidden_states): + return hidden_states * torch.tanh(torch.nn.functional.softplus(hidden_states)) diff --git a/core/inference/utilities/animatediff/models/unet.py b/core/inference/utilities/animatediff/models/unet.py new file mode 100644 index 000000000..cc67f927b --- /dev/null +++ b/core/inference/utilities/animatediff/models/unet.py @@ -0,0 +1,614 @@ +# Adapted from https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/unet_2d_condition.py + +from dataclasses import dataclass +from os import PathLike +from pathlib import Path +from typing import Any, Dict, List, Optional, Tuple, Union + +import torch +import torch.utils.checkpoint +from diffusers.configuration_utils import ConfigMixin, register_to_config +from diffusers.models import ModelMixin # type: ignore +from diffusers.models.unet_2d_condition import UNet2DConditionModel +from diffusers.models.embeddings import TimestepEmbedding, Timesteps +from diffusers.utils import BaseOutput, logging # type: ignore +from safetensors.torch import load_file +from torch import Tensor, nn + +from .resnet import InflatedConv3d +from .unet_blocks import ( + CrossAttnDownBlock3D, + CrossAttnUpBlock3D, + DownBlock3D, + UNetMidBlock3DCrossAttn, + UpBlock3D, + get_down_block, + get_up_block, +) +from . import MMV2_DIM_KEY + +logger = logging.get_logger(__name__) # pylint: disable=invalid-name + + +@dataclass +class UNet3DConditionOutput(BaseOutput): + sample: torch.FloatTensor + + +class UNet3DConditionModel(ModelMixin, ConfigMixin): + _supports_gradient_checkpointing = True + + @register_to_config + def __init__( + self, + sample_size: Optional[int] = None, + in_channels: int = 4, + out_channels: int = 4, + center_input_sample: bool = False, + flip_sin_to_cos: bool = True, + freq_shift: int = 0, + down_block_types: Tuple[str] = ( # type: ignore + "CrossAttnDownBlock3D", + "CrossAttnDownBlock3D", + "CrossAttnDownBlock3D", + "DownBlock3D", + ), + mid_block_type: str = "UNetMidBlock3DCrossAttn", + up_block_types: Tuple[str] = ( # type: ignore + "UpBlock3D", + "CrossAttnUpBlock3D", + "CrossAttnUpBlock3D", + "CrossAttnUpBlock3D", + ), + only_cross_attention: Union[bool, Tuple[bool]] = False, + block_out_channels: Tuple[int] = (320, 640, 1280, 1280), # type: ignore + layers_per_block: int = 2, + downsample_padding: int = 1, + mid_block_scale_factor: float = 1, + act_fn: str = "silu", + norm_num_groups: int = 32, + norm_eps: float = 1e-5, + cross_attention_dim: int = 1280, + attention_head_dim: Union[int, Tuple[int]] = 8, + num_attention_heads: Optional[Union[int, Tuple[int]]] = None, + dual_cross_attention: bool = False, + use_linear_projection: bool = False, + class_embed_type: Optional[str] = None, + num_class_embeds: Optional[int] = None, + upcast_attention: bool = False, + resnet_time_scale_shift: str = "default", + # Additional + use_motion_module=False, + motion_module_resolutions=(1, 2, 4, 8), + motion_module_mid_block=False, + motion_module_decoder_only=False, + motion_module_type=None, + motion_module_kwargs={}, + unet_use_cross_frame_attention=None, + unet_use_temporal_attention=None, + ): + super().__init__() + + self.sample_size = sample_size + time_embed_dim = block_out_channels[0] * 4 + + # input + self.conv_in = InflatedConv3d( + in_channels, block_out_channels[0], kernel_size=3, padding=(1, 1) + ) + + # time + self.time_proj = Timesteps(block_out_channels[0], flip_sin_to_cos, freq_shift) + timestep_input_dim = block_out_channels[0] + + self.time_embedding = TimestepEmbedding(timestep_input_dim, time_embed_dim) + + # class embedding + if class_embed_type is None and num_class_embeds is not None: + self.class_embedding = nn.Embedding(num_class_embeds, time_embed_dim) + elif class_embed_type == "timestep": + self.class_embedding = TimestepEmbedding(timestep_input_dim, time_embed_dim) + elif class_embed_type == "identity": + self.class_embedding = nn.Identity(time_embed_dim, time_embed_dim) + else: + self.class_embedding = None + + self.down_blocks = nn.ModuleList([]) + self.mid_block = None + self.up_blocks = nn.ModuleList([]) + + if isinstance(only_cross_attention, bool): + only_cross_attention = [only_cross_attention] * len(down_block_types) # type: ignore + + if isinstance(attention_head_dim, int): + attention_head_dim = (attention_head_dim,) * len(down_block_types) # type: ignore + + # down + output_channel = block_out_channels[0] + for i, down_block_type in enumerate(down_block_types): + res = 2**i + input_channel = output_channel + output_channel = block_out_channels[i] + is_final_block = i == len(block_out_channels) - 1 + + down_block = get_down_block( + down_block_type, + num_layers=layers_per_block, + in_channels=input_channel, + out_channels=output_channel, + temb_channels=time_embed_dim, + add_downsample=not is_final_block, + resnet_eps=norm_eps, + resnet_act_fn=act_fn, + resnet_groups=norm_num_groups, + cross_attention_dim=cross_attention_dim, + attn_num_head_channels=attention_head_dim[i], # type: ignore + downsample_padding=downsample_padding, + dual_cross_attention=dual_cross_attention, + use_linear_projection=use_linear_projection, + only_cross_attention=only_cross_attention[i], # type: ignore + upcast_attention=upcast_attention, + resnet_time_scale_shift=resnet_time_scale_shift, + unet_use_cross_frame_attention=unet_use_cross_frame_attention, + unet_use_temporal_attention=unet_use_temporal_attention, + use_motion_module=use_motion_module + and (res in motion_module_resolutions) + and (not motion_module_decoder_only), + motion_module_type=motion_module_type, + motion_module_kwargs=motion_module_kwargs, + ) + self.down_blocks.append(down_block) + + # mid + if mid_block_type == "UNetMidBlock3DCrossAttn": + self.mid_block = UNetMidBlock3DCrossAttn( + in_channels=block_out_channels[-1], + temb_channels=time_embed_dim, + resnet_eps=norm_eps, + resnet_act_fn=act_fn, + output_scale_factor=mid_block_scale_factor, + resnet_time_scale_shift=resnet_time_scale_shift, + cross_attention_dim=cross_attention_dim, + attn_num_head_channels=attention_head_dim[-1], # type: ignore + resnet_groups=norm_num_groups, + dual_cross_attention=dual_cross_attention, + use_linear_projection=use_linear_projection, + upcast_attention=upcast_attention, + unet_use_cross_frame_attention=unet_use_cross_frame_attention, + unet_use_temporal_attention=unet_use_temporal_attention, + use_motion_module=use_motion_module and motion_module_mid_block, + motion_module_type=motion_module_type, + motion_module_kwargs=motion_module_kwargs, + ) + else: + raise ValueError(f"unknown mid_block_type : {mid_block_type}") + + # count how many layers upsample the videos + self.num_upsamplers = 0 + + # up + reversed_block_out_channels = list(reversed(block_out_channels)) + reversed_attention_head_dim = list(reversed(attention_head_dim)) # type: ignore + only_cross_attention = list(reversed(only_cross_attention)) # type: ignore + output_channel = reversed_block_out_channels[0] + for i, up_block_type in enumerate(up_block_types): + res = 2 ** (3 - i) + is_final_block = i == len(block_out_channels) - 1 + + prev_output_channel = output_channel + output_channel = reversed_block_out_channels[i] + input_channel = reversed_block_out_channels[ + min(i + 1, len(block_out_channels) - 1) + ] + + # add upsample block for all BUT final layer + if not is_final_block: + add_upsample = True + self.num_upsamplers += 1 + else: + add_upsample = False + + up_block = get_up_block( + up_block_type, + num_layers=layers_per_block + 1, + in_channels=input_channel, + out_channels=output_channel, + prev_output_channel=prev_output_channel, + temb_channels=time_embed_dim, + add_upsample=add_upsample, + resnet_eps=norm_eps, + resnet_act_fn=act_fn, + resnet_groups=norm_num_groups, + cross_attention_dim=cross_attention_dim, + attn_num_head_channels=reversed_attention_head_dim[i], + dual_cross_attention=dual_cross_attention, + use_linear_projection=use_linear_projection, + only_cross_attention=only_cross_attention[i], # type: ignore + upcast_attention=upcast_attention, + resnet_time_scale_shift=resnet_time_scale_shift, + unet_use_cross_frame_attention=unet_use_cross_frame_attention, + unet_use_temporal_attention=unet_use_temporal_attention, + use_motion_module=use_motion_module + and (res in motion_module_resolutions), + motion_module_type=motion_module_type, + motion_module_kwargs=motion_module_kwargs, + ) + self.up_blocks.append(up_block) + prev_output_channel = output_channel + + # out + self.conv_norm_out = nn.GroupNorm( + num_channels=block_out_channels[0], num_groups=norm_num_groups, eps=norm_eps + ) + self.conv_act = nn.SiLU() + self.conv_out = InflatedConv3d( + block_out_channels[0], out_channels, kernel_size=3, padding=1 + ) + + def set_attention_slice(self, slice_size): + r""" + Enable sliced attention computation. + + When this option is enabled, the attention module will split the input tensor in slices, to compute attention + in several steps. This is useful to save some memory in exchange for a small speed decrease. + + Args: + slice_size (`str` or `int` or `list(int)`, *optional*, defaults to `"auto"`): + When `"auto"`, halves the input to the attention heads, so attention will be computed in two steps. If + `"max"`, maxium amount of memory will be saved by running only one slice at a time. If a number is + provided, uses as many slices as `attention_head_dim // slice_size`. In this case, `attention_head_dim` + must be a multiple of `slice_size`. + """ + sliceable_head_dims = [] + + def fn_recursive_retrieve_slicable_dims(module: nn.Module): + if hasattr(module, "set_attention_slice"): + sliceable_head_dims.append(module.sliceable_head_dim) + + for child in module.children(): + fn_recursive_retrieve_slicable_dims(child) + + # retrieve number of attention layers + for module in self.children(): + fn_recursive_retrieve_slicable_dims(module) + + num_slicable_layers = len(sliceable_head_dims) + + if slice_size == "auto": + # half the attention head size is usually a good trade-off between + # speed and memory + slice_size = [dim // 2 for dim in sliceable_head_dims] + elif slice_size == "max": + # make smallest slice possible + slice_size = num_slicable_layers * [1] + + slice_size = ( + num_slicable_layers * [slice_size] + if not isinstance(slice_size, list) + else slice_size + ) + + if len(slice_size) != len(sliceable_head_dims): + raise ValueError( + f"You have provided {len(slice_size)}, but {self.config} has {len(sliceable_head_dims)} different" + f" attention layers. Make sure to match `len(slice_size)` to be {len(sliceable_head_dims)}." + ) + + for i in range(len(slice_size)): + size = slice_size[i] + dim = sliceable_head_dims[i] + if size is not None and size > dim: + raise ValueError(f"size {size} has to be smaller or equal to {dim}.") + + # Recursively walk through all the children. + # Any children which exposes the set_attention_slice method + # gets the message + def fn_recursive_set_attention_slice(module: nn.Module, slice_size: List[int]): + if hasattr(module, "set_attention_slice"): + module.set_attention_slice(slice_size.pop()) + + for child in module.children(): + fn_recursive_set_attention_slice(child, slice_size) + + reversed_slice_size = list(reversed(slice_size)) + for module in self.children(): + fn_recursive_set_attention_slice(module, reversed_slice_size) + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance( + module, (CrossAttnDownBlock3D, DownBlock3D, CrossAttnUpBlock3D, UpBlock3D) + ): + module.gradient_checkpointing = value + + def forward( + self, + sample: torch.FloatTensor, + timestep: Union[Tensor, float, int], + encoder_hidden_states: Tensor, + class_labels: Optional[Tensor] = None, + attention_mask: Optional[Tensor] = None, + cross_attention_kwargs: Optional[Dict[str, Any]] = None, + added_cond_kwargs: Optional[Dict[str, torch.Tensor]] = None, + encoder_attention_mask: Optional[torch.Tensor] = None, + return_dict: bool = True, + ) -> Union[UNet3DConditionOutput, Tuple]: + r""" + Args: + sample (`torch.FloatTensor`): (batch, channel, height, width) noisy inputs tensor + timestep (`torch.FloatTensor` or `float` or `int`): (batch) timesteps + encoder_hidden_states (`torch.FloatTensor`): (batch, sequence_length, feature_dim) encoder hidden states + return_dict (`bool`, *optional*, defaults to `True`): + Whether or not to return a [`models.unet_2d_condition.UNet2DConditionOutput`] instead of a plain tuple. + + Returns: + [`~models.unet_2d_condition.UNet2DConditionOutput`] or `tuple`: + [`~models.unet_2d_condition.UNet2DConditionOutput`] if `return_dict` is True, otherwise a `tuple`. When + returning a tuple, the first element is the sample tensor. + """ + # By default samples have to be at least a multiple of the overall upsampling factor. + # The overall upsampling factor is equal to 2 ** (# num of upsampling layears). + # However, the upsampling interpolation output size can be forced to fit any upsampling size + # on the fly if necessary. + default_overall_up_factor = 2**self.num_upsamplers + + # upsample size should be forwarded when sample is not a multiple of `default_overall_up_factor` + forward_upsample_size = False + upsample_size = None + + if any(s % default_overall_up_factor != 0 for s in sample.shape[-2:]): + logger.debug("Forward upsample size to force interpolation output size.") + forward_upsample_size = True + + # ensure attention_mask is a bias, and give it a singleton query_tokens dimension + # expects mask of shape: + # [batch, key_tokens] + # adds singleton query_tokens dimension: + # [batch, 1, key_tokens] + # this helps to broadcast it as a bias over attention scores, which will be in one of the following shapes: + # [batch, heads, query_tokens, key_tokens] (e.g. torch sdp attn) + # [batch * heads, query_tokens, key_tokens] (e.g. xformers or classic attn) + if attention_mask is not None: + # assume that mask is expressed as: + # (1 = keep, 0 = discard) + # convert mask into a bias that can be added to attention scores: + # (keep = +0, discard = -10000.0) + attention_mask = (1 - attention_mask.to(sample.dtype)) * -10000.0 + attention_mask = attention_mask.unsqueeze(1) + + # convert encoder_attention_mask to a bias the same way we do for attention_mask + if encoder_attention_mask is not None: + encoder_attention_mask = ( + 1 - encoder_attention_mask.to(sample.dtype) + ) * -10000.0 + encoder_attention_mask = encoder_attention_mask.unsqueeze(1) + + # 0. center input if necessary + if self.config["center_input_sample"]: + sample = 2 * sample - 1.0 # type: ignore + + # 1. time + timesteps = timestep + if not torch.is_tensor(timesteps): + # TODO: this requires sync between CPU and GPU. So try to pass timesteps as tensors if you can + # This would be a good case for the `match` statement (Python 3.10+) + is_mps = sample.device.type == "mps" + if isinstance(timestep, float): + dtype = torch.float32 if is_mps else torch.float64 + else: + dtype = torch.int32 if is_mps else torch.int64 + timesteps = torch.tensor([timesteps], dtype=dtype, device=sample.device) + elif len(timesteps.shape) == 0: # type: ignore + timesteps = timesteps[None].to(sample.device) # type: ignore + + # broadcast to batch dimension in a way that's compatible with ONNX/Core ML + timesteps = timesteps.expand(sample.shape[0]) # type: ignore + + t_emb = self.time_proj(timesteps) + + # `Timesteps` does not contain any weights and will always return f32 tensors + # but time_embedding might actually be running in fp16. so we need to cast here. + # there might be better ways to encapsulate this. + t_emb = t_emb.to(dtype=sample.dtype) + + emb = self.time_embedding(t_emb) + + if self.class_embedding is not None: + if class_labels is None: + raise ValueError( + "class_labels should be provided when num_class_embeds > 0" + ) + + if self.config["class_embed_type"] == "timestep": + class_labels = self.time_proj(class_labels) + + # `Timesteps` does not contain any weights and will always return f32 tensors + # there might be better ways to encapsulate this. + class_labels = class_labels.to(dtype=sample.dtype) # type: ignore + + class_emb = self.class_embedding(class_labels).to(dtype=sample.dtype) + + if self.config["class_embeddings_concat"]: + emb = torch.cat([emb, class_emb], dim=-1) + else: + emb = emb + class_emb + + # 2. pre-process + sample = self.conv_in(sample) + + # 3. down + down_block_res_samples = (sample,) + for downsample_block in self.down_blocks: + if ( + hasattr(downsample_block, "has_cross_attention") + and downsample_block.has_cross_attention + ): + sample, res_samples = downsample_block( + hidden_states=sample, + temb=emb, + encoder_hidden_states=encoder_hidden_states, + attention_mask=attention_mask, + cross_attention_kwargs=cross_attention_kwargs, + encoder_attention_mask=encoder_attention_mask, + ) + else: + sample, res_samples = downsample_block( + hidden_states=sample, + temb=emb, + encoder_hidden_states=encoder_hidden_states, + ) + + down_block_res_samples = down_block_res_samples + res_samples + + # 4. mid + if self.mid_block is not None: + sample = self.mid_block( + sample, + emb, + encoder_hidden_states=encoder_hidden_states, + attention_mask=attention_mask, + cross_attention_kwargs=cross_attention_kwargs, + ) + + # up + for i, upsample_block in enumerate(self.up_blocks): + is_final_block = i == len(self.up_blocks) - 1 + + res_samples = down_block_res_samples[-len(upsample_block.resnets) :] + down_block_res_samples = down_block_res_samples[ + : -len(upsample_block.resnets) + ] + + # if we have not reached the final block and need to forward the + # upsample size, we do it here + if not is_final_block and forward_upsample_size: + upsample_size = down_block_res_samples[-1].shape[2:] + + if ( + hasattr(upsample_block, "has_cross_attention") + and upsample_block.has_cross_attention + ): + sample = upsample_block( + hidden_states=sample, + temb=emb, + res_hidden_states_tuple=res_samples, + encoder_hidden_states=encoder_hidden_states, + upsample_size=upsample_size, + attention_mask=attention_mask, + ) + else: + sample = upsample_block( + hidden_states=sample, + temb=emb, + res_hidden_states_tuple=res_samples, + upsample_size=upsample_size, + encoder_hidden_states=encoder_hidden_states, + ) + + # post-process + sample = self.conv_norm_out(sample) + sample = self.conv_act(sample) + sample = self.conv_out(sample) + + if not return_dict: + return (sample,) + + return UNet3DConditionOutput(sample=sample) + + @classmethod + def from_pretrained_2d( + cls, + unet: UNet2DConditionModel, + motion_module_path: PathLike, + subfolder: Optional[str] = None, + unet_additional_kwargs: Optional[dict] = None, + ): + motion_module_path = Path(motion_module_path) + state_dict = unet.state_dict() + + # load the motion module weights + if motion_module_path.exists() and motion_module_path.is_file(): + if motion_module_path.suffix.lower() in [".pth", ".pt", ".ckpt"]: + motion_state_dict = torch.load( + motion_module_path, map_location="cpu", weights_only=True + ) + elif motion_module_path.suffix.lower() == ".safetensors": + motion_state_dict = load_file(motion_module_path, device="cpu") + else: + raise RuntimeError( + f"unknown file format for motion module weights: {motion_module_path.suffix}" + ) + else: + raise FileNotFoundError( + f"no motion module weights found in {motion_module_path}" + ) + + # merge the state dicts + motion_state_dict.update(state_dict) + + # check if we have a v1 or v2 motion module + motion_up_dim = motion_state_dict[MMV2_DIM_KEY].shape + unet_additional_kwargs = { + "unet_use_cross_frame_attention": False, + "unet_use_temporal_attention": False, + "use_motion_module": True, + "motion_module_resolutions": [1, 2, 4, 8], + "motion_module_mid_block": False, + "motion_module_decoder_only": False, + "motion_module_type": "Vanilla", + "motion_module_kwargs": { + "num_attention_heads": 8, + "num_transformer_block": 1, + "attention_block_types": ["Temporal_Self", "Temporal_Self"], + "temporal_position_encoding": True, + "temporal_position_encoding_max_len": 24, + "temporal_attention_dim_div": 1, + }, + } + if motion_up_dim[1] != 24: + logger.info("Detected V2 motion module") + if unet_additional_kwargs: + motion_module_kwargs = unet_additional_kwargs.pop( + "motion_module_kwargs", {} + ) + motion_module_kwargs[ + "temporal_position_encoding_max_len" + ] = motion_up_dim[1] + unet_additional_kwargs["motion_module_kwargs"] = motion_module_kwargs + else: + unet_additional_kwargs = { + "motion_module_kwargs": { + "temporal_position_encoding_max_len": motion_up_dim[2] + } + } + + unet_config = dict(unet.config) + unet_config["_class_name"] = cls.__name__ + unet_config["down_block_types"] = [ + "CrossAttnDownBlock3D", + "CrossAttnDownBlock3D", + "CrossAttnDownBlock3D", + "DownBlock3D", + ] + unet_config["up_block_types"] = [ + "UpBlock3D", + "CrossAttnUpBlock3D", + "CrossAttnUpBlock3D", + "CrossAttnUpBlock3D", + ] + unet_config["mid_block_type"] = "UNetMidBlock3DCrossAttn" + + if unet_additional_kwargs is None: + unet_additional_kwargs = {} + model: nn.Module = cls.from_config(unet_config, **unet_additional_kwargs) # type: ignore + + # load the weights into the model + m, u = model.load_state_dict(motion_state_dict, strict=False) + logger.info(f"### missing keys: {len(m)}; \n### unexpected keys: {len(u)};") + + params = [ + p.numel() if "temporal" in n.lower() else 0 + for n, p in model.named_parameters() + ] + logger.info(f"Loaded {sum(params) / 1e6}M-parameter motion module") + + return model diff --git a/core/inference/utilities/animatediff/models/unet_blocks.py b/core/inference/utilities/animatediff/models/unet_blocks.py new file mode 100644 index 000000000..cfe14ce96 --- /dev/null +++ b/core/inference/utilities/animatediff/models/unet_blocks.py @@ -0,0 +1,851 @@ +# Adapted from https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/unet_2d_blocks.py + +from typing import Any, Dict, Optional, Tuple + +import torch +from torch import nn +from torch._dynamo import allow_in_graph as maybe_allow_in_graph + +from .attention import Transformer3DModel +from .motion_module import get_motion_module +from .resnet import Downsample3D, ResnetBlock3D, Upsample3D + + +def get_down_block( + down_block_type, + num_layers, + in_channels, + out_channels, + temb_channels, + add_downsample, + resnet_eps, + resnet_act_fn, + attn_num_head_channels, + resnet_groups=None, + cross_attention_dim=None, + downsample_padding=None, + dual_cross_attention=False, + use_linear_projection=False, + only_cross_attention=False, + upcast_attention=False, + resnet_time_scale_shift="default", + unet_use_cross_frame_attention=None, + unet_use_temporal_attention=None, + use_motion_module=None, + motion_module_type=None, + motion_module_kwargs=None, +): + down_block_type = ( + down_block_type[7:] + if down_block_type.startswith("UNetRes") + else down_block_type + ) + if down_block_type == "DownBlock3D": + return DownBlock3D( + num_layers=num_layers, + in_channels=in_channels, + out_channels=out_channels, + temb_channels=temb_channels, + add_downsample=add_downsample, + resnet_eps=resnet_eps, + resnet_act_fn=resnet_act_fn, + resnet_groups=resnet_groups, # type: ignore + downsample_padding=downsample_padding, # type: ignore + resnet_time_scale_shift=resnet_time_scale_shift, + use_motion_module=use_motion_module, + motion_module_type=motion_module_type, + motion_module_kwargs=motion_module_kwargs, + ) + elif down_block_type == "CrossAttnDownBlock3D": + if cross_attention_dim is None: + raise ValueError( + "cross_attention_dim must be specified for CrossAttnDownBlock3D" + ) + return CrossAttnDownBlock3D( + num_layers=num_layers, + in_channels=in_channels, + out_channels=out_channels, + temb_channels=temb_channels, + add_downsample=add_downsample, + resnet_eps=resnet_eps, + resnet_act_fn=resnet_act_fn, + resnet_groups=resnet_groups, # type: ignore + downsample_padding=downsample_padding, # type: ignore + cross_attention_dim=cross_attention_dim, + attn_num_head_channels=attn_num_head_channels, + dual_cross_attention=dual_cross_attention, + use_linear_projection=use_linear_projection, + only_cross_attention=only_cross_attention, + upcast_attention=upcast_attention, + resnet_time_scale_shift=resnet_time_scale_shift, + unet_use_cross_frame_attention=unet_use_cross_frame_attention, + unet_use_temporal_attention=unet_use_temporal_attention, + use_motion_module=use_motion_module, + motion_module_type=motion_module_type, + motion_module_kwargs=motion_module_kwargs, + ) + raise ValueError(f"{down_block_type} does not exist.") + + +def get_up_block( + up_block_type, + num_layers, + in_channels, + out_channels, + prev_output_channel, + temb_channels, + add_upsample, + resnet_eps, + resnet_act_fn, + attn_num_head_channels, + resnet_groups=None, + cross_attention_dim=None, + dual_cross_attention=False, + use_linear_projection=False, + only_cross_attention=False, + upcast_attention=False, + resnet_time_scale_shift="default", + unet_use_cross_frame_attention=None, + unet_use_temporal_attention=None, + use_motion_module=None, + motion_module_type=None, + motion_module_kwargs=None, +): + up_block_type = ( + up_block_type[7:] if up_block_type.startswith("UNetRes") else up_block_type + ) + if up_block_type == "UpBlock3D": + return UpBlock3D( + num_layers=num_layers, + in_channels=in_channels, + out_channels=out_channels, + prev_output_channel=prev_output_channel, + temb_channels=temb_channels, + add_upsample=add_upsample, + resnet_eps=resnet_eps, + resnet_act_fn=resnet_act_fn, + resnet_groups=resnet_groups, # type: ignore + resnet_time_scale_shift=resnet_time_scale_shift, + use_motion_module=use_motion_module, + motion_module_type=motion_module_type, + motion_module_kwargs=motion_module_kwargs, + ) + elif up_block_type == "CrossAttnUpBlock3D": + if cross_attention_dim is None: + raise ValueError( + "cross_attention_dim must be specified for CrossAttnUpBlock3D" + ) + return CrossAttnUpBlock3D( + num_layers=num_layers, + in_channels=in_channels, + out_channels=out_channels, + prev_output_channel=prev_output_channel, + temb_channels=temb_channels, + add_upsample=add_upsample, + resnet_eps=resnet_eps, + resnet_act_fn=resnet_act_fn, + resnet_groups=resnet_groups, # type: ignore + cross_attention_dim=cross_attention_dim, + attn_num_head_channels=attn_num_head_channels, + dual_cross_attention=dual_cross_attention, + use_linear_projection=use_linear_projection, + only_cross_attention=only_cross_attention, + upcast_attention=upcast_attention, + resnet_time_scale_shift=resnet_time_scale_shift, + unet_use_cross_frame_attention=unet_use_cross_frame_attention, + unet_use_temporal_attention=unet_use_temporal_attention, + use_motion_module=use_motion_module, + motion_module_type=motion_module_type, + motion_module_kwargs=motion_module_kwargs, + ) + raise ValueError(f"{up_block_type} does not exist.") + + +@maybe_allow_in_graph +class UNetMidBlock3DCrossAttn(nn.Module): + def __init__( + self, + in_channels: int, + temb_channels: int, + dropout: float = 0.0, + num_layers: int = 1, + resnet_eps: float = 1e-6, + resnet_time_scale_shift: str = "default", + resnet_act_fn: str = "swish", + resnet_groups: int = 32, + resnet_pre_norm: bool = True, + attn_num_head_channels=1, + output_scale_factor=1.0, + cross_attention_dim=1280, + dual_cross_attention=False, + use_linear_projection=False, + upcast_attention=False, + unet_use_cross_frame_attention=None, + unet_use_temporal_attention=None, + use_motion_module=None, + motion_module_type=None, + motion_module_kwargs=None, + ): + super().__init__() + + self.has_cross_attention = True + self.attn_num_head_channels = attn_num_head_channels + resnet_groups = ( + resnet_groups if resnet_groups is not None else min(in_channels // 4, 32) + ) + + # there is always at least one resnet + resnets = [ + ResnetBlock3D( + in_channels=in_channels, + out_channels=in_channels, + temb_channels=temb_channels, + eps=resnet_eps, + groups=resnet_groups, + dropout=dropout, + time_embedding_norm=resnet_time_scale_shift, + non_linearity=resnet_act_fn, + output_scale_factor=output_scale_factor, + pre_norm=resnet_pre_norm, + ) + ] + attentions = [] + motion_modules = [] + + for _ in range(num_layers): + if dual_cross_attention: + raise NotImplementedError + attentions.append( + Transformer3DModel( + attn_num_head_channels, + in_channels // attn_num_head_channels, + in_channels=in_channels, + num_layers=1, + cross_attention_dim=cross_attention_dim, + norm_num_groups=resnet_groups, + use_linear_projection=use_linear_projection, + upcast_attention=upcast_attention, + unet_use_cross_frame_attention=unet_use_cross_frame_attention, + unet_use_temporal_attention=unet_use_temporal_attention, + ) + ) + motion_modules.append( + get_motion_module( + in_channels=in_channels, + motion_module_type=motion_module_type, # type: ignore + motion_module_kwargs=motion_module_kwargs, # type: ignore + ) + if use_motion_module + else None + ) + resnets.append( + ResnetBlock3D( + in_channels=in_channels, + out_channels=in_channels, + temb_channels=temb_channels, + eps=resnet_eps, + groups=resnet_groups, + dropout=dropout, + time_embedding_norm=resnet_time_scale_shift, + non_linearity=resnet_act_fn, + output_scale_factor=output_scale_factor, + pre_norm=resnet_pre_norm, + ) + ) + + self.attentions = nn.ModuleList(attentions) + self.resnets = nn.ModuleList(resnets) + self.motion_modules = nn.ModuleList(motion_modules) + + def forward( + self, + hidden_states: torch.FloatTensor, + temb: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + cross_attention_kwargs: Optional[Dict[str, Any]] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + ) -> torch.FloatTensor: + hidden_states = self.resnets[0](hidden_states, temb) + for attn, resnet, motion_module in zip(self.attentions, self.resnets[1:], self.motion_modules): # type: ignore + hidden_states = attn( + hidden_states, + encoder_hidden_states=encoder_hidden_states, + cross_attention_kwargs=cross_attention_kwargs, + attention_mask=attention_mask, + encoder_attention_mask=encoder_attention_mask, + return_dict=False, + )[0] + if motion_module is not None: + hidden_states = motion_module( + hidden_states, + temb, + encoder_hidden_states=encoder_hidden_states, + encoder_attention_mask=encoder_attention_mask, + ) + hidden_states = resnet(hidden_states, temb) + + return hidden_states + + +@maybe_allow_in_graph +class CrossAttnDownBlock3D(nn.Module): + def __init__( + self, + in_channels: int, + out_channels: int, + temb_channels: int, + dropout: float = 0.0, + num_layers: int = 1, + transformer_layers_per_block: int = 1, + resnet_eps: float = 1e-6, + resnet_time_scale_shift: str = "default", + resnet_act_fn: str = "swish", + resnet_groups: int = 32, + resnet_pre_norm: bool = True, + attn_num_head_channels=1, + cross_attention_dim=1280, + output_scale_factor=1.0, + downsample_padding=1, + add_downsample=True, + dual_cross_attention=False, + use_linear_projection=False, + only_cross_attention=False, + upcast_attention=False, + unet_use_cross_frame_attention=None, + unet_use_temporal_attention=None, + use_motion_module=None, + motion_module_type=None, + motion_module_kwargs=None, + ): + super().__init__() + resnets = [] + attentions = [] + motion_modules = [] + + self.has_cross_attention = True + self.attn_num_head_channels = attn_num_head_channels + + for i in range(num_layers): + in_channels = in_channels if i == 0 else out_channels + resnets.append( + ResnetBlock3D( + in_channels=in_channels, + out_channels=out_channels, + temb_channels=temb_channels, + eps=resnet_eps, + groups=resnet_groups, + dropout=dropout, + time_embedding_norm=resnet_time_scale_shift, + non_linearity=resnet_act_fn, + output_scale_factor=output_scale_factor, + pre_norm=resnet_pre_norm, + ) + ) + if dual_cross_attention: + raise NotImplementedError + attentions.append( + Transformer3DModel( + num_attention_heads=attn_num_head_channels, + attention_head_dim=out_channels // attn_num_head_channels, + in_channels=out_channels, + num_layers=transformer_layers_per_block, + cross_attention_dim=cross_attention_dim, + norm_num_groups=resnet_groups, + use_linear_projection=use_linear_projection, + only_cross_attention=only_cross_attention, + upcast_attention=upcast_attention, + unet_use_cross_frame_attention=unet_use_cross_frame_attention, + unet_use_temporal_attention=unet_use_temporal_attention, + ) + ) + motion_modules.append( + get_motion_module( + in_channels=out_channels, + motion_module_type=motion_module_type, # type: ignore + motion_module_kwargs=motion_module_kwargs, # type: ignore + ) + if use_motion_module + else None + ) + + self.attentions = nn.ModuleList(attentions) + self.resnets = nn.ModuleList(resnets) + self.motion_modules = nn.ModuleList(motion_modules) + + if add_downsample: + self.downsamplers = nn.ModuleList( + [ + Downsample3D( + out_channels, + use_conv=True, + out_channels=out_channels, + padding=downsample_padding, + name="op", + ) + ] + ) + else: + self.downsamplers = None + + self.gradient_checkpointing = False + + def forward( + self, + hidden_states: torch.FloatTensor, + temb: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + attention_mask: Optional[torch.FloatTensor] = None, + cross_attention_kwargs: Optional[Dict[str, Any]] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + ) -> torch.FloatTensor: + output_states = () + + for resnet, attn, motion_module in zip( + self.resnets, self.attentions, self.motion_modules + ): + if self.training and self.gradient_checkpointing: + + def create_custom_forward(module, return_dict=None): + def custom_forward(*inputs): + if return_dict is not None: + return module(*inputs, return_dict=return_dict) + else: + return module(*inputs) + + return custom_forward + + hidden_states = torch.utils.checkpoint.checkpoint( # type: ignore + create_custom_forward(resnet), hidden_states, temb + ) + hidden_states = torch.utils.checkpoint.checkpoint( # type: ignore + create_custom_forward(attn, return_dict=False), + hidden_states, + encoder_hidden_states, + )[0] + if motion_module is not None: + hidden_states = torch.utils.checkpoint.checkpoint( # type: ignore + create_custom_forward(motion_module), + hidden_states.requires_grad_(), + temb, + encoder_hidden_states, + ) + + else: + hidden_states = resnet(hidden_states, temb) + hidden_states = attn( + hidden_states, + encoder_hidden_states=encoder_hidden_states, + cross_attention_kwargs=cross_attention_kwargs, + attention_mask=attention_mask, + encoder_attention_mask=encoder_attention_mask, + return_dict=False, + )[0] + # add motion module + hidden_states = ( + motion_module( + hidden_states, temb, encoder_hidden_states=encoder_hidden_states + ) + if motion_module is not None + else hidden_states + ) + + output_states = output_states + (hidden_states,) + + if self.downsamplers is not None: + for downsampler in self.downsamplers: + hidden_states = downsampler(hidden_states) + + output_states = output_states + (hidden_states,) + + return hidden_states, output_states # type: ignore + + +@maybe_allow_in_graph +class DownBlock3D(nn.Module): + def __init__( + self, + in_channels: int, + out_channels: int, + temb_channels: int, + dropout: float = 0.0, + num_layers: int = 1, + resnet_eps: float = 1e-6, + resnet_time_scale_shift: str = "default", + resnet_act_fn: str = "swish", + resnet_groups: int = 32, + resnet_pre_norm: bool = True, + output_scale_factor=1.0, + add_downsample=True, + downsample_padding=1, + use_motion_module=None, + motion_module_type=None, + motion_module_kwargs=None, + ): + super().__init__() + resnets = [] + motion_modules = [] + + for i in range(num_layers): + in_channels = in_channels if i == 0 else out_channels + resnets.append( + ResnetBlock3D( + in_channels=in_channels, + out_channels=out_channels, + temb_channels=temb_channels, + eps=resnet_eps, + groups=resnet_groups, + dropout=dropout, + time_embedding_norm=resnet_time_scale_shift, + non_linearity=resnet_act_fn, + output_scale_factor=output_scale_factor, + pre_norm=resnet_pre_norm, + ) + ) + motion_modules.append( + get_motion_module( + in_channels=out_channels, + motion_module_type=motion_module_type, # type: ignore + motion_module_kwargs=motion_module_kwargs, # type: ignore + ) + if use_motion_module + else None + ) + + self.resnets = nn.ModuleList(resnets) + self.motion_modules = nn.ModuleList(motion_modules) + + if add_downsample: + self.downsamplers = nn.ModuleList( + [ + Downsample3D( + out_channels, + use_conv=True, + out_channels=out_channels, + padding=downsample_padding, + name="op", + ) + ] + ) + else: + self.downsamplers = None + + self.gradient_checkpointing = False + + def forward(self, hidden_states, temb=None, encoder_hidden_states=None): + output_states = () + + for resnet, motion_module in zip(self.resnets, self.motion_modules): + if self.training and self.gradient_checkpointing: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs) + + return custom_forward + + hidden_states = torch.utils.checkpoint.checkpoint( # type: ignore + create_custom_forward(resnet), hidden_states, temb + ) + if motion_module is not None: + hidden_states = torch.utils.checkpoint.checkpoint( # type: ignore + create_custom_forward(motion_module), + hidden_states.requires_grad_(), + temb, + encoder_hidden_states, + ) + else: + hidden_states = resnet(hidden_states, temb) + + # add motion module + if motion_module: + hidden_states = motion_module( + hidden_states, temb, encoder_hidden_states=encoder_hidden_states + ) + + output_states = output_states + (hidden_states,) + + if self.downsamplers is not None: + for downsampler in self.downsamplers: + hidden_states = downsampler(hidden_states) + + output_states = output_states + (hidden_states,) + + return hidden_states, output_states + + +@maybe_allow_in_graph +class CrossAttnUpBlock3D(nn.Module): + def __init__( + self, + in_channels: int, + out_channels: int, + prev_output_channel: int, + temb_channels: int, + dropout: float = 0.0, + num_layers: int = 1, + transformer_layers_per_block: int = 1, + resnet_eps: float = 1e-6, + resnet_time_scale_shift: str = "default", + resnet_act_fn: str = "swish", + resnet_groups: int = 32, + resnet_pre_norm: bool = True, + attn_num_head_channels=1, + cross_attention_dim=1280, + output_scale_factor=1.0, + add_upsample=True, + dual_cross_attention=False, + use_linear_projection=False, + only_cross_attention=False, + upcast_attention=False, + unet_use_cross_frame_attention=None, + unet_use_temporal_attention=None, + use_motion_module=None, + motion_module_type=None, + motion_module_kwargs=None, + ): + super().__init__() + resnets = [] + attentions = [] + motion_modules = [] + + self.has_cross_attention = True + self.attn_num_head_channels = attn_num_head_channels + + for i in range(num_layers): + res_skip_channels = in_channels if (i == num_layers - 1) else out_channels + resnet_in_channels = prev_output_channel if i == 0 else out_channels + + resnets.append( + ResnetBlock3D( + in_channels=resnet_in_channels + res_skip_channels, + out_channels=out_channels, + temb_channels=temb_channels, + eps=resnet_eps, + groups=resnet_groups, + dropout=dropout, + time_embedding_norm=resnet_time_scale_shift, + non_linearity=resnet_act_fn, + output_scale_factor=output_scale_factor, + pre_norm=resnet_pre_norm, + ) + ) + if dual_cross_attention: + raise NotImplementedError + attentions.append( + Transformer3DModel( + attn_num_head_channels, + out_channels // attn_num_head_channels, + in_channels=out_channels, + num_layers=transformer_layers_per_block, + cross_attention_dim=cross_attention_dim, + norm_num_groups=resnet_groups, + use_linear_projection=use_linear_projection, + only_cross_attention=only_cross_attention, + upcast_attention=upcast_attention, + unet_use_cross_frame_attention=unet_use_cross_frame_attention, + unet_use_temporal_attention=unet_use_temporal_attention, + ) + ) + motion_modules.append( + get_motion_module( + in_channels=out_channels, + motion_module_type=motion_module_type, # type: ignore + motion_module_kwargs=motion_module_kwargs, # type: ignore + ) + if use_motion_module + else None + ) + + self.attentions = nn.ModuleList(attentions) + self.resnets = nn.ModuleList(resnets) + self.motion_modules = nn.ModuleList(motion_modules) + + if add_upsample: + self.upsamplers = nn.ModuleList( + [Upsample3D(out_channels, use_conv=True, out_channels=out_channels)] + ) + else: + self.upsamplers = None + + self.gradient_checkpointing = False + + def forward( + self, + hidden_states: torch.FloatTensor, + res_hidden_states_tuple: Tuple[torch.FloatTensor, ...], + temb: Optional[torch.FloatTensor] = None, + encoder_hidden_states: Optional[torch.FloatTensor] = None, + cross_attention_kwargs: Optional[Dict[str, Any]] = None, + upsample_size: Optional[int] = None, + attention_mask: Optional[torch.FloatTensor] = None, + encoder_attention_mask: Optional[torch.FloatTensor] = None, + ): + for resnet, attn, motion_module in zip( + self.resnets, self.attentions, self.motion_modules + ): + # pop res hidden states + res_hidden_states = res_hidden_states_tuple[-1] + res_hidden_states_tuple = res_hidden_states_tuple[:-1] + hidden_states = torch.cat([hidden_states, res_hidden_states], dim=1) # type: ignore + + if self.training and self.gradient_checkpointing: + + def create_custom_forward(module, return_dict=None): + def custom_forward(*inputs): + if return_dict is not None: + return module(*inputs, return_dict=return_dict) + else: + return module(*inputs) + + return custom_forward + + hidden_states = torch.utils.checkpoint.checkpoint( # type: ignore + create_custom_forward(resnet), hidden_states, temb + ) + hidden_states = torch.utils.checkpoint.checkpoint( # type: ignore + create_custom_forward(attn, return_dict=False), + hidden_states, + encoder_hidden_states, + )[0] + if motion_module is not None: + hidden_states = torch.utils.checkpoint.checkpoint( # type: ignore + create_custom_forward(motion_module), + hidden_states.requires_grad_(), + temb, + encoder_hidden_states, + ) + + else: + hidden_states = resnet(hidden_states, temb) + hidden_states = attn( + hidden_states, + encoder_hidden_states=encoder_hidden_states, + cross_attention_kwargs=cross_attention_kwargs, + attention_mask=attention_mask, + encoder_attention_mask=encoder_attention_mask, + return_dict=False, + )[0] + + # add motion module + if motion_module: + hidden_states = motion_module( + hidden_states, temb, encoder_hidden_states=encoder_hidden_states + ) + + if self.upsamplers is not None: + for upsampler in self.upsamplers: + hidden_states = upsampler(hidden_states, upsample_size) + + return hidden_states + + +@maybe_allow_in_graph +class UpBlock3D(nn.Module): + def __init__( + self, + in_channels: int, + prev_output_channel: int, + out_channels: int, + temb_channels: int, + dropout: float = 0.0, + num_layers: int = 1, + resnet_eps: float = 1e-6, + resnet_time_scale_shift: str = "default", + resnet_act_fn: str = "swish", + resnet_groups: int = 32, + resnet_pre_norm: bool = True, + output_scale_factor=1.0, + add_upsample=True, + use_motion_module=None, + motion_module_type=None, + motion_module_kwargs=None, + ): + super().__init__() + resnets = [] + motion_modules = [] + + for i in range(num_layers): + res_skip_channels = in_channels if (i == num_layers - 1) else out_channels + resnet_in_channels = prev_output_channel if i == 0 else out_channels + + resnets.append( + ResnetBlock3D( + in_channels=resnet_in_channels + res_skip_channels, + out_channels=out_channels, + temb_channels=temb_channels, + eps=resnet_eps, + groups=resnet_groups, + dropout=dropout, + time_embedding_norm=resnet_time_scale_shift, + non_linearity=resnet_act_fn, + output_scale_factor=output_scale_factor, + pre_norm=resnet_pre_norm, + ) + ) + motion_modules.append( + get_motion_module( + in_channels=out_channels, + motion_module_type=motion_module_type, # type: ignore + motion_module_kwargs=motion_module_kwargs, # type: ignore + ) + if use_motion_module + else None + ) + + self.resnets = nn.ModuleList(resnets) + self.motion_modules = nn.ModuleList(motion_modules) + + if add_upsample: + self.upsamplers = nn.ModuleList( + [Upsample3D(out_channels, use_conv=True, out_channels=out_channels)] + ) + else: + self.upsamplers = None + + self.gradient_checkpointing = False + + def forward( + self, + hidden_states, + res_hidden_states_tuple, + temb=None, + upsample_size=None, + encoder_hidden_states=None, + ): + for resnet, motion_module in zip(self.resnets, self.motion_modules): + # pop res hidden states + res_hidden_states = res_hidden_states_tuple[-1] + res_hidden_states_tuple = res_hidden_states_tuple[:-1] + hidden_states = torch.cat([hidden_states, res_hidden_states], dim=1) + + if self.training and self.gradient_checkpointing: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs) + + return custom_forward + + hidden_states = torch.utils.checkpoint.checkpoint( # type: ignore + create_custom_forward(resnet), hidden_states, temb + ) + if motion_module is not None: + hidden_states = torch.utils.checkpoint.checkpoint( # type: ignore + create_custom_forward(motion_module), + hidden_states.requires_grad_(), + temb, + encoder_hidden_states, + ) + else: + hidden_states = resnet(hidden_states, temb) + if motion_module: + hidden_states = motion_module( + hidden_states, temb, encoder_hidden_states=encoder_hidden_states + ) + + if self.upsamplers is not None: + for upsampler in self.upsamplers: + hidden_states = upsampler(hidden_states, upsample_size) + + return hidden_states diff --git a/core/optimizations/context_manager.py b/core/optimizations/context_manager.py index d975d0d64..cb236f3fa 100644 --- a/core/optimizations/context_manager.py +++ b/core/optimizations/context_manager.py @@ -1,10 +1,9 @@ from contextlib import ExitStack -from typing import List, Optional +from typing import List, Optional, Type import torch from diffusers.models.autoencoder_kl import AutoencoderKL from diffusers.models.unet_2d_condition import UNet2DConditionModel -from diffusers.models.unet_motion_model import UNetMotionModel, MotionAdapter from core.config import config from core.flags import AnimateDiffFlag, Flag @@ -18,12 +17,19 @@ class InferenceContext(ExitStack): unet: torch.nn.Module vae: torch.nn.Module + flags: List[Optional[Flag]] = [] components: dict = {} def to(self, device: str, dtype: torch.dtype): self.unet.to(device=device, dtype=dtype) self.vae.to(device=device, dtype=dtype) + def get_flag(self, _type: Type) -> Optional[Flag]: + try: + return [x for x in self.flags if isinstance(x, _type)].pop() + except IndexError: + return None + def inference_context( unet: UNet2DConditionModel, @@ -43,26 +49,29 @@ def inference_context( disable=config.api.autocast and not unet.force_autocast, ) ) - animatediff = [x for x in flags if isinstance(x, AnimateDiffFlag)] - print(len(flags) - len(animatediff)) - if len(animatediff) != 0: - flag: AnimateDiffFlag = animatediff[0] - motion_adapter: MotionAdapter = MotionAdapter.from_pretrained(flag.motion_model) # type: ignore - motion_adapter.to(dtype=config.api.load_dtype, device=config.api.device) + s.flags = flags + + animatediff: Optional[AnimateDiffFlag] = s.get_flag(AnimateDiffFlag) # type: ignore + if animatediff is not None: + from core.inference.utilities.animatediff.models.unet import ( + UNet3DConditionModel, + ) + from core.inference.utilities.animatediff import patch as patch_animatediff offload = s.unet.device.type == "cpu" - s.unet = UNetMotionModel.from_unet2d( # type: ignore - s.unet, motion_adapter # type: ignore + s.unet = UNet3DConditionModel.from_pretrained_2d( # type: ignore + s.unet, animatediff.motion_model # type: ignore ) - if flag.chunk_feed_forward: - s.unet.enable_forward_chunking() # type: ignore + if config.api.clear_memory_policy == "always": + from core.shared_dependent import gpu + + gpu.memory_cleanup() s.components.update({"unet": s.unet}) cast(s, device=config.api.device, dtype=config.api.dtype, offload=offload) # type: ignore - - s.unet.to(dtype=config.api.load_dtype, device=config.api.device) # type: ignore + patch_animatediff(s) if is_hypertile_available() and config.api.hypertile: s.enter_context(hypertile(unet, height, width)) if config.api.torch_compile: diff --git a/core/png_metadata.py b/core/png_metadata.py index 0c7f13bac..66562ac09 100644 --- a/core/png_metadata.py +++ b/core/png_metadata.py @@ -187,7 +187,7 @@ def save_images( # Save the image buffer = BytesIO() if extension == "gif": - buffer: BytesIO = image + buffer: BytesIO = image # type: ignore else: image.save(buffer, quality=config.api.image_quality) diff --git a/data/motion-models/.gitkeep b/data/motion-models/.gitkeep new file mode 100644 index 000000000..e69de29bb From d1a9b420668cd150429a29227c5f612677abcc56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Kissik?= Date: Tue, 12 Dec 2023 08:45:15 +0100 Subject: [PATCH 104/143] channels last 3d --- core/optimizations/context_manager.py | 19 ++++++++++++++++--- core/optimizations/dtype.py | 23 +++++++++++++---------- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/core/optimizations/context_manager.py b/core/optimizations/context_manager.py index cb236f3fa..65b1926da 100644 --- a/core/optimizations/context_manager.py +++ b/core/optimizations/context_manager.py @@ -7,6 +7,7 @@ from core.config import config from core.flags import AnimateDiffFlag, Flag +from .attn import set_attention_processor from .autocast_utils import autocast from .dtype import cast from .hypertile import is_hypertile_available, hypertile @@ -20,9 +21,15 @@ class InferenceContext(ExitStack): flags: List[Optional[Flag]] = [] components: dict = {} - def to(self, device: str, dtype: torch.dtype): - self.unet.to(device=device, dtype=dtype) - self.vae.to(device=device, dtype=dtype) + def to(self, device: str, dtype: torch.dtype, memory_format): + from core.inference.utilities.animatediff.models.unet import ( + UNet3DConditionModel, + ) + + self.vae.to(device=device, dtype=dtype, memory_format=memory_format) + if isinstance(self.unet, UNet3DConditionModel) and memory_format == torch.channels_last: + memory_format = torch.channels_last_3d + self.unet.to(device=device, dtype=dtype, memory_format=memory_format) def get_flag(self, _type: Type) -> Optional[Flag]: try: @@ -30,6 +37,9 @@ def get_flag(self, _type: Type) -> Optional[Flag]: except IndexError: return None + def enable_xformers_memory_efficient_attention(self): + self.unet.enable_xformers_memory_efficient_attention() + def inference_context( unet: UNet2DConditionModel, @@ -70,7 +80,10 @@ def inference_context( gpu.memory_cleanup() s.components.update({"unet": s.unet}) + cast(s, device=config.api.device, dtype=config.api.dtype, offload=offload) # type: ignore + set_attention_processor(s) + patch_animatediff(s) if is_hypertile_available() and config.api.hypertile: s.enter_context(hypertile(unet, height, width)) diff --git a/core/optimizations/dtype.py b/core/optimizations/dtype.py index 280797362..e66b7f878 100644 --- a/core/optimizations/dtype.py +++ b/core/optimizations/dtype.py @@ -6,6 +6,7 @@ ) from core.config import config +from core.inference.utilities.animatediff.models.unet import UNet3DConditionModel try: force_autocast = [torch.float8_e4m3fn, torch.float8_e5m2] @@ -24,25 +25,26 @@ def cast( # Change the order of the channels to be more efficient for the GPU # DirectML only supports contiguous memory format # Disable for IPEX as well, they don't like torch's way of setting memory format + memory_format = torch.preserve_format if config.api.channels_last: if "privateuseone" in device: logger.warn( "Optimization: Skipping channels_last, since DirectML doesn't support it." ) else: - if hasattr(pipe, "unet"): - pipe.unet.to(memory_format=torch.channels_last) # type: ignore - if hasattr(pipe, "vae"): - pipe.vae.to(memory_format=torch.channels_last) # type: ignore + memory_format = torch.channels_last logger.info("Optimization: Enabled channels_last memory format") pipe.unet.force_autocast = dtype in force_autocast if pipe.unet.force_autocast: - for m in [x.modules() for x in pipe.components.values() if hasattr(x, "modules")]: # type: ignore - if "CLIP" in m.__class__.__name__: - m.to(device=None if offload else device, dtype=config.api.load_dtype) + for b in [x for x in pipe.components.values() if hasattr(x, "modules")]: # type: ignore + mem = memory_format + if isinstance(b, UNet3DConditionModel) and memory_format == torch.channels_last: + mem = torch.channels_last_3d + if "CLIP" in b.__class__.__name__: + b.to(device=None if offload else device, dtype=config.api.load_dtype) else: - for module in m: + for module in b.modules(): if any( [ x @@ -54,15 +56,16 @@ def cast( del module.fp16_weight if config.api.cache_fp16_weight: module.fp16_weight = module.weight.clone().half() - module.to(device=None if offload else device, dtype=dtype) + module.to(device=None if offload else device, dtype=dtype, memory_format=mem) else: module.to( device=None if offload else device, dtype=config.api.load_dtype, + memory_format=mem, ) if not config.api.autocast: logger.info("Optimization: Forcing autocast on due to float8 weights.") else: - pipe.to(device=None if offload else device, dtype=dtype) + pipe.to(device=None if offload else device, dtype=dtype, memory_format=memory_format) return pipe From 7cbacaeedc986923fa8fac94a6340a59241d6bd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Kissik?= Date: Tue, 12 Dec 2023 12:55:46 +0100 Subject: [PATCH 105/143] fix circular import --- core/optimizations/dtype.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/optimizations/dtype.py b/core/optimizations/dtype.py index e66b7f878..76600ae80 100644 --- a/core/optimizations/dtype.py +++ b/core/optimizations/dtype.py @@ -6,7 +6,6 @@ ) from core.config import config -from core.inference.utilities.animatediff.models.unet import UNet3DConditionModel try: force_autocast = [torch.float8_e4m3fn, torch.float8_e5m2] @@ -39,6 +38,9 @@ def cast( if pipe.unet.force_autocast: for b in [x for x in pipe.components.values() if hasattr(x, "modules")]: # type: ignore mem = memory_format + + from core.inference.utilities.animatediff.models.unet import UNet3DConditionModel + if isinstance(b, UNet3DConditionModel) and memory_format == torch.channels_last: mem = torch.channels_last_3d if "CLIP" in b.__class__.__name__: From 84fa9e92b8142bd556154f2c7afa7cc775c28552 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Kissik?= Date: Tue, 12 Dec 2023 13:19:18 +0100 Subject: [PATCH 106/143] SAG with SDPA --- core/inference/utilities/sag/cross_attn.py | 154 +++++++++++++++++---- core/inference/utilities/sag/diffusers.py | 4 +- core/inference/utilities/sag/kdiff.py | 4 +- core/inference/utilities/sag/sag_utils.py | 3 +- 4 files changed, 134 insertions(+), 31 deletions(-) diff --git a/core/inference/utilities/sag/cross_attn.py b/core/inference/utilities/sag/cross_attn.py index 2a30cd88c..b29af8851 100644 --- a/core/inference/utilities/sag/cross_attn.py +++ b/core/inference/utilities/sag/cross_attn.py @@ -1,11 +1,14 @@ import torch +from core.config import config + class CrossAttnStoreProcessor: "Modified Cross Attention Processor with capabilities to store probabilities." def __init__(self): - self.attention_probs = None + self.attention_map = None + self.use_sdpa = any([x == config.api.attention_processor for x in ["sdpa", "xformers"]]) def __call__( self, @@ -13,34 +16,135 @@ def __call__( hidden_states, encoder_hidden_states=None, attention_mask=None, + temb=None, ): - batch_size, sequence_length, _ = hidden_states.shape - attention_mask = attn.prepare_attention_mask( - attention_mask, sequence_length, batch_size - ) - query = attn.to_q(hidden_states) - - if encoder_hidden_states is None: - encoder_hidden_states = hidden_states - elif attn.norm_cross: - encoder_hidden_states = attn.norm_encoder_hidden_states( - encoder_hidden_states + if not self.use_sdpa: + residual = hidden_states + + if attn.spatial_norm is not None: + hidden_states = attn.spatial_norm(hidden_states, temb) + + input_ndim = hidden_states.ndim + + if input_ndim == 4: + batch_size, channel, height, width = hidden_states.shape + hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2) + + batch_size, sequence_length, _ = ( + hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape ) + attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size) + + if attn.group_norm is not None: + hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2) + + query = attn.to_q(hidden_states) + + if encoder_hidden_states is None: + encoder_hidden_states = hidden_states + elif attn.norm_cross: + encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states) + + key = attn.to_k(encoder_hidden_states) + value = attn.to_v(encoder_hidden_states) + + query = attn.head_to_batch_dim(query) + key = attn.head_to_batch_dim(key) + value = attn.head_to_batch_dim(value) + + attention_probs = attn.get_attention_scores(query, key, attention_mask) + self.attention_map = attention_probs.reshape(batch_size, -1, *attention_probs.shape[1:]).mean(1).sum(1) + hidden_states = torch.bmm(attention_probs, value) + hidden_states = attn.batch_to_head_dim(hidden_states) + + # linear proj + hidden_states = attn.to_out[0](hidden_states) + # dropout + hidden_states = attn.to_out[1](hidden_states) + + if input_ndim == 4: + hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width) # type: ignore + + if attn.residual_connection: + hidden_states = hidden_states + residual + + hidden_states = hidden_states / attn.rescale_output_factor + + return hidden_states + else: + residual = hidden_states + + if attn.spatial_norm is not None: + hidden_states = attn.spatial_norm(hidden_states, temb) + + input_ndim = hidden_states.ndim + + if input_ndim == 4: + batch_size, channel, height, width = hidden_states.shape + hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2) + + batch_size, sequence_length, _ = ( + hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape + ) + + if attention_mask is not None: + attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size) + # scaled_dot_product_attention expects attention_mask shape to be + # (batch, heads, source_length, target_length) + attention_mask = attention_mask.view(batch_size, attn.heads, -1, attention_mask.shape[-1]) + + if attn.group_norm is not None: + hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2) + + query = attn.to_q(hidden_states) + + if encoder_hidden_states is None: + encoder_hidden_states = hidden_states + elif attn.norm_cross: + encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states) + + key = attn.to_k(encoder_hidden_states) + value = attn.to_v(encoder_hidden_states) + + inner_dim = key.shape[-1] + head_dim = inner_dim // attn.heads + + query = query.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2) + + key = key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2) + value = value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2) + + # the output of sdp = (batch, num_heads, seq_len, head_dim) + # TODO: add support for attn.scale when we move to Torch 2.1 + hidden_states = torch.nn.functional.scaled_dot_product_attention( + query, key, value, attn_mask=attention_mask, dropout_p=0.0, is_causal=False + ) + + dummy_value_eye = torch.eye(value.shape[2], device=value.device, dtype=value.dtype).expand( + batch_size, attn.heads, -1, -1 + ) + self.attention_map = ( + torch.nn.functional.scaled_dot_product_attention( + query, key, dummy_value_eye, attn_mask=attention_mask, dropout_p=0.0, is_causal=False + ) + .mean(1) + .sum(1) + ) + + hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, attn.heads * head_dim) + hidden_states = hidden_states.to(query.dtype) - key = attn.to_k(encoder_hidden_states) - value = attn.to_v(encoder_hidden_states) + # linear proj + hidden_states = attn.to_out[0](hidden_states) + # dropout + hidden_states = attn.to_out[1](hidden_states) - query = attn.head_to_batch_dim(query) - key = attn.head_to_batch_dim(key) - value = attn.head_to_batch_dim(value) + if input_ndim == 4: + hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width) # type: ignore - self.attention_probs = attn.get_attention_scores(query, key, attention_mask) - hidden_states = torch.bmm(self.attention_probs, value) - hidden_states = attn.batch_to_head_dim(hidden_states) + if attn.residual_connection: + hidden_states = hidden_states + residual - # linear proj - hidden_states = attn.to_out[0](hidden_states) - # dropout - hidden_states = attn.to_out[1](hidden_states) + hidden_states = hidden_states / attn.rescale_output_factor - return hidden_states + return hidden_states \ No newline at end of file diff --git a/core/inference/utilities/sag/diffusers.py b/core/inference/utilities/sag/diffusers.py index a679d6255..ddb4c4b37 100644 --- a/core/inference/utilities/sag/diffusers.py +++ b/core/inference/utilities/sag/diffusers.py @@ -21,10 +21,10 @@ def calculate_sag( ) -> torch.Tensor: pred: torch.Tensor = pred_x0(pipe, latent, noise, timestep) if cfg > 1: - cond_attn, _ = store_processor.attention_probs.chunk(2) + cond_attn, _ = store_processor.attention_map.chunk(2) text_embeddings, _ = text_embeddings.chunk(2) else: - cond_attn = store_processor.attention_probs + cond_attn = store_processor.attention_map eps = pred_epsilon(pipe, latent, noise, timestep) degraded: torch.Tensor = sag_masking(pipe, pred, cond_attn, map_size, timestep, eps) diff --git a/core/inference/utilities/sag/kdiff.py b/core/inference/utilities/sag/kdiff.py index 91c037c08..bb7bbd4a5 100644 --- a/core/inference/utilities/sag/kdiff.py +++ b/core/inference/utilities/sag/kdiff.py @@ -21,10 +21,10 @@ def calculate_sag( ) -> torch.Tensor: pred: torch.Tensor = noise # noise is already pred_x0 with kdiff if cfg > 1: - cond_attn, _ = store_processor.attention_probs.chunk(2) + cond_attn, _ = store_processor.attention_map.chunk(2) text_embeddings, _ = text_embeddings.chunk(2) else: - cond_attn = store_processor.attention_probs + cond_attn = store_processor.attention_map degraded: torch.Tensor = sag_masking(pipe, pred, cond_attn, map_size, timestep, 0) diff --git a/core/inference/utilities/sag/sag_utils.py b/core/inference/utilities/sag/sag_utils.py index e4ad10325..bd45346cd 100644 --- a/core/inference/utilities/sag/sag_utils.py +++ b/core/inference/utilities/sag/sag_utils.py @@ -47,8 +47,7 @@ def sag_masking(pipe, original_latents, attn_map, map_size, t, eps): h = h[-1] # Produce attention mask - attn_map = attn_map.reshape(b, h, hw1, hw2) - attn_mask = attn_map.mean(1, keepdim=False).sum(1, keepdim=False) > 1.0 + attn_mask = attn_map > 1.0 attn_mask = ( attn_mask.reshape(b, map_size[0], map_size[1]) .unsqueeze(1) From 982bfb6a0ba575638150864a3941ad07977f59e2 Mon Sep 17 00:00:00 2001 From: gabe56f Date: Tue, 12 Dec 2023 16:30:52 +0100 Subject: [PATCH 107/143] format --- core/inference/utilities/sag/cross_attn.py | 80 ++++++++++++++++------ core/optimizations/context_manager.py | 9 ++- core/optimizations/dtype.py | 25 +++++-- 3 files changed, 84 insertions(+), 30 deletions(-) diff --git a/core/inference/utilities/sag/cross_attn.py b/core/inference/utilities/sag/cross_attn.py index b29af8851..f699c9bcd 100644 --- a/core/inference/utilities/sag/cross_attn.py +++ b/core/inference/utilities/sag/cross_attn.py @@ -8,7 +8,9 @@ class CrossAttnStoreProcessor: def __init__(self): self.attention_map = None - self.use_sdpa = any([x == config.api.attention_processor for x in ["sdpa", "xformers"]]) + self.use_sdpa = any( + [x == config.api.attention_processor for x in ["sdpa", "xformers"]] + ) def __call__( self, @@ -28,22 +30,32 @@ def __call__( if input_ndim == 4: batch_size, channel, height, width = hidden_states.shape - hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2) + hidden_states = hidden_states.view( + batch_size, channel, height * width + ).transpose(1, 2) batch_size, sequence_length, _ = ( - hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape + hidden_states.shape + if encoder_hidden_states is None + else encoder_hidden_states.shape + ) + attention_mask = attn.prepare_attention_mask( + attention_mask, sequence_length, batch_size ) - attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size) if attn.group_norm is not None: - hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2) + hidden_states = attn.group_norm( + hidden_states.transpose(1, 2) + ).transpose(1, 2) query = attn.to_q(hidden_states) if encoder_hidden_states is None: encoder_hidden_states = hidden_states elif attn.norm_cross: - encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states) + encoder_hidden_states = attn.norm_encoder_hidden_states( + encoder_hidden_states + ) key = attn.to_k(encoder_hidden_states) value = attn.to_v(encoder_hidden_states) @@ -53,7 +65,11 @@ def __call__( value = attn.head_to_batch_dim(value) attention_probs = attn.get_attention_scores(query, key, attention_mask) - self.attention_map = attention_probs.reshape(batch_size, -1, *attention_probs.shape[1:]).mean(1).sum(1) + self.attention_map = ( + attention_probs.reshape(batch_size, -1, *attention_probs.shape[1:]) + .mean(1) + .sum(1) + ) hidden_states = torch.bmm(attention_probs, value) hidden_states = attn.batch_to_head_dim(hidden_states) @@ -81,27 +97,39 @@ def __call__( if input_ndim == 4: batch_size, channel, height, width = hidden_states.shape - hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2) + hidden_states = hidden_states.view( + batch_size, channel, height * width + ).transpose(1, 2) batch_size, sequence_length, _ = ( - hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape + hidden_states.shape + if encoder_hidden_states is None + else encoder_hidden_states.shape ) if attention_mask is not None: - attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size) + attention_mask = attn.prepare_attention_mask( + attention_mask, sequence_length, batch_size + ) # scaled_dot_product_attention expects attention_mask shape to be # (batch, heads, source_length, target_length) - attention_mask = attention_mask.view(batch_size, attn.heads, -1, attention_mask.shape[-1]) + attention_mask = attention_mask.view( + batch_size, attn.heads, -1, attention_mask.shape[-1] + ) if attn.group_norm is not None: - hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2) + hidden_states = attn.group_norm( + hidden_states.transpose(1, 2) + ).transpose(1, 2) query = attn.to_q(hidden_states) if encoder_hidden_states is None: encoder_hidden_states = hidden_states elif attn.norm_cross: - encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states) + encoder_hidden_states = attn.norm_encoder_hidden_states( + encoder_hidden_states + ) key = attn.to_k(encoder_hidden_states) value = attn.to_v(encoder_hidden_states) @@ -117,21 +145,33 @@ def __call__( # the output of sdp = (batch, num_heads, seq_len, head_dim) # TODO: add support for attn.scale when we move to Torch 2.1 hidden_states = torch.nn.functional.scaled_dot_product_attention( - query, key, value, attn_mask=attention_mask, dropout_p=0.0, is_causal=False + query, + key, + value, + attn_mask=attention_mask, + dropout_p=0.0, + is_causal=False, ) - dummy_value_eye = torch.eye(value.shape[2], device=value.device, dtype=value.dtype).expand( - batch_size, attn.heads, -1, -1 - ) + dummy_value_eye = torch.eye( + value.shape[2], device=value.device, dtype=value.dtype + ).expand(batch_size, attn.heads, -1, -1) self.attention_map = ( torch.nn.functional.scaled_dot_product_attention( - query, key, dummy_value_eye, attn_mask=attention_mask, dropout_p=0.0, is_causal=False + query, + key, + dummy_value_eye, + attn_mask=attention_mask, + dropout_p=0.0, + is_causal=False, ) .mean(1) .sum(1) ) - hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, attn.heads * head_dim) + hidden_states = hidden_states.transpose(1, 2).reshape( + batch_size, -1, attn.heads * head_dim + ) hidden_states = hidden_states.to(query.dtype) # linear proj @@ -147,4 +187,4 @@ def __call__( hidden_states = hidden_states / attn.rescale_output_factor - return hidden_states \ No newline at end of file + return hidden_states diff --git a/core/optimizations/context_manager.py b/core/optimizations/context_manager.py index 65b1926da..14d9e8f5c 100644 --- a/core/optimizations/context_manager.py +++ b/core/optimizations/context_manager.py @@ -26,10 +26,13 @@ def to(self, device: str, dtype: torch.dtype, memory_format): UNet3DConditionModel, ) - self.vae.to(device=device, dtype=dtype, memory_format=memory_format) - if isinstance(self.unet, UNet3DConditionModel) and memory_format == torch.channels_last: + self.vae.to(device=device, dtype=dtype, memory_format=memory_format) # type: ignore + if ( + isinstance(self.unet, UNet3DConditionModel) + and memory_format == torch.channels_last + ): memory_format = torch.channels_last_3d - self.unet.to(device=device, dtype=dtype, memory_format=memory_format) + self.unet.to(device=device, dtype=dtype, memory_format=memory_format) # type: ignore def get_flag(self, _type: Type) -> Optional[Flag]: try: diff --git a/core/optimizations/dtype.py b/core/optimizations/dtype.py index 76600ae80..b4394baf5 100644 --- a/core/optimizations/dtype.py +++ b/core/optimizations/dtype.py @@ -38,10 +38,15 @@ def cast( if pipe.unet.force_autocast: for b in [x for x in pipe.components.values() if hasattr(x, "modules")]: # type: ignore mem = memory_format - - from core.inference.utilities.animatediff.models.unet import UNet3DConditionModel - - if isinstance(b, UNet3DConditionModel) and memory_format == torch.channels_last: + + from core.inference.utilities.animatediff.models.unet import ( + UNet3DConditionModel, + ) + + if ( + isinstance(b, UNet3DConditionModel) + and memory_format == torch.channels_last + ): mem = torch.channels_last_3d if "CLIP" in b.__class__.__name__: b.to(device=None if offload else device, dtype=config.api.load_dtype) @@ -58,9 +63,13 @@ def cast( del module.fp16_weight if config.api.cache_fp16_weight: module.fp16_weight = module.weight.clone().half() - module.to(device=None if offload else device, dtype=dtype, memory_format=mem) + module.to( # type: ignore + device=None if offload else device, + dtype=dtype, + memory_format=mem, + ) else: - module.to( + module.to( # type: ignore device=None if offload else device, dtype=config.api.load_dtype, memory_format=mem, @@ -68,6 +77,8 @@ def cast( if not config.api.autocast: logger.info("Optimization: Forcing autocast on due to float8 weights.") else: - pipe.to(device=None if offload else device, dtype=dtype, memory_format=memory_format) + pipe.to( + device=None if offload else device, dtype=dtype, memory_format=memory_format + ) return pipe From c514e6255f7ae7f4428a942b934231196d1174e7 Mon Sep 17 00:00:00 2001 From: Stax124 Date: Tue, 12 Dec 2023 16:45:06 +0100 Subject: [PATCH 108/143] DeepShrink and scalecrafter default settings, better UI --- core/config/default_settings.py | 2 + core/config/flags_settings.py | 11 +- core/flags.py | 4 + frontend/dist/assets/AccelerateView.js | 2 +- frontend/dist/assets/DescriptionsItem.js | 2 +- frontend/dist/assets/ExtraView.js | 2 +- ...ion.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/Image2ImageView.js | 4 +- frontend/dist/assets/ImageBrowserView.js | 2 +- ...put.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/ImageProcessingView.js | 2 +- frontend/dist/assets/ImageUpload.js | 2 +- frontend/dist/assets/InputNumber.js | 2 +- ...pup.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/ModelsView.js | 2 +- ...ter.vue_vue_type_script_setup_true_lang.js | 368 ++++++++++++++++++ ...tTo.vue_vue_type_script_setup_true_lang.js | 2 +- frontend/dist/assets/Settings.js | 2 +- frontend/dist/assets/SettingsView.js | 5 +- frontend/dist/assets/Slider.js | 2 +- frontend/dist/assets/Switch.js | 2 +- frontend/dist/assets/TaggerView.js | 2 +- frontend/dist/assets/TestView.js | 2 +- frontend/dist/assets/TextToImageView.js | 347 ++--------------- frontend/dist/assets/TrashBin.js | 2 +- ...ale.vue_vue_type_script_setup_true_lang.js | 244 ++++++------ frontend/dist/assets/clock.js | 2 +- frontend/dist/assets/index.js | 60 +-- .../src/components/generate/DeepShrink.vue | 197 +++++----- .../src/components/generate/HighResFix.vue | 209 +++++----- .../components/generate/HighResFixTabs.vue | 34 ++ .../src/components/generate/Scalecrafter.vue | 80 ++-- frontend/src/components/generate/index.ts | 1 + frontend/src/components/inference/Txt2Img.vue | 12 +- .../defaultSettings/ControlNetSettings.vue | 4 +- .../defaultSettings/ImageToImageSettings.vue | 4 +- .../defaultSettings/InpaintingSettings.vue | 4 +- .../defaultSettings/TextToImageSettings.vue | 4 +- 38 files changed, 874 insertions(+), 758 deletions(-) create mode 100644 frontend/dist/assets/Scalecrafter.vue_vue_type_script_setup_true_lang.js create mode 100644 frontend/src/components/generate/HighResFixTabs.vue diff --git a/core/config/default_settings.py b/core/config/default_settings.py index 1c33da11b..807da04d3 100644 --- a/core/config/default_settings.py +++ b/core/config/default_settings.py @@ -68,6 +68,8 @@ class InpaintingConfig(BaseDiffusionMixin): class ControlNetConfig(BaseDiffusionMixin): "Configuration for the inpainting pipeline" + self_attention_scale: float = 0.0 + controlnet: str = "lllyasviel/sd-controlnet-canny" controlnet_conditioning_scale: float = 1.0 detection_resolution: int = 512 diff --git a/core/config/flags_settings.py b/core/config/flags_settings.py index e1a2394e3..b921fba7b 100644 --- a/core/config/flags_settings.py +++ b/core/config/flags_settings.py @@ -1,20 +1,11 @@ from dataclasses import dataclass, field -from core.flags import ( - HighResFixFlag, - SDXLFlag, - SDXLRefinerFlag, - DeepshrinkFlag, - ScalecrafterFlag, -) +from core.flags import SDXLFlag, SDXLRefinerFlag @dataclass class FlagsConfig: "Configuration for flags" - highres: HighResFixFlag = field(default_factory=HighResFixFlag) refiner: SDXLRefinerFlag = field(default_factory=SDXLRefinerFlag) sdxl: SDXLFlag = field(default_factory=SDXLFlag) - deepshrink: DeepshrinkFlag = field(default_factory=DeepshrinkFlag) - scalecrafter: ScalecrafterFlag = field(default_factory=ScalecrafterFlag) diff --git a/core/flags.py b/core/flags.py index 651b130b8..f5390ed57 100644 --- a/core/flags.py +++ b/core/flags.py @@ -43,6 +43,8 @@ class HighResFixFlag(Flag, DataClassJsonMixin): class DeepshrinkFlag(Flag, DataClassJsonMixin): "Flag for deepshrink" + enabled: bool = False # For storing in json + depth_1: int = 3 # -1 to 12; steps of 1 stop_at_1: float = 0.15 # 0 to 0.5; steps of 0.01 @@ -58,6 +60,8 @@ class DeepshrinkFlag(Flag, DataClassJsonMixin): class ScalecrafterFlag(Flag, DataClassJsonMixin): "Flag for Scalecrafter settings" + enabled: bool = False # For storing in json + base: str = "sd15" # In other words: allow untested/"unsafe" resolutions like "1234x4321" unsafe_resolutions: bool = True diff --git a/frontend/dist/assets/AccelerateView.js b/frontend/dist/assets/AccelerateView.js index f75c598cc..3dd08490d 100644 --- a/frontend/dist/assets/AccelerateView.js +++ b/frontend/dist/assets/AccelerateView.js @@ -1,4 +1,4 @@ -import { Q as cB, ab as cM, aa as c, at as cE, aT as iconSwitchTransition, ac as cNotM, d as defineComponent, S as useConfig, ag as useRtl, T as useTheme, a3 as provide, x as h, aw as flatten, ax as getSlot, P as createInjectionKey, bi as stepsLight, R as inject, a_ as throwError, c as computed, ah as createKey, Y as useThemeClass, a1 as call, av as resolveWrappedSlot, ai as resolveSlot, aI as NIconSwitchTransition, aj as NBaseIcon, bj as FinishedIcon, bk as ErrorIcon, n as useMessage, j as useState, y as ref, o as openBlock, g as createElementBlock, e as createVNode, w as withCtx, f as unref, k as NSpace, N as NCard, b as createBaseVNode, h as NSelect, z as NButton, l as createTextVNode, bf as NModal, s as serverUrl, u as useSettings, a as createBlock, C as NTabPane, D as NTabs } from "./index.js"; +import { Q as cB, ab as cM, aa as c, at as cE, aT as iconSwitchTransition, ac as cNotM, d as defineComponent, S as useConfig, ag as useRtl, T as useTheme, a3 as provide, x as h, aw as flatten, ax as getSlot, P as createInjectionKey, bi as stepsLight, R as inject, a_ as throwError, i as computed, ah as createKey, Y as useThemeClass, a1 as call, av as resolveWrappedSlot, ai as resolveSlot, aI as NIconSwitchTransition, aj as NBaseIcon, bj as FinishedIcon, bk as ErrorIcon, n as useMessage, a as useState, y as ref, o as openBlock, g as createElementBlock, e as createVNode, w as withCtx, f as unref, j as NSpace, N as NCard, b as createBaseVNode, m as NSelect, z as NButton, k as createTextVNode, bf as NModal, s as serverUrl, u as useSettings, c as createBlock, C as NTabPane, D as NTabs } from "./index.js"; import { N as NSlider } from "./Slider.js"; import { N as NInputNumber } from "./InputNumber.js"; import { N as NSwitch } from "./Switch.js"; diff --git a/frontend/dist/assets/DescriptionsItem.js b/frontend/dist/assets/DescriptionsItem.js index 640125c63..df59f7845 100644 --- a/frontend/dist/assets/DescriptionsItem.js +++ b/frontend/dist/assets/DescriptionsItem.js @@ -1,4 +1,4 @@ -import { aa as c, Q as cB, ac as cNotM, ab as cM, at as cE, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, c as computed, ah as createKey, Y as useThemeClass, bU as useCompitable, aw as flatten, x as h, aQ as repeat, ax as getSlot, bV as descriptionsLight } from "./index.js"; +import { aa as c, Q as cB, ac as cNotM, ab as cM, at as cE, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, i as computed, ah as createKey, Y as useThemeClass, bV as useCompitable, aw as flatten, x as h, aQ as repeat, ax as getSlot, bW as descriptionsLight } from "./index.js"; function getVNodeChildren(vNode, slotName = "default", fallback = []) { const { children } = vNode; if (children !== null && typeof children === "object" && !Array.isArray(children)) { diff --git a/frontend/dist/assets/ExtraView.js b/frontend/dist/assets/ExtraView.js index 34e03be17..1c56eef7b 100644 --- a/frontend/dist/assets/ExtraView.js +++ b/frontend/dist/assets/ExtraView.js @@ -1,4 +1,4 @@ -import { _ as _export_sfc, d as defineComponent, j as useState, o as openBlock, a as createBlock, w as withCtx, f as unref, e as createVNode, C as NTabPane, D as NTabs } from "./index.js"; +import { _ as _export_sfc, d as defineComponent, a as useState, o as openBlock, c as createBlock, w as withCtx, f as unref, e as createVNode, C as NTabPane, D as NTabs } from "./index.js"; const _sfc_main$2 = {}; function _sfc_render$1(_ctx, _cache) { return "Autofill manager"; diff --git a/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js index 2bfa8ef52..a990552c6 100644 --- a/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/GenerateSection.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, j as useState, u as useSettings, y as ref, ba as onMounted, p as onUnmounted, s as serverUrl, a as createBlock, w as withCtx, e as createVNode, f as unref, q as NGi, z as NButton, A as NIcon, l as createTextVNode, r as NGrid, bW as NAlert, i as createCommentVNode, N as NCard } from "./index.js"; +import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, a as useState, u as useSettings, y as ref, ba as onMounted, p as onUnmounted, s as serverUrl, c as createBlock, w as withCtx, e as createVNode, f as unref, q as NGi, z as NButton, A as NIcon, k as createTextVNode, r as NGrid, bE as NAlert, h as createCommentVNode, N as NCard } from "./index.js"; const _hoisted_1$1 = { xmlns: "http://www.w3.org/2000/svg", "xmlns:xlink": "http://www.w3.org/1999/xlink", diff --git a/frontend/dist/assets/Image2ImageView.js b/frontend/dist/assets/Image2ImageView.js index 19023db00..fb58e584c 100644 --- a/frontend/dist/assets/Image2ImageView.js +++ b/frontend/dist/assets/Image2ImageView.js @@ -1,9 +1,9 @@ -import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, j as useState, u as useSettings, n as useMessage, c as computed, p as onUnmounted, e as createVNode, w as withCtx, f as unref, q as NGi, N as NCard, k as NSpace, m as NTooltip, l as createTextVNode, h as NSelect, a as createBlock, i as createCommentVNode, r as NGrid, s as serverUrl, t as pushScopeId, v as popScopeId, _ as _export_sfc, x as h, y as ref, z as NButton, A as NIcon, B as toDisplayString, C as NTabPane, D as NTabs } from "./index.js"; +import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, a as useState, u as useSettings, n as useMessage, i as computed, p as onUnmounted, e as createVNode, w as withCtx, f as unref, q as NGi, N as NCard, j as NSpace, l as NTooltip, k as createTextVNode, m as NSelect, c as createBlock, h as createCommentVNode, r as NGrid, s as serverUrl, t as pushScopeId, v as popScopeId, _ as _export_sfc, x as h, y as ref, z as NButton, A as NIcon, B as toDisplayString, C as NTabPane, D as NTabs } from "./index.js"; import { B as BurnerClock, P as Prompt, _ as _sfc_main$5, a as _sfc_main$6, b as _sfc_main$7, c as _sfc_main$8, d as _sfc_main$d } from "./clock.js"; import { _ as _sfc_main$b } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; import { _ as _sfc_main$c } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; import { I as ImageUpload } from "./ImageUpload.js"; -import { _ as _sfc_main$4, a as _sfc_main$9, b as _sfc_main$a } from "./Upscale.vue_vue_type_script_setup_true_lang.js"; +import { _ as _sfc_main$4, b as _sfc_main$9, a as _sfc_main$a } from "./Upscale.vue_vue_type_script_setup_true_lang.js"; import { v as v4 } from "./v4.js"; import { N as NSlider } from "./Slider.js"; import { N as NInputNumber } from "./InputNumber.js"; diff --git a/frontend/dist/assets/ImageBrowserView.js b/frontend/dist/assets/ImageBrowserView.js index f64024d37..144f48b50 100644 --- a/frontend/dist/assets/ImageBrowserView.js +++ b/frontend/dist/assets/ImageBrowserView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, b7 as useCssVars, j as useState, u as useSettings, R as inject, y as ref, c as computed, bK as urlFromPath, b9 as reactive, ba as onMounted, p as onUnmounted, e as createVNode, f as unref, w as withCtx, F as Fragment, L as renderList, b8 as themeOverridesKey, s as serverUrl, I as NInput, A as NIcon, bf as NModal, r as NGrid, q as NGi, z as NButton, l as createTextVNode, M as NScrollbar, a as createBlock, bA as convertToTextString, B as toDisplayString, i as createCommentVNode, bL as diffusersSchedulerTuple, _ as _export_sfc } from "./index.js"; +import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, b7 as useCssVars, a as useState, u as useSettings, R as inject, y as ref, i as computed, bL as urlFromPath, b9 as reactive, ba as onMounted, p as onUnmounted, e as createVNode, f as unref, w as withCtx, F as Fragment, L as renderList, b8 as themeOverridesKey, s as serverUrl, I as NInput, A as NIcon, bf as NModal, r as NGrid, q as NGi, z as NButton, k as createTextVNode, M as NScrollbar, c as createBlock, bA as convertToTextString, B as toDisplayString, h as createCommentVNode, bM as diffusersSchedulerTuple, _ as _export_sfc } from "./index.js"; import { D as Download, _ as _sfc_main$1 } from "./SendOutputTo.vue_vue_type_script_setup_true_lang.js"; import { N as NImage, T as TrashBin } from "./TrashBin.js"; import { N as NSlider } from "./Slider.js"; diff --git a/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js index 55e8d61c2..f5b4f964a 100644 --- a/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/ImageOutput.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { d as defineComponent, y as ref, j as useState, o as openBlock, a as createBlock, w as withCtx, f as unref, q as NGi, e as createVNode, A as NIcon, l as createTextVNode, z as NButton, i as createCommentVNode, r as NGrid, c as computed, b as createBaseVNode, g as createElementBlock, F as Fragment, L as renderList, M as NScrollbar, N as NCard } from "./index.js"; +import { d as defineComponent, y as ref, a as useState, o as openBlock, c as createBlock, w as withCtx, f as unref, q as NGi, e as createVNode, A as NIcon, k as createTextVNode, z as NButton, h as createCommentVNode, r as NGrid, i as computed, b as createBaseVNode, g as createElementBlock, F as Fragment, L as renderList, M as NScrollbar, N as NCard } from "./index.js"; import { D as Download, _ as _sfc_main$2 } from "./SendOutputTo.vue_vue_type_script_setup_true_lang.js"; import { T as TrashBin, N as NImage } from "./TrashBin.js"; const _sfc_main$1 = /* @__PURE__ */ defineComponent({ diff --git a/frontend/dist/assets/ImageProcessingView.js b/frontend/dist/assets/ImageProcessingView.js index 9792ea445..081f5a5f2 100644 --- a/frontend/dist/assets/ImageProcessingView.js +++ b/frontend/dist/assets/ImageProcessingView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, j as useState, u as useSettings, n as useMessage, c as computed, K as upscalerOptions, o as openBlock, g as createElementBlock, e as createVNode, w as withCtx, f as unref, q as NGi, N as NCard, k as NSpace, b as createBaseVNode, h as NSelect, m as NTooltip, l as createTextVNode, r as NGrid, s as serverUrl, a as createBlock, C as NTabPane, D as NTabs } from "./index.js"; +import { d as defineComponent, a as useState, u as useSettings, n as useMessage, i as computed, K as upscalerOptions, o as openBlock, g as createElementBlock, e as createVNode, w as withCtx, f as unref, q as NGi, N as NCard, j as NSpace, b as createBaseVNode, m as NSelect, l as NTooltip, k as createTextVNode, r as NGrid, s as serverUrl, c as createBlock, C as NTabPane, D as NTabs } from "./index.js"; import { _ as _sfc_main$2 } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; import { _ as _sfc_main$3 } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; import { I as ImageUpload } from "./ImageUpload.js"; diff --git a/frontend/dist/assets/ImageUpload.js b/frontend/dist/assets/ImageUpload.js index 4f71b434f..62a763014 100644 --- a/frontend/dist/assets/ImageUpload.js +++ b/frontend/dist/assets/ImageUpload.js @@ -1,4 +1,4 @@ -import { d as defineComponent, y as ref, c as computed, ba as onMounted, o as openBlock, a as createBlock, w as withCtx, b as createBaseVNode, bd as withModifiers, g as createElementBlock, e as createVNode, f as unref, A as NIcon, B as toDisplayString, N as NCard, t as pushScopeId, v as popScopeId, _ as _export_sfc } from "./index.js"; +import { d as defineComponent, y as ref, i as computed, ba as onMounted, o as openBlock, c as createBlock, w as withCtx, b as createBaseVNode, bd as withModifiers, g as createElementBlock, e as createVNode, f as unref, A as NIcon, B as toDisplayString, N as NCard, t as pushScopeId, v as popScopeId, _ as _export_sfc } from "./index.js"; import { C as CloudUpload } from "./CloudUpload.js"; const _withScopeId = (n) => (pushScopeId("data-v-9ed1514f"), n = n(), popScopeId(), n); const _hoisted_1 = { class: "image-container" }; diff --git a/frontend/dist/assets/InputNumber.js b/frontend/dist/assets/InputNumber.js index 70465022a..dcf6aae8d 100644 --- a/frontend/dist/assets/InputNumber.js +++ b/frontend/dist/assets/InputNumber.js @@ -1,4 +1,4 @@ -import { d as defineComponent, x as h, aa as c, Q as cB, S as useConfig, T as useTheme, ad as useLocale, ar as useFormItem, y as ref, X as toRef, ae as useMergedState, as as useMemo, J as watch, ag as useRtl, c as computed, bX as rgba, I as NInput, av as resolveWrappedSlot, bY as inputNumberLight, aD as on, ai as resolveSlot, aj as NBaseIcon, bZ as XButton, a$ as AddIcon, a1 as call, W as nextTick } from "./index.js"; +import { d as defineComponent, x as h, aa as c, Q as cB, S as useConfig, T as useTheme, ad as useLocale, ar as useFormItem, y as ref, X as toRef, ae as useMergedState, as as useMemo, J as watch, ag as useRtl, i as computed, bX as rgba, I as NInput, av as resolveWrappedSlot, bY as inputNumberLight, aD as on, ai as resolveSlot, aj as NBaseIcon, bZ as XButton, a$ as AddIcon, a1 as call, W as nextTick } from "./index.js"; const RemoveIcon = defineComponent({ name: "Remove", render() { diff --git a/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js index 22abeae2a..56f631aaa 100644 --- a/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/ModelPopup.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { bl as upperFirst, bm as toString, bn as createCompounder, bo as cloneVNode, a3 as provide, P as createInjectionKey, R as inject, a_ as throwError, d as defineComponent, S as useConfig, y as ref, bp as onBeforeUpdate, x as h, bq as indexMap, c as computed, ba as onMounted, aB as onBeforeUnmount, Q as cB, at as cE, aa as c, ab as cM, a4 as keep, ae as useMergedState, X as toRef, af as watchEffect, br as onUpdated, J as watch, W as nextTick, T as useTheme, Y as useThemeClass, aw as flatten, aL as VResizeObserver, bs as resolveSlotWithProps, bt as withDirectives, bu as vShow, aX as Transition, bb as normalizeStyle, bv as getPreciseEventTarget, aD as on, aC as off, bw as carouselLight, ac as cNotM, ar as useFormItem, ah as createKey, bx as color2Class, L as renderList, aj as NBaseIcon, by as rateLight, a1 as call, n as useMessage, u as useSettings, b9 as reactive, o as openBlock, a as createBlock, w as withCtx, e as createVNode, g as createElementBlock, f as unref, C as NTabPane, r as NGrid, q as NGi, F as Fragment, b as createBaseVNode, N as NCard, l as createTextVNode, B as toDisplayString, bz as NTag, h as NSelect, z as NButton, D as NTabs, bf as NModal, s as serverUrl } from "./index.js"; +import { bl as upperFirst, bm as toString, bn as createCompounder, bo as cloneVNode, a3 as provide, P as createInjectionKey, R as inject, a_ as throwError, d as defineComponent, S as useConfig, y as ref, bp as onBeforeUpdate, x as h, bq as indexMap, i as computed, ba as onMounted, aB as onBeforeUnmount, Q as cB, at as cE, aa as c, ab as cM, a4 as keep, ae as useMergedState, X as toRef, af as watchEffect, br as onUpdated, J as watch, W as nextTick, T as useTheme, Y as useThemeClass, aw as flatten, aL as VResizeObserver, bs as resolveSlotWithProps, bt as withDirectives, bu as vShow, aX as Transition, bb as normalizeStyle, bv as getPreciseEventTarget, aD as on, aC as off, bw as carouselLight, ac as cNotM, ar as useFormItem, ah as createKey, bx as color2Class, L as renderList, aj as NBaseIcon, by as rateLight, a1 as call, n as useMessage, u as useSettings, b9 as reactive, o as openBlock, c as createBlock, w as withCtx, e as createVNode, g as createElementBlock, f as unref, C as NTabPane, r as NGrid, q as NGi, F as Fragment, b as createBaseVNode, N as NCard, k as createTextVNode, B as toDisplayString, bz as NTag, m as NSelect, z as NButton, D as NTabs, bf as NModal, s as serverUrl } from "./index.js"; import { a as NDescriptions, N as NDescriptionsItem } from "./DescriptionsItem.js"; function capitalize(string) { return upperFirst(toString(string).toLowerCase()); diff --git a/frontend/dist/assets/ModelsView.js b/frontend/dist/assets/ModelsView.js index c60b9dc1c..20cc0dd55 100644 --- a/frontend/dist/assets/ModelsView.js +++ b/frontend/dist/assets/ModelsView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, x as h, O as replaceable, P as createInjectionKey, Q as cB, R as inject, S as useConfig, T as useTheme, U as popselectLight, c as computed, V as createTreeMate, J as watch, W as nextTick, X as toRef, Y as useThemeClass, Z as NInternalSelectMenu, $ as createTmOptions, a0 as happensIn, a1 as call, a2 as keysOf, y as ref, a3 as provide, a4 as keep, a5 as createRefSetter, a6 as mergeEventHandlers, a7 as omit, a8 as NPopover, a9 as popoverBaseProps, aa as c, ab as cM, ac as cNotM, ad as useLocale, ae as useMergedState, af as watchEffect, ag as useRtl, ah as createKey, ai as resolveSlot, I as NInput, h as NSelect, F as Fragment, aj as NBaseIcon, ak as useAdjustedTo, al as paginationLight, am as useMergedClsPrefix, an as ellipsisLight, ao as onDeactivated, m as NTooltip, ap as mergeProps, aq as useStyle, ar as useFormItem, as as useMemo, at as cE, au as radioLight, av as resolveWrappedSlot, aw as flatten$1, ax as getSlot, ay as depx, az as formatLength, z as NButton, aA as NScrollbar, aB as onBeforeUnmount, aC as off, aD as on, aE as ChevronDownIcon, aF as NDropdown, aG as pxfy, aH as get, aI as NIconSwitchTransition, aJ as NBaseLoading, aK as ChevronRightIcon, p as onUnmounted, aL as VResizeObserver, aM as warn, aN as cssrAnchorMetaName, aO as VVirtualList, aP as NEmpty, aQ as repeat, aR as beforeNextFrameOnce, aS as fadeInScaleUpTransition, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, aW as createId, aX as Transition, aY as dataTableLight, aZ as loadingBarApiInjectionKey, a_ as throwError, a$ as AddIcon, b0 as NProgress, b1 as NFadeInExpandTransition, b2 as EyeIcon, b3 as fadeInHeightExpandTransition, b4 as Teleport, b5 as uploadLight, o as openBlock, g as createElementBlock, b as createBaseVNode, b6 as createStaticVNode, b7 as useCssVars, f as unref, b8 as themeOverridesKey, b9 as reactive, ba as onMounted, e as createVNode, w as withCtx, A as NIcon, L as renderList, _ as _export_sfc, u as useSettings, i as createCommentVNode, bb as normalizeStyle, l as createTextVNode, B as toDisplayString, bc as NText, a as createBlock, bd as withModifiers, j as useState, n as useMessage, be as huggingfaceModelsFile, N as NCard, s as serverUrl, t as pushScopeId, v as popScopeId, k as NSpace, bf as NModal, q as NGi, r as NGrid, bg as NDivider, bh as Backends, C as NTabPane, D as NTabs } from "./index.js"; +import { d as defineComponent, x as h, O as replaceable, P as createInjectionKey, Q as cB, R as inject, S as useConfig, T as useTheme, U as popselectLight, i as computed, V as createTreeMate, J as watch, W as nextTick, X as toRef, Y as useThemeClass, Z as NInternalSelectMenu, $ as createTmOptions, a0 as happensIn, a1 as call, a2 as keysOf, y as ref, a3 as provide, a4 as keep, a5 as createRefSetter, a6 as mergeEventHandlers, a7 as omit, a8 as NPopover, a9 as popoverBaseProps, aa as c, ab as cM, ac as cNotM, ad as useLocale, ae as useMergedState, af as watchEffect, ag as useRtl, ah as createKey, ai as resolveSlot, I as NInput, m as NSelect, F as Fragment, aj as NBaseIcon, ak as useAdjustedTo, al as paginationLight, am as useMergedClsPrefix, an as ellipsisLight, ao as onDeactivated, l as NTooltip, ap as mergeProps, aq as useStyle, ar as useFormItem, as as useMemo, at as cE, au as radioLight, av as resolveWrappedSlot, aw as flatten$1, ax as getSlot, ay as depx, az as formatLength, z as NButton, aA as NScrollbar, aB as onBeforeUnmount, aC as off, aD as on, aE as ChevronDownIcon, aF as NDropdown, aG as pxfy, aH as get, aI as NIconSwitchTransition, aJ as NBaseLoading, aK as ChevronRightIcon, p as onUnmounted, aL as VResizeObserver, aM as warn, aN as cssrAnchorMetaName, aO as VVirtualList, aP as NEmpty, aQ as repeat, aR as beforeNextFrameOnce, aS as fadeInScaleUpTransition, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, aW as createId, aX as Transition, aY as dataTableLight, aZ as loadingBarApiInjectionKey, a_ as throwError, a$ as AddIcon, b0 as NProgress, b1 as NFadeInExpandTransition, b2 as EyeIcon, b3 as fadeInHeightExpandTransition, b4 as Teleport, b5 as uploadLight, o as openBlock, g as createElementBlock, b as createBaseVNode, b6 as createStaticVNode, b7 as useCssVars, f as unref, b8 as themeOverridesKey, b9 as reactive, ba as onMounted, e as createVNode, w as withCtx, A as NIcon, L as renderList, _ as _export_sfc, u as useSettings, h as createCommentVNode, bb as normalizeStyle, k as createTextVNode, B as toDisplayString, bc as NText, c as createBlock, bd as withModifiers, a as useState, n as useMessage, be as huggingfaceModelsFile, N as NCard, s as serverUrl, t as pushScopeId, v as popScopeId, j as NSpace, bf as NModal, q as NGi, r as NGrid, bg as NDivider, bh as Backends, C as NTabPane, D as NTabs } from "./index.js"; import { _ as _sfc_main$6, n as nsfwIndex, N as NRate } from "./ModelPopup.vue_vue_type_script_setup_true_lang.js"; import { N as NCheckboxGroup, a as NCheckbox, S as Settings } from "./Settings.js"; import { N as NSwitch } from "./Switch.js"; diff --git a/frontend/dist/assets/Scalecrafter.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/Scalecrafter.vue_vue_type_script_setup_true_lang.js new file mode 100644 index 000000000..5e06125df --- /dev/null +++ b/frontend/dist/assets/Scalecrafter.vue_vue_type_script_setup_true_lang.js @@ -0,0 +1,368 @@ +import { d as defineComponent, u as useSettings, i as computed, o as openBlock, g as createElementBlock, b as createBaseVNode, e as createVNode, f as unref, w as withCtx, k as createTextVNode, bE as NAlert, N as NCard, m as NSelect, h as createCommentVNode, F as Fragment, c as createBlock, C as NTabPane, D as NTabs, l as NTooltip, j as NSpace } from "./index.js"; +import { N as NSwitch } from "./Switch.js"; +import { N as NInputNumber } from "./InputNumber.js"; +import { N as NSlider } from "./Slider.js"; +import { b as _sfc_main$3 } from "./Upscale.vue_vue_type_script_setup_true_lang.js"; +const _hoisted_1$1 = { class: "flex-container" }; +const _hoisted_2$1 = /* @__PURE__ */ createBaseVNode("div", { class: "slider-label" }, [ + /* @__PURE__ */ createBaseVNode("p", null, "Enabled") +], -1); +const _hoisted_3$1 = { key: 0 }; +const _hoisted_4$1 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "diffusers", -1); +const _hoisted_5$1 = { class: "flex-container space-between" }; +const _hoisted_6$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Depth", -1); +const _hoisted_7$1 = { class: "flex-container" }; +const _hoisted_8$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Stop at", -1); +const _hoisted_9$1 = { class: "flex-container space-between" }; +const _hoisted_10 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Depth", -1); +const _hoisted_11 = { class: "flex-container" }; +const _hoisted_12 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Stop at", -1); +const _hoisted_13 = { class: "flex-container" }; +const _hoisted_14 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Scale", -1); +const _hoisted_15 = { class: "flex-container" }; +const _hoisted_16 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Latent scaler", -1); +const _hoisted_17 = { class: "flex-container" }; +const _hoisted_18 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Early out", -1); +const _sfc_main$2 = /* @__PURE__ */ defineComponent({ + __name: "DeepShrink", + props: { + tab: { + type: String, + required: true + }, + target: { + type: String, + required: false, + default: "settings" + } + }, + setup(__props) { + const props = __props; + const settings = useSettings(); + const latentUpscalerOptions = [ + { label: "Nearest", value: "nearest" }, + { label: "Nearest exact", value: "nearest-exact" }, + { label: "Area", value: "area" }, + { label: "Bilinear", value: "bilinear" }, + { label: "Bicubic", value: "bicubic" }, + { label: "Bislerp", value: "bislerp" } + ]; + const target = computed(() => { + if (props.target === "settings") { + return settings.data.settings; + } + return settings.defaultSettings; + }); + return (_ctx, _cache) => { + return openBlock(), createElementBlock(Fragment, null, [ + createBaseVNode("div", _hoisted_1$1, [ + _hoisted_2$1, + createVNode(unref(NSwitch), { + value: target.value[props.tab].deepshrink.enabled, + "onUpdate:value": _cache[0] || (_cache[0] = ($event) => target.value[props.tab].deepshrink.enabled = $event) + }, null, 8, ["value"]) + ]), + target.value[props.tab].deepshrink.enabled ? (openBlock(), createElementBlock("div", _hoisted_3$1, [ + createVNode(unref(NAlert), { type: "warning" }, { + default: withCtx(() => [ + createTextVNode(" Only works on "), + _hoisted_4$1, + createTextVNode(" samplers ") + ]), + _: 1 + }), + createVNode(unref(NCard), { + bordered: false, + title: "First layer" + }, { + default: withCtx(() => [ + createBaseVNode("div", _hoisted_5$1, [ + _hoisted_6$1, + createVNode(unref(NInputNumber), { + value: target.value[props.tab].deepshrink.depth_1, + "onUpdate:value": _cache[1] || (_cache[1] = ($event) => target.value[props.tab].deepshrink.depth_1 = $event), + max: 4, + min: 1, + step: 1 + }, null, 8, ["value"]) + ]), + createBaseVNode("div", _hoisted_7$1, [ + _hoisted_8$1, + createVNode(unref(NSlider), { + value: target.value[props.tab].deepshrink.stop_at_1, + "onUpdate:value": _cache[2] || (_cache[2] = ($event) => target.value[props.tab].deepshrink.stop_at_1 = $event), + min: 0.05, + max: 1, + step: 0.05, + style: { "margin-right": "12px" } + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: target.value[props.tab].deepshrink.stop_at_1, + "onUpdate:value": _cache[3] || (_cache[3] = ($event) => target.value[props.tab].deepshrink.stop_at_1 = $event), + max: 1, + min: 0.05, + step: 0.05 + }, null, 8, ["value"]) + ]) + ]), + _: 1 + }), + createVNode(unref(NCard), { + bordered: false, + title: "Second layer" + }, { + default: withCtx(() => [ + createBaseVNode("div", _hoisted_9$1, [ + _hoisted_10, + createVNode(unref(NInputNumber), { + value: target.value[props.tab].deepshrink.depth_2, + "onUpdate:value": _cache[4] || (_cache[4] = ($event) => target.value[props.tab].deepshrink.depth_2 = $event), + max: 4, + min: 1, + step: 1 + }, null, 8, ["value"]) + ]), + createBaseVNode("div", _hoisted_11, [ + _hoisted_12, + createVNode(unref(NSlider), { + value: target.value[props.tab].deepshrink.stop_at_2, + "onUpdate:value": _cache[5] || (_cache[5] = ($event) => target.value[props.tab].deepshrink.stop_at_2 = $event), + min: 0.05, + max: 1, + step: 0.05 + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: target.value[props.tab].deepshrink.stop_at_2, + "onUpdate:value": _cache[6] || (_cache[6] = ($event) => target.value[props.tab].deepshrink.stop_at_2 = $event), + max: 1, + min: 0.05, + step: 0.05 + }, null, 8, ["value"]) + ]) + ]), + _: 1 + }), + createVNode(unref(NCard), { + bordered: false, + title: "Scale" + }, { + default: withCtx(() => [ + createBaseVNode("div", _hoisted_13, [ + _hoisted_14, + createVNode(unref(NSlider), { + value: target.value[props.tab].deepshrink.base_scale, + "onUpdate:value": _cache[7] || (_cache[7] = ($event) => target.value[props.tab].deepshrink.base_scale = $event), + min: 0.05, + max: 1, + step: 0.05 + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: target.value[props.tab].deepshrink.base_scale, + "onUpdate:value": _cache[8] || (_cache[8] = ($event) => target.value[props.tab].deepshrink.base_scale = $event), + max: 1, + min: 0.05, + step: 0.05 + }, null, 8, ["value"]) + ]), + createBaseVNode("div", _hoisted_15, [ + _hoisted_16, + createVNode(unref(NSelect), { + value: target.value[props.tab].deepshrink.scaler, + "onUpdate:value": _cache[9] || (_cache[9] = ($event) => target.value[props.tab].deepshrink.scaler = $event), + filterable: "", + options: latentUpscalerOptions + }, null, 8, ["value"]) + ]) + ]), + _: 1 + }), + createVNode(unref(NCard), { + bordered: false, + title: "Other" + }, { + default: withCtx(() => [ + createBaseVNode("div", _hoisted_17, [ + _hoisted_18, + createVNode(unref(NSwitch), { + value: target.value[props.tab].deepshrink.early_out, + "onUpdate:value": _cache[10] || (_cache[10] = ($event) => target.value[props.tab].deepshrink.early_out = $event) + }, null, 8, ["value"]) + ]) + ]), + _: 1 + }) + ])) : createCommentVNode("", true) + ], 64); + }; + } +}); +const _sfc_main$1 = /* @__PURE__ */ defineComponent({ + __name: "HighResFixTabs", + props: { + tab: { + type: String, + required: true + }, + target: { + type: String, + required: false, + default: "settings" + } + }, + setup(__props) { + const props = __props; + return (_ctx, _cache) => { + return openBlock(), createBlock(unref(NCard), { + title: "High Resolution Fix", + class: "generate-extra-card" + }, { + default: withCtx(() => [ + createVNode(unref(NTabs), { + animated: "", + type: "segment" + }, { + default: withCtx(() => [ + createVNode(unref(NTabPane), { + tab: "Image to Image", + name: "highresfix" + }, { + default: withCtx(() => [ + createVNode(unref(_sfc_main$3), { + tab: props.tab, + target: props.target + }, null, 8, ["tab", "target"]) + ]), + _: 1 + }), + createVNode(unref(NTabPane), { + tab: "Scalecrafter", + name: "scalecrafter" + }, { + default: withCtx(() => [ + createVNode(unref(_sfc_main), { + tab: props.tab, + target: props.target + }, null, 8, ["tab", "target"]) + ]), + _: 1 + }), + createVNode(unref(NTabPane), { + tab: "DeepShrink", + name: "deepshrink" + }, { + default: withCtx(() => [ + createVNode(unref(_sfc_main$2), { + tab: props.tab, + target: props.target + }, null, 8, ["tab", "target"]) + ]), + _: 1 + }) + ]), + _: 1 + }) + ]), + _: 1 + }); + }; + } +}); +const _hoisted_1 = { class: "flex-container" }; +const _hoisted_2 = /* @__PURE__ */ createBaseVNode("div", { class: "slider-label" }, [ + /* @__PURE__ */ createBaseVNode("p", null, "Enabled") +], -1); +const _hoisted_3 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "Automatic", -1); +const _hoisted_4 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, "Karras", -1); +const _hoisted_5 = { class: "flex-container" }; +const _hoisted_6 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Disperse", -1); +const _hoisted_7 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, " However, this comes at the cost of increased vram usage, generally in the range of 3-4x. ", -1); +const _hoisted_8 = { class: "flex-container" }; +const _hoisted_9 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Unsafe resolutions", -1); +const _sfc_main = /* @__PURE__ */ defineComponent({ + __name: "Scalecrafter", + props: { + tab: { + type: String, + required: true + }, + target: { + type: String, + required: false, + default: "settings" + } + }, + setup(__props) { + const props = __props; + const settings = useSettings(); + const target = computed(() => { + if (props.target === "settings") { + return settings.data.settings; + } + return settings.defaultSettings; + }); + return (_ctx, _cache) => { + return openBlock(), createElementBlock(Fragment, null, [ + createBaseVNode("div", _hoisted_1, [ + _hoisted_2, + createVNode(unref(NSwitch), { + value: target.value[props.tab].scalecrafter.enabled, + "onUpdate:value": _cache[0] || (_cache[0] = ($event) => target.value[props.tab].scalecrafter.enabled = $event) + }, null, 8, ["value"]) + ]), + target.value[props.tab].scalecrafter.enabled ? (openBlock(), createBlock(unref(NSpace), { + key: 0, + vertical: "", + class: "left-container" + }, { + default: withCtx(() => [ + createVNode(unref(NAlert), { type: "warning" }, { + default: withCtx(() => [ + createTextVNode(" Only works with "), + _hoisted_3, + createTextVNode(" and "), + _hoisted_4, + createTextVNode(" sigmas ") + ]), + _: 1 + }), + createBaseVNode("div", _hoisted_5, [ + createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { + trigger: withCtx(() => [ + _hoisted_6 + ]), + default: withCtx(() => [ + createTextVNode(" May generate more unique images. "), + _hoisted_7 + ]), + _: 1 + }), + createVNode(unref(NSwitch), { + value: target.value[props.tab].scalecrafter.disperse, + "onUpdate:value": _cache[1] || (_cache[1] = ($event) => target.value[props.tab].scalecrafter.disperse = $event) + }, null, 8, ["value"]) + ]), + createBaseVNode("div", _hoisted_8, [ + createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { + trigger: withCtx(() => [ + _hoisted_9 + ]), + default: withCtx(() => [ + createTextVNode(" Allow generating with unique resolutions that don't have configs ready for them, or clamp them (really, force them) to the closest resolution. ") + ]), + _: 1 + }), + createVNode(unref(NSwitch), { + value: target.value[props.tab].scalecrafter.unsafe_resolutions, + "onUpdate:value": _cache[2] || (_cache[2] = ($event) => target.value[props.tab].scalecrafter.unsafe_resolutions = $event) + }, null, 8, ["value"]) + ]) + ]), + _: 1 + })) : createCommentVNode("", true) + ], 64); + }; + } +}); +export { + _sfc_main$1 as _ +}; diff --git a/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js index e649932af..ac365d9bc 100644 --- a/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, bM as useRouter, u as useSettings, j as useState, y as ref, b9 as reactive, J as watch, c as computed, e as createVNode, w as withCtx, f as unref, N as NCard, z as NButton, l as createTextVNode, M as NScrollbar, F as Fragment, L as renderList, B as toDisplayString, bg as NDivider, bf as NModal, a as createBlock, q as NGi, r as NGrid, i as createCommentVNode } from "./index.js"; +import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, bN as useRouter, u as useSettings, a as useState, y as ref, b9 as reactive, J as watch, i as computed, e as createVNode, w as withCtx, f as unref, N as NCard, z as NButton, k as createTextVNode, M as NScrollbar, F as Fragment, L as renderList, B as toDisplayString, bg as NDivider, bf as NModal, c as createBlock, q as NGi, r as NGrid, h as createCommentVNode } from "./index.js"; import { N as NSwitch } from "./Switch.js"; const _hoisted_1$3 = { xmlns: "http://www.w3.org/2000/svg", diff --git a/frontend/dist/assets/Settings.js b/frontend/dist/assets/Settings.js index d2e509a9c..d3d408303 100644 --- a/frontend/dist/assets/Settings.js +++ b/frontend/dist/assets/Settings.js @@ -1,4 +1,4 @@ -import { x as h, d as defineComponent, S as useConfig, ar as useFormItem, y as ref, c as computed, ae as useMergedState, a3 as provide, X as toRef, P as createInjectionKey, a1 as call, aa as c, Q as cB, ab as cM, at as cE, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, R as inject, as as useMemo, T as useTheme, bJ as checkboxLight, ag as useRtl, ah as createKey, Y as useThemeClass, aW as createId, av as resolveWrappedSlot, aI as NIconSwitchTransition, aD as on, o as openBlock, g as createElementBlock, b as createBaseVNode } from "./index.js"; +import { x as h, d as defineComponent, S as useConfig, ar as useFormItem, y as ref, i as computed, ae as useMergedState, a3 as provide, X as toRef, P as createInjectionKey, a1 as call, aa as c, Q as cB, ab as cM, at as cE, aT as iconSwitchTransition, aU as insideModal, aV as insidePopover, R as inject, as as useMemo, T as useTheme, bK as checkboxLight, ag as useRtl, ah as createKey, Y as useThemeClass, aW as createId, av as resolveWrappedSlot, aI as NIconSwitchTransition, aD as on, o as openBlock, g as createElementBlock, b as createBaseVNode } from "./index.js"; const CheckMark = h( "svg", { viewBox: "0 0 64 64", class: "check-icon" }, diff --git a/frontend/dist/assets/SettingsView.js b/frontend/dist/assets/SettingsView.js index 7431ed37b..019e0f8cc 100644 --- a/frontend/dist/assets/SettingsView.js +++ b/frontend/dist/assets/SettingsView.js @@ -1,7 +1,8 @@ -import { d as defineComponent, u as useSettings, o as openBlock, a as createBlock, w as withCtx, e as createVNode, f as unref, I as NInput, h as NSelect, N as NCard, b9 as reactive, c as computed, bA as convertToTextString, y as ref, s as serverUrl, J as watch, j as useState, b as createBaseVNode, g as createElementBlock, L as renderList, bc as NText, l as createTextVNode, B as toDisplayString, F as Fragment, i as createCommentVNode, C as NTabPane, D as NTabs, R as inject, bB as themeKey, z as NButton, m as NTooltip, n as useMessage, bC as useNotification, p as onUnmounted, bD as defaultSettings } from "./index.js"; -import { c as NFormItem, _ as _sfc_main$g, b as _sfc_main$h, a as _sfc_main$i, N as NForm } from "./Upscale.vue_vue_type_script_setup_true_lang.js"; +import { d as defineComponent, u as useSettings, o as openBlock, c as createBlock, w as withCtx, e as createVNode, f as unref, I as NInput, m as NSelect, N as NCard, b9 as reactive, i as computed, bA as convertToTextString, y as ref, s as serverUrl, J as watch, a as useState, b as createBaseVNode, g as createElementBlock, L as renderList, bc as NText, k as createTextVNode, B as toDisplayString, F as Fragment, h as createCommentVNode, C as NTabPane, D as NTabs, R as inject, bB as themeKey, z as NButton, l as NTooltip, n as useMessage, bC as useNotification, p as onUnmounted, bD as defaultSettings } from "./index.js"; +import { c as NFormItem, _ as _sfc_main$g, a as _sfc_main$h, N as NForm } from "./Upscale.vue_vue_type_script_setup_true_lang.js"; import { N as NSwitch } from "./Switch.js"; import { N as NInputNumber } from "./InputNumber.js"; +import { _ as _sfc_main$i } from "./Scalecrafter.vue_vue_type_script_setup_true_lang.js"; import { N as NSlider } from "./Slider.js"; import "./Settings.js"; const _sfc_main$f = /* @__PURE__ */ defineComponent({ diff --git a/frontend/dist/assets/Slider.js b/frontend/dist/assets/Slider.js index 931ecb9b3..879ee7dcd 100644 --- a/frontend/dist/assets/Slider.js +++ b/frontend/dist/assets/Slider.js @@ -1,4 +1,4 @@ -import { y as ref, bp as onBeforeUpdate, aa as c, Q as cB, ab as cM, at as cE, aS as fadeInScaleUpTransition, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, ar as useFormItem, c as computed, X as toRef, ae as useMergedState, J as watch, W as nextTick, aB as onBeforeUnmount, Y as useThemeClass, bQ as isMounted, ak as useAdjustedTo, x as h, b_ as VBinder, b$ as VTarget, ai as resolveSlot, c0 as VFollower, aX as Transition, c1 as sliderLight, aD as on, aC as off, a1 as call } from "./index.js"; +import { y as ref, bp as onBeforeUpdate, aa as c, Q as cB, ab as cM, at as cE, aS as fadeInScaleUpTransition, aU as insideModal, aV as insidePopover, d as defineComponent, S as useConfig, T as useTheme, ar as useFormItem, i as computed, X as toRef, ae as useMergedState, J as watch, W as nextTick, aB as onBeforeUnmount, Y as useThemeClass, bR as isMounted, ak as useAdjustedTo, x as h, b_ as VBinder, b$ as VTarget, ai as resolveSlot, c0 as VFollower, aX as Transition, c1 as sliderLight, aD as on, aC as off, a1 as call } from "./index.js"; function isTouchEvent(e) { return window.TouchEvent && e instanceof window.TouchEvent; } diff --git a/frontend/dist/assets/Switch.js b/frontend/dist/assets/Switch.js index 8988e74bb..762abd2de 100644 --- a/frontend/dist/assets/Switch.js +++ b/frontend/dist/assets/Switch.js @@ -1,4 +1,4 @@ -import { Q as cB, at as cE, aT as iconSwitchTransition, aa as c, ab as cM, ac as cNotM, d as defineComponent, S as useConfig, T as useTheme, ar as useFormItem, y as ref, X as toRef, ae as useMergedState, c as computed, ah as createKey, aG as pxfy, ay as depx, Y as useThemeClass, c2 as isSlotEmpty, x as h, av as resolveWrappedSlot, c3 as switchLight, aI as NIconSwitchTransition, aJ as NBaseLoading, a1 as call } from "./index.js"; +import { Q as cB, at as cE, aT as iconSwitchTransition, aa as c, ab as cM, ac as cNotM, d as defineComponent, S as useConfig, T as useTheme, ar as useFormItem, y as ref, X as toRef, ae as useMergedState, i as computed, ah as createKey, aG as pxfy, ay as depx, Y as useThemeClass, c2 as isSlotEmpty, x as h, av as resolveWrappedSlot, c3 as switchLight, aI as NIconSwitchTransition, aJ as NBaseLoading, a1 as call } from "./index.js"; const style = cB("switch", ` height: var(--n-height); min-width: var(--n-width); diff --git a/frontend/dist/assets/TaggerView.js b/frontend/dist/assets/TaggerView.js index 17fdb1624..ec5a7444a 100644 --- a/frontend/dist/assets/TaggerView.js +++ b/frontend/dist/assets/TaggerView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, j as useState, u as useSettings, n as useMessage, y as ref, c as computed, E as spaceRegex, o as openBlock, g as createElementBlock, e as createVNode, w as withCtx, f as unref, q as NGi, N as NCard, k as NSpace, b as createBaseVNode, h as NSelect, m as NTooltip, l as createTextVNode, I as NInput, B as toDisplayString, r as NGrid, s as serverUrl, t as pushScopeId, v as popScopeId, _ as _export_sfc } from "./index.js"; +import { d as defineComponent, a as useState, u as useSettings, n as useMessage, y as ref, i as computed, E as spaceRegex, o as openBlock, g as createElementBlock, e as createVNode, w as withCtx, f as unref, q as NGi, N as NCard, j as NSpace, b as createBaseVNode, m as NSelect, l as NTooltip, k as createTextVNode, I as NInput, B as toDisplayString, r as NGrid, s as serverUrl, t as pushScopeId, v as popScopeId, _ as _export_sfc } from "./index.js"; import { _ as _sfc_main$1 } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; import { I as ImageUpload } from "./ImageUpload.js"; import { v as v4 } from "./v4.js"; diff --git a/frontend/dist/assets/TestView.js b/frontend/dist/assets/TestView.js index d9fbaff73..b38d6910d 100644 --- a/frontend/dist/assets/TestView.js +++ b/frontend/dist/assets/TestView.js @@ -1,4 +1,4 @@ -import { d as defineComponent, y as ref, o as openBlock, a as createBlock, f as unref } from "./index.js"; +import { d as defineComponent, y as ref, o as openBlock, c as createBlock, f as unref } from "./index.js"; import { _ as _sfc_main$1 } from "./ModelPopup.vue_vue_type_script_setup_true_lang.js"; import "./DescriptionsItem.js"; const _sfc_main = /* @__PURE__ */ defineComponent({ diff --git a/frontend/dist/assets/TextToImageView.js b/frontend/dist/assets/TextToImageView.js index 64410867f..627820e19 100644 --- a/frontend/dist/assets/TextToImageView.js +++ b/frontend/dist/assets/TextToImageView.js @@ -1,214 +1,25 @@ -import { d as defineComponent, u as useSettings, c as computed, o as openBlock, a as createBlock, w as withCtx, b as createBaseVNode, e as createVNode, f as unref, g as createElementBlock, N as NCard, h as NSelect, i as createCommentVNode, j as useState, k as NSpace, l as createTextVNode, m as NTooltip, n as useMessage, p as onUnmounted, q as NGi, r as NGrid, s as serverUrl } from "./index.js"; -import { _ as _sfc_main$d } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; -import { _ as _sfc_main$e } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; -import { B as BurnerClock, P as Prompt, _ as _sfc_main$7, a as _sfc_main$8, b as _sfc_main$9, c as _sfc_main$a, d as _sfc_main$f } from "./clock.js"; +import { d as defineComponent, u as useSettings, a as useState, o as openBlock, c as createBlock, w as withCtx, b as createBaseVNode, e as createVNode, f as unref, g as createElementBlock, h as createCommentVNode, N as NCard, i as computed, j as NSpace, k as createTextVNode, l as NTooltip, m as NSelect, n as useMessage, p as onUnmounted, q as NGi, r as NGrid, s as serverUrl } from "./index.js"; +import { _ as _sfc_main$b } from "./GenerateSection.vue_vue_type_script_setup_true_lang.js"; +import { _ as _sfc_main$c } from "./ImageOutput.vue_vue_type_script_setup_true_lang.js"; +import { B as BurnerClock, P as Prompt, _ as _sfc_main$5, a as _sfc_main$6, b as _sfc_main$7, c as _sfc_main$8, d as _sfc_main$d } from "./clock.js"; +import { _ as _sfc_main$9 } from "./Scalecrafter.vue_vue_type_script_setup_true_lang.js"; import { N as NSwitch } from "./Switch.js"; -import { N as NInputNumber } from "./InputNumber.js"; import { N as NSlider } from "./Slider.js"; -import { _ as _sfc_main$6, a as _sfc_main$b, b as _sfc_main$c } from "./Upscale.vue_vue_type_script_setup_true_lang.js"; +import { N as NInputNumber } from "./InputNumber.js"; +import { _ as _sfc_main$4, a as _sfc_main$a } from "./Upscale.vue_vue_type_script_setup_true_lang.js"; import { v as v4 } from "./v4.js"; import "./SendOutputTo.vue_vue_type_script_setup_true_lang.js"; import "./TrashBin.js"; import "./DescriptionsItem.js"; import "./Settings.js"; -const _hoisted_1$4 = { class: "flex-container" }; -const _hoisted_2$4 = /* @__PURE__ */ createBaseVNode("div", { class: "slider-label" }, [ - /* @__PURE__ */ createBaseVNode("p", null, "Enabled") -], -1); -const _hoisted_3$4 = { key: 0 }; -const _hoisted_4$4 = { class: "flex-container space-between" }; -const _hoisted_5$4 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Depth", -1); -const _hoisted_6$4 = { class: "flex-container" }; -const _hoisted_7$4 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Stop at", -1); -const _hoisted_8$2 = { class: "flex-container space-between" }; -const _hoisted_9$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Depth", -1); -const _hoisted_10$1 = { class: "flex-container" }; -const _hoisted_11$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Stop at", -1); -const _hoisted_12$1 = { class: "flex-container" }; -const _hoisted_13$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Scale", -1); -const _hoisted_14$1 = { class: "flex-container" }; -const _hoisted_15$1 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Latent scaler", -1); -const _hoisted_16$1 = { class: "flex-container" }; -const _hoisted_17 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Early out", -1); -const _sfc_main$5 = /* @__PURE__ */ defineComponent({ - __name: "DeepShrink", - props: { - tab: { - type: String, - required: true - }, - target: { - type: String, - required: false, - default: "settings" - } - }, - setup(__props) { - const props = __props; - const settings = useSettings(); - const latentUpscalerOptions = [ - { label: "Nearest", value: "nearest" }, - { label: "Nearest exact", value: "nearest-exact" }, - { label: "Area", value: "area" }, - { label: "Bilinear", value: "bilinear" }, - { label: "Bicubic", value: "bicubic" }, - { label: "Bislerp", value: "bislerp" } - ]; - const target = computed(() => { - if (props.target === "settings") { - return settings.data.settings; - } - return settings.defaultSettings; - }); - return (_ctx, _cache) => { - return openBlock(), createBlock(unref(NCard), { - title: "Deepshrink", - class: "generate-extra-card" - }, { - default: withCtx(() => [ - createBaseVNode("div", _hoisted_1$4, [ - _hoisted_2$4, - createVNode(unref(NSwitch), { - value: target.value[props.tab].deepshrink.enabled, - "onUpdate:value": _cache[0] || (_cache[0] = ($event) => target.value[props.tab].deepshrink.enabled = $event) - }, null, 8, ["value"]) - ]), - target.value[props.tab].deepshrink.enabled ? (openBlock(), createElementBlock("div", _hoisted_3$4, [ - createVNode(unref(NCard), { - bordered: false, - title: "First layer" - }, { - default: withCtx(() => [ - createBaseVNode("div", _hoisted_4$4, [ - _hoisted_5$4, - createVNode(unref(NInputNumber), { - value: target.value[props.tab].deepshrink.depth_1, - "onUpdate:value": _cache[1] || (_cache[1] = ($event) => target.value[props.tab].deepshrink.depth_1 = $event), - max: 4, - min: 1, - step: 1 - }, null, 8, ["value"]) - ]), - createBaseVNode("div", _hoisted_6$4, [ - _hoisted_7$4, - createVNode(unref(NSlider), { - value: target.value[props.tab].deepshrink.stop_at_1, - "onUpdate:value": _cache[2] || (_cache[2] = ($event) => target.value[props.tab].deepshrink.stop_at_1 = $event), - min: 0.05, - max: 1, - step: 0.05, - style: { "margin-right": "12px" } - }, null, 8, ["value"]), - createVNode(unref(NInputNumber), { - value: target.value[props.tab].deepshrink.stop_at_1, - "onUpdate:value": _cache[3] || (_cache[3] = ($event) => target.value[props.tab].deepshrink.stop_at_1 = $event), - max: 1, - min: 0.05, - step: 0.05 - }, null, 8, ["value"]) - ]) - ]), - _: 1 - }), - createVNode(unref(NCard), { - bordered: false, - title: "Second layer" - }, { - default: withCtx(() => [ - createBaseVNode("div", _hoisted_8$2, [ - _hoisted_9$2, - createVNode(unref(NInputNumber), { - value: target.value[props.tab].deepshrink.depth_2, - "onUpdate:value": _cache[4] || (_cache[4] = ($event) => target.value[props.tab].deepshrink.depth_2 = $event), - max: 4, - min: 1, - step: 1 - }, null, 8, ["value"]) - ]), - createBaseVNode("div", _hoisted_10$1, [ - _hoisted_11$1, - createVNode(unref(NSlider), { - value: target.value[props.tab].deepshrink.stop_at_2, - "onUpdate:value": _cache[5] || (_cache[5] = ($event) => target.value[props.tab].deepshrink.stop_at_2 = $event), - min: 0.05, - max: 1, - step: 0.05 - }, null, 8, ["value"]), - createVNode(unref(NInputNumber), { - value: target.value[props.tab].deepshrink.stop_at_2, - "onUpdate:value": _cache[6] || (_cache[6] = ($event) => target.value[props.tab].deepshrink.stop_at_2 = $event), - max: 1, - min: 0.05, - step: 0.05 - }, null, 8, ["value"]) - ]) - ]), - _: 1 - }), - createVNode(unref(NCard), { - bordered: false, - title: "Scale" - }, { - default: withCtx(() => [ - createBaseVNode("div", _hoisted_12$1, [ - _hoisted_13$1, - createVNode(unref(NSlider), { - value: target.value[props.tab].deepshrink.base_scale, - "onUpdate:value": _cache[7] || (_cache[7] = ($event) => target.value[props.tab].deepshrink.base_scale = $event), - min: 0.05, - max: 1, - step: 0.05 - }, null, 8, ["value"]), - createVNode(unref(NInputNumber), { - value: target.value[props.tab].deepshrink.base_scale, - "onUpdate:value": _cache[8] || (_cache[8] = ($event) => target.value[props.tab].deepshrink.base_scale = $event), - max: 1, - min: 0.05, - step: 0.05 - }, null, 8, ["value"]) - ]), - createBaseVNode("div", _hoisted_14$1, [ - _hoisted_15$1, - createVNode(unref(NSelect), { - value: target.value[props.tab].deepshrink.scaler, - "onUpdate:value": _cache[9] || (_cache[9] = ($event) => target.value[props.tab].deepshrink.scaler = $event), - filterable: "", - options: latentUpscalerOptions - }, null, 8, ["value"]) - ]) - ]), - _: 1 - }), - createVNode(unref(NCard), { - bordered: false, - title: "Other" - }, { - default: withCtx(() => [ - createBaseVNode("div", _hoisted_16$1, [ - _hoisted_17, - createVNode(unref(NSwitch), { - value: target.value[props.tab].deepshrink.early_out, - "onUpdate:value": _cache[10] || (_cache[10] = ($event) => target.value[props.tab].deepshrink.early_out = $event) - }, null, 8, ["value"]) - ]) - ]), - _: 1 - }) - ])) : createCommentVNode("", true) - ]), - _: 1 - }); - }; - } -}); -const _hoisted_1$3 = { class: "flex-container" }; -const _hoisted_2$3 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Enabled", -1); -const _hoisted_3$3 = { key: 0 }; -const _hoisted_4$3 = { class: "flex-container" }; -const _hoisted_5$3 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Width", -1); -const _hoisted_6$3 = { class: "flex-container" }; -const _hoisted_7$3 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Height", -1); -const _sfc_main$4 = /* @__PURE__ */ defineComponent({ +const _hoisted_1$2 = { class: "flex-container" }; +const _hoisted_2$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Enabled", -1); +const _hoisted_3$2 = { key: 0 }; +const _hoisted_4$2 = { class: "flex-container" }; +const _hoisted_5$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Width", -1); +const _hoisted_6$2 = { class: "flex-container" }; +const _hoisted_7$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Height", -1); +const _sfc_main$3 = /* @__PURE__ */ defineComponent({ __name: "ResizeFromDimensionsInput", setup(__props) { const settings = useSettings(); @@ -219,16 +30,16 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({ class: "generate-extra-card" }, { default: withCtx(() => [ - createBaseVNode("div", _hoisted_1$3, [ - _hoisted_2$3, + createBaseVNode("div", _hoisted_1$2, [ + _hoisted_2$2, createVNode(unref(NSwitch), { value: unref(global).state.txt2img.sdxl_resize, "onUpdate:value": _cache[0] || (_cache[0] = ($event) => unref(global).state.txt2img.sdxl_resize = $event) }, null, 8, ["value"]) ]), - unref(global).state.txt2img.sdxl_resize ? (openBlock(), createElementBlock("div", _hoisted_3$3, [ - createBaseVNode("div", _hoisted_4$3, [ - _hoisted_5$3, + unref(global).state.txt2img.sdxl_resize ? (openBlock(), createElementBlock("div", _hoisted_3$2, [ + createBaseVNode("div", _hoisted_4$2, [ + _hoisted_5$2, createVNode(unref(NSlider), { value: unref(settings).data.settings.flags.sdxl.original_size.width, "onUpdate:value": _cache[1] || (_cache[1] = ($event) => unref(settings).data.settings.flags.sdxl.original_size.width = $event), @@ -245,8 +56,8 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({ step: 1 }, null, 8, ["value"]) ]), - createBaseVNode("div", _hoisted_6$3, [ - _hoisted_7$3, + createBaseVNode("div", _hoisted_6$2, [ + _hoisted_7$2, createVNode(unref(NSlider), { value: unref(settings).data.settings.flags.sdxl.original_size.height, "onUpdate:value": _cache[3] || (_cache[3] = ($event) => unref(settings).data.settings.flags.sdxl.original_size.height = $event), @@ -270,96 +81,6 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({ }; } }); -const _hoisted_1$2 = { class: "flex-container" }; -const _hoisted_2$2 = /* @__PURE__ */ createBaseVNode("div", { class: "slider-label" }, [ - /* @__PURE__ */ createBaseVNode("p", null, "Enabled") -], -1); -const _hoisted_3$2 = { class: "flex-container" }; -const _hoisted_4$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Disperse", -1); -const _hoisted_5$2 = /* @__PURE__ */ createBaseVNode("b", { class: "highlight" }, " However, this comes at the cost of increased vram usage, generally in the range of 3-4x. ", -1); -const _hoisted_6$2 = { class: "flex-container" }; -const _hoisted_7$2 = /* @__PURE__ */ createBaseVNode("p", { class: "slider-label" }, "Unsafe resolutions", -1); -const _sfc_main$3 = /* @__PURE__ */ defineComponent({ - __name: "Scalecrafter", - props: { - tab: { - type: String, - required: true - }, - target: { - type: String, - required: false, - default: "settings" - } - }, - setup(__props) { - const props = __props; - const settings = useSettings(); - const target = computed(() => { - if (props.target === "settings") { - return settings.data.settings; - } - return settings.defaultSettings; - }); - return (_ctx, _cache) => { - return openBlock(), createBlock(unref(NCard), { - title: "Scalecrafter", - class: "generate-extra-card" - }, { - default: withCtx(() => [ - createBaseVNode("div", _hoisted_1$2, [ - _hoisted_2$2, - createVNode(unref(NSwitch), { - value: target.value[props.tab].scalecrafter.enabled, - "onUpdate:value": _cache[0] || (_cache[0] = ($event) => target.value[props.tab].scalecrafter.enabled = $event) - }, null, 8, ["value"]) - ]), - target.value[props.tab].scalecrafter.enabled ? (openBlock(), createBlock(unref(NSpace), { - key: 0, - vertical: "", - class: "left-container" - }, { - default: withCtx(() => [ - createBaseVNode("div", _hoisted_3$2, [ - createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { - trigger: withCtx(() => [ - _hoisted_4$2 - ]), - default: withCtx(() => [ - createTextVNode(" May generate more unique images. "), - _hoisted_5$2 - ]), - _: 1 - }), - createVNode(unref(NSwitch), { - value: target.value[props.tab].scalecrafter.disperse, - "onUpdate:value": _cache[1] || (_cache[1] = ($event) => target.value[props.tab].scalecrafter.disperse = $event) - }, null, 8, ["value"]) - ]), - createBaseVNode("div", _hoisted_6$2, [ - createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { - trigger: withCtx(() => [ - _hoisted_7$2 - ]), - default: withCtx(() => [ - createTextVNode(" Allow generating with unique resolutions that don't have configs ready for them, or clamp them (really, force them) to the closest resolution. ") - ]), - _: 1 - }), - createVNode(unref(NSwitch), { - value: target.value[props.tab].scalecrafter.unsafe_resolutions, - "onUpdate:value": _cache[2] || (_cache[2] = ($event) => target.value[props.tab].scalecrafter.unsafe_resolutions = $event) - }, null, 8, ["value"]) - ]) - ]), - _: 1 - })) : createCommentVNode("", true) - ]), - _: 1 - }); - }; - } -}); const _hoisted_1$1 = { class: "flex-container" }; const _hoisted_2$1 = /* @__PURE__ */ createBaseVNode("div", { class: "slider-label" }, [ /* @__PURE__ */ createBaseVNode("p", null, "Enabled") @@ -709,8 +430,8 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ }, { default: withCtx(() => [ createVNode(unref(Prompt), { tab: "txt2img" }), - createVNode(unref(_sfc_main$6), { type: "txt2img" }), - createVNode(unref(_sfc_main$7), { + createVNode(unref(_sfc_main$4), { type: "txt2img" }), + createVNode(unref(_sfc_main$5), { "dimensions-object": unref(settings).data.settings.txt2img }, null, 8, ["dimensions-object"]), createBaseVNode("div", _hoisted_2, [ @@ -738,8 +459,8 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ style: { "min-width": "96px", "width": "96px" } }, null, 8, ["value"]) ]), - createVNode(unref(_sfc_main$8), { tab: "txt2img" }), - createVNode(unref(_sfc_main$9), { tab: "txt2img" }), + createVNode(unref(_sfc_main$6), { tab: "txt2img" }), + createVNode(unref(_sfc_main$7), { tab: "txt2img" }), createBaseVNode("div", _hoisted_5, [ createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { trigger: withCtx(() => [ @@ -764,7 +485,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ style: { "min-width": "96px", "width": "96px" } }, null, 8, ["value"]) ]), - createVNode(unref(_sfc_main$a), { + createVNode(unref(_sfc_main$8), { "batch-size-object": unref(settings).data.settings.txt2img }, null, 8, ["batch-size-object"]), createBaseVNode("div", _hoisted_7, [ @@ -791,28 +512,26 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({ ]), _: 1 }), - isSelectedModelSDXL.value ? (openBlock(), createBlock(unref(_sfc_main$4), { + isSelectedModelSDXL.value ? (openBlock(), createBlock(unref(_sfc_main$3), { key: 0, "dimensions-object": unref(settings).data.settings.txt2img }, null, 8, ["dimensions-object"])) : createCommentVNode("", true), isSelectedModelSDXL.value ? (openBlock(), createBlock(unref(_sfc_main$2), { key: 1 })) : createCommentVNode("", true), - createVNode(unref(_sfc_main$b), { tab: "txt2img" }), - createVNode(unref(_sfc_main$c), { tab: "txt2img" }), - createVNode(unref(_sfc_main$5), { tab: "txt2img" }), - createVNode(unref(_sfc_main$3), { tab: "txt2img" }) + createVNode(unref(_sfc_main$9), { tab: "txt2img" }), + createVNode(unref(_sfc_main$a), { tab: "txt2img" }) ]), _: 1 }), createVNode(unref(NGi), null, { default: withCtx(() => [ - createVNode(unref(_sfc_main$d), { generate }), - createVNode(unref(_sfc_main$e), { + createVNode(unref(_sfc_main$b), { generate }), + createVNode(unref(_sfc_main$c), { "current-image": unref(global).state.txt2img.currentImage, images: unref(global).state.txt2img.images, data: unref(settings).data.settings.txt2img, onImageClicked: _cache[5] || (_cache[5] = ($event) => unref(global).state.txt2img.currentImage = $event) }, null, 8, ["current-image", "images", "data"]), - createVNode(unref(_sfc_main$f), { + createVNode(unref(_sfc_main$d), { style: { "margin-top": "12px" }, "gen-data": unref(global).state.txt2img.genData }, null, 8, ["gen-data"]) diff --git a/frontend/dist/assets/TrashBin.js b/frontend/dist/assets/TrashBin.js index 72fa42813..373cad46c 100644 --- a/frontend/dist/assets/TrashBin.js +++ b/frontend/dist/assets/TrashBin.js @@ -1,4 +1,4 @@ -import { O as replaceable, x as h, d as defineComponent, bN as isBrowser, T as useTheme, P as createInjectionKey, aa as c, Q as cB, bO as fadeInTransition, aS as fadeInScaleUpTransition, ac as cNotM, X as toRef, bP as imageLight, y as ref, ad as useLocale, J as watch, aD as on, aC as off, aB as onBeforeUnmount, R as inject, c as computed, S as useConfig, Y as useThemeClass, bQ as isMounted, bR as LazyTeleport, bt as withDirectives, bS as zindexable, aX as Transition, F as Fragment, aj as NBaseIcon, bu as vShow, bb as normalizeStyle, bT as kebabCase, m as NTooltip, aR as beforeNextFrameOnce, aW as createId, a3 as provide, bE as getCurrentInstance, ba as onMounted, af as watchEffect, o as openBlock, g as createElementBlock, b as createBaseVNode } from "./index.js"; +import { O as replaceable, x as h, d as defineComponent, bO as isBrowser, T as useTheme, P as createInjectionKey, aa as c, Q as cB, bP as fadeInTransition, aS as fadeInScaleUpTransition, ac as cNotM, X as toRef, bQ as imageLight, y as ref, ad as useLocale, J as watch, aD as on, aC as off, aB as onBeforeUnmount, R as inject, i as computed, S as useConfig, Y as useThemeClass, bR as isMounted, bS as LazyTeleport, bt as withDirectives, bT as zindexable, aX as Transition, F as Fragment, aj as NBaseIcon, bu as vShow, bb as normalizeStyle, bU as kebabCase, l as NTooltip, aR as beforeNextFrameOnce, aW as createId, a3 as provide, bF as getCurrentInstance, ba as onMounted, af as watchEffect, o as openBlock, g as createElementBlock, b as createBaseVNode } from "./index.js"; const RotateClockwiseIcon = replaceable("rotateClockwise", h( "svg", { viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, diff --git a/frontend/dist/assets/Upscale.vue_vue_type_script_setup_true_lang.js b/frontend/dist/assets/Upscale.vue_vue_type_script_setup_true_lang.js index 269970ced..84863a86b 100644 --- a/frontend/dist/assets/Upscale.vue_vue_type_script_setup_true_lang.js +++ b/frontend/dist/assets/Upscale.vue_vue_type_script_setup_true_lang.js @@ -1,4 +1,4 @@ -import { R as inject, bE as getCurrentInstance, J as watch, aB as onBeforeUnmount, Q as cB, ab as cM, aa as c, P as createInjectionKey, d as defineComponent, S as useConfig, T as useTheme, y as ref, a3 as provide, x as h, bF as formLight, a2 as keysOf, c as computed, az as formatLength, aH as get, bG as commonVariables, at as cE, X as toRef, aW as createId, bH as formItemInjectionKey, ba as onMounted, ah as createKey, Y as useThemeClass, aX as Transition, av as resolveWrappedSlot, aM as warn, u as useSettings, j as useState, K as upscalerOptions, o as openBlock, a as createBlock, w as withCtx, b as createBaseVNode, e as createVNode, f as unref, k as NSpace, h as NSelect, g as createElementBlock, l as createTextVNode, m as NTooltip, i as createCommentVNode, N as NCard, F as Fragment, L as renderList, z as NButton, B as toDisplayString, bA as convertToTextString, bI as resolveDynamicComponent, bf as NModal, A as NIcon } from "./index.js"; +import { R as inject, bF as getCurrentInstance, J as watch, aB as onBeforeUnmount, Q as cB, ab as cM, aa as c, P as createInjectionKey, d as defineComponent, S as useConfig, T as useTheme, y as ref, a3 as provide, x as h, bG as formLight, a2 as keysOf, i as computed, az as formatLength, aH as get, bH as commonVariables, at as cE, X as toRef, aW as createId, bI as formItemInjectionKey, ba as onMounted, ah as createKey, Y as useThemeClass, aX as Transition, av as resolveWrappedSlot, aM as warn, u as useSettings, a as useState, K as upscalerOptions, o as openBlock, g as createElementBlock, b as createBaseVNode, e as createVNode, f as unref, c as createBlock, w as withCtx, m as NSelect, k as createTextVNode, l as NTooltip, j as NSpace, h as createCommentVNode, F as Fragment, N as NCard, L as renderList, z as NButton, B as toDisplayString, bA as convertToTextString, bJ as resolveDynamicComponent, bf as NModal, A as NIcon } from "./index.js"; import { N as NSwitch } from "./Switch.js"; import { N as NSlider } from "./Slider.js"; import { N as NInputNumber } from "./InputNumber.js"; @@ -1904,136 +1904,130 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({ { label: "Bislerp", value: "bislerp" } ]; return (_ctx, _cache) => { - return openBlock(), createBlock(unref(NCard), { - title: "Highres fix", - class: "generate-extra-card" - }, { - default: withCtx(() => [ - createBaseVNode("div", _hoisted_1$2, [ - _hoisted_2$2, - createVNode(unref(NSwitch), { - value: target.value[props.tab].highres.enabled, - "onUpdate:value": _cache[0] || (_cache[0] = ($event) => target.value[props.tab].highres.enabled = $event) - }, null, 8, ["value"]) - ]), - target.value[props.tab].highres.enabled ? (openBlock(), createBlock(unref(NSpace), { - key: 0, - vertical: "", - class: "left-container" - }, { - default: withCtx(() => [ - createBaseVNode("div", _hoisted_3$2, [ - _hoisted_4$2, + return openBlock(), createElementBlock(Fragment, null, [ + createBaseVNode("div", _hoisted_1$2, [ + _hoisted_2$2, + createVNode(unref(NSwitch), { + value: target.value[props.tab].highres.enabled, + "onUpdate:value": _cache[0] || (_cache[0] = ($event) => target.value[props.tab].highres.enabled = $event) + }, null, 8, ["value"]) + ]), + target.value[props.tab].highres.enabled ? (openBlock(), createBlock(unref(NSpace), { + key: 0, + vertical: "", + class: "left-container" + }, { + default: withCtx(() => [ + createBaseVNode("div", _hoisted_3$2, [ + _hoisted_4$2, + createVNode(unref(NSelect), { + value: target.value[props.tab].highres.mode, + "onUpdate:value": _cache[1] || (_cache[1] = ($event) => target.value[props.tab].highres.mode = $event), + options: [ + { label: "Latent", value: "latent" }, + { label: "Image", value: "image" } + ] + }, null, 8, ["value"]) + ]), + target.value[props.tab].highres.mode === "image" ? (openBlock(), createElementBlock("div", _hoisted_5$2, [ + createBaseVNode("div", _hoisted_6$2, [ + _hoisted_7$2, createVNode(unref(NSelect), { - value: target.value[props.tab].highres.mode, - "onUpdate:value": _cache[1] || (_cache[1] = ($event) => target.value[props.tab].highres.mode = $event), - options: [ - { label: "Latent", value: "latent" }, - { label: "Image", value: "image" } - ] - }, null, 8, ["value"]) - ]), - target.value[props.tab].highres.mode === "image" ? (openBlock(), createElementBlock("div", _hoisted_5$2, [ - createBaseVNode("div", _hoisted_6$2, [ - _hoisted_7$2, - createVNode(unref(NSelect), { - value: target.value[props.tab].highres.image_upscaler, - "onUpdate:value": _cache[2] || (_cache[2] = ($event) => target.value[props.tab].highres.image_upscaler = $event), - size: "small", - style: { "flex-grow": "1" }, - filterable: "", - options: imageUpscalerOptions.value - }, null, 8, ["value", "options"]) - ]) - ])) : (openBlock(), createElementBlock("div", _hoisted_8$1, [ - createBaseVNode("div", _hoisted_9$1, [ - _hoisted_10$1, - createVNode(unref(NSwitch), { - value: target.value[props.tab].highres.antialiased, - "onUpdate:value": _cache[3] || (_cache[3] = ($event) => target.value[props.tab].highres.antialiased = $event) - }, null, 8, ["value"]) - ]), - createBaseVNode("div", _hoisted_11, [ - _hoisted_12, - createVNode(unref(NSelect), { - value: target.value[props.tab].highres.latent_scale_mode, - "onUpdate:value": _cache[4] || (_cache[4] = ($event) => target.value[props.tab].highres.latent_scale_mode = $event), - size: "small", - style: { "flex-grow": "1" }, - filterable: "", - options: latentUpscalerOptions - }, null, 8, ["value"]) - ]) - ])), - createBaseVNode("div", _hoisted_13, [ - createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { - trigger: withCtx(() => [ - _hoisted_14 - ]), - default: withCtx(() => [ - createTextVNode(" Number of steps to take in the diffusion process. Higher values will result in more detailed images but will take longer to generate. There is also a point of diminishing returns around 100 steps. "), - _hoisted_15 - ]), - _: 1 - }), - createVNode(unref(NSlider), { - value: target.value[props.tab].highres.steps, - "onUpdate:value": _cache[5] || (_cache[5] = ($event) => target.value[props.tab].highres.steps = $event), - min: 5, - max: 300, - style: { "margin-right": "12px" } - }, null, 8, ["value"]), - createVNode(unref(NInputNumber), { - value: target.value[props.tab].highres.steps, - "onUpdate:value": _cache[6] || (_cache[6] = ($event) => target.value[props.tab].highres.steps = $event), + value: target.value[props.tab].highres.image_upscaler, + "onUpdate:value": _cache[2] || (_cache[2] = ($event) => target.value[props.tab].highres.image_upscaler = $event), size: "small", - style: { "min-width": "96px", "width": "96px" } - }, null, 8, ["value"]) - ]), - createBaseVNode("div", _hoisted_16, [ - _hoisted_17, - createVNode(unref(NSlider), { - value: target.value[props.tab].highres.scale, - "onUpdate:value": _cache[7] || (_cache[7] = ($event) => target.value[props.tab].highres.scale = $event), - min: 1, - max: 8, - step: 0.1, - style: { "margin-right": "12px" } - }, null, 8, ["value"]), - createVNode(unref(NInputNumber), { - value: target.value[props.tab].highres.scale, - "onUpdate:value": _cache[8] || (_cache[8] = ($event) => target.value[props.tab].highres.scale = $event), - size: "small", - style: { "min-width": "96px", "width": "96px" }, - step: 0.1 + style: { "flex-grow": "1" }, + filterable: "", + options: imageUpscalerOptions.value + }, null, 8, ["value", "options"]) + ]) + ])) : (openBlock(), createElementBlock("div", _hoisted_8$1, [ + createBaseVNode("div", _hoisted_9$1, [ + _hoisted_10$1, + createVNode(unref(NSwitch), { + value: target.value[props.tab].highres.antialiased, + "onUpdate:value": _cache[3] || (_cache[3] = ($event) => target.value[props.tab].highres.antialiased = $event) }, null, 8, ["value"]) ]), - createBaseVNode("div", _hoisted_18, [ - _hoisted_19, - createVNode(unref(NSlider), { - value: target.value[props.tab].highres.strength, - "onUpdate:value": _cache[9] || (_cache[9] = ($event) => target.value[props.tab].highres.strength = $event), - min: 0.1, - max: 0.9, - step: 0.05, - style: { "margin-right": "12px" } - }, null, 8, ["value"]), - createVNode(unref(NInputNumber), { - value: target.value[props.tab].highres.strength, - "onUpdate:value": _cache[10] || (_cache[10] = ($event) => target.value[props.tab].highres.strength = $event), + createBaseVNode("div", _hoisted_11, [ + _hoisted_12, + createVNode(unref(NSelect), { + value: target.value[props.tab].highres.latent_scale_mode, + "onUpdate:value": _cache[4] || (_cache[4] = ($event) => target.value[props.tab].highres.latent_scale_mode = $event), size: "small", - style: { "min-width": "96px", "width": "96px" }, - min: 0.1, - max: 0.9, - step: 0.05 + style: { "flex-grow": "1" }, + filterable: "", + options: latentUpscalerOptions }, null, 8, ["value"]) ]) + ])), + createBaseVNode("div", _hoisted_13, [ + createVNode(unref(NTooltip), { style: { "max-width": "600px" } }, { + trigger: withCtx(() => [ + _hoisted_14 + ]), + default: withCtx(() => [ + createTextVNode(" Number of steps to take in the diffusion process. Higher values will result in more detailed images but will take longer to generate. There is also a point of diminishing returns around 100 steps. "), + _hoisted_15 + ]), + _: 1 + }), + createVNode(unref(NSlider), { + value: target.value[props.tab].highres.steps, + "onUpdate:value": _cache[5] || (_cache[5] = ($event) => target.value[props.tab].highres.steps = $event), + min: 5, + max: 300, + style: { "margin-right": "12px" } + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: target.value[props.tab].highres.steps, + "onUpdate:value": _cache[6] || (_cache[6] = ($event) => target.value[props.tab].highres.steps = $event), + size: "small", + style: { "min-width": "96px", "width": "96px" } + }, null, 8, ["value"]) ]), - _: 1 - })) : createCommentVNode("", true) - ]), - _: 1 - }); + createBaseVNode("div", _hoisted_16, [ + _hoisted_17, + createVNode(unref(NSlider), { + value: target.value[props.tab].highres.scale, + "onUpdate:value": _cache[7] || (_cache[7] = ($event) => target.value[props.tab].highres.scale = $event), + min: 1, + max: 8, + step: 0.1, + style: { "margin-right": "12px" } + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: target.value[props.tab].highres.scale, + "onUpdate:value": _cache[8] || (_cache[8] = ($event) => target.value[props.tab].highres.scale = $event), + size: "small", + style: { "min-width": "96px", "width": "96px" }, + step: 0.1 + }, null, 8, ["value"]) + ]), + createBaseVNode("div", _hoisted_18, [ + _hoisted_19, + createVNode(unref(NSlider), { + value: target.value[props.tab].highres.strength, + "onUpdate:value": _cache[9] || (_cache[9] = ($event) => target.value[props.tab].highres.strength = $event), + min: 0.1, + max: 0.9, + step: 0.05, + style: { "margin-right": "12px" } + }, null, 8, ["value"]), + createVNode(unref(NInputNumber), { + value: target.value[props.tab].highres.strength, + "onUpdate:value": _cache[10] || (_cache[10] = ($event) => target.value[props.tab].highres.strength = $event), + size: "small", + style: { "min-width": "96px", "width": "96px" }, + min: 0.1, + max: 0.9, + step: 0.05 + }, null, 8, ["value"]) + ]) + ]), + _: 1 + })) : createCommentVNode("", true) + ], 64); }; } }); @@ -2412,7 +2406,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({ export { NForm as N, _sfc_main$1 as _, - _sfc_main$2 as a, - _sfc_main as b, + _sfc_main as a, + _sfc_main$2 as b, NFormItem as c }; diff --git a/frontend/dist/assets/clock.js b/frontend/dist/assets/clock.js index d80c85bd8..09668e74d 100644 --- a/frontend/dist/assets/clock.js +++ b/frontend/dist/assets/clock.js @@ -5,7 +5,7 @@ var __publicField = (obj, key, value) => { return value; }; import { N as NDescriptionsItem, a as NDescriptions } from "./DescriptionsItem.js"; -import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, a as createBlock, w as withCtx, e as createVNode, f as unref, l as createTextVNode, B as toDisplayString, N as NCard, i as createCommentVNode, u as useSettings, m as NTooltip, c as computed, F as Fragment, j as useState, E as spaceRegex, A as NIcon, h as NSelect, G as promptHandleKeyUp, H as promptHandleKeyDown, I as NInput, _ as _export_sfc, J as watch, y as ref, s as serverUrl } from "./index.js"; +import { d as defineComponent, o as openBlock, g as createElementBlock, b as createBaseVNode, c as createBlock, w as withCtx, e as createVNode, f as unref, k as createTextVNode, B as toDisplayString, N as NCard, h as createCommentVNode, u as useSettings, l as NTooltip, i as computed, F as Fragment, a as useState, E as spaceRegex, A as NIcon, m as NSelect, G as promptHandleKeyUp, H as promptHandleKeyDown, I as NInput, _ as _export_sfc, J as watch, y as ref, s as serverUrl } from "./index.js"; import { N as NSlider } from "./Slider.js"; import { N as NInputNumber } from "./InputNumber.js"; import { N as NForm, c as NFormItem } from "./Upscale.vue_vue_type_script_setup_true_lang.js"; diff --git a/frontend/dist/assets/index.js b/frontend/dist/assets/index.js index 282e949db..9fe43b07c 100644 --- a/frontend/dist/assets/index.js +++ b/frontend/dist/assets/index.js @@ -43483,12 +43483,12 @@ const router = createRouter({ { path: "/", name: "home", - component: () => __vitePreload(() => import("./TextToImageView.js"), true ? ["assets/TextToImageView.js","assets/GenerateSection.vue_vue_type_script_setup_true_lang.js","assets/ImageOutput.vue_vue_type_script_setup_true_lang.js","assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js","assets/Switch.js","assets/TrashBin.js","assets/clock.js","assets/DescriptionsItem.js","assets/Slider.js","assets/InputNumber.js","assets/Upscale.vue_vue_type_script_setup_true_lang.js","assets/Settings.js","assets/v4.js"] : void 0) + component: () => __vitePreload(() => import("./TextToImageView.js"), true ? ["assets/TextToImageView.js","assets/GenerateSection.vue_vue_type_script_setup_true_lang.js","assets/ImageOutput.vue_vue_type_script_setup_true_lang.js","assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js","assets/Switch.js","assets/TrashBin.js","assets/clock.js","assets/DescriptionsItem.js","assets/Slider.js","assets/InputNumber.js","assets/Upscale.vue_vue_type_script_setup_true_lang.js","assets/Settings.js","assets/Scalecrafter.vue_vue_type_script_setup_true_lang.js","assets/v4.js"] : void 0) }, { path: "/txt2img", name: "txt2img", - component: () => __vitePreload(() => import("./TextToImageView.js"), true ? ["assets/TextToImageView.js","assets/GenerateSection.vue_vue_type_script_setup_true_lang.js","assets/ImageOutput.vue_vue_type_script_setup_true_lang.js","assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js","assets/Switch.js","assets/TrashBin.js","assets/clock.js","assets/DescriptionsItem.js","assets/Slider.js","assets/InputNumber.js","assets/Upscale.vue_vue_type_script_setup_true_lang.js","assets/Settings.js","assets/v4.js"] : void 0) + component: () => __vitePreload(() => import("./TextToImageView.js"), true ? ["assets/TextToImageView.js","assets/GenerateSection.vue_vue_type_script_setup_true_lang.js","assets/ImageOutput.vue_vue_type_script_setup_true_lang.js","assets/SendOutputTo.vue_vue_type_script_setup_true_lang.js","assets/Switch.js","assets/TrashBin.js","assets/clock.js","assets/DescriptionsItem.js","assets/Slider.js","assets/InputNumber.js","assets/Upscale.vue_vue_type_script_setup_true_lang.js","assets/Settings.js","assets/Scalecrafter.vue_vue_type_script_setup_true_lang.js","assets/v4.js"] : void 0) }, { path: "/img2img", @@ -43528,7 +43528,7 @@ const router = createRouter({ { path: "/settings", name: "settings", - component: () => __vitePreload(() => import("./SettingsView.js"), true ? ["assets/SettingsView.js","assets/Upscale.vue_vue_type_script_setup_true_lang.js","assets/Switch.js","assets/Slider.js","assets/InputNumber.js","assets/Settings.js"] : void 0) + component: () => __vitePreload(() => import("./SettingsView.js"), true ? ["assets/SettingsView.js","assets/Upscale.vue_vue_type_script_setup_true_lang.js","assets/Switch.js","assets/Slider.js","assets/InputNumber.js","assets/Settings.js","assets/Scalecrafter.vue_vue_type_script_setup_true_lang.js"] : void 0) }, { path: "/imageBrowser", @@ -43588,7 +43588,7 @@ export { useThemeClass as Y, NInternalSelectMenu as Z, _export_sfc as _, - createBlock as a, + useState2 as a, AddIcon as a$, happensIn as a0, call as a1, @@ -43669,25 +43669,25 @@ export { themeKey as bB, useNotification as bC, defaultSettings as bD, - getCurrentInstance as bE, - formLight$1 as bF, - commonVariables$m as bG, - formItemInjectionKey as bH, - resolveDynamicComponent as bI, - checkboxLight$1 as bJ, - urlFromPath as bK, - diffusersSchedulerTuple as bL, - useRouter as bM, - isBrowser$3 as bN, - fadeInTransition as bO, - imageLight as bP, - isMounted as bQ, - LazyTeleport as bR, - zindexable$1 as bS, - kebabCase$1 as bT, - useCompitable as bU, - descriptionsLight$1 as bV, - NAlert as bW, + NAlert as bE, + getCurrentInstance as bF, + formLight$1 as bG, + commonVariables$m as bH, + formItemInjectionKey as bI, + resolveDynamicComponent as bJ, + checkboxLight$1 as bK, + urlFromPath as bL, + diffusersSchedulerTuple as bM, + useRouter as bN, + isBrowser$3 as bO, + fadeInTransition as bP, + imageLight as bQ, + isMounted as bR, + LazyTeleport as bS, + zindexable$1 as bT, + kebabCase$1 as bU, + useCompitable as bV, + descriptionsLight$1 as bW, rgba as bX, inputNumberLight$1 as bY, XButton as bZ, @@ -43718,7 +43718,7 @@ export { color2Class as bx, rateLight as by, NTag as bz, - computed as c, + createBlock as c, VFollower as c0, sliderLight$1 as c1, isSlotEmpty as c2, @@ -43728,12 +43728,12 @@ export { createVNode as e, unref as f, createElementBlock as g, - NSelect as h, - createCommentVNode as i, - useState2 as j, - NSpace as k, - createTextVNode as l, - NTooltip as m, + createCommentVNode as h, + computed as i, + NSpace as j, + createTextVNode as k, + NTooltip as l, + NSelect as m, useMessage as n, openBlock as o, onUnmounted as p, diff --git a/frontend/src/components/generate/DeepShrink.vue b/frontend/src/components/generate/DeepShrink.vue index 1a278a940..a6b1a588c 100644 --- a/frontend/src/components/generate/DeepShrink.vue +++ b/frontend/src/components/generate/DeepShrink.vue @@ -1,109 +1,118 @@ diff --git a/frontend/src/components/generate/Scalecrafter.vue b/frontend/src/components/generate/Scalecrafter.vue index a7ce2bcce..ea6d21876 100644 --- a/frontend/src/components/generate/Scalecrafter.vue +++ b/frontend/src/components/generate/Scalecrafter.vue @@ -1,53 +1,55 @@ diff --git a/frontend/src/Content.vue b/frontend/src/Content.vue index 6915ba635..045b62ce9 100644 --- a/frontend/src/Content.vue +++ b/frontend/src/Content.vue @@ -1,6 +1,6 @@