diff --git a/MANUAL_TRAIN.md b/MANUAL_TRAIN.md index 9a1d7c2..fe2256d 100644 --- a/MANUAL_TRAIN.md +++ b/MANUAL_TRAIN.md @@ -1,17 +1,21 @@ # I. 단일폴더 수동 학습 사용 예시 ## 1. 기본 사용 (자동 계산) -```bash +```cmd run-train-single --folder ../dataset/training/01_alice ``` ## 2. Epochs만 수동 지정 -```bash +```cmd run-train-single --folder ../dataset/training/01_alice --epochs 25 + +또는 + +run-train-single --folder ../training/mainchar/01_alic3 --epochs 17 --resume alic3-000009.safetensors ``` ## 3. 세밀한 조정 -```bash +```cmd run-train-single ^ --folder ../dataset/training/01_alice ^ --epochs 30 ^ @@ -22,7 +26,7 @@ run-train-single ^ ``` ## 4. 고해상도 학습 -```bash +```cmd run-train-single ^ --folder ../dataset/training/01_alice ^ --resolution 1024,1024 ^ @@ -30,7 +34,7 @@ run-train-single ^ ``` ## 5. 빠른 테스트 -```bash +```cmd run-train-single ^ --folder ../dataset/training/01_alice ^ --epochs 5 ^ @@ -39,7 +43,7 @@ run-train-single ^ ``` ## 6. 완전 수동 모드 -```bash +```cmd run-train-single ^ --folder ../dataset/training/01_alice ^ --no-auto ^ @@ -75,14 +79,14 @@ run-train-single ^ ## 비교 ### train_batch.py (일괄 자동) -```bash +```cmd # 여러 폴더 자동 학습 python train_batch.py → 01_alice, 02_bob, 03_background 모두 학습 ``` ### train_single.py (단일 수동) -```bash +```cmd # 특정 폴더만 세밀 조정 run-train-single --folder ../dataset/training/mainchar/01_alice --epochs 30 --lr 0.00015 → alice만 커스텀 파라미터로 학습 @@ -91,7 +95,7 @@ run-train-single --folder ../dataset/training/mainchar/01_alice --epochs 30 --lr ## 워크플로우 추천 ### 초보자 -```bash +```cmd # 1. 먼저 일괄 자동으로 테스트 python train_batch.py @@ -100,7 +104,7 @@ run-train-single --folder ../dataset/training/mainchar/01_alice --epochs 25 ``` ### 고급 사용자 -```bash +```cmd # 처음부터 세밀하게 조정 run-train-single ^ --folder ../dataset/training/mainchar/01_alice ^ diff --git a/README.md b/README.md index 60dd1cb..dde98e7 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.4\bin으로 복사합니 ## 학습방법 1: 폴더명 규칙 사용 (자동) ./train.sh config.json 0 + # 방법 2: 강제로 15번 반복 ./train.sh config.json 0 15 diff --git a/TRAINING.md b/TRAINING.md new file mode 100644 index 0000000..042b245 --- /dev/null +++ b/TRAINING.md @@ -0,0 +1,82 @@ +🎨 폴더 명명 예시: + +```cmd +01_alice_woman (3단어와 언더스코어 2개: 클래스 포함) +- name=alice, class=woman -> --class_tokens=woman 적용. + +02_style (2단어와 언더스코어 1개: 클래스 미포함) +- name=style, class=None -> --class_tokens 미적용. +``` + +🎨 클래스 키워드 선정 기준 및 분류 예시 + +#### 클래스 키워드를 선정할 때는 **"이 대상이 없었을 때, 모델이 원래 무엇을 생성해야 하는가?"**를 생각하면 쉽습니다. + +### 1. 인물/캐릭터 학습 시 + +사람이나 캐릭터를 학습시킬 때는 성별, 연령대, 종족 등 가장 넓은 카테고리를 사용합니다. + +| 학습 대상 (ID 토큰) | 클래스 키워드 | 설명 | +|---------------------|---------------------------|-------| +| 특정 인물 (alice) | woman 또는 man | 성별을 나타내는 가장 일반적인 단어. | +| 특정 어린이 (child_A) | child 또는 kid | 연령대를 나타내는 일반적인 단어. | +| 특정 동물 캐릭터 (pet_dragon) | dragon 또는 monster | 해당 대상의 종족 또는 종류. | +| 만화체 캐릭터 (manga_hero) | person 또는 character | 스타일이 강한 경우 일반적인 '사람'이나 '캐릭터'로 정의. | + +### 2. 스타일/화풍 학습 시 +스타일을 학습시킬 때는 그 스타일이 적용될 가장 일반적인 대상을 클래스로 지정합니다. + +| 학습 대상 (ID 토큰) | 클래스 키워드 | 설명 | +|---------------------|---------------------------|--------| +| 특정 작가 화풍 (artstyle_A) | style 또는 art | '스타일' 자체를 클래스로 지정하는 것이 일반적입니다. | +| 특정 조명 효과 (cinema_light) | lighting 또는 effect | 모델이 **'조명'**의 개념을 잃지 않도록 합니다. | +| 특정 의상 (maid_dress_v2) | clothing 또는 dress | 의류의 일반적인 카테고리. | + +### 3. 사물/배경 학습 시 +특정 사물이나 배경을 학습시킬 때는 그 사물의 가장 넓은 범주를 사용합니다. + +| 학습 대상 (ID 토큰) | 클래스 키워드 | 설명 | +|---------------------|---------------------------|--------| +| 특정 자동차 모델 (car_v1) | car 또는 vehicle | 해당 사물의 일반적인 명칭. | +| 특정 건물 (my_house) | house 또는 building | 해당 배경의 일반적인 명칭. | +| 특정 음식 (korean_dish) | food 또는 dish | 해당 카테고리의 일반적인 명칭. | + + +### 🛑 클래스 키워드를 넣는 경우 (정규화의 중요성) + +클래스 키워드를 01_alice_woman처럼 넣는다는 것은 다음과 같은 의미가 있습니다. + +ID 토큰 정의: alice는 **woman**이다. + +정규화 활성화: Kohya_SS에게 **woman**이라는 클래스에 대한 **정규화 이미지(Regularization Images)**를 찾아서 함께 학습하라고 지시합니다. + +정규화 이미지가 없다면 클래스 키워드를 넣어도 효과가 없거나 미미합니다. 따라서 클래스 키워드를 정했다면, 해당 키워드(예: woman)로 생성된 수백~수천 장의 이미지를 정규화 폴더 (일반적으로 reg_woman 등)에 넣어 함께 학습해야 가장 좋은 품질을 얻을 수 있습니다. + + +### 🎯 SDXL Base 모델 학습 시 정규화 이미지의 역할 + +#### SDXL Base 1.0 모델을 기반으로 학습할 때, woman과 같은 일반적인 클래스 이미지(정규화 이미지)를 추가로 넣어줄 필요는 없습니다. + +### 1. SDXL의 강점: 이미 "알고 있음" +- SDXL Base 1.0은 수많은 이미지로 학습된 **대규모 모델(Foundation Model)**입니다. +- 이미 **woman (여성), car (자동차), house (집)**과 같은 일반적인 개념과 해당 개념의 다양한 형태를 매우 잘 이해하고 표현할 수 있습니다. +- LoRA 학습의 목표는 SDXL이 이미 알고 있는 **일반적인 지식(클래스 지식)**을 잊어버리지 않게 하면서, **새로운 고유 개념(ID 토큰)**만 추가로 학습시키는 것입니다. + +### 2. 정규화 이미지의 필요성 +- 일반 LoRA/Dreambooth 학습: SD 1.5 같은 구형 모델이나 미세 조정되지 않은 모델로 학습할 때는 정규화 이미지가 필수였습니다. 이는 모델이 일반적인 개념을 잊어버리는 **재앙적 망각(Catastrophic Forgetting)**을 방지하기 위함이었습니다. +- SDXL LoRA 학습: SDXL은 기본적으로 이 지식을 매우 잘 보존합니다. 따라서 **woman**이라는 클래스에 대해 수백, 수천 장의 정규화 이미지를 직접 수집하고 넣어주는 노동은 대부분의 경우 불필요합니다. + +### 3. Kohya_SS 설정 (SDXL에 특화된 방식) +- Kohya_SS를 포함한 최신 학습 툴들은 SDXL 학습 시 정규화 이미지 폴더를 비워두거나, 아예 지정하지 않는 방식을 지원합니다. +- 이 방식은 SDXL이 이미 방대한 내부 지식을 가지고 있기 때문에, 따로 외부 이미지를 가져와 정규화하지 않아도 충분히 안정적인 결과를 얻을 수 있다는 전제에 기반합니다. + +### ⚠️ 예외적인 경우: 정규화가 필요한 경우 + +- 대부분의 경우 woman에 대한 정규화는 불필요하지만, 매우 특수한 형태의 클래스를 학습시킬 때는 고려해 볼 수 있습니다. + +| 경우 | 예시 | 설명 | +|---------------------|---------------------------|--------| +| 강력한 스타일 학습 | artstyle_A (극도로 만화적인 스타일) | "스타일 자체가 SDXL이 '인간'으로 인식하는 방식을 크게 왜곡할 때, 일반적인 woman 이미지를 정규화하여 모델의 지식을 보호할 수 있습니다." | +| 특정 자세/배경에 과적합 우려 | 특정 포즈만 있는 pose_v1 |"pose 클래스에 대해 다양한 일반 포즈 이미지를 정규화하여, 모델이 모든 사람의 포즈를 해당 포즈로 고정시키지 않도록 방지합니다." | + +#### - 일반적으로 사람이나 평범한 사물을 학습할 때는 클래스 명만 지정(01_alice_woman)하고 정규화 이미지는 넣지 않는 것이 시간과 자원(디스크 공간)을 아끼는 가장 효율적인 방법입니다. diff --git a/docker-build.cmd b/docker-build.cmd index 31ce934..de3dfae 100644 --- a/docker-build.cmd +++ b/docker-build.cmd @@ -1,3 +1,3 @@ -docker build --no-cache -t aicompanion/sdxl_train_captioner:1.0.2 . +docker build --no-cache -t aicompanion/sdxl_train_captioner:1.0.3 . -docker tag aicompanion/sdxl_train_captioner:1.0.2 aicompanion/sdxl_train_captioner:latest \ No newline at end of file +docker tag aicompanion/sdxl_train_captioner:1.0.3 aicompanion/sdxl_train_captioner:latest \ No newline at end of file diff --git a/resume-train.cmd b/resume-train.cmd index 67a9646..231f203 100644 --- a/resume-train.cmd +++ b/resume-train.cmd @@ -1,31 +1 @@ -accelerate launch --num_cpu_threads_per_process 1 --mixed_precision bf16 ^ - sdxl_train_network.py ^ - --resume="../output_models" ^ - --max_train_epochs=20 ^ - --pretrained_model_name_or_path="../models/sd_xl_base_1.0.safetensors" ^ - --train_data_dir="../dataset/train/mainchar" ^ - --output_dir="../output_models" ^ - --logging_dir="../logs" ^ - --output_name="karina" ^ - --network_module=networks.lora ^ - --network_dim=32 ^ - --network_alpha=16 ^ - --learning_rate=1e-4 ^ - --optimizer_type="AdamW8bit" ^ - --lr_scheduler="cosine" ^ - --lr_warmup_steps=100 ^ - --save_every_n_epochs=1 ^ - --mixed_precision="bf16" ^ - --save_precision="bf16" ^ - --cache_latents ^ - --cache_latents_to_disk ^ - --gradient_checkpointing ^ - --xformers ^ - --seed=42 ^ - --bucket_no_upscale ^ - --min_bucket_reso=512 ^ - --max_bucket_reso=2048 ^ - --bucket_reso_steps=64 ^ - --resolution="1024,1024" ^ - --network_train_unet_only ^ - --cache_text_encoder_outputs \ No newline at end of file +run-train-single --resume ../output_models/alic3-000009.safetensors --epochs 17 --folder ../training/mainchar/01_alic3 \ No newline at end of file diff --git a/run-train-single.ps1 b/run-train-single.ps1 deleted file mode 100644 index 60a20e7..0000000 --- a/run-train-single.ps1 +++ /dev/null @@ -1,55 +0,0 @@ -# =================================== -# SDXL LoRA 단일 학습 (PowerShell → Docker) -# =================================== - -param( - [Parameter(ValueFromRemainingArguments=$true)] - [string[]]$Arguments -) - -if ($Arguments.Count -eq 0) { - Write-Host "Usage: run-train-single.ps1 --folder FOLDER [OPTIONS]" -ForegroundColor Yellow - Write-Host "" - Write-Host "Examples:" -ForegroundColor Cyan - Write-Host " .\run-train-single.ps1 --folder ../dataset/training/01_alice" - Write-Host " .\run-train-single.ps1 --folder ../dataset/training/01_alice --epochs 25" - Write-Host " .\run-train-single.ps1 --folder ../dataset/training/01_alice --lr 0.0002 --dim 64" - exit 1 -} - -# 타임스탬프 -$timestamp = Get-Date -Format "yyyyMMdd_HHmmss" - -# Arguments를 문자열로 결합 -$argsString = $Arguments -join ' ' - -# 작은따옴표 이스케이프 -$argsString = $argsString -replace "'", "'\\''" - -Write-Host "===================================" -ForegroundColor Green -Write-Host "Starting SDXL LoRA Training" -ForegroundColor Green -Write-Host "===================================" -ForegroundColor Green -Write-Host "Arguments: $argsString" -ForegroundColor Cyan -Write-Host "Log file: train_$timestamp.log" -ForegroundColor Cyan -Write-Host "===================================" -ForegroundColor Green -Write-Host "" - -# Docker 명령어 -$dockerCmd = "cd /app/sdxl_train_captioner/sd-scripts && python run-train-single.py $argsString 2>&1 | tee /app/sdxl_train_captioner/logs/train_$timestamp.log" - -# 실행 -docker exec -it sdxl_train_captioner bash -c $dockerCmd - -if ($LASTEXITCODE -eq 0) { - Write-Host "" - Write-Host "===================================" -ForegroundColor Green - Write-Host "Training completed successfully!" -ForegroundColor Green - Write-Host "===================================" -ForegroundColor Green -} else { - Write-Host "" - Write-Host "===================================" -ForegroundColor Red - Write-Host "Training failed with error code: $LASTEXITCODE" -ForegroundColor Red - Write-Host "===================================" -ForegroundColor Red -} - -pause \ No newline at end of file diff --git a/sd-scripts b/sd-scripts index 22f559d..8cf42e0 160000 --- a/sd-scripts +++ b/sd-scripts @@ -1 +1 @@ -Subproject commit 22f559dbe24db93979ce508a5033a8272989a80d +Subproject commit 8cf42e0e2fbd1ff5dc55aa0a7e63acb5f98e89de