稳定的diffus离子企业级教程:揭秘Inpainting工作的秘密!
来说一下理论设计内容。总的来说,我们想谈谈基于SD实现的不同功能的组合方法。
比如在基本的文生图应用中,我们知道文本信息和图像信息是通过跨attention结合起来的,可以是几层transformer。那么如何创建qkv呢?对于图像制作工作,输入的图像组合如何影响最终的图像制作?说到绘画,为什么要有单独的绘画模型呢?原模型如何进行喷漆?
接下来,让我们深入代码,看看文本和图像如何在 SD 中神奇地结合在一起。
2。 TextToImage

这张图相信大家都认识。diffus吉恩潜在原理示意图取自《High-Resolution Image Synthesis with Latent Diffusion Models》。也正是基于这个原则,稳定的diffus才能训练成功,和大家见面。
论文称文本向量和图像向量是通过“跨attention”结合在一起的。 “跨attention”源自字母“attention就是你所需要的”。虽然文中没有明确说明,但“编码器-解码器attention”已经具备了“跨attention”的身份——即QKV的来源不同。
在原自attention中,QKV是通过将原始和不同的矩阵进行积分来计算的,而在“跨attention”中,“X”首先来自不同的来源,产生基于不同来源的QKV,然后在attention的下一次计算中,来自不同来源的“X”被组合起来。
在SD中,X有两个来源:文本和图像。从信中我们知道,sd中的交叉attention发生在不存在的部分。通过启用 在这个类中,我们通过配置文件将 类中 在下面的类 其实更容易理解,因为在SD的训练过程中,文本编码器部分是固定的,不更新,所以很自然地让相机和文本编码更接近,很自然地用文本编码作为value,利用Self-attention机制生成新的条件图像信息。 那么接下来的finetune,比如中文编码器的训练,我们是否可以考虑把这里的关系反过来,用文本字符替换q,用图形字符替换k和v,让中文编码器直接添加到训练好的unet中?靠近点。这是一个值得考虑的指南~ 使用webui的同学应该对这个页面很熟悉。我们可以使用此页面来创建快速视线图。即在创建 SD 时以图像和文本作为参考来指导最终图像的创建。 除了页面之外,在我们的项目中,您可以通过 这里需要讲一下SD的基本原理。如果您想以任何方式获取它,您可以查看下面的链接。我在这里简单解释一下推理过程。图解稳定扩散jalammar.github.io/illusterated-stable-diffus ion/ 在SD模型推理过程中,我们通过采样得到了一张图像random,它是随机噪声。 ;根据当前处理步骤数和当前图像 A,我们可以使用diffus离子模型计算图像 B。模型认为,当我们从图片A中取出图片B时,剩下的图片会更接近,我们想要的结果是A_new = A-B。然后不断重复“猜B、减B”的过程,最后剩下的就是我们最终的猜测图像。 当用于SD预测的文本和迭代次数一定时,唯一能影响最终结果的就是第一张随机图像。因此,一方面可以认为,当其他内容确定后,最终的图像结果将由初始噪声决定。 回到留声机问题,要让输入图像来指导图像的创建,利用输入图像来产生这种噪声是一个非常直观的想法。具体步骤可以参考diffus离子原理中给原图添加K步声音的过程,这里不再赘述。代码中主要体现在下图中标注的两个地方。 位置1)是把原始图像转换成VQGAN的隐藏空间向量,因为diffus的离子过程就是在这个空间完成的; 位置2)是给隐藏空间向量添加噪声,使其成为随机噪声。 如果有兴趣,可以仔细看看 通过在制作过程中添加介绍性图片和文字指南,我们可以更好地控制生成的输出。例如下图中,我希望创建一个建筑物(building),主导图像是百度大厦。从最终结果中可以看出,生成的建筑物在声音和角度方面与指南的地图相似。 还要注意,这里控制的是输出图像和输入图像的相似程度,它由两个参数定义:1)采样步长; 2)降噪强度。 乘以2就是去噪过程中的最后一个数字。上图为采样步长为20、降噪强度为0.8的结果;下图为采样步数为50、降噪强度为0.8的结果和采样步数为50、降噪强度为0.2的结果 == ==== =20230613 补充===== == = 这段时间我在Imagen中应用了绘图工作,发现有很多东西可以讲。这个绘图工作并不像我们想象的那么简单。 。 首先,我们可以在配置文件中看到,训练时使用了1000个时间步,这说明了两点: 1。我在原始图像上添加了 1000 次噪声,将其变成纯噪声。 ; 2。我对噪声图像进行了1000次过滤,并将其转换为原始图像; 这里注意,纯噪声和原始图像是这个轴的最后两个点,只有时间过程负责这部分,时间步长只是表示这部分是如何切割的。这并不意味着时间步长越大,添加的噪声就越多或者图像越好。因此,当timesteps=1000时,添加噪声500次,当timesteps=100时,添加噪声50次,噪声图的结果几乎相同。 我谈论这个过程是为了更好地理解下一代过程。生成时,我们选择生成步长为20,那么根据训练时设置的timestep=1000,会选择20个数字来覆盖这1000步。一种简单的方法是选择[0,50,100,150,…,1000]作为20个点进行去噪。这也部分解释了为什么当随机数固定时,不同去噪步骤的结果是相同的。 那么涂胜涂会怎么样呢?前面提到的第一个噪声的定义不是很清楚。具体操作如下。以去噪步长为 20 为例,我们在这里选择 power = 0.2,因此我们期望最终图像更接近原始图像。对于20步,对应的噪声步强度为[0,50,100…1000],1000代表纯噪声。因此,对于原始图像我们选择idx = 20 * 0.2 = 4,对应的噪声级别为150,去除原始图像得到原始噪声。由于这个噪声对应的是150,所以很明显,噪声不能从1000开始降低,而是需要从150开始降低。降噪强度分别为150、100、50、0,得到原始图像。这也解释了为什么,在绘制过程中,当选择power时,迭代步长是sampling_steps * power。 成像相当于在某个部位对应的图像上添加噪声,然后将其抵消,之前从扩散过程的中间,到原始图像。 绘画是一项有趣且有用的活动。这允许我们更改所选区域而不影响图像的其他区域。 上图是webui提供的着色功能。但是当你使用这个功能的时候,你是否对WebUI是如何利用底层SD模型来实现着色功能感兴趣呢? 无论是runwayml、compvis还是stable,他们似乎都选择使用新模型来提供涂装工作。这和基于原sd的inpaint有什么区别? https://github.com/runwayml/stable-diffus ion/github.com/runwayml/stable-diffus ion/https://github.com/CompVis/stable-diffus iongithub.com/CompVis /stable- diffus ionGitHub - Stability-AI/stablediffus ion:使用潜在扩散模型进行高分辨率图像合成github.com/Stability-AI/stablediffus ion 首先我们要知道我们画画的时候有哪些数据。除了主要文本内容之外,我们还会有原始图像、蒙版图像和容易被忽视的蒙版图像。我个人的理解是,与其让模型根据图像和掩模生成掩模图像,不如手动提供,这样可以减少模型的计算压力。 其次我们看一下修复模型的配置文件 关键是如何重复使用这两个新条件,达到“只是改变遮罩区域并与原始图像匹配良好”的目标。 新模型非常简单。预处理后,我们将掩模和掩模图像转换为VQGAN空间中的张量,每次返回时,通过等待将这两个张量分开。将带噪声的输入向量concat,输入待预测的diffus离子模型,得到相关的预测结果。 具体编码过程参见这些文件和方法: 这样的“懒惰”行为实际上会让模型不仅需要学习如何处理额外的数据,还需要调整已经掌握的绘画技巧。因此,在 runwayml 存储库中,它显示 ok,接下来就看看webui如何神奇的使用basemodel来实现这个任务。 注意着色功能有两个条件: 这里参考代码是这个,大家都知道~ https://github.com/AUTOMATIC1111/stable-diffus ion-webuigithub.com/AUTOMATIC1111/stable-diffus ion-webui 这里是我们讨论DDIM-Sampler下webui上inpaint的实现。同样,它有原始图像 img_org、掩码和文本。其着色过程如下: 具体基于DDIM-Sampler的视线可以参考webui中的这个方法。 上面介绍了webui中着色的方法,这里也详细讨论了它的配置的几个事情。 本文主要是理论总结,整理SD模型以及基于SD模型的webui,如何理解文生圣像、绘画作品。 提到的模型融合是一项非常关键的技能,可能是深度学习皇冠上的下一颗钻石(笑)。另外,你需要对diffus离子模型有特别的了解,不是数学层面的,而是模型系统层面的。有需要的朋友可以看参考文献“diffus稳定离子带图片”中的第四个链接。pokemon.yaml
中的unet部分,我们可以看到ldm/modules/diffus ionmodules/openaimodel.py
UNetModelUNet 。
类。 成员变量。一个简单的理解是定义我应该发送给模型的第一个图像区域,可以是整个图像,也可以是掩模附近的区域。 use_spatial_transformer
设置为True,因此在创建attention模块时,类SpatialTransformer的使用方式有所不同。 ›
SpatialTransformer
我们看到它对图像数据进行拉伸,将(b,c,h,w)转换为(b,(hw),张量c)就是将图像数据转换成数组长度为 hw,尺寸为 c。 ldm/modules/attention.py/CrossAttention
中,我们生成图像变化序列的查询,并使用数据生成attention十字的键和值。 3。 ImageToImage
scripts/img2img.py
体验相关功能。那么使用 img2img 函数,如何添加图像来生成最终图像呢? decode
方法,你会发现z_enc
需要替换这里的噪声变量。几代人中随机生成的。 4。着色
4.1 使用新模型进行绘画♷He❀ 参见,尤其是绘画作品中使用的模型是如何应用这项技能的?
configs\stable-diffus ion\inpaint\v1-finetune-for-inpainting-laion-iaesthe.yaml,但是主要区别在于两点,一方面,主模型从
⇒LatentDiffusion
变为LatentInpaintDiffusion
;另外,更重要的是在unet部分(即diffus离子模型部分),图像输入的维度从4变为9。 LatentInpaintDiffusion
在数据处理上有影响。这里我们会添加额外的处理逻辑,帮助我们使用字典来组织需要进行不同处理的条件的信息(比如“crossattn”中的字符,而在“concat”下我们放入一些需要组合的条件);而unet部分新增的5个通道对应了上面提到的两个mask相关数据:mask(通道1)和图像mask(通道4)。 scripts/inpaint_sd.py
⇒ ⓙ VQ GAN 张量图: ldm/model s /嚚明ION/ddpm.py
⇒ LatentInpaintDiffusion.get_input()
DiffusionWrapper.forward
sd-v1-5-inpaint.ckpt
是基于获得的 sd-v1-5.ckpt
440K 过程进行训练的。您应该知道 sd-v1-5.ckpt
,因为基础模型经过了 595K 步骤的训练。 4.2 使用basemodel进行绘画
init_latent
;init_latent
数据并添加相应的噪声♷t♸,此时我们有两个噪声,一个是在上一步的基础上去噪得到的张量x_dec
,另一个是根据原始图像 img_noise_t ❀ 得到的张量。现在我们将两者与mask结合起来,
x_dec_new = mask * img_noise_t + (1-mask) * x_dec
即原始图像的未掩模区域和噪声图像的掩模区域。融合完成得到一张新地图。 modules/sd_samplers_compvis.py
4.3着色附加说明
modules/processing.py
,StableDiffusionProcessingImg››本身。 npainting_fill
变量成员。需要明确的是,该选项控制如何根据初始图像生成 init_latent
(也在 4.2 中进行了描述)。modules/processing.py
,StableDiffusionProcessingImg2Img
5。总结
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。