该存储库为AIGC研究人员提供了最简单的教程代码,只需几行使用Lora。使用本手册,您可以轻松地使用来自Huggingface和Cititai的活跃社区的任何Lora模型。
现在,我们还支持控制网络 - 散布器,T2-apapter-for-fiffusers。
Microsoft开发了大型语言模型(LORA)的低级改编,以减少可训练参数的数量,通过学习成对的排名零件矩阵,同时冻结原始权重。洛拉(Lora)试图微调模型的“残差”,而不是整个模型:即,训练
在哪里
这种训练技巧对于大型通用基础模型上的定制模型非常有用。已经建立在官方稳定扩散的顶部的各种文本到图像模型。现在,有了洛拉,您可以有效地使用更少的资源来培训自己的模型。
SafetEnsors是一种新的简单格式,用于通过拥抱的脸安全地存储张量(与泡菜相对),这仍然很快(零拷贝)。为了效率,许多稳定的扩散模型,尤其是LORA模型都以安全性格式发布。您可以从HuggingFace/SafetEnsors找到更多的优势,并通过PIP安装安装。
pip install safetensors在本教程中,我们显示将预训练的洛拉(Lora)加载或插入扩散器框架中。在Huggingface和Cititai中可以找到许多有趣的项目,但主要是在稳定的扩散 - Webui框架中,这对于高级开发人员而言并不方便。我们是由cloneofsimo/lora激励着加载,合并和插值训练的洛拉斯的动机。我们主要讨论与扩散器不太兼容的安全性格式的模型。
一个完整的模型包括所有需要的模块(带有或不带有LORA层的基本模型),它们通常以.ckpt或.safetensor格式存储。我们在下面提供了两个示例,向您展示了如何使用。
稳定性/稳定扩散2-1来自HuggingFace。
来自Civitai的Dreamshaper。
您只能下载.ckpt或.safetensors文件。尽管扩散器不支持直接加载它们,但它们确实提供了转换脚本。首先将扩散器下载到本地。
git clone https://github.com/huggingface/diffusers cd ./diffusers
# assume you have downloaded xxx.safetensors, it will out save_dir in diffusers format.
python ./scripts/convert_original_stable_diffusion_to_diffusers.py --checkpoint_path xxx.safetensors --dump_path save_dir --from_safetensors
# assume you have downloaded xxx.ckpt, it will out save_dir in diffusers format.
python ./scripts/convert_original_stable_diffusion_to_diffusers.py --checkpoint_path xxx.ckpt --dump_path save_dir然后,您可以加载模型
from diffusers import StableDiffusionPipeline
pipeline = StableDiffusionPipeline.from_pretrained(save_dir,torch_dtype=torch.float32)目前,扩散器无法支持LORA中的负载权重(通常为.safetEnsor格式)。在这里,我们以一种不高的风格展示了我们的尝试。我们还提供一个例子。
请注意,文件的大小比完整型号小得多,因为它仅包含额外的洛拉权重。在这种情况下,我们必须加载基本模型。仅加载稳定扩散1.5作为基础也很好,但是要获得满足结果,建议下载建议的基本模型。
我们的方法非常简单:从.safetEnsor中取出重量,然后将Lora的重量合并为受支持的重量。我们不会将.safetensor转换为其他格式,而是更新基本模型的重量。
我们的脚本应与Huggingface和Cititai的大多数模型一起使用,如果不是,您也可以自己修改代码。相信我,这真的很简单,您可以做到。
# the default mergering ratio is 0.75, you can manually set it
python convert_lora_safetensor_to_diffusers.py我们已经在这个问题上为扩散器建立了PR,在此过程中,我们进一步扭曲了转换功能,以使其更加灵活。如果您不能等待,可以直接检查它。它应尽快合并为扩散器!
扩散器提供了一个简单的train_text_to_image_lora.py来训练您的lora模型。请遵循其说明以安装要求。
export MODEL_NAME= " CompVis/stable-diffusion-v1-4 "
export DATASET_NAME= " lambdalabs/pokemon-blip-captions "
accelerate launch --mixed_precision= " fp16 " train_text_to_image_lora.py
--pretrained_model_name_or_path= $MODEL_NAME
--dataset_name= $DATASET_NAME --caption_column= " text "
--resolution=512 --random_flip
--train_batch_size=1
--num_train_epochs=100 --checkpointing_steps=5000
--learning_rate=1e-04 --lr_scheduler= " constant " --lr_warmup_steps=0
--seed=42
--output_dir= " sd-pokemon-model-lora "
--validation_prompt= " cute dragon creature " --report_to= " wandb "一旦您使用上述命令训练了模型,就可以在加载训练有素的Lora权重后使用StablediffusionPipeline进行推理。您需要传递output_dir来加载Lora权重,在这种情况下,这是SD-Pokemon-Model-Lora。
import torch
from diffusers import StableDiffusionPipeline
model_path = " your_path/sd-model-finetuned-lora-t4 "
pipe = StableDiffusionPipeline.from_pretrained( " CompVis/stable-diffusion-v1-4 " , torch_dtype=torch.float16)
pipe.unet.load_attn_procs(model_path)
pipe.to( " cuda " )
prompt = " A pokemon with green eyes and red legs. "
image = pipe(prompt, num_inference_steps=30, guidance_scale=7.5).images[0]
image.save( " pokemon.png " )目前,扩散器仅支持洛拉(Lora)的UNET。我们已经支持并制作了PR,如果您需要的话,请检查我们的PR或打开问题。
Colossalai已经支持Lora。我们只需要在train_dreambooth_colossalai.py的顶部修改几行。此示例是为Dreambooth提供的,但是您可以轻松地采用常规文本进行图像培训。生成的洛拉重量仅用于UNET的注意力层。如果您也想支持文本编码器,请在扩散器中使用加速框架,因为Colossalai尚不支持多个模型。
from diffusers.loaders import AttnProcsLayers
from diffusers.models.cross_attention import LoRACrossAttnProcessor
# attention here! It is necessaray to init unet under ColoInitContext, not just lora layers
with ColoInitContext(device=get_current_device()):
unet = UNet2DConditionModel.from_pretrained(
args.pretrained_model_name_or_path,
subfolder= " unet " ,
revision=args.revision,
low_cpu_mem_usage=False
)
unet.requires_grad_(False)
# Set correct lora layers
lora_attn_procs = {}
for name in unet.attn_processors.keys ():
cross_attention_dim = None if name.endswith( " attn1.processor " ) else unet.config.cross_attention_dim
if name.startswith( " mid_block " ):
hidden_size = unet.config.block_out_channels[-1]
elif name.startswith( " up_blocks " ):
block_id = int(name[len( " up_blocks. " )])
hidden_size = list(reversed(unet.config.block_out_channels))[block_id]
elif name.startswith( " down_blocks " ):
block_id = int(name[len( " down_blocks. " )])
hidden_size = unet.config.block_out_channels[block_id]
lora_attn_procs[name] = LoRACrossAttnProcessor(
hidden_size=hidden_size, cross_attention_dim=cross_attention_dim
)
unet.set_attn_processor(lora_attn_procs)
lora_layers = AttnProcsLayers(unet.attn_processors)
# DDP
unet = gemini_zero_dpp(unet, args.placement)
# config optimizer for colossalai zero, set initial_scale to large value to avoid underflow
optimizer = GeminiAdamOptimizer(unet,
lr=args.learning_rate,
betas=(args.adam_beta1, args.adam_beta2),
weight_decay=args.adam_weight_decay,
eps=args.adam_epsilon,
initial_scale=2 ** 16,
clipping_norm=args.max_grad_norm)我们走了,唯一的是UNET的初始化方式。仅节省洛拉重量,
torch_unet = get_static_torch_model(unet)
if gpc.get_local_rank(ParallelMode.DATA) == 0:
torch_unet = torch_unet.to(torch.float32)
torch_unet.save_attn_procs(save_path)然后,进行推断
from diffusers import StableDiffusionPipeline
import torch
model_path = " sd-model-finetuned-lora "
pipe = StableDiffusionPipeline.from_pretrained( " CompVis/stable-diffusion-v1-4 " , torch_dtype=torch.float16)
pipe.unet.load_attn_procs(model_path)
pipe.to( " cuda " )
prompt = " A pokemon with green eyes and red legs. "
image = pipe(prompt, num_inference_steps=30, guidance_scale=7.5).images[0]
image.save( " pokemon.png " )您可能会发现生成的LORA重量仅约3MB大小,这是由于默认设置。为了增加尺寸,您可以手动设置Lora层的等级(低等级分解的尺寸)。
lora_attn_procs[name] = LoRACrossAttnProcessor(hidden_size=hidden_size, cross_attention_dim=cross_attention_dim, rank=128)然后,Lora的重量约为100-200MB。一般而言,洛拉层易于过度贴合,一般而言,在小型数据集(小于1k图像)上仅训练100-2000步,批处理大小= 64。
(1)我可以在合并时手动调整洛拉的重量吗?
是的,这里的alpha是洛拉的重量。我们已向扩散器提交了PR,在那里我们提供了灵活的搏动功能。
(2)我只能将lora(.safetensor)转换为扩散器支持的其他格式吗?
您可以,但我们不建议,请看到此问题。有很多局限性。例如,我们的脚本无法推广到所有.safetensors,因为其中一些具有不同的命名。此外,当前的扩散器框架仅支持将Lora添加到UNET的注意层中,而来自Civitai的许多safetEnsor都包含用于其他模块(例如文本编码器)的lora权重。但是,应尽快支持文本编码器的Lora。
(3)我可以混合多个洛拉模型吗?
是的,唯一的是合并两次。但是,请小心地设置α(Lora的重量),如果Alpha太大,模型会降低。
(4)这个项目的动机是什么?
我们发现Civitai平台上有许多令人难以置信的模型,但是大多数Lora权重都采用安全性格式,这对于扩散器用户而言并不方便。因此,我们编写一个转换脚本,以便您可以在扩散器中使用这些Loras。请注意,我们不是稳定扩散 - webui的目标,它已经非常成熟,但作为扩散器的API完全不同。