LoRA(Low-Rank Adaptation) 튜닝

Soogyung Gwon·2026년 5월 30일

구름을잡아라

목록 보기
64/76

LoRA(Low-Rank Adapation) 튜닝

LoRA는 LLM이나 딥러닝 모델을 전체 재학습(full fine-tuning) 하지 않고, 아주 작은 추가 파라미터만 학습해서 모델을 튜닝하는 기법이다.

"원래 모델 가중치는 그대로 두고, 작은 변화량만 학습하자."

사용 이유

대형 모델은 수십억~ 수천억 개의 파라미터를 가지는데, 전체 Fine-tuning을 하면:

  • GPU 메모리 많이 필요
  • 학습 비용 큼
  • 저장 용량 큼
  • 모델 버전 관리 어려움
    과 같은 고충이 있을 수 있다.

때문에 기존 가중치인 W를 직접 수정하지 않고, 작은 행렬을 두 개 추가하여 사용한다.

W + BA

  • W: 원래 모델 가중치(고정)
  • A, B: 새로 학습하는 작은 행렬
  • BA: 변화량(update)

BA≈ΔW

큰 가중치 변화도 작은 저차원(low-rank) 행렬로 근사할 수 있다고 보는 것이다.

장점

  1. GPU 메모리 절약 (전체 모델 대신 일부만 학습)
  2. 학습 속도 빠름 (파라미터 수 크게 감소)
  3. 여러 튜닝 버전 관리 쉬움 (기본 모델 하나 + LoRA 파일 여러 개)
  4. 기존 성능 보존

실제 사용 예

  • 한국어 스타일 강화
  • 고객지원 챗봇
  • 코드 생성
  • 게임 NPC 대화

작은 행렬 두 개 A, B를 추가하는 이유

큰 가중치 변화 ΔW 를 훨씬 적은 파라미터로 표현하기 위해서 이다.
핵심 개념은 Low-Rank(저차원 근사) 이다.

원래 가중치 업데이트는 보통:

W′=W+ΔW

여기서 ΔW 자체를 직접 학습하면 파라미터 수가 매우 커진다.

예)

W 크기: 4096×4096 이면,

ΔW 도 같은 크기라서: 약 1,677만 개 파라미터

를 학습해야 하는 것이 된다.

그래서 LoRA는 ΔW 를 작은 두 행렬의 곱으로 압축한다.

ΔW≈BA

B: 4096×r
A: r×4096
r: 매우 작은 값 (예: 4, 8, 16)

예를 들어 r=8 이면:

학습 파라미터 수는...

4096×8 + 8×4096 = 약 6만 5천 개

왜 두 개가 필요한가?

행렬 하나만으로는 큰 2차원 변환을 충분히 표현하기 어렵기 때문.

두 행렬을 곱하면:

(4096×8)(8×4096) -> 4096×4096

처럼 다시 원래 크기의 변화를 만들어낼 수 있다.

진짜 이렇게 하면 변환을 충분히 표현할 수 있나?

딥러닝에서는 실제로 필요한 가중치 변화가 생각보다 단순한 경우가 많다.
그렇기 때문에 모든 파라미터를 독립적으로 크게 바꿀 필요는 없고, 몇 개의 핵심 방향만 조정하면 된다는 개념 아래 LoRA는 이 핵심 변화 방향만 학습하는 것이다.

작은 행렬 A, B를 정하는 방법

LoRA의 작은 행렬 A, B는 사람이 직접 정하는 값이 아니라, 일반 신경망 가중치 처럼 학습(training) 으로 결정된다.

초기 값으로 랜덤하게 시작하고, 데이터 학습을 통해, loss를 줄이는 방향으로 업데이트 된다.

Step 1. 초기화

보통 시작은:

  • A: 작은 랜덤값
  • B: 0 또는 작은 랜덤값

초기에는 BA≈0 이기 때문에 원래 모델(W + 0)과 거의 동일하게 동작한다.
(이렇게 함으로써 pretrained 모델 성능을 망가뜨리지 않고 진행한다.)

Step 2. Forward
입력 값을 모델에 넣어 계산한다.

y = (W + BA)x

Step3. Loss 계산
정답과 비교한다.

Step4. Backpropagatoin
Gradient는 W는 적용되지 않고 A,B에만 적용 된다.
즉 A,B는 업데이트 되고 W는 그대로 유지한다.

사람이 정하는 값 r과 α

rank r

r이 작으면

  • 메모리 적게 사용
  • 빠름
  • 표현력 제한

r이 크면

  • 더 많은 변화 가능
  • 성능 향상 가능
  • 메모리 증가

보통 많이 쓰는 값은 4~64 정도

α

알파는 LoRA가 만들어내는 변화량의 크기를 조절하는 하이퍼파라미터이다.

W=W+αrBA{W' = W + \frac{\alpha}{r}BA}

W: 원래 가중치
A,B: LoRA 학습 행렬
r: LoRA rank
α: LoRA scaling factor

LoRA는 rank r이 작은 저차원 구조이나 이 rank의 값에 따라 출력 크기가 작아지기도 커지기도 하기 때문에 업데이트 크기가 들쭉날쭉해 질 수 있다.

그렇기 때문에 rank가 바뀌어도 업데이트 크기를 비슷하기 유지하기 위해서 αr{\frac{\alpha}{r}} 를 넣는 것이다.

그래서 1r{\frac{1}{r}} 을 해서 normalization 비슷하게 해줄 수 있지만 여기에 알파를 더해서

“LoRA 영향력을 어느 정도로 할지”

를 사람이 조절하도록 만든 값이 α 이다.

α 크면:
LoRA 영향 강함
α 작으면:
원래 모델 유지

effective scale= αr{\frac{\alpha}{r}}

rαα/r
8162
16161
64160.25

표에서 보면 rank가 커질수록 자동으로 scaling이 줄어드는 것을 알 수 있다.

Code

LoraConfig(
    r=16,
    lora_alpha=32
)

위에서 실제 scale은 32 / 16 = 2 가 된다.

αr{\frac{\alpha}{r}} 은 경험적 설계

αr{\frac{\alpha}{r}} 은 수학적 필수 공식이라기 보다는 학습 안정성과 rank-independent scaling을 위한 경험적인 설계에 가깝다.

LoRA의 task type

목적TaskType
챗봇, LLM 생성CAUSAL_LM
번역, 요약(T5 계열)SEQ_2_SEQ_LM
감정 분석SEQ_CLS
NERTOKEN_CLS
Extractive QAQUESTION_ANS
임베딩 모델 튜닝FEATURE_EXTRACTION
profile
오랜시간 망설였던 코딩을 다시 해보려고 노력하고 있는 사람

0개의 댓글