검색
← 모듈 로드맵

트랜스포머 블록 한 층을 손으로: 멀티헤드 · 잔차 · 정규화 · FFN

강의 · 준전문가 · KAITABASE 정리

원제 · The Transformer Block (D2L 11.7 참고)

토큰 2개 · 헤드 2개 예로 트랜스포머 블록 한 층을 끝까지 손계산하는 수업

먼저 알아야 할 것

스케일드 내적 어텐션인과 마스킹레이어 정규화잔차 연결행렬 곱

다루는 내용

트랜스포머 블록 하나의 계산 순서(정규화 → 멀티헤드 어텐션 → 잔차 → 정규화 → FFN → 잔차)를 4차원 작은 행렬로 끝까지 계산합니다. 층당 파라미터가 약 12d²인 이유를 유도해 GPT-3 규모에 대입하고, Pre-LN · RMSNorm · SwiGLU로 바뀐 이유를 원 논문 근거로 정리합니다.

해설

트랜스포머 블록 한 층을 손으로: 멀티헤드 · 잔차 · 정규화 · FFN

GPT도 BERT도 결국 같은 블록을 수십 번 쌓은 것 입니다. 블록 하나 안에서는 ① 정규화 ② 멀티헤드 어텐션 ③ 잔차 더하기 ④ 다시 정규화 ⑤ 피드포워드 신경망(FFN) ⑥ 잔차 더하기가 차례로 일어납니다. 이 수업에서는 토큰 2개 · 4차원 · 헤드 2개짜리 작은 예로 이 여섯 단계를 끝까지 손으로 계산하고, 파라미터 수가 어디서 나오는지, 왜 요즘 모델은 Pre-LN · RMSNorm · SwiGLU를 쓰는지 정리합니다.

항목내용
참고 출처D2L 11.5절 멀티헤드 어텐션 · 11.7절 트랜스포머 · 트랜스포머 원 논문 · Pre-LN 분석(arXiv 2002.04745) · RMSNorm(arXiv 1910.07467) · GLU 변형(arXiv 2002.05202)
트랙 · 수준NLP·트랜스포머 · 중급
이 수업이 다루는 범위블록 구조, 멀티헤드 계산, 인과 마스크, 잔차 연결, 레이어 정규화 · RMSNorm, Post-LN vs Pre-LN, FFN · GELU · SwiGLU, 파라미터 수 세기

들어가기 전에

한눈에 보기

  • 트랜스포머 블록 하나의 계산 순서를 그림 없이 말로 설명할 수 있습니다.
  • 헤드 2개짜리 멀티헤드 어텐션을 작은 행렬로 직접 계산합니다.
  • 잔차 연결과 레이어 정규화가 왜 깊은 모델을 학습 가능하게 하는지 압니다.
  • 층 하나의 파라미터가 대략 12d212d^2 개라는 것을 유도하고, GPT-3 규모에 대입해 봅니다.
  • Post-LN → Pre-LN, LayerNorm → RMSNorm, ReLU → SwiGLU로 바뀐 이유를 압니다.

1. 블록 전체 그림

직관(해설용 비유). 회의를 떠올립니다. ① 각자 메모를 정리하고(정규화) ② 서로의 말을 듣고 필요한 부분을 받아 적고(어텐션) ③ 원래 내 메모에 받아 적은 것을 덧붙입니다(잔차). ④ 다시 정리한 뒤 ⑤ 혼자 곰곰이 생각해 내용을 다듬고(FFN) ⑥ 그 생각도 메모에 덧붙입니다(잔차). 어텐션은 토큰끼리 정보를 주고받는 단계, FFN은 토큰마다 따로 생각하는 단계 입니다.

요즘 디코더 LLM이 주로 쓰는 Pre-LN 블록을 식으로 쓰면 다음과 같습니다.

H=X+MHA(LN(X)),Y=H+FFN(LN(H))H = X + \mathrm{MHA}\big(\mathrm{LN}(X)\big),\qquad Y = H + \mathrm{FFN}\big(\mathrm{LN}(H)\big)
기호크기뜻
XXn×dn\times d블록 입력(토큰 nn 개, 각 dd 차원)
LN\mathrm{LN}—레이어 정규화(토큰마다 평균 0 · 분산 1로)
MHA\mathrm{MHA}—멀티헤드 셀프 어텐션
HHn×dn\times d어텐션 결과를 더한 중간값
FFN\mathrm{FFN}—토큰마다 같은 2층 신경망
YYn×dn\times d블록 출력. 다음 블록의 입력이 됩니다

입력과 출력 크기가 같다는 점이 중요합니다. 그래서 블록을 몇 개든 쌓을 수 있습니다.

mermaid
flowchart TB
  X[입력 X] --> LN1[레이어 정규화]
  LN1 --> MHA[멀티헤드 셀프 어텐션<br/>인과 마스크]
  MHA --> ADD1((+))
  X --> ADD1
  ADD1 --> H[H]
  H --> LN2[레이어 정규화]
  LN2 --> FFN[FFN: 확장 → 활성화 → 축소]
  FFN --> ADD2((+))
  H --> ADD2
  ADD2 --> Y[출력 Y → 다음 블록]

2. 손으로 계산하기: 준비

설정(해설용). 토큰 2개, d=4d=4, 헤드 2개(헤드당 2차원), 인과 마스크를 씁니다. 계산을 보이기 쉽게 WQ=WK=WV=WO=IW_Q=W_K=W_V=W_O=I(항등 행렬)로 둡니다. 그러면 헤드 1은 정규화된 벡터의 앞 두 칸, 헤드 2는 뒤 두 칸을 그대로 쿼리 · 키 · 값으로 씁니다. 실제 모델에서는 이 행렬들이 학습되는 값입니다.

X=(10212013)X=\begin{pmatrix}1&0&2&1\\2&0&1&3\end{pmatrix}

3. 단계 ①: 레이어 정규화

직관. 토큰마다 숫자의 평균을 0, 퍼짐(분산)을 1로 맞춥니다. 층을 지날수록 값이 커지거나 작아지는 것을 막아 학습을 안정시킵니다.

LN(x)=γ⊙x−μσ2+ϵ+β\mathrm{LN}(x)=\gamma\odot\frac{x-\mu}{\sqrt{\sigma^2+\epsilon}}+\beta
기호뜻
μ, σ2\mu,\ \sigma^2그 토큰 벡터 원소들의 평균 · 분산
ϵ\epsilon0으로 나누기 방지용 아주 작은 수(여기서는 0으로 둠)
γ, β\gamma,\ \beta학습되는 크기 · 이동 값(여기서는 1, 0)

계산.

  • 토큰 1: 평균 11, 분산 0+1+1+04=0.5\frac{0+1+1+0}{4}=0.5, 0.5=0.707\sqrt{0.5}=0.707 → (0, −1.414, 1.414, 0)(0,\ -1.414,\ 1.414,\ 0)
  • 토큰 2: 평균 1.51.5, 분산 0.25+2.25+0.25+2.254=1.25\frac{0.25+2.25+0.25+2.25}{4}=1.25, 1.25=1.118\sqrt{1.25}=1.118 → (0.447, −1.342, −0.447, 1.342)(0.447,\ -1.342,\ -0.447,\ 1.342)

4. 단계 ②: 멀티헤드 어텐션

왜 여러 헤드인가. 헤드 하나는 "한 가지 기준"으로만 관련성을 봅니다. 헤드를 여러 개 두면 문법 관계, 가까운 단어, 지시어 등 서로 다른 기준을 동시에 볼 수 있습니다. 차원을 헤드 수로 나눠 쓰므로 계산량은 헤드 하나일 때와 비슷합니다. 원 논문의 기본 모델은 d=512d=512, 헤드 8개, 헤드당 64차원이었습니다.

헤드 1(앞 두 칸). q1=k1=v1=(0,−1.414)q_1=k_1=v_1=(0,-1.414), q2=k2=v2=(0.447,−1.342)q_2=k_2=v_2=(0.447,-1.342).

  • 토큰 1은 자기 자신만 봅니다(인과 마스크). 가중치 (1,0)(1, 0) → 출력 (0, −1.414)(0,\ -1.414)
  • 토큰 2의 점수: q2⋅k1/2=(0+1.898)/1.414=1.342q_2\cdot k_1/\sqrt2 = (0+1.898)/1.414 = 1.342, q2⋅k2/2=(0.2+1.8)/1.414=1.414q_2\cdot k_2/\sqrt2=(0.2+1.8)/1.414=1.414
  • 소프트맥스 ≈(0.482, 0.518)\approx(0.482,\ 0.518) → 출력 0.482(0,−1.414)+0.518(0.447,−1.342)≈(0.232, −1.377)0.482(0,-1.414)+0.518(0.447,-1.342)\approx(0.232,\ -1.377)

헤드 2(뒤 두 칸). k1=(1.414,0)k_1=(1.414, 0), k2=(−0.447,1.342)k_2=(-0.447, 1.342).

  • 토큰 1: 출력 (1.414, 0)(1.414,\ 0)
  • 토큰 2의 점수: q2⋅k1/2=−0.632/1.414=−0.447q_2\cdot k_1/\sqrt2=-0.632/1.414=-0.447, q2⋅k2/2=2/1.414=1.414q_2\cdot k_2/\sqrt2=2/1.414=1.414
  • 소프트맥스 ≈(0.135, 0.865)\approx(0.135,\ 0.865) → 출력 ≈(−0.197, 1.161)\approx(-0.197,\ 1.161)

같은 토큰 2인데 헤드 1은 두 토큰을 거의 반반, 헤드 2는 자기 자신을 87% 봅니다. 헤드마다 보는 방식이 다르다 는 것이 멀티헤드의 핵심입니다.

이어 붙이기. 두 헤드 출력을 옆으로 붙이고 WOW_O(여기서는 II)를 곱합니다.

MHA=(0−1.4141.41400.232−1.377−0.1971.161)\mathrm{MHA}=\begin{pmatrix}0&-1.414&1.414&0\\0.232&-1.377&-0.197&1.161\end{pmatrix}

5. 단계 ③: 잔차 연결

직관. 어텐션 결과로 입력을 대체하지 않고, 덧붙입니다. 블록은 "입력을 얼마나 고칠지"만 배우면 됩니다. 기울기도 덧셈 길을 따라 깊은 층까지 바로 흐릅니다(ResNet의 아이디어).

H=X+MHA=(1−1.4143.41412.232−1.3770.8034.161)H = X + \mathrm{MHA} = \begin{pmatrix}1&-1.414&3.414&1\\2.232&-1.377&0.803&4.161\end{pmatrix}

6. 단계 ④~⑥: 정규화 → FFN → 잔차

FFN의 역할. 토큰마다 따로 적용되는 2층 신경망입니다. 차원을 넓혔다가(확장) 비선형 함수를 지나 다시 줄입니다(축소). 원 논문 기본 모델은 d=512d=512 를 dff=2048d_{ff}=2048 (4배)로 넓혔습니다. 어텐션이 정보를 모으는 곳이라면, FFN은 모은 정보를 가공하는 곳으로 흔히 설명합니다.

FFN(x)=max⁡(0, xW1+b1) W2+b2\mathrm{FFN}(x) = \max(0,\ xW_1 + b_1)\,W_2 + b_2

계산(해설용, dff=4d_{ff}=4 로 축소). HH 를 정규화하면 토큰 1은 (0,−1.414,1.414,0)(0,-1.414,1.414,0), 토큰 2는 ≈(0.384,−1.400,−0.322,1.338)\approx(0.384,-1.400,-0.322,1.338) 입니다. W1W_1 과 W2=0.5IW_2=0.5I 를 다음처럼 정합니다.

W1=(1−10001−10001−11001)W_1=\begin{pmatrix}1&-1&0&0\\0&1&-1&0\\0&0&1&-1\\1&0&0&1\end{pmatrix}
  • 토큰 1: xW1=(0, −1.414, 2.828, −1.414)xW_1=(0,\ -1.414,\ 2.828,\ -1.414) → ReLU (0,0,2.828,0)(0,0,2.828,0) → ×0.5\times0.5 → (0,0,1.414,0)(0,0,1.414,0)
  • 토큰 2: xW1≈(1.722, −1.784, 1.078, 1.660)xW_1\approx(1.722,\ -1.784,\ 1.078,\ 1.660) → ReLU (1.722,0,1.078,1.660)(1.722,0,1.078,1.660) → ×0.5\times0.5 → (0.861,0,0.539,0.830)(0.861,0,0.539,0.830)

최종 출력.

Y=H+FFN≈(1−1.4144.82813.093−1.3771.3424.991)Y = H + \mathrm{FFN} \approx \begin{pmatrix}1&-1.414&4.828&1\\3.093&-1.377&1.342&4.991\end{pmatrix}

모든 값은 파이썬(넘파이)으로 검산했습니다. 이 YY 가 다음 블록의 XX 가 되고, 마지막 블록 뒤에는 정규화 → 어휘 크기 행렬 곱 → 소프트맥스로 다음 토큰 확률을 냅니다.

7. 파라미터 수 세기

층 하나의 행렬 크기를 세면(편향 · 정규화 파라미터는 작아서 뺌):

부품행렬파라미터
어텐션WQ,WK,WV,WOW_Q, W_K, W_V, W_O 각 d×dd\times d4d24d^2
FFNW1W_1: d×4dd\times 4d, W2W_2: 4d×d4d\times d8d28d^2
합계12d212d^2

숫자로 해 보기. GPT-3 논문 표에서 가장 큰 모델은 층 96개, d=12288d=12288 입니다. 12×122882×96≈1.74×101112\times12288^2\times96\approx1.74\times10^{11}, 즉 약 1,740억 개로 논문이 밝힌 175.0B와 거의 맞습니다(남는 차이는 임베딩 등). 이 계산은 스케일링 법칙과 연산 예산 수업에서 학습 비용을 셀 때 다시 씁니다.

8. 원조 이후 바뀐 부품들

Post-LN → Pre-LN. 원 논문은 LN(x+Sublayer(x))\mathrm{LN}(x+\mathrm{Sublayer}(x)), 즉 더한 뒤에 정규화했습니다(Post-LN). Xiong 외(2020)는 Post-LN에서는 출력 근처 층의 기울기가 초기에 커서 학습률 워밍업(처음에 아주 작은 학습률에서 천천히 올리는 것)이 꼭 필요하고, 정규화를 서브층 앞에 두는 Pre-LN은 기울기가 초기부터 안정적이라 워밍업 없이도 학습되는 것을 보였습니다. 위 식이 Pre-LN입니다.

LayerNorm → RMSNorm. RMSNorm은 평균을 빼는 과정(재중심화)을 생략하고 제곱평균제곱근(RMS)으로만 나눕니다. RMSNorm(x)=γ⊙x/1d∑xi2\mathrm{RMSNorm}(x)=\gamma\odot x/\sqrt{\tfrac1d\sum x_i^2}. 논문은 LayerNorm과 비슷한 성능에 실행 시간을 모델에 따라 7%~64% 줄였다고 보고합니다. 위 토큰 1이면 RMS =(1+0+4+1)/4=1.225=\sqrt{(1+0+4+1)/4}=1.225 이므로 (0.816, 0, 1.633, 0.816)(0.816,\ 0,\ 1.633,\ 0.816) 이 됩니다.

ReLU → GELU → SwiGLU. GPT-1 · BERT는 ReLU 대신 GELU를 썼습니다. Shazeer(2020)는 FFN에 게이트를 단 GLU 변형을 비교했는데, SwiGLU는 (Swish(xW)⊙xV)W2(\mathrm{Swish}(xW)\odot xV)W_2 처럼 행렬이 셋입니다. 파라미터 수를 같게 맞추려고 숨은 차원을 2/32/3 로 줄였고, 이 조건에서 SwiGLU 등이 더 낮은 퍼플렉서티를 보였습니다. LLaMA는 SwiGLU를 쓰면서 숨은 차원을 4d4d 대신 23⋅4d\tfrac23\cdot4d 로 두었습니다.

왜 이렇게 바뀌었나(요약). 모두 "더 깊고 큰 모델을 더 안정적이고 싸게 학습"하려는 선택입니다. Pre-LN은 안정성, RMSNorm은 속도, SwiGLU는 같은 비용에서의 품질 때문입니다.

연습 문제

  1. x=(2,2,2,2)x=(2,2,2,2) 를 레이어 정규화하면? (ϵ\epsilon 은 아주 작은 양수)
    • 풀이: 평균 2, 분산 0이라 (x−μ)=0(x-\mu)=0 → 결과는 (0,0,0,0)(0,0,0,0) 입니다(ϵ\epsilon 덕분에 0으로 나누지 않습니다).
  2. d=4096d=4096, 층 32개 모델의 층 파라미터는 대략?
    • 풀이: 12×40962×32≈6.44×10912\times4096^2\times32\approx6.44\times10^9, 약 64억 개입니다. 어휘 임베딩은 따로입니다.
  3. 4절에서 토큰 1의 출력이 헤드마다 자기 값 그대로인 이유는?
    • 풀이: 인과 마스크 때문에 첫 토큰은 자기 자신만 볼 수 있어 가중치가 (1,0)(1,0) 이기 때문입니다.
  4. 잔차 연결이 없고 블록이 모두 0을 출력하도록 초기화되면 어떤 일이 생기나요? 잔차가 있으면?
    • 풀이: 없으면 신호가 첫 블록에서 사라져 이후 층이 아무것도 받지 못합니다. 있으면 Y=X+0=XY=X+0=X 로 입력이 그대로 통과해, 블록은 '항등에서 조금씩 고치는 법'부터 배우면 됩니다.

스스로 점검

  1. 어텐션과 FFN의 역할 차이를 한 문장씩 말해 보세요.
    • 답: 어텐션은 토큰들 사이에 정보를 섞고, FFN은 섞인 정보를 토큰마다 따로 비선형 변환해 가공합니다.
  2. 블록 입력과 출력 크기가 같아야 하는 이유는?
    • 답: 같은 블록을 원하는 만큼 반복해 쌓고, 잔차 덧셈 X+f(X)X+f(X) 를 할 수 있게 하기 위해서입니다.
  3. Pre-LN이 Post-LN보다 학습이 쉬운 이유는?
    • 답: 정규화가 서브층 앞에 있어 잔차 길이 정규화를 거치지 않고 그대로 이어지므로, 초기 기울기가 안정적이고 워밍업 의존이 줄어듭니다.

용어 정리

용어쉬운 뜻
트랜스포머 블록어텐션 + FFN + 잔차 + 정규화로 이루어진 반복 단위
멀티헤드 어텐션차원을 나눠 여러 기준의 어텐션을 동시에 하고 이어 붙이는 것
잔차 연결(residual)입력을 출력에 더해 '고칠 부분'만 배우게 하는 연결
레이어 정규화토큰마다 평균 0 · 분산 1로 맞추는 정규화
RMSNorm평균 빼기 없이 제곱평균제곱근으로만 나누는 정규화
Post-LN · Pre-LN정규화를 잔차 덧셈 뒤에 두느냐, 서브층 앞에 두느냐
FFN토큰마다 따로 적용하는 확장 → 활성화 → 축소 신경망
SwiGLU게이트를 곱해 주는 FFN 변형
워밍업학습 초반에 학습률을 작게 시작해 천천히 올리는 것

더 깊이 보려면

다음에 볼 것

라이선스

본문은 KAITABASE 자체 해설입니다. 참고 자료 Dive into Deep Learning은 CC BY-SA 4.0으로 공개되어 있습니다. 행렬 값은 이 수업을 위해 만든 해설용 예이며 파이썬으로 검산했습니다. 논문 수치는 각 원문에서 확인한 것만 옮겼습니다.

출처

AI 원리부터 이해하기 · NLP·트랜스포머 모듈

NLP·트랜스포머 모듈 학습

이 글은 NLP·트랜스포머 모듈의 학습 자료입니다. 전체 23개 자료 중 11번째입니다.

AI 기초 과정은 현재 진도 저장을 지원하지 않습니다.

출처·원문

원문 보기

요약만

본문 자체 작성 · 참고 자료 D2L(CC BY-SA 4.0) · arXiv 원 논문