在复刻黏土风图生成中学习(2) — ControlNet / IPAdapter / instantID

2024-6-2

接上篇,继续优化我们的黏土风 workflow。

引导图控制

来看看上篇里的最后一个case:

1

黏土风格效果还可以,但人物动作总会跟原图不一致,一会双手放地板,一会侧身。图生图一般希望整体轮廓、人物姿态与原图一致,有没有办法控制?

我们可以给它加上 ControlNet 节点,用 canny 边缘检测,试试控制画面主体的轮廓结构:

3

这下就比较准确地还原了原图的姿势了。

ControlNet 介绍

ControlNet 是一种神经网络架构,能做到通过添加额外的引导图片输入(如边缘图、姿态图等)来控制 SD 模型的扩散生成方向,实现对图像生成过程的精确引导。

通过这套架构,可以训练出每种控制方式对应的模型,生图过程中应用这个模型,输入对应的引导图,就能生成对应的图。

以下是 ControlNet 作者训练好的几种模型,以及用这些引导图生成的图片效果:sketch草稿、map法线贴图、depth深度图、canny边缘、line线、edge边缘、场景、Pose人物姿势

2

看下 ComfyUI ControlNet 相关的这几个节点:

4

  1. 每个 ControlNet 模型的输入,都是预处理好的一张引导图,一般用简单的算法就能处理出来,这里用的是 ControlNet canny 边缘控制的一个模型,对应一个 canny 算法节点,一个古老的算法,python 的 OpenCV 库就有。
  2. 接着加载 canny 对应的 ControlNet 模型。
  3. 这张边缘图片输入到 ControlNet 模型,跟文本一起,作为模型降噪生成过程中的引导,指引降噪方向,生成符合文本描述、符合图片边缘形状的图。

这里的 canny 可以替换成 sketch、depth、pose 等算法,搭配上对应的 ControlNet 模型,就能实现不同的控制方式。

ControlNet 原理

扩散生图模型出现后,就有很多人探索怎样更好控制它的生成,显然如果只能用文字生图,可控性太差,最直观的还是能通过草图指引控制它画什么。

怎么解这个问题?对模型简单做一个端到端微调是否可行?例如想让模型按 canny 检测出来的边缘去生成图片,那造一堆 原图 – canny图 的配对作为训练集,微调让模型学习到边缘图和最终生图的关系,是否就可以?大思路是这样,但需要解决微调带来的过拟合、破坏原模型能力的问题,需要设计一个网络结构,能很好认得 canny 引导图特征、跟扩散模型很好结合、效果稳定。

有很多人做过不同的研究,提出过多种方法,ControlNet 的方法相对前人有很大优势,能稳定用在各种场景上,效果最佳,应用广泛。

网络架构

来看看 ControlNet 的这张架构图,我把相应的输入输出示意图加上:

4

理解这个网络结构前,可以看回这篇文章理解下 SD UNet 网络。上采样 = encoder,下采样 = decoder,为了方便和与上图对应,下面就只提 encoder 和 decoder。

这个图左边是 SD 原 UNet 网络,右边是 ControlNet 新加的网络。首先是把 SD 原网络的参数冻结,不参与训练,这跟前面介绍的 LoRA 套路是一样的,训练不影响原网络,只调整新网络,有诸多好处。

接着它把 SD UNet 网络里的 encoder 和 middle 部分复制出来,再用零卷积(zero convolution)连接到原 SD 网络对应的 decoder 层。几个要点:

  1. 与 decoder 的连接:
    1. 整个 ControlNet 网络的目的并不是按 UNet 网络流程有一个输入和输出,ControlNet 网络是只有输入没有输出的,它的目的是在 encoder 识别处理引导图(外加与降噪图/文字Prompt/步数的关系),再把这些信息跳跃连接回原 SD 网络的 decoder,所以 ControlNet 网络本身是不需要 decoder 的,图上的零卷积只是把 encoder 层跳跃连接回 decoder 对应的层。
    2. 为什么这样做?SD UNet 网络里 encoder 各层保留了图片的细节信息,decoder 只有宏观信息,所以把 encoder 各层都跳跃连接回 decoder 对应的层,这样 decoder 拥有宏观和微观细节所有信息,进行一步步生图。那 ControlNet 这里做的,就是为 decoder 增加信息,不止是原降噪图的细节信息,还加上引导图信息,指引降噪生成方向。
  2. 为什么用 1×1 卷积作为连接,而不是做一个简单的叠加?
    1. 如果叠加,会破坏原生图能力。这个 1×1 的卷积,最开始训练前初始化值为0,encoder 里的参数经过这个零卷积相乘,最终输出是0,叠加作用在 SD 网络里的值也是0,也就是训练一开始这个网络对 SD 生图完全没有影响,保留完整的生图能力。随着训练进行,这里的 1×1 不再是零卷积,会逐渐变成一个个权重值,那参数经过这个卷积叠加到 SD 网络,影响就不再是0,可以指引降噪方向。我理解为整个训练过程中生图能力都没被破坏,引导图 ControlNet 对网络带来的影响是一点一点叠加上去的。
    2. 另一点,自己猜的,与 1×1 卷积 相乘的主要作用是降维,引导图信息有限,低通道低维度的数据已经能比较好地表示,不需要跟降噪生图那么大的数据量,对原网络的影响也小些?
  3. 其他几个小点:
    1. 它这里原样地复制了 SD UNet 网络一半的参数,并没有像 LoRA 那样对数据进行压缩,也可以理解为因为这样所以对网络的控制可以更细致。所以它的模型大小是比LoRA大很多,但比原 SD 模型小的。
    2. 一开始输入的 Condition 是像边缘图这样的图片,图上没画出来的是这个图片还会经过一个四层卷积层,把这张图片转化为隐空间的表示。
    3. SD 的输入,包括噪声图、文字 prompt 和 timestep 步数,都会进入到 ControlNet 网络参与训练,因为 ControlNet 是从 UNet 原网络复制出来的,有完整的处理这些输入的能力。

训练过程

沿着上面这张图再复述一下训练过程:

  1. 准备好训练数据:原图 – canny引导图 – 文本描述(可选)
  2. 前向传播:
    1. ControlNet:在 SD 每一步降噪过程中,噪声图与引导图 c 叠加,与文本prompt、步数 一起进入 ControlNet 网络,这里的输入跟 SD 原网络是一样的,每层的输出也一样,每一层推理出的噪声图数据表示,都通过 1×1 卷积连接回到 SD 网络。
    2. Stable Diffusion:噪声图、文本 prompt、步数,一起输入网络推理出下一步噪声图,跟原 SD 训练和推理流程一致,只是这里的 decoder 网络已经叠加了 ControlNet 的网络。
    3. SD 这里的文本输入也可以为空,训练网络只拟合边缘图信息,实际上 ControlNet 作者训练的那几个模型,训练过程中有一半数据集是无文本输入。
  3. 损失函数计算:我们知道每一步期望这个网络输出的图是什么(参考SD扩散训练过程),评估预测和输出的差异。
  4. 反向传播:把差异(损失函数梯度)回传网络,更新网络参数值。SD 网络是锁住的,不回传,参数不变。只在 ControlNet 网络做回传和参数值更新,这里的更新包括每个 encoder 块的参数值,以及1×1卷积的权重值。

训练完后,ControlNet 部分就变成了一个“认得” canny 边缘图片条件的网络,给这个网络输入其他的 Canny 图,经过 ControlNet 作用叠加在 SD 模型上,引导 SD 降噪方向。

论文上还提到一个现象:突然收敛,模型没有逐渐学习识别输入的边缘图片条件,而是在训练到6000多步的时候,突然认得边缘图开始遵循这个输入条件生图。为什么是会突然收敛,也没说为什么,特定架构下的现象,有些玄学。

6

这是非常通用的架构,只要是跟原图关联的引导图,像上面示例的 sketch、depth、pose 等都可以用同样的方法训练出对应的 ControllNet 模型。

若要自己训练一个 ControlNet 模型,作者有篇详细的教程和探讨:《Train a ControlNet to Control SD》

消融实验

消融实验(Ablation Study)是机器学习领域常用概念,指通过修改或移除模块,来测量这些模块/结构设计对结果的影响,也就是 ABTest。

作者这篇文章分享了做的两个消融实验:《Why ControlNets use deep encoder》。尝试了 ControlNet-Lite 和 ControlNet-MLP 这两个更简单的网络对比效果。这俩不是从原 UNet 网络复制出来,而是自定一个网络,再把这网络作用回原 UNet 网络,ControlNet-Lite是简单的卷积网络,ControlNet-MLP是用像素级多层感知机(Multilayer Perceptron)构造这个网络。

5

文中可以看出,在 prompt 充足的情况下,这俩简单的架构都能得到很好效果,甚至更简单的架构也能起作用,要指引图片按轮廓生成,并没有很难,难点在与生图模型的结合。在 prompt 不清晰、或没有 prompt 的情况下,这俩架构表现就差多了,生成的图无意义。

之前也有不少其他人的尝试各种方法,比如这篇论文《Sketch-Guided Text-to-Image Diffusion Models》,不足的地方也是与 SD 图生成的语义没法很好结合,只认识边不能让物体与边很好结合。作者认为 ControlNet 现在的架构能做到跟原网络很好结合,两个关键点:

  1. 用零卷积连接,确保了训练刚开始时对原网络无影响。上面也有说到,沿用 SD 原网络对物体的理解能力,再逐步调节,每一步训练都完整应用 SD 原本的高质量生图能力。否则按随机初始化叠加,一开始几个训练步骤下来,整个网络识别物体的能力很快被破坏。
  2. ControlNet 的网络也需要接收 Prompt 作为输入,这样 ControlNet 编码器才能认识 Prompt 对象,不会与用户输入脱节,比如训练过程中 ControlNet 网络认识了房子的轮廓,如果没有 Prompt 参与训练,就算用户输入蛋糕,网络也会引导向生成房子,而不是蛋糕模样的房子。

ControlNet 先学到这里,我们继续来优化黏土风 workflow。

人脸保持

我们拿目前加了 ControlNet 的 workflow 试试人物的效果:

8

效果还行,但人脸跟原图有些对不上,如果我们想让人脸更接近原图,做一个人物美化的黏土风,有没有什么办法?

可以试试给 workflow 加上 IPAdapter 节点,IPAdapter 有强大的风格迁移、人脸保持的能力,先看看效果:

9

用的是针对人脸训练的 ipadapter-face 模型,人脸美化多了,相比之前相似度高一些,算是人脸美化风格的黏土风,但也不怎么像。

提高 IPAdapter 的权重,能得到越来越像的脸,但跟黏土风融合得不是很好,权重越大黏土风格的感觉越弱:

10

IPAdapter 还有一个专门为人脸保持做的版本 IPAdapter-FaceID,与黏土风格的融合效果好一些,但人脸特征保持程度也一般:

11

在进一步优化前,先来认识一下IPAdapter。

IPAdapter 介绍

IPAdapter 是垫图神器,提供风格迁移能力,输入一张参考图,模型会按这张参考图的风格去生成图片。IPAdapter 目前有两类模型:

  1. IPAdapter
    1. 提供整图风格迁移能力,与直接图生图有本质区别,原理上图生图是在原图加噪点基础上做演化生成,IPAdapter 是让模型认识图片风格要素,生成跟原图宏观风格一致的图片。12
    2. 结合 ControlNet 等插件,在一些场景下能得到很惊艳的效果:13
    3. IPAdapter 针对 SD1.5 和 SDXL 训了好几个模型,也针对人脸迁移做了优化, **ip-adapter-plus-face** 就是其中之一,使用裁剪的人脸图像作为训练集,对人脸的迁移效果好一些。上面第一步用的就是这个模型。14
  2. IPAdapter-FaceID
    1. 在 IPAdapter 的架构下,使用人脸特征代替用 CLIP 编码的图片特征,模型对人脸识别能力更强。这个版本实验中,不允许商用。15
    2. 跟着上面 IPAdapter-FaceID 的 workflow 说明一下各模块:16
      1. 用 InsightFace 提取人脸特征
      2. 人脸特征不像图像特征那么容易学习,因此这个模型配套训练了一个 LoRA 提高学习效果。
      3. 仅使用人脸特征,模型生成结果不稳定,受 Prompt 的影响很大,因此 IPAdapter-FaceID-Plus 版本尝试将人脸特征和 CLIP 编码的图像特征结合起来,所以这里还是需要一个 CLIP 模块。

IPAdapter 原理

17

IPAdapter 由两部分组成:提取图像特征的编码器,以及把图像特征接入网络而新增的解耦交叉注意力模块。

  1. 图片编码器:对参考图编码,提取图像特征
    1. IPAdapter 对参考图的编码,使用了 CLIP 模型,但不是 SD 内置的 CLIP,CLIP 是一个模型家族,作者应该是挑了对图像特征识别编码效果更好的 CLIP 模型。
    2. 后续新出的 IPAdapter-FaceID,是使用了 人脸特征 FaceID 代替图像特征,具体来说是用 InsightFace 库提取人脸特征向量进入网络,更好保留参考图里的人脸身份特征。
    3. 编码后的图像,这里加一个可训练小型投影网络,通过 Linear layer 和 Layer Normalization 投影到长度4的特征序列中,进入网络。
  2. 解耦交叉注意力(decoupled cross-attention):
    1. 回顾 SD UNet 网络的构成,整个网络有16个 Transformer 模块,每个 Transformer 模块里有一个自注意力层和一个交叉注意力层。
    2. 将编码后的图像特征加入到 SD UNet 网络,常规做法是图片特征与文字特征相加,再一起进入 Transformer 模块里训练。但 IPAdapter 用了另一种方式,它向这些 Transformer 模块另外增加一个交叉注意力层,用以处理图像特征,然后把文字和图像两个交叉注意力层相加,称为解耦交叉注意力。
    3. 为什么这样做?不跟文本 prompt 混合,这样图片的特征可以在网络中完整保存下来,跟文字一样具有独立引导能力。
    4. 如果不用解耦交叉注意力机制会怎样?作者做了消融实验,用一般的方法 — 图片特征与文本特征直接连接,一起嵌入到 UNet 的交叉注意力层中,结果如下图的 Simple adapter 所示,能根据图像风格生图,但质量低很多。18

ComfyUI 上 IPAdapter 的两个节点,一个是 CLIP 图片编码器,一个是包含架构图里红色区域可训练参数的 IPAdapter 模型。

训练时跟 ControlNet / LoRA 等一样,也是冻结原 SD 网络,只训练新加的 IPAdapter Transformer 网络,大概2200万个参数,IPAdapter SD 1.5 的模型大小基本 44M,对应着 22M 个参数。但 IPAdapter SDXL 的模型大了20倍,原因不明(原 XL 参数量只比 1.5 大 7 倍)。

InstantID

IPAdapter 在很多场景生图场景下做风格迁移和人脸保持都是神器,但在我们黏土风 workflow 下表现一般,我们试试另一个专门针对人脸迁移的技术:InstantID

19

人脸特征的保持以及黏土风格融合的效果比 IPAdapter 好很多。试过其他图,人脸轮廓特征也很明显能更好保留下来:

20

InstantID 原理

InstantID的 原理很简单,可以近似理解为 InstantID = IPAdapter-FaceID + 人脸ControlNet。

看这两张图,ComfyUI 里使用 InstantID 的几个模块,跟架构图对应,由三部分组成:

22

21

  1. 用 InsightFace 库提取人脸特征,用一个 projection layer 投影映射成跟文本的特征空间一致的向量表示。
  2. 添加解耦交叉注意力层,与 IPAdapter 一致。
  3. 加一个面部识别的 ControlNet,但有些小改动:
    1. 只使用五个面部关键点(两个用于眼睛,一个用于鼻子,两个用于嘴巴)作为条件输入,而不是细粒度的 OpenPose 面部关键点。防止强调多余的面部特性,比如嘴巴闭合这种是可以由prompt控制,而不需要保持的。
    2. 原 ControlNet 文本 Prompt 是加入网络训练的,这里没有加入,只用人脸信息作为ControlNet 中交叉注意力层的条件,主要是希望这个网络只控制人脸,不受文本对人脸描述的影响。

前两步基本就是 IPAdapter-FaceID,第三步就是一个特制的 ControlNet。

从前面效果看起来,第三步这个人脸特征 ControlNet 对人脸特征保持作用很大,用已有的技术方法做组合微调,已经能很好解决一些问题。

最后

我们使用 ControlNet、IPAdapter、InstantID 对黏土风格 workflow 做优化,希望能达到跟原图一致性较高、人脸迁移较好的效果,其中 InstantID 组合了前面两个技术,有很强的人脸迁移能力,但这也带来副作用。在原网络上叠加各种修改,对原生图模型都会造成不同程度的破坏,比如加了 InstantID 后,原文字 Prompt 和 Canny ControlNet 的控制就没那么精准了,上面几个例子可以看出,原来的 ControlNet Canny 边缘图已经很难起作用了,这很好理解,在原网络上叠加的处理,各部分是相对独立的,很难有非常好的融合,InstantID 把方向强力往人脸保持上引,其他输入条件就会被弱化。

这种 Adapter 类,需要在效果和原模型侵入程度间保持平衡,不同场景选择不同的方案,在某些场景要更好的效果,还是得自行微调模型,目前还没看到很完美的方案。

到这里已经可以有一个还算可以、对人脸风格化友好的黏土风格图生成 workflow 了。目前黏土风 workflow 要再进一步优化到生产环境,就是继续调整 Prompt、调整各组件参数,或者训练专有的 LoRA 模型了。

目前对应 workflow 见下图,可在 ComfyUI 上导入:

23

 

参考资料

ControlNet 论文:https://arxiv.org/abs/2302.05543

ControlNet如何为扩散模型添加额外模态的引导信息:https://zhuanlan.zhihu.com/p/605761756

精确控制 AI 图像生成的破冰方案,ControlNet 和 T2I-Adapter:https://zhuanlan.zhihu.com/p/608609941

浅谈扩散模型的有分类器引导和无分类器引导:https://zhuanlan.zhihu.com/p/582880086

使用 diffusers 训练你自己的 ControlNet:https://huggingface.co/blog/zh/train-your-controlnet

深入浅出完整解析ControlNet核心基础知识:https://zhuanlan.zhihu.com/p/660924126

快速理解AIGC图像控制利器ControlNet和Lora的架构原理:https://blog.csdn.net/colorant/article/details/136732221

InstantID技术小结:http://www.myhz0606.com/article/instantID

IP-Adapter 原理和实践:https://zhuanlan.zhihu.com/p/683504661

IPAdapter使用:https://www.runcomfy.com/zh-CN/tutorials/comfyui-ipadapter-plus-deep-dive-tutorial

新一代“垫图”神器,IP-Adapter的完整应用解读:https://developer.jdcloud.com/article/3483

如何在 ComfyUI 中使用 IPAdapter Plus 进行风格迁移:https://www.comflowy.com/zh-CN/blog/IPAdapter-Plus

IP‐Adapter‐Face:https://github.com/tencent-ailab/IP-Adapter/wiki/IP‐Adapter‐Face

分类:技术文章 Tags:
评论

*

*