DALL·E- 2 能够通过自然语言的形容创立事实的图像。Openai 公布了 dall·e- 2 的 Beta 版。在本文中,咱们将认真钻研 DALL·E- 2 的原始钻研论文,并理解其确切的工作形式。因为并没有凋谢源代码,Boris Dayma 等人依据论文创立了一个迷你然而开源的模型 Dall·E Mini(命名为 Craiyon),并且在 craiyon.com 上提供了一个 DEMO。
在本文中,咱们还将应用 Meadowrun(一个开源库,能够轻松地在云中运行 Python 代码)把 DALL·E Mini 生成的图像输出到其余图像处理模型 (GLID-3-xl 和 SwinIR) 中来进步生成图像的品质,通过这种形式来演示如何将开源的 ML 模型部署到咱们的云服务器上(AWS 的 EC2)。
DALL·E- 2 论文要点
DALL·E- 2 基于以前提出的 unCLIP 模型,而 unCLIP 模型实质上是对 GLIDE 模型 [4] 的增强版,通过在文本到图像生成流程中增加基于预训练的 CLIP 模型的图像嵌入。
与 GLIDE 相比,unCLIP 能够生成更多样化的图像,在照片真实感和题目相似性方面损失最小。unCLIP 中的解码器也能够产生多种不同图像,并且能够同时进行文本到图像和图像到图像的生成。
unCLIP 框架
为了对给定的文本生成图像,提出了两阶段的过程:
1)应用先验编码器将文本编码到图像嵌入空间
2)应用图像扩散解码器依据图像嵌入生成图像。
因为它是通过反转 CLIP 图像编码器来生成图像的,因而本文将该框架命名为 unCLIP。
CLIP[3]能够独特学习文本和图像的示意模式,如上图(虚线上方)所示将一对(文本,图像)对雷同的嵌入空间进行编码。
训练过程
给定一个(图像 x,文本 y)对,首先获取图像和文本嵌入,称为 zᵢ= clip(x),zₜ= clip(y)。
先验:p(zᵢ| y,zₜ)产生图像嵌入 zᵢ条件 y。
解码器:P(X |Zᵢ,Y),依据图像嵌入 zᵢ(和可选的文本题目 y)产生图像。
p(x | y)= p(x | y,zₜ)= p(x |zᵢ,y)p(zᵢ| y,zₜ)
训练细节
应用 CLIP 数据 [3] 和 DALL-E[2]数据 (共计 650M 图像) 进行训练。
VIT-H/16 图像编码器:输出为 256×256 图像,总计 32 层 transformers,嵌入尺寸为 1280。
GPT 文本编码器:具备 1024 个嵌入和 24 层 transformers 解码器。
CLIP Model 训练实现后,先验模型、解码器模型和上采样模型都只在 DALL- E 数据集 (总共约 250M 幅) 上训练。
解码器模型是一个 3.5B 的 Glide 模型,蕴含两个模块:1.2B 24 层 transformers 文本编码器和 2.3B 的 ADM 模型。在训练期间,有 50%的概率删除题目,有 10%概率删除图像的嵌入。
为了生成高分辨率图像,作者训练了两个 UPS 采样器模型。两者都应用 ADMNET 体系结构。第一个将图像从 64×64 到 256×256,第二个图像从 256×256 到 1024×1024。
对 GLIDE 模型的改良
与 Glide 相比,Unclip 通过训练先验模型进一步生成了一些示例图像嵌入。因而解码器(ADM 模型)应用了所有输出,包含文本和“假”图像嵌入,生成最终图像。
下面咱们对 DALLE 有了一个大抵的介绍,上面咱们看看如何部署咱们本人的模型
部署 dall·e mini(craiyon)
本文的这部分将介绍不须要 $ 1,700 GPU,就能够部署本人的 dall·e mini 模型,咱们将展现如何运行 Saharmor/Dalle-Playground,并且将 DALL·E Mini 代码包装成一个 HTTP API,而后通过一个简略的网页来调用该 API 生成图像。
Dalle-Playground 提供了一个能够在 Google Colab 中运行的 Jupyter Notebook。然而如果你想长期应用,有时候就会遇到 COLAB 的动静应用限度。这就须要你降级到 Colab Pro($ 9.99/ 月)或 COLAB PRO+($ 49.99/ 月),然而咱们能够通过间接应用 AWS,花几分钱就能搞定这个事。
后期筹备
首先,你须要一个 AWS 账户。如果以前从未在 AWS 上应用过 GPU 实例则须要减少配额。AWS 帐户在每个地区都有限度特定实例类型的配额。GPU 实例配额共有 4 个:
L-3819A6DF:“所有 G 和 VT 实例申请”
L-7212CCBC:“所有 P 实例申请”
L-DB2E81BA:“按需运行 G 和 VT 实例”
L-417A185B:“按需运行 P 实例”
对于一个新的 EC2 帐户,这些都设置为 0,所以如果你运行代码如果失去这个音讯,阐明须要首先申请配额
Unable to launch new g4dn.xlarge spot instances due to the L-3819A6DF quota which is set to 0. This means you cannot have more than 0 CPUs across all of your spot instances from the g, vt instance families. This quota is currently met. Run `aws service-quotas request-service-quota-increase --service-code ec2 --quota-code L-3819A6DF --desired-value X` to set the quota to X, where X is larger than the current quota. (Note that terminated instances sometimes count against this limit: https://stackoverflow.com/a/54538652/908704 Also, quota increases are not granted immediately.)
能够点击下面的 stackoverflow 链接来理解如何申请减少配额。然而申请配额是须要审核的所以个别会要等 1 - 2 天。
而后就是须要装置 Meadowrun。上面是一个在 Linux 中应用 pip 的例子:
$ python3 -m venv meadowrun-venv
$ source meadowrun-venv/bin/activate
$ pip install meadowrun
$ meadowrun-manage-ec2 install --allow-authorize-ips
运行 dall·e mini
下面筹备实现后就能够运行 Dalle-Playground 的后端了
mport asyncio
import meadowrun
async def run_dallemini():
return await meadowrun.run_command(
"python backend/app.py --port 8080 --model_version mini",
meadowrun.AllocCloudInstance("EC2"),
meadowrun.Resources(
logical_cpu=1,
memory_gb=16,
max_eviction_rate=80,
gpu_memory=4,
flags="nvidia"
),
meadowrun.Deployment.git_repo(
"https://github.com/hrichardlee/dalle-playground",
interpreter=meadowrun.PipRequirementsFile("backend/requirements.txt", "3.9")
),
ports=8080
)
asyncio.run(run_dallemini())
下面的代码性能如下:
- run_command 通知 Meadowrun 在 EC2 实例上运行 Python Backend/app.py-port 8080 -model_version mini。这段代码应用 Dalle-playground 后端在端口 8080 上启动了 Dall·e Mini 的迷你版本。这个迷你版本比 Dall·e Mini 的超大(Mega)版本小 27 倍,尽管性能有一些损失,然而占用的资源很少,不便咱们应用。
- 接下来的几行通知 Meadowrun 咱们对云服务的要求是什么:1 CPU,16 GB 内存,并且咱们申请的是可能承受概率 80%中断的抢占实例,抢占实例可能会因为他人的高竞价而中断,如果不想被中断则能够将 max_eviction_rate 更改为 0,也就是咱们当初想要一个按需实例。然而因为按需的破费比拟多,所以 Dall·e Mini 的最低要求是至多 4GB GPU 内存的 NVIDIA GPU。
- 上面就是在 https://github.com/hrichardle… repo 中下载代码,而后装置相应的 python 包,然而这里须要进行一个批改,以将 jax [cuda]软件包增加到 requiending.txt 文件中。JAX 是 Google 的机器学习库,大抵相当于 Tensorflow 或 Pytorch。
- 最初,就是在机器上关上 8080 端口,这样内部能够进行拜访。
运行下面的代码,如果看到相似的输入,阐明曾经能够启动了实例
Launched a new instance for the job: ec2-3-138-184-193.us-east-2.compute.amazonaws.com: g4dn.xlarge (4.0 CPU, 16.0 GB, 1.0 GPU), spot ($0.1578/hr, 61.0% chance of interruption), will run 1 workers
Meadowrun 通知咱们这个实例将破费咱们多少钱(每小时只有 15 美分!)
Building python environment in container eccac6...
接下来,Meadowrun 会基于咱们指定的 requirements.txt 文件的内容构建一个容器。这会破费一些工夫然而在构建实现后 Meadowrun 会对容器的镜像进行缓存(除非 requirements.txt 文件更改,否则不会从新构建)。然而如果有一段时间不必这个镜像,Meadowrun 也会将其清理。
--> Starting DALL-E Server. This might take up to two minutes.
如果你看到下面的音讯,阐明 dalle-playground 曾经胜利下载了,然而它须要进行几分钟的初始化。
--> DALL-E Server is up and running!
这句话阐明曾经胜利运行了,最初就是须要在本地机器上运行前端,而后调用咱们方才运行好的后端代码,如果你没有 npm,还须要装置 node.js:
git clone https://github.com/saharmor/dalle-playground
cd dalle-playground/interface
npm start
在本地运行的前端页面中须要输出咱们方才构建的后端地址,例如 http://xxx.us-east-2.compute…., 如下图所示
咱们输出:olive oil and vinegar drizzled on a plate in the shape of the solar system,看看后果
咱们本人的服务曾经失常的运行了,当初看看成果,在第一组图像中,咱们显然有一个蝙蝠侠般的人物,但他并没有真的在祷告。在第二组图像中,看起来咱们要么失去橄榄油,要么失去行星,但他们也没有在同一幅图像中同时呈现。这可能是因为咱们用的是迷你版的起因,上面让咱们看看“超级”版本的 DALL·E Mini 是否能做得更好。
DALL·E Mega
dall·e Mega 是 Dall·e Mini 的超大版本(超大杯),这意味着它们的体系结构类似,但参数更多。从实践上讲,咱们能够在下面代码中 -model_version mega_full 替换 – model_version mini 就能够。然而这样 Dalle-playground 初始化代码大概须要 45 分钟。因为 Mega 版的预训练文件有 10GB 而咱们下载的带宽只有 35 Mbps。
为了省钱咱们对 Dalle-playground 进行了一些调整,将模型先缓存到 S3 中,再从 S3 中下载。cache_in_s3.py 能够调用 wandb.Api().artifact(” dale -mini/ dale -mini/mega-1:latest”).download()下载预训练模型,而后上传到 S3 中。
要应用 S3 咱们就要创立一个 S3 bucket,并赋予 Meadowrun EC2 角色拜访它:
aws s3 mb s3://meadowrun-dallemini
meadowrun-manage-ec2 grant-permission-to-s3-bucket meadowrun-dallemini
S3 bucket 名称须要全局惟一,而后应用 Meadowrun 在一台更便宜的机器上启动长时间运行的下载工作,下载很简略,只须要很小的内存,也不须要 GPU:
import asyncio
import meadowrun
async def cache_pretrained_model_in_s3():
return await meadowrun.run_command(
"python backend/cache_in_s3.py --model_version mega_full --s3_bucket meadowrun-dallemini --s3_bucket_region us-east-2",
meadowrun.AllocCloudInstance("EC2"),
meadowrun.Resources(1, 2, 80),
meadowrun.Deployment.git_repo(
"https://github.com/hrichardlee/dalle-playground",
branch="s3cache",
interpreter=meadowrun.PipRequirementsFile("backend/requirements_for_caching.txt", "3.9")
)
)
asyncio.run(cache_pretrained_model_in_s3())
而后就是批改模型代码,让它从 S3 而不是从 wandb 下载文件,并且咱们应用 /meadowrun/machine_cache 文件夹,该文件夹能够在一台机器上由 meadowrun 的所有容器共享。这样在同一台机器上屡次运行同一个容器,就不须要从新下载这些文件了。
import asyncio
import meadowrun
async def run_dallemega():
return await meadowrun.run_command(
"python backend/app.py --port 8080 --model_version mega_full --s3_bucket meadowrun-dallemini --s3_bucket_region us-east-2",
meadowrun.AllocCloudInstance("EC2"),
meadowrun.Resources(1, 32, 80, gpu_memory=12, flags="nvidia"),
meadowrun.Deployment.git_repo(
"https://github.com/hrichardlee/dalle-playground",
branch="s3cache",
interpreter=meadowrun.PipRequirementsFile("backend/requirements.txt", "3.9")
),
ports=8080
)
asyncio.run(run_dallemega())
最初须要留神的是:Meadowrun 的装置会设置了一个 AWS Lambda 并且定期运行,如果有一段时间没有运行作业,它会主动清理实例。当然你也能够手动清理实例, 命令如下:
meadowrun-manage-ec2 clean
上面看看成果:
看样子很不错了,然而这些图像还不能与 OpenAI 的 DALL·E 等量齐观,因为咱们本人也没法像 OpenAI 的 DALL·E 那样训练模型,但咱们能够尝试增加一个扩散模型来改良图像中的更精密的细节。咱们还将增加一个模型来放大图像,因为它们当初只有 256×256 像素。
构建咱们本人的图像生成模型
在本文的后半局部,咱们将应用 meadowdata/meadowrun-dallemini-demo,来优化模型生成的图像,这个想法来自于 jina-ai/dalle-flow。
DALL·E Mini: 咱们在文章的上半局部曾经做了介绍了,DALL·E 是两种模型的组合。第一个模型以图像为训练对象,学习如何将图像“压缩”为向量,而后将这些向量“解压缩”回原始图像。第二个模型在图像 / 题目对上进行训练,并学习如何将题目转换为图像向量。训练完结后,咱们能够在第二个模型中输出新的文本并产生一个图像向量,而后将该图像向量输出到第一个模型中,产生一个新的图像。
GLID-3-xl: 扩散模型。扩散模型是通过,含糊(又名扩散)图像并在原始 / 含糊图像对上训练模型来训练的。该模型学会从含糊版本重建原始图像。扩散模型可用于各种工作,咱们这里将应用 GLID-3-XL 优化图像中的细节。
SwinIR: 图像缩放模型(又叫图像复原)。图像复原模型是通过对图像进行降尺度解决来训练的。该模型学习从放大后的图像产生原始的高分辨率图像。
git clone https://github.com/meadowdata/meadowrun-dallemini-demo
cd meadowrun-dallemini-demo
# assuming you are already in a virtualenv from before
pip install -r local_requirements.txt
jupyter notebook
咱们编辑 S3_BUCKET_NAME 和 S3_BUCKET_REGION,以匹配在下面中创立的存储桶。
咱们这里对一些重要的代码所做简略的正文:
调整了所有模型随附的示例代码减少了 S3 缓存的局部,并在 dalle_wrapper.py,glid3xl_wrapper.py 和 swinir_wrapper.py 中提供易于应用的接口。
所有模型在 Linux 以外的任何其余操作上都可能无奈运行,所以将 local_requirement.txt 从 model_requirentess.txt 离开,这样在 Windows 或 Mac 上也都没有问题了。
当初这些模型是作为批处理作业来运行的,Meadowrun 将重用单个 EC2 实例。如果你有趣味(钱)也能够应用 meadow.run_map 在多台 GPU 机器上并行运行这些模型。
让咱们看看后果吧!DALL·E Mini 生成 8 张图片:
咱们抉择一张图片时,GLID-3-xl 会依据抉择的图片生成 8 张新的图片。
而后咱们抉择其中一张图片,并将其从 256×256 降级到 1024×1024 像素:
看着还不错啊,
以下是 OpenAI 的 DALL·E 从雷同的内容:
看看另外一个的比拟:
这是 OpenAI 的
OpenAI 的 DALL·E 的成果还是最好的,毕竟鼎力出奇观么。然而通过咱们优化的 DALL·E Mini 也还过的去,毕竟是开源的并且随着一直的训练它会变得更好。
总结
这篇文章介绍 DALL·E- 2 论文的一些要点,并且演示了如何应用 Meadowrun 来部署他的一个开源版本的实现,如果你有趣味,能够依照咱们提供的流程搭建一个属于本人的图像生成服务。
援用:
[1] Aditya Ramesh et al.“Hierarchical Text-Conditional Image Generation with CLIP Latents.”arXiv:2204.06125, 2022
[2] Aditya Ramesh et al.“Zero-Shot Text-to-Image Generation.”arXiv:2102.12092, 2021.
[3] Alec Radford et al.“Learning Transferable Visual Models From Natural Language Supervision.”arXiv:2103.00020, 2021.
[4] Alex Nichol et al.“GLIDE: Towards Photorealistic Image Generation and Editing with Text-Guided Diffusion Models.”arXiv:2112.10741, 2021.
[5] https://avoid.overfit.cn/post/8f08832ec42d402a836a5c3f5ee0440d