[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를 차지하고 있습니다.
📍 목차
- BERT의 탄생: 언어 모델의 진화
- BERT 아키텍처 이해하기
- 사전학습(Pre-training): 마스크 언어 모델(MLM)과 NSP
- 파인튜닝(Fine-tuning): BERT를 우리 것으로 만들기
- 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 13️⃣ 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-base | BERT-large |
|---|---|---|
| 층 개수 | 12 | 24 |
| 은닉 크기 | 768 | 1024 |
| 헤드 개수 | 12 | 16 |
| 파라미터 | 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,0004. 파인튜닝(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, 19765-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.886. 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를 더 깊게 배우고 싶다면:
- arXiv – BERT 원본 논문 – Jacob Devlin 등 (2018)
- WikiDocs – BERT 완벽 가이드 – 한글 설명
- Hugging Face – BERT – 공식 구현
- Google AI – BERT 블로그 – 발표 글
- GLUE 벤치마크 – 성능 비교
최종 정리: 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의 비밀을 파헤칩니다!
