参考https://github.com/cubiq/ComfyUI_Workflows
进行的demo实验,部分内容可能会过时,但只是为了玩下所以无所谓
第一个demo
- 加载了
v1-5-pruned-emaonly
- 设置潜在空间大小
- CLIP(Contrastive Language-Image Pre-Training)对prompt做encode
- 采样过程KSampler:
- 种子Seed: 数字随机数,不同的种子 = 不同的图
- 步数Steps: 到达最终图片的步数,更多的步骤需要更多的计算时间,但可能会获得更好的合成效果。根据提示词、采样器、检查点的组合差异很大。如果不确定则取15-20
- CFG(Classifier-free Guidance):定义图片距离提示词的距离,数值越小距离越近。如果尝试创造模型没有训练过的复杂图像更高的CFG可能会有帮助。一般来说在4-9可以覆盖所有使用场景,但会受到很多因子的影响,包括正在使用的模型checkpoints。
- 采样器和调度器共同负责处理潜在空间中的噪音,直至在规定的步骤内生成最终图像。
euler+ancestral
和dpmpp_2m+karras
是个常用的组合
- Vae Decode阶段:图片是在一个特殊的环境中被处理的,这个环境是潜在空间,其中有很多对模型计算有用但对人没用的信息,一旦计算完成这些数据将被转换为一些人眼看得见的东西,比如像素。
LoRA-demo
LoRA(Low-rank Adaptation)是一种快速FT(Fine-tuning)方法
基座模型
重绘模型
LoRA
可以增加或减小strength_model
和strength_clip
参数的值来调整lora的影响。正常情况下这两个值是一致的,但你可以尝试不同的组合来获取不同的结果,参考文章。
SDXL
SDXL模型是用1024×1024的图片训练的,由两个模型组成。虽然只用基础模型是ok的,但增强模型可能会给图片带来更多清晰的细节。
把放入ComfyUI/models/checkpoints
即可,有_0.9vae
结尾的文件是将一个更好的VAE融合进去的版本,也可以自己用外部的 VAE
生成过程包括基础Base阶段和增强Refiner阶段,因此步数控制变成了2个参数,Total控制总步数,Base控制的是基础模型的步数,一个比较好的原则是让基础模型的步数占比是80%
这次我们用了更高级的KSampler,它是一个很重要的节点来让我们更精确的让采样器工作,我们设置了总步数是25但同时设定了在第19步结束,注意必须让return_with_leftover_noise=enable
以此来让refiner可以完成剩余的工作
SDXL引入了两个新的CLIP文本编码节点分别给基础模型和增强模型,他们增加了text_g
、text_l
、width/height系列条件
. Text G
是自然语言的提示词,你仅仅和模型说人话就行。 Text L
就像SD1.x/2.x那样独立的概念词组,非常多的实验结果表明一般来说G和L设置相同的值可以让模型看起来更好的理解我们想要的是什么。后续也有实验工作流来拆开这两个提示词
目前还没有完全搞清楚这几个宽高的条件是如何影响最终的结果。通过初步测试,宽高设置为 4096 时生成的细节似乎会稍微清晰一些。为了在图像分辨率更高的情况下保持正确的宽高比,将CLIP 宽度和高度设置为潜在空间尺寸的4倍会比较好。
超分 upscale
背景介绍
- 潜在空间和像素空间的区别
图片生成过程实际发生在潜在空间,潜在空间是GPU处理所有数据信息的地方,这些信息需要被模型(VAE)解码并被转换成像素。潜在空间解码是一个有损的过程,这个过程需要很多计算资源,越大的图片就需要越多的计算资源。这就是为什么我们在最后一个阶段才转换成像素的原因。
- 传统超分器和基于模型的超分器区别
为了超分辨率我们可以使用像bicubic、bilinear之类的传统算法或机器学习模型来达成这个目的。一般传统方法会更快但受缩放比例影响结果一般都比较模糊。
- 降噪参数的影响
为了找回更多的细节我们可以对图片应用二次编码,这个过程包括将图像传递给第二个KSampler并使用降噪(denoise)参数。这个参数越小图片看起来会和原始的更加接近但处理效果也就越差,如果你不关心最终图像是否和原始图像1:1,你可以增大这个参数并在第一轮就获得一个虽然略有不同但效果非常鲜明非常的结果。如果你想尽可能接近原始图片那你应该使用一个较小的降噪参数
当在像素空间超分时denoise在0.25~0.5之间时足够获得比较好的结果,当然基于模型的超分器会要求耕地的降噪参数,因为被超分的图片应当已经很好了。
一个被超分的潜在空间信息会包含非常多的噪音,所以你需要更大的降噪参数,一般来说在二次编码阶段至少要0.55
这里也有基于模型的潜在空间超分器:
- NNLatentUpscale
- SD Latent Upscaler 实验中但值得尝试
总之:一个图片无论用何种方式如果已经被超分过,那么尽可能用最低的降噪参数就会获得最好的结果。基于潜在空间的超分已经足够完美因为它需要更少的资源。
对潜在空间超分
这是最简单并且最快的方式,upscale_latent.json
在这个工作流中我们对潜在空间超分了1.5倍,并且在二次编码降噪参数取了0.7,不巧的是超分后的潜在空间噪音较多所以最终的图片看起来和原版不太一样,好处是资源占用比较低
传统插值法对像素超分
upscale_pixel.json
在这个场景中原始图片先被解码到了像素空间,然后用传统插值法做了两倍的缩放。尽管缩放比例比之前的工作流要高但因为噪音比较少所以降噪参数0.55写的比较小
用模型对像素超分
upscale_by_model.json
这就是事情变的有趣的地方,值得一提的最好结果目前可以被基于模型的像素空间超分达成。
- 原始图像需要首先被从潜在空间解码
- 紧接着需要加载超分模型,在这个例子中用的是4x-UltraSharp,没有好模型或坏模型,每一个都有它独特的目标。适用于尝试的模型可以是RealSR, Remacri。UltraSharp和这俩可以在OpenmodelDB找到
- 实际超分的过程
- 大部分超分器用固定的超分参数训练,一般是4倍的,但也可以找到8x, 3x, 2x 甚至1x(他们通常是降噪过滤器)。我们用的是4倍的所以在这一步我们选0.5来使得最终结果是2x的
- 在进行二次编码之前我们需要将图片转换回潜在空间,因为SD只能工作在潜在空间,这个过程使用VAE编码节点完成。如果你没有足够的显存,图片将会被自动分片平铺并分块编码,这个过程可能会耗时较长
现在超分完成并且准备好了二次编码,这次我们选择降噪参数0.25是因为原始数据已经很好了,注意二次编码仅需要很少的步数即可
SDXL对潜在空间超分
upscale_latent_SDXL.json
这个相同的概念也同样适用于SDXL,尽管在base+refiner工作流中超分可能看起来不是那么直观 如果你对完整的超分不是那么感兴趣的话,你可以只用base基础模型执行几步创建一个草稿,然后在潜在空间进行超分,最后使用base进行二次编码,然后用refiner进行三次编码
我们在二次编码使用了高级的KSampler,但设置了start_at_step=5
而不是start_at_step=0
,是因为这是和设置一个较低的降噪参数等价: start_at_step = 0
和denoise = 1.0
是一样的。这个工作流会进行潜在空间的超分所以我们需要维持这个值在较低的水平,你可以进行尝试但大概20步左右3-5步通常是ok的,等价于降噪参数设置成0.6~0.7
用模型对潜在空间超分
upscale_latent_with_model.json
像前面说的我们尽可能在潜在空间工作而不是在与像素空间反复横跳,因为在潜在空间超分会引入非常多的噪音,除非你用模型。在潜在空间用模型超分不像在像素空间的传统算法,但比传统算法要好不少 在这个工作流我们使用NNLatentUpscaler自定义节点,它兼容SD1.x和SDXL的潜在空间。被超分的图片有一点模糊但没有噪音并且我们可以通过在二次编码应用较低的降噪参数找回一些细节
用ControlNet超分
upscale_tile_controlnet.json
Tile是一个非常有趣的ControlNet,确认下载它并放入ComfyUI/models/controlnet/
文件夹,在这个工作流我们不需要前置处理器
Tile 获取一个图片并且使用颜色信息生成一个新的图片,如果你在第一次编码生成的图片上超分,并用相同的图片引用传递给二次编码阶段,结果的细节会变得非常多并且非常接近原始图片。这个技术非常强大并且灵活所以经常被用来作为超分的方法
- Tile工作在像素空间,所以我们需要从潜在空间解码
- 图片使用简单的nearest-exact超分了2倍,我们不需要很高的分辨率因为我们在二次编码使用了很高的降噪参数
- 超分后的图片被移动到了潜在空间并喂给了第二个采样器。注意:在二次编码使用超分后的图片作为基础不是严格必须的,在技术上来说可以使用空的潜在空间配合1.0的降噪参数。经过一些实验后我发现在这个工作流中这样做可以有更好的效果
- 加载Tile control net
- 我们对原始图片而不是超分后的图片应用controlnet,并使用相同的提示词作为条件,强度
strength=1.0
是因为我们想让最终的图片尽可能接近原始的图片 最终我们运行二次编码,你可以调整controlnet的强度和降噪参数来尝试让结果距离原始图片更远或更近,通过降低降噪参数可以更近但会在二次编码丢失更多形状细节,在这张图上0.75
看起来不错。
文生图
文字提示是Stable Diffusion图片生成的基础,但这里有很多方法我们可以尝试来获得更好的结果。这些工作流探索了我们可以使用的多种方法来做图片调整
Important: 不总是很轻易预测对于一个给定的任务哪种调整方法会更好。通常来说结果都是玄学的并且预测模型做什么是不可能的。唯一的方法就是实际实验,幸好ComfyUI工作流非常擅长做比较。
单词权重
word_weighting.json
这是非常简单也最广为人知的方法,你可以给一个或一系列单词或加括号。例如closeup a photo of a (freckled) woman smiling
。在这个例子中我们给freckled
设置了一个更高的权重,不写的默认值是1.1
,我们可以通过(freckled:1.3)
这样的写法继续增加更大的权重,一般来说1.1到1.4是足够的,但具体的值还是要具体模型具体分析。你也可以通过设置小于1的值来降低权重例如(freckled:0.7)
Embedding/Textual inversion
embeddings.json
Embedding是一种非常简单受欢迎的调整方式,因为非常容易训练并且有时非常的有效。
为了跑这个工作流你需要下载下面的模型并放 ComfyUI/models/embeddings
想要激活embedding的语法是embedding:FileName
,文件扩展名是非必须的。例如为了使用UnrealisticDream的语法是embedding:UnrealisticDream
,
Embeddings的行为和标准单词是一样的,所以单词的位置会有影响。例如越早出现的单词重要性越高。在下面的例子中你可以看到不同 (embedding:UnrealisticDream:1.2), embedding:BadDream
注意: 值得注意的是embedding并不是魔法所以不能解决所有的问题,有时候反而会带来更多的问题,谨慎的使用他们并多做实验
Conditioning Concat
conditioning_concat.json
通过conditioning concat节点使用提示词是一个强大的方法,模型通常不擅长在多个不同的元素间理解上下文的多重概念,例如指定不同物体的颜色就非常困难。 这个提示词a blue ball a red bucket on the beach
的成功率就非常低,大约是1/25。我们通过concat增加成功率
Conditioning Average
conditioning_average.json
有时你想合并两个概念,例如zebra-chameleon。你可以简单的用提示词但更好的选项是 conditioning average节点
Area conditioning
conditioning_area.json
有时你需要将特定的物体放在特定的位置,在不用ControlNet的情况下最简单的办法是使用area conditioning节点,语法非常简单
- 用提示词描述你的场景
- 用第二个提示词描述你想的物品
- 链接第二个提示词到conditioning area节点并设置区域的大小和位置。在这个例子中我们有一个768×512的潜在空间,我们想让”godzilla”在右侧。所以我们设置区域是512×512并在X轴设置了256px
- 连接场景提示词和特殊条件到Conditioning combine
左侧的操作是将条件组合送给KSampler的正向提示词然后等待奇迹发生,当然你也可以用这个方法放置多个物体。
注意: 源码里的工作流有一点点不一样,它先设定了2个区域然后再传递给了二次编码来使得整个画面是统一的,这是在SDXL上正常工作的好办法
Timestepping
timestepping.json
ConditioningSetTimestepRange
是一个新节点也是我们目前拥有的最强文本调整工具,这个节点让你可以设置每个提示词临时开始和结束位置。假设我们有20步骤,你可以让采样器从第5步开始”画”猫然后忘掉刚才的猫继续在剩余的15步生成狗
这是一种非常有效组合提示词的方式,可以进行更高层次微调。每个提示词不必等前一个结束,但他们依然会在几步内相互融合
在这个工作流里我们尝试生成freckled African-American/Japanese woman。为了达成这个目标我们需要在降噪阶段的不同的时间点混合3个概念(freckels, Japanese, African-American)
注意: 你可以设置多个节点,每个都可以设置独立的时间。但重要的是不要有空白的时间序列。例如:一个结束于0.5第二个就应当在0~0.5之间开始,否则就会有一些步骤没条件。
GLIGEN Box
gligen_box.json
这个工作流使用dreamshaper需要提前下载
GLIGEN是一个可控的文生图模型,Comfy目前仅支持box conditioning,和之前提到的area conditioning相似。为了正常工作你需要下载GLIGEN放入ComfyUI/models/gligen
文件夹
第一步是编写你的场景提示词,然后你需要为每一个你想控制的场景元素创建GLIGENTextBoxApply
然后链接到GLIGENLoader
在这个例子中提示词是high quality illustration of red riding hood hugging the wolf in the forest
。然后我们设置了2个GLIGEN,其中一个应用于red riding hood
另一个应用于wolf
并且同时设定了位置。多个节点可以直接连接最终可以共同作用于采样器
结果通常会比单个area conditioning更好但GLIGEN模型未能引起人们的关注。
Image-to-Image 图生图
一图胜千言,有时候从一个参考图片开始会比从文本开始抽奖更有效率。 在开始前请确认将input的内容放入了ComfyUI/input/
.
简单的图生图
img2img_SDXL.json
最简单的图生图工作流就是从一个已有图片开始,并在采样器用小于1的降噪参数,越小的降噪参数会使结果越接近原始图像
我们当然也可以用合适的提示词来影响生成过程,在这个工作流中我们使用一个女性基础图像迁移到一个男性
注意: 我们在这个例子中使用的是SDXL,潜在空间的大小是1024x1024
但基准图片只有512x512
。最好让基准图片和潜在图片保持相同的尺寸,这也是例子中对原始图片缩放的原因。一般来说对每一个图生图工作流都是这样的, 包括ControlNets。特别是aspect aspect ratio不同的时候。
unCLIP model
conditioning_unclip.json
有时你想基于某个图片的风格创建新的图片,而不是在已有图片的基础上重画。这个过程可以通过unCLIP models完成,在这个例子中我们使用sd21-unclip-h.ckpt
- 我们加载
unCLIPCheckpointLoader
节点,注意因为是SD2.1所以我们用768x768
潜在空间和模型训练时的保持一致 - 使用
CLIP Vision Encode
来引用原始图片 - 控制的过程发生在
unCLIPConditioning
节点noise_augmentation
定义了新图片会和原始图片有多接近,0
表示最接近的,一般来说设置0.1-0.3
比较好。strength
权重是和其他条件的关系距离,在这个例子中是text clip。就像在文本提示词中设置的一样:(red hat:1.2)
.
提示: 你可能已经注意到了unCLIP有两个可用模型,sd21-unclip-l.ckpt
和sd21-unclip-h.ckpt
。一般来说-h
更加精确一些,-l
是用来给资源不够的场景或对速度有明确要求的场景使用
Style Model
conditioning_style.json
Style model和unCLIP很相似但它是一个CLIP Vision conditioning,可以被用于任何的SD1.5模型这个例子需要下载以下模型
- CLIP Vision model 放入
ComfyUI/models/clip_vision/clip-vit-large-patch14.bin
- the style model 放入
ComfyUI/models/style_models/coadapter-style-sd15v1.pth
- 加载CLIP Vision模型
- 对原始图像编码
- 加载Style模型
- 连接提示词到
Apply style model
节点,并提供给KSampler采样器的正向参数。注意尽管这个节点没有提供强度权重strength
参数,但技术上你可以通过timestepping来调整它。
**注意:**style模型和其他图生图模型一样不能处理它不理解的概念,一个名画或人会很容易迁移风格,但更抽象的概念可能不会有更好的结果
IPAdapter image + text
IPAdapter_basic_SDXL.json
IPAdapter是一系列非常有效的微调模型,他们可以被独立使用或配合文本、ControlNet一同使用
- 下载这些模型
- 安装ComgyUI extension **同时需要模型和图片编码器
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
cd ComfyUI/custom_nodes git@github.com:cubiq/ComfyUI_IPAdapter_plus.git cd ComfyUI/models/clip_vision curl -L -o CLIP-ViT-H-14-laion2B-s32B-b79K.safetensors 'https://huggingface.co/h94/IP-Adapter/resolve/main/models/image_encoder/model.safetensors' curl -L -o CLIP-ViT-bigG-14-laion2B-39B-b160k.safetensors 'https://huggingface.co/h94/IP-Adapter/resolve/main/sdxl_models/image_encoder/model.safetensors' curl -L -o clip-vit-large-patch14-336.bin 'https://huggingface.co/Kwai-Kolors/Kolors-IP-Adapter-Plus/resolve/main/image_encoder/pytorch_model.bin' mkdir -p cd ComfyUI/models/ipadapter cd ComfyUI/models/ipadapter curl -L -o ip-adapter_sd15.safetensors 'https://huggingface.co/h94/IP-Adapter/resolve/main/models/ip-adapter_sd15.safetensors' curl -L -o ip-adapter_sd15_light_v11.bin 'https://huggingface.co/h94/IP-Adapter/resolve/main/models/ip-adapter_sd15_light_v11.bin' curl -L -o ip-adapter-plus_sd15.safetensors 'https://huggingface.co/h94/IP-Adapter/resolve/main/models/ip-adapter-plus_sd15.safetensors' curl -L -o ip-adapter-plus-face_sd15.safetensors 'https://huggingface.co/h94/IP-Adapter/resolve/main/models/ip-adapter-plus-face_sd15.safetensors' curl -L -o ip-adapter-full-face_sd15.safetensors 'https://huggingface.co/h94/IP-Adapter/resolve/main/models/ip-adapter-full-face_sd15.safetensors' curl -L -o ip-adapter_sd15_vit-G.safetensors 'https://huggingface.co/h94/IP-Adapter/resolve/main/models/ip-adapter_sd15_vit-G.safetensors' curl -L -o ip-adapter_sdxl_vit-h.safetensors 'https://huggingface.co/h94/IP-Adapter/resolve/main/sdxl_models/ip-adapter_sdxl_vit-h.safetensors' curl -L -o ip-adapter-plus_sdxl_vit-h.safetensors 'https://huggingface.co/h94/IP-Adapter/resolve/main/sdxl_models/ip-adapter-plus_sdxl_vit-h.safetensors' curl -L -o ip-adapter-plus-face_sdxl_vit-h.safetensors 'https://huggingface.co/h94/IP-Adapter/resolve/main/sdxl_models/ip-adapter-plus-face_sdxl_vit-h.safetensors' curl -L -o ip-adapter_sdxl.safetensors 'https://huggingface.co/h94/IP-Adapter/resolve/main/sdxl_models/ip-adapter_sdxl.safetensors' |
SDXL Revision
revision_SDXL.json
Stability AI发布了the Revision model和其他方法很相似,但是给SDXL专用的
Revision是被用来为图片(包括多张图片)进行图文微调或变体的有效工具
- 下载clip vision model放入
ComfyUI/models/clip_vision
文件夹
注意: 为了消除任何来自文本的干扰我们使用ConditioningZeroOut
节点,这是可选的。仅仅为了这个例子也就意味着因为纯粹图生图没有任何外部的干扰,稍后你可以自行修改掉这个系欸但并添加自定义的提示词
In/Out Painting
当你需要改变一个图片的细节,或你想像某个方面扩展图片的时候,在Stable Diffusion中Inpainting是一个非常有效的方法
注意当重绘时候最好使用被特别训练过的模型,他们通常后缀上标记了inpainting
。虽然普通的模型也可以用来重绘,但专用的模型会有更好的效果。
- 下载DreamShaper Inpainting放入models中
**提示:**大多数图片节点都会包含蒙版编辑器,右键点击任意图像并选择Open in Mask Editor
即可。或者你可以自己创建一个alpha通道的蒙版,例如GIMP
Inpainting重绘
inpaint.json
这个工作流非常简单,唯一需要注意的是我们使用了VAE Encode (for Inpainting)
专用节点进行了编码并设置了grow_mask_by=8
,让蒙版区域大一点能让模型”看”到相邻的区域来获得更好的效果
在接缝处出现线条是很常见的,在这个例子中我们可以在二次编码时做一个值较小的降噪,或者你可以在超分过程中轻易修复这个问题。
Outpainting扩图
outpaint.json
Outpainting扩图和重绘非常相似,我们继续使用相同的模型,除了Pad Image for Outpainting
节点工作流和前一个基本一样,这个节点让我们添加空白区域在图片的某个边上,它提供了feathering选项但一般来说都是没用的,你可以简单的通过在VAE Encode (for Inpainting)
增加grow_mask_by
来获得更好的效果。
Inpainting SDXL with SD1.5
SDXL_inpaint_SD15.json
At the time of this writing SDXL only has a beta inpainting model but nothing stops us from using SD1.x/2.x for inpainting. This workflow shows you how and it also adds a final pass with the SDXL refiner to fix any possible seamline generated by the inpainting process.
Guided 可控组合
从这里开始变得因吹斯听了,文本描述或图生图只能让你走到这了, ControlNets和可控组合才能让你走的更远。
大多数本节的工作流需要下载ComfyUI’s ControlNet Auxiliary Preprocessors extension
0 1 2 3 4 |
cd ComfyUI/custom_nodes git clone https://github.com/Fannovel16/comfyui_controlnet_aux/ cd comfyui_controlnet_aux ../../../python_embeded/python.exe -s -m pip install -r requirements.txt |
Pose 动作
pose.json
对于所有control nets的工作流基本上是一样的,唯一不同的是你用的模型以及预处理器,第一个例子我们用openpose转换一位跳舞的人到一个实际的角色。 你可能会注意到每个Controlnet或T2Adapter可以和多个预处理器同时使用,对动作来说DWPreprocessor
是一个非常有效的并且结果好于OpenPose
的预处理器
Canny 线条
canny.json
canny以难以置信的效率和资源占用把图片简化成线条,并且可用作新构图的参考
Depth 深度
depth.json
depth controlnet是一个非常有用的网络,它可以让你在三维空间定义形状和体积,一个比较好的预处理器是Zoe.
注意: 只要你有合适的参考图片,使用预处理器并不是必须的。如果你用Blender的小工具,PoseMy.Art让你可以很容易的创建一个角色。Cascadeur是另一个专业的解决方案可以让角色摆出合适的动作
提示: 为了更好的结果你永远可以串联多个controlnets
提示: 记得多试试Apply ControlNet
节点的strength参数,通常降低这个值可以给模型更小的发挥空间
重要: controlnet必须匹配你当前用的SD版本
0 Comments