Attention 메커니즘 - AI에게 '집중력'을 선물한 기술 (feat. Transformer)
1. 프롤로그 - 번역기가 긴 문장을 망치는 이유
제가 처음 자연어 처리(NLP)를 공부하며 챗봇을 만들었을 때의 일입니다. "안녕?", "오늘 날씨 어때?" 같은 짧은 문장은 기가 막히게 알아들었습니다. 하지만 문장이 조금만 길어져도 챗봇은 횡설수설하기 시작했습니다.
"어제 친구랑 강남역에서 만나서 밥을 먹었는데, 거기가 원래 웨이팅이 긴 곳이라 걱정했지만 다행히 바로 들어갔어"라는 문장을 당시의 번역기(RNN 기반)에 넣으면, 뒷부분에 가서는 "밥을 먹었다"는 사실을 까먹고 "긴 곳이라 걱정했다"는 말만 앵무새처럼 반복하곤 했습니다.
이것이 바로 초기 딥러닝 모델인 RNN(Recurrent Neural Network)의 치명적인 단점, "장기 의존성 문제(Long-term Dependency Problem)"였습니다. 문장을 순서대로(Sequential) 읽다 보니, 문장이 길어질수록 앞쪽의 중요한 정보를 잃어버리는 일종의 '디지털 치매' 현상이었죠.
이 문제를 해결하기 위해 등장한 구세주가 바로 Attention(어텐션) 메커니즘입니다. 오늘은 구글이 2017년 "Attention Is All You Need"라는 도발적인 논문으로 세상을 뒤집기 전, 우리가 어떤 삽질을 했는지와 Attention이 어떻게 AI에게 '집중력'을 선물했는지 제 관점에서 정리해 보았습니다.
2. 처음엔 뭐가 이해가 안 갔나
Attention을 처음 독학할 때 가장 난해했던 건 용어의 장벽이었습니다.
- "Query, Key, Value? 갑자기 웬 데이터베이스 용어?"
- "벡터 내적(Dot Product)을 하면 왜 유사도가 나오지?"
- "Self-Attention이랑 그냥 Attention은 뭐가 다른 거지?"
특히 수식에 압도되어 본질을 보지 못했습니다. Attention(Q, K, V) = softmax(QKᵀ / √dₖ) · V 같은 수식을 보면 누구나 '뒤로 가기'를 누르고 싶어집니다. 하지만 코드로 한 줄 한 줄 뜯어보고 나서야, 이것이 사실은 "가중 평균(Weighted Average)"을 구하는 아주 세련된 통계적 방식일 뿐이라는 걸 깨달았습니다.
3. 어떤 포인트에서 이해가 됐나
이 복잡한 개념을 한방에 이해시켜 준 비유는 "도서관 사서와 검색 시스템" 그리고 "칵테일 파티 효과"였습니다.
비유 1 - 도서관 검색 시스템 (Query, Key, Value)
여러분이 도서관 키오스크에서 책을 찾는 상황을 상상해 보세요.
- Query (질문): 여러분이 검색창에 입력한 검색어입니다. (예: "머신러닝 입문")
- Key (색인): 도서관의 모든 책들에 붙어 있는 제목이나 태그입니다. (예: "파이썬 딥러닝", "머신러닝 실습", "요리 대백과")
- Value (내용): 실제 책의 내용(본문)입니다.
Attention 알고리즘은 다음 3단계로 작동합니다.
- 유사도 측정 (Similarity Calculation): 내 검색어(Query)와 모든 책 제목(Key)이 얼마나 비슷한지 비교합니다.
- "머신러닝 입문" vs "요리 대백과" -> 유사도 0.01 (무시)
- "머신러닝 입문" vs "머신러닝 실습" -> 유사도 0.95 (높음)
- 주목 (Softmax): 유사도가 높은 책에 더 많은 점수(가중치)를 줍니다. 합쳐서 100%가 되도록 확률로 변환합니다.
- 정보 가져오기 (Weighted Sum): 점수가 높은 책들의 내용(Value)을 위주로 정보를 섞어서 가져옵니다.
이것이 끝입니다. AI도 문장을 번역할 때 "I(나)"라는 단어를 번역하기 위해 입력 문장의 모든 단어(Key)를 훑어보고, 가장 관련 있는 단어(Value)에 집중(Attention)하는 것입니다.
비유 2 - 칵테일 파티 효과 (Cocktail Party Effect)
시끄러운 클럽이나 파티장에서도 우리는 내 이름이 들리거나 흥미로운 대화 주제가 나오면 그 소리만 귀신같이 골라 들을 수 있습니다. 귀에는 모든 소음이 다 들어오지만(Input), 뇌가 특정 주파수나 패턴에 가중치(Weight)를 둬서 처리(Processing)하는 것이죠.
Attention 메커니즘이 바로 AI에게 이 "선택적 청취 능력(Selective Hearing)"을 부여한 기술입니다.
4. 깊게 파고들기 - 메커니즘의 해부
(1) Dot-Product Attention (내적 어텐션)
그렇다면 "유사도"를 수학적으로 어떻게 계산할까요? 가장 간단하고 계산 효율적인 방법이 벡터의 내적(Dot Product)입니다. 고등학교 기하와 벡터 시간에 배웠듯이, 두 벡터의 방향이 비슷할수록 내적 값은 커집니다.
- $Query \cdot Key = Score$
- Query가 "사과"($[1, 0, 0]$)이고 Key가 "과일"($[0.9, 0.1, 0]$)이면 벡터가 비슷해서 점수가 높습니다.
- Query가 "사과"이고 Key가 "자동차"($[0, 0, 1]$)면 직교해서 점수가 0에 가깝습니다.
(2) Softmax: 점수를 확률로 변환
내적 점수는 100이 될 수도, -50이 될 수도 있습니다. 이를 "합쳐서 1.0(100%)이 되는 확률"로 바꿔주는 것이 Softmax 함수입니다. 이 확률 분포가 바로 "어디를 얼마나 쳐다볼 것인가(Attention Weight)"를 결정합니다.
(3) Multi-Head Attention: 천수관음의 눈
트랜스포머 논문의 핵심은 "Attention을 한 번만 하지 말고, 여러 번 동시에 하자"는 것입니다. 이것이 Multi-Head Attention입니다. 왜 머리가 여러 개 필요할까요? 우리가 문장을 이해할 때 여러 관점이 필요하기 때문입니다.
- Head 1: 문법적 관계(주어-동사)에 집중합니다. ("I"와 "am"의 관계)
- Head 2: 의미적 관계(대명사-지칭 대상)에 집중합니다. ("it"과 "dog"의 관계)
- Head 3: 시제나 장소 정보에 집중합니다.
마치 8명의 전문가가 각자 다른 관점에서 문장을 분석하고, 그 결과를 합치는 것과 같습니다. 이 덕분에 AI는 문맥을 입체적으로 이해하게 됩니다.
5. Self-Attention: 트랜스포머의 심장
기존 Attention은 번역기에서 "영어 문장(Source)"과 "프랑스어 문장(Target)" 사이를 연결하는 다리였습니다. 하지만 구글 연구진은 천재적인 발상을 합니다. "문장 안에서 자기 자신끼리 Attention을 하면 어떨까?"
이것이 Self-Attention입니다. 예문: "The animal didn't cross the street because it was too tired."
여기서 it이 가리키는 것은 무엇일까요? 'animal'일까요, 'street'일까요? 전통적인 통계 기반 모델은 이걸 헷갈려했습니다. 하지만 Self-Attention을 사용하는 모델은 'it'이라는 단어를 처리할 때 문장 내 모든 단어와의 내적을 계산합니다. 그 결과 'it'은 'street'보다 'animal'과 훨씬 높은 Attention 점수(유사도)를 갖게 되고, AI는 "it = animal"이라는 것을 스스로 깨닫습니다.
이 Self-Attention 블록을 레고처럼 층층이 쌓아 올린 괴물이 바로 그 유명한 Transformer 모델이고, 이것의 인코더를 떼어내 키운 게 BERT, 디코더를 키운 게 GPT입니다.
6. 실제로의 활용 (PyTorch 구현)
백번 듣는 것보다 코드로 한 번 보는 게 낫습니다. 가장 투박하지만 핵심을 담은 Scaled Dot-Product Attention 구현입니다.
import torch
import torch.nn as nn
import torch.nn.functional as F
import math
def scaled_dot_product_attention(query, key, value, mask=None):
"""
Args:
query: (Batch_Size, Num_Heads, Seq_Len, Depth)
key: (Batch_Size, Num_Heads, Seq_Len, Depth)
value: (Batch_Size, Num_Heads, Seq_Len, Depth)
"""
d_k = query.size(-1) # 키 벡터의 차원 크기
# 1. Score 계산: Q와 K의 행렬 곱 (내적)
# transpose(-2, -1)로 K를 전치시켜야 곱셈이 가능합니다.
scores = torch.matmul(query, key.transpose(-2, -1)) / math.sqrt(d_k)
# 2. 마스킹 (Masking)
# 패딩(padding) 토큰이나 미래의 단어를 보지 못하게 가리는 작업
if mask is not None:
scores = scores.masked_fill(mask == 0, -1e9)
# 3. Attention Weights 계산 (Softmax)
# 점수를 0~1 사이의 확률값으로 변환
attention_weights = F.softmax(scores, dim=-1)
# 4. 가중합 (Weighted Sum) 계산
# 확률에 따라 Value(실제 정보)를 섞어서 가져옴
output = torch.matmul(attention_weights, value)
return output, attention_weights
이 코드가 현대 NLP의 모든 것을 지탱하고 있는 심장입니다. 코드를 보면 파라미터(학습되는 가중치)가 하나도 없습니다. 그저 행렬 곱셈뿐입니다. 학습되는 가중치는 Query, Key, Value를 만들어내는 Linear Layer들에 들어있습니다.
7. 텍스트를 넘어 이미지로: Vision Transformer (ViT)
Attention 메커니즘은 텍스트(NLP)에서 시작했지만, 이제는 이미지 처리(Computer Vision) 분야까지 정복했습니다. Vision Transformer (ViT)가 대표적입니다.
- 기존 CNN: 이미지를 픽셀 단위로 훑으며 주변(Local) 특징을 찾았습니다.
- ViT: 이미지를 16x16 크기의 조각(Patch)으로 잘라서, 각 조각을 단어(Token)처럼 취급합니다.
- 그리고 조각들끼리 Self-Attention을 수행합니다.
- "강아지 코 조각"을 볼 때 "강아지 귀 조각"과 "강아지 꼬리 조각"에 높은 Attention을 줍니다.
- 이를 통해 이미지를 전체적(Global)으로 이해하게 됩니다.
이제 Attention은 모달리티(Modality)를 가리지 않는 범용 알고리즘이 되었습니다.
8. 요약 및 마무리
개발자로서 AI 기술을 대할 때, 복잡한 수식의 숲에 빠져 길을 잃지 않는 것이 중요합니다. Attention의 본질은 결국 "정보의 홍수 속에서 중요한 것에 선택과 집중을 하는 메커니즘"입니다.
- RNN의 한계: 긴 문장을 기억하지 못함 (치매 현상, Gradient Vanishing).
- Attention의 해결책: 모든 단어를 다 연결해놓고, 상황에 따라 중요한 단어에 가중치(Weight)를 줌.
- 비유: 도서관에서 "Query(검색어)"와 "Key(색인)"를 대조해 "Value(책 내용)"를 찾아내는 과정.
- Self-Attention: 문장 내 단어들끼리의 관계를 파악해 "맥락(Context)"을 이해하는 기술.
이제 누군가 "요즘 AI는 왜 이렇게 사람처럼 말해?"라고 묻는다면, 이렇게 대답해 주세요. "옛날 AI는 무식하게 처음부터 끝까지 다 외우려다가 까먹었는데, 요즘 AI는 중요한 것만 골라 보는 눈(Attention)이 생겼거든. 마치 벼락치기 공부할 때 형광펜 칠하는 거랑 똑같아."