ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Diffusers 实战:用 InstructPix2Pix 微调 Stable Diffusion 实现指令驱动图像编辑

Diffusers 实战:用 InstructPix2Pix 微调 Stable Diffusion 实现指令驱动图像编辑 Diffusers 实战用 InstructPix2Pix 微调 Stable Diffusion 实现指令驱动图像编辑【免费下载链接】diffusers Diffusers: State-of-the-art diffusion models for image, video, and audio generation in PyTorch.项目地址: https://gitcode.com/GitHub_Trending/di/diffusers本文基于 diffusers 仓库中的 train_instruct_pix2pix.py 训练脚本系统讲解如何对 Stable Diffusion 进行 InstructPix2Pix 微调使其能根据一句自然语言编辑指令修改输入图片。读完本文你将掌握从依赖安装、数据准备、单卡与多卡训练到参数调优与推理部署的完整闭环并能理解训练脚本与推理管线背后的关键实现原理。InstructPix2Pix 方法概述InstructPix2Pix对应论文 arXiv 2211.09800是一种对文本条件扩散模型进行微调的方法目标是让模型能够遵循针对单张输入图像的编辑指令完成图像编辑。经过该方法微调后的模型其输入由两部分组成原始输入图像待编辑的目标图片编辑指令edit prompt一段描述期望编辑效果的自然语言例如 把雪山变成草地、擦除湖面。模型的输出则是应用了该编辑指令后的已编辑图像即输入图像与编辑指令语义对齐的新图片。在该训练框架中训练数据由三元组构成input_image原始图、edit_prompt编辑指令、edited_image编辑后的目标图。训练目标是让模型学会从原始图 指令出发去噪出编辑后的图从而实现指令驱动instruction-driven的编辑能力。环境准备与依赖安装从源码安装 diffusers官方强烈建议从源码source安装 diffusers因为示例脚本更新频繁且带有示例专属依赖。请在全新虚拟环境中执行git clone https://github.com/huggingface/diffusers cd diffusers pip install -e .说明上述命令将仓库克隆到本地并以可编辑模式安装。本文所分析的当前仓库即为该示例脚本的所在项目训练脚本位于 examples/instruct_pix2pix/train_instruct_pix2pix.py。安装示例专属依赖进入示例目录并安装 requirements.txt 中声明的依赖cd examples/instruct_pix2pix pip install -r requirements.txt该文件声明的核心依赖如下依赖版本要求用途accelerate0.16.0分布式训练、混合精度与训练基础设施torchvision—图像变换transforms与数据增强transformers4.25.1CLIP 文本编码器与分词器datasets—加载 Hugging Face Hub 数据集或本地imagefolderftfy—文本清洗修正 Unicode 编码问题tensorboard—默认训练日志记录如需在训练中启用验证推理可视化report_towandb还需额外安装pip install wandb。初始化 Accelerate 环境训练依赖 Accelerate 管理设备、混合精度与分布式环境。三种初始化方式任选其一交互式配置推荐可按环境定制accelerate config使用默认配置无需回答环境问题accelerate config default非交互式环境如 notebook 无法使用交互式 shellfrom accelerate.utils import write_basic_config write_basic_config()从源码实现看脚本通过Accelerator统一管理梯度累积步数、混合精度与日志后端见 train_instruct_pix2pix.py 中accelerator Accelerator(gradient_accumulation_steps..., mixed_precision..., log_with..., project_config...)的初始化逻辑。数据集准备使用公开玩具数据集快速验证脚本作者已声明train_instruct_pix2pix.py忠实实现了 InstructPix2Pix 的训练流程但仅在小型数据集上测试过这可能会影响最终效果。为了更好的结果建议使用更大的数据集、训练更长时间。本文示例使用小型玩具数据集fusing/instructpix2pix-1000-samples它是论文原始数据集CLIP 过滤版的缩小版本。脚本内置了该数据集的三元组列名映射DATASET_NAME_MAPPING { fusing/instructpix2pix-1000-samples: (input_image, edit_prompt, edited_image), }即默认约定input_image列为原始图、edit_prompt列为编辑指令、edited_image列为编辑后的目标图。若使用自定义数据集可通过--original_image_column、--edit_prompt_column、--edited_image_column三个参数覆盖默认列名数据加载支持两种方式--dataset_nameHugging Face Hub 上的数据集标识符或本地数据集路径--train_data_dir本地文件夹需遵循imagefolder结构含metadata.jsonl提供标注。关于如何构建自己的训练数据集可参考仓库中的 create_dataset 指南。设置环境变量export MODEL_NAMEstable-diffusion-v1-5/stable-diffusion-v1-5 export DATASET_IDfusing/instructpix2pix-1000-samplesMODEL_NAME作为--pretrained_model_name_or_path传入可以是 Hub 上的模型仓库标识符也可以是包含模型权重的本地文件夹路径DATASET_ID作为--dataset_name传入指定训练数据集。启动训练完整命令与参数解析执行以下命令启动训练。脚本会把所有组件feature_extractor、scheduler、text_encoder、unet、vae等以 diffusers 格式保存到输出目录的子文件夹中accelerate launch --mixed_precisionfp16 train_instruct_pix2pix.py \ --pretrained_model_name_or_path$MODEL_NAME \ --dataset_name$DATASET_ID \ --enable_xformers_memory_efficient_attention \ --resolution256 --random_flip \ --train_batch_size4 --gradient_accumulation_steps4 --gradient_checkpointing \ --max_train_steps15000 \ --checkpointing_steps5000 --checkpoints_total_limit1 \ --learning_rate5e-05 --max_grad_norm1 --lr_warmup_steps0 \ --conditioning_dropout_prob0.05 \ --mixed_precisionfp16 \ --seed42 \ --push_to_hub关键参数详解结合 train_instruct_pix2pix.py 中的参数定义逐项说明参数示例值说明--pretrained_model_name_or_path必填预训练模型路径或 Hub 标识符脚本会分别加载scheduler、tokenizer、text_encoder、vae、unet子目录--revision/--variant—模型仓库的分支/标签版本如fp16variant--dataset_namefusing/instructpix2pix-1000-samples训练数据集与--train_data_dir二选一二者皆空会直接报错--resolution256输入图像统一缩放分辨率论文作者观察到 256 分辨率训练的模型可良好泛化到 512 等更大分辨率得益于其大训练数据集--center_crop/--random_flip—中心裁剪默认随机裁剪/ 随机水平翻转增强--train_batch_size4每设备 batch 大小默认 16--gradient_accumulation_steps4累积多少步后再执行一次参数更新默认 1--gradient_checkpointing开以更慢的反向传播换取显存节省--max_train_steps15000总训练步数指定后覆盖--num_train_epochs默认 100 轮--checkpointing_steps5000每多少步保存一次训练状态默认 500可用于--resume_from_checkpoint恢复训练--checkpoints_total_limit1最多保留的 checkpoint 数量超限时自动删除最旧的--learning_rate5e-05学习率默认1e-4可用--scale_lr按 GPU 数、batch、累积步数缩放--lr_scheduler/--lr_warmup_stepsconstant/0调度器类型支持linear、cosine、cosine_with_restarts、polynomial、constant、constant_with_warmup与预热步数默认 500--max_grad_norm1梯度裁剪范数上限--conditioning_dropout_prob0.05条件丢弃概率见下文原理章节--mixed_precisionfp16混合精度可选no/fp16/bf16bf16 需 PyTorch 1.10 与 Ampere GPU--seed42训练随机种子--push_to_hub开训练结束后把模型推送至 Hub--use_ema—为 UNet 维护指数移动平均EMA模型通常可提升生成质量--use_8bit_adam—使用 bitsandbytes 的 8-bit AdamW 节省显存--allow_tf32—在 Ampere GPU 上允许 TF32 加速训练--report_totensorboard日志后端支持tensorboard默认、wandb、comet_ml、all--resume_from_checkpoint—传入 checkpoint 路径或latest自动恢复最近一次训练状态训练数据预处理要点脚本对数据集的预处理逻辑值得注意对应preprocess_images/preprocess_train函数原始图与编辑后的目标图会被拼接在一起后施加相同的数据增强随机裁剪或中心裁剪、随机水平翻转以保证两张图经过完全一致的几何变换像素值归一化到[-1, 1]区间2 * (images / 255) - 1编辑指令通过 CLIP tokenizer 以max_length填充并截断为定长序列。用 Weights Biases 监控训练与验证推理脚本额外支持在训练过程中执行验证推理将原始图 验证提示词送入当前训练状态的模型生成编辑结果并上传到 WB便于实时观察模型是否在学会遵循指令对模型调试非常有用。启用方式为--report_towandbaccelerate launch --mixed_precisionfp16 train_instruct_pix2pix.py \ --pretrained_model_name_or_path$MODEL_NAME \ --dataset_name$DATASET_ID \ --enable_xformers_memory_efficient_attention \ --resolution256 --random_flip \ --train_batch_size4 --gradient_accumulation_steps4 --gradient_checkpointing \ --max_train_steps15000 \ --checkpointing_steps5000 --checkpoints_total_limit1 \ --learning_rate5e-05 --max_grad_norm1 --lr_warmup_steps0 \ --conditioning_dropout_prob0.05 \ --mixed_precisionfp16 \ --val_image_urlhttps://hf.co/datasets/diffusers/diffusers-images-docs/resolve/main/mountain.png \ --validation_promptmake the mountains snowy \ --seed42 \ --report_towandb \ --push_to_hub相关参数--val_image_url验证用的原始图片 URL用于调试推理--validation_prompt验证提示词例如上例的 make the mountains snowy让山脉积雪--num_validation_images验证生成张数默认 4--validation_epochs每多少轮执行一次验证默认 1。从源码看验证在log_validation函数中实现每轮结束时若指定了验证 URL 与提示词脚本会用当前或 EMA 的UNet 重建StableDiffusionInstructPix2PixPipeline以num_inference_steps20、image_guidance_scale1.5、guidance_scale7的参数生成编辑图并将原始图、编辑图、编辑指令以 WB Table 的形式记录。注意--report_towandb与--hub_token不能同时使用存在 token 泄露风险Hub 认证请使用hf auth login。注论文作者发现用 256×256 分辨率训练得到的模型可以很好地泛化到 512×512 等更高分辨率这主要归功于其训练所用的大规模数据集。多 GPU 分布式训练accelerate提供了无缝的多 GPU 训练支持。先通过accelerate config完成分布式环境配置或阅读 Accelerate 的 launch 教程再使用--multi_gpu启动。示例命令accelerate launch --mixed_precisionfp16 --multi_gpu train_instruct_pix2pix.py \ --pretrained_model_name_or_pathstable-diffusion-v1-5/stable-diffusion-v1-5 \ --dataset_namesayakpaul/instructpix2pix-1000-samples \ --use_ema \ --enable_xformers_memory_efficient_attention \ --resolution512 --random_flip \ --train_batch_size4 --gradient_accumulation_steps4 --gradient_checkpointing \ --max_train_steps15000 \ --checkpointing_steps5000 --checkpoints_total_limit1 \ --learning_rate5e-05 --lr_warmup_steps0 \ --conditioning_dropout_prob0.05 \ --mixed_precisionfp16 \ --seed42 \ --push_to_hub与单卡命令相比此例额外开启了--use_ema并将分辨率提升至 512。脚本内部对分布式做了多处适配例如用accelerator.prepare统一包装 UNet、优化器、数据加载器与 LR 调度器学习率调度器的 warmup 步数与总步数会乘以进程数num_warmup_steps_for_scheduler args.lr_warmup_steps * accelerator.num_processescheckpoint 的保存与加载通过save_model_hook/load_model_hook以 diffusers 格式序列化 UNet 与 EMA 权重损失值通过accelerator.gather跨进程聚合后用于日志记录。训练核心实现原理源码级解析8 通道 UNet为双条件输入扩展输入层InstructPix2Pix 使用额外的图像原始图作为条件。为此UNet 第一个卷积层的输入通道数从 4 扩为8其中 4 个通道承载加噪后的编辑目标图潜在表示另外 4 个通道承载原始输入图的潜在表示。脚本的关键初始化代码如下in_channels 8 out_channels unet.conv_in.out_channels unet.register_to_config(in_channelsin_channels) with torch.no_grad(): new_conv_in nn.Conv2d( in_channels, out_channels, unet.conv_in.kernel_size, unet.conv_in.stride, unet.conv_in.padding ) new_conv_in.weight.zero_() new_conv_in.weight[:, :4, :, :].copy_(unet.conv_in.weight) unet.conv_in new_conv_in新增的 4 个通道权重初始化为零前 4 个通道则从预训练 checkpoint 复制从而在保留预训练能力的同时引入图像条件输入。其余组件保持冻结vae与text_encoder均requires_grad_(False)只有 UNet 参与训练EMA 可选地维护 UNet 权重副本。前向扩散与损失计算每个训练步的核心流程对应主训练循环将编辑目标图编码到潜在空间并采样latents vae.encode(edited_pixel_values).latent_dist.sample()再乘以vae.config.scaling_factor为每个样本采样随机时间步按 DDPM 调度器执行前向加噪noisy_latents noise_scheduler.add_noise(latents, noise, timesteps)文本条件encoder_hidden_states text_encoder(input_ids)[0]图像条件取原始图潜在表示的**众数mode**而非随机采样original_image_embeds vae.encode(original_pixel_values).latent_dist.mode()将加噪潜在表示与原始图条件在通道维拼接torch.cat([noisy_latents, original_image_embeds], dim1)依据prediction_type确定回归目标epsilon类型直接以噪声为 targetv_prediction类型则用get_velocity计算UNet 前向得到预测值与目标计算 MSE 损失F.mse_loss(model_pred.float(), target.float(), reductionmean)梯度裁剪max_grad_norm、优化器与调度器步进、EMA 更新若启用。Conditioning Dropout支撑推理时的 Classifier-Free Guidance训练中的--conditioning_dropout_prob论文第 3.2.1 节是让模型在推理时支持无分类器引导的关键。实现逻辑为以2 * conditioning_dropout_prob的概率把文本条件替换为空文本嵌入用空字符串 tokenize 得到以conditioning_dropout_prob的概率把图像条件置零if args.conditioning_dropout_prob is not None: random_p torch.rand(bsz, devicelatents.device, generatorgenerator) # 文本条件 mask以 2*p 概率替换为空条件 prompt_mask random_p 2 * args.conditioning_dropout_prob encoder_hidden_states torch.where(prompt_mask, null_conditioning, encoder_hidden_states) # 图像条件 mask以 p 概率置零 image_mask 1 - ((random_p p) * (random_p 3 * p)) original_image_embeds image_mask * original_image_embeds这样训练出的模型同时见过有/无文本条件与有/无图像条件推理时即可通过引导尺度在忠实指令与忠实原图之间自由权衡。推理加载模型并编辑图像训练完成后即可用StableDiffusionInstructPix2PixPipeline进行推理import PIL import requests import torch from diffusers import StableDiffusionInstructPix2PixPipeline model_id your_model_id # - 替换为你的模型 ID pipe StableDiffusionInstructPix2PixPipeline.from_pretrained(model_id, dtypetorch.float16).to(cuda) generator torch.Generator(cuda).manual_seed(0) url https://huggingface.co/datasets/sayakpaul/sample-datasets/resolve/main/test_pix2pix_4.png def download_image(url): image PIL.Image.open(requests.get(url, streamTrue).raw) image PIL.ImageOps.exif_transpose(image) image image.convert(RGB) return image image download_image(url) prompt wipe out the lake num_inference_steps 20 image_guidance_scale 1.5 guidance_scale 10 edited_image pipe( prompt, imageimage, num_inference_stepsnum_inference_steps, image_guidance_scaleimage_guidance_scale, guidance_scaleguidance_scale, generatorgenerator, ).images[0] edited_image.save(edited_image.png)注意model_id需要替换为你自己的模型标识符该训练脚本产出的示例模型仓库可参考社区公开示例sayakpaul/instruct-pix2pix。三个关键推理参数官方建议重点调节以下三个参数来控制生成速度与质量参数默认值作用num_inference_steps20示例去噪步数步数越多质量越高但耗时越长guidance_scale10示例文本指令引导强度越大越忠实于指令文本image_guidance_scale1.5示例原图引导强度越大越接近输入原图其中image_guidance_scale与guidance_scale对生成的已编辑图像影响尤为显著值得重点调参。双引导的数学实现在 pipeline_stable_diffusion_instruct_pix2pix.py 的推理循环中无分类器引导被同时应用于文本与输入图像两个条件。因为存在两类条件潜变量被复制为 3 份分别得到纯文本引导预测noise_pred_text、文本图像引导预测noise_pred_image、无条件预测noise_pred_uncond最终融合公式为noise_pred noise_pred_uncond guidance_scale * (noise_pred_text - noise_pred_image) image_guidance_scale * (noise_pred_image - noise_pred_uncond)该公式见管线源码第 441-448 行直观体现了两个尺度的语义guidance_scale控制编辑指令的影响力image_guidance_scale控制原图的保持程度。管线还通过do_classifier_free_guidance属性guidance_scale 1.0 且 image_guidance_scale 1.0时为真判断是否启用双引导并对 UNet 输入通道进行校验加噪潜变量通道数与原图潜变量通道数之和必须等于 UNet 配置的in_channels即 8否则报错提示配置不一致。进阶Stable Diffusion XL 变体仓库还提供了等价的 train_instruct_pix2pix_sdxl.py 脚本针对 Stable Diffusion XL详见 README_sdxl.md。SDXL 变体的训练范式与本例一致仅在基础模型与部分组件上有所差异。常见问题与实用建议效果不佳时优先增大数据与训练时长脚本仅在 1000 样本的小数据集上验证过官方明确提示小数据集会直接影响最终效果论文原版使用 CLIP 过滤的大规模数据集建议获取更大数据集并延长训练显存紧张组合使用--gradient_checkpointing、--use_8bit_adam、--mixed_precisionfp16、--enable_xformers_memory_efficient_attention需安装 xformers注意 0.0.16 版本在部分 GPU 上有已知问题建议升级到 0.0.17可显著降低占用想要更稳定的生成质量开启--use_ema维护 EMA 权重验证与最终保存时脚本会自动把 EMA 参数复制回 UNet断点续训用--checkpointing_steps定期保存、--resume_from_checkpointlatest自动恢复最近一次训练进度灵活的实验数据集如需快速验证脚本流程可用--max_train_samples截断训练样本数进行小规模调试。如果希望探索 InstructPix2Pix 训练方法论在更多场景中的应用可进一步阅读社区关于Instruction-tuning Stable Diffusion with InstructPix2Pix的相关技术文章官方博客与社区示例均有讨论。【免费下载链接】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),仅供参考
返回列表