PaddleFormers 文图生成实战:disco_diffusion_clip_rn50 模块原理、API 调参与服务部署全指南
【免费下载链接】PaddleFormersPaddleFormers is an easy-to-use library of pre-trained large language model zoo based on PaddlePaddle.项目地址: https://gitcode.com/gh_mirrors/pa/PaddleFormers
本篇技术指南以 PaddleFormers 仓库中 disco_diffusion_clip_rn50 模块 为核心,系统讲解该文图(text-to-image)生成模型的原理构成、安装方式、命令行与 Python API 两种预测途径、全部核心调参项,以及基于 PaddleHub Serving 的在线服务部署方案。读完本文,你将能够在本地复现"输入一句自然语言 Prompt,生成与之语义匹配的绘画作品"的完整流程,并掌握扩散模型 + CLIP 双模型协同工作的底层机制。
一、模块基本信息与模型原理
1.1 模块概览
| 项目 | 说明 |
|---|---|
| 模块名称 | disco_diffusion_clip_rn50 |
| 类别 | text to image(文图生成) |
| 网络结构 | dd + clip ResNet50 |
| 训练数据集 | - |
| 是否支持 Fine-tuning | 否 |
| 模块大小 | 2.8GB |
| 最新更新日期 | 2022-08-02 |
| 数据指标 | - |
1.2 模型构成:扩散模型 + CLIP 多模态预训练模型
disco_diffusion_clip_rn50 由两部分组成(该说明来自 模块 README):
- 扩散模型(Diffusion Model):一种生成模型,可以从噪声输入中重建出原始图像。在本模块中,它负责从初始噪声(或指定的初始图像)出发,逐步生成目标图像。
- 多模态预训练模型(CLIP):能够将文本和图像表示在同一个特征空间,语义相近的文本与图像在该空间中距离更近。本模块中 CLIP 负责引导扩散模型生成的图像语义尽可能接近输入文本的语义。
整个生成过程可以概括为:扩散模型在 CLIP 的引导下不断迭代生成新图像,最终生成文本所描述内容的图像。
从源码实现看,模块的 CLIP 视觉编码器为 ResNet50(ModifiedResNet)结构,实现在 clip/clip/model.py 中。与标准 ResNet 相比,该实现有三处改动:3 层 stem 卷积并使用平均池化替代最大池化;对 stride > 1 的卷积前置 avgpool 做抗锯齿处理;最终池化层采用 QKV 注意力(AttentionPool2d)而非平均池化。扩散主干则采用无类别条件的 UNet 结构(配置见 reverse_diffusion/helper.py 中512x512_diffusion_uncond_finetune_008100模型:image_size=512、num_channels=256、num_res_blocks=2、learn_sigma=True、noise_schedule='linear')。
更深入的理论背景可参阅论文Diffusion Models Beat GANs on Image Synthesis与Learning Transferable Visual Models From Natural Language Supervision。
二、安装与环境依赖
2.1 环境依赖
paddlepaddle >= 2.0.0paddlehub >= 2.2.0
PaddleHub 的安装方法参见 PaddleHub 安装文档。
2.2 安装模块
$ hub install disco_diffusion_clip_rn50如安装遇到问题,可参考各平台的零基础安装指南:Windows 快速开始、Linux 快速开始、Mac 快速开始。
模块运行还依赖一组 Python 第三方库,记录在 requirements.txt 中,包括numpy、paddle_lpips==0.1.2(用于初始图像相似度损失)、ftfy、docarray>=0.13.29(结果容器)、pyyaml、regex、tqdm、ipywidgets。
注意:模块首次加载时需要下载并加载扩散模型与 CLIP 模型权重(约 2.8GB),首次运行耗时较长。
三、模型 API 预测
模块提供了两种预测方式:命令行预测与 Python 代码调用,二者最终都汇入 module.py 中DiscoDiffusionClip.generate_image这一统一入口。
3.1 命令行预测
$ hub run disco_diffusion_clip_rn50 --text_prompts "A beautiful painting of a singular lighthouse, shining its light across a tumultuous sea of blood by greg rutkowski and thomas kinkade, Trending on artstation." --output_dir disco_diffusion_clip_rn50_out命令行入口由module.py中的run_cmd与add_module_config_arg/add_module_input_arg注册(见 module.py),除--text_prompts为必填输入外,--style、--artist、--init_image、--width_height、--steps、--seed、--clip_guidance_scale、--use_gpu、--output_dir等全部进阶参数均可在命令行直接指定。
3.2 Python 代码预测
import paddlehub as hub module = hub.Module(name="disco_diffusion_clip_rn50") text_prompts = ["A beautiful painting of a singular lighthouse, shining its light across a tumultuous sea of blood by greg rutkowski and thomas kinkade, Trending on artstation."] # Output images will be saved in disco_diffusion_clip_rn50_out directory. # The returned da is a DocumentArray object, which contains all immediate and final results # You can manipulate the DocumentArray object to do post-processing and save images da = module.generate_image(text_prompts=text_prompts, output_dir='./disco_diffusion_clip_rn50_out/') # Save final result image to a file da[0].save_uri_to_file('disco_diffusion_clip_rn50_out-result.png') # Show all immediate results da[0].chunks.plot_image_sprites(skip_empty=True, show_index=True, keep_aspect_ratio=True) # Save the generating process as a gif da[0].chunks.save_gif('disco_diffusion_clip_rn50_out-result.gif')关键点说明:
- 返回对象:
generate_image返回一个DocumentArray对象,包含n_batches个Document。其中每个Document都保存了迭代过程中的全部中间结果,可通过da[0].chunks访问中间帧。这是基于docarray库的容器结构,更多用法参见 DocumentArray 官方教程。 - 进度图与 GIF:
plot_image_sprites将所有中间结果拼成雪碧图;save_gif将生成过程导出为动态图。 - 设备与结果目录:
generate_image内部会按use_gpu自动设置 Paddle 设备(GPU 时读取CUDA_VISIBLE_DEVICES环境变量,否则回退 CPU),并自动创建输出目录(见 module.py)。
3.3 API 签名与核心参数
README 中给出的精简签名如下:
def generate_image( text_prompts, style: Optional[str] = None, artist: Optional[str] = None, width_height: Optional[List[int]] = [1280, 768], seed: Optional[int] = None, output_dir: Optional[str] = 'disco_diffusion_clip_rn50_out'):实际上,module.py 中generate_image的完整签名还包含init_image、skip_steps、steps、cut_ic_pow、init_scale、clip_guidance_scale、tv_scale、range_scale、sat_scale、cutn_batches、diffusion_sampling_mode、perlin_init、perlin_mode、eta、clamp_grad、clamp_max、randomize_class、clip_denoised、fuzzy_prompt、rand_mag、cut_overview、cut_innercut、cut_icgray_p、display_rate、n_batches、batch_size、batch_name、use_gpu等 30 余个参数,默认值均与原版 DiscoArt 对齐。
基础参数
| 参数 | 类型/默认值 | 说明 |
|---|---|---|
| text_prompts | str 或 List[str] | 必填。描述目标图像内容的语句。推荐按"内容描述" + "艺术家/风格"的结构构造,如"a beautiful painting of Chinese architecture, by krenz, sunny, super wide angle, artstation."。prompt 构造技巧可参考公开的 Disco Diffusion prompt 指南 |
| style | Optional[str] = None | 指定绘画风格(如watercolor、Chinese painting)。不指定时风格完全由 prompt 决定 |
| artist | Optional[str] = None | 指定艺术家(如 Greg Rutkowsk、krenz),生成该艺术家风格的画作。不指定时由 prompt 决定 |
| init_image | Optional[str] = None | 初始图像路径。提供后扩散将以该图而非纯噪声为起点;配合较大的skip_steps(约总步数的 50%)可保留原图结构 |
| width_height | List[int] = [1280, 768] | 输出图像宽高。宽高应为 64 的倍数(非 64 的倍数会被自动修正为最近的倍数,见 runner.py);尺寸越大计算时间越长 |
| seed | Optional[int] = None | 随机种子。默认每次随机;指定种子可获得可复现且相近(非完全一致)的结果。实际使用的种子会在运行时参数表中打印,便于复现 |
| output_dir | str = 'disco_diffusion_clip_rn50_out' | 输出目录。运行中每隔display_rate步会写入progress-{n}.png进度图 |
扩散过程控制参数
| 参数 | 类型/默认值 | 说明 |
|---|---|---|
| skip_steps | int = 0 | 跳过的去噪步数。早期步噪声极高、画面变化剧烈,跳过约 10%~15% 步数通常不影响最终效果,可显著缩短渲染时间;使用 init_image 时建议跳过约 50% 步数以保留原图形态 |
| steps | int = 250 | 总扩散步数。每步 AI 观察若干"cuts"并计算引导方向。250~500 步后收益递减,复杂图像可增至 1000+ 步,渲染时间与步数成正比 |
| eta | float = 0.8 | 每时间步混入的随机缩放噪声量(0 为无噪声,1.0 噪声最大)。eta=0 时约 50~75 步即可获得不错结果;eta≈1.0 时建议 250 步以上 |
| diffusion_sampling_mode | str = 'ddim' | 采样算法。ddim成熟稳定;plms可在更少步数下获得良好结果但测试较少 |
| clip_guidance_scale | int = 5000 | CGS,最重要的参数之一。控制 CLIP 每时间步向 prompt 靠拢的强度。过高会过冲导致图像失真;该值一般随图像尺寸增大而线性放大(如尺寸增大 50% 时从 5000 调到 7500) |
| init_scale | int = 1000 | 控制 CLIP 匹配 init_image 的强度,与 CGS 相互制衡。过大则图像变化小,过小则初始图像信息丢失 |
| tv_scale | int = 0 | 全变分去噪强度,控制输出平滑度,0 为关闭。图像过于"噪点/脆"时调大 |
| range_scale | int = 0 | 颜色对比度调节,0 为关闭。调低增强对比(更鲜艳或海报化),调高减弱对比(更柔和) |
| sat_scale | int = 0 | 饱和度调节,0 为关闭。图像过饱和时调大以降低饱和度 |
切割(Cut)相关参数
| 参数 | 类型/默认值 | 说明 |
|---|---|---|
| cutn_batches | int = 4 | 每时间步切割批次数。默认每步 16 个 cuts,cutn_batches=4时每步共 64 个 cuts(分 4 批各 16 个顺序评估),在内存占用不变的前提下提升精度,代价是渲染时间约增至 4 倍 |
| cut_ic_pow | int = 1 | 内切割(inner cut)边框尺寸的指数。越大边框越大、切割块越小、细节越细,过大易导致整体不连贯或马赛克效果 |
| cut_overview | str = '[12]*400+[4]*600' | 概览切割(overview cut)的调度表,形式为[数量]*步数拼接,控制扩散各阶段的切割数量 |
| cut_innercut | str = '[4]*400+[12]*600' | 内切割(inner cut)调度表 |
| cut_icgray_p | str = '[0.2]*400+[0]*600' | 内切割中灰度化比例调度表 |
从 runner.py 的cond_fn可以看到 cuts 的具体作用方式:每个时间步对当前图像调用MakeCutoutsDango生成概览/内切割块(实现见 make_cutouts.py),经过随机翻转、仿射、灰度、颜色抖动等数据增强后送入 CLIP 编码,再与文本目标嵌入计算球面距离损失spherical_dist_loss,最终以clip_guidance_scale加权后的梯度反向引导扩散过程。
高级参数
| 参数 | 类型/默认值 | 说明 |
|---|---|---|
| perlin_init | bool = False | 是否使用 Perlin 噪声作为初始状态替代随机噪声。注意:开启后会覆盖 init_image 设置 |
| perlin_mode | str = 'mixed' | Perlin 噪声类型:color(彩色)、gray(灰度)、mixed(混合) |
| clamp_grad | bool = True | 梯度裁剪开关,防止产生极端结果。若关闭后图像剧烈变化,说明 CGS 过高 |
| clamp_max | float = 0.05 | 梯度裁剪上限。默认 0.05 色彩更平滑内敛;调至 0.15~0.3 可增强对比与活力 |
| fuzzy_prompt | bool = False | 为 prompt 损失叠加多个带噪 prompt,增大输出多样性 |
| rand_mag | float = 0.05 | 仅作用于 fuzzy_prompt,控制叠加随机噪声的幅度 |
| randomize_class | bool = True | 是否随机化类别(影响无条件模型推理) |
| clip_denoised | bool = False | 是否对去噪结果做 CLIP 裁剪 |
| display_rate | int = 10 | 每隔多少步显示一次中间进度图;设为 steps 可减少显示开销 |
| n_batches | int = 1 | 生成图像数量。每个 batch 对应 DocumentArray 中的一个 Document |
| batch_size | int = 1 | 单批并行生成的图像数 |
| batch_name | str = '' | 批次命名,会话 ID 形如disco_diffusion_clip_rn50-{batch_name}-{seed},建议使用唯一名称避免结果被覆盖 |
| use_gpu | bool = True | 是否使用 GPU 推理 |
Prompt 权重语法:text_prompts中的每个 prompt 支持描述:权重后缀语法。从 helper.py 的parse_prompt实现可见,prompt 会按最后一个冒号拆分为文本与浮点权重(未写权重时默认为 1),且权重归一化后求和不能为 0,否则会抛出RuntimeError('The weights must not sum to 0.')。此外,若传入style/artist,模块会自动将,{style}、,{artist},trending on artstation拼接进 prompt 末尾(见 module.py)。
返回对象:DocumentArray,包含n_batches个 Documents,每个 Document 的chunks保存了生成过程中的全部中间结果,其tags记录本次运行的全部参数(见 runner.py)。
四、生成流程的源码级拆解
generate_image内部调用reverse_diffusion.create()(入口见 reverse_diffusion/init.py),随后经过三个环节:
- 配置加载:config.py 将用户参数与
default.yml默认配置合并(未识别参数会告警忽略),并把浮点型整数参数强制转 int,随后打印参数表供核对。 - 模型加载:
load_all_models加载 512x512 无条件扩散 UNet 与 Secondary Diffusion 模型(SecondaryDiffusionImageNet2,用于更快地清理中间图像供 CLIP 评估),load_clip_models按clip_models=['RN50']加载 CLIP 编码器,所有参数均设为stop_gradient=True冻结(见 helper.py)。 - 迭代采样:
do_run根据diffusion_sampling_mode选择ddim_sample_loop_progressive或plms_sample_loop_progressive,在每个时间步通过cond_fn计算 CLIP 引导梯度并施加损失(CLIP 球面距离损失 + TV/range/saturation 损失 + LPIPS 初始图损失),完成整幅图像的迭代生成(见 runner.py)。
在每步迭代中,中间图像会被保存为progress-{n}.png并作为Document.chunks追加进结果,这正是后续save_gif能还原生成过程的原因。
五、服务部署(PaddleHub Serving)
PaddleHub Serving 可以将文图生成能力部署为在线服务。
5.1 第一步:启动 PaddleHub Serving
$ hub serving start -m disco_diffusion_clip_rn50执行后即完成文图生成在线服务 API 的部署,默认端口为8866。
注意:如使用 GPU 预测,需在启动服务前设置CUDA_VISIBLE_DEVICES环境变量;CPU 环境则无需设置。
5.2 第二步:发送预测请求
服务端就绪后,以下代码即可发送预测请求并获取结果:
import requests import json import cv2 import base64 from docarray import DocumentArray # Send an HTTP request data = {'text_prompts': 'in the morning light,Overlooking TOKYO city by greg rutkowski and thomas kinkade,Trending on artstation.'} headers = {"Content-type": "application/json"} url = "http://127.0.0.1:8866/predict/disco_diffusion_clip_rn50" r = requests.post(url=url, headers=headers, data=json.dumps(data)) # Get results da = DocumentArray.from_base64(r.json()["results"]) # Save final result image to a file da[0].save_uri_to_file('disco_diffusion_clip_rn50_out-result.png') # Save the generating process as a gif da[0].chunks.save_gif('disco_diffusion_clip_rn50_out-result.gif')服务端处理逻辑对应 module.py 中@serving装饰的serving_method:它调用generate_image后将DocumentArray序列化为 base64 返回。因此客户端在反序列化后拿到的仍是DocumentArray对象,对结果的操作方式与直接调用generate_image完全相同(保存 PNG、拼接雪碧图、导出 GIF 均可复用同一套 API)。
六、版本与更新历史
- 1.0.0:初始发布。
如需指定版本安装:
$ hub install disco_diffusion_clip_rn50 == 1.0.0结语
disco_diffusion_clip_rn50 完整复现了"扩散模型生成 + CLIP 语义引导"的文图生成范式:通过 module.py 统一的参数入口,你既可以hub run一行命令出图,也可以基于generate_image精细控制从扩散步数、CGS 引导强度到切割调度的全部细节,还能借助 PaddleHub Serving 将模型快速封装为 HTTP 在线服务。对于希望深入理解 Diffusion + CLIP 协同原理、或需要在 PaddlePaddle 生态中落地文图生成能力的开发者,这是一个可以直接上手、可完整复现的参考实现。
【免费下载链接】PaddleFormersPaddleFormers is an easy-to-use library of pre-trained large language model zoo based on PaddlePaddle.项目地址: https://gitcode.com/gh_mirrors/pa/PaddleFormers
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考