ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Diffusers 中的 LoRA 低秩适配训练:从 DreamBooth 到 Text-to-Image 的完整实战指南

Diffusers 中的 LoRA 低秩适配训练:从 DreamBooth 到 Text-to-Image 的完整实战指南 Diffusers 中的 LoRA 低秩适配训练从 DreamBooth 到 Text-to-Image 的完整实战指南【免费下载链接】diffusers Diffusers: State-of-the-art diffusion models for image, video, and audio generation in PyTorch.项目地址: https://gitcode.com/GitHub_Trending/di/diffusers本文围绕 Diffusers 仓库中基于 LoRALow-Rank Adaptation of Large Language Models的低成本微调方案展开系统讲解 LoRA 的核心原理、train_dreambooth_lora.py与train_text_to_image_lora.py两个训练脚本的完整用法、关键命令行参数以及训练完成后如何用load_attn_procs/load_lora_weights加载适配器并通过scale控制融合强度。读完本文你将能够在单张消费级 GPU 上完成 Stable Diffusion 的个性化微调并掌握从训练到推理的完整闭环。LoRA 是什么用极少量可训练参数完成大模型微调LoRALow-Rank Adaptation of Large Language Models 是一种在保持内存占用较低的同时加速大模型训练的轻量级学习方法。它的核心思路是向模型中插入一组秩分解权重矩阵对rank-decomposition weight matrix pairs即所谓的更新矩阵update matrices并且在训练过程中只训练这些新加入的权重原始预训练权重保持冻结。这种设计带来几个关键优势避免灾难性遗忘catastrophic forgetting由于预先训练好的权重始终被固定模型在学习新数据时不会破坏原有能力参数规模极小、便于分发秩分解矩阵的参数量远小于原始模型训练得到的 LoRA 权重文件通常只有几百 MB容易存储与共享也可以与其他训练技术如 DreamBooth组合使用以加速训练低显存门槛内存效率显著提升可以在 Tesla T4、RTX 3080 或 RTX 2080 Ti 这类消费级 GPU 上直接运行微调其中 T4 在 Kaggle 或 Google Colab 笔记本上即可免费获得。[!WARNING] 当前版本中LoRA 权重主要作用于模型内部的注意力attention层。文档明确指出当前 LoRA 仅在UNet2DConditionModel的注意力层中得到支持。[!TIP] LoRA 并不局限于注意力层。原作者发现在语言模型中仅修改注意力层即可高效获得良好性能这正是 LoRA 权重通常被添加到模型注意力层的普遍原因。关于 LoRA 原理更深入的解释可参考 Hugging Face 官方博客Using LoRA for effective Stable Diffusion fine-tuning。在 Diffusers 中cloneofsimo最早在公开的lora仓库中尝试了对 Stable Diffusion 的 LoRA 训练。随后 Diffusers 官方在 text-to-image 训练 与 DreamBooth 训练 两个示例脚本中都内置了 LoRA 支持本文会逐一演示这两种用法。开始之前如果希望将模型保存到 Hub 或与社区共享请先登录 Hugging Face 账号没有账号可先注册hf auth login环境准备安装依赖与配置 Accelerate从源码安装 Diffusers 并安装示例依赖训练脚本运行前建议直接从源码安装 Diffusers以确保使用到仓库中最新的 APIgit clone https://github.com/huggingface/diffusers cd diffusers pip install .随后进入包含训练脚本的示例目录安装该脚本所需的依赖cd examples/text_to_image pip install -r requirements.txt若使用 DreamBooth LoRA 脚本则安装 examples/dreambooth/requirements.txt 中的依赖。初始化 Accelerate 环境 Accelerate 用于在多 GPU/TPU 或混合精度场景下辅助训练它会根据硬件与环境自动配置训练设置。初始化方式有三种# 交互式配置 accelerate config# 使用默认配置不做任何自定义选择 accelerate config default对于不支持交互式 shell 的环境如 Jupyter Notebook可以在代码中直接写入基础配置from accelerate.utils import write_basic_config write_basic_config()准备自己的训练数据集如果想用自己的数据训练可以参考 创建训练数据集指南学习如何构造与训练脚本兼容的数据集脚本同时支持从 Hub 加载数据集与从本地imagefolder目录读取数据两种方式见 train_text_to_image_lora.py。训练脚本参数LoRA 相关的两个核心参数训练脚本通过parse_args()暴露了大量可定制参数大多数参数都提供了表现良好的默认值。基础参数的详细说明可参考 Text-to-image 训练指南这里重点介绍与 LoRA 直接相关的两个参数--rank低秩矩阵的内部维度inner dimension。rank越大可训练参数越多模型表达能力越强但显存与存储开销也随之上升在 train_text_to_image_lora.py 中其默认值为4--learning_rate默认学习率为1e-4。得益于 LoRA 只训练少量新参数通常可以采用比全量微调更高的学习率。例如要增加训练轮数可以这样指定accelerate launch train_text_to_image_lora.py \ --num_train_epochs150 \训练脚本剖析LoRA 适配器如何接入模型训练脚本的数据预处理与训练循环都集中在main()函数中见 train_text_to_image_lora.py如果要改造脚本这里就是修改的切入点。与全量微调脚本train_text_to_image.py相比LoRA 版本的主要差异集中在适配器的创建与过滤上。UNet 场景用 PEFT 的 LoraConfig 注入适配器Diffusers 使用 PEFT 库中的LoraConfig来配置 LoRA 适配器的参数包括rank、alpha以及要插入 LoRA 权重的目标模块。适配器被添加到 UNet 上随后通过lora_layers过滤出唯一需要优化的 LoRA 层unet_lora_config LoraConfig( rargs.rank, lora_alphaargs.rank, init_lora_weightsgaussian, target_modules[to_k, to_q, to_v, to_out.0], ) unet.add_adapter(unet_lora_config) lora_layers filter(lambda p: p.requires_grad, unet.parameters())从源码可见训练前会先将 UNet、VAE、文本编码器全部冻结requires_grad_(False)见 train_text_to_image_lora.py再通过add_adapter注入 LoRA 层从而保证只有 LoRA 权重参与更新。在 fp16 混合精度训练时还会调用cast_training_params(unet, dtypetorch.float32)将可训练参数上转为 float32以保障数值稳定性见 train_text_to_image_lora.py。target_modules中的to_q、to_k、to_v、to_out.0分别对应注意力机制中的 query、key、value 投影与输出投影这正是 LoRA 作用于注意力层的直接体现。文本编码器场景SDXL 等模型的扩展支持当需要微调文本编码器时例如训练 Stable Diffusion XLDiffusers 同样通过 PEFT 的LoraConfig为文本编码器添加适配器并只过滤训练 LoRA 层text_lora_config LoraConfig( rargs.rank, lora_alphaargs.rank, init_lora_weightsgaussian, target_modules[q_proj, k_proj, v_proj, out_proj], ) text_encoder_one.add_adapter(text_lora_config) text_encoder_two.add_adapter(text_lora_config) text_lora_parameters_one list(filter(lambda p: p.requires_grad, text_encoder_one.parameters())) text_lora_parameters_two list(filter(lambda p: p.requires_grad, text_encoder_two.parameters()))优化器只优化 LoRA 层优化器使用前面过滤出的lora_layers初始化因为这些是唯一需要优化的权重见 train_text_to_image_lora.pyoptimizer optimizer_cls( lora_layers, lrargs.learning_rate, betas(args.adam_beta1, args.adam_beta2), weight_decayargs.adam_weight_decay, epsargs.adam_epsilon, )默认使用torch.optim.AdamW若安装了bitsandbytes并传入--use_8bit_adam则会切换为bnb.optim.AdamW8bit8 位优化器以进一步降低显存占用见 train_text_to_image_lora.py。此外脚本通过accelerator.register_save_state_pre_hook/register_load_state_pre_hook注册了 LoRA 权重的专用保存与加载钩子见 train_text_to_image_lora.py保存时调用StableDiffusionPipeline.save_lora_weights写出pytorch_lora_weights.safetensors断点续训时则通过lora_state_dict与convert_unet_state_dict_to_peft将权重还原回 PEFT 适配器。除 LoRA 层的设置外训练脚本整体流程与train_text_to_image.py基本一致。实战一Text-to-Image 的 LoRA 微调启动训练下面用 Naruto BLIP captions 数据集微调stable-diffusion-v1-5/stable-diffusion-v1-5训练一个能生成火影忍者风格角色的模型。首先设置环境变量MODEL_NAME指定基础模型DATASET_NAME指定数据集OUTPUT_DIR与HUB_MODEL_ID可选分别指定模型在本地与 Hub 上的保存位置export MODEL_NAMEstable-diffusion-v1-5/stable-diffusion-v1-5 export OUTPUT_DIR/sddata/finetune/lora/naruto export HUB_MODEL_IDnaruto-lora export DATASET_NAMElambdalabs/naruto-blip-captions训练完成后脚本会在输出目录中生成以下文件模型检查点checkpointpytorch_lora_weights.safetensors训练得到的 LoRA 权重多卡训练时请在accelerate launch命令中追加--multi_gpu参数。[!WARNING] 在 11GB 显存的 2080 Ti GPU 上完整训练一次大约需要 5 小时。启动训练accelerate launch --mixed_precisionfp16 train_text_to_image_lora.py \ --pretrained_model_name_or_path$MODEL_NAME \ --dataset_name$DATASET_NAME \ --dataloader_num_workers8 \ --resolution512 \ --center_crop \ --random_flip \ --train_batch_size1 \ --gradient_accumulation_steps4 \ --max_train_steps15000 \ --learning_rate1e-04 \ --max_grad_norm1 \ --lr_schedulercosine \ --lr_warmup_steps0 \ --output_dir${OUTPUT_DIR} \ --push_to_hub \ --hub_model_id${HUB_MODEL_ID} \ --report_towandb \ --checkpointing_steps500 \ --validation_promptA naruto with blue eyes. \ --seed1337推理加载 LoRA 权重生成图像训练完成后用AutoPipelineForText2Image加载基础模型与 LoRA 权重进行推理from diffusers import AutoPipelineForText2Image import torch pipeline AutoPipelineForText2Image.from_pretrained(stable-diffusion-v1-5/stable-diffusion-v1-5, dtypetorch.float16).to(cuda) # 或 mps、xpu、cpu pipeline.load_lora_weights(path/to/lora/model, weight_namepytorch_lora_weights.safetensors) image pipeline(A naruto with blue eyes).images[0]其中load_lora_weights是 Diffusers 在 lora_pipeline.py 中提供的通用 LoRA 加载接口支持从本地路径或 Hub 仓库加载pytorch_lora_weights.safetensors。实战二DreamBooth LoRA 微调准备环境变量DreamBooth 是另一种常见的个性化微调方案通过少量通常 3~5 张同一主体的图片配合唯一标识符如sks dog来学习特定对象。与 LoRA 结合后训练速度与显存开销都大幅下降。以下基于 train_dreambooth_lora.py 演示。训练前需要设置MODEL_NAME基础模型与INSTANCE_DIR实例图片目录即待学习主体所在的本地文件夹。OUTPUT_DIR与HUB_MODEL_ID可选分别指定模型在本地与 Hub 上的保存位置export MODEL_NAMEstable-diffusion-v1-5/stable-diffusion-v1-5 export INSTANCE_DIR./dog # 包含 sks dog 示例图片的本地目录 export OUTPUT_DIR/sddata/finetune/lora/dog export HUB_MODEL_IDdog-lora关键训练标志说明开始训练前需要了解几个重要参数--push_to_hub将训练好的 LoRA 权重保存到 Hub--report_towandb将训练结果与日志上报到 Weights Biases 仪表盘--learning_rate1e-04LoRA 训练通常可以采用比全量微调更高的学习率--rank低秩矩阵维度默认4见 train_dreambooth_lora.py--lora_dropoutLoRA 层的 dropout 概率默认0.0见 train_dreambooth_lora.py。启动训练accelerate launch train_dreambooth_lora.py \ --pretrained_model_name_or_path$MODEL_NAME \ --instance_data_dir$INSTANCE_DIR \ --output_dir$OUTPUT_DIR \ --instance_prompta photo of sks dog \ --resolution512 \ --train_batch_size1 \ --gradient_accumulation_steps1 \ --checkpointing_steps100 \ --learning_rate1e-4 \ --report_towandb \ --lr_schedulerconstant \ --lr_warmup_steps0 \ --max_train_steps500 \ --validation_promptA photo of sks dog in a bucket \ --validation_epochs50 \ --seed0 \ --push_to_hub推理加载注意力处理器并控制融合比例训练完成后通过StableDiffusionPipeline加载基础模型然后在基础模型权重之上叠加 DreamBooth 微调得到的 LoRA 权重并将 pipeline 迁移到 GPU 以加速推理import torch from diffusers import StableDiffusionPipeline model_base stable-diffusion-v1-5/stable-diffusion-v1-5 pipe StableDiffusionPipeline.from_pretrained(model_base, dtypetorch.float16) pipe.unet.load_attn_procs(model_path) pipe.to(cuda)[!TIP] scale参数用于控制 LoRA 权重与冻结的预训练权重合并时的比例scale0表示完全不使用 LoRA 权重等价于只用原始模型scale1表示完全使用微调后的 LoRA 权重0 到 1 之间的值则是在两者结果之间进行插值。# 使用 50% 的 LoRA 权重 50% 的基础模型权重 image pipe( A picture of a sks dog in a bucket., num_inference_steps25, guidance_scale7.5, cross_attention_kwargs{scale: 0.5}, ).images[0] # 完全使用微调后的 LoRA 权重 image pipe(A picture of a sks dog in a bucket., num_inference_steps25, guidance_scale7.5).images[0] image.save(bucket-dog.png)load_attn_procs 背后的实现load_attn_procs定义于 src/diffusers/loaders/unet.py用于将预训练的注意力处理器attention processor层加载进UNet2DConditionModel。其入参可以是 Hub 上的模型 ID、包含权重的本地目录路径或直接传入 torch state dict同时支持weight_name指定序列化的权重文件名、cache_dir指定缓存目录、revision指定模型版本等参数。它的执行流程是优先尝试加载.safetensors权重再通过set_peft_model_state_dict将状态字典还原到 PEFT 适配器结构中参见 train_text_to_image_lora.py 中的加载钩子实现。Diffusers 还提供更高级的fuse_lora方法见 src/diffusers/loaders/peft.py可以在推理前将 LoRA 权重**融合fuse**进原始权重中从而在不额外调用 LoRA 前向逻辑的情况下获得与scale参数等价的控制效果——传入lora_scale即对应这里的scale语义。下一步学习恭喜你完成了 LoRA 微调的全流程想进一步深入可以参考以下主题学习如何加载 Kohya、TheLastBen 等社区训练器产出的不同 LoRA 格式学习如何使用 PEFT 组合多个 LoRA 进行推理实现风格叠加参考 DreamBooth 训练指南 与 Text-to-image 训练指南对比 LoRA 方案与全量微调方案在参数、脚本结构与训练流程上的异同。【免费下载链接】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),仅供参考
返回列表