LoRA Betanítási Útmutató
Mik azok a LoRA-k?
A LoRA (Low-Rank Adaptation - Alacsony Rangú Adaptáció) egy olyan technika, amelyet nagy méretű nyelvi és diffúziós modellek hatékony finomhangolására terveztek. Ahelyett, hogy a teljes modellparaméter-készletet átdolgoznák - ami milliárdos nagyságrendű lehet - a LoRA kis méretű, betanítható “alacsony rangú” mátrixokat vezet be a modell viselkedésének adaptálására. Ezt az innovatív megközelítést a Microsoft kutatói részletezték a “LoRA: Low-Rank Adaptation of Large Language Models” című tanulmányukban.
Alszekciók
- 10 Perces LoRA Tréning a Legvégső Degeneráltak Számára
- Egy offenzív, etikátlan és elfogult útmutató arról, hogyan potyogtassunk ki király LoRÁ-kat minimális erőfeszítéssel és számítási idővel.
- DoRA
- Egy új, paraméter-hatékony finomhangolási módszer, amely a betanított súlyokat nagyság és irány komponensekre bontja a hatékonyabb adaptáció érdekében
- Egyéni Optimalizálók Hozzáadása
- Ez a cikk átfogó útmutatót nyújt az egyéni optimalizálók beépítéséhez az
sd-scripts
könyvtárba. Bemutatja egy új optimalizálók mappa létrehozásának folyamatát és egy egyéni optimalizáló osztály létrehozását Python segítségével. - Hogyan Dolgozódnak Fel a Feliratok?
- Ez a cikk elmagyarázza az sd-scripts
process_caption
metódusát, részletezve, hogyan szabja testre a feliratokat különböző paraméterek alapján. Kitér az előtag és utótag hozzáadására, a kiejtési mechanizmusokra, a helyettesítő karakterek feldolgozására, a token manipulációra és a szöveges inverzió helyettesítésekre. A módszer biztosítja, hogy a feliratok dinamikusan módosuljanak a tanítási adatok minőségének és a modell robusztusságának javítása érdekében. - NoobAI Jegyzetek
- Átfogó útmutató a NoobAI SDXL modellel való tanításhoz, beleértve az optimális VRAM beállításokat, tanítási paramétereket és címkézési technikákat időszak-specifikus címkékkel.
- Tanítási Változások Követése
- Ismerje meg, hogyan használhat automatizált szkripteket a LoRA tanítási folyamat rendszerezéséhez és követéséhez, beleértve a modellverziók kezelését, a konfigurációk biztonsági mentését és a tiszta tanítási munkakörnyezet fenntartását.
Telepítési Tippek
Először töltsd le kohya_ss sd-scripts csomagját. A környezetet vagy úgy kell beállítanod, ahogy itt le van írva Windows esetén, vagy ha Linuxot vagy Minicondát használsz Windowson, valószínűleg elég okos vagy, hogy magadtól is rájöjj a telepítésre. Mindig ajánlott a legújabb PyTorch verziót telepíteni abba a virtuális környezetbe, amit használni fogsz - ami jelenleg a 2.5.1
.
Na jó, arra az esetre, ha mégsem lennél elég okos az sd-scripts Miniconda alatti telepítéséhez Windowson, nemrég “segítettem” valakinek, így el tudom mondani:
# sd-scripts telepítése
git clone https://github.com/kohya-ss/sd-scripts
cd sd-scripts
# Conda környezet létrehozása és követelmények telepítése
conda create -n sdscripts python=3.10.14
conda activate sdscripts
conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia
python -m pip install --use-pep517 --upgrade -r requirements.txt
python -m pip install --use-pep517 lycoris_lora
accelerate config
Az accelerate config
több kérdést fog feltenni, mindegyiket el kell olvasnod és az igazat kell válaszolnod. A legtöbb esetben az igazság így néz ki: This machine, No distributed training, no, no, no, all, fp16
.
Lehet, hogy telepíteni szeretnéd az xformers
-t vagy a bitsandbytes
-t is.
# xformers telepítése
# Mindig figyelj arra hogy a megfelelő virtuális környezetben legyél!
python -m pip install --use-pep517 xformers
# bitsandbytes telepítése windowsra
python -m pip install --use-pep517 bitsandbytes --index-url=https://jllllll.github.io/bitsandbytes-windows-webui
Pony Betanítás
Nem hazudok, kicsit bonyolult mindent elmagyarázni. De itt van a legjobb próbálkozásom, hogy végigmenjek néhány “alapvető” dolgon és szinte minden soron sorrendben.
Pony Letöltése Diffusers Formátumban
A betanításhoz a diffusers verziót használom, amit én konvertáltam, letöltheted git
segítségével.
git clone https://huggingface.co/k4d3/ponydiffusers
Minta Prompt Fájl
A betanítás során egy minta prompt fájlt használunk képek mintavételezéséhez. Egy minta prompt például így nézhet ki Pony esetében:
# anthro female kindred
score_9, score_8_up, score_7_up, score_6_up, rating_explicit, source_furry, solo, female anthro kindred, mask, presenting, white pillow, bedroom, looking at viewer, detailed background, amazing_background, scenery porn, realistic, photo --n low quality, worst quality, blurred background, blurry, simple background --w 1024 --h 1024 --d 1 --l 6.0 --s 40
# anthro female wolf
score_9, score_8_up, score_7_up, score_6_up, rating_explicit, source_furry, solo, anthro female wolf, sexy pose, standing, gray fur, brown fur, canine pussy, black nose, blue eyes, pink areola, pink nipples, detailed background, amazing_background, realistic, photo --n low quality, worst quality, blurred background, blurry, simple background --w 1024 --h 1024 --d 1 --l 6.0 --s 40
Kérlek vedd figyelembe, hogy a minta promptok nem haladhatják meg a 77 tokent, használhatod a Count Tokens in Sample Prompts eszközt a /dataset_tools mappából a promptjaid elemzéséhez.
Ha több GPU-val tanítasz, győződj meg róla, hogy a promptok teljes száma maradék nélkül osztható a GPU-k számával, különben egy kártya tétlen marad.
Betanítási Parancsok
accelerate launch
Két GPU esetén:
accelerate launch --num_processes=2 --multi_gpu --num_machines=1 --gpu_ids=0,1 --num_cpu_threads_per_process=2 "./sdxl_train_network.py"
Egy GPU esetén:
accelerate launch --num_cpu_threads_per_process=2 "./sdxl_train_network.py"
És most nézzük át az sd-scripts
-nek átadható paramétereket.
--lowram
Ha kifutsz a rendszermemóriából, mint ahogy én is 2 GPU-val és egy nagyon nagy modellel, ami GPU-nként betöltődik, ez az opció segít spórolni egy kicsit és kimenthet az OOM pokolból.
--pretrained_model_name_or_path
A letöltött checkpoint könyvtára. Javaslom, hogy zárd le az elérési utat egy /
-rel, ha helyi diffusers modellt használsz. Megadhatsz .safetensors
vagy .ckpt
fájlt is, ha olyan van!
--pretrained_model_name_or_path="/ponydiffusers/"
--output_dir
Itt kerülnek mentésre az összes mentett epoch vagy lépés, beleértve az utolsót is.
--output_dir="/output_dir"
--train_data_dir
Az adatkészletet tartalmazó könyvtár. Ezt korábban együtt készítettük elő.
--train_data_dir="/training_dir"
--resolution
Mindig állítsd be a modell felbontásának megfelelően, ami Pony esetében 1024x1024. Ha nem fér bele a VRAM-ba, végső megoldásként csökkentheted 512,512
-re.
--resolution="1024,1024"
--enable_bucket
Különböző tárolókat hoz létre a különböző képarányú képek előzetes kategorizálásával. Ez a technika segít elkerülni az olyan problémákat, mint a természetellenes vágások, amelyek gyakran előfordulnak, amikor a modelleket négyzet alakú képek előállítására tanítják. Ez lehetővé teszi olyan kötegek létrehozását, ahol minden elem azonos méretű, de a kötegek képmérete különbözhet.
--bucket_no_upscale
A hálózat által feldolgozott képek felbontását befolyásolja a képek felskálázásának letiltásával. Ha ez az opció be van állítva, a hálózat csak akkor fogja lekicsinyíteni a képeket, hogy beleférjenek a self.max_area
által meghatározott maximális területbe, ha a kép $szélesség \times magasság$ értéke meghaladja ezt az értéket.
- A
select_bucket
függvény ellenőrzi, hogy szükséges-e a lekicsinyítés: Ha aimage_width
ésimage_height
szorzata nagyobb, mint aself.max_area
, akkor a kép túl nagy, és le kell kicsinyíteni a képarány megtartása mellett. - Ezután kiszámítja azt a szélességet és magasságot, amelyre a képet át kell méretezni úgy, hogy az átméretezett kép területe ne haladja meg a
self.max_area
értéket, és a képarány megmaradjon. - A
round_to_steps
függvény a kerekítéshez használatos, amely az átméretezett dimenziókat aself.reso_steps
legközelebbi többszörösére kerekíti, ami egy paraméter, amely meghatározza a felbontási tárolók lépésközét. - A kód összehasonlítja a szélesség és magasság képarányát a kerekítés után, hogy eldöntse, melyik dimenziót részesítse előnyben az átméretezés utáni képarány-hiba minimalizálása érdekében.
- A kisebb képarány-hiba alapján kiválasztja azokat az átméretezett dimenziókat, amelyek a legjobban megőrzik a kép eredeti képarányát.
Összefoglalva, a select_bucket
függvény biztosítja, hogy amikor lekicsinyítésre van szükség, a kép olyan dimenziókra legyen átméretezve, amelyek a felbontási lépésköz (self.reso_steps
) többszörösei, és a lehető legközelebb állnak az eredeti képarányhoz, anélkül, hogy meghaladnák a megengedett maximális területet (self.max_area
). A felskálázás nem történik meg, ha a --bucket_no_upscale
be van állítva.
--min_bucket_reso
és --max_bucket_reso
Meghatározza a tárolók által használt minimális és maximális felbontásokat. Ezek az értékek figyelmen kívül maradnak, ha a --bucket_no_upscale
be van állítva.
--min_bucket_reso=256 --max_bucket_reso=1024
--network_alpha
Meghatározza, hogy a betanított Hálózati Rangok közül hány módosíthatja az alapmodellt.
--network_alpha=4
--save_model_as
Használhatod ezt a ckpt
vagy safetensors
fájlformátum megadásához.
--save_model_as="safetensors"
--network_module
Meghatározza, hogy melyik hálózati modult fogod betanítani.
--network_module="lycoris.kohya"
--network_args
A hálózatnak átadott argumentumok.
--network_args \
"use_reentrant=False" \
"preset=full" \
"conv_dim=256" \
"conv_alpha=4" \
"use_tucker=False" \
"use_scalar=False" \
"rank_dropout_scale=False" \
"algo=locon" \
"train_norm=False" \
"block_dims=8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8" \
"block_alphas=0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625" \
Nézzük meg részletesen!
preset
A LyCORIS-hoz hozzáadott Preset/konfiguráció rendszer a finomabb irányítás érdekében.
full
- alapértelmezett preset, az UNet és CLIP összes rétegét betanítja.
full-lin
full
, de kihagyja a konvolúciós rétegeket.
attn-mlp
- “kohya preset”, az összes transformer blokkot betanítja.
attn-only
- csak a figyelmi réteg lesz betanítva, sok tanulmány csak a figyelmi réteget tanítja.
unet-transformer-only
- ugyanaz, mint a kohya_ss/sd_scripts kikapcsolt TE-vel, vagy az attn-mlp preset engedélyezett train_unet_only-val.
unet-convblock-only
- csak a ResBlock, UpSample, DownSample lesz betanítva.
conv_dim
és conv_alpha
A konvolúciós dimenziók a modell konvolúciójának rangjához kapcsolódnak. Ennek az értéknek a módosítása jelentős hatással lehet, és csökkentése befolyásolta a különböző LoRA minták közötti esztétikai különbségeket. Egy karakter arcának betanításához 128
-as alfa értéket használtak, míg Kohaku azt javasolta, hogy ezt állítsuk 1
-re mind a LoCon, mind a LoHa esetében.
conv_block_dims = [conv_dim] * num_total_blocks
conv_block_alphas = [conv_alpha] * num_total_blocks
module_dropout
és dropout
és rank_dropout
A rank_dropout
a dropout egy formája, amely egy szabályozási technika a neurális hálózatokban a túltanulás megakadályozására és az általánosítás javítására. Azonban a hagyományos dropouttal ellentétben, amely véletlenszerűen nullára állítja a bemenetek egy részét, a rank_dropout
az lx
bemeneti tenzor rangján működik. Először egy bináris maszk jön létre ugyanazzal a ranggal, mint az lx
, ahol minden elem True
értékű 1 - rank_dropout
valószínűséggel és False
egyébként. Ezután a mask
alkalmazásra kerül az lx
-re, hogy véletlenszerűen nullára állítson néhány elemet. A dropout alkalmazása után egy skálázási tényező kerül alkalmazásra az lx
-re, hogy kompenzálja a kiejtett elemeket. Ez azért történik, hogy biztosítsa, hogy az lx
várható összege ugyanaz maradjon a dropout előtt és után. A skálázási tényező 1.0 / (1.0 - self.rank_dropout)
.
Azért hívják “rang” dropoutnak, mert a bemeneti tenzor rangján működik, nem pedig az egyes elemein. Ez különösen hasznos lehet olyan feladatoknál, ahol a bemenet rangja fontos.
Ha a rank_dropout
értéke 0
, az azt jelenti, hogy nem kerül alkalmazásra dropout az lx
bemeneti tenzor rangján. A maszk minden eleme True
értékű lenne, és amikor a maszk alkalmazásra kerül az lx
-re, minden eleme megmaradna, és amikor a skálázási tényező alkalmazásra kerül a dropout után, az értéke egyenlő lenne a self.scale
-lel, mert 1.0 / (1.0 - 0)
az 1
. Alapvetően, ha ezt 0
-ra állítjuk, az hatékonyan kikapcsolja a dropout mechanizmust, de még mindig végez néhány értelmetlen számítást, és nem állíthatod None-ra, szóval ha tényleg ki akarod kapcsolni a dropoutokat, egyszerűen ne add meg őket! 😇
def forward(self, x):
org_forwarded = self.org_forward(x)
# modul dropout
if self.module_dropout is not None and self.training:
if torch.rand(1) < self.module_dropout:
return org_forwarded
lx = self.lora_down(x)
# normál dropout
if self.dropout is not None and self.training:
lx = torch.nn.functional.dropout(lx, p=self.dropout)
# rang dropout
if self.rank_dropout is not None and self.training:
mask = torch.rand((lx.size(0), self.lora_dim), device=lx.device) > self.rank_dropout
if len(lx.size()) == 3:
mask = mask.unsqueeze(1)
elif len(lx.size()) == 4:
mask = mask.unsqueeze(-1).unsqueeze(-1)
lx = lx * mask
scale = self.scale * (1.0 / (1.0 - self.rank_dropout))
else:
scale = self.scale
lx = self.lora_up(lx)
return org_forwarded + lx * self.multiplier * scale
A betanítandó hálózatnak támogatnia kell ezt! További részletekért lásd a PR#545 pull requestet.
use_tucker
Minden algoritmushoz használható, kivéve az (IA)^3
-at és a natív finomhangolást.
A Tucker-dekompozíció egy matematikai módszer, amely egy tenzort mátrixok halmazára és egy kis mag tenzorra bont, csökkentve a modell számítási komplexitását és memóriaigényét. Különböző LyCORIS modulokban használják különböző blokkokon. A LoCon esetében például, ha a use_tucker
True
és a kernel méret k_size
nem (1, 1)
, akkor a konvolúciós művelet három külön műveletre bomlik:
- Egy 1x1-es konvolúció, amely csökkenti a csatornák számát
in_dim
-rőllora_dim
-re. - Egy konvolúció az eredeti kernel mérettel
k_size
, lépésközzelstride
, és paddingelpadding
, de csökkentett számú csatornávallora_dim
. - Egy 1x1-es konvolúció, amely visszanöveli a csatornák számát
lora_dim
-rőlout_dim
-re.
Ha a use_tucker
False
vagy nincs beállítva, vagy ha a kernel méret k_size
(1, 1)
, akkor egy standard konvolúciós művelet kerül végrehajtásra az eredeti kernel mérettel, lépésközzel és paddingel, és a csatornák száma in_dim
-ről lora_dim
-re csökken.
use_scalar
Egy további tanulható paraméter, amely skálázza az alacsony rangú súlyok hozzájárulását, mielőtt azok hozzáadódnának az eredeti súlyokhoz. Ez a skalár szabályozhatja, hogy az alacsony rangú adaptáció mennyire módosítja az eredeti súlyokat. A skalár tanításával a modell megtanulhatja az optimális egyensúlyt az eredeti előtanított súlyok megőrzése és az alacsony rangú adaptáció engedélyezése között.
# Ellenőrizzük, hogy a 'use_scalar' flag be van-e állítva True-ra
if use_scalar:
# Ha igen, inicializálunk egy tanulható 'scalar' paramétert 0.0 kezdőértékkel.
# Ez a paraméter optimalizálódik a tanítási folyamat során.
self.scalar = nn.Parameter(torch.tensor(0.0))
else:
# Ha a 'use_scalar' flag False, a 'scalar' értéke fix 1.0 lesz.
# Ez azt jelenti, hogy az alacsony rangú súlyok skálázás nélkül adódnak hozzá az eredeti súlyokhoz.
self.scalar = torch.tensor(1.0)
A use_scalar
flag lehetővé teszi a modell számára, hogy meghatározza, mennyi befolyása legyen az alacsony rangú súlyoknak a végső súlyokra. Ha a use_scalar
True
, a modell megtanulhatja a self.scalar
optimális értékét a tanítás során, amely megszorozza az alacsony rangú súlyokat, mielőtt azok hozzáadódnának az eredeti súlyokhoz. Ez lehetőséget biztosít az eredeti előtanított súlyok és az új alacsony rangú adaptációk közötti egyensúly megteremtésére, potenciálisan jobb teljesítményhez és hatékonyabb tanításhoz vezetve. A self.scalar
0.0
kezdőértéke azt sugallja, hogy a modell az alacsony rangú súlyok nélkül kezd, és a tanítás során tanulja meg a megfelelő skálát.
rank_dropout_scale
Egy logikai flag, amely meghatározza, hogy a dropout maszkot úgy skálázzuk-e, hogy átlagértéke 1
legyen vagy sem. Ez különösen hasznos, amikor meg szeretnénk őrizni a tenzor értékeinek eredeti skáláját a dropout alkalmazása után, ami fontos lehet a tanítási folyamat stabilitása szempontjából.
def forward(self, orig_weight, org_bias, new_weight, new_bias, *args, **kwargs):
# Lekérjük az 'oft_blocks' tenzor eszközét. Ez biztosítja, hogy minden új tenzor ugyanazon az eszközön jöjjön létre.
device = self.oft_blocks.device
# Ellenőrizzük, hogy a rang dropout engedélyezve van-e és a modell tanítási módban van-e.
if self.rank_dropout and self.training:
# Létrehozunk egy véletlenszerű tenzort ugyanolyan alakkal, mint az 'oft_blocks', egyenletes eloszlásból vett értékekkel.
# Ezután létrehozunk egy dropout maszkot annak ellenőrzésével, hogy minden érték kisebb-e, mint a 'self.rank_dropout' valószínűség.
drop = (torch.rand(self.oft_blocks, device=device) < self.rank_dropout).to(
self.oft_blocks.dtype
)
# Ha a 'rank_dropout_scale' True, a dropout maszkot úgy skálázzuk, hogy átlagértéke 1 legyen.
# Ez segít megőrizni a tenzor értékeinek skáláját a dropout alkalmazása után.
if self.rank_dropout_scale:
drop /= drop.mean()
else:
# Ha a rang dropout nincs engedélyezve vagy a modell nincs tanítási módban, a 'drop' értéke 1 (nincs dropout).
drop = 1
algo
A használt LyCORIS algoritmus. Megtalálhatod a megvalósított algoritmusok listáját és magyarázatát, egy demóval együtt, valamint beleáshatsz a kutatási tanulmányba is.
train_norm
Szabályozza, hogy betanítsuk-e a normalizációs rétegeket, amelyeket minden algoritmus használ, kivéve az (IA)^3
-at.
block_dims
Meghatározza minden blokk rangját, pontosan 25 számot vesz fel, ezért olyan hosszú ez a sor.
block_alphas
Meghatározza minden blokk alfáját, ez is pontosan 25 számot vesz fel, ha nem adod meg, akkor helyette a network_alpha
értéke lesz használva.
Ezzel befejeztük a network_args
ismertetését.
--network_dropout
Ez a lebegőpontos szám szabályozza a neuronok kiesését a tanításból minden lépésben, 0
vagy None
az alapértelmezett viselkedés (nincs dropout), 1 az összes neuront kiejtené. A weight_decompose=True
használata figyelmen kívül hagyja a network_dropout
-ot, és csak a rang és modul dropout lesz alkalmazva.
--network_dropout=0 \
--lr_scheduler
A PyTorch-ban a tanulási ráta ütemező egy olyan eszköz, amely a tanulási rátát a tanítási folyamat során állítja. A modell teljesítményének függvényében modulálja a tanulási rátát, ami jobb teljesítményhez és rövidebb tanítási időhöz vezethet.
Lehetséges értékek: linear
, cosine
, cosine_with_restarts
, polynomial
, constant
(alapértelmezett), constant_with_warmup
, adafactor
Megjegyzés: az adafactor
ütemező csak az adafactor
optimalizálóval használható!
--lr_scheduler="cosine" \
--lr_scheduler_num_cycles
Az újraindítások száma a cosine ütemezőnél újraindításokkal. Más ütemező nem használja.
--lr_scheduler_num_cycles=1 \
--learning_rate
és --unet_lr
és --text_encoder_lr
A tanulási ráta határozza meg, hogy a hálózat súlyai mennyire módosulnak a becsült hiba alapján minden alkalommal, amikor a súlyok frissülnek. Ha a tanulási ráta túl nagy, a súlyok túlléphetik az optimális megoldást. Ha túl kicsi, a súlyok elakadhatnak egy szuboptimális megoldásban.
Az AdamW esetében az optimális LR 0.0001
vagy 1e-4
szokott lenni, ha le akarod nyűgözni a barátaidat.
--learning_rate=0.0001 --unet_lr=0.0001 --text_encoder_lr=0.0001
--network_dim
A Hálózati Rang (Dimenzió) felelős azért, hogy hány jellemzőt fog a LoRA betanítani. Szoros kapcsolatban áll a Hálózati Alfával és az Unet + TE tanulási rátákkal, valamint természetesen az adatkészlet minőségével. Erősen ajánlott személyes kísérletezés ezekkel az értékekkel.
--network_dim=8
--output_name
Add meg a kimeneti nevet a fájlkiterjesztés nélkül.
FIGYELMEZTETÉS: Ha valamilyen okból ez valaha üresen marad, az utolsó epoch nem lesz elmentve!
--output_name="last"
--scale_weight_norms
A max-norm regularizáció egy olyan technika, amely korlátozza a bejövő súlyvektorok normáját minden rejtett egységnél egy rögzített konstans felső határral. Megakadályozza, hogy a súlyok túl nagyra nőjenek, és segít javítani a sztochasztikus gradiens ereszkedés teljesítményét a mély neurális hálók tanítása során.
A Dropout a hálózat architektúráját érinti a súlyok megváltoztatása nélkül, míg a Max-Norm Regularizáció közvetlenül módosítja a hálózat súlyait. Mindkét technikát a túltanulás megakadályozására és a modell általánosításának javítására használják. Mindkettőről többet tanulhatsz ebben a kutatási tanulmányban.
--scale_weight_norms=1.0
--max_grad_norm
Más néven Gradiens Vágás, ha azt veszed észre, hogy a gradiensek felrobbannak a tanítás során (a veszteség NaN lesz vagy nagyon nagy), fontold meg a --max_grad_norm
paraméter beállítását. Ez a gradienseken működik a visszaterjesztési folyamat során, míg a --scale_weight_norms
a neurális hálózat súlyain működik. Ez lehetővé teszi, hogy kiegészítsék egymást és robusztusabb megközelítést nyújtsanak a tanulási folyamat stabilizálásához és a modell teljesítményének javításához.
--max_grad_norm=1.0
--no_half_vae
Kikapcsolja a kevert pontosságot az SDXL VAE esetében és float32
-re állítja. Nagyon hasznos, ha nem szereted a NaN-okat.
--save_every_n_epochs
és --save_last_n_epochs
vagy --save_every_n_steps
és --save_last_n_steps
--save_every_n_steps
és--save_every_n_epochs
: Egy LoRA fájl jön létre minden n-edik lépésnél vagy epochnál, amit itt megadsz.--save_last_n_steps
és--save_last_n_epochs
: Eldobja az összes mentett fájlt, kivéve az utolsón
darabot, amit itt megadsz.
A tanulás mindig azzal fog véget érni, amit a --max_train_epochs
vagy --max_train_steps
paraméterben megadsz.
--save_every_n_epochs=50
--mixed_precision
Ez a beállítás határozza meg a számítási pontosságot a tanítás során. A kevert pontosság választása felgyorsíthatja a tanítást és csökkentheti a memóriahasználatot, de potenciális numerikus instabilitást okozhat. Íme a lehetőségek és azok előnyei-hátrányai:
- “no”: Teljes 32-bites pontosságot használ. Lassabb, de stabilabb.
- “fp16”: 16-bites pontosságot használ ahol lehetséges, visszaesik 32-bitre amikor szükséges. Ez felgyorsíthatja a tanítást és csökkentheti a memóriahasználatot, de időnként numerikus instabilitáshoz vezethet.
- “bf16”: bfloat16 pontosságot használ. Jó egyensúlyt kínál a 32-bites lebegőpontosok tartománya és a 16-bites lebegőpontosok memóriamegtakarítása között.
Válassz bölcsen a hardvered képességei és a stabilitási követelmények alapján. Ha NaN veszteségeket vagy más numerikus problémákat tapasztalsz a tanítás során, fontold meg a teljes pontosságra váltást vagy más hiperparaméterek módosítását.
--mixed_precision="bf16"
--save_precision
Ez a paraméter határozza meg a mentett modellsúlyok pontosságát. Ez egy kulcsfontosságú választás, amely mind a fájlméretet, mind a betanított LoRA pontosságát befolyásolja. Íme, amit tudnod kell:
- “fp32”: Teljes 32-bites pontosság. Ez a legpontosabb, de több tárolóhelyet foglal.
- “fp16”: 16-bites pontosság. Jó egyensúly a pontosság és a fájlméret között, a legtöbb esetben megfelelő.
- “bf16”: bfloat16 pontosság. Szélesebb tartományt kínál, mint az fp16, de kevesebb pontossággal, bizonyos hardverkonfigurációknál hasznos.
Válassz a tárolási korlátaid és pontossági követelményeid alapján. Ha nem vagy biztos benne, az “fp16” egy megbízható alapértelmezett érték, amely a legtöbb helyzetben jól működik. Ésszerű méretű LoRA fájlt eredményez túl sok pontosság feláldozása nélkül.
--save_precision="fp16"
--caption_extension
A feliratfájlok kiterjesztése. Az alapértelmezett .caption
. Ezek a feliratfájlok olyan szöveges leírásokat tartalmaznak, amelyek a tanítási képekhez kapcsolódnak. Amikor futtatod a tanítási szkriptet, az a megadott kiterjesztésű fájlokat fogja keresni a tanítási adatok mappájában. A szkript ezeknek a fájloknak a tartalmát használja feliratként, hogy kontextust biztosítson a képekhez a tanítási folyamat során.
Például, ha a képeid neve image1.jpg
, image2.jpg
, és így tovább, és az alapértelmezett .caption kiterjesztést használod, a szkript azt várja, hogy a feliratfájlok neve image1.caption
, image2.caption
, stb. legyen. Ha más kiterjesztést szeretnél használni, például .txt
-t, akkor a caption_extension paramétert .txt
-re állítanád, és a szkript ekkor image1.txt
, image2.txt
, és így tovább fájlokat keresne.
--caption_extension=".txt"
--cache_latents
és --cache_latents_to_disk
Ez a két paraméter együttműködik a memóriahasználat optimalizálásában és potenciálisan felgyorsíthatja a tanítást:
--cache_latents
: Ez az opció a memóriában tárolja a tanítási képek látens reprezentációit. Ezáltal a modellnek nem kell minden tanítási lépésnél újra kódolnia a képeket látens térbe, ami jelentősen felgyorsíthatja a tanítást, különösen nagyobb adatkészletek esetén.--cache_latents_to_disk
: A--cache_latents
-szel együtt használva ez az opció lehetővé teszi, hogy a gyorsítótárazott látens reprezentációk a lemezen tárolódjanak ahelyett, hogy mind a memóriában maradnának. Ez különösen hasznos, ha olyan nagy adatkészleted van, amely meghaladja a rendelkezésre álló RAM-ot.
Ezeknek az opcióknak a használata több előnnyel járhat:
- Gyorsabb tanítás: A látens reprezentációk előzetes kiszámításával és gyorsítótárazásával csökkented a számítási terhelést minden tanítási lépésnél.
- Csökkentett VRAM használat: A lemezre történő gyorsítótárazás segíthet hatékonyabban kezelni a memóriát, különösen nagy adatkészletek esetén.
- Konzisztencia: Az előre kiszámított látens reprezentációk biztosítják, hogy ugyanaz a látens reprezentáció legyen használva minden képhez az epochok során, ami stabilabb tanításhoz vezethet.
Azonban vedd figyelembe, hogy a látens reprezentációk gyorsítótárazása jelentős lemezterületet használhat, különösen nagy adatkészletek esetén. Győződj meg róla, hogy elegendő tárhely áll rendelkezésre, amikor a --cache_latents_to_disk
opciót használod.
--cache_latents --cache_latents_to_disk
--optimizer_type
Az alapértelmezett optimalizáló az AdamW
, és havonta vagy úgy körülbelül egy csomó új kerül hozzáadásra, ezért nem sorolom fel mindet, megtalálhatod a listát, ha tényleg akarod, de az AdamW
a legjobb e sorok írásakor, így ezt használjuk!
--optimizer_type="AdamW"
--dataset_repeats
Megismétli az adatkészletet feliratokkal történő tanításkor, alapértelmezetten 1
-re van állítva, így mi ezt 0
-ra állítjuk:
--dataset_repeats=0
--max_train_steps
Add meg a tanítási lépések vagy epochok számát. Ha mind a --max_train_steps
, mind a --max_train_epochs
meg van adva, az epochok száma élvez elsőbbséget.
--max_train_steps=400
--shuffle_caption
Összekeveri a --caption_separator
által meghatározott feliratokat, alapértelmezetten ez egy vessző ,
, ami tökéletesen működik a mi esetünkben, mivel a felirataink így néznek ki:
rating_questionable, 5 fingers, anthro, bent over, big breasts, blue eyes, blue hair, breasts, butt, claws, curved horn, female, finger claws, fingers, fur, hair, huge breasts, looking at viewer, looking back, looking back at viewer, nipples, nude, pink body, pink hair, pink nipples, rear view, solo, tail, tail tuft, tuft, by lunarii, by x-leon-x, mythology, krystal \(darkmaster781\), dragon, scalie, wickerbeast, The image showcases a pink-scaled wickerbeast a furred dragon creature with blue eyes., She has large breasts and a thick tail., Her blue and pink horns are curved and pointy and she has a slight smiling expression on her face., Her scales are shiny and she has a blue and pink pattern on her body., Her hair is a mix of pink and blue., She is looking back at the viewer with a curious expression., She has a slight blush.,
Mint láthatod, nemcsak a címkéket, hanem a felirat részt is vesszővel választottam el, hogy minden összekeveredjen.
MEGJEGYZÉS: A --cache_text_encoder_outputs
és a --cache_text_encoder_outputs_to_disk
nem használható együtt a --shuffle_caption
-nel. Mindkettő a VRAM használat csökkentését célozza, neked kell eldöntened, melyiket választod!
--sdpa
vagy --xformers
vagy --mem_eff_attn
Mindegyik opció módosítja a modellben használt figyelmi mechanizmust, ami jelentős hatással lehet a modell teljesítményére és memóriahasználatára. A választás az --xformers
vagy --mem_eff_attn
és az --spda
között a GPU-dtól függ. Tesztelheted őket egy tanítás megismétlésével!
--xformers
: Ez a flag engedélyezi az XFormers használatát a modellben. Az XFormers egy Facebook Research által fejlesztett könyvtár, amely különböző hardverekre és felhasználási esetekre optimalizált transformer modellek gyűjteményét biztosítja. Ezek a modellek úgy vannak tervezve, hogy nagyon hatékonyak, rugalmasak és testreszabhatóak legyenek. Különféle figyelmi mechanizmusokat és egyéb funkciókat kínálnak, amelyek hasznosak lehetnek olyan helyzetekben, ahol korlátozott GPU memóriával rendelkezel vagy nagy méretű adatokat kell kezelned.--mem_eff_attn
: Ez a flag engedélyezi a memória-hatékony figyelmi mechanizmusok használatát a modellben. A memória-hatékony figyelem úgy van tervezve, hogy csökkentse a memóriahasználatot a transformer modellek tanítása során, ami különösen hasznos lehet nagy modellek vagy adatkészletek esetén.--sdpa
: Ez az opció engedélyezi a Skálázott Skaláris Szorzat Figyelem (SDPA) használatát a modellben. Az SDPA a transformer modellek alapvető komponense, amely kiszámítja a figyelmi pontszámokat a lekérdezések és kulcsok között. A skaláris szorzatokat a kulcsok dimenziójával skálázza a gradiensek stabilizálása érdekében a tanítás során. Ez a mechanizmus különösen hasznos hosszú sorozatok kezelésére és potenciálisan javíthatja a modell képességét a hosszú távú függőségek megragadására.
--sdpa
--multires_noise_iterations
és --multires_noise_discount
A többfelbontású zaj egy új megközelítés, amely több felbontásban ad zajt egy képhez vagy látens képhez a diffúziós modellek tanítása során. Az ezzel a technikával tanított modell vizuálisan lenyűgöző képeket generálhat, amelyek esztétikailag különböznek a diffúziós modellek szokásos kimeneteitől.
A többfelbontású zajjal tanított modell változatosabb képeket tud generálni, mint a hagyományos stabil diffúzió, beleértve a rendkívül világos vagy sötét képeket is. Ezek történelmileg nehezen voltak elérhetők anélkül, hogy nagy számú mintavételi lépést használtunk volna.
Ez a technika különösen előnyös kis adatkészletekkel való munka során, de szerintem soha nem kellene nem használni.
A --multires_noise_discount
paraméter szabályozza, hogy mennyire gyengül a zaj mennyisége minden felbontásnál. A 0.1 érték ajánlott. A --multires_noise_iterations
paraméter határozza meg a többfelbontású zaj hozzáadásának iterációszámát, 6-10 közötti ajánlott tartománnyal.
Kérlek vedd figyelembe, hogy a --multires_noise_discount
-nak nincs hatása a --multires_noise_iterations
nélkül.
Implementációs Részletek
A get_noise_noisy_latents_and_timesteps
függvény mintavételezi a zajt, amely hozzáadódik a látens reprezentációkhoz. Ha az args.noise_offset
igaz, zajeltolást alkalmaz. Ha az args.multires_noise_iterations
igaz, többfelbontású zajt alkalmaz a mintavételezett zajra.
A függvény ezután minden képhez véletlenszerű időlépést mintavételez, és zajt ad a látens reprezentációkhoz az egyes időlépéseknél lévő zajmagnitude szerint. Ez az előre irányuló diffúziós folyamat.
A pyramid_noise_like
függvény piramis szerkezetű zajt generál. Az eredeti zajjal kezdi, és felskálázott zajt ad hozzá csökkenő felbontásokban. A zaj minden szinten egy diszkontfaktorral skálázódik, amely a szint hatványára van emelve. A zaj ezután visszaskálázódik körülbelül egységnyi varianciára. Ezt a függvényt használják a többfelbontású zaj megvalósításához.
--multires_noise_iterations=10 --multires_noise_discount=0.1
--sample_prompts
és --sample_sampler
és --sample_every_n_steps
Lehetőséged van képeket generálni a tanítás során, hogy ellenőrizhesd a haladást. Az argumentum lehetővé teszi, hogy különböző mintavételezők között válassz, alapértelmezetten ddim
-en van, úgyhogy jobb, ha megváltoztatod!
A --sample_every_n_epochs
használhatod helyette, ami elsőbbséget élvez a lépésekkel szemben. A k_
előtag karras-t jelent, és az _a
utótag ancestral-t.
--sample_prompts=/training_dir/sample-prompts.txt --sample_sampler="euler_a" --sample_every_n_steps=100
A Pony esetében az ajánlásom a rajzfilmszerű képekhez az euler_a
, a realisztikushoz pedig a k_dpm_2
.
A mintavételezési lehetőségeid a következők:
ddim, pndm, lms, euler, euler_a, heun, dpm_2, dpm_2_a, dpmsolver, dpmsolver++, dpmsingle, k_lms, k_euler, k_euler_a, k_dpm_2, k_dpm_2_a
Tehát az egész így nézne ki:
accelerate launch --num_cpu_threads_per_process=2 "./sdxl_train_network.py" \
--lowram \
--pretrained_model_name_or_path="/ponydiffusers/" \
--train_data_dir="/training_dir" \
--resolution="1024,1024" \
--output_dir="/output_dir" \
--enable_bucket \
--min_bucket_reso=256 \
--max_bucket_reso=1024 \
--network_alpha=4 \
--save_model_as="safetensors" \
--network_module="lycoris.kohya" \
--network_args \
"preset=full" \
"conv_dim=256" \
"conv_alpha=4" \
"use_tucker=False" \
"use_scalar=False" \
"rank_dropout_scale=False" \
"algo=locon" \
"train_norm=False" \
"block_dims=8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8" \
"block_alphas=0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625,0.0625" \
--network_dropout=0 \
--lr_scheduler="cosine" \
--learning_rate=0.0001 \
--unet_lr=0.0001 \
--text_encoder_lr=0.0001 \
--network_dim=8 \
--output_name="yifftoolkit" \
--scale_weight_norms=1 \
--no_half_vae \
--save_every_n_epochs=50 \
--mixed_precision="fp16" \
--save_precision="fp16" \
--caption_extension=".txt" \
--cache_latents \
--cache_latents_to_disk \
--optimizer_type="AdamW" \
--max_grad_norm=1 \
--keep_tokens=1 \
--max_data_loader_n_workers=8 \
--bucket_reso_steps=32 \
--multires_noise_iterations=10 \
--multires_noise_discount=0.1 \
--log_prefix=xl-locon \
--gradient_accumulation_steps=6 \
--gradient_checkpointing \
--train_batch_size=8 \
--dataset_repeats=0 \
--max_train_steps=400 \
--shuffle_caption \
--sdpa \
--sample_prompts=/training_dir/sample-prompts.txt \
--sample_sampler="euler_a" \
--sample_every_n_steps=100
Zsugorítás
Most, hogy a tanításod befejeződött és elkészült az első LoRA-d, csökkentsük a méretét egy jelentős* mértékben. A csökkentett fájlméret mellett ez segít a LoRA-dnak jobban működni más modellekkel, és nagyban segít olyan helyzetekben, ahol elég sok van belőlük egymásra halmozva, a kimenetben tapasztalható teljesen elhanyagolható különbségért cserébe, amit én nem neveznék minőségnek, a megfelelő beállításokkal.
Ehhez a folyamathoz a resize_lora-t fogjuk használni.
git clone https://github.com/elias-gaeros/resize_lora
cd resize_lora
Győződj meg róla, hogy a torch
, tqdm
, safetensors
telepítve van a Python környezetedben. Ezután futtasd a következő parancsot:
python resize_lora.py -o {output_directory} -r fro_ckpt=1,thr=-3.55 model.safetensors lora.safetensors
Csak cseréld ki az {output_directory}
-t a kívánt kimeneti könyvtáraddal és a model.safetensors
-t azzal a checkpointtal, amit a LoRA betanításához használtál, vagy amivel az új LoRA-dat használni szeretnéd, és a lora.safetensors
-t azzal a LoRA-val, amit le szeretnél zsugorítani.
Nyugodtan kísérletezz bármelyik SVD recepttel, amelyekről a projekt README-jében olvashatsz, az én ajánlásom nyilvánvalóan csak személyes elfogultság, de próbáltam tesztelni, sokat, hogy másoknak ne kelljen!
Lépések vs Epochák
Egy modell tanításakor fontos megérteni a különbséget a lépések és az epochák között. Mindkettő kulcsfontosságú koncepció a tanítási folyamatban, de különböző célokat szolgálnak.
Lépések
Egy lépés a tanítási folyamat egyetlen iterációját jelenti, ahol a modell feldolgoz egy adagot az adatokból, és frissíti a paramétereit az abból az adagból számított veszteség alapján. A lépések számát általában az adagméret és a teljes tanítási adatmennyiség határozza meg. Más szóval, egy lépés a modell paramétereinek egyetlen frissítése.
Epochák
Egy epocha ezzel szemben a teljes tanítási adatkészleten való egy teljes áthaladást jelent. Egy epocha egyenértékű az egész adatkészlet egyszeri feldolgozásával, ahol minden adag egy lépések sorozatában kerül feldolgozásra. Az epochák száma határozza meg, hogy hányszor látja a modell a teljes tanítási adatkészletet a tanítás során.
Az illusztráláshoz vegyünk egy példát, ahol a tanítási adatkészlet 1000 képből áll, az adagméret 10, és összesen 10 epocha van. Ebben az esetben:
- A modell 100 lépést fog feldolgozni epochonként (1000 kép / 10 kép adagonként).
- A modell 10-szer fogja látni az egész adatkészletet, ahol minden epocha 100 lépésből áll.
A lépések és epochák közötti különbség megértése kulcsfontosságú a tanítási paraméterek, például a tanulási ráta ütemezés beállításához, és a modell haladásának nyomon követéséhez a tanítás során.
Gradiens Akkumuláció
A gradiens akkumuláció egy olyan technika, amely csökkenti a mély neurális hálózatok tanításának memóriaigényét. Úgy működik, hogy több iteráción keresztül gyűjti a veszteségfüggvény gradienseit a modell paramétereire vonatkozóan, ahelyett, hogy minden iterációnál kiszámítaná a gradienseket. Ez nagyobb adagméretet és hatékonyabb GPU memóriahasználatot tesz lehetővé.
A LoRA tanítás kontextusában a gradiens akkumuláció használható a tanítási folyamat stabilitásának és hatékonyságának javítására. A gradiensek több iteráción keresztüli akkumulálásával a modell hatékonyabban tanulhatja meg felismerni a mintákat az adatokban, ami jobb teljesítményhez vezethet.
A gradiens akkumuláció használatához a LoRA tanításban a következő argumentumot adhatod a tanítási parancsodhoz:
--gradient_accumulation_steps=6
Fontos megjegyezni, hogy az epochonkénti lépések számát az adagméret és a teljes tanítási adatmennyiség határozza meg. Ezért gradiens akkumuláció használatakor az epochonkénti lépések száma a teljes tanítási adatkészlet feldolgozásához szükséges iterációk száma lesz, nem pedig az adagok száma. Ez a különbség fontos a tanulási ráta ütemezés beállításakor és a modell haladásának nyomon követésekor a tanítás során.
Tensorboard
A Tensorboard-ot engedélyezheted a következők konfigurációdhoz adásával:
--log_prefix=xl-locon \
--log_with=tensorboard \
--logging_dir=/output_dir/logs \
Természetesen először telepítened kell a Tensorboard-ot, hogy ténylegesen meg tudd nézni a tanítást, és ezután csak ezt kell használnod a kimeneti könyvtáradban:
tensorboard --logdir=logs
Ezután megnyithatod a böngésződben a http://localhost:6006/ címen, és próbálhatsz teafüvet olvasni, ööö, bocsánat! Úgy értettem, veszteségi görbéket!