ที่เก็บนี้ให้รหัสการสอนที่ง่ายที่สุดสำหรับนักวิจัย AIGC ที่จะใช้ LORA ในไม่กี่บรรทัด การใช้คู่มือนี้คุณสามารถเล่นกับรุ่น LORA ได้อย่างง่ายดายจากชุมชนที่ใช้งานเช่น HuggingFace และ Cititai
ตอนนี้เรายังรองรับการควบคุม Net-for-diffusers, t2i-adapter-for-diffusers
การปรับระดับต่ำของแบบจำลองภาษาขนาดใหญ่ (LORA) ได้รับการพัฒนาโดย Microsoft เพื่อลดจำนวนพารามิเตอร์ที่สามารถฝึกอบรมได้โดยการเรียนรู้คู่ของเมทริกซ์การลดระดับการลดระดับในขณะที่แช่แข็งน้ำหนักดั้งเดิม Lora พยายามปรับแต่ง "ตกค้าง" ของโมเดลแทนโมเดลทั้งหมด: IE ฝึกอบรม
ที่ไหน
เคล็ดลับการฝึกอบรมนี้ค่อนข้างมีประโยชน์สำหรับการปรับแต่งโมเดลแบบปรับแต่งแบบปรับแต่งในรูปแบบฐานทั่วไปขนาดใหญ่ แบบจำลองข้อความถึงภาพต่าง ๆ ได้รับการพัฒนาขึ้นที่ด้านบนของการแพร่กระจายที่มั่นคงอย่างเป็นทางการ ตอนนี้ด้วย Lora คุณสามารถฝึกอบรมโมเดลของคุณเองได้อย่างมีประสิทธิภาพด้วยทรัพยากรน้อยกว่ามาก
Safetensors เป็นรูปแบบที่เรียบง่ายใหม่สำหรับการจัดเก็บเทนเซอร์อย่างปลอดภัย (ตรงข้ามกับดอง) ที่ปล่อยออกมาจากการกอดใบหน้าและยังคงเร็ว (เป็นศูนย์คัดลอก) เพื่อประสิทธิภาพของมันโมเดลการแพร่กระจายที่เสถียรจำนวนมากโดยเฉพาะรุ่น LORA จะถูกปล่อยออกมาในรูปแบบ Safetensors คุณสามารถค้นหาข้อดีเพิ่มเติมจาก HuggingFace/Safetensors และติดตั้งผ่านการติดตั้ง PIP
pip install safetensorsในบทช่วยสอนนี้เราแสดงให้เห็นว่าโหลดหรือแทรก LORA ที่ผ่านการฝึกอบรมมาล่วงหน้าลงในกรอบการกระจาย โครงการที่น่าสนใจมากมายสามารถพบได้ใน HuggingFace และ Cititai แต่ส่วนใหญ่อยู่ในกรอบการทำงานที่มีเสถียรภาพการกระจาย-Webui ซึ่งไม่สะดวกสำหรับนักพัฒนาขั้นสูง เราได้รับแรงบันดาลใจอย่างมากจาก Cloneofsimo/Lora เกี่ยวกับการโหลดการรวมและการสอดแทรก Loras ที่ผ่านการฝึกอบรม เราหารือเกี่ยวกับโมเดลในรูปแบบ Safetensors ซึ่งไม่สามารถใช้งานได้ดีกับ diffusers
โมเดลเต็มรูปแบบรวมถึงโมดูลทั้งหมดที่จำเป็น (แบบจำลองพื้นฐานที่มีหรือไม่มีเลเยอร์ LORA) พวกเขามักจะเก็บไว้ในรูปแบบ. ckpt หรือ. safetensors เราให้สองตัวอย่างด้านล่างเพื่อแสดงวิธีใช้ในมือ
เสถียรภาพ/เสถียร-การกระจาย -2-1 จาก HuggingFace
Dreamshaper จาก Civitai
คุณสามารถดาวน์โหลดไฟล์. ckpt หรือ. safetensors เท่านั้น แม้ว่า diffusers ไม่สนับสนุนการโหลดโดยตรง แต่พวกเขาจะให้สคริปต์แปลง ดาวน์โหลด diffusers ครั้งแรกไปยังท้องถิ่น
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)สำหรับตอนนี้ diffusers ไม่สามารถรองรับน้ำหนักโหลดใน LORA (โดยปกติจะอยู่ในรูปแบบ. Safetensor) ที่นี่เราแสดงความพยายามของเราในสไตล์ที่ไม่ได้รับการคัดค้าน เรายังให้ตัวอย่างหนึ่ง
โปรดทราบว่าขนาดของไฟล์มีขนาดเล็กกว่ารุ่นเต็มมากเนื่องจากมีน้ำหนัก LORA พิเศษเท่านั้น ในกรณีเราต้องโหลดโมเดลพื้นฐาน นอกจากนี้ยังเป็นเรื่องปกติที่จะโหลดความเสถียรการกระจาย 1.5 เป็นฐาน แต่เพื่อให้ได้ผลลัพธ์ที่น่าพอใจขอแนะนำให้ดาวน์โหลดโมเดลพื้นฐานที่แนะนำ
วิธีการของเราตรงไปตรงมามาก: ลดน้ำหนักจาก. Safetensor และรวมน้ำหนัก Lora เข้ากับน้ำหนักที่รองรับ diffusers เราไม่แปลง. Safetensor เป็นรูปแบบอื่นเราอัปเดตน้ำหนักของโมเดลฐานแทน
สคริปต์ของเราควรทำงานได้ดีกับโมเดลส่วนใหญ่จาก HuggingFace และ Cititai หากไม่เป็นเช่นนั้นคุณสามารถแก้ไขรหัสได้ด้วยตัวเอง เชื่อฉันสิมันง่ายมากและคุณสามารถทำได้
# the default mergering ratio is 0.75, you can manually set it
python convert_lora_safetensor_to_diffusers.pyเราได้ทำประชาสัมพันธ์สำหรับ diffusers เกี่ยวกับปัญหานี้ซึ่งเราจะบิดเบือนฟังก์ชั่นการแปลงเพื่อให้มีความยืดหยุ่นมากขึ้น คุณสามารถตรวจสอบได้โดยตรงว่าคุณไม่สามารถรอได้หรือไม่ มันจะถูกรวมเข้ากับ diffusers เร็ว ๆ นี้!
Diffusers ให้ Train_Text_To_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 "เมื่อคุณได้รับการฝึกอบรมแบบจำลองโดยใช้คำสั่งด้านบนการอนุมานสามารถทำได้ง่ายๆโดยใช้ StablediffusionPipeline หลังจากโหลดน้ำหนัก LORA ที่ผ่านการฝึกอบรม คุณต้องผ่าน 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 " )สำหรับตอนนี้ diffusers รองรับรถไฟ Lora สำหรับ UNET เท่านั้น เราได้รับการสนับสนุนและทำ PR หากคุณต้องการโปรดตรวจสอบกับ PR หรือเปิดปัญหา
Colossalai สนับสนุน Lora แล้ว เราต้องการการแก้ไขเพียงไม่กี่บรรทัดที่ด้านบนของ train_dreambooth_colossalai.py ตัวอย่างนี้มีไว้สำหรับ Dreambooth แต่คุณสามารถนำข้อความปกติมาใช้กับการฝึกอบรมภาพได้อย่างง่ายดาย น้ำหนัก LORA ที่สร้างขึ้นนั้นมีไว้สำหรับชั้นความสนใจใน UNET เท่านั้น หากคุณต้องการสนับสนุนตัวเข้ารหัสข้อความด้วยโปรดใช้เฟรมเวิร์กแบบเร่งด่วนใน diffusers เนื่องจาก 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 เพื่อประหยัดน้ำหนัก 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)จากนั้นทำการอนุมาน
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 โปรดทราบว่าเลเยอร์ LORA นั้นง่ายต่อการใช้งานมากเกินไปโดยทั่วไปการพูดควรเพียงพอที่จะฝึกฝนเพียง 100 - 2000 ขั้นตอนในชุดข้อมูลขนาดเล็ก (น้อยกว่า 1K ภาพ) ที่มีขนาดแบทช์ = 64
(1) ฉันสามารถปรับน้ำหนักของ Lora ด้วยตนเองเมื่อรวมกันได้หรือไม่?
ใช่อัลฟ่านี่คือน้ำหนักสำหรับ Lora เราได้ส่ง PR ไปยัง diffusers ซึ่งเราให้ฟังก์ชั่นการทำสงครามที่ยืดหยุ่น
(2) ฉันสามารถแปลง LORA (.safetensors) เป็นรูปแบบอื่น ๆ ที่รองรับ diffusers ได้หรือไม่?
คุณทำได้ แต่เราไม่แนะนำให้ดูปัญหานี้ มีข้อ จำกัด มากมาย ตัวอย่างเช่นสคริปต์ของเราไม่สามารถพูดคุยกับ. safetensors ทั้งหมดได้เพราะบางคนมีการตั้งชื่อที่แตกต่างกัน นอกจากนี้เฟรมเวิร์ก Diffusers ปัจจุบันรองรับการเพิ่ม LORA ลงในเลเยอร์ความสนใจของ UNET เท่านั้น แต่ควรรองรับ Lora สำหรับตัวเข้ารหัสข้อความในไม่ช้า
(3) ฉันสามารถผสมมากกว่าหนึ่งรุ่น Lora ได้หรือไม่?
ใช่สิ่งเดียวคือการรวมสองครั้ง แต่โปรดตั้งค่าอัลฟ่า (น้ำหนักของ LORA) อย่างระมัดระวังแบบจำลองจะลดลงหากอัลฟ่ามีขนาดใหญ่เกินไป
(4) แรงจูงใจของโครงการนี้คืออะไร?
เราพบว่ามีโมเดลที่น่าทึ่งมากมายในแพลตฟอร์ม Civitai แต่น้ำหนักส่วนใหญ่ของ Lora อยู่ในรูปแบบ Safetensors ซึ่งไม่สะดวกสำหรับผู้ใช้ diffusers ดังนั้นเราจึงเขียนสคริปต์แปลงเพื่อให้คุณสามารถใช้ loras เหล่านี้ใน diffusers โปรดทราบว่าเราไม่ได้เป็นเป้าหมายสำหรับการกระจายความเสถียร-เวบยะซึ่งเป็นผู้ใหญ่อยู่แล้ว แต่มี API ที่แตกต่างกันโดยสิ้นเชิงกับตัวกระจาย