파라미터 효율적 파인튜닝 기법들(LoRA, Prefix Tuning, Prompt Tuning 등)은 각자 별도 코드베이스로 구현됐다. 모델마다, 태스크마다 통합 방법이 달랐다.
Hugging Face의 PEFT 라이브러리는 이 기법들을 하나의 통일된 API로 제공한다. transformers 생태계와 자연스럽게 통합된다.
지원 기법
LoRA (Low-Rank Adaptation): 어텐션 레이어의 가중치 업데이트를 저랭크 행렬로 근사한다. 가장 널리 쓰인다. 다음 글(090)에서 Quantization과 함께 QLoRA로 다룬다.
Prefix Tuning: 각 레이어의 Key/Value에 학습 가능한 접두사를 추가한다. 088에서 설명했다.
Prompt Tuning: 입력 임베딩에 소프트 프롬프트를 추가한다. 088에서 설명했다.
Adapter: 트랜스포머 레이어 사이에 작은 보틀넥 레이어를 삽입한다. 원본 가중치는 고정하고 Adapter만 학습한다. Prefix보다 레이어 수준에서 더 유연한 조정이 가능하다.
IA3 (Infused Adapter by Inhibiting and Amplifying Inner Activations): 가중치를 변경하지 않고 학습된 스케일 벡터를 곱해 활성화를 조정한다. LoRA보다 더 적은 파라미터(~10배)로 비슷한 성능을 낸다.
통일된 API
from peft import (
get_peft_model,
LoraConfig,
PrefixTuningConfig,
PromptTuningConfig,
TaskType,
)
from transformers import AutoModelForSeq2SeqLM
model = AutoModelForSeq2SeqLM.from_pretrained("t5-base")
# LoRA 설정
lora_config = LoraConfig(
task_type=TaskType.SEQ_2_SEQ_LM,
r=8, # 랭크
lora_alpha=32, # 스케일링 계수
target_modules=["q", "v"], # 어텐션 Q, V에 적용
lora_dropout=0.1,
)
peft_model = get_peft_model(model, lora_config)
peft_model.print_trainable_parameters()
# trainable params: 294,912 || all params: 247,577,856 || trainable%: 0.12%
# 학습 (일반 Trainer와 동일)
trainer = Trainer(model=peft_model, ...)
trainer.train()
# 저장 (어댑터 가중치만)
peft_model.save_pretrained("./lora-t5")
# 파일 크기: ~1MB (전체 모델 900MB 대비)
로드와 추론
from peft import PeftModel
base_model = AutoModelForSeq2SeqLM.from_pretrained("t5-base")
model = PeftModel.from_pretrained(base_model, "./lora-t5")
# 여러 어댑터를 전환
model.load_adapter("./lora-translation", adapter_name="translation")
model.load_adapter("./lora-summary", adapter_name="summary")
model.set_adapter("translation")
output = model.generate(...)
model.set_adapter("summary")
output = model.generate(...)
같은 베이스 모델에 태스크별 어댑터를 교체하며 사용한다.
어댑터 병합
LoRA는 추론 시 별도 어댑터 레이어가 필요해 약간의 오버헤드가 있다. 병합하면 오버헤드가 사라진다.
# LoRA 가중치를 베이스 모델에 병합
merged_model = peft_model.merge_and_unload()
# 이제 일반 모델과 동일, LoRA 오버헤드 없음
merged_model.save_pretrained("./merged-model")
병합 후에는 어댑터를 교체할 수 없다.
멀티 어댑터 조합
여러 LoRA를 가중 합산으로 동시에 적용할 수 있다.
# LoRA A (코딩 스타일)와 LoRA B (한국어) 동시 적용
model.add_weighted_adapter(
adapters=["coding", "korean"],
weights=[0.7, 0.3],
adapter_name="combined"
)
LoRA 가중치를 선형 결합하는 방식이다. 두 특성을 동시에 부여하거나 강도를 조절할 수 있다.
트레이드오프
PEFT는 전체 파인튜닝보다 표현력이 제한된다. 태스크가 베이스 모델의 능력 범위 안에 있다면 PEFT로 충분하지만, 베이스 모델이 전혀 다루지 않은 도메인이나 완전히 새로운 형식의 출력이 필요하면 전체 파인튜닝이 필요할 수 있다.
또한 어댑터 개수가 늘어나면 관리가 복잡해진다. 베이스 모델 버전과 어댑터 버전의 호환성을 추적해야 한다. Hugging Face Hub에 어댑터를 공개하면 커뮤니티와 공유할 수 있어 이 문제를 일부 완화한다.