From a4579ceddb7bf7e92f8a94e28123f454080a6b62 Mon Sep 17 00:00:00 2001 From: cavinHuang Date: Sat, 25 May 2024 18:57:13 +0800 Subject: [PATCH] feat: update ipa dosc --- docs/IPAAdapterFaceIDBatch.md | 31 ++++++ docs/IPAdapter.md | 78 +++++++++++++++ docs/IPAdapterAdvanced.md | 73 ++++++++++++++ docs/IPAdapterBatch.md | 72 ++++++++++++++ docs/IPAdapterCombineEmbeds.md | 77 +++++++++++++++ docs/IPAdapterEmbeds.md | 89 +++++++++++++++++ docs/IPAdapterEncoder.md | 82 ++++++++++++++++ docs/IPAdapterFaceID.md | 66 +++++++++++++ docs/IPAdapterInsightFaceLoader.md | 38 ++++++++ docs/IPAdapterLoadEmbeds.md | 41 ++++++++ docs/IPAdapterMS.md | 70 ++++++++++++++ docs/IPAdapterModelLoader.md | 39 ++++++++ docs/IPAdapterNoise.md | 79 +++++++++++++++ docs/IPAdapterSaveEmbeds.md | 51 ++++++++++ docs/IPAdapterStyleComposition.md | 66 +++++++++++++ docs/IPAdapterStyleCompositionBatch.md | 72 ++++++++++++++ docs/IPAdapterTiled.md | 122 ++++++++++++++++++++++++ docs/IPAdapterTiledBatch.md | 80 ++++++++++++++++ docs/IPAdapterUnifiedLoader.md | 115 ++++++++++++++++++++++ docs/IPAdapterUnifiedLoaderCommunity.md | 38 ++++++++ docs/IPAdapterUnifiedLoaderFaceID.md | 50 ++++++++++ docs/IPAdapterWeights.md | 88 +++++++++++++++++ docs/LLMCLIPTextEncode.md | 64 +++++++++++++ docs/LLMNode.md | 58 +++++++++++ docs/PrepImageForClipVision.md | 88 +++++++++++++++++ 25 files changed, 1727 insertions(+) create mode 100644 docs/IPAAdapterFaceIDBatch.md create mode 100644 docs/IPAdapter.md create mode 100644 docs/IPAdapterAdvanced.md create mode 100644 docs/IPAdapterBatch.md create mode 100644 docs/IPAdapterCombineEmbeds.md create mode 100644 docs/IPAdapterEmbeds.md create mode 100644 docs/IPAdapterEncoder.md create mode 100644 docs/IPAdapterFaceID.md create mode 100644 docs/IPAdapterInsightFaceLoader.md create mode 100644 docs/IPAdapterLoadEmbeds.md create mode 100644 docs/IPAdapterMS.md create mode 100644 docs/IPAdapterModelLoader.md create mode 100644 docs/IPAdapterNoise.md create mode 100644 docs/IPAdapterSaveEmbeds.md create mode 100644 docs/IPAdapterStyleComposition.md create mode 100644 docs/IPAdapterStyleCompositionBatch.md create mode 100644 docs/IPAdapterTiled.md create mode 100644 docs/IPAdapterTiledBatch.md create mode 100644 docs/IPAdapterUnifiedLoader.md create mode 100644 docs/IPAdapterUnifiedLoaderCommunity.md create mode 100644 docs/IPAdapterUnifiedLoaderFaceID.md create mode 100644 docs/IPAdapterWeights.md create mode 100644 docs/LLMCLIPTextEncode.md create mode 100644 docs/LLMNode.md create mode 100644 docs/PrepImageForClipVision.md diff --git a/docs/IPAAdapterFaceIDBatch.md b/docs/IPAAdapterFaceIDBatch.md new file mode 100644 index 0000000..938997d --- /dev/null +++ b/docs/IPAAdapterFaceIDBatch.md @@ -0,0 +1,31 @@ +# Documentation +- Class name: IPAAdapterFaceIDBatch +- Category: Adapter +- Output node: False +- Repo Ref: https://github.com/cubiq/ComfyUI_IPAdapter_plus.git + +IPAAdapterFaceIDBatch节点作为输入数据和FaceID模型之间的中介,确保高效处理批量数据。它旨在简化将FaceID模型应用于数据批量的过程,提高系统的整体性能和吞吐量。 + +# Input types +## Required +- input_data + - input_data参数至关重要,因为它代表了节点将处理的图像批次。它的组织和质量直接影响节点正确应用FaceID模型并产生准确结果的能力。 + - Comfy dtype: torch.Tensor + - Python dtype: torch.Tensor + +# Output types +- output_data + - output_data代表将FaceID模型应用于输入批次后的处理结果。它包含了模型的预测或识别,这对于进一步分析或下游任务非常重要。 + - Comfy dtype: torch.Tensor + - Python dtype: torch.Tensor + +# Usage tips +- Infra type: CPU + +# Source code +``` +class IPAAdapterFaceIDBatch(IPAdapterFaceID): + + def __init__(self): + self.unfold_batch = True +``` \ No newline at end of file diff --git a/docs/IPAdapter.md b/docs/IPAdapter.md new file mode 100644 index 0000000..c7d2821 --- /dev/null +++ b/docs/IPAdapter.md @@ -0,0 +1,78 @@ +# Documentation +- Class name: IPAdapterSimple +- Category: ipadapter +- Output node: False +- Repo Ref: https://github.com/cubiq/ComfyUI_IPAdapter_plus.git + +IPAdapterSimple节点旨在将图像处理适配器无缝集成到模型的工作流程中。它根据提供的图像和适配器配置对模型应用各种转换和加权,增强了模型根据特定风格或提示生成或处理图像的能力。 + +# Input types +## Required +- model + - 模型参数是必不可少的,因为它代表了将由IPAdapterSimple节点适应或修改的核心结构。这是决定节点后续处理和输出的主要输入。 + - Comfy dtype: MODEL + - Python dtype: torch.nn.Module +- ipadapter + - ipadapter参数指定了将指导节点内图像处理的适配器配置。它是一个关键组件,使节点能够应用特定的风格或转换。 + - Comfy dtype: IPADAPTER + - Python dtype: Dict[str, Any] +- image + - 图像参数是IPAdapterSimple节点的关键输入,因为它是将根据适配器设置进行处理和转换的视觉数据。它直接影响节点的最终输出。 + - Comfy dtype: IMAGE + - Python dtype: torch.Tensor +- weight + - 权重参数调整图像对模型输出的影响。它是一个浮点值,根据其大小可以显著改变节点的处理。 + - Comfy dtype: FLOAT + - Python dtype: float +- start_at + - start_at参数定义了图像对模型影响的起始点。它是一个浮点值,有助于控制转换的初始强度。 + - Comfy dtype: FLOAT + - Python dtype: float +- end_at + - end_at参数标记了图像对模型影响的终点。它与start_at参数一起工作,以确定转换效果的范围。 + - Comfy dtype: FLOAT + - Python dtype: float +- weight_type + - weight_type参数指示权重参数如何影响模型。它可以指定诸如'standard'、'prompt is more important'或'style transfer'等风格,每种风格对节点的功能都有不同的影响。 + - Comfy dtype: COMBO[standard, prompt is more important, style transfer] + - Python dtype: str +## Optional +- attn_mask + - 可选的attn_mask参数用于指定在处理期间模型应关注输入的哪些部分。它对于将模型的注意力集中在图像的某些区域特别有用。 + - Comfy dtype: MASK + - Python dtype: torch.Tensor + +# Output types +- model + - 输出模型代表了应用IPAdapterSimple节点转换后的输入模型的适应或修改版本。它封装了节点赋予的新图像处理能力。 + - Comfy dtype: MODEL + - Python dtype: torch.nn.Module + +# Usage tips +- Infra type: GPU + +# Source code +``` +class IPAdapterSimple: + + @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}), '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}), 'weight_type': (['standard', 'prompt is more important', 'style transfer'],)}, 'optional': {'attn_mask': ('MASK',)}} + RETURN_TYPES = ('MODEL',) + FUNCTION = 'apply_ipadapter' + CATEGORY = 'ipadapter' + + def apply_ipadapter(self, model, ipadapter, image, weight, start_at, end_at, weight_type, attn_mask=None): + if weight_type.startswith('style'): + weight_type = 'style transfer' + elif weight_type == 'prompt is more important': + weight_type = 'ease out' + else: + weight_type = 'linear' + ipa_args = {'image': image, 'weight': weight, 'start_at': start_at, 'end_at': end_at, 'attn_mask': attn_mask, 'weight_type': weight_type, 'insightface': ipadapter['insightface']['model'] if 'insightface' in ipadapter else None} + 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.') + return (ipadapter_execute(model.clone(), ipadapter['ipadapter']['model'], ipadapter['clipvision']['model'], **ipa_args),) +``` \ No newline at end of file diff --git a/docs/IPAdapterAdvanced.md b/docs/IPAdapterAdvanced.md new file mode 100644 index 0000000..abff1a4 --- /dev/null +++ b/docs/IPAdapterAdvanced.md @@ -0,0 +1,73 @@ +# Documentation +- Class name: IPAdapterAdvanced +- Category: ipadapter +- Output node: False +- Repo Ref: https://github.com/cubiq/ComfyUI_IPAdapter_plus.git + +IPAdapterAdvanced节点旨在使用IPAdapter模型应用高级图像处理技术。它智能地结合不同的嵌入和权重,以增强模型在风格和组合转移等任务中的性能。该节点在使模型适应特定图像处理要求中发挥关键作用,确保输出满足所需的美学和技术标准。 + +# Input types +## Required +- model + - 模型参数对于IPAdapterAdvanced节点至关重要,因为它定义了将应用图像处理技术的基线模型。它直接影响节点的执行和处理后图像的质量。 + - Comfy dtype: MODEL + - Python dtype: torch.nn.Module +- ipadapter + - ipadapter参数是节点功能的关键组成部分,为图像处理任务提供必要的适配和配置。它决定了模型如何与输入图像互动以实现期望的结果。 + - Comfy dtype: IPADAPTER + - Python dtype: Dict[str, Any] +- image + - 图像参数至关重要,因为它代表了节点将处理的输入图像。图像的质量和特性显著影响节点的操作和最终输出。 + - Comfy dtype: IMAGE + - Python dtype: torch.Tensor +## Optional +- weight + - 权重参数允许用户调整图像处理对模型的影响。这对于微调节点的性能很重要,以便在原始图像和处理后的图像之间实现所需的平衡。 + - Comfy dtype: FLOAT + - Python dtype: float + +# Output types +- model + - IPAdapterAdvanced节点的输出模型是融合了高级图像处理技术的加工模型。它很重要,因为它代表了所有转换应用后模型的最终状态。 + - Comfy dtype: MODEL + - Python dtype: torch.nn.Module + +# Usage tips +- Infra type: GPU + +# Source code +``` +class IPAdapterAdvanced: + + def __init__(self): + self.unfold_batch = False + + @classmethod + def INPUT_TYPES(s): + return {'required': {'model': ('MODEL',), 'ipadapter': ('IPADAPTER',), 'image': ('IMAGE',), 'weight': ('FLOAT', {'default': 1.0, 'min': -1, 'max': 5, '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}), 'embeds_scaling': (['V only', 'K+V', 'K+V w/ C penalty', 'K+mean(V) w/ C penalty'],)}, 'optional': {'image_negative': ('IMAGE',), 'attn_mask': ('MASK',), 'clip_vision': ('CLIP_VISION',)}} + RETURN_TYPES = ('MODEL',) + FUNCTION = 'apply_ipadapter' + CATEGORY = 'ipadapter' + + def apply_ipadapter(self, model, ipadapter, start_at, end_at, weight=1.0, weight_style=1.0, weight_composition=1.0, expand_style=False, weight_type='linear', combine_embeds='concat', weight_faceidv2=None, image=None, image_style=None, image_composition=None, image_negative=None, clip_vision=None, attn_mask=None, insightface=None, embeds_scaling='V only', layer_weights=None): + is_sdxl = isinstance(model.model, (comfy.model_base.SDXL, comfy.model_base.SDXLRefiner, comfy.model_base.SDXL_instructpix2pix)) + if image_style is not None: + if not is_sdxl: + raise Exception('Style + Composition transfer is only available for SDXL models at the moment.') + image = image_style + weight = weight_style + if image_composition is None: + image_composition = image_style + weight_type = 'strong style and composition' if expand_style else 'style and composition' + ipa_args = {'image': image, 'image_composition': image_composition, 'image_negative': image_negative, 'weight': weight, 'weight_composition': weight_composition, '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, 'embeds_scaling': embeds_scaling, 'insightface': insightface if insightface is not None else ipadapter['insightface']['model'] if 'insightface' in ipadapter else None, 'layer_weights': layer_weights} + 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),) +``` \ No newline at end of file diff --git a/docs/IPAdapterBatch.md b/docs/IPAdapterBatch.md new file mode 100644 index 0000000..5b515ee --- /dev/null +++ b/docs/IPAdapterBatch.md @@ -0,0 +1,72 @@ +# Documentation +- Class name: IPAdapterBatch +- Category: Image Processing +- Output node: False +- Repo Ref: https://github.com/cubiq/ComfyUI_IPAdapter_plus.git + +IPAdapterBatch节点旨在以批量方式高效处理图像数据,利用底层IPAdapterAdvanced类的处理能力。它专注于将图像适配以与其他模型或处理管道集成,确保图像数据格式正确且权重适当,以实现最佳性能。 + +# Input types +## Required +- model + - 模型参数对于节点的操作至关重要,因为它定义了将用于处理图像数据的机器学习模型。它直接影响节点的执行和产生的结果质量。 + - Comfy dtype: MODEL + - Python dtype: torch.nn.Module +- ipadapter + - ipadapter参数是必不可少的,因为它指定了将用于将图像数据与模型集成的适配器。它在图像数据处理方式及其后续结果中扮演着重要角色。 + - Comfy dtype: IPADAPTER + - Python dtype: Any +- image + - 图像输入对节点的功能至关重要,提供了将由模型处理和转换的原始数据。它是节点操作的主要信息源。 + - Comfy dtype: IMAGE + - Python dtype: torch.Tensor +- weight + - 权重参数允许调整图像数据对模型输出的影响。在为特定应用微调节点行为时尤其重要。 + - Comfy dtype: FLOAT + - Python dtype: float +- weight_type + - weight_type参数决定了权重将如何应用于图像数据,这对于控制处理过程中对数据不同方面的强调至关重要。 + - Comfy dtype: WEIGHT_TYPES + - Python dtype: str +- start_at + - start_at参数定义了处理图像数据的起始点,这对于专注于图像中的特定区域或特征非常有用。 + - Comfy dtype: FLOAT + - Python dtype: float +- end_at + - end_at参数标记了图像数据处理的终点,允许选择要考虑的图像数据的子集。 + - Comfy dtype: FLOAT + - Python dtype: float +- embeds_scaling + - embeds_scaling参数非常重要,因为它决定了嵌入的缩放方法,影响图像特征在模型中的表示和使用方式。 + - Comfy dtype: COMBO['V only', 'K+V', 'K+V w/ C penalty', 'K+mean(V) w/ C penalty'] + - Python dtype: str +## Optional +- image_negative + - 可选的image_negative参数提供了一个用于比较或对比的额外图像,增强了节点区分类似图像的能力。 + - Comfy dtype: IMAGE + - Python dtype: torch.Tensor +- attn_mask + - 当提供attn_mask参数时,可以用来指定模型在处理期间应该关注或忽略图像数据的哪些部分。 + - Comfy dtype: MASK + - Python dtype: torch.Tensor +- clip_vision + - clip_vision参数用于集成CLIP视觉模型以增强图像特征提取,这可以在某些应用中提高节点的性能。 + - Comfy dtype: CLIP_VISION + - Python dtype: Any + +# Output types + +# Usage tips +- Infra type: CPU + +# Source code +``` +class IPAdapterBatch(IPAdapterAdvanced): + + 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': 5, '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}), 'embeds_scaling': (['V only', 'K+V', 'K+V w/ C penalty', 'K+mean(V) w/ C penalty'],)}, 'optional': {'image_negative': ('IMAGE',), 'attn_mask': ('MASK',), 'clip_vision': ('CLIP_VISION',)}} +``` \ No newline at end of file diff --git a/docs/IPAdapterCombineEmbeds.md b/docs/IPAdapterCombineEmbeds.md new file mode 100644 index 0000000..66e3fa2 --- /dev/null +++ b/docs/IPAdapterCombineEmbeds.md @@ -0,0 +1,77 @@ +# Documentation +- Class name: IPAdapterCombineEmbeds +- Category: ipadapter/embeds +- Output node: False +- Repo Ref: https://github.com/cubiq/ComfyUI_IPAdapter_plus.git + +IPAdapterCombineEmbeds节点旨在通过多种指定方法智能地组合多个嵌入输入,例如连接、加法、减法、平均、归一化平均、最大值或最小值操作。它在机器学习模型中处理和整合不同嵌入数据到统一格式中发挥关键作用,增强了嵌入操作的灵活性和适应性。 + +# Input types +## Required +- embed1 + - embed1是节点操作必需的主要嵌入输入。它为后续组合方法提供了基础,对节点的执行和最终输出至关重要。 + - Comfy dtype: EMBEDS + - Python dtype: torch.Tensor +- method + - method参数决定了嵌入是如何组合的。它至关重要,因为它决定应用于嵌入输入的数学运算,显著影响节点的功能和输出的性质。 + - Comfy dtype: ['concat', 'add', 'subtract', 'average', 'norm average', 'max', 'min'] + - Python dtype: str +## Optional +- embed2 + - embed2是可选的额外嵌入输入,可以被包括以进行更复杂的嵌入组合。它的包含丰富了节点处理的嵌入数据的多样性。 + - Comfy dtype: EMBEDS + - Python dtype: torch.Tensor +- embed3 + - embed3是另一个可选的嵌入输入,可用于进一步多样化嵌入组合过程。它为节点的操作提供了额外的复杂性层。 + - Comfy dtype: EMBEDS + - Python dtype: torch.Tensor +- embed4 + - embed4作为可选的嵌入输入,可以用来扩展嵌入组合的范围。它为节点处理嵌入数据的能力增加了深度。 + - Comfy dtype: EMBEDS + - Python dtype: torch.Tensor +- embed5 + - embed5是提供给节点用于嵌入组合的最后一个可选嵌入输入。它代表了可以引入到节点嵌入处理中的最高复杂性水平。 + - Comfy dtype: EMBEDS + - Python dtype: torch.Tensor + +# Output types +- combined_embeds + - combined_embeds输出代表了将指定方法应用于输入嵌入的结果。它包含了节点目的的精髓,提供了输入数据的合成形式,可以用于进一步的分析或模型训练。 + - Comfy dtype: EMBEDS + - Python dtype: torch.Tensor + +# Usage tips +- Infra type: GPU + +# Source code +``` +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/embeds' + + 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,) +``` \ No newline at end of file diff --git a/docs/IPAdapterEmbeds.md b/docs/IPAdapterEmbeds.md new file mode 100644 index 0000000..04d1fb3 --- /dev/null +++ b/docs/IPAdapterEmbeds.md @@ -0,0 +1,89 @@ +# Documentation +- Class name: IPAdapterEmbeds +- Category: ipadapter/embeds +- Output node: False +- Repo Ref: https://github.com/cubiq/ComfyUI_IPAdapter_plus.git + +IPAdapterEmbeds节点旨在将IPAdapter修改集成并应用于给定模型。它通过利用IPAdapter的能力,定制模型的嵌入空间,允许对模型行为进行微调,以适应特定的输入特征。该节点抽象了嵌入操作的复杂性,为模型增强提供了一个简化的接口。 + +# Input types +## Required +- model + - 模型参数是必需的,因为它代表了将由IPAdapter进行适配的基础模型。它是主要的输入参数,决定了结果适配模型的结构和行为。 + - Comfy dtype: MODEL + - Python dtype: torch.nn.Module +- ipadapter + - ipadapter参数指定了将用于修改模型的适配器。它是一个关键组件,可以定制模型的嵌入能力。 + - Comfy dtype: IPADAPTER + - Python dtype: Dict[str, Any] +- pos_embed + - pos_embed参数提供了用于指导适配过程的正向嵌入输入。它在塑造适配模型对特定特征的响应中起着重要作用。 + - Comfy dtype: EMBEDS + - Python dtype: torch.Tensor +- weight + - 权重参数决定了IPAdapter修改对模型的影响。它是控制适配程度的关键因素。 + - Comfy dtype: FLOAT + - Python dtype: float +- weight_type + - weight_type参数定义了权重在模型的不同层中应用的方式。它对于将适配的重点指向模型的特定区域很重要。 + - Comfy dtype: WEIGHT_TYPES + - Python dtype: str +- start_at + - start_at参数建立了适配过程的起始点。它对于定义模型开始适配的初始条件至关重要。 + - Comfy dtype: FLOAT + - Python dtype: float +- end_at + - end_at参数标记了适配过程的终点。它对于指定适配结束时的条件是必不可少的。 + - Comfy dtype: FLOAT + - Python dtype: float +- embeds_scaling + - embeds_scaling参数决定了嵌入在模型内的缩放或组合方式。这是一个关键设置,可以显著影响适配模型的性能。 + - Comfy dtype: COMBO['V only', 'K+V', 'K+V w/ C penalty', 'K+mean(V) w/ C penalty'] + - Python dtype: str +## Optional +- neg_embed + - neg_embed参数提供了负向嵌入输入,可以在适配期间用于平衡正向嵌入。它有助于细化模型对所需特征的关注。 + - Comfy dtype: EMBEDS + - Python dtype: torch.Tensor +- attn_mask + - attn_mask参数用于在适配期间对注意力机制应用掩码,这对于控制模型内部信息流很重要。 + - Comfy dtype: MASK + - Python dtype: torch.Tensor +- clip_vision + - clip_vision参数指定了CLIP Vision模型,该模型可以与IPAdapter结合使用,以增强特征提取。 + - Comfy dtype: CLIP_VISION + - Python dtype: torch.nn.Module + +# Output types +- model + - 输出模型是输入模型的适配版本,根据IPAdapterEmbeds节点提供的规格进行修改。它代表了适配过程的成果。 + - Comfy dtype: MODEL + - Python dtype: torch.nn.Module + +# Usage tips +- Infra type: GPU + +# Source code +``` +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}), 'embeds_scaling': (['V only', 'K+V', 'K+V w/ C penalty', 'K+mean(V) w/ C penalty'],)}, 'optional': {'neg_embed': ('EMBEDS',), 'attn_mask': ('MASK',), 'clip_vision': ('CLIP_VISION',)}} + RETURN_TYPES = ('MODEL',) + FUNCTION = 'apply_ipadapter' + CATEGORY = 'ipadapter/embeds' + + def apply_ipadapter(self, model, ipadapter, pos_embed, weight, weight_type, start_at, end_at, neg_embed=None, attn_mask=None, clip_vision=None, embeds_scaling='V only'): + 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, 'embeds_scaling': embeds_scaling} + 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),) +``` \ No newline at end of file diff --git a/docs/IPAdapterEncoder.md b/docs/IPAdapterEncoder.md new file mode 100644 index 0000000..dc83b5c --- /dev/null +++ b/docs/IPAdapterEncoder.md @@ -0,0 +1,82 @@ +# Documentation +- Class name: IPAdapterEncoder +- Category: ipadapter/embeds +- Output node: False +- Repo Ref: https://github.com/cubiq/ComfyUI_IPAdapter_plus.git + +IPAdapterEncoder节点旨在使用预训练的CLIPVision模型处理和编码图像数据。它利用CLIPVision架构的力量生成捕获图像中语义信息的嵌入。该节点能够根据掩码的存在和权重参数处理条件和非条件嵌入,允许微调图像内容对生成的嵌入的影响。 + +# Input types +## Required +- ipadapter + - ipadapter参数对于节点的操作至关重要,因为它提供了用于编码图像数据的模型。预期它是一个包含编码过程所需模型信息的字典。此参数的存在确保节点可以访问所需的模型以生成嵌入。 + - Comfy dtype: IPADAPTER + - Python dtype: Dict[str, Any] +- image + - image参数是必需的,因为它表示节点将处理的输入数据。预期它是一个图像张量,节点将将其编码为嵌入。图像数据的质量和格式直接影响节点生成有意义的嵌入的能力。 + - Comfy dtype: IMAGE + - Python dtype: torch.Tensor +- weight + - 权重参数允许调整图像内容对生成的嵌入的影响。它是一个浮点数,当不等于1时,可以缩放嵌入以强调或淡化图像数据的某些方面。 + - Comfy dtype: FLOAT + - Python dtype: float +## Optional +- mask + - 可选的掩码参数可以在编码之前用于对图像数据应用空间掩码。这对于集中节点的注意力在图像的特定区域或从编码过程中排除图像的不相关部分可能很有用。 + - Comfy dtype: MASK + - Python dtype: torch.Tensor +- clip_vision + - clip_vision参数是一个可选模型,可以提供给节点用于编码图像数据。如果没有提供,节点将使用ipadapter参数中指定的模型。这允许在不同的编码任务中使用不同的CLIPVision模型。 + - Comfy dtype: CLIP_VISION + - Python dtype: Any + +# Output types +- pos_embed + - pos_embed输出代表节点生成的条件嵌入。这些嵌入受到图像数据和应用的任何掩码的影响,捕获图像中的语义信息。 + - Comfy dtype: EMBEDS + - Python dtype: torch.Tensor +- neg_embed + - neg_embed输出提供非条件嵌入,这些嵌入是在不考虑图像内容的情况下生成的。这些嵌入可以作为基线或与条件嵌入进行比较的参考点。 + - Comfy dtype: EMBEDS + - Python dtype: torch.Tensor + +# Usage tips +- Infra type: GPU + +# Source code +``` +class IPAdapterEncoder: + + @classmethod + def INPUT_TYPES(s): + return {'required': {'ipadapter': ('IPADAPTER',), 'image': ('IMAGE',), '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/embeds' + + 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'] + 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) + 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) +``` \ No newline at end of file diff --git a/docs/IPAdapterFaceID.md b/docs/IPAdapterFaceID.md new file mode 100644 index 0000000..27bc095 --- /dev/null +++ b/docs/IPAdapterFaceID.md @@ -0,0 +1,66 @@ +# Documentation +- Class name: IPAdapterFaceID +- Category: ipadapter/faceid +- Output node: False +- Repo Ref: https://github.com/cubiq/ComfyUI_IPAdapter_plus.git + +IPAdapterFaceID节点旨在成像流程中集成和处理面部识别数据。它利用高级模型提高面部识别任务的准确性,确保系统能够从图像中可靠地识别个人。 + +# Input types +## Required +- model + - 模型参数对于节点的操作至关重要,因为它定义了用于面部识别的机器学习模型。它是面部识别过程的主干,使节点能够分析和处理面部特征。 + - Comfy dtype: MODEL + - Python dtype: torch.nn.Module +- ipadapter + - ipadapter参数是必需的,因为它为节点提供了与系统中其他组件通信的必要接口,促进了面部识别数据的交换。 + - Comfy dtype: IPADAPTER + - Python dtype: str +- image + - 图像输入对节点的功能至关重要,提供了面部识别模型分析的视觉数据。它是节点处理以提取面部特征进行识别的原始材料。 + - Comfy dtype: IMAGE + - Python dtype: torch.Tensor +## Optional +- weight + - 权重参数允许调整面部识别结果对总体结果的影响。它是一个调整因子,可以修改以在准确性和性能之间实现平衡。 + - Comfy dtype: FLOAT + - Python dtype: float +- weight_faceidv2 + - weight_faceidv2参数用于微调FaceID版本2模型在面部识别过程中的贡献。它允许定制模型对最终识别结果的影响。 + - Comfy dtype: FLOAT + - Python dtype: float +- combine_embeds + - combine_embeds参数决定了面部识别过程中不同嵌入如何组合。它是融合面部特征数据以增强识别能力的关键因素。 + - Comfy dtype: COMBO[concat, add, subtract, average, norm average] + - Python dtype: str +- start_at + - start_at参数指定面部特征提取过程的起始点。它用于控制用于面部识别的图像片段。 + - Comfy dtype: FLOAT + - Python dtype: float +- end_at + - end_at参数标记面部特征提取过程的终点。它与start_at一起,定义了用于分析的图像范围。 + - Comfy dtype: FLOAT + - Python dtype: float +- embeds_scaling + - embeds_scaling参数负责缩放面部识别中使用的嵌入。它调整特征向量的大小以优化识别过程。 + - Comfy dtype: COMBO[V only, K+V, K+V w/ C penalty, K+mean(V) w/ C penalty] + - Python dtype: str + +# Output types +- face_id_output + - face_id_output在通过模型处理输入图像后提供最终的面部识别结果。它是节点分析的结晶,代表了识别任务的结果。 + - Comfy dtype: OUTPUT + - Python dtype: torch.Tensor + +# Usage tips +- Infra type: GPU + +# Source code +``` +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}), 'embeds_scaling': (['V only', 'K+V', 'K+V w/ C penalty', 'K+mean(V) w/ C penalty'],)}, 'optional': {'image_negative': ('IMAGE',), 'attn_mask': ('MASK',), 'clip_vision': ('CLIP_VISION',), 'insightface': ('INSIGHTFACE',)}} + CATEGORY = 'ipadapter/faceid' +``` \ No newline at end of file diff --git a/docs/IPAdapterInsightFaceLoader.md b/docs/IPAdapterInsightFaceLoader.md new file mode 100644 index 0000000..cb9a3da --- /dev/null +++ b/docs/IPAdapterInsightFaceLoader.md @@ -0,0 +1,38 @@ +# Documentation +- Class name: IPAdapterInsightFaceLoader +- Category: ipadapter/loaders +- Output node: False +- Repo Ref: https://github.com/cubiq/ComfyUI_IPAdapter_plus.git + +IPAdapterInsightFaceLoader节点旨在方便加载和准备用于面部分析任务的InsightFace模型。它封装了使用指定的执行提供程序初始化模型的复杂性,抽象了底层技术细节。该节点确保InsightFace模型准备好进行高级操作,如面部检测和识别。 + +# Input types +## Required +- provider + - ‘provider’参数指定了InsightFace模型的执行提供程序。这对于确定模型的执行方式至关重要,这可能显著影响性能以及与不同硬件设置的兼容性。 + - Comfy dtype: str + - Python dtype: str + +# Output types +- model + - ‘model’输出代表已加载并准备好的InsightFace模型,可用于面部分析操作。它是节点功能的最终成果,为用户提供了与模型交互的高级接口。 + - Comfy dtype: FaceAnalysis + - Python dtype: insightface.app.FaceAnalysis + +# Usage tips +- Infra type: CPU + +# Source code +``` +class IPAdapterInsightFaceLoader: + + @classmethod + def INPUT_TYPES(s): + return {'required': {'provider': (['CPU', 'CUDA', 'ROCM'],)}} + RETURN_TYPES = ('INSIGHTFACE',) + FUNCTION = 'load_insightface' + CATEGORY = 'ipadapter/loaders' + + def load_insightface(self, provider): + return (insightface_loader(provider),) +``` \ No newline at end of file diff --git a/docs/IPAdapterLoadEmbeds.md b/docs/IPAdapterLoadEmbeds.md new file mode 100644 index 0000000..054dbfb --- /dev/null +++ b/docs/IPAdapterLoadEmbeds.md @@ -0,0 +1,41 @@ +# Documentation +- Class name: IPAdapterLoadEmbeds +- Category: ipadapter/embeds +- Output node: False +- Repo Ref: https://github.com/cubiq/ComfyUI_IPAdapter_plus.git + +IPAdapterLoadEmbeds 节点的 `load` 方法旨在从指定文件中检索和处理嵌入数据。它是系统中处理嵌入数据的关键组件,确保嵌入数据被正确加载并为下游任务提供可用性。 + +# Input types +## Required +- embeds + - 参数 'embeds' 是一个包含嵌入数据存储文件路径的列表。这个参数至关重要,因为它指导节点定位数据的正确位置,使得节点能够成功加载和处理嵌入数据。 + - Comfy dtype: List[str] + - Python dtype: List[str] + +# Output types +- EMBEDS + - 输出参数 'EMBEDS' 表示加载的嵌入数据作为张量。这个张量非常重要,因为它是输入数据的加工形式,准备用于后续的分析或模型训练。 + - Comfy dtype: torch.Tensor + - Python dtype: torch.Tensor + +# Usage tips +- Infra type: CPU + +# Source code +``` +class IPAdapterLoadEmbeds: + + @classmethod + def INPUT_TYPES(s): + input_dir = folder_paths.get_input_directory() + files = [os.path.relpath(os.path.join(root, file), input_dir) for (root, dirs, files) in os.walk(input_dir) for file in files if file.endswith('.ipadpt')] + return {'required': {'embeds': [sorted(files)]}} + RETURN_TYPES = ('EMBEDS',) + FUNCTION = 'load' + CATEGORY = 'ipadapter/embeds' + + def load(self, embeds): + path = folder_paths.get_annotated_filepath(embeds) + return (torch.load(path).cpu(),) +``` \ No newline at end of file diff --git a/docs/IPAdapterMS.md b/docs/IPAdapterMS.md new file mode 100644 index 0000000..f8c7da7 --- /dev/null +++ b/docs/IPAdapterMS.md @@ -0,0 +1,70 @@ +# Documentation +- Class name: IPAdapterMS +- Category: ipadapter/dev +- Output node: False +- Repo Ref: https://github.com/cubiq/ComfyUI_IPAdapter_plus.git + +IPAdapterMS节点旨在将各种图像处理模型集成到一个统一的框架中。它通过一组可配置的参数促进图像数据的操作和增强,旨在优化集成模型的性能。 + +# Input types +## Required +- model + - 模型参数对节点的操作至关重要,因为它定义了要使用的核心图像处理模型。它直接影响节点处理和分析图像数据的能力。 + - Comfy dtype: MODEL + - Python dtype: torch.nn.Module +- ipadapter + - ipadapter参数对节点至关重要,因为它指定了将用于与模型接口的适配器。它在节点与模型的交互以及增强模型功能方面扮演着重要角色。 + - Comfy dtype: IPADAPTER + - Python dtype: str +- image + - 图像参数是节点功能的基础,它为图像处理提供输入数据。它是节点将操作和分析的视觉内容的主要来源。 + - Comfy dtype: IMAGE + - Python dtype: torch.Tensor +- weight + - 权重参数允许调整图像处理的某些方面对最终输出的影响。它是微调节点操作以实现期望结果的关键因素。 + - Comfy dtype: FLOAT + - Python dtype: float +## Optional +- weight_faceidv2 + - weight_faceidv2参数用于调节图像处理中面部特征识别的强调程度。在处理面部识别任务时,它是一个可选但重要的因素。 + - Comfy dtype: FLOAT + - Python dtype: float +- combine_embeds + - combine_embeds参数决定了节点内不同嵌入的组合方法。这是一个关键的决策点,影响节点输出的整合和一致性。 + - Comfy dtype: COMBO[concat, add, subtract, average, norm average] + - Python dtype: str +- start_at + - start_at参数定义了图像处理操作的起始点。它用于指定节点开始分析和操作图像数据的初始阶段。 + - Comfy dtype: FLOAT + - Python dtype: float +- end_at + - end_at参数设置了图像处理操作的终点。它决定了节点分析和操作图像数据的最终阶段。 + - Comfy dtype: FLOAT + - Python dtype: float +- embeds_scaling + - embeds_scaling参数用于缩放节点内的嵌入。它是控制嵌入对节点输出大小和影响的重要因素。 + - Comfy dtype: COMBO[V only, K+V, K+V w/ C penalty, K+mean(V) w/ C penalty] + - Python dtype: str +- layer_weights + - layer_weights参数允许为模型内的不同层指定权重。它是一个可选但强大的工具,用于根据特定需求定制节点的行为。 + - Comfy dtype: STRING + - Python dtype: str + +# Output types +- processed_image + - processed_image输出代表了节点执行的图像处理的结果。它包含了节点的操作和分析,提供了所有操作完成后的最终视觉内容。 + - Comfy dtype: IMAGE + - Python dtype: torch.Tensor + +# Usage tips +- Infra type: GPU + +# Source code +``` +class IPAdapterMS(IPAdapterAdvanced): + + @classmethod + def INPUT_TYPES(s): + return {'required': {'model': ('MODEL',), 'ipadapter': ('IPADAPTER',), 'image': ('IMAGE',), 'weight': ('FLOAT', {'default': 1.0, 'min': -1, 'max': 5, '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}), 'embeds_scaling': (['V only', 'K+V', 'K+V w/ C penalty', 'K+mean(V) w/ C penalty'],), 'layer_weights': ('STRING', {'default': '', 'multiline': True})}, 'optional': {'image_negative': ('IMAGE',), 'attn_mask': ('MASK',), 'clip_vision': ('CLIP_VISION',), 'insightface': ('INSIGHTFACE',)}} + CATEGORY = 'ipadapter/dev' +``` \ No newline at end of file diff --git a/docs/IPAdapterModelLoader.md b/docs/IPAdapterModelLoader.md new file mode 100644 index 0000000..96782a4 --- /dev/null +++ b/docs/IPAdapterModelLoader.md @@ -0,0 +1,39 @@ +# Documentation +- Class name: IPAdapterModelLoader +- Category: ipadapter/loaders +- Output node: False +- Repo Ref: https://github.com/cubiq/ComfyUI_IPAdapter_plus.git + +IPAdapterModelLoader旨在高效加载并集成IPAdapter模型到系统中,确保模型与框架的兼容性和无缝功能。 + +# Input types +## Required +- ipadapter_file + - ipadapter_file是一个关键参数,用于指定IPAdapter模型文件的路径。它对于节点正确加载和处理模型至关重要,影响系统的整体性能和准确性。 + - Comfy dtype: COMBO[string] + - Python dtype: str + +# Output types +- ipadapter + - 输出提供了已加载的IPAdapter模型的结构化表示,这对于系统内的后续处理和分析至关重要。 + - Comfy dtype: dict + - Python dtype: Dict[str, Any] + +# Usage tips +- Infra type: CPU + +# Source code +``` +class IPAdapterModelLoader: + + @classmethod + def INPUT_TYPES(s): + return {'required': {'ipadapter_file': (folder_paths.get_filename_list('ipadapter'),)}} + RETURN_TYPES = ('IPADAPTER',) + FUNCTION = 'load_ipadapter_model' + CATEGORY = 'ipadapter/loaders' + + def load_ipadapter_model(self, ipadapter_file): + ipadapter_file = folder_paths.get_full_path('ipadapter', ipadapter_file) + return (ipadapter_model_loader(ipadapter_file),) +``` \ No newline at end of file diff --git a/docs/IPAdapterNoise.md b/docs/IPAdapterNoise.md new file mode 100644 index 0000000..b23e28c --- /dev/null +++ b/docs/IPAdapterNoise.md @@ -0,0 +1,79 @@ +# Documentation +- Class name: IPAdapterNoise +- Category: ipadapter/utils +- Output node: False +- Repo Ref: https://github.com/cubiq/ComfyUI_IPAdapter_plus.git + +IPAdapterNoise节点旨在向图像中引入受控噪声,可用于数据增强或增强模型鲁棒性等多种目的。它提供了多种噪声类型的选择,并允许调整噪声强度,因此为不同用例提供了灵活的解决方案。 + +# Input types +## Required +- type + - “type”参数决定了要生成的噪声类型,这显著影响了噪声应用的结果。这是一个关键的决策点,因为不同的噪声类型有不同的功能,并以不同的方式影响图像。 + - Comfy dtype: COMBO[fade, dissolve, gaussian, shuffle] + - Python dtype: str +- strength + - “strength”参数调整噪声的强度,直接影响图像的改变程度。这是一个重要的参数,它允许用户调整噪声效果以满足他们的具体需求。 + - Comfy dtype: FLOAT + - Python dtype: float +## Optional +- blur + - “blur”参数对噪声应用高斯模糊,这可以帮助在某些应用中平滑噪声。它在噪声的最终视觉结果中发挥作用,提供了进一步细化噪声纹理的手段。 + - Comfy dtype: INT + - Python dtype: int +- image_optional + - “image_optional”参数允许提供一个可选的图像作为噪声生成的基础。这个参数很重要,因为它使得噪声可以应用于特定图像,而不是默认的空白图像,提供了更大的灵活性和定制化。 + - Comfy dtype: IMAGE + - Python dtype: torch.Tensor + +# Output types +- noise + - “noise”输出是IPAdapterNoise节点的主要结果,代表了引入噪声的图像。它是一个关键组件,因为它承载了应用的噪声效果,准备在后续过程或分析中使用。 + - Comfy dtype: IMAGE + - Python dtype: torch.Tensor + +# Usage tips +- Infra type: CPU + +# Source code +``` +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 = 'make_noise' + CATEGORY = 'ipadapter/utils' + + def make_noise(self, type, strength, blur, image_optional=None): + if image_optional is None: + image = torch.zeros([1, 224, 224, 3]) + else: + 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]) + seed = int(torch.sum(image).item()) % 1000000007 + 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,) +``` \ No newline at end of file diff --git a/docs/IPAdapterSaveEmbeds.md b/docs/IPAdapterSaveEmbeds.md new file mode 100644 index 0000000..aca2ba4 --- /dev/null +++ b/docs/IPAdapterSaveEmbeds.md @@ -0,0 +1,51 @@ +# Documentation +- Class name: IPAdapterSaveEmbeds +- Category: ipadapter/embeds +- Output node: True +- Repo Ref: https://github.com/cubiq/ComfyUI_IPAdapter_plus.git + +IPAdapterSaveEmbeds节点旨在存储由图像处理系统生成的嵌入。它的目的是将这些嵌入以结构化的方式持久化到磁盘上,便于检索和进一步分析。该节点在工作流程中扮演着关键角色,确保嵌入过程的输出不会丢失,从而促进后续任务,如模型训练或特征比较。 + +# Input types +## Required +- embeds + - ‘embeds’参数对于节点至关重要,因为它表示要保存的嵌入。它是节点操作的核心数据,其适当处理确保了嵌入过程的完整性。此参数直接影响节点的执行,它决定了要持久化的数据。 + - Comfy dtype: EMBEDS + - Python dtype: torch.Tensor +## Optional +- filename_prefix + - ‘filename_prefix’参数用于定义保存嵌入的文件名的起始部分。它对于组织和识别保存的文件很重要。此参数允许用户根据输入数据的上下文或类型对嵌入进行分类。 + - Comfy dtype: STRING + - Python dtype: str + +# Output types +- None + - 该节点不返回任何值,其主要功能是将嵌入保存到文件中。没有返回值表示保存操作的完成。 + - Comfy dtype: None + - Python dtype: NoneType + +# Usage tips +- Infra type: CPU + +# Source code +``` +class IPAdapterSaveEmbeds: + + def __init__(self): + self.output_dir = folder_paths.get_output_directory() + + @classmethod + def INPUT_TYPES(s): + return {'required': {'embeds': ('EMBEDS',), 'filename_prefix': ('STRING', {'default': 'IP_embeds'})}} + RETURN_TYPES = () + FUNCTION = 'save' + OUTPUT_NODE = True + CATEGORY = 'ipadapter/embeds' + + 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 = os.path.join(full_output_folder, file) + torch.save(embeds, file) + return (None,) +``` \ No newline at end of file diff --git a/docs/IPAdapterStyleComposition.md b/docs/IPAdapterStyleComposition.md new file mode 100644 index 0000000..b4ef558 --- /dev/null +++ b/docs/IPAdapterStyleComposition.md @@ -0,0 +1,66 @@ +# Documentation +- Class name: IPAdapterStyleComposition +- Category: ipadapter/style_composition +- Output node: False +- Repo Ref: https://github.com/cubiq/ComfyUI_IPAdapter_plus.git + +IPAdapterStyleComposition节点旨在无缝融合图像风格和构图,为创意图像处理提供了一个强大的框架。它巧妙地将风格元素与构图结构融合,增强了最终输出的视觉效果和连贯性。 + +# Input types +## Required +- model + - 模型参数对于节点的操作至关重要,因为它决定了用于风格和构图适应的底层架构。它是节点功能构建的基础,使得输入图像的转换成为可能。 + - Comfy dtype: MODEL + - Python dtype: torch.nn.Module +- ipadapter + - ipadapter参数对于节点至关重要,因为它提供了必要的适配器机制,以便与模型集成进行风格组合。它在节点处理和适应构图框架内的风格中起着关键作用。 + - Comfy dtype: IPADAPTER + - Python dtype: torch.Tensor +- image_style + - image_style参数对节点的目的至关重要,因为它代表了将要与其他元素艺术地组合的风格输入。它是节点旨在融入最终图像的主要视觉风格来源。 + - Comfy dtype: IMAGE + - Python dtype: PIL.Image or numpy.ndarray +- image_composition + - image_composition参数对于定义风格元素将被整合的结构布局至关重要。它为节点的构图过程设定了舞台,确保最终图像反映了风格和结构的和谐融合。 + - Comfy dtype: IMAGE + - Python dtype: PIL.Image or numpy.ndarray +## Optional +- weight_style + - weight_style参数允许对组合中的风格影响进行微调。它是控制风格和构图之间平衡的关键因素,确保最终输出与所需的审美相一致。 + - Comfy dtype: FLOAT + - Python dtype: float +- combine_embeds + - combine_embeds参数决定了用于整合风格特征的嵌入组合方法。它对于节点有效合并不同风格输入的能力至关重要,影响最终图像的风格一致性。 + - Comfy dtype: COMBO[concat, add, subtract, average, norm average] + - Python dtype: str +- start_at + - start_at参数定义了构图过程的起始点,允许控制风格整合的初始阶段。它是节点管理风格应用进程的重要因素。 + - Comfy dtype: FLOAT + - Python dtype: float +- end_at + - end_at参数指定了构图过程的终点,允许控制风格整合的最终阶段。它对于节点确定风格在构图中的影响范围至关重要。 + - Comfy dtype: FLOAT + - Python dtype: float +- embeds_scaling + - embeds_scaling参数调整了构图中使用的嵌入的缩放,这对于在整个过程中保持风格特征的完整性和质量至关重要。 + - Comfy dtype: COMBO[V only, K+V, K+V w/ C penalty, K+mean(V) w/ C penalty] + - Python dtype: str + +# Output types +- composed_image + - composed_image输出代表了风格组合过程的最终结果,其中风格元素已经和谐地融入到构图结构中。它是对节点产生视觉上令人愉悦和连贯图像能力的一个证明。 + - Comfy dtype: IMAGE + - Python dtype: PIL.Image or numpy.ndarray + +# Usage tips +- Infra type: GPU + +# Source code +``` +class IPAdapterStyleComposition(IPAdapterAdvanced): + + @classmethod + def INPUT_TYPES(s): + return {'required': {'model': ('MODEL',), 'ipadapter': ('IPADAPTER',), 'image_style': ('IMAGE',), 'image_composition': ('IMAGE',), 'weight_style': ('FLOAT', {'default': 1.0, 'min': -1, 'max': 5, 'step': 0.05}), 'weight_composition': ('FLOAT', {'default': 1.0, 'min': -1, 'max': 5, 'step': 0.05}), 'expand_style': ('BOOLEAN', {'default': False}), 'combine_embeds': (['concat', 'add', 'subtract', 'average', 'norm average'], {'default': '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}), 'embeds_scaling': (['V only', 'K+V', 'K+V w/ C penalty', 'K+mean(V) w/ C penalty'],)}, 'optional': {'image_negative': ('IMAGE',), 'attn_mask': ('MASK',), 'clip_vision': ('CLIP_VISION',)}} + CATEGORY = 'ipadapter/style_composition' +``` \ No newline at end of file diff --git a/docs/IPAdapterStyleCompositionBatch.md b/docs/IPAdapterStyleCompositionBatch.md new file mode 100644 index 0000000..ca29474 --- /dev/null +++ b/docs/IPAdapterStyleCompositionBatch.md @@ -0,0 +1,72 @@ +# Documentation +- Class name: IPAdapterStyleCompositionBatch +- Category: Style Composition +- Output node: False +- Repo Ref: https://github.com/cubiq/ComfyUI_IPAdapter_plus.git + +IPAdapterStyleCompositionBatch节点旨在以批量处理的方式促进图像风格和图像组合的组合。它集成了风格适应技术,以无缝融合不同的视觉元素,强调生成图像中风格一致性的重要性。 + +# Input types +## Required +- model + - 模型参数对节点的操作至关重要,因为它定义了用于风格组合的底层神经网络架构。它直接影响节点生成具有所需风格特征的图像的能力。 + - Comfy dtype: MODEL + - Python dtype: torch.nn.Module +- ipadapter + - ipadapter参数对于将输入图像适应模型的风格至关重要。它在确保输入图像与模型的风格期望保持一致以实现有效的风格组合中扮演着重要角色。 + - Comfy dtype: IPADAPTER + - Python dtype: torch.Tensor +- image_style + - image_style参数是提供组合过程风格参考的关键输入。它决定了输出图像应体现的视觉风格,影响整体的审美结果。 + - Comfy dtype: IMAGE + - Python dtype: torch.Tensor +- image_composition + - image_composition参数是节点操作的组合基础。它是将根据image_style提供的风格进行风格化和转换的图像,形成最终输出。 + - Comfy dtype: IMAGE + - Python dtype: torch.Tensor +## Optional +- weight_style + - weight_style参数允许微调风格输入对最终组合的影响。当需要在原始组合和应用的风格之间取得平衡时,它特别有用。 + - Comfy dtype: FLOAT + - Python dtype: float +- weight_composition + - weight_composition参数调整组合元素对最终输出的贡献。它对于实现生成图像的风格和组合方面的和谐融合很重要。 + - Comfy dtype: FLOAT + - Python dtype: float +- expand_style + - expand_style参数决定是否应扩展风格以适应组合。这对于确保风格均匀应用于整个图像可能很重要。 + - Comfy dtype: BOOLEAN + - Python dtype: bool +- start_at + - start_at参数指定组合过程的起始点。它用于控制风格应用的初始阶段,影响组合的进展。 + - Comfy dtype: FLOAT + - Python dtype: float +- end_at + - end_at参数标记组合过程的终点。它决定了风格应用的最后阶段,影响风格在整个组合中应用的范围。 + - Comfy dtype: FLOAT + - Python dtype: float +- embeds_scaling + - embeds_scaling参数用于选择风格组合中涉及的嵌入的缩放方法。它是确定组合图像质量和特性的关键因素。 + - Comfy dtype: COMBO['V only', 'K+V', 'K+V w/ C penalty', 'K+mean(V) w/ C penalty'] + - Python dtype: str + +# Output types +- composed_images + - composed_images输出代表了风格组合过程的最终结果。它包含了根据输入参数风格化和组合后的合成图像,展示了节点的能力。 + - Comfy dtype: IMAGE + - Python dtype: torch.Tensor + +# Usage tips +- Infra type: GPU + +# Source code +``` +class IPAdapterStyleCompositionBatch(IPAdapterStyleComposition): + + def __init__(self): + self.unfold_batch = True + + @classmethod + def INPUT_TYPES(s): + return {'required': {'model': ('MODEL',), 'ipadapter': ('IPADAPTER',), 'image_style': ('IMAGE',), 'image_composition': ('IMAGE',), 'weight_style': ('FLOAT', {'default': 1.0, 'min': -1, 'max': 5, 'step': 0.05}), 'weight_composition': ('FLOAT', {'default': 1.0, 'min': -1, 'max': 5, 'step': 0.05}), 'expand_style': ('BOOLEAN', {'default': False}), '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}), 'embeds_scaling': (['V only', 'K+V', 'K+V w/ C penalty', 'K+mean(V) w/ C penalty'],)}, 'optional': {'image_negative': ('IMAGE',), 'attn_mask': ('MASK',), 'clip_vision': ('CLIP_VISION',)}} +``` \ No newline at end of file diff --git a/docs/IPAdapterTiled.md b/docs/IPAdapterTiled.md new file mode 100644 index 0000000..c375d53 --- /dev/null +++ b/docs/IPAdapterTiled.md @@ -0,0 +1,122 @@ +# Documentation +- Class name: IPAdapterTiled +- Category: ipadapter/tiled +- Output node: False +- Repo Ref: https://github.com/cubiq/ComfyUI_IPAdapter_plus.git + +IPAdapterTiled节点旨在通过平铺机制处理图像,这对于处理可能不适合作为整体处理时放入内存的大型图像特别有用。它对图像平铺应用一系列变换和调整,利用IPAdapter和CLIPVision模型的能力生成嵌入,这些嵌入可以用于进一步的处理或模型训练。 + +# Input types +## Required +- model + - 模型参数是必需的,因为它代表了将用于处理图像数据的深度学习模型。它是节点功能的核心组件,决定了图像平铺最终如何被分析和转换。 + - Comfy dtype: MODEL + - Python dtype: torch.nn.Module +- ipadapter + - ipadapter参数指定了适配器模型,该模型将与主模型一起使用以适配图像特征。它在节点修改和增强图像数据以提高模型性能的能力中起着关键作用。 + - Comfy dtype: IPADAPTER + - Python dtype: Dict[str, Any] +- image + - 图像输入是节点的主要数据源。它是原始图像数据,将被分解成平铺并由节点处理。图像数据的质量和格式直接影响节点的输出和后续分析。 + - Comfy dtype: IMAGE + - Python dtype: torch.Tensor +## Optional +- weight + - 权重参数允许调整图像平铺对模型输出的影响。它可以微调每个平铺的贡献,以实现最终结果中所需的效果或平衡。 + - Comfy dtype: FLOAT + - Python dtype: float + +# Output types +- MODEL + - 输出模型代表了应用平铺和图像处理技术后的处理模型。它封装了已经应用于输入图像平铺的学到的特征和转换。 + - Comfy dtype: MODEL + - Python dtype: torch.nn.Module +- tiles + - 平铺输出包含处理后的图像平铺。每个平铺都经历了节点的转换过程,并且可以用于进一步使用或分析。 + - Comfy dtype: IMAGE + - Python dtype: torch.Tensor +- masks + - 掩码输出提供了在处理图像平铺期间使用的关注掩码。这些掩码对于聚焦图像的特定区域或从分析中排除某些区域可能有用。 + - Comfy dtype: MASK + - Python dtype: torch.Tensor + +# Usage tips +- Infra type: GPU + +# Source code +``` +class IPAdapterTiled: + + def __init__(self): + self.unfold_batch = False + + @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}), 'embeds_scaling': (['V only', 'K+V', 'K+V w/ C penalty', 'K+mean(V) w/ C penalty'],)}, 'optional': {'image_negative': ('IMAGE',), 'attn_mask': ('MASK',), 'clip_vision': ('CLIP_VISION',)}} + RETURN_TYPES = ('MODEL', 'IMAGE', 'MASK') + RETURN_NAMES = ('MODEL', 'tiles', 'masks') + FUNCTION = 'apply_tiled' + CATEGORY = 'ipadapter/tiled' + + 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, embeds_scaling='V only'): + 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 + tile_size = 256 + (_, oh, ow, _) = image.shape + if attn_mask is None: + attn_mask = torch.ones([1, oh, ow], dtype=image.dtype, device=image.device) + image = image.permute([0, 3, 1, 2]) + attn_mask = attn_mask.unsqueeze(1) + attn_mask = T.Resize((oh, ow), interpolation=T.InterpolationMode.BICUBIC, antialias=True)(attn_mask) + if oh / ow > 0.75 and oh / ow < 1.33: + image = T.CenterCrop(min(oh, ow))(image) + resize = (tile_size * 2, tile_size * 2) + attn_mask = T.CenterCrop(min(oh, ow))(attn_mask) + 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) + img = img.resize(resize, resample=Image.Resampling['LANCZOS']) + imgs.append(T.ToTensor()(img)) + image = torch.stack(imgs) + del imgs, img + attn_mask = T.Resize(resize[::-1], interpolation=T.InterpolationMode.BICUBIC, antialias=True)(attn_mask) + 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) + attn_mask = T.CenterCrop(crop)(attn_mask) + 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 + 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 = torch.zeros([attn_mask.shape[0], oh, ow], dtype=image.dtype, device=image.device) + 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, :]) + mask = base_mask.clone() + mask[:, start_y:start_y + tile_size, start_x:start_x + tile_size] = attn_mask[:, start_y:start_y + tile_size, start_x:start_x + tile_size] + masks.append(mask) + del mask + 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, 'embeds_scaling': embeds_scaling} + model = ipadapter_execute(model, ipadapter_model, clip_vision, **ipa_args) + return (model, torch.cat(tiles), torch.cat(masks)) +``` \ No newline at end of file diff --git a/docs/IPAdapterTiledBatch.md b/docs/IPAdapterTiledBatch.md new file mode 100644 index 0000000..dfbad83 --- /dev/null +++ b/docs/IPAdapterTiledBatch.md @@ -0,0 +1,80 @@ +# Documentation +- Class name: IPAdapterTiledBatch +- Category: Image Processing +- Output node: False +- Repo Ref: https://github.com/cubiq/ComfyUI_IPAdapter_plus.git + +IPAdapterTiledBatch节点旨在以批量格式适应和处理图像数据,使用平铺技术进行高效计算。它特别适用于处理大型图像或需要批量处理的情况。该节点强调灵活性和性能,允许通过各种参数进行定制,这些参数影响图像转换过程。 + +# Input types +## Required +- model + - 模型参数对于节点至关重要,因为它定义了用于图像处理的基础模型。它直接影响节点的执行和处理后的图像质量。 + - Comfy dtype: MODEL + - Python dtype: torch.nn.Module +- ipadapter + - ipadapter参数对于节点的操作至关重要,因为它指定了用于平铺图像数据的适配器。它在节点有效处理大型图像的能力中起着关键作用。 + - Comfy dtype: IPADAPTER + - Python dtype: Any +- image + - 图像参数是节点功能的基础,因为它代表了要处理的输入图像。节点的输出严重依赖于输入图像的质量和特征。 + - Comfy dtype: IMAGE + - Python dtype: torch.Tensor +## Optional +- weight + - 权重参数允许调整图像处理对最终输出的影响。它很重要,因为它提供了一种控制图像转换强度的方法。 + - Comfy dtype: FLOAT + - Python dtype: float +- weight_type + - 权重类型参数确定要应用于图像处理的加权类型。它很重要,因为它可以显著改变节点的处理方法和生成的图像特征。 + - Comfy dtype: WEIGHT_TYPES + - Python dtype: str +- start_at + - start_at参数指定图像处理的起始点。它很重要,因为它决定了节点开始其操作的初始位置。 + - Comfy dtype: FLOAT + - Python dtype: float +- end_at + - end_at参数定义了图像处理的终点。它很关键,因为它设置了节点处理图像数据的限制。 + - Comfy dtype: FLOAT + - Python dtype: float +- sharpening + - 锐化参数用于增强处理后图像的清晰度。它很重要,因为它可以通过增加锐度来提高输出的视觉质量。 + - Comfy dtype: FLOAT + - Python dtype: float +- embeds_scaling + - embeds_scaling参数用于缩放图像处理期间生成的嵌入。它很重要,因为它可以影响嵌入的维度和质量,影响节点的性能。 + - Comfy dtype: COMBO['V only', 'K+V', 'K+V w/ C penalty', 'K+mean(V) w/ C penalty'] + - Python dtype: str +- image_negative + - image_negative参数用于为图像处理提供负面示例。在应用对比学习的情况下,它可能很重要。 + - Comfy dtype: IMAGE + - Python dtype: torch.Tensor +- attn_mask + - attn_mask参数用于在处理期间屏蔽图像的某些部分。它对于集中节点对图像特定区域的注意力很重要。 + - Comfy dtype: MASK + - Python dtype: torch.Tensor +- clip_vision + - clip_vision参数用于将CLIP视觉模型集成到图像处理中。对于需要理解和生成图像特征的任务,它可能很重要。 + - Comfy dtype: CLIP_VISION + - Python dtype: Any + +# Output types +- processed_images + - processed_images输出包含节点执行的图像处理的结果。它很重要,因为它代表了节点操作的最终输出。 + - Comfy dtype: IMAGE + - Python dtype: torch.Tensor + +# Usage tips +- Infra type: CPU + +# Source code +``` +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}), 'embeds_scaling': (['V only', 'K+V', 'K+V w/ C penalty', 'K+mean(V) w/ C penalty'],)}, 'optional': {'image_negative': ('IMAGE',), 'attn_mask': ('MASK',), 'clip_vision': ('CLIP_VISION',)}} +``` \ No newline at end of file diff --git a/docs/IPAdapterUnifiedLoader.md b/docs/IPAdapterUnifiedLoader.md new file mode 100644 index 0000000..d5ce2b9 --- /dev/null +++ b/docs/IPAdapterUnifiedLoader.md @@ -0,0 +1,115 @@ +# Documentation +- Class name: IPAdapterUnifiedLoader +- Category: ipadapter +- Output node: False +- Repo Ref: https://github.com/cubiq/ComfyUI_IPAdapter_plus.git + +IPAdapterUnifiedLoader节点旨在简化图像处理任务所需的各种模型的加载和管理过程。它集中了加载Clip Vision、IPAdapter、LoRA和InsightFace模型的过程,确保根据指定的预设和提供程序使用正确的模型。节点的功能专注于提供模型加载的统一接口,减少冗余并提高整个系统的效率。 + +# Input types +## Required +- model + - 模型参数对节点的操作至关重要,因为它定义了将用于处理的基模型。它通过确定模型架构和功能来影响节点的执行。 + - Comfy dtype: MODEL + - Python dtype: torch.nn.Module +- preset + - 预设参数是必需的,因为它决定了要加载的模型的特定配置。它通过根据用户的需求选择适当的模型预设来影响节点的执行。 + - Comfy dtype: STRING + - Python dtype: str +## Optional +- lora_strength + - LoRA强度参数是可选的,用于调整LoRA模型对基模型的影响。它在微调特定任务的模型性能方面发挥作用。 + - Comfy dtype: FLOAT + - Python dtype: float +- provider + - 提供程序参数指定InsightFace模型的执行提供程序。它对于确定模型执行期间使用的硬件加速方法很重要。 + - Comfy dtype: STRING + - Python dtype: str +- ipadapter + - 可选的ipadapter参数允许指定自定义IPAdapter模型文件。当用户需要加载IPAdapter模型的特定版本或配置时使用。 + - Comfy dtype: IPADAPTER + - Python dtype: Dict[str, Any] + +# Output types +- model + - 模型输出代表了已加载和配置的基模型,该模型准备好用于图像处理任务。它是节点功能的顶点,为用户提供了一个根据其指定要求量身定制的模型。 + - Comfy dtype: MODEL + - Python dtype: torch.nn.Module +- ipadapter + - ipadapter输出包含已加载的IPAdapter模型,这是某些图像处理任务的关键组件。它为模型提供了额外的功能和定制选项。 + - Comfy dtype: IPADAPTER + - Python dtype: Dict[str, Any] + +# Usage tips +- Infra type: CPU + +# Source code +``` +class IPAdapterUnifiedLoader: + + def __init__(self): + self.lora = None + self.clipvision = {'file': None, 'model': None} + self.ipadapter = {'file': None, 'model': None} + self.insightface = {'provider': 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 + 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'\x1b[33mINFO: Clip Vision model loaded from {clipvision_file}\x1b[0m') + else: + self.clipvision = pipeline['clipvision'] + is_sdxl = isinstance(model.model, (comfy.model_base.SDXL, comfy.model_base.SDXLRefiner, comfy.model_base.SDXL_instructpix2pix)) + (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'\x1b[33mINFO: IPAdapter model loaded from {ipadapter_file}\x1b[0m') + else: + self.ipadapter = pipeline['ipadapter'] + 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: + self.lora = None + torch.cuda.empty_cache() + if lora_model is None: + lora_model = comfy.utils.load_torch_file(lora_file, safe_load=True) + self.lora = {'file': lora_file, 'model': lora_model} + print(f'\x1b[33mINFO: LoRA model loaded from {lora_file}\x1b[0m') + if lora_strength > 0: + (model, _) = load_lora_for_models(model, None, lora_model, lora_strength, 0) + if is_insightface: + if provider != self.insightface['provider']: + if pipeline['insightface']['provider'] != provider: + self.insightface['provider'] = provider + self.insightface['model'] = insightface_loader(provider) + print(f'\x1b[33mINFO: InsightFace model loaded with {provider} provider\x1b[0m') + else: + self.insightface = pipeline['insightface'] + return (model, {'clipvision': self.clipvision, 'ipadapter': self.ipadapter, 'insightface': self.insightface}) +``` \ No newline at end of file diff --git a/docs/IPAdapterUnifiedLoaderCommunity.md b/docs/IPAdapterUnifiedLoaderCommunity.md new file mode 100644 index 0000000..75769be --- /dev/null +++ b/docs/IPAdapterUnifiedLoaderCommunity.md @@ -0,0 +1,38 @@ +# Documentation +- Class name: IPAdapterUnifiedLoaderCommunity +- Category: ipadapter/loaders +- Output node: False +- Repo Ref: https://github.com/cubiq/ComfyUI_IPAdapter_plus.git + +IPAdapterUnifiedLoaderCommunity节点旨在简化IPAdapter框架中各种模型和预设的加载和管理。它提供了一个统一的接口来访问不同的模型配置,确保在不同应用中的兼容性和易用性。 + +# Input types +## Required +- model + - ‘model’参数对于节点的操作至关重要,因为它指定了要加载的模型。它直接影响节点的执行,因为它决定了将使用的特定模型配置。 + - Comfy dtype: MODEL + - Python dtype: str +## Optional +- preset + - ‘preset’参数允许从预定义列表中选择特定的预设配置,这可以显著影响节点的功能和结果输出。 + - Comfy dtype: COMBO['Composition'] + - Python dtype: str +- ipadapter + - 可选的‘ipadapter’参数用于指定节点要使用的特定IPAdapter。其包含可以增强节点对不同IPAdapter配置的适应性。 + - Comfy dtype: IPADAPTER + - Python dtype: str + +# Output types + +# Usage tips +- Infra type: CPU + +# Source code +``` +class IPAdapterUnifiedLoaderCommunity(IPAdapterUnifiedLoader): + + @classmethod + def INPUT_TYPES(s): + return {'required': {'model': ('MODEL',), 'preset': (['Composition'],)}, 'optional': {'ipadapter': ('IPADAPTER',)}} + CATEGORY = 'ipadapter/loaders' +``` \ No newline at end of file diff --git a/docs/IPAdapterUnifiedLoaderFaceID.md b/docs/IPAdapterUnifiedLoaderFaceID.md new file mode 100644 index 0000000..180619f --- /dev/null +++ b/docs/IPAdapterUnifiedLoaderFaceID.md @@ -0,0 +1,50 @@ +# Documentation +- Class name: IPAdapterUnifiedLoaderFaceID +- Category: ipadapter/faceid +- Output node: False +- Repo Ref: https://github.com/cubiq/ComfyUI_IPAdapter_plus.git + +IPAdapterUnifiedLoaderFaceID类作为一个专门的接口,用于加载和管理面部识别模型,确保系统内的兼容性和无缝集成。 + +# Input types +## Required +- model + - 模型参数对于指定系统内要使用的面部识别模型至关重要,指导整体功能和预期结果。 + - Comfy dtype: MODEL + - Python dtype: str +- preset + - 预设参数决定了要应用的面部识别模型的变体,影响面部识别过程的性能和准确性。 + - Comfy dtype: COMBO[preset] + - Python dtype: str +- lora_strength + - lora_strength参数微调模型的适应性,允许在面部识别过程中进行细微调整以获得最佳结果。 + - Comfy dtype: FLOAT + - Python dtype: float +- provider + - provider参数对于确定面部识别模型的执行环境至关重要,影响其操作效率和资源利用。 + - Comfy dtype: COMBO[provider] + - Python dtype: str + +# Output types +- MODEL + - 输出的MODEL代表加载的面部识别模型,准备在系统内的多种任务和应用中部署。 + - Comfy dtype: MODEL + - Python dtype: torch.nn.Module +- ipadapter + - ipadapter输出促进了面部识别模型与系统其他组件的集成,确保了顺畅的操作和数据流。 + - Comfy dtype: IPADAPTER + - Python dtype: IPADAPTER + +# Usage tips +- Infra type: CPU + +# Source code +``` +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') + CATEGORY = 'ipadapter/faceid' +``` \ No newline at end of file diff --git a/docs/IPAdapterWeights.md b/docs/IPAdapterWeights.md new file mode 100644 index 0000000..f78dc70 --- /dev/null +++ b/docs/IPAdapterWeights.md @@ -0,0 +1,88 @@ +# Documentation +- Class name: IPAdapterWeights +- Category: ipadapter/utils +- Output node: False +- Repo Ref: https://github.com/cubiq/ComfyUI_IPAdapter_plus.git + +IPAdapterWeights节点的`weights`方法旨在根据指定的时间函数处理和插值一系列权重。它接受一个权重字符串、一个时间参数和帧详细信息,以生成可以应用于一系列帧的权重列表。此方法对于在时间上调整模型或系统中不同组件的影响至关重要,允许进行动态调整。 + +# Input types +## Required +- weights + - ‘weights’参数是一个包含以逗号分隔的浮点数列表的字符串。它对于定义节点将处理和随时间插值的初始权重集至关重要。这些权重的应用方式可以显著影响它们所集成的系统或模型的输出。 + - Comfy dtype: STRING + - Python dtype: str +## Optional +- timing + - ‘timing’参数决定了在指定帧上插值权重时使用的时间函数。它可以是几种预定义选项之一,每种选项都会在时间上产生不同的权重变化速率。这个参数对于控制不同权重值之间过渡的节奏非常重要。 + - Comfy dtype: COMBO['custom', 'linear', 'ease_in_out', 'ease_in', 'ease_out', 'reverse_in_out', 'random'] + - Python dtype: str +- frames + - ‘frames’参数指定将应用权重的总帧数。它是一个整数值,为权重序列的持续时间设置了上限。这个参数对于定义权重应用的范围并确保其与系统的时序要求一致非常重要。 + - Comfy dtype: INT + - Python dtype: int +- start_frame + - ‘start_frame’参数指示权重序列应该开始的帧号。它允许自定义权重应用在整体帧序列中的开始时间。这对于将权重应用与系统中的其他事件或进程同步特别有用。 + - Comfy dtype: INT + - Python dtype: int +- end_frame + - ‘end_frame’参数定义了权重序列结束的帧号。它用于控制权重应用的终点,确保权重只应用到帧序列的某个特定点。这有助于在系统中创建更细致和受控的效果。 + - Comfy dtype: INT + - Python dtype: int + +# Output types +- weights + - 输出的‘weights’是一个浮点数列表,代表将应用于帧序列的经过处理和插值的权重。这个输出非常重要,因为它直接影响权重所集成的模型或系统的行为。 + - Comfy dtype: FLOAT + - Python dtype: List[float] + +# Usage tips +- Infra type: CPU + +# Source code +``` +class IPAdapterWeights: + + @classmethod + def INPUT_TYPES(s): + return {'required': {'weights': ('STRING', {'default': '1.0', 'multiline': True}), 'timing': (['custom', 'linear', 'ease_in_out', 'ease_in', 'ease_out', 'reverse_in_out', 'random'],), 'frames': ('INT', {'default': 0, 'min': 0, 'max': 9999, 'step': 1}), 'start_frame': ('INT', {'default': 0, 'min': 0, 'max': 9999, 'step': 1}), 'end_frame': ('INT', {'default': 9999, 'min': 0, 'max': 9999, 'step': 1})}} + RETURN_TYPES = ('FLOAT',) + FUNCTION = 'weights' + CATEGORY = 'ipadapter/utils' + + def weights(self, weights, timing, frames, start_frame, end_frame): + import random + weights = weights.replace('\n', ',') + weights = [float(weight) for weight in weights.split(',') if weight.strip() != ''] + if timing != 'custom': + start = 0.0 + end = 1.0 + if len(weights) > 0: + start = weights[0] + end = weights[-1] + weights = [] + end_frame = min(end_frame, frames) + duration = end_frame - start_frame + if start_frame > 0: + weights.extend([start] * start_frame) + for i in range(duration): + n = duration - 1 + if timing == 'linear': + weights.append(start + (end - start) * i / n) + elif timing == 'ease_in_out': + weights.append(start + (end - start) * (1 - math.cos(i / n * math.pi)) / 2) + elif timing == 'ease_in': + weights.append(start + (end - start) * math.sin(i / n * math.pi / 2)) + elif timing == 'ease_out': + weights.append(start + (end - start) * (1 - math.cos(i / n * math.pi / 2))) + elif timing == 'reverse_in_out': + weights.append(start + (end - start) * (1 - math.sin((1 - i / n) * math.pi / 2))) + elif timing == 'random': + weights.append(random.uniform(start, end)) + weights[-1] = end if timing != 'random' else weights[-1] + if end_frame < frames: + weights.extend([end] * (frames - end_frame)) + if len(weights) == 0: + weights = [0.0] + return (weights,) +``` \ No newline at end of file diff --git a/docs/LLMCLIPTextEncode.md b/docs/LLMCLIPTextEncode.md new file mode 100644 index 0000000..319652d --- /dev/null +++ b/docs/LLMCLIPTextEncode.md @@ -0,0 +1,64 @@ +# Documentation +- Class name: LLMCLIPTextEncode +- Category: llm +- Output node: False +- Repo Ref: https://github.com/esheep/esheep_custom_nodes.git + +该节点通过CLIP模型对文本输入进行编码,集成会话元素以完善下游任务的条件上下文。 + +# Input types +## Required +- clip + - clip参数至关重要,它代表了CLIP模型本身,使得文本编码过程得以进行并提供上下文信息。 + - Comfy dtype: CLIP + - Python dtype: CLIPModel +- text + - text参数对于节点的操作至关重要,因为它是节点处理和编码的输入数据。 + - Comfy dtype: STRING + - Python dtype: str + +# Output types +- CONDITIONING + - 输出提供了一个条件化的表示,可以作为进一步处理的上下文或作为生成响应的基础。 + - Comfy dtype: POOLED_OUTPUT + - Python dtype: Dict[str, Any] + +# Usage tips +- Infra type: CPU + +# Source code +``` +class LLMCLIPTextEncode: + + @classmethod + def INPUT_TYPES(s): + return {'required': {'clip': ('CLIP',), 'text': ('STRING', {'multiline': True})}, 'hidden': {}} + RETURN_TYPES = ('CONDITIONING',) + FUNCTION = 'chat' + CATEGORY = 'llm' + + def chat(self, clip, text): + messages_copy = messages.copy() + messages_copy.append({'role': 'user', 'content': text}) + data = {'messages': messages_copy, 'stops': ['[INST]', '', '']} + response = requests.post(url, headers=headers, data=json.dumps(data)) + if response.status_code != 200: + (cond, pooled) = clip.encode_from_tokens(clip.tokenize(text), return_pooled=True) + return ([[cond, {'pooled_output': pooled}]],) + response_dict = json.loads(response.text) + last_message = response_dict['messages'][-1] + if last_message['role'] != 'assistant': + (cond, pooled) = clip.encode_from_tokens(clip.tokenize(text), return_pooled=True) + return ([[cond, {'pooled_output': pooled}]],) + result = last_message['content'] + last_image_index = result.rfind('') + if last_image_index != -1: + result = result[last_image_index + len(''):] + last_edit_index = result.rfind('') + if last_edit_index != -1: + result = result[last_edit_index + len(''):] + print('result: ', result) + tokens = clip.tokenize(result) + (cond, pooled) = clip.encode_from_tokens(tokens, return_pooled=True) + return ([[cond, {'pooled_output': pooled}]],) +``` \ No newline at end of file diff --git a/docs/LLMNode.md b/docs/LLMNode.md new file mode 100644 index 0000000..daa6871 --- /dev/null +++ b/docs/LLMNode.md @@ -0,0 +1,58 @@ +# Documentation +- Class name: LLMNode +- Category: llm +- Output node: True +- Repo Ref: https://github.com/esheep/esheep_custom_nodes.git + +该节点便于与语言模型进行交互式通信,能够处理用户输入并生成响应,实现信息的交流。 + +# Input types +## Required +- text + - 文本输入对于启动与语言模型的对话至关重要,它为AI的响应设定了上下文。 + - Comfy dtype: STRING + - Python dtype: str + +# Output types +- result + - 结果输出包含语言模型对用户输入的响应,是节点功能的核心结果。 + - Comfy dtype: COMBO[STRING] + - Python dtype: List[str] + +# Usage tips +- Infra type: CPU + +# Source code +``` +class LLMNode: + + @classmethod + def INPUT_TYPES(s): + return {'required': {'text': ('STRING', {'multiline': True})}, 'hidden': {}} + RETURN_TYPES = ('STRING',) + FUNCTION = 'chat' + CATEGORY = 'llm' + OUTPUT_IS_LIST = (True,) + OUTPUT_NODE = True + + def chat(self, text): + messages_copy = messages.copy() + messages_copy.append({'role': 'user', 'content': text}) + data = {'messages': messages_copy, 'stops': ['[INST]', '', '']} + response = requests.post(url, headers=headers, data=json.dumps(data)) + if response.status_code != 200: + return {'ui': {'result': [text]}, 'result': ([text],)} + response_dict = json.loads(response.text) + last_message = response_dict['messages'][-1] + if last_message['role'] != 'assistant': + return {'ui': {'result': [text]}, 'result': ([text],)} + result = last_message['content'] + last_image_index = result.rfind('') + if last_image_index != -1: + result = result[last_image_index + len(''):] + last_edit_index = result.rfind('') + if last_edit_index != -1: + result = result[last_edit_index + len(''):] + print('result: ', result) + return {'ui': {'result': [result]}, 'result': ([result],)} +``` \ No newline at end of file diff --git a/docs/PrepImageForClipVision.md b/docs/PrepImageForClipVision.md new file mode 100644 index 0000000..ec75106 --- /dev/null +++ b/docs/PrepImageForClipVision.md @@ -0,0 +1,88 @@ +# Documentation +- Class name: PrepImageForClipVision +- Category: ipadapter/utils +- Output node: False +- Repo Ref: https://github.com/cubiq/ComfyUI_IPAdapter_plus.git + +该节点旨在为ClipVision模型预处理图像,确保它们被正确格式化以供分析。它专注于调整图像大小、裁剪和锐化图像,以增强其特征并符合模型的输入要求。 + +# Input types +## Required +- image + - 图像参数至关重要,因为它是节点处理的主要输入。它影响节点的整体操作,决定了输出的质量和特征。 + - Comfy dtype: IMAGE + - Python dtype: PIL.Image or torch.Tensor +## Optional +- interpolation + - 插值模式定义了应该如何调整图像大小,这会显著影响结果图像的清晰度和细节。这是一个可选参数,允许在调整大小后控制图像的外观。 + - Comfy dtype: COMBO[('LANCZOS', 'BICUBIC', 'HAMMING', 'BILINEAR', 'BOX', 'NEAREST')] + - Python dtype: str +- crop_position + - 裁剪位置决定了调整大小后图像的裁剪方式。这影响了图像的构图和焦点,确保最相关的特征被居中或适当定位。 + - Comfy dtype: COMBO[('top', 'bottom', 'left', 'right', 'center', 'pad')] + - Python dtype: str +- sharpening + - 锐化调整图像的对比度,增强其边缘和细节。该参数允许微调图像的视觉清晰度,并且可以显著提高模型识别特征的能力。 + - Comfy dtype: FLOAT + - Python dtype: float + +# Output types +- output + - 输出是处理后的图像,现在已格式化并准备好供ClipVision模型分析。它代表了节点处理的结晶,包含了对原始图像进行的所有调整。 + - Comfy dtype: IMAGE + - Python dtype: torch.Tensor + +# Usage tips +- Infra type: CPU + +# Source code +``` +class PrepImageForClipVision: + + @classmethod + def INPUT_TYPES(s): + return {'required': {'image': ('IMAGE',), 'interpolation': (['LANCZOS', 'BICUBIC', 'HAMMING', 'BILINEAR', 'BOX', 'NEAREST'],), 'crop_position': (['top', 'bottom', 'left', 'right', 'center', 'pad'],), 'sharpening': ('FLOAT', {'default': 0.0, 'min': 0, 'max': 1, 'step': 0.05})}} + RETURN_TYPES = ('IMAGE',) + FUNCTION = 'prep_image' + CATEGORY = 'ipadapter/utils' + + def prep_image(self, image, interpolation='LANCZOS', crop_position='center', sharpening=0.0): + size = (224, 224) + (_, oh, ow, _) = image.shape + output = image.permute([0, 3, 1, 2]) + if crop_position == 'pad': + if oh != ow: + 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: + 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 + output = output[:, :, y:y2, x:x2] + imgs = [] + for img in output: + img = T.ToPILImage()(img) + 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,) +``` \ No newline at end of file