Buckets:
Ö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 neden olabilir, 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ğercrossattn_kv'dir ancak çapraz dikkat katmanındaki tüm parametreleri eğitmek içincrossattnolarak 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_tokengö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:
CustomDiffusionDataset: eğitim için görüntüleri, sınıf görüntülerini ve istemleri ön işlerPromptDataset: sınıf görselleri üretmek için istemleri hazırlar
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şkenini MODEL_NAME olarak Hub'daki bir model kimliğine veya yerel bir modele giden yola, INSTANCE_DIR olarak az önce kedi görsellerini indirdiğiniz yola ve OUTPUT_DIR olarak modeli kaydetmek istediğiniz yola ayarlayın. Yeni öğrenilen gömme (embedding)leri bağlamak için özel kelime olarak <new1> kullanacaksınız. Betik, model denetim noktalarını 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_steps1000 ile 2000 arasında herhangi bir değer olabilir ---freeze_model=crossattn- eğitim için en az 15-20 görsel kullanın
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
Custom Diffusion, öğrenmesi gereken her kavramla ilgili bazı ayrıntıları içeren bir JSON dosyası sağlarsanız birden fazla kavramı da öğrenebilir.
Düzenleme için kullanılacak bazı gerçek görüntüleri toplamak için clip-retrieval'i çalıştırın:
pip install clip-retrieval
python retrieve.py --class_prompt {} --class_data_dir {} --num_class_images 200
Ardından betiği başlatabilirsiniz:
export MODEL_NAME="CompVis/stable-diffusion-v1-4"
export OUTPUT_DIR="path-to-save-model"
accelerate launch train_custom_diffusion.py \
--pretrained_model_name_or_path=$MODEL_NAME \
--output_dir=$OUTPUT_DIR \
--concepts_list=./concept_list.json \
--with_prior_preservation \
--real_prior \
--prior_loss_weight=1.0 \
--resolution=512 \
--train_batch_size=2 \
--learning_rate=1e-5 \
--lr_warmup_steps=0 \
--max_train_steps=500 \
--num_class_images=200 \
--scale_lr \
--hflip \
--modifier_token "<new1>+<new2>" \
--push_to_hub
Eğitim tamamlandıktan sonra, yeni Custom Diffusion modelinizi çıkarım için kullanabilirsiniz.
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")
import torch
from huggingface_hub.repocard import RepoCard
from diffusers import DiffusionPipeline
pipeline = DiffusionPipeline.from_pretrained(
"CompVis/stable-diffusion-v1-4", dtype=torch.float16,
).to("cuda") # or "mps", "xpu", "cpu"
model_id = "sayakpaul/custom-diffusion-cat-wooden-pot"
pipeline.unet.load_attn_procs(model_id, weight_name="pytorch_custom_diffusion_weights.bin")
pipeline.load_textual_inversion(model_id, weight_name="<new1>.bin")
pipeline.load_textual_inversion(model_id, weight_name="<new2>.bin")
image = pipeline(
"the <new1> cat sculpture in the style of a <new2> wooden pot",
num_inference_steps=100,
guidance_scale=6.0,
eta=1.0,
).images[0]
image.save("multi-subject.png")
Sonraki adımlar
Custom Diffusion ile bir model eğittiğiniz için tebrikler! 🎉 Daha fazla bilgi edinmek için:
- Custom Diffusion ekibinin deneysel sonuçlarına ilişkin daha fazla ayrıntı için Multi-Concept Customization of Text-to-Image Diffusion blog yazısını okuyun.
Xet Storage Details
- Size:
- 16.7 kB
- Xet hash:
- 2d8d4add28dad681b2de8be867ea538d757a641a8d86a3ea1249e5ba36ef4acd
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.