AI 애플리케이션을 구축할 때 BERT와 GPT 중 하나를 선택하는 것은 단순한 취향의 문제가 아닙니다. 이는 여러분의 모델이 ‘읽어야’ 하는지, 아니면 ‘써야’ 하는지에 대한 구조적인 결정입니다.
두 모델 모두 2018년 구글이 발표한 혁신적인 트랜스포머(Transformer) 아키텍처에서 파생되었지만, 서로 근본적으로 다른 문제를 해결하기 위해 트랜스포머 엔진의 서로 다른 부품을 사용합니다. 이 차이를 오해하면 모델의 성능 저하는 물론 컴퓨팅 자원의 낭비로 이어질 수 있습니다. 이 가이드에서는 두 모델의 메커니즘, 활용 사례, 그리고 코드 구현 방법까지 상세히 분석합니다.
핵심 개념: 트랜스포머의 분화 (The Transformer Split)
원래의 트랜스포머 아키텍처는 두 개의 스택으로 구성되어 있습니다.
- 인코더 (The Encoder): 입력을 처리합니다. 문맥을 이해(understand) 하도록 설계되었습니다.
- 디코더 (The Decoder): 출력을 생성합니다. 다음 단계를 예측(predict) 하도록 설계되었습니다.
현대적인 LLM(거대언어모델)들은 보통 이 방정식의 한쪽 부분에만 특화되어 있습니다.
BERT (Bidirectional Encoder Representations from Transformers)
BERT는 인코더 전용(Encoder-only) 모델입니다. 양방향(Bi-directional) 특성을 가지며, 단어의 왼쪽과 오른쪽 문맥을 동시에 파악합니다.
- 비유: 고문서를 해독하는 학자와 같습니다. 문장 전체를 한 번에 보고, 앞뒤 내용을 바탕으로 모호한 단어의 의미를 파악합니다.
- 특기: 이해, 분류, 검색.
GPT (Generative Pre-trained Transformer)
GPT는 디코더 전용(Decoder-only) 모델입니다. 자기 회귀(Auto-regressive, 단방향) 특성을 가지며, 왼쪽에서 오른쪽으로 읽어나가기 때문에 미래의 토큰을 “볼 수” 없습니다. 오로지 과거의 기록에 의존하여 다음 단어를 예측합니다.
- 비유: 즉석에서 연설문을 작성하는 작가와 같습니다. 문맥의 흐름을 유지하기 위해 바로 앞 단어 다음에 올 가장 자연스러운 단어에 집중합니다.
- 특기: 생성, 채팅, 텍스트 완성.
아키텍처 시각화
가장 큰 차이점은 어텐션 메커니즘(Attention Mechanism)을 통해 정보가 흐르는 방식에 있습니다.
graph TD
subgraph "BERT (인코더)"
A["입력: 'The bank of the river'"] --> B["셀프 어텐션 (양방향)"]
B --> C["'bank'는 'The', 'of', 'river'를 모두 봄"]
C --> D["출력: 문맥적 임베딩 (Contextual Embedding)"]
end
subgraph "GPT (디코더)"
E["입력: 'The bank of'"] --> F["마스크드 셀프 어텐션 (단방향)"]
F --> G["'of'는 오직 'The', 'bank'만 봄"]
G --> H["출력: 다음 단어 예측 'the'"]
end
style A fill:#e1f5fe,stroke:#01579b
style E fill:#fff3e0,stroke:#e65100
기능 비교 매트릭스
| 기능 | BERT (인코더) | GPT (디코더) |
|---|---|---|
| 방향성 | 양방향 (좌 <-> 우) | 단방향 (좌 -> 우) |
| 주요 작업 | 이해 / 판별 (Understanding / Discrimination) | 생성 (Generation) |
| 사전 학습 목표 | 마스크 언어 모델링 (빈칸 채우기) | 인과적 언어 모델링 (다음 토큰 예측) |
| 최적의 활용 사례 | 감성 분석, 개체명 인식(NER), 스팸 탐지, 의미 기반 검색 | 챗봇, 코드 생성, 스토리텔링, 요약 |
| 입력 제한 | 고정됨 (보통 512 토큰) | 유연함 (가변적인 컨텍스트 윈도우) |
구현: 코드로 보는 차이
실제 차이를 확인하기 위해 Hugging Face의 Python transformers 라이브러리를 사용해 보겠습니다.
1. 이해를 위한 BERT (특성 추출)
BERT를 사용하여 텍스트를 그 의미를 나타내는 벡터(숫자)로 변환합니다. 여기서 우리는 모델에게 “말하기”를 요청하지 않는다는 점에 주목하세요.
from transformers import BertTokenizer, BertModel
import torch
# 1. BERT 초기화 (인코더)
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertModel.from_pretrained('bert-base-uncased')
text = "The bank of the river."
inputs = tokenizer(text, return_tensors="pt")
# 2. 순전파(Forward pass)를 통해 히든 스테이트(hidden states) 추출
with torch.no_grad():
outputs = model(**inputs)
# 'last_hidden_state'에는 모든 토큰에 대한 문맥적 임베딩이 포함됨
# 형태(Shape): [Batch_Size, Sequence_Length, Hidden_Size]
embeddings = outputs.last_hidden_state
print(f"Vector Shape: {embeddings.shape}")
# 출력 예시: torch.Size([1, 7, 768])
2. 생성을 위한 GPT
GPT는 텍스트를 생성하는 데 사용됩니다. 모델은 한 번에 하나의 토큰을 예측하기 위해 루프(또는 generate 유틸리티)가 필요합니다.
from transformers import GPT2Tokenizer, GPT2LMHeadModel
# 1. GPT 초기화 (디코더)
tokenizer = GPT2Tokenizer.from_pretrained('gpt2')
model = GPT2LMHeadModel.from_pretrained('gpt2')
prompt = "The future of AI is"
inputs = tokenizer(prompt, return_tensors="pt")
# 2. 텍스트 생성 (내부적으로 자기 회귀 루프 처리)
output_sequences = model.generate(
input_ids=inputs['input_ids'],
max_length=20,
temperature=0.7,
num_return_sequences=1,
do_sample=True
)
generated_text = tokenizer.decode(output_sequences[0], skip_special_tokens=True)
print(f"Generated: {generated_text}")
# 출력 예시: Generated: The future of AI is likely to be shaped by the development of new technologies...
단계별 가이드: 선택 방법
프로젝트에 적합한 아키텍처를 선택하려면 다음의 논리 흐름을 따르세요.
- 출력 정의하기:
- 출력이 *라벨(Label)*인가요? (예: “긍정”, “스팸”, “카테고리 A”) -> BERT 사용.
- 출력이 *숫자(Number)*인가요? (예: 뉴스를 기반으로 한 주가 예측) -> BERT 사용.
- 출력이 새로운 텍스트인가요? -> GPT 사용.
- 문맥 요구사항 평가:
- 문장 앞부분의 의미가 뒷부분에 의존하나요? (예: DNA 서열 분석, 복잡한 법률 조항 해석).
- 조치: 그렇다면 인코더 모델의 양방향성이 훨씬 유리합니다.
- 지연 시간(Latency) 고려:
- 인코더 모델은 입력을 한 번의 패스로 처리하기 때문에 분류 작업에서 일반적으로 더 빠릅니다.
- 디코더 모델은 생성되는 모든 단어마다 모델을 순차적으로 실행해야 하므로 생성 작업에서 속도가 느립니다.
수학적 직관
핵심적인 차이는 확률 계산 방식에 있습니다.
GPT (자기 회귀, Auto-regressive):
시퀀스 $W$의 확률은 조건부 확률의 곱입니다.
BERT (마스크 오토 인코딩, Masked Auto-encoding):
BERT는 시퀀스 내의 다른 모든 토큰을 감안하여 마스킹된 토큰 $w_i$를 예측합니다.
파워 유저를 위한 프로 팁
- 임베딩 품질: 의미 기반 검색이나 클러스터링에 원시(raw) GPT 임베딩을 사용하지 마세요. GPT는 왼쪽만 보기 때문에, 마지막 단어의 임베딩이 최근 문맥을 과도하게 반영하는 경향이 있습니다. BERT(또는 S-BERT)가 훨씬 더 나은 문장 임베딩을 생성합니다.
- “인코더-디코더” 절충안: 텍스트를 입력받아 텍스트를 출력해야 한다면(예: 번역 또는 요약), T5나 BART를 사용하세요. 이 모델들은 원문을 읽는 인코더와 번역문을 생성하는 디코더, 두 가지 스택을 모두 활용합니다.
- 지시 튜닝 (Instruction Tuning): 최신 “Chat” 모델들(ChatGPT나 Llama 3 같은)은 지시사항을 이해하는 것처럼 행동하도록 파인튜닝(fine-tuning)된 디코더 전용 모델입니다. 이들은 디코더이지만, 거대한 스케일 덕분에 과거에는 인코더의 영역이었던 추론(reasoning) 작업도 수행할 수 있게 되었습니다.
요약: 기계가 분석, 분류 또는 검색을 해야 한다면 인코더(BERT)를 사용하세요. 기계가 창작, 대화 또는 내용을 확장해야 한다면 디코더(GPT)를 사용하세요.
