Section 01LoRA의 발상
특정 요구에 맞춰 모델을 미세 조정하려면, 강력한 GPU 없이는 매우 느리다. 게다가 미세 조정된 모델은 보통 원본 파일과 같은 크기다. LLM 이웃 커뮤니티의 연구자들이 이 문제에 해법을 내놓았다 — Low-Rank Adaptation (LoRA).
Microsoft의 Edward J. Hu 등이 제안한 LoRA는, 원본 checkpoint를 수정 없이 동결하고, 조정된 가중치 변화만을 독립 파일에 저장한다. 이것이 LoRA 파일이다. CIVITAI와 Hugging Face에 수많은 커뮤니티 LoRA가 공유돼 있다.
Section 02저랭크 분해
LoRA 파일이 그토록 작은 이유는 ΔW가 두 개의 작은 행렬 A와 B로 표현될 수 있기 때문이다.
alpha를 4 같은 값으로, rank도 4로 설정한다. 실제 적용 시의 스케일 α는 α = alpha / rank로 계산된다. alpha와 rank를 모두 4로 두면 α는 1이 된다. LoRA 키 이름의 접두사 lora_te_는 텍스트 인코더에, lora_unet_은 UNet에 적용됨을 뜻한다.
Section 03Diffusers로 LoRA 사용
오픈 소스 커뮤니티 덕분에 Python으로 LoRA를 로드하는 일은 그 어느 때보다 쉽다. Diffusers는 LoRA 로딩·오프로딩을 PEFT(Parameter-Efficient Fine-Tuning) 라이브러리로 관리한다. PEFT는 모델의 모든 매개변수가 아니라 작은 부분만 미세 조정해, 소비자 하드웨어에서도 거대 모델을 다룰 수 있게 한다.
pipeline = StableDiffusionPipeline.from_pretrained(
"runwayml/stable-diffusion-v1-5",
torch_dtype = torch.float16
).to("cuda:0")
# 파이프라인에 LoRA 로드 — 모델 캐시에 없으면 자동 다운로드
pipeline.load_lora_weights(
"andrewzhu/MoXinV1",
weight_name = "MoXinV1.safetensors",
adapter_name = "MoXinV1"
)
# 두 번째 LoRA 추가 pipeline.load_lora_weights( "andrewzhu/civitai-light-shadow-lora", weight_name = "light_and_shadow.safetensors", adapter_name = "light_and_shadow") # 어댑터별 가중치 지정 pipeline.set_adapters( ["MoXinV1", "light_and_shadow"], adapter_weights = [0.5, 1.0]) # 한 줄로 모든 LoRA 비활성화 pipeline.disable_lora()
state_dict에서 A·B 행렬을 찾고 레이어 이름을 매칭해 — A1111과 같은 결과를 내는 커스텀 로더를 구현한다.
Section 04Textual Inversion
Textual Inversion(TI)은 사전 학습 모델에 기능을 더하는 또 다른 방법이다. LoRA가 어텐션 가중치를 미세 조정하는 기법이라면, TI는 가중치를 건드리지 않고 새로운 임베딩 공간을 추가하는 기법이다.
TI 모델을 학습하려면 이미지가 단 3~5개면 충분하고, 결과 파일은 보통 몇 KB짜리 pt 또는 bin이다. 새 요소·개념·스타일을 통합하면서도 뛰어난 이동성을 유지한다.
pipe = StableDiffusionPipeline.from_pretrained(
"stablediffusionapi/deliberate-v2",
torch_dtype = torch.float16).to("cuda")
# TI 를 로드하고 토큰 이름을 지정 — 자동 다운로드
pipe.load_textual_inversion(
"sd-concepts-library/midjourney-style",
token = "midjourney-style")
prompt = "a futuristic city in deep space, midjourney-style"
image = pipe(prompt, num_inference_steps=50).images[0]
token="colorful-magic-style"처럼 다른 이름으로 로드하면, 그 이름이 같은 임베딩으로 역변환되어 동일한 효과를 낸다. 토크나이저에 없는 어떤 문자열이든 플레이스홀더로 쓸 수 있다.
Section 05TI의 작동 원리
TI 학습은 간단히 말해, 대상 이미지(스타일·객체·얼굴)에 가장 잘 맞는 텍스트 임베딩을 찾는 것이다. 핵심은 현재 텍스트 인코더에 존재하지 않는 새 임베딩을 찾는 데 있다. 학습의 유일한 작업은 새 임베딩 v*를 찾고, 토큰 문자열 플레이스홀더 S*로 가리키는 것이다.