# SDXL ## 概述 SDXL(Stable Diffusion XL)是Stability AI发布的文生图扩散模型,是Stable Diffusion系列的最新一代产品。SDXL在架构上进行了重大升级,包括更大的UNet、Refiner模块和CLIP文本编码器组合,显著提升了生成图像的质量和细节。 ## 1. SDXL整体结构 ### 1.1 模型架构概览 SDXL采用两阶段生成架构: ``` 文本提示 → CLIP编码器(双)→ UNet(base)→ 潜空间 → Refiner → 图像 ↓ 扩散去噪过程 ``` **核心组件:** 1. OpenCLIP ViT-L/14 文本编码器(主体) 2. OpenCLIP ViT-g/14 文本编码器(补充) 3. Base UNet(基础生成) 4. Refiner UNet(细节增强) ### 1.2 与SD 1.5/2.1的对比 | 特性 | SD 1.5 | SD 2.1 | SDXL | |------|--------|--------|------| | 参数量(UNet) | 860M | 865M | 3.5B | | 文本编码器 | CLIP ViT-L/14 | CLIP ViT-L/14 | OpenCLIP g/14+L/14 | | 基础分辨率 | 512×512 | 768×768 | 1024×1024 | | latent通道 | 4 | 4 | 4 | | 分辨率灵活度 | 固定 | 固定 | 多分辨率 | ## 2. UNet升级 ### 2.1 架构改进 **模型尺寸:** ```python # SDXL UNet配置 config = { 'in_channels': 4, 'out_channels': 4, 'model_channels': 320, 'num_res_blocks': 2, 'attention_resolutions': [4, 2, 1], 'context_dim': 2048, # 更大的context维度 'use_reentrant': False, 'guidance_embed': True } ``` **Transformer块增强:** - 每层注意力头数增加 - Cross-attention层增强 - 时间步嵌入改进 ### 2.2 注意力机制 **多尺度注意力:** ```python # SDXL使用三种注意力分辨率 attention_resolutions = { '32x32': 较粗粒度(早期层) '16x16': 中等粒度(中间层) '8x8': 细粒度(后期层) } # Cross-attention用于文本条件注入 class CrossAttention(nn.Module): def __init__(self, d_model, num_heads, context_dim): self.query = nn.Linear(d_model, d_model) self.key = nn.Linear(context_dim, d_model) # 文本维度:2048 self.value = nn.Linear(context_dim, d_model) self.num_heads = num_heads ``` ### 2.3 时间步条件 **改进的时间编码:** ```python # Timestep embedding升级 class TimestepEmbedder(nn.Module): def __init__(self, dim, freq_embed_size=256): self.mlp = nn.Sequential( nn.Linear(dim, freq_embed_size * 4), nn.SiLU(), nn.Linear(freq_embed_size * 4, freq_embed_size * 4), ) self.freq_embed = nn.Linear(freq_embed_size, dim) def forward(self, t): t_freq = self.mlp(t) return self.freq_embed(t_freq) ``` ### 2.4 条件注入机制 **Guidance Scale控制:** ```python # Classifier-Free Guidance # 在推理时使用guidance scale控制条件强度 def guidance_scale_forward(unet, latents, timestep, cond, cfg_scale=7.5): # 条件和无条件同时推理 cond_output = unet(latents, timestep, cond) # 有条件 uncond_output = unet(latents, timestep, uncond) # 无条件 # 插值 guided_output = uncond_output + cfg_scale * (cond_output - uncond_output) return guided_output ``` ## 3. Refiner模块 ### 3.1 Refiner作用 Refiner是SDXL独有的细节增强模块: ``` Base输出 → Refiner输入 → 细节增强 → 最终输出 (latent) (latent) (噪声细化) ``` **功能:** - 提升图像细节质量 - 改善纹理和边缘 - 增强全局一致性 ### 3.2 Refiner架构 ```python class RefinerUNet(nn.Module): def __init__(self): # 结构与Base UNet类似,但: self.in_channels = 4 self.model_channels = 320 self.num_res_blocks = 2 # 使用相同的时间步条件 # 使用相同的文本编码器 # 区别: # 1. 专注于细粒度特征 # 2. 更强的注意力机制 # 3. 接受Base输出作为输入 ``` ### 3.3 级联生成策略 ```python # 两阶段推理流程 def generate_sdxl(prompt, num_steps=20, cfg_scale=7.5): # Stage 1: Base生成 latents = base_unet.sample( num_steps=num_steps, prompt_embedding=prompt_emb, guidance_scale=cfg_scale ) # Stage 2: Refiner增强 refined_latents = refiner_unet.sample( num_steps=8, # 较少步数 latents=latents, prompt_embedding=prompt_emb, guidance_scale=cfg_scale, image_cond=True # 以Base结果为条件 ) # 解码到像素空间 image = vae.decode(refined_latents) return image ``` ## 4. CLIP文本编码器组合 ### 4.1 双编码器设计 SDXL使用两个CLIP文本编码器: **主编码器:OpenCLIP ViT-L/14** ```python # 参数量:428M # 特征维度:768 # 作用:提供主要的文本理解能力 ``` **辅助编码器:OpenCLIP ViT-g/14** ```python # 参数量:1.3B # 特征维度:1024 # 作用:增强复杂文本理解 ``` ### 4.2 文本嵌入融合 ```python class DualTextEncoder(nn.Module): def __init__(self): self.encoder_l = CLIPViT_L() # 768维 self.encoder_g = CLIPViT_G() # 1024维 # 融合层 self.fusion = nn.Linear(768 + 1024, 2048) def forward(self, text): feat_l = self.encoder_l(text) # [B, 768] feat_g = self.encoder_g(text) # [B, 1024] # 拼接后投影到统一空间 combined = torch.cat([feat_l, feat_g], dim=-1) # [B, 1792] projected = self.fusion(combined) # [B, 2048] return projected ``` ### 4.3 文本编码器重要性 | 编码器 | 能力提升 | |--------|----------| | ViT-L/14 | 基础文本-图像对齐 | | ViT-g/14 | 复杂语义理解 | | 双编码器融合 | 细节描述准确生成 | ## 5. 训练技术 ### 5.1 潜空间扩散 ```python # VAE编码图像到潜空间 def encode_image(image): # image: [B, 3, 1024, 1024] latent = vae.encode(image) # latent: [B, 4, 128, 128] return latent * 0.18215 # 缩放因子 # 潜空间噪声 noise = torch.randn_like(latent) # 扩散过程 def diffuse(latent, t): # 添加噪声 noisy = sqrt(alpha_bar[t]) * latent + sqrt(1 - alpha_bar[t]) * noise return noisy ``` ### 5.2 多分辨率训练 SDXL支持灵活的图像分辨率: ```python # 训练时随机采样分辨率 train_resolutions = [ (1024, 1024), (512, 1024), (1024, 512), (768, 768), (640, 896), (896, 640) ] # 使用aspect ratio bucketing def get_aspect_ratio_bucket(target_size): ratio = target_size[0] / target_size[1] if ratio > 1.3: return 'wide' elif ratio < 0.77: return 'tall' else: return 'square' ``` ### 5.3 训练数据 | 数据类型 | 数量 | 处理方式 | |----------|------|----------| | LAION-5B | 5B | 安全过滤 + 审美过滤 | | AAIA | ~600M | 高审美质量筛选 | | 内部数据 | 专有 | 高质量标注 | ## 6. 推理优化 ### 6.1 采样器选择 | 采样器 | 步数 | 速度 | 质量 | |--------|------|------|------| | DPM++ 2M Karras | 20-30 | 中 | 高 | | Euler a | 20-30 | 快 | 中 | | DDIM | 10-20 | 快 | 中 | | PLMS | 20 | 中 | 中 | ### 6.2 量化优化 ```python # INT8量化 quantized_model = quantize(model, bits=8) # 内存优化 model.enable_xformers() # 使用Flash Attention model.enable_attention_slicing() # 切片注意力 ``` ## 7. 使用指南 ### 7.1 基本推理代码 ```python from diffusers import StableDiffusionXLPipeline pipe = StableDiffusionXLPipeline.from_pretrained( "stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16, variant="fp16" ) prompt = "a photo of an astronaut riding a horse on mars" image = pipe( prompt=prompt, height=1024, width=1024, num_inference_steps=25, guidance_scale=7.5 ).images[0] ``` ### 7.2 高级参数 ```python # Refiner使用 result = pipe( prompt=prompt, num_inference_steps=25, denoise_end=0.8, # Base停止时机 guidance_scale=7.5, negative_prompt="blurry, low quality" # 负提示 ) ``` ## 8. 性能评估 ### 8.1 人类偏好评估 | 模型 | 偏好率(vs SD 2.1)| |------|-------------------| | SDXL | 65% | | SD 2.1 | 35% | ### 8.2 FID指标 | 模型 | FID ↓ | IS ↑ | |------|-------|------| | SDXL | 6.5 | 120 | | SD 2.1 | 8.1 | 105 | | SD 1.5 | 10.2 | 95 | ## 9. 总结 SDXL的主要升级点: | 升级 | 效果 | |------|------| | UNet规模(3.5B) | 更高生成质量 | | 双CLIP编码器 | 更准确的文本理解 | | Refiner模块 | 细节增强 | | 多分辨率支持 | 灵活尺寸生成 | SDXL代表了开源文生图模型的最高水平,为后续的SDXL-Turbo、SDXL-Lightning等快速采样模型奠定了基础。