티스토리 뷰
핵심 요약
"양방향"이라는 단어가 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 에포크
데이터 적음 (<1000): 3-5 에포크
이유: 데이터가 적으면 과적합 위험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) 데이터 적음 (<1K): 마지막 3층만 학습 가능. 근데 최근 추세: 전체를 낮은 학습률로 학습이 더 좋음.
Q3. BERT-base vs BERT-large, 뭘 써야 하나?
A. 데이터 양에 따라: (1) <10K: 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의 비밀을 파헤칩니다!
'AI' 카테고리의 다른 글
| [AI 101] BERT vs GPT - 두 거인의 차이점 (0) | 2025.12.05 |
|---|---|
| [AI 101] GPT - 창의적인 글을 쓰는 AI (1) | 2025.12.05 |
| [AI 101] Transformer - AI 혁명의 시작 (0) | 2025.12.05 |
| [AI 101] CNN과 RNN의 결합 - 복합 모델의 무한한 가능성 (0) | 2025.12.05 |
| [AI 101] RNN과 LSTM - 시간을 기억하는 AI의 마법 (0) | 2025.12.05 |
- Total
- Today
- Yesterday
- Next.js보안
- 강화학습
- React2Shell
- 사이버보안
- Reinforcement Learning
- Supervised Learning
- 원격코드실행
- 머신러닝
- 군집화
- 분류
- k-means
- CVE-2025-55182
- 중국해킹
- React취약점
- Unsupervised Learning
- AI 학습
- 해킹
- 고객 세분화
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
