V1.2 - LYCORIS

This commit is contained in:
Leslie Perjes
2023-12-19 22:04:43 +01:00
parent 3755f1ded7
commit e1b7240c4e
9 changed files with 1793 additions and 824 deletions
+88 -10
View File
@@ -18,6 +18,7 @@ import requests
from ..components import hypernetwork
import comfy.sd
import comfy.utils
from ..utils import comfy_dir
class PrimereSamplers:
CATEGORY = TREE_DASHBOARD
@@ -430,6 +431,7 @@ class PrimereCLIP:
"optional": {
"model_keywords": ("MODEL_KEYWORD", {"forceInput": True}),
"lora_keywords": ("MODEL_KEYWORD", {"forceInput": True}),
"lycoris_keywords": ("MODEL_KEYWORD", {"forceInput": True}),
"embedding_pos": ("EMBEDDING", {"forceInput": True}),
"embedding_neg": ("EMBEDDING", {"forceInput": True}),
@@ -452,7 +454,7 @@ class PrimereCLIP:
}
}
def clip_encode(self, clip, negative_strength, int_style_pos_strength, int_style_neg_strength, opt_pos_strength, opt_neg_strength, style_pos_strength, style_neg_strength, int_style_pos, int_style_neg, adv_encode, token_normalization, weight_interpretation, sdxl_l_strength, copy_prompt_to_l = True, width = 1024, height = 1024, positive_prompt = "", negative_prompt = "", model_keywords = None, lora_keywords = None, embedding_pos = None, embedding_neg = None, opt_pos_prompt = "", opt_neg_prompt = "", style_neg_prompt = "", style_pos_prompt = "", sdxl_positive_l = "", sdxl_negative_l = "", use_int_style = False, model_version = "BaseModel_1024"):
def clip_encode(self, clip, negative_strength, int_style_pos_strength, int_style_neg_strength, opt_pos_strength, opt_neg_strength, style_pos_strength, style_neg_strength, int_style_pos, int_style_neg, adv_encode, token_normalization, weight_interpretation, sdxl_l_strength, copy_prompt_to_l = True, width = 1024, height = 1024, positive_prompt = "", negative_prompt = "", model_keywords = None, lora_keywords = None, lycoris_keywords = None, embedding_pos = None, embedding_neg = None, opt_pos_prompt = "", opt_neg_prompt = "", style_neg_prompt = "", style_pos_prompt = "", sdxl_positive_l = "", sdxl_negative_l = "", use_int_style = False, model_version = "BaseModel_1024"):
is_sdxl = 0
match model_version:
case 'SDXL_2048':
@@ -509,6 +511,16 @@ class PrimereCLIP:
else:
positive_text = positive_text + ', ' + lora_keyword
if lycoris_keywords is not None:
lykw_list = list(filter(None, lycoris_keywords))
if len(lykw_list) == 2:
lyco_keyword = lykw_list[0]
lyplacement = lykw_list[1]
if (lyplacement == 'First'):
positive_text = lyco_keyword + ', ' + positive_text
else:
positive_text = positive_text + ', ' + lyco_keyword
if embedding_pos is not None:
embp_list = list(filter(None, embedding_pos))
if len(embp_list) == 2:
@@ -714,11 +726,12 @@ class PrimereClearPrompt:
"remove_comfy_embedding": ("BOOLEAN", {"default": False}),
"remove_a1111_embedding": ("BOOLEAN", {"default": False}),
"remove_lora": ("BOOLEAN", {"default": False}),
"remove_lycoris": ("BOOLEAN", {"default": False}),
"remove_hypernetwork": ("BOOLEAN", {"default": False}),
},
}
def clean_prompt(self, positive_prompt, negative_prompt, remove_comfy_embedding, remove_a1111_embedding, remove_lora, remove_hypernetwork, remove_only_if_sdxl, model_version = 'BaseModel_1024'):
def clean_prompt(self, positive_prompt, negative_prompt, remove_comfy_embedding, remove_a1111_embedding, remove_lora, remove_lycoris, remove_hypernetwork, remove_only_if_sdxl, model_version = 'BaseModel_1024'):
NETWORK_START = []
is_sdxl = 0
@@ -735,6 +748,9 @@ class PrimereClearPrompt:
if remove_lora == True:
NETWORK_START.append('<lora:')
if remove_lycoris == True:
NETWORK_START.append('<lyco:')
if remove_hypernetwork == True:
NETWORK_START.append('<hypernet:')
@@ -758,8 +774,8 @@ class PrimereClearPrompt:
return (positive_prompt, negative_prompt,)
class PrimereNetworkTagLoader:
RETURN_TYPES = ("MODEL", "CLIP", "LORA_STACK", "HYPERNETWORK_STACK", "MODEL_KEYWORD")
RETURN_NAMES = ("MODEL", "CLIP", "LORA_STACK", "HYPERNETWORK_STACK", "LORA_KEYWORD")
RETURN_TYPES = ("MODEL", "CLIP", "LORA_STACK", "LYCORIS_STACK", "HYPERNETWORK_STACK", "MODEL_KEYWORD", "MODEL_KEYWORD")
RETURN_NAMES = ("MODEL", "CLIP", "LORA_STACK", "LYCORIS_STACK", "HYPERNETWORK_STACK", "LORA_KEYWORD", "LYCORIS_KEYWORD")
FUNCTION = "load_networks"
CATEGORY = TREE_DASHBOARD
@classmethod
@@ -770,46 +786,65 @@ class PrimereNetworkTagLoader:
"clip": ("CLIP",),
"positive_prompt": ("STRING", {"forceInput": True}),
"process_lora": ("BOOLEAN", {"default": True}),
"process_lycoris": ("BOOLEAN", {"default": True}),
"process_hypernetwork": ("BOOLEAN", {"default": True}),
"hypernetwork_safe_load": ("BOOLEAN", {"default": True}),
"copy_weight_to_clip": ("BOOLEAN", {"default": False}),
"lora_clip_custom_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"lycoris_clip_custom_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"use_lora_keyword": ("BOOLEAN", {"default": False}),
"lora_keyword_placement": (["First", "Last"], {"default": "Last"}),
"lora_keyword_selection": (["Select in order", "Random select"], {"default": "Select in order"}),
"lora_keywords_num": ("INT", {"default": 1, "min": 1, "max": 50, "step": 1}),
"lora_keyword_weight": ("FLOAT", {"default": 1.0, "min": 0, "max": 10.0, "step": 0.1}),
"use_lycoris_keyword": ("BOOLEAN", {"default": False}),
"lycoris_keyword_placement": (["First", "Last"], {"default": "Last"}),
"lycoris_keyword_selection": (["Select in order", "Random select"], {"default": "Select in order"}),
"lycoris_keywords_num": ("INT", {"default": 1, "min": 1, "max": 50, "step": 1}),
"lycoris_keyword_weight": ("FLOAT", {"default": 1.0, "min": 0, "max": 10.0, "step": 0.1}),
}
}
def load_networks(self, model, clip, positive_prompt, process_lora, process_hypernetwork, copy_weight_to_clip, lora_clip_custom_weight, use_lora_keyword, lora_keyword_placement, lora_keyword_selection, lora_keywords_num, lora_keyword_weight, hypernetwork_safe_load = True):
def load_networks(self, model, clip, positive_prompt, process_lora, process_lycoris, process_hypernetwork, copy_weight_to_clip, lora_clip_custom_weight, lycoris_clip_custom_weight, use_lora_keyword, use_lycoris_keyword, lora_keyword_placement, lycoris_keyword_placement, lora_keyword_selection, lycoris_keyword_selection, lora_keywords_num, lycoris_keywords_num, lora_keyword_weight, lycoris_keyword_weight, hypernetwork_safe_load = True):
NETWORK_START = []
cloned_model = model
cloned_clip = clip
list_of_keyword_items = []
lora_keywords_num_set = lora_keywords_num
model_keyword = [None, None]
lycoris_keywords_num_set = lycoris_keywords_num
model_lora_keyword = [None, None]
model_lyco_keyword = [None, None]
lora_stack = []
lycoris_stack = []
hnet_stack = []
HypernetworkList = folder_paths.get_filename_list("hypernetworks")
LoraList = folder_paths.get_filename_list("loras")
LYCO_DIR = os.path.join(comfy_dir, 'models', 'lycoris')
folder_paths.add_model_folder_path("lycoris", LYCO_DIR)
LyCORIS = folder_paths.get_filename_list("lycoris")
LycorisList = folder_paths.filter_files_extensions(LyCORIS, ['.ckpt', '.safetensors'])
if process_lora == True:
NETWORK_START.append('<lora:')
if process_lycoris == True:
NETWORK_START.append('<lyco:')
if process_hypernetwork == True:
NETWORK_START.append('<hypernet:')
if len(NETWORK_START) == 0:
return (model, clip, lora_stack, hnet_stack, model_keyword)
return (model, clip, lora_stack, lycoris_stack, hnet_stack, model_lora_keyword, model_lyco_keyword)
else:
NETWORK_END = ['>'] + NETWORK_START
NETWORK_TUPLE = utility.get_networks_prompt(NETWORK_START, NETWORK_END, positive_prompt)
if (len(NETWORK_TUPLE) == 0):
return (model, clip, lora_stack, hnet_stack, model_keyword)
return (model, clip, lora_stack, lycoris_stack, hnet_stack, model_lora_keyword, model_lyco_keyword)
else:
for NETWORK_DATA in NETWORK_TUPLE:
NetworkName = NETWORK_DATA[0]
@@ -860,7 +895,50 @@ class PrimereNetworkTagLoader:
if (lora_keyword_weight != 1):
keywords = '(' + keywords + ':' + str(lora_keyword_weight) + ')'
model_keyword = [keywords, lora_keyword_placement]
model_lora_keyword = [keywords, lora_keyword_placement]
if (process_lycoris == True and NetworkType == 'LYCORIS'):
lycoris_name = utility.get_closest_element(NetworkName, LycorisList)
if lycoris_name is not None:
lycoris_path = folder_paths.get_full_path("lycoris", lycoris_name)
lycoris = comfy.utils.load_torch_file(lycoris_path, safe_load=True)
if (copy_weight_to_clip == True):
lycoris_clip_custom_weight = NetworkStrenght
lycoris_stack.append([lycoris_name, NetworkStrenght, lycoris_clip_custom_weight])
cloned_model, cloned_clip = comfy.sd.load_lora_for_models(cloned_model, cloned_clip, lycoris, NetworkStrenght, lycoris_clip_custom_weight)
if use_lycoris_keyword == True:
ModelKvHash = utility.get_model_hash(lycoris_path)
if ModelKvHash is not None:
KEYWORD_PATH = os.path.join(PRIMERE_ROOT, 'front_end', 'keywords', 'lora-keyword.txt')
keywords = utility.get_model_keywords(KEYWORD_PATH, ModelKvHash, lycoris_name)
if keywords is not None and keywords != "":
if keywords.find('|') > 1:
keyword_list = [word.strip() for word in keywords.split('|')]
keyword_list = list(filter(None, keyword_list))
if (len(keyword_list) > 0):
lycoris_keywords_num = lycoris_keywords_num_set
keyword_qty = len(keyword_list)
if (lycoris_keywords_num > keyword_qty):
lycoris_keywords_num = keyword_qty
if lycoris_keyword_selection == 'Select in order':
list_of_keyword_items.extend(keyword_list[:lycoris_keywords_num])
else:
list_of_keyword_items.extend(random.sample(keyword_list, lycoris_keywords_num))
else:
list_of_keyword_items.append(keywords)
if len(list_of_keyword_items) > 0:
if lycoris_keyword_selection != 'Select in order':
random.shuffle(list_of_keyword_items)
list_of_keyword_items = list(set(list_of_keyword_items))
keywords = ", ".join(list_of_keyword_items)
if (lycoris_keyword_weight != 1):
keywords = '(' + keywords + ':' + str(lycoris_keyword_weight) + ')'
model_lyco_keyword = [keywords, lycoris_keyword_placement]
if (process_hypernetwork == True and NetworkType == 'HYPERNET'):
hyper_name = utility.get_closest_element(NetworkName, HypernetworkList)
@@ -877,7 +955,7 @@ class PrimereNetworkTagLoader:
hnet_stack.append([hyper_name, NetworkStrenght])
cloned_model = model_hypernetwork
return (cloned_model, cloned_clip, lora_stack, hnet_stack, model_keyword)
return (cloned_model, cloned_clip, lora_stack, lycoris_stack, hnet_stack, model_lora_keyword, model_lyco_keyword)
class PrimereModelKeyword:
RETURN_TYPES = ("MODEL_KEYWORD",)
+66 -1
View File
@@ -701,4 +701,69 @@ class PrimereEmbeddingKeywordMerger:
if (len(embedding_neg) == 0):
embedding_neg = [None, None]
return (embedding_pos, embedding_neg,)
return (embedding_pos, embedding_neg,)
class PrimereLycorisStackMerger:
RETURN_TYPES = ("LYCORIS_STACK",)
RETURN_NAMES = ("LYCORIS_STACK",)
FUNCTION = "lycoris_stack_merger"
CATEGORY = TREE_INPUTS
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"lycoris_stack_1": ("LYCORIS_STACK",),
"lycoris_stack_2": ("LYCORIS_STACK",),
}
}
def lycoris_stack_merger(self, lycoris_stack_1, lycoris_stack_2):
if lycoris_stack_1 is not None and lycoris_stack_2 is not None:
return (lycoris_stack_1 + lycoris_stack_2, )
else:
return ([], )
class PrimereLycorisKeywordMerger:
RETURN_TYPES = ("MODEL_KEYWORD",)
RETURN_NAMES = ("LYCORIS_KEYWORD",)
FUNCTION = "lycoris_keyword_merger"
CATEGORY = TREE_INPUTS
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"lycoris_keyword_SD": ("MODEL_KEYWORD",),
"lycoris_keyword_SDXL": ("MODEL_KEYWORD",),
},
"optional": {
"lycoris_keyword_tagloader": ("MODEL_KEYWORD",),
},
}
def lycoris_keyword_merger(self, lycoris_keyword_SD, lycoris_keyword_SDXL, lycoris_keyword_tagloader):
model_keyword = [None, None]
if lycoris_keyword_SD is not None:
mkw_list_1 = list(filter(None, lycoris_keyword_SD))
if len(mkw_list_1) == 2:
model_keyword_1 = mkw_list_1[0]
placement = mkw_list_1[1]
model_keyword = [model_keyword_1, placement]
if lycoris_keyword_SDXL is not None:
mkw_list_2 = list(filter(None, lycoris_keyword_SDXL))
if len(mkw_list_2) == 2:
model_keyword_2 = mkw_list_2[0]
placement = mkw_list_2[1]
model_keyword = [model_keyword_2, placement]
if lycoris_keyword_tagloader is not None:
mkw_list_3 = list(filter(None, lycoris_keyword_tagloader))
if len(mkw_list_3) == 2:
model_keyword_3 = mkw_list_3[0]
placement = mkw_list_3[1]
model_keyword = [model_keyword_3, placement]
return (model_keyword,)
+134 -1
View File
@@ -8,6 +8,7 @@ import comfy.utils
import os
import random
from pathlib import Path
from ..utils import comfy_dir
# import comfy_extras.nodes_hypernetwork as comfy_extras
class PrimereLORA:
@@ -315,4 +316,136 @@ class PrimereHypernetwork:
else:
return (model, [],)
return (model_hypernetwork, hnetwork_stack,)
return (model_hypernetwork, hnetwork_stack,)
class PrimereLYCORIS:
RETURN_TYPES = ("MODEL", "CLIP", "LYCORIS_STACK", "MODEL_KEYWORD")
RETURN_NAMES = ("MODEL", "CLIP", "LYCORIS_STACK", "LYCORIS_KEYWORD")
FUNCTION = "primere_lycoris_stacker"
CATEGORY = TREE_NETWORKS
LYCOSCOUNT = 6
@classmethod
def INPUT_TYPES(cls):
LYCO_DIR = os.path.join(comfy_dir, 'models', 'lycoris')
folder_paths.add_model_folder_path("lycoris", LYCO_DIR)
LyCORIS = folder_paths.get_filename_list("lycoris")
LyCORISList = folder_paths.filter_files_extensions(LyCORIS, ['.ckpt', '.safetensors'])
return {
"required": {
"model": ("MODEL",),
"clip": ("CLIP",),
"model_version": ("STRING", {"default": 'BaseModel_1024', "forceInput": True}),
"stack_version": (["SD", "SDXL", "Any"], {"default": "Any"}),
"use_only_model_weight": ("BOOLEAN", {"default": True}),
"use_lycoris_1": ("BOOLEAN", {"default": False}),
"lycoris_1": (LyCORISList,),
"lycoris_1_model_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"lycoris_1_clip_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"use_lycoris_2": ("BOOLEAN", {"default": False}),
"lycoris_2": (LyCORISList,),
"lycoris_2_model_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"lycoris_2_clip_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"use_lycoris_3": ("BOOLEAN", {"default": False}),
"lycoris_3": (LyCORISList,),
"lycoris_3_model_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"lycoris_3_clip_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"use_lycoris_4": ("BOOLEAN", {"default": False}),
"lycoris_4": (LyCORISList,),
"lycoris_4_model_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"lycoris_4_clip_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"use_lycoris_5": ("BOOLEAN", {"default": False}),
"lycoris_5": (LyCORISList,),
"lycoris_5_model_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"lycoris_5_clip_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"use_lycoris_6": ("BOOLEAN", {"default": False}),
"lycoris_6": (LyCORISList,),
"lycoris_6_model_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"lycoris_6_clip_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"use_lycoris_keyword": ("BOOLEAN", {"default": False}),
"lycoris_keyword_placement": (["First", "Last"], {"default": "Last"}),
"lycoris_keyword_selection": (["Select in order", "Random select"], {"default": "Select in order"}),
"lycoris_keywords_num": ("INT", {"default": 1, "min": 1, "max": 50, "step": 1}),
"lycoris_keyword_weight": ("FLOAT", {"default": 1.0, "min": 0, "max": 10.0, "step": 0.1}),
},
}
def primere_lycoris_stacker(self, model, clip, use_only_model_weight, use_lycoris_keyword, lycoris_keyword_placement, lycoris_keyword_selection, lycoris_keywords_num, lycoris_keyword_weight, stack_version = 'Any', model_version = "BaseModel_1024", **kwargs):
model_keyword = [None, None]
if model_version == 'SDXL_2048' and stack_version == 'SD':
return (model, clip, [], model_keyword)
if model_version != 'SDXL_2048' and stack_version == 'SDXL':
return (model, clip, [], model_keyword)
lycoris = [kwargs.get(f"lycoris_{i}") for i in range(1, self.LYCOSCOUNT + 1)]
model_weight = [kwargs.get(f"lycoris_{i}_model_weight") for i in range(1, self.LYCOSCOUNT + 1)]
if use_only_model_weight == True:
clip_weight =[kwargs.get(f"lycoris_{i}_model_weight") for i in range(1, self.LYCOSCOUNT + 1)]
else:
clip_weight =[kwargs.get(f"lycoris_{i}_clip_weight") for i in range(1, self.LYCOSCOUNT + 1)]
uses = [kwargs.get(f"use_lycoris_{i}") for i in range(1, self.LYCOSCOUNT + 1)]
lycoris_stack = [(lycoris_name, lycoris_model_weight, lycoris_clip_weight) for lycoris_name, lycoris_model_weight, lycoris_clip_weight, lycoris_uses in zip(lycoris, model_weight, clip_weight, uses) if lycoris_uses == True]
lycoris_params = list()
if lycoris_stack and len(lycoris_stack) > 0:
lycoris_params.extend(lycoris_stack)
else:
return (model, clip, lycoris_stack, model_keyword)
model_lyco = model
clip_lyco = clip
list_of_keyword_items = []
lycoris_keywords_num_set = lycoris_keywords_num
for tup in lycoris_params:
lycoris_name, strength_model, strength_clip = tup
lycoris_path = folder_paths.get_full_path("lycoris", lycoris_name)
lyco = comfy.utils.load_torch_file(lycoris_path, safe_load=True)
model_lyco, clip_lyco = comfy.sd.load_lora_for_models(model_lyco, clip_lyco, lyco, strength_model, strength_clip)
if use_lycoris_keyword == True:
ModelKvHash = utility.get_model_hash(lycoris_path)
if ModelKvHash is not None:
KEYWORD_PATH = os.path.join(PRIMERE_ROOT, 'front_end', 'keywords', 'lora-keyword.txt')
keywords = utility.get_model_keywords(KEYWORD_PATH, ModelKvHash, lycoris_name)
if keywords is not None and keywords != "":
if keywords.find('|') > 1:
keyword_list = [word.strip() for word in keywords.split('|')]
keyword_list = list(filter(None, keyword_list))
if (len(keyword_list) > 0):
lycoris_keywords_num = lycoris_keywords_num_set
keyword_qty = len(keyword_list)
if (lycoris_keywords_num > keyword_qty):
lycoris_keywords_num = keyword_qty
if lycoris_keyword_selection == 'Select in order':
list_of_keyword_items.extend(keyword_list[:lycoris_keywords_num])
else:
list_of_keyword_items.extend(random.sample(keyword_list, lycoris_keywords_num))
else:
list_of_keyword_items.append(keywords)
if len(list_of_keyword_items) > 0:
if lycoris_keyword_selection != 'Select in order':
random.shuffle(list_of_keyword_items)
list_of_keyword_items = list(set(list_of_keyword_items))
keywords = ", ".join(list_of_keyword_items)
if (lycoris_keyword_weight != 1):
keywords = '(' + keywords + ':' + str(lycoris_keyword_weight) + ')'
model_keyword = [keywords, lycoris_keyword_placement]
return (model_lyco, clip_lyco, lycoris_stack, model_keyword)
+137 -1
View File
@@ -12,6 +12,7 @@ from pathlib import Path
import chardet
import pandas
import re
from ..utils import comfy_dir
# import comfy_extras.nodes_hypernetwork as comfy_extras
class PrimereVisualCKPT:
@@ -447,4 +448,139 @@ class PrimereVisualStyle:
if use_orientation == False:
prefered_orientation = None
return (positive_prompt, negative_prompt, prefered_subpath, prefered_model, prefered_orientation)
return (positive_prompt, negative_prompt, prefered_subpath, prefered_model, prefered_orientation)
class PrimereVisualLYCORIS:
RETURN_TYPES = ("MODEL", "CLIP", "LYCORIS_STACK", "MODEL_KEYWORD")
RETURN_NAMES = ("MODEL", "CLIP", "LYCORIS_STACK", "LYCORIS_KEYWORD")
FUNCTION = "primere_visual_lycoris_stacker"
CATEGORY = TREE_VISUALS
LYCOSCOUNT = 6
@classmethod
def INPUT_TYPES(cls):
LYCO_DIR = os.path.join(comfy_dir, 'models', 'lycoris')
folder_paths.add_model_folder_path("lycoris", LYCO_DIR)
LyCORIS = folder_paths.get_filename_list("lycoris")
LyCORISList = folder_paths.filter_files_extensions(LyCORIS, ['.ckpt', '.safetensors'])
return {
"required": {
"model": ("MODEL",),
"clip": ("CLIP",),
"model_version": ("STRING", {"default": 'BaseModel_1024', "forceInput": True}),
"stack_version": (["SD", "SDXL", "Any"], {"default": "Any"}),
"show_modal": ("BOOLEAN", {"default": True}),
"show_hidden": ("BOOLEAN", {"default": True}),
"use_only_model_weight": ("BOOLEAN", {"default": True}),
"use_lycoris_1": ("BOOLEAN", {"default": False}),
"lycoris_1": (LyCORISList,),
"lycoris_1_model_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"lycoris_1_clip_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"use_lycoris_2": ("BOOLEAN", {"default": False}),
"lycoris_2": (LyCORISList,),
"lycoris_2_model_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"lycoris_2_clip_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"use_lycoris_3": ("BOOLEAN", {"default": False}),
"lycoris_3": (LyCORISList,),
"lycoris_3_model_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"lycoris_3_clip_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"use_lycoris_4": ("BOOLEAN", {"default": False}),
"lycoris_4": (LyCORISList,),
"lycoris_4_model_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"lycoris_4_clip_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"use_lycoris_5": ("BOOLEAN", {"default": False}),
"lycoris_5": (LyCORISList,),
"lycoris_5_model_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"lycoris_5_clip_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"use_lycoris_6": ("BOOLEAN", {"default": False}),
"lycoris_6": (LyCORISList,),
"lycoris_6_model_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"lycoris_6_clip_weight": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"use_lycoris_keyword": ("BOOLEAN", {"default": False}),
"lycoris_keyword_placement": (["First", "Last"], {"default": "Last"}),
"lycoris_keyword_selection": (["Select in order", "Random select"], {"default": "Select in order"}),
"lycoris_keywords_num": ("INT", {"default": 1, "min": 1, "max": 50, "step": 1}),
"lycoris_keyword_weight": ("FLOAT", {"default": 1.0, "min": 0, "max": 10.0, "step": 0.1}),
},
}
def primere_visual_lycoris_stacker(self, model, clip, use_only_model_weight, use_lycoris_keyword, lycoris_keyword_placement, lycoris_keyword_selection, lycoris_keywords_num, lycoris_keyword_weight, stack_version = 'Any', model_version = "BaseModel_1024", **kwargs):
model_keyword = [None, None]
if model_version == 'SDXL_2048' and stack_version == 'SD':
return (model, clip, [], model_keyword)
if model_version != 'SDXL_2048' and stack_version == 'SDXL':
return (model, clip, [], model_keyword)
lycoris = [kwargs.get(f"lycoris_{i}") for i in range(1, self.LYCOSCOUNT + 1)]
model_weight = [kwargs.get(f"lycoris_{i}_model_weight") for i in range(1, self.LYCOSCOUNT + 1)]
if use_only_model_weight == True:
clip_weight =[kwargs.get(f"lycoris_{i}_model_weight") for i in range(1, self.LYCOSCOUNT + 1)]
else:
clip_weight =[kwargs.get(f"lycoris_{i}_clip_weight") for i in range(1, self.LYCOSCOUNT + 1)]
uses = [kwargs.get(f"use_lycoris_{i}") for i in range(1, self.LYCOSCOUNT + 1)]
lycoris_stack = [(lycoris_name, lycoris_model_weight, lycoris_clip_weight) for lycoris_name, lycoris_model_weight, lycoris_clip_weight, lycoris_uses in zip(lycoris, model_weight, clip_weight, uses) if lycoris_uses == True]
lycoris_params = list()
if lycoris_stack and len(lycoris_stack) > 0:
lycoris_params.extend(lycoris_stack)
else:
return (model, clip, lycoris_stack, model_keyword)
model_lyco = model
clip_lyco = clip
list_of_keyword_items = []
lycoris_keywords_num_set = lycoris_keywords_num
for tup in lycoris_params:
lycoris_name, strength_model, strength_clip = tup
lycoris_path = folder_paths.get_full_path("lycoris", lycoris_name)
lyco = comfy.utils.load_torch_file(lycoris_path, safe_load=True)
model_lyco, clip_lyco = comfy.sd.load_lora_for_models(model_lyco, clip_lyco, lyco, strength_model, strength_clip)
if use_lycoris_keyword == True:
ModelKvHash = utility.get_model_hash(lycoris_path)
if ModelKvHash is not None:
KEYWORD_PATH = os.path.join(PRIMERE_ROOT, 'front_end', 'keywords', 'lora-keyword.txt')
keywords = utility.get_model_keywords(KEYWORD_PATH, ModelKvHash, lycoris_name)
if keywords is not None and keywords != "":
if keywords.find('|') > 1:
keyword_list = [word.strip() for word in keywords.split('|')]
keyword_list = list(filter(None, keyword_list))
if (len(keyword_list) > 0):
lycoris_keywords_num = lycoris_keywords_num_set
keyword_qty = len(keyword_list)
if (lycoris_keywords_num > keyword_qty):
lycoris_keywords_num = keyword_qty
if lycoris_keyword_selection == 'Select in order':
list_of_keyword_items.extend(keyword_list[:lycoris_keywords_num])
else:
list_of_keyword_items.extend(random.sample(keyword_list, lycoris_keywords_num))
else:
list_of_keyword_items.append(keywords)
if len(list_of_keyword_items) > 0:
if lycoris_keyword_selection != 'Select in order':
random.shuffle(list_of_keyword_items)
list_of_keyword_items = list(set(list_of_keyword_items))
keywords = ", ".join(list_of_keyword_items)
if (lycoris_keyword_weight != 1):
keywords = '(' + keywords + ':' + str(lycoris_keyword_weight) + ')'
model_keyword = [keywords, lycoris_keyword_placement]
return (model_lyco, clip_lyco, lycoris_stack, model_keyword)
File diff suppressed because it is too large Load Diff
+8
View File
@@ -72,6 +72,8 @@ NODE_CLASS_MAPPINGS = {
"PrimereLoraStackMerger": Inputs.PrimereLoraStackMerger,
"PrimereLoraKeywordMerger": Inputs.PrimereLoraKeywordMerger,
"PrimereEmbeddingKeywordMerger": Inputs.PrimereEmbeddingKeywordMerger,
"PrimereLycorisStackMerger": Inputs.PrimereLycorisStackMerger,
"PrimereLycorisKeywordMerger": Inputs.PrimereLycorisKeywordMerger,
"PrimereMetaSave": Outputs.PrimereMetaSave,
"PrimereAnyOutput": Outputs.PrimereAnyOutput,
@@ -84,10 +86,12 @@ NODE_CLASS_MAPPINGS = {
"PrimereVisualEmbedding": Visuals.PrimereVisualEmbedding,
"PrimereVisualHypernetwork": Visuals.PrimereVisualHypernetwork,
"PrimereVisualStyle": Visuals.PrimereVisualStyle,
"PrimereVisualLYCORIS": Visuals.PrimereVisualLYCORIS,
"PrimereLORA": Networks.PrimereLORA,
"PrimereEmbedding": Networks.PrimereEmbedding,
"PrimereHypernetwork": Networks.PrimereHypernetwork,
"PrimereLYCORIS": Networks.PrimereLYCORIS,
}
NODE_DISPLAY_NAME_MAPPINGS = {
@@ -117,6 +121,8 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"PrimereLoraStackMerger": "Primere Lora Stack Merger",
"PrimereLoraKeywordMerger": 'Primere Lora Keyword Merger',
"PrimereEmbeddingKeywordMerger": "Primere Embedding Keyword Merger",
"PrimereLycorisStackMerger": 'Primere Lycoris Stack Merger',
"PrimereLycorisKeywordMerger": 'Primere Lycoris Keyword Merger',
"PrimereMetaSave": "Primere Image Meta Saver",
"PrimereAnyOutput": "Primere Any Debug",
@@ -129,8 +135,10 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"PrimereVisualEmbedding": 'Primere Visual Embedding Selector',
"PrimereVisualHypernetwork": 'Primere Visual Hypernetwork Selector',
"PrimereVisualStyle": 'Primere Visual Style Selector',
"PrimereVisualLYCORIS": 'Primere Visual LYCORIS Selector',
"PrimereLORA": 'Primere LORA',
"PrimereEmbedding": 'Primere Embedding',
"PrimereHypernetwork": 'Primere Hypernetwork',
"PrimereLYCORIS": 'Primere LYCORIS',
}
+2
View File
@@ -141,6 +141,8 @@ def get_networks_prompt(NETWORK_START, NETWORK_END, promptstring):
networkdata.append('1')
if LABEL == '<lora:':
networkdata.append('LORA')
if LABEL == '<lyco:':
networkdata.append('LYCORIS')
if LABEL == '<hypernet:':
networkdata.append('HYPERNET')
+2
View File
@@ -0,0 +1,2 @@
Duplicate your original checkpoint structure here, but copy/symlink only the images, name as {checkpoint_filename}.jpg
For example if you have checkpoint in path Design/dvarchInterior.safetensors, you must create here Design/dvarchInterior.jpg for preview.
+8 -1
View File
@@ -1,7 +1,7 @@
import { app } from "/scripts/app.js";
const realPath = "extensions/Primere";
const validClasses = ['PrimereVisualCKPT', 'PrimereVisualLORA', 'PrimereVisualEmbedding', 'PrimereVisualHypernetwork', 'PrimereVisualStyle'];
const validClasses = ['PrimereVisualCKPT', 'PrimereVisualLORA', 'PrimereVisualEmbedding', 'PrimereVisualHypernetwork', 'PrimereVisualStyle', 'PrimereVisualLYCORIS'];
let lastDirObject = {};
let currentClass = false;
@@ -342,6 +342,13 @@ app.registerExtension({
isnumeric_end = false;
}
if (node.type == 'PrimereVisualLYCORIS') {
subdirname = 'lycoris';
modaltitle = 'Select LYCORIS';
nodematch = '^lycoris_';
isnumeric_end = true;
}
if (event.type != LiteGraph.pointerevents_method + "down") {
return lcg.call(this, node, pos, event, active_widget);
}