LLM 동작원리 (Decoder Achitecture)

LLM 모델의 동작 원리

by Dr Jenna

우리가 매일 사용하는 ChatGPT, Gemini, Perplexity와 같은 AI Assistant는 대부분 Decoder-only 형태의 LLM(대규모 언어 모델) 구조를 기반으로 한다.


이러한 모델은 어떻게 우리의 질문을 이해하고, 맥락에 맞는 적절한 답변을 생성할 수 있을까?


2023년 초 ChatGPT가 처음 출시되었을 때 전 세계는 큰 충격을 받았지만, 불과 1년이 지나지 않아 이러한 기술은 많은 사람들의 일상에 자연스럽게 녹아들어 ‘뉴노멀’로 자리잡았다.


그만큼 LLM은 되돌리기 어려운 필수 기술이 되었으며, 앞으로도 다양한 분야에서 핵심적인 역할을 할 것으로 보인다.


이번 글에서는 LLM의 기본 구조 중 하나인 Decoder-only Transformer를 구성 요소별로 분석하고, 데이터 흐름과 차원 변화를 함께 설명한다.



[전체 흐름]

1. Input 생성: Tokenization → Token Embedding → Positional Encoding

2. Attention 모듈: Masked Multi-head Self-attention → Residual Connection →Layer normalization

3. FFN 모듈: Feed Forward Network → Residual Connection → Layer Normalization

4. 최종 출력: Layer Normalization → Output Projection(Linear) → Softmax 또는 CrossEntropy Loss (학습 시)


* 가정: 보통 batch size 만큼 여러개의 Input Sequence를 batch로 묶어서 동시에 처리하지만, 본 설명에서는 batch size = 1 인 것으로 가정


----- Input 생성 -----

1. Tokenization >> (n, 1)

사용자가 자연어로 질문을 하게 되면, 이 질문이 n개의 Token으로 구성되어 있을 때 각 Token에 할당된 숫자로 Encoding 된다. (즉, 해당 Input의 sequence length가 n)

>> (n,1) matrix

예를 들어, "Hello this is me"라는 문장은 [Hello, this, is, me] 4개의 Token으로 분할되어 (4,1)의 matrix가 생성된다.


2. Token Embedding >> (n, m)

각 n개의 Token을 Token Embedding Table (vocab_size, m)을 Lookup하여 m 차원의 Embedding Vector로 나타낸다.

>> (n, m) matrix

Token Embedding Table은 지정된 단어들에 대해 미리 학습되어 있고, 새로운 단어를 추가하고 싶다면 추가 학습이 필요하다.


3. Positional Encoding >> (n, m)

Positional Embedding Matrix는 n개의 Token에 대해 구축되어 있는 Positional Embedding Table (max_position, m)을 Slicing하여 생성된다.

Positional Embedding Table은 Learned Positional Embedding 또는 Sinusoidal Positional Encoding 방법으로 생성함

Input Context Length를 늘리고 싶다면 Position interpolation이나 RoPE scaling 기법 등으로 Positional Embedding Table의 확장이 필요하다.


4. 최종 Input Embedding 생성 >> (n, m)

2번의 Token Embedding에 3번의 Positional Encoding를 더하여 각 Token의 위치 정보를 추가한다.

>> (n, m) matrix


----- Attention Module -----

5. Masked Multi-head self attention 계산 >> (n, m)

생성된 Input (n,m) matrix는 Self-attention 블록을 거치게 된다. Self-attention 블록은, Input 내 각 Token들 간 관계를 참고하여 전체 문맥을 반영하고 더욱 고차원의 Context-aware한 Matrix로 표현한다.

Self-attention에서는 세 개의 Weight Matrix (W_q, W_k, W_v)로 Q, K, V를 생성한다.

Masked Self-attention가 필요한 이유는 Decoder 모델은 지금까지의 토큰들을 토대로 다음 토큰을 예측하는 Auto-regressive generation 방식이기 때문에, 학습 시에는 미래 토큰을 마스킹하여 현재 시점 이후의 정보는 못보게한 후 다음 토큰을 예측한다.

Multi-head란 여러 버전 (head)의 W_q, W_k, W_v를 둠으로써 여러 버전의 Q, K, V를 생성한다는 것이다. 그 이유는 다양한 관점에서 Input을 이해하기 위한 노력이라고 볼 수 있다.

X가 (n, m) Input Matrix일 때
W_q는 (m, d_q), W_k는 (m, d_k), W_v는 (m, d_v)로 구성되고
d_q = d_k = d_v = m / h 이다. (d_v는 일부 변형 모델에서 메모리 절약 등을 위해 다른 경우도 있다.)
Q, K, V는 다음과 같이 계산된다.
Q1 = X @ W_q1 >> (n, m/h) matrix
K1 = X @ W_k1 >> (n, m/h) matrix
V1 = X @ W_v1 >> (n, m/h) matrix

Q1과 transposed K1을 MatMul (행렬곱) 계산하여 (n, n) matrix를 생성 후 스케일링을 진행하고, 이를 m 기준으로 모든 값이 0~1 사이 값을 가지며서 전체 합이 1이 되도록 Softmax 처리한다. (softmax (QK^T / sqrt(d_k))

그리고 이 (n, n) matrix를 다시 V1과 dot product 계산하여 (n, m/h)의 Attention Score를 계산한다.

이 과정을 h개의 head에 대하여 반복하고 그 결과를 Concatenation하여 이어 붙이면 (n, m) matrix가 된다.

이 (n, m) matrix는 각 토큰이 다른 토큰에 얼마나 주의를 기울이는지를 나타내는 Attention score를 의미한다.

>> (n, m) matrix


6. Residual Connection과 Linear Normalization >> (n, m)

Multi-head self-attention의 최종 output인 (n, m) matrix에 3번의 (n, m) matrix를 Residual로 더해준다. 그 이유는 1) 원래 입력 정보의 손실을 방지하고 2) 학습 시 Back propagation에서 발생하는 Gradient Vanishing을 예방하여 수렴 속도를 높이고 학습 안정성을 높이는 효과가 있기 때문이다.

>> (n, m) matrix

이 Matrix를 n을 기준으로 m dimension의 Vector 값들이 평균 0, 분산 1이 되도록 Normalization을 하여 각 모듈마다 (여기서는 Self-attention 모듈) 값의 분포가 일정하게 함으로써 Gradient vanishing 또는 exploding을 예방하여 수렴 속도를 높이고 학습 안정성을 높이는 효과가 있다.

Attention is All You Need 원 논문에서는 Attention 이후와 FFN 이후에 Layer Normalization을 하는 Post-LN 구조를 설명했지만, 최근 대부분의 LLM에서는 Attention과 FFN 이전에 수행하는 Pre-LN 구조를 채택하고 있고, 이 방법이 학습 안정성을 더욱 높이기 때문이다.

Pre-NL 구조에서는 4. Input Embedding 이후에 Layer Normalization을 먼저 수행하고 Attention Module, Residual Connection Add 순으로 진행된다.


----- FFN Module -----

7. Feed Forward Network

위 (n, m) Matrix를 두개의 Layer로 구성된 Feed Forward Network에 통과시키는데, 그 목적은 Attention 모듈에서 얻은 표현을 비선형적으로 변환하여 더욱 복잡한 표현을 고차원으로 학습하기 위함이다.

두개의 Weight Matrix와 계산하는데 첫번째 Weight Matrix와 dot product를 계산한 후 Activation Function을 지나게 된다. 이를 수식으로 나타내면 FFN(X) = W2 @ GELU(X @ W1 + b1) + b2 가 되겠다.

X @ W1 = (n, m) @ (m, d_ff) = (n, d_ff)
(n, d_ff) @ W2 = (n, d_ff) @ (d_ff1, m) = (n, m)
hidden layer dimension d_ff > m

>> (n, m)

여기서 GELU (Gaussian Error Linear Unit)는 Activatio Function 중 하나로, SwiGLU, ReLU, ReGLU 등의 Activation이 있다. (많은 LLM에서 GELU를 사용하지만 LLaMa 계열은 SwiGLU 등 변형이 사용됨)

GELU는 ReLU의 단점을 보완하여 LLM에서 대표적인 Activation Function으로 사용되고 있다.

ReLU는 x > 0 일 때 gradient = x이 되어 DNN의 특성인 Layer가 깊어짐에 따라 1보다 작은 값의 gradient가 지속 곱해지면서 발생하는 Gradient Vanishing 문제를 해결하는 장점이 있다. 하지만 1) x=0에서 gradient가 0에서 x로 불연속적으로 변함에 따라 학습 안정성이 떨어지고, 2) x <= 0 에서는 gradient = 0이 되어 가중치가 업데이트 되지 않는다는 단점이 있다.

GELU는 x <= 0 에서도 0이 아닌 비선형성을 제공하고 x=0 기점에서 gradient가 연속적으로 변함으로써 학습 안정성을 보장한다.

하지만 여전히 ReLU와 GELU 모두 x가 커지면 gradient도 함께 커짐에 따라 Gradient Exploding 현상이 발생한다는 이슈는 존재한다.

Activation Function에서 비선형성이 중요한 이유는 복잡하고 고차원의 패턴을 더 잘 학습하기 위함이다.


8. Residual Connection + Layer Normalization >> (n, m)

FFN 통과 후 (n, m) Matrix에 5번의 (n, m) Matrix를 더해준다. 그 이유는 마찬가지로 1) 원래 입력 정보의 손실을 방지하고 2) 학습 시 Back propagation에서 발생하는 Gradient Vanishing을 예방하여 수렴 속도를 높이고 학습 안정성을 높이는 효과가 있기 때문이다.

>> (n, m) Matrix

이 Matrix를 n을 기준으로 m dimension의 Vector 값들이 평균 0, 분산 1이 되도록 Normalization을 하여 각 모듈마다 (여기서는 FFN 모듈) 값의 분포가 일정하게 함으로써 Gradient vanishing 또는 exploding을 예방하여 수렴 속도를 높이고 학습 안정성을 높이는 효과가 있다.


----- Final Module -----

9. Layer Normalization & Fully Connected Network & Softmax >> (1, vocab_size)

N개의 Decoder Block을 지난 후에는 (n, m) matrix를 얻게 되고, 각 m에 대해 최종 Layer Normalization을 한 번 더 진행하기도 한다.

학습 시에는 (n, m) matrix를 Fully Connected Network에 통과시켜 각 토큰의 위치에서 다음으로 올 Token들의 Logit을 계산한다. (n, m) @ (m, vocab_size) = (n, vocab_size)
이를 Softmax에 통과시켜 각 값이 0~1 사이의 확률 값을 가지고 전체 합이 1이 되도록하여 각 Vocab의 Probability를 계산한다.
여기서 vocab_size는 2번 Token Embedding Table에서 사용했던 것 처럼 모델이 알고 있는 모든 후보 토큰들이다.
Loss Function은 CrossEntropy를 활용하고 loss는 "-log (정답토큰의 예측 확률)"로 계산된다.
즉, 이 최종 Matrix는 다음 단어로 올 후보들의 점수판이 된다.

>> (n, voca_size) matrix

추론 시에는
(n, m) matrix 중 이전 Token을 모두 반영한 '최종 문맥 표현 (Contextual represntation)'인 가장 마지막 (1, m)만 Projection Layer (FCN + Softmax)에 넣어 (1, vocab_size)을 만듦으로써 다음 토큰 후보의 점수판을 얻는다. argmax나 샘플링으로 다음 토큰을 선택한다.

>> (1, vocab_size) matrix



10. 전체 흐름

Tokenization

→ Token Embedding + Positional Encoding

→ [for i in 1..N]

LayerNorm → Masked Multi-head Self-Attention → Residual Add

LayerNorm → Feed Forward Network → Residual Add

end

→ LayerNorm

→ Linear Projection to vocab_size

→ Softmax or CrossEntropy Loss


[요약]

Decoder-only 모델은 입력 시퀀스를 Embedding 후 N개의 Decoder Block을 거쳐 최종 LayerNorm을 적용하고, Linear Projection을 통해 어휘집 크기(vocab_size)만큼의 로짓(logits)을 생성한다.

학습 시에는 이 로짓에 Softmax를 적용하여 각 토큰의 확률 분포를 계산하고, 정답 토큰과 비교하여 CrossEntropy Loss를 구한다. Inference 시에는 이 확률 분포를 기반으로 argmax 또는 샘플링 전략을 통해 다음 토큰을 생성하며, 이를 반복하여 문장을 완성한다.

keyword
작가의 이전글Multi-Agent 기반 추천 시스템 설계