Diffusers documentation

Stable Diffusion XL

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.43.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Stable Diffusion XL

Este script é experimental e é fácil sofrer overfitting e enfrentar problemas como o esquecimento catastrófico. Tente explorar diferentes hiperparâmetros para obter os melhores resultados no seu conjunto de dados.

Stable Diffusion XL (SDXL) é uma iteração maior e mais poderosa do modelo Stable Diffusion, capaz de produzir imagens com resolução mais alta.

O UNet do SDXL é 3x maior e o modelo adiciona um segundo codificador de texto à arquitetura. Dependendo do hardware disponível para você, isso pode ser muito intensivo computacionalmente e pode não rodar em uma GPU de consumidor como uma Tesla T4. Para ajudar a caber esse modelo maior na memória e acelerar o treinamento, tente habilitar gradient_checkpointing, mixed_precision e gradient_accumulation_steps. Você pode reduzir ainda mais o uso de memória habilitando a atenção eficiente em memória com xFormers e usando o otimizador de 8 bits do bitsandbytes.

Este guia explorará o script de treinamento train_text_to_image_sdxl.py para ajudá-lo a se familiarizar melhor com ele e como você pode adaptá-lo para o seu próprio caso de uso.

Antes de executar o script, certifique-se de instalar a biblioteca a partir do código-fonte:

git clone https://github.com/huggingface/diffusers
cd diffusers
pip install .

Em seguida, navegue até a pasta de exemplo que contém o script de treinamento e instale as dependências necessárias para o script que você está usando:

cd examples/text_to_image
pip install -r requirements_sdxl.txt

🤗 Accelerate é uma biblioteca para ajudar você a treinar em múltiplos GPUs/TPUs ou com precisão mista. Ela configura automaticamente seu ambiente de treinamento com base no seu hardware e ambiente. Dê uma olhada no Quick tour do 🤗 Accelerate para saber mais.

Inicialize um ambiente do 🤗 Accelerate:

accelerate config

Para configurar um ambiente padrão do 🤗 Accelerate sem escolher nenhuma configuração:

accelerate config default

Ou, se o seu ambiente não suporta um shell interativo, como um notebook, você pode usar:

from accelerate.utils import write_basic_config

write_basic_config()

Por fim, se você deseja treinar um modelo em seu próprio conjunto de dados, consulte o guia Criar um conjunto de dados para treinamento para aprender a criar um conjunto de dados que funcione com o script de treinamento.

Parâmetros do script

As seções a seguir destacam partes do script de treinamento que são importantes para entender como modificá-lo, mas não cobrem todos os aspectos do script em detalhes. Se você tiver interesse em aprender mais, sinta-se à vontade para ler o script e nos informar caso tenha alguma dúvida ou preocupação.

O script de treinamento fornece muitos parâmetros para ajudar você a personalizar sua execução de treinamento. Todos os parâmetros e suas descrições estão encontrados na função parse_args(). Esta função fornece valores padrão para cada parâmetro, como o tamanho do lote de treinamento e a taxa de aprendizado, mas você também pode definir seus próprios valores no comando de treinamento, se desejar.

Por exemplo, para acelerar o treinamento com precisão mista usando o formato bf16, adicione o parâmetro --mixed_precision ao comando de treinamento:

accelerate launch train_text_to_image_sdxl.py \
  --mixed_precision="bf16"

A maioria dos parâmetros é idêntica aos parâmetros do guia de treinamento Texto-para-imagem, então você se concentrará nos parâmetros relevantes para o treinamento do SDXL neste guia.

  • --pretrained_vae_model_name_or_path: caminho para um VAE pré-treinado; o VAE do SDXL é conhecido por sofrer de instabilidade numérica, portanto, este parâmetro permite especificar um VAE melhor
  • --proportion_empty_prompts: a proporção de prompts de imagem a serem substituídos por strings vazias
  • --timestep_bias_strategy: onde (mais cedo ou mais tarde) no timestep aplicar um viés, o que pode incentivar o modelo a aprender detalhes de baixa ou alta frequência
  • --timestep_bias_multiplier: o peso do viés a ser aplicado ao timestep
  • --timestep_bias_begin: o timestep em que se começa a aplicar o viés
  • --timestep_bias_end: o timestep em que a aplicação do viés termina
  • --timestep_bias_portion: a proporção de timesteps para aplicar o viés

Ponderação Min-SNR

A estratégia de ponderação Min-SNR pode ajudar no treinamento ao reequilibrar a perda para alcançar uma convergência mais rápida. O script de treinamento suporta a previsão de epsilon (ruído) ou v_prediction, mas o Min-SNR é compatível com ambos os tipos de previsão. Essa estratégia de ponderação é suportada apenas pelo PyTorch.

Adicione o parâmetro --snr_gamma e defina-o com o valor recomendado de 5.0:

accelerate launch train_text_to_image_sdxl.py \
  --snr_gamma=5.0

Script de treinamento

O script de treinamento também é semelhante ao guia de treinamento Texto-para-imagem, mas foi modificado para suportar o treinamento do SDXL. Este guia se concentrará no código que é exclusivo do script de treinamento do SDXL.

Começa criando funções para tokenizar os prompts para calcular os embeddings dos prompts e para calcular os embeddings das imagens com o VAE. Em seguida, você criará uma função para gerar os pesos dos timesteps dependendo do número de timesteps e da estratégia de viés de timestep a ser aplicada.

Dentro da função main(), além de carregar um tokenizer, o script carrega um segundo tokenizer e um codificador de texto, pois a arquitetura SDXL usa dois de cada:

tokenizer_one = AutoTokenizer.from_pretrained(
    args.pretrained_model_name_or_path, subfolder="tokenizer", revision=args.revision, use_fast=False
)
tokenizer_two = AutoTokenizer.from_pretrained(
    args.pretrained_model_name_or_path, subfolder="tokenizer_2", revision=args.revision, use_fast=False
)

text_encoder_cls_one = import_model_class_from_model_name_or_path(
    args.pretrained_model_name_or_path, args.revision
)
text_encoder_cls_two = import_model_class_from_model_name_or_path(
    args.pretrained_model_name_or_path, args.revision, subfolder="text_encoder_2"
)

Os embeddings do prompt e da imagem são calculados primeiro e mantidos na memória, o que normalmente não é um problema para um conjunto de dados menor, mas para conjuntos de dados maiores pode levar a problemas de memória. Se esse for o caso, você deve salvar os embeddings pré-calculados no disco separadamente e carregá-los na memória durante o processo de treinamento (veja este PR para mais discussões sobre esse tópico).

text_encoders = [text_encoder_one, text_encoder_two]
tokenizers = [tokenizer_one, tokenizer_two]
compute_embeddings_fn = functools.partial(
    encode_prompt,
    text_encoders=text_encoders,
    tokenizers=tokenizers,
    proportion_empty_prompts=args.proportion_empty_prompts,
    caption_column=args.caption_column,
)

train_dataset = train_dataset.map(compute_embeddings_fn, batched=True, new_fingerprint=new_fingerprint)
train_dataset = train_dataset.map(
    compute_vae_encodings_fn,
    batched=True,
    batch_size=args.train_batch_size * accelerator.num_processes * args.gradient_accumulation_steps,
    new_fingerprint=new_fingerprint_for_vae,
)

Após calcular os embeddings, o codificador de texto, o VAE e o tokenizer são removidos para liberar um pouco de memória:

del text_encoders, tokenizers, vae
gc.collect()
torch.cuda.empty_cache()

Por fim, o training loop cuida do restante. Se você optou por aplicar uma estratégia de viés de timestep, verá que os pesos dos timesteps são calculados e adicionados como ruído:

weights = generate_timestep_weights(args, noise_scheduler.config.num_train_timesteps).to(
        model_input.device
    )
    timesteps = torch.multinomial(weights, bsz, replacement=True).long()

noisy_model_input = noise_scheduler.add_noise(model_input, noise, timesteps)

Se você quiser saber mais sobre como funciona o loop de treinamento, confira o tutorial Entendendo pipelines, modelos e agendadores, que detalha o padrão básico do processo de remoção de ruído.

Inicie o script

Depois de fazer todas as alterações ou se você estiver satisfeito com a configuração padrão, está pronto para executar o script de treinamento! 🚀

Vamos treinar no dataset Naruto BLIP captions para gerar seus próprios personagens de Naruto. Defina as variáveis de ambiente MODEL_NAME e DATASET_NAME para o modelo e o dataset (seja do Hub ou um caminho local). Você também deve especificar um VAE diferente do VAE do SDXL (seja do Hub ou um caminho local) com VAE_NAME para evitar instabilidades numéricas.

Para monitorar o progresso do treinamento com Weights & Biases, adicione o parâmetro --report_to=wandb ao comando de treinamento. Você também precisará adicionar --validation_prompt e --validation_epochs ao comando de treinamento para acompanhar os resultados. Isso pode ser muito útil para depurar o modelo e visualizar resultados intermediários.

export MODEL_NAME="stabilityai/stable-diffusion-xl-base-1.0"
export VAE_NAME="madebyollin/sdxl-vae-fp16-fix"
export DATASET_NAME="lambdalabs/naruto-blip-captions"

accelerate launch train_text_to_image_sdxl.py \
  --pretrained_model_name_or_path=$MODEL_NAME \
  --pretrained_vae_model_name_or_path=$VAE_NAME \
  --dataset_name=$DATASET_NAME \
  --enable_xformers_memory_efficient_attention \
  --resolution=512 \
  --center_crop \
  --random_flip \
  --proportion_empty_prompts=0.2 \
  --train_batch_size=1 \
  --gradient_accumulation_steps=4 \
  --gradient_checkpointing \
  --max_train_steps=10000 \
  --use_8bit_adam \
  --learning_rate=1e-06 \
  --lr_scheduler="constant" \
  --lr_warmup_steps=0 \
  --mixed_precision="fp16" \
  --report_to="wandb" \
  --validation_prompt="a cute Sundar Pichai creature" \
  --validation_epochs 5 \
  --checkpointing_steps=5000 \
  --output_dir="sdxl-naruto-model" \
  --push_to_hub

Depois de terminar o treinamento, você pode usar seu novo modelo SDXL treinado para inferência!

PyTorch
PyTorch XLA
from diffusers import DiffusionPipeline
import torch

pipeline = DiffusionPipeline.from_pretrained("path/to/your/model", dtype=torch.float16).to("cuda")  # or "mps", "xpu", "cpu"

prompt = "A naruto with green eyes and red legs."
image = pipeline(prompt, num_inference_steps=30, guidance_scale=7.5).images[0]
image.save("naruto.png")

Próximas etapas

Parabéns por treinar um modelo SDXL! Para saber mais sobre como usar seu novo modelo, os seguintes guias podem ser úteis:

  • Leia o guia do Stable Diffusion XL para aprender a usá-lo em uma variedade de tarefas diferentes (texto-para-imagem, imagem-para-imagem, inpainting), como usar seu modelo refinador e os diferentes tipos de micro-condicionamentos.
  • Confira os guias de treinamento de DreamBooth e LoRA para aprender a treinar um modelo SDXL personalizado com apenas algumas imagens de exemplo. Essas duas técnicas de treinamento podem até ser combinadas!
Update on GitHub