본문 바로가기

LLM

LoRA / QLoRA 완전 가이드 — LLM 파인튜닝을 저렴하게 하는 법

반응형

70B 모델을 처음부터 파인튜닝하면 H100 4~8개, 수십만 달러가 필요해요.

LoRA/QLoRA를 쓰면 RTX 4090 한 장으로, 몇 시간 안에, $10 정도 비용으로 동일한 작업이 가능해요.


왜 풀 파인튜닝 대신 LoRA인가

LLM을 풀 파인튜닝하면 수십억 개의 파라미터를 전부 업데이트해요. 메모리와 연산이 엄청나게 필요하죠.

LoRA의 핵심 아이디어는 이래요.

"모델을 업데이트할 때 변화량 자체가 저랭크(low-rank)다."

즉, 수십억 개 파라미터를 다 바꾸는 게 아니라 변화량을 표현하는 작은 행렬 2개만 학습해요.

풀 파인튜닝:
W (d×d 행렬 전체) 업데이트 → 수백만 GB

LoRA:
W' = W + BA
A: (r×d), B: (d×r) — r은 보통 8~64
→ 학습 파라미터가 0.1~1%로 줄어듦

기존 가중치 W는 고정(freeze), A와 B 어댑터만 학습해요. 추론 때는 W+BA를 합쳐서 레이턴시 오버헤드 없이 사용해요.


QLoRA — 메모리를 더 줄이는 법

LoRA만으로도 파라미터는 줄었지만, 기반 모델 자체가 FP16으로 메모리를 먹어요. 7B 모델 기준 14GB.

QLoRA는 여기에 4비트 양자화를 추가해요.

LoRA:   기반 모델 FP16 (14GB) + 어댑터 → RTX 4090 필요
QLoRA:  기반 모델 NF4 4비트 (4GB) + 어댑터 FP16 → RTX 3090으로 가능

QLoRA 3가지 핵심 기술

  1. NF4 양자화 — 신경망 가중치 분포(정규분포)에 최적화된 4비트 포맷
  2. 이중 양자화 — 양자화 상수 자체도 양자화 → 추가 메모리 절감
  3. 페이지드 옵티마이저 — 메모리 스파이크 시 CPU 메모리로 임시 오프로드

품질은 어느 정도 잃을까? LoRA 대비 1~2% 손실, 풀 파인튜닝 대비 5~10% 손실이에요. 대부분의 프로덕션 팀이 이 트레이드오프를 받아들여요.


GPU 요구사항 정리

모델 크기 LoRA QLoRA

7~8B RTX 4090 (24GB) RTX 3090 (24GB) 또는 RTX 4080 (16GB)
13B A100 40GB RTX 4090 (24GB)
70B 2~4× H100 A100 80GB 1개

핵심 하이퍼파라미터

Rank (r)

어댑터의 표현력을 결정해요. 높을수록 품질 좋지만 메모리 증가.

스타일/포맷 변경:  r=8~16
도메인 적응:      r=16~32
추론 능력 이전:   r=32~64

Alpha (α)

어댑터의 학습률 스케일링 팩터예요. 보통 α = 2×r로 시작해요.

r=16이면 α=32 (실효 학습률 = α/r = 2.0)

Target Modules

어떤 레이어에 LoRA를 붙일지 결정해요.

# 기본 (어텐션만)
target_modules=["q_proj", "v_proj"]

# 권장 (어텐션 + MLP)
target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
                "gate_proj", "up_proj", "down_proj"]

# 간단하게
target_modules="all-linear"  # 모든 선형 레이어

실전 코드 — Unsloth + SFTTrainer (2026 권장 스택)

Unsloth는 기존 HuggingFace PEFT 대비 메모리 40% 절감, 속도 2배 향상이에요. 2026년 현재 가장 많이 쓰는 QLoRA 스택이에요.

from unsloth import FastLanguageModel
from trl import SFTTrainer
from transformers import TrainingArguments

# 1. 모델 로드 (QLoRA)
model, tokenizer = FastLanguageModel.from_pretrained(
    model_name="meta-llama/Llama-3.1-8B-Instruct",
    max_seq_length=2048,
    load_in_4bit=True,  # QLoRA 활성화
)

# 2. LoRA 어댑터 추가
model = FastLanguageModel.get_peft_model(
    model,
    r=16,
    lora_alpha=32,
    target_modules="all-linear",
    lora_dropout=0.05,
    use_dora=True,  # DoRA: 품질 개선 (2026 권장)
)

# 3. 학습
trainer = SFTTrainer(
    model=model,
    tokenizer=tokenizer,
    train_dataset=dataset,
    args=TrainingArguments(
        output_dir="./output",
        per_device_train_batch_size=2,
        gradient_accumulation_steps=8,
        num_train_epochs=3,
        learning_rate=2e-4,
        lr_scheduler_type="cosine",
        bf16=True,
        logging_steps=10,
        save_strategy="epoch",
    ),
)
trainer.train()

# 4. 어댑터 저장
model.save_pretrained("my-lora-adapter")

데이터셋 형식

파인튜닝 데이터는 대화 형식으로 준비해요.

# 데이터 형식 (JSON Lines)
{"messages": [
    {"role": "user", "content": "환불 정책이 어떻게 되나요?"},
    {"role": "assistant", "content": "구매 후 30일 이내 환불 가능합니다."}
]}

# 최소 데이터량 가이드
스타일/포맷:    200~1,000개
태스크 특화:   1,000~5,000개
도메인 지식:  10,000~50,000개

어댑터 병합 후 배포

학습이 끝나면 어댑터를 기반 모델에 합쳐서 배포해요.

# 어댑터 + 기반 모델 병합
merged_model = model.merge_and_unload()
merged_model.save_pretrained("merged-model")

# GGUF로 변환 (Ollama/llama.cpp용)
model.save_pretrained_gguf("my-model-gguf", tokenizer, quantization_method="q4_k_m")

병합 후 어댑터 파일 크기는 50~200MB예요. 기반 모델(14GB)과 별도로 버전 관리 가능해요.


vLLM으로 멀티 LoRA 서빙

하나의 기반 모델 위에 여러 LoRA 어댑터를 동시에 서빙해요. 고객마다 다른 어댑터를 쓸 수 있어요.

from vllm import LLM, LoRARequest

llm = LLM(
    model="meta-llama/Llama-3.1-8B-Instruct",
    enable_lora=True,
    max_lora_rank=64
)

# 요청마다 다른 어댑터 선택
output = llm.generate(
    "고객 문의 처리해줘",
    lora_request=LoRARequest("customer_support", 1, "./adapters/cs_lora")
)

LoRA 변종들

DoRA (Direction + Rank Adaptation) 가중치를 크기(magnitude)와 방향(direction)으로 분리해서 학습해요. 2026년 현재 LoRA 대신 기본 선택으로 자리잡고 있어요. use_dora=True 한 줄만 추가하면 돼요.

LoftQ / PiSSA QLoRA에서 4비트 양자화 오류를 더 잘 보정하는 초기화 방법이에요. 양자화 품질 저하가 눈에 띌 때 시도해봐요.

LongLoRA 긴 컨텍스트(32K, 128K)로 파인튜닝할 때 사용해요. Shifted Short Attention으로 메모리 효율을 높여요.


파인튜닝 vs RAG vs 프롬프트 엔지니어링

언제 파인튜닝을 써야 하는지 명확히 해야 해요.

프롬프트 엔지니어링:
→ 빠른 실험, 지식이 자주 바뀜

RAG:
→ 최신 지식 필요, 출처 추적 중요

파인튜닝 (LoRA/QLoRA):
→ 일관된 출력 형식 필요
→ 특정 도메인 어조/스타일 학습
→ 고빈도 요청에서 토큰 비용 절감
→ 프라이버시 (데이터를 외부 API에 안 보내고 싶음)

2026년 현재 가장 좋은 전략은 RAG(사실 정보) + LoRA(행동 양식) 조합이에요.


마무리

LoRA/QLoRA를 한 줄로 요약하면 이래요.

"기반 모델은 건드리지 말고, 변화량만 작게 학습해라."

7B 모델 기준 RTX 4090 한 장에서 몇 시간 만에 파인튜닝이 가능해요. 어댑터는 50~200MB로 작아서 버전 관리도 편해요. 2026년에는 DoRA + QLoRA 조합이 가장 많이 쓰이는 스택이에요. 😄

 

반응형