StupidGame's picture
Upload 1941 files
baa8e90
import torch
import inspect
from pathlib import Path
from functools import partial
import os
from .modules import prompt_parser, devices, shared
from .modules.sd_hijack import model_hijack
from .smZNodes import run, prepare_noise
from nodes import MAX_RESOLUTION
import comfy.sd
import comfy.model_management
import comfy.samplers
import comfy.sample
BOOLEAN = [False, True]
try:
cwd_path = Path(__file__).parent
comfy_path = cwd_path.parent.parent
widgets_path = os.path.join(comfy_path, "web", "scripts", "widgets.js")
with open(widgets_path, encoding='utf8') as f:
widgets_js = f.read()
if 'BOOLEAN(' in widgets_js:
BOOLEAN = "BOOLEAN"
del widgets_js
except Exception as err:
print("[smZNodes]:", err)
class smZ_CLIPTextEncode:
@classmethod
def INPUT_TYPES(s):
return {"required": {
"text": ("STRING", {"multiline": True}),
"clip": ("CLIP", ),
"parser": (["comfy", "comfy++", "A1111", "full", "compel", "fixed attention"],{"default": "comfy"}),
# whether weights are normalized by taking the mean
"mean_normalization": (BOOLEAN, {"default": True}),
"multi_conditioning": (BOOLEAN, {"default": True}),
"use_old_emphasis_implementation": (BOOLEAN, {"default": False}),
"with_SDXL": (BOOLEAN, {"default": False}),
"ascore": ("FLOAT", {"default": 6.0, "min": 0.0, "max": 1000.0, "step": 0.01}),
"width": ("INT", {"default": 1024.0, "min": 0, "max": MAX_RESOLUTION}),
"height": ("INT", {"default": 1024.0, "min": 0, "max": MAX_RESOLUTION}),
"crop_w": ("INT", {"default": 0, "min": 0, "max": MAX_RESOLUTION}),
"crop_h": ("INT", {"default": 0, "min": 0, "max": MAX_RESOLUTION}),
"target_width": ("INT", {"default": 1024.0, "min": 0, "max": MAX_RESOLUTION}),
"target_height": ("INT", {"default": 1024.0, "min": 0, "max": MAX_RESOLUTION}),
"text_g": ("STRING", {"multiline": True, "placeholder": "CLIP_G"}),
"text_l": ("STRING", {"multiline": True, "placeholder": "CLIP_L"}),
},
"optional": {
"smZ_steps": ("INT", {"default": 1, "min": 1, "max": 0xffffffffffffffff}),
},
}
RETURN_TYPES = ("CONDITIONING",)
FUNCTION = "encode"
CATEGORY = "conditioning"
def encode(self, clip: comfy.sd.CLIP, text, parser, mean_normalization,
multi_conditioning, use_old_emphasis_implementation,
with_SDXL, ascore, width, height, crop_w,
crop_h, target_width, target_height, text_g, text_l, smZ_steps=1):
params = locals()
params['steps'] = params.pop('smZ_steps', smZ_steps)
from .modules.shared import opts
is_sdxl = "SDXL" in type(clip.cond_stage_model).__name__
should_use_fp16_signature = inspect.signature(comfy.model_management.should_use_fp16)
_p = should_use_fp16_signature.parameters
devices.device = shared.device = clip.patcher.load_device if hasattr(clip.patcher, 'load_device') else clip.device
if 'device' in _p and 'prioritize_performance' in _p:
should_use_fp16 = partial(comfy.model_management.should_use_fp16, device=devices.device, prioritize_performance=False)
elif 'device' in should_use_fp16_signature.parameters:
should_use_fp16 = partial(comfy.model_management.should_use_fp16, device=devices.device)
else:
should_use_fp16 = comfy.model_management.should_use_fp16
dtype = torch.float16 if should_use_fp16() else torch.float32
dtype_unet= dtype
devices.dtype = dtype
# devices.dtype_unet was hijacked so it will be the correct dtype by default
if devices.dtype_unet == torch.float16:
devices.dtype_unet = dtype_unet
devices.unet_needs_upcast = opts.upcast_sampling and devices.dtype == torch.float16 and devices.dtype_unet == torch.float16
devices.dtype_vae = comfy.model_management.vae_dtype() if hasattr(comfy.model_management, 'vae_dtype') else torch.float32
params.pop('self', None)
result = run(**params)
result[0][0][1]['params'] = {}
result[0][0][1]['params'].update(params)
if opts.pad_cond_uncond:
text=params['text']
with_SDXL=params['with_SDXL']
params['text'] = ''
params['with_SDXL'] = False
empty = run(**params)[0]
params['text'] = text
params['with_SDXL'] = with_SDXL
shared.sd_model.cond_stage_model_empty_prompt = empty[0][0]
return result
# Hack: string type that is always equal in not equal comparisons
class AnyType(str):
def __ne__(self, __value: object) -> bool:
return False
# Our any instance wants to be a wildcard string
anytype = AnyType("*")
class smZ_Settings:
@classmethod
def INPUT_TYPES(s):
from .modules.shared import opts
return {"required": {
"clip": ("CLIP", ),
},
"optional": {
"extra": ("STRING", {"multiline": True, "default": '{"show":true}'}),
"ㅤ"*1: ( "STRING", {"multiline": False, "default": "Stable Diffusion"}),
"info_comma_padding_backtrack": ("STRING", {"multiline": True, "default": "Prompt word wrap length limit\nin tokens - for texts shorter than specified, if they don't fit into 75 token limit, move them to the next 75 token chunk"}),
"Prompt word wrap length limit": ("INT", {"default": opts.comma_padding_backtrack, "min": 0, "max": 74, "step": 1}),
# "enable_emphasis": (BOOLEAN, {"default": opts.enable_emphasis}),
"info_RNG": ("STRING", {"multiline": True, "default": "Random number generator source.\nchanges seeds drastically; use CPU to produce the same picture across different videocard vendors; use NV to produce same picture as on NVidia videocards"}),
"RNG": (["cpu", "gpu", "nv"],{"default": opts.randn_source}),
"ㅤ"*2: ("STRING", {"multiline": False, "default": "Compute Settings"}),
"info_disable_nan_check": ("STRING", {"multiline": True, "default": "Disable NaN check in produced images/latent spaces. Only for CFGDenoiser."}),
"disable_nan_check": (BOOLEAN, {"default": opts.disable_nan_check}),
"ㅤ"*3: ("STRING", {"multiline": False, "default": "Sampler parameters"}),
"info_eta_noise_seed_delta": ("STRING", {"multiline": True, "default": "Eta noise seed delta\ndoes not improve anything, just produces different results for ancestral samplers - only useful for reproducing images"}),
"ENSD": ("INT", {"default": opts.eta_noise_seed_delta, "min": 0, "max": 0xffffffffffffffff, "step": 1}),
"info_sgm_noise_multiplier": ("STRING", {"multiline": True, "default": "SGM noise multiplier\nmatch initial noise to official SDXL implementation - only useful for reproducing images\nsee https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12818"}),
"sgm_noise_multiplier": (BOOLEAN, {"default": opts.sgm_noise_multiplier}),
"info_upcast_sampling": ("STRING", {"multiline": True, "default": "upcast sampling.\nNo effect with --force-fp32. Usually produces similar results to --force-fp32 with better performance while using less memory."}),
"upcast_sampling": (BOOLEAN, {"default": opts.upcast_sampling}),
"ㅤ"*4: ("STRING", {"multiline": False, "default": "Optimizations"}),
"info_NGMS": ("STRING", {"multiline": True, "default": "Negative Guidance minimum sigma\nskip negative prompt for some steps when the image is almost ready; 0=disable, higher=faster. Only for CFGDenoiser.\nsee https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/9177"}),
"NGMS": ("FLOAT", {"default": opts.s_min_uncond, "min": 0.0, "max": 4.0, "step": 0.01}),
"info_pad_cond_uncond": ("STRING", {"multiline": True, "default": "Pad prompt/negative prompt to be same length\nimproves performance when prompt and negative prompt have different lengths; changes seeds. Only for CFGDenoiser."}),
"pad_cond_uncond": (BOOLEAN, {"default": opts.pad_cond_uncond}),
"info_batch_cond_uncond": ("STRING", {"multiline": True, "default": "Batch cond/uncond\ndo both conditional and unconditional denoising in one batch; uses a bit more VRAM during sampling, but improves speed – enabled on SDXL models. Only for CFGDenoiser."}),
"batch_cond_uncond": (BOOLEAN, {"default": opts.batch_cond_uncond}),
"ㅤ"*5: ("STRING", {"multiline": False, "default": "Compatibility"}),
"info_use_prev_scheduling": ("STRING", {"multiline": True, "default": "Previous prompt editing timelines\nFor [red:green:N]; previous: If N < 1, it's a fraction of steps (and hires fix uses range from 0 to 1), if N >= 1, it's an absolute number of steps; new: If N has a decimal point in it, it's a fraction of steps (and hires fix uses range from 1 to 2), othewrwise it's an absolute number of steps"}),
"Use previous prompt editing timelines": (BOOLEAN, {"default": opts.use_old_scheduling}),
"ㅤ"*6: ("STRING", {"multiline": False, "default": "Experimental"}),
"info_use_CFGDenoiser": ("STRING", {"multiline": True, "default": "CFGDenoiser\nAn experimental option to use stable-diffusion-webui's denoiser. It may not work as expected with inpainting/UnCLIP models or ComfyUI's Conditioning nodes, but it allows you to get identical images regardless of the prompt."}),
"Use CFGDenoiser": (BOOLEAN, {"default": opts.use_CFGDenoiser}),
"info_debug": ("STRING", {"multiline": True, "default": "Debugging messages in the console."}),
"Debug": (BOOLEAN, {"default": opts.debug, "label_on": "on", "label_off": "off"}),
}}
RETURN_TYPES = ("CLIP",)
OUTPUT_NODE = False
FUNCTION = "run"
CATEGORY = "advanced"
def run(self, *args, **kwargs):
from .modules.shared import opts
device = comfy.model_management.get_torch_device()
clip = kwargs.pop('clip', None) if 'clip' in kwargs else args[0]
kwargs['s_min_uncond'] = max(min(kwargs.pop('NGMS'), 4.0), 0)
kwargs['comma_padding_backtrack'] = kwargs.pop('Prompt word wrap length limit')
kwargs['comma_padding_backtrack'] = max(min(kwargs['comma_padding_backtrack'], 74), 0)
kwargs['use_old_scheduling']=kwargs.pop("Use previous prompt editing timelines")
kwargs['use_CFGDenoiser'] = kwargs.pop("Use CFGDenoiser")
kwargs['debug'] = kwargs.pop('Debug')
kwargs['randn_source'] = kwargs.pop('RNG')
kwargs['eta_noise_seed_delta'] = kwargs.pop('ENSD')
[kwargs.pop(k, None) for k in [k for k in kwargs.keys() if 'info' in k or 'heading' in k or 'ㅤ' in k]]
for k,v in kwargs.items():
setattr(opts, k, v)
if not hasattr(comfy.sample, 'prepare_noise_orig'):
comfy.sample.prepare_noise_orig = comfy.sample.prepare_noise
if opts.randn_source == 'cpu':
device = torch.device("cpu")
_prepare_noise = partial(prepare_noise, device=device.type)
comfy.sample.prepare_noise = _prepare_noise
return (clip,)
# A dictionary that contains all nodes you want to export with their names
# NOTE: names should be globally unique
NODE_CLASS_MAPPINGS = {
"smZ CLIPTextEncode": smZ_CLIPTextEncode,
"smZ Settings": smZ_Settings,
}
# A dictionary that contains the friendly/humanly readable titles for the nodes
NODE_DISPLAY_NAME_MAPPINGS = {
"smZ CLIPTextEncode" : "CLIP Text Encode++",
"smZ Settings" : "Settings (smZ)",
}