- Published on
LoRA: 대규모 언어 모델의 효율적 파인튜닝 논문 분석
- Authors
- Name
- 1. 들어가며
- 2. Full Fine-tuning의 문제점
- 3. LoRA 핵심 아이디어: 가중치 변화량의 Low-Rank 분해
- 4. 수학적 배경: Intrinsic Dimensionality
- 5. Rank 선택 전략 및 적용 레이어
- 6. QLoRA: 4-bit 양자화 + LoRA
- 7. HuggingFace PEFT 라이브러리 실습
- 8. LoRA vs Full Fine-tuning 성능 비교
- 9. 실무 팁: Learning Rate, Rank, Alpha 조정
- 10. LoRA 생태계와 변형 기법
- 11. 마치며
- References
1. 들어가며
GPT-3(175B), LLaMA(65B), Falcon(180B) 등 대규모 언어 모델(LLM)이 다양한 NLP 태스크에서 놀라운 성능을 보여주고 있다. 하지만 이러한 모델을 특정 도메인이나 태스크에 맞게 적응시키는 Fine-tuning 과정은 여전히 막대한 컴퓨팅 자원을 요구한다. 2021년 Microsoft Research에서 발표한 LoRA(Low-Rank Adaptation of Large Language Models) 논문은 이 문제에 대한 우아한 해법을 제시했고, 현재 LLM Fine-tuning의 사실상 표준(de facto standard)으로 자리 잡았다.
이 글에서는 LoRA 논문(Hu et al., 2021)의 핵심 원리를 수학적으로 분석하고, 후속 연구인 QLoRA, 그리고 HuggingFace PEFT 라이브러리를 활용한 실전 적용법까지 체계적으로 정리한다.
2. Full Fine-tuning의 문제점
2.1 파라미터 수와 GPU 메모리
Full Fine-tuning은 사전 학습된 모델의 모든 파라미터를 업데이트한다. GPT-3 175B 모델을 기준으로 살펴보면 그 비용이 명확해진다.
| 항목 | Full Fine-tuning | LoRA (r=4) |
|---|---|---|
| 학습 가능 파라미터 수 | 175B (100%) | 4.7M (~0.003%) |
| GPU VRAM 요구량 | ~1.2TB | ~350GB |
| Checkpoint 크기 | ~350GB | ~35MB |
Full Fine-tuning에서 Adam optimizer를 사용할 경우, 각 파라미터에 대해 momentum과 variance 두 가지 상태값을 추가로 저장해야 한다. 따라서 16-bit 정밀도 기준으로도 모델 가중치(2 bytes) + gradient(2 bytes) + optimizer states(8 bytes) = 파라미터당 약 12 bytes가 필요하다. 175B 모델이라면 약 2.1TB의 메모리가 필요한 셈이다.
2.2 저장 및 배포 비용
Full Fine-tuning을 수행하면 태스크마다 전체 모델의 복사본을 저장해야 한다. 10개의 다른 태스크에 GPT-3를 Fine-tuning한다면 350GB x 10 = 3.5TB의 저장 공간이 필요하다. 반면 LoRA는 태스크별로 약 35MB의 adapter 가중치만 저장하면 되므로, 같은 시나리오에서 350MB로 충분하다. 이는 약 10,000배의 저장 공간 절약에 해당한다.
2.3 Inference Latency 문제
기존의 Adapter 기반 방법들(Houlsby et al., 2019)은 모델 구조에 추가적인 레이어를 삽입하기 때문에, 추론(inference) 시 latency가 증가하는 문제가 있었다. 특히 batch size가 작은 온라인 서빙 환경에서는 이 overhead가 무시할 수 없는 수준이 된다. LoRA는 이 문제를 근본적으로 해결한다.
3. LoRA 핵심 아이디어: 가중치 변화량의 Low-Rank 분해
3.1 핵심 가정
LoRA의 핵심 가정은 다음과 같다:
사전 학습된 모델의 가중치를 특정 태스크에 적응시킬 때, 가중치의 변화량(delta W)은 낮은 내재적 차원(low intrinsic rank)을 가진다.
이 가정은 Aghajanyan et al.(2020)의 연구에서 영감을 받은 것으로, 사전 학습된 모델이 이미 충분히 좋은 표현을 학습하고 있기 때문에, 태스크 적응에 필요한 변화량이 전체 파라미터 공간의 극히 일부분에만 집중된다는 직관에 기반한다.
3.2 수학적 공식화
사전 학습된 가중치 행렬을 라 하자. Full Fine-tuning에서는 이를 로 업데이트하며, 는 전체 파라미터 공간과 동일한 차원을 갖는다.
LoRA는 이 를 두 개의 저랭크(low-rank) 행렬의 곱으로 분해한다:
여기서:
- (down-projection)
- (up-projection)
- (rank, 보통 1~64)
따라서 Forward pass는 다음과 같이 수정된다:
학습 가능한 파라미터 수는 에서 로 대폭 줄어든다. 예를 들어, (GPT-3의 hidden dimension)이고 이면:
- Full Fine-tuning: 파라미터
- LoRA: 파라미터 (약 768배 감소)
3.3 초기화 전략
LoRA의 초기화는 학습 시작 시점에서 이 되도록 설계되어 있다:
- 행렬 A: Random Gaussian 초기화
- 행렬 B: Zero 초기화
이렇게 하면 학습 시작 시 이므로, LoRA adapter가 추가되더라도 원래 사전 학습된 모델과 동일한 출력을 생성한다. 이는 학습의 안정성을 보장하는 중요한 설계 결정이다.
3.4 Scaling Factor: alpha/r
실제 Forward pass에서 LoRA의 출력에는 scaling factor 이 곱해진다:
여기서 는 상수(hyperparameter)이다. 원 논문에서는 를 처음 시도한 값으로 설정하고 이후 변경하지 않았다고 언급한다. 이 scaling factor의 역할은 rank 을 변경할 때 learning rate를 재조정할 필요를 줄여주는 것이다.
최근에는 **Rank-Stabilized LoRA(rsLoRA)**가 제안되어, scaling factor를 로 설정함으로써 높은 rank에서의 학습 안정성을 개선하였다. HuggingFace PEFT에서는 use_rslora=True 옵션으로 이를 활성화할 수 있다.
3.5 Inference 시 병합 (Merge)
LoRA의 가장 큰 장점 중 하나는 추론 시 추가적인 latency가 없다는 것이다. 학습이 완료되면 adapter 가중치를 원래 모델에 병합할 수 있다:
병합 후에는 원래 모델과 동일한 구조이므로, 추론 속도가 전혀 저하되지 않는다. 반면, 다른 태스크에 대한 adapter로 전환하고 싶다면 를 빼고 다른 를 더하면 된다. 이러한 유연성 덕분에 하나의 base model에 여러 태스크별 adapter를 효율적으로 관리할 수 있다.
4. 수학적 배경: Intrinsic Dimensionality
4.1 Intrinsic Dimensionality란?
Aghajanyan et al.(2020)은 "Intrinsic Dimensionality Explains the Effectiveness of Language Model Fine-Tuning" 논문에서, 사전 학습된 언어 모델의 Fine-tuning 과정이 놀랍도록 낮은 내재적 차원(intrinsic dimension)을 가진다는 것을 실험적으로 보였다.
핵심 아이디어는 다음과 같다. 전체 파라미터 공간 (D는 전체 파라미터 수)에서의 최적화 문제를 훨씬 작은 부분 공간 () 에서의 최적화 문제로 재매개변수화(reparameterize)해도, Full Fine-tuning과 유사한 성능을 달성할 수 있다는 것이다.
4.2 LoRA와의 연결
LoRA는 이 관찰을 직접적으로 활용한다. 가중치 업데이트 가 낮은 intrinsic rank를 가진다면, 이를 저랭크 행렬 곱 로 근사하는 것이 합리적이다.
실제로 LoRA 논문의 실험 결과는 이 가설을 강력히 뒷받침한다. GPT-3 175B 모델에서 , 에 LoRA를 적용했을 때, rank r=1만으로도 상당히 경쟁력 있는 성능을 달성했다:
| Rank (r) | WikiSQL Acc. | MultiNLI Acc. |
|---|---|---|
| 1 | 73.4% | 91.3% |
| 2 | 73.3% | 91.4% |
| 4 | 73.7% | 91.3% |
| 8 | 73.8% | 91.6% |
| 64 | 73.5% | 91.4% |
과 의 성능 차이가 거의 없다는 점은, 가중치 변화량의 intrinsic rank가 매우 낮다는 가설을 실험적으로 입증한다. 이는 "더 큰 rank가 항상 더 좋은 것은 아니다"라는 실용적 시사점을 준다.
5. Rank 선택 전략 및 적용 레이어
5.1 어떤 레이어에 LoRA를 적용할 것인가?
Transformer의 Self-Attention 블록에는 4개의 가중치 행렬이 있다: (Query), (Key), (Value), (Output projection). LoRA 논문에서는 GPT-3 175B 모델에 동일한 파라미터 예산(18M) 하에서 다양한 조합을 실험했다.
결과적으로 와 를 동시에 적용하는 것이 최적의 성능을 보였다. 단일 행렬에만 적용하면(예: 만 또는 만) 성능이 떨어졌고, 모든 행렬에 적용하면 각 행렬당 할당되는 rank가 줄어들어 오히려 성능이 저하되었다.
그러나 이후의 연구와 실무 경험에서는 모든 Linear 레이어에 LoRA를 적용하는 것이 더 좋은 결과를 낳는 경우가 많다는 것이 밝혀졌다. Sebastian Raschka의 실험에 따르면, LLaMA-2 7B 모델에서 Attention의 Q, K, V, O 및 MLP의 gate, up, down projection까지 모든 레이어에 LoRA를 적용했을 때:
- 학습 가능 파라미터: 4,194,304 -> 20,277,248 (약 5배 증가)
- GPU 메모리: 14.18 GB -> 16.62 GB (약 17% 증가)
- 성능: 눈에 띄는 개선
파라미터 수와 메모리는 다소 증가하지만, 성능 대비 효율이 우수하므로 실무에서는 target_modules="all-linear" 설정을 권장하는 추세이다.
5.2 Rank 선택 가이드라인
Rank 선택에 대한 절대적인 규칙은 없지만, 다음과 같은 가이드라인을 참고할 수 있다:
| 사용 사례 | 권장 Rank | 이유 |
|---|---|---|
| 간단한 태스크 적응 (감성 분류 등) | r=4~8 | 낮은 intrinsic dimension으로 충분 |
| 일반적인 Instruction tuning | r=16~32 | 다양한 지시사항에 대한 적응 필요 |
| 복잡한 도메인 적응 (의료, 법률 등) | r=64~256 | 전문 지식의 표현에 더 많은 용량 필요 |
| 성능 최대화가 목표인 경우 | r=256+ | rsLoRA와 함께 사용 권장 |
Sebastian Raschka의 실험에서는 r=256이 r=8, 32, 64, 128보다 좋은 성능을 보였으나, r=512에서는 오히려 성능이 하락하는 경향이 관찰되었다. 이는 과도한 rank가 overfitting을 유발할 수 있음을 시사한다.
6. QLoRA: 4-bit 양자화 + LoRA
6.1 QLoRA 개요
2023년 Tim Dettmers et al.이 발표한 **QLoRA(Quantized LoRA)**는 LoRA의 메모리 효율성을 한 단계 더 끌어올린 기법이다. 핵심 아이디어는 base model의 가중치를 4-bit로 양자화하여 저장하고, LoRA adapter만 16-bit(또는 BFloat16)로 학습하는 것이다.
QLoRA의 세 가지 기술적 혁신:
6.2 4-bit NormalFloat (NF4)
NF4는 QLoRA에서 제안된 새로운 데이터 타입으로, 정규 분포를 따르는 가중치에 대해 정보 이론적으로 최적인 양자화 방식이다.
사전 학습된 신경망의 가중치는 일반적으로 zero-centered normal distribution을 따른다. NF4는 quantile quantization을 사용하여, 각 양자화 구간(bin)이 목표 정규 분포에서 동일한 기대 값의 수를 표현하도록 설계되었다. 이를 통해 기존의 INT4나 FP4보다 원래 가중치 분포를 훨씬 정확하게 보존할 수 있다.
6.3 Double Quantization
Double Quantization은 양자화 상수(quantization constants) 자체를 다시 양자화하는 기법이다. Block-wise quantization에서는 각 블록마다 scaling factor가 필요한데, 이 scaling factor 자체를 다시 양자화함으로써 파라미터당 평균 약 0.37 bits를 추가로 절약한다. 65B 모델 기준으로 약 3GB의 메모리를 추가 절약할 수 있다.
6.4 Paged Optimizers
Paged Optimizers는 NVIDIA Unified Memory를 활용하여, GPU 메모리가 포화 상태가 되면 optimizer states를 자동으로 CPU 메모리로 이전(page out)하는 기법이다. 이는 긴 시퀀스를 처리할 때 발생하는 gradient checkpointing memory spike를 효과적으로 처리한다. CUDA Toolkit 6.0에서 도입된 Unified Memory 모델을 기반으로, CPU와 GPU가 직접 접근할 수 있는 단일 메모리 공간을 활용한다.
6.5 QLoRA의 성능
QLoRA를 통해 65B 파라미터 모델을 단일 48GB GPU에서 Fine-tuning할 수 있게 되었으며, 16-bit Full Fine-tuning과 동등한 태스크 성능을 유지한다. QLoRA로 학습된 Guanaco 모델 패밀리는 Vicuna 벤치마크에서 이전의 모든 공개 모델을 능가했으며, ChatGPT 성능의 99.3%에 도달했다. 이는 단일 GPU에서 24시간의 학습만으로 달성한 결과이다.
6.6 LoRA vs QLoRA 비교
| 항목 | LoRA (16-bit) | QLoRA (4-bit) |
|---|---|---|
| 학습 시간 (7B, 동일 데이터) | ~1.85시간 | ~2.79시간 |
| GPU 메모리 | ~21.33 GB | ~14.18 GB |
| 성능 | 기준 | 거의 동일 (미세한 차이) |
| 장점 | 빠른 학습 속도 | 적은 메모리 요구량 |
QLoRA는 약 33%의 메모리를 절약하는 대신, 양자화/역양자화 과정으로 인해 약 39%의 학습 시간 증가가 발생한다. 메모리가 제한된 환경에서는 QLoRA가, 학습 속도가 중요한 환경에서는 LoRA가 더 적합하다.
7. HuggingFace PEFT 라이브러리 실습
7.1 설치
pip install peft transformers trl datasets bitsandbytes accelerate
7.2 기본 LoRA 설정 및 학습
다음은 HuggingFace PEFT를 사용하여 Causal Language Model에 LoRA를 적용하는 기본 예제이다.
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import LoraConfig, get_peft_model, TaskType
import torch
# 1. 모델과 토크나이저 로드
model_id = "meta-llama/Llama-2-7b-hf"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
model_id,
torch_dtype=torch.bfloat16,
device_map="auto",
)
# 2. LoRA 설정
lora_config = LoraConfig(
r=16, # rank
lora_alpha=32, # scaling factor (alpha)
target_modules="all-linear", # 모든 Linear 레이어에 적용
lora_dropout=0.05, # dropout 비율
bias="none", # bias 학습 비활성화
task_type=TaskType.CAUSAL_LM, # 태스크 유형
)
# 3. PEFT 모델 생성
model = get_peft_model(model, lora_config)
# 4. 학습 가능 파라미터 확인
model.print_trainable_parameters()
# 출력 예: trainable params: 20,277,248 || all params: 6,758,404,096 || trainable%: 0.30
7.3 SFTTrainer를 활용한 Instruction Tuning
TRL 라이브러리의 SFTTrainer와 PEFT를 결합하면 더 간결하게 Fine-tuning을 수행할 수 있다.
from trl import SFTTrainer, SFTConfig
from peft import LoraConfig
from datasets import load_dataset
# 데이터셋 로드
dataset = load_dataset("tatsu-lab/alpaca", split="train")
# LoRA 설정
peft_config = LoraConfig(
r=16,
lora_alpha=32,
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"],
)
# SFTTrainer 설정 및 학습
trainer = SFTTrainer(
model=model_id,
args=SFTConfig(
output_dir="./lora-output",
num_train_epochs=1,
per_device_train_batch_size=4,
gradient_accumulation_steps=4,
learning_rate=2e-4,
bf16=True,
logging_steps=10,
save_strategy="epoch",
max_seq_length=2048,
),
train_dataset=dataset,
peft_config=peft_config,
)
trainer.train()
# 학습된 adapter 저장
trainer.save_model("./lora-adapter")
7.4 QLoRA 적용 예제
QLoRA를 적용하려면 bitsandbytes를 활용하여 4-bit 양자화 설정을 추가한다.
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
import torch
# 4-bit 양자화 설정
bnb_config = BitsAndBytesConfig(
load_in_4bit=True, # 4-bit 양자화 활성화
bnb_4bit_quant_type="nf4", # NormalFloat4 타입 사용
bnb_4bit_compute_dtype=torch.bfloat16, # 연산 시 BFloat16 사용
bnb_4bit_use_double_quant=True, # Double Quantization 활성화
)
# 양자화된 모델 로드
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-2-7b-hf",
quantization_config=bnb_config,
device_map="auto",
)
# k-bit 학습을 위한 모델 준비
model = prepare_model_for_kbit_training(model)
# LoRA 설정 (QLoRA에서도 동일하게 사용)
lora_config = LoraConfig(
r=16,
lora_alpha=32,
target_modules="all-linear",
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
)
# PEFT 모델 생성
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
7.5 학습된 Adapter 로드 및 Inference
from peft import PeftModel, PeftConfig
from transformers import AutoModelForCausalLM, AutoTokenizer
# Base 모델 로드
base_model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-2-7b-hf",
torch_dtype=torch.bfloat16,
device_map="auto",
)
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-2-7b-hf")
# LoRA adapter 로드
model = PeftModel.from_pretrained(base_model, "./lora-adapter")
# (선택) Adapter를 base model에 병합하여 inference 속도 최적화
model = model.merge_and_unload()
# Inference
inputs = tokenizer("AI의 미래는", return_tensors="pt").to(model.device)
outputs = model.generate(**inputs, max_new_tokens=100)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
8. LoRA vs Full Fine-tuning 성능 비교
8.1 원 논문의 결과 (GPT-3 175B)
LoRA 원 논문에서 보고한 GPT-3 175B 결과는 다음과 같다:
| Method | Params | WikiSQL Acc. | MNLI-m Acc. | SAMSum (R1/R2/RL) |
|---|---|---|---|---|
| Full Fine-tuning | 175B | 73.8% | 89.5% | 52.0/28.0/44.5 |
| Prefix Tuning | 0.77M | - | - | - |
| LoRA | 4.7M | 73.4% | 91.7% | 53.8/29.8/45.9 |
| LoRA | 37.7M | 74.0% | 91.6% | 53.4/29.2/45.1 |
주목할 점은 LoRA가 MNLI와 SAMSum에서 Full Fine-tuning을 능가했다는 것이다. 단 4.7M 파라미터(전체의 0.003%)만 학습했음에도 불구하고, 175B 전체를 학습한 것보다 더 좋은 결과를 얻었다. 이는 LoRA의 implicit regularization 효과로 해석된다. 즉, 저랭크 분해가 일종의 정규화(regularization) 역할을 하여 overfitting을 방지한다.
8.2 추론 성능 및 학습 효율
| 지표 | Full Fine-tuning | LoRA |
|---|---|---|
| 학습 속도 | 기준 | ~25% 빠름 |
| VRAM 사용량 | 기준 | ~67% 절감 |
| Inference latency | 기준 | 동일 (병합 후) |
| 다중 태스크 전환 | 전체 모델 교체 필요 | Adapter만 교체 |
8.3 LoRA의 한계
LoRA가 항상 Full Fine-tuning과 동등한 것은 아니다. 최근 연구(Biderman et al., 2024, "LoRA vs Full Fine-tuning: An Illusion of Equivalence")에서는 다음을 지적한다:
- SVD 구조의 차이: LoRA와 Full Fine-tuning으로 학습된 가중치 행렬의 Singular Value Decomposition 구조가 상이하다.
- 분포 외 일반화(OOD Generalization): 학습 데이터 분포를 벗어난 입력에 대해 LoRA와 Full Fine-tuning 모델이 다른 일반화 패턴을 보인다.
- 데이터셋 크기 의존성: 데이터셋 크기가 LoRA의 학습 가능 파라미터 수를 크게 초과하면 Full Fine-tuning이 우위를 보일 수 있다.
따라서 LoRA를 적용할 때는 태스크의 복잡도와 데이터셋 규모를 고려하여 rank와 target modules를 적절히 설정해야 한다.
9. 실무 팁: Learning Rate, Rank, Alpha 조정
9.1 Learning Rate
- LoRA에서는 Full Fine-tuning 대비 약 10배 높은 learning rate가 필요하다. Full Fine-tuning에서 1e-5~3e-5를 사용한다면, LoRA에서는 1e-4~3e-4 범위가 적절하다.
- Learning rate는 다른 hyperparameter보다 먼저 최적화해야 한다. Rank와 alpha의 효과가 learning rate에 의존하기 때문이다.
- Cosine annealing 스케줄러는 SGD에서는 효과적이지만, Adam/AdamW에서는 영향이 미미하다.
9.2 Rank (r) 설정
- 시작점: r=16으로 시작하여 성능을 평가한 후, 필요에 따라 조정한다.
- 과소 설정 위험: Rank가 너무 낮으면 태스크에 필요한 표현력이 부족해진다.
- 과대 설정 위험: Rank가 너무 높으면 overfitting이 발생할 수 있으며, 메모리와 연산 비용이 증가한다.
- rsLoRA 활용: r=32 이상의 높은 rank를 사용할 때는
use_rslora=True를 설정하여 scaling factor를 로 조정하는 것이 좋다. 이는 높은 rank에서의 학습 안정성을 개선한다.
9.3 Alpha 설정
- 일반적인 휴리스틱:
alpha = 2 * r로 설정한다. 즉, rank가 16이면 alpha는 32으로 설정한다. - 이 비율은 대부분의 경우 좋은 결과를 보이지만, 최적의 비율은 모델과 데이터셋에 따라 달라질 수 있다.
- Sebastian Raschka의 실험에서는 r=256, alpha=128 (0.5배 비율)이 더 좋은 결과를 보인 사례도 있었다.
9.4 Dropout
- LoRA dropout은 일반적으로 0.05~0.1 범위로 설정한다.
- 데이터셋이 작거나 overfitting이 우려되는 경우에는 0.1, 대규모 데이터셋에서는 0.05 또는 비활성화(0.0)를 고려한다.
9.5 Optimizer 선택
- AdamW: 가장 안정적이고 널리 사용되는 선택이다.
- SGD: 낮은 rank에서는 AdamW와 메모리 차이가 미미하지만, 높은 rank(r=256)에서는 의미 있는 메모리 절약이 가능하다 (17.86 GB vs 14.46 GB).
- 대부분의 경우 AdamW를 기본으로 사용하되, 메모리가 극히 제한된 환경에서 높은 rank를 사용해야 한다면 SGD를 고려한다.
9.6 데이터셋 관련 팁
- Multi-epoch 학습 주의: 동일한 데이터셋을 여러 번 반복하면 overfitting이 발생할 수 있다. Sebastian Raschka의 실험에서는 Alpaca 데이터셋에 대해 2 epochs 학습 시 성능이 오히려 하락했다.
- 데이터 품질 > 양: 1K 예제의 LIMA 데이터셋이 50K 예제의 Alpaca 데이터셋과 유사하거나 더 좋은 결과를 보인 사례가 있다. 고품질 데이터셋 구축이 hyperparameter tuning보다 중요할 수 있다.
9.7 실전 설정 템플릿
아래는 실무에서 바로 활용할 수 있는 LoRA 설정 템플릿이다.
from peft import LoraConfig
# 일반적인 Instruction Tuning 설정
config_standard = LoraConfig(
r=16,
lora_alpha=32,
target_modules="all-linear",
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
)
# 메모리 절약 우선 설정 (QLoRA와 함께 사용)
config_memory_efficient = LoraConfig(
r=8,
lora_alpha=16,
target_modules=["q_proj", "v_proj"],
lora_dropout=0.1,
bias="none",
task_type="CAUSAL_LM",
)
# 성능 최대화 설정
config_high_performance = LoraConfig(
r=64,
lora_alpha=128,
target_modules="all-linear",
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
use_rslora=True, # 높은 rank에서 Rank-Stabilized LoRA 사용
)
10. LoRA 생태계와 변형 기법
LoRA의 성공 이후 다양한 변형 기법이 등장했다. 간략히 정리하면 다음과 같다:
| 기법 | 핵심 아이디어 | PEFT 지원 |
|---|---|---|
| LoRA | 저랭크 행렬 분해 (BA) | O |
| QLoRA | 4-bit 양자화 + LoRA | O |
| DoRA | Weight-Decomposed LoRA (방향/크기 분리) | O |
| AdaLoRA | 중요도 기반 rank 동적 할당 | O |
| LoHa | Hadamard Product 기반 분해 | O |
| LoKr | Kronecker Product 기반 분해 | O |
| PiSSA | Principal Singular values 기반 초기화 | O |
| rsLoRA | Rank-Stabilized scaling factor | O |
HuggingFace PEFT 라이브러리는 이 모든 기법을 LoraConfig의 옵션이나 별도의 Config 클래스로 지원하고 있어, 최소한의 코드 변경으로 다양한 기법을 실험할 수 있다.
11. 마치며
LoRA는 "사전 학습된 모델의 가중치 변화량이 낮은 intrinsic rank를 가진다"는 간결한 가설에서 출발하여, 대규모 언어 모델의 Fine-tuning 비용을 획기적으로 줄인 기법이다. 수학적으로 우아하고, 구현이 간단하며, 추론 시 추가 비용이 없다는 세 가지 장점이 LoRA를 현재 LLM Fine-tuning의 표준으로 만들었다.
QLoRA의 등장으로 소비자급 GPU에서도 대규모 모델의 Fine-tuning이 가능해졌고, HuggingFace PEFT 라이브러리는 이러한 기법들을 몇 줄의 코드로 적용할 수 있게 만들어주었다. LLM을 활용한 프로젝트를 진행한다면, LoRA는 반드시 숙지해야 할 핵심 기술이다.
References
Hu, E. J., Shen, Y., Wallis, P., Allen-Zhu, Z., Li, Y., Wang, S., Wang, L., & Chen, W. (2021). LoRA: Low-Rank Adaptation of Large Language Models. arXiv. https://arxiv.org/abs/2106.09685
Dettmers, T., Pagnoni, A., Holtzman, A., & Zettlemoyer, L. (2023). QLoRA: Efficient Finetuning of Quantized LLMs. arXiv. https://arxiv.org/abs/2305.14314
Aghajanyan, A., Gupta, S., & Zettlemoyer, L. (2020). Intrinsic Dimensionality Explains the Effectiveness of Language Model Fine-Tuning. arXiv. https://arxiv.org/abs/2012.13255
HuggingFace PEFT - LoRA Documentation. https://huggingface.co/docs/peft/en/package_reference/lora
HuggingFace PEFT - LoRA Methods Guide. https://huggingface.co/docs/peft/en/task_guides/lora_based_methods
HuggingFace PEFT GitHub Repository. https://github.com/huggingface/peft
Microsoft LoRA GitHub Repository. https://github.com/microsoft/LoRA
Raschka, S. (2023). Practical Tips for Finetuning LLMs Using LoRA (Low-Rank Adaptation). Sebastian Raschka's Magazine. https://magazine.sebastianraschka.com/p/practical-tips-for-finetuning-llms
Biderman, S., et al. (2024). LoRA vs Full Fine-tuning: An Illusion of Equivalence. arXiv. https://arxiv.org/abs/2410.21228
Kalajdzievski, D. (2023). Rank-Stabilized LoRA (rsLoRA). arXiv. https://arxiv.org/abs/2312.03732
Liu, S., et al. (2024). DoRA: Weight-Decomposed Low-Rank Adaptation. arXiv. https://arxiv.org/abs/2402.09353
HuggingFace Blog - Making LLMs even more accessible with bitsandbytes, 4-bit quantization and QLoRA. https://huggingface.co/blog/4bit-transformers-bitsandbytes