资讯动态

Diffusers DiffEdit 实战指南:用 StableDiffusionDiffEditPipeline 实现文本驱动的语义图像编辑

发布时间:2026/9/10 10:41:20 来源:尧图企业网站定制
Diffusers DiffEdit 实战指南用 StableDiffusionDiffEditPipeline 实现文本驱动的语义图像编辑【免费下载链接】diffusers Diffusers: State-of-the-art diffusion models for image, video, and audio generation in PyTorch.项目地址: https://gitcode.com/GitHub_Trending/di/diffusers本文以 Hugging Face Diffusers 仓库中的 DiffEdit 使用指南为蓝本对应文档diffedit.md英文用户可参考 controlling_generation.md 中的 DiffEdit 章节系统讲解如何使用StableDiffusionDiffEditPipeline完成免手工蒙版的语义图像编辑从文本自动生成编辑掩码、用 DDIM 反演获得图像 latent再到掩码引导的局部重绘最后介绍用 Flan-T5 与 BLIP 将整个流程自动化的进阶方案。读完本文你将掌握 DiffEdit 三阶段算法的完整调用链、全部关键参数的含义与调优方法以及一条可复制运行的端到端编辑管线。DiffEdit 是什么三步语义编辑原理传统的图像编辑如 inpainting通常要求用户手工提供要改哪里的蒙版而 DiffEdit 的价值在于只需给出描述原图的source_prompt与描述编辑目标的target_prompt蒙版便会自动生成无需任何图像编辑软件。DiffEdit 算法分为三个步骤与文档描述一致且每一步都能在StableDiffusionDiffEditPipeline源码中找到对应实现语义掩码推断让扩散模型分别以查询文本target和参考文本source为条件对图像去噪对图像不同区域产生不同的噪声估计取两者噪声预测的差异即可推断出为了匹配查询文本图像中哪些区域需要被修改据此生成掩码。这一步对应源码中的generate_mask方法。潜在空间编码使用 DDIM 将输入图像编码反演到潜在空间得到部分反演的 latents。对应源码中的invert方法与DDIMInverseScheduler调度器。掩码引导解码以掩码为引导用条件于查询文本的扩散模型对 latents 去噪同时保证掩码之外的像素与输入图像保持一致。对应管线主入口__call__中的去噪循环——在每一步源码通过latents latents * mask_image image_latents[i] * (1 - mask_image)源码第 1516 行将掩码区域的重绘结果与掩码外的原始图像 latent 融合。从源码结构看StableDiffusionDiffEditPipeline位于 src/diffusers/pipelines/deprecated/stable_diffusion_diffedit/pipeline_stable_diffusion_diffedit.py它继承自DiffusionPipeline、StableDiffusionMixin并组合了TextualInversionLoaderMixin与StableDiffusionLoraLoaderMixin因此天然支持文本反转textual inversion与 LoRA 权重加载同时该管线被标记为实验性/已弃用deprecated特性_last_supported_version 0.33.1使用前请确认版本兼容性。环境准备与安装开始之前请确保以下库已安装# 取消注释以在 Colab 中安装所需库 #!pip install -q diffusers transformers accelerate其中diffusers提供管线本体transformers提供文本编码器CLIP以及进阶方案中的 Flan-T5、BLIP 模型accelerate用于设备管理与 CPU offload。从 deprecated/stable_diffusion_diffedit/init.py 可以看到StableDiffusionDiffEditPipeline的导入依赖torch与transformers同时可用否则只会得到一个占位空对象。完整工作流从零编辑一张图片加载管线、调度器与内存优化StableDiffusionDiffEditPipeline需要两类调度器配合使用正向去噪用的DDIMScheduler以及反演用的DDIMInverseScheduler。此外文档还建议启用模型 CPU offload 与 VAE 切片来降低显存占用import torch from diffusers import DDIMScheduler, DDIMInverseScheduler, StableDiffusionDiffEditPipeline pipeline StableDiffusionDiffEditPipeline.from_pretrained( stabilityai/stable-diffusion-2-1, dtypetorch.float16, safety_checkerNone, use_safetensorsTrue, ) pipeline.scheduler DDIMScheduler.from_config(pipeline.scheduler.config) pipeline.inverse_scheduler DDIMInverseScheduler.from_config(pipeline.scheduler.config) pipeline.enable_model_cpu_offload() pipeline.vae.enable_slicing()几点说明结合源码从 源码示例文档字符串 看官方推荐的精确保数参数写法是torch_dtypetorch.float16文档中的dtype为旧式写法二者效果相同use_safetensorsTrue表示优先加载 safetensors 权重。safety_checkerNone会跳过安全检测器源码中会打印警告提示仅在分析或审计场景下禁用inverse_scheduler属于可选组件见_optional_components [safety_checker, feature_extractor, inverse_scheduler]源码第 288 行但 DiffEdit 流程必须手动挂载它。enable_model_cpu_offload()按text_encoder-unet-vae的顺序model_cpu_offload_seq源码第 287 行逐模块卸载到 CPU。加载输入图片from diffusers.utils import load_image, make_image_grid img_url https://github.com/Xiang-cd/DiffEdit-stable-diffusion/raw/main/assets/origin.png raw_image load_image(img_url).resize((768, 768)) raw_imageload_image是 diffusers 提供的小工具可直接从 URL 或本地路径读取图片。注意由于 VAE 的 8 倍下采样特性图片宽高需要是 8 的整数倍源码preprocess中也有resize to integer multiple of 8的说明示例中统一resize((768, 768))正是为此。生成语义掩码generate_mask掩码是 DiffEdit 自动化的核心。调用generate_mask时传入source_prompt与target_prompt两者共同决定图片中改什么from PIL import Image source_prompt a bowl of fruits target_prompt a basket of pears mask_image pipeline.generate_mask( imageraw_image, source_promptsource_prompt, target_prompttarget_prompt, ) Image.fromarray((mask_image.squeeze()*255).astype(uint8), L).resize((768, 768))例如要把一碗水果a bowl of fruits改成一篮梨a basket of pearssource_prompt描述现状target_prompt描述目标。源码中掩码的计算过程为第 1041-1051 行对同一张图分别以 source 和 target 为条件做一次带噪声的前向得到两组噪声预测noise_pred_source与noise_pred_target取两者绝对差torch.abs(noise_pred_target - noise_pred_source)在num_maps_per_mask张噪声图与通道维度上求平均得到语义引导图mask guidance map用mask_guidance_map.mean() * mask_thresholding_ratio作为钳制上限做归一化再以 0.5 为阈值二值化得到最终掩码0/1。返回的掩码形状为(height // vae_scale_factor, width // vae_scale_factor)潜在空间分辨率示例代码把它放大回 768×768 以便可视化。DDIM 反演invert下一步用invert将输入图像反演为部分加噪的 latents。这里传入描述图像的prompt即 caption它能引导反演采样过程使结果更稳定——caption 通常直接用source_prompt但完全可以用其他文本描述做实验inv_latents pipeline.invert(promptsource_prompt, imageraw_image).latents源码中反演循环使用inverse_scheduler.step()逐时间步执行第 1268 行并收集每个时间步的 latents 后逆序堆叠输出维度为(batch, num_timesteps, ...)的张量——这也是后续__call__期望的输入格式。invert还支持 Pix2PixZero 风格的噪声正则化lambda_auto_corr、lambda_kl、num_reg_steps、num_auto_corr_rolls默认分别为 20.0、20.0、0、5源码注释明确说明这部分并非原始论文内容而是借鉴自 Pix2PixZero。掩码引导的修复生成调用管线最后把掩码与反演 latents 交给管线主入口。此时target_prompt作为正向promptsource_prompt作为negative_prompt使用output_image pipeline( prompttarget_prompt, mask_imagemask_image, image_latentsinv_latents, negative_promptsource_prompt, ).images[0] mask_image Image.fromarray((mask_image.squeeze()*255).astype(uint8), L).resize((768, 768)) make_image_grid([raw_image, mask_image, output_image], rows1, cols3)将原始图、掩码、编辑结果拼成三格图即可直观对比。__call__的去噪循环中掩码通过latents latents * mask_image image_latents[i] * (1 - mask_image)第 1516 行起作用掩码为 1白色的区域被重绘掩码为 0黑色的区域保留原始图像内容。输入的mask_image会在preprocess_mask中被转为单通道张量、校验数值在 [0,1] 区间并以 0.5 为阈值二值化第 237-239 行。进阶一用 Flan-T5 自动生成 source/target 文本并编码为嵌入手工编写source_prompt/target_prompt之外还可以借助 Flan-T5 语言模型自动生成一批候选描述再通过文本编码器聚合成嵌入向量实现给一个概念词自动完成语义编辑的流程。加载 Flan-T5 模型与分词器import torch from transformers import AutoTokenizer, T5ForConditionalGeneration tokenizer AutoTokenizer.from_pretrained(google/flan-t5-large) model T5ForConditionalGeneration.from_pretrained(google/flan-t5-large, device_mapauto, dtypetorch.float16)构造生成提示词给定 source 概念原图中的物体与 target 概念目标物体构造为包含某物体的图片生成英文描述不超过 150 字符的指令式文本source_concept bowl target_concept basket source_text fProvide a caption for images containing a {source_concept}. The captions should be in English and should be no longer than 150 characters. target_text fProvide a caption for images containing a {target_concept}. The captions should be in English and should be no longer than 150 characters.批量采样候选描述定义生成函数通过temperature、top_k、do_sample控制生成策略的随机性与多样性关于各类采样策略的取舍可参考 Transformers 文档中的 generation strategies 指南torch.no_grad() def generate_prompts(input_prompt): input_ids tokenizer(input_prompt, return_tensorspt).input_ids.to(cuda) outputs model.generate( input_ids, temperature0.8, num_return_sequences16, do_sampleTrue, max_new_tokens128, top_k10 ) return tokenizer.batch_decode(outputs, skip_special_tokensTrue) source_prompts generate_prompts(source_text) target_prompts generate_prompts(target_text) print(source_prompts) print(target_prompts)用管线的文本编码器编码嵌入复用StableDiffusionDiffEditPipeline自带的 CLIP 分词器与文本编码器pipeline.tokenizer/pipeline.text_encoder将每个候选描述编码后取平均得到单个代表嵌入import torch from diffusers import StableDiffusionDiffEditPipeline pipeline StableDiffusionDiffEditPipeline.from_pretrained( stabilityai/stable-diffusion-2-1, dtypetorch.float16, use_safetensorsTrue ) pipeline.enable_model_cpu_offload() pipeline.vae.enable_slicing() torch.no_grad() def embed_prompts(sentences, tokenizer, text_encoder, devicecuda): embeddings [] for sent in sentences: text_inputs tokenizer( sent, paddingmax_length, max_lengthtokenizer.model_max_length, truncationTrue, return_tensorspt, ) text_input_ids text_inputs.input_ids prompt_embeds text_encoder(text_input_ids.to(device), attention_maskNone)[0] embeddings.append(prompt_embeds) return torch.concatenate(embeddings, dim0).mean(dim0).unsqueeze(0) source_embeds embed_prompts(source_prompts, pipeline.tokenizer, pipeline.text_encoder) target_embeds embed_prompts(target_prompts, pipeline.tokenizer, pipeline.text_encoder)用嵌入替换文本参数最终将嵌入传给generate_mask、invert与管线主入口。注意source_embeds在反演阶段作为prompt_embeds在主入口中作为negative_prompt_embedstarget_embeds则作为prompt_embedsfrom diffusers import DDIMInverseScheduler, DDIMScheduler from diffusers.utils import load_image, make_image_grid from PIL import Image pipeline.scheduler DDIMScheduler.from_config(pipeline.scheduler.config) pipeline.inverse_scheduler DDIMInverseScheduler.from_config(pipeline.scheduler.config) img_url https://github.com/Xiang-cd/DiffEdit-stable-diffusion/raw/main/assets/origin.png raw_image load_image(img_url).resize((768, 768)) mask_image pipeline.generate_mask( imageraw_image, source_prompt_embedssource_embeds, target_prompt_embedstarget_embeds, ) inv_latents pipeline.invert( prompt_embedssource_embeds, imageraw_image, ).latents output_image pipeline( mask_imagemask_image, image_latentsinv_latents, prompt_embedstarget_embeds, negative_prompt_embedssource_embeds, ).images[0] mask_image Image.fromarray((mask_image.squeeze()*255).astype(uint8), L) make_image_grid([raw_image, mask_image, output_image], rows1, cols3)补充说明prompt与prompt_embeds是互斥参数两者同时传入会触发源码check_inputs中的ValueError直接传入嵌入时generate_mask会以num_maps_per_mask作为encode_prompt的num_images_per_prompt对嵌入做 batch 扩展因此手工构造嵌入时务必保证source_embeds与target_embeds形状一致check_source_inputs会校验。进阶二用 BLIP 自动生成反演用的图片描述invert需要一个能描述原图的 caption 来引导反演采样。除了直接用source_prompt也可以用 BLIP 图像描述模型自动生成——让图片理解也自动化。加载 BLIP 模型与处理器import torch from transformers import BlipForConditionalGeneration, BlipProcessor processor BlipProcessor.from_pretrained(Salesforce/blip-image-captioning-base) model BlipForConditionalGeneration.from_pretrained(Salesforce/blip-image-captioning-base, dtypetorch.float16, low_cpu_mem_usageTrue)定义生成 caption 的工具函数generate_caption以a photograph of作为前缀提示生成后立即把模型移回 CPU避免长期占用显存torch.no_grad() def generate_caption(images, caption_generator, caption_processor): text a photograph of inputs caption_processor(images, text, return_tensorspt).to(devicecuda, dtypecaption_generator.dtype) caption_generator.to(cuda) outputs caption_generator.generate(**inputs, max_new_tokens128) # 将 caption generator 移回 CPU caption_generator.to(cpu) caption caption_processor.batch_decode(outputs, skip_special_tokensTrue)[0] return caption生成 caption 并用于反演from diffusers.utils import load_image img_url https://github.com/Xiang-cd/DiffEdit-stable-diffusion/raw/main/assets/origin.png raw_image load_image(img_url).resize((768, 768)) caption generate_caption(raw_image, model, processor)对示例原图BLIP 生成的描述约为 a photograph of a bowl of fruit on a table一碗摆在桌上的水果。随后把该 caption 传给invert即可获得部分反演的 latentsinv_latents pipeline.invert(promptcaption, imageraw_image).latents关键参数速查与调参建议以下参数均以源码中的默认值与校验逻辑为准参数所属方法默认值含义与取值范围source_prompt/target_promptgenerate_mask必填描述原图现状与编辑目标二选一传入字符串或对应*_prompt_embedsnum_maps_per_maskgenerate_mask10用于生成语义掩码的噪声图数量必须是正整数越多掩码越平滑但计算量线性增长mask_encode_strengthgenerate_mask0.5掩码生成时对图像添加噪声的强度取值 [0, 1]同时充当check_inputs中的strength校验mask_thresholding_ratiogenerate_mask3.0语义引导图钳制上限 均值 × 该倍数必须为正越大掩码区域越小更保守num_inference_steps三个方法50去噪/反演步数越多质量越高但越慢guidance_scale三个方法7.5无分类器引导强度 1时启用 CFG源码中do_classifier_free_guidance guidance_scale 1.0inpaint_strengthinvert/__call__0.8反演/重绘的噪声化程度[0, 1]1 表示跑满全部时间步0 表示不修复prompt/negative_promptinvert/__call__—反演时 prompt 通常为原图 caption主入口中 prompt 为目标文本、negative_prompt 为 source 文本eta__call__0.0DDIM 的 η 参数仅DDIMScheduler生效源码prepare_extra_step_kwargs会按调度器签名注入lambda_auto_corr/lambda_kl/num_reg_steps/num_auto_corr_rollsinvert20.0 / 20.0 / 0 / 5Pix2PixZero 风格的反演噪声正则化非论文原生内容一般保持默认output_type三个方法np/pilgenerate_mask默认输出 numpy 数组invert与__call__默认输出 PIL调参直觉掩码过大/过小mask_thresholding_ratio调大→掩码更小只改差异最明显的区域num_maps_per_mask增大可抑制掩码噪声抖动。编辑强度主入口的inpaint_strength决定重绘区域被改得多彻底值越低越接近原图。编辑保真度guidance_scale越大越贴合target_prompt但可能牺牲图像质量negative_promptsource_prompt本身就在引导模型不要保持原样。注意事项管线状态StableDiffusionDiffEditPipeline在仓库中被归入 src/diffusers/pipelines/deprecated/stable_diffusion_diffedit/属于实验性且已标记弃用的特性_last_supported_version 0.33.1在较新版本中可能被移除生产使用前请核对 diffusers 版本。输入约束图片宽高需为 8 的整数倍mask_image必须是单通道L且数值落在 [0,1]源码会以 0.5 阈值强制二值化。参数互斥prompt与prompt_embeds、negative_prompt与negative_prompt_embeds不可同时传入且直接传入的prompt_embeds与negative_prompt_embeds形状必须一致。显存策略整套流程包含掩码生成、反演、重绘三次前向建议开启enable_model_cpu_offload()与vae.enable_slicing()BLIP 生成 caption 后记得把模型移回 CPU文档示例中已示范。安全合规safety_checkerNone仅建议在分析、审计等场景使用面向公众的服务应保持安全过滤器开启并遵守 Stable Diffusion 模型许可条件。至此你已经掌握 DiffEdit 从两个文本提示到自动掩码 反演 局部重绘的完整链路并具备用 Flan-T5 自动生成提示、用 BLIP 自动生成 caption 的全自动化扩展能力——整个流程无需任何图像编辑软件介入。【免费下载链接】diffusers Diffusers: State-of-the-art diffusion models for image, video, and audio generation in PyTorch.项目地址: https://gitcode.com/GitHub_Trending/di/diffusers创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价