
Transformer: 현대 AI의 기반
Transformer 아키텍처의 동작 원리를 경험을 통해 이해한 과정

Transformer 아키텍처의 동작 원리를 경험을 통해 이해한 과정
AI 시대의 금광, 엔비디아 GPU. 도대체 게임용 그래픽카드로 왜 AI를 돌리는 걸까? 단순 노동자(CUDA)와 행렬 계산 천재(Tensor)의 차이로 파헤쳐봤습니다.

LLM 커스터마이징 방법인 파인튜닝과 프롬프트 엔지니어링의 차이와 선택 기준

AI와 딥러닝은 왜 CPU를 버리고 GPU를 선택했을까요? ALU 구조 차이부터 CUDA 메모리 계층, 그래픽 API(Vulakn/DirectX), 그리고 생성형 AI의 원리까지 하드웨어 가속의 모든 것을 다룹니다.

신경망의 동작 원리를 프로젝트 경험을 통해 이해한 과정. 공장 라인 비유부터 역전파, 하이퍼파라미터 튜닝까지.

2016년 말, 구글 번역기가 갑자기 '외계인 고문설'이 돌 정도로 똑똑해졌다는 뉴스 기억하시나요? 그전까지 "아버지가 방에 들어가신다"를 "Father bag enter" 수준으로 번역하던 녀석이, 갑자기 유려한 영어 문장을 뱉어내기 시작했죠. 그 배후에는 Transformer 아키텍처가 있었습니다.
저는 당시 프로젝트에서 LSTM(Long Short-Term Memory)으로 챗봇을 만들고 있었는데, 긴 문장만 들어오면 멍청이가 되는 문제 때문에 골머리를 앓고 있었습니다. "앞의 내용을 다 까먹어버려요." 선배가 말했습니다. "야, 구글이 논문 하나 냈더라. 'Attention Is All You Need'. 그거 한번 봐봐."
제목부터 도발적인 이 논문은, 제 AI 인생을 완전히 바꿔놓았습니다.
논문을 처음 폈을 때, 저는 멘붕에 빠졌습니다.
그전까지 NLP(자연어 처리)의 국룰은 RNN이었습니다. "나는 학교에 간다"를 처리하려면 당연히 "나는" -> "학교에" -> "간다" 순서로 읽어야 하잖아요? 그런데 트랜스포머는 "순서 따위 필요 없다. 한방에(Parallel) 다 넣어라"라고 합니다. "아니, 순서가 없는 언어가 말이 돼?"
"Q, K, V... 쿼리, 키, 밸류?"
데이터베이스 용어인가? 왜 여기서 나오지?
수식은 softmax(QK^T / sqrt(d)) 같은 외계어였고, 도대체 이게 왜 "문맥을 이해하는" 원리인지 와닿지가 않았습니다.
이해하는 데 결정적이었던 비유는 "소개팅"과 "도서관 검색"이었습니다.
여러 명이 모인 미팅 자리(문장)를 상상해보세요. "철수가 영희에게 사과를 주었다."
각 단어가 "나랑 연관 있는 놈이 누구야?"하고 눈빛 교환(Attention)을 하는 겁니다. 거리가 멀리 떨어져 있어도 상관없습니다. 그냥 쳐다보면 되니까요. 이게 바로 RNN의 한계(거리 먼 단어 못 기억함)를 깨부순 비결이었습니다.
'철수'(Query)가 문장 전체를 훑으면서 '주었다'(Key)와 딱 맞는 열쇠구멍을 찾으면, 그 단어의 의미(Value)를 쏙 가져와서 자신의 의미를 강화합니다. 결국 '철수'는 그냥 '철수'가 아니라 '영희에게 사과를 준 철수'라는 풍부한 문맥을 가진 벡터로 다시 태어납니다.
트랜스포머는 크게 인코더(Encoder)와 디코더(Decoder)로 나뉩니다. "영어를 한국어로 번역하는 상황"을 예로 들어보죠.
트랜스포머는 병렬로 처리하기 때문에 순서를 모릅니다. ("학교에 나는 간다"와 "나는 학교에 간다"를 똑같이 취급) 그래서 각 단어에 번호표를 붙여줍니다. "너는 1번, 너는 2번..." 이걸 수학적으로 사인/코사인 함수를 써서 우아하게 붙입니다.
하나의 Attention만 쓰면 시야가 좁아집니다. 그래서 8개의 눈(Head)을 만듭니다.
각자 다른 관점에서 문장을 뜯어보고, 나중에 합칩니다. 이게 Multi-Head Attention입니다.
Attention으로 얻은 정보를 잘 섞어서(Feed Forward), 원래 정보와 더해줍니다(Residual Connection). "원래의 나" + "문맥을 파악한 나" = "더 똑똑해진 나"가 되는 거죠.
전체 구조를 다 짜는 건 복잡하니, 핵심인 Attention 부분만 보겠습니다.
import torch
import torch.nn as nn
import math
class MultiHeadAttention(nn.Module):
def __init__(self, d_model=512, num_heads=8):
super().__init__()
self.num_heads = num_heads
self.d_k = d_model // num_heads # 각 헤드의 차원
# Q, K, V, O를 위한 선형 변환 층
self.W_q = nn.Linear(d_model, d_model)
self.W_k = nn.Linear(d_model, d_model)
self.W_v = nn.Linear(d_model, d_model)
self.W_o = nn.Linear(d_model, d_model)
def forward(self, x):
batch_size, seq_len, d_model = x.shape
# 1. Q, K, V 생성 (Linear Projection)
Q = self.W_q(x)
K = self.W_k(x)
V = self.W_v(x)
# 2. 헤드 나누기 (Split Heads)
Q = Q.view(batch_size, seq_len, self.num_heads, self.d_k).transpose(1, 2)
K = K.view(batch_size, seq_len, self.num_heads, self.d_k).transpose(1, 2)
V = V.view(batch_size, seq_len, self.num_heads, self.d_k).transpose(1, 2)
# 3. Attention Score 계산 (Scaled Dot-Product)
# Q와 K를 곱해서 유사도를 구함
scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(self.d_k)
# 4. Softmax로 확률로 변환
attention_weights = torch.softmax(scores, dim=-1)
# 5. Value와 곱해서 최종 정보 추출
context = torch.matmul(attention_weights, V)
# 6. 헤드 합치기 (Concat)
context = context.transpose(1, 2).contiguous().view(batch_size, seq_len, d_model)
output = self.W_o(context)
return output
이 코드를 처음 짰을 때, transpose와 view에서 차원(Dimension)이 꼬여서 정말 많이 울었습니다.
하지만 한 번 돌아가는 걸 보고 나니, "와, 이게 진짜 for loop 하나 없이 행렬 곱셈만으로 문장을 이해하네?" 싶어서 소름이 돋았습니다. GPU가 좋아하는 이유를 알겠더군요.
이 논문 하나가 AI의 역사를 다시 썼습니다.
결국 우리는 Transformer의 시대에 살고 있습니다.
Transformer는 'Attention'이라는 메커니즘을 통해 문장 내 모든 단어의 관계를 한 번에(Parallel) 파악하는 혁명적인 아키텍처입니다. RNN의 고질병이었던 '기억 상실'과 '속도 저하'를 동시에 해결했으며, 오늘날 모든 거대 언어 모델(LLM)의 조상님입니다.