diff --git a/.gitignore b/.gitignore index 42b4d89..b921ebf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /__pycache__/ /models/*.bin /models/*.safetensors +.directory \ No newline at end of file diff --git a/CrossAttentionPatch.py b/CrossAttentionPatch.py new file mode 100644 index 0000000..591d6b2 --- /dev/null +++ b/CrossAttentionPatch.py @@ -0,0 +1,142 @@ +import torch +import math +import torch.nn.functional as F +from comfy.ldm.modules.attention import optimized_attention +from .utils import tensor_to_size + +class CrossAttentionPatch: + # forward for patching + def __init__(self, ipadapter=None, number=0, weight=1.0, cond=None, uncond=None, weight_type="linear", mask=None, sigma_start=0.0, sigma_end=1.0, unfold_batch=False): + self.weights = [weight] + self.ipadapters = [ipadapter] + self.conds = [cond] + self.unconds = [uncond] + self.weight_types = [weight_type] + self.masks = [mask] + self.sigma_starts = [sigma_start] + self.sigma_ends = [sigma_end] + self.unfold_batch = [unfold_batch] + self.number = number + self.layers = 10 if '101_to_k_ip' in ipadapter.ip_layers.to_kvs else 15 + + self.k_key = str(self.number*2+1) + "_to_k_ip" + self.v_key = str(self.number*2+1) + "_to_v_ip" + + def set_new_condition(self, ipadapter=None, number=0, weight=1.0, cond=None, uncond=None, weight_type="linear", mask=None, sigma_start=0.0, sigma_end=1.0, unfold_batch=False): + self.weights.append(weight) + self.ipadapters.append(ipadapter) + self.conds.append(cond) + self.unconds.append(uncond) + self.weight_types.append(weight_type) + self.masks.append(mask) + self.sigma_starts.append(sigma_start) + self.sigma_ends.append(sigma_end) + self.unfold_batch.append(unfold_batch) + + def __call__(self, q, k, v, extra_options): + dtype = q.dtype + cond_or_uncond = extra_options["cond_or_uncond"] + sigma = extra_options["sigmas"].detach().cpu()[0].item() if 'sigmas' in extra_options else 999999999.9 + block_type = extra_options["block"][0] + #block_id = extra_options["block"][1] + t_idx = extra_options["transformer_index"] + + # extra options for AnimateDiff + ad_params = extra_options['ad_params'] if "ad_params" in extra_options else None + + b = q.shape[0] + seq_len = q.shape[1] + batch_prompt = b // len(cond_or_uncond) + out = optimized_attention(q, k, v, extra_options["n_heads"]) + _, _, oh, ow = extra_options["original_shape"] + + for weight, cond, uncond, ipadapter, mask, weight_type, sigma_start, sigma_end, unfold_batch in zip(self.weights, self.conds, self.unconds, self.ipadapters, self.masks, self.weight_types, self.sigma_starts, self.sigma_ends, self.unfold_batch): + if sigma <= sigma_start and sigma >= sigma_end: + if unfold_batch and cond.shape[0] > 1: + # Check AnimateDiff context window + if ad_params is not None and ad_params["sub_idxs"] is not None: + # if image length matches or exceeds full_length get sub_idx images + if cond.shape[0] >= ad_params["full_length"]: + cond = torch.Tensor(cond[ad_params["sub_idxs"]]) + uncond = torch.Tensor(uncond[ad_params["sub_idxs"]]) + # otherwise get sub_idxs images + else: + cond = tensor_to_size(cond, ad_params["full_length"]) + uncond = tensor_to_size(uncond, ad_params["full_length"]) + cond = cond[ad_params["sub_idxs"]] + uncond = uncond[ad_params["sub_idxs"]] + + cond = tensor_to_size(cond, batch_prompt) + uncond = tensor_to_size(uncond, batch_prompt) + + k_cond = ipadapter.ip_layers.to_kvs[self.k_key](cond) + k_uncond = ipadapter.ip_layers.to_kvs[self.k_key](uncond) + v_cond = ipadapter.ip_layers.to_kvs[self.v_key](cond) + v_uncond = ipadapter.ip_layers.to_kvs[self.v_key](uncond) + else: + k_cond = ipadapter.ip_layers.to_kvs[self.k_key](cond).repeat(batch_prompt, 1, 1) + k_uncond = ipadapter.ip_layers.to_kvs[self.k_key](uncond).repeat(batch_prompt, 1, 1) + v_cond = ipadapter.ip_layers.to_kvs[self.v_key](cond).repeat(batch_prompt, 1, 1) + v_uncond = ipadapter.ip_layers.to_kvs[self.v_key](uncond).repeat(batch_prompt, 1, 1) + + ip_k = torch.cat([(k_cond, k_uncond)[i] for i in cond_or_uncond], dim=0) + ip_v = torch.cat([(v_cond, v_uncond)[i] for i in cond_or_uncond], dim=0) + + out_ip = optimized_attention(q, ip_k, ip_v, extra_options["n_heads"]) + + if weight_type == 'ease in': + weight = weight * (0.05 + 0.95 * (1 - t_idx / self.layers)) + elif weight_type == 'ease out': + weight = weight * (0.05 + 0.95 * (t_idx / self.layers)) + elif weight_type == 'ease in-out': + weight = weight * (0.05 + 0.95 * (1 - abs(t_idx - (self.layers/2)) / (self.layers/2))) + elif weight_type == 'reverse in-out': + weight = weight * (0.05 + 0.95 * (abs(t_idx - (self.layers/2)) / (self.layers/2))) + elif weight_type == 'weak input' and block_type == 'input': + weight = weight * 0.2 + elif weight_type == 'weak middle' and block_type == 'middle': + weight = weight * 0.2 + elif weight_type == 'weak output' and block_type == 'output': + weight = weight * 0.2 + elif weight_type == 'strong middle' and (block_type == 'input' or block_type == 'output'): + weight = weight * 0.2 + + if mask is not None: + mask_h = oh / math.sqrt(oh * ow / seq_len) + mask_h = int(mask_h) + int((seq_len % int(mask_h)) != 0) + mask_w = seq_len // mask_h + + # check if using AnimateDiff and sliding context window + if (mask.shape[0] > 1 and ad_params is not None and ad_params["sub_idxs"] is not None): + # if mask length matches or exceeds full_length, get sub_idx masks + if mask.shape[0] >= ad_params["full_length"]: + mask = torch.Tensor(mask[ad_params["sub_idxs"]]) + mask = F.interpolate(mask.unsqueeze(1), size=(mask_h, mask_w), mode="bilinear").squeeze(1) + else: + mask = F.interpolate(mask.unsqueeze(1), size=(mask_h, mask_w), mode="bilinear").squeeze(1) + mask = tensor_to_size(mask, ad_params["full_length"]) + mask = mask[ad_params["sub_idxs"]] + else: + mask = F.interpolate(mask.unsqueeze(1), size=(mask_h, mask_w), mode="bilinear").squeeze(1) + mask = tensor_to_size(mask, batch_prompt) + + mask = mask.repeat(len(cond_or_uncond), 1, 1) + mask = mask.view(mask.shape[0], -1, 1).repeat(1, 1, out.shape[2]) + + # covers cases where extreme aspect ratios can cause the mask to have a wrong size + mask_len = mask_h * mask_w + if mask_len < seq_len: + pad_len = seq_len - mask_len + pad1 = pad_len // 2 + pad2 = pad_len - pad1 + mask = F.pad(mask, (0, 0, pad1, pad2), value=0.0) + elif mask_len > seq_len: + crop_start = (mask_len - seq_len) // 2 + mask = mask[:, crop_start:crop_start+seq_len, :] + + out_ip = out_ip * mask + + out_ip = out_ip * weight + out = out + out_ip + + return out.to(dtype=dtype) diff --git a/IPAdapterPlus.py b/IPAdapterPlus.py index 3dd17f4..3ecbbcb 100644 --- a/IPAdapterPlus.py +++ b/IPAdapterPlus.py @@ -1,150 +1,124 @@ import torch import os import math - -import comfy.utils -import comfy.model_management -from comfy.clip_vision import clip_preprocess, Output -from comfy.ldm.modules.attention import optimized_attention -from nodes import MAX_RESOLUTION import folder_paths +import comfy.model_management as model_management +from comfy.clip_vision import load as load_clip_vision +from comfy.sd import load_lora_for_models +import comfy.utils + import torch.nn as nn from PIL import Image -import torch.nn.functional as F -import torchvision.transforms as TT +import torchvision.transforms.v2 as T -from .resampler import PerceiverAttention, FeedForward, Resampler +from .image_proj_models import MLPProjModel, MLPProjModelFaceId, ProjModelFaceIdPlus, Resampler, ImageProjModel +from .CrossAttentionPatch import CrossAttentionPatch +from .utils import ( + encode_image_masked, + tensor_to_size, + contrast_adaptive_sharpening, + tensor_to_image, + image_to_tensor, + ipadapter_model_loader, + insightface_loader, + get_clipvision_file, + get_ipadapter_file, + get_lora_file, +) -# set the models directory backward compatible -GLOBAL_MODELS_DIR = os.path.join(folder_paths.models_dir, "ipadapter") -MODELS_DIR = GLOBAL_MODELS_DIR if os.path.isdir(GLOBAL_MODELS_DIR) else os.path.join(os.path.dirname(os.path.realpath(__file__)), "models") +# set the models directory if "ipadapter" not in folder_paths.folder_names_and_paths: - current_paths = [MODELS_DIR] + current_paths = [os.path.join(folder_paths.models_dir, "ipadapter")] else: current_paths, _ = folder_paths.folder_names_and_paths["ipadapter"] folder_paths.folder_names_and_paths["ipadapter"] = (current_paths, folder_paths.supported_pt_extensions) -INSIGHTFACE_DIR = os.path.join(folder_paths.models_dir, "insightface") +WEIGHT_TYPES = ["linear", "ease in", "ease out", 'ease in-out', 'reverse in-out', 'weak input', 'weak output', 'weak middle', 'strong middle'] -class FacePerceiverResampler(torch.nn.Module): - def __init__( - self, - *, - dim=768, - depth=4, - dim_head=64, - heads=16, - embedding_dim=1280, - output_dim=768, - ff_mult=4, - ): - super().__init__() - - self.proj_in = torch.nn.Linear(embedding_dim, dim) - self.proj_out = torch.nn.Linear(dim, output_dim) - self.norm_out = torch.nn.LayerNorm(output_dim) - self.layers = torch.nn.ModuleList([]) - for _ in range(depth): - self.layers.append( - torch.nn.ModuleList( - [ - PerceiverAttention(dim=dim, dim_head=dim_head, heads=heads), - FeedForward(dim=dim, mult=ff_mult), - ] - ) - ) - - def forward(self, latents, x): - x = self.proj_in(x) - for attn, ff in self.layers: - latents = attn(x, latents) + latents - latents = ff(latents) + latents - latents = self.proj_out(latents) - return self.norm_out(latents) - -class MLPProjModel(torch.nn.Module): - def __init__(self, cross_attention_dim=1024, clip_embeddings_dim=1024): - super().__init__() - - self.proj = torch.nn.Sequential( - torch.nn.Linear(clip_embeddings_dim, clip_embeddings_dim), - torch.nn.GELU(), - torch.nn.Linear(clip_embeddings_dim, cross_attention_dim), - torch.nn.LayerNorm(cross_attention_dim) - ) - - def forward(self, image_embeds): - clip_extra_context_tokens = self.proj(image_embeds) - return clip_extra_context_tokens - -class MLPProjModelFaceId(torch.nn.Module): - def __init__(self, cross_attention_dim=768, id_embeddings_dim=512, num_tokens=4): +""" +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Main IPAdapter Class +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +""" +class IPAdapter(nn.Module): + def __init__(self, ipadapter_model, cross_attention_dim=1024, output_cross_attention_dim=1024, clip_embeddings_dim=1024, clip_extra_context_tokens=4, is_sdxl=False, is_plus=False, is_full=False, is_faceid=False): super().__init__() + self.clip_embeddings_dim = clip_embeddings_dim self.cross_attention_dim = cross_attention_dim - self.num_tokens = num_tokens + self.output_cross_attention_dim = output_cross_attention_dim + self.clip_extra_context_tokens = clip_extra_context_tokens + self.is_sdxl = is_sdxl + self.is_full = is_full + self.is_plus = is_plus - self.proj = torch.nn.Sequential( - torch.nn.Linear(id_embeddings_dim, id_embeddings_dim*2), - torch.nn.GELU(), - torch.nn.Linear(id_embeddings_dim*2, cross_attention_dim*num_tokens), + if is_faceid: + self.image_proj_model = self.init_proj_faceid() + elif is_full: + self.image_proj_model = self.init_proj_full() + elif is_plus: + self.image_proj_model = self.init_proj_plus() + else: + self.image_proj_model = self.init_proj() + + self.image_proj_model.load_state_dict(ipadapter_model["image_proj"]) + self.ip_layers = To_KV(ipadapter_model["ip_adapter"]) + + def init_proj(self): + image_proj_model = ImageProjModel( + cross_attention_dim=self.cross_attention_dim, + clip_embeddings_dim=self.clip_embeddings_dim, + clip_extra_context_tokens=self.clip_extra_context_tokens ) - self.norm = torch.nn.LayerNorm(cross_attention_dim) + return image_proj_model - def forward(self, id_embeds): - clip_extra_context_tokens = self.proj(id_embeds) - clip_extra_context_tokens = clip_extra_context_tokens.reshape(-1, self.num_tokens, self.cross_attention_dim) - clip_extra_context_tokens = self.norm(clip_extra_context_tokens) - return clip_extra_context_tokens - -class ProjModelFaceIdPlus(torch.nn.Module): - def __init__(self, cross_attention_dim=768, id_embeddings_dim=512, clip_embeddings_dim=1280, num_tokens=4): - super().__init__() - - self.cross_attention_dim = cross_attention_dim - self.num_tokens = num_tokens - - self.proj = torch.nn.Sequential( - torch.nn.Linear(id_embeddings_dim, id_embeddings_dim*2), - torch.nn.GELU(), - torch.nn.Linear(id_embeddings_dim*2, cross_attention_dim*num_tokens), - ) - self.norm = torch.nn.LayerNorm(cross_attention_dim) - - self.perceiver_resampler = FacePerceiverResampler( - dim=cross_attention_dim, + def init_proj_plus(self): + image_proj_model = Resampler( + dim=self.cross_attention_dim, depth=4, dim_head=64, - heads=cross_attention_dim // 64, - embedding_dim=clip_embeddings_dim, - output_dim=cross_attention_dim, - ff_mult=4, + heads=20 if self.is_sdxl else 12, + num_queries=self.clip_extra_context_tokens, + embedding_dim=self.clip_embeddings_dim, + output_dim=self.output_cross_attention_dim, + ff_mult=4 ) - - def forward(self, id_embeds, clip_embeds, scale=1.0, shortcut=False): - x = self.proj(id_embeds) - x = x.reshape(-1, self.num_tokens, self.cross_attention_dim) - x = self.norm(x) - out = self.perceiver_resampler(x, clip_embeds) - if shortcut: - out = x + scale * out - return out + return image_proj_model -class ImageProjModel(nn.Module): - def __init__(self, cross_attention_dim=1024, clip_embeddings_dim=1024, clip_extra_context_tokens=4): - super().__init__() - - self.cross_attention_dim = cross_attention_dim - self.clip_extra_context_tokens = clip_extra_context_tokens - self.proj = nn.Linear(clip_embeddings_dim, self.clip_extra_context_tokens * cross_attention_dim) - self.norm = nn.LayerNorm(cross_attention_dim) - - def forward(self, image_embeds): - embeds = image_embeds - clip_extra_context_tokens = self.proj(embeds).reshape(-1, self.clip_extra_context_tokens, self.cross_attention_dim) - clip_extra_context_tokens = self.norm(clip_extra_context_tokens) - return clip_extra_context_tokens + def init_proj_full(self): + image_proj_model = MLPProjModel( + cross_attention_dim=self.cross_attention_dim, + clip_embeddings_dim=self.clip_embeddings_dim + ) + return image_proj_model + + def init_proj_faceid(self): + if self.is_plus: + image_proj_model = ProjModelFaceIdPlus( + cross_attention_dim=self.cross_attention_dim, + id_embeddings_dim=512, + clip_embeddings_dim=self.clip_embeddings_dim, # 1280, + num_tokens=self.clip_extra_context_tokens, # 4, + ) + else: + image_proj_model = MLPProjModelFaceId( + cross_attention_dim=self.cross_attention_dim, + id_embeddings_dim=512, + num_tokens=self.clip_extra_context_tokens, + ) + return image_proj_model + + @torch.inference_mode() + def get_image_embeds(self, clip_embed, clip_embed_zeroed): + image_prompt_embeds = self.image_proj_model(clip_embed) + uncond_image_prompt_embeds = self.image_proj_model(clip_embed_zeroed) + return image_prompt_embeds, uncond_image_prompt_embeds + + @torch.inference_mode() + def get_image_embeds_faceid_plus(self, face_embed, clip_embed, s_scale, shortcut): + embeds = self.image_proj_model(face_embed, clip_embed, scale=s_scale, shortcut=shortcut) + return embeds class To_KV(nn.Module): def __init__(self, state_dict): @@ -166,417 +140,299 @@ def set_model_patch_replace(model, patch_kwargs, key): else: to["patches_replace"]["attn2"][key].set_new_condition(**patch_kwargs) -def masked_tiling(image, short_side_tiles, weight=0.6, blur=0): - _, orig_height, orig_width, _ = image.shape - tile_size = 224 +def ipadapter_execute(model, + ipadapter, + clipvision, + insightface=None, + image=None, + image_negative=None, + weight=1.0, + weight_faceidv2=None, + weight_type="original", + combine_embeds="concat", + start_at=0.0, + end_at=1.0, + attn_mask=None, + pos_embed=None, + neg_embed=None, + unfold_batch=False,): + dtype = torch.float16 if model_management.should_use_fp16() else torch.bfloat16 if model_management.should_use_bf16() else torch.float32 + device = model_management.get_torch_device() - if orig_width < orig_height: - num_tiles_x = short_side_tiles - new_width = tile_size * num_tiles_x - new_height = orig_height * new_width // orig_width - num_tiles_y = new_height // tile_size - else: - num_tiles_y = short_side_tiles - new_height = tile_size * num_tiles_y - new_width = orig_width * new_height // orig_height - num_tiles_x = new_width // tile_size + is_full = "proj.3.weight" in ipadapter["image_proj"] + is_portrait = "proj.2.weight" in ipadapter["image_proj"] and not "proj.3.weight" in ipadapter["image_proj"] and not "0.to_q_lora.down.weight" in ipadapter["ip_adapter"] + is_faceid = is_portrait or "0.to_q_lora.down.weight" in ipadapter["ip_adapter"] + is_plus = is_full or "latents" in ipadapter["image_proj"] or "perceiver_resampler.proj_in.weight" in ipadapter["image_proj"] + is_faceidv2 = "faceidplusv2" in ipadapter - start_x = start_y = 0 - if (new_height % tile_size) >= tile_size//4: - num_tiles_y += 1 - else: - start_y = (new_height - tile_size*num_tiles_y) // 2 + if is_faceidv2: + weight_faceidv2 = weight_faceidv2 if weight_faceidv2 is not None else weight*2 - if (new_width % tile_size) >= tile_size//4: - num_tiles_x += 1 - else: - start_x = (new_width - tile_size*num_tiles_x) // 2 + if is_faceid and not insightface: + raise Exception("insightface model is required for FaceID models") - weight = 1.0 if num_tiles_x == 1 or num_tiles_y == 1 else weight + output_cross_attention_dim = ipadapter["ip_adapter"]["1.to_k_ip.weight"].shape[1] + is_sdxl = output_cross_attention_dim == 2048 + cross_attention_dim = 1280 if is_plus and is_sdxl and not is_faceid else output_cross_attention_dim + clip_extra_context_tokens = 16 if (is_plus and not is_faceid) or is_portrait else 4 - ref_image = F.interpolate(image.permute([0,3,1,2]), size=(new_height, new_width), mode="bicubic").permute([0,2,3,1]) + if image is not None and image.shape[1] != image.shape[2]: + print("\033[33mINFO: the IPAdapter reference image is not a square, CLIPImageProcessor will resize and crop it at the center. If the main focus of the picture is not in the middle the result might not be what you are expecting.\033[0m") - tiles = [] - attn_mask = [] + face_cond_embeds = None + if is_faceid: + if insightface is None: + raise Exception("Insightface model is required for FaceID models") - for i in range(num_tiles_y): - for j in range(num_tiles_x): - start_height = i * tile_size + start_y - end_height = start_height + tile_size + start_y - start_width = j * tile_size + start_x - end_width = start_width + tile_size + start_x + from insightface.utils import face_align - if end_height > new_height: - start_height = new_height - tile_size - end_height = new_height - if end_width > new_width: - start_width = new_width - tile_size - end_width = new_width + insightface.det_model.input_size = (640,640) # reset the detection size + image_iface = tensor_to_image(image) + face_cond_embeds = [] + image = [] - tile = ref_image[:1, start_height:end_height, start_width:end_width, :] - tiles.append(tile.squeeze(0)) + for i in range(image_iface.shape[0]): + for size in [(size, size) for size in range(640, 256, -64)]: + insightface.det_model.input_size = size # TODO: hacky but seems to be working + face = insightface.get(image_iface[i]) + if face: + face_cond_embeds.append(torch.from_numpy(face[0].normed_embedding).unsqueeze(0)) + image.append(image_to_tensor(face_align.norm_crop(image_iface[i], landmark=face[0].kps, image_size=256))) - # create mask - mask = torch.zeros([new_height, new_width], dtype=image.dtype, device=image.device) - mask[start_height:end_height, start_width:end_width] = weight - - attn_mask.append(mask) - - image = torch.stack(tiles, dim=0) - attn_mask = torch.stack(attn_mask, dim=0) - - # If we have a lot of tiles we add bigger tiles with a higher weight to give clipvision a better idea of the overall image - if num_tiles_x != 1 and num_tiles_y != 1: - comp_tiles, comp_attn_mask = masked_tiling(ref_image, 1, 1.0, blur) - - if image.shape[1:3] != comp_tiles.shape[1:3]: - comp_tiles = F.interpolate(comp_tiles.permute([0,3,1,2]), size=(image.shape[1], image.shape[2]), mode="bicubic").permute([0,2,3,1]) - image = torch.cat([comp_tiles, image], dim=0) - - if attn_mask.shape[1:3] != comp_attn_mask.shape[1:3]: - comp_attn_mask = F.interpolate(comp_attn_mask.unsqueeze(1), size=(attn_mask.shape[1], attn_mask.shape[2]), mode="bicubic").squeeze(1) - attn_mask = torch.cat([comp_attn_mask, attn_mask], dim=0) - - if blur > 0: - attn_mask = TT.GaussianBlur(int(6*blur+1), blur)(attn_mask.unsqueeze(1)).permute([0,2,3,1]).squeeze(-1) - - return image, attn_mask - -def image_add_noise(image, noise): - image = image.permute([0,3,1,2]) - torch.manual_seed(0) # use a fixed random for reproducible results - transforms = TT.Compose([ - TT.CenterCrop(min(image.shape[2], image.shape[3])), - TT.Resize((224, 224), interpolation=TT.InterpolationMode.BICUBIC, antialias=True), - TT.ElasticTransform(alpha=75.0, sigma=noise*3.5), # shuffle the image - TT.RandomVerticalFlip(p=1.0), # flip the image to change the geometry even more - TT.RandomHorizontalFlip(p=1.0), - ]) - image = transforms(image.cpu()) - image = image.permute([0,2,3,1]) - image = image + ((0.25*(1-noise)+0.05) * torch.randn_like(image) ) # add further random noise - return image - -def zeroed_hidden_states(clip_vision, batch_size): - image = torch.zeros([batch_size, 224, 224, 3]) - comfy.model_management.load_model_gpu(clip_vision.patcher) - pixel_values = clip_preprocess(image.to(clip_vision.load_device)).float() - outputs = clip_vision.model(pixel_values=pixel_values, intermediate_output=-2) - - # we only need the penultimate hidden states - return outputs[1].to(comfy.model_management.intermediate_device()) - -def encode_image_masked(clip_vision, image, mask=None): - comfy.model_management.load_model_gpu(clip_vision.patcher) - pixel_values = clip_preprocess(image.to(clip_vision.load_device)).float() - - if mask is not None: - pixel_values = pixel_values * mask.to(clip_vision.load_device) - - out = clip_vision.model(pixel_values=pixel_values, intermediate_output=-2) - - outputs = Output() - outputs["last_hidden_state"] = out[0].to(comfy.model_management.intermediate_device()) - outputs["image_embeds"] = out[2].to(comfy.model_management.intermediate_device()) - outputs["penultimate_hidden_states"] = out[1].to(comfy.model_management.intermediate_device()) - return outputs - -def min_(tensor_list): - # return the element-wise min of the tensor list. - x = torch.stack(tensor_list) - mn = x.min(axis=0)[0] - return torch.clamp(mn, min=0) - -def max_(tensor_list): - # return the element-wise max of the tensor list. - x = torch.stack(tensor_list) - mx = x.max(axis=0)[0] - return torch.clamp(mx, max=1) - -# From https://github.com/Jamy-L/Pytorch-Contrast-Adaptive-Sharpening/ -def contrast_adaptive_sharpening(image, amount): - img = F.pad(image, pad=(1, 1, 1, 1)).cpu() - - a = img[..., :-2, :-2] - b = img[..., :-2, 1:-1] - c = img[..., :-2, 2:] - d = img[..., 1:-1, :-2] - e = img[..., 1:-1, 1:-1] - f = img[..., 1:-1, 2:] - g = img[..., 2:, :-2] - h = img[..., 2:, 1:-1] - i = img[..., 2:, 2:] - - # Computing contrast - cross = (b, d, e, f, h) - mn = min_(cross) - mx = max_(cross) - - diag = (a, c, g, i) - mn2 = min_(diag) - mx2 = max_(diag) - mx = mx + mx2 - mn = mn + mn2 - - # Computing local weight - inv_mx = torch.reciprocal(mx) - amp = inv_mx * torch.minimum(mn, (2 - mx)) - - # scaling - amp = torch.sqrt(amp) - w = - amp * (amount * (1/5 - 1/8) + 1/8) - div = torch.reciprocal(1 + 4*w) - - output = ((b + d + f + h)*w + e) * div - output = torch.nan_to_num(output) - output = output.clamp(0, 1) - - return (output) - -def tensorToNP(image): - out = torch.clamp(255. * image.detach().cpu(), 0, 255).to(torch.uint8) - out = out[..., [2, 1, 0]] - out = out.numpy() - - return out - -def NPToTensor(image): - out = torch.from_numpy(image) - out = torch.clamp(out.to(torch.float)/255., 0.0, 1.0) - out = out[..., [2, 1, 0]] - - return out - -class IPAdapter(nn.Module): - def __init__(self, ipadapter_model, cross_attention_dim=1024, output_cross_attention_dim=1024, clip_embeddings_dim=1024, clip_extra_context_tokens=4, is_sdxl=False, is_plus=False, is_full=False, is_faceid=False): - super().__init__() - - self.clip_embeddings_dim = clip_embeddings_dim - self.cross_attention_dim = cross_attention_dim - self.output_cross_attention_dim = output_cross_attention_dim - self.clip_extra_context_tokens = clip_extra_context_tokens - self.is_sdxl = is_sdxl - self.is_full = is_full - self.is_plus = is_plus - - if is_faceid: - self.image_proj_model = self.init_proj_faceid() - elif is_plus: - self.image_proj_model = self.init_proj_plus() - else: - self.image_proj_model = self.init_proj() - - self.image_proj_model.load_state_dict(ipadapter_model["image_proj"]) - self.ip_layers = To_KV(ipadapter_model["ip_adapter"]) - - def init_proj(self): - image_proj_model = ImageProjModel( - cross_attention_dim=self.cross_attention_dim, - clip_embeddings_dim=self.clip_embeddings_dim, - clip_extra_context_tokens=self.clip_extra_context_tokens - ) - return image_proj_model - - def init_proj_plus(self): - if self.is_full: - image_proj_model = MLPProjModel( - cross_attention_dim=self.cross_attention_dim, - clip_embeddings_dim=self.clip_embeddings_dim - ) - else: - image_proj_model = Resampler( - dim=self.cross_attention_dim, - depth=4, - dim_head=64, - heads=20 if self.is_sdxl else 12, - num_queries=self.clip_extra_context_tokens, - embedding_dim=self.clip_embeddings_dim, - output_dim=self.output_cross_attention_dim, - ff_mult=4 - ) - return image_proj_model - - def init_proj_faceid(self): - if self.is_plus: - image_proj_model = ProjModelFaceIdPlus( - cross_attention_dim=self.cross_attention_dim, - id_embeddings_dim=512, - clip_embeddings_dim=1280, - num_tokens=4, - ) - else: - image_proj_model = MLPProjModelFaceId( - cross_attention_dim=self.cross_attention_dim, - id_embeddings_dim=512, - num_tokens=self.clip_extra_context_tokens, - ) - return image_proj_model - - @torch.inference_mode() - def get_image_embeds(self, clip_embed, clip_embed_zeroed): - image_prompt_embeds = self.image_proj_model(clip_embed) - uncond_image_prompt_embeds = self.image_proj_model(clip_embed_zeroed) - return image_prompt_embeds, uncond_image_prompt_embeds - - @torch.inference_mode() - def get_image_embeds_faceid_plus(self, face_embed, clip_embed, s_scale, shortcut): - embeds = self.image_proj_model(face_embed, clip_embed, scale=s_scale, shortcut=shortcut) - return embeds - -class CrossAttentionPatch: - # forward for patching - def __init__(self, weight, ipadapter, number, cond, uncond, weight_type="original", mask=None, sigma_start=0.0, sigma_end=1.0, unfold_batch=False): - self.weights = [weight] - self.ipadapters = [ipadapter] - self.conds = [cond] - self.unconds = [uncond] - self.number = number - self.weight_type = [weight_type] - self.masks = [mask] - self.sigma_start = [sigma_start] - self.sigma_end = [sigma_end] - self.unfold_batch = [unfold_batch] - - self.k_key = str(self.number*2+1) + "_to_k_ip" - self.v_key = str(self.number*2+1) + "_to_v_ip" - - def set_new_condition(self, weight, ipadapter, number, cond, uncond, weight_type="original", mask=None, sigma_start=0.0, sigma_end=1.0, unfold_batch=False): - self.weights.append(weight) - self.ipadapters.append(ipadapter) - self.conds.append(cond) - self.unconds.append(uncond) - self.masks.append(mask) - self.weight_type.append(weight_type) - self.sigma_start.append(sigma_start) - self.sigma_end.append(sigma_end) - self.unfold_batch.append(unfold_batch) - - def __call__(self, n, context_attn2, value_attn2, extra_options): - org_dtype = n.dtype - cond_or_uncond = extra_options["cond_or_uncond"] - sigma = extra_options["sigmas"][0] if 'sigmas' in extra_options else None - sigma = sigma.item() if sigma is not None else 999999999.9 - - # extra options for AnimateDiff - ad_params = extra_options['ad_params'] if "ad_params" in extra_options else None - - q = n - k = context_attn2 - v = value_attn2 - b = q.shape[0] - qs = q.shape[1] - batch_prompt = b // len(cond_or_uncond) - out = optimized_attention(q, k, v, extra_options["n_heads"]) - _, _, lh, lw = extra_options["original_shape"] - - for weight, cond, uncond, ipadapter, mask, weight_type, sigma_start, sigma_end, unfold_batch in zip(self.weights, self.conds, self.unconds, self.ipadapters, self.masks, self.weight_type, self.sigma_start, self.sigma_end, self.unfold_batch): - if sigma > sigma_start or sigma < sigma_end: - continue - - if unfold_batch and cond.shape[0] > 1: - # Check AnimateDiff context window - if ad_params is not None and ad_params["sub_idxs"] is not None: - # if images length matches or exceeds full_length get sub_idx images - if cond.shape[0] >= ad_params["full_length"]: - cond = torch.Tensor(cond[ad_params["sub_idxs"]]) - uncond = torch.Tensor(uncond[ad_params["sub_idxs"]]) - # otherwise, need to do more to get proper sub_idxs masks - else: - # check if images length matches full_length - if not, make it match - if cond.shape[0] < ad_params["full_length"]: - cond = torch.cat((cond, cond[-1:].repeat((ad_params["full_length"]-cond.shape[0], 1, 1))), dim=0) - uncond = torch.cat((uncond, uncond[-1:].repeat((ad_params["full_length"]-uncond.shape[0], 1, 1))), dim=0) - # if we have too many remove the excess (should not happen, but just in case) - if cond.shape[0] > ad_params["full_length"]: - cond = cond[:ad_params["full_length"]] - uncond = uncond[:ad_params["full_length"]] - cond = cond[ad_params["sub_idxs"]] - uncond = uncond[ad_params["sub_idxs"]] - - # if we don't have enough reference images repeat the last one until we reach the right size - if cond.shape[0] < batch_prompt: - cond = torch.cat((cond, cond[-1:].repeat((batch_prompt-cond.shape[0], 1, 1))), dim=0) - uncond = torch.cat((uncond, uncond[-1:].repeat((batch_prompt-uncond.shape[0], 1, 1))), dim=0) - # if we have too many remove the exceeding - elif cond.shape[0] > batch_prompt: - cond = cond[:batch_prompt] - uncond = uncond[:batch_prompt] - - k_cond = ipadapter.ip_layers.to_kvs[self.k_key](cond) - k_uncond = ipadapter.ip_layers.to_kvs[self.k_key](uncond) - v_cond = ipadapter.ip_layers.to_kvs[self.v_key](cond) - v_uncond = ipadapter.ip_layers.to_kvs[self.v_key](uncond) + if 640 not in size: + print(f"\033[33mINFO: InsightFace detection resolution lowered to {size}.\033[0m") + break else: - k_cond = ipadapter.ip_layers.to_kvs[self.k_key](cond).repeat(batch_prompt, 1, 1) - k_uncond = ipadapter.ip_layers.to_kvs[self.k_key](uncond).repeat(batch_prompt, 1, 1) - v_cond = ipadapter.ip_layers.to_kvs[self.v_key](cond).repeat(batch_prompt, 1, 1) - v_uncond = ipadapter.ip_layers.to_kvs[self.v_key](uncond).repeat(batch_prompt, 1, 1) + raise Exception('InsightFace: No face detected.') + face_cond_embeds = torch.stack(face_cond_embeds).to(device, dtype=dtype) + image = torch.stack(image) + del image_iface, face - if weight_type.startswith("linear"): - ip_k = torch.cat([(k_cond, k_uncond)[i] for i in cond_or_uncond], dim=0) * weight - ip_v = torch.cat([(v_cond, v_uncond)[i] for i in cond_or_uncond], dim=0) * weight + if image is not None: + img_cond_embeds = encode_image_masked(clipvision, image) + + if is_plus: + img_cond_embeds = img_cond_embeds.penultimate_hidden_states + image_negative = image_negative if image_negative is not None else torch.zeros([1, 224, 224, 3]) + img_uncond_embeds = encode_image_masked(clipvision, image_negative).penultimate_hidden_states + else: + img_cond_embeds = img_cond_embeds.image_embeds if not is_faceid else face_cond_embeds + if image_negative is not None: + img_uncond_embeds = encode_image_masked(clipvision, image_negative).image_embeds else: - ip_k = torch.cat([(k_cond, k_uncond)[i] for i in cond_or_uncond], dim=0) - ip_v = torch.cat([(v_cond, v_uncond)[i] for i in cond_or_uncond], dim=0) + img_uncond_embeds = torch.zeros_like(img_cond_embeds) + elif pos_embed is not None: + img_cond_embeds = pos_embed - if weight_type.startswith("channel"): - # code by Lvmin Zhang at Stanford University as also seen on Fooocus IPAdapter implementation - ip_v_mean = torch.mean(ip_v, dim=1, keepdim=True) - ip_v_offset = ip_v - ip_v_mean - _, _, C = ip_k.shape - channel_penalty = float(C) / 1280.0 - W = weight * channel_penalty - ip_k = ip_k * W - ip_v = ip_v_offset + ip_v_mean * W + if neg_embed is not None: + img_uncond_embeds = neg_embed + else: + if is_plus: + img_uncond_embeds = encode_image_masked(clipvision, torch.zeros([1, 224, 224, 3])).penultimate_hidden_states + else: + img_uncond_embeds = torch.zeros_like(img_cond_embeds) + else: + raise Exception("Images or Embeds are required") - out_ip = optimized_attention(q, ip_k, ip_v, extra_options["n_heads"]) - if weight_type.startswith("original"): - out_ip = out_ip * weight + # ensure that cond and uncond have the same batch size + img_uncond_embeds = tensor_to_size(img_uncond_embeds, img_cond_embeds.shape[0]) - if mask is not None: - # TODO: needs checking - mask_h = lh / math.sqrt(lh * lw / qs) - mask_h = int(mask_h) + int((qs % int(mask_h)) != 0) - mask_w = qs // mask_h + img_cond_embeds = img_cond_embeds.to(device, dtype=dtype) + img_uncond_embeds = img_uncond_embeds.to(device, dtype=dtype) - # check if using AnimateDiff and sliding context window - if (mask.shape[0] > 1 and ad_params is not None and ad_params["sub_idxs"] is not None): - # if mask length matches or exceeds full_length, just get sub_idx masks, resize, and continue - if mask.shape[0] >= ad_params["full_length"]: - mask_downsample = torch.Tensor(mask[ad_params["sub_idxs"]]) - mask_downsample = F.interpolate(mask_downsample.unsqueeze(1), size=(mask_h, mask_w), mode="bicubic").squeeze(1) - # otherwise, need to do more to get proper sub_idxs masks - else: - # resize to needed attention size (to save on memory) - mask_downsample = F.interpolate(mask.unsqueeze(1), size=(mask_h, mask_w), mode="bicubic").squeeze(1) - # check if mask length matches full_length - if not, make it match - if mask_downsample.shape[0] < ad_params["full_length"]: - mask_downsample = torch.cat((mask_downsample, mask_downsample[-1:].repeat((ad_params["full_length"]-mask_downsample.shape[0], 1, 1))), dim=0) - # if we have too many remove the excess (should not happen, but just in case) - if mask_downsample.shape[0] > ad_params["full_length"]: - mask_downsample = mask_downsample[:ad_params["full_length"]] - # now, select sub_idxs masks - mask_downsample = mask_downsample[ad_params["sub_idxs"]] - # otherwise, perform usual mask interpolation + # combine the embeddings if needed + if combine_embeds != "concat" and img_cond_embeds.shape[0] > 1 and not unfold_batch: + if combine_embeds == "add": + img_cond_embeds = torch.sum(img_cond_embeds, dim=0).unsqueeze(0) + if face_cond_embeds is not None: + face_cond_embeds = torch.sum(face_cond_embeds, dim=0).unsqueeze(0) + elif combine_embeds == "subtract": + img_cond_embeds = img_cond_embeds[0] - torch.mean(img_cond_embeds[1:], dim=0) + img_cond_embeds = img_cond_embeds.unsqueeze(0) + if face_cond_embeds is not None: + face_cond_embeds = face_cond_embeds[0] - torch.mean(face_cond_embeds[1:], dim=0) + face_cond_embeds = face_cond_embeds.unsqueeze(0) + elif combine_embeds == "average": + img_cond_embeds = torch.mean(img_cond_embeds, dim=0).unsqueeze(0) + if face_cond_embeds is not None: + face_cond_embeds = torch.mean(face_cond_embeds, dim=0).unsqueeze(0) + elif combine_embeds == "norm average": + img_cond_embeds = torch.mean(img_cond_embeds / torch.norm(img_cond_embeds, dim=0, keepdim=True), dim=0).unsqueeze(0) + if face_cond_embeds is not None: + face_cond_embeds = torch.mean(face_cond_embeds / torch.norm(face_cond_embeds, dim=0, keepdim=True), dim=0).unsqueeze(0) + img_uncond_embeds = img_uncond_embeds[0].unsqueeze(0) # TODO: better strategy for uncond could be to average them + + if attn_mask is not None: + attn_mask = attn_mask.to(device, dtype=dtype) + + ipa = IPAdapter( + ipadapter, + cross_attention_dim=cross_attention_dim, + output_cross_attention_dim=output_cross_attention_dim, + clip_embeddings_dim=img_cond_embeds.shape[-1], + clip_extra_context_tokens=clip_extra_context_tokens, + is_sdxl=is_sdxl, + is_plus=is_plus, + is_full=is_full, + is_faceid=is_faceid + ).to(device, dtype=dtype) + + if is_faceid and is_plus: + cond = ipa.get_image_embeds_faceid_plus(face_cond_embeds, img_cond_embeds, weight_faceidv2, is_faceidv2) + # TODO: check if noise helps with the uncod face embeds + uncod = ipa.get_image_embeds_faceid_plus(torch.zeros_like(face_cond_embeds), img_uncond_embeds, weight_faceidv2, is_faceidv2) + else: + cond, uncod = ipa.get_image_embeds(img_cond_embeds, img_uncond_embeds) + + cond = cond.to(device, dtype=dtype) + uncod = uncod.to(device, dtype=dtype) + + del img_cond_embeds, img_uncond_embeds + + sigma_start = model.model.model_sampling.percent_to_sigma(start_at) + sigma_end = model.model.model_sampling.percent_to_sigma(end_at) + + patch_kwargs = { + "ipadapter": ipa, + "number": 0, + "weight": weight, + "cond": cond, + "uncond": uncod, + "weight_type": weight_type, + "mask": attn_mask, + "sigma_start": sigma_start, + "sigma_end": sigma_end, + "unfold_batch": unfold_batch, + } + + if not is_sdxl: + for id in [1,2,4,5,7,8]: # id of input_blocks that have cross attention + set_model_patch_replace(model, patch_kwargs, ("input", id)) + patch_kwargs["number"] += 1 + for id in [3,4,5,6,7,8,9,10,11]: # id of output_blocks that have cross attention + set_model_patch_replace(model, patch_kwargs, ("output", id)) + patch_kwargs["number"] += 1 + set_model_patch_replace(model, patch_kwargs, ("middle", 0)) + else: + for id in [4,5,7,8]: # id of input_blocks that have cross attention + block_indices = range(2) if id in [4, 5] else range(10) # transformer_depth + for index in block_indices: + set_model_patch_replace(model, patch_kwargs, ("input", id, index)) + patch_kwargs["number"] += 1 + for id in range(6): # id of output_blocks that have cross attention + block_indices = range(2) if id in [3, 4, 5] else range(10) # transformer_depth + for index in block_indices: + set_model_patch_replace(model, patch_kwargs, ("output", id, index)) + patch_kwargs["number"] += 1 + for index in range(10): + set_model_patch_replace(model, patch_kwargs, ("middle", 0, index)) + patch_kwargs["number"] += 1 + + return model + + +""" +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Loaders +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +""" +class IPAdapterUnifiedLoader: + def __init__(self): + self.lora = None + self.clipvision = { "file": None, "model": None } + self.ipadapter = { "file": None, "model": None } + + @classmethod + def INPUT_TYPES(s): + return {"required": { + "model": ("MODEL", ), + "preset": (['LIGHT - SD1.5 only (low strength)', 'STANDARD (medium strength)', 'VIT-G (medium strength)', 'PLUS (high strength)', 'PLUS FACE (portraits)', 'FULL FACE - SD1.5 only (portraits stronger)'], ), + }, + "optional": { + "ipadapter": ("IPADAPTER", ), + }} + + RETURN_TYPES = ("MODEL", "IPADAPTER", ) + RETURN_NAMES = ("model", "ipadapter", ) + FUNCTION = "load_models" + CATEGORY = "ipadapter" + + def load_models(self, model, preset, lora_strength=0.0, provider="CPU", ipadapter=None): + pipeline = { "clipvision": { 'file': None, 'model': None }, "ipadapter": { 'file': None, 'model': None }, "insightface": { 'provider': None, 'model': None } } + if ipadapter is not None: + pipeline = ipadapter + + # 1. Load the clipvision model + clipvision_file = get_clipvision_file(preset) + if clipvision_file is None: + raise Exception("ClipVision model not found.") + + if clipvision_file != self.clipvision['file']: + if clipvision_file != pipeline['clipvision']['file']: + self.clipvision['file'] = clipvision_file + self.clipvision['model'] = load_clip_vision(clipvision_file) + print(f"\033[33mINFO: Clip Vision model loaded from {clipvision_file}\033[0m") + else: + self.clipvision = pipeline['clipvision'] + + # 2. Load the ipadapter model + is_sdxl = isinstance(model.model, comfy.model_base.SDXL) + ipadapter_file, is_insightface, lora_pattern = get_ipadapter_file(preset, is_sdxl) + if ipadapter_file is None: + raise Exception("IPAdapter model not found.") + + if ipadapter_file != self.ipadapter['file']: + if pipeline['ipadapter']['file'] != ipadapter_file: + self.ipadapter['file'] = ipadapter_file + self.ipadapter['model'] = ipadapter_model_loader(ipadapter_file) + print(f"\033[33mINFO: IPAdapter model loaded from {ipadapter_file}\033[0m") + else: + self.ipadapter = pipeline['ipadapter'] + + # 3. Load the lora model if needed + if lora_pattern is not None: + lora_file = get_lora_file(lora_pattern) + lora_model = None + if lora_file is None: + raise Exception("LoRA model not found.") + + if self.lora is not None: + if lora_file == self.lora['file']: + lora_model = self.lora['model'] else: - mask_downsample = F.interpolate(mask.unsqueeze(1), size=(mask_h, mask_w), mode="bicubic").squeeze(1) + self.lora = None + torch.cuda.empty_cache() - # if we don't have enough masks repeat the last one until we reach the right size - if mask_downsample.shape[0] < batch_prompt: - mask_downsample = torch.cat((mask_downsample, mask_downsample[-1:, :, :].repeat((batch_prompt-mask_downsample.shape[0], 1, 1))), dim=0) - # if we have too many remove the exceeding - elif mask_downsample.shape[0] > batch_prompt: - mask_downsample = mask_downsample[:batch_prompt, :, :] - - # repeat the masks - mask_downsample = mask_downsample.repeat(len(cond_or_uncond), 1, 1) - mask_downsample = mask_downsample.view(mask_downsample.shape[0], -1, 1).repeat(1, 1, out.shape[2]) + if lora_model is None: + lora_model = comfy.utils.load_torch_file(lora_file, safe_load=True) + print(f"\033[33mINFO: LoRA model loaded from {lora_file}\033[0m") - out_ip = out_ip * mask_downsample + if lora_strength > 0: + model, _ = load_lora_for_models(model, None, lora_model, lora_strength, 0) - out = out + out_ip + # 4. Load the insightface model if needed + if is_insightface: + if pipeline['insightface']['provider'] != provider: + pipeline['insightface']['provider'] = provider + pipeline['insightface']['model'] = insightface_loader(provider) + print(f"\033[33mINFO: InsightFace model loaded with {provider} provider\033[0m") - return out.to(dtype=org_dtype) + return (model, { 'clipvision': self.clipvision, 'ipadapter': self.ipadapter, 'insightface': pipeline['insightface'] }, ) + +class IPAdapterUnifiedLoaderFaceID(IPAdapterUnifiedLoader): + @classmethod + def INPUT_TYPES(s): + return {"required": { + "model": ("MODEL", ), + "preset": (['FACEID', 'FACEID PLUS - SD1.5 only', 'FACEID PLUS V2', 'FACEID PORTRAIT (style transfer)'], ), + "lora_strength": ("FLOAT", { "default": 0.6, "min": 0, "max": 1, "step": 0.01 }), + "provider": (["CPU", "CUDA", "ROCM", "DirectML", "OpenVINO", "CoreML"], ), + }, + "optional": { + "ipadapter": ("IPADAPTER", ), + }} + + RETURN_NAMES = ("MODEL", "ipadapter", ) class IPAdapterModelLoader: @classmethod @@ -588,26 +444,10 @@ class IPAdapterModelLoader: CATEGORY = "ipadapter" def load_ipadapter_model(self, ipadapter_file): - ckpt_path = folder_paths.get_full_path("ipadapter", ipadapter_file) + ipadapter_file = folder_paths.get_full_path("ipadapter", ipadapter_file) + return (ipadapter_model_loader(ipadapter_file),) - model = comfy.utils.load_torch_file(ckpt_path, safe_load=True) - - if ckpt_path.lower().endswith(".safetensors"): - st_model = {"image_proj": {}, "ip_adapter": {}} - for key in model.keys(): - if key.startswith("image_proj."): - st_model["image_proj"][key.replace("image_proj.", "")] = model[key] - elif key.startswith("ip_adapter."): - st_model["ip_adapter"][key.replace("ip_adapter.", "")] = model[key] - model = st_model - - if not "ip_adapter" in model.keys() or not model["ip_adapter"]: - raise Exception("invalid IPAdapter model {}".format(ckpt_path)) - - return (model,) - -insightface_face_align = None -class InsightFaceLoader: +class IPAdapterInsightFaceLoader: @classmethod def INPUT_TYPES(s): return { @@ -617,39 +457,28 @@ class InsightFaceLoader: } RETURN_TYPES = ("INSIGHTFACE",) - FUNCTION = "load_insight_face" + FUNCTION = "load_insightface" CATEGORY = "ipadapter" - def load_insight_face(self, provider): - try: - from insightface.app import FaceAnalysis - except ImportError as e: - raise Exception(e) - - from insightface.utils import face_align - global insightface_face_align - insightface_face_align = face_align + def load_insightface(self, provider): + return (insightface_loader(provider),) - model = FaceAnalysis(name="buffalo_l", root=INSIGHTFACE_DIR, providers=[provider + 'ExecutionProvider',]) - model.prepare(ctx_id=0, det_size=(640, 640)) - - return (model,) - -class IPAdapterApply: +""" +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Main Apply Nodes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +""" +class IPAdapterSimple: @classmethod def INPUT_TYPES(s): return { "required": { - "ipadapter": ("IPADAPTER", ), - "clip_vision": ("CLIP_VISION",), - "image": ("IMAGE",), "model": ("MODEL", ), + "ipadapter": ("IPADAPTER", ), + "image": ("IMAGE",), "weight": ("FLOAT", { "default": 1.0, "min": -1, "max": 3, "step": 0.05 }), - "noise": ("FLOAT", { "default": 0.0, "min": 0.0, "max": 1.0, "step": 0.01 }), - "weight_type": (["original", "linear", "channel penalty"], ), "start_at": ("FLOAT", { "default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001 }), "end_at": ("FLOAT", { "default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001 }), - "unfold_batch": ("BOOLEAN", { "default": False }), }, "optional": { "attn_mask": ("MASK",), @@ -660,320 +489,504 @@ class IPAdapterApply: FUNCTION = "apply_ipadapter" CATEGORY = "ipadapter" - def apply_ipadapter(self, - ipadapter, - model, - weight, - clip_vision=None, - image=None, - weight_type="original", - noise=None, - embeds=None, - attn_mask=None, - start_at=0.0, - end_at=1.0, - unfold_batch=False, - insightface=None, - faceid_v2=False, - weight_v2=False, - clip_vision_mask=None, - short_side_tiles=0, - tile_weight=0.0, - tile_blur=0, - ): - - self.dtype = torch.float16 if comfy.model_management.should_use_fp16() else torch.float32 - self.device = comfy.model_management.get_torch_device() - self.weight = weight - self.is_full = "proj.3.weight" in ipadapter["image_proj"] - self.is_portrait = "proj.2.weight" in ipadapter["image_proj"] and not "proj.3.weight" in ipadapter["image_proj"] and not "0.to_q_lora.down.weight" in ipadapter["ip_adapter"] - self.is_faceid = self.is_portrait or "0.to_q_lora.down.weight" in ipadapter["ip_adapter"] - self.is_plus = (self.is_full or "latents" in ipadapter["image_proj"] or "perceiver_resampler.proj_in.weight" in ipadapter["image_proj"]) - is_tiled = True if short_side_tiles > 0 else False + def apply_ipadapter(self, model, ipadapter, image, weight, start_at, end_at, attn_mask=None): + ipa_args = { + "image": image, + "weight": weight, + "start_at": start_at, + "end_at": end_at, + "attn_mask": attn_mask, + "insightface": ipadapter['insightface']['model'] if 'insightface' in ipadapter else None, + } - if is_tiled: - image, attn_mask = masked_tiling(image, short_side_tiles, tile_weight, tile_blur) + if 'ipadapter' not in ipadapter: + raise Exception("IPAdapter model not present in the pipeline. Please load the models with the IPAdapterUnifiedLoader node.") + if 'clipvision' not in ipadapter: + raise Exception("CLIPVision model not present in the pipeline. Please load the models with the IPAdapterUnifiedLoader node.") - if self.is_faceid and not insightface: - raise Exception('InsightFace must be provided for FaceID models.') + return (ipadapter_execute(model.clone(), ipadapter['ipadapter']['model'], ipadapter['clipvision']['model'], **ipa_args), ) - output_cross_attention_dim = ipadapter["ip_adapter"]["1.to_k_ip.weight"].shape[1] - self.is_sdxl = output_cross_attention_dim == 2048 - cross_attention_dim = 1280 if self.is_plus and self.is_sdxl and not self.is_faceid else output_cross_attention_dim - clip_extra_context_tokens = 16 if self.is_plus or self.is_portrait else 4 +class IPAdapterAdvanced: + def __init__(self): + self.unfold_batch = False - if embeds is not None: - embeds = torch.unbind(embeds) - clip_embed = embeds[0].cpu() - clip_embed_zeroed = embeds[1].cpu() - else: - if self.is_faceid: - insightface.det_model.input_size = (640,640) # reset the detection size - face_img = tensorToNP(image) - face_embed = [] - face_clipvision = [] - - for i in range(face_img.shape[0]): - for size in [(size, size) for size in range(640, 128, -64)]: - insightface.det_model.input_size = size # TODO: hacky but seems to be working - face = insightface.get(face_img[i]) - if face: - face_embed.append(torch.from_numpy(face[0].normed_embedding).unsqueeze(0)) - face_clipvision.append(NPToTensor(insightface_face_align.norm_crop(face_img[i], landmark=face[0].kps, image_size=256))) - - if 640 not in size: - print(f"\033[33mINFO: InsightFace detection resolution lowered to {size}.\033[0m") - break - else: - raise Exception('InsightFace: No face detected.') - - face_embed = torch.stack(face_embed, dim=0) - image = torch.stack(face_clipvision, dim=0) - - neg_image = image_add_noise(image, noise) if noise > 0 else None - - if self.is_plus: - clip_embed = clip_vision.encode_image(image).penultimate_hidden_states - if noise > 0: - clip_embed_zeroed = clip_vision.encode_image(neg_image).penultimate_hidden_states - else: - clip_embed_zeroed = zeroed_hidden_states(clip_vision, image.shape[0]) - - # TODO: check noise to the uncods too - face_embed_zeroed = torch.zeros_like(face_embed) - else: - clip_embed = face_embed - clip_embed_zeroed = torch.zeros_like(clip_embed) - else: - if image.shape[1] != image.shape[2]: - print("\033[33mINFO: the IPAdapter reference image is not a square, CLIPImageProcessor will resize and crop it at the center. If the main focus of the picture is not in the middle the result might not be what you are expecting.\033[0m") - - clip_embed = encode_image_masked(clip_vision, image, clip_vision_mask) - neg_image = image_add_noise(image, noise) if noise > 0 else None - - if self.is_plus: - clip_embed = clip_embed.penultimate_hidden_states - if noise > 0: - clip_embed_zeroed = clip_vision.encode_image(neg_image).penultimate_hidden_states - else: - clip_embed_zeroed = zeroed_hidden_states(clip_vision, image.shape[0]) - else: - clip_embed = clip_embed.image_embeds - if noise > 0: - clip_embed_zeroed = clip_vision.encode_image(neg_image).image_embeds - else: - clip_embed_zeroed = torch.zeros_like(clip_embed) - - clip_embeddings_dim = clip_embed.shape[-1] - - self.ipadapter = IPAdapter( - ipadapter, - cross_attention_dim=cross_attention_dim, - output_cross_attention_dim=output_cross_attention_dim, - clip_embeddings_dim=clip_embeddings_dim, - clip_extra_context_tokens=clip_extra_context_tokens, - is_sdxl=self.is_sdxl, - is_plus=self.is_plus, - is_full=self.is_full, - is_faceid=self.is_faceid, - ) - - self.ipadapter.to(self.device, dtype=self.dtype) - - if self.is_faceid and self.is_plus: - image_prompt_embeds = self.ipadapter.get_image_embeds_faceid_plus(face_embed.to(self.device, dtype=self.dtype), clip_embed.to(self.device, dtype=self.dtype), weight_v2, faceid_v2) - uncond_image_prompt_embeds = self.ipadapter.get_image_embeds_faceid_plus(face_embed_zeroed.to(self.device, dtype=self.dtype), clip_embed_zeroed.to(self.device, dtype=self.dtype), weight_v2, faceid_v2) - else: - image_prompt_embeds, uncond_image_prompt_embeds = self.ipadapter.get_image_embeds(clip_embed.to(self.device, dtype=self.dtype), clip_embed_zeroed.to(self.device, dtype=self.dtype)) - - image_prompt_embeds = image_prompt_embeds.to(self.device, dtype=self.dtype) - uncond_image_prompt_embeds = uncond_image_prompt_embeds.to(self.device, dtype=self.dtype) - - self.work_model = model.clone() - - if attn_mask is not None: - attn_mask = attn_mask.to(self.device) - - sigma_start = self.work_model.model.model_sampling.percent_to_sigma(start_at) - sigma_end = self.work_model.model.model_sampling.percent_to_sigma(end_at) - - if is_tiled: - for i in range(image_prompt_embeds.shape[0]): #TODO: check if we can apply one mask per image in the attention patch phase - patch_kwargs = { - "number": 0, - "weight": self.weight, - "ipadapter": self.ipadapter, - "cond": image_prompt_embeds[i].unsqueeze(0), - "uncond": uncond_image_prompt_embeds[i].unsqueeze(0), - "weight_type": weight_type, - "mask": attn_mask[i].unsqueeze(0), - "sigma_start": sigma_start, - "sigma_end": sigma_end, - "unfold_batch": unfold_batch, - } - self.apply_patch(patch_kwargs) - else: - patch_kwargs = { - "number": 0, - "weight": self.weight, - "ipadapter": self.ipadapter, - "cond": image_prompt_embeds, - "uncond": uncond_image_prompt_embeds, - "weight_type": weight_type, - "mask": attn_mask, - "sigma_start": sigma_start, - "sigma_end": sigma_end, - "unfold_batch": unfold_batch, - } - self.apply_patch(patch_kwargs) - - return (self.work_model, attn_mask, image,) - - def apply_patch(self, patch_kwargs): - if not self.is_sdxl: - for id in [1,2,4,5,7,8]: # id of input_blocks that have cross attention - set_model_patch_replace(self.work_model, patch_kwargs, ("input", id)) - patch_kwargs["number"] += 1 - for id in [3,4,5,6,7,8,9,10,11]: # id of output_blocks that have cross attention - set_model_patch_replace(self.work_model, patch_kwargs, ("output", id)) - patch_kwargs["number"] += 1 - set_model_patch_replace(self.work_model, patch_kwargs, ("middle", 0)) - else: - for id in [4,5,7,8]: # id of input_blocks that have cross attention - block_indices = range(2) if id in [4, 5] else range(10) # transformer_depth - for index in block_indices: - set_model_patch_replace(self.work_model, patch_kwargs, ("input", id, index)) - patch_kwargs["number"] += 1 - for id in range(6): # id of output_blocks that have cross attention - block_indices = range(2) if id in [3, 4, 5] else range(10) # transformer_depth - for index in block_indices: - set_model_patch_replace(self.work_model, patch_kwargs, ("output", id, index)) - patch_kwargs["number"] += 1 - for index in range(10): - set_model_patch_replace(self.work_model, patch_kwargs, ("middle", 0, index)) - patch_kwargs["number"] += 1 - -class IPAdapterTilesMasked(IPAdapterApply): @classmethod def INPUT_TYPES(s): return { "required": { - "ipadapter": ("IPADAPTER", ), - "clip_vision": ("CLIP_VISION",), - "image": ("IMAGE",), "model": ("MODEL", ), - "weight": ("FLOAT", { "default": 0.7, "min": -1, "max": 3, "step": 0.05 }), - "noise": ("FLOAT", { "default": 0.0, "min": 0.0, "max": 1.0, "step": 0.01 }), - "weight_type": (["original", "linear", "channel penalty"], ), + "ipadapter": ("IPADAPTER", ), + "image": ("IMAGE",), + "weight": ("FLOAT", { "default": 1.0, "min": -1, "max": 3, "step": 0.05 }), + "weight_type": (WEIGHT_TYPES, ), + "combine_embeds": (["concat", "add", "subtract", "average", "norm average"],), "start_at": ("FLOAT", { "default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001 }), "end_at": ("FLOAT", { "default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001 }), - "short_side_tiles": ("INT", { "default": 1, "min": 0, "max": 12, "step": 1 }), - "tile_weight": ("FLOAT", { "default": 0.6, "min": 0.0, "max": 1.0, "step": 0.05 }), - #"tile_blur": ("INT", { "default": 0, "min": 0, "max": 112, "step": 1 }), }, + "optional": { + "image_negative": ("IMAGE",), + "attn_mask": ("MASK",), + "clip_vision": ("CLIP_VISION",), + } } RETURN_TYPES = ("MODEL",) - -class IPAdapterApplyFaceID(IPAdapterApply): + FUNCTION = "apply_ipadapter" + CATEGORY = "ipadapter" + + def apply_ipadapter(self, model, ipadapter, image, weight, weight_type, start_at, end_at, combine_embeds="concat", weight_faceidv2=None, image_negative=None, clip_vision=None, attn_mask=None, insightface=None): + ipa_args = { + "image": image, + "image_negative": image_negative, + "weight": weight, + "weight_faceidv2": weight_faceidv2, + "weight_type": weight_type, + "combine_embeds": combine_embeds, + "start_at": start_at, + "end_at": end_at, + "attn_mask": attn_mask, + "unfold_batch": self.unfold_batch, + "insightface": insightface if insightface is not None else ipadapter['insightface']['model'] if 'insightface' in ipadapter else None + } + + if 'ipadapter' in ipadapter: + ipadapter_model = ipadapter['ipadapter']['model'] + clip_vision = clip_vision if clip_vision is not None else ipadapter['clipvision']['model'] + else: + ipadapter_model = ipadapter + clip_vision = clip_vision + + if clip_vision is None: + raise Exception("Missing CLIPVision model.") + + del ipadapter + + return (ipadapter_execute(model.clone(), ipadapter_model, clip_vision, **ipa_args), ) + +class IPAdapterBatch(IPAdapterAdvanced): + def __init__(self): + self.unfold_batch = True + @classmethod def INPUT_TYPES(s): return { "required": { - "ipadapter": ("IPADAPTER", ), - "clip_vision": ("CLIP_VISION",), - "insightface": ("INSIGHTFACE",), - "image": ("IMAGE",), "model": ("MODEL", ), + "ipadapter": ("IPADAPTER", ), + "image": ("IMAGE",), "weight": ("FLOAT", { "default": 1.0, "min": -1, "max": 3, "step": 0.05 }), - "noise": ("FLOAT", { "default": 0.0, "min": 0.0, "max": 1.0, "step": 0.01 }), - "weight_type": (["original", "linear", "channel penalty"], ), + "weight_type": (WEIGHT_TYPES, ), "start_at": ("FLOAT", { "default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001 }), "end_at": ("FLOAT", { "default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001 }), - "faceid_v2": ("BOOLEAN", { "default": False }), - "weight_v2": ("FLOAT", { "default": 1.0, "min": -1, "max": 3, "step": 0.05 }), - "unfold_batch": ("BOOLEAN", { "default": False }), }, "optional": { + "image_negative": ("IMAGE",), "attn_mask": ("MASK",), + "clip_vision": ("CLIP_VISION",), } } -def prepImage(image, interpolation="LANCZOS", crop_position="center", size=(224,224), sharpening=0.0, padding=0): - _, oh, ow, _ = image.shape - output = image.permute([0,3,1,2]) +class IPAdapterFaceID(IPAdapterAdvanced): + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "model": ("MODEL", ), + "ipadapter": ("IPADAPTER", ), + "image": ("IMAGE",), + "weight": ("FLOAT", { "default": 1.0, "min": -1, "max": 3, "step": 0.05 }), + "weight_faceidv2": ("FLOAT", { "default": 1.0, "min": -1, "max": 5.0, "step": 0.05 }), + "weight_type": (WEIGHT_TYPES, ), + "combine_embeds": (["concat", "add", "subtract", "average", "norm average"],), + "start_at": ("FLOAT", { "default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001 }), + "end_at": ("FLOAT", { "default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001 }), + }, + "optional": { + "image_negative": ("IMAGE",), + "attn_mask": ("MASK",), + "clip_vision": ("CLIP_VISION",), + "insightface": ("INSIGHTFACE",), + } + } - if "pad" in crop_position: - target_length = max(oh, ow) - pad_l = (target_length - ow) // 2 - pad_r = (target_length - ow) - pad_l - pad_t = (target_length - oh) // 2 - pad_b = (target_length - oh) - pad_t - output = F.pad(output, (pad_l, pad_r, pad_t, pad_b), value=0, mode="constant") - else: - crop_size = min(oh, ow) - x = (ow-crop_size) // 2 - y = (oh-crop_size) // 2 - if "top" in crop_position: - y = 0 - elif "bottom" in crop_position: - y = oh-crop_size - elif "left" in crop_position: - x = 0 - elif "right" in crop_position: - x = ow-crop_size - - x2 = x+crop_size - y2 = y+crop_size +class IPAAdapterFaceIDBatch(IPAdapterFaceID): + def __init__(self): + self.unfold_batch = True - # crop - output = output[:, :, y:y2, x:x2] +class IPAdapterTiled: + def __init__(self): + self.unfold_batch = False - # resize (apparently PIL resize is better than tourchvision interpolate) - imgs = [] - for i in range(output.shape[0]): - img = TT.ToPILImage()(output[i]) - img = img.resize(size, resample=Image.Resampling[interpolation]) - imgs.append(TT.ToTensor()(img)) - output = torch.stack(imgs, dim=0) - imgs = None # zelous GC - - if sharpening > 0: - output = contrast_adaptive_sharpening(output, sharpening) - - if padding > 0: - output = F.pad(output, (padding, padding, padding, padding), value=255, mode="constant") + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "model": ("MODEL", ), + "ipadapter": ("IPADAPTER", ), + "image": ("IMAGE",), + "weight": ("FLOAT", { "default": 1.0, "min": -1, "max": 3, "step": 0.05 }), + "weight_type": (WEIGHT_TYPES, ), + "combine_embeds": (["concat", "add", "subtract", "average", "norm average"],), + "start_at": ("FLOAT", { "default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001 }), + "end_at": ("FLOAT", { "default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001 }), + "sharpening": ("FLOAT", { "default": 0.0, "min": 0.0, "max": 1.0, "step": 0.05 }), + }, + "optional": { + "image_negative": ("IMAGE",), + "attn_mask": ("MASK",), + "clip_vision": ("CLIP_VISION",), + } + } - output = output.permute([0,2,3,1]) + RETURN_TYPES = ("MODEL", "IMAGE", "MASK", ) + RETURN_NAMES = ("MODEL", "tiles", "masks", ) + FUNCTION = "apply_tiled" + CATEGORY = "ipadapter" - return output + def apply_tiled(self, model, ipadapter, image, weight, weight_type, start_at, end_at, sharpening, combine_embeds="concat", image_negative=None, attn_mask=None, clip_vision=None): + # 1. Select the models + if 'ipadapter' in ipadapter: + ipadapter_model = ipadapter['ipadapter']['model'] + clip_vision = clip_vision if clip_vision is not None else ipadapter['clipvision']['model'] + else: + ipadapter_model = ipadapter + clip_vision = clip_vision -class PrepImageForInsightFace: + if clip_vision is None: + raise Exception("Missing CLIPVision model.") + + del ipadapter + + # 2. Extract the tiles + tile_size = 256 # I'm using 256 instead of 224 as it is more likely divisible by the latent size, it will be downscaled to 224 by the clip vision encoder + _, oh, ow, _ = image.shape + image = image.permute([0,3,1,2]) + if attn_mask is not None: + attn_mask = attn_mask.unsqueeze(1) + # the mask should have the same proportions as the reference image and the latent + attn_mask = T.Resize((oh, ow), interpolation=T.InterpolationMode.BICUBIC, antialias=True)(attn_mask) + + # if the image is almost a square, we crop it to a square + if oh / ow > 0.75 and oh / ow < 1.33: + # crop the image to a square + image = T.CenterCrop(min(oh, ow))(image) + resize = (tile_size*2, tile_size*2) + + if attn_mask is not None: + attn_mask = T.CenterCrop(min(oh, ow))(attn_mask) + # otherwise resize the smallest side to 224 and the other proportionally + else: + resize = (int(tile_size * ow / oh), tile_size) if oh < ow else (tile_size, int(tile_size * oh / ow)) + + imgs = [] + for img in image: + img = T.ToPILImage()(img) # using PIL for better results + img = img.resize(resize, resample=Image.Resampling['LANCZOS']) + imgs.append(T.ToTensor()(img)) + image = torch.stack(imgs) + del imgs, img + + if attn_mask is not None: + attn_mask = T.Resize(resize[::-1], interpolation=T.InterpolationMode.BICUBIC, antialias=True)(attn_mask) # we don't need a high quality resize for the mask + + # we allow a maximum of 4 tiles + if oh / ow > 4 or oh / ow < 0.25: + crop = (tile_size, tile_size*4) if oh < ow else (tile_size*4, tile_size) + image = T.CenterCrop(crop)(image) + if attn_mask is not None: + attn_mask = T.CenterCrop(crop)(attn_mask) + + if attn_mask is not None: + attn_mask = attn_mask.squeeze(1) + + if sharpening > 0: + image = contrast_adaptive_sharpening(image, sharpening) + + image = image.permute([0,2,3,1]) + + _, oh, ow, _ = image.shape + + # find the number of tiles for each side + tiles_x = math.ceil(ow / tile_size) + tiles_y = math.ceil(oh / tile_size) + overlap_x = max(0, (tiles_x * tile_size - ow) / (tiles_x - 1 if tiles_x > 1 else 1)) + overlap_y = max(0, (tiles_y * tile_size - oh) / (tiles_y - 1 if tiles_y > 1 else 1)) + + base_mask = None + if attn_mask is None: + base_mask = torch.zeros([1, oh, ow], dtype=image.dtype, device=image.device) + + # extract all the tiles from the image and create the masks + tiles = [] + masks = [] + for y in range(tiles_y): + for x in range(tiles_x): + start_x = int(x * (tile_size - overlap_x)) + start_y = int(y * (tile_size - overlap_y)) + tiles.append(image[:, start_y:start_y+tile_size, start_x:start_x+tile_size, :]) + if attn_mask is not None: + mask = attn_mask[:, start_y:start_y+tile_size, start_x:start_x+tile_size] + else: + mask = base_mask.clone() + mask[:, start_y:start_y+tile_size, start_x:start_x+tile_size] = 1 + masks.append(mask) + del mask + + # 3. Apply the ipadapter to each group of tiles + model = model.clone() + for i in range(len(tiles)): + ipa_args = { + "image": tiles[i], + "image_negative": image_negative, + "weight": weight, + "weight_type": weight_type, + "combine_embeds": combine_embeds, + "start_at": start_at, + "end_at": end_at, + "attn_mask": masks[i], + "unfold_batch": self.unfold_batch, + } + # apply the ipadapter to the model without cloning it + model = ipadapter_execute(model, ipadapter_model, clip_vision, **ipa_args) + + return (model, torch.cat(tiles), torch.cat(masks), ) + +class IPAdapterTiledBatch(IPAdapterTiled): + def __init__(self): + self.unfold_batch = True + + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "model": ("MODEL", ), + "ipadapter": ("IPADAPTER", ), + "image": ("IMAGE",), + "weight": ("FLOAT", { "default": 1.0, "min": -1, "max": 3, "step": 0.05 }), + "weight_type": (WEIGHT_TYPES, ), + "start_at": ("FLOAT", { "default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001 }), + "end_at": ("FLOAT", { "default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001 }), + "sharpening": ("FLOAT", { "default": 0.0, "min": 0.0, "max": 1.0, "step": 0.05 }), + }, + "optional": { + "image_negative": ("IMAGE",), + "attn_mask": ("MASK",), + "clip_vision": ("CLIP_VISION",), + } + } + +class IPAdapterEmbeds: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "model": ("MODEL", ), + "ipadapter": ("IPADAPTER", ), + "pos_embed": ("EMBEDS",), + "weight": ("FLOAT", { "default": 1.0, "min": -1, "max": 3, "step": 0.05 }), + "weight_type": (WEIGHT_TYPES, ), + "start_at": ("FLOAT", { "default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001 }), + "end_at": ("FLOAT", { "default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001 }), + }, + "optional": { + "neg_embed": ("EMBEDS",), + "attn_mask": ("MASK",), + "clip_vision": ("CLIP_VISION",), + } + } + + RETURN_TYPES = ("MODEL",) + FUNCTION = "apply_ipadapter" + CATEGORY = "ipadapter" + + def apply_ipadapter(self, model, ipadapter, pos_embed, weight, weight_type, start_at, end_at, neg_embed=None, attn_mask=None, clip_vision=None): + ipa_args = { + "pos_embed": pos_embed, + "neg_embed": neg_embed, + "weight": weight, + "weight_type": weight_type, + "start_at": start_at, + "end_at": end_at, + "attn_mask": attn_mask, + } + + if 'ipadapter' in ipadapter: + ipadapter_model = ipadapter['ipadapter']['model'] + clip_vision = clip_vision if clip_vision is not None else ipadapter['clipvision']['model'] + else: + ipadapter_model = ipadapter + clip_vision = clip_vision + + if clip_vision is None and neg_embed is None: + raise Exception("Missing CLIPVision model.") + + del ipadapter + + return (ipadapter_execute(model.clone(), ipadapter_model, clip_vision, **ipa_args), ) + +""" +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Helpers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +""" +class IPAdapterEncoder: @classmethod def INPUT_TYPES(s): return {"required": { + "ipadapter": ("IPADAPTER",), "image": ("IMAGE",), - "crop_position": (["center", "top", "bottom", "left", "right"],), - "sharpening": ("FLOAT", {"default": 0.0, "min": 0, "max": 1, "step": 0.05}), - "pad_around": ("BOOLEAN", { "default": True }), + "weight": ("FLOAT", { "default": 1.0, "min": -1.0, "max": 3.0, "step": 0.01 }), }, + "optional": { + "mask": ("MASK",), + "clip_vision": ("CLIP_VISION",), + } + } + + RETURN_TYPES = ("EMBEDS", "EMBEDS",) + RETURN_NAMES = ("pos_embed", "neg_embed",) + FUNCTION = "encode" + CATEGORY = "ipadapter" + + def encode(self, ipadapter, image, weight, mask=None, clip_vision=None): + if 'ipadapter' in ipadapter: + ipadapter_model = ipadapter['ipadapter']['model'] + clip_vision = clip_vision if clip_vision is not None else ipadapter['clipvision']['model'] + else: + ipadapter_model = ipadapter + clip_vision = clip_vision + + if clip_vision is None: + raise Exception("Missing CLIPVision model.") + + is_plus = "proj.3.weight" in ipadapter_model["image_proj"] or "latents" in ipadapter_model["image_proj"] or "perceiver_resampler.proj_in.weight" in ipadapter_model["image_proj"] + + # resize and crop the mask to 224x224 + if mask is not None and mask.shape[1:3] != torch.Size([224, 224]): + mask = mask.unsqueeze(1) + transforms = T.Compose([ + T.CenterCrop(min(mask.shape[2], mask.shape[3])), + T.Resize((224, 224), interpolation=T.InterpolationMode.BICUBIC, antialias=True), + ]) + mask = transforms(mask).squeeze(1) + #mask = T.Resize((image.shape[1], image.shape[2]), interpolation=T.InterpolationMode.BICUBIC, antialias=True)(mask.unsqueeze(1)).squeeze(1) + + img_cond_embeds = encode_image_masked(clip_vision, image, mask) + + if is_plus: + img_cond_embeds = img_cond_embeds.penultimate_hidden_states + img_uncond_embeds = encode_image_masked(clip_vision, torch.zeros([1, 224, 224, 3])).penultimate_hidden_states + else: + img_cond_embeds = img_cond_embeds.image_embeds + img_uncond_embeds = torch.zeros_like(img_cond_embeds) + + if weight != 1: + img_cond_embeds = img_cond_embeds * weight + + return (img_cond_embeds, img_uncond_embeds, ) + +class IPAdapterCombineEmbeds: + @classmethod + def INPUT_TYPES(s): + return {"required": { + "embed1": ("EMBEDS",), + "method": (["concat", "add", "subtract", "average", "norm average", "max", "min"], ), + }, + "optional": { + "embed2": ("EMBEDS",), + "embed3": ("EMBEDS",), + "embed4": ("EMBEDS",), + "embed5": ("EMBEDS",), + }} + + RETURN_TYPES = ("EMBEDS",) + FUNCTION = "batch" + CATEGORY = "ipadapter" + + def batch(self, embed1, method, embed2=None, embed3=None, embed4=None, embed5=None): + if method=='concat' and embed2 is None and embed3 is None and embed4 is None and embed5 is None: + return (embed1, ) + + embeds = [embed1, embed2, embed3, embed4, embed5] + embeds = [embed for embed in embeds if embed is not None] + embeds = torch.cat(embeds, dim=0) + + if method == "add": + embeds = torch.sum(embeds, dim=0).unsqueeze(0) + elif method == "subtract": + embeds = embeds[0] - torch.mean(embeds[1:], dim=0) + embeds = embeds.unsqueeze(0) + elif method == "average": + embeds = torch.mean(embeds, dim=0).unsqueeze(0) + elif method == "norm average": + embeds = torch.mean(embeds / torch.norm(embeds, dim=0, keepdim=True), dim=0).unsqueeze(0) + elif method == "max": + embeds = torch.max(embeds, dim=0).values.unsqueeze(0) + elif method == "min": + embeds = torch.min(embeds, dim=0).values.unsqueeze(0) + + return (embeds, ) + +class IPAdapterNoise: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "type": (["fade", "dissolve", "gaussian", "shuffle"], ), + "strength": ("FLOAT", { "default": 1.0, "min": 0, "max": 1, "step": 0.05 }), + "blur": ("INT", { "default": 0, "min": 0, "max": 32, "step": 1 }), + }, + "optional": { + "image_optional": ("IMAGE",), + } } RETURN_TYPES = ("IMAGE",) - FUNCTION = "prep_image" - + FUNCTION = "make_noise" CATEGORY = "ipadapter" - def prep_image(self, image, crop_position, sharpening=0.0, pad_around=True): - if pad_around: - padding = 30 - size = (580, 580) + def make_noise(self, type, strength, blur, image_optional=None): + if image_optional is None: + image = torch.zeros([1, 224, 224, 3]) else: - padding = 0 - size = (640, 640) - output = prepImage(image, "LANCZOS", crop_position, size, sharpening, padding) + transforms = T.Compose([ + T.CenterCrop(min(image_optional.shape[1], image_optional.shape[2])), + T.Resize((224, 224), interpolation=T.InterpolationMode.BICUBIC, antialias=True), + ]) + image = transforms(image_optional.permute([0,3,1,2])).permute([0,2,3,1]) - return (output, ) + seed = int(torch.sum(image).item()) % 1000000007 # hash the image to get a seed, grants predictability + torch.manual_seed(seed) + + if type == "fade": + noise = torch.rand_like(image) + noise = image * (1 - strength) + noise * strength + elif type == "dissolve": + mask = (torch.rand_like(image) < strength).float() + noise = torch.rand_like(image) + noise = image * (1-mask) + noise * mask + elif type == "gaussian": + noise = torch.randn_like(image) * strength + noise = image + noise + elif type == "shuffle": + transforms = T.Compose([ + T.ElasticTransform(alpha=75.0, sigma=(1-strength)*3.5), + T.RandomVerticalFlip(p=1.0), + T.RandomHorizontalFlip(p=1.0), + ]) + image = transforms(image.permute([0,3,1,2])).permute([0,2,3,1]) + noise = torch.randn_like(image) * (strength*0.75) + noise = image * (1-noise) + noise + + del image + noise = torch.clamp(noise, 0, 1) + + if blur > 0: + if blur % 2 == 0: + blur += 1 + noise = T.functional.gaussian_blur(noise.permute([0,3,1,2]), blur).permute([0,2,3,1]) + + return (noise, ) class PrepImageForClipVision: @classmethod @@ -993,100 +1006,49 @@ class PrepImageForClipVision: def prep_image(self, image, interpolation="LANCZOS", crop_position="center", sharpening=0.0): size = (224, 224) - output = prepImage(image, interpolation, crop_position, size, sharpening, 0) - return (output, ) + _, oh, ow, _ = image.shape + output = image.permute([0,3,1,2]) -class IPAdapterEncoder: - @classmethod - def INPUT_TYPES(s): - return {"required": { - "clip_vision": ("CLIP_VISION",), - "image_1": ("IMAGE",), - "ipadapter_plus": ("BOOLEAN", { "default": False }), - "noise": ("FLOAT", { "default": 0.0, "min": 0.0, "max": 1.0, "step": 0.01 }), - "weight_1": ("FLOAT", { "default": 1.0, "min": 0, "max": 1.0, "step": 0.01 }), - }, - "optional": { - "image_2": ("IMAGE",), - "image_3": ("IMAGE",), - "image_4": ("IMAGE",), - "weight_2": ("FLOAT", { "default": 1.0, "min": 0, "max": 1.0, "step": 0.01 }), - "weight_3": ("FLOAT", { "default": 1.0, "min": 0, "max": 1.0, "step": 0.01 }), - "weight_4": ("FLOAT", { "default": 1.0, "min": 0, "max": 1.0, "step": 0.01 }), - } - } - - RETURN_TYPES = ("EMBEDS",) - FUNCTION = "preprocess" - CATEGORY = "ipadapter" - - def preprocess(self, clip_vision, image_1, ipadapter_plus, noise, weight_1, image_2=None, image_3=None, image_4=None, weight_2=1.0, weight_3=1.0, weight_4=1.0): - weight_1 *= (0.1 + (weight_1 - 0.1)) - weight_2 *= (0.1 + (weight_2 - 0.1)) - weight_3 *= (0.1 + (weight_3 - 0.1)) - weight_4 *= (0.1 + (weight_4 - 0.1)) - - image = image_1 - weight = [weight_1]*image_1.shape[0] - - if image_2 is not None: - if image_1.shape[1:] != image_2.shape[1:]: - image_2 = comfy.utils.common_upscale(image_2.movedim(-1,1), image.shape[2], image.shape[1], "bilinear", "center").movedim(1,-1) - image = torch.cat((image, image_2), dim=0) - weight += [weight_2]*image_2.shape[0] - if image_3 is not None: - if image.shape[1:] != image_3.shape[1:]: - image_3 = comfy.utils.common_upscale(image_3.movedim(-1,1), image.shape[2], image.shape[1], "bilinear", "center").movedim(1,-1) - image = torch.cat((image, image_3), dim=0) - weight += [weight_3]*image_3.shape[0] - if image_4 is not None: - if image.shape[1:] != image_4.shape[1:]: - image_4 = comfy.utils.common_upscale(image_4.movedim(-1,1), image.shape[2], image.shape[1], "bilinear", "center").movedim(1,-1) - image = torch.cat((image, image_4), dim=0) - weight += [weight_4]*image_4.shape[0] - - clip_embed = clip_vision.encode_image(image) - neg_image = image_add_noise(image, noise) if noise > 0 else None - - if ipadapter_plus: - clip_embed = clip_embed.penultimate_hidden_states - if noise > 0: - clip_embed_zeroed = clip_vision.encode_image(neg_image).penultimate_hidden_states - else: - clip_embed_zeroed = zeroed_hidden_states(clip_vision, image.shape[0]) + if crop_position == "pad": + if oh > ow: + pad = (oh - ow) // 2 + pad = (pad, 0, pad, 0) + elif ow > oh: + pad = (ow - oh) // 2 + pad = (0, pad, 0, pad) + output = T.functional.pad(output, pad, fill=0) else: - clip_embed = clip_embed.image_embeds - if noise > 0: - clip_embed_zeroed = clip_vision.encode_image(neg_image).image_embeds - else: - clip_embed_zeroed = torch.zeros_like(clip_embed) + crop_size = min(oh, ow) + x = (ow-crop_size) // 2 + y = (oh-crop_size) // 2 + if "top" in crop_position: + y = 0 + elif "bottom" in crop_position: + y = oh-crop_size + elif "left" in crop_position: + x = 0 + elif "right" in crop_position: + x = ow-crop_size - if any(e != 1.0 for e in weight): - weight = torch.tensor(weight).unsqueeze(-1) if not ipadapter_plus else torch.tensor(weight).unsqueeze(-1).unsqueeze(-1) - clip_embed = clip_embed * weight - - output = torch.stack((clip_embed, clip_embed_zeroed)) + x2 = x+crop_size + y2 = y+crop_size - return( output, ) + output = output[:, :, y:y2, x:x2] -class IPAdapterApplyEncoded(IPAdapterApply): - @classmethod - def INPUT_TYPES(s): - return { - "required": { - "ipadapter": ("IPADAPTER", ), - "embeds": ("EMBEDS",), - "model": ("MODEL", ), - "weight": ("FLOAT", { "default": 1.0, "min": -1, "max": 3, "step": 0.05 }), - "weight_type": (["original", "linear", "channel penalty"], ), - "start_at": ("FLOAT", { "default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001 }), - "end_at": ("FLOAT", { "default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001 }), - "unfold_batch": ("BOOLEAN", { "default": False }), - }, - "optional": { - "attn_mask": ("MASK",), - } - } + imgs = [] + for img in output: + img = T.ToPILImage()(img) # using PIL for better results + img = img.resize(size, resample=Image.Resampling[interpolation]) + imgs.append(T.ToTensor()(img)) + output = torch.stack(imgs, dim=0) + del imgs, img + + if sharpening > 0: + output = contrast_adaptive_sharpening(output, sharpening) + + output = output.permute([0,2,3,1]) + + return (output, ) class IPAdapterSaveEmbeds: def __init__(self): @@ -1096,7 +1058,7 @@ class IPAdapterSaveEmbeds: def INPUT_TYPES(s): return {"required": { "embeds": ("EMBEDS",), - "filename_prefix": ("STRING", {"default": "embeds/IPAdapter"}) + "filename_prefix": ("STRING", {"default": "IP_embeds"}) }, } @@ -1107,13 +1069,12 @@ class IPAdapterSaveEmbeds: def save(self, embeds, filename_prefix): full_output_folder, filename, counter, subfolder, filename_prefix = folder_paths.get_save_image_path(filename_prefix, self.output_dir) - file = f"{filename}_{counter:05}_.ipadpt" + file = f"{filename}_{counter:05}.ipadpt" file = os.path.join(full_output_folder, file) torch.save(embeds, file) return (None, ) - class IPAdapterLoadEmbeds: @classmethod def INPUT_TYPES(s): @@ -1127,52 +1088,61 @@ class IPAdapterLoadEmbeds: def load(self, embeds): path = folder_paths.get_annotated_filepath(embeds) - output = torch.load(path).cpu() - - return (output, ) - - -class IPAdapterBatchEmbeds: - @classmethod - def INPUT_TYPES(s): - return {"required": { - "embed1": ("EMBEDS",), - "embed2": ("EMBEDS",), - }} - - RETURN_TYPES = ("EMBEDS",) - FUNCTION = "batch" - CATEGORY = "ipadapter" - - def batch(self, embed1, embed2): - return (torch.cat((embed1, embed2), dim=1), ) + return (torch.load(path).cpu(), ) +""" +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Register +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +""" NODE_CLASS_MAPPINGS = { + # Main Apply Nodes + "IPAdapter": IPAdapterSimple, + "IPAdapterAdvanced": IPAdapterAdvanced, + "IPAdapterBatch": IPAdapterBatch, + "IPAdapterFaceID": IPAdapterFaceID, + "IPAAdapterFaceIDBatch": IPAAdapterFaceIDBatch, + "IPAdapterTiled": IPAdapterTiled, + "IPAdapterTiledBatch": IPAdapterTiledBatch, + "IPAdapterEmbeds": IPAdapterEmbeds, + + # Loaders + "IPAdapterUnifiedLoader": IPAdapterUnifiedLoader, + "IPAdapterUnifiedLoaderFaceID": IPAdapterUnifiedLoaderFaceID, "IPAdapterModelLoader": IPAdapterModelLoader, - "IPAdapterApply": IPAdapterApply, - "IPAdapterTilesMasked": IPAdapterTilesMasked, - "IPAdapterApplyFaceID": IPAdapterApplyFaceID, - "IPAdapterApplyEncoded": IPAdapterApplyEncoded, - "PrepImageForClipVision": PrepImageForClipVision, + "IPAdapterInsightFaceLoader": IPAdapterInsightFaceLoader, + + # Helpers "IPAdapterEncoder": IPAdapterEncoder, + "IPAdapterCombineEmbeds": IPAdapterCombineEmbeds, + "IPAdapterNoise": IPAdapterNoise, + "PrepImageForClipVision": PrepImageForClipVision, "IPAdapterSaveEmbeds": IPAdapterSaveEmbeds, "IPAdapterLoadEmbeds": IPAdapterLoadEmbeds, - "IPAdapterBatchEmbeds": IPAdapterBatchEmbeds, - "InsightFaceLoader": InsightFaceLoader, - "PrepImageForInsightFace": PrepImageForInsightFace, } NODE_DISPLAY_NAME_MAPPINGS = { - "IPAdapterModelLoader": "Load IPAdapter Model", - "IPAdapterApply": "Apply IPAdapter", - "IPAdapterTilesMasked": "IPAdapter Masked Tiles (experimental)", - "IPAdapterApplyFaceID": "Apply IPAdapter FaceID", - "IPAdapterApplyEncoded": "Apply IPAdapter from Encoded", - "PrepImageForClipVision": "Prepare Image For Clip Vision", - "IPAdapterEncoder": "Encode IPAdapter Image", - "IPAdapterSaveEmbeds": "Save IPAdapter Embeds", - "IPAdapterLoadEmbeds": "Load IPAdapter Embeds", - "IPAdapterBatchEmbeds": "IPAdapter Batch Embeds", - "InsightFaceLoader": "Load InsightFace", - "PrepImageForInsightFace": "Prepare Image For InsightFace", -} + # Main Apply Nodes + "IPAdapter": "IPAdapter", + "IPAdapterAdvanced": "IPAdapter Advanced", + "IPAdapterBatch": "IPAdapter Batch (Adv.)", + "IPAdapterFaceID": "IPAdapter FaceID", + "IPAAdapterFaceIDBatch": "IPAdapter FaceID Batch", + "IPAdapterTiled": "IPAdapter Tiled", + "IPAdapterTiledBatch": "IPAdapter Tiled Batch", + "IPAdapterEmbeds": "IPAdapter Embeds", + + # Loaders + "IPAdapterUnifiedLoader": "IPAdapter Unified Loader", + "IPAdapterUnifiedLoaderFaceID": "IPAdapter Unified Loader FaceID", + "IPAdapterModelLoader": "IPAdapter Model Loader", + "IPAdapterInsightFaceLoader": "IPAdapter InsightFace Loader", + + # Helpers + "IPAdapterEncoder": "IPAdapter Encoder", + "IPAdapterCombineEmbeds": "IPAdapter Combine Embeds", + "IPAdapterNoise": "IPAdapter Noise", + "PrepImageForClipVision": "Prep Image For ClipVision", + "IPAdapterSaveEmbeds": "IPAdapter Save Embeds", + "IPAdapterLoadEmbeds": "IPAdapter Load Embeds", +} \ No newline at end of file diff --git a/README.md b/README.md index ede71eb..c8261ee 100644 --- a/README.md +++ b/README.md @@ -3,38 +3,50 @@ IPAdapter implementation that follows the ComfyUI way of doing things. The code is memory efficient, fast, and shouldn't break with Comfy updates. +# Open source for you but not free for me... + +I started working on IPAdapter because I needed it for my work. As the project evolved I'm inevitably receiving feature requests, bug reports and support requests. + +I'm an open source advocate and I'm happy to share all my code for free but maintaining the IPAdapter, the [Essentials](https://github.com/cubiq/ComfyUI_essentials), [InstantID](https://github.com/cubiq/ComfyUI_InstantID) and [Face Analysis](https://github.com/cubiq/ComfyUI_FaceAnalysis) takes time. + +**I'm not expecting donations but if you are making a profit from my projects it is only fair that you give something back.** I'm talking especially to companies here, I know the struggles of being a freelancer. + +Please contact me if you are interested in a sponsorship at _matt3o@gmail_ or consider a contribution via [PayPal](paypal.me/matt3o) (Matteo "matt3o" Spinelli, Firenze, IT). That will help mainining the code, adding new features and working on better documentation. + +And in that regard I really need to thank [Nathan Shipley](https://www.nathanshipley.com/) for his generous donation. Go check his website, he's terribly talented. + +## :warning: IPAdapter V2: complete Code rewrite warning + +A code cleanup was long overdue and with the occasion I also added a few new important features. The code should be faster and should take less resources but with such an important code rewrite it's inevitable to have introduced some new bugs. + +**At the moment I'm releasing this completely undocumented!** I will post better documentation and video tutorials in the coming days. In the meantime you can check the `example` directory for most of the old and new features. + ## Important updates +**2024/03/23**: Complete code rewrite!. **This is a breaking update!** Your previous workflows won't work and you'll need to recreate them. You've been warned! After the update, refresh your browser, delete the old IPAdapter nodes and create the new ones. + **2024/02/02**: Added experimental [tiled IPAdapter](#tiled-ipadapter). It lets you easily handle reference images that are not square. Can be useful for upscaling. **2024/01/19**: Support for FaceID Portrait models. **2024/01/16**: Notably increased quality of FaceID Plus/v2 models. Check the [comparison](https://github.com/cubiq/ComfyUI_IPAdapter_plus/issues/195) of all face models. -**2023/12/30**: Added support for FaceID Plus v2 models. **Important:** this update again breaks the previous implementation. This time I had to make a new node just for FaceID. The base `IPAdapter Apply` node will work with all previous models; for all FaceID models you'll find an `IPAdapter Apply FaceID` node. **When using v2 remember to check the `v2` options otherwise it won't work as expected!** As always the examples directory is full of workflows for you to play with. - -**2023/12/28**: Added support for FaceID Plus models. **Important:** this update breaks the previous implementation of FaceID. Check the updated workflows in the example directory! Remember to refresh the browser ComfyUI page to clear up the local cache. - -**2023/12/22**: Added support for FaceID models. [Read the documentation](#faceid) for details. - -**2023/12/05**: Added `batch embeds` node. This lets you encode images in batches and merge them together into an `IPAdapter Apply Encoded` node. Useful mostly for animations because the clip vision encoder takes a lot of VRAM. My suggestion is to split the animation in batches of about 120 frames. - -**2023/11/29**: Added `unfold_batch` option to send the reference images sequentially to a latent batch. Useful for animations. - *(previous updates removed for better readability)* ## What is it? -The IPAdapter are very powerful models for image-to-image conditioning. Given a reference image you can do variations augmented by text prompt, controlnets and masks. Think of it as a 1-image lora. +The IPAdapter are very powerful models for image-to-image conditioning. Given one or more reference images you can do variations augmented by text prompt, controlnets and masks. Think of it as a 1-image lora. ## Example workflow -![IPAdapter Example workflow](./ipadapter_workflow.png) - The [example directory](./examples/) has many workflows that cover all IPAdapter functionalities. +![IPAdapter Example workflow](./examples/demo_workflow.jpg) + ## Video Tutorials +The following are mostly outdated now but the overall concepts are still valid. + Watch the video @@ -51,9 +63,13 @@ The [example directory](./examples/) has many workflows that cover all IPAdapter Download or git clone this repository inside `ComfyUI/custom_nodes/` directory or use the Manager. Beware that the automatic update of the manager sometimes doesn't work and you may need to upgrade manually. +IPAdapter always requires the latest version of ComfyUI. If something doesn't work be sure to upgrade! + +There's now an *Unified Model Loader*, for it to work you need to name the files exactly how it is described below. + The pre-trained models are available on [huggingface](https://huggingface.co/h94/IP-Adapter), download and place them in the `ComfyUI/models/ipadapter` directory (create it if not present). You can also use any custom location setting an `ipadapter` entry in the `extra_model_paths.yaml` file. -IPAdapter also needs the image encoders. You need the [CLIP-**ViT-H**-14-laion2B-s32B-b79K](https://huggingface.co/h94/IP-Adapter/resolve/main/models/image_encoder/model.safetensors) and [CLIP-**ViT-bigG**-14-laion2B-39B-b160k](https://huggingface.co/h94/IP-Adapter/resolve/main/sdxl_models/image_encoder/model.safetensors) image encoders, you may already have them. If you don't, download them but **be careful because the file name is the same!** Rename them to something easy to remember and place them in the `ComfyUI/models/clip_vision/` directory. +IPAdapter also needs the image encoders. You need the [CLIP-ViT-H-14-laion2B-s32B-b79K.safetensors](https://huggingface.co/h94/IP-Adapter/resolve/main/models/image_encoder/model.safetensors) and [CLIP-ViT-bigG-14-laion2B-39B-b160k.safetensors](https://huggingface.co/h94/IP-Adapter/resolve/main/sdxl_models/image_encoder/model.safetensors) image encoders, you may already have them. If you don't, download them but **be careful because the file name is the same for both!** Rename them and place them in the `ComfyUI/models/clip_vision/` directory. The following table shows the combination of Checkpoint and Image encoder to use for each IPAdapter Model. Any Tensor size mismatch you may get it is likely caused by a wrong combination. @@ -88,156 +104,20 @@ When the dependencies are satisfied you need: The loras need to be placed into `ComfyUI/models/loras/` directory. -## How to +## Generic suggestions -There's a basic workflow included in this repo and a few examples in the [examples](./examples/) directory. Usually it's a good idea to lower the `weight` to at least `0.8`. +There's a basic workflow included in this repo and a few examples in the [examples](./examples/) directory. Usually it's a good idea to lower the `weight` to at least `0.8` and increase the steps a little. -The `noise` parameter is an experimental exploitation of the IPAdapter models. You can set it as low as `0.01` for an arguably better result. +## Documentation soon to come... -
-More info about the noise option - -canny controlnet - -Basically the IPAdapter sends two pictures for the conditioning, one is the reference the other --that you don't see-- is an empty image that could be considered like a negative conditioning. - -What I'm doing is to send a very noisy image instead of an empty one. The `noise` parameter determines the amount of noise that is added. A value of `0.01` adds a lot of noise (more noise == less impact becaue the model doesn't get it); a value of `1.0` removes most of noise so the generated image gets conditioned more. -
- -### Preparing the reference image - -The reference image needs to be encoded by the CLIP vision model. The encoder resizes the image to 224×224 **and crops it to the center!**. It's not an IPAdapter thing, it's how the clip vision works. This means that if you use a portrait or landscape image and the main attention (eg: the face of a character) is not in the middle you'll likely get undesired results. Use square pictures as reference for more predictable results. - -I've added a `PrepImageForClipVision` node that does all the required operations for you. You just have to select the crop position (top/left/center/etc...) and a sharpening amount if you want. - -In the image below you can see the difference between prepped and not prepped images. - -prepped images - -### KSampler configuration suggestions - -The IPAdapter generally requires a few more `steps` than usual, if the result is underwhelming try to add 10+ steps. The model tends to burn the images a little. If needed lower the CFG scale. - -The `noise` option generally grants better results, experiment with it. - -### IPAdapter + ControlNet - -The model is very effective when paired with a ControlNet. In the example below I experimented with Canny. [The workflow](./examples/IPAdapter_Canny.json) is in the examples directory. - -canny controlnet - -### IPAdapter Face - -IPAdapter offers an interesting model for a kind of "face swap" effect. [The workflow is provided](./examples/IPAdapter_face.json). Set a close up face as reference image and then input your text prompt as always. The generated character should have the face of the reference. It also works with img2img given a high denoise. - -face swap - -**Note:** there's a new `full-face` model available that's arguably better. - -### Masking (Inpainting) - -The most effective way to apply the IPAdapter to a region is by an [inpainting workflow](./examples/IPAdapter_inpaint.json). Remeber to use a specific checkpoint for inpainting otherwise it won't work. Even if you are inpainting a face I find that the *IPAdapter-Plus* (not the *face* one), works best. - -inpainting - -### Image Batches - -It is possible to pass multiple images for the conditioning with the `Batch Images` node. An [example workflow](./examples/IPAdapter_batch_images.json) is provided; in the picture below you can see the result of one and two images conditioning. - -batcg images - -It seems to be effective with 2-3 images, beyond that it tends to *blur* the information too much. - -### Image Weighting - -When sending multiple images you can increase/decrease the weight of each image by using the `IPAdapterEncoder` node. The workflow ([included in the examples](examples/IPAdapter_weighted.json)) looks like this: - -image weighting - -The node accepts 4 images, but remember that you can send batches of images to each slot. - -### Weight types - -You can choose how the IPAdapter weight is applied to the image embeds. Options are: - -- **original**: The weight is applied to the aggregated tensors. The weight works predictably for values greater and lower than 1. -- **linear**: The weight is applied to the individual tensors before aggretating them. Compared to `original` the influence is weaker when weight is <1 and stronger when >1. **Note:** at weight `1` the two methods are equivalent. -- **channel penalty**: This method is a modified version of Lvmin Zhang's (Fooocus). Results are sometimes sharper. It works very well also when weight is >1. Still experimental, may change in the future. - -The image below shows the difference (zoom in). - -weight types - -In the examples directory you can find [a workflow](examples/IPAdapter_weight_types.json) that lets you easily compare the three methods. - -### Attention masking - -It's possible to add a mask to define the area where the IPAdapter will be applied to. Everything outside the mask will ignore the reference images and will only listen to the text prompt. - -It is suggested to use a mask of the same size of the final generated image. - -In the picture below I use two reference images masked one on the left and the other on the right. The image is generated only with IPAdapter and one ksampler (without in/outpainting or area conditioning). - -masking - -It is also possible to send a batch of masks that will be applied to a batch of latents, one per frame. The size should be the same but if needed some normalization will be performed to avoid errors. This feature also supports (experimentally) AnimateDiff including context sliding. - -In the examples directory you'll find a couple of masking workflows: [simple](examples/IPAdapter_mask.json) and [two masks](examples/IPAdapter_2_masks.json). - -### Timestepping - -In the `Apply IPAdapter` node you can set a start and an end point. The IPAdapter will be applied exclusively in that timeframe of the generation. This is a very powerful tool to modulate the intesity of IPAdapter models. - -timestepping - -### Tiled IPAdapter - -This is an experimental node that automatically splits a reference image in quadrants. It can be especially useful when the reference image is not in 1:1 ratio as the Clip Vision encoder only works with 224x224 square images. - -The `short_side_tiles` parameter defines the number of tiles to use for ther shorter side of the reference image; the number of tiles for the other side are calculated automatically. If the image is in landscape or portrait mode that generally means that only 2 tiles are created. If the image is a square, the value must be at least `2` for the node to have any meaninful effect. - -**If the aspect ratio of the refence image and the latent are very diffirent the image will almost certainly be stretched or squished.** - -`tile_weight` is very important any time the `short_side_tiles` value is greater than 1. The default value of `0.6` should be good for most scenarios but you may need to lower it a little (0.5) for SDXL. **This parameter has no effect if the `short_side_tiles` is = 1.** - -The main IPAdapter `weight` should also be lowered, `0.7` is a good starting point. - -**Important:** With a high number of tiles we are going to reiterate on the same _concept_ multiple times so I suggest to lower the CFG or better use the CFG Rescale node. Please check the workflow in the examples directory for reference. - -The node is experimental and will likely change in the future. - -### FaceID - -FaceID is a new IPAdapter model that takes the embeddings from [InsightFace](https://github.com/deepinsight/insightface). As such you need to install `insightface` in your ComfyUI python environment. You may also need `onnxruntime` and `onnxruntime-gpu`. Note that your CUDA version might not be compatible with onnxruntime, in that case you can select the "CPU" provider from the `Load InsightFace model` node. - -The first time you use InsightFace the model will be downloaded automatically, check the console to see the progress. If you get an error you need to donwload the [buffalo_l](https://github.com/deepinsight/insightface/releases) model manually inside the `ComfyUI/models/insightface/models` directory. Also every time you run the workflow for the first time InsightFace will take quite a few seconds to load. - -**The FaceID model is used in conjuction with its Lora!** Check the [installation instructions](#installation) for the links to all models. - -The reference image needs to be prepared differently compared to the other IPAdapter face models. While standard face models expect the face to take basically the whole frame, FaceID prefers the subject to be a little further away. Don't cut the face too close and leave hair, beard, ears, neck in the picture. - -**InsightFace will often fail to detect the face** and it will throw an error. Try with a different picture possibly cut to half-bust. FaceID generally works with drawings/illustrations too and the result is often very nice. - -I just implemented the FaceID code so I don't have best practices yet and more testing is needed. It's important to understand that **FaceID can (and should) be used as a first pass for an additional IPAdapter Face model**. - -In the [examples directory](./examples/) you'll find a few workflows to get you started with FaceID. - -The following would be a basic workflow that includes FaceID enhanced by a Plus Face model. - -timestepping +Working on it! ## Troubleshooting -Please check the [troubleshooting](https://github.com/cubiq/ComfyUI_IPAdapter_plus/issues/108) before posting a new issue. - -## Diffusers version - -If you are interested I've also implemented the same features for [Huggingface Diffusers](https://github.com/cubiq/Diffusers_IPAdapter). +Please check the [troubleshooting](https://github.com/cubiq/ComfyUI_IPAdapter_plus/issues/108) before posting a new issue. Alse remember to check the previous closed issues. ## Credits - [IPAdapter](https://github.com/tencent-ailab/IP-Adapter/) - [ComfyUI](https://github.com/comfyanonymous/ComfyUI) - [laksjdjf](https://github.com/laksjdjf/IPAdapter-ComfyUI/) -- [fooocus](https://github.com/lllyasviel/Fooocus/blob/main/fooocus_extras/ip_adapter.py) - diff --git a/__init__.py b/__init__.py index cdd2511..03a9149 100644 --- a/__init__.py +++ b/__init__.py @@ -1,3 +1,19 @@ +""" + ██▓ ██▓███ ▄▄▄ ▓█████▄ ▄▄▄ ██▓███ ▄▄▄█████▓▓█████ ██▀███ +▓██▒▓██░ ██▒▒████▄ ▒██▀ ██▌▒████▄ ▓██░ ██▒▓ ██▒ ▓▒▓█ ▀ ▓██ ▒ ██▒ +▒██▒▓██░ ██▓▒▒██ ▀█▄ ░██ █▌▒██ ▀█▄ ▓██░ ██▓▒▒ ▓██░ ▒░▒███ ▓██ ░▄█ ▒ +░██░▒██▄█▓▒ ▒░██▄▄▄▄██ ░▓█▄ ▌░██▄▄▄▄██ ▒██▄█▓▒ ▒░ ▓██▓ ░ ▒▓█ ▄ ▒██▀▀█▄ +░██░▒██▒ ░ ░ ▓█ ▓██▒░▒████▓ ▓█ ▓██▒▒██▒ ░ ░ ▒██▒ ░ ░▒████▒░██▓ ▒██▒ +░▓ ▒▓▒░ ░ ░ ▒▒ ▓▒█░ ▒▒▓ ▒ ▒▒ ▓▒█░▒▓▒░ ░ ░ ▒ ░░ ░░ ▒░ ░░ ▒▓ ░▒▓░ + ▒ ░░▒ ░ ▒ ▒▒ ░ ░ ▒ ▒ ▒ ▒▒ ░░▒ ░ ░ ░ ░ ░ ░▒ ░ ▒░ + ▒ ░░░ ░ ▒ ░ ░ ░ ░ ▒ ░░ ░ ░ ░░ ░ + ░ ░ ░ ░ ░ ░ ░ ░ ░ + ░ + ·-—+ IPAdapter Plus Extension for ComfyUI +—-· · + Brought to you by Matteo "Matt3o/Cubiq" Spinelli + https://github.com/cubiq/ComfyUI_IPAdapter_plus/ +""" + from .IPAdapterPlus import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS __all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS'] diff --git a/examples/FaceID_Plus.json b/examples/FaceID_Plus.json deleted file mode 100644 index e57eb75..0000000 --- a/examples/FaceID_Plus.json +++ /dev/null @@ -1,705 +0,0 @@ -{ - "last_node_id": 36, - "last_link_id": 93, - "nodes": [ - { - "id": 6, - "type": "VAEDecode", - "pos": [ - 1800, - 610 - ], - "size": { - "0": 140, - "1": 50 - }, - "flags": {}, - "order": 12, - "mode": 0, - "inputs": [ - { - "name": "samples", - "type": "LATENT", - "link": 7 - }, - { - "name": "vae", - "type": "VAE", - "link": 8 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 72 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAEDecode" - } - }, - { - "id": 7, - "type": "VAELoader", - "pos": [ - 1510, - 910 - ], - "size": { - "0": 240, - "1": 60 - }, - "flags": {}, - "order": 0, - "mode": 0, - "outputs": [ - { - "name": "VAE", - "type": "VAE", - "links": [ - 8 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAELoader" - }, - "widgets_values": [ - "vae-ft-mse-840000-ema-pruned.safetensors" - ] - }, - { - "id": 2, - "type": "CheckpointLoaderSimple", - "pos": [ - 50, - 700 - ], - "size": { - "0": 290, - "1": 100 - }, - "flags": {}, - "order": 1, - "mode": 0, - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 15 - ], - "slot_index": 0 - }, - { - "name": "CLIP", - "type": "CLIP", - "links": [ - 5, - 6 - ], - "slot_index": 1 - }, - { - "name": "VAE", - "type": "VAE", - "links": [], - "slot_index": 2 - } - ], - "properties": { - "Node name for S&R": "CheckpointLoaderSimple" - }, - "widgets_values": [ - "sd15/realisticVisionV51_v51VAE.safetensors" - ] - }, - { - "id": 4, - "type": "CLIPTextEncode", - "pos": [ - 710, - 570 - ], - "size": { - "0": 400, - "1": 160 - }, - "flags": {}, - "order": 8, - "mode": 0, - "inputs": [ - { - "name": "clip", - "type": "CLIP", - "link": 5 - } - ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 2 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPTextEncode" - }, - "widgets_values": [ - "closeup photo of a woman wearing a white spring dress in a garden\n\nhigh quality, diffuse light, highly detailed, 4k" - ], - "color": "#232", - "bgcolor": "#353" - }, - { - "id": 5, - "type": "CLIPTextEncode", - "pos": [ - 710, - 777 - ], - "size": { - "0": 400, - "1": 160 - }, - "flags": {}, - "order": 9, - "mode": 0, - "inputs": [ - { - "name": "clip", - "type": "CLIP", - "link": 6 - } - ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 3 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPTextEncode" - }, - "widgets_values": [ - "blurry, malformed, distorted, naked" - ], - "color": "#322", - "bgcolor": "#533" - }, - { - "id": 3, - "type": "EmptyLatentImage", - "pos": [ - 892, - 994 - ], - "size": { - "0": 210, - "1": 110 - }, - "flags": {}, - "order": 2, - "mode": 0, - "outputs": [ - { - "name": "LATENT", - "type": "LATENT", - "links": [ - 4 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "EmptyLatentImage" - }, - "widgets_values": [ - 512, - 512, - 1 - ] - }, - { - "id": 14, - "type": "LoraLoaderModelOnly", - "pos": [ - 770, - 410 - ], - "size": { - "0": 210, - "1": 82 - }, - "flags": {}, - "order": 7, - "mode": 0, - "inputs": [ - { - "name": "model", - "type": "MODEL", - "link": 15 - } - ], - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 85 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "LoraLoaderModelOnly" - }, - "widgets_values": [ - "ip-adapter-faceid_sd15_lora.safetensors", - 0.6 - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 22, - "type": "PreviewImage", - "pos": [ - 1990, - 530 - ], - "size": { - "0": 527.009765625, - "1": 548.077880859375 - }, - "flags": {}, - "order": 13, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 72 - } - ], - "properties": { - "Node name for S&R": "PreviewImage" - } - }, - { - "id": 32, - "type": "InsightFaceLoader", - "pos": [ - 691, - 291 - ], - "size": { - "0": 290, - "1": 60 - }, - "flags": {}, - "order": 3, - "mode": 0, - "outputs": [ - { - "name": "INSIGHTFACE", - "type": "INSIGHTFACE", - "links": [ - 84 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "InsightFaceLoader" - }, - "widgets_values": [ - "CPU" - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 31, - "type": "CLIPVisionLoader", - "pos": [ - 691, - 172 - ], - "size": { - "0": 290, - "1": 60 - }, - "flags": {}, - "order": 4, - "mode": 0, - "outputs": [ - { - "name": "CLIP_VISION", - "type": "CLIP_VISION", - "links": [ - 82 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPVisionLoader" - }, - "widgets_values": [ - "IPAdapter_image_encoder_sd15.safetensors" - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 10, - "type": "LoadImage", - "pos": [ - 180, - -50 - ], - "size": { - "0": 390.733154296875, - "1": 482.0174560546875 - }, - "flags": {}, - "order": 5, - "mode": 0, - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 83 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "MASK", - "type": "MASK", - "links": null, - "shape": 3 - } - ], - "properties": { - "Node name for S&R": "LoadImage" - }, - "widgets_values": [ - "cwf_portrait.jpg", - "image" - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 9, - "type": "IPAdapterModelLoader", - "pos": [ - 691, - 58 - ], - "size": { - "0": 290, - "1": 60 - }, - "flags": {}, - "order": 6, - "mode": 0, - "outputs": [ - { - "name": "IPADAPTER", - "type": "IPADAPTER", - "links": [ - 81 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterModelLoader" - }, - "widgets_values": [ - "ip-adapter-faceid-plus_sd15.bin" - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 33, - "type": "IPAdapterApplyFaceID", - "pos": [ - 1095, - 166 - ], - "size": { - "0": 315, - "1": 326 - }, - "flags": {}, - "order": 10, - "mode": 0, - "inputs": [ - { - "name": "ipadapter", - "type": "IPADAPTER", - "link": 81 - }, - { - "name": "clip_vision", - "type": "CLIP_VISION", - "link": 82 - }, - { - "name": "insightface", - "type": "INSIGHTFACE", - "link": 84 - }, - { - "name": "image", - "type": "IMAGE", - "link": 83 - }, - { - "name": "model", - "type": "MODEL", - "link": 85 - }, - { - "name": "attn_mask", - "type": "MASK", - "link": null - } - ], - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 93 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterApplyFaceID" - }, - "widgets_values": [ - 1.2, - 0, - "original", - 0, - 1, - false, - 1, - false - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 1, - "type": "KSampler", - "pos": [ - 1510, - 610 - ], - "size": { - "0": 240, - "1": 262 - }, - "flags": {}, - "order": 11, - "mode": 0, - "inputs": [ - { - "name": "model", - "type": "MODEL", - "link": 93 - }, - { - "name": "positive", - "type": "CONDITIONING", - "link": 2 - }, - { - "name": "negative", - "type": "CONDITIONING", - "link": 3 - }, - { - "name": "latent_image", - "type": "LATENT", - "link": 4 - } - ], - "outputs": [ - { - "name": "LATENT", - "type": "LATENT", - "links": [ - 7 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "KSampler" - }, - "widgets_values": [ - 1, - "fixed", - 25, - 7, - "dpmpp_2m", - "karras", - 1 - ] - } - ], - "links": [ - [ - 2, - 4, - 0, - 1, - 1, - "CONDITIONING" - ], - [ - 3, - 5, - 0, - 1, - 2, - "CONDITIONING" - ], - [ - 4, - 3, - 0, - 1, - 3, - "LATENT" - ], - [ - 5, - 2, - 1, - 4, - 0, - "CLIP" - ], - [ - 6, - 2, - 1, - 5, - 0, - "CLIP" - ], - [ - 7, - 1, - 0, - 6, - 0, - "LATENT" - ], - [ - 8, - 7, - 0, - 6, - 1, - "VAE" - ], - [ - 15, - 2, - 0, - 14, - 0, - "MODEL" - ], - [ - 72, - 6, - 0, - 22, - 0, - "IMAGE" - ], - [ - 81, - 9, - 0, - 33, - 0, - "IPADAPTER" - ], - [ - 82, - 31, - 0, - 33, - 1, - "CLIP_VISION" - ], - [ - 83, - 10, - 0, - 33, - 3, - "IMAGE" - ], - [ - 84, - 32, - 0, - 33, - 2, - "INSIGHTFACE" - ], - [ - 85, - 14, - 0, - 33, - 4, - "MODEL" - ], - [ - 93, - 33, - 0, - 1, - 0, - "MODEL" - ] - ], - "groups": [], - "config": {}, - "extra": {}, - "version": 0.4 -} \ No newline at end of file diff --git a/examples/FaceID_Plus_v2.json b/examples/FaceID_Plus_v2.json deleted file mode 100644 index 15a5761..0000000 --- a/examples/FaceID_Plus_v2.json +++ /dev/null @@ -1,705 +0,0 @@ -{ - "last_node_id": 36, - "last_link_id": 93, - "nodes": [ - { - "id": 6, - "type": "VAEDecode", - "pos": [ - 1800, - 610 - ], - "size": { - "0": 140, - "1": 50 - }, - "flags": {}, - "order": 12, - "mode": 0, - "inputs": [ - { - "name": "samples", - "type": "LATENT", - "link": 7 - }, - { - "name": "vae", - "type": "VAE", - "link": 8 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 72 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAEDecode" - } - }, - { - "id": 7, - "type": "VAELoader", - "pos": [ - 1510, - 910 - ], - "size": { - "0": 240, - "1": 60 - }, - "flags": {}, - "order": 0, - "mode": 0, - "outputs": [ - { - "name": "VAE", - "type": "VAE", - "links": [ - 8 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAELoader" - }, - "widgets_values": [ - "vae-ft-mse-840000-ema-pruned.safetensors" - ] - }, - { - "id": 2, - "type": "CheckpointLoaderSimple", - "pos": [ - 50, - 700 - ], - "size": { - "0": 290, - "1": 100 - }, - "flags": {}, - "order": 1, - "mode": 0, - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 15 - ], - "slot_index": 0 - }, - { - "name": "CLIP", - "type": "CLIP", - "links": [ - 5, - 6 - ], - "slot_index": 1 - }, - { - "name": "VAE", - "type": "VAE", - "links": [], - "slot_index": 2 - } - ], - "properties": { - "Node name for S&R": "CheckpointLoaderSimple" - }, - "widgets_values": [ - "sd15/realisticVisionV51_v51VAE.safetensors" - ] - }, - { - "id": 4, - "type": "CLIPTextEncode", - "pos": [ - 710, - 570 - ], - "size": { - "0": 400, - "1": 160 - }, - "flags": {}, - "order": 8, - "mode": 0, - "inputs": [ - { - "name": "clip", - "type": "CLIP", - "link": 5 - } - ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 2 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPTextEncode" - }, - "widgets_values": [ - "closeup photo of a woman wearing a white spring dress in a garden\n\nhigh quality, diffuse light, highly detailed, 4k" - ], - "color": "#232", - "bgcolor": "#353" - }, - { - "id": 5, - "type": "CLIPTextEncode", - "pos": [ - 710, - 777 - ], - "size": { - "0": 400, - "1": 160 - }, - "flags": {}, - "order": 9, - "mode": 0, - "inputs": [ - { - "name": "clip", - "type": "CLIP", - "link": 6 - } - ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 3 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPTextEncode" - }, - "widgets_values": [ - "blurry, malformed, distorted, naked" - ], - "color": "#322", - "bgcolor": "#533" - }, - { - "id": 3, - "type": "EmptyLatentImage", - "pos": [ - 892, - 994 - ], - "size": { - "0": 210, - "1": 110 - }, - "flags": {}, - "order": 2, - "mode": 0, - "outputs": [ - { - "name": "LATENT", - "type": "LATENT", - "links": [ - 4 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "EmptyLatentImage" - }, - "widgets_values": [ - 512, - 512, - 1 - ] - }, - { - "id": 22, - "type": "PreviewImage", - "pos": [ - 1990, - 530 - ], - "size": { - "0": 527.009765625, - "1": 548.077880859375 - }, - "flags": {}, - "order": 13, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 72 - } - ], - "properties": { - "Node name for S&R": "PreviewImage" - } - }, - { - "id": 32, - "type": "InsightFaceLoader", - "pos": [ - 691, - 291 - ], - "size": { - "0": 290, - "1": 60 - }, - "flags": {}, - "order": 3, - "mode": 0, - "outputs": [ - { - "name": "INSIGHTFACE", - "type": "INSIGHTFACE", - "links": [ - 84 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "InsightFaceLoader" - }, - "widgets_values": [ - "CPU" - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 31, - "type": "CLIPVisionLoader", - "pos": [ - 691, - 172 - ], - "size": { - "0": 290, - "1": 60 - }, - "flags": {}, - "order": 4, - "mode": 0, - "outputs": [ - { - "name": "CLIP_VISION", - "type": "CLIP_VISION", - "links": [ - 82 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPVisionLoader" - }, - "widgets_values": [ - "IPAdapter_image_encoder_sd15.safetensors" - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 10, - "type": "LoadImage", - "pos": [ - 180, - -50 - ], - "size": { - "0": 390.733154296875, - "1": 482.0174560546875 - }, - "flags": {}, - "order": 5, - "mode": 0, - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 83 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "MASK", - "type": "MASK", - "links": null, - "shape": 3 - } - ], - "properties": { - "Node name for S&R": "LoadImage" - }, - "widgets_values": [ - "cwf_portrait.jpg", - "image" - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 9, - "type": "IPAdapterModelLoader", - "pos": [ - 691, - 58 - ], - "size": { - "0": 290, - "1": 60 - }, - "flags": {}, - "order": 6, - "mode": 0, - "outputs": [ - { - "name": "IPADAPTER", - "type": "IPADAPTER", - "links": [ - 81 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterModelLoader" - }, - "widgets_values": [ - "ip-adapter-faceid-plusv2_sd15.bin" - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 33, - "type": "IPAdapterApplyFaceID", - "pos": [ - 1095, - 166 - ], - "size": { - "0": 315, - "1": 326 - }, - "flags": {}, - "order": 10, - "mode": 0, - "inputs": [ - { - "name": "ipadapter", - "type": "IPADAPTER", - "link": 81 - }, - { - "name": "clip_vision", - "type": "CLIP_VISION", - "link": 82 - }, - { - "name": "insightface", - "type": "INSIGHTFACE", - "link": 84 - }, - { - "name": "image", - "type": "IMAGE", - "link": 83 - }, - { - "name": "model", - "type": "MODEL", - "link": 85 - }, - { - "name": "attn_mask", - "type": "MASK", - "link": null - } - ], - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 93 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterApplyFaceID" - }, - "widgets_values": [ - 0.9, - 0, - "original", - 0, - 1, - true, - 1, - false - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 1, - "type": "KSampler", - "pos": [ - 1510, - 610 - ], - "size": { - "0": 240, - "1": 262 - }, - "flags": {}, - "order": 11, - "mode": 0, - "inputs": [ - { - "name": "model", - "type": "MODEL", - "link": 93 - }, - { - "name": "positive", - "type": "CONDITIONING", - "link": 2 - }, - { - "name": "negative", - "type": "CONDITIONING", - "link": 3 - }, - { - "name": "latent_image", - "type": "LATENT", - "link": 4 - } - ], - "outputs": [ - { - "name": "LATENT", - "type": "LATENT", - "links": [ - 7 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "KSampler" - }, - "widgets_values": [ - 1, - "fixed", - 25, - 6.5, - "dpmpp_2m", - "karras", - 1 - ] - }, - { - "id": 14, - "type": "LoraLoaderModelOnly", - "pos": [ - 770, - 410 - ], - "size": { - "0": 210, - "1": 82 - }, - "flags": {}, - "order": 7, - "mode": 0, - "inputs": [ - { - "name": "model", - "type": "MODEL", - "link": 15 - } - ], - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 85 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "LoraLoaderModelOnly" - }, - "widgets_values": [ - "ip-adapter-faceid-plusv2_sd15_lora.safetensors", - 0.6 - ], - "color": "#223", - "bgcolor": "#335" - } - ], - "links": [ - [ - 2, - 4, - 0, - 1, - 1, - "CONDITIONING" - ], - [ - 3, - 5, - 0, - 1, - 2, - "CONDITIONING" - ], - [ - 4, - 3, - 0, - 1, - 3, - "LATENT" - ], - [ - 5, - 2, - 1, - 4, - 0, - "CLIP" - ], - [ - 6, - 2, - 1, - 5, - 0, - "CLIP" - ], - [ - 7, - 1, - 0, - 6, - 0, - "LATENT" - ], - [ - 8, - 7, - 0, - 6, - 1, - "VAE" - ], - [ - 15, - 2, - 0, - 14, - 0, - "MODEL" - ], - [ - 72, - 6, - 0, - 22, - 0, - "IMAGE" - ], - [ - 81, - 9, - 0, - 33, - 0, - "IPADAPTER" - ], - [ - 82, - 31, - 0, - 33, - 1, - "CLIP_VISION" - ], - [ - 83, - 10, - 0, - 33, - 3, - "IMAGE" - ], - [ - 84, - 32, - 0, - 33, - 2, - "INSIGHTFACE" - ], - [ - 85, - 14, - 0, - 33, - 4, - "MODEL" - ], - [ - 93, - 33, - 0, - 1, - 0, - "MODEL" - ] - ], - "groups": [], - "config": {}, - "extra": {}, - "version": 0.4 -} \ No newline at end of file diff --git a/examples/FaceID_basic.json b/examples/FaceID_basic.json deleted file mode 100644 index f089a0d..0000000 --- a/examples/FaceID_basic.json +++ /dev/null @@ -1,705 +0,0 @@ -{ - "last_node_id": 36, - "last_link_id": 93, - "nodes": [ - { - "id": 6, - "type": "VAEDecode", - "pos": [ - 1800, - 610 - ], - "size": { - "0": 140, - "1": 50 - }, - "flags": {}, - "order": 12, - "mode": 0, - "inputs": [ - { - "name": "samples", - "type": "LATENT", - "link": 7 - }, - { - "name": "vae", - "type": "VAE", - "link": 8 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 72 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAEDecode" - } - }, - { - "id": 7, - "type": "VAELoader", - "pos": [ - 1510, - 910 - ], - "size": { - "0": 240, - "1": 60 - }, - "flags": {}, - "order": 0, - "mode": 0, - "outputs": [ - { - "name": "VAE", - "type": "VAE", - "links": [ - 8 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAELoader" - }, - "widgets_values": [ - "vae-ft-mse-840000-ema-pruned.safetensors" - ] - }, - { - "id": 2, - "type": "CheckpointLoaderSimple", - "pos": [ - 50, - 700 - ], - "size": { - "0": 290, - "1": 100 - }, - "flags": {}, - "order": 1, - "mode": 0, - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 15 - ], - "slot_index": 0 - }, - { - "name": "CLIP", - "type": "CLIP", - "links": [ - 5, - 6 - ], - "slot_index": 1 - }, - { - "name": "VAE", - "type": "VAE", - "links": [], - "slot_index": 2 - } - ], - "properties": { - "Node name for S&R": "CheckpointLoaderSimple" - }, - "widgets_values": [ - "sd15/realisticVisionV51_v51VAE.safetensors" - ] - }, - { - "id": 4, - "type": "CLIPTextEncode", - "pos": [ - 710, - 570 - ], - "size": { - "0": 400, - "1": 160 - }, - "flags": {}, - "order": 8, - "mode": 0, - "inputs": [ - { - "name": "clip", - "type": "CLIP", - "link": 5 - } - ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 2 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPTextEncode" - }, - "widgets_values": [ - "closeup photo of a woman wearing a white spring dress in a garden\n\nhigh quality, diffuse light, highly detailed, 4k" - ], - "color": "#232", - "bgcolor": "#353" - }, - { - "id": 5, - "type": "CLIPTextEncode", - "pos": [ - 710, - 777 - ], - "size": { - "0": 400, - "1": 160 - }, - "flags": {}, - "order": 9, - "mode": 0, - "inputs": [ - { - "name": "clip", - "type": "CLIP", - "link": 6 - } - ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 3 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPTextEncode" - }, - "widgets_values": [ - "blurry, malformed, distorted, naked" - ], - "color": "#322", - "bgcolor": "#533" - }, - { - "id": 3, - "type": "EmptyLatentImage", - "pos": [ - 892, - 994 - ], - "size": { - "0": 210, - "1": 110 - }, - "flags": {}, - "order": 2, - "mode": 0, - "outputs": [ - { - "name": "LATENT", - "type": "LATENT", - "links": [ - 4 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "EmptyLatentImage" - }, - "widgets_values": [ - 512, - 512, - 1 - ] - }, - { - "id": 14, - "type": "LoraLoaderModelOnly", - "pos": [ - 770, - 410 - ], - "size": { - "0": 210, - "1": 82 - }, - "flags": {}, - "order": 7, - "mode": 0, - "inputs": [ - { - "name": "model", - "type": "MODEL", - "link": 15 - } - ], - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 85 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "LoraLoaderModelOnly" - }, - "widgets_values": [ - "ip-adapter-faceid_sd15_lora.safetensors", - 0.6 - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 22, - "type": "PreviewImage", - "pos": [ - 1990, - 530 - ], - "size": { - "0": 527.009765625, - "1": 548.077880859375 - }, - "flags": {}, - "order": 13, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 72 - } - ], - "properties": { - "Node name for S&R": "PreviewImage" - } - }, - { - "id": 32, - "type": "InsightFaceLoader", - "pos": [ - 691, - 291 - ], - "size": { - "0": 290, - "1": 60 - }, - "flags": {}, - "order": 3, - "mode": 0, - "outputs": [ - { - "name": "INSIGHTFACE", - "type": "INSIGHTFACE", - "links": [ - 84 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "InsightFaceLoader" - }, - "widgets_values": [ - "CPU" - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 9, - "type": "IPAdapterModelLoader", - "pos": [ - 691, - 58 - ], - "size": { - "0": 290, - "1": 60 - }, - "flags": {}, - "order": 4, - "mode": 0, - "outputs": [ - { - "name": "IPADAPTER", - "type": "IPADAPTER", - "links": [ - 81 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterModelLoader" - }, - "widgets_values": [ - "ip-adapter-faceid_sd15.bin" - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 31, - "type": "CLIPVisionLoader", - "pos": [ - 691, - 172 - ], - "size": { - "0": 290, - "1": 60 - }, - "flags": {}, - "order": 5, - "mode": 0, - "outputs": [ - { - "name": "CLIP_VISION", - "type": "CLIP_VISION", - "links": [ - 82 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPVisionLoader" - }, - "widgets_values": [ - "IPAdapter_image_encoder_sd15.safetensors" - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 10, - "type": "LoadImage", - "pos": [ - 180, - -50 - ], - "size": { - "0": 390.733154296875, - "1": 482.0174560546875 - }, - "flags": {}, - "order": 6, - "mode": 0, - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 83 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "MASK", - "type": "MASK", - "links": null, - "shape": 3 - } - ], - "properties": { - "Node name for S&R": "LoadImage" - }, - "widgets_values": [ - "cwf_portrait.jpg", - "image" - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 1, - "type": "KSampler", - "pos": [ - 1510, - 610 - ], - "size": { - "0": 240, - "1": 262 - }, - "flags": {}, - "order": 11, - "mode": 0, - "inputs": [ - { - "name": "model", - "type": "MODEL", - "link": 93 - }, - { - "name": "positive", - "type": "CONDITIONING", - "link": 2 - }, - { - "name": "negative", - "type": "CONDITIONING", - "link": 3 - }, - { - "name": "latent_image", - "type": "LATENT", - "link": 4 - } - ], - "outputs": [ - { - "name": "LATENT", - "type": "LATENT", - "links": [ - 7 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "KSampler" - }, - "widgets_values": [ - 1, - "fixed", - 30, - 6, - "dpmpp_2m", - "karras", - 1 - ] - }, - { - "id": 33, - "type": "IPAdapterApplyFaceID", - "pos": [ - 1095, - 166 - ], - "size": { - "0": 315, - "1": 326 - }, - "flags": {}, - "order": 10, - "mode": 0, - "inputs": [ - { - "name": "ipadapter", - "type": "IPADAPTER", - "link": 81 - }, - { - "name": "clip_vision", - "type": "CLIP_VISION", - "link": 82 - }, - { - "name": "insightface", - "type": "INSIGHTFACE", - "link": 84 - }, - { - "name": "image", - "type": "IMAGE", - "link": 83 - }, - { - "name": "model", - "type": "MODEL", - "link": 85 - }, - { - "name": "attn_mask", - "type": "MASK", - "link": null - } - ], - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 93 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterApplyFaceID" - }, - "widgets_values": [ - 1, - 0, - "original", - 0, - 1, - false, - 1, - false - ], - "color": "#223", - "bgcolor": "#335" - } - ], - "links": [ - [ - 2, - 4, - 0, - 1, - 1, - "CONDITIONING" - ], - [ - 3, - 5, - 0, - 1, - 2, - "CONDITIONING" - ], - [ - 4, - 3, - 0, - 1, - 3, - "LATENT" - ], - [ - 5, - 2, - 1, - 4, - 0, - "CLIP" - ], - [ - 6, - 2, - 1, - 5, - 0, - "CLIP" - ], - [ - 7, - 1, - 0, - 6, - 0, - "LATENT" - ], - [ - 8, - 7, - 0, - 6, - 1, - "VAE" - ], - [ - 15, - 2, - 0, - 14, - 0, - "MODEL" - ], - [ - 72, - 6, - 0, - 22, - 0, - "IMAGE" - ], - [ - 81, - 9, - 0, - 33, - 0, - "IPADAPTER" - ], - [ - 82, - 31, - 0, - 33, - 1, - "CLIP_VISION" - ], - [ - 83, - 10, - 0, - 33, - 3, - "IMAGE" - ], - [ - 84, - 32, - 0, - 33, - 2, - "INSIGHTFACE" - ], - [ - 85, - 14, - 0, - 33, - 4, - "MODEL" - ], - [ - 93, - 33, - 0, - 1, - 0, - "MODEL" - ] - ], - "groups": [], - "config": {}, - "extra": {}, - "version": 0.4 -} \ No newline at end of file diff --git a/examples/FaceID_enhanced.json b/examples/FaceID_enhanced.json deleted file mode 100644 index 73f38c5..0000000 --- a/examples/FaceID_enhanced.json +++ /dev/null @@ -1,839 +0,0 @@ -{ - "last_node_id": 36, - "last_link_id": 92, - "nodes": [ - { - "id": 6, - "type": "VAEDecode", - "pos": [ - 1800, - 610 - ], - "size": { - "0": 140, - "1": 50 - }, - "flags": {}, - "order": 14, - "mode": 0, - "inputs": [ - { - "name": "samples", - "type": "LATENT", - "link": 7 - }, - { - "name": "vae", - "type": "VAE", - "link": 8 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 72 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAEDecode" - } - }, - { - "id": 7, - "type": "VAELoader", - "pos": [ - 1510, - 910 - ], - "size": { - "0": 240, - "1": 60 - }, - "flags": {}, - "order": 0, - "mode": 0, - "outputs": [ - { - "name": "VAE", - "type": "VAE", - "links": [ - 8 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAELoader" - }, - "widgets_values": [ - "vae-ft-mse-840000-ema-pruned.safetensors" - ] - }, - { - "id": 2, - "type": "CheckpointLoaderSimple", - "pos": [ - 50, - 700 - ], - "size": { - "0": 290, - "1": 100 - }, - "flags": {}, - "order": 1, - "mode": 0, - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 15 - ], - "slot_index": 0 - }, - { - "name": "CLIP", - "type": "CLIP", - "links": [ - 5, - 6 - ], - "slot_index": 1 - }, - { - "name": "VAE", - "type": "VAE", - "links": [], - "slot_index": 2 - } - ], - "properties": { - "Node name for S&R": "CheckpointLoaderSimple" - }, - "widgets_values": [ - "sd15/realisticVisionV51_v51VAE.safetensors" - ] - }, - { - "id": 4, - "type": "CLIPTextEncode", - "pos": [ - 710, - 570 - ], - "size": { - "0": 400, - "1": 160 - }, - "flags": {}, - "order": 9, - "mode": 0, - "inputs": [ - { - "name": "clip", - "type": "CLIP", - "link": 5 - } - ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 2 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPTextEncode" - }, - "widgets_values": [ - "closeup photo of a woman wearing a white spring dress in a garden\n\nhigh quality, diffuse light, highly detailed, 4k" - ], - "color": "#232", - "bgcolor": "#353" - }, - { - "id": 5, - "type": "CLIPTextEncode", - "pos": [ - 710, - 777 - ], - "size": { - "0": 400, - "1": 160 - }, - "flags": {}, - "order": 10, - "mode": 0, - "inputs": [ - { - "name": "clip", - "type": "CLIP", - "link": 6 - } - ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 3 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPTextEncode" - }, - "widgets_values": [ - "blurry, malformed, distorted, naked" - ], - "color": "#322", - "bgcolor": "#533" - }, - { - "id": 3, - "type": "EmptyLatentImage", - "pos": [ - 892, - 994 - ], - "size": { - "0": 210, - "1": 110 - }, - "flags": {}, - "order": 2, - "mode": 0, - "outputs": [ - { - "name": "LATENT", - "type": "LATENT", - "links": [ - 4 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "EmptyLatentImage" - }, - "widgets_values": [ - 512, - 512, - 1 - ] - }, - { - "id": 14, - "type": "LoraLoaderModelOnly", - "pos": [ - 770, - 410 - ], - "size": { - "0": 210, - "1": 82 - }, - "flags": {}, - "order": 8, - "mode": 0, - "inputs": [ - { - "name": "model", - "type": "MODEL", - "link": 15 - } - ], - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 85 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "LoraLoaderModelOnly" - }, - "widgets_values": [ - "ip-adapter-faceid_sd15_lora.safetensors", - 0.6 - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 22, - "type": "PreviewImage", - "pos": [ - 1990, - 530 - ], - "size": { - "0": 527.009765625, - "1": 548.077880859375 - }, - "flags": {}, - "order": 15, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 72 - } - ], - "properties": { - "Node name for S&R": "PreviewImage" - } - }, - { - "id": 33, - "type": "IPAdapterApplyFaceID", - "pos": [ - 1095, - 166 - ], - "size": { - "0": 315, - "1": 326 - }, - "flags": {}, - "order": 11, - "mode": 0, - "inputs": [ - { - "name": "ipadapter", - "type": "IPADAPTER", - "link": 81 - }, - { - "name": "clip_vision", - "type": "CLIP_VISION", - "link": 82 - }, - { - "name": "insightface", - "type": "INSIGHTFACE", - "link": 84 - }, - { - "name": "image", - "type": "IMAGE", - "link": 83 - }, - { - "name": "model", - "type": "MODEL", - "link": 85 - }, - { - "name": "attn_mask", - "type": "MASK", - "link": null - } - ], - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 87 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterApplyFaceID" - }, - "widgets_values": [ - 1, - 0, - "original", - 0, - 1, - false, - 1, - false - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 32, - "type": "InsightFaceLoader", - "pos": [ - 691, - 291 - ], - "size": { - "0": 290, - "1": 60 - }, - "flags": {}, - "order": 3, - "mode": 0, - "outputs": [ - { - "name": "INSIGHTFACE", - "type": "INSIGHTFACE", - "links": [ - 84 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "InsightFaceLoader" - }, - "widgets_values": [ - "CPU" - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 9, - "type": "IPAdapterModelLoader", - "pos": [ - 691, - 58 - ], - "size": { - "0": 290, - "1": 60 - }, - "flags": {}, - "order": 4, - "mode": 0, - "outputs": [ - { - "name": "IPADAPTER", - "type": "IPADAPTER", - "links": [ - 81 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterModelLoader" - }, - "widgets_values": [ - "ip-adapter-faceid_sd15.bin" - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 31, - "type": "CLIPVisionLoader", - "pos": [ - 691, - 172 - ], - "size": { - "0": 290, - "1": 60 - }, - "flags": {}, - "order": 5, - "mode": 0, - "outputs": [ - { - "name": "CLIP_VISION", - "type": "CLIP_VISION", - "links": [ - 82, - 89 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPVisionLoader" - }, - "widgets_values": [ - "IPAdapter_image_encoder_sd15.safetensors" - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 10, - "type": "LoadImage", - "pos": [ - 180, - -50 - ], - "size": { - "0": 390.733154296875, - "1": 482.0174560546875 - }, - "flags": {}, - "order": 6, - "mode": 0, - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 83, - 91 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "MASK", - "type": "MASK", - "links": null, - "shape": 3 - } - ], - "properties": { - "Node name for S&R": "LoadImage" - }, - "widgets_values": [ - "cwf_portrait.jpg", - "image" - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 36, - "type": "IPAdapterModelLoader", - "pos": [ - 1131, - 28 - ], - "size": [ - 294.14974698153355, - 58 - ], - "flags": {}, - "order": 7, - "mode": 0, - "outputs": [ - { - "name": "IPADAPTER", - "type": "IPADAPTER", - "links": [ - 90 - ], - "shape": 3 - } - ], - "properties": { - "Node name for S&R": "IPAdapterModelLoader" - }, - "widgets_values": [ - "ip-adapter-plus-face_sd15.safetensors" - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 1, - "type": "KSampler", - "pos": [ - 1510, - 610 - ], - "size": { - "0": 240, - "1": 262 - }, - "flags": {}, - "order": 13, - "mode": 0, - "inputs": [ - { - "name": "model", - "type": "MODEL", - "link": 92 - }, - { - "name": "positive", - "type": "CONDITIONING", - "link": 2 - }, - { - "name": "negative", - "type": "CONDITIONING", - "link": 3 - }, - { - "name": "latent_image", - "type": "LATENT", - "link": 4 - } - ], - "outputs": [ - { - "name": "LATENT", - "type": "LATENT", - "links": [ - 7 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "KSampler" - }, - "widgets_values": [ - 1, - "fixed", - 30, - 6, - "dpmpp_2m", - "karras", - 1 - ] - }, - { - "id": 35, - "type": "IPAdapterApply", - "pos": [ - 1488, - 107 - ], - "size": { - "0": 315, - "1": 258 - }, - "flags": {}, - "order": 12, - "mode": 0, - "inputs": [ - { - "name": "ipadapter", - "type": "IPADAPTER", - "link": 90, - "slot_index": 0 - }, - { - "name": "clip_vision", - "type": "CLIP_VISION", - "link": 89 - }, - { - "name": "image", - "type": "IMAGE", - "link": 91 - }, - { - "name": "model", - "type": "MODEL", - "link": 87 - }, - { - "name": "attn_mask", - "type": "MASK", - "link": null - } - ], - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 92 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterApply" - }, - "widgets_values": [ - 0.3, - 0.33, - "original", - 0, - 0.8, - false - ], - "color": "#223", - "bgcolor": "#335" - } - ], - "links": [ - [ - 2, - 4, - 0, - 1, - 1, - "CONDITIONING" - ], - [ - 3, - 5, - 0, - 1, - 2, - "CONDITIONING" - ], - [ - 4, - 3, - 0, - 1, - 3, - "LATENT" - ], - [ - 5, - 2, - 1, - 4, - 0, - "CLIP" - ], - [ - 6, - 2, - 1, - 5, - 0, - "CLIP" - ], - [ - 7, - 1, - 0, - 6, - 0, - "LATENT" - ], - [ - 8, - 7, - 0, - 6, - 1, - "VAE" - ], - [ - 15, - 2, - 0, - 14, - 0, - "MODEL" - ], - [ - 72, - 6, - 0, - 22, - 0, - "IMAGE" - ], - [ - 81, - 9, - 0, - 33, - 0, - "IPADAPTER" - ], - [ - 82, - 31, - 0, - 33, - 1, - "CLIP_VISION" - ], - [ - 83, - 10, - 0, - 33, - 3, - "IMAGE" - ], - [ - 84, - 32, - 0, - 33, - 2, - "INSIGHTFACE" - ], - [ - 85, - 14, - 0, - 33, - 4, - "MODEL" - ], - [ - 87, - 33, - 0, - 35, - 3, - "MODEL" - ], - [ - 89, - 31, - 0, - 35, - 1, - "CLIP_VISION" - ], - [ - 90, - 36, - 0, - 35, - 0, - "IPADAPTER" - ], - [ - 91, - 10, - 0, - 35, - 2, - "IMAGE" - ], - [ - 92, - 35, - 0, - 1, - 0, - "MODEL" - ] - ], - "groups": [], - "config": {}, - "extra": {}, - "version": 0.4 -} \ No newline at end of file diff --git a/examples/IPAdapter_2_masks.json b/examples/IPAdapter_2_masks.json deleted file mode 100644 index e32e4ae..0000000 --- a/examples/IPAdapter_2_masks.json +++ /dev/null @@ -1,1173 +0,0 @@ -{ - "last_node_id": 56, - "last_link_id": 101, - "nodes": [ - { - "id": 5, - "type": "CLIPTextEncode", - "pos": [ - 550, - 510 - ], - "size": { - "0": 400, - "1": 160 - }, - "flags": {}, - "order": 10, - "mode": 0, - "inputs": [ - { - "name": "clip", - "type": "CLIP", - "link": 6 - } - ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 3 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPTextEncode" - }, - "widgets_values": [ - "blurry, malformed, illustration, video game, rendering, naked, cleavage, horror, zombie" - ], - "color": "#322", - "bgcolor": "#533" - }, - { - "id": 6, - "type": "VAEDecode", - "pos": [ - 1430, - 300 - ], - "size": { - "0": 140, - "1": 50 - }, - "flags": {}, - "order": 20, - "mode": 0, - "inputs": [ - { - "name": "samples", - "type": "LATENT", - "link": 7 - }, - { - "name": "vae", - "type": "VAE", - "link": 8 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 9 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAEDecode" - } - }, - { - "id": 7, - "type": "VAELoader", - "pos": [ - 1160, - 600 - ], - "size": { - "0": 240, - "1": 60 - }, - "flags": {}, - "order": 0, - "mode": 0, - "outputs": [ - { - "name": "VAE", - "type": "VAE", - "links": [ - 8 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAELoader" - }, - "widgets_values": [ - "vae-ft-mse-840000-ema-pruned.safetensors" - ] - }, - { - "id": 2, - "type": "CheckpointLoaderSimple", - "pos": [ - 210, - 410 - ], - "size": { - "0": 290, - "1": 100 - }, - "flags": {}, - "order": 1, - "mode": 0, - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 88 - ], - "slot_index": 0 - }, - { - "name": "CLIP", - "type": "CLIP", - "links": [ - 5, - 6 - ], - "slot_index": 1 - }, - { - "name": "VAE", - "type": "VAE", - "links": [], - "slot_index": 2 - } - ], - "properties": { - "Node name for S&R": "CheckpointLoaderSimple" - }, - "widgets_values": [ - "sd15/dreamshaper_8.safetensors" - ] - }, - { - "id": 3, - "type": "EmptyLatentImage", - "pos": [ - 740, - 710 - ], - "size": { - "0": 210, - "1": 110 - }, - "flags": {}, - "order": 2, - "mode": 0, - "outputs": [ - { - "name": "LATENT", - "type": "LATENT", - "links": [ - 4 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "EmptyLatentImage" - }, - "widgets_values": [ - 768, - 512, - 1 - ] - }, - { - "id": 34, - "type": "SolidMask", - "pos": [ - -570, - -50 - ], - "size": { - "0": 210, - "1": 106 - }, - "flags": {}, - "order": 3, - "mode": 0, - "outputs": [ - { - "name": "MASK", - "type": "MASK", - "links": [ - 51, - 57 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "SolidMask" - }, - "widgets_values": [ - 0, - 768, - 512 - ], - "color": "#232", - "bgcolor": "#353" - }, - { - "id": 4, - "type": "CLIPTextEncode", - "pos": [ - 550, - 310 - ], - "size": { - "0": 400, - "1": 160 - }, - "flags": {}, - "order": 9, - "mode": 0, - "inputs": [ - { - "name": "clip", - "type": "CLIP", - "link": 5 - } - ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 2 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPTextEncode" - }, - "widgets_values": [ - "two girl friends laughing" - ], - "color": "#232", - "bgcolor": "#353" - }, - { - "id": 8, - "type": "PreviewImage", - "pos": [ - 1450, - 400 - ], - "size": { - "0": 675.9465942382812, - "1": 480.1444091796875 - }, - "flags": {}, - "order": 21, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 9 - } - ], - "properties": { - "Node name for S&R": "PreviewImage" - } - }, - { - "id": 52, - "type": "PrepImageForClipVision", - "pos": [ - 760, - -380 - ], - "size": { - "0": 243.60000610351562, - "1": 110 - }, - "flags": {}, - "order": 12, - "mode": 0, - "inputs": [ - { - "name": "image", - "type": "IMAGE", - "link": 91 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 92 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "PrepImageForClipVision" - }, - "widgets_values": [ - "LANCZOS", - "center", - 0 - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 11, - "type": "CLIPVisionLoader", - "pos": [ - 50, - -350 - ], - "size": { - "0": 300, - "1": 60 - }, - "flags": {}, - "order": 4, - "mode": 0, - "outputs": [ - { - "name": "CLIP_VISION", - "type": "CLIP_VISION", - "links": [ - 80, - 86 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPVisionLoader" - }, - "widgets_values": [ - "IPAdapter_image_encoder_sd15.safetensors" - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 12, - "type": "LoadImage", - "pos": [ - -270, - -420 - ], - "size": { - "0": 230, - "1": 320 - }, - "flags": {}, - "order": 5, - "mode": 0, - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 32 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "MASK", - "type": "MASK", - "links": [], - "shape": 3, - "slot_index": 1 - } - ], - "properties": { - "Node name for S&R": "LoadImage" - }, - "widgets_values": [ - "woman.png", - "image" - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 13, - "type": "PrepImageForClipVision", - "pos": [ - 20, - -200 - ], - "size": { - "0": 243.60000610351562, - "1": 110 - }, - "flags": {}, - "order": 11, - "mode": 0, - "inputs": [ - { - "name": "image", - "type": "IMAGE", - "link": 32 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 87 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "PrepImageForClipVision" - }, - "widgets_values": [ - "LANCZOS", - "center", - 0 - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 27, - "type": "LoadImage", - "pos": [ - 480, - -600 - ], - "size": { - "0": 240, - "1": 330 - }, - "flags": {}, - "order": 6, - "mode": 0, - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 91 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "MASK", - "type": "MASK", - "links": [], - "shape": 3, - "slot_index": 1 - } - ], - "properties": { - "Node name for S&R": "LoadImage" - }, - "widgets_values": [ - "venere.jpg", - "image" - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 10, - "type": "IPAdapterModelLoader", - "pos": [ - 50, - -460 - ], - "size": { - "0": 300, - "1": 60 - }, - "flags": {}, - "order": 7, - "mode": 0, - "outputs": [ - { - "name": "IPADAPTER", - "type": "IPADAPTER", - "links": [ - 79, - 85 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterModelLoader" - }, - "widgets_values": [ - "ip-adapter-plus_sd15.safetensors" - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 51, - "type": "IPAdapterApply", - "pos": [ - 523, - -214 - ], - "size": { - "0": 210, - "1": 258 - }, - "flags": {}, - "order": 17, - "mode": 0, - "inputs": [ - { - "name": "ipadapter", - "type": "IPADAPTER", - "link": 85 - }, - { - "name": "clip_vision", - "type": "CLIP_VISION", - "link": 86 - }, - { - "name": "image", - "type": "IMAGE", - "link": 87 - }, - { - "name": "model", - "type": "MODEL", - "link": 88 - }, - { - "name": "attn_mask", - "type": "MASK", - "link": 89 - } - ], - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 90 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterApply" - }, - "widgets_values": [ - 0.7000000000000001, - 0.5, - "channel penalty", - 0, - 1, - false - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 1, - "type": "KSampler", - "pos": [ - 1160, - 300 - ], - "size": { - "0": 240, - "1": 262 - }, - "flags": {}, - "order": 19, - "mode": 0, - "inputs": [ - { - "name": "model", - "type": "MODEL", - "link": 98 - }, - { - "name": "positive", - "type": "CONDITIONING", - "link": 2 - }, - { - "name": "negative", - "type": "CONDITIONING", - "link": 3 - }, - { - "name": "latent_image", - "type": "LATENT", - "link": 4 - } - ], - "outputs": [ - { - "name": "LATENT", - "type": "LATENT", - "links": [ - 7 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "KSampler" - }, - "widgets_values": [ - 37, - "fixed", - 30, - 5, - "dpmpp_2m", - "karras", - 1 - ] - }, - { - "id": 33, - "type": "MaskComposite", - "pos": [ - -50, - 40 - ], - "size": { - "0": 210, - "1": 130 - }, - "flags": {}, - "order": 15, - "mode": 0, - "inputs": [ - { - "name": "destination", - "type": "MASK", - "link": 51 - }, - { - "name": "source", - "type": "MASK", - "link": 72 - } - ], - "outputs": [ - { - "name": "MASK", - "type": "MASK", - "links": [ - 89 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "MaskComposite" - }, - "widgets_values": [ - 0, - 0, - "add" - ], - "color": "#232", - "bgcolor": "#353" - }, - { - "id": 50, - "type": "IPAdapterApply", - "pos": [ - 1044, - -107 - ], - "size": { - "0": 210, - "1": 258 - }, - "flags": {}, - "order": 18, - "mode": 0, - "inputs": [ - { - "name": "ipadapter", - "type": "IPADAPTER", - "link": 79 - }, - { - "name": "clip_vision", - "type": "CLIP_VISION", - "link": 80 - }, - { - "name": "image", - "type": "IMAGE", - "link": 92 - }, - { - "name": "model", - "type": "MODEL", - "link": 90 - }, - { - "name": "attn_mask", - "type": "MASK", - "link": 83 - } - ], - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 98 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterApply" - }, - "widgets_values": [ - 0.7000000000000001, - 0.5, - "channel penalty", - 0, - 1, - false - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 32, - "type": "SolidMask", - "pos": [ - -570, - 100 - ], - "size": { - "0": 210, - "1": 106 - }, - "flags": {}, - "order": 8, - "mode": 0, - "outputs": [ - { - "name": "MASK", - "type": "MASK", - "links": [ - 71, - 99 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "SolidMask" - }, - "widgets_values": [ - 1, - 400, - 512 - ], - "color": "#232", - "bgcolor": "#353" - }, - { - "id": 38, - "type": "MaskComposite", - "pos": [ - 788, - 22 - ], - "size": { - "0": 210, - "1": 126 - }, - "flags": {}, - "order": 16, - "mode": 0, - "inputs": [ - { - "name": "destination", - "type": "MASK", - "link": 57 - }, - { - "name": "source", - "type": "MASK", - "link": 76 - } - ], - "outputs": [ - { - "name": "MASK", - "type": "MASK", - "links": [ - 83 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "MaskComposite" - }, - "widgets_values": [ - 368, - 0, - "add" - ], - "color": "#232", - "bgcolor": "#353" - }, - { - "id": 48, - "type": "FeatherMask", - "pos": [ - 530, - 90 - ], - "size": { - "0": 210, - "1": 130 - }, - "flags": {}, - "order": 14, - "mode": 0, - "inputs": [ - { - "name": "mask", - "type": "MASK", - "link": 99 - } - ], - "outputs": [ - { - "name": "MASK", - "type": "MASK", - "links": [ - 76 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "FeatherMask" - }, - "widgets_values": [ - 100, - 0, - 0, - 0 - ], - "color": "#232", - "bgcolor": "#353" - }, - { - "id": 47, - "type": "FeatherMask", - "pos": [ - -305, - 65 - ], - "size": { - "0": 210, - "1": 130 - }, - "flags": {}, - "order": 13, - "mode": 0, - "inputs": [ - { - "name": "mask", - "type": "MASK", - "link": 71 - } - ], - "outputs": [ - { - "name": "MASK", - "type": "MASK", - "links": [ - 72 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "FeatherMask" - }, - "widgets_values": [ - 0, - 0, - 100, - 0 - ], - "color": "#232", - "bgcolor": "#353" - } - ], - "links": [ - [ - 2, - 4, - 0, - 1, - 1, - "CONDITIONING" - ], - [ - 3, - 5, - 0, - 1, - 2, - "CONDITIONING" - ], - [ - 4, - 3, - 0, - 1, - 3, - "LATENT" - ], - [ - 5, - 2, - 1, - 4, - 0, - "CLIP" - ], - [ - 6, - 2, - 1, - 5, - 0, - "CLIP" - ], - [ - 7, - 1, - 0, - 6, - 0, - "LATENT" - ], - [ - 8, - 7, - 0, - 6, - 1, - "VAE" - ], - [ - 9, - 6, - 0, - 8, - 0, - "IMAGE" - ], - [ - 32, - 12, - 0, - 13, - 0, - "IMAGE" - ], - [ - 51, - 34, - 0, - 33, - 0, - "MASK" - ], - [ - 57, - 34, - 0, - 38, - 0, - "MASK" - ], - [ - 71, - 32, - 0, - 47, - 0, - "MASK" - ], - [ - 72, - 47, - 0, - 33, - 1, - "MASK" - ], - [ - 76, - 48, - 0, - 38, - 1, - "MASK" - ], - [ - 79, - 10, - 0, - 50, - 0, - "IPADAPTER" - ], - [ - 80, - 11, - 0, - 50, - 1, - "CLIP_VISION" - ], - [ - 83, - 38, - 0, - 50, - 4, - "MASK" - ], - [ - 85, - 10, - 0, - 51, - 0, - "IPADAPTER" - ], - [ - 86, - 11, - 0, - 51, - 1, - "CLIP_VISION" - ], - [ - 87, - 13, - 0, - 51, - 2, - "IMAGE" - ], - [ - 88, - 2, - 0, - 51, - 3, - "MODEL" - ], - [ - 89, - 33, - 0, - 51, - 4, - "MASK" - ], - [ - 90, - 51, - 0, - 50, - 3, - "MODEL" - ], - [ - 91, - 27, - 0, - 52, - 0, - "IMAGE" - ], - [ - 92, - 52, - 0, - 50, - 2, - "IMAGE" - ], - [ - 98, - 50, - 0, - 1, - 0, - "MODEL" - ], - [ - 99, - 32, - 0, - 48, - 0, - "MASK" - ] - ], - "groups": [], - "config": {}, - "extra": {}, - "version": 0.4 -} \ No newline at end of file diff --git a/examples/IPAdapter_mask.json b/examples/IPAdapter_mask.json deleted file mode 100644 index e2e5045..0000000 --- a/examples/IPAdapter_mask.json +++ /dev/null @@ -1,668 +0,0 @@ -{ - "last_node_id": 51, - "last_link_id": 96, - "nodes": [ - { - "id": 5, - "type": "CLIPTextEncode", - "pos": [ - 550, - 510 - ], - "size": { - "0": 400, - "1": 160 - }, - "flags": {}, - "order": 7, - "mode": 0, - "inputs": [ - { - "name": "clip", - "type": "CLIP", - "link": 6 - } - ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 3 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPTextEncode" - }, - "widgets_values": [ - "blurry, malformed, video game, rendering, naked, cleavage, horror, zombie, text, watermark" - ], - "color": "#322", - "bgcolor": "#533" - }, - { - "id": 6, - "type": "VAEDecode", - "pos": [ - 1360, - 270 - ], - "size": { - "0": 140, - "1": 50 - }, - "flags": {}, - "order": 11, - "mode": 0, - "inputs": [ - { - "name": "samples", - "type": "LATENT", - "link": 7 - }, - { - "name": "vae", - "type": "VAE", - "link": 8 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 9 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAEDecode" - } - }, - { - "id": 7, - "type": "VAELoader", - "pos": [ - 1090, - 570 - ], - "size": { - "0": 240, - "1": 60 - }, - "flags": {}, - "order": 0, - "mode": 0, - "outputs": [ - { - "name": "VAE", - "type": "VAE", - "links": [ - 8 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAELoader" - }, - "widgets_values": [ - "vae-ft-mse-840000-ema-pruned.safetensors" - ] - }, - { - "id": 2, - "type": "CheckpointLoaderSimple", - "pos": [ - 210, - 410 - ], - "size": { - "0": 290, - "1": 100 - }, - "flags": {}, - "order": 1, - "mode": 0, - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 88 - ], - "slot_index": 0 - }, - { - "name": "CLIP", - "type": "CLIP", - "links": [ - 5, - 6 - ], - "slot_index": 1 - }, - { - "name": "VAE", - "type": "VAE", - "links": [], - "slot_index": 2 - } - ], - "properties": { - "Node name for S&R": "CheckpointLoaderSimple" - }, - "widgets_values": [ - "sd15/dreamshaper_8.safetensors" - ] - }, - { - "id": 11, - "type": "CLIPVisionLoader", - "pos": [ - 490, - 20 - ], - "size": { - "0": 300, - "1": 60 - }, - "flags": {}, - "order": 2, - "mode": 0, - "outputs": [ - { - "name": "CLIP_VISION", - "type": "CLIP_VISION", - "links": [ - 86 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPVisionLoader" - }, - "widgets_values": [ - "IPAdapter_image_encoder_sd15.safetensors" - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 13, - "type": "PrepImageForClipVision", - "pos": [ - 540, - 130 - ], - "size": { - "0": 243.60000610351562, - "1": 110 - }, - "flags": {}, - "order": 8, - "mode": 0, - "inputs": [ - { - "name": "image", - "type": "IMAGE", - "link": 32 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 87 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "PrepImageForClipVision" - }, - "widgets_values": [ - "LANCZOS", - "center", - 0 - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 4, - "type": "CLIPTextEncode", - "pos": [ - 550, - 310 - ], - "size": { - "0": 400, - "1": 160 - }, - "flags": {}, - "order": 6, - "mode": 0, - "inputs": [ - { - "name": "clip", - "type": "CLIP", - "link": 5 - } - ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 2 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPTextEncode" - }, - "widgets_values": [ - "photography of a warrior woman in a cherry blossom forest, high quality, highly detailed" - ], - "color": "#232", - "bgcolor": "#353" - }, - { - "id": 3, - "type": "EmptyLatentImage", - "pos": [ - 740, - 720 - ], - "size": { - "0": 210, - "1": 110 - }, - "flags": {}, - "order": 3, - "mode": 0, - "outputs": [ - { - "name": "LATENT", - "type": "LATENT", - "links": [ - 4 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "EmptyLatentImage" - }, - "widgets_values": [ - 768, - 512, - 1 - ] - }, - { - "id": 1, - "type": "KSampler", - "pos": [ - 1090, - 270 - ], - "size": { - "0": 240, - "1": 262 - }, - "flags": {}, - "order": 10, - "mode": 0, - "inputs": [ - { - "name": "model", - "type": "MODEL", - "link": 93 - }, - { - "name": "positive", - "type": "CONDITIONING", - "link": 2 - }, - { - "name": "negative", - "type": "CONDITIONING", - "link": 3 - }, - { - "name": "latent_image", - "type": "LATENT", - "link": 4 - } - ], - "outputs": [ - { - "name": "LATENT", - "type": "LATENT", - "links": [ - 7 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "KSampler" - }, - "widgets_values": [ - 40, - "fixed", - 30, - 5, - "ddim", - "ddim_uniform", - 1 - ] - }, - { - "id": 12, - "type": "LoadImage", - "pos": [ - 230, - -80 - ], - "size": { - "0": 230, - "1": 320 - }, - "flags": {}, - "order": 4, - "mode": 0, - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 32 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "MASK", - "type": "MASK", - "links": [ - 96 - ], - "shape": 3, - "slot_index": 1 - } - ], - "properties": { - "Node name for S&R": "LoadImage" - }, - "widgets_values": [ - "clipspace/clipspace-mask-790059.png [input]", - "image" - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 8, - "type": "PreviewImage", - "pos": [ - 1365, - 369 - ], - "size": { - "0": 675.9465942382812, - "1": 480.1444091796875 - }, - "flags": {}, - "order": 12, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 9 - } - ], - "properties": { - "Node name for S&R": "PreviewImage" - } - }, - { - "id": 51, - "type": "IPAdapterApply", - "pos": [ - 829, - -23 - ], - "size": [ - 210, - 258 - ], - "flags": {}, - "order": 9, - "mode": 0, - "inputs": [ - { - "name": "ipadapter", - "type": "IPADAPTER", - "link": 85 - }, - { - "name": "clip_vision", - "type": "CLIP_VISION", - "link": 86 - }, - { - "name": "image", - "type": "IMAGE", - "link": 87 - }, - { - "name": "model", - "type": "MODEL", - "link": 88 - }, - { - "name": "attn_mask", - "type": "MASK", - "link": 96 - } - ], - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 93 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterApply" - }, - "widgets_values": [ - 0.7000000000000001, - 0, - "linear", - 0, - 1, - false - ], - "color": "#223", - "bgcolor": "#335" - }, - { - "id": 10, - "type": "IPAdapterModelLoader", - "pos": [ - 490, - -80 - ], - "size": { - "0": 300, - "1": 60 - }, - "flags": {}, - "order": 5, - "mode": 0, - "outputs": [ - { - "name": "IPADAPTER", - "type": "IPADAPTER", - "links": [ - 85 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterModelLoader" - }, - "widgets_values": [ - "ip-adapter-plus_sd15.safetensors" - ], - "color": "#223", - "bgcolor": "#335" - } - ], - "links": [ - [ - 2, - 4, - 0, - 1, - 1, - "CONDITIONING" - ], - [ - 3, - 5, - 0, - 1, - 2, - "CONDITIONING" - ], - [ - 4, - 3, - 0, - 1, - 3, - "LATENT" - ], - [ - 5, - 2, - 1, - 4, - 0, - "CLIP" - ], - [ - 6, - 2, - 1, - 5, - 0, - "CLIP" - ], - [ - 7, - 1, - 0, - 6, - 0, - "LATENT" - ], - [ - 8, - 7, - 0, - 6, - 1, - "VAE" - ], - [ - 9, - 6, - 0, - 8, - 0, - "IMAGE" - ], - [ - 32, - 12, - 0, - 13, - 0, - "IMAGE" - ], - [ - 85, - 10, - 0, - 51, - 0, - "IPADAPTER" - ], - [ - 86, - 11, - 0, - 51, - 1, - "CLIP_VISION" - ], - [ - 87, - 13, - 0, - 51, - 2, - "IMAGE" - ], - [ - 88, - 2, - 0, - 51, - 3, - "MODEL" - ], - [ - 93, - 51, - 0, - 1, - 0, - "MODEL" - ], - [ - 96, - 12, - 1, - 51, - 4, - "MASK" - ] - ], - "groups": [], - "config": {}, - "extra": {}, - "version": 0.4 -} \ No newline at end of file diff --git a/examples/IPAdapter_sdxl_vit-h.json b/examples/IPAdapter_simple.json similarity index 72% rename from examples/IPAdapter_sdxl_vit-h.json rename to examples/IPAdapter_simple.json index dc20bf4..e43b058 100644 --- a/examples/IPAdapter_sdxl_vit-h.json +++ b/examples/IPAdapter_simple.json @@ -1,26 +1,224 @@ { - "last_node_id": 12, - "last_link_id": 13, + "last_node_id": 13, + "last_link_id": 17, "nodes": [ { - "id": 8, - "type": "CLIPTextEncode", + "id": 11, + "type": "IPAdapterUnifiedLoader", "pos": [ - 650, - 420 + 440, + 440 ], "size": { - "0": 210, - "1": 120 + "0": 315, + "1": 78 }, "flags": {}, - "order": 8, + "order": 3, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 10 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": null + } + ], + "outputs": [ + { + "name": "model", + "type": "MODEL", + "links": [ + 11 + ], + "shape": 3, + "slot_index": 0 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "links": [ + 12 + ], + "shape": 3, + "slot_index": 1 + } + ], + "properties": { + "Node name for S&R": "IPAdapterUnifiedLoader" + }, + "widgets_values": [ + "PLUS (high strength)" + ] + }, + { + "id": 4, + "type": "CheckpointLoaderSimple", + "pos": [ + 50, + 730 + ], + "size": { + "0": 315, + "1": 98 + }, + "flags": {}, + "order": 0, + "mode": 0, + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 10 + ], + "slot_index": 0 + }, + { + "name": "CLIP", + "type": "CLIP", + "links": [ + 3, + 5 + ], + "slot_index": 1 + }, + { + "name": "VAE", + "type": "VAE", + "links": [ + 8 + ], + "slot_index": 2 + } + ], + "properties": { + "Node name for S&R": "CheckpointLoaderSimple" + }, + "widgets_values": [ + "sd15/realisticVisionV51_v51VAE.safetensors" + ] + }, + { + "id": 12, + "type": "LoadImage", + "pos": [ + 440, + 60 + ], + "size": [ + 315, + 314 + ], + "flags": {}, + "order": 1, + "mode": 0, + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 17 + ], + "shape": 3 + }, + { + "name": "MASK", + "type": "MASK", + "links": null, + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "warrior_woman.png", + "image" + ] + }, + { + "id": 3, + "type": "KSampler", + "pos": [ + 1210, + 700 + ], + "size": { + "0": 315, + "1": 262 + }, + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 13 + }, + { + "name": "positive", + "type": "CONDITIONING", + "link": 4 + }, + { + "name": "negative", + "type": "CONDITIONING", + "link": 6 + }, + { + "name": "latent_image", + "type": "LATENT", + "link": 2 + } + ], + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 7 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "KSampler" + }, + "widgets_values": [ + 0, + "fixed", + 30, + 6.5, + "dpmpp_2m", + "karras", + 1 + ] + }, + { + "id": 6, + "type": "CLIPTextEncode", + "pos": [ + 690, + 610 + ], + "size": { + "0": 422.84503173828125, + "1": 164.31304931640625 + }, + "flags": {}, + "order": 4, "mode": 0, "inputs": [ { "name": "clip", "type": "CLIP", - "link": 6 + "link": 3 } ], "outputs": [ @@ -28,9 +226,8 @@ "name": "CONDITIONING", "type": "CONDITIONING", "links": [ - 9 + 4 ], - "shape": 3, "slot_index": 0 } ], @@ -38,24 +235,105 @@ "Node name for S&R": "CLIPTextEncode" }, "widgets_values": [ - "blurry, horror" + "closeup of a fierce warrior woman wearing a full armor at the end of a battle\n\nhigh quality, detailed" + ] + }, + { + "id": 10, + "type": "IPAdapter", + "pos": [ + 820, + 350 ], - "color": "#322", - "bgcolor": "#533" + "size": { + "0": 315, + "1": 166 + }, + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 11 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": 12 + }, + { + "name": "image", + "type": "IMAGE", + "link": 17, + "slot_index": 2 + }, + { + "name": "attn_mask", + "type": "MASK", + "link": null + } + ], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 13 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "IPAdapter" + }, + "widgets_values": [ + 0.8, + 0, + 1 + ] + }, + { + "id": 9, + "type": "SaveImage", + "pos": [ + 1770, + 710 + ], + "size": [ + 529.7760009765616, + 582.3048192804504 + ], + "flags": {}, + "order": 9, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 9 + } + ], + "properties": {}, + "widgets_values": [ + "IPAdapter" + ] }, { "id": 7, "type": "CLIPTextEncode", "pos": [ - 650, - 250 + 690, + 840 ], "size": { - "0": 210, - "1": 120 + "0": 425.27801513671875, + "1": 180.6060791015625 }, "flags": {}, - "order": 7, + "order": 5, "mode": 0, "inputs": [ { @@ -69,9 +347,8 @@ "name": "CONDITIONING", "type": "CONDITIONING", "links": [ - 8 + 6 ], - "shape": 3, "slot_index": 0 } ], @@ -79,35 +356,33 @@ "Node name for S&R": "CLIPTextEncode" }, "widgets_values": [ - "beautiful renaissance girl, detailed" - ], - "color": "#232", - "bgcolor": "#353" + "blurry, noisy, messy, lowres, jpeg, artifacts, ill, distorted, malformed" + ] }, { - "id": 11, + "id": 8, "type": "VAEDecode", "pos": [ - 1300, - 170 + 1570, + 700 + ], + "size": [ + 140, + 46 ], - "size": { - "0": 140, - "1": 50 - }, "flags": {}, - "order": 10, + "order": 8, "mode": 0, "inputs": [ { "name": "samples", "type": "LATENT", - "link": 11 + "link": 7 }, { "name": "vae", "type": "VAE", - "link": 12 + "link": 8 } ], "outputs": [ @@ -115,9 +390,8 @@ "name": "IMAGE", "type": "IMAGE", "links": [ - 13 + 9 ], - "shape": 3, "slot_index": 0 } ], @@ -126,112 +400,15 @@ } }, { - "id": 12, - "type": "SaveImage", - "pos": [ - 1300, - 270 - ], - "size": { - "0": 400, - "1": 450 - }, - "flags": {}, - "order": 11, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 13 - } - ], - "properties": {}, - "widgets_values": [ - "IPAdapter" - ] - }, - { - "id": 6, - "type": "LoadImage", - "pos": [ - 40, - 60 - ], - "size": { - "0": 220, - "1": 320 - }, - "flags": {}, - "order": 0, - "mode": 0, - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 3 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "MASK", - "type": "MASK", - "links": null, - "shape": 3 - } - ], - "properties": { - "Node name for S&R": "LoadImage" - }, - "widgets_values": [ - "venere.jpg", - "image" - ] - }, - { - "id": 2, - "type": "VAELoader", - "pos": [ - 940, - 480 - ], - "size": { - "0": 300, - "1": 60 - }, - "flags": {}, - "order": 1, - "mode": 0, - "outputs": [ - { - "name": "VAE", - "type": "VAE", - "links": [ - 12 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAELoader" - }, - "widgets_values": [ - "sdxl_vae.safetensors" - ] - }, - { - "id": 10, + "id": 5, "type": "EmptyLatentImage", "pos": [ - 650, - 590 + 801, + 1097 ], "size": { - "0": 210, - "1": 110 + "0": 315, + "1": 106 }, "flags": {}, "order": 2, @@ -241,9 +418,8 @@ "name": "LATENT", "type": "LATENT", "links": [ - 10 + 2 ], - "shape": 3, "slot_index": 0 } ], @@ -251,284 +427,40 @@ "Node name for S&R": "EmptyLatentImage" }, "widgets_values": [ - 1024, - 1024, + 512, + 512, 1 ] - }, - { - "id": 9, - "type": "KSampler", - "pos": [ - 930, - 170 - ], - "size": { - "0": 315, - "1": 262 - }, - "flags": {}, - "order": 9, - "mode": 0, - "inputs": [ - { - "name": "model", - "type": "MODEL", - "link": 7 - }, - { - "name": "positive", - "type": "CONDITIONING", - "link": 8 - }, - { - "name": "negative", - "type": "CONDITIONING", - "link": 9 - }, - { - "name": "latent_image", - "type": "LATENT", - "link": 10 - } - ], - "outputs": [ - { - "name": "LATENT", - "type": "LATENT", - "links": [ - 11 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "KSampler" - }, - "widgets_values": [ - 0, - "fixed", - 25, - 5, - "ddim", - "ddim_uniform", - 1 - ] - }, - { - "id": 4, - "type": "CLIPVisionLoader", - "pos": [ - 290, - 170 - ], - "size": { - "0": 300, - "1": 60 - }, - "flags": {}, - "order": 3, - "mode": 0, - "outputs": [ - { - "name": "CLIP_VISION", - "type": "CLIP_VISION", - "links": [ - 2 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPVisionLoader" - }, - "widgets_values": [ - "IPAdapter_image_encoder_sd15.safetensors" - ] - }, - { - "id": 5, - "type": "IPAdapterApply", - "pos": [ - 652, - -55 - ], - "size": { - "0": 210, - "1": 258 - }, - "flags": {}, - "order": 6, - "mode": 0, - "inputs": [ - { - "name": "ipadapter", - "type": "IPADAPTER", - "link": 1 - }, - { - "name": "clip_vision", - "type": "CLIP_VISION", - "link": 2 - }, - { - "name": "image", - "type": "IMAGE", - "link": 3 - }, - { - "name": "model", - "type": "MODEL", - "link": 4 - }, - { - "name": "attn_mask", - "type": "MASK", - "link": null - } - ], - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 7 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterApply" - }, - "widgets_values": [ - 0.8, - 0, - "original", - 0, - 1, - false - ] - }, - { - "id": 3, - "type": "IPAdapterModelLoader", - "pos": [ - 290, - 60 - ], - "size": { - "0": 300, - "1": 60 - }, - "flags": {}, - "order": 4, - "mode": 0, - "outputs": [ - { - "name": "IPADAPTER", - "type": "IPADAPTER", - "links": [ - 1 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterModelLoader" - }, - "widgets_values": [ - "ip-adapter_sdxl_vit-h.safetensors" - ] - }, - { - "id": 1, - "type": "CheckpointLoaderSimple", - "pos": [ - 290, - 280 - ], - "size": { - "0": 300, - "1": 100 - }, - "flags": {}, - "order": 5, - "mode": 0, - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 4 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "CLIP", - "type": "CLIP", - "links": [ - 5, - 6 - ], - "shape": 3, - "slot_index": 1 - }, - { - "name": "VAE", - "type": "VAE", - "links": null, - "shape": 3 - } - ], - "properties": { - "Node name for S&R": "CheckpointLoaderSimple" - }, - "widgets_values": [ - "sdxl/sd_xl_base_1.0_0.9vae.safetensors" - ] } ], "links": [ - [ - 1, - 3, - 0, - 5, - 0, - "IPADAPTER" - ], [ 2, - 4, - 0, 5, - 1, - "CLIP_VISION" + 0, + 3, + 3, + "LATENT" ], [ 3, + 4, + 1, 6, 0, - 5, - 2, - "IMAGE" + "CLIP" ], [ 4, - 1, + 6, 0, - 5, 3, - "MODEL" + 1, + "CONDITIONING" ], [ 5, - 1, + 4, 1, 7, 0, @@ -536,66 +468,74 @@ ], [ 6, - 1, - 1, - 8, - 0, - "CLIP" - ], - [ - 7, - 5, - 0, - 9, - 0, - "MODEL" - ], - [ - 8, 7, 0, - 9, - 1, - "CONDITIONING" - ], - [ - 9, - 8, - 0, - 9, - 2, - "CONDITIONING" - ], - [ - 10, - 10, - 0, - 9, 3, - "LATENT" - ], - [ - 11, - 9, - 0, - 11, - 0, - "LATENT" - ], - [ - 12, 2, + "CONDITIONING" + ], + [ + 7, + 3, 0, - 11, + 8, + 0, + "LATENT" + ], + [ + 8, + 4, + 2, + 8, 1, "VAE" ], [ - 13, + 9, + 8, + 0, + 9, + 0, + "IMAGE" + ], + [ + 10, + 4, + 0, 11, 0, + "MODEL" + ], + [ + 11, + 11, + 0, + 10, + 0, + "MODEL" + ], + [ + 12, + 11, + 1, + 10, + 1, + "IPADAPTER" + ], + [ + 13, + 10, + 0, + 3, + 0, + "MODEL" + ], + [ + 17, 12, 0, + 10, + 2, "IMAGE" ] ], diff --git a/examples/IPAdapter_weighted.json b/examples/IPAdapter_weighted.json deleted file mode 100644 index 7eeb8c4..0000000 --- a/examples/IPAdapter_weighted.json +++ /dev/null @@ -1,719 +0,0 @@ -{ - "last_node_id": 15, - "last_link_id": 22, - "nodes": [ - { - "id": 10, - "type": "EmptyLatentImage", - "pos": [ - 820, - 520 - ], - "size": { - "0": 210, - "1": 110 - }, - "flags": {}, - "order": 0, - "mode": 0, - "outputs": [ - { - "name": "LATENT", - "type": "LATENT", - "links": [ - 10 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "EmptyLatentImage" - }, - "widgets_values": [ - 512, - 512, - 1 - ] - }, - { - "id": 8, - "type": "CLIPTextEncode", - "pos": [ - 820, - 350 - ], - "size": { - "0": 210, - "1": 120 - }, - "flags": {}, - "order": 8, - "mode": 0, - "inputs": [ - { - "name": "clip", - "type": "CLIP", - "link": 6 - } - ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 9 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPTextEncode" - }, - "widgets_values": [ - "blurry, horror" - ], - "color": "#322", - "bgcolor": "#533" - }, - { - "id": 7, - "type": "CLIPTextEncode", - "pos": [ - 820, - 180 - ], - "size": { - "0": 210, - "1": 120 - }, - "flags": {}, - "order": 7, - "mode": 0, - "inputs": [ - { - "name": "clip", - "type": "CLIP", - "link": 5 - } - ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 8 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPTextEncode" - }, - "widgets_values": [ - "beautiful renaissance girl, detailed" - ], - "color": "#232", - "bgcolor": "#353" - }, - { - "id": 11, - "type": "VAEDecode", - "pos": [ - 1470, - 120 - ], - "size": { - "0": 140, - "1": 50 - }, - "flags": {}, - "order": 12, - "mode": 0, - "inputs": [ - { - "name": "samples", - "type": "LATENT", - "link": 11 - }, - { - "name": "vae", - "type": "VAE", - "link": 12 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 13 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAEDecode" - } - }, - { - "id": 12, - "type": "SaveImage", - "pos": [ - 1470, - 220 - ], - "size": { - "0": 400, - "1": 450 - }, - "flags": {}, - "order": 13, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 13 - } - ], - "properties": {}, - "widgets_values": [ - "IPAdapter" - ] - }, - { - "id": 4, - "type": "CLIPVisionLoader", - "pos": [ - 120, - -280 - ], - "size": { - "0": 300, - "1": 60 - }, - "flags": {}, - "order": 1, - "mode": 0, - "outputs": [ - { - "name": "CLIP_VISION", - "type": "CLIP_VISION", - "links": [ - 16 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPVisionLoader" - }, - "widgets_values": [ - "IPAdapter_image_encoder_sd15.safetensors" - ] - }, - { - "id": 15, - "type": "LoadImage", - "pos": [ - -40, - -170 - ], - "size": { - "0": 220, - "1": 320 - }, - "flags": {}, - "order": 2, - "mode": 0, - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 21 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "MASK", - "type": "MASK", - "links": null, - "shape": 3 - } - ], - "properties": { - "Node name for S&R": "LoadImage" - }, - "widgets_values": [ - "cwf_portrait.jpg", - "image" - ] - }, - { - "id": 1, - "type": "CheckpointLoaderSimple", - "pos": [ - 410, - 210 - ], - "size": { - "0": 300, - "1": 100 - }, - "flags": {}, - "order": 3, - "mode": 0, - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 19 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "CLIP", - "type": "CLIP", - "links": [ - 5, - 6 - ], - "shape": 3, - "slot_index": 1 - }, - { - "name": "VAE", - "type": "VAE", - "links": null, - "shape": 3 - } - ], - "properties": { - "Node name for S&R": "CheckpointLoaderSimple" - }, - "widgets_values": [ - "v1-5-pruned-emaonly.safetensors" - ] - }, - { - "id": 6, - "type": "LoadImage", - "pos": [ - 200, - -170 - ], - "size": { - "0": 220, - "1": 320 - }, - "flags": {}, - "order": 4, - "mode": 0, - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 20 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "MASK", - "type": "MASK", - "links": null, - "shape": 3 - } - ], - "properties": { - "Node name for S&R": "LoadImage" - }, - "widgets_values": [ - "venere.jpg", - "image" - ] - }, - { - "id": 2, - "type": "VAELoader", - "pos": [ - 1110, - 460 - ], - "size": { - "0": 300, - "1": 60 - }, - "flags": {}, - "order": 5, - "mode": 0, - "outputs": [ - { - "name": "VAE", - "type": "VAE", - "links": [ - 12 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAELoader" - }, - "widgets_values": [ - "vae-ft-mse-840000-ema-pruned.safetensors" - ] - }, - { - "id": 14, - "type": "IPAdapterEncoder", - "pos": [ - 500, - -100 - ], - "size": { - "0": 210, - "1": 260 - }, - "flags": {}, - "order": 9, - "mode": 0, - "inputs": [ - { - "name": "clip_vision", - "type": "CLIP_VISION", - "link": 16 - }, - { - "name": "image_1", - "type": "IMAGE", - "link": 21 - }, - { - "name": "image_2", - "type": "IMAGE", - "link": 20 - }, - { - "name": "image_3", - "type": "IMAGE", - "link": null - }, - { - "name": "image_4", - "type": "IMAGE", - "link": null - } - ], - "outputs": [ - { - "name": "EMBEDS", - "type": "EMBEDS", - "links": [ - 18 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterEncoder" - }, - "widgets_values": [ - false, - 0.31, - 0.38, - 1, - 1, - 1 - ] - }, - { - "id": 9, - "type": "KSampler", - "pos": [ - 1100, - 150 - ], - "size": { - "0": 315, - "1": 262 - }, - "flags": {}, - "order": 11, - "mode": 0, - "inputs": [ - { - "name": "model", - "type": "MODEL", - "link": 22 - }, - { - "name": "positive", - "type": "CONDITIONING", - "link": 8 - }, - { - "name": "negative", - "type": "CONDITIONING", - "link": 9 - }, - { - "name": "latent_image", - "type": "LATENT", - "link": 10 - } - ], - "outputs": [ - { - "name": "LATENT", - "type": "LATENT", - "links": [ - 11 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "KSampler" - }, - "widgets_values": [ - 0, - "fixed", - 35, - 5, - "ddim", - "ddim_uniform", - 1 - ] - }, - { - "id": 3, - "type": "IPAdapterModelLoader", - "pos": [ - 450, - -210 - ], - "size": { - "0": 260, - "1": 60 - }, - "flags": {}, - "order": 6, - "mode": 0, - "outputs": [ - { - "name": "IPADAPTER", - "type": "IPADAPTER", - "links": [ - 17 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterModelLoader" - }, - "widgets_values": [ - "ip-adapter_sd15.safetensors" - ] - }, - { - "id": 13, - "type": "IPAdapterApplyEncoded", - "pos": [ - 804, - -87 - ], - "size": [ - 235.1999969482422, - 214 - ], - "flags": {}, - "order": 10, - "mode": 0, - "inputs": [ - { - "name": "ipadapter", - "type": "IPADAPTER", - "link": 17 - }, - { - "name": "embeds", - "type": "EMBEDS", - "link": 18 - }, - { - "name": "model", - "type": "MODEL", - "link": 19 - }, - { - "name": "attn_mask", - "type": "MASK", - "link": null - } - ], - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 22 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterApplyEncoded" - }, - "widgets_values": [ - 1, - "original", - 0, - 1, - false - ] - } - ], - "links": [ - [ - 5, - 1, - 1, - 7, - 0, - "CLIP" - ], - [ - 6, - 1, - 1, - 8, - 0, - "CLIP" - ], - [ - 8, - 7, - 0, - 9, - 1, - "CONDITIONING" - ], - [ - 9, - 8, - 0, - 9, - 2, - "CONDITIONING" - ], - [ - 10, - 10, - 0, - 9, - 3, - "LATENT" - ], - [ - 11, - 9, - 0, - 11, - 0, - "LATENT" - ], - [ - 12, - 2, - 0, - 11, - 1, - "VAE" - ], - [ - 13, - 11, - 0, - 12, - 0, - "IMAGE" - ], - [ - 16, - 4, - 0, - 14, - 0, - "CLIP_VISION" - ], - [ - 17, - 3, - 0, - 13, - 0, - "IPADAPTER" - ], - [ - 18, - 14, - 0, - 13, - 1, - "EMBEDS" - ], - [ - 19, - 1, - 0, - 13, - 2, - "MODEL" - ], - [ - 20, - 6, - 0, - 14, - 2, - "IMAGE" - ], - [ - 21, - 15, - 0, - 14, - 1, - "IMAGE" - ], - [ - 22, - 13, - 0, - 9, - 0, - "MODEL" - ] - ], - "groups": [], - "config": {}, - "extra": {}, - "version": 0.4 -} \ No newline at end of file diff --git a/examples/batch_images.jpg b/examples/batch_images.jpg deleted file mode 100644 index fffae3e..0000000 Binary files a/examples/batch_images.jpg and /dev/null differ diff --git a/examples/canny_controlnet.jpg b/examples/canny_controlnet.jpg deleted file mode 100644 index 8fd1ef5..0000000 Binary files a/examples/canny_controlnet.jpg and /dev/null differ diff --git a/examples/demo_workflow.jpg b/examples/demo_workflow.jpg new file mode 100644 index 0000000..d30bb7c Binary files /dev/null and b/examples/demo_workflow.jpg differ diff --git a/examples/face_id_wf.jpg b/examples/face_id_wf.jpg deleted file mode 100644 index 076a040..0000000 Binary files a/examples/face_id_wf.jpg and /dev/null differ diff --git a/examples/face_swap.jpg b/examples/face_swap.jpg deleted file mode 100644 index d638483..0000000 Binary files a/examples/face_swap.jpg and /dev/null differ diff --git a/examples/image_weighting.jpg b/examples/image_weighting.jpg deleted file mode 100644 index 94c27ec..0000000 Binary files a/examples/image_weighting.jpg and /dev/null differ diff --git a/examples/inpainting.jpg b/examples/inpainting.jpg deleted file mode 100644 index d8ab437..0000000 Binary files a/examples/inpainting.jpg and /dev/null differ diff --git a/examples/IPAdapter_face.json b/examples/ipadapter_advanced.json similarity index 76% rename from examples/IPAdapter_face.json rename to examples/ipadapter_advanced.json index ddb4a31..ae712dd 100644 --- a/examples/IPAdapter_face.json +++ b/examples/ipadapter_advanced.json @@ -1,59 +1,66 @@ { - "last_node_id": 18, - "last_link_id": 28, + "last_node_id": 17, + "last_link_id": 26, "nodes": [ { - "id": 11, - "type": "VAEDecode", + "id": 4, + "type": "CheckpointLoaderSimple", "pos": [ - 1300, - 170 + 50, + 730 ], "size": { - "0": 140, - "1": 50 + "0": 315, + "1": 98 }, "flags": {}, - "order": 10, + "order": 0, "mode": 0, - "inputs": [ - { - "name": "samples", - "type": "LATENT", - "link": 11 - }, - { - "name": "vae", - "type": "VAE", - "link": 12 - } - ], "outputs": [ { - "name": "IMAGE", - "type": "IMAGE", + "name": "MODEL", + "type": "MODEL", "links": [ - 13 + 20 ], - "shape": 3, "slot_index": 0 + }, + { + "name": "CLIP", + "type": "CLIP", + "links": [ + 3, + 5 + ], + "slot_index": 1 + }, + { + "name": "VAE", + "type": "VAE", + "links": [ + 8 + ], + "slot_index": 2 } ], "properties": { - "Node name for S&R": "VAEDecode" - } + "Node name for S&R": "CheckpointLoaderSimple" + }, + "widgets_values": [ + "sd15/realisticVisionV51_v51VAE.safetensors" + ] }, { - "id": 12, + "id": 9, "type": "SaveImage", "pos": [ - 1300, - 270 + 1770, + 710 + ], + "size": [ + 529.7760009765616, + 582.3048192804504 ], - "size": { - "0": 400, - "1": 450 - }, "flags": {}, "order": 11, "mode": 0, @@ -61,7 +68,7 @@ { "name": "images", "type": "IMAGE", - "link": 13 + "link": 9 } ], "properties": {}, @@ -69,51 +76,19 @@ "IPAdapter" ] }, - { - "id": 2, - "type": "VAELoader", - "pos": [ - 940, - 480 - ], - "size": { - "0": 300, - "1": 60 - }, - "flags": {}, - "order": 0, - "mode": 0, - "outputs": [ - { - "name": "VAE", - "type": "VAE", - "links": [ - 12 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAELoader" - }, - "widgets_values": [ - "vae-ft-mse-840000-ema-pruned.safetensors" - ] - }, { "id": 7, "type": "CLIPTextEncode", "pos": [ - 650, - 250 + 690, + 840 ], "size": { - "0": 210, - "1": 120 + "0": 425.27801513671875, + "1": 180.6060791015625 }, "flags": {}, - "order": 7, + "order": 6, "mode": 0, "inputs": [ { @@ -127,9 +102,8 @@ "name": "CONDITIONING", "type": "CONDITIONING", "links": [ - 25 + 6 ], - "shape": 3, "slot_index": 0 } ], @@ -137,21 +111,59 @@ "Node name for S&R": "CLIPTextEncode" }, "widgets_values": [ - "closeup photo of a guy flexing muscles at the gym" - ], - "color": "#232", - "bgcolor": "#353" + "blurry, noisy, messy, lowres, jpeg, artifacts, ill, distorted, malformed" + ] }, { - "id": 10, + "id": 8, + "type": "VAEDecode", + "pos": [ + 1570, + 700 + ], + "size": [ + 140, + 46 + ], + "flags": {}, + "order": 10, + "mode": 0, + "inputs": [ + { + "name": "samples", + "type": "LATENT", + "link": 7 + }, + { + "name": "vae", + "type": "VAE", + "link": 8 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 9 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "VAEDecode" + } + }, + { + "id": 5, "type": "EmptyLatentImage", "pos": [ - 650, - 590 + 801, + 1097 ], "size": { - "0": 210, - "1": 110 + "0": 315, + "1": 106 }, "flags": {}, "order": 1, @@ -161,9 +173,8 @@ "name": "LATENT", "type": "LATENT", "links": [ - 26 + 2 ], - "shape": 3, "slot_index": 0 } ], @@ -177,25 +188,198 @@ ] }, { - "id": 14, - "type": "LoadImage", + "id": 16, + "type": "CLIPVisionLoader", "pos": [ - 40, - 60 + 308, + 161 ], "size": { - "0": 220, - "1": 320 + "0": 315, + "1": 58 }, "flags": {}, "order": 2, "mode": 0, + "outputs": [ + { + "name": "CLIP_VISION", + "type": "CLIP_VISION", + "links": [ + 24 + ], + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "CLIPVisionLoader" + }, + "widgets_values": [ + "IPAdapter_image_encoder_sd15.safetensors" + ] + }, + { + "id": 15, + "type": "IPAdapterModelLoader", + "pos": [ + 308, + 52 + ], + "size": { + "0": 315, + "1": 58 + }, + "flags": {}, + "order": 3, + "mode": 0, + "outputs": [ + { + "name": "IPADAPTER", + "type": "IPADAPTER", + "links": [ + 21 + ], + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "IPAdapterModelLoader" + }, + "widgets_values": [ + "ip-adapter-plus_sd15.safetensors" + ] + }, + { + "id": 14, + "type": "IPAdapterAdvanced", + "pos": [ + 793, + 304 + ], + "size": { + "0": 315, + "1": 254 + }, + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 20 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": 21, + "slot_index": 1 + }, + { + "name": "image", + "type": "IMAGE", + "link": 26 + }, + { + "name": "image_negative", + "type": "IMAGE", + "link": null + }, + { + "name": "attn_mask", + "type": "MASK", + "link": null + }, + { + "name": "clip_vision", + "type": "CLIP_VISION", + "link": 24, + "slot_index": 5 + } + ], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 23 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "IPAdapterAdvanced" + }, + "widgets_values": [ + 0.8, + "linear", + "concat", + 0, + 1 + ] + }, + { + "id": 17, + "type": "PrepImageForClipVision", + "pos": [ + 798, + 145 + ], + "size": { + "0": 315, + "1": 106 + }, + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [ + { + "name": "image", + "type": "IMAGE", + "link": 25 + } + ], "outputs": [ { "name": "IMAGE", "type": "IMAGE", "links": [ - 28 + 26 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "PrepImageForClipVision" + }, + "widgets_values": [ + "LANCZOS", + "top", + 0.15 + ] + }, + { + "id": 12, + "type": "LoadImage", + "pos": [ + 311, + 270 + ], + "size": [ + 315, + 314 + ], + "flags": {}, + "order": 4, + "mode": 0, + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 25 ], "shape": 3, "slot_index": 0 @@ -211,48 +395,54 @@ "Node name for S&R": "LoadImage" }, "widgets_values": [ - "einstein.jpg", + "girl_sitting.png", "image" ] }, { - "id": 4, - "type": "CLIPVisionLoader", + "id": 6, + "type": "CLIPTextEncode", "pos": [ - 290, - 170 + 690, + 610 ], "size": { - "0": 300, - "1": 60 + "0": 422.84503173828125, + "1": 164.31304931640625 }, "flags": {}, - "order": 3, + "order": 5, "mode": 0, + "inputs": [ + { + "name": "clip", + "type": "CLIP", + "link": 3 + } + ], "outputs": [ { - "name": "CLIP_VISION", - "type": "CLIP_VISION", + "name": "CONDITIONING", + "type": "CONDITIONING", "links": [ - 2 + 4 ], - "shape": 3, "slot_index": 0 } ], "properties": { - "Node name for S&R": "CLIPVisionLoader" + "Node name for S&R": "CLIPTextEncode" }, "widgets_values": [ - "IPAdapter_image_encoder_sd15.safetensors" + "in a peaceful spring morning a woman wearing a white shirt is sitting in a park on a bench\n\nhigh quality, detailed, diffuse light" ] }, { - "id": 9, + "id": 3, "type": "KSampler", "pos": [ - 930, - 170 + 1210, + 700 ], "size": { "0": 315, @@ -265,22 +455,22 @@ { "name": "model", "type": "MODEL", - "link": 7 + "link": 23 }, { "name": "positive", "type": "CONDITIONING", - "link": 25 + "link": 4 }, { "name": "negative", "type": "CONDITIONING", - "link": 9 + "link": 6 }, { "name": "latent_image", "type": "LATENT", - "link": 26 + "link": 2 } ], "outputs": [ @@ -288,9 +478,8 @@ "name": "LATENT", "type": "LATENT", "links": [ - 11 + 7 ], - "shape": 3, "slot_index": 0 } ], @@ -298,229 +487,44 @@ "Node name for S&R": "KSampler" }, "widgets_values": [ - 32, - "fixed", - 35, - 6, - "ddim", - "ddim_uniform", - 1 - ] - }, - { - "id": 5, - "type": "IPAdapterApply", - "pos": [ - 654, - -52 - ], - "size": { - "0": 210, - "1": 258 - }, - "flags": {}, - "order": 6, - "mode": 0, - "inputs": [ - { - "name": "ipadapter", - "type": "IPADAPTER", - "link": 1 - }, - { - "name": "clip_vision", - "type": "CLIP_VISION", - "link": 2 - }, - { - "name": "image", - "type": "IMAGE", - "link": 28 - }, - { - "name": "model", - "type": "MODEL", - "link": 4 - }, - { - "name": "attn_mask", - "type": "MASK", - "link": null - } - ], - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 7 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterApply" - }, - "widgets_values": [ - 0.6000000000000001, - 0.3, - "original", 0, - 1, - false - ] - }, - { - "id": 3, - "type": "IPAdapterModelLoader", - "pos": [ - 290, - 60 - ], - "size": { - "0": 300, - "1": 60 - }, - "flags": {}, - "order": 4, - "mode": 0, - "outputs": [ - { - "name": "IPADAPTER", - "type": "IPADAPTER", - "links": [ - 1 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterModelLoader" - }, - "widgets_values": [ - "ip-adapter-plus-face_sd15.safetensors" - ] - }, - { - "id": 8, - "type": "CLIPTextEncode", - "pos": [ - 650, - 420 - ], - "size": { - "0": 210, - "1": 120 - }, - "flags": {}, - "order": 8, - "mode": 0, - "inputs": [ - { - "name": "clip", - "type": "CLIP", - "link": 6 - } - ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 9 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPTextEncode" - }, - "widgets_values": [ - "blurry, horror, distorted, malformed, monochrome" - ], - "color": "#322", - "bgcolor": "#533" - }, - { - "id": 1, - "type": "CheckpointLoaderSimple", - "pos": [ - 290, - 280 - ], - "size": { - "0": 300, - "1": 100 - }, - "flags": {}, - "order": 5, - "mode": 0, - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 4 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "CLIP", - "type": "CLIP", - "links": [ - 5, - 6 - ], - "shape": 3, - "slot_index": 1 - }, - { - "name": "VAE", - "type": "VAE", - "links": null, - "shape": 3 - } - ], - "properties": { - "Node name for S&R": "CheckpointLoaderSimple" - }, - "widgets_values": [ - "sd15/realisticVisionV51_v51VAE.safetensors" + "fixed", + 30, + 6.5, + "ddpm", + "karras", + 1 ] } ], "links": [ - [ - 1, - 3, - 0, - 5, - 0, - "IPADAPTER" - ], [ 2, - 4, - 0, 5, - 1, - "CLIP_VISION" - ], - [ - 4, - 1, 0, - 5, 3, - "MODEL" + 3, + "LATENT" + ], + [ + 3, + 4, + 1, + 6, + 0, + "CLIP" + ], + [ + 4, + 6, + 0, + 3, + 1, + "CONDITIONING" ], [ 5, - 1, + 4, 1, 7, 0, @@ -528,73 +532,81 @@ ], [ 6, - 1, - 1, - 8, - 0, - "CLIP" - ], - [ 7, - 5, 0, - 9, - 0, - "MODEL" - ], - [ - 9, - 8, - 0, - 9, + 3, 2, "CONDITIONING" ], [ - 11, - 9, + 7, + 3, 0, - 11, + 8, 0, "LATENT" ], [ - 12, + 8, + 4, 2, - 0, - 11, + 8, 1, "VAE" ], [ - 13, - 11, + 9, + 8, 0, - 12, + 9, 0, "IMAGE" ], [ - 25, - 7, + 20, + 4, 0, - 9, + 14, + 0, + "MODEL" + ], + [ + 21, + 15, + 0, + 14, 1, - "CONDITIONING" + "IPADAPTER" + ], + [ + 23, + 14, + 0, + 3, + 0, + "MODEL" + ], + [ + 24, + 16, + 0, + 14, + 5, + "CLIP_VISION" + ], + [ + 25, + 12, + 0, + 17, + 0, + "IMAGE" ], [ 26, - 10, + 17, 0, - 9, - 3, - "LATENT" - ], - [ - 28, 14, - 0, - 5, 2, "IMAGE" ] diff --git a/examples/IPAdapter_weight_types.json b/examples/ipadapter_combine_embeds.json similarity index 69% rename from examples/IPAdapter_weight_types.json rename to examples/ipadapter_combine_embeds.json index 5b9d099..f961f67 100644 --- a/examples/IPAdapter_weight_types.json +++ b/examples/ipadapter_combine_embeds.json @@ -1,182 +1,20 @@ { - "last_node_id": 57, - "last_link_id": 154, + "last_node_id": 51, + "last_link_id": 118, "nodes": [ - { - "id": 18, - "type": "CLIPVisionLoader", - "pos": [ - 260, - -470 - ], - "size": { - "0": 310, - "1": 60 - }, - "flags": {}, - "order": 0, - "mode": 0, - "outputs": [ - { - "name": "CLIP_VISION", - "type": "CLIP_VISION", - "links": [ - 89, - 94, - 98 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPVisionLoader" - }, - "widgets_values": [ - "IPAdapter_image_encoder_sd15.safetensors" - ] - }, - { - "id": 7, - "type": "CLIPTextEncode", - "pos": [ - 360, - 120 - ], - "size": { - "0": 380, - "1": 160 - }, - "flags": {}, - "order": 7, - "mode": 0, - "inputs": [ - { - "name": "clip", - "type": "CLIP", - "link": 72 - } - ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 6, - 102, - 111, - 129 - ], - "slot_index": 0 - } - ], - "title": "CLIP Text Encode (Negative)", - "properties": { - "Node name for S&R": "CLIPTextEncode" - }, - "widgets_values": [ - "blurry, distorted, malformed, gore, naked, bare skin, tattoo" - ], - "color": "#322", - "bgcolor": "#533" - }, - { - "id": 11, - "type": "VAELoader", - "pos": [ - 440, - 480 - ], - "size": { - "0": 300, - "1": 60 - }, - "flags": {}, - "order": 1, - "mode": 0, - "outputs": [ - { - "name": "VAE", - "type": "VAE", - "links": [ - 12, - 104, - 106, - 133 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAELoader" - }, - "widgets_values": [ - "vae-ft-mse-840000-ema-pruned.safetensors" - ] - }, - { - "id": 4, - "type": "CheckpointLoaderSimple", - "pos": [ - -184, - 113 - ], - "size": { - "0": 340, - "1": 100 - }, - "flags": {}, - "order": 2, - "mode": 0, - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 91, - 96, - 100, - 131 - ], - "slot_index": 0 - }, - { - "name": "CLIP", - "type": "CLIP", - "links": [ - 71, - 72 - ], - "slot_index": 1 - }, - { - "name": "VAE", - "type": "VAE", - "links": [], - "slot_index": 2 - } - ], - "properties": { - "Node name for S&R": "CheckpointLoaderSimple" - }, - "widgets_values": [ - "sd15/deliberate_v3.safetensors" - ] - }, { "id": 5, "type": "EmptyLatentImage", "pos": [ - 520, - 330 + 801, + 1097 ], "size": { - "0": 220, + "0": 315, "1": 106 }, "flags": {}, - "order": 3, + "order": 0, "mode": 0, "outputs": [ { @@ -184,9 +22,9 @@ "type": "LATENT", "links": [ 2, - 103, - 112, - 130 + 89, + 100, + 111 ], "slot_index": 0 } @@ -201,212 +39,63 @@ ] }, { - "id": 17, - "type": "IPAdapterModelLoader", + "id": 16, + "type": "CLIPVisionLoader", "pos": [ - 260, - -570 + 650, + 80 ], "size": { - "0": 310, - "1": 60 + "0": 315, + "1": 58 }, "flags": {}, - "order": 4, + "order": 1, "mode": 0, "outputs": [ { - "name": "IPADAPTER", - "type": "IPADAPTER", + "name": "CLIP_VISION", + "type": "CLIP_VISION", "links": [ - 88, - 93, - 97 + 24, + 96, + 107, + 118 ], - "shape": 3, - "slot_index": 0 + "shape": 3 } ], "properties": { - "Node name for S&R": "IPAdapterModelLoader" + "Node name for S&R": "CLIPVisionLoader" }, "widgets_values": [ - "ip-adapter-plus_sd15.bin" + "IPAdapter_image_encoder_sd15.safetensors" ] }, - { - "id": 51, - "type": "PreviewImage", - "pos": [ - 960, - 10 - ], - "size": { - "0": 527.208984375, - "1": 576.05859375 - }, - "flags": {}, - "order": 17, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 134 - } - ], - "properties": { - "Node name for S&R": "PreviewImage" - } - }, - { - "id": 42, - "type": "PreviewImage", - "pos": [ - 2730, - 10 - ], - "size": { - "0": 532.08154296875, - "1": 578.00732421875 - }, - "flags": {}, - "order": 23, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 107 - } - ], - "properties": { - "Node name for S&R": "PreviewImage" - } - }, - { - "id": 43, - "type": "KSampler", - "pos": [ - 2970, - -290 - ], - "size": { - "0": 290, - "1": 262 - }, - "flags": {}, - "order": 16, - "mode": 0, - "inputs": [ - { - "name": "model", - "type": "MODEL", - "link": 115 - }, - { - "name": "positive", - "type": "CONDITIONING", - "link": 151 - }, - { - "name": "negative", - "type": "CONDITIONING", - "link": 111 - }, - { - "name": "latent_image", - "type": "LATENT", - "link": 112 - } - ], - "outputs": [ - { - "name": "LATENT", - "type": "LATENT", - "links": [ - 117 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "KSampler" - }, - "widgets_values": [ - 292, - "fixed", - 40, - 5.5, - "dpmpp_2m", - "karras", - 1 - ] - }, - { - "id": 41, - "type": "VAEDecode", - "pos": [ - 2810, - -90 - ], - "size": { - "0": 140, - "1": 60 - }, - "flags": {}, - "order": 20, - "mode": 0, - "inputs": [ - { - "name": "samples", - "type": "LATENT", - "link": 117 - }, - { - "name": "vae", - "type": "VAE", - "link": 106 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 107 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAEDecode" - } - }, { "id": 3, "type": "KSampler", "pos": [ - 2370, - -300 + 1580, + 300 ], "size": { - "0": 300, + "0": 315, "1": 262 }, "flags": {}, - "order": 14, + "order": 13, "mode": 0, "inputs": [ { "name": "model", "type": "MODEL", - "link": 92 + "link": 23 }, { "name": "positive", "type": "CONDITIONING", - "link": 149 + "link": 4 }, { "name": "negative", @@ -433,580 +122,89 @@ "Node name for S&R": "KSampler" }, "widgets_values": [ - 292, + 0, "fixed", - 40, - 5.5, + 30, + 6.5, "dpmpp_2m", "karras", 1 ] }, { - "id": 8, - "type": "VAEDecode", + "id": 4, + "type": "CheckpointLoaderSimple", "pos": [ - 2210, - -100 + 300, + 700 ], "size": { - "0": 140, - "1": 60 + "0": 315, + "1": 98 }, "flags": {}, - "order": 18, + "order": 2, "mode": 0, - "inputs": [ - { - "name": "samples", - "type": "LATENT", - "link": 7 - }, - { - "name": "vae", - "type": "VAE", - "link": 12 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 56 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAEDecode" - } - }, - { - "id": 38, - "type": "KSampler", - "pos": [ - 1770, - -310 - ], - "size": { - "0": 290, - "1": 262 - }, - "flags": {}, - "order": 15, - "mode": 0, - "inputs": [ - { - "name": "model", - "type": "MODEL", - "link": 108 - }, - { - "name": "positive", - "type": "CONDITIONING", - "link": 150 - }, - { - "name": "negative", - "type": "CONDITIONING", - "link": 102 - }, - { - "name": "latent_image", - "type": "LATENT", - "link": 103 - } - ], - "outputs": [ - { - "name": "LATENT", - "type": "LATENT", - "links": [ - 116 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "KSampler" - }, - "widgets_values": [ - 292, - "fixed", - 40, - 5.5, - "dpmpp_2m", - "karras", - 1 - ] - }, - { - "id": 39, - "type": "VAEDecode", - "pos": [ - 1610, - -110 - ], - "size": { - "0": 140, - "1": 60 - }, - "flags": {}, - "order": 19, - "mode": 0, - "inputs": [ - { - "name": "samples", - "type": "LATENT", - "link": 116 - }, - { - "name": "vae", - "type": "VAE", - "link": 104 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 105 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAEDecode" - } - }, - { - "id": 50, - "type": "VAEDecode", - "pos": [ - 1000, - -110 - ], - "size": { - "0": 140, - "1": 60 - }, - "flags": {}, - "order": 13, - "mode": 0, - "inputs": [ - { - "name": "samples", - "type": "LATENT", - "link": 135 - }, - { - "name": "vae", - "type": "VAE", - "link": 133 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 134 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAEDecode" - } - }, - { - "id": 6, - "type": "CLIPTextEncode", - "pos": [ - 360, - -90 - ], - "size": { - "0": 380, - "1": 170 - }, - "flags": { - "collapsed": false - }, - "order": 6, - "mode": 0, - "inputs": [ - { - "name": "clip", - "type": "CLIP", - "link": 71 - } - ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 149, - 150, - 151, - 152 - ], - "slot_index": 0 - } - ], - "title": "CLIP Text Encode (Positive)", - "properties": { - "Node name for S&R": "CLIPTextEncode" - }, - "widgets_values": [ - "portrait illustration of a warrior woman in full armor, in a dungeon\n\nhighly detailed, dramatic lighting, 4k" - ], - "color": "#232", - "bgcolor": "#353" - }, - { - "id": 20, - "type": "PrepImageForClipVision", - "pos": [ - 320, - -350 - ], - "size": { - "0": 243.60000610351562, - "1": 110 - }, - "flags": {}, - "order": 8, - "mode": 0, - "inputs": [ - { - "name": "image", - "type": "IMAGE", - "link": 148 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 144, - 146, - 147 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "PrepImageForClipVision" - }, - "widgets_values": [ - "LANCZOS", - "center", - 0 - ] - }, - { - "id": 49, - "type": "KSampler", - "pos": [ - 1160, - -310 - ], - "size": { - "0": 300, - "1": 262 - }, - "flags": {}, - "order": 9, - "mode": 0, - "inputs": [ - { - "name": "model", - "type": "MODEL", - "link": 131 - }, - { - "name": "positive", - "type": "CONDITIONING", - "link": 152 - }, - { - "name": "negative", - "type": "CONDITIONING", - "link": 129 - }, - { - "name": "latent_image", - "type": "LATENT", - "link": 130 - } - ], - "outputs": [ - { - "name": "LATENT", - "type": "LATENT", - "links": [ - 135 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "KSampler" - }, - "widgets_values": [ - 292, - "fixed", - 46, - 5.5, - "dpmpp_2m", - "karras", - 1 - ] - }, - { - "id": 40, - "type": "PreviewImage", - "pos": [ - 1540, - 10 - ], - "size": { - "0": 520, - "1": 570 - }, - "flags": {}, - "order": 22, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 105 - } - ], - "properties": { - "Node name for S&R": "PreviewImage" - } - }, - { - "id": 29, - "type": "PreviewImage", - "pos": [ - 2130, - 10 - ], - "size": { - "0": 520, - "1": 570 - }, - "flags": {}, - "order": 21, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 56 - } - ], - "properties": { - "Node name for S&R": "PreviewImage" - } - }, - { - "id": 36, - "type": "IPAdapterApply", - "pos": [ - 1520, - -320 - ], - "size": { - "0": 234.41876220703125, - "1": 166 - }, - "flags": {}, - "order": 11, - "mode": 0, - "inputs": [ - { - "name": "ipadapter", - "type": "IPADAPTER", - "link": 93 - }, - { - "name": "clip_vision", - "type": "CLIP_VISION", - "link": 94 - }, - { - "name": "image", - "type": "IMAGE", - "link": 146 - }, - { - "name": "model", - "type": "MODEL", - "link": 96 - } - ], - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 108 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterApply" - }, - "widgets_values": [ - 0.25, - 0.3, - "linear" - ] - }, - { - "id": 35, - "type": "IPAdapterApply", - "pos": [ - 2100, - -310 - ], - "size": { - "0": 246.50965881347656, - "1": 166 - }, - "flags": {}, - "order": 10, - "mode": 0, - "inputs": [ - { - "name": "ipadapter", - "type": "IPADAPTER", - "link": 88 - }, - { - "name": "clip_vision", - "type": "CLIP_VISION", - "link": 89 - }, - { - "name": "image", - "type": "IMAGE", - "link": 144 - }, - { - "name": "model", - "type": "MODEL", - "link": 91 - } - ], - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 92 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterApply" - }, - "widgets_values": [ - 0.25, - 0.3, - "original" - ] - }, - { - "id": 37, - "type": "IPAdapterApply", - "pos": [ - 2710, - -300 - ], - "size": { - "0": 239.32774353027344, - "1": 166 - }, - "flags": {}, - "order": 12, - "mode": 0, - "inputs": [ - { - "name": "ipadapter", - "type": "IPADAPTER", - "link": 97 - }, - { - "name": "clip_vision", - "type": "CLIP_VISION", - "link": 98 - }, - { - "name": "image", - "type": "IMAGE", - "link": 147 - }, - { - "name": "model", - "type": "MODEL", - "link": 100 - } - ], "outputs": [ { "name": "MODEL", "type": "MODEL", "links": [ + 20, + 93, + 104, 115 ], - "shape": 3, "slot_index": 0 + }, + { + "name": "CLIP", + "type": "CLIP", + "links": [ + 3, + 5 + ], + "slot_index": 1 + }, + { + "name": "VAE", + "type": "VAE", + "links": [ + 8, + 91, + 102, + 113 + ], + "slot_index": 2 } ], "properties": { - "Node name for S&R": "IPAdapterApply" + "Node name for S&R": "CheckpointLoaderSimple" }, "widgets_values": [ - 0.25, - 0.3, - "channel penalty" + "sd15/realisticVisionV51_v51VAE.safetensors" ] }, { - "id": 19, + "id": 12, "type": "LoadImage", "pos": [ - 78, - -351 + 240, + -60 ], "size": { - "0": 210, - "1": 280 + "0": 315, + "1": 314 }, "flags": {}, - "order": 5, + "order": 3, "mode": 0, "outputs": [ { "name": "IMAGE", "type": "IMAGE", "links": [ - 148 + 83 ], "shape": 3, "slot_index": 0 @@ -1022,9 +220,929 @@ "Node name for S&R": "LoadImage" }, "widgets_values": [ - "woman.png", + "warrior_woman.png", "image" ] + }, + { + "id": 7, + "type": "CLIPTextEncode", + "pos": [ + 740, + 780 + ], + "size": { + "0": 425.27801513671875, + "1": 180.6060791015625 + }, + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [ + { + "name": "clip", + "type": "CLIP", + "link": 5 + } + ], + "outputs": [ + { + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 6, + 88, + 99, + 110 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "CLIPTextEncode" + }, + "widgets_values": [ + "blurry, noisy, messy, lowres, jpeg, artifacts, ill, distorted, malformed" + ] + }, + { + "id": 14, + "type": "IPAdapterAdvanced", + "pos": [ + 1220, + 260 + ], + "size": { + "0": 315, + "1": 254 + }, + "flags": {}, + "order": 9, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 20 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": 21, + "slot_index": 1 + }, + { + "name": "image", + "type": "IMAGE", + "link": 85 + }, + { + "name": "image_negative", + "type": "IMAGE", + "link": null + }, + { + "name": "attn_mask", + "type": "MASK", + "link": null + }, + { + "name": "clip_vision", + "type": "CLIP_VISION", + "link": 24, + "slot_index": 5 + } + ], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 23 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "IPAdapterAdvanced" + }, + "widgets_values": [ + 0.8, + "linear", + "concat", + 0, + 1 + ] + }, + { + "id": 42, + "type": "SaveImage", + "pos": [ + 1950, + 1070 + ], + "size": { + "0": 529.7760009765625, + "1": 582.3048095703125 + }, + "flags": {}, + "order": 22, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 92 + } + ], + "properties": {}, + "widgets_values": [ + "IPAdapter" + ] + }, + { + "id": 40, + "type": "KSampler", + "pos": [ + 1580, + 1070 + ], + "size": { + "0": 315, + "1": 262 + }, + "flags": {}, + "order": 14, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 86 + }, + { + "name": "positive", + "type": "CONDITIONING", + "link": 87 + }, + { + "name": "negative", + "type": "CONDITIONING", + "link": 88 + }, + { + "name": "latent_image", + "type": "LATENT", + "link": 89 + } + ], + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 90 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "KSampler" + }, + "widgets_values": [ + 0, + "fixed", + 30, + 6.5, + "dpmpp_2m", + "karras", + 1 + ] + }, + { + "id": 9, + "type": "SaveImage", + "pos": [ + 1950, + 420 + ], + "size": { + "0": 529.7760009765625, + "1": 582.3048095703125 + }, + "flags": {}, + "order": 21, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 9 + } + ], + "properties": {}, + "widgets_values": [ + "IPAdapter" + ] + }, + { + "id": 6, + "type": "CLIPTextEncode", + "pos": [ + 740, + 550 + ], + "size": { + "0": 422.84503173828125, + "1": 164.31304931640625 + }, + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [ + { + "name": "clip", + "type": "CLIP", + "link": 3 + } + ], + "outputs": [ + { + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 4, + 87, + 98, + 109 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "CLIPTextEncode" + }, + "widgets_values": [ + "closeup of a fierce warrior woman wearing a full armor at the end of a battle\n\nhigh quality, detailed" + ] + }, + { + "id": 15, + "type": "IPAdapterModelLoader", + "pos": [ + 650, + -20 + ], + "size": { + "0": 315, + "1": 58 + }, + "flags": {}, + "order": 4, + "mode": 0, + "outputs": [ + { + "name": "IPADAPTER", + "type": "IPADAPTER", + "links": [ + 21, + 94, + 105, + 116 + ], + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "IPAdapterModelLoader" + }, + "widgets_values": [ + "ip-adapter-plus_sd15.safetensors" + ] + }, + { + "id": 39, + "type": "ImageBatch", + "pos": [ + 714, + 287 + ], + "size": { + "0": 210, + "1": 46 + }, + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [ + { + "name": "image1", + "type": "IMAGE", + "link": 83 + }, + { + "name": "image2", + "type": "IMAGE", + "link": 84 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 85, + 95, + 106, + 117 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "ImageBatch" + } + }, + { + "id": 38, + "type": "LoadImage", + "pos": [ + 240, + 310 + ], + "size": { + "0": 315, + "1": 314 + }, + "flags": {}, + "order": 5, + "mode": 0, + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 84 + ], + "shape": 3, + "slot_index": 0 + }, + { + "name": "MASK", + "type": "MASK", + "links": null, + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "anime_illustration.png", + "image" + ] + }, + { + "id": 43, + "type": "IPAdapterAdvanced", + "pos": [ + 1220, + 1030 + ], + "size": { + "0": 315, + "1": 254 + }, + "flags": {}, + "order": 10, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 93 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": 94, + "slot_index": 1 + }, + { + "name": "image", + "type": "IMAGE", + "link": 95 + }, + { + "name": "image_negative", + "type": "IMAGE", + "link": null + }, + { + "name": "attn_mask", + "type": "MASK", + "link": null + }, + { + "name": "clip_vision", + "type": "CLIP_VISION", + "link": 96, + "slot_index": 5 + } + ], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 86 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "IPAdapterAdvanced" + }, + "widgets_values": [ + 0.8, + "linear", + "add", + 0, + 1 + ] + }, + { + "id": 44, + "type": "KSampler", + "pos": [ + 3470, + 390 + ], + "size": { + "0": 315, + "1": 262 + }, + "flags": {}, + "order": 15, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 97 + }, + { + "name": "positive", + "type": "CONDITIONING", + "link": 98 + }, + { + "name": "negative", + "type": "CONDITIONING", + "link": 99 + }, + { + "name": "latent_image", + "type": "LATENT", + "link": 100 + } + ], + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 101 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "KSampler" + }, + "widgets_values": [ + 0, + "fixed", + 30, + 6.5, + "dpmpp_2m", + "karras", + 1 + ] + }, + { + "id": 45, + "type": "VAEDecode", + "pos": [ + 3840, + 400 + ], + "size": { + "0": 140, + "1": 46 + }, + "flags": {}, + "order": 19, + "mode": 0, + "inputs": [ + { + "name": "samples", + "type": "LATENT", + "link": 101 + }, + { + "name": "vae", + "type": "VAE", + "link": 102 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 103 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "VAEDecode" + } + }, + { + "id": 48, + "type": "KSampler", + "pos": [ + 3480, + 1170 + ], + "size": { + "0": 315, + "1": 262 + }, + "flags": {}, + "order": 16, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 108 + }, + { + "name": "positive", + "type": "CONDITIONING", + "link": 109 + }, + { + "name": "negative", + "type": "CONDITIONING", + "link": 110 + }, + { + "name": "latent_image", + "type": "LATENT", + "link": 111 + } + ], + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 112 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "KSampler" + }, + "widgets_values": [ + 0, + "fixed", + 30, + 6.5, + "dpmpp_2m", + "karras", + 1 + ] + }, + { + "id": 49, + "type": "VAEDecode", + "pos": [ + 3850, + 1180 + ], + "size": { + "0": 140, + "1": 46 + }, + "flags": {}, + "order": 20, + "mode": 0, + "inputs": [ + { + "name": "samples", + "type": "LATENT", + "link": 112 + }, + { + "name": "vae", + "type": "VAE", + "link": 113 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 114 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "VAEDecode" + } + }, + { + "id": 51, + "type": "IPAdapterAdvanced", + "pos": [ + 3120, + 1130 + ], + "size": { + "0": 315, + "1": 254 + }, + "flags": {}, + "order": 12, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 115 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": 116, + "slot_index": 1 + }, + { + "name": "image", + "type": "IMAGE", + "link": 117 + }, + { + "name": "image_negative", + "type": "IMAGE", + "link": null + }, + { + "name": "attn_mask", + "type": "MASK", + "link": null + }, + { + "name": "clip_vision", + "type": "CLIP_VISION", + "link": 118, + "slot_index": 5 + } + ], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 108 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "IPAdapterAdvanced" + }, + "widgets_values": [ + 0.8, + "linear", + "norm average", + 0, + 1 + ] + }, + { + "id": 47, + "type": "IPAdapterAdvanced", + "pos": [ + 3110, + 350 + ], + "size": { + "0": 315, + "1": 254 + }, + "flags": {}, + "order": 11, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 104 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": 105, + "slot_index": 1 + }, + { + "name": "image", + "type": "IMAGE", + "link": 106 + }, + { + "name": "image_negative", + "type": "IMAGE", + "link": null + }, + { + "name": "attn_mask", + "type": "MASK", + "link": null + }, + { + "name": "clip_vision", + "type": "CLIP_VISION", + "link": 107, + "slot_index": 5 + } + ], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 97 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "IPAdapterAdvanced" + }, + "widgets_values": [ + 0.8, + "linear", + "average", + 0, + 1 + ] + }, + { + "id": 8, + "type": "VAEDecode", + "pos": [ + 1748, + 613 + ], + "size": { + "0": 140, + "1": 46 + }, + "flags": {}, + "order": 17, + "mode": 0, + "inputs": [ + { + "name": "samples", + "type": "LATENT", + "link": 7 + }, + { + "name": "vae", + "type": "VAE", + "link": 8 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 9 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "VAEDecode" + } + }, + { + "id": 41, + "type": "VAEDecode", + "pos": [ + 1746, + 1386 + ], + "size": { + "0": 140, + "1": 46 + }, + "flags": {}, + "order": 18, + "mode": 0, + "inputs": [ + { + "name": "samples", + "type": "LATENT", + "link": 90 + }, + { + "name": "vae", + "type": "VAE", + "link": 91 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 92 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "VAEDecode" + } + }, + { + "id": 50, + "type": "SaveImage", + "pos": [ + 2530, + 1073 + ], + "size": { + "0": 529.7760009765625, + "1": 582.3048095703125 + }, + "flags": {}, + "order": 24, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 114 + } + ], + "properties": {}, + "widgets_values": [ + "IPAdapter" + ] + }, + { + "id": 46, + "type": "SaveImage", + "pos": [ + 2518, + 419 + ], + "size": { + "0": 529.7760009765625, + "1": 582.3048095703125 + }, + "flags": {}, + "order": 23, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 103 + } + ], + "properties": {}, + "widgets_values": [ + "IPAdapter" + ] } ], "links": [ @@ -1036,6 +1154,30 @@ 3, "LATENT" ], + [ + 3, + 4, + 1, + 6, + 0, + "CLIP" + ], + [ + 4, + 6, + 0, + 3, + 1, + "CONDITIONING" + ], + [ + 5, + 4, + 1, + 7, + 0, + "CLIP" + ], [ 6, 7, @@ -1053,159 +1195,127 @@ "LATENT" ], [ - 12, - 11, - 0, + 8, + 4, + 2, 8, 1, "VAE" ], [ - 56, + 9, 8, 0, - 29, + 9, 0, "IMAGE" ], [ - 71, + 20, 4, - 1, - 6, 0, - "CLIP" + 14, + 0, + "MODEL" ], [ - 72, - 4, + 21, + 15, + 0, + 14, 1, - 7, - 0, - "CLIP" - ], - [ - 88, - 17, - 0, - 35, - 0, "IPADAPTER" ], [ - 89, - 18, + 23, + 14, 0, - 35, - 1, + 3, + 0, + "MODEL" + ], + [ + 24, + 16, + 0, + 14, + 5, "CLIP_VISION" ], + [ + 83, + 12, + 0, + 39, + 0, + "IMAGE" + ], + [ + 84, + 38, + 0, + 39, + 1, + "IMAGE" + ], + [ + 85, + 39, + 0, + 14, + 2, + "IMAGE" + ], + [ + 86, + 43, + 0, + 40, + 0, + "MODEL" + ], + [ + 87, + 6, + 0, + 40, + 1, + "CONDITIONING" + ], + [ + 88, + 7, + 0, + 40, + 2, + "CONDITIONING" + ], + [ + 89, + 5, + 0, + 40, + 3, + "LATENT" + ], + [ + 90, + 40, + 0, + 41, + 0, + "LATENT" + ], [ 91, 4, - 0, - 35, - 3, - "MODEL" - ], - [ - 92, - 35, - 0, - 3, - 0, - "MODEL" - ], - [ - 93, - 17, - 0, - 36, - 0, - "IPADAPTER" - ], - [ - 94, - 18, - 0, - 36, - 1, - "CLIP_VISION" - ], - [ - 96, - 4, - 0, - 36, - 3, - "MODEL" - ], - [ - 97, - 17, - 0, - 37, - 0, - "IPADAPTER" - ], - [ - 98, - 18, - 0, - 37, - 1, - "CLIP_VISION" - ], - [ - 100, - 4, - 0, - 37, - 3, - "MODEL" - ], - [ - 102, - 7, - 0, - 38, 2, - "CONDITIONING" - ], - [ - 103, - 5, - 0, - 38, - 3, - "LATENT" - ], - [ - 104, - 11, - 0, - 39, - 1, - "VAE" - ], - [ - 105, - 39, - 0, - 40, - 0, - "IMAGE" - ], - [ - 106, - 11, - 0, 41, 1, "VAE" ], [ - 107, + 92, 41, 0, 42, @@ -1213,164 +1323,212 @@ "IMAGE" ], [ - 108, - 36, + 93, + 4, 0, - 38, + 43, 0, "MODEL" ], [ - 111, - 7, + 94, + 15, 0, 43, + 1, + "IPADAPTER" + ], + [ + 95, + 39, + 0, + 43, + 2, + "IMAGE" + ], + [ + 96, + 16, + 0, + 43, + 5, + "CLIP_VISION" + ], + [ + 97, + 47, + 0, + 44, + 0, + "MODEL" + ], + [ + 98, + 6, + 0, + 44, + 1, + "CONDITIONING" + ], + [ + 99, + 7, + 0, + 44, 2, "CONDITIONING" ], [ - 112, + 100, 5, 0, - 43, + 44, 3, "LATENT" ], [ - 115, - 37, + 101, + 44, 0, - 43, + 45, + 0, + "LATENT" + ], + [ + 102, + 4, + 2, + 45, + 1, + "VAE" + ], + [ + 103, + 45, + 0, + 46, + 0, + "IMAGE" + ], + [ + 104, + 4, + 0, + 47, + 0, + "MODEL" + ], + [ + 105, + 15, + 0, + 47, + 1, + "IPADAPTER" + ], + [ + 106, + 39, + 0, + 47, + 2, + "IMAGE" + ], + [ + 107, + 16, + 0, + 47, + 5, + "CLIP_VISION" + ], + [ + 108, + 51, + 0, + 48, + 0, + "MODEL" + ], + [ + 109, + 6, + 0, + 48, + 1, + "CONDITIONING" + ], + [ + 110, + 7, + 0, + 48, + 2, + "CONDITIONING" + ], + [ + 111, + 5, + 0, + 48, + 3, + "LATENT" + ], + [ + 112, + 48, + 0, + 49, + 0, + "LATENT" + ], + [ + 113, + 4, + 2, + 49, + 1, + "VAE" + ], + [ + 114, + 49, + 0, + 50, + 0, + "IMAGE" + ], + [ + 115, + 4, + 0, + 51, 0, "MODEL" ], [ 116, - 38, + 15, 0, - 39, - 0, - "LATENT" + 51, + 1, + "IPADAPTER" ], [ 117, - 43, - 0, - 41, - 0, - "LATENT" - ], - [ - 129, - 7, - 0, - 49, - 2, - "CONDITIONING" - ], - [ - 130, - 5, - 0, - 49, - 3, - "LATENT" - ], - [ - 131, - 4, - 0, - 49, - 0, - "MODEL" - ], - [ - 133, - 11, - 0, - 50, - 1, - "VAE" - ], - [ - 134, - 50, + 39, 0, 51, - 0, - "IMAGE" - ], - [ - 135, - 49, - 0, - 50, - 0, - "LATENT" - ], - [ - 144, - 20, - 0, - 35, 2, "IMAGE" ], [ - 146, - 20, + 118, + 16, 0, - 36, - 2, - "IMAGE" - ], - [ - 147, - 20, - 0, - 37, - 2, - "IMAGE" - ], - [ - 148, - 19, - 0, - 20, - 0, - "IMAGE" - ], - [ - 149, - 6, - 0, - 3, - 1, - "CONDITIONING" - ], - [ - 150, - 6, - 0, - 38, - 1, - "CONDITIONING" - ], - [ - 151, - 6, - 0, - 43, - 1, - "CONDITIONING" - ], - [ - 152, - 6, - 0, - 49, - 1, - "CONDITIONING" + 51, + 5, + "CLIP_VISION" ] ], "groups": [], diff --git a/examples/IPAdapter_tiled.json b/examples/ipadapter_faceid.json similarity index 67% rename from examples/IPAdapter_tiled.json rename to examples/ipadapter_faceid.json index bc6a69a..99d0bbe 100644 --- a/examples/IPAdapter_tiled.json +++ b/examples/ipadapter_faceid.json @@ -1,181 +1,114 @@ { - "last_node_id": 27, - "last_link_id": 53, + "last_node_id": 20, + "last_link_id": 36, "nodes": [ { - "id": 1, - "type": "CheckpointLoaderSimple", + "id": 8, + "type": "VAEDecode", "pos": [ - 140, - 770 + 1640, + 710 ], "size": { - "0": 300, - "1": 100 - }, - "flags": {}, - "order": 0, - "mode": 0, - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 51 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "CLIP", - "type": "CLIP", - "links": [ - 5, - 6 - ], - "shape": 3, - "slot_index": 1 - }, - { - "name": "VAE", - "type": "VAE", - "links": null, - "shape": 3 - } - ], - "properties": { - "Node name for S&R": "CheckpointLoaderSimple" - }, - "widgets_values": [ - "sd15/realisticVisionV51_v51VAE.safetensors" - ] - }, - { - "id": 2, - "type": "VAELoader", - "pos": [ - 890, - 820 - ], - "size": { - "0": 300, - "1": 60 - }, - "flags": {}, - "order": 1, - "mode": 0, - "outputs": [ - { - "name": "VAE", - "type": "VAE", - "links": [ - 12 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAELoader" - }, - "widgets_values": [ - "vae-ft-mse-840000-ema-pruned.safetensors" - ] - }, - { - "id": 25, - "type": "IPAdapterTilesMasked", - "pos": [ - 530, - 170 - ], - "size": { - "0": 315, - "1": 262 + "0": 140, + "1": 46 }, "flags": {}, "order": 8, "mode": 0, "inputs": [ { - "name": "ipadapter", - "type": "IPADAPTER", - "link": 48 + "name": "samples", + "type": "LATENT", + "link": 7 }, { - "name": "clip_vision", - "type": "CLIP_VISION", - "link": 49 - }, - { - "name": "image", - "type": "IMAGE", - "link": 50 - }, - { - "name": "model", - "type": "MODEL", - "link": 51 + "name": "vae", + "type": "VAE", + "link": 8 } ], "outputs": [ { - "name": "MODEL", - "type": "MODEL", + "name": "IMAGE", + "type": "IMAGE", "links": [ - 52 + 9 ], - "shape": 3, "slot_index": 0 } ], "properties": { - "Node name for S&R": "IPAdapterTilesMasked" + "Node name for S&R": "VAEDecode" + } + }, + { + "id": 5, + "type": "EmptyLatentImage", + "pos": [ + 870, + 1100 + ], + "size": { + "0": 315, + "1": 106 + }, + "flags": {}, + "order": 0, + "mode": 0, + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 2 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "EmptyLatentImage" }, "widgets_values": [ - 0.65, - 0, - "original", - 0, - 1, - 1, - 0.6 + 512, + 512, + 1 ] }, { - "id": 9, + "id": 3, "type": "KSampler", "pos": [ - 880, - 500 + 1280, + 710 ], "size": { "0": 315, "1": 262 }, "flags": {}, - "order": 10, + "order": 7, "mode": 0, "inputs": [ { "name": "model", "type": "MODEL", - "link": 31 + "link": 32 }, { "name": "positive", "type": "CONDITIONING", - "link": 8 + "link": 4 }, { "name": "negative", "type": "CONDITIONING", - "link": 9 + "link": 6 }, { "name": "latent_image", "type": "LATENT", - "link": 10 + "link": 2 } ], "outputs": [ @@ -183,9 +116,8 @@ "name": "LATENT", "type": "LATENT", "links": [ - 11 + 7 ], - "shape": 3, "slot_index": 0 } ], @@ -193,220 +125,61 @@ "Node name for S&R": "KSampler" }, "widgets_values": [ - 11, + 0, "fixed", 30, - 6, + 6.5, "ddpm", "karras", 1 ] }, { - "id": 18, - "type": "RescaleCFG", + "id": 9, + "type": "SaveImage", "pos": [ - 980, - 390 - ], - "size": [ - 210, - 58 + 1830, + 700 ], + "size": { + "0": 529.7760009765625, + "1": 582.3048095703125 + }, "flags": {}, "order": 9, "mode": 0, "inputs": [ { - "name": "model", - "type": "MODEL", - "link": 52 + "name": "images", + "type": "IMAGE", + "link": 9 } ], - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 31 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "RescaleCFG" - }, + "properties": {}, "widgets_values": [ - 0.9 + "IPAdapter" ] }, { - "id": 4, - "type": "CLIPVisionLoader", - "pos": [ - 150, - 190 - ], - "size": { - "0": 300, - "1": 60 - }, - "flags": {}, - "order": 2, - "mode": 0, - "outputs": [ - { - "name": "CLIP_VISION", - "type": "CLIP_VISION", - "links": [ - 49 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPVisionLoader" - }, - "widgets_values": [ - "IPAdapter_image_encoder_sd15.safetensors" - ] - }, - { - "id": 3, - "type": "IPAdapterModelLoader", - "pos": [ - 150, - 80 - ], - "size": { - "0": 300, - "1": 60 - }, - "flags": {}, - "order": 3, - "mode": 0, - "outputs": [ - { - "name": "IPADAPTER", - "type": "IPADAPTER", - "links": [ - 48 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterModelLoader" - }, - "widgets_values": [ - "ip-adapter-plus_sd15.safetensors" - ] - }, - { - "id": 7, - "type": "CLIPTextEncode", - "pos": [ - 570, - 500 - ], - "size": { - "0": 210, - "1": 120 - }, - "flags": {}, - "order": 6, - "mode": 0, - "inputs": [ - { - "name": "clip", - "type": "CLIP", - "link": 5 - } - ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 8 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPTextEncode" - }, - "widgets_values": [ - "" - ], - "color": "#232", - "bgcolor": "#353" - }, - { - "id": 8, - "type": "CLIPTextEncode", - "pos": [ - 570, - 680 - ], - "size": { - "0": 210, - "1": 120 - }, - "flags": {}, - "order": 7, - "mode": 0, - "inputs": [ - { - "name": "clip", - "type": "CLIP", - "link": 6 - } - ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 9 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPTextEncode" - }, - "widgets_values": [ - "" - ], - "color": "#322", - "bgcolor": "#533" - }, - { - "id": 6, + "id": 12, "type": "LoadImage", "pos": [ - 50, - 310 + 450, + 240 ], "size": { - "0": 404.8474426269531, - "1": 404.49200439453125 + "0": 315, + "1": 314 }, "flags": {}, - "order": 4, + "order": 1, "mode": 0, "outputs": [ { "name": "IMAGE", "type": "IMAGE", "links": [ - 50 + 29 ], "shape": 3, "slot_index": 0 @@ -422,116 +195,292 @@ "Node name for S&R": "LoadImage" }, "widgets_values": [ - "example.png", + "rosario_4.jpg", "image" ] }, { - "id": 11, - "type": "VAEDecode", + "id": 20, + "type": "IPAdapterUnifiedLoaderFaceID", "pos": [ - 1253, - 502 + 460, + 60 ], "size": { - "0": 140, - "1": 50 + "0": 315, + "1": 126 }, "flags": {}, - "order": 11, + "order": 3, "mode": 0, "inputs": [ { - "name": "samples", - "type": "LATENT", - "link": 11 + "name": "model", + "type": "MODEL", + "link": 36 }, { - "name": "vae", - "type": "VAE", - "link": 12 + "name": "ipadapter", + "type": "IPADAPTER", + "link": null } ], "outputs": [ { - "name": "IMAGE", - "type": "IMAGE", + "name": "MODEL", + "type": "MODEL", "links": [ - 53 + 35 ], "shape": 3, "slot_index": 0 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "links": [ + 34 + ], + "shape": 3 } ], "properties": { - "Node name for S&R": "VAEDecode" - } - }, - { - "id": 27, - "type": "SaveImage", - "pos": [ - 1450, - 503 - ], - "size": { - "0": 315, - "1": 58 + "Node name for S&R": "IPAdapterUnifiedLoaderFaceID" }, - "flags": {}, - "order": 12, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 53 - } - ], - "properties": {}, "widgets_values": [ - "ComfyUI" + "FACEID PLUS V2", + 0.6, + "CPU" ] }, { - "id": 10, - "type": "EmptyLatentImage", + "id": 7, + "type": "CLIPTextEncode", "pos": [ - 570, - 860 + 760, + 850 ], "size": { - "0": 210, - "1": 110 + "0": 425.27801513671875, + "1": 180.6060791015625 }, "flags": {}, "order": 5, "mode": 0, + "inputs": [ + { + "name": "clip", + "type": "CLIP", + "link": 5 + } + ], "outputs": [ { - "name": "LATENT", - "type": "LATENT", + "name": "CONDITIONING", + "type": "CONDITIONING", "links": [ - 10 + 6 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "CLIPTextEncode" + }, + "widgets_values": [ + "blurry, noisy, messy, lowres, jpeg, artifacts, ill, distorted, malformed, naked" + ] + }, + { + "id": 6, + "type": "CLIPTextEncode", + "pos": [ + 760, + 620 + ], + "size": { + "0": 422.84503173828125, + "1": 164.31304931640625 + }, + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [ + { + "name": "clip", + "type": "CLIP", + "link": 3 + } + ], + "outputs": [ + { + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 4 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "CLIPTextEncode" + }, + "widgets_values": [ + "closeup of a beautiful woman wearing a black dress on the seaside\n\nserene, sunset, spring, high quality, detailed, diffuse light" + ] + }, + { + "id": 4, + "type": "CheckpointLoaderSimple", + "pos": [ + 10, + 680 + ], + "size": { + "0": 315, + "1": 98 + }, + "flags": {}, + "order": 2, + "mode": 0, + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 36 + ], + "slot_index": 0 + }, + { + "name": "CLIP", + "type": "CLIP", + "links": [ + 3, + 5 + ], + "slot_index": 1 + }, + { + "name": "VAE", + "type": "VAE", + "links": [ + 8 + ], + "slot_index": 2 + } + ], + "properties": { + "Node name for S&R": "CheckpointLoaderSimple" + }, + "widgets_values": [ + "sd15/realisticVisionV51_v51VAE.safetensors" + ] + }, + { + "id": 18, + "type": "IPAdapterFaceID", + "pos": [ + 850, + 190 + ], + "size": { + "0": 315, + "1": 298 + }, + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 35 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": 34, + "slot_index": 1 + }, + { + "name": "image", + "type": "IMAGE", + "link": 29 + }, + { + "name": "image_negative", + "type": "IMAGE", + "link": null + }, + { + "name": "attn_mask", + "type": "MASK", + "link": null + }, + { + "name": "clip_vision", + "type": "CLIP_VISION", + "link": null + }, + { + "name": "insightface", + "type": "INSIGHTFACE", + "link": null + } + ], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 32 ], "shape": 3, "slot_index": 0 } ], "properties": { - "Node name for S&R": "EmptyLatentImage" + "Node name for S&R": "IPAdapterFaceID" }, "widgets_values": [ - 512, - 512, + 1, + 2, + "linear", + "concat", + 0, 1 ] } ], "links": [ [ + 2, 5, + 0, + 3, + 3, + "LATENT" + ], + [ + 3, + 4, 1, + 6, + 0, + "CLIP" + ], + [ + 4, + 6, + 0, + 3, + 1, + "CONDITIONING" + ], + [ + 5, + 4, 1, 7, 0, @@ -539,107 +488,75 @@ ], [ 6, - 1, - 1, - 8, - 0, - "CLIP" - ], - [ - 8, 7, 0, - 9, - 1, + 3, + 2, "CONDITIONING" ], [ - 9, + 7, + 3, + 0, 8, 0, - 9, - 2, - "CONDITIONING" - ], - [ - 10, - 10, - 0, - 9, - 3, "LATENT" ], [ - 11, - 9, - 0, - 11, - 0, - "LATENT" - ], - [ - 12, + 8, + 4, 2, - 0, - 11, + 8, 1, "VAE" ], [ - 31, - 18, + 9, + 8, 0, 9, 0, - "MODEL" + "IMAGE" ], [ - 48, - 3, + 29, + 12, 0, - 25, - 0, - "IPADAPTER" - ], - [ - 49, - 4, - 0, - 25, - 1, - "CLIP_VISION" - ], - [ - 50, - 6, - 0, - 25, + 18, 2, "IMAGE" ], [ - 51, - 1, + 32, + 18, 0, - 25, 3, + 0, "MODEL" ], [ - 52, - 25, + 34, + 20, + 1, + 18, + 1, + "IPADAPTER" + ], + [ + 35, + 20, 0, 18, 0, "MODEL" ], [ - 53, - 11, + 36, + 4, 0, - 27, + 20, 0, - "IMAGE" + "MODEL" ] ], "groups": [], diff --git a/examples/FaceID_portrait.json b/examples/ipadapter_faceid_batch.json similarity index 70% rename from examples/FaceID_portrait.json rename to examples/ipadapter_faceid_batch.json index ba3a028..3dd6685 100644 --- a/examples/FaceID_portrait.json +++ b/examples/ipadapter_faceid_batch.json @@ -1,20 +1,20 @@ { - "last_node_id": 30, - "last_link_id": 52, + "last_node_id": 32, + "last_link_id": 54, "nodes": [ { "id": 8, "type": "VAEDecode", "pos": [ - 1420, - 200 + 1640, + 710 ], "size": { - "0": 210, + "0": 140, "1": 46 }, "flags": {}, - "order": 18, + "order": 19, "mode": 0, "inputs": [ { @@ -43,415 +43,57 @@ } }, { - "id": 4, - "type": "CheckpointLoaderSimple", + "id": 5, + "type": "EmptyLatentImage", "pos": [ - -72, - 187 + 870, + 1100 ], "size": { "0": 315, - "1": 98 + "1": 106 }, "flags": {}, "order": 0, "mode": 0, "outputs": [ { - "name": "MODEL", - "type": "MODEL", + "name": "LATENT", + "type": "LATENT", "links": [ - 14 + 2 ], "slot_index": 0 - }, - { - "name": "CLIP", - "type": "CLIP", - "links": [ - 3, - 5 - ], - "slot_index": 1 - }, - { - "name": "VAE", - "type": "VAE", - "links": [ - 8 - ], - "slot_index": 2 } ], "properties": { - "Node name for S&R": "CheckpointLoaderSimple" + "Node name for S&R": "EmptyLatentImage" }, "widgets_values": [ - "sd15/realisticVisionV51_v51VAE.safetensors" - ] - }, - { - "id": 15, - "type": "LoadImage", - "pos": [ - -900, - -540 - ], - "size": { - "0": 315, - "1": 314 - }, - "flags": {}, - "order": 1, - "mode": 0, - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 17 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "MASK", - "type": "MASK", - "links": null, - "shape": 3 - } - ], - "properties": { - "Node name for S&R": "LoadImage" - }, - "widgets_values": [ - "theron2.jpg", - "image" - ] - }, - { - "id": 9, - "type": "SaveImage", - "pos": [ - 1422, - 294 - ], - "size": [ - 548.0061157226553, - 599.3138153076163 - ], - "flags": {}, - "order": 19, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 9 - } - ], - "properties": {}, - "widgets_values": [ - "ComfyUI" - ] - }, - { - "id": 16, - "type": "LoadImage", - "pos": [ - -900, - -170 - ], - "size": { - "0": 315, - "1": 314 - }, - "flags": {}, - "order": 2, - "mode": 0, - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 36 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "MASK", - "type": "MASK", - "links": null, - "shape": 3 - } - ], - "properties": { - "Node name for S&R": "LoadImage" - }, - "widgets_values": [ - "theron_8.jpg", - "image" - ] - }, - { - "id": 18, - "type": "ImageBatch", - "pos": [ - -380, - -281 - ], - "size": { - "0": 210, - "1": 46 - }, - "flags": {}, - "order": 13, - "mode": 0, - "inputs": [ - { - "name": "image1", - "type": "IMAGE", - "link": 18 - }, - { - "name": "image2", - "type": "IMAGE", - "link": 36 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 47 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "ImageBatch" - } - }, - { - "id": 27, - "type": "LoadImage", - "pos": [ - -900, - 200 - ], - "size": { - "0": 315, - "1": 314 - }, - "flags": {}, - "order": 3, - "mode": 0, - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 48 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "MASK", - "type": "MASK", - "links": null, - "shape": 3 - } - ], - "properties": { - "Node name for S&R": "LoadImage" - }, - "widgets_values": [ - "theron_6.jpg", - "image" - ] - }, - { - "id": 28, - "type": "ImageBatch", - "pos": [ - -390, - -109 - ], - "size": { - "0": 210, - "1": 46 - }, - "flags": {}, - "order": 14, - "mode": 0, - "inputs": [ - { - "name": "image1", - "type": "IMAGE", - "link": 47 - }, - { - "name": "image2", - "type": "IMAGE", - "link": 48 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 49 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "ImageBatch" - } - }, - { - "id": 29, - "type": "LoadImage", - "pos": [ - -900, - 580 - ], - "size": { - "0": 315, - "1": 314 - }, - "flags": {}, - "order": 4, - "mode": 0, - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 50 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "MASK", - "type": "MASK", - "links": null, - "shape": 3 - } - ], - "properties": { - "Node name for S&R": "LoadImage" - }, - "widgets_values": [ - "theron_7.jpg", - "image" - ] - }, - { - "id": 30, - "type": "ImageBatch", - "pos": [ - -391, - 44 - ], - "size": { - "0": 210, - "1": 46 - }, - "flags": {}, - "order": 15, - "mode": 0, - "inputs": [ - { - "name": "image1", - "type": "IMAGE", - "link": 49 - }, - { - "name": "image2", - "type": "IMAGE", - "link": 50 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 51 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "ImageBatch" - } - }, - { - "id": 6, - "type": "CLIPTextEncode", - "pos": [ - 444, - 154 - ], - "size": { - "0": 422.84503173828125, - "1": 164.31304931640625 - }, - "flags": {}, - "order": 10, - "mode": 0, - "inputs": [ - { - "name": "clip", - "type": "CLIP", - "link": 3 - } - ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 4 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPTextEncode" - }, - "widgets_values": [ - "bronze sculpture of a woman\n\nhighly detailed, 4k, high resolution" + 512, + 512, + 1 ] }, { "id": 3, "type": "KSampler", "pos": [ - 1070, - 199 + 1280, + 710 ], "size": { "0": 315, "1": 262 }, "flags": {}, - "order": 17, + "order": 18, "mode": 0, "inputs": [ { "name": "model", "type": "MODEL", - "link": 52 + "link": 42 }, { "name": "positive", @@ -483,312 +125,54 @@ "Node name for S&R": "KSampler" }, "widgets_values": [ - 134335974046449, + 0, "fixed", - 35, - 7, + 30, + 6.5, "ddpm", "karras", 1 ] }, { - "id": 10, - "type": "IPAdapterApplyFaceID", + "id": 9, + "type": "SaveImage", "pos": [ - 539, - -232 + 1830, + 700 ], "size": { - "0": 315, - "1": 326 + "0": 529.7760009765625, + "1": 582.3048095703125 }, "flags": {}, - "order": 16, + "order": 20, "mode": 0, "inputs": [ { - "name": "ipadapter", - "type": "IPADAPTER", - "link": 10, - "slot_index": 0 - }, - { - "name": "clip_vision", - "type": "CLIP_VISION", - "link": 11, - "slot_index": 1 - }, - { - "name": "insightface", - "type": "INSIGHTFACE", - "link": 12, - "slot_index": 2 - }, - { - "name": "image", + "name": "images", "type": "IMAGE", - "link": 51, - "slot_index": 3 - }, - { - "name": "model", - "type": "MODEL", - "link": 14, - "slot_index": 4 - }, - { - "name": "attn_mask", - "type": "MASK", - "link": null + "link": 9 } ], - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 52 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterApplyFaceID" - }, + "properties": {}, "widgets_values": [ - 1, - 0, - "original", - 0, - 1, - false, - 1, - false - ] - }, - { - "id": 17, - "type": "ImageBatch", - "pos": [ - -371, - -450 - ], - "size": { - "0": 210, - "1": 46 - }, - "flags": {}, - "order": 12, - "mode": 0, - "inputs": [ - { - "name": "image1", - "type": "IMAGE", - "link": 16 - }, - { - "name": "image2", - "type": "IMAGE", - "link": 17 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 18 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "ImageBatch" - } - }, - { - "id": 14, - "type": "LoadImage", - "pos": [ - -900, - -930 - ], - "size": [ - 315, - 314 - ], - "flags": {}, - "order": 5, - "mode": 0, - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 16 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "MASK", - "type": "MASK", - "links": null, - "shape": 3 - } - ], - "properties": { - "Node name for S&R": "LoadImage" - }, - "widgets_values": [ - "theron.jpg", - "image" - ] - }, - { - "id": 13, - "type": "InsightFaceLoader", - "pos": [ - 48, - -244 - ], - "size": { - "0": 315, - "1": 58 - }, - "flags": {}, - "order": 6, - "mode": 0, - "outputs": [ - { - "name": "INSIGHTFACE", - "type": "INSIGHTFACE", - "links": [ - 12 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "InsightFaceLoader" - }, - "widgets_values": [ - "CPU" - ] - }, - { - "id": 12, - "type": "CLIPVisionLoader", - "pos": [ - 43, - -359 - ], - "size": { - "0": 315, - "1": 58 - }, - "flags": {}, - "order": 7, - "mode": 0, - "outputs": [ - { - "name": "CLIP_VISION", - "type": "CLIP_VISION", - "links": [ - 11 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPVisionLoader" - }, - "widgets_values": [ - "IPAdapter_image_encoder_sd15.safetensors" - ] - }, - { - "id": 11, - "type": "IPAdapterModelLoader", - "pos": [ - 34, - -468 - ], - "size": { - "0": 315, - "1": 58 - }, - "flags": {}, - "order": 8, - "mode": 0, - "outputs": [ - { - "name": "IPADAPTER", - "type": "IPADAPTER", - "links": [ - 10 - ], - "shape": 3 - } - ], - "properties": { - "Node name for S&R": "IPAdapterModelLoader" - }, - "widgets_values": [ - "ip-adapter-faceid-portrait_sd15.bin" - ] - }, - { - "id": 5, - "type": "EmptyLatentImage", - "pos": [ - 559, - 638 - ], - "size": { - "0": 315, - "1": 106 - }, - "flags": {}, - "order": 9, - "mode": 0, - "outputs": [ - { - "name": "LATENT", - "type": "LATENT", - "links": [ - 2 - ], - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "EmptyLatentImage" - }, - "widgets_values": [ - 512, - 512, - 1 + "IPAdapter" ] }, { "id": 7, "type": "CLIPTextEncode", "pos": [ - 443, - 393 + 760, + 850 ], "size": { "0": 425.27801513671875, "1": 180.6060791015625 }, "flags": {}, - "order": 11, + "order": 9, "mode": 0, "inputs": [ { @@ -811,7 +195,751 @@ "Node name for S&R": "CLIPTextEncode" }, "widgets_values": [ - "blurry, low quality, distorted, photo, frame, naked, horror" + "blurry, noisy, messy, lowres, jpeg, artifacts, ill, distorted, malformed, naked" + ] + }, + { + "id": 6, + "type": "CLIPTextEncode", + "pos": [ + 760, + 620 + ], + "size": { + "0": 422.84503173828125, + "1": 164.31304931640625 + }, + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [ + { + "name": "clip", + "type": "CLIP", + "link": 3 + } + ], + "outputs": [ + { + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 4 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "CLIPTextEncode" + }, + "widgets_values": [ + "closeup of a beautiful woman wearing a black dress on the seaside\n\nserene, sunset, spring, high quality, detailed, diffuse light" + ] + }, + { + "id": 4, + "type": "CheckpointLoaderSimple", + "pos": [ + 10, + 680 + ], + "size": { + "0": 315, + "1": 98 + }, + "flags": {}, + "order": 1, + "mode": 0, + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 36 + ], + "slot_index": 0 + }, + { + "name": "CLIP", + "type": "CLIP", + "links": [ + 3, + 5 + ], + "slot_index": 1 + }, + { + "name": "VAE", + "type": "VAE", + "links": [ + 8 + ], + "slot_index": 2 + } + ], + "properties": { + "Node name for S&R": "CheckpointLoaderSimple" + }, + "widgets_values": [ + "sd15/realisticVisionV51_v51VAE.safetensors" + ] + }, + { + "id": 22, + "type": "IPAdapterUnifiedLoader", + "pos": [ + 855, + 51 + ], + "size": { + "0": 315, + "1": 78 + }, + "flags": {}, + "order": 15, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 43 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": 38 + } + ], + "outputs": [ + { + "name": "model", + "type": "MODEL", + "links": [ + 40 + ], + "shape": 3, + "slot_index": 0 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "links": [ + 37 + ], + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "IPAdapterUnifiedLoader" + }, + "widgets_values": [ + "FULL FACE - SD1.5 only (portraits stronger)" + ] + }, + { + "id": 21, + "type": "IPAdapter", + "pos": [ + 1280, + 170 + ], + "size": { + "0": 315, + "1": 166 + }, + "flags": {}, + "order": 17, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 40 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": 37, + "slot_index": 1 + }, + { + "name": "image", + "type": "IMAGE", + "link": 53 + }, + { + "name": "attn_mask", + "type": "MASK", + "link": null + } + ], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 42 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "IPAdapter" + }, + "widgets_values": [ + 0.4, + 0, + 1 + ] + }, + { + "id": 20, + "type": "IPAdapterUnifiedLoaderFaceID", + "pos": [ + 457, + 57 + ], + "size": { + "0": 315, + "1": 126 + }, + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 36 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": null + } + ], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 35 + ], + "shape": 3, + "slot_index": 0 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "links": [ + 34, + 38 + ], + "shape": 3, + "slot_index": 1 + } + ], + "properties": { + "Node name for S&R": "IPAdapterUnifiedLoaderFaceID" + }, + "widgets_values": [ + "FACEID PLUS V2", + 0.6, + "CPU" + ] + }, + { + "id": 12, + "type": "LoadImage", + "pos": [ + -220, + -370 + ], + "size": { + "0": 315, + "1": 314 + }, + "flags": {}, + "order": 2, + "mode": 0, + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 44 + ], + "shape": 3, + "slot_index": 0 + }, + { + "name": "MASK", + "type": "MASK", + "links": null, + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "rosario-1.jpg", + "image" + ] + }, + { + "id": 25, + "type": "LoadImage", + "pos": [ + -580, + -380 + ], + "size": { + "0": 315, + "1": 314 + }, + "flags": {}, + "order": 3, + "mode": 0, + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 45 + ], + "shape": 3, + "slot_index": 0 + }, + { + "name": "MASK", + "type": "MASK", + "links": null, + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "rosario_4.jpg", + "image" + ] + }, + { + "id": 24, + "type": "LoadImage", + "pos": [ + -230, + 0 + ], + "size": { + "0": 315, + "1": 314 + }, + "flags": {}, + "order": 4, + "mode": 0, + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 46 + ], + "shape": 3, + "slot_index": 0 + }, + { + "name": "MASK", + "type": "MASK", + "links": null, + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "rosario_5.jpg", + "image" + ] + }, + { + "id": 26, + "type": "LoadImage", + "pos": [ + -580, + 0 + ], + "size": { + "0": 315, + "1": 314 + }, + "flags": {}, + "order": 5, + "mode": 0, + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 47 + ], + "shape": 3, + "slot_index": 0 + }, + { + "name": "MASK", + "type": "MASK", + "links": null, + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "rosario-2.jpg", + "image" + ] + }, + { + "id": 27, + "type": "ImageBatch", + "pos": [ + 180, + -210 + ], + "size": { + "0": 210, + "1": 46 + }, + "flags": {}, + "order": 10, + "mode": 0, + "inputs": [ + { + "name": "image1", + "type": "IMAGE", + "link": 44 + }, + { + "name": "image2", + "type": "IMAGE", + "link": 45 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 48 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "ImageBatch" + } + }, + { + "id": 28, + "type": "ImageBatch", + "pos": [ + 180, + -110 + ], + "size": { + "0": 210, + "1": 46 + }, + "flags": {}, + "order": 11, + "mode": 0, + "inputs": [ + { + "name": "image1", + "type": "IMAGE", + "link": 46 + }, + { + "name": "image2", + "type": "IMAGE", + "link": 47 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 49 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "ImageBatch" + } + }, + { + "id": 18, + "type": "IPAdapterFaceID", + "pos": [ + 850, + 190 + ], + "size": { + "0": 315, + "1": 298 + }, + "flags": {}, + "order": 13, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 35 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": 34, + "slot_index": 1 + }, + { + "name": "image", + "type": "IMAGE", + "link": 50 + }, + { + "name": "image_negative", + "type": "IMAGE", + "link": null + }, + { + "name": "attn_mask", + "type": "MASK", + "link": null + }, + { + "name": "clip_vision", + "type": "CLIP_VISION", + "link": null + }, + { + "name": "insightface", + "type": "INSIGHTFACE", + "link": null + } + ], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 43 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "IPAdapterFaceID" + }, + "widgets_values": [ + 0.8, + 2, + "linear", + "concat", + 0, + 1 + ] + }, + { + "id": 29, + "type": "ImageBatch", + "pos": [ + 420, + -170 + ], + "size": { + "0": 210, + "1": 46 + }, + "flags": {}, + "order": 12, + "mode": 0, + "inputs": [ + { + "name": "image1", + "type": "IMAGE", + "link": 48 + }, + { + "name": "image2", + "type": "IMAGE", + "link": 49 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 50, + 51 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "ImageBatch" + } + }, + { + "id": 31, + "type": "ImageListToBatch+", + "pos": [ + 1218, + -208 + ], + "size": { + "0": 210, + "1": 26 + }, + "flags": {}, + "order": 16, + "mode": 0, + "inputs": [ + { + "name": "image", + "type": "IMAGE", + "link": 52 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 53 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "ImageListToBatch+" + } + }, + { + "id": 30, + "type": "FaceBoundingBox", + "pos": [ + 848, + -211 + ], + "size": { + "0": 315, + "1": 162 + }, + "flags": {}, + "order": 14, + "mode": 0, + "inputs": [ + { + "name": "analysis_models", + "type": "ANALYSIS_MODELS", + "link": 54, + "slot_index": 0 + }, + { + "name": "image", + "type": "IMAGE", + "link": 51 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 52 + ], + "shape": 6, + "slot_index": 0 + }, + { + "name": "x", + "type": "INT", + "links": null, + "shape": 6 + }, + { + "name": "y", + "type": "INT", + "links": null, + "shape": 6 + }, + { + "name": "width", + "type": "INT", + "links": null, + "shape": 6 + }, + { + "name": "height", + "type": "INT", + "links": null, + "shape": 6 + } + ], + "properties": { + "Node name for S&R": "FaceBoundingBox" + }, + "widgets_values": [ + 30, + -1 + ] + }, + { + "id": 32, + "type": "FaceAnalysisModels", + "pos": [ + 602, + -369 + ], + "size": [ + 210, + 82 + ], + "flags": {}, + "order": 6, + "mode": 0, + "outputs": [ + { + "name": "ANALYSIS_MODELS", + "type": "ANALYSIS_MODELS", + "links": [ + 54 + ], + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "FaceAnalysisModels" + }, + "widgets_values": [ + "dlib", + "CPU" ] } ], @@ -881,116 +1009,156 @@ "IMAGE" ], [ - 10, - 11, - 0, - 10, - 0, + 34, + 20, + 1, + 18, + 1, "IPADAPTER" ], [ - 11, - 12, + 35, + 20, 0, - 10, - 1, - "CLIP_VISION" - ], - [ - 12, - 13, + 18, 0, - 10, - 2, - "INSIGHTFACE" - ], - [ - 14, - 4, - 0, - 10, - 4, "MODEL" ], - [ - 16, - 14, - 0, - 17, - 0, - "IMAGE" - ], - [ - 17, - 15, - 0, - 17, - 1, - "IMAGE" - ], - [ - 18, - 17, - 0, - 18, - 0, - "IMAGE" - ], [ 36, - 16, + 4, 0, - 18, + 20, + 0, + "MODEL" + ], + [ + 37, + 22, 1, + 21, + 1, + "IPADAPTER" + ], + [ + 38, + 20, + 1, + 22, + 1, + "IPADAPTER" + ], + [ + 40, + 22, + 0, + 21, + 0, + "MODEL" + ], + [ + 42, + 21, + 0, + 3, + 0, + "MODEL" + ], + [ + 43, + 18, + 0, + 22, + 0, + "MODEL" + ], + [ + 44, + 12, + 0, + 27, + 0, + "IMAGE" + ], + [ + 45, + 25, + 0, + 27, + 1, + "IMAGE" + ], + [ + 46, + 24, + 0, + 28, + 0, "IMAGE" ], [ 47, - 18, + 26, 0, 28, - 0, + 1, "IMAGE" ], [ 48, 27, 0, - 28, - 1, + 29, + 0, "IMAGE" ], [ 49, 28, 0, - 30, - 0, + 29, + 1, "IMAGE" ], [ 50, 29, 0, + 18, + 2, + "IMAGE" + ], + [ + 51, + 29, + 0, 30, 1, "IMAGE" ], [ - 51, + 52, 30, 0, - 10, - 3, + 31, + 0, "IMAGE" ], [ - 52, - 10, + 53, + 31, 0, - 3, + 21, + 2, + "IMAGE" + ], + [ + 54, + 32, 0, - "MODEL" + 30, + 0, + "ANALYSIS_MODELS" ] ], "groups": [], diff --git a/examples/IPAdapter_inpaint.json b/examples/ipadapter_ideal_faceid_config.json similarity index 67% rename from examples/IPAdapter_inpaint.json rename to examples/ipadapter_ideal_faceid_config.json index 2737d2b..70df91a 100644 --- a/examples/IPAdapter_inpaint.json +++ b/examples/ipadapter_ideal_faceid_config.json @@ -1,58 +1,17 @@ { "last_node_id": 23, - "last_link_id": 37, + "last_link_id": 43, "nodes": [ { "id": 8, - "type": "CLIPTextEncode", - "pos": [ - 650, - 420 - ], - "size": { - "0": 210, - "1": 120 - }, - "flags": {}, - "order": 7, - "mode": 0, - "inputs": [ - { - "name": "clip", - "type": "CLIP", - "link": 6 - } - ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 9 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPTextEncode" - }, - "widgets_values": [ - "blurry, horror" - ], - "color": "#322", - "bgcolor": "#533" - }, - { - "id": 11, "type": "VAEDecode", "pos": [ - 1300, - 170 + 1640, + 710 ], "size": { "0": 140, - "1": 50 + "1": 46 }, "flags": {}, "order": 11, @@ -61,12 +20,12 @@ { "name": "samples", "type": "LATENT", - "link": 11 + "link": 7 }, { "name": "vae", "type": "VAE", - "link": 12 + "link": 8 } ], "outputs": [ @@ -74,9 +33,8 @@ "name": "IMAGE", "type": "IMAGE", "links": [ - 13 + 9 ], - "shape": 3, "slot_index": 0 } ], @@ -85,15 +43,107 @@ } }, { - "id": 12, - "type": "SaveImage", + "id": 5, + "type": "EmptyLatentImage", "pos": [ - 1300, - 270 + 870, + 1100 ], "size": { - "0": 400, - "1": 450 + "0": 315, + "1": 106 + }, + "flags": {}, + "order": 0, + "mode": 0, + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 2 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "EmptyLatentImage" + }, + "widgets_values": [ + 512, + 512, + 1 + ] + }, + { + "id": 3, + "type": "KSampler", + "pos": [ + 1280, + 710 + ], + "size": { + "0": 315, + "1": 262 + }, + "flags": {}, + "order": 10, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 42 + }, + { + "name": "positive", + "type": "CONDITIONING", + "link": 4 + }, + { + "name": "negative", + "type": "CONDITIONING", + "link": 6 + }, + { + "name": "latent_image", + "type": "LATENT", + "link": 2 + } + ], + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 7 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "KSampler" + }, + "widgets_values": [ + 0, + "fixed", + 30, + 6.5, + "ddpm", + "karras", + 1 + ] + }, + { + "id": 9, + "type": "SaveImage", + "pos": [ + 1830, + 700 + ], + "size": { + "0": 529.7760009765625, + "1": 582.3048095703125 }, "flags": {}, "order": 12, @@ -102,7 +152,7 @@ { "name": "images", "type": "IMAGE", - "link": 13 + "link": 9 } ], "properties": {}, @@ -110,16 +160,55 @@ "IPAdapter" ] }, + { + "id": 12, + "type": "LoadImage", + "pos": [ + 450, + 240 + ], + "size": { + "0": 315, + "1": 314 + }, + "flags": {}, + "order": 1, + "mode": 0, + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 29 + ], + "shape": 3, + "slot_index": 0 + }, + { + "name": "MASK", + "type": "MASK", + "links": null, + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "rosario_4.jpg", + "image" + ] + }, { "id": 7, "type": "CLIPTextEncode", "pos": [ - 650, - 250 + 760, + 850 ], "size": { - "0": 210, - "1": 120 + "0": 425.27801513671875, + "1": 180.6060791015625 }, "flags": {}, "order": 6, @@ -136,9 +225,8 @@ "name": "CONDITIONING", "type": "CONDITIONING", "links": [ - 25 + 6 ], - "shape": 3, "slot_index": 0 } ], @@ -146,306 +234,233 @@ "Node name for S&R": "CLIPTextEncode" }, "widgets_values": [ - "closeup photo of a renaissance astronaut " - ], - "color": "#232", - "bgcolor": "#353" - }, - { - "id": 14, - "type": "LoadImage", - "pos": [ - 40, - 60 - ], - "size": { - "0": 220, - "1": 320 - }, - "flags": {}, - "order": 0, - "mode": 0, - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 28 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "MASK", - "type": "MASK", - "links": null, - "shape": 3 - } - ], - "properties": { - "Node name for S&R": "LoadImage" - }, - "widgets_values": [ - "venere.jpg", - "image" + "blurry, noisy, messy, lowres, jpeg, artifacts, ill, distorted, malformed, naked" ] }, { - "id": 2, - "type": "VAELoader", + "id": 6, + "type": "CLIPTextEncode", "pos": [ - 290, - 430 + 760, + 620 ], "size": { - "0": 300, - "1": 60 + "0": 422.84503173828125, + "1": 164.31304931640625 }, "flags": {}, - "order": 1, - "mode": 0, - "outputs": [ - { - "name": "VAE", - "type": "VAE", - "links": [ - 12, - 30 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAELoader" - }, - "widgets_values": [ - "vae-ft-mse-840000-ema-pruned.safetensors" - ] - }, - { - "id": 9, - "type": "KSampler", - "pos": [ - 930, - 170 - ], - "size": { - "0": 315, - "1": 262 - }, - "flags": {}, - "order": 10, + "order": 5, "mode": 0, "inputs": [ { - "name": "model", - "type": "MODEL", - "link": 7 - }, - { - "name": "positive", - "type": "CONDITIONING", - "link": 25 - }, - { - "name": "negative", - "type": "CONDITIONING", - "link": 9 - }, - { - "name": "latent_image", - "type": "LATENT", - "link": 32 + "name": "clip", + "type": "CLIP", + "link": 3 } ], "outputs": [ { - "name": "LATENT", - "type": "LATENT", + "name": "CONDITIONING", + "type": "CONDITIONING", "links": [ - 11 + 4 ], - "shape": 3, "slot_index": 0 } ], "properties": { - "Node name for S&R": "KSampler" + "Node name for S&R": "CLIPTextEncode" }, "widgets_values": [ - 34, - "fixed", - 35, - 6, - "ddim", - "ddim_uniform", - 1 - ] - }, - { - "id": 20, - "type": "VAEEncodeForInpaint", - "pos": [ - 650, - 590 - ], - "size": { - "0": 230, - "1": 100 - }, - "flags": {}, - "order": 9, - "mode": 0, - "inputs": [ - { - "name": "pixels", - "type": "IMAGE", - "link": 29 - }, - { - "name": "vae", - "type": "VAE", - "link": 30 - }, - { - "name": "mask", - "type": "MASK", - "link": 37 - } - ], - "outputs": [ - { - "name": "LATENT", - "type": "LATENT", - "links": [ - 32 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAEEncodeForInpaint" - }, - "widgets_values": [ - 12 + "closeup of a beautiful woman wearing a black dress on the seaside\n\nserene, sunset, spring, high quality, detailed, diffuse light" ] }, { "id": 4, - "type": "CLIPVisionLoader", + "type": "CheckpointLoaderSimple", "pos": [ - 290, - 170 + 10, + 680 ], "size": { - "0": 300, - "1": 60 + "0": 315, + "1": 98 }, "flags": {}, "order": 2, "mode": 0, - "outputs": [ - { - "name": "CLIP_VISION", - "type": "CLIP_VISION", - "links": [ - 2 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPVisionLoader" - }, - "widgets_values": [ - "IPAdapter_image_encoder_sd15.safetensors" - ] - }, - { - "id": 1, - "type": "CheckpointLoaderSimple", - "pos": [ - 290, - 280 - ], - "size": { - "0": 300, - "1": 100 - }, - "flags": {}, - "order": 3, - "mode": 0, "outputs": [ { "name": "MODEL", "type": "MODEL", "links": [ - 4 + 36 ], - "shape": 3, "slot_index": 0 }, { "name": "CLIP", "type": "CLIP", "links": [ - 5, - 6 + 3, + 5 ], - "shape": 3, "slot_index": 1 }, { "name": "VAE", "type": "VAE", - "links": null, - "shape": 3 + "links": [ + 8 + ], + "slot_index": 2 } ], "properties": { "Node name for S&R": "CheckpointLoaderSimple" }, "widgets_values": [ - "sd15/absolutereality_v181INPAINTING.safetensors" + "sd15/realisticVisionV51_v51VAE.safetensors" ] }, { - "id": 5, - "type": "IPAdapterApply", + "id": 20, + "type": "IPAdapterUnifiedLoaderFaceID", "pos": [ - 654, - -60 + 460, + 60 ], "size": { - "0": 210, - "1": 258 + "0": 315, + "1": 126 + }, + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 36 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": null + } + ], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 35 + ], + "shape": 3, + "slot_index": 0 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "links": [ + 34, + 38 + ], + "shape": 3, + "slot_index": 1 + } + ], + "properties": { + "Node name for S&R": "IPAdapterUnifiedLoaderFaceID" + }, + "widgets_values": [ + "FACEID PLUS V2", + 0.6, + "CPU" + ] + }, + { + "id": 22, + "type": "IPAdapterUnifiedLoader", + "pos": [ + 855, + 51 + ], + "size": { + "0": 315, + "1": 78 }, "flags": {}, "order": 8, "mode": 0, "inputs": [ { - "name": "ipadapter", - "type": "IPADAPTER", - "link": 1 + "name": "model", + "type": "MODEL", + "link": 43 }, { - "name": "clip_vision", - "type": "CLIP_VISION", - "link": 2 + "name": "ipadapter", + "type": "IPADAPTER", + "link": 38 + } + ], + "outputs": [ + { + "name": "model", + "type": "MODEL", + "links": [ + 40 + ], + "shape": 3, + "slot_index": 0 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "links": [ + 37 + ], + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "IPAdapterUnifiedLoader" + }, + "widgets_values": [ + "FULL FACE - SD1.5 only (portraits stronger)" + ] + }, + { + "id": 21, + "type": "IPAdapter", + "pos": [ + 1280, + 170 + ], + "size": { + "0": 315, + "1": 166 + }, + "flags": {}, + "order": 9, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 40 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": 37, + "slot_index": 1 }, { "name": "image", "type": "IMAGE", - "link": 28 - }, - { - "name": "model", - "type": "MODEL", - "link": 4 + "link": 41 }, { "name": "attn_mask", @@ -458,76 +473,116 @@ "name": "MODEL", "type": "MODEL", "links": [ - 7 + 42 ], "shape": 3, "slot_index": 0 } ], "properties": { - "Node name for S&R": "IPAdapterApply" + "Node name for S&R": "IPAdapter" + }, + "widgets_values": [ + 0.4, + 0, + 1 + ] + }, + { + "id": 18, + "type": "IPAdapterFaceID", + "pos": [ + 850, + 190 + ], + "size": { + "0": 315, + "1": 298 + }, + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 35 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": 34, + "slot_index": 1 + }, + { + "name": "image", + "type": "IMAGE", + "link": 29 + }, + { + "name": "image_negative", + "type": "IMAGE", + "link": null + }, + { + "name": "attn_mask", + "type": "MASK", + "link": null + }, + { + "name": "clip_vision", + "type": "CLIP_VISION", + "link": null + }, + { + "name": "insightface", + "type": "INSIGHTFACE", + "link": null + } + ], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 43 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "IPAdapterFaceID" }, "widgets_values": [ 0.8, + 2, + "linear", + "concat", 0, - "original", - 0, - 1, - false + 1 ] }, { - "id": 3, - "type": "IPAdapterModelLoader", - "pos": [ - 290, - 60 - ], - "size": { - "0": 300, - "1": 60 - }, - "flags": {}, - "order": 4, - "mode": 0, - "outputs": [ - { - "name": "IPADAPTER", - "type": "IPADAPTER", - "links": [ - 1 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterModelLoader" - }, - "widgets_values": [ - "ip-adapter-plus_sd15.safetensors" - ] - }, - { - "id": 19, + "id": 23, "type": "LoadImage", "pos": [ - 370, - 600 + 1280, + -230 ], "size": { - "0": 220, - "1": 320 + "0": 315, + "1": 314 }, "flags": {}, - "order": 5, + "order": 3, "mode": 0, "outputs": [ { "name": "IMAGE", "type": "IMAGE", "links": [ - 29 + 41 ], "shape": 3, "slot_index": 0 @@ -535,50 +590,47 @@ { "name": "MASK", "type": "MASK", - "links": [ - 37 - ], - "shape": 3, - "slot_index": 1 + "links": null, + "shape": 3 } ], "properties": { "Node name for S&R": "LoadImage" }, "widgets_values": [ - "clipspace/clipspace-mask-1375556.png [input]", + "rosario.png", "image" ] } ], "links": [ - [ - 1, - 3, - 0, - 5, - 0, - "IPADAPTER" - ], [ 2, - 4, - 0, 5, - 1, - "CLIP_VISION" - ], - [ - 4, - 1, 0, - 5, 3, - "MODEL" + 3, + "LATENT" + ], + [ + 3, + 4, + 1, + 6, + 0, + "CLIP" + ], + [ + 4, + 6, + 0, + 3, + 1, + "CONDITIONING" ], [ 5, - 1, + 4, 1, 7, 0, @@ -586,99 +638,115 @@ ], [ 6, - 1, - 1, - 8, - 0, - "CLIP" - ], - [ 7, - 5, 0, - 9, - 0, - "MODEL" - ], - [ - 9, - 8, - 0, - 9, + 3, 2, "CONDITIONING" ], [ - 11, - 9, + 7, + 3, 0, - 11, + 8, 0, "LATENT" ], [ - 12, + 8, + 4, 2, - 0, - 11, + 8, 1, "VAE" ], [ - 13, - 11, - 0, - 12, - 0, - "IMAGE" - ], - [ - 25, - 7, + 9, + 8, 0, 9, - 1, - "CONDITIONING" - ], - [ - 28, - 14, 0, - 5, - 2, "IMAGE" ], [ 29, - 19, - 0, - 20, + 12, 0, + 18, + 2, "IMAGE" ], [ - 30, - 2, - 0, + 34, 20, 1, - "VAE" + 18, + 1, + "IPADAPTER" ], [ - 32, + 35, 20, 0, - 9, - 3, - "LATENT" + 18, + 0, + "MODEL" + ], + [ + 36, + 4, + 0, + 20, + 0, + "MODEL" ], [ 37, - 19, + 22, 1, + 21, + 1, + "IPADAPTER" + ], + [ + 38, 20, + 1, + 22, + 1, + "IPADAPTER" + ], + [ + 40, + 22, + 0, + 21, + 0, + "MODEL" + ], + [ + 41, + 23, + 0, + 21, 2, - "MASK" + "IMAGE" + ], + [ + 42, + 21, + 0, + 3, + 0, + "MODEL" + ], + [ + 43, + 18, + 0, + 22, + 0, + "MODEL" ] ], "groups": [], diff --git a/examples/IPAdapter_prepped.json b/examples/ipadapter_negative_image.json similarity index 65% rename from examples/IPAdapter_prepped.json rename to examples/ipadapter_negative_image.json index d346c3a..2c783bd 100644 --- a/examples/IPAdapter_prepped.json +++ b/examples/ipadapter_negative_image.json @@ -1,58 +1,93 @@ { - "last_node_id": 29, - "last_link_id": 64, + "last_node_id": 24, + "last_link_id": 49, "nodes": [ { - "id": 8, - "type": "CLIPTextEncode", + "id": 4, + "type": "CheckpointLoaderSimple", "pos": [ - 650, - 420 + 50, + 730 ], "size": { - "0": 210, - "1": 120 + "0": 315, + "1": 98 }, "flags": {}, - "order": 8, + "order": 0, "mode": 0, - "inputs": [ - { - "name": "clip", - "type": "CLIP", - "link": 6 - } - ], "outputs": [ { - "name": "CONDITIONING", - "type": "CONDITIONING", + "name": "MODEL", + "type": "MODEL", "links": [ - 9 + 20, + 44 ], - "shape": 3, "slot_index": 0 + }, + { + "name": "CLIP", + "type": "CLIP", + "links": [ + 3, + 5 + ], + "slot_index": 1 + }, + { + "name": "VAE", + "type": "VAE", + "links": [ + 8, + 42 + ], + "slot_index": 2 } ], "properties": { - "Node name for S&R": "CLIPTextEncode" + "Node name for S&R": "CheckpointLoaderSimple" }, "widgets_values": [ - "blurry, horror" + "sd15/realisticVisionV51_v51VAE.safetensors" + ] + }, + { + "id": 9, + "type": "SaveImage", + "pos": [ + 1770, + 710 ], - "color": "#322", - "bgcolor": "#533" + "size": { + "0": 529.7760009765625, + "1": 582.3048095703125 + }, + "flags": {}, + "order": 15, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 9 + } + ], + "properties": {}, + "widgets_values": [ + "IPAdapter" + ] }, { "id": 7, "type": "CLIPTextEncode", "pos": [ - 650, - 250 + 690, + 840 ], "size": { - "0": 210, - "1": 120 + "0": 425.27801513671875, + "1": 180.6060791015625 }, "flags": {}, "order": 7, @@ -69,9 +104,9 @@ "name": "CONDITIONING", "type": "CONDITIONING", "links": [ - 8 + 6, + 39 ], - "shape": 3, "slot_index": 0 } ], @@ -79,101 +114,66 @@ "Node name for S&R": "CLIPTextEncode" }, "widgets_values": [ - "" - ], - "color": "#232", - "bgcolor": "#353" + "blurry, noisy, messy, lowres, jpeg, artifacts, ill, distorted, malformed" + ] }, { - "id": 11, - "type": "VAEDecode", + "id": 5, + "type": "EmptyLatentImage", "pos": [ - 1300, - 170 + 801, + 1097 ], "size": { - "0": 140, - "1": 50 + "0": 315, + "1": 106 }, "flags": {}, - "order": 14, + "order": 1, "mode": 0, - "inputs": [ - { - "name": "samples", - "type": "LATENT", - "link": 11 - }, - { - "name": "vae", - "type": "VAE", - "link": 12 - } - ], "outputs": [ { - "name": "IMAGE", - "type": "IMAGE", + "name": "LATENT", + "type": "LATENT", "links": [ - 13 + 2, + 40 ], - "shape": 3, "slot_index": 0 } ], "properties": { - "Node name for S&R": "VAEDecode" - } - }, - { - "id": 12, - "type": "SaveImage", - "pos": [ - 1300, - 270 - ], - "size": { - "0": 400, - "1": 450 + "Node name for S&R": "EmptyLatentImage" }, - "flags": {}, - "order": 15, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 13 - } - ], - "properties": {}, "widgets_values": [ - "IPAdapter" + 512, + 512, + 1 ] }, { - "id": 4, + "id": 16, "type": "CLIPVisionLoader", "pos": [ - 290, - 170 + 308, + 161 ], "size": { - "0": 300, - "1": 60 + "0": 315, + "1": 58 }, "flags": {}, - "order": 0, + "order": 2, "mode": 0, "outputs": [ { "name": "CLIP_VISION", "type": "CLIP_VISION", "links": [ - 2 + 24, + 48 ], - "shape": 3, - "slot_index": 0 + "shape": 3 } ], "properties": { @@ -184,39 +184,71 @@ ] }, { - "id": 9, + "id": 15, + "type": "IPAdapterModelLoader", + "pos": [ + 308, + 52 + ], + "size": { + "0": 315, + "1": 58 + }, + "flags": {}, + "order": 3, + "mode": 0, + "outputs": [ + { + "name": "IPADAPTER", + "type": "IPADAPTER", + "links": [ + 33, + 45 + ], + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "IPAdapterModelLoader" + }, + "widgets_values": [ + "ip-adapter-plus_sd15.safetensors" + ] + }, + { + "id": 3, "type": "KSampler", "pos": [ - 930, - 170 + 1210, + 700 ], "size": { "0": 315, "1": 262 }, "flags": {}, - "order": 13, + "order": 11, "mode": 0, "inputs": [ { "name": "model", "type": "MODEL", - "link": 7 + "link": 23 }, { "name": "positive", "type": "CONDITIONING", - "link": 8 + "link": 4 }, { "name": "negative", "type": "CONDITIONING", - "link": 9 + "link": 6 }, { "name": "latent_image", "type": "LATENT", - "link": 10 + "link": 2 } ], "outputs": [ @@ -224,9 +256,8 @@ "name": "LATENT", "type": "LATENT", "links": [ - 11 + 7 ], - "shape": 3, "slot_index": 0 } ], @@ -237,136 +268,368 @@ 0, "fixed", 30, - 5, - "ddim", - "ddim_uniform", + 6.5, + "dpmpp_2m_sde_gpu", + "exponential", 1 ] }, { - "id": 1, - "type": "CheckpointLoaderSimple", + "id": 8, + "type": "VAEDecode", "pos": [ - 290, - 280 + 1575, + 705 ], "size": { - "0": 300, - "1": 100 + "0": 140, + "1": 46 }, "flags": {}, - "order": 1, + "order": 13, "mode": 0, + "inputs": [ + { + "name": "samples", + "type": "LATENT", + "link": 7 + }, + { + "name": "vae", + "type": "VAE", + "link": 8 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 9 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "VAEDecode" + } + }, + { + "id": 6, + "type": "CLIPTextEncode", + "pos": [ + 690, + 610 + ], + "size": { + "0": 422.84503173828125, + "1": 164.31304931640625 + }, + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [ + { + "name": "clip", + "type": "CLIP", + "link": 3 + } + ], + "outputs": [ + { + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 4, + 38 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "CLIPTextEncode" + }, + "widgets_values": [ + "a castle on a cliff\n\nhigh quality, detailed, diffuse light" + ] + }, + { + "id": 24, + "type": "IPAdapterAdvanced", + "pos": [ + 1800, + 330 + ], + "size": { + "0": 315, + "1": 254 + }, + "flags": {}, + "order": 10, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 44 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": 45, + "slot_index": 1 + }, + { + "name": "image", + "type": "IMAGE", + "link": 46 + }, + { + "name": "image_negative", + "type": "IMAGE", + "link": 49 + }, + { + "name": "attn_mask", + "type": "MASK", + "link": null + }, + { + "name": "clip_vision", + "type": "CLIP_VISION", + "link": 48, + "slot_index": 5 + } + ], "outputs": [ { "name": "MODEL", "type": "MODEL", "links": [ - 4 + 37 ], "shape": 3, "slot_index": 0 - }, - { - "name": "CLIP", - "type": "CLIP", - "links": [ - 5, - 6 - ], - "shape": 3, - "slot_index": 1 - }, - { - "name": "VAE", - "type": "VAE", - "links": null, - "shape": 3 } ], "properties": { - "Node name for S&R": "CheckpointLoaderSimple" + "Node name for S&R": "IPAdapterAdvanced" }, "widgets_values": [ - "sdxl/sd_xl_base_1.0.safetensors" + 0.7000000000000001, + "linear", + "concat", + 0, + 1 ] }, { - "id": 10, - "type": "EmptyLatentImage", + "id": 20, + "type": "PrepImageForClipVision", "pos": [ - 650, - 590 + 775, + 347 + ], + "size": [ + 210, + 106 + ], + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [ + { + "name": "image", + "type": "IMAGE", + "link": 35 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 36, + 46 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "PrepImageForClipVision" + }, + "widgets_values": [ + "LANCZOS", + "top", + 0 + ] + }, + { + "id": 21, + "type": "KSampler", + "pos": [ + 2190, + 330 ], "size": { - "0": 210, - "1": 110 + "0": 315, + "1": 262 }, "flags": {}, - "order": 2, + "order": 12, "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 37 + }, + { + "name": "positive", + "type": "CONDITIONING", + "link": 38 + }, + { + "name": "negative", + "type": "CONDITIONING", + "link": 39 + }, + { + "name": "latent_image", + "type": "LATENT", + "link": 40 + } + ], "outputs": [ { "name": "LATENT", "type": "LATENT", "links": [ - 10 + 41 ], - "shape": 3, "slot_index": 0 } ], "properties": { - "Node name for S&R": "EmptyLatentImage" + "Node name for S&R": "KSampler" }, "widgets_values": [ - 1024, - 1024, + 0, + "fixed", + 30, + 6.5, + "dpmpp_2m_sde_gpu", + "exponential", 1 ] }, { - "id": 2, - "type": "VAELoader", + "id": 14, + "type": "IPAdapterAdvanced", "pos": [ - 940, - 480 + 1199, + 346 ], "size": { - "0": 300, - "1": 60 + "0": 315, + "1": 254 }, "flags": {}, - "order": 3, + "order": 9, "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 20 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": 33, + "slot_index": 1 + }, + { + "name": "image", + "type": "IMAGE", + "link": 36 + }, + { + "name": "image_negative", + "type": "IMAGE", + "link": null + }, + { + "name": "attn_mask", + "type": "MASK", + "link": null + }, + { + "name": "clip_vision", + "type": "CLIP_VISION", + "link": 24, + "slot_index": 5 + } + ], "outputs": [ { - "name": "VAE", - "type": "VAE", + "name": "MODEL", + "type": "MODEL", "links": [ - 12 + 23 ], "shape": 3, "slot_index": 0 } ], "properties": { - "Node name for S&R": "VAELoader" + "Node name for S&R": "IPAdapterAdvanced" }, "widgets_values": [ - "sdxl_vae.safetensors" + 0.7000000000000001, + "linear", + "concat", + 0, + 1 ] }, { - "id": 21, - "type": "LoadImage", + "id": 23, + "type": "SaveImage", "pos": [ - -10, - 440 + 2333, + 711 ], "size": { - "0": 220, - "1": 320 + "0": 529.7760009765625, + "1": 582.3048095703125 + }, + "flags": {}, + "order": 16, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 43 + } + ], + "properties": {}, + "widgets_values": [ + "IPAdapter" + ] + }, + { + "id": 19, + "type": "LoadImage", + "pos": [ + 1206, + -41 + ], + "size": { + "0": 315, + "1": 314 }, "flags": {}, "order": 4, @@ -376,7 +639,7 @@ "name": "IMAGE", "type": "IMAGE", "links": [ - 61 + 49 ], "shape": 3, "slot_index": 0 @@ -392,20 +655,20 @@ "Node name for S&R": "LoadImage" }, "widgets_values": [ - "woman.png", + "trees.jpg", "image" ] }, { - "id": 6, + "id": 12, "type": "LoadImage", "pos": [ - -10, - 70 + 313, + 291 ], "size": { - "0": 220, - "1": 320 + "0": 315, + "1": 314 }, "flags": {}, "order": 5, @@ -415,7 +678,7 @@ "name": "IMAGE", "type": "IMAGE", "links": [ - 63 + 35 ], "shape": 3, "slot_index": 0 @@ -431,34 +694,34 @@ "Node name for S&R": "LoadImage" }, "widgets_values": [ - "girl_sitting.png", + "castle.jpg", "image" ] }, { - "id": 24, - "type": "ImageBatch", + "id": 22, + "type": "VAEDecode", "pos": [ - 380, - 420 + 2581, + 331 ], "size": { - "0": 210, + "0": 140, "1": 46 }, "flags": {}, - "order": 11, + "order": 14, "mode": 0, "inputs": [ { - "name": "image1", - "type": "IMAGE", - "link": 64 + "name": "samples", + "type": "LATENT", + "link": 41 }, { - "name": "image2", - "type": "IMAGE", - "link": 62 + "name": "vae", + "type": "VAE", + "link": 42 } ], "outputs": [ @@ -466,223 +729,44 @@ "name": "IMAGE", "type": "IMAGE", "links": [ - 45 + 43 ], - "shape": 3, "slot_index": 0 } ], "properties": { - "Node name for S&R": "ImageBatch" + "Node name for S&R": "VAEDecode" } - }, - { - "id": 28, - "type": "PrepImageForClipVision", - "pos": [ - 350, - 510 - ], - "size": { - "0": 243.60000610351562, - "1": 110 - }, - "flags": {}, - "order": 9, - "mode": 0, - "inputs": [ - { - "name": "image", - "type": "IMAGE", - "link": 61 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 62 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "PrepImageForClipVision" - }, - "widgets_values": [ - "LANCZOS", - "top", - 0 - ] - }, - { - "id": 29, - "type": "PrepImageForClipVision", - "pos": [ - 350, - 660 - ], - "size": { - "0": 243.60000610351562, - "1": 110 - }, - "flags": {}, - "order": 10, - "mode": 0, - "inputs": [ - { - "name": "image", - "type": "IMAGE", - "link": 63 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 64 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "PrepImageForClipVision" - }, - "widgets_values": [ - "LANCZOS", - "top", - 0 - ] - }, - { - "id": 5, - "type": "IPAdapterApply", - "pos": [ - 653, - -60 - ], - "size": { - "0": 210, - "1": 258 - }, - "flags": {}, - "order": 12, - "mode": 0, - "inputs": [ - { - "name": "ipadapter", - "type": "IPADAPTER", - "link": 1 - }, - { - "name": "clip_vision", - "type": "CLIP_VISION", - "link": 2 - }, - { - "name": "image", - "type": "IMAGE", - "link": 45 - }, - { - "name": "model", - "type": "MODEL", - "link": 4 - }, - { - "name": "attn_mask", - "type": "MASK", - "link": null - } - ], - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 7 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterApply" - }, - "widgets_values": [ - 1, - 0, - "original", - 0, - 1, - false - ] - }, - { - "id": 3, - "type": "IPAdapterModelLoader", - "pos": [ - 290, - 60 - ], - "size": { - "0": 300, - "1": 60 - }, - "flags": {}, - "order": 6, - "mode": 0, - "outputs": [ - { - "name": "IPADAPTER", - "type": "IPADAPTER", - "links": [ - 1 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterModelLoader" - }, - "widgets_values": [ - "ip-adapter_sdxl_vit-h.safetensors" - ] } ], "links": [ - [ - 1, - 3, - 0, - 5, - 0, - "IPADAPTER" - ], [ 2, - 4, - 0, 5, - 1, - "CLIP_VISION" - ], - [ - 4, - 1, 0, - 5, 3, - "MODEL" + 3, + "LATENT" + ], + [ + 3, + 4, + 1, + 6, + 0, + "CLIP" + ], + [ + 4, + 6, + 0, + 3, + 1, + "CONDITIONING" ], [ 5, - 1, + 4, 1, 7, 0, @@ -690,106 +774,178 @@ ], [ 6, - 1, - 1, - 8, - 0, - "CLIP" - ], - [ - 7, - 5, - 0, - 9, - 0, - "MODEL" - ], - [ - 8, 7, 0, - 9, - 1, - "CONDITIONING" - ], - [ - 9, - 8, - 0, - 9, - 2, - "CONDITIONING" - ], - [ - 10, - 10, - 0, - 9, 3, - "LATENT" - ], - [ - 11, - 9, - 0, - 11, - 0, - "LATENT" - ], - [ - 12, 2, + "CONDITIONING" + ], + [ + 7, + 3, 0, - 11, + 8, + 0, + "LATENT" + ], + [ + 8, + 4, + 2, + 8, 1, "VAE" ], [ - 13, - 11, + 9, + 8, 0, - 12, + 9, 0, "IMAGE" ], [ - 45, - 24, + 20, + 4, 0, + 14, + 0, + "MODEL" + ], + [ + 23, + 14, + 0, + 3, + 0, + "MODEL" + ], + [ + 24, + 16, + 0, + 14, 5, + "CLIP_VISION" + ], + [ + 33, + 15, + 0, + 14, + 1, + "IPADAPTER" + ], + [ + 35, + 12, + 0, + 20, + 0, + "IMAGE" + ], + [ + 36, + 20, + 0, + 14, 2, "IMAGE" ], [ - 61, + 37, + 24, + 0, 21, 0, - 28, + "MODEL" + ], + [ + 38, + 6, + 0, + 21, + 1, + "CONDITIONING" + ], + [ + 39, + 7, + 0, + 21, + 2, + "CONDITIONING" + ], + [ + 40, + 5, + 0, + 21, + 3, + "LATENT" + ], + [ + 41, + 21, + 0, + 22, + 0, + "LATENT" + ], + [ + 42, + 4, + 2, + 22, + 1, + "VAE" + ], + [ + 43, + 22, + 0, + 23, 0, "IMAGE" ], [ - 62, - 28, + 44, + 4, + 0, + 24, + 0, + "MODEL" + ], + [ + 45, + 15, 0, 24, 1, - "IMAGE" + "IPADAPTER" ], [ - 63, - 6, - 0, - 29, - 0, - "IMAGE" - ], - [ - 64, - 29, + 46, + 20, 0, 24, + 2, + "IMAGE" + ], + [ + 48, + 16, 0, + 24, + 5, + "CLIP_VISION" + ], + [ + 49, + 19, + 0, + 24, + 3, "IMAGE" ] ], diff --git a/examples/IPAdapter_batch_images.json b/examples/ipadapter_noise_injection.json similarity index 75% rename from examples/IPAdapter_batch_images.json rename to examples/ipadapter_noise_injection.json index e166f6c..0146c03 100644 --- a/examples/IPAdapter_batch_images.json +++ b/examples/ipadapter_noise_injection.json @@ -1,95 +1,94 @@ { - "last_node_id": 14, - "last_link_id": 23, + "last_node_id": 18, + "last_link_id": 30, "nodes": [ { - "id": 10, - "type": "EmptyLatentImage", + "id": 4, + "type": "CheckpointLoaderSimple", "pos": [ - 650, - 590 + 50, + 730 ], "size": { - "0": 210, - "1": 110 + "0": 315, + "1": 98 }, "flags": {}, "order": 0, "mode": 0, "outputs": [ { - "name": "LATENT", - "type": "LATENT", + "name": "MODEL", + "type": "MODEL", "links": [ - 10 + 20 ], - "shape": 3, "slot_index": 0 + }, + { + "name": "CLIP", + "type": "CLIP", + "links": [ + 3, + 5 + ], + "slot_index": 1 + }, + { + "name": "VAE", + "type": "VAE", + "links": [ + 8 + ], + "slot_index": 2 } ], "properties": { - "Node name for S&R": "EmptyLatentImage" + "Node name for S&R": "CheckpointLoaderSimple" }, "widgets_values": [ - 512, - 512, - 1 + "sd15/realisticVisionV51_v51VAE.safetensors" ] }, { - "id": 8, - "type": "CLIPTextEncode", + "id": 9, + "type": "SaveImage", "pos": [ - 650, - 420 + 1770, + 710 ], "size": { - "0": 210, - "1": 120 + "0": 529.7760009765625, + "1": 582.3048095703125 }, "flags": {}, - "order": 9, + "order": 12, "mode": 0, "inputs": [ { - "name": "clip", - "type": "CLIP", - "link": 6 + "name": "images", + "type": "IMAGE", + "link": 9 } ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 9 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPTextEncode" - }, + "properties": {}, "widgets_values": [ - "blurry, horror" - ], - "color": "#322", - "bgcolor": "#533" + "IPAdapter" + ] }, { "id": 7, "type": "CLIPTextEncode", "pos": [ - 650, - 250 + 690, + 840 ], "size": { - "0": 210, - "1": 120 + "0": 425.27801513671875, + "1": 180.6060791015625 }, "flags": {}, - "order": 8, + "order": 6, "mode": 0, "inputs": [ { @@ -103,9 +102,8 @@ "name": "CONDITIONING", "type": "CONDITIONING", "links": [ - 8 + 6 ], - "shape": 3, "slot_index": 0 } ], @@ -113,35 +111,200 @@ "Node name for S&R": "CLIPTextEncode" }, "widgets_values": [ - "beautiful renaissance girl, detailed" - ], - "color": "#232", - "bgcolor": "#353" + "blurry, noisy, messy, lowres, jpeg, artifacts, ill, distorted, malformed" + ] }, { - "id": 11, - "type": "VAEDecode", + "id": 5, + "type": "EmptyLatentImage", "pos": [ - 1300, - 170 + 801, + 1097 ], "size": { - "0": 140, - "1": 50 + "0": 315, + "1": 106 }, "flags": {}, - "order": 12, + "order": 1, + "mode": 0, + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 2 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "EmptyLatentImage" + }, + "widgets_values": [ + 512, + 512, + 1 + ] + }, + { + "id": 16, + "type": "CLIPVisionLoader", + "pos": [ + 308, + 161 + ], + "size": { + "0": 315, + "1": 58 + }, + "flags": {}, + "order": 2, + "mode": 0, + "outputs": [ + { + "name": "CLIP_VISION", + "type": "CLIP_VISION", + "links": [ + 24 + ], + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "CLIPVisionLoader" + }, + "widgets_values": [ + "IPAdapter_image_encoder_sd15.safetensors" + ] + }, + { + "id": 15, + "type": "IPAdapterModelLoader", + "pos": [ + 308, + 52 + ], + "size": { + "0": 315, + "1": 58 + }, + "flags": {}, + "order": 3, + "mode": 0, + "outputs": [ + { + "name": "IPADAPTER", + "type": "IPADAPTER", + "links": [ + 21 + ], + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "IPAdapterModelLoader" + }, + "widgets_values": [ + "ip-adapter-plus_sd15.safetensors" + ] + }, + { + "id": 6, + "type": "CLIPTextEncode", + "pos": [ + 690, + 610 + ], + "size": { + "0": 422.84503173828125, + "1": 164.31304931640625 + }, + "flags": {}, + "order": 5, "mode": 0, "inputs": [ { - "name": "samples", - "type": "LATENT", - "link": 11 + "name": "clip", + "type": "CLIP", + "link": 3 + } + ], + "outputs": [ + { + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 4 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "CLIPTextEncode" + }, + "widgets_values": [ + "in a peaceful spring morning a woman wearing a white shirt is sitting in a park on a bench\n\nhigh quality, detailed, diffuse light" + ] + }, + { + "id": 12, + "type": "LoadImage", + "pos": [ + 311, + 270 + ], + "size": { + "0": 315, + "1": 314 + }, + "flags": {}, + "order": 4, + "mode": 0, + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 25 + ], + "shape": 3, + "slot_index": 0 }, { - "name": "vae", - "type": "VAE", - "link": 12 + "name": "MASK", + "type": "MASK", + "links": null, + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "girl_sitting.png", + "image" + ] + }, + { + "id": 17, + "type": "PrepImageForClipVision", + "pos": [ + 728, + 290 + ], + "size": [ + 210, + 106 + ], + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [ + { + "name": "image", + "type": "IMAGE", + "link": 25 } ], "outputs": [ @@ -149,108 +312,126 @@ "name": "IMAGE", "type": "IMAGE", "links": [ - 13 + 26, + 29 ], "shape": 3, "slot_index": 0 } ], "properties": { - "Node name for S&R": "VAEDecode" - } - }, - { - "id": 2, - "type": "VAELoader", - "pos": [ - 940, - 480 - ], - "size": { - "0": 300, - "1": 60 - }, - "flags": {}, - "order": 1, - "mode": 0, - "outputs": [ - { - "name": "VAE", - "type": "VAE", - "links": [ - 12 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAELoader" + "Node name for S&R": "PrepImageForClipVision" }, "widgets_values": [ - "vae-ft-mse-840000-ema-pruned.safetensors" + "LANCZOS", + "top", + 0.15 ] }, { - "id": 12, - "type": "SaveImage", + "id": 14, + "type": "IPAdapterAdvanced", "pos": [ - 1300, - 270 + 1351, + 214 ], "size": { - "0": 400, - "1": 450 + "0": 315, + "1": 254 }, "flags": {}, - "order": 13, + "order": 9, "mode": 0, "inputs": [ { - "name": "images", + "name": "model", + "type": "MODEL", + "link": 20 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": 21, + "slot_index": 1 + }, + { + "name": "image", "type": "IMAGE", - "link": 13 + "link": 26 + }, + { + "name": "image_negative", + "type": "IMAGE", + "link": 30 + }, + { + "name": "attn_mask", + "type": "MASK", + "link": null + }, + { + "name": "clip_vision", + "type": "CLIP_VISION", + "link": 24, + "slot_index": 5 } ], - "properties": {}, + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 23 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "IPAdapterAdvanced" + }, "widgets_values": [ - "IPAdapter" + 0.7000000000000001, + "linear", + "concat", + 0, + 1 ] }, { - "id": 9, + "id": 3, "type": "KSampler", "pos": [ - 930, - 170 + 1210, + 700 ], "size": { "0": 315, "1": 262 }, "flags": {}, - "order": 11, + "order": 10, "mode": 0, "inputs": [ { "name": "model", "type": "MODEL", - "link": 7 + "link": 23 }, { "name": "positive", "type": "CONDITIONING", - "link": 8 + "link": 4 }, { "name": "negative", "type": "CONDITIONING", - "link": 9 + "link": 6 }, { "name": "latent_image", "type": "LATENT", - "link": 10 + "link": 2 } ], "outputs": [ @@ -258,9 +439,8 @@ "name": "LATENT", "type": "LATENT", "links": [ - 11 + 7 ], - "shape": 3, "slot_index": 0 } ], @@ -270,115 +450,78 @@ "widgets_values": [ 0, "fixed", - 25, - 6, - "ddim", - "ddim_uniform", + 30, + 6.5, + "dpmpp_2m_sde_gpu", + "exponential", 1 ] }, { - "id": 6, - "type": "LoadImage", + "id": 18, + "type": "IPAdapterNoise", "pos": [ - 40, - 60 + 1019, + 405 + ], + "size": [ + 210, + 106 ], - "size": { - "0": 220, - "1": 320 - }, "flags": {}, - "order": 2, + "order": 8, "mode": 0, + "inputs": [ + { + "name": "image_optional", + "type": "IMAGE", + "link": 29 + } + ], "outputs": [ { "name": "IMAGE", "type": "IMAGE", "links": [ - 21 + 30 ], "shape": 3, "slot_index": 0 - }, - { - "name": "MASK", - "type": "MASK", - "links": null, - "shape": 3 } ], "properties": { - "Node name for S&R": "LoadImage" + "Node name for S&R": "IPAdapterNoise" }, "widgets_values": [ - "venere.jpg", - "image" + "fade", + 0.3, + 5 ] }, { - "id": 13, - "type": "LoadImage", + "id": 8, + "type": "VAEDecode", "pos": [ - 40, - 420 + 1575, + 705 ], "size": { - "0": 220, - "1": 320 - }, - "flags": {}, - "order": 3, - "mode": 0, - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 14 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "MASK", - "type": "MASK", - "links": null, - "shape": 3 - } - ], - "properties": { - "Node name for S&R": "LoadImage" - }, - "widgets_values": [ - "portrait.jpg", - "image" - ] - }, - { - "id": 14, - "type": "ImageBatch", - "pos": [ - 290, - 430 - ], - "size": { - "0": 210, + "0": 140, "1": 46 }, "flags": {}, - "order": 7, + "order": 11, "mode": 0, "inputs": [ { - "name": "image1", - "type": "IMAGE", - "link": 21 + "name": "samples", + "type": "LATENT", + "link": 7 }, { - "name": "image2", - "type": "IMAGE", - "link": 14 + "name": "vae", + "type": "VAE", + "link": 8 } ], "outputs": [ @@ -386,221 +529,44 @@ "name": "IMAGE", "type": "IMAGE", "links": [ - 23 + 9 ], - "shape": 3, "slot_index": 0 } ], "properties": { - "Node name for S&R": "ImageBatch" + "Node name for S&R": "VAEDecode" } - }, - { - "id": 1, - "type": "CheckpointLoaderSimple", - "pos": [ - 290, - 280 - ], - "size": { - "0": 300, - "1": 100 - }, - "flags": {}, - "order": 4, - "mode": 0, - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 4 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "CLIP", - "type": "CLIP", - "links": [ - 5, - 6 - ], - "shape": 3, - "slot_index": 1 - }, - { - "name": "VAE", - "type": "VAE", - "links": null, - "shape": 3 - } - ], - "properties": { - "Node name for S&R": "CheckpointLoaderSimple" - }, - "widgets_values": [ - "sd15/absolutereality_v181.safetensors" - ] - }, - { - "id": 5, - "type": "IPAdapterApply", - "pos": [ - 649, - -62 - ], - "size": { - "0": 210, - "1": 258 - }, - "flags": {}, - "order": 10, - "mode": 0, - "inputs": [ - { - "name": "ipadapter", - "type": "IPADAPTER", - "link": 1 - }, - { - "name": "clip_vision", - "type": "CLIP_VISION", - "link": 2 - }, - { - "name": "image", - "type": "IMAGE", - "link": 23 - }, - { - "name": "model", - "type": "MODEL", - "link": 4 - }, - { - "name": "attn_mask", - "type": "MASK", - "link": null - } - ], - "outputs": [ - { - "name": "MODEL", - "type": "MODEL", - "links": [ - 7 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterApply" - }, - "widgets_values": [ - 1, - 0, - "original", - 0, - 1, - false - ] - }, - { - "id": 3, - "type": "IPAdapterModelLoader", - "pos": [ - 291, - -35 - ], - "size": { - "0": 300, - "1": 60 - }, - "flags": {}, - "order": 5, - "mode": 0, - "outputs": [ - { - "name": "IPADAPTER", - "type": "IPADAPTER", - "links": [ - 1 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "IPAdapterModelLoader" - }, - "widgets_values": [ - "ip-adapter_sd15.safetensors" - ] - }, - { - "id": 4, - "type": "CLIPVisionLoader", - "pos": [ - 297, - 82 - ], - "size": { - "0": 300, - "1": 60 - }, - "flags": {}, - "order": 6, - "mode": 0, - "outputs": [ - { - "name": "CLIP_VISION", - "type": "CLIP_VISION", - "links": [ - 2 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPVisionLoader" - }, - "widgets_values": [ - "IPAdapter_image_encoder_sd15.safetensors" - ] } ], "links": [ - [ - 1, - 3, - 0, - 5, - 0, - "IPADAPTER" - ], [ 2, - 4, - 0, 5, - 1, - "CLIP_VISION" - ], - [ - 4, - 1, 0, - 5, 3, - "MODEL" + 3, + "LATENT" + ], + [ + 3, + 4, + 1, + 6, + 0, + "CLIP" + ], + [ + 4, + 6, + 0, + 3, + 1, + "CONDITIONING" ], [ 5, - 1, + 4, 1, 7, 0, @@ -608,91 +574,99 @@ ], [ 6, - 1, - 1, - 8, - 0, - "CLIP" - ], - [ - 7, - 5, - 0, - 9, - 0, - "MODEL" - ], - [ - 8, 7, 0, - 9, - 1, - "CONDITIONING" - ], - [ - 9, - 8, - 0, - 9, - 2, - "CONDITIONING" - ], - [ - 10, - 10, - 0, - 9, 3, - "LATENT" - ], - [ - 11, - 9, - 0, - 11, - 0, - "LATENT" - ], - [ - 12, 2, + "CONDITIONING" + ], + [ + 7, + 3, 0, - 11, + 8, + 0, + "LATENT" + ], + [ + 8, + 4, + 2, + 8, 1, "VAE" ], [ - 13, - 11, + 9, + 8, 0, - 12, + 9, 0, "IMAGE" ], [ - 14, - 13, + 20, + 4, 0, 14, - 1, - "IMAGE" + 0, + "MODEL" ], [ 21, - 6, + 15, 0, 14, - 0, - "IMAGE" + 1, + "IPADAPTER" ], [ 23, 14, 0, + 3, + 0, + "MODEL" + ], + [ + 24, + 16, + 0, + 14, 5, + "CLIP_VISION" + ], + [ + 25, + 12, + 0, + 17, + 0, + "IMAGE" + ], + [ + 26, + 17, + 0, + 14, 2, "IMAGE" + ], + [ + 29, + 17, + 0, + 18, + 0, + "IMAGE" + ], + [ + 30, + 18, + 0, + 14, + 3, + "IMAGE" ] ], "groups": [], diff --git a/IPAdapter_workflow.json b/examples/ipadapter_tiled.json similarity index 77% rename from IPAdapter_workflow.json rename to examples/ipadapter_tiled.json index 6f66f28..48a02c8 100644 --- a/IPAdapter_workflow.json +++ b/examples/ipadapter_tiled.json @@ -1,92 +1,65 @@ { - "last_node_id": 12, - "last_link_id": 13, + "last_node_id": 18, + "last_link_id": 32, "nodes": [ { - "id": 10, - "type": "EmptyLatentImage", + "id": 4, + "type": "CheckpointLoaderSimple", "pos": [ - 650, - 590 + 50, + 730 ], "size": { - "0": 210, - "1": 110 + "0": 315, + "1": 98 }, "flags": {}, "order": 0, "mode": 0, "outputs": [ { - "name": "LATENT", - "type": "LATENT", + "name": "MODEL", + "type": "MODEL", "links": [ - 10 + 29 ], - "shape": 3, "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "EmptyLatentImage" - }, - "widgets_values": [ - 512, - 512, - 1 - ] - }, - { - "id": 8, - "type": "CLIPTextEncode", - "pos": [ - 650, - 420 - ], - "size": { - "0": 210, - "1": 120 - }, - "flags": {}, - "order": 7, - "mode": 0, - "inputs": [ + }, { - "name": "clip", + "name": "CLIP", "type": "CLIP", - "link": 6 - } - ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", "links": [ - 9 + 3, + 5 ], - "shape": 3, - "slot_index": 0 + "slot_index": 1 + }, + { + "name": "VAE", + "type": "VAE", + "links": [ + 8 + ], + "slot_index": 2 } ], "properties": { - "Node name for S&R": "CLIPTextEncode" + "Node name for S&R": "CheckpointLoaderSimple" }, "widgets_values": [ - "blurry, horror" - ], - "color": "#322", - "bgcolor": "#533" + "sd15/realisticVisionV51_v51VAE.safetensors" + ] }, { "id": 7, "type": "CLIPTextEncode", "pos": [ - 650, - 250 + 690, + 840 ], "size": { - "0": 210, - "1": 120 + "0": 425.27801513671875, + "1": 180.6060791015625 }, "flags": {}, "order": 6, @@ -103,9 +76,8 @@ "name": "CONDITIONING", "type": "CONDITIONING", "links": [ - 8 + 6 ], - "shape": 3, "slot_index": 0 } ], @@ -113,35 +85,33 @@ "Node name for S&R": "CLIPTextEncode" }, "widgets_values": [ - "beautiful renaissance girl, detailed" - ], - "color": "#232", - "bgcolor": "#353" + "blurry, noisy, messy, lowres, jpeg, artifacts, ill, distorted, malformed" + ] }, { - "id": 11, + "id": 8, "type": "VAEDecode", "pos": [ - 1300, - 170 + 1570, + 700 ], "size": { "0": 140, - "1": 50 + "1": 46 }, "flags": {}, - "order": 10, + "order": 9, "mode": 0, "inputs": [ { "name": "samples", "type": "LATENT", - "link": 11 + "link": 7 }, { "name": "vae", "type": "VAE", - "link": 12 + "link": 8 } ], "outputs": [ @@ -149,9 +119,8 @@ "name": "IMAGE", "type": "IMAGE", "links": [ - 13 + 9 ], - "shape": 3, "slot_index": 0 } ], @@ -160,83 +129,25 @@ } }, { - "id": 2, - "type": "VAELoader", + "id": 12, + "type": "LoadImage", "pos": [ - 940, - 480 + 250, + 290 ], "size": { - "0": 300, - "1": 60 + "0": 315, + "1": 314 }, "flags": {}, "order": 1, "mode": 0, - "outputs": [ - { - "name": "VAE", - "type": "VAE", - "links": [ - 12 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAELoader" - }, - "widgets_values": [ - "vae-ft-mse-840000-ema-pruned.safetensors" - ] - }, - { - "id": 12, - "type": "SaveImage", - "pos": [ - 1300, - 270 - ], - "size": { - "0": 400, - "1": 450 - }, - "flags": {}, - "order": 11, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 13 - } - ], - "properties": {}, - "widgets_values": [ - "IPAdapter" - ] - }, - { - "id": 6, - "type": "LoadImage", - "pos": [ - 40, - 60 - ], - "size": { - "0": 220, - "1": 320 - }, - "flags": {}, - "order": 2, - "mode": 0, "outputs": [ { "name": "IMAGE", "type": "IMAGE", "links": [ - 3 + 27 ], "shape": 3, "slot_index": 0 @@ -252,90 +163,68 @@ "Node name for S&R": "LoadImage" }, "widgets_values": [ - "venere.jpg", + "girl_sitting.png", "image" ] }, { - "id": 9, - "type": "KSampler", + "id": 6, + "type": "CLIPTextEncode", "pos": [ - 930, - 170 + 690, + 610 ], "size": { - "0": 315, - "1": 262 + "0": 422.84503173828125, + "1": 164.31304931640625 }, "flags": {}, - "order": 9, + "order": 5, "mode": 0, "inputs": [ { - "name": "model", - "type": "MODEL", - "link": 7 - }, - { - "name": "positive", - "type": "CONDITIONING", - "link": 8 - }, - { - "name": "negative", - "type": "CONDITIONING", - "link": 9 - }, - { - "name": "latent_image", - "type": "LATENT", - "link": 10 + "name": "clip", + "type": "CLIP", + "link": 3 } ], "outputs": [ { - "name": "LATENT", - "type": "LATENT", + "name": "CONDITIONING", + "type": "CONDITIONING", "links": [ - 11 + 4 ], - "shape": 3, "slot_index": 0 } ], "properties": { - "Node name for S&R": "KSampler" + "Node name for S&R": "CLIPTextEncode" }, "widgets_values": [ - 0, - "fixed", - 25, - 6, - "ddim", - "ddim_uniform", - 1 + "in a peaceful spring morning a woman wearing a white shirt is sitting in a park on a bench\n\nhigh quality, detailed, diffuse light" ] }, { - "id": 4, + "id": 16, "type": "CLIPVisionLoader", "pos": [ - 290, - 170 + 250, + 180 ], "size": { - "0": 300, - "1": 60 + "0": 315, + "1": 58 }, "flags": {}, - "order": 3, + "order": 2, "mode": 0, "outputs": [ { "name": "CLIP_VISION", "type": "CLIP_VISION", "links": [ - 2 + 32 ], "shape": 3, "slot_index": 0 @@ -349,137 +238,117 @@ ] }, { - "id": 1, - "type": "CheckpointLoaderSimple", + "id": 5, + "type": "EmptyLatentImage", "pos": [ - 290, - 280 + 801, + 1097 ], "size": { - "0": 300, - "1": 100 + "0": 315, + "1": 106 }, "flags": {}, - "order": 4, + "order": 3, "mode": 0, "outputs": [ { - "name": "MODEL", - "type": "MODEL", + "name": "LATENT", + "type": "LATENT", "links": [ - 4 + 2 ], - "shape": 3, "slot_index": 0 - }, - { - "name": "CLIP", - "type": "CLIP", - "links": [ - 5, - 6 - ], - "shape": 3, - "slot_index": 1 - }, - { - "name": "VAE", - "type": "VAE", - "links": null, - "shape": 3 } ], "properties": { - "Node name for S&R": "CheckpointLoaderSimple" + "Node name for S&R": "EmptyLatentImage" }, "widgets_values": [ - "v1-5-pruned-emaonly.safetensors" + 512, + 768, + 1 ] }, { - "id": 5, - "type": "IPAdapterApply", + "id": 3, + "type": "KSampler", "pos": [ - 651, - -57 + 1210, + 700 ], "size": { - "0": 210, - "1": 258 + "0": 315, + "1": 262 }, "flags": {}, "order": 8, "mode": 0, "inputs": [ - { - "name": "ipadapter", - "type": "IPADAPTER", - "link": 1 - }, - { - "name": "clip_vision", - "type": "CLIP_VISION", - "link": 2 - }, - { - "name": "image", - "type": "IMAGE", - "link": 3 - }, { "name": "model", "type": "MODEL", + "link": 30 + }, + { + "name": "positive", + "type": "CONDITIONING", "link": 4 }, { - "name": "attn_mask", - "type": "MASK", - "link": null + "name": "negative", + "type": "CONDITIONING", + "link": 6 + }, + { + "name": "latent_image", + "type": "LATENT", + "link": 2 } ], "outputs": [ { - "name": "MODEL", - "type": "MODEL", + "name": "LATENT", + "type": "LATENT", "links": [ 7 ], - "shape": 3, "slot_index": 0 } ], "properties": { - "Node name for S&R": "IPAdapterApply" + "Node name for S&R": "KSampler" }, "widgets_values": [ - 1, - 0, - "original", - 0, - 1, - false + 2, + "fixed", + 30, + 6.5, + "ddpm", + "karras", + 1 ] }, { - "id": 3, + "id": 15, "type": "IPAdapterModelLoader", "pos": [ - 290, - 60 + 250, + 70 ], "size": { - "0": 300, - "1": 60 + "0": 315, + "1": 58 }, "flags": {}, - "order": 5, + "order": 4, "mode": 0, "outputs": [ { "name": "IPADAPTER", "type": "IPADAPTER", "links": [ - 1 + 31 ], "shape": 3, "slot_index": 0 @@ -489,46 +358,145 @@ "Node name for S&R": "IPAdapterModelLoader" }, "widgets_values": [ - "ip-adapter_sd15.safetensors" + "ip-adapter-plus_sd15.safetensors" + ] + }, + { + "id": 18, + "type": "IPAdapterTiled", + "pos": [ + 700, + 230 + ], + "size": { + "0": 315, + "1": 278 + }, + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 29 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": 31 + }, + { + "name": "image", + "type": "IMAGE", + "link": 27 + }, + { + "name": "image_negative", + "type": "IMAGE", + "link": null + }, + { + "name": "attn_mask", + "type": "MASK", + "link": null + }, + { + "name": "clip_vision", + "type": "CLIP_VISION", + "link": 32 + } + ], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 30 + ], + "shape": 3, + "slot_index": 0 + }, + { + "name": "tiles", + "type": "IMAGE", + "links": null, + "shape": 3 + }, + { + "name": "masks", + "type": "MASK", + "links": null, + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "IPAdapterTiled" + }, + "widgets_values": [ + 0.7000000000000001, + "ease in", + "concat", + 0, + 1, + 0 + ] + }, + { + "id": 9, + "type": "SaveImage", + "pos": [ + 1768, + 700 + ], + "size": { + "0": 529.7760009765625, + "1": 582.3048095703125 + }, + "flags": {}, + "order": 10, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 9 + } + ], + "properties": {}, + "widgets_values": [ + "IPAdapter" ] } ], "links": [ - [ - 1, - 3, - 0, - 5, - 0, - "IPADAPTER" - ], [ 2, - 4, - 0, 5, - 1, - "CLIP_VISION" + 0, + 3, + 3, + "LATENT" ], [ 3, + 4, + 1, 6, 0, - 5, - 2, - "IMAGE" + "CLIP" ], [ 4, - 1, + 6, 0, - 5, 3, - "MODEL" + 1, + "CONDITIONING" ], [ 5, - 1, + 4, 1, 7, 0, @@ -536,67 +504,75 @@ ], [ 6, - 1, - 1, - 8, - 0, - "CLIP" - ], - [ - 7, - 5, - 0, - 9, - 0, - "MODEL" - ], - [ - 8, 7, 0, - 9, - 1, - "CONDITIONING" - ], - [ - 9, - 8, - 0, - 9, - 2, - "CONDITIONING" - ], - [ - 10, - 10, - 0, - 9, 3, - "LATENT" - ], - [ - 11, - 9, - 0, - 11, - 0, - "LATENT" - ], - [ - 12, 2, + "CONDITIONING" + ], + [ + 7, + 3, 0, - 11, + 8, + 0, + "LATENT" + ], + [ + 8, + 4, + 2, + 8, 1, "VAE" ], [ - 13, - 11, + 9, + 8, 0, - 12, + 9, 0, "IMAGE" + ], + [ + 27, + 12, + 0, + 18, + 2, + "IMAGE" + ], + [ + 29, + 4, + 0, + 18, + 0, + "MODEL" + ], + [ + 30, + 18, + 0, + 3, + 0, + "MODEL" + ], + [ + 31, + 15, + 0, + 18, + 1, + "IPADAPTER" + ], + [ + 32, + 16, + 0, + 18, + 5, + "CLIP_VISION" ] ], "groups": [], diff --git a/examples/ipadapter_weight_types.json b/examples/ipadapter_weight_types.json new file mode 100644 index 0000000..1c42cf6 --- /dev/null +++ b/examples/ipadapter_weight_types.json @@ -0,0 +1,1733 @@ +{ + "last_node_id": 37, + "last_link_id": 82, + "nodes": [ + { + "id": 4, + "type": "CheckpointLoaderSimple", + "pos": [ + 50, + 730 + ], + "size": { + "0": 315, + "1": 98 + }, + "flags": {}, + "order": 0, + "mode": 0, + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 20, + 35, + 46, + 57, + 68 + ], + "slot_index": 0 + }, + { + "name": "CLIP", + "type": "CLIP", + "links": [ + 3, + 5 + ], + "slot_index": 1 + }, + { + "name": "VAE", + "type": "VAE", + "links": [ + 8, + 33, + 44, + 55, + 66 + ], + "slot_index": 2 + } + ], + "properties": { + "Node name for S&R": "CheckpointLoaderSimple" + }, + "widgets_values": [ + "sd15/realisticVisionV51_v51VAE.safetensors" + ] + }, + { + "id": 6, + "type": "CLIPTextEncode", + "pos": [ + 690, + 610 + ], + "size": { + "0": 422.84503173828125, + "1": 164.31304931640625 + }, + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [ + { + "name": "clip", + "type": "CLIP", + "link": 3 + } + ], + "outputs": [ + { + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 4, + 29, + 40, + 51, + 62 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "CLIPTextEncode" + }, + "widgets_values": [ + "closeup of a fierce warrior woman wearing a full armor at the end of a battle\n\nhigh quality, detailed" + ] + }, + { + "id": 7, + "type": "CLIPTextEncode", + "pos": [ + 690, + 840 + ], + "size": { + "0": 425.27801513671875, + "1": 180.6060791015625 + }, + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [ + { + "name": "clip", + "type": "CLIP", + "link": 5 + } + ], + "outputs": [ + { + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 6, + 30, + 41, + 52, + 63 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "CLIPTextEncode" + }, + "widgets_values": [ + "blurry, noisy, messy, lowres, jpeg, artifacts, ill, distorted, malformed" + ] + }, + { + "id": 5, + "type": "EmptyLatentImage", + "pos": [ + 801, + 1097 + ], + "size": { + "0": 315, + "1": 106 + }, + "flags": {}, + "order": 1, + "mode": 0, + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 2, + 31, + 42, + 53, + 64 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "EmptyLatentImage" + }, + "widgets_values": [ + 512, + 512, + 1 + ] + }, + { + "id": 16, + "type": "CLIPVisionLoader", + "pos": [ + 308, + 161 + ], + "size": { + "0": 315, + "1": 58 + }, + "flags": {}, + "order": 2, + "mode": 0, + "outputs": [ + { + "name": "CLIP_VISION", + "type": "CLIP_VISION", + "links": [ + 24, + 38, + 49, + 60, + 71 + ], + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "CLIPVisionLoader" + }, + "widgets_values": [ + "IPAdapter_image_encoder_sd15.safetensors" + ] + }, + { + "id": 15, + "type": "IPAdapterModelLoader", + "pos": [ + 308, + 52 + ], + "size": { + "0": 315, + "1": 58 + }, + "flags": {}, + "order": 3, + "mode": 0, + "outputs": [ + { + "name": "IPADAPTER", + "type": "IPADAPTER", + "links": [ + 21, + 36, + 47, + 58, + 69 + ], + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "IPAdapterModelLoader" + }, + "widgets_values": [ + "ip-adapter-plus_sd15.safetensors" + ] + }, + { + "id": 12, + "type": "LoadImage", + "pos": [ + 311, + 270 + ], + "size": { + "0": 315, + "1": 314 + }, + "flags": {}, + "order": 4, + "mode": 0, + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 27, + 37, + 48, + 59, + 70 + ], + "shape": 3, + "slot_index": 0 + }, + { + "name": "MASK", + "type": "MASK", + "links": null, + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "warrior_woman.png", + "image" + ] + }, + { + "id": 3, + "type": "KSampler", + "pos": [ + 1660, + 290 + ], + "size": { + "0": 315, + "1": 262 + }, + "flags": {}, + "order": 12, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 23 + }, + { + "name": "positive", + "type": "CONDITIONING", + "link": 4 + }, + { + "name": "negative", + "type": "CONDITIONING", + "link": 6 + }, + { + "name": "latent_image", + "type": "LATENT", + "link": 2 + } + ], + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 7 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "KSampler" + }, + "widgets_values": [ + 0, + "fixed", + 30, + 6.5, + "dpmpp_2m", + "karras", + 1 + ] + }, + { + "id": 20, + "type": "SaveImage", + "pos": [ + 2030, + 940 + ], + "size": { + "0": 529.7760009765625, + "1": 582.3048095703125 + }, + "flags": {}, + "order": 23, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 34 + } + ], + "properties": {}, + "widgets_values": [ + "IPAdapter" + ] + }, + { + "id": 18, + "type": "KSampler", + "pos": [ + 1660, + 940 + ], + "size": { + "0": 315, + "1": 262 + }, + "flags": {}, + "order": 13, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 28 + }, + { + "name": "positive", + "type": "CONDITIONING", + "link": 29 + }, + { + "name": "negative", + "type": "CONDITIONING", + "link": 30 + }, + { + "name": "latent_image", + "type": "LATENT", + "link": 31 + } + ], + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 32 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "KSampler" + }, + "widgets_values": [ + 0, + "fixed", + 30, + 6.5, + "dpmpp_2m", + "karras", + 1 + ] + }, + { + "id": 19, + "type": "VAEDecode", + "pos": [ + 1830, + 1280 + ], + "size": { + "0": 140, + "1": 46 + }, + "flags": {}, + "order": 18, + "mode": 0, + "inputs": [ + { + "name": "samples", + "type": "LATENT", + "link": 32 + }, + { + "name": "vae", + "type": "VAE", + "link": 33 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 34 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "VAEDecode" + } + }, + { + "id": 8, + "type": "VAEDecode", + "pos": [ + 1820, + 610 + ], + "size": { + "0": 140, + "1": 46 + }, + "flags": {}, + "order": 17, + "mode": 0, + "inputs": [ + { + "name": "samples", + "type": "LATENT", + "link": 7 + }, + { + "name": "vae", + "type": "VAE", + "link": 8 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 9 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "VAEDecode" + } + }, + { + "id": 9, + "type": "SaveImage", + "pos": [ + 2040, + 300 + ], + "size": { + "0": 529.7760009765625, + "1": 582.3048095703125 + }, + "flags": {}, + "order": 22, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 9 + } + ], + "properties": {}, + "widgets_values": [ + "IPAdapter" + ] + }, + { + "id": 14, + "type": "IPAdapterAdvanced", + "pos": [ + 1290, + 250 + ], + "size": { + "0": 315, + "1": 254 + }, + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 20 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": 21, + "slot_index": 1 + }, + { + "name": "image", + "type": "IMAGE", + "link": 27 + }, + { + "name": "image_negative", + "type": "IMAGE", + "link": null + }, + { + "name": "attn_mask", + "type": "MASK", + "link": null + }, + { + "name": "clip_vision", + "type": "CLIP_VISION", + "link": 24, + "slot_index": 5 + } + ], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 23 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "IPAdapterAdvanced" + }, + "widgets_values": [ + 0.8, + "linear", + "concat", + 0, + 1 + ] + }, + { + "id": 21, + "type": "IPAdapterAdvanced", + "pos": [ + 1280, + 900 + ], + "size": { + "0": 315, + "1": 254 + }, + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 35 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": 36, + "slot_index": 1 + }, + { + "name": "image", + "type": "IMAGE", + "link": 37 + }, + { + "name": "image_negative", + "type": "IMAGE", + "link": null + }, + { + "name": "attn_mask", + "type": "MASK", + "link": null + }, + { + "name": "clip_vision", + "type": "CLIP_VISION", + "link": 38, + "slot_index": 5 + } + ], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 28 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "IPAdapterAdvanced" + }, + "widgets_values": [ + 0.8, + "ease in", + "concat", + 0, + 1 + ] + }, + { + "id": 22, + "type": "KSampler", + "pos": [ + 1660, + 1580 + ], + "size": { + "0": 315, + "1": 262 + }, + "flags": {}, + "order": 14, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 39 + }, + { + "name": "positive", + "type": "CONDITIONING", + "link": 40 + }, + { + "name": "negative", + "type": "CONDITIONING", + "link": 41 + }, + { + "name": "latent_image", + "type": "LATENT", + "link": 42 + } + ], + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 43 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "KSampler" + }, + "widgets_values": [ + 0, + "fixed", + 30, + 6.5, + "dpmpp_2m", + "karras", + 1 + ] + }, + { + "id": 23, + "type": "VAEDecode", + "pos": [ + 1830, + 1920 + ], + "size": { + "0": 140, + "1": 46 + }, + "flags": {}, + "order": 19, + "mode": 0, + "inputs": [ + { + "name": "samples", + "type": "LATENT", + "link": 43 + }, + { + "name": "vae", + "type": "VAE", + "link": 44 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 45 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "VAEDecode" + } + }, + { + "id": 25, + "type": "IPAdapterAdvanced", + "pos": [ + 1280, + 1540 + ], + "size": { + "0": 315, + "1": 254 + }, + "flags": {}, + "order": 9, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 46 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": 47, + "slot_index": 1 + }, + { + "name": "image", + "type": "IMAGE", + "link": 48 + }, + { + "name": "image_negative", + "type": "IMAGE", + "link": null + }, + { + "name": "attn_mask", + "type": "MASK", + "link": null + }, + { + "name": "clip_vision", + "type": "CLIP_VISION", + "link": 49, + "slot_index": 5 + } + ], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 39 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "IPAdapterAdvanced" + }, + "widgets_values": [ + 0.8, + "ease out", + "concat", + 0, + 1 + ] + }, + { + "id": 24, + "type": "SaveImage", + "pos": [ + 2030, + 1580 + ], + "size": { + "0": 529.7760009765625, + "1": 582.3048095703125 + }, + "flags": {}, + "order": 24, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 45 + } + ], + "properties": {}, + "widgets_values": [ + "IPAdapter" + ] + }, + { + "id": 27, + "type": "VAEDecode", + "pos": [ + 3750, + 670 + ], + "size": { + "0": 140, + "1": 46 + }, + "flags": {}, + "order": 20, + "mode": 0, + "inputs": [ + { + "name": "samples", + "type": "LATENT", + "link": 54 + }, + { + "name": "vae", + "type": "VAE", + "link": 55 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 56 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "VAEDecode" + } + }, + { + "id": 28, + "type": "SaveImage", + "pos": [ + 2620, + 300 + ], + "size": { + "0": 529.7760009765625, + "1": 582.3048095703125 + }, + "flags": {}, + "order": 25, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 56 + } + ], + "properties": {}, + "widgets_values": [ + "IPAdapter" + ] + }, + { + "id": 30, + "type": "KSampler", + "pos": [ + 3590, + 1000 + ], + "size": { + "0": 315, + "1": 262 + }, + "flags": {}, + "order": 16, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 61 + }, + { + "name": "positive", + "type": "CONDITIONING", + "link": 62 + }, + { + "name": "negative", + "type": "CONDITIONING", + "link": 63 + }, + { + "name": "latent_image", + "type": "LATENT", + "link": 64 + } + ], + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 65 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "KSampler" + }, + "widgets_values": [ + 0, + "fixed", + 30, + 6.5, + "dpmpp_2m", + "karras", + 1 + ] + }, + { + "id": 31, + "type": "VAEDecode", + "pos": [ + 3760, + 1340 + ], + "size": { + "0": 140, + "1": 46 + }, + "flags": {}, + "order": 21, + "mode": 0, + "inputs": [ + { + "name": "samples", + "type": "LATENT", + "link": 65 + }, + { + "name": "vae", + "type": "VAE", + "link": 66 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 67 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "VAEDecode" + } + }, + { + "id": 32, + "type": "SaveImage", + "pos": [ + 2610, + 940 + ], + "size": { + "0": 529.7760009765625, + "1": 582.3048095703125 + }, + "flags": {}, + "order": 26, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 67 + } + ], + "properties": {}, + "widgets_values": [ + "IPAdapter" + ] + }, + { + "id": 26, + "type": "KSampler", + "pos": [ + 3590, + 350 + ], + "size": { + "0": 315, + "1": 262 + }, + "flags": {}, + "order": 15, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 50 + }, + { + "name": "positive", + "type": "CONDITIONING", + "link": 51 + }, + { + "name": "negative", + "type": "CONDITIONING", + "link": 52 + }, + { + "name": "latent_image", + "type": "LATENT", + "link": 53 + } + ], + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 54 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "KSampler" + }, + "widgets_values": [ + 0, + "fixed", + 30, + 6.5, + "dpmpp_2m", + "karras", + 1 + ] + }, + { + "id": 29, + "type": "IPAdapterAdvanced", + "pos": [ + 3220, + 310 + ], + "size": { + "0": 315, + "1": 254 + }, + "flags": {}, + "order": 10, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 57 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": 58, + "slot_index": 1 + }, + { + "name": "image", + "type": "IMAGE", + "link": 59 + }, + { + "name": "image_negative", + "type": "IMAGE", + "link": null + }, + { + "name": "attn_mask", + "type": "MASK", + "link": null + }, + { + "name": "clip_vision", + "type": "CLIP_VISION", + "link": 60, + "slot_index": 5 + } + ], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 50 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "IPAdapterAdvanced" + }, + "widgets_values": [ + 0.8, + "ease in-out", + "concat", + 0, + 1 + ] + }, + { + "id": 33, + "type": "IPAdapterAdvanced", + "pos": [ + 3210, + 960 + ], + "size": { + "0": 315, + "1": 254 + }, + "flags": {}, + "order": 11, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 68 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": 69, + "slot_index": 1 + }, + { + "name": "image", + "type": "IMAGE", + "link": 70 + }, + { + "name": "image_negative", + "type": "IMAGE", + "link": null + }, + { + "name": "attn_mask", + "type": "MASK", + "link": null + }, + { + "name": "clip_vision", + "type": "CLIP_VISION", + "link": 71, + "slot_index": 5 + } + ], + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 61 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "IPAdapterAdvanced" + }, + "widgets_values": [ + 0.8, + "reverse in-out", + "concat", + 0, + 1 + ] + } + ], + "links": [ + [ + 2, + 5, + 0, + 3, + 3, + "LATENT" + ], + [ + 3, + 4, + 1, + 6, + 0, + "CLIP" + ], + [ + 4, + 6, + 0, + 3, + 1, + "CONDITIONING" + ], + [ + 5, + 4, + 1, + 7, + 0, + "CLIP" + ], + [ + 6, + 7, + 0, + 3, + 2, + "CONDITIONING" + ], + [ + 7, + 3, + 0, + 8, + 0, + "LATENT" + ], + [ + 8, + 4, + 2, + 8, + 1, + "VAE" + ], + [ + 9, + 8, + 0, + 9, + 0, + "IMAGE" + ], + [ + 20, + 4, + 0, + 14, + 0, + "MODEL" + ], + [ + 21, + 15, + 0, + 14, + 1, + "IPADAPTER" + ], + [ + 23, + 14, + 0, + 3, + 0, + "MODEL" + ], + [ + 24, + 16, + 0, + 14, + 5, + "CLIP_VISION" + ], + [ + 27, + 12, + 0, + 14, + 2, + "IMAGE" + ], + [ + 28, + 21, + 0, + 18, + 0, + "MODEL" + ], + [ + 29, + 6, + 0, + 18, + 1, + "CONDITIONING" + ], + [ + 30, + 7, + 0, + 18, + 2, + "CONDITIONING" + ], + [ + 31, + 5, + 0, + 18, + 3, + "LATENT" + ], + [ + 32, + 18, + 0, + 19, + 0, + "LATENT" + ], + [ + 33, + 4, + 2, + 19, + 1, + "VAE" + ], + [ + 34, + 19, + 0, + 20, + 0, + "IMAGE" + ], + [ + 35, + 4, + 0, + 21, + 0, + "MODEL" + ], + [ + 36, + 15, + 0, + 21, + 1, + "IPADAPTER" + ], + [ + 37, + 12, + 0, + 21, + 2, + "IMAGE" + ], + [ + 38, + 16, + 0, + 21, + 5, + "CLIP_VISION" + ], + [ + 39, + 25, + 0, + 22, + 0, + "MODEL" + ], + [ + 40, + 6, + 0, + 22, + 1, + "CONDITIONING" + ], + [ + 41, + 7, + 0, + 22, + 2, + "CONDITIONING" + ], + [ + 42, + 5, + 0, + 22, + 3, + "LATENT" + ], + [ + 43, + 22, + 0, + 23, + 0, + "LATENT" + ], + [ + 44, + 4, + 2, + 23, + 1, + "VAE" + ], + [ + 45, + 23, + 0, + 24, + 0, + "IMAGE" + ], + [ + 46, + 4, + 0, + 25, + 0, + "MODEL" + ], + [ + 47, + 15, + 0, + 25, + 1, + "IPADAPTER" + ], + [ + 48, + 12, + 0, + 25, + 2, + "IMAGE" + ], + [ + 49, + 16, + 0, + 25, + 5, + "CLIP_VISION" + ], + [ + 50, + 29, + 0, + 26, + 0, + "MODEL" + ], + [ + 51, + 6, + 0, + 26, + 1, + "CONDITIONING" + ], + [ + 52, + 7, + 0, + 26, + 2, + "CONDITIONING" + ], + [ + 53, + 5, + 0, + 26, + 3, + "LATENT" + ], + [ + 54, + 26, + 0, + 27, + 0, + "LATENT" + ], + [ + 55, + 4, + 2, + 27, + 1, + "VAE" + ], + [ + 56, + 27, + 0, + 28, + 0, + "IMAGE" + ], + [ + 57, + 4, + 0, + 29, + 0, + "MODEL" + ], + [ + 58, + 15, + 0, + 29, + 1, + "IPADAPTER" + ], + [ + 59, + 12, + 0, + 29, + 2, + "IMAGE" + ], + [ + 60, + 16, + 0, + 29, + 5, + "CLIP_VISION" + ], + [ + 61, + 33, + 0, + 30, + 0, + "MODEL" + ], + [ + 62, + 6, + 0, + 30, + 1, + "CONDITIONING" + ], + [ + 63, + 7, + 0, + 30, + 2, + "CONDITIONING" + ], + [ + 64, + 5, + 0, + 30, + 3, + "LATENT" + ], + [ + 65, + 30, + 0, + 31, + 0, + "LATENT" + ], + [ + 66, + 4, + 2, + 31, + 1, + "VAE" + ], + [ + 67, + 31, + 0, + 32, + 0, + "IMAGE" + ], + [ + 68, + 4, + 0, + 33, + 0, + "MODEL" + ], + [ + 69, + 15, + 0, + 33, + 1, + "IPADAPTER" + ], + [ + 70, + 12, + 0, + 33, + 2, + "IMAGE" + ], + [ + 71, + 16, + 0, + 33, + 5, + "CLIP_VISION" + ] + ], + "groups": [], + "config": {}, + "extra": {}, + "version": 0.4 +} \ No newline at end of file diff --git a/examples/IPAdapter_Canny.json b/examples/ipadapter_weighted_embeds.json similarity index 67% rename from examples/IPAdapter_Canny.json rename to examples/ipadapter_weighted_embeds.json index d91bd2b..e248a44 100644 --- a/examples/IPAdapter_Canny.json +++ b/examples/ipadapter_weighted_embeds.json @@ -1,29 +1,180 @@ { - "last_node_id": 17, - "last_link_id": 19, + "last_node_id": 18, + "last_link_id": 29, "nodes": [ { - "id": 10, - "type": "EmptyLatentImage", + "id": 4, + "type": "CheckpointLoaderSimple", "pos": [ - 650, - 590 + 50, + 730 ], "size": { - "0": 210, - "1": 110 + "0": 315, + "1": 98 }, "flags": {}, "order": 0, "mode": 0, "outputs": [ { - "name": "LATENT", - "type": "LATENT", + "name": "MODEL", + "type": "MODEL", "links": [ 10 ], - "shape": 3, + "slot_index": 0 + }, + { + "name": "CLIP", + "type": "CLIP", + "links": [ + 3, + 5 + ], + "slot_index": 1 + }, + { + "name": "VAE", + "type": "VAE", + "links": [ + 8 + ], + "slot_index": 2 + } + ], + "properties": { + "Node name for S&R": "CheckpointLoaderSimple" + }, + "widgets_values": [ + "sd15/realisticVisionV51_v51VAE.safetensors" + ] + }, + { + "id": 6, + "type": "CLIPTextEncode", + "pos": [ + 690, + 610 + ], + "size": { + "0": 422.84503173828125, + "1": 164.31304931640625 + }, + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [ + { + "name": "clip", + "type": "CLIP", + "link": 3 + } + ], + "outputs": [ + { + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 4 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "CLIPTextEncode" + }, + "widgets_values": [ + "closeup of a fierce warrior woman wearing a full armor at the end of a battle\n\nhigh quality, detailed" + ] + }, + { + "id": 9, + "type": "SaveImage", + "pos": [ + 1770, + 710 + ], + "size": { + "0": 529.7760009765625, + "1": 582.3048095703125 + }, + "flags": {}, + "order": 13, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 9 + } + ], + "properties": {}, + "widgets_values": [ + "IPAdapter" + ] + }, + { + "id": 8, + "type": "VAEDecode", + "pos": [ + 1570, + 700 + ], + "size": { + "0": 140, + "1": 46 + }, + "flags": {}, + "order": 12, + "mode": 0, + "inputs": [ + { + "name": "samples", + "type": "LATENT", + "link": 7 + }, + { + "name": "vae", + "type": "VAE", + "link": 8 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 9 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "VAEDecode" + } + }, + { + "id": 5, + "type": "EmptyLatentImage", + "pos": [ + 801, + 1097 + ], + "size": { + "0": 315, + "1": 106 + }, + "flags": {}, + "order": 1, + "mode": 0, + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 2 + ], "slot_index": 0 } ], @@ -37,59 +188,210 @@ ] }, { - "id": 8, - "type": "CLIPTextEncode", + "id": 12, + "type": "LoadImage", "pos": [ - 650, - 420 + 453, + -296 ], "size": { - "0": 210, - "1": 120 + "0": 315, + "1": 314 + }, + "flags": {}, + "order": 2, + "mode": 0, + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 21 + ], + "shape": 3, + "slot_index": 0 + }, + { + "name": "MASK", + "type": "MASK", + "links": null, + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "warrior_woman.png", + "image" + ] + }, + { + "id": 15, + "type": "LoadImage", + "pos": [ + 458, + 70 + ], + "size": { + "0": 315, + "1": 314 + }, + "flags": {}, + "order": 3, + "mode": 0, + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 23 + ], + "shape": 3, + "slot_index": 0 + }, + { + "name": "MASK", + "type": "MASK", + "links": null, + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "anime_illustration.png", + "image" + ] + }, + { + "id": 11, + "type": "IPAdapterUnifiedLoader", + "pos": [ + 440, + 440 + ], + "size": { + "0": 315, + "1": 78 + }, + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 10 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": null + } + ], + "outputs": [ + { + "name": "model", + "type": "MODEL", + "links": [ + 19 + ], + "shape": 3, + "slot_index": 0 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "links": [ + 20, + 22, + 27 + ], + "shape": 3, + "slot_index": 1 + } + ], + "properties": { + "Node name for S&R": "IPAdapterUnifiedLoader" + }, + "widgets_values": [ + "PLUS (high strength)" + ] + }, + { + "id": 3, + "type": "KSampler", + "pos": [ + 1210, + 700 + ], + "size": { + "0": 315, + "1": 262 }, "flags": {}, "order": 11, "mode": 0, "inputs": [ { - "name": "clip", - "type": "CLIP", + "name": "model", + "type": "MODEL", + "link": 28 + }, + { + "name": "positive", + "type": "CONDITIONING", + "link": 4 + }, + { + "name": "negative", + "type": "CONDITIONING", "link": 6 + }, + { + "name": "latent_image", + "type": "LATENT", + "link": 2 } ], "outputs": [ { - "name": "CONDITIONING", - "type": "CONDITIONING", + "name": "LATENT", + "type": "LATENT", "links": [ - 9 + 7 ], - "shape": 3, "slot_index": 0 } ], "properties": { - "Node name for S&R": "CLIPTextEncode" + "Node name for S&R": "KSampler" }, "widgets_values": [ - "blurry, horror" - ], - "color": "#322", - "bgcolor": "#533" + 0, + "fixed", + 30, + 6.5, + "dpmpp_2m", + "karras", + 1 + ] }, { "id": 7, "type": "CLIPTextEncode", "pos": [ - 650, - 250 + 690, + 840 ], "size": { - "0": 210, - "1": 120 + "0": 425.27801513671875, + "1": 180.6060791015625 }, "flags": {}, - "order": 10, + "order": 6, "mode": 0, "inputs": [ { @@ -103,9 +405,8 @@ "name": "CONDITIONING", "type": "CONDITIONING", "links": [ - 16 + 6 ], - "shape": 3, "slot_index": 0 } ], @@ -113,546 +414,172 @@ "Node name for S&R": "CLIPTextEncode" }, "widgets_values": [ - "beautiful renaissance girl with a necklace, detailed" - ], - "color": "#232", - "bgcolor": "#353" - }, - { - "id": 11, - "type": "VAEDecode", - "pos": [ - 1300, - 170 - ], - "size": { - "0": 140, - "1": 50 - }, - "flags": {}, - "order": 15, - "mode": 0, - "inputs": [ - { - "name": "samples", - "type": "LATENT", - "link": 11 - }, - { - "name": "vae", - "type": "VAE", - "link": 12 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 13 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAEDecode" - } - }, - { - "id": 2, - "type": "VAELoader", - "pos": [ - 940, - 480 - ], - "size": { - "0": 300, - "1": 60 - }, - "flags": {}, - "order": 1, - "mode": 0, - "outputs": [ - { - "name": "VAE", - "type": "VAE", - "links": [ - 12 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "VAELoader" - }, - "widgets_values": [ - "vae-ft-mse-840000-ema-pruned.safetensors" - ] - }, - { - "id": 12, - "type": "SaveImage", - "pos": [ - 1300, - 270 - ], - "size": { - "0": 400, - "1": 450 - }, - "flags": {}, - "order": 16, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 13 - } - ], - "properties": {}, - "widgets_values": [ - "IPAdapter" - ] - }, - { - "id": 6, - "type": "LoadImage", - "pos": [ - 40, - 60 - ], - "size": { - "0": 220, - "1": 320 - }, - "flags": {}, - "order": 2, - "mode": 0, - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 3 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "MASK", - "type": "MASK", - "links": null, - "shape": 3 - } - ], - "properties": { - "Node name for S&R": "LoadImage" - }, - "widgets_values": [ - "venere.jpg", - "image" - ] - }, - { - "id": 14, - "type": "LoadImage", - "pos": [ - 50, - 860 - ], - "size": { - "0": 220, - "1": 320 - }, - "flags": {}, - "order": 3, - "mode": 0, - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 14 - ], - "shape": 3, - "slot_index": 0 - }, - { - "name": "MASK", - "type": "MASK", - "links": null, - "shape": 3 - } - ], - "properties": { - "Node name for S&R": "LoadImage" - }, - "widgets_values": [ - "portrait.jpg", - "image" - ] - }, - { - "id": 15, - "type": "ControlNetLoader", - "pos": [ - 190, - 750 - ], - "size": { - "0": 310, - "1": 60 - }, - "flags": {}, - "order": 4, - "mode": 0, - "outputs": [ - { - "name": "CONTROL_NET", - "type": "CONTROL_NET", - "links": [ - 15 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "ControlNetLoader" - }, - "widgets_values": [ - "control_v11p_sd15_canny_fp16.safetensors" + "blurry, noisy, messy, lowres, jpeg, artifacts, ill, distorted, malformed, hat, hood, scars, blood" ] }, { "id": 17, - "type": "PreviewImage", + "type": "IPAdapterEncoder", "pos": [ - 579.412728881836, - 903.3208389282227 + 859, + 69 ], - "size": { - "0": 210, - "1": 246 - }, - "flags": {}, - "order": 12, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 19 - } + "size": [ + 210, + 118 ], - "properties": { - "Node name for S&R": "PreviewImage" - } - }, - { - "id": 13, - "type": "Canny", - "pos": [ - 290, - 860 - ], - "size": { - "0": 210, - "1": 82 - }, "flags": {}, "order": 8, "mode": 0, "inputs": [ { - "name": "image", - "type": "IMAGE", - "link": 14 - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 18, - 19 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "Canny" - }, - "widgets_values": [ - 0.1, - 0.5 - ] - }, - { - "id": 16, - "type": "ControlNetApply", - "pos": [ - 540, - 750 - ], - "size": { - "0": 317.4000244140625, - "1": 98 - }, - "flags": {}, - "order": 13, - "mode": 0, - "inputs": [ - { - "name": "conditioning", - "type": "CONDITIONING", - "link": 16 - }, - { - "name": "control_net", - "type": "CONTROL_NET", - "link": 15 - }, - { - "name": "image", - "type": "IMAGE", - "link": 18 - } - ], - "outputs": [ - { - "name": "CONDITIONING", - "type": "CONDITIONING", - "links": [ - 17 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "ControlNetApply" - }, - "widgets_values": [ - 0.8 - ] - }, - { - "id": 9, - "type": "KSampler", - "pos": [ - 930, - 170 - ], - "size": { - "0": 315, - "1": 262 - }, - "flags": {}, - "order": 14, - "mode": 0, - "inputs": [ - { - "name": "model", - "type": "MODEL", - "link": 7 - }, - { - "name": "positive", - "type": "CONDITIONING", - "link": 17 - }, - { - "name": "negative", - "type": "CONDITIONING", - "link": 9 - }, - { - "name": "latent_image", - "type": "LATENT", - "link": 10 - } - ], - "outputs": [ - { - "name": "LATENT", - "type": "LATENT", - "links": [ - 11 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "KSampler" - }, - "widgets_values": [ - 27, - "fixed", - 30, - 6, - "ddim", - "ddim_uniform", - 1 - ] - }, - { - "id": 4, - "type": "CLIPVisionLoader", - "pos": [ - 290, - 170 - ], - "size": { - "0": 300, - "1": 60 - }, - "flags": {}, - "order": 5, - "mode": 0, - "outputs": [ - { - "name": "CLIP_VISION", - "type": "CLIP_VISION", - "links": [ - 2 - ], - "shape": 3, - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "CLIPVisionLoader" - }, - "widgets_values": [ - "IPAdapter_image_encoder_sd15.safetensors" - ] - }, - { - "id": 3, - "type": "IPAdapterModelLoader", - "pos": [ - 290, - 60 - ], - "size": { - "0": 300, - "1": 60 - }, - "flags": {}, - "order": 6, - "mode": 0, - "outputs": [ - { - "name": "IPADAPTER", + "name": "ipadapter", "type": "IPADAPTER", - "links": [ - 1 - ], - "shape": 3, - "slot_index": 0 + "link": 22 + }, + { + "name": "image", + "type": "IMAGE", + "link": 23 + }, + { + "name": "mask", + "type": "MASK", + "link": null + }, + { + "name": "clip_vision", + "type": "CLIP_VISION", + "link": null } ], - "properties": { - "Node name for S&R": "IPAdapterModelLoader" - }, - "widgets_values": [ - "ip-adapter-plus_sd15.safetensors" - ] - }, - { - "id": 1, - "type": "CheckpointLoaderSimple", - "pos": [ - 290, - 280 - ], - "size": { - "0": 300, - "1": 100 - }, - "flags": {}, - "order": 7, - "mode": 0, "outputs": [ { - "name": "MODEL", - "type": "MODEL", + "name": "pos_embed", + "type": "EMBEDS", "links": [ - 4 + 25 ], "shape": 3, "slot_index": 0 }, { - "name": "CLIP", - "type": "CLIP", - "links": [ - 5, - 6 - ], - "shape": 3, - "slot_index": 1 - }, - { - "name": "VAE", - "type": "VAE", + "name": "neg_embed", + "type": "EMBEDS", "links": null, "shape": 3 } ], "properties": { - "Node name for S&R": "CheckpointLoaderSimple" + "Node name for S&R": "IPAdapterEncoder" }, "widgets_values": [ - "sd15/realisticVisionV51_v51VAE.safetensors" + 1.5 ] }, { - "id": 5, - "type": "IPAdapterApply", + "id": 18, + "type": "IPAdapterCombineEmbeds", "pos": [ - 656, - -51 + 1136, + -95 + ], + "size": [ + 210, + 138 ], - "size": { - "0": 210, - "1": 258 - }, "flags": {}, "order": 9, "mode": 0, "inputs": [ { - "name": "ipadapter", - "type": "IPADAPTER", - "link": 1 + "name": "embed1", + "type": "EMBEDS", + "link": 24 }, { - "name": "clip_vision", - "type": "CLIP_VISION", - "link": 2 + "name": "embed2", + "type": "EMBEDS", + "link": 25 }, { - "name": "image", - "type": "IMAGE", - "link": 3 + "name": "embed3", + "type": "EMBEDS", + "link": null }, + { + "name": "embed4", + "type": "EMBEDS", + "link": null + }, + { + "name": "embed5", + "type": "EMBEDS", + "link": null + } + ], + "outputs": [ + { + "name": "EMBEDS", + "type": "EMBEDS", + "links": [ + 26 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "IPAdapterCombineEmbeds" + }, + "widgets_values": [ + "average" + ] + }, + { + "id": 14, + "type": "IPAdapterEmbeds", + "pos": [ + 1143, + 160 + ], + "size": { + "0": 315, + "1": 230 + }, + "flags": {}, + "order": 10, + "mode": 0, + "inputs": [ { "name": "model", "type": "MODEL", - "link": 4 + "link": 19 + }, + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": 27 + }, + { + "name": "pos_embed", + "type": "EMBEDS", + "link": 26 + }, + { + "name": "neg_embed", + "type": "EMBEDS", + "link": 29 }, { "name": "attn_mask", "type": "MASK", "link": null + }, + { + "name": "clip_vision", + "type": "CLIP_VISION", + "link": null } ], "outputs": [ @@ -660,61 +587,114 @@ "name": "MODEL", "type": "MODEL", "links": [ - 7 + 28 ], "shape": 3, "slot_index": 0 } ], "properties": { - "Node name for S&R": "IPAdapterApply" + "Node name for S&R": "IPAdapterEmbeds" }, "widgets_values": [ 0.8, + "linear", 0, - "original", - 0, - 1, - false + 1 + ] + }, + { + "id": 16, + "type": "IPAdapterEncoder", + "pos": [ + 863, + -285 + ], + "size": [ + 210, + 118 + ], + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [ + { + "name": "ipadapter", + "type": "IPADAPTER", + "link": 20 + }, + { + "name": "image", + "type": "IMAGE", + "link": 21 + }, + { + "name": "mask", + "type": "MASK", + "link": null + }, + { + "name": "clip_vision", + "type": "CLIP_VISION", + "link": null + } + ], + "outputs": [ + { + "name": "pos_embed", + "type": "EMBEDS", + "links": [ + 24 + ], + "shape": 3, + "slot_index": 0 + }, + { + "name": "neg_embed", + "type": "EMBEDS", + "links": [ + 29 + ], + "shape": 3, + "slot_index": 1 + } + ], + "properties": { + "Node name for S&R": "IPAdapterEncoder" + }, + "widgets_values": [ + 0.6 ] } ], "links": [ - [ - 1, - 3, - 0, - 5, - 0, - "IPADAPTER" - ], [ 2, - 4, - 0, 5, - 1, - "CLIP_VISION" + 0, + 3, + 3, + "LATENT" ], [ 3, + 4, + 1, 6, 0, - 5, - 2, - "IMAGE" + "CLIP" ], [ 4, - 1, + 6, 0, - 5, 3, - "MODEL" + 1, + "CONDITIONING" ], [ 5, - 1, + 4, 1, 7, 0, @@ -722,107 +702,131 @@ ], [ 6, - 1, - 1, - 8, - 0, - "CLIP" - ], - [ 7, - 5, 0, - 9, - 0, - "MODEL" - ], - [ - 9, - 8, - 0, - 9, + 3, 2, "CONDITIONING" ], [ - 10, - 10, - 0, - 9, + 7, 3, - "LATENT" - ], - [ - 11, - 9, 0, - 11, + 8, 0, "LATENT" ], [ - 12, + 8, + 4, 2, - 0, - 11, + 8, 1, "VAE" ], [ - 13, - 11, - 0, - 12, - 0, - "IMAGE" - ], - [ - 14, - 14, - 0, - 13, - 0, - "IMAGE" - ], - [ - 15, - 15, - 0, - 16, - 1, - "CONTROL_NET" - ], - [ - 16, - 7, - 0, - 16, - 0, - "CONDITIONING" - ], - [ - 17, - 16, + 9, + 8, 0, 9, - 1, - "CONDITIONING" + 0, + "IMAGE" ], [ - 18, - 13, + 10, + 4, 0, - 16, - 2, - "IMAGE" + 11, + 0, + "MODEL" ], [ 19, - 13, + 11, 0, + 14, + 0, + "MODEL" + ], + [ + 20, + 11, + 1, + 16, + 0, + "IPADAPTER" + ], + [ + 21, + 12, + 0, + 16, + 1, + "IMAGE" + ], + [ + 22, + 11, + 1, 17, 0, + "IPADAPTER" + ], + [ + 23, + 15, + 0, + 17, + 1, "IMAGE" + ], + [ + 24, + 16, + 0, + 18, + 0, + "EMBEDS" + ], + [ + 25, + 17, + 0, + 18, + 1, + "EMBEDS" + ], + [ + 26, + 18, + 0, + 14, + 2, + "EMBEDS" + ], + [ + 27, + 11, + 1, + 14, + 1, + "IPADAPTER" + ], + [ + 28, + 14, + 0, + 3, + 0, + "MODEL" + ], + [ + 29, + 16, + 1, + 14, + 3, + "EMBEDS" ] ], "groups": [], diff --git a/examples/masking.jpg b/examples/masking.jpg deleted file mode 100644 index dd45bae..0000000 Binary files a/examples/masking.jpg and /dev/null differ diff --git a/examples/noise_example.jpg b/examples/noise_example.jpg deleted file mode 100644 index c73dc93..0000000 Binary files a/examples/noise_example.jpg and /dev/null differ diff --git a/examples/prep_images.jpg b/examples/prep_images.jpg deleted file mode 100644 index 8aed282..0000000 Binary files a/examples/prep_images.jpg and /dev/null differ diff --git a/examples/timestepping.jpg b/examples/timestepping.jpg deleted file mode 100644 index 3878778..0000000 Binary files a/examples/timestepping.jpg and /dev/null differ diff --git a/examples/weight_types.jpg b/examples/weight_types.jpg deleted file mode 100644 index 228cd7b..0000000 Binary files a/examples/weight_types.jpg and /dev/null differ diff --git a/resampler.py b/image_proj_models.py similarity index 54% rename from resampler.py rename to image_proj_models.py index 2426667..da61b53 100644 --- a/resampler.py +++ b/image_proj_models.py @@ -1,8 +1,4 @@ -# modified from https://github.com/mlfoundations/open_flamingo/blob/main/open_flamingo/src/helpers.py -# and https://github.com/lucidrains/imagen-pytorch/blob/main/imagen_pytorch/imagen_pytorch.py - import math - import torch import torch.nn as nn from einops import rearrange @@ -156,3 +152,124 @@ def masked_mean(t, *, dim, mask=None): masked_t = t.masked_fill(~mask, 0.0) return masked_t.sum(dim=dim) / denom.clamp(min=1e-5) + + +class FacePerceiverResampler(nn.Module): + def __init__( + self, + *, + dim=768, + depth=4, + dim_head=64, + heads=16, + embedding_dim=1280, + output_dim=768, + ff_mult=4, + ): + super().__init__() + + self.proj_in = nn.Linear(embedding_dim, dim) + self.proj_out = nn.Linear(dim, output_dim) + self.norm_out = nn.LayerNorm(output_dim) + self.layers = nn.ModuleList([]) + for _ in range(depth): + self.layers.append( + nn.ModuleList( + [ + PerceiverAttention(dim=dim, dim_head=dim_head, heads=heads), + FeedForward(dim=dim, mult=ff_mult), + ] + ) + ) + + def forward(self, latents, x): + x = self.proj_in(x) + for attn, ff in self.layers: + latents = attn(x, latents) + latents + latents = ff(latents) + latents + latents = self.proj_out(latents) + return self.norm_out(latents) + + +class MLPProjModel(nn.Module): + def __init__(self, cross_attention_dim=1024, clip_embeddings_dim=1024): + super().__init__() + + self.proj = nn.Sequential( + nn.Linear(clip_embeddings_dim, clip_embeddings_dim), + nn.GELU(), + nn.Linear(clip_embeddings_dim, cross_attention_dim), + nn.LayerNorm(cross_attention_dim) + ) + + def forward(self, image_embeds): + clip_extra_context_tokens = self.proj(image_embeds) + return clip_extra_context_tokens + +class MLPProjModelFaceId(nn.Module): + def __init__(self, cross_attention_dim=768, id_embeddings_dim=512, num_tokens=4): + super().__init__() + + self.cross_attention_dim = cross_attention_dim + self.num_tokens = num_tokens + + self.proj = nn.Sequential( + nn.Linear(id_embeddings_dim, id_embeddings_dim*2), + nn.GELU(), + nn.Linear(id_embeddings_dim*2, cross_attention_dim*num_tokens), + ) + self.norm = nn.LayerNorm(cross_attention_dim) + + def forward(self, id_embeds): + x = self.proj(id_embeds) + x = x.reshape(-1, self.num_tokens, self.cross_attention_dim) + x = self.norm(x) + return x + +class ProjModelFaceIdPlus(nn.Module): + def __init__(self, cross_attention_dim=768, id_embeddings_dim=512, clip_embeddings_dim=1280, num_tokens=4): + super().__init__() + + self.cross_attention_dim = cross_attention_dim + self.num_tokens = num_tokens + + self.proj = nn.Sequential( + nn.Linear(id_embeddings_dim, id_embeddings_dim*2), + nn.GELU(), + nn.Linear(id_embeddings_dim*2, cross_attention_dim*num_tokens), + ) + self.norm = nn.LayerNorm(cross_attention_dim) + + self.perceiver_resampler = FacePerceiverResampler( + dim=cross_attention_dim, + depth=4, + dim_head=64, + heads=cross_attention_dim // 64, + embedding_dim=clip_embeddings_dim, + output_dim=cross_attention_dim, + ff_mult=4, + ) + + def forward(self, id_embeds, clip_embeds, scale=1.0, shortcut=False): + x = self.proj(id_embeds) + x = x.reshape(-1, self.num_tokens, self.cross_attention_dim) + x = self.norm(x) + out = self.perceiver_resampler(x, clip_embeds) + if shortcut: + out = x + scale * out + return out + +class ImageProjModel(nn.Module): + def __init__(self, cross_attention_dim=1024, clip_embeddings_dim=1024, clip_extra_context_tokens=4): + super().__init__() + + self.cross_attention_dim = cross_attention_dim + self.clip_extra_context_tokens = clip_extra_context_tokens + self.proj = nn.Linear(clip_embeddings_dim, self.clip_extra_context_tokens * cross_attention_dim) + self.norm = nn.LayerNorm(cross_attention_dim) + + def forward(self, image_embeds): + embeds = image_embeds + x = self.proj(embeds).reshape(-1, self.clip_extra_context_tokens, self.cross_attention_dim) + x = self.norm(x) + return x diff --git a/ipadapter_workflow.png b/ipadapter_workflow.png deleted file mode 100644 index f061ca1..0000000 Binary files a/ipadapter_workflow.png and /dev/null differ diff --git a/models/legacy_models_location.txt b/models/legacy_directory_do_not_use.txt similarity index 100% rename from models/legacy_models_location.txt rename to models/legacy_directory_do_not_use.txt diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..22d44b6 --- /dev/null +++ b/utils.py @@ -0,0 +1,222 @@ +import re +import torch +import os +import folder_paths +from comfy.clip_vision import clip_preprocess, Output +import comfy.utils +import comfy.model_management as model_management +import torchvision.transforms.v2 as T + +def get_clipvision_file(preset): + preset = preset.lower() + clipvision_list = folder_paths.get_filename_list("clip_vision") + + if preset.startswith("vit-g"): + pattern = '(ViT.bigG.14.*39B.b160k|ipadapter.*sdxl|sdxl*.model\.(bin|safetensors))' + else: + pattern = '(ViT.H.14.*s32B.b79K|ipadapter.*sd15|sd15*.model\.(bin|safetensors))' + clipvision_file = [e for e in clipvision_list if re.search(pattern, e, re.IGNORECASE)] + + clipvision_file = folder_paths.get_full_path("clip_vision", clipvision_file[0]) if clipvision_file else None + + return clipvision_file + +def get_ipadapter_file(preset, is_sdxl): + preset = preset.lower() + ipadapter_list = folder_paths.get_filename_list("ipadapter") + is_insightface = False + lora_pattern = None + + if preset.startswith("light"): + if is_sdxl: + raise Exception("light model is not supported for SDXL") + pattern = 'sd15.light\.(safetensors|bin)$' + elif preset.startswith("standard"): + if is_sdxl: + pattern = 'ip.adapter.sdxl.vit.h\.(safetensors|bin)$' + else: + pattern = 'ip.adapter.sd15\.(safetensors|bin)$' + elif preset.startswith("vit-g"): + if is_sdxl: + pattern = 'ip.adapter.sdxl\.(safetensors|bin)$' + else: + pattern = 'sd15.vit.g\.(safetensors|bin)$' + elif preset.startswith("plus ("): + if is_sdxl: + pattern = 'plus.sdxl.vit.h\.(safetensors|bin)$' + else: + pattern = 'ip.adapter.plus.sd15\.(safetensors|bin)$' + elif preset.startswith("plus face"): + if is_sdxl: + pattern = 'plus.face.sdxl.vit.h\.(safetensors|bin)$' + else: + pattern = 'plus.face.sd15\.(safetensors|bin)$' + elif preset.startswith("full"): + if is_sdxl: + raise Exception("full face model is not supported for SDXL") + pattern = 'full.face.sd15\.(safetensors|bin)$' + elif preset.startswith("faceid portrait"): + if is_sdxl: + raise Exception("portrait model is not supported for SDXL") + pattern = 'portrait.sd15\.(safetensors|bin)$' + is_insightface = True + elif preset == "faceid": + if is_sdxl: + pattern = 'faceid.sdxl\.(safetensors|bin)$' + lora_pattern = 'faceid.sdxl.lora\.safetensors$' + else: + pattern = 'faceid.sd15\.(safetensors|bin)$' + lora_pattern = 'faceid.sd15.lora\.safetensors$' + is_insightface = True + elif preset.startswith("faceid plus -"): + if is_sdxl: + raise Exception("faceid plus model is not supported for SDXL") + pattern = 'faceid.plus.sd15\.(safetensors|bin)$' + lora_pattern = 'faceid.plus.sd15.lora\.safetensors$' + is_insightface = True + elif preset.startswith("faceid plus v2"): + if is_sdxl: + pattern = 'faceid.plusv2.sdxl\.(safetensors|bin)$' + lora_pattern = 'faceid.plusv2.sdxl.lora\.safetensors$' + else: + pattern = 'faceid.plusv2.sd15\.(safetensors|bin)$' + lora_pattern = 'faceid.plusv2.sd15.lora\.safetensors$' + is_insightface = True + else: + raise Exception(f"invalid type '{preset}'") + + ipadapter_file = [e for e in ipadapter_list if re.search(pattern, e, re.IGNORECASE)] + ipadapter_file = folder_paths.get_full_path("ipadapter", ipadapter_file[0]) if ipadapter_file else None + + return ipadapter_file, is_insightface, lora_pattern + +def get_lora_file(pattern): + lora_list = folder_paths.get_filename_list("loras") + lora_file = [e for e in lora_list if re.search(pattern, e, re.IGNORECASE)] + lora_file = folder_paths.get_full_path("loras", lora_file[0]) if lora_file else None + + return lora_file + +def ipadapter_model_loader(file): + model = comfy.utils.load_torch_file(file, safe_load=True) + + if file.lower().endswith(".safetensors"): + st_model = {"image_proj": {}, "ip_adapter": {}} + for key in model.keys(): + if key.startswith("image_proj."): + st_model["image_proj"][key.replace("image_proj.", "")] = model[key] + elif key.startswith("ip_adapter."): + st_model["ip_adapter"][key.replace("ip_adapter.", "")] = model[key] + model = st_model + del st_model + + if not "ip_adapter" in model.keys() or not model["ip_adapter"]: + raise Exception("invalid IPAdapter model {}".format(file)) + + if 'plusv2' in file.lower(): + model["faceidplusv2"] = True + + return model + +def insightface_loader(provider): + try: + from insightface.app import FaceAnalysis + except ImportError as e: + raise Exception(e) + + path = os.path.join(folder_paths.models_dir, "insightface") + model = FaceAnalysis(name="buffalo_l", root=path, providers=[provider + 'ExecutionProvider',]) + model.prepare(ctx_id=0, det_size=(640, 640)) + return model + +def encode_image_masked(clip_vision, image, mask=None): + model_management.load_model_gpu(clip_vision.patcher) + image = image.to(clip_vision.load_device) + + pixel_values = clip_preprocess(image.to(clip_vision.load_device)).float() + + if mask is not None: + pixel_values = pixel_values * mask.to(clip_vision.load_device) + + out = clip_vision.model(pixel_values=pixel_values, intermediate_output=-2) + + outputs = Output() + outputs["last_hidden_state"] = out[0].to(model_management.intermediate_device()) + outputs["image_embeds"] = out[2].to(model_management.intermediate_device()) + outputs["penultimate_hidden_states"] = out[1].to(model_management.intermediate_device()) + return outputs + +def tensor_to_size(source, dest_size): + if isinstance(dest_size, torch.Tensor): + dest_size = dest_size.shape[0] + source_size = source.shape[0] + + if source_size < dest_size: + shape = [dest_size - source_size] + [1]*(source.dim()-1) + source = torch.cat((source, source[-1:].repeat(shape)), dim=0) + elif source_size > dest_size: + source = source[:dest_size] + + return source + +def min_(tensor_list): + # return the element-wise min of the tensor list. + x = torch.stack(tensor_list) + mn = x.min(axis=0)[0] + return torch.clamp(mn, min=0) + +def max_(tensor_list): + # return the element-wise max of the tensor list. + x = torch.stack(tensor_list) + mx = x.max(axis=0)[0] + return torch.clamp(mx, max=1) + +# From https://github.com/Jamy-L/Pytorch-Contrast-Adaptive-Sharpening/ +def contrast_adaptive_sharpening(image, amount): + img = T.functional.pad(image, (1, 1, 1, 1)).cpu() + + a = img[..., :-2, :-2] + b = img[..., :-2, 1:-1] + c = img[..., :-2, 2:] + d = img[..., 1:-1, :-2] + e = img[..., 1:-1, 1:-1] + f = img[..., 1:-1, 2:] + g = img[..., 2:, :-2] + h = img[..., 2:, 1:-1] + i = img[..., 2:, 2:] + + # Computing contrast + cross = (b, d, e, f, h) + mn = min_(cross) + mx = max_(cross) + + diag = (a, c, g, i) + mn2 = min_(diag) + mx2 = max_(diag) + mx = mx + mx2 + mn = mn + mn2 + + # Computing local weight + inv_mx = torch.reciprocal(mx) + amp = inv_mx * torch.minimum(mn, (2 - mx)) + + # scaling + amp = torch.sqrt(amp) + w = - amp * (amount * (1/5 - 1/8) + 1/8) + div = torch.reciprocal(1 + 4*w) + + output = ((b + d + f + h)*w + e) * div + output = torch.nan_to_num(output) + output = output.clamp(0, 1) + + return output + +def tensor_to_image(tensor): + image = tensor.mul(255).clamp(0, 255).byte().cpu() + image = image[..., [2, 1, 0]].numpy() + return image + +def image_to_tensor(image): + tensor = torch.clamp(torch.from_numpy(image).float() / 255., 0, 1) + tensor = tensor[..., [2, 1, 0]] + return tensor \ No newline at end of file