LoRA와 QLoRA, 전체를 다시 학습하지 않고 모델을 길들이는 법
요약
- PEFT는 모델의 수십억 개 가중치를 전부 갱신하는 대신 소수 파라미터만 학습해 파인튜닝 비용을 낮추는 방법의 총칭이고, 그 대표가 LoRA입니다.
- LoRA는 파인튜닝으로 생기는 가중치 변화량을 두 작은 행렬의 곱으로 근사하고, 원래 가중치는 동결합니다. 학습하는 건 작은 행렬 두 개뿐입니다.
- 효과가 큽니다. LoRA 논문은 GPT-3 175B 기준 학습 파라미터가 약 10,000배, GPU 메모리가 약 3배 줄었다고 보고합니다. 산출물인 어댑터가 수 MB라 태스크별로 저장하고 교체하기 쉽습니다.
- QLoRA는 동결된 베이스를 4비트로 양자화한 위에 LoRA를 얹습니다. 논문은 65B 모델을 단일 48GB GPU에서 파인튜닝하면서 16비트 성능을 보존했다고 보고합니다.
- 주의할 점. 성능은 태스크에 따라 전체 파인튜닝에 근접하지만, 대규모 도메인 적응에는 전체 파인튜닝이 유리할 수 있습니다.
왜 전체를 다시 학습하지 않나
전체 파인튜닝은 두 가지 비용이 큽니다.
메모리가 문제입니다. 모든 가중치의 옵티마이저 상태까지 GPU에 올려야 합니다. 학습 시 필요한 메모리는 모델 크기의 수 배에 이릅니다.
저장도 문제입니다. 태스크마다 모델 전체를 통째로 복제해야 합니다. 태스크가 10개면 큰 모델이 10벌입니다.
PEFT는 사전학습 가중치는 대부분 동결하고 소수 파라미터만 학습해, 전체 파인튜닝에 준하는 성능을 훨씬 낮은 비용으로 얻으려는 접근입니다. HuggingFace의 peft 라이브러리가 널리 쓰이는 구현입니다.
LoRA는 그 대표 방식입니다. 파인튜닝으로 생기는 가중치 변화량을 원래대로 다 학습하지 않고, 두 작은 행렬의 곱으로 근사합니다. 원 가중치는 얼려두고 이 작은 부분만 학습합니다.
오해 세 가지를 짚어둡니다.
"LoRA는 성능을 포기하는 저가형이다" 는 정확하지 않습니다. 여러 태스크에서 전체 파인튜닝에 근접하고, 데이터가 적을 때는 오히려 유리한 경우도 보고됩니다. 다만 대규모 도메인 적응처럼 큰 변화가 필요하면 전체 파인튜닝이 나을 수 있습니다.
"LoRA는 원 모델을 바꾼다" 도 틀립니다. 원 가중치는 그대로 얼려두고 옆에 붙는 부분만 학습합니다.
"QLoRA는 LoRA를 4비트로 학습하는 것" 도 틀립니다. 학습되는 어댑터는 보통 bf16이나 fp16 고정밀도입니다. 4비트인 건 동결된 베이스이고, 그 위로 그래디언트가 흘러 고정밀 어댑터를 학습합니다.
원본 그림 위에 덧대는 얇은 필름
수식이 낯설면 이렇게 떠올리면 됩니다.
큰 원본 그림은 손대지 않고, 그 위에 얇고 값싼 투명 필름만 그려 넣어 원하는 태스크로 바꿉니다.
필름은 작아서 여러 장 만들어 두었다가 갈아 끼울 수 있습니다. 번역용 필름, 요약용 필름, 도구호출용 필름을 한 원본 위에서 바꿔 낍니다.
원하면 원본에 합쳐 인쇄할 수도 있습니다. 그러면 한 장의 완성 그림이 되어 추론할 때 필름을 겹치는 추가 수고가 사라집니다.
"작은 필름만 그린다"가 곧 학습과 저장 비용이 작다는 뜻이고, "필름을 갈아 낀다"가 곧 다중 태스크 어댑터 스왑입니다.
어떻게 동작하나
원래 선형층의 가중치를 W0라 하면, 파인튜닝은 W0에서 W0 + ΔW로 가는 걸 배우는 것입니다. LoRA는 이 ΔW를 저랭크 곱으로 대체합니다.
h = W0 x + ΔW x
= W0 x + (α/r) BA x
W0 동결 (d × k)
B 학습 (d × r)
A 학습 (r × k)
r 랭크, r << min(d, k)구조를 그리면 이렇습니다.
입력 x
│
┌────┴────┐
│ │
▼ ▼
W0 A (r×k) 학습
동결 │
│ ▼
│ B (d×r) 학습
│ │
│ ▼
│ × α/r
│ │
└────►(+)◄┘
│
▼
출력 h학습 파라미터 수가 d × k에서 r × (d+k)로 급감합니다. d = k = 4096, r = 8이면 약 1,680만 개에서 약 6.6만 개, 그러니까 0.4퍼센트가 됩니다.
몇 가지 세부 설계가 있습니다.
alpha와 스케일링. ΔW에 α/r 배율을 곱해 어댑터 기여도를 조절합니다. 랭크를 바꿔도 스케일이 안정되도록 하는 장치입니다.
초기화. A는 랜덤으로, B는 0으로 시작합니다. 그래서 학습 초기에 ΔW가 0이 되어 원 모델과 동일한 출력에서 안정적으로 출발합니다.
적용 대상. 보통 어텐션의 q_proj와 v_proj에 붙이고, 필요하면 모든 선형층으로 확장합니다. 원 논문은 어텐션 가중치에만 적용해도 충분함을 보였습니다.
배포는 두 갈래입니다
병합은 W0 + (α/r) BA로 합쳐서 저장합니다. 추론할 때 원 모델과 똑같은 단일 가중치가 되므로 추가 지연이 0입니다.
어댑터 유지는 베이스는 공유하고 태스크별 어댑터만 런타임에 붙였다 뗍니다. 한 베이스로 다중 태스크 스왑 서빙이 가능합니다.
여기가 실무에서 선택이 갈리는 지점입니다. 태스크가 하나면 병합이 단순하고, 여러 개를 한 서버에서 굴려야 하면 스왑이 유리합니다.
QLoRA는 무엇을 더했나
QLoRA는 LoRA 위에 세 가지 장치를 더해 대형 모델을 단일 GPU에서 파인튜닝할 수 있게 합니다.
4비트 NF4 베이스. 동결 베이스를 NF4로 양자화합니다. 정규분포를 따르는 가중치에 정보이론적으로 맞춘 4비트 데이터 타입입니다.
이중 양자화. 양자화에 쓰는 상수까지 한 번 더 양자화해 메모리를 추가로 아낍니다.
paged optimizer. 메모리가 급증하는 구간을 CPU RAM으로 페이징해 OOM을 방지합니다.
동작은 이렇습니다. 순전파 때 4비트 베이스를 계산용 정밀도로 되돌려 쓰고, 그래디언트는 그 위의 고정밀 LoRA 어댑터로만 흐릅니다. 무거운 베이스는 압축된 채 읽기 전용으로 두고, 실제 학습은 가벼운 어댑터에서만 일어납니다.
PEFT 계열 비교
| 방식 | 무엇을 학습하나 | 학습 파라미터 | 추론 추가지연 | 특징 |
|---|---|---|---|---|
| LoRA | 각 선형층에 저랭크 BA |
매우 작음 | 0 (병합 시) | 병합 가능, 어댑터 스왑 |
| QLoRA | LoRA와 같은 어댑터 + 4비트 동결 베이스 | LoRA와 비슷 | 소 (양자화 오버헤드) | 메모리 최소 |
| Adapter | 층 사이에 삽입한 작은 병목 MLP | 작음 | 있음 | 원조 PEFT. 병합 불가 |
| Prefix-tuning | 각 층 어텐션 앞의 연속 prefix 벡터 | 매우 작음 | 소 | 가중치 미변경 |
| Prompt-tuning | 입력 임베딩 앞의 소프트 프롬프트 | 극소 | 소 | 모델이 클수록 전체 FT에 근접 |
| DoRA | 가중치를 크기와 방향으로 분해 후 방향에 LoRA | LoRA와 비슷 | 0 | LoRA와 전체 FT의 간극 축소를 주장 |
핵심 축은 셋입니다.
어디에 붙나. 가중치 옆(LoRA, Adapter)인가, 입력이나 어텐션 앞(prefix, prompt)인가.
병합으로 지연을 없앨 수 있나. LoRA와 DoRA는 가능하고, Adapter는 추가 층이라 불가능하며, prefix와 prompt는 입력 확장이라 병합 개념이 아닙니다.
메모리. QLoRA가 가장 작습니다.
전체 파인튜닝과 비교
| 관점 | 전체 파인튜닝 | LoRA |
|---|---|---|
| 학습 파라미터 | 100퍼센트 | 대개 1퍼센트 미만 |
| GPU 메모리 | 큼. 옵티마이저 상태 포함 모델의 수 배 | 작음. 어댑터에만 옵티마이저 |
| 저장 (태스크 N개) | 모델 전체 × N | 베이스 1개 + 어댑터 수 MB × N |
| 추론 지연 | 기준 | 병합 시 동일 |
알아둘 제약
QLoRA에는 배포할 때 걸리는 제약이 하나 있습니다. QLoRA 어댑터는 4비트 베이스에 그대로 병합할 수 없습니다. 병합하려면 베이스를 고정밀로 되돌린 뒤 합치고 다시 양자화해야 하는데, 이 과정에서 오차가 들어갑니다.
그래서 QLoRA로 학습했다면 어댑터를 유지한 채 서빙하거나, 병합 시 품질 변화를 따로 확인하는 게 안전합니다.
마치며
핵심 세 가지로 정리합니다.
- LoRA는 가중치 변화량을 저랭크 곱으로 근사하고 원 가중치는 동결합니다. 학습 파라미터가 1퍼센트 미만으로 줄고, 어댑터가 수 MB라 교체가 쉽습니다.
- QLoRA는 동결 베이스를 4비트로 양자화해 메모리를 한 번 더 줄입니다. 학습되는 어댑터 자체는 고정밀입니다.
- 배포는 병합과 어댑터 유지 두 갈래이고, 태스크가 여럿이면 스왑이, 하나면 병합이 단순합니다.
용어 정리
| 용어 | 한 줄 뜻 |
|---|---|
| PEFT | 소수 파라미터만 학습하는 파인튜닝 방법의 총칭 |
| LoRA | 가중치 변화량을 저랭크 행렬 곱으로 근사하는 PEFT |
| QLoRA | 4비트로 양자화한 동결 베이스 위에 LoRA를 얹은 방식 |
| 랭크 r | 저랭크 근사의 차원. 작을수록 파라미터가 적음 |
| alpha | 어댑터 기여도를 조절하는 스케일 계수 |
| 어댑터 | 학습된 저랭크 행렬 묶음. 수 MB 크기 |
| 병합 (merge) | 어댑터를 원 가중치에 합쳐 단일 모델로 만드는 것 |
| NF4 | 정규분포 가중치에 맞춘 4비트 자료형 |
| 이중 양자화 | 양자화 상수까지 한 번 더 양자화하는 기법 |
| DoRA | 가중치를 크기와 방향으로 분해한 뒤 방향에 LoRA를 적용하는 방식 |
참고자료
- Hu et al., "LoRA: Low-Rank Adaptation of Large Language Models" (ICLR 2022, arXiv:2106.09685)
- Dettmers et al., "QLoRA: Efficient Finetuning of Quantized LLMs" (NeurIPS 2023, arXiv:2305.14314)
- Liu et al., "DoRA: Weight-Decomposed Low-Rank Adaptation" (ICML 2024, arXiv:2402.09353)
- Houlsby et al., "Parameter-Efficient Transfer Learning for NLP" (ICML 2019, arXiv:1902.00751)
- Li & Liang, "Prefix-Tuning: Optimizing Continuous Prompts for Generation" (ACL 2021, arXiv:2101.00190)
- Hugging Face PEFT 공식 문서
댓글