개요
**“Attention is All You Need”**는 2017년 구글의 8명의 연구자들이 발표한 논문으로, 현대 인공지능의 토대가 된 Transformer(트랜스포머) 구조를 처음 소개했습니다1. 이 논문은 ChatGPT, GPT-4, BERT 같은 현대의 거의 모든 대형 언어 모델의 기반이 되었으며, AI 붐을 일으킨 핵심 기술입니다.
2025년 기준으로 173,000회 이상 인용되어 21세기에 가장 많이 인용된 논문 10편 중 하나입니다2.
왜 혁명적인가?
이전 방식의 문제점
Transformer 이전에는 문장을 번역하거나 이해할 때 RNN(순환 신경망)이나 LSTM 같은 모델을 사용했습니다. 이 모델들의 큰 문제는:
-
순차적 처리: 문장을 앞에서부터 한 단어씩 순서대로 처리해야 했습니다
- “나는 오늘 학교에 갔다” 라는 문장이 있으면, “나는” → “오늘” → “학교에” → “갔다” 순서로 하나씩 처리
- 마치 책을 한 글자씩만 읽을 수 있는 것과 같아서 매우 느렸습니다
-
장거리 의존성 문제: 문장이 길어질수록 앞부분의 정보를 잊어버리는 경향
- 긴 문장의 첫 단어와 마지막 단어의 관계를 파악하기 어려웠습니다
Transformer의 해결책
Transformer는 Attention(주목) 메커니즘만을 사용하여 이 문제들을 해결했습니다. 핵심 아이디어는:
모든 단어를 동시에 보면서, 각 단어가 다른 어떤 단어들과 관련이 있는지 파악하는 것입니다.
Attention 메커니즘이란?
Attention을 일상적인 예시로 이해해봅시다.
비유: 책 읽기
책을 읽을 때 우리는:
- 현재 문장을 읽으면서도
- 이전 페이지의 관련 내용을 떠올리고
- 특정 단어가 나오면 앞에서 언급된 인물이나 사건을 연결합니다
이것이 바로 Attention입니다. 지금 보고 있는 것과 관련된 정보에 “주목”하는 능력입니다.
기술적 설명
“나는 학교에 갔다”라는 문장에서:
- “갔다”를 이해할 때 → “나는”과 “학교에”에 주목
- “학교에”를 이해할 때 → “갔다”에 주목하여 목적지임을 파악
Attention 메커니즘은 각 단어가 문장 내 다른 모든 단어들과 얼마나 관련이 있는지 점수를 계산하고, 관련성이 높은 단어들에 더 집중합니다.
Self-Attention의 구체적 작동 원리
Self-Attention은 3가지 핵심 구성 요소를 사용합니다: Query(질문), Key(열쇠), Value(값)
Query, Key, Value 이해하기
실생활 비유: 도서관에서 책 찾기
- Query (질문): “나는 기계 학습에 대한 책을 찾고 있어”
- Key (열쇠): 각 책의 목차나 키워드 (“인공지능”, “데이터 분석”, “요리법” 등)
- Value (값): 실제 책의 내용
도서관 사서(Attention 메커니즘)는:
- 당신의 질문(Query)과 각 책의 키워드(Key)를 비교
- 얼마나 관련 있는지 점수를 매김
- 관련성이 높은 책의 내용(Value)을 가져옴
단계별 계산 과정
문장: “The animal didn’t cross the street because it was too tired”
1단계: Query, Key, Value 벡터 생성
각 단어의 임베딩(예: 512차원)을 세 개의 가중치 행렬과 곱하여 생성:
- Query 벡터 (q): 64차원
- Key 벡터 (k): 64차원
- Value 벡터 (v): 64차원
단어 "it"의 임베딩 × W_Q = Query 벡터 "it"
단어 "it"의 임베딩 × W_K = Key 벡터 "it"
단어 "it"의 임베딩 × W_V = Value 벡터 "it"
2단계: Attention 점수 계산
단어 “it”이 무엇을 가리키는지 파악하기 위해, “it”의 Query와 모든 단어의 Key를 내적(dot product):
"it" Query · "The" Key = 2
"it" Query · "animal" Key = 96 ← 높은 점수!
"it" Query · "didn't" Key = 1
"it" Query · "cross" Key = 8
"it" Query · "the" Key = 3
"it" Query · "street" Key = 12
"it" Query · "because" Key = 4
"it" Query · "it" Key = 112 ← 가장 높은 점수
"it" Query · "was" Key = 5
"it" Query · "too" Key = 2
"it" Query · "tired" Key = 88 ← 높은 점수!
3단계: 정규화 (Scaling)
점수를 Key 벡터 차원의 제곱근(√64 = 8)으로 나눔:
- 이유: 큰 내적 값은 softmax를 극단적으로 만들어 학습을 어렵게 함
점수들을 8로 나눔:
"animal": 96/8 = 12
"it": 112/8 = 14
"tired": 88/8 = 11
...
4단계: Softmax 적용
점수들을 확률 분포로 변환 (모든 값의 합 = 1):
"The": 0.01
"animal": 0.32 ← "it"이 "animal"을 가리킬 확률 32%
"didn't": 0.00
"cross": 0.02
"the": 0.01
"street": 0.03
"because": 0.01
"it": 0.40 ← 자기 자신에 대한 주목 40%
"was": 0.01
"too": 0.01
"tired": 0.18 ← "tired"와도 관련성 18%
5단계: Value 벡터에 가중치 적용
각 단어의 Value 벡터에 softmax 점수를 곱함:
"animal" Value × 0.32 = [강하게 반영]
"it" Value × 0.40 = [가장 강하게 반영]
"tired" Value × 0.18 = [중간 정도 반영]
"The" Value × 0.01 = [거의 반영 안 됨]
...
6단계: 가중합 계산
모든 가중치가 적용된 Value 벡터를 더하여 최종 출력:
출력 벡터 for "it" = ∑(softmax 점수 × Value 벡터)
= (0.32 × V_animal) + (0.40 × V_it) + (0.18 × V_tired) + ...
이 출력 벡터는 “it”이 주로 “animal”과 “tired”를 참조한다는 정보를 담고 있습니다!
시각화
입력: [The] [animal] [didn't] [cross] [the] [street] [because] [it] [was] [too] [tired]
↑
이 단어를 처리 중
Attention 가중치:
The : ▁ (0.01)
animal : ████████████ (0.32) ← 강한 연관성
didn't : ▁ (0.00)
cross : ▁ (0.02)
the : ▁ (0.01)
street : ▁ (0.03)
because : ▁ (0.01)
it : ██████████████ (0.40) ← 자기 자신
was : ▁ (0.01)
too : ▁ (0.01)
tired : ██████ (0.18) ← 중간 연관성
결과: "it"은 주로 "animal"을 가리키며, "tired"와도 관련이 있음
Multi-Head Attention의 장점
실제 Transformer는 8개의 서로 다른 Query/Key/Value 가중치 세트를 사용합니다:
- 헤드 1: “it” → “animal” 관계 포착 (누가?)
- 헤드 2: “it” → “tired” 관계 포착 (어떤 상태?)
- 헤드 3: “cross” → “street” 관계 포착 (무엇을 건너?)
- 헤드 4: 문법적 관계 포착
- 헤드 5~8: 다른 의미적 측면들
각 헤드가 다른 관점에서 문장을 분석하고, 모든 결과를 합쳐서 풍부한 이해를 만듭니다.
Transformer 구조
Transformer는 크게 두 부분으로 구성됩니다:
1. Encoder (인코더)
역할: 입력 문장을 이해하고 의미를 파악
작동 방식:
- 입력 문장의 모든 단어를 동시에 처리
- Self-Attention을 통해 각 단어가 문장 내 다른 단어들과 어떤 관계인지 파악
- 6개의 동일한 층이 쌓여 있어, 점점 더 깊은 이해를 만듭니다
비유: 책을 읽는 독자
- 한 번에 전체 문장을 보면서
- 단어들 간의 관계를 파악하고
- 문장의 전체적인 의미를 이해합니다
2. Decoder (디코더)
역할: 이해한 내용을 바탕으로 결과(번역 등)를 생성
작동 방식:
- Encoder가 이해한 내용을 참고
- 지금까지 생성한 단어들을 보면서
- 다음에 올 단어를 예측하여 하나씩 생성
비유: 통역사
- 원문(Encoder의 이해)을 참고하면서
- 지금까지 말한 내용을 기억하고
- 다음 단어를 자연스럽게 이어갑니다
핵심 구성 요소
Multi-Head Attention (다중 헤드 어텐션)
여러 개의 “주목 관점”을 동시에 사용합니다.
비유: 여러 전문가가 동시에 문장 분석
- 전문가 A: 문법적 관계 파악 (주어-동사 관계 등)
- 전문가 B: 의미적 연관성 파악 (유사한 개념 찾기)
- 전문가 C: 감정이나 뉘앙스 파악
각 “헤드(head)“가 다른 측면에서 단어 관계를 파악하여, 더 풍부하고 다양한 이해가 가능합니다.
Positional Encoding (위치 인코딩)
모든 단어를 동시에 처리하기 때문에, 순서 정보를 별도로 알려줘야 합니다.
비유: 책의 페이지 번호
- 단어들이 섞여 있어도
- 각 단어에 “몇 번째 위치인지” 표시를 추가
- “1번째: 나는, 2번째: 학교에, 3번째: 갔다” 식으로 순서를 기억
Transformer는 사인(sine)과 코사인(cosine) 함수를 사용하여 각 위치에 고유한 값을 부여합니다.
Feed-Forward Network (피드포워드 네트워크)
각 단어의 표현을 더욱 정교하게 다듬습니다.
비유: 편집자의 교정
- Attention으로 이해한 내용을
- 더 명확하고 정제된 형태로 변환
- 각 단어를 독립적으로 처리
왜 혁신적인가?
1. 병렬 처리 가능
이전 방식:
나는 → (처리 완료) → 학교에 → (처리 완료) → 갔다
순차적으로 하나씩 처리
Transformer:
나는 + 학교에 + 갔다 → 동시에 처리
모든 단어를 한 번에 처리
이로 인해:
- 학습 속도가 획기적으로 빨라짐
- GPU를 효율적으로 활용 가능
- 더 큰 모델과 데이터셋 학습 가능
2. 장거리 의존성 해결
아무리 문장이 길어도, 첫 단어와 마지막 단어를 직접 연결하여 관계를 파악할 수 있습니다.
예시: “나는 어제 아침 일찍 일어나서, 운동을 하고, 샤워를 한 후, 아침을 먹고, 옷을 갈아입고, 학교에 갔다”
- 이전 방식: “나는”과 “갔다”의 관계 파악이 어려움 (중간 정보 손실)
- Transformer: 직접 연결하여 “나는”이 “갔다”의 주체임을 명확히 파악
3. 범용성
처음에는 번역을 위해 만들어졌지만, 다양한 분야로 확장되었습니다:
- 자연어 처리: GPT, BERT, ChatGPT 등 대부분의 언어 모델
- 컴퓨터 비전: Vision Transformer (이미지 인식)
- 음성 인식: Whisper 등
- 멀티모달: CLIP, GPT-4 (텍스트+이미지 동시 처리)
실제 성과
논문에서 보고한 기계 번역 성과:
- 영어→독일어 번역: 당시 최고 성능 달성 (BLEU 점수 28.4)
- 영어→프랑스어 번역: 새로운 최고 기록 (BLEU 점수 41.8)
- 학습 시간: 기존 모델보다 훨씬 짧은 시간으로 더 좋은 성능
영향력
Transformer는 현대 AI의 기반이 되었습니다:
- GPT 시리즈 (GPT-2, GPT-3, GPT-4, ChatGPT): Transformer의 Decoder 부분만 사용
- BERT: Transformer의 Encoder 부분만 사용
- T5, BART: Encoder와 Decoder 모두 사용
2020년대 AI 붐의 핵심 기술이며, 거의 모든 최신 언어 모델과 생성형 AI가 Transformer 구조를 기반으로 합니다.
주요 저자
- Ashish Vaswani (제1저자)
- Noam Shazeer
- Niki Parmar
- Jakob Uszkoreit
- Llion Jones
- Aidan N. Gomez
- Łukasz Kaiser
- Illia Polosukhin
모두 구글에서 근무했으며, 이 논문 발표 후 일부는 OpenAI, Anthropic 등 주요 AI 기업을 설립하거나 합류했습니다.
구현 예제
Python으로 Self-Attention 구현하기
PyTorch를 사용한 Scaled Dot-Product Attention의 핵심 구현:
import torch
import torch.nn.functional as F
import math
def scaled_dot_product_attention(query, key, value, mask=None):
"""
Scaled Dot-Product Attention 계산
Args:
query: Query 행렬 (batch_size, seq_len, d_k)
key: Key 행렬 (batch_size, seq_len, d_k)
value: Value 행렬 (batch_size, seq_len, d_v)
mask: 마스킹 (선택적, padding이나 미래 토큰 숨기기 용도)
Returns:
output: Attention 적용된 결과
attention_weights: Attention 가중치 (시각화 가능)
"""
# 1. Query와 Key의 내적 계산
d_k = query.size(-1)
scores = torch.matmul(query, key.transpose(-2, -1))
# 2. Scaling: √d_k로 나누기
scores = scores / math.sqrt(d_k)
# 3. 마스킹 적용 (선택적)
if mask is not None:
# 마스킹된 위치는 매우 작은 값으로 (-∞에 가까운 값)
scores = scores.masked_fill(mask == 0, -1e9)
# 4. Softmax로 확률 분포 변환
attention_weights = F.softmax(scores, dim=-1)
# 5. Value와 가중합 계산
output = torch.matmul(attention_weights, value)
return output, attention_weights
사용 예제
# 예제: 3개 단어, 임베딩 차원 64
batch_size = 1
seq_len = 3
d_model = 64
# 임의의 Query, Key, Value 생성
query = torch.randn(batch_size, seq_len, d_model)
key = torch.randn(batch_size, seq_len, d_model)
value = torch.randn(batch_size, seq_len, d_model)
# Attention 계산
output, attention_weights = scaled_dot_product_attention(query, key, value)
print(f"출력 크기: {output.shape}") # (1, 3, 64)
print(f"Attention 가중치 크기: {attention_weights.shape}") # (1, 3, 3)
# Attention 가중치 확인 (각 단어가 다른 단어들에 주목하는 정도)
print("\nAttention 가중치:")
print(attention_weights[0])
# 출력 예:
# tensor([[0.35, 0.33, 0.32], # 첫 번째 단어
# [0.28, 0.45, 0.27], # 두 번째 단어
# [0.31, 0.29, 0.40]]) # 세 번째 단어
Multi-Head Attention 구현
class MultiHeadAttention(torch.nn.Module):
def __init__(self, d_model=512, num_heads=8):
"""
Multi-Head Attention 모듈
Args:
d_model: 모델의 임베딩 차원
num_heads: Attention 헤드 개수
"""
super().__init__()
assert d_model % num_heads == 0, "d_model은 num_heads로 나누어떨어져야 합니다"
self.d_model = d_model
self.num_heads = num_heads
self.d_k = d_model // num_heads # 각 헤드의 차원
# Query, Key, Value를 위한 선형 변환
self.W_q = torch.nn.Linear(d_model, d_model)
self.W_k = torch.nn.Linear(d_model, d_model)
self.W_v = torch.nn.Linear(d_model, d_model)
# 최종 출력을 위한 선형 변환
self.W_o = torch.nn.Linear(d_model, d_model)
def forward(self, query, key, value, mask=None):
batch_size = query.size(0)
# 1. 선형 변환 후 multi-head로 분할
# (batch, seq_len, d_model) -> (batch, seq_len, num_heads, d_k)
Q = self.W_q(query).view(batch_size, -1, self.num_heads, self.d_k)
K = self.W_k(key).view(batch_size, -1, self.num_heads, self.d_k)
V = self.W_v(value).view(batch_size, -1, self.num_heads, self.d_k)
# 2. 차원 재배열: (batch, num_heads, seq_len, d_k)
Q = Q.transpose(1, 2)
K = K.transpose(1, 2)
V = V.transpose(1, 2)
# 3. 각 헤드에서 Attention 계산
scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(self.d_k)
if mask is not None:
scores = scores.masked_fill(mask == 0, -1e9)
attention = F.softmax(scores, dim=-1)
output = torch.matmul(attention, V)
# 4. 헤드들을 다시 합침
# (batch, num_heads, seq_len, d_k) -> (batch, seq_len, d_model)
output = output.transpose(1, 2).contiguous()
output = output.view(batch_size, -1, self.d_model)
# 5. 최종 선형 변환
output = self.W_o(output)
return output, attention
# 사용 예제
mha = MultiHeadAttention(d_model=512, num_heads=8)
x = torch.randn(1, 10, 512) # (batch=1, seq_len=10, d_model=512)
output, attention = mha(x, x, x)
print(f"Multi-Head Attention 출력: {output.shape}") # (1, 10, 512)
print(f"Attention 가중치: {attention.shape}") # (1, 8, 10, 10)
핵심 수식
Scaled Dot-Product Attention:
Multi-Head Attention:
여기서:
실제 활용 코드 (Hugging Face Transformers)
from transformers import BertTokenizer, BertModel
import torch
# BERT 모델 로드 (Transformer의 Encoder 부분 사용)
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertModel.from_pretrained('bert-base-uncased',
output_attentions=True) # Attention 가중치 출력
# 텍스트 입력
text = "The animal didn't cross the street because it was too tired"
inputs = tokenizer(text, return_tensors='pt')
# 모델 실행
with torch.no_grad():
outputs = model(**inputs)
# Attention 가중치 확인
# outputs.attentions: 각 레이어의 attention weights
# (12개 레이어, 각 레이어마다 12개 헤드)
attention = outputs.attentions # Tuple of (12 layers)
first_layer_attention = attention[0] # 첫 번째 레이어
print(f"레이어 개수: {len(attention)}") # 12
print(f"첫 레이어 attention 크기: {first_layer_attention.shape}")
# (batch_size, num_heads, seq_len, seq_len)
# "it" 토큰이 어느 단어에 주목하는지 확인
tokens = tokenizer.convert_ids_to_tokens(inputs['input_ids'][0])
print("\n토큰:", tokens)
# 예: "it" 토큰의 attention 가중치 (헤드 0)
it_position = tokens.index('it')
it_attention = first_layer_attention[0, 0, it_position, :] # (seq_len,)
print(f"\n'it'이 주목하는 단어들:")
for i, (token, weight) in enumerate(zip(tokens, it_attention)):
if weight > 0.1: # 가중치가 0.1 이상인 것만 출력
print(f" {token}: {weight:.3f}")
핵심 개념 요약
- Attention: 각 단어가 다른 단어들과 얼마나 관련 있는지 파악하는 메커니즘
- Self-Attention: 한 문장 내에서 단어들끼리 서로의 관계를 파악
- Multi-Head Attention: 여러 관점에서 동시에 관계를 파악
- Positional Encoding: 단어의 순서 정보를 추가
- Encoder-Decoder: 이해(Encoder)와 생성(Decoder)의 분리된 구조
- 병렬 처리: 모든 단어를 동시에 처리하여 속도 향상
참고 자료
논문
- 원문 논문 (arXiv) - 원본 논문
- Attention Is All You Need - Wikipedia - 논문 개요 및 영향력
학습 자료 (강력 추천)
- The Illustrated Transformer - 시각적 설명, 초보자에게 가장 적합
- The Annotated Transformer - 코드와 함께 단계별 구현
- Transformer Explainer - 인터랙티브 시각화
구현 및 활용
- Hugging Face Transformers 문서 - 실제 사용 가능한 사전 학습 모델
- PyTorch nn.Transformer 문서 - PyTorch 공식 Transformer API
Footnotes
-
Vaswani, A., Shazeer, N., Parmar, N., Uszkoreit, J., Jones, L., Gomez, A. N., Kaiser, Ł., & Polosukhin, I. (2017). “Attention is All You Need”. 31st Conference on Neural Information Processing Systems (NeurIPS 2017, 당시 NIPS). ↩
-
“Attention Is All You Need” Wikipedia, accessed 2025-10-06. 173,000+ citations as of 2025. ↩