10억-parameter model full fine-tune = 10억 gradient 저장, 10억 optimizer state, 10억-parameter checkpoint. single consumer GPU 에 fit X 하고 거대 artifact 생산. LoRA (Low-Rank Adaptation) 가 문제 회피.
LoRA idea
원본 weight freeze. 적응할 각 linear layer 위, 작은 'delta' 형식 ΔW = B @ A 추가, A 는 (rank, in_features), B 는 (out_features, rank). rank=8, in/out=4096 면 layer 당 8*4096 + 4096*8 = 65,536 trainable parameter — full fine-tune 의 4096*4096 = 16,777,216 와 비교. 대략 0.4% size.
adapter weight 가 0 시작 → step 0 에선 model 이 pretrained 와 동일 행동. Training 이 adapter 만 update; inference 가 그대로 (작은 overhead) 또는 원본 weight 에 merge (0 overhead) 가능.
PEFT 라이브러리
Hugging Face peft 라이브러리가 LoRA, AdaLoRA, IA³, prompt tuning 등 구현. transformers 와 깔끔히 통합 — model wrap, 정상 train, adapter 만 저장 (몇 MB).
왜 모든 거 바꿈
7B-param Llama 를 24GB consumer GPU 에 fine-tune.
Adapter checkpoint 가 GB 아니라 MB — 공유 / version / A/B test 쉬움.
multi-task model 위해 여러 adapter stack, parameter count 폭발 없이.
'frozen base + 작은 adapter' 결합이 호스팅된 LLM fine-tuning 을 economically viable 하게.
Code
LoRA 로 model wrap — 최소 예·python
# pip install peft transformers
from peft import LoraConfig, get_peft_model, TaskType
from transformers import AutoModelForSequenceClassification
base = AutoModelForSequenceClassification.from_pretrained(
"bert-base-uncased", num_labels=2,
)
lora_cfg = LoraConfig(
task_type=TaskType.SEQ_CLS,
r=8, # rank — bigger = more capacity, more params
lora_alpha=32, # scaling factor
lora_dropout=0.1,
target_modules=["query", "value"], # adapt Q and V in attention
)
model = get_peft_model(base, lora_cfg)
model.print_trainable_parameters()
# trainable params: 294,912 || all params: 109,777,410 || trainable%: 0.27%
adapter 만 save 와 load·python
from peft import PeftModel
from transformers import AutoModelForSequenceClassification
# After training:
model.save_pretrained("my-lora-adapter") # tiny — usually a few MB
# Load on a fresh base model
base = AutoModelForSequenceClassification.from_pretrained(
"bert-base-uncased", num_labels=2,
)
model = PeftModel.from_pretrained(base, "my-lora-adapter")
# For inference — merge the adapter into the base for zero overhead
merged = model.merge_and_unload()
# `merged` is now a vanilla transformers model with ΔW baked in
target_modules 고르기 — architecture 중요·python
from peft import LoraConfig
# LLaMA-family — adapt these projection names
llama_lora = LoraConfig(
r=16, lora_alpha=32, lora_dropout=0.05,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
task_type="CAUSAL_LM",
)
# BERT — query / value
bert_lora = LoraConfig(
r=8, lora_alpha=32,
target_modules=["query", "value"],
task_type="SEQ_CLS",
)
# Or, let PEFT discover all linear layers automatically
auto_lora = LoraConfig(
r=16, target_modules="all-linear",
task_type="CAUSAL_LM",
)
bert-base-uncased 를 LoRA config (r=8, query/value adapter) 로 wrap. model.print_trainable_parameters() 와 full fine-tune 비교 (just len(list(base.parameters())) 의 requires_grad=True param). 비율이 대략 1:400 이어야.
Progress
Progress is local-only — sign in to sync across devices.