🤖 AI/ML

Adapter

모델 레이어 사이에 삽입되는 작은 학습 모듈

📖 상세 설명

Adapter는 사전 학습된 대규모 모델을 효율적으로 특정 태스크에 적응시키기 위해 Transformer 레이어 사이에 삽입되는 작은 학습 모듈입니다. 원본 모델의 파라미터는 고정(freeze)하고 Adapter만 학습하므로, 전체 fine-tuning 대비 0.5~4%의 파라미터만 업데이트하면서도 유사한 성능을 달성합니다.

2019년 Google Research의 논문 "Parameter-Efficient Transfer Learning for NLP"에서 처음 제안되었습니다. 이후 PEFT(Parameter-Efficient Fine-Tuning)의 핵심 기법으로 발전하였으며, LoRA, Prefix Tuning 등 다양한 변형 기법의 기반이 되었습니다.

Adapter의 구조는 다운프로젝션(down-projection), 비선형 활성화, 업프로젝션(up-projection)으로 구성된 보틀넥(bottleneck) 형태입니다. 예를 들어 768차원 입력을 64차원으로 줄였다가 다시 768차원으로 복원합니다. 이 보틀넥 차원이 Adapter의 용량을 결정하며, 일반적으로 원래 차원의 1~10%를 사용합니다.

다국어/다도메인 서비스에서 하나의 기본 모델에 여러 Adapter를 태스크별로 교체하며 사용할 수 있습니다. 의료, 법률, 금융 등 도메인별 Adapter를 준비해두면 추론 시 필요한 Adapter만 로드하여 빠르게 전환할 수 있어, 다양한 전문 분야를 커버하는 서비스 구축에 효과적입니다.

💻 코드 예제

from transformers import AutoModelForSequenceClassification
from peft import get_peft_model, LoraConfig, TaskType

# 기본 모델 로드
model_name = "bert-base-uncased"
model = AutoModelForSequenceClassification.from_pretrained(
    model_name, num_labels=2
)

# LoRA (Low-Rank Adaptation) 설정 - Adapter의 인기 변형
lora_config = LoraConfig(
    task_type=TaskType.SEQ_CLS,
    r=8,                  # 보틀넥 차원 (rank)
    lora_alpha=32,        # 스케일링 팩터
    lora_dropout=0.1,     # 드롭아웃
    target_modules=["query", "value"]  # 적용할 레이어
)

# Adapter가 적용된 PEFT 모델 생성
peft_model = get_peft_model(model, lora_config)

# 학습 가능한 파라미터 확인
trainable_params = sum(p.numel() for p in peft_model.parameters() if p.requires_grad)
total_params = sum(p.numel() for p in peft_model.parameters())
print(f"학습 파라미터: {trainable_params:,} / {total_params:,}")
print(f"학습 비율: {100 * trainable_params / total_params:.2f}%")

# 학습 후 Adapter만 저장
peft_model.save_pretrained("./my_adapter")

# 다른 태스크용 Adapter 로드하여 교체
from peft import PeftModel
base_model = AutoModelForSequenceClassification.from_pretrained(model_name)
medical_model = PeftModel.from_pretrained(base_model, "./medical_adapter")
legal_model = PeftModel.from_pretrained(base_model, "./legal_adapter")

🗣️ 실무 대화 예시

📊 MLOps 설계 회의에서

"각 고객사별로 full fine-tuning하면 모델 저장 비용이 너무 커요. Adapter 방식으로 가면 기본 모델 하나에 고객별 Adapter만 따로 저장할 수 있어서, 저장 공간을 90% 이상 줄일 수 있습니다."

💼 기술 면접에서

"Adapter와 LoRA의 차이점을 설명해주세요. Adapter는 레이어 사이에 새로운 모듈을 추가하는 방식이고, LoRA는 기존 가중치에 저차원 행렬을 더하는 방식입니다. LoRA가 추론 시 오버헤드 없이 병합 가능해서 더 많이 쓰입니다."

🔧 모델 최적화 논의에서

"7B 모델 전체 fine-tuning에 A100 80GB 4장이 필요한데, LoRA 쓰면 24GB GPU 1장으로도 가능해요. 학습 시간도 3분의 1로 줄어들고요."

⚠️ 주의사항

📊
보틀넥 차원(rank) 선택

rank가 너무 작으면 표현력이 부족하고, 너무 크면 효율성이 떨어집니다. 일반적으로 r=4~16으로 시작하여 태스크 복잡도에 따라 조정하세요. 복잡한 태스크에서는 r=64까지 필요할 수 있습니다.

🎯
적용 레이어 선택

모든 레이어에 Adapter를 적용하면 파라미터가 늘어납니다. Attention의 Query/Value에만 적용해도 대부분 충분하며, 태스크에 따라 FFN 레이어 추가를 고려하세요.

⚠️
Adapter 호환성

Adapter는 특정 기본 모델에 종속됩니다. 기본 모델이 업데이트되면 기존 Adapter가 동작하지 않을 수 있으니, 기본 모델 버전을 함께 기록하세요.

🔗 관련 용어

📚 더 배우기