LLM WikiAccess-protected knowledge portal
← 스터디 홈
161편 · 약 16분

LLM 파인튜닝 실전: LoRA·QLoRA·DoRA로 소비자 GPU에서 전문화 모델 만들기

요약

대형 언어 모델(LLM)을 특정 도메인에 맞게 조정하려면 파인튜닝이 필요하다. 그런데 70억 파라미터 모델을 전체 가중치로 학습하면 A100 80GB 8장도 부족하다. 파라미터 효율적 파인튜닝(PEFT)은 가중치의 일부만 업데이트해 소비자 GPU 한 장(16~24 GB)으로도 프로덕션 수준의 전문화 모델을 만들 수 있게 한다.

기법메모리성능특징
Full Fine-tuning극히 많음최상기준선
LoRA↓ 70% 이상Full과 근접가장 널리 쓰임
QLoRA↓ 90% 이상LoRA에 근접소비자 GPU 가능
DoRALoRA와 유사LoRA보다 우수수렴 빠름
GaLoreFull과 유사Full에 근접전체 파라미터 업데이트, 저랭크 그래디언트

2026년 기준 권장 시작점은 DoRA r=16, alpha=16, all-linear 대상이다. Unsloth와 HuggingFace PEFT가 이 스택을 지원한다.


왜 전체 파인튜닝이 어려운가

LLM 파인튜닝에서 메모리를 잡아먹는 것은 가중치(weight)만이 아니다.

  • 가중치(weight): 7B 모델 BF16 ≈ 14 GB
  • 그래디언트(gradient): 가중치와 동일 크기 ≈ 14 GB
  • 옵티마이저 상태(Adam): 가중치의 2배 ≈ 28 GB (1차·2차 모멘텀)
  • 활성화값(activation): 배치 크기·시퀀스 길이에 비례

합산하면 7B 모델 하나를 Adam으로 학습하는 데 약 56–80 GB가 필요하다. A100 80GB 한 장도 빠듯하다.

PEFT는 이 중 옵티마이저 상태와 그래디언트 저장 대상을 극적으로 줄인다. 학습 가능한 파라미터 수를 전체의 0.1~1%로 제한하면, 그 파라미터에 대한 옵티마이저 상태만 유지하면 된다.


LoRA: 저랭크 분해로 학습 가능 파라미터 줄이기

핵심 아이디어

LoRA(Low-Rank Adaptation, 2021)는 가중치 행렬 W ∈ ℝ^(d×k)를 직접 업데이트하지 않고, 변화량 ΔW를 두 개의 작은 행렬의 곱으로 분해한다.

W' = W + ΔW = W + B·A
  • A ∈ ℝ^(r×k): 랜덤 초기화
  • B ∈ ℝ^(d×r): 0으로 초기화
  • r (rank): 하이퍼파라미터, 보통 4~64

초기에는 B가 0이므로 ΔW = 0이다. 학습이 진행되면서 A와 B만 업데이트되고, W는 동결(frozen)된다.

학습 파라미터 수 비교: d=4096, k=4096인 attention 행렬의 경우

  • Full: 4096 × 4096 = 16,777,216
  • LoRA r=16: (4096+4096) × 16 = 131,072 → 0.78%

스케일링 팩터 alpha

실제로는 ΔW = (alpha/r) · B·A를 사용한다. alpha는 학습률과 유사한 역할로, 기본값은 rank와 같게(alpha=r) 설정하는 것이 2026년 권장 관행이다. 과거 alpha=2r 관행은 Unsloth의 ablation 실험에서 이점이 없는 것으로 확인됐다.

target_modules 선택

어떤 레이어에 LoRA를 붙일지가 성능에 영향을 준다.

대상파라미터 비율효과
q_proj, v_proj만낮음빠르지만 성능 제한
q, k, v, o_proj중간균형
all-linear높음2026년 권장, 0.5~1% 파라미터
LoRA: 저랭크 행렬 분해와 추론 경로 W (동결) d × k 예: 4096 × 4096 = 16.7M 파라미터 학습 없음, 기울기 없음 옵티마이저 상태 불필요 A (학습) r × k 16 × 4096 = 65,536 B (학습) d × r 4096 × 16 = 65,536 ΔW = B·A d × k 총 131,072 파라미터 = 0.78% of W 출력: W·x + (α/r)·B·A·x 동결 경로 + 저랭크 경로의 합산 추론 시 W += B·A 병합 → 추가 레이턴시 없음 입력 x 파라미터 비교 (7B) Full FT: 7,000M LoRA r=16: ~54M LoRA r=4: ~14M 옵티마이저 상태도 비례하여 감소
LoRA 저랭크 분해 원리

QLoRA: 4비트 양자화로 메모리 90% 줄이기

QLoRA(Quantized LoRA, Dettmers et al. 2023)는 세 가지 혁신을 결합한다.

1. NormalFloat4 (NF4) 양자화

일반 INT4는 균일 분포를 가정하지만, 신경망 가중치는 정규 분포(Normal Distribution)에 가깝다. NF4는 정규 분포의 확률 밀도에 맞춰 16개 값(4비트)의 경계를 불균일하게 배치한다.

BF16 가중치 (16비트) → NF4 가중치 (4비트): 4× 메모리 절감

분위수(quantile) 기반 할당: 각 구간이 정규 분포에서 같은 확률 질량을 갖도록 설계. 중앙 밀집 구간에 더 많은 레벨을 할당해 정보 손실을 최소화한다.

2. 이중 양자화 (Double Quantization)

일반 양자화에서 각 블록의 스케일 팩터(FP32)를 저장하는 비용도 무시할 수 없다. QLoRA는 이 스케일 팩터 자체도 양자화해 추가로 약 0.37 bits/parameter를 절약한다.

3. 페이지드 옵티마이저 (Paged Optimizer)

CUDA 통합 메모리(Unified Memory)를 활용해, GPU 메모리가 부족하면 옵티마이저 상태를 CPU RAM으로 페이징한다. 배치 처리 중 스파이크 발생 시 OOM(Out-of-Memory) 오류를 방지한다.

QLoRA 메모리 요약

단계BF16 Full FTQLoRA
기반 모델 저장14 GB3.5 GB (NF4)
그래디언트14 GB0 (동결, 없음)
옵티마이저 상태28 GB~0.5 GB (LoRA 파라미터만)
합계 (7B)~56 GB~5–6 GB

RTX 4070 Ti (12 GB) 한 장으로 7B 모델 파인튜닝이 가능해진다.


DoRA: 크기와 방향을 분리한 가중치 분해

DoRA(Weight-Decomposed Low-Rank Adaptation, Liu et al. 2024)는 LoRA의 학습 동역학이 Full Fine-tuning과 다르다는 관찰에서 출발한다.

핵심 관찰

가중치 행렬을 크기(magnitude)방향(direction)으로 분해한다.

W = m · (V / ‖V‖_c)
  • m ∈ ℝ^(1×k): 각 열의 크기 벡터 (학습 가능한 벡터)
  • V / ‖V‖_c: 열 단위 정규화된 방향 행렬

DoRA는 방향 성분에만 LoRA를 적용하고, 크기 성분은 독립적으로 학습한다.

W' = m · (W + B·A) / ‖W + B·A‖_c

왜 더 좋은가

Full Fine-tuning은 크기와 방향을 동시에 조정한다. LoRA는 둘을 연동해 조정하지만, DoRA는 독립적으로 제어한다. 이 분리 덕분에:

  • Full Fine-tuning의 학습 패턴에 더 가깝다
  • 같은 rank에서 LoRA보다 수렴이 빠르고 성능이 높다
  • 낮은 rank(r=4)에서도 품질 유지 가능

DoRA vs LoRA 실험 결과

벤치마크LoRA r=16DoRA r=16
MT-Bench6.77.1
MMLU61.4%63.2%
HumanEval37.8%41.5%

출처: DoRA 원 논문, LLaMA 2 7B 기반 측정


GaLore: 그래디언트 저랭크 투영

GaLore(Gradient Low-Rank Projection, Zhao et al. 2024)는 LoRA와 달리 전체 가중치 행렬을 업데이트하되, 그래디언트를 저랭크 부분 공간에 투영해 메모리를 절약한다.

G_projected = P^T · G · Q
  • G: 원래 그래디언트 행렬
  • P, Q: SVD로 구한 저랭크 투영 행렬 (주기적으로 갱신)

차이점: LoRA는 파라미터를 고정하고 어댑터만 학습하지만, GaLore는 모든 파라미터를 학습한다. 이론적으로는 Full FT에 더 가까운 품질을 낼 수 있다. 실제로는 투영 행렬 갱신 비용이 있어 속도가 느릴 수 있다.


실전 설정 가이드

2026년 권장 시작 설정 (Unsloth + HuggingFace PEFT)

from peft import LoraConfig, get_peft_model

config = LoraConfig(
    r=16,                        # rank — 보통 8~64 시작
    lora_alpha=16,               # alpha = r 권장 (2026 관행)
    target_modules="all-linear", # 모든 선형 레이어 대상
    use_dora=True,               # DoRA 활성화 (기본 LoRA보다 권장)
    lora_dropout=0.05,
    bias="none",
)

Unsloth FastLanguageModel 사용 시 2배 빠른 학습과 70% 추가 메모리 절감 가능:

from unsloth import FastLanguageModel

model, tokenizer = FastLanguageModel.from_pretrained(
    model_name="meta-llama/Llama-3.1-8B",
    max_seq_length=4096,
    load_in_4bit=True,   # QLoRA
    dtype=None,
)
model = FastLanguageModel.get_peft_model(
    model,
    r=16,
    target_modules=["q_proj","k_proj","v_proj","o_proj",
                    "gate_proj","up_proj","down_proj"],
    use_dora=True,
)

하이퍼파라미터 선택 기준

설정작은 값큰 값권장
rank (r)메모리 작음, 표현력 제한메모리 많음, 표현력 풍부8~32 시작
alpha낮은 LoRA 기여높은 LoRA 기여r과 같게 설정
dropout정규화 없음과적합 방지0.0~0.1
learning_rate느린 수렴불안정1e-4 ~ 3e-4

데이터 수량과 품질

500개의 고품질 예제 > 5,000개의 노이즈 섞인 예제. 파인튜닝 전 데이터 정제에 더 많은 시간을 투자하는 것이 일반적으로 효과적이다.

학습 후 어댑터 병합

추론 시 레이턴시 추가 없이 배포하려면 어댑터를 기반 모델에 병합한다.

model = model.merge_and_unload()   # LoRA 가중치를 W에 흡수
model.save_pretrained("merged-model")

기법 선택 트리

GPU 메모리 확인
GPU 8–16 GB (소비자 GPU)
QLoRA
NF4 4비트 기반 모델
DoRA 추가
use_dora=True
GPU 24–48 GB (A10G, RTX 3090/4090)
BF16 LoRA
빠른 속도
DoRA r=16
권장 시작점
GPU 80 GB+ (A100, H100)
Full FT
최고 품질
또는 GaLore
파라미터 효율
파인튜닝 기법 선택 기준

운영 체크리스트

학습 전

  • [ ] 데이터셋 크기 확인: 최소 100~500개 고품질 예제
  • [ ] 베이스 모델 라이선스 확인: Llama-3.1의 경우 Meta 약관 준수 필요
  • [ ] 평가 셋 분리: 학습 전 10~20% holdout 확보

학습 중

  • [ ] 첫 100 스텝 후 loss 트렌드 확인: 감소 없으면 lr 조정
  • [ ] 그래디언트 norm 모니터링: 1.0 초과 지속 시 gradient clipping 검토
  • [ ] eval_loss 기준 checkpoint 저장 (학습 loss가 아니라 eval loss 기준)

학습 후

  • [ ] 기준 모델 대비 벤치마크 비교 (MMLU, MT-Bench 등)
  • [ ] 원치 않는 행동 변화 테스트 (catastrophic forgetting 확인)
  • [ ] 어댑터 병합 후 추론 속도 측정

References

  • https://arxiv.org/abs/2106.09685 (LoRA: Low-Rank Adaptation of Large Language Models, Hu et al. 2021)
  • https://arxiv.org/abs/2305.14314 (QLoRA: Efficient Finetuning of Quantized LLMs, Dettmers et al. 2023)
  • https://arxiv.org/abs/2402.09353 (DoRA: Weight-Decomposed Low-Rank Adaptation, Liu et al. 2024)
  • https://arxiv.org/abs/2403.03507 (GaLore: Memory-Efficient LLM Training by Gradient Low-Rank Projection, Zhao et al. 2024)
  • https://huggingface.co/docs/peft/index (HuggingFace PEFT Documentation)
  • https://github.com/unslothai/unsloth (Unsloth: 2x faster LLM fine-tuning)
  • https://letsdatascience.com/blog/fine-tuning-llms-with-lora-and-qlora-complete-guide
  • https://pub.towardsai.net/fine-tuning-llms-in-2026-lora-qlora-unsloth-and-everything-in-between-929eaf94aea2