Plane Helper
세부 정보
파일 다운로드
이 버전에 대해
모델 설명
Plane Helper 도입! v2.1용 다중 개념 LyCORIS(LoHa로 훈련됨). Plane Helper는 71종류의 비행기 약 2,300장의 이미지로 훈련되었습니다. 복잡한 개념에 대해 다중 개념 LoHa를 훈련하는 과정을 알고 싶은 분들에게 제 훈련 프로세스를 공유하고자 합니다. 이는 과학적이지 않지만, 제가 겪었던 같은 어려움을 겪고 있을 수 있는 다른 사람들에게 도움이 되고자 하는 목적입니다.
데이터셋:
이 모델에 포함된 71종류의 비행기와 각각의 키 토큰이 담긴 데이터 테이블은 여기서 확인하실 수 있습니다:
https://docs.google.com/spreadsheets/d/1N7o4pc9mGyYSYIoeD4fU_WpO_2tL_JfKDETOJPVQw18/edit?usp=sharing
이 프로젝트는 v2.1이 비행기 생성에 매우 부족하다는 것을 깨달은 후 시작되었습니다. 비행기의 날개가 잘못된 위치에 나오거나, 추가 날개가 생기거나, 디테일이 부족했으며, 때로는 뾰족한 기하학적 형태들의 덩어리밖에 나오지 않았습니다. 저는 이를 개선하고자 했습니다. 따라서 먼저 멋진 비행기 이미지 약 130장을 수집해 배치 인터로게이터를 통해 캡션을 생성했습니다. Kohya로 훈련했지만, 얼마나 더 훈련해도 같은 문제점이 계속 나타났습니다. 이 문제의 원인이 너무 다양한 개체를 포함하고 있어, 이들을 구분하지 않고 단지 ‘비행기’나 ‘제트기’로만 부르기 때문이라고 판단했습니다. 그래서 각 비행기 유형을 특정하고, 그 이름을 각 이미지의 캡션에 삽입하기로 결정했습니다.
비행기에 대해 잘 알지 못했지만, v2.1이 멋진 비행기 이미지를 만들 수 있기를 원했습니다. 그래서 각 이미지를 image.google.com에 업로드해 모든 비행기를 식별하는 작업은 번거롭고 시간이 많이 걸렸지만, 반드시 필요한 과정이었습니다. 결과적으로 71가지 다른 비행기 유형을 확보했습니다. 단순히 2가지만 선택하고 넘어가는 대신, 이 LoHa 유형 모델이 무엇으로 구성되어 있는지 확인하고자 각 비행기 유형마다 최소 30장 이상의 이미지를 수집해 한 개의 LoHa로 모두 훈련하기로 결정했습니다. 일부 비행기 유형은 양질의 이미지 30장을 확보하지 못했지만, 최종 목표가 일반적인 비행기 모델을 훈련하는 것이었기 때문에 이들 역시 데이터셋에 포함하기로 했습니다. 이 목표를 달성했을 때, 총 71가지 비행기 유형에 해당하는 약 2,300장의 이미지를 각각의 폴더에 정리했습니다. 그 다음 캡션 작업이 시작되었습니다.
Captionr를 사용해 배치 인터로게이션을 마친 후, 각 비행기 유형을 구글로 검색해 이름과 함께 항공기의 간단하지만 상세한 설명을 엑셀 테이블로 만들었습니다. 그 후 각 폴더를 Dataset Tag Editor 확장 프로그램에 하나씩 불러들여 캡션을 정리하고, 앞서 만든 엑셀 테이블의 토큰을 각 캡션에 삽입했습니다. 또한, 틸트로터 비행기(모양이 매우 다르기 때문)에 대해 디버그 토큰인 "CHV3CPlane"과 "CHV3CTiltRotor"도 각 캡션에 추가했습니다. 이 디버그 토큰은 고유한 비행기를 생성하는 데에도 매우 효과적입니다. 또한 가중 캡션을 허용해 디버그 토큰과 비행기 유형 식별 토큰에 가중치를 적용했습니다. 예를 들어 캡션은 다음과 같이 구성될 수 있습니다:
"(Hawker Hunter), transonic jet-powered fighter aircraft, Hawker Aircraft, Royal Air Force (RAF), Avon turbojet engine, swept wing, (CHV3CPlane), a plane is flying in the air, swiss, low level, man, viewed in profile from far away, switzerland, illustration, overhead"
이 길고 인내심을 요하는 테스트 과정을 마친 후, 드디어 훈련을 시작할 만큼 충분히 양질의 데이터셋을 확보했습니다.
반복 횟수:
처음에는 각 폴더의 반복 횟수를 5로 설정했지만, 일부 비행기 유형은 이미지 수가 적었기 때문에, 이미지 수가 많은 유형은 5회 반복, 적은 유형은 10~15회 반복하도록 대략적으로 균형을 맞췄습니다.
훈련 방법:
이 프로젝트를 다소 비전통적인 방식으로 진행했습니다. 이처럼 큰 데이터셋을 다루다 보니 과적합 문제가 자연스럽게 발생했습니다. LoHa의 네트워크 차원은 8이 권장되지만, 저는 더 많은 훈련 공간을 확보하기 위해 32로 변경했습니다. 몇 단계를 거치며, 너무 과적합되기 전에 더 많은 에포크를 훈련할 수 있는 최적의 설정을 찾아냈습니다. 원본 소스 모델은 v2-1_768-ema-pruned이었지만, 각 훈련 후에는 이전 훈련에서 생성된 LoHa를 v2-1_768-ema-pruned에 병합하고, 이를 다음 훈련의 소스 모델로 사용했습니다. 이 방법의 이론적 배경은 이전 훈련에서 얻은 추가 지식이 다음 훈련에 도움이 되어 약간의 우위를 제공할 것이라는 것이었으며, 이 이론은 더 많은 테스트가 필요합니다. 특히 작은 데이터셋에서 테스트하는 것이 바람직합니다. 각 훈련 후에는 이전 소스 모델을 새롭게 병합된 소스 모델과 다시 병합하고, 이를 새로운 소스 모델로 사용했습니다. 또한 Extract LyCORIS LoCON을 사용해 LoRA를 추출했습니다. 이 특정 모델은 동일한 71개 비행기 데이터셋을 사용해 4번의 훈련을 거친 LoHa를 병합한 후 추출한 것입니다.
훈련 사양:
훈련 사양을 너무 구체적으로 설명하지는 않겠습니다. 대신 이 프로젝트에서 가장 효과적인 설정을 아래에 제시하고, 보다 상세한 내용을 다룬 3개의 다른 가이드를 안내하겠습니다.
기타 LoRA 훈련 가이드
LoRA 훈련 가이드
RFKTR의 고품질 모델 훈련에 대한 심층 가이드
https://civitai.com/articles/397
제 사양:
{
"LoRA_type": "LyCORIS/LoHa",
"adaptive_noise_scale": 0,
"additional_parameters": "",
"block_alphas": "",
"block_dims": "",
"block_lr_zero_threshold": "",
"bucket_no_upscale": true,
"bucket_reso_steps": 64,
"cache_latents": true,
"cache_latents_to_disk": false,
"caption_dropout_every_n_epochs": 0.0,
"caption_dropout_rate": 0,
"caption_extension": ".txt",
"clip_skip": "1",
"color_aug": false,
"conv_alpha": 1,
"conv_alphas": "",
"conv_dim": 4,
"conv_dims": "",
"decompose_both": false,
"dim_from_weights": false,
"down_lr_weight": "",
"enable_bucket": true,
"epoch": 20,
"factor": -1,
"flip_aug": true,
"full_fp16": false,
"gradient_accumulation_steps": 2.0,
"gradient_checkpointing": true,
"keep_tokens": "0",
"learning_rate": 0.0001,
"logging_dir": "",
"lora_network_weights": "",
"lr_scheduler": "cosine",
"lr_scheduler_num_cycles": "",
"lr_scheduler_power": "",
"lr_warmup": "10",
"max_data_loader_n_workers": "4",
"max_resolution": "768,768",
"max_timestep": 1000,
"max_token_length": "150",
"max_train_epochs": "",
"mem_eff_attn": true,
"mid_lr_weight": "",
"min_snr_gamma": 5,
"min_timestep": 0,
"mixed_precision": "bf16",
"model_list": "custom",
"module_dropout": 0,
"multires_noise_discount": 0,
"multires_noise_iterations": 0,
"network_alpha": 4,
"network_dim": 32,
"network_dropout": 0,
"no_token_padding": false,
"noise_offset": 0,
"noise_offset_type": "Original",
"num_cpu_threads_per_process": 4,
"optimizer": "AdamW8bit",
"optimizer_args":
"output_dir": "",
"output_name": "",
"persistent_data_loader_workers": false,
"pretrained_model_name_or_path": "",
"prior_loss_weight": 1.0,
"random_crop": false,
"rank_dropout": 0,
"reg_data_dir": "",
"resume": "",
"sample_every_n_epochs": 0,
"sample_every_n_steps": 0,
"sample_prompts": "",
"sample_sampler": "euler_a",
"save_every_n_epochs": 1,
"save_every_n_steps": 0,
"save_last_n_steps": 0,
"save_last_n_steps_state": 0,
"save_model_as": "safetensors",
"save_precision": "bf16",
"save_state": true,
"scale_v_pred_loss_like_noise_pred": true,
"scale_weight_norms": 0,
"sdxl": false,
"sdxl_cache_text_encoder_outputs": false,
"sdxl_no_half_vae": false,
"seed": "",
"shuffle_caption": true,
"stop_text_encoder_training": 0,
"text_encoder_lr": 5e-05,
"train_batch_size": 2,
"train_data_dir": "",
"train_on_input": false,
"training_comment": "",
"unet_lr": 8e-05,
"unit": 1,
"up_lr_weight": "",
"use_cp": false,
"use_wandb": false,
"v2": true,
"v_parameterization": true,
"vae_batch_size": 0,
"wandb_api_key": "",
"weighted_captions": true,
"xformers": true
}




















