참조 사이트
- SKALA 4기 - LLM과 Transformer 아키텍처 (SK AX SKALA)
- Attention Is All You Need (Vaswani et al., 2017)
- Deep Residual Learning for Image Recognition (He et al., 2015)
- Root Mean Square Normalization (Zhang et al., 2019)
- GLU Variants Improve Transformer (Shazeer, 2020)
개요

지난 [LLM Pipeline 4]에서는 단어 간 상호 연관성을 동적으로 계산하여 문맥 정보를 융합하는 셀프 어텐션(Self-Attention)과 멀티헤드 어텐션(Multi-Head Attention)의 핵심 원리를 살펴보았다.
어텐션 연산을 거쳐 출력된 결과물은 각 토큰의 문맥 정보가 반영된 [Batch, Time, Dimension] (이하 [B, T, D]) 형태의 3차원 실수 밀집 텐서이다. 하지만 수십 개에서 수백 개 이상의 레이어를 깊게 쌓아 올리는 현대 대형 언어 모델(LLM) 환경에서 단순히 어텐션 레이어만 연속적으로 적층할 경우, 신경망 학습 과정에서 기울기가 불안정해져 학습이 쉽게 무너진다.
또한 어텐션 블록은 본질적으로 토큰 간의 선형 결합(Linear Combination)을 수행하므로, 모델이 사실적 지식(Factual Knowledge)을 기억하고 복잡한 비선형 패턴을 학습하기 위해서는 추가적인 비선형 변환 모듈이 필수적으로 결합되어야 한다.
이번 글에서는 어텐션 출력을 안정적으로 전달하고 모델의 표현력을 극대화하는 3대 핵심 모듈인 잔차 연결(Residual Connection), 정규화(LayerNorm & RMSNorm), 그리고 피드포워드 네트워크(FFN & SwiGLU)의 동작 원리와 순전파 메커니즘을 정리한다.
💡 용어 사전: 트랜스포머 블록(Transformer Block) 어텐션(Attention) 서브레이어와 피드포워드(FFN) 서브레이어, 그리고 이들을 감싸는 잔차 연결(Residual Connection) 및 정규화(Normalization) 레이어로 구성된 트랜스포머 신경망의 기본 반복 단위이다. LLaMA-3-8B는 이 블록을 32개, LLaMA-3-70B는 80개를 직렬로 적층하여 아키텍처를 구성한다.
1. 잔차 연결(Residual Connection): 100층 이상 깊어져도 학습이 무너지지 않는 이유
① 기울기 소실 극복과 역전파 경로 (Gradient Highway)

신경망의 층이 깊어질수록 역전파(Backpropagation) 과정에서 오차 기울기(Gradient)가 연쇄적으로 곱해지며 0으로 수렴하는 기울기 소실(Gradient Vanishing) 문제가 발생할 수 있다. ResNet에서 제안되어 트랜스포머의 표준 구조가 된 잔차 연결(Residual Connection / Skip Connection)은 서브레이어의 입력을 출력에 직접 더해주는(Addition) 연산으로 이 문제를 해결한다.
- 순전파 수식: y = x + F(x)
- x: 서브레이어 입력 텐서
- F(x): 서브레이어(어텐션 또는 FFN)의 연산 결과
- y: 잔차 연결이 적용된 최종 출력 텐서
이 구조는 역전파 수식에서 진가를 드러낸다. 손실 함수 L에 대한 입력 x의 편미분을 계산하면 다음과 같다.
- 역전파 기울기 수식: ∂L/∂x = ∂L/∂y · (1 + ∂F(x)/∂x) = ∂L/∂y + ∂L/∂y · ∂F(x)/∂x
수식에서 볼 수 있듯이, 괄호 안의 + 1 덕분에 서브레이어의 가중치 미분값(∂F(x)/∂x)이 아무리 0에 수렴하더라도 최소한 상위 레이어의 기울기(∂L/∂y)가 이전 레이어에 직접 전달되는 경로(Gradient Highway)가 확보된다.
② 텐서 차원의 보존 (D)
잔차 연결은 원소별 덧셈(Element-wise Addition) 연산이므로, 서브레이어의 입력 차원과 출력 차원이 완벽하게 일치해야 한다.
- 입력 x의 차원: [B, T, D]
- F(x)의 출력 차원: [B, T, D]
- 잔차 덧셈 결과: [B, T, D]
이 제약 조건으로 인해 트랜스포머 내부의 모든 서브레이어는 은닉 차원(Hidden Dimension, D)을 처음부터 끝까지 동일하게 유지하는 대칭 구조를 갖춘다.
2. 정규화의 진화: LayerNorm에서 현대 LLM의 표준 RMSNorm까지

① NLP에서 BatchNorm 대신 LayerNorm을 쓰는 이유
컴퓨터 비전(CV) 분야에서 널리 쓰이는 배치 정규화(Batch Normalization)는 미니배치(B) 축을 기준으로 평균과 분산을 계산한다. 하지만 자연어 처리(NLP) 분야에서는 다음과 같은 이유로 배치 정규화가 제대로 작동하지 않는다.
- 가변적인 문장 길이: 문장마다 입력 길이가 달라 패딩 토큰이 섞이면 배치 단위 통계량이 왜곡된다.
- 배치 크기 의존성: 생성 추론(Inference) 단계에서 배치 크기가 1이 될 경우 통계량 추정이 불가능해진다.
이를 해결하기 위해 도입된 LayerNorm은 배치 크기나 시퀀스 길이와 무관하게, 각 토큰의 D차원 특징 벡터(Feature Vector) 독립적으로 평균(μ)과 분산(σ²)을 계산하여 정규화한다.
💡 용어 사전: 레이어 정규화 (Layer Normalization)
입력 데이터의 특정 축(트랜스포머에서는 은닉 차원 D 축)을 기준으로 평균을 0, 분산을 1로 맞춘 뒤, 학습 가능한 스케일(γ) 및 시프트(β) 파라미터를 적용하여 특징 벡터의 분포를 안정화하는 기술이다.
- LayerNorm 공식:
- μ = (1 / D) · Σ x_i
- σ² = (1 / D) · Σ (x_i - μ)²
- LN(x) = ( (x - μ) / √(σ² + ε) ) · γ + β
- ε (Epsilon): 0으로 나누는 것을 방지하는 작은 상수 (예: 1e-5)
- γ (Gain), β (Bias): 학습 가능한 가중치
② Pre-LN vs Post-LN의 패러다임 전환
정규화 레이어가 배치되는 위치에 따라 심층 신경망의 학습 안정성이 크게 달라진다.
- Post-LN (초기 트랜스포머, BERT):
- 구조: x_(l+1) = LN(x_l + F(x_l))
- 문제점: 층이 깊어질수록 잔차 경로의 활성화 값 분산이 통제 불능 상태로 누적된다. 이를 억제하기 위해 학습 초기에 정밀한 웜업(Warm-up) 학습률 스케줄러를 필수적으로 적용해야 한다.
- Pre-LN (현대 LLM 표준: GPT-3, LLaMA, Mistral, Gemma):
- 구조: x_(l+1) = x_l + F(LN(x_l))
- 장점: 서브레이어 연산 직전에 입력을 정규화하므로 메인 잔차 경로(x_l)가 왜곡 없이 보존된다. Pre-LN은 잔차 경로를 안정적으로 보존하여 Post-LN보다 깊은 모델의 학습을 안정화하고, warm-up에 대한 의존성을 줄여준다.
③ 연산 효율 극대화: RMSNorm (Root Mean Square Normalization)
LLaMA, Mistral, Gemma 등 최신 오픈소스 모델은 기존 LayerNorm 대신 RMSNorm을 탑재하고 있다.
Zhang & Sennrich (2019)의 연구에 따르면, 정규화가 학습 안정성을 높이는 핵심 요인은 평균을 0으로 맞추는 행위(Mean Centering)가 아니라 출력의 스케일을 일정하게 제한하는 스케일링 불변성(Scaling Invariance)에 있음이 밝혀졌다. 따라서 계산 비용이 큰 평균(μ)과 편향(β) 연산을 과감히 생략하고 제곱평균제곱근(RMS)만으로 데이터 분포를 조율한다.
- RMSNorm 공식:
- RMS(x) = √( (1 / D) · Σ x_i² + ε )
- RMSNorm(x) = ( x / RMS(x) ) · γ
- 엔지니어링 이점: 평균 계산 과정이 빠지고 편향(β) 파라미터가 제거되면서 연산량이 약 10%~50% 감소한다. 이는 GPU의 메모리 대역폭(Memory Bandwidth) 접근 병목을 완화하는 성능상 이점을 가져온다.
3. 피드포워드 네트워크(FFN): 비선형 변환과 지식 표현의 핵심 모듈

① Attention과 FFN의 명확한 역할 분담
트랜스포머 블록 내부에서 어텐션과 피드포워드 네트워크는 담당하는 역할이 엄격히 분리되어 있다.
- 어텐션(Attention):
- "어느 토큰과 상호작용해야 하는가?"를 다루며 시퀀스 축(T)을 가로지르며 공간적으로 문맥을 결합한다.
- 피드포워드 네트워크(FFN):
- 문맥적 상호작용 없이 개별 토큰 벡터 내부에서만 1:1로 수행되는 독립적인 연산이다.
- 여러 신경망 연구(Geva et al., 2021)에 따르면, FFN의 학습된 가중치들이 거대한 사전학습 말뭉치의 사실적 정보들을 담아내는 키-값 메모리(Key-Value Memory) 역할을 수행함이 밝혀졌다.
💡 용어 사전: 피드포워드 네트워크 (FFN) 각 토큰의 위치 정보와 상관없이 다층 퍼셉트론(MLP)을 통해 비선형적인 특징을 풍부하게 생성하고 복원하는 트랜스포머 내부의 완전 연결 레이어(Fully Connected Layer)이다.
② 표준 FFN (Position-wise MLP)
초기 트랜스포머 및 GPT-2/3 등에서 사용된 구조이다.
- 수식: FFN(x) = GELU( x · W_1 + b_1 ) · W_2 + b_2
- W_1 ∈ ℝ^(D × 4D): 은닉 차원을 4배로 확장하는 업-프로젝션 행렬
- W_2 ∈ ℝ^(4D × D): 원래 차원으로 복원하는 다운-프로젝션 행렬
- GELU: 부드러운 활성화 함수 (Gaussian Error Linear Unit)
- 은닉 차원을 일시적으로 4배(4D)로 확장하여 비선형 차원 특징을 풍부하게 결합한다.
- 비선형 활성화 함수를 통과시킨 뒤, 다시 본래의 차원(D)으로 투영 압축하여 다음 레이어로 넘긴다.
③ 현대 LLM의 글로벌 표준: SwiGLU (Swish Gated Linear Unit)

최신 LLM 연구들을 이끄는 핵심 아키텍처 변화 중 하나는 표준 FFN 대신 SwiGLU를 채택한 것이다.
단순 선형 변환 후 활성화를 적용하는 것과 달리, SwiGLU는 정보 전달량을 스스로 조율할 수 있는 게이팅 메커니즘(Gating Mechanism)과 SiLU(Swish) 활성화 함수를 결합하여 동작한다.
- SwiGLU 공식:
- SwiGLU(x) = ( SiLU( x · W_gate ) ⊗ ( x · W_up ) ) · W_down
- W_gate ∈ ℝ^(D × D_hidden): 정보 제어 게이트 가중치
- W_up ∈ ℝ^(D × D_hidden): 데이터 정보 생성을 담당하는 업-프로젝션 가중치
- W_down ∈ ℝ^(D_hidden × D): 원래 차원으로 복원하는 다운-프로젝션 가중치
- ⊗: 원소별 곱 (Hadamard Product)
- SiLU(z) = z · σ(z) = z / (1 + e^(-z))
- 차원 설계 원칙:
- SwiGLU는 3개의 가중치 행렬을 사용하므로 연산량 균형을 맞추기 위해 은닉 팽창 차원 D_hidden을 표준 FFN의 4D 대신 대략 (8/3) · D ≈ 2.67D 크기로 설정한다 (예: LLaMA-3-8B 아키텍처는 D = 4096, D_hidden = 14336을 적용한다).
💡 용어 사전: 게이팅 메커니즘(Gating Mechanism)
특정 정보가 다음 단계로 얼마나 흘러갈지(통과 비율)를 0과 1 사이의 실수값으로 동적으로 조절하는 기법이다. 활성화 함수를 거친 게이트 신호와 실제 데이터 벡터를 원소별로 곱해(Element-wise Product), 유의미한 특징은 통과시키고 불필요한 노이즈는 걸러내는 필터 역할을 수행한다.
💡 용어 사전: SiLU (Sigmoid Linear Unit / Swish)
입력값 x에 시그모이드(Sigmoid) 함수를 곱한 비선형 활성화 함수이다 [f(x) = x · σ(x)]. 음수 구간에서 기울기가 완전히 0이 되어 뉴런이 죽는 ReLU의 단점을 보완하며, 모든 구간에서 부드럽게 미분 가능한 곡선을 지녀 LLaMA 등 현대 LLM의 심층 역전파 수렴 안정성을 크게 높여준다.
4. 정규화 및 FFN 구조 핵심 비교
| 비교 항목 | LayerNorm | RMSNorm (현대 표준) |
| 평균 계산 (Mean Centering) | 수행함 (μ 산출 필수) | 생략함 (0 중심화 연산 생략) |
| 학습 파라미터 | 스케일(γ), 시프트(β) | 스케일(γ) 파라미터만 단독 사용 |
| 연산 가속화율 | 기본 수준 | 10% ~ 50%의 처리 가속 효과 실현 |
| 적용 대표 모델 | Original Transformer, BERT, GPT-2/3 | LLaMA 1/2/3, Mistral, Gemma, Qwen |
| 비교 항목 | 표준 FFN (GELU MLP) | SwiGLU (현대 표준) |
| 가중치 행렬 개수 | 2개 (W_1, W_2) | 3개 (W_gate, W_up, W_down) |
| 은닉 확장 차원 (D_hidden) | 4 · D | 약 (8/3) · D (약 2.67 · D) |
| 정보 제어 게이트 | 없음 | 원소별 게이트 곱 연산 적용 |
| 수렴 속도 및 완성도 | 기준 설계 구조 | 우수한 언어 모델링 능력 및 빠른 수렴 |
| 적용 대표 모델 | BERT, GPT-2, GPT-3 | LLaMA 1/2/3, Mistral, Gemma, PaLM |
5. PyTorch로 완성하는 단일 Transformer Block 전체 순전파 구현
이론으로 정리한 Pre-RMSNorm, Causal-Attention, SwiGLU FFN 및 잔차 연결을 하나의 완성된 모듈로 조립하는 파이토치 예제 코드는 다음과 같다.
import torch
import torch.nn as nn
import torch.nn.functional as F
class RMSNorm(nn.Module):
def __init__(self, dim, eps=1e-6):
super().__init__()
self.eps = eps
self.weight = nn.Parameter(torch.ones(dim))
def forward(self, x):
# 분산(Variance)만 구하고 평균 차감은 생략하는 고속 정규화
variance = x.pow(2).mean(-1, keepdim=True)
return x * torch.rsqrt(variance + self.eps) * self.weight
class CausalSelfAttention(nn.Module):
def __init__(self, dim, n_heads):
super().__init__()
assert dim % n_heads == 0
self.n_heads = n_heads
self.head_dim = dim // n_heads
self.w_q = nn.Linear(dim, dim, bias=False)
self.w_k = nn.Linear(dim, dim, bias=False)
self.w_v = nn.Linear(dim, dim, bias=False)
self.w_o = nn.Linear(dim, dim, bias=False)
def forward(self, x):
B, T, D = x.shape
# Q, K, V 매핑 및 멀티헤드 정렬
q = self.w_q(x).view(B, T, self.n_heads, self.head_dim).transpose(1, 2)
k = self.w_k(x).view(B, T, self.n_heads, self.head_dim).transpose(1, 2)
v = self.w_v(x).view(B, T, self.n_heads, self.head_dim).transpose(1, 2)
# 어텐션 맵 연산
scores = torch.matmul(q, k.transpose(-2, -1)) / torch.sqrt(torch.tensor(self.head_dim, dtype=torch.float32))
# 미래 정보 노출을 배제하는 인과적 마스크(Causal Mask) 주입
mask = torch.triu(torch.ones(T, T, device=x.device), diagonal=1).bool()
scores = scores.masked_fill(mask, float('-inf'))
attn_weights = F.softmax(scores, dim=-1)
out = torch.matmul(attn_weights, v)
# 쪼개졌던 병렬 구조 복원 및 최종 융합
out = out.transpose(1, 2).contiguous().view(B, T, D)
return self.w_o(out)
class SwiGLU(nn.Module):
def __init__(self, dim, hidden_dim):
super().__init__()
self.w_gate = nn.Linear(dim, hidden_dim, bias=False)
self.w_up = nn.Linear(dim, hidden_dim, bias=False)
self.w_down = nn.Linear(hidden_dim, dim, bias=False)
def forward(self, x):
# SiLU(xW_gate)와 xW_up의 곱 연산
return self.w_down(F.silu(self.w_gate(x)) * self.w_up(x))
class TransformerBlock(nn.Module):
def __init__(self, dim, n_heads, hidden_dim):
super().__init__()
self.norm1 = RMSNorm(dim)
self.attn = CausalSelfAttention(dim, n_heads)
self.norm2 = RMSNorm(dim)
self.ffn = SwiGLU(dim, hidden_dim)
def forward(self, x):
# 1) Pre-Norm ➔ 셀프 어텐션 ➔ 1차 잔차 더하기
x = x + self.attn(self.norm1(x))
# 2) Pre-Norm ➔ SwiGLU FFN ➔ 2차 잔차 더하기
x = x + self.ffn(self.norm2(x))
return x
# 가상 입력을 통한 단일 블록 연산 작동성 검증
if __name__ == "__main__":
B, T, D = 2, 4, 768
n_heads = 8
hidden_dim = int((8/3) * D) # 약 2.67배 확장한 2048차원 은닉 영역 지정
# [B, T, D] 정밀 텐서 생성
inputs = torch.randn(B, T, D)
print("1. 입력 텐서 차원 (X) :", inputs.shape)
block = TransformerBlock(dim=D, n_heads=n_heads, hidden_dim=hidden_dim)
outputs = block(inputs)
print("2. 최종 출력 텐서 차원 :", outputs.shape)
실행 결과 출력
1. 입력 텐서 차원 (X) : torch.Size([2, 4, 768])
2. 최종 출력 텐서 차원 : torch.Size([2, 4, 768])
6. 데이터 파이프라인 텐서 차원(Tensor Shape) 변화 요약
결국 Transformer Block은 세 가지 역할을 분담한다.
- Attention → 토큰과 토큰 사이의 정보를 섞는다.
- FFN → 각 토큰 내부의 표현을 비선형적으로 변환한다.
- Residual + Norm → 이 두 연산을 깊게 반복할 수 있도록 학습을 안정화한다.
트랜스포머 단일 블록을 통과하면서 변화하는 핵심 텐서 흐름은 다음과 같이 정렬된다.
- 블록 입력단: 이전 트랜스포머 블록 또는 임베딩 룩업 레이어에서 수신한 [B, T, D] 밀집 데이터에서 연산이 시작된다.
- Pre-Norm (1차): 토큰 특징 방향(D 축)으로 RMSNorm 정규화를 거친다. 결과 차원은 [B, T, D]로 보존된다.
- 어텐션 서브레이어: 어텐션 연산(QKV 사영, 헤드 정렬, 인과 마스킹, 가중합, 병합)을 수행한다. 차원은 [B, T, D] 그대로 출력된다.
- 1차 잔차 합산: 연산 전에 복제하여 들고 가던 원본 입력 x와 어텐션 결과를 가산한다. 차원 변화 없이 메인 고속도로 [B, T, D]가 유지된다.
- Pre-Norm (2차): FFN 진입 직전 다시 차원 벡터 방향으로 RMSNorm 연산을 통과시킨다. [B, T, D]가 유지된다.
- SwiGLU FFN: W_gate와 W_up 가중치를 만나 은닉 확장 영역 D_hidden으로 일시 팽창하며 게이팅 제어를 거친 뒤, 다운-프로젝션을 통해 다시 [B, T, D] 형태로 복원된다.
- 2차 잔차 합산: 중간 텐서와 최종 FFN 결과물을 융합한다. 최종 [B, T, D] 차원을 완성하여 다음 블록으로 전달한다.
요약 및 다음 단계
- 잔차 연결(Residual Connection): 가중합 공식 괄호 내부의 + 1을 통해, 심층 레이어에서도 기울기 소실 없이 안정적으로 역전파를 수행한다.
- 정규화의 고속 진화(RMSNorm): 불필요한 평균 중심화 연산 및 편향(β) 변수를 제거하고, 출력 스케일 조율(RMS)만 수행함으로써 학습 안정성과 속도 향상을 함께 달성했다.
- 지식 저장 게이터(SwiGLU FFN): 토큰 벡터 내부의 팽창과 능동 게이팅 연산을 결합하여, 모델 고유의 사실적 지식을 저장하고 인출하는 역할을 수행한다.
다음 [LLM Pipeline 6]에서는 수십 개의 트랜스포머 블록을 통과하여 최종 완성된 [B, T, D] 실수형 은닉 텐서를 전체 어휘 사전 확률로 매핑하는 언임베딩(Unembedding / LM Head), Softmax, 그리고 생성 전략(Temperature, Top-k, Top-p sampling) 파이프라인의 최종 완결을 다룬다.
틀린 부분이 있거나 인용한 부분에 대해 문제가 있을 시
댓글로 알려주시면 감사하겠습니다.
'Programming > Dev notes' 카테고리의 다른 글
| [LLM Pipeline 6] 언어 모델 헤드(LM Head)와 디코딩 전략: Temperature, Top-k, Top-p (0) | 2026.09.02 |
|---|---|
| [LLM Pipeline 4] 트랜스포머: Q·K·V 수식 분해와 4대 어텐션(Attention) 메커니즘 (0) | 2026.08.31 |
| [LLM Pipeline 3] 토큰 임베딩(Token Embedding)과 위치 인코딩(Positional Encoding & RoPE) (0) | 2026.08.28 |
| [LLM Pipeline 2] Sliding Window와 Stride 기반 데이터로더(DataLoader) 파이프라인 (0) | 2026.08.28 |
| [LLM Pipeline 1] 토크나이저(Tokenizer)와 BPE 알고리즘 (0) | 2026.08.27 |