Este repositório fornece o código do tutorial mais simples para os pesquisadores da AIGC usarem o LORA em apenas algumas linhas. Usando este manual, você pode brincar facilmente com qualquer modelo LORA de comunidades ativas como Huggingface e Cititai.
Agora, também apoiamos o ControlNet-For-Hiffusers, T2I-Adapter-For-Diffusers.
A adaptação de baixo rank de grandes modelos de linguagem (LORA) é desenvolvida pela Microsoft para reduzir o número de parâmetros treináveis, aprendendo pares de matrizes de decomposição de classificação enquanto congelam os pesos originais. Lora tenta ajustar o "resíduo" do modelo em vez de todo o modelo: ou seja, treinar o
Onde
Esse truque de treinamento é bastante útil para modelos personalizados de ajuste de FUNE em um grande modelo de base geral. Vários modelos de texto para imagens foram desenvolvidos construídos na parte superior da difusão estável oficial. Agora, com a Lora, você pode treinar com eficiência seu próprio modelo com muito menos recursos.
O SafeTetens é um novo formato simples para armazenar tensores com segurança (em oposição ao picles) liberado abraçando o rosto e isso ainda é rápido (zero cópia). Para sua eficiência, muitos modelos de difusão estáveis, especialmente os modelos LORA, são liberados no formato SafeTetens. Você pode encontrar mais suas vantagens a partir de Huggingface/SafeTetens e instalá -lo via instalação PIP.
pip install safetensorsNeste tutorial, mostramos carregar ou inserir a estrutura de Lora pré-treinada na estrutura de difusores. Muitos projetos interessantes podem ser encontrados no Huggingface e Cititai, mas principalmente na estrutura estável-difusão-webui, o que não é conveniente para desenvolvedores avançados. Altamente motivados por CloneofSimo/Lora sobre o carregamento, a fusão e a interpolação de Loras treinados. Discutimos principalmente modelos no formato SafeTetens, que não são bem compatíveis com os difusores.
Um modelo completo inclui todos os módulos necessários (modelo base com ou sem camadas de LORA), eles geralmente são armazenados no formato .ckpt ou. Fornecemos dois exemplos abaixo para mostrar como usar em mãos.
Stabilityai/stable-difusão-2-1 do huggingface.
Dreamshaper de Civitai.
Você pode baixar apenas o arquivo .ckpt ou .SafeTenors. Embora os difusores não suportem carregá -los diretamente, eles fornecem o script de conversão. Primeiro baixe difusores para o local.
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_dirEntão, você pode carregar o modelo
from diffusers import StableDiffusionPipeline
pipeline = StableDiffusionPipeline.from_pretrained(save_dir,torch_dtype=torch.float32)Por enquanto, os difusores não podem suportar pesos de carga em Lora (geralmente em formato. Safetensor). Aqui mostramos nossas tentativas em um estilo deselegante. Também fornecemos um exemplo.
Observe que o tamanho do arquivo é muito menor que o modelo completo, pois contém apenas pesos extras da LORA. No caso, temos que carregar o modelo básico. Também é bom carregar apenas a difusão estável 1.5 como base, mas, para obter resultados satisfeitos, é recomendável baixar o modelo base sugerido.
Nosso método é muito direto: retire o peso do .Sesetensor e mescla o peso de Lora em um peso suportado por difusores. Não convertemos .Sesetensor em outro formato, atualizamos o peso do modelo básico.
Nosso script deve funcionar bem com a maioria dos modelos, desde o Huggingface e o Cititai, se não, você também pode modificar o código por conta própria. Acredite, é realmente simples e você pode fazê -lo.
# the default mergering ratio is 0.75, you can manually set it
python convert_lora_safetensor_to_diffusers.pyFizemos um PR para difusores sobre esse assunto, onde distorcemos ainda mais a função conversora para que seja mais flexível. Você pode verificar diretamente se não puder esperar. Em breve será fundido em difusores!
Os difusores fornecem um simples trem_text_to_image_lora.py para treinar seu modelo Lora. Siga suas instruções para instalar os requisitos.
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 "Depois de treinar um modelo usando o comando acima, a inferência pode ser feita simplesmente usando o StabledIfFusionPipline após carregar os pesos treinados da LORA. Você precisa passar no output_dir para carregar os pesos da LORA que, neste caso, são 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 " )Por enquanto, os difusores suportam apenas o trem Lora para o UNET. Nós apoiamos e fizemos um PR, se você precisar, verifique com o nosso PR ou abra um problema.
Colossalai já apoia Lora. Precisamos apenas modificar algumas linhas no topo de Train_Dreambooth_Colossalai.py. Este exemplo é para o Dreambooth, mas você pode adotá -lo com texto regular para o treinamento de imagens. Os pesos de Lora gerados são apenas para camadas de atenção no UNET. Se você também deseja oferecer suporte ao codificador de texto, use a estrutura do Accepatate em difusores, pois o Colossalai ainda não suporta vários modelos.
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)Aqui vamos nós, a única coisa é o modo de inicialização do UNET. Para salvar apenas pesos de Lora,
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)Então, faça inferência
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 " )Você pode achar que o peso Lora gerado é de apenas cerca de 3 MB, isso se deve à configuração padrão. Para aumentar o tamanho, você pode definir manualmente a classificação (dimensão para decomposição de baixa classificação) para camadas de Lora.
lora_attn_procs[name] = LoRACrossAttnProcessor(hidden_size=hidden_size, cross_attention_dim=cross_attention_dim, rank=128)Em seguida, os pesos da Lora terão cerca de 100-200 MB. Esteja ciente de que as camadas de Lora são fáceis de sobrecarregar, em geral, deve ser suficiente para treinar apenas 100 a 2000 etapas em pequenos conjuntos de dados (menos de 1 mil imagens) com tamanho em lote = 64.
(1) Posso ajustar manualmente o peso de Lora ao se fundir?
Sim, o alfa aqui está o peso para Lora. Enviamos um RP para os difusores, onde fornecemos a função flexível Warpped.
(2) Posso apenas converter Lora (.Safetetensors) em outros formatos que os difusores suportados?
Você pode, mas não sugerimos, veja esses problemas. Existem muitas limitações. Por exemplo, nosso script não pode generalizar para todos .Sesetensors, porque alguns deles têm uma nomeação diferente. Além disso, a estrutura de difusores de corrente suporta apenas a adição de Lora às camadas de atenção da UNET, enquanto muitos .fetensors do civitai contêm pesos de Lora para outros módulos como o codificador de texto. Mas o Lora for Text Encoder deve ser suportado em breve.
(3) Posso misturar mais de um modelo Lora?
Sim, a única coisa é mesclar duas vezes. Mas defina cuidadosamente o alfa (peso da Lora), o modelo degrada se o Alpha for muito grande.
(4) Qual é a motivação deste projeto?
Descobrimos que existem muitos modelos incríveis na plataforma Civitai, mas a maioria dos pesos da LORA está no formato SafeTetens, o que não é conveniente para os usuários de difusores. Assim, escrevemos um script de conversão para que você possa usar esses loras em difusores. Esteja ciente de que não somos alvos para a difusão estável-webui, que já é muito madura, mas possui API totalmente diferente como difusores.