Skip to main content
BERT는 2018년 Google이 발표한 양방향 인코더 모델로, NLP의 사전학습 패러다임을 본격적으로 열었습니다. 발표 당시 11개 NLP 벤치마크에서 SOTA(State-of-the-Art)를 달성하며, 사전학습 후 Fine-tuning이라는 접근법을 NLP의 표준으로 확립했습니다.

핵심 아이디어

기존 언어 모델(ELMo, GPT-1)은 좌에서 우로(left-to-right) 또는 좌우를 독립적으로 학습하는 방식이었습니다. BERT는 **양방향 컨텍스트(bidirectional context)**를 동시에 학습하여, 단어의 의미를 문맥 전체에서 파악합니다. 핵심 차이: GPT는 다음 토큰을 예측하지만, BERT는 문장 중간의 가려진 토큰을 양쪽 문맥을 모두 사용하여 예측합니다.

아키텍처 상세

BERT는 Transformer의 인코더(Encoder) 블록만 사용합니다.
구성 요소BERT-BaseBERT-Large
Transformer 레이어 (L)1224
Hidden 차원 (H)7681024
Attention Head 수 (A)1216
파라미터 수110M340M
최대 시퀀스 길이512512

입력 표현 (Input Representation)

BERT의 입력은 세 가지 임베딩의 합으로 구성됩니다.
  • Token Embedding: WordPiece 토크나이저로 분리된 각 토큰의 임베딩
  • Segment Embedding: 첫 번째 문장(A)과 두 번째 문장(B)을 구분하는 임베딩
  • Position Embedding: 학습 가능한(learned) 위치 임베딩 (최대 512)
특수 토큰:
  • [CLS]: 문장의 시작. 이 토큰의 최종 Hidden State를 분류 태스크에 사용합니다.
  • [SEP]: 문장 사이의 구분자. 두 문장을 하나의 입력으로 연결할 때 사용합니다.
  • [MASK]: MLM에서 가려진 토큰 위치를 나타냅니다.

사전학습 목표 (Pre-training Objectives)

BERT는 두 가지 사전학습 목표를 동시에 학습합니다.

1. Masked Language Model (MLM)

입력 토큰의 15%를 무작위로 선택하고, 해당 위치의 토큰을 예측하는 것이 목표입니다. 선택된 15% 토큰의 처리 방식:
  • 80%: [MASK] 토큰으로 대체 → "I love [MASK]""NLP" 예측
  • 10%: 무작위 토큰으로 대체 → "I love apple""NLP" 예측
  • 10%: 변경하지 않음 → "I love NLP""NLP" 확인
이 전략은 Fine-tuning 시 [MASK] 토큰이 없는 환경과의 괴리(mismatch)를 줄이기 위해 설계되었습니다. MLM 손실 함수: LMLM=iMlogP(xix\M)\mathcal{L}_{\text{MLM}} = -\sum_{i \in \mathcal{M}} \log P(x_i \mid \mathbf{x}_{\backslash \mathcal{M}}) 여기서 M\mathcal{M}은 마스킹된 토큰의 위치 집합이고, x\M\mathbf{x}_{\backslash \mathcal{M}}은 마스킹되지 않은 나머지 토큰입니다.

2. Next Sentence Prediction (NSP)

두 문장이 연속된 문장인지 예측하는 이진 분류 태스크입니다.
입력레이블
[CLS] 오늘 날씨가 좋다 [SEP] 산책을 나가자 [SEP]IsNext
[CLS] 오늘 날씨가 좋다 [SEP] 주식이 올랐다 [SEP]NotNext
학습 데이터의 50%는 실제 연속 문장, 50%는 무작위 문장 쌍으로 구성됩니다. [CLS] 토큰의 출력 벡터에 분류 헤드를 달아 예측합니다.
참고: 후속 연구(RoBERTa)에서 NSP는 성능 향상에 기여하지 않거나 오히려 방해가 될 수 있다는 결과가 나왔습니다. 자세한 내용은 RoBERTa, ALBERT, DeBERTa 문서에서 다룹니다.

사전학습 데이터 및 설정

항목
학습 데이터BooksCorpus (800M 단어) + English Wikipedia (2,500M 단어)
배치 크기256 시퀀스
학습 스텝1,000,000 (약 40 에폭)
옵티마이저Adam (lr=1e-4, warmup 10,000 스텝)
학습 시간4일 (TPU v3 Pod 16칩, BERT-Base 기준)

Fine-tuning 전략

BERT의 가장 큰 강점은 다양한 다운스트림 태스크에 쉽게 적용할 수 있다는 것입니다. 사전학습된 BERT 위에 간단한 출력 레이어를 추가하고, 전체 모델을 태스크 데이터로 미세 조정합니다.

Fine-tuning 하이퍼파라미터 권장 값

하이퍼파라미터권장 범위
학습률 (Learning Rate)2e-5, 3e-5, 5e-5
배치 크기16, 32
에폭 수2~4
Warmup 비율학습 스텝의 10%
Weight Decay0.01

구현 예제

HuggingFace Transformers를 사용하여 BERT로 텍스트 분류를 수행하는 예제입니다.

Masked Language Model 추론

from transformers import BertTokenizer, BertForMaskedLM
import torch

# 모델과 토크나이저 로드
tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
model = BertForMaskedLM.from_pretrained("bert-base-uncased")
model.eval()

# 마스킹된 문장 입력
text = "The capital of France is [MASK]."
inputs = tokenizer(text, return_tensors="pt")

# 예측 수행
with torch.no_grad():
    outputs = model(**inputs)
    predictions = outputs.logits

# [MASK] 위치의 상위 5개 예측 토큰
mask_index = (inputs["input_ids"] == tokenizer.mask_token_id).nonzero(as_tuple=True)[1]
top_5 = torch.topk(predictions[0, mask_index, :], 5, dim=-1)

print("입력:", text)
print("상위 5개 예측:")
for i, (token_id, score) in enumerate(zip(top_5.indices[0], top_5.values[0])):
    token = tokenizer.decode(token_id)
    print(f"  {i+1}. {token} (점수: {score:.4f})")

Fine-tuning: 텍스트 분류

from transformers import BertTokenizer, BertForSequenceClassification
from transformers import Trainer, TrainingArguments
from datasets import load_dataset

# 데이터셋 로드 (IMDB 감성 분류)
dataset = load_dataset("imdb")
tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")

# 토큰화 함수
def tokenize_fn(examples):
    """텍스트를 BERT 입력 형식으로 토큰화합니다."""
    return tokenizer(
        examples["text"],
        padding="max_length",
        truncation=True,
        max_length=256,
    )

tokenized = dataset.map(tokenize_fn, batched=True)

# 모델 초기화 (이진 분류)
model = BertForSequenceClassification.from_pretrained(
    "bert-base-uncased",
    num_labels=2,
)

# 학습 설정
training_args = TrainingArguments(
    output_dir="./results",
    num_train_epochs=3,
    per_device_train_batch_size=16,
    per_device_eval_batch_size=32,
    learning_rate=2e-5,
    weight_decay=0.01,
    warmup_ratio=0.1,
    evaluation_strategy="epoch",
    save_strategy="epoch",
    load_best_model_at_end=True,
)

# Trainer로 학습 실행
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized["train"],
    eval_dataset=tokenized["test"],
)

trainer.train()

Feature Extraction (임베딩 추출)

from transformers import BertTokenizer, BertModel
import torch

tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
model = BertModel.from_pretrained("bert-base-uncased")
model.eval()

# 문장 인코딩
text = "BERT produces contextualized embeddings."
inputs = tokenizer(text, return_tensors="pt")

with torch.no_grad():
    outputs = model(**inputs)

# [CLS] 토큰의 Hidden State (문장 표현)
cls_embedding = outputs.last_hidden_state[:, 0, :]  # shape: (1, 768)

# 전체 토큰의 Hidden State
all_embeddings = outputs.last_hidden_state  # shape: (1, seq_len, 768)

# 평균 풀링으로 문장 임베딩 생성
# attention_mask를 사용하여 패딩 토큰 제외
mask = inputs["attention_mask"].unsqueeze(-1).float()
mean_embedding = (outputs.last_hidden_state * mask).sum(dim=1) / mask.sum(dim=1)

print(f"[CLS] 임베딩 차원: {cls_embedding.shape}")
print(f"평균 풀링 임베딩 차원: {mean_embedding.shape}")

관련 기술 비교

모델방향성사전학습 목표주요 용도
ELMo (2018)양방향 (독립적)양방향 LMFeature 추출
GPT-1 (2018)단방향 (좌→우)Autoregressive LM생성, Fine-tuning
BERT (2018)양방향 (동시)MLM + NSP이해, 분류, 추출
XLNet (2019)순열 기반 양방향Permutation LM이해 + 생성
BERT는 ELMo의 양방향 아이디어와 GPT-1의 Fine-tuning 접근법을 결합하여, 두 모델의 장점을 취한 아키텍처입니다.

BERT의 한계

  1. 고정 길이 제한: 최대 512 토큰까지만 처리 가능합니다. 긴 문서 처리에 한계가 있습니다.
  2. [MASK] 토큰 불일치: 사전학습 시 사용하는 [MASK]가 Fine-tuning에는 없어 미스매치가 발생합니다.
  3. 토큰 독립 가정: MLM에서 마스킹된 토큰들이 서로 독립이라고 가정하지만 실제로는 상관관계가 있을 수 있습니다.
  4. NSP의 효과: 후속 연구에서 NSP가 불필요하거나 해로울 수 있다는 결과가 보고되었습니다.
이러한 한계를 극복하기 위한 후속 모델은 RoBERTa, ALBERT, DeBERTa에서 다룹니다.
WordPiece는 BPE(Byte Pair Encoding)의 변형으로, 빈도가 아닌 우도(likelihood)를 기준으로 서브워드를 병합합니다. "playing"["play", "##ing"]으로 분리하며, ## 접두사는 이전 토큰에 이어지는 서브워드임을 나타냅니다. 어휘 크기는 30,522개입니다.
BERT의 [CLS] 토큰은 NSP 목표에 최적화되어 있어, 범용 문장 임베딩으로는 부적합할 수 있습니다. 문장 유사도 태스크에는 Sentence-BERT(SBERT)처럼 전용으로 학습된 모델을 사용하거나, 평균 풀링(mean pooling)을 적용하는 것이 더 나은 결과를 보입니다.
BERT는 양방향 모델이므로 자기회귀(autoregressive) 텍스트 생성에는 적합하지 않습니다. 생성이 필요하다면 GPT 계열(디코더 모델)이나 T5(인코더-디코더 모델)를 사용하는 것이 적절합니다. 다만, BERT의 MLM 헤드를 활용한 제한적인 빈칸 채우기는 가능합니다.

참고 논문

논문저자연도핵심 기여
BERT: Pre-training of Deep Bidirectional Transformers for Language UnderstandingDevlin et al.2018MLM + NSP 기반 양방향 사전학습
Attention Is All You NeedVaswani et al.2017Transformer 아키텍처 (BERT의 기반)
Deep contextualized word representations (ELMo)Peters et al.2018문맥 의존적 임베딩의 시초

RoBERTa, ALBERT, DeBERTa

BERT의 한계를 극복한 개선 모델들을 비교합니다

한국어 PLM

KoBERT, KoELECTRA 등 한국어 BERT 변형 모델을 학습합니다