当前位置: 首页 > news >正文

diffusers学习--stable diffusion的管线解析

1. 核心组件加载

一个完整的 Stable Diffusion 潜在扩散模型主要由以下 5 个核心组件构成:

  1. VAE (Variational Autoencoder): 一个图像自编码器,负责在像素空间(我们看到的图片)和潜空间(UNet 处理的低维数据)之间进行转换。
  2. Tokenizer: 文本分词器,负责将人类语言(提示词)转换为模型能够理解的数字 ID(Tokens)。
  3. Text Encoder: 文本编码器(通常是 CLIP),负责将 Token ID 转换为包含丰富语义信息的词嵌入向量(Embeddings)。
  4. UNet: 模型的核心,一个在潜空间中运行的噪声预测模型。它在每一步根据文本编码器的指导,预测并移除噪声。
  5. Scheduler: 调度器,负责定义去噪的时间步长和策略。它根据 UNet 的预测结果,计算出下一个时间步的潜空间状态。
# 加载所有组件,并指定 subfolder
repo_id="CompVis/stable-diffusion-v1-4"
vae = AutoencoderKL.from_pretrained(repo_id, subfolder="vae", ...)
tokenizer = CLIPTokenizer.from_pretrained(repo_id, subfolder="tokenizer")
text_encoder = CLIPTextModel.from_pretrained(repo_id, subfolder="text_encoder", ...)
unet = UNet2DConditionModel.from_pretrained(repo_id, subfolder="unet", ...) # 注意:这里原代码有误,应使用 UNet2DConditionModel
scheduler = UniPCMultistepScheduler.from_pretrained(repo_id, subfolder="scheduler")

2. 提示词处理

这是将文本指令转换为 UNet “指导”信息的过程。

  1. 分词与编码:将正面提示词(如“宇航员骑马”)转换为词嵌入向量 text_emb

  2. 准备无条件/负面提示词:为了实现 CFG,我们还需要一个“无指导”的基准。这通常是通过编码一个空字符串 "" 来实现的,它代表了模型的“自由创作”状态,在应用上等同于一个负面提示词。这里只把提示词嵌入,还有负面提示词的嵌入,这里就不写负面提示词了,就用 “”

  3. 拼接:将无条件嵌入 uncond_embeddings 和有条件嵌入 text_emb 拼接在一起,形成一个 (2, 77, 768) 的张量,为 CFG 的并行计算做准备。

# 正面提示词
text_input = tokenizer(prompt, ...)
text_emb = text_encoder(text_input.input_ids.to(device))[0]# 负面/无条件提示词 (空字符串)
uncond_input = tokenizer([""], ...)
uncond_embeddings = text_encoder(uncond_input.input_ids.to(device))[0]# 拼接成一个批次为 2 的张量
text_embeddings = torch.cat([uncond_embeddings, text_emb])

3. 潜空间初始化

我们不直接生成图片,而是在潜空间中创建初始的随机噪声。

  1. 确定尺寸:由于 VAE 的下采样因子为 8,一个 512x512 的图像对应的潜空间尺寸是 64x64。因此,初始噪声的尺寸是 height // 8width // 8
  2. 调整噪声尺度:使用 torch.randn 创建的是标准正态分布噪声(强度为 1)。但像 UniPCMultistepScheduler 这样的高级调度器,其数学模型要求一个特定的初始噪声强度,这个值存储在 scheduler.init_noise_sigma 中。因此,我们需要将标准噪声乘以这个值,进行缩放。
# 创建潜空间噪声
latents = torch.randn((batch_size, unet.config.in_channels, height // 8, width // 8), ...)# 根据调度器要求进行缩放
latents = latents * scheduler.init_noise_sigma

4. 核心:去噪循环

这是从纯噪声生成图像潜空间表示的核心迭代过程。

scheduler.set_timesteps(num_inference_steps) # 使用正确的函数调用
for i, timestep in enumerate(scheduler.timesteps):# ... 循环体 ...

循环中的每一步都包含以下关键操作:

  1. 复制 Latents: 这里只创建了正面提示词的随机噪声,负面提示词的直接复制一份正面的,对齐词向量嵌入

    latent_model_input = torch.cat([latents] * 2)
    
  2. UNet 预测: 将复制后的 latents 和拼接好的 text_embeddings 一同送入 UNet,UNet 会并行地预测出两个噪声:noise_uncond (无指导的) 和 noise_text (有指导的)。

  3. CFG 计算: 应用公式 noise = noise_uncond + guidance_scale * (noise_text - noise_uncond),计算出最终的、被强力引导的噪声。

  4. Scheduler 步进: 调用 scheduler.step(),根据最终的噪声,计算出下一个时间步的、噪声更少的 latents

5. VAE 解码与保存

循环结束后,我们得到了最终的图像潜空间表示,需要将其解码成像素图像。

  1. 逆向缩放: 在送入 VAE 解码器之前,需要用 1 / vae.config.scaling_factor (即 1 / 0.18215) 对 latents 进行一次逆向缩放,以匹配 VAE 解码器的输入尺度。
  2. 解码: 调用 vae.decode(latents) 将潜空间表示转换回像素图像。
  3. 后处理与保存: 将图像的数值范围从 [-1, 1] 转换到 [0, 255],并保存为图片文件。
http://www.dtcms.com/a/333053.html

相关文章:

  • 第五天~提取Arxml的模板信息
  • react项目性能优化的hook
  • UGUI源码剖析(9):布局的实现——LayoutGroup的算法与实践
  • java程序打包成exe,再打成安装包,没有jdk环境下可运行
  • 【完整源码+数据集+部署教程】孔洞检测系统源码和数据集:改进yolo11-RetBlock
  • 金刚石基植入体新突破!Adv. Funct. Mater. 报道首例增材制造固态摩擦电能量收集器
  • 【FastGTP✨】[01] 使用 FastGPT 搭建简易 AI 应用
  • 部署Qwen-Image,通过API返回可访问的图像URL
  • 以下是对智能电梯控制系统功能及系统云端平台设计要点的详细分析,结合用户提供的梯控系统网络架构设计和系统软硬件组成,分点论述并补充关键要点:
  • 一文打通 AI 知识脉络:大语言模型等关键内容详解
  • 铨林接纸机学习记录1
  • AI智能文档生成系统需求规格说明书
  • Linux 进程、线程与 exec/系统调用详解
  • MySQL中的字符串函数
  • PowerShell 格式化系统完全掌握(下):自定义列/格式字符串/对齐与宽度 + 实战模板
  • 抗日胜利80周年 | HTML页面
  • 智和信通全栈式运维平台落地深圳某学院,赋能运维管理提质提效
  • TCP传输层协议(4)
  • 微信实名认证组件
  • 二十四、Mybatis-基础操作-删除(预编译SQL)
  • SAP ALV导出excel 报 XML 错误的 /xl/sharedStrings.xml
  • Android协程的用法大全
  • 汽车电子:现代汽车的智能核心
  • Unity_数据持久化_Json
  • 使用原生css实现word目录样式,标题后面的...动态长度并始终在标题后方(生成点线)
  • 第七十章:告别“手写循环”噩梦!Trainer结构搭建:PyTorch Lightning让你“一键炼丹”!
  • Codeforces Deque工艺
  • 用 FreeMarker 动态构造 SQL 实现数据透视分析
  • STM32学习笔记12-串口数据包收发FlyMcuST-LINK Utility
  • Shortest Routes II(Floyd最短路)