Skip to content

✍️ 필사 모드: Transformer 아키텍처 완전 가이드 2025: Self-Attention, Positional Encoding, Multi-Head, GPT vs BERT — ChatGPT 뒤의 수학

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

들어가며: 한 편의 논문이 바꾼 세계

2017년 6월, Google의 한 논문

"Attention Is All You Need". Ashish Vaswani 등 8명의 저자. NIPS 2017.

이 논문이 Transformer 아키텍처를 소개했다. 그리고 AI의 모든 것이 바뀌었다.

2017년 이전: RNN, LSTM이 자연어 처리의 표준. 2017년 이후: Transformer가 모든 곳에.

7년 후:

  • GPT-4: Transformer.
  • Claude: Transformer.
  • Gemini: Transformer.
  • Llama: Transformer.
  • Stable Diffusion: Transformer (부분적).
  • DALL-E: Transformer.
  • AlphaFold: Transformer.

거의 모든 현대 AI가 Transformer 기반이다.

Transformer의 혁명

이전 (RNN/LSTM)의 문제:

  • 순차 처리: 단어를 하나씩.
  • 병렬화 불가: GPU 활용 제한.
  • Long-range dependency: 먼 단어 관계 학습 어려움.
  • 학습 느림.

Transformer의 해결:

  • 병렬 처리: 모든 단어 동시에.
  • Self-attention: 모든 단어 쌍 관계 직접.
  • GPU 최적: 행렬 연산 중심.
  • 확장성: 더 큰 모델 → 더 나은 성능.

"Scaling law": Transformer는 크기를 늘리면 그에 비례해 좋아진다. 이것이 GPT 시리즈의 기반이다.

이 글에서 다룰 것

  1. 배경: RNN의 한계.
  2. Attention 메커니즘: 기본 아이디어.
  3. Self-Attention: 핵심 수학.
  4. Multi-Head Attention: 병렬 attention.
  5. Positional Encoding: 순서 정보.
  6. Transformer Block: 전체 구조.
  7. Encoder vs Decoder: 두 가지 사용법.
  8. GPT vs BERT: 차이점.
  9. Scaling & 변형: 최신 아키텍처.

1. 배경: 왜 RNN이 부족했나

RNN의 기본 아이디어

RNN (Recurrent Neural Network): 이전 상태를 기억하며 순차 처리.

input:  "I love pizza"
        ↓     ↓     ↓
        RNNRNNRNN
        (h1)  (h2)  (h3)

각 스텝에서:

  • 현재 입력 + 이전 hidden state.
  • 새 hidden state 생성.
  • 다음 스텝으로 전달.

수식: ht=tanh(Whht1+Wxxt+b)h_t = \tanh(W_h h_{t-1} + W_x x_t + b)

LSTM의 등장

기본 RNN의 문제: Long-range dependency. 먼 단어의 정보가 소실.

LSTM (Long Short-Term Memory): Gate 구조로 정보 흐름 제어.

  • Forget gate: 무엇을 잊을지.
  • Input gate: 무엇을 기억할지.
  • Output gate: 무엇을 출력할지.

GRU (Gated Recurrent Unit): LSTM의 단순화.

그럼에도 근본 한계는 있었다.

RNN의 근본 문제

1. Sequential 실행:

for t in range(seq_length):
    h[t] = f(h[t-1], x[t])  # t-1 완료 후 t 실행

병렬화 불가. GPU가 하나의 예제에 대해 기다려야.

2. Vanishing/Exploding Gradients:

역전파 시 gradient가 시간을 거꾸로 흐른다. 긴 시퀀스면:

  • Vanishing: Gradient가 0에 가까워져 학습 안 됨.
  • Exploding: Gradient가 폭발.

LSTM이 완화하지만 완전 해결 못 함.

3. Long-range Dependency:

"The cat, which I saw yesterday at the park after a long walk, was ..."

"was"가 "cat"에 연결됨. 하지만 중간에 수많은 단어. RNN이 잊어버리기 쉬움.

필요한 것

이상적 속성:

  • 병렬 실행.
  • 모든 단어 쌍의 직접 관계.
  • 확장 가능.

Attention이 답이었다.


2. Attention의 기본 아이디어

Attention의 직관

Attention: "어느 부분에 주의를 기울일까?"

예: 번역에서

  • "I love pizza" → "나는 피자를 좋아한다"
  • "사랑" → "love"에 주의.
  • "피자" → "pizza"에 주의.

RNN은 이를 단일 벡터로 압축해서 번역. Attention은 각 출력에 대해 입력의 관련 부분을 직접 본다.

초기 Attention (Bahdanau 2014)

Neural Machine Translation:

  1. Encoder (RNN)가 입력 문장을 hidden states로.
  2. Decoder (RNN)가 각 출력 단어 생성 시:
    • 모든 encoder hidden states에 대한 attention weight 계산.
    • 가중 합으로 context vector.
    • 이를 사용해 출력 생성.

혁신: "단일 벡터" 한계 극복. 긴 문장에서 훨씬 좋은 번역.

Self-Attention의 등장

"Attention Is All You Need" (2017): RNN을 버리자. Self-attention만으로 충분.

Self-attention: 같은 시퀀스 내에서 단어들끼리 attention.

"The cat sat on the mat"
각 단어가 다른 모든 단어에 attention.
"cat""The" (0.1), "cat" (0.5), "sat" (0.2), ..., "mat" (0.1)

각 단어가 자신의 문맥을 스스로 결정.

왜 이것이 작동하는가

병렬 처리: 모든 단어 동시에.

Direct 관계: 먼 단어도 한 번의 attention으로 직접 연결.

Contextual embedding: 각 단어의 표현이 문맥에 따라 달라짐.

"bank" (강둑) vs "bank" (은행) — 문맥이 다르면 다른 표현.


3. Self-Attention의 수학

Query, Key, Value

Self-attention의 핵심 아이디어: Query-Key-Value 매커니즘.

비유: 도서관.

  • Query: "어떤 책을 찾고 싶어?"
  • Key: 각 책의 색인.
  • Value: 책의 내용.

Query와 Key가 매칭되면 그 Value를 가져옴.

Linear Transformations

각 입력 토큰 xx에서 세 가지 벡터를 만든다:

Q=xWQQ = xW^Q K=xWKK = xW^K V=xWVV = xW^V

WQ,WK,WVW^Q, W^K, W^V학습되는 가중치 행렬.

형태:

  • xx: [seq_length,dmodel][seq\_length, d_{model}]
  • WQ,WK,WVW^Q, W^K, W^V: [dmodel,dk][d_{model}, d_k]
  • Q,K,VQ, K, V: [seq_length,dk][seq\_length, d_k]

Attention Scores

핵심 공식:

Attention(Q,K,V)=softmax(QKTdk)V\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V

단계별 이해:

1단계: QKTQK^T

Q: [seq_len, d_k]
K^T: [d_k, seq_len]
QK^T: [seq_len, seq_len]

각 요소 (QKT)ij(QK^T)_{ij}query ii와 key jj의 내적. 유사도 점수.

2단계: /dk/\sqrt{d_k}

스케일링. dkd_k가 크면 내적이 너무 커짐. Softmax가 포화. Gradient 소실.

dk\sqrt{d_k}로 나눠서 방지.

3단계: Softmax

각 row에 softmax → 확률 분포:

softmax(xi)=exijexj\text{softmax}(x_i) = \frac{e^{x_i}}{\sum_j e^{x_j}}

각 query에 대해 "모든 key들 중 어디에 주의를 기울일지"의 확률.

4단계: ×V\times V

Attention weight로 value들을 가중 합.

결과: [seq_length,dk][seq\_length, d_k].

전체 흐름 예시

입력: "I love pizza" (3×dmodel3 \times d_{model}).

  1. Linear projections:

    • Q,K,VQ, K, V: 각 3×dk3 \times d_k.
  2. QKTQK^T: 3×33 \times 3 matrix. 모든 단어 쌍의 관계.

  3. Scale + softmax:

           I    love   pizza
    I    [0.5, 0.2, 0.3]
    love [0.1, 0.6, 0.3]
    pizza[0.2, 0.3, 0.5]
    

    "love"는 주로 "love" 자신(0.6)과 "pizza"(0.3)에 집중.

  4. ×V\times V: 각 단어의 새 표현 (문맥 반영).

Masked Self-Attention

Decoder (GPT)에서 중요. "미래를 보면 안 됨":

          t1  t2  t3  t4
    t1 [  ✓  ×  ×  × ]
    t2 [  ✓  ✓  ×  × ]
    t3 [  ✓  ✓  ✓  × ]
    t4 [  ✓  ✓  ✓  ✓ ]

Softmax 전에 미래 위치의 점수를 -\infty 로 설정. Softmax 후 0이 됨.

이유: 언어 모델링은 다음 단어 예측. 학습 중에 미래를 보면 cheating.


4. Multi-Head Attention

왜 여러 개?

하나의 attention으로는 한 종류의 관계만 학습.

여러 attention으로 다른 관계들을 동시에:

  • 문법적 관계.
  • 의미적 관계.
  • 공시적 참조.
  • 등등.

구조

Multi-Head Attention:

MultiHead(Q,K,V)=Concat(head1,...,headh)WO\text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, ..., \text{head}_h)W^O

headi=Attention(QWiQ,KWiK,VWiV)\text{head}_i = \text{Attention}(QW_i^Q, KW_i^K, VW_i^V)

단계:

  1. 입력을 h개의 head로 분할.
  2. 각 head가 자기 Q, K, V 투영.
  3. Attention 병렬 계산.
  4. 결과들을 concatenate.
  5. 최종 linear projection.

차원

dmodel=512d_{model} = 512, h=8h = 8 이면:

  • 각 head: dk=dv=64d_k = d_v = 64 (512/8512 / 8).
  • 각 head의 attention: [seq_len,64][seq\_len, 64].
  • Concat: [seq_len,512][seq\_len, 512].
  • 최종 projection: [seq_len,512][seq\_len, 512].

총 parameter 수는 single head와 비슷. Head가 독립적으로 다른 것을 학습.

시각화

각 head는 다른 패턴을 학습:

  • Head 1: 짧은 범위 구문.
  • Head 2: 대명사 resolution.
  • Head 3: 주어-동사 관계.
  • Head 4: 긴 문맥.
  • 등등.

학습 완료 후 attention weights를 시각화하면 이런 패턴들이 실제로 나타남.

구현 팁

효율을 위해 실제론:

  • 하나의 큰 projection: WQRdmodel×dmodelW^Q \in \mathbb{R}^{d_{model} \times d_{model}}.
  • Reshape해서 [batch,numheads,seqlen,dk][batch, num_heads, seq_len, d_k].
  • 병렬 attention.
  • Reshape back.

5. Positional Encoding

문제

Self-attention은 순서 정보가 없다:

"dog bites man" vs "man bites dog".

단어 집합이 같으면 같은 결과. 치명적.

RNN은 순서대로 처리하니 순서가 자동으로 들어감. Transformer는?

해결: Positional Encoding

각 위치에 고유한 벡터를 더해준다:

inputi=embedding(wi)+PE(i)\text{input}_i = \text{embedding}(w_i) + \text{PE}(i)

이제 같은 단어라도 위치에 따라 다른 입력.

Sinusoidal Encoding

"Attention Is All You Need" 논문의 방식:

PE(pos,2i)=sin(pos100002i/dmodel)\text{PE}(pos, 2i) = \sin\left(\frac{pos}{10000^{2i/d_{model}}}\right)

PE(pos,2i+1)=cos(pos100002i/dmodel)\text{PE}(pos, 2i+1) = \cos\left(\frac{pos}{10000^{2i/d_{model}}}\right)

짝수 차원은 sin, 홀수 차원은 cos. 서로 다른 주파수.

왜 이 공식?:

  1. Unique: 각 위치가 고유한 벡터.
  2. Bounded: -1 ~ 1.
  3. Relative position: sin(a+b)=sin(a)cos(b)+cos(a)sin(b)\sin(a+b) = \sin(a)\cos(b) + \cos(a)\sin(b) → 상대 위치 학습 가능.
  4. Extrapolation: 학습 시 본 적 없는 긴 시퀀스에도 적용 가능.

Learned Positional Embedding

BERT 등에서 사용:

  • 각 위치를 학습 가능한 embedding으로.
  • 단순하지만 고정 max length.

Rotary Positional Embedding (RoPE)

최신 (LLaMA, GPT-NeoX, Chinchilla):

Q와 K에 회전 변환을 적용:

Q~m=RmQm\tilde{Q}_m = R_m Q_m K~n=RnKn\tilde{K}_n = R_n K_n

RR은 회전 행렬. 회전 각도가 위치 m,nm, n에 의존.

내적: Q~mK~n=QmRnmKn\tilde{Q}_m \cdot \tilde{K}_n = Q_m \cdot R_{n-m} K_n

상대 위치 nmn - m 중요. 절대 위치 불필요.

장점:

  • 긴 컨텍스트에 extrapolation 좋음.
  • 상대 위치 자연스럽게.
  • LLaMA 이후 표준.

ALiBi (Attention with Linear Biases)

BLOOM, MosaicML 등에서 사용:

  • Positional encoding 자체를 안 씀.
  • 대신 attention score에 위치 차이 기반 bias:

scoreij+=mij\text{score}_{ij} += -m \cdot |i - j|

mm은 head별 학습 가능 파라미터.

극도의 단순함 + 좋은 extrapolation.


6. Transformer Block

Encoder Block

Transformer encoder block 하나:

Input
[Multi-Head Self-Attention]
Add & LayerNorm (residual)
[Feed-Forward Network]
Add & LayerNorm (residual)
Output

각 컴포넌트

1. Multi-Head Self-Attention: 앞서 설명. 입력의 각 토큰이 다른 모든 토큰에 attention.

2. Residual Connection:

output=LayerNorm(x+SubLayer(x))\text{output} = \text{LayerNorm}(x + \text{SubLayer}(x))

이점:

  • Gradient flow 개선.
  • 깊은 네트워크 학습 가능.
  • ResNet에서 영감.

3. Layer Normalization:

Batch norm의 대안. 각 예제의 feature를 정규화:

LN(x)=xμσγ+β\text{LN}(x) = \frac{x - \mu}{\sigma} \cdot \gamma + \beta

4. Feed-Forward Network (FFN):

간단한 2-layer MLP:

FFN(x)=ReLU(xW1+b1)W2+b2\text{FFN}(x) = \text{ReLU}(xW_1 + b_1)W_2 + b_2

보통 dff=4×dmodeld_{ff} = 4 \times d_{model}.

역할: 각 위치에 독립적으로 비선형 변환 적용. Attention이 "믹싱"이라면 FFN은 "처리".

Encoder Stack

여러 encoder block을 쌓는다:

Input Embeddings + Positional Encoding
[Encoder Block 1]
[Encoder Block 2]
  ...
[Encoder Block N]
Output

BERT-base: 12 blocks. BERT-large: 24 blocks. GPT-3: 96 blocks. GPT-4: ~120+ blocks (추정).

Decoder Block

Decoder block은 세 부분:

Input
[Masked Multi-Head Self-Attention]  ← 미래 못 봄
Add & LayerNorm
[Multi-Head Cross-Attention]Encoder output에 attention
Add & LayerNorm
[Feed-Forward Network]
Add & LayerNorm
Output

Cross-Attention: Decoder가 encoder output에 attention. 번역에서:

  • Decoder의 현재 생성 위치 → Query.
  • Encoder의 모든 출력 → Key, Value.

원본 문장의 어느 부분을 보면서 번역할지 결정.

원 Transformer 구조

원 논문의 전체 구조:

Source     Target (shifted right)
  ↓          ↓
Embed      Embed
  ↓          ↓
+ PE       + PE
  ↓          ↓
Encoder → → Cross Attn
  ↓          ↓
Encoder    Decoder
  ↓          ↓
  ...        ...
  ↓          ↓
Encoder  Decoder
           Linear + Softmax
           Output probabilities

기계 번역을 위한 설계. Encoder가 source 언어, decoder가 target 언어.


7. Encoder vs Decoder 아키텍처

Encoder-Only: BERT

BERT (Bidirectional Encoder Representations from Transformers): Google 2018.

특징:

  • Encoder만 사용.
  • 양방향 (bidirectional) attention.
  • 각 단어가 전체 문장 문맥 봄.
  • 학습: Masked Language Modeling (MLM).

Masked Language Modeling:

Input: "I love [MASK] and pasta"
Goal: [MASK] = "pizza"

일부 단어를 가리고 예측. 모델이 문맥 이해 학습.

용도:

  • 이해 작업: 분류, 개체명 인식, 질문 응답.
  • 임베딩: 문장 벡터 표현.
  • Sentence embedding: Sentence-BERT.

생성 불가: 순차적 generation 구조가 아니라.

Decoder-Only: GPT

GPT (Generative Pre-trained Transformer): OpenAI 2018.

특징:

  • Decoder만 사용 (encoder-decoder의 decoder가 아닌, 더 단순).
  • 단방향 (unidirectional, causal) attention.
  • 각 단어가 이전 단어만 봄.
  • 학습: 다음 단어 예측.

학습:

Input: "I love pizza and"
Target: "pasta"

용도:

  • 생성: 텍스트, 코드, 대화.
  • Few-shot learning: Prompt 기반.
  • ChatGPT의 기반.

모델 진화:

  • GPT-1: 117M params.
  • GPT-2: 1.5B.
  • GPT-3: 175B.
  • GPT-4: ~1.7T (mixture of experts).

Encoder-Decoder: T5, BART

T5 (Text-to-Text Transfer Transformer): Google 2019.

특징:

  • Encoder + Decoder 전체.
  • 모든 task를 text → text로.
  • 번역, 요약, 질문 응답 등 통합.

예시:

Input: "translate English to Korean: I love pizza"
Output: "나는 피자를 좋아한다"

Input: "summarize: [long article]"
Output: "[summary]"

장점:

  • 다양한 task 한 모델.
  • Encoder의 이해 + Decoder의 생성.

단점:

  • 더 큰 모델.
  • 학습 복잡.

선택 기준

Encoder-only (BERT 류):

  • 이해 task.
  • 분류, 검색, 임베딩.
  • 생성 안 하면.

Decoder-only (GPT 류):

  • 생성 task.
  • 대화, 작문.
  • 현재 LLM의 주류.

Encoder-decoder (T5 류):

  • 번역, 요약 등 "입력 → 출력" 변환.
  • Multi-task.

흥미로운 사실: 생성 중심으로 흐르며 GPT류가 압도적 주류가 됨. T5류는 감소.


8. Scaling Laws와 거대 모델

Scaling Laws

OpenAI의 연구 (Kaplan et al. 2020):

Loss가 power law로 model 크기, data 크기, 계산량에 따라 감소:

L=L+(A/N)α+(B/D)β+(C/Ccompute)γL = L_\infty + (A/N)^\alpha + (B/D)^\beta + (C/C_{compute})^\gamma

의미:

  • 더 큰 모델 = 더 나은 성능.
  • 더 많은 데이터 = 더 나음.
  • 더 많은 계산 = 더 나음.

Chinchilla (DeepMind, 2022): 최적 비율 발견.

  • GPT-3는 너무 큰 모델, 너무 적은 데이터.
  • compute-optimal: 비슷한 비율로 model과 data 증가.

거대 모델의 진화

파라미터 수:

  • BERT: 340M.
  • GPT-2: 1.5B.
  • GPT-3: 175B.
  • LaMDA: 137B.
  • PaLM: 540B.
  • GPT-4: ~1.7T (mixture of experts).
  • Gemini Ultra: 추정 1T+.

거대 모델의 도전

1. 메모리:

  • 1T parameter × 2 bytes (FP16) = 2 TB 메모리.
  • 단일 GPU 불가.
  • Model parallelism.

2. 학습 비용:

  • GPT-3: $4-5M.
  • GPT-4: $100M+ (추정).
  • 전기와 GPU 시간.

3. Inference 비용:

  • 각 토큰 생성에 막대한 계산.
  • 최적화 필수: KV cache, quantization 등.

4. Emergent abilities:

  • 특정 크기 이상에서 갑자기 능력 출현.
  • "Chain of thought", "in-context learning".
  • 작은 모델엔 없음.

9. 최신 Transformer 변형

Mixture of Experts (MoE)

GPT-4, Mixtral, DeepSeek 등:

모든 파라미터를 매번 사용하지 않음.

구조:

  • 여러 "expert" FFN.
  • Router가 각 토큰을 일부 expert에 보냄 (top-2 등).
                  Router
                 /   |   \
            Expert Expert Expert ... Expert (32)
              ↓     ↓     ↓           ↓
              ↓     ↓     ↓           
            (top-2만 활성)
              ↓     ↓
               \   /
               Merge

Mixtral 8x7B:

  • 7B × 8 experts = 56B params.
  • 각 토큰: 14B만 활성.
  • Smaller than 56B in compute, but performance of larger.

Flash Attention

Memory efficient attention (Tri Dao 2022):

  • 표준 attention: 메모리 O(N2)O(N^2).
  • Flash attention: 메모리 O(N)O(N).
  • 타일링 + recomputation 트릭.

효과:

  • 긴 컨텍스트 가능 (100k+ tokens).
  • 더 빠름.
  • 대부분의 현대 LLM이 사용.

Grouped-Query Attention (GQA)

LLaMA 2, Gemini:

Multi-head attention의 변형:

  • Query head는 많음 (예: 32).
  • Key, Value head는 적음 (예: 8).
  • 여러 Q가 같은 K, V 공유.

이점: 파라미터와 메모리 절약. 성능 유사.

Sliding Window Attention

Mistral, Gemma:

긴 컨텍스트에서:

  • Full attention: O(N2)O(N^2).
  • Sliding window: 각 토큰이 최근 W개만 봄. O(NW)O(NW).

효과: 긴 컨텍스트 효율.

State Space Models (Mamba)

Transformer의 대안 (2024):

  • RNN 스타일, 선형 복잡도.
  • 매우 긴 시퀀스.
  • 아직 초기, Transformer 대체 여부 불명.

Retrieval-Augmented Generation (RAG)

Transformer + external knowledge:

  • 질문 임베딩.
  • 벡터 DB에서 관련 문서 검색.
  • Context에 추가.
  • Transformer가 생성.

이점: 최신 정보, 도메인 지식. 환각 감소.


10. 학습 방법

Pre-training

거대 corpus에서 self-supervised 학습:

GPT 스타일 (다음 단어 예측):

Input: "The cat sat on the"
Target: "mat"

BERT 스타일 (masked language modeling):

Input: "The [MASK] sat on the mat"
Target: "cat"

데이터:

  • Common Crawl (웹 스크레이프).
  • Wikipedia.
  • Books.
  • GitHub code.
  • 수 TB 텍스트.

Instruction Tuning

Pre-training 후:

  • 수천~수백만의 instruction-response 쌍.
  • 모델이 지시를 따르는 방법 학습.
Instruction: "Explain photosynthesis"
Response: "Photosynthesis is the process..."

RLHF (Reinforcement Learning from Human Feedback)

ChatGPT의 핵심:

  1. Reward model 학습: 사람이 여러 응답에 점수. 모델이 이를 학습.
  2. PPO로 언어 모델 최적화: Reward를 최대화하는 방향으로.

효과: 더 도움이 되고, 덜 해로운 응답.

문제: Reward hacking, alignment tax.

DPO (Direct Preference Optimization)

RLHF의 단순화 (2023):

  • Reward model 불필요.
  • Preference 쌍에서 직접 최적화.
  • 더 쉽고 안정적.

Constitutional AI

Anthropic의 접근:

  • "헌법" (원칙) 기반.
  • 모델이 자기 출력을 "헌법"으로 비평.
  • Self-improvement.
  • Claude의 기반.

11. Inference 최적화

핵심 문제

거대 LLM inference는 비싸다:

  • 각 토큰 생성 = 전체 모델 forward pass.
  • 1000 토큰 응답 = 1000 passes.
  • GPT-4급: 초당 수십 토큰.

최적화 필수.

KV Cache

문제: Decoder-only에서 각 스텝마다 모든 이전 토큰의 K, V 재계산.

해결: KV cache.

  • 각 토큰의 K, V 저장.
  • 다음 스텝에 재사용.
  • 새 토큰의 K, V만 계산.

메모리:

  • 모델 크기에 비례.
  • 긴 컨텍스트에서 수 GB.

vLLM의 PagedAttention: OS의 virtual memory처럼 KV cache 관리. 메모리 효율.

Speculative Decoding

작은 "draft" 모델이 빠르게 예측 → 큰 모델이 검증.

  • Draft model: 5 토큰 생성.
  • Big model: 5 토큰 검증 (한 번의 forward pass).
  • 맞으면 5 토큰 한 번에 수락.
  • 틀린 부분부터 재생성.

효과: 2-3배 빠름.

Quantization

정밀도 감소:

  • FP32 (32-bit) → FP16 → INT8 → INT4 → INT2.
  • 메모리 1/16, 속도 수 배.

정확도 손실: 최소화 기법 다수.

  • GPTQ, AWQ, GGUF.
  • 실전에서 4-bit가 품질 손실 거의 없이 작동.

Batching

여러 요청을 동시에 처리:

  • Static batching: 동일 길이 요청.
  • Continuous batching: 요청이 끝나면 즉시 새 요청 삽입.
  • Throughput 수십 배 증가.

서빙 프레임워크

vLLM: PagedAttention, continuous batching. TensorRT-LLM: NVIDIA 최적화. Text Generation Inference (TGI): Hugging Face. llama.cpp: CPU/Apple Silicon.


12. 실전 Transformer

Code 구현 (PyTorch)

간단한 self-attention:

import torch
import torch.nn as nn
import torch.nn.functional as F

class SelfAttention(nn.Module):
    def __init__(self, d_model, num_heads):
        super().__init__()
        self.d_model = d_model
        self.num_heads = num_heads
        self.d_k = d_model // num_heads
        
        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, mask=None):
        batch_size, seq_len, d_model = x.shape
        
        # Linear projections
        Q = self.W_q(x)
        K = self.W_k(x)
        V = self.W_v(x)
        
        # Reshape for multi-head
        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)
        
        # Attention scores
        scores = torch.matmul(Q, K.transpose(-2, -1)) / (self.d_k ** 0.5)
        
        if mask is not None:
            scores = scores.masked_fill(mask == 0, -1e9)
        
        attn = F.softmax(scores, dim=-1)
        
        # Apply attention
        out = torch.matmul(attn, V)
        
        # Concat heads
        out = out.transpose(1, 2).contiguous().view(batch_size, seq_len, d_model)
        
        return self.W_o(out)

Transformer block:

class TransformerBlock(nn.Module):
    def __init__(self, d_model, num_heads, d_ff, dropout=0.1):
        super().__init__()
        self.attention = SelfAttention(d_model, num_heads)
        self.norm1 = nn.LayerNorm(d_model)
        self.norm2 = nn.LayerNorm(d_model)
        self.ff = nn.Sequential(
            nn.Linear(d_model, d_ff),
            nn.ReLU(),
            nn.Linear(d_ff, d_model)
        )
        self.dropout = nn.Dropout(dropout)
    
    def forward(self, x, mask=None):
        # Attention + residual
        attn_out = self.attention(x, mask)
        x = self.norm1(x + self.dropout(attn_out))
        
        # FFN + residual
        ff_out = self.ff(x)
        x = self.norm2(x + self.dropout(ff_out))
        
        return x

Hugging Face Transformers

실전에선 보통 직접 구현 안 함:

from transformers import AutoTokenizer, AutoModelForCausalLM

tokenizer = AutoTokenizer.from_pretrained("gpt2")
model = AutoModelForCausalLM.from_pretrained("gpt2")

inputs = tokenizer("The future of AI is", return_tensors="pt")
outputs = model.generate(**inputs, max_length=50)
print(tokenizer.decode(outputs[0]))

수십 줄의 코드로 GPT-2 실행.

Hugging Face는 사실상 Transformer의 표준 라이브러리.


퀴즈로 복습하기

Q1. Self-Attention의 QKT/dkQK^T/\sqrt{d_k}에서 dk\sqrt{d_k}로 나누는 이유는?

A.

: Softmax의 gradient 소실 문제를 방지하기 위해.

상세 설명:

문제 시나리오:

dkd_k가 크면 (예: dk=512d_k = 512), QQKK의 내적 qk=i=1dkqikiq \cdot k = \sum_{i=1}^{d_k} q_i k_i크기가 커진다.

이유:

  • qiq_ikik_i가 평균 0, 분산 1이면:
  • 내적의 분산은 dkd_k.
  • 따라서 크기는 O(dk)O(\sqrt{d_k}).

소프트맥스의 문제:

큰 값이 softmax에 들어가면:

softmax(xi)=exijexj\text{softmax}(x_i) = \frac{e^{x_i}}{\sum_j e^{x_j}}

예시: 점수가 [1,10,100,...][1, 10, 100, ...] 이면:

  • e12.7e^1 \approx 2.7
  • e1022026e^{10} \approx 22026
  • e1002.7×1043e^{100} \approx 2.7 \times 10^{43}

거대한 값이 모든 확률을 독점. 나머지는 사실상 0.

Gradient 관점:

Softmax의 gradient는 자기 값 기준:

  • 큰 값: gradient 거의 0 (saturation).
  • 작은 값: gradient 거의 0.

거의 모든 위치의 gradient가 0학습 불가.

dk\sqrt{d_k}로 나누면:

내적의 분산을 1로 정규화:

  • Var(qk/dk)=dk/dk=1\text{Var}(q \cdot k / \sqrt{d_k}) = d_k / d_k = 1.
  • 점수가 적절한 범위 (~[3,3][-3, 3]).
  • Softmax가 부드러운 분포 생성.
  • Gradient가 의미 있는 크기.

수학적 근거:

q,kN(0,1)q, k \sim \mathcal{N}(0, 1) 가정:

  • qk=iqikiq \cdot k = \sum_i q_i k_i.
  • qikiq_i k_i: 평균 0, 분산 1.
  • dkd_k개 합: 평균 0, 분산 dkd_k.
  • 표준편차 dk\sqrt{d_k}.
  • dk\sqrt{d_k}로 나누면 표준편차 1.

왜 1이 좋은가:

Softmax가 잘 작동하는 범위는 대략 [5,5][-5, 5].

  • 너무 크면 saturation.
  • 너무 작으면 uniform에 가까워 의미 없음.

분산 1이면 대부분 [3,3][-3, 3]에 들어옴. 적절.

실험적 증거:

논문의 실험:

  • Scaling 없이: 큰 dkd_k에서 학습 실패.
  • Scaling 있으면: 안정적 학습.

대안과 비교:

1. 더 작은 dkd_k:

  • 계산 적음.
  • 표현력 감소.
  • Multi-head를 통해 보완.

2. Layer norm 만으로:

  • 다른 scale 문제 있음.
  • dk\sqrt{d_k}가 더 간단하고 효과적.

3. 학습 가능한 scale:

  • 시도되었지만 복잡도만 증가.

직관:

수학적으로는 "분산을 1로 유지" 인데, 직관적으로는:

"너무 극단적 attention을 막아라. 한 위치에만 완전히 집중하지 말고, 여러 위치를 부드럽게 고려하라."

너무 뾰족한 attention은 학습 초기에 특히 문제. 학습이 진행되며 필요하면 sharpening 가능.

다른 attention 변형:

Relative position bias (T5 등):

  • 점수에 상대 위치 기반 bias 추가.
  • 스케일링은 여전히.

Flash Attention:

  • 수학적으로 동일.
  • 구현만 최적화.

Performer, Linformer:

  • Linear complexity attention.
  • 스케일링 여전히 중요.

교훈:

dk\sqrt{d_k}라는 간단한 수정이 Transformer의 학습 가능성을 결정했다. 이런 작은 디테일이 큰 차이를 만든다.

"Attention Is All You Need" 논문은 이런 작은 것들로 가득하다:

  • Residual connection.
  • Layer norm 위치.
  • Positional encoding 방식.
  • dk\sqrt{d_k} scaling.

각각이 학습의 성공을 좌우한다. 논문을 읽을 때 이런 디테일을 주목해야 한다.

딥러닝 교훈: 좋은 아키텍처는 좋은 gradient를 만든다. Gradient가 0이 되거나 폭발하면 학습 불가. 모든 "trick"이 궁극적으로 gradient flow를 제어하는 것.

ResNet의 residual, Transformer의 scaling, layer norm 등 — 모두 gradient를 부드럽게 만드는 장치다. 이것이 딥러닝 엔지니어링의 핵심이다.


마치며: 한 아이디어의 승리

핵심 정리

  1. Self-attention: Query-Key-Value. 모든 단어 쌍의 관계.
  2. Multi-head: 여러 관점의 attention.
  3. Positional encoding: 순서 정보 주입.
  4. Transformer block: Attention + FFN + residual + layer norm.
  5. Encoder vs Decoder: BERT vs GPT.
  6. Scaling: 더 크면 더 좋다.
  7. 변형: MoE, Flash Attention, RoPE, GQA.

Transformer의 성공 비결

  1. 병렬화: GPU 완전 활용.
  2. 단순성: Attention + FFN만 반복.
  3. 확장성: 크기 올리면 성능 향상.
  4. 유연성: 다양한 task에 적용.
  5. 전이 학습: Pre-train + fine-tune 패턴.

**"Attention is all you need"**가 2017년에 맞는 말이었고, 2025년에도 맞다. 수많은 변형이 있지만 핵심 아이디어는 그대로.

마지막 교훈

Transformer는 AI 역사상 가장 영향력 있는 아키텍처 중 하나다. 8명의 저자가 2017년에 발표한 한 논문이 7년 만에 세계를 바꿨다.

당신이 ChatGPT와 대화할 때, 그 응답의 배후에는:

  • 수조 개의 파라미터.
  • 수만 개의 GPU 시간의 학습.
  • 수백 개의 transformer block.
  • 수백만 개의 attention head.

하지만 이 모든 것의 본질은 하나의 방정식:

Attention(Q,K,V)=softmax(QKTdk)V\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V

간단하고, 우아하고, 강력하다. 이것이 좋은 과학의 증거다.

Transformer를 이해하면 현대 AI의 80%를 이해한 것이다. 당신이 ML 엔지니어든, 연구자든, 단순 사용자든, 이 지식은 AI와의 관계를 깊게 만든다.

AI의 미래는 여전히 쓰이고 있다. 다음 혁명은 또 다른 논문에서 시작될 것이다. 하지만 지금은, 2025년은, Transformer의 시대다.


참고 자료

현재 단락 (1/675)

**"Attention Is All You Need"**. Ashish Vaswani 등 8명의 저자. NIPS 2017.

작성 글자: 0원문 글자: 18,158작성 단락: 0/675