10 KiB
10 KiB
Documentation
- Class name: IPAdapterModelHelper
- Category: InspirePack/models
- Output node: False
- Repo Ref: https://github.com/ltdrdata/ComfyUI-Inspire-Pack.git
IPAdapterModelHelper节点是InspirePack套件中的一个关键组件,它促进了各种模型和预设的无缝集成和应用。它巧妙地管理了模型加载的复杂性并确保了兼容性,使用户能够以最小的摩擦力利用不同模型的强大功能。该节点旨在简化模型使用过程,为访问多样化功能提供统一的接口。
Input types
Required
- model
- 模型参数对于节点的操作至关重要,因为它定义了要使用的核心技术模型。它显著影响节点的执行和产生的结果质量,使其成为节点功能的一个基本方面。
- Comfy dtype: MODEL
- Python dtype: torch.nn.Module
- clip
- clip参数通过提供图像处理所需的上下文,在节点的功能中发挥着重要作用。它对于节点根据输入数据生成准确和相关的输出至关重要。
- Comfy dtype: CLIP
- Python dtype: torch.Tensor
- preset
- 预设参数允许用户选择预定义的设置,将节点的行为调整为特定用例。它是根据用户需求定制节点操作的关键元素。
- Comfy dtype: COMBO[list(model_preset.keys())]
- Python dtype: str
- lora_strength_model
- lora_strength_model参数调整LoRA模型对节点输出的影响。它是一个重要的调整因素,可以显著影响最终结果,允许对节点行为进行细粒度控制。
- Comfy dtype: FLOAT
- Python dtype: float
- lora_strength_clip
- lora_strength_clip参数微调CLIP模型对节点处理的影响。对于需要控制CLIP模型影响与其他因素之间平衡的用户来说,它是一个关键参数。
- Comfy dtype: FLOAT
- Python dtype: float
- insightface_provider
- insightface_provider参数指定用于InsightFace模型的后端,这对于面部识别任务至关重要。这是一个重要的选择,可以影响节点的性能和与用户系统的兼容性。
- Comfy dtype: COMBO'CPU', 'CUDA', 'ROCM'
- Python dtype: str
- cache_mode
- cache_mode参数确定节点的缓存策略,可以通过减少冗余操作来提高性能。对于优化节点的效率,这是一个重要的考虑因素。
- Comfy dtype: COMBO'insightface only', 'clip_vision only', 'all', 'none'
- Python dtype: str
- unique_id
- unique_id参数用于在系统中跟踪和识别节点,这对于调试和管理节点的多个实例特别有用。
- Comfy dtype: UNIQUE_ID
- Python dtype: str
Output types
- IPADAPTER_PIPE
- IPADAPTER_PIPE输出是一个复合结构,封装了处理后的数据和模型,为进一步分析或利用提供了全面的流水线。
- Comfy dtype: IPADAPTER_PIPE
- Python dtype: Tuple[torch.nn.Module, torch.Tensor, torch.Tensor, Any, Callabletorch.nn.Module], torch.nn.Module
- IPADAPTER
- IPADAPTER输出代表已加载的IPAdapter模型,可用于后续图像处理任务中的应用。
- Comfy dtype: IPADAPTER
- Python dtype: torch.nn.Module
- CLIP_VISION
- CLIP_VISION输出提供了已加载的CLIP模型,这对于从图像生成上下文嵌入至关重要。
- Comfy dtype: CLIP_VISION
- Python dtype: torch.Tensor
- INSIGHTFACE
- INSIGHTFACE输出提供了InsightFace模型,该模型专门用于节点操作中的面部识别和分析。
- Comfy dtype: INSIGHTFACE
- Python dtype: Any
- MODEL
- MODEL输出指的是已被节点增强或修改的主要模型,可供进一步处理或直接应用。
- Comfy dtype: MODEL
- Python dtype: torch.nn.Module
- CLIP
- CLIP输出表示处理过的CLIP数据,可用于涉及图像和文本交互的各种下游任务。
- Comfy dtype: CLIP
- Python dtype: torch.Tensor
- insightface_cache_key
- insightface_cache_key输出是用于缓存InsightFace模型的唯一标识符,它优化了节点重复使用时的性能。
- Comfy dtype: STRING
- Python dtype: str
- clip_vision_cache_key
- clip_vision_cache_key输出为CLIP Vision模型提供了一个用于缓存的唯一标识符,这有助于提高节点在重复任务中的效率。
- Comfy dtype: STRING
- Python dtype: str
Usage tips
- Infra type: GPU
Source code
class IPAdapterModelHelper:
@classmethod
def INPUT_TYPES(s):
return {'required': {'model': ('MODEL',), 'clip': ('CLIP',), 'preset': (list(model_preset.keys()),), 'lora_strength_model': ('FLOAT', {'default': 1.0, 'min': -20.0, 'max': 20.0, 'step': 0.01}), 'lora_strength_clip': ('FLOAT', {'default': 1.0, 'min': -20.0, 'max': 20.0, 'step': 0.01}), 'insightface_provider': (['CPU', 'CUDA', 'ROCM'],), 'cache_mode': (['insightface only', 'clip_vision only', 'all', 'none'], {'default': 'insightface only'})}, 'hidden': {'unique_id': 'UNIQUE_ID'}}
RETURN_TYPES = ('IPADAPTER_PIPE', 'IPADAPTER', 'CLIP_VISION', 'INSIGHTFACE', 'MODEL', 'CLIP', 'STRING', 'STRING')
RETURN_NAMES = ('IPADAPTER_PIPE', 'IPADAPTER', 'CLIP_VISION', 'INSIGHTFACE', 'MODEL', 'CLIP', 'insightface_cache_key', 'clip_vision_cache_key')
FUNCTION = 'doit'
CATEGORY = 'InspirePack/models'
def doit(self, model, clip, preset, lora_strength_model, lora_strength_clip, insightface_provider, cache_mode='none', unique_id=None):
if 'IPAdapterApply' not in nodes.NODE_CLASS_MAPPINGS:
utils.try_install_custom_node('https://github.com/cubiq/ComfyUI_IPAdapter_plus', "To use 'IPAdapterModelHelper' node, 'ComfyUI IPAdapter Plus' extension is required.")
raise Exception(f"[ERROR] To use IPAdapterModelHelper, you need to install 'ComfyUI IPAdapter Plus'")
is_sdxl_preset = 'SDXL' in preset
is_sdxl_model = isinstance(clip.tokenizer, sdxl_clip.SDXLTokenizer)
if is_sdxl_preset != is_sdxl_model:
server.PromptServer.instance.send_sync('inspire-node-output-label', {'node_id': unique_id, 'output_idx': 1, 'label': 'IPADAPTER (fail)'})
server.PromptServer.instance.send_sync('inspire-node-output-label', {'node_id': unique_id, 'output_idx': 2, 'label': 'CLIP_VISION (fail)'})
server.PromptServer.instance.send_sync('inspire-node-output-label', {'node_id': unique_id, 'output_idx': 3, 'label': 'INSIGHTFACE (fail)'})
server.PromptServer.instance.send_sync('inspire-node-output-label', {'node_id': unique_id, 'output_idx': 4, 'label': 'MODEL (fail)'})
server.PromptServer.instance.send_sync('inspire-node-output-label', {'node_id': unique_id, 'output_idx': 5, 'label': 'CLIP (fail)'})
print(f'[ERROR] IPAdapterModelHelper: You cannot mix SDXL and SD1.5 in the checkpoint and IPAdapter.')
raise Exception('[ERROR] You cannot mix SDXL and SD1.5 in the checkpoint and IPAdapter.')
(ipadapter, clipvision, lora, is_insightface) = model_preset[preset]
(ipadapter, ok1) = lookup_model('ipadapter', ipadapter)
(clipvision, ok2) = lookup_model('clip_vision', clipvision)
(lora, ok3) = lookup_model('loras', lora)
if ok1 == 'OK':
ok1 = 'IPADAPTER'
else:
ok1 = f'IPADAPTER ({ok1})'
if ok2 == 'OK':
ok2 = 'CLIP_VISION'
else:
ok2 = f'CLIP_VISION ({ok2})'
server.PromptServer.instance.send_sync('inspire-node-output-label', {'node_id': unique_id, 'output_idx': 1, 'label': ok1})
server.PromptServer.instance.send_sync('inspire-node-output-label', {'node_id': unique_id, 'output_idx': 2, 'label': ok2})
if ok3 == 'FAIL':
server.PromptServer.instance.send_sync('inspire-node-output-label', {'node_id': unique_id, 'output_idx': 4, 'label': 'MODEL (fail)'})
server.PromptServer.instance.send_sync('inspire-node-output-label', {'node_id': unique_id, 'output_idx': 5, 'label': 'CLIP (fail)'})
else:
server.PromptServer.instance.send_sync('inspire-node-output-label', {'node_id': unique_id, 'output_idx': 4, 'label': 'MODEL'})
server.PromptServer.instance.send_sync('inspire-node-output-label', {'node_id': unique_id, 'output_idx': 5, 'label': 'CLIP'})
if ok1 == 'FAIL' or ok2 == 'FAIL' or ok3 == 'FAIL':
raise Exception('ERROR: Failed to load several models in IPAdapterModelHelper.')
if ipadapter is not None:
ipadapter = nodes.NODE_CLASS_MAPPINGS['IPAdapterModelLoader']().load_ipadapter_model(ipadapter_file=ipadapter)[0]
ccache_key = ''
if clipvision is not None:
if cache_mode in ['clip_vision only', 'all']:
ccache_key = clipvision
if ccache_key not in backend_support.cache:
backend_support.cache[ccache_key] = (False, nodes.CLIPVisionLoader().load_clip(clip_name=clipvision)[0])
clipvision = backend_support.cache[ccache_key][1]
else:
clipvision = nodes.CLIPVisionLoader().load_clip(clip_name=clipvision)[0]
if lora is not None:
(model, clip) = nodes.LoraLoader().load_lora(model=model, clip=clip, lora_name=lora, strength_model=lora_strength_model, strength_clip=lora_strength_clip)
def f(x):
return nodes.LoraLoader().load_lora(model=x, clip=clip, lora_name=lora, strength_model=lora_strength_model, strength_clip=lora_strength_clip)
lora_loader = f
else:
def f(x):
return x
lora_loader = f
icache_key = ''
if is_insightface:
if cache_mode in ['insightface only', 'all']:
icache_key = 'insightface-' + insightface_provider
if icache_key not in backend_support.cache:
backend_support.cache[icache_key] = (False, nodes.NODE_CLASS_MAPPINGS['InsightFaceLoader']().load_insight_face(insightface_provider)[0])
insightface = backend_support.cache[icache_key][1]
else:
insightface = nodes.NODE_CLASS_MAPPINGS['InsightFaceLoader']().load_insight_face(insightface_provider)[0]
server.PromptServer.instance.send_sync('inspire-node-output-label', {'node_id': unique_id, 'output_idx': 3, 'label': 'INSIGHTFACE'})
else:
insightface = None
server.PromptServer.instance.send_sync('inspire-node-output-label', {'node_id': unique_id, 'output_idx': 3, 'label': 'INSIGHTFACE (N/A)'})
pipe = (ipadapter, model, clipvision, insightface, lora_loader)
return (pipe, ipadapter, clipvision, insightface, model, clip, icache_key, ccache_key)