added clip scanner node
This commit is contained in:
@@ -89,6 +89,7 @@ from .nodes.FL_API_ImageSaver import FL_API_ImageSaver
|
||||
from .nodes.FL_GoogleDriveImageDownloader import FL_GoogleDriveImageDownloader
|
||||
from .nodes.FL_AnimeLineExtractor import FL_AnimeLineExtractor
|
||||
from .nodes.FL_HunyuanDelight import FL_HunyuanDelight
|
||||
from .nodes.FL_ClipScanner import FL_ClipScanner
|
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
@@ -184,6 +185,7 @@ NODE_CLASS_MAPPINGS = {
|
||||
"FL_GoogleDriveImageDownloader": FL_GoogleDriveImageDownloader,
|
||||
"FL_AnimeLineExtractor": FL_AnimeLineExtractor,
|
||||
"FL_HunyuanDelight": FL_HunyuanDelight,
|
||||
"FL_ClipScanner": FL_ClipScanner,
|
||||
|
||||
}
|
||||
|
||||
@@ -280,6 +282,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"FL_GoogleDriveImageDownloader": "FL Google Drive Image Downloader",
|
||||
"FL_AnimeLineExtractor": "FL Anime Line Extractor",
|
||||
"FL_HunyuanDelight": "FL Hunyuan Delight",
|
||||
"FL_ClipScanner": "FL Clip Scanner (Kytra)",
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
import open_clip
|
||||
|
||||
class FL_ClipScanner:
|
||||
def __init__(self):
|
||||
self.current_model = None
|
||||
self.current_pretrained = None
|
||||
self.tokenizer = None
|
||||
|
||||
# Model configurations
|
||||
self.model_configs = {
|
||||
"SDXL (ViT-G/14)": {
|
||||
"model": "ViT-g-14",
|
||||
"pretrained": "laion2b_s12b_b42k"
|
||||
},
|
||||
"SD 1.5 (ViT-L/14)": {
|
||||
"model": "ViT-L-14",
|
||||
"pretrained": "openai"
|
||||
},
|
||||
"FLUX (ViT-L/14)": {
|
||||
"model": "ViT-L-14",
|
||||
"pretrained": "openai"
|
||||
}
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"model_type": (list(cls().model_configs.keys()),),
|
||||
"text": ("STRING", {"default": "", "multiline": True}),
|
||||
},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("STRING",)
|
||||
FUNCTION = "analyze_tokens"
|
||||
CATEGORY = "🏵️Fill Nodes/Analysis"
|
||||
OUTPUT_NODE = True
|
||||
|
||||
def initialize_model(self, model_type):
|
||||
if (self.current_model != self.model_configs[model_type]["model"] or
|
||||
self.current_pretrained != self.model_configs[model_type]["pretrained"]):
|
||||
try:
|
||||
config = self.model_configs[model_type]
|
||||
self.tokenizer = open_clip.get_tokenizer(config["model"])
|
||||
self.current_model = config["model"]
|
||||
self.current_pretrained = config["pretrained"]
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"Error initializing CLIP tokenizer: {str(e)}")
|
||||
self.tokenizer = None
|
||||
return False
|
||||
return True
|
||||
|
||||
def analyze_tokens(self, model_type: str, text: str) -> tuple[str]:
|
||||
if not self.initialize_model(model_type):
|
||||
return ("Error: Failed to initialize CLIP tokenizer.",)
|
||||
|
||||
try:
|
||||
# Tokenize the input text
|
||||
tokens = self.tokenizer(text)
|
||||
|
||||
# Convert token IDs to words
|
||||
decoded_tokens = [self.tokenizer.decoder.get(tok, f"[{tok}]")
|
||||
for tok in tokens[0].tolist()]
|
||||
|
||||
# Remove start, end, and padding tokens
|
||||
filtered_tokens = [t for t in decoded_tokens
|
||||
if not t.startswith("<") and t != "!"]
|
||||
|
||||
# Create formatted output
|
||||
output = []
|
||||
output.append("=" * 60)
|
||||
output.append(f"Model: {model_type}")
|
||||
output.append(f"CLIP: {self.current_model} ({self.current_pretrained})")
|
||||
output.append(f"Prompt: \"{text}\"")
|
||||
output.append(f"Tokenized Output: {filtered_tokens}")
|
||||
output.append(f"Token Count: {len(filtered_tokens)}")
|
||||
output.append("=" * 60)
|
||||
|
||||
return ("\n".join(output),)
|
||||
|
||||
except Exception as e:
|
||||
return (f"Error analyzing tokens: {str(e)}",)
|
||||
|
||||
@classmethod
|
||||
def IS_CHANGED(cls, model_type, text):
|
||||
return float("NaN")
|
||||
@@ -19,3 +19,4 @@ ollama
|
||||
kornia
|
||||
opencv-python
|
||||
gdown
|
||||
open_clip_torch
|
||||
Reference in New Issue
Block a user