Stable Diffusion的文本转图像过程是一个复杂的流程,文本提示(prompt)会被转换成嵌入向量,然后通过条件扩散模型引导图像生成。以下是完整的流程:
当您输入文本提示时,首先会经过以下处理:
文本首先被分解成标记(tokens),这是由CLIP文本编码器完成的:
python# modules/sd_hijack_clip.py
def tokenize(self, texts):
# 将文本转换成token标记ID列表
tokenized = self.wrapped.tokenizer(texts, truncation=False, add_special_tokens=False)["input_ids"]
return tokenized
例如,"a photo of a cat"会被分解成["a", "photo", "of", "a", "cat"]等标记,然后转换为数字ID。
标记化后的文本会通过CLIP的文本编码器转换为嵌入向量:
python# modules/sd_hijack_clip.py
def encode_with_transformers(self, tokens):
# 对标记进行编码,生成隐藏状态
outputs = self.wrapped.transformer(input_ids=tokens, output_hidden_states=-opts.CLIP_stop_at_last_layers)
if opts.CLIP_stop_at_last_layers > 1:
z = outputs.hidden_states[-opts.CLIP_stop_at_last_layers]
z = self.wrapped.transformer.text_model.final_layer_norm(z)
else:
z = outputs.last_hidden_state
return z
这将每个标记转换为一个高维向量(SD1.5是768维,SDXL是1024维)。
处理类StableDiffusionProcessing
中的get_conds
方法获取条件向量:
python# modules/processing.py
def get_conds(self):
# 返回文本条件向量(c)和无条件向量(uc)
return self.c, self.uc
这里会返回两个关键的条件向量:
在采样过程开始时,文本条件被传递给采样器:
python# modules/sd_samplers_kdiffusion.py
self.sampler_extra_args = {
'cond': conditioning, # 正面提示的条件向量
'image_cond': image_conditioning,
'uncond': unconditional_conditioning, # 负面提示的无条件向量
'cond_scale': p.cfg_scale, # CFG缩放比例
's_min_uncond': self.s_min_uncond
}
CFG缩放在CFGDenoiser.forward
方法中实现,这是文本条件实际影响图像生成的关键部分:
python# modules/sd_samplers_cfg_denoiser.py
def forward(self, x, sigma, uncond, cond, cond_scale, s_min_uncond, image_cond):
# ... [代码省略]
# 对噪声图像应用模型,获取噪声预测
x_out = self.inner_model(x_in, sigma_in, cond=make_condition_dict(cond_in, image_cond_in))
# ... [代码省略]
# 关键公式:结合条件和无条件预测
denoised = self.combine_denoised(x_out, conds_list, uncond, cond_scale)
# ... [代码省略]
return denoised
文本提示通过以下公式直接影响每一步的去噪过程:
python# modules/sd_samplers_cfg_denoiser.py
def combine_denoised(self, x_out, conds_list, uncond, cond_scale):
denoised_uncond = x_out[-uncond.shape[0]:] # 无条件预测结果
denoised = torch.clone(denoised_uncond) # 从无条件结果开始
# 应用条件预测的影响,加权以cond_scale(也就是CFG Scale)
for i, conds in enumerate(conds_list):
for cond_index, weight in conds:
denoised[i] += (x_out[cond_index] - denoised_uncond[i]) * (weight * cond_scale)
return denoised
这个公式的简化版本是:
最终预测 = 无条件预测 + CFG_Scale × (条件预测 - 无条件预测)
以数学形式表示:
其中:
当您提供一个文本提示如"一只漂亮的黑猫"时:
提示被标记化并通过CLIP文本编码器转换成嵌入向量
同样,负面提示也被编码成嵌入向量
采样过程开始,执行多步去噪
在每个去噪步骤:
经过多次迭代后,最终的潜在表示被解码成像素图像
CFG Scale参数直接控制了文本提示的影响程度:
当您使用提示"一只漂亮的黑猫"时:
文本提示通过CLIP文本编码器转换为条件向量,然后在每个采样步骤中通过CFG机制引导去噪过程。CFG Scale参数控制文本提示对生成过程的影响程度,使Stable Diffusion能够根据用户的文本描述生成相应的图像。整个过程是一个精妙的平衡,既保持了生成的多样性,又确保了与文本提示的相关性。
本文作者:Dong
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!