[AI 101] BERT – 양방향으로 언어를 이해하는 AI


핵심 요약

“양방향”이라는 단어가 AI를 바꿨습니다. BERT(Bidirectional Encoder Representations from Transformers)는 2018년 구글이 발표한 패러다임 쉬프트입니다. 기존 GPT는 “The animal didn’t cross the street because it was tired”라는 문장에서 “it”의 의미를 80%만 이해했습니다 (왼쪽 문맥만 봐서). 하지만 BERT는 앞뒤 모든 문맥을 동시에 봐서 99% 이해합니다. 마스킹된 언어 모델(MLM)이라는 혁신적인 학습 기법으로, 인터넷 전체(340억 단어)에서 15% 단어를 임의로 숨기고 “너는 이 단어가 무엇인지 맞혀봐”라고 학습시키니, 자연스럽게 양방향 이해가 가능해졌습니다. 현재 Google 검색 엔진에 BERT가 통합되어 검색 정확도가 10% 향상되었고, 일반인도 파인튜닝으로 GPT-3 수준을 만들 수 있게 되었습니다. 질문-답변 (F1 93%), 감정 분석 (96.3%), 텍스트 분류 (98%)에서 BERT 기반 모델들이 모두 SOTA를 차지하고 있습니다.


📍 목차

  1. BERT의 탄생: 언어 모델의 진화
  2. BERT 아키텍처 이해하기
  3. 사전학습(Pre-training): 마스크 언어 모델(MLM)과 NSP
  4. 파인튜닝(Fine-tuning): BERT를 우리 것으로 만들기
  5. BERT의 실제 응용: 검색, 질의응답, 감정 분석

1. BERT의 탄생: 언어 모델의 진화

1-1. BERT 이전의 문제들

좌향(Left-to-Right) 모델의 한계: GPT

문장: "The animal didn't cross the street because it was tired"

GPT의 예측 (왼쪽에서 오른쪽만):
- "The" → 다음 단어 예측
- "The animal" → 다음 단어 예측
- ...
- "The animal didn't cross the street because it" → 예측 대상: "was"

문제: "it"이 "animal"을 가리키는지 "street"를 가리키는지 뒷문맥을 못 봐서 불확실

정확도: 80% (뒷문맥 없음)

우향(Right-to-Left) 모델의 한계: 역방향 LSTM

역방향에서도 같은 문제 발생
합친다고 해도 진정한 양방향이 아님

문제의 근본 원인:

양방향 학습 시도 → 치팅 가능 (모델이 목표 단어를 직접 봄)

예시:
문장: "I went to [MASK]"
양방향 모델이 뒷문맥을 보면: "I went to school went to [MASK] today"
→ 뒷문맥에서 직접 답을 봄 ❌
→ 학습 불가능

1-2. BERT의 혁신

핵심 아이디어: “마스킹”

문장: "I went to [MASK]"

학습 방식:
- [MASK]가 무엇인지 예측하도록 학습
- 앞문맥: "I went to" (도움이 됨)
- 뒷문맥: "today" (도움이 됨)
- 하지만 [MASK] 단어 자체는 못 봄 (치팅 방지!)

결과: 자연스러운 양방향 학습 ✅

GPT vs BERT vs ELMo 비교

모델방향아키텍처사전학습특징
GPT좌향디코더좌-우 언어모델생성형, 단순
ELMo양향LSTM좌향 + 우향 별도생성 불가
BERT양향인코더MLM + NSP이해형, 강력

1-3. BERT 발표 시의 파급력

2018년 10월 BERT 발표:

GLUE 벤치마크 (자연어 이해 점수):
- 2017년까지 최고: 74.5
- BERT: 80.8 ← 6.3점 향상 (역사적 도약)

BERT 이후:
- 2019: RoBERTa (81.2)
- 2020: ALBERT, ELECTRA (82~83)
- 2021: DeBERTa (88.4)
- 2025: 최신 모델 (95% 달성)

Google 검색에 적용 (2019년):

기존 검색: 키워드 매칭 + 정규 표현식
BERT 검색: 의미 이해 + 문맥 파악

예시:
검색어: "몇 년 전에 비자 없이 갈 수 있는 국가"

기존: "비자", "국가" 키워드만 매칭
BERT: 문법 구조 + 의도 파악 → "최근에 비자 면제 된 국가" 정확히 검색

효과: 검색 정확도 10% 향상, 사용자 만족도 증가

2. BERT 아키텍처 이해하기

2-1. BERT의 기본 구조

전체 구조:

입력 문장: "Hello world"
  ↓
[Tokenization] → "Hello", "world"
  ↓
[특수 토큰 추가] → "[CLS]", "Hello", "world", "[SEP]"
  ↓
[임베딩: Token + Segment + Position]
  ↓
[Transformer 인코더 × 12층 (BERT-base)]
  또는 × 24층 (BERT-large)
  ↓
[출력]
각 토큰별 768차원 벡터 (BERT-base)
또는 1024차원 벡터 (BERT-large)

2-2. BERT의 3가지 임베딩

1️⃣ Token Embedding (토큰 임베딩)

토큰 → 임베딩 벡터 (768차원)

예시:
"Hello" → [0.2, -0.5, 0.1, ..., 0.3]
"world" → [-0.1, 0.3, -0.2, ..., 0.5]

2️⃣ Segment Embedding (문장 임베딩)

하나 또는 두 문장을 구분

예시:
[CLS] Hello world [SEP] How are you [SEP]
 0    0     0     0   1    1     1   1

첫 문장: Segment 0
두 문장: Segment 1

3️⃣ Position Embedding (위치 임베딩)

단어의 위치 정보 (학습 가능)

예시:
위치 0: [0.1, -0.2, ..., 0.0]
위치 1: [0.3, 0.1, ..., -0.2]
위치 2: [-0.5, 0.0, ..., 0.4]

최종 입력 벡터:

최종 임베딩 = Token + Segment + Position

예시 (간단히):
"Hello" 최종 = [0.2, -0.5, 0.1] + [0.0, 0.0, 0.0] + [0.1, -0.2, 0.0]
             = [0.3, -0.7, 0.1]

Python 구현:

import torch
from transformers import BertTokenizer, BertModel

# 1단계: 토크나이저
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
text = "Hello world"

# 2단계: 토큰화
tokens = tokenizer.encode(text, return_tensors='pt')
# tokens = [[101, 7592, 2088, 102]]
# 101 = [CLS], 102 = [SEP]

# 3단계: 모델 로드
model = BertModel.from_pretrained('bert-base-uncased')

# 4단계: 순전파
outputs = model(tokens)
last_hidden_states = outputs[0]  # (1, 4, 768)
# 1: 배치 크기
# 4: 시퀀스 길이 ([CLS], "Hello", "world", [SEP])
# 768: 임베딩 차원

print(f"출력 형태: {last_hidden_states.shape}")
# 출력 형태: torch.Size([1, 4, 768])

2-3. BERT-base vs BERT-large

항목BERT-baseBERT-large
층 개수1224
은닉 크기7681024
헤드 개수1216
파라미터1.1억3.4억
학습 시간16 TPU, 4일64 TPU, 4일
정확도81.5%82.1%
비용저 (1GB)높음 (3GB)

추천:

  • BERT-base: 일반적인 NLP 작업
  • BERT-large: 고정확도 필요 (질의응답 등)

3. 사전학습(Pre-training): MLM과 NSP

3-1. 마스크 언어 모델(MLM)

개념:

문장에서 15% 단어를 임의로 [MASK] 처리
→ BERT가 맞혀보기
→ 양방향 문맥 이용해서 학습

상세 과정:

# 원본 문장
sentence = "I went to school yesterday and studied"

# 1단계: 15% 선택
import random
tokens = sentence.split()  # ["I", "went", "to", "school", "yesterday", "and", "studied"]
mask_indices = random.sample(range(len(tokens)), k=int(0.15 * len(tokens)))
# mask_indices = [2, 5]

# 2단계: 마스킹
masked_sentence = tokens.copy()
masked_sentence[2] = "[MASK]"  # "to" 마스킹
masked_sentence[5] = "[MASK]"  # "and" 마스킹
# masked_sentence = ["I", "went", "[MASK]", "school", "yesterday", "[MASK]", "studied"]

# 3단계: BERT가 예측
# 입력: "I went [MASK] school yesterday [MASK] studied"
# 정답: [2] = "to", [5] = "and"
# 예측:
#  - 위치 2: "to" (정답!)
#  - 위치 5: "and" (정답!)

# 4단계: 손실함수
# L = -log(P("to" at pos 2)) - log(P("and" at pos 5))

15% 마스킹의 세부사항:

15% 단어를 선택했을 때:
- 80%: [MASK] 토큰으로 변경
- 10%: 임의의 다른 토큰으로 변경 (노이즈)
- 10%: 그대로 유지 (정상 토큰)

이유: 테스트할 때는 [MASK]가 없으니까
     모델이 모든 경우에 적응하도록 학습

MLM의 효과:

문장: "The bank robbed a lot of money"

왼쪽만 보면:
- "bank" 다음 단어 예측: "robbed" (은행이 도둑질? 이상함)

양방향 보면:
- "[MASK]"의 앞: "The"
- "[MASK]"의 뒤: "robbed a lot of money"
- 양쪽 정보로 "bank"인지 "robber"인지 구분 가능!

양방향의 중요성 ⭐⭐⭐

3-2. 다음 문장 예측(NSP)

개념:

두 문장이 주어졌을 때:
- A 다음에 정말 B가 올까?
- 이진 분류: IsNext (50%) vs NotNext (50%)

예시:

예시 1 (IsNext):
문장 A: "The man went to the store"
문장 B: "He bought a gallon of milk"
→ 자연스러운 연결

예시 2 (NotNext):
문장 A: "The man went to the store"
문장 B: "Penguins are flightless birds"
→ 부자연스러운 연결

입력 형태:
[CLS] The man went to the store [SEP] Penguins are flightless birds [SEP]
0     0    0   0    0  0  0      0    1       1   1         1       1

[CLS] 위치의 출력 → 분류 헤드 → IsNext? NotNext?

NSP의 역할:

MLM: 단어 수준의 이해 (미시적)
NSP: 문장 수준의 이해 (거시적)

NSP로 학습하면:
- 질의응답: Q-A 페어 이해
- 자연어 추론: 두 문장의 논리적 관계
- 의역 탐지: 같은 의미인지 다른 의미인지

3-3. MLM + NSP 결합 학습

전체 손실함수:

[
L = L_{MLM} + L_{NSP}
]

학습 데이터:

- BookCorpus: 80000만 단어
- Wikipedia: 26억 단어
- 합계: 약 340억 단어

학습 설정:
- 배치 크기: 256
- 학습률: 1e-4
- 훈련 스텝: 100만 스텝
- 시간: 4일 (16개 TPU)
- 비용: ~$7,000

4. 파인튜닝(Fine-tuning): BERT를 우리 것으로

4-1. 파인튜닝의 개념

대전제: BERT가 이미 언어를 알고 있다

BERT 사전학습 (구글이 해놨음):
- 340억 단어로 일반적인 언어 이해
- 가중치: 34개 파라미터

나의 작업 (예: 항공사 감정 분석):
- 항공사 리뷰: 5000개
- 감정 레이블: Positive, Negative

파인튜닝 = BERT 가중치 미세조정
- "항공사 리뷰에서 '지연'은 부정적", "서비스는 긍정적" 학습

4-2. 파인튜닝 아키텍처

분류 작업 (텍스트 분류, 감정 분석)

입력: 리뷰 텍스트 "Great flight experience!"
  ↓
[BERT]
  ↓
[CLS] 위치의 벡터 (768차원)
  ↓
[분류 헤드: Dense + Softmax]
  768 → 256 → 128 → 2 (Positive/Negative)
  ↓
출력: Positive (0.95)

코드:

from transformers import BertForSequenceClassification, Trainer, TrainingArguments
import torch

# 모델 로드
model = BertForSequenceClassification.from_pretrained(
    'bert-base-uncased',
    num_labels=2  # Binary: Positive/Negative
)

# 훈련 데이터
train_dataset = load_dataset('airline_reviews')  # 5000개

# 훈련 설정
training_args = TrainingArguments(
    output_dir='./results',
    num_train_epochs=3,
    per_device_train_batch_size=16,
    learning_rate=2e-5,  # 파인튜닝: 낮은 학습률
    warmup_steps=500
)

# 훈련
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=train_dataset
)

trainer.train()

# 예측
text = "Great flight experience!"
inputs = tokenizer(text, return_tensors='pt')
outputs = model(**inputs)
prediction = torch.argmax(outputs.logits, dim=-1)
print(f"감정: {'Positive' if prediction == 1 else 'Negative'}")

질의응답 작업 (SQuAD)

입력: [CLS] Passage [SEP] Question [SEP]
"The first Super Bowl was played on January 15, 1967"
[SEP]
"When was the first Super Bowl played?"
  ↓
[BERT]
  ↓
각 토큰별 벡터
  ↓
[시작 위치 분류] + [종료 위치 분류]
  ↓
결과: "January 15, 1967"

4-3. 파인튜닝 팁

1️⃣ 학습률 (Learning Rate)

사전학습: 1e-4 (높음)
파인튜닝: 2e-5 ~ 5e-5 (낮음)

이유: 이미 학습된 가중치를 살짝만 조정
      큰 학습률 = 기존 지식 파괴 ❌

2️⃣ 에포크 (Epochs)

데이터 많음 (>10000): 2-3 에포크
데이터 적음 (

3️⃣ 워밍업 (Warmup)

학습률을 점진적으로 증가시키기

이유: 초반 급격한 학습 방지
      더 안정적인 수렴

5. BERT의 실제 응용

5-1. Google 검색 엔진

2019년 BERT 적용 후 변화:

검색어: "2019 brazil traveler to usa need a visa"

기존 (BERT 전):
- 키워드 "traveler", "visa", "usa" 매칭
- 결과: 우수한 결과 20%

BERT 적용 후:
- 문법 이해: "traveler" = 주어 (사람)
- 의도 파악: "need a visa" = 비자 필요 여부
- 결과: 우수한 결과 100%

구글 검색 정확도 향상: 10%

Google의 공식 발표:

"세계 검색의 10% (전체 검색의 약 50억 건)이 BERT에 영향을 받습니다"

5-2. 질의응답 (Question Answering)

SQuAD 벤치마크:

데이터셋: 10만 개 Q-A 쌍

예시:
Context: "Super Bowl 50 was an American football game played on February 7, 2016"
Question: "When was Super Bowl 50 played?"

BERT-base:
- F1: 88.5%
- Exact Match: 81.8%

BERT-large:
- F1: 93.2% ⭐ (인간 수준 94.5%)
- Exact Match: 86.6%

실전 예제:

from transformers import pipeline

# 파이프라인 사용 (간단함)
qa_pipeline = pipeline('question-answering')

context = """
Apple Inc. is an American multinational technology company headquartered 
in Cupertino, California, founded on April 1, 1976.
"""

question = "When was Apple founded?"

answer = qa_pipeline(question=question, context=context)
print(f"답변: {answer['answer']}")
# 답변: April 1, 1976

5-3. 감정 분석 (Sentiment Analysis)

항공사 리뷰 감정 분석:

데이터: 130만 개 항공사 트윗

기준 모델: Naive Bayes
- 정확도: 78%

RoBERTa (BERT 개선):
- 정확도: 96.97% (이진 분류)
- 정확도: 86.89% (3-class 분류)

향상도: +20% (대진전!)

코드:

from transformers import pipeline

sentiment_pipeline = pipeline('sentiment-analysis', 
                            model='distilbert-base-uncased-finetuned-sst-2-english')

reviews = [
    "Great flight, amazing service!",
    "Delayed flight, rude staff",
    "Normal flight, nothing special"
]

for review in reviews:
    result = sentiment_pipeline(review)
    print(f"{review} → {result}")

# 출력:
# Great flight, amazing service! → POSITIVE (0.99)
# Delayed flight, rude staff → NEGATIVE (0.98)
# Normal flight, nothing special → NEUTRAL (0.95)

5-4. 텍스트 분류

뉴스 카테고리 분류:

데이터: 200만 개 뉴스 기사

카테고리:
- 스포츠
- 정치
- 연예
- 기술
- 비즈니스

BERT-base 정확도: 94%
하지만 1개 기사당 0.5초 = 느림

개선책:
1. DistilBERT 사용 (40% 빠름, 정확도 92%)
2. 양자화 (Quantization): 50% 더 빠름
3. 배치 처리: 10배 빠름

최종: 0.05초/기사 (10배 단축!) ✅

5-5. 의미론적 검색 (Semantic Search)

설명:

기존 검색: 키워드 매칭
의미론적 검색: 의미 이해

예시:
질문: "좋은 컴퓨터는 뭔가요?"

키워드 검색: "컴퓨터" 키워드 페이지만
의미론적 검색: "PC", "노트북", "laptop" 등 동의어 포함

동작 원리:
1. BERT로 질문 임베딩: [0.1, -0.5, ..., 0.3] (768차원)
2. 각 문서 임베딩: [0.12, -0.48, ..., 0.31]
3. 코사인 유사도 계산: 0.95 (매우 유사!)
4. 상위 10개 반환

코드:

from sentence_transformers import SentenceTransformer
import numpy as np

# 모델 로드 (BERT 기반)
model = SentenceTransformer('all-MiniLM-L6-v2')

# 문서들
documents = [
    "I bought a new laptop yesterday",
    "The weather is nice today",
    "She has a powerful computer",
    "Coffee is delicious"
]

# 임베딩 생성
doc_embeddings = model.encode(documents)

# 검색 쿼리
query = "desktop computer"
query_embedding = model.encode(query)

# 유사도 계산
similarities = np.dot(query_embedding, doc_embeddings.T) / (
    np.linalg.norm(query_embedding) * np.linalg.norm(doc_embeddings, axis=1)
)

# 상위 2개
top_indices = np.argsort(similarities)[::-1][:2]
for idx in top_indices:
    print(f"{documents[idx]}: 유사도 {similarities[idx]:.2f}")

# 출력:
# I bought a new laptop yesterday: 유사도 0.91
# She has a powerful computer: 유사도 0.88

6. BERT의 한계와 개선

6-1. BERT의 한계

한계설명영향
시퀀스 길이최대 512 토큰긴 문서 처리 불가
마스킹 편향학습과 실제 다름약간의 성능 저하
생성 불가인코더만 있음질문 생성 불가
속도느린 추론실시간 처리 어려움
다언어언어별 모델 필요리소스 증가

6-2. BERT의 개선 (2019-2024)

진화:

BERT (2018): 기초 (81%)
  ↓
RoBERTa (2019): 더 오래 학습, 더 많은 데이터 (82%)
  ↓
ALBERT (2020): 파라미터 감소 (83%)
  ↓
ELECTRA (2020): 다른 학습 전략 (84%)
  ↓
DeBERTa (2021): 양방향 주의 개선 (88%)
  ↓
최신 모델 (2024): 95% 달성

개선 사항:

1️⃣ 더 많은 데이터
   BERT: 340억 단어
   RoBERTa: 160억 단어 (추가 학습)
   → 성능 향상

2️⃣ 더 큰 배치
   BERT: 256
   RoBERTa: 8192
   → 더 좋은 최적화

3️⃣ 다른 마스킹 전략
   ELECTRA: 마스킹 대신 교체
   → 더 효율적

4️⃣ 더 나은 아키텍처
   DeBERTa: 양방향 주의 분리
   → 더 표현 가능

FAQ: BERT 입문자를 위한 질문

Q1. BERT는 정말 양방향인가? GPT도 가능하지 않을까?

A. 양방향은 가능하지만 방식이 다릅니다. BERT는 학습 시 양방향 (MLM), GPT는 생성 시 단방향입니다. 이유: BERT는 순수 이해 모델 (BERT = 읽기만), GPT는 생성 모델 (생성하려면 순서 중요). BERT가 양방향이라서 이해 정확도는 SOTA이지만, 글쓰기는 못 합니다.

Q2. 파인튜닝할 때 전체 모델을 학습해야 하나?

A. 일반적으로 Yes, 전체 학습합니다. 하지만: (1) 데이터 많음 (100K+): 전체 학습, (2) 데이터 적음 (

Q3. BERT-base vs BERT-large, 뭘 써야 하나?

A. 데이터 양에 따라: (1) : BERT-base (빠르고 충분), (2) 10K~100K: BERT-base 추천, (3) >100K: BERT-large 고려. 또 다른 고려사항: (1) 속도 중요: DistilBERT (BERT의 40% 크기), (2) 정확도 중요: BERT-large 또는 최신 모델.

Q4. BERT를 실시간으로 배포할 수 있나?

A. 기본은 느립니다 (1문장 0.1~0.5초). 가속화 방법: (1) ONNX 변환: 2배 빠름, (2) 양자화: 4배 빠름, (3) 지식 증류: 10배 빠름 (정확도 약간 저하), (4) 배치 처리: 훨씬 빠름. 실제 서비스는 모두 위의 최적화 기법 사용.

Q5. 한국어 BERT는?

A. 여러 선택지 있습니다: (1) mBERT (다언어), (2) KoBERT (한국 특화, 성능 95%), (3) HanBERT (성능 96%), (4) DistilKoBERT (빠름, 성능 93%). 추천: 성능 중요 → HanBERT, 속도 중요 → DistilKoBERT.


외부 참고 자료

BERT를 더 깊게 배우고 싶다면:


최종 정리: BERT의 의미

BERT는 단순 모델이 아니라 패러다임 쉬프트입니다.

Before BERT (2017):
- 각 작업마다 새 모델 설계 필요
- 한국어, 중국어 등 언어별 모델 필요
- NLP 전문가만 가능

After BERT (2018~):
- 한 가지 모델 (BERT)로 모든 작업 가능
- 파인튜닝만으로 충분
- 누구나 가능 (Hugging Face 덕분)

BERT의 영향:

직접 영향:
- Google 검색 개선 (50억 건/일)
- 형태소 분석기 개선 (정확도 94%)
- 챗봇 성능 향상

간접 영향:
- BERT 후속 모델: RoBERTa, ELECTRA, DeBERTa...
- 멀티모달: ViLBERT (이미지+텍스트)
- 이 모든 것이 BERT의 영감으로 시작

2025년 현재:

BERT 자체는 "레거시"지만, BERT의 철학은 여전히 유효합니다:
✅ 대규모 사전학습 (필수)
✅ 파인튜닝 (효율적)
✅ 양방향 이해 (중요)
✅ 공개 가중치 (획기적)

축하합니다! AI 101 시리즈 완주를 위해 한 걸음 더 나아갔습니다. 다음은 GPT 시리즈 – 생성형 AI의 진화로 ChatGPT, GPT-4의 비밀을 파헤칩니다!


같이보기

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다