前言
终于开写本CV多模态系列的核心主题:stable diffusion相关的了,为何执着于想写这个stable diffusion呢,源于三点
- 去年stable diffusion和midjourney很火的时候,就想写,因为经常被刷屏,但那会时间错不开
- 去年11月底ChatGPT出来后,我今年1月初开始写ChatGPT背后的技术原理,而今年2月份的时候,一读者“天之骄子呃”在我这篇ChatGPT原理文章下面留言:“点赞,十年前看你的svm懂了,但感觉之后好多年没写了,还有最近的AI绘画 stable diffusion 相关也可以写一下以及相关的采样加速算法
我当时回复到:哈,十年之前了啊,欢迎回来,感谢老读者、老朋友
确实非常非常多的朋友都看过我那篇SVM笔记,影响力巨大,但SVM笔记之后,也还是写了很多新的博客/文章滴,包括但不限于:xgboost、CNN、RNN、LSTM、BERT等
今后基本每季度都有更新的计划,欢迎常来
关于Stable Diffusion,可以先看下这篇图解Stable Diffusion的文章”(此篇文章也是本文的参考之一) - 今年3月中旬,当OpenAI宣称GPT4具备了CV多模态的能力之后,让我对AI绘画和CV多模态有了更强的动力去研究探索,并把背后的技术细节写出来
其实当时就想写了,但当时因为写各种开源平替模型的原理、部署、微调去了,所以一直没来得及写,包括之前计划的100篇论文也因此耽搁
4.23,我所讲的ChatGPT原理课开课之后,终于有时间开写这篇多模态博客,然想写清楚stable diffusion和midjourney背后的技术细节,不得不先从扩散模型开始,于此便有了上一篇《AI绘画能力的起源:从VAE、扩散模型DDPM、DETR到ViT/MAE/Swin transformer》「且如果你此前不了解何谓扩散模型、何谓DDPM,务必先看该文,不然没法看懂本文」
援引上一篇文章的这段话“AI绘画随着去年stable diffusion和Midjourney的推出,使得文生图火爆异常,各种游戏的角色设计、网上店铺的商品/页面设计都用上了AI绘画这样的工具,更有不少朋友利用AI绘画取得了不少的创收,省时省力还能赚钱,真香”
沿着上文之后,本文将写清楚下面表格中带下划线的模型
1月 | 3月 | 4月 | 5月 | 6月 | 8月 | 10月 | 11月 | |
2020 | DETR | DDPM | DDIM VisionTransformer | |||||
2021 | CLIP DALL·E | SwinTransformer | MAE SwinTransformerV2 | |||||
2022 | BLIP | DALL·E 2 | StableDiffusion BEiT-3 Midjourney V3 | |||||
2023 | BLIP2 | VisualChatGPT GPT4 Midjourney V5 | SAM(Segment Anything Model) | FastSAM (中科院版SAM) MobileSAM |
且过程中会顺带介绍MiniGPT-4、VisualGPT到HuggingGPT、AutoGPT这几个模型
第一部分 从CLIP到BLIP1/BLIP2、DALLE/DALLE 2
1.1 CLIP:基于对比文本-图像对的预训练方法
我第一次见识到CLIP这个论文的时候,当时的第一反应是,特么也太强悍了..
CLIP由OpenAI在2021年1月发布
- 通过超大规模模型预训练提取视觉特征,进行图片和文本之间的对比学习(简单粗暴理解就是发微博/朋友圈时,人喜欢发一段文字然后再配一张或几张图,CLIP便是学习这种对应关系)
- 且预训练好之后不微调直接推理(即zero-shot,用见过的图片特征去判断没见过的图片的类别,而不用下游任务训练集进行微调),使得在ImageNet数据集上,CLIP模型在不使用ImageNet数据集的任何一张图片进行训练的的情况下,最终模型精度能跟一个有监督的训练好的ResNet-50打成平手(在ImageNet上zero-shot精度为76.2%,这在之前一度被认为是不可能的)
为了训练CLIP,OpenAI从互联网收集了共4个亿的文本-图像对,论文称之为WIT(Web Image Text。WIT质量很高,而且清理的非常好,其规模相当于JFT-300M,这也是CLIP如此强大的原因之一(后续在WIT上还孕育出了DALL-E模型)
其训练过程如下图所示:
- 如下图的第一步所示,CLIP的输入是一对对配对好的的图片-文本对(比如输入是一张狗的图片,对应文本也表示这是一只狗),这些文本和图片分别通过Text Encoder和Image Encoder输出对应的特征。然后在这些输出的文字特征和图片特征上进行对比学习
假如模型输入的是n对图片-文本对,那么这n对互相配对的图像–文本对是正样本(下图输出特征矩阵对角线上标识蓝色的部位),其它对样本都是负样本,这样模型的训练过程就是最大化n个正样本的相似度,同时最小化个负样本的相似度
Text Encoder可以采用NLP中常用的text transformer模型
而Image Encoder可以采用常用CNN模型或者vision transformer等模型
相似度是计算文本特征和图像特征的余弦相似性cosine similarity
之后,CLIP可以直接实现zero-shot的图像分类,即不需要任何训练和微调,其实现zero-shot分类只需要简单的两步,如下第2、3点所示 - 根据任务的分类标签构建每个类别的描述文本:A photo of {label},然后将这些文本送入Text Encoder得到对应的文本特征,如果类别数目为n,那么将得到n个文本特征
- 将要预测的图像送入Image Encoder得到图像特征,然后与n个文本特征计算缩放的余弦相似度(和训练过程保持一致),然后选择相似度最大的文本对应的类别作为图像分类预测结果
进一步地,可以将这些相似度看成logits,送入softmax后可以到每个类别的预测概率
以下是对应的伪代码
# image_encoder - ResNet or Vision Transformer
# text_encoder - CBOW or Text Transformer
# I[n, h, w, c] - 输入图片维度
# T[n, l] - 输入文本维度,l表示序列长度
# W_i[d_i, d_e] - learned proj of image to embed
# W_t[d_t, d_e] - learned proj of text to embed
# t - learned temperature parameter
# 分别提取图像特征和文本特征
I_f = image_encoder(I) #[n, d_i]
T_f = text_encoder(T) #[n, d_t]
# 对两个特征进行线性投射,得到相同维度的特征d_e,并进行l2归一化,保持数据尺度的一致性
# 多模态embedding [n, d_e]
I_e = l2_normalize(np.dot(I_f, W_i), axis=1)
T_e = l2_normalize(np.dot(T_f, W_t), axis=1)
# 计算缩放的余弦相似度:[n, n]
logits = np.dot(I_e, T_e.T) * np.exp(t)
# symmetric loss function
labels = np.arange(n) # 对角线元素的labels
loss_i = cross_entropy_loss(logits, labels, axis=0) # image loss
loss_t = cross_entropy_loss(logits, labels, axis=1) # text loss
loss = (loss_i + loss_t)/2 # 对称式的目标函数
2021年10月,Accomplice发布的disco diffusion,便是第一个结合CLIP模型和diffusion模型的AI开源绘画工具,其内核便是采用的CLIP引导扩散模型(CLIP-Guided diffusion model)
且后续有很多基于CLIP的一系列改进模型,比如Lseg、GroupViT、ViLD、GLIP
1.2 从BLIP1、BLIP2到miniGPT4
1.2.1 BLIP1:ViT + BERT ——通过encoder-decoder统一理解与生成任务
随着AI的迅速发展,多模态日渐成为一种趋势,而Vision-Language Pre-training (VLP) + Fine-tuning => Zero Shot / Few Shot 的模式是 快速 解决 多下游任务 的一个好的模式,VLP 是这个模式的开端,所以对于 VLP 的相关研究也很多。BLIP 是一个新的 VLP 架构,可以灵活、快速的应用到下游任务,如:图像-文本检索、图像翻译、以及 VQA 等
简单来讲,BLIP的主要特点是结合了encoder和decoder,形成了统一的理解和生成多模态模型。再利用BLIP进行后续工作的时候,既可以使用其理解的能力(encoder),又可以利用其生成的能力(decoder),拓展了多模态模型的应用
1.2.1.1 BLIP的模型结构
CLIP 采用了 image-encoder (ViT / ResNet) & text-encoder (transformer),然后直接拿 图片特征 和 文本特征 做余弦相似度对比,得到结果,而BLIP 的做法要复杂挺多
如下图所示,为了预训练一个同时具有理解和生成能力的统一模型,BLIP模型主要由4个部分组成,从左至右分别是
- 上图第1部分:视觉编码器Image Encoder(ViT)——提取图片特征
视觉编码器本质就是 ViT 的架构:将输入图像分割成一个个的 Patch 并将它们编码为一系列 Image Embedding,并使用额外的 [CLS] token 来表示全局的图像特征 - 上图第2部分:文本编码器Text Encoder(BERT)——提取文本特征
文本编码器就是 BERT 的架构,其中 [CLS] token 附加到文本输入的开头以总结句子,作用是提取文本特征与第1部分的图像特征做对比学习
在这个过程中会训练一个对比学习目标函数 (Image-Text Contrastive Loss, ITC)
ITC 作用于第1部分的视觉编码器(ViT)和第2部分的文本编码器(BERT),目标是对齐视觉和文本的特征空间,方法是使得正样本图文对的相似性更大,负样本图文对的相似性更低,在 ALBEF 里面也有使用到。作者在这里依然使用了 ALBEF 中的动量编码器,它的目的是产生一些伪标签,辅助模型的训练
为方便对比,把BLIP的模型结构图再贴一遍
- 上图第3部分:视觉文本编码器Image-grounded Text Encoder(变种 BERT)——BERT中插入交叉注意层,从而针对图片特征和文本特征做二分类
视觉文本编码器的具体做法是在文本编码器比如BERT的每个transformer block的自注意(Bi Self-Att)层和前馈网络(Feed Forward)之间额外插入一个交叉注意(Cross-Attention),以引入视觉特征,作用是根据 ViT 给的图片特征和文本输入做二分类,所以使用的是编码器,且注意力部分是双向的 Self-Attention,且添加一个额外的 [Encode] token,作为图像文本的联合表征
在这个过程中则训练一个图文匹配目标函数 (Image-Text Matching Loss, ITM)
ITM 作用于第1部分的视觉编码器和第3部分的视觉文本编码器,是一个二分类任务,目标是学习图像文本的联合表征,使用一个分类头来预测 image-text pair 的 正匹配 还是 负匹配,目的是学习 image-text 的多模态表示,调整视觉和语言之间的细粒度对齐,作者在这里依然使用了 ALBEF 中的 hard negative mining 技术
- 上图第4部分:视觉文本解码器Image-grounded Text Decoder(变种 BERT)——根据图片特征和文本特征做文本生成
视觉文本解码器使用 Cross-Attention,作用是根据 ViT 给的图片特征和文本输入做文本生成的任务,所以使用的是解码器,且将 上图第3部分的 Image-grounded Text Encoder 结构中的 Bi Self-Att 替换为 Causal Self-Att,目标是预测下一个 token,且添加一个额外的 [Decode] token 和结束 token,作为生成结果的起点和终点
一个需要注意的点是:相同颜色的部分是参数共享的,即视觉文本编码器和视觉文本解码器共享除 Self-Attention 层之外的所有参数。每个 image-text 在输入时,image 部分只需要过一个 ViT 模型,text 部分需要过3次文本模型
过程中训练一个语言模型目标函数 (Language Modeling Loss, LM)
毕竟由于BLIP 包含解码器,用于生成任务。既然有这个任务需求,那就意味着需要一个针对于生成任务的语言模型目标函数,LM 作用于第1部分的视觉编码器和第4部分的视觉文本解码器,目标是根据给定的图像以自回归方式来生成关于文本的描述。与 VLP 中广泛使用的 MLM 损失(完形填空)相比,LM 使模型能够将视觉信息转换为连贯的字幕
1.2.1.2 BLIP的字幕与过滤器方法CapFiltg
上述整个过程中,有一个不可忽略的问题,即高质量的人工注释图像-文本对(例如,COCO) 因为成本高昂所以数量不多
- CLIP 的数据来源于 Web 上爬来的 图像-文本对,所以数据集很容易扩充的很大,而且采用 对比学习的方式,基本属于自监督了,不太需要做数据标注;
- BLIP 改进了 CLIP 直接从 Web 取数据 噪声大 的缺点,提出了 Captioning and Filtering (CapFilt) 模块,这个模块就是用来 减小噪声、丰富数据的,主要包括两个模块:即字幕与过滤器方法CapFilt (Captioning and Filtering)
如下图所示
CapFilt 方法包含两个模块:
- 字幕器 Captioner:相当于给一张网络图片,生成字幕。它是一个视觉文本解码器(对应于上述BLIP模型结构的第4部分),在 COCO数据集上使用 LM 目标函数微调,对给定图像的文本进行解码,从而实现给定网络图片,Captioner 生成字幕的效果
- 过滤器 Filter:过滤掉噪声图文对image-text pair,它是一个视觉文本编码器(对应于上述BLIP模型结构的第3部分),看文本是否与图像匹配,在 COCO 数据集上使用 ITC 和 ITM 目标函数微调
Filter 删除原始 Web 文本和合成文本 中的嘈杂文本,如果 ITM 头将其预测为与图像不匹配,则认为文本有噪声
最后,将过滤后的图像-文本对与人工注释对相结合,形成一个新的数据集,作者用它来预训练一个新的模型
下图展示了被过滤器接受和拒绝的文本可视化(绿色 文本是被 filter 认可的,而 红色 文本是被 filter 拒绝的)
1.2.2 BLIP2:CLIP ViT-G/14 + Q-Former + FLAN-T5
下图是BLIP-2的模型结构 (论文地址:BLIP-2: Bootstrapping Language-Image Pre-training with Frozen Image Encoders and Large Language Models),其中视觉侧和文本侧分别使用预训练的CLIP ViT-G/14模型和FLAN-T5模型,仅中间的起桥接作用的Q-Former参与训练,训练需要的成本和数据量进一步降低,BLIP-2的训练数据量仅129M,16卡A100训练9天
- 后来的LLAVA工作更是将这一思路简化到极致,仅通过一个projection layer将CLIP ViT-L/14和Vicuna语言模型缝合在一起,训练数据仅用了595K图文对以及158K指令微调数据
- miniGPT4则是在复用BLIP-2的vision encoder + Q-Former的基础上,通过一层project layer缝合了Vicuna语言模型,训练数据仅用了5M的图文对数据+3.5K的指令微调数据
1.2.3 MiniGPT4:基于LLaMA微调的Vicuna + BLIP2 + 线性投影层
MiniGPT-4具有许多类似于GPT-4所展示的功能,如详细的图像描述生成和从手写草稿创建网站,以及根据给定图像编写灵感的故事和诗歌,为图像中显示的问题提供解决方案,比如教用户如何根据食物照片烹饪等
模型结构
miniGPT4的模型架构由一个语言模型拼接一个视觉模型,最后加一个线性投影层来对齐,具体而言
-
它先是使用基于LLaMA微调的小羊驼Vicuna,作为语言解码器
-
在视觉感知方面,采用了与BLIP-2相同的预训练视觉组件(该组件由EVA-CLIP[13]的ViT- G/14和Q-Former组成)
-
再之后,增加了一个单一的投影层,将编码的视觉特征与语言模型小羊驼对齐,并冻结所有其他视觉和语言组件
模型训练:预训练(500万图像文本对)-微调
训练上,还是经典的预训练-微调模式
- 在整个预训练过程中,无论是预训练的视觉编码器还是LLM都保持冻结状态,只有线性投影层被预训练。具体是使用Conceptual Caption、SBU和LAION的组合数据集来训练我们的模型,历经2万个训练步骤,批大小为256,覆盖了大约500万对图像-文本,整个过程花费大约10小时,且使用的4个A100 (80GB) gpu
- 然而,简单地将视觉特征与LLM对齐不足以训练出像聊天机器人那样具有视觉会话能力的高性能模型,并且原始图像-文本对背后的噪声可能导致语言输出不连贯。因此,我们收集了另外3500个高质量对齐的图像-文本对,用设计好的会话模板进一步微调模型(只需要400个训练步骤,批量大小为12,使用单个A100 GPU最终7分钟即可完成),以提高生成语言的自然度及其可用性
1.3 从DALLE到DALLE 2
1.3.1 DALL-E:Zero-Shot Text-to-Image Generation
有趣的是,DALL-E和CLIP一样,也是21年年初发布的,对应论文为《Zero-Shot Text-to-Image Generation》,且数据集:2.5 亿个图像文本对 + 120 亿参数
通过上一篇文章可知,VQ-VAE的生成模式是pixcl-CNN +codebook,其中pixcl-CNN就是一个自回归模型,OpenAI 将pixcl-CNN换成GPT,再加上那会多模态相关工作的火热进展,可以考虑使用文本引导图像生成,所以就有了DALL·E
DALL·E和VQ-VAE-2一样,也是一个两阶段模型:
- Stage1:Learning the Visual Codebook
先是输入:一对图像-文本对(训练时)
之后编码特征
一方面,文本经过BPE编码得到256维的特征
二方面,图像(256×256)经过VQ-VAE得到图片特征(就是上面训练好的VQ-VAE,将其codebook直接拿来用,维度下降到32×32) - Stage2:Learning the Prior
重构原图
将拉直为1024维的tokens,然后连上256维的文本特征,这样就得到了1280维的token序列,然后直接送入GPT(masked decoder)重构原图
推理时,输入文本经过编码得到文本特征,再将文本通过GPT利用自回归的方式生成图片。生成的多张图片会通过CLIP模型和输入的文本进行相似度计算,然后调出最相似(描述最贴切)的图像
1.3.2 DALL-E 2
对于DALL·E2而言,基本就是整合了CLIP和基于扩散模型的GLIDE,而后者则采用了两阶段的训练方式:文本 → 文本特征 → 图片特征 → 图片
- CLIP训练过程
如上图所示,CLIP的输入是一对对配对好的的图片-文本对(根据对应文本一条狗,去匹配一条狗的图片),这些文本和图片分别通过Text Encoder和Image Encoder输出对应的特征。然后在这些输出的文字特征和图片特征上进行对比学习 - DALL·E2:prior + decoder
上面的CLIP训练好之后,就将其冻住了,不再参与任何训练和微调,DALL·E2训练时,输入也是文本-图像对,下面就是DALL·E2的两阶段训练:
阶段一 prior:根据文本特征(即CLIP text encoder编码后得到的文本特征),预测图像特征(CLIP image encoder编码后得到的图片特征)
换言之,prior模型的输入就是上面CLIP编码的文本特征,然后利用文本特征预测图片特征(其ground truth就是CLIP编码的图片特征),就完成了prior的训练
推理时,文本还是通过CLIP text encoder得到文本特征,然后根据训练好的prior得到类似CLIP生成的图片特征,此时图片特征应该训练的非常好,不仅可以用来生成图像,而且和文本联系的非常紧(包含丰富的语义信息)
阶段二 decoder:常规的扩散模型解码器,解码生成图像
这里的decoder就是升级版的GLIDE,所以说DALL·E2 = CLIP + GLIDE
第二部分 通俗理解stable diffusion:文本到图像的潜在扩散模型(改进版DDPM)
2.1 SD与DDPM的对比
我们在上篇博客《AI绘画能力的起源:从VAE、扩散模型DDPM、DETR到ViT/MAE/Swin transformer》中,已经详细介绍了扩散模型DDPM,为方便对后续内容的理解,特再回顾下DDPM相关的内容(至于详细的请看上篇博客):
- 前向过程加噪
- 逆向过程去噪,由于反向扩散过程不可直接计算,因此训练神经网络εθ来近似它,训练目标(损失函数)如下
所以,DDPM的关键是训练噪声估计模型,使其预测的噪声 与真实用于破坏的噪声 相近,具体怎么个训练过程呢?
比如可以选择选择一个训练图像,例如海边沙滩的照片,然后生成随机噪声图像,通过将此噪声图像添加到一定数量的步骤来损坏训练图像
然后通过一个噪声估计器U-Net 预测添加的噪声,使其与实际噪声做差异对比,从而建立损失函数做反向传播,最后更新噪声估计器的参数,说白了,就是通过告诉U-Net 我们在每一步添加了多少噪声,从而手把手一步步教U-Net 怎么去估计噪声 U-Net训练好了之后,我们便可以基于训练好的 U-Net 来生成图像:原理很简单,通过噪声估计器预测出噪声后,不模糊的图片便减去每一步添加的噪声以清晰化 不就ok了么
而如果用一句话介绍stable diffusion,可以理解为:改进版的DDPM,Stable Diffusion原来的名字叫“Latent Diffusion Model”(LDM),很明显就是扩散过程发生隐空间中(即latent space,下文或其他地方也有说潜在空间或压缩空间之类的,都一个意思),其实就是对图片做了压缩
不过,为何要弄这么个隐空间或潜在空间呢?
原因很简单,为了使扩散模型在有限的计算资源上训练,并且保留它们的质量和灵活性,故首先训练了一个强大的预训练自编码器,这个自编码器所学习到的是一个潜在的空间,这个潜在的空间要比像素空间要小的多,把扩散模型在这个潜在的空间去训练,大大的降低了对算力的要求,这也是Stable Diffusion比Diffusion速度快的原因
总之,Stable Diffusion会先训练一个自编码器,来学习将图像压缩成低维表示
- 通过训练好的编码器,可以将原始大小的图像压缩成低维的latent data(图像压缩)
- 通过训练好的解码器,可以将latent data还原为原始大小的图像
在将图像压缩成latent data后,便可以在latent space中完成扩散过程,对比下和Diffusion扩散过程的区别,如下图所示:
可以看到Diffusion扩散模型就是在原图 上进行的操作,而Stale Diffusion是在压缩后的图像 上进行操作
2.2 理解stable diffusion的三层境界
2.2.1 第一层境界:不看公式只看意图整体理解SD
SD的整体框架流程图
stable diffusion和上面DALL E2的原理其实差不多,具体而言,会先后经历以下几个步骤(左边红色是像素空间 pixel space 含编码器和解码器、中间绿色区域是潜在空间latent space、右边灰色的是条件 condition)
- 潜在空间(Latent Space)
图像编码器将图像从515✖️512的像素空间(Pixel Space)压缩到更小维度4✖️64✖️64的潜在空间(Latent Space) - 针对潜在空间的图片做扩散:添加噪声
对潜在空间Latent Space中的图片添加噪声,进行扩散过程(Diffusion Process) - 根据用户的输入text/prompt 获取去噪条件
通过 CLIP的文本编码器 将输入的描述语(text/prompt)转换为去噪过程的条件(Conditioning) - 噪声估计器U-Net 预测噪声,然后依据「去噪条件」去噪:生成图片的潜在表示
首先,噪声预测器 U-Net 将潜在噪声图像和文本提示作为输入,并预测噪声,也在潜在空间(4x64x64 张量)中
之后,基于上面第3步的条件对图像通过 噪声估计器U-NET 进行去噪(Denoising),以获得生成图片的潜在表示
当然了,去噪步骤可以灵活地以文本、图像和其他形式为条件,比如以文本为条件即text2img、以图像为条件即 img2img - 潜在空间转换成最终图像
图像解码器通过将图像从潜在空间转换回像素空间来生成最终图
问题1:怎么理解潜在空间
如何理解 “潜在空间” 呢?
- 大家都有自己的身份证号码,前 6 位代表地区、中间 8 位代表生日、后 4 位代表个人其他信息。放到空间上如图所示,这个空间就是「人类潜在空间」 这个空间上相近的人,可能就是生日、地区接近的人。人可以对应为这个空间的一个点,这个空间的一个点也对应一个人。如果在空间中我的附近找一个点,对应的人可能跟我非常相似,没准就是我失散多年的兄弟
- AI 就是通过学习找到了一个「图片潜在空间」,每张图片都可以对应到其中一个点,相近的两个点可能就是内容、风格相似的图片
问题2:CLIP的应用举例
如果让你把左侧三张图和右侧三句话配对,你可以轻松完成这个连线。但对 AI 来说,图片就是一系列像素点,文本就是一串字符,要完成这个工作可不简单。
原因在于
- 这需要 AI 在海量「文本-图片」数据上学习图片和文本的匹配。图中绿色方块是「图片潜在空间」的 N 张图片,紫色方块是「文本潜在空间」的 N 句描述语。AI 会努力将对应的 I1 与 T1 (蓝色方块)匹配,而不是 I2 与 T3 (灰色方块)匹配。这个 AI 就是广泛被用在 AI 作画中的 CLIP(Contrastive Language-Image Pre-Training / 对比式语言-文字预训练)
- 当 AI 能成功完成这个连线,也就意味着 AI 建立了「文字潜在空间」到「图片潜在空间」的对应关系,这样才能通过文字控制图片的去噪过程,实现通过文字描述得到图像的生成
2.2.2 第二层境界:依托公式深入模型结构
SD的模型结构:autoencoder + CLIP text encoder + UNet
还是看这个图
- 上图最左侧:编码输入/解码输出
编码器encoder 可以对图像进行压缩,可以理解为它能忽略图片中的高频信息,只保留重要的深层特征,将其压缩到一个 latent space「维度为(4, 64, 64)」,然后我们可以在这个 latent space 中进行 Diffusion Process,将其结果作为 U-Net 的输入
解码器decoder 负责将去噪后的 latent 图像恢复到原始像素空间「各维度为:(3,512,512),即(红/绿/蓝, 宽, 高)」
这个就是所谓的感知压缩(Perceptual Compression),它将高维特征压缩到低维,然后再在低维空间上进行操作的方法具有普适性,可以很容易的推广到文本、音频、视频等不同模态的数据上 - 上图最右侧:用户的输入text或prompt
通过CLIP的text encoder提取输入text的text embeddings(维度为77✖️768,意味着77个token嵌入向量,其中每个向量包含768个维度)
然后通过cross attention方式送入噪声估计模型UNet中作为去噪条件condition
事实上,扩散模型可以理解为一个时序去噪自编码器,我们需要训练使得预测的噪声与真实噪声相近,则目标函数为:
而在 Latent Diffusion Models 中,引入了预训练的感知压缩模型,它包含一个编码器和一个解码器,这样就可以在训练时利用 得到 latent representation ,从而让模型在潜在表示空间中学习,其目标函数为:
对于条件生成任务,我们将拓展为:,这样就可以通过来控制图片合成的过程,通过在 UNet 上增加 cross-attention 机制来实现
而为了能够从不同的模态预处理,论文引入了一个领域专用编码器,它用来将映射成一个中间表示,这样我们就可以很方便的引入各种形式的条件,例如文本、类别、layout等,最终模型可
通过一个 cross-attention 将条件引导信息融入到 UNet 中,cross-attention 表示为:
其中是 UNet 的一个中间表征,则目标函数可以写为: - 上图中底部:基于噪声估计模型U-Net实现文本条件引导下的latent生成
加噪后的隐式表达和文本语义表征通过Attention的方式输入到U-Net,用以更好的学习文本和图像的匹配关系,这里文本的语义向量就是条件(用户的输入text或prompt),控制图像生成往我们想要的方向发展,通过U-Net来预测每一步要减少的噪声
然后计算网络输出噪声和真实噪声的差距,最小化损失来反向传播更新参数,注意整个训练阶段VAE是冻结的
下图亦可辅助理解
2.2.3 第三层境界:从源码层面理解SD
// 待更
第三部分 Midjourney V5
// 待更
参考文献与推荐阅读
- Learning Transferable Visual Models From Natural Language Supervision
CLIP原始论文 - CLIP 论文逐段精读,这是针对该视频解读的笔记之一:CLIP和改进工作串讲
- BLIP: Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generation
BLIP原始论文 - 多模态超详细解读 (六):BLIP:统一理解和生成的自举多模态模型
极智AI | 多模态新姿势 详解 BLIP 算法实现 - 理解DALL·E 2, Stable Diffusion和 Midjourney工作原理
- 读完 DALL-E 论文,我们发现大型数据集也有平替版
- Hierarchical Text-Conditional Image Generation with CLIP Latents
DALL E2原始论文 - DALL·E 2(内含扩散模型介绍),这是针对该视频解读的笔记
- The Illustrated Stable Diffusion,这是图解SD的翻译版
- Stable Diffusion Clearly Explained!
How does Stable Diffusion paint an AI artwork? Understanding the tech behind the rise of AI-generated art. - Getting Started With Stable Diffusion
- High-Resolution Image Synthesis with Latent Diffusion Models
- 知乎上关于SD原理的几篇文章:Stable Diffusion 的技术原理是什么?、人工智能Ai画画——stable diffusion 原理和使用方法详解、十分钟读懂Stable Diffusion
- Memory-efficient array redistribution through portable collective communication
- stable diffusion 原理介绍 - AI绘画每日一帖
- How does Stable Diffusion work?
- Stable Diffusion 原理介绍与源码分析(一)
- 保姆级讲解 Stable Diffusion
- 李宏毅生成式AI模型diffusion model/stable diffusion概念讲解
首发之后的创作、修改、新增记录
- 端午假期三天,持续完善BLIP/BLIP2、DALLE/DALLE 2等相关的内容
- 6.25,开始写SD的原理部分
- 6.26,考虑到公式太多 容易把初学者绕晕,故把理解SD划分为三层境界
第一层境界 不涉及任何公式,从意图层面整体理解SD
且初步写清SD的基本逻辑
顺带感叹,这几天在网上反复看了大量关于stable diffusion原理的解读文章
我站在初学者角度上,没有一篇令我满意
我也不知道怎么回事,把文章写通俗没有那么难啊.. - 6.27,修改SD的原理部分,以让逻辑清晰明确
- 6.28,写清楚DALL·E2的模型架构
- 6.29,写DALL·E的部分,并梳理全文逻辑
断断续续两个月,总算通过本文和上一篇文章把SD相关的基本写清楚了,后续就是不断优化所有行文细节
以让逻辑更清晰 细节更明确,初学最爱看
感叹过程中 被各种资料反复绕晕过,好在 终究还是像之前解读各种稍复杂点的模型一样
一如既往的绕出来了 - 7.7,优化对潜在空间的说明描述