Diffusers documentation

Özel Difüzyon

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

and get access to the augmented documentation experience

to get started

Özel Difüzyon

Custom Diffusion, görüntü üretim modellerini kişiselleştirmek için kullanılan bir eğitim tekniğidir. Textual Inversion, DreamBooth ve LoRA gibi Custom Diffusion da yalnızca birkaç (~4-5) örnek görüntü gerektirir. Bu teknik, yalnızca cross-attention katmanlarındaki ağırlıkları eğiterek çalışır ve yeni öğrenilen kavramı temsil etmek için özel bir kelime kullanır. Custom Diffusion'ın benzersiz yanı, aynı anda birden fazla kavramı da öğrenebilmesidir.

Sınırlı vRAM’a sahip bir GPU üzerinde eğitim yapıyorsanız, daha düşük vRAM gereksinimi (16GB) ile daha hızlı eğitim için xFormers’ı --enable_xformers_memory_efficient_attention ile etkinleştirmeyi denemelisiniz. Daha fazla bellek tasarrufu sağlamak için, eğitimin argümanlarına --set_grads_to_none ekleyerek gradyanları sıfır yerine None olarak ayarlayın (bu seçenek bazı sorunlara yol açabilir, bu nedenle herhangi bir sorun yaşarsanız bu parametreyi kaldırmayı deneyin).

Bu kılavuz, train_custom_diffusion.py betiğini inceleyerek onu daha yakından tanımanıza ve kendi kullanım senaryonuza nasıl uyarlayabileceğinizi gösterir.

Betik çalıştırmadan önce, kütüphanenin kaynak kodundan yüklendiğinden emin olun:

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

Eğitim betiği bulunan örnek klasörüne gidin ve gerekli bağımlılıkları yükleyin:

cd examples/custom_diffusion
pip install -r requirements.txt
pip install clip-retrieval

🤗 Accelerate, birden fazla GPU/TPU ile veya karma hassasiyetle eğitim yapmanıza yardımcı olmak için tasarlanmış bir kütüphanedir. Donanımınıza ve ortamınıza göre eğitim kurulumunuzu otomatik olarak yapılandırır. Daha fazla bilgi edinmek için 🤗 Accelerate Hızlı tur sayfasına göz atın.

Bir 🤗 Accelerate ortamı başlatın:

accelerate config

Herhangi bir yapılandırma seçmeden varsayılan bir 🤗 Accelerate ortamı kurmak için:

accelerate config default

Ya da ortamınız, bir notebook gibi, etkileşimli bir kabuğu desteklemiyorsa, şunu kullanabilirsiniz:

from accelerate.utils import write_basic_config

write_basic_config()

Son olarak, kendi veri setiniz üzerinde bir model eğitmek istiyorsanız, eğitim scriptiyle uyumlu bir veri seti oluşturma yöntemini öğrenmek için Eğitim için veri seti oluşturma kılavuzuna göz atın.

Aşağıdaki bölümler, betiğin nasıl değiştirileceğini anlamak için önemli olan eğitim betiğinin kısımlarını vurgular, ancak betiğin her yönünü ayrıntılı olarak kapsamaz. Daha fazla bilgi edinmek isterseniz, betiği okumaktan çekinmeyin ve herhangi bir sorunuz veya endişeniz varsa bize bildirin.

Betik parametreleri

Eğitim betiği, eğitim çalışmanızı özelleştirmenize yardımcı olmak için tüm parametreleri içerir. Bunlar parse_args() fonksiyonunda bulunur. Fonksiyon varsayılan değerlerle birlikte gelir, ancak isterseniz kendi değerlerinizi eğitim komutunda da ayarlayabilirsiniz.

Örneğin, giriş görüntüsünün çözünürlüğünü değiştirmek için:

accelerate launch train_custom_diffusion.py \
  --resolution=256

Temel parametrelerin çoğu DreamBooth eğitim kılavuzunda anlatıldığından, bu kılavuz Custom Diffusion'a özgü parametrelere odaklanmaktadır:

  • --freeze_model: çapraz dikkat katmanındaki anahtar ve değer parametrelerini dondurur; varsayılan değer crossattn_kv'dir ancak çapraz dikkat katmanındaki tüm parametreleri eğitmek için crossattn olarak ayarlayabilirsiniz
  • --concepts_list: birden fazla kavram öğrenmek için, kavramları içeren bir JSON dosyasının yolunu belirtin
  • --modifier_token: öğrenilen kavramı temsil etmek için kullanılan özel bir kelime
  • --initializer_token: modifier_token gömmelemelerini başlatmak için kullanılan özel bir kelime

Önceden var olan bilgi kaybı

Öncül koruma kaybı, bir modelin kendi ürettiği örnekleri kullanarak daha çeşitli görseller üretmeyi öğrenmesine yardımcı olan bir yöntemdir. Bu üretilmiş örnek görsellerler, sağladığınız görsellerle aynı sınıfa ait olduğu için, modelin sınıfa dair öğrendiklerini korumasına ve sınıfa zaten bildiklerini kullanarak yeni kompozisyonlar oluşturmasına yardımcı olurlar.

Önceki koruma kaybı için parametrelerin çoğu DreamBooth eğitim kılavuzunda açıklanmıştır.

Düzenleme

Custom Diffusion, aşırı öğrenmeyi önlemek için hedef görselleri küçük bir gerçek görsel setiyle eğitir. Sadece birkaç görselle eğitim yaptığınızı düşündüğünüzde bunun ne kadar kolay yapılabileceğini hayal edebilirsiniz. clip_retrieval ile 200 gerçek görsel indirin. class_prompt, hedef görsellerle aynı kategori olmalıdır. Bu görseller class_data_dir içinde saklanır.

python retrieve.py --class_prompt cat --class_data_dir real_reg/samples_cat --num_class_images 200

Düzenlemeyi etkinleştirmek için aşağıdaki parametreleri ekleyin:

  • --with_prior_preservation: prior preservation loss kullanılıp kullanılmayacağı
  • --prior_loss_weight: model üzerindeki öncül koruma kaybının etkisini kontrol eder
  • --real_prior: aşırı öğrenmeyi önlemek için küçük bir gerçek görsel kümesi kullanılıp kullanılmayacağı
accelerate launch train_custom_diffusion.py \
  --with_prior_preservation \
  --prior_loss_weight=1.0 \
  --class_data_dir="./real_reg/samples_cat" \
  --class_prompt="cat" \
  --real_prior=True \

Eğitim betiği

Custom Diffusion eğitim betiğindeki kodun büyük bir kısmı DreamBooth betiğine benzer. Bu kılavuz bunun yerine Custom Diffusion ile ilgili koda odaklanır.

Custom Diffusion eğitim betiğinin iki veri seti sınıfı vardır:

Ardından, modifier_token tokenizatora eklenir, token kimliklerine dönüştürülür ve yeni modifier_token için token gömme boyutları yeniden ayarlanır. Daha sonra modifier_token gömmeleri, initializer_token gömmeleriyle başlatılır. Metin kodlayıcıdaki tüm parametreler, modelin kavramlarla ilişkilendirmeyi öğrenmeye çalıştığı şey olan token gömmeleri hariç olmak üzere dondurulur.

params_to_freeze = itertools.chain(
    text_encoder.text_model.encoder.parameters(),
    text_encoder.text_model.final_layer_norm.parameters(),
    text_encoder.text_model.embeddings.position_embedding.parameters(),
)
freeze_params(params_to_freeze)

Şimdi dikkat katmanlarına Custom Diffusion ağırlıklarını eklemeniz gerekecek. Dikkat ağırlıklarının şeklinin ve boyutunun doğru olması ve her UNet bloğunda uygun sayıda dikkat işleyicisinin ayarlanması için bu gerçekten önemli bir adımdır.

st = unet.state_dict()
for name, _ in unet.attn_processors.items():
    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]
    layer_name = name.split(".processor")[0]
    weights = {
        "to_k_custom_diffusion.weight": st[layer_name + ".to_k.weight"],
        "to_v_custom_diffusion.weight": st[layer_name + ".to_v.weight"],
    }
    if train_q_out:
        weights["to_q_custom_diffusion.weight"] = st[layer_name + ".to_q.weight"]
        weights["to_out_custom_diffusion.0.weight"] = st[layer_name + ".to_out.0.weight"]
        weights["to_out_custom_diffusion.0.bias"] = st[layer_name + ".to_out.0.bias"]
    if cross_attention_dim is not None:
        custom_diffusion_attn_procs[name] = attention_class(
            train_kv=train_kv,
            train_q_out=train_q_out,
            hidden_size=hidden_size,
            cross_attention_dim=cross_attention_dim,
        ).to(unet.device)
        custom_diffusion_attn_procs[name].load_state_dict(weights)
    else:
        custom_diffusion_attn_procs[name] = attention_class(
            train_kv=False,
            train_q_out=False,
            hidden_size=hidden_size,
            cross_attention_dim=cross_attention_dim,
        )
del st
unet.set_attn_processor(custom_diffusion_attn_procs)
custom_diffusion_layers = AttnProcsLayers(unet.attn_processors)

optimizer, çapraz dikkat katmanı parametrelerini güncellemek üzere başlatılır:

optimizer = optimizer_class(
    itertools.chain(text_encoder.get_input_embeddings().parameters(), custom_diffusion_layers.parameters())
    if args.modifier_token is not None
    else custom_diffusion_layers.parameters(),
    lr=args.learning_rate,
    betas=(args.adam_beta1, args.adam_beta2),
    weight_decay=args.adam_weight_decay,
    eps=args.adam_epsilon,
)

eğitim döngüsünde, öğrenmeye çalıştığınız kavram için yalnızca gömme değerlerini güncellemek önemlidir. Bu, diğer tüm token gömme değerlerinin gradyanlarını sıfıra ayarlamak anlamına gelir:

if args.modifier_token is not None:
    if accelerator.num_processes > 1:
        grads_text_encoder = text_encoder.module.get_input_embeddings().weight.grad
    else:
        grads_text_encoder = text_encoder.get_input_embeddings().weight.grad
    index_grads_to_zero = torch.arange(len(tokenizer)) != modifier_token_id[0]
    for i in range(len(modifier_token_id[1:])):
        index_grads_to_zero = index_grads_to_zero & (
            torch.arange(len(tokenizer)) != modifier_token_id[i]
        )
    grads_text_encoder.data[index_grads_to_zero, :] = grads_text_encoder.data[
        index_grads_to_zero, :
    ].fill_(0)

Betik başlat

Tüm değişikliklerinizi yaptıysanız veya varsayılan yapılandırmayla sorununuz yoksa, eğitim betiğini başlatmaya hazırsınız! 🚀

Bu kılavuzda, bu örnek kedi görsellerini indirip kullanacaksınız. İsterseniz kendi veri setinizi oluşturup kullanabilirsiniz (Eğitim için veri seti oluşturma kılavuzuna bakın).

Ortam değişkeni MODEL_NAME değerini Hub'daki bir model kimliğine veya yerel bir modele giden yola, INSTANCE_DIR değerini az önce kedi görsellerini indirdiğiniz konuma ve OUTPUT_DIR değerini modelin kaydedilmesini istediğiniz konuma ayarlayın. Yeni öğrenilen gömme (embedding)leri bağlamak için özel kelime olarak <new1> kullanacaksınız. Betik, model denetim noktalarını (checkpoint) ve pytorch_custom_diffusion_weights.bin dosyasını oluşturup deponuza kaydeder.

Eğitim ilerlemesini Weights and Biases ile izlemek için eğitim komutuna --report_to=wandb parametresini ekleyin ve --validation_prompt ile bir doğrulama istemci belirleyin. Bu, hata ayıklama ve ara sonuçları kaydetmek için kullanışlıdır.

İnsan yüzleri üzerinde eğitim yapıyorsanız, Custom Diffusion ekibi aşağıdaki parametrelerin iyi çalıştığını bulmuştur:

  • --learning_rate=5e-6
  • --max_train_steps 1000 ile 2000 arasında herhangi bir yerde olabilir
  • --freeze_model=crossattn
  • eğitim için en az 15-20 görsel kullanın
tek kavram
birden fazla kavram
export MODEL_NAME="CompVis/stable-diffusion-v1-4"
export OUTPUT_DIR="path-to-save-model"
export INSTANCE_DIR="./data/cat"

accelerate launch train_custom_diffusion.py \
  --pretrained_model_name_or_path=$MODEL_NAME  \
  --instance_data_dir=$INSTANCE_DIR \
  --output_dir=$OUTPUT_DIR \
  --class_data_dir=./real_reg/samples_cat/ \
  --with_prior_preservation \
  --real_prior \
  --prior_loss_weight=1.0 \
  --class_prompt="cat" \
  --num_class_images=200 \
  --instance_prompt="photo of a <new1> cat"  \
  --resolution=512  \
  --train_batch_size=2  \
  --learning_rate=1e-5  \
  --lr_warmup_steps=0 \
  --max_train_steps=250 \
  --scale_lr \
  --hflip  \
  --modifier_token "<new1>" \
  --validation_prompt="<new1> cat sitting in a bucket" \
  --report_to="wandb" \
  --push_to_hub

Eğitim tamamlandıktan sonra, yeni Custom Diffusion modelinizi çıkarım için kullanabilirsiniz.

tek kavram
birden fazla kavram
import torch
from diffusers import DiffusionPipeline

pipeline = DiffusionPipeline.from_pretrained(
    "CompVis/stable-diffusion-v1-4", dtype=torch.float16,
).to("cuda")  # or "mps", "xpu", "cpu"
pipeline.unet.load_attn_procs("path-to-save-model", weight_name="pytorch_custom_diffusion_weights.bin")
pipeline.load_textual_inversion("path-to-save-model", weight_name="<new1>.bin")

image = pipeline(
    "<new1> cat sitting in a bucket",
    num_inference_steps=100,
    guidance_scale=6.0,
    eta=1.0,
).images[0]
image.save("cat.png")

Sonraki adımlar

Custom Diffusion ile bir model eğittiğiniz için tebrikler! 🎉 Daha fazla bilgi edinmek için:

Update on GitHub