AI 입문 시리즈
6편에서는 트랜스포머 블록 내부의 핵심 구성 요소인 FFN과 잔차 연결을 수식과 미분 관점에서 상세히 살펴보았다.
본 7편에서는 트랜스포머의 큰 틀을 구성하는 인코더(Encoder)와 디코더(Decoder)의 내부 동작 원리와 이들이 협력하는 방식, 그리고 어텐션이 가지는 순서 무관 문제를 해결하는 포지셔널 인코딩(Positional Encoding)을 정리한다.
0. 이번 편의 핵심
- 인코더 : 입력 시퀀스를 받아 토큰별 문맥 표현을 구축한다. 각 레이어는 LayerNorm, Multi-Head Attention(MHA), 잔차 연결, FFN으로 구성된다.
- 디코더 : 자동 생성(autoregressive) 방식으로 출력 토큰을 하나씩 생성하며, 마스크된 MHA와 인코더-디코더 MHA를 통해 과거 출력과 인코더 문맥을 결합한다.
- 포지셔널 인코딩 : 어텐션의 순서 무관성을 보완하기 위해 임베딩에 위치 정보를 더하는 방법이다. 사인/코사인 방식, 학습 가능한 방식, 회전 위치 인코딩(RoPE) 등을 다룬다.
- 수식적 관점에서 인코더→디코더로 이어지는 역전파 경로를 체인룰로 전개해 기울기 흐름을 분석한다.
- 실전에서는 pre-norm/post-norm 선택, PE 타입, 마스크 구현, 시퀀스 길이 처리 등 세부 구현 이슈가 중요하다.
1. 인코더(Encoder) — 입력을 문맥 표현으로 변환하는 모듈
1.1 배경과 필요성
시퀀스-투-시퀀스 문제(예: 번역, 요약)는 입력 시퀀스의 각 토큰이 주변 토큰들과 상호작용한 정보를 기반으로 출력 결과를 생성해야 한다.
전통적인 RNN 계열은 순차 처리로 인해 병렬화가 어렵고, 장기 의존성 문제에서 효율이 떨어진다.
트랜스포머 인코더는 병렬화 가능한 어텐션 연산을 통해 모든 토큰 쌍의 상호작용을 계산하고, FFN으로 위치별 비선형 변환을 수행해 표현력을 확보한다.
1.2 구조와 수식
인코더는 동일한 구조의 레이어를 L번 반복해 쌓는다.
l번째 레이어에서 입력 $X_l$ (형상: $N \times d_{\text{model}}$)에 대한 계산은 다음과 같다.
- 정규화:
$X_l’ = \text{LayerNorm}(X_l)$
- 셀프 어텐션과 잔차 연결:
$\text{AttnOut}_l = X_l + \text{MHA}(X_l’, X_l’, X_l’)$
- 두 번째 정규화:
$N_l = \text{LayerNorm}(\text{AttnOut}_l)$
- 위치별 FFN와 잔차 연결:
$X_{l+1} = \text{AttnOut}_l + \text{FFN}(N_l)$
세부 요소 설명:
- LayerNorm: 각 토큰 벡터의 원소들에 대해 평균과 분산을 계산해 정규화한다.
수식으로는
여기서 $\mu_L$와 $\sigma_L^2$는 해당 토큰 벡터 차원 방향의 평균과 분산이다.
정규화는 학습 안정성과 기울기 흐름 개선에 기여한다.
-
Multi-Head Attention (MHA): 입력 $X_l’$에서 쿼리, 키, 값 행렬을 생성하고, 각각을 여러 헤드로 분할한 뒤 병렬로 attention을 계산한다.
한 헤드의 연산은 다음과 같다.$Q = X_l’ W_Q, \quad K = X_l’ W_K, \quad V = X_l’ W_V$
$\text{Attention}(Q,K,V) = \text{softmax}\left( \frac{Q K^T}{\sqrt{d_k}} \right) V$
여러 헤드의 출력을 연결(concat)한 뒤 출력 투영을 수행한다.
MHA는 모든 토큰 쌍 간의 상호작용을 동시 계산하므로 병렬 처리에 유리하지만 계산량은 입력 길이 $N$에 대해 $O(N^2)$이다. -
FFN: 각 토큰 독립적으로 동일한 두 개의 밀집층과 활성화(GELU 권장)를 적용한다.
$\text{FFN}(x) = W_2 f(W_1 x + b_1) + b_2$
여기서 중간 차원 $d_{\text{ff}}$는 일반적으로 $4 \times d_{\text{model}}$로 설정된다.
1.3 역전파와 기울기 흐름
손실 $L$에 대한 기울기 전파를 간단히 적으면, 최종 출력에서 입력으로 오는 기울기는 잔차로 인한 항을 포함한다.
$X_{l+1}$에 대한 기울기 $\frac{\partial L}{\partial X_{l+1}}$가 주어질 때, FFN 블록을 통과해 $N_l$로 전달되는 기울기는
$\frac{\partial L}{\partial N_l} = \frac{\partial L}{\partial X_{l+1}} \cdot \left(1 + \frac{\partial \text{FFN}}{\partial N_l}\right)$
이 되고, LayerNorm과 MHA를 거쳐 입력 $X_l$에 도달할 때에도 각각의 야코비안이 곱해진다.
특히 잔차 항의 1은 직접 경로를 제공해 연쇄적으로 곱해지는 작은 계수들 때문에 발생하는 기울기 소실 문제를 완화한다.
1.4 장단점 및 구현 고려사항
장점:
- 병렬 연산을 통한 고속 처리. 모든 토큰 쌍 간의 관계를 동시에 고려하므로 긴 문맥에서 유용하다.
- FFN과 MHA의 분리로 지역적 처리와 전역적 처리가 명확히 분리되어 모델 설계가 명확하다.
단점 및 주의사항:
- 계산 복잡도 및 메모리 사용량이 $O(N^2)$이므로 매우 긴 시퀀스에서 비효율적이다.
긴 시퀀스 처리에는 희소화된 어텐션, 로컬 윈도우 어텐션 등 변형이 필요하다. - LayerNorm 위치(pre-norm과 post-norm)에 따라 학습 안정성 차이가 발생한다.
일반적으로 pre-norm을 사용하면 깊은 네트워크에서 수렴이 더 안정적이라는 보고가 있다.
1.5 변형과 실제 적용 사례
- BERT 계열: 순수 인코더 쌓기로 사전학습 목표를 수행한다.
입력 간 관계를 문맥적으로 풍부하게 표현한 뒤 분류나 마스킹 복원 등의 태스크에 사용한다. - Vision Transformer (ViT): 이미지 패치를 토큰으로 보고 동일한 인코더 블록을 적용한다.
패치 임베딩에 포지셔널 인코딩을 더해 공간 정보를 반영한다.
2. 디코더(Decoder) — 조건부 생성 모듈
2.1 역할과 필요성
디코더는 출력 시퀀스를 생성하는 모듈로, 현재 생성 중인 위치에서 이용 가능한 이전 출력 정보와 인코더가 제공한 문맥 정보를 동시에 활용해 다음 토큰을 예측한다.
자동 회귀 방식(autoregressive)을 택하므로 생성 시점에는 미래 토큰 정보를 볼 수 없어야 한다.
이를 위해 마스크(masked attention)를 적용한다.
2.2 구조와 수식
l번째 디코더 레이어에서 입력 $Y_l$ (형상: $M \times d_{\text{model}}$)과 인코더 출력 $Z$에 대한 연산은 다음과 같다.
- 정규화:
$Y_l’ = \text{LayerNorm}(Y_l)$
- 마스크된 셀프 어텐션과 잔차:
$\text{MaskAttnOut}_l = Y_l + \text{MaskedMHA}(Y_l’, Y_l’, Y_l’)$
마스크는 상삼각행렬 형태로 미래 위치에 $-\infty$를 더해 softmax 결과가 0이 되도록 만든다.
- 정규화:
$N_l = \text{LayerNorm}(\text{MaskAttnOut}_l)$
- 인코더-디코더 어텐션(문맥 참조)과 잔차:
$\text{EncDecOut}_l = N_l + \text{MHA}(N_l, Z, Z)$
- 정규화 및 FFN, 최종 잔차:
$F_l = \text{LayerNorm}(\text{EncDecOut}_l)$
$Y_{l+1} = \text{EncDecOut}_l + \text{FFN}(F_l)$
2.3 역전파에서의 주요 포인트
- 마스크된 어텐션의 softmax는 미래 위치에 대해 기울기가 0이 되므로 역전파 경로에서 해당 요소는 완전히 차단된다.
이로 인해 모델은 생성 시점에 미래 정보에 의존하지 않게 된다. - 인코더-디코더 MHA는 쿼리 쪽(디코더)에서 키/값(인코더 출력)을 참조하므로, 이 연산을 통해 인코더 쪽으로 기울기가 전파된다.
따라서 디코더의 학습은 인코더 파라미터의 업데이트에도 영향을 미친다.
2.4 장단점 및 구현 고려사항
장점:
- 인코더가 제공한 문맥을 직접 참조해 출력 품질을 높일 수 있다.
- 마스크 기법으로 자동 회귀 조건을 엄격히 적용할 수 있다.
단점 및 주의사항:
- 추론 시에는 토큰을 한 단계씩 생성해야 하므로 디코더 기반 모델은 실시간 응답이나 긴 출력 생성에서 속도 제약이 있다.
배치화된 빔 서치 등 최적화 기법으로 완화할 수 있다. - 마스크 구현 시 인덱스 정렬과 패딩 처리를 정확히 해야 하며, 패딩 토큰이 attention에 영향을 주지 않도록 별도 마스크를 적용해야 한다.
2.5 변형과 실제 사례
- GPT 계열: 디코더 구조만을 쌓아 언어 모델링 태스크에 사용한다. 대규모 자기회귀 학습으로 텍스트 생성 능력을 확보한다.
- 인코더-디코더 모델: 번역, 요약 등에서 인코더와 디코더의 결합이 널리 사용된다.
3. 인코더-디코더 전체 흐름과 수식 정리
모든 처리의 전체 흐름은 다음과 같다.
- 입력 임베딩과 포지셔널 인코딩 추가:
$X_{\text{input}} = \text{Embedding}(X) + \text{PE}(\text{pos})$
- 인코더로부터 문맥 벡터 생성:
$Z = \text{Encoder}(X_{\text{input}})$
- 디코더 입력(학습 시 teacher forcing으로 한 칸씩 쉬프트된 정답 사용):
$Y_{\text{input}} = \text{Embedding}(Y_{\text{shifted}}) + \text{PE}(\text{pos})$
- 디코더에서 출력 예측:
$Y_{\text{hat}} = \text{Decoder}(Y_{\text{input}}, Z)$
- 출력층 확률화:
$P(\text{token} | \text{context}) = \text{softmax}(W_o Y_{\text{hat}} + b_o)$ |
학습은 최종 확률과 정답 간의 교차 엔트로피 손실을 최소화하는 방향으로 진행된다.
4. 포지셔널 인코딩(Positional Encoding) — 위치 정보를 임베딩에 주입하는 방법
4.1 문제 정리
어텐션 연산은 입력 순서를 반영하지 않으므로, 동일한 토큰 집합이 입력 순서만 달라졌을 때 동일한 처리 결과를 내는 성질이 있다.
순서가 중요한 데이터에서는 위치 정보를 모델 입력에 명시적으로 추가해야 한다.
4.2 원본 사인/코사인 포지셔널 인코딩
원본 트랜스포머에서 사용한 포지셔널 인코딩은 주기적 함수의 기초 성질을 이용한다.
각 위치 $\text{pos}$와 임베딩 차원 $i$에 대해
$\text{PE}(\text{pos}, 2i) = \sin\left( \text{pos} / 10000^{2i / d_{\text{model}}} \right), \quad \text{PE}(\text{pos}, 2i+1) = \cos\left( \text{pos} / 10000^{2i / d_{\text{model}}} \right)$
설계 의도 및 성질:
- 차원 $i$마다 다른 주파수 스케일 $\omega_i = 1 / 10000^{2i / d_{\text{model}}}$을 사용한다. 낮은 차원은 고주파 성분을, 높은 차원은 저주파 성분을 제공한다.
- 두 위치 $p$와 $q$에 대해 그들의 포지셔널 벡터가 선형 결합을 통해 상대적 거리나 위상 차이를 어느 정도 복원할 수 있다.
- 고정형이므로 학습 가능한 파라미터는 아니며, 메모리 부담이 작고 시퀀스 길이 증가에 대해 비교적 안정적이다.
4.3 학습 가능한 위치 임베딩
대신 각 위치에 대해 학습 가능한 벡터를 부여하는 방식이 있다.
이 방식은 데이터셋 특성에 따라 위치 표현을 조정할 수 있다는 장점이 있으나, 최대 시퀀스 길이만큼 파라미터가 증가하고 사인/코사인 방식만큼 일반화 성능을 보장하지는 않는다.
4.4 RoPE(회전 위치 인코딩) 및 상대 위치 표현
RoPE는 쿼리와 키에 회전 행렬을 곱해 내적 계산 시 상대 위치 정보를 반영하도록 설계한 방식이다.
이 방식은 절대 위치가 아닌 상대적 거리를 더 직접적으로 반영하며, 긴 시퀀스에서도 더 유연한 동작을 보이는 장점이 있다.
4.5 구현상 고려사항
- 고정형 사인/코사인 PE는 입력 길이가 설계된 최대 길이보다 클 경우 확장 성능을 확인해야 한다. 학습형 PE는 최대 길이에 대한 파라미터를 사전에 확보해야 한다.
- 패딩 토큰 처리 시에는 포지셔널 인코딩이 의미하지 않으므로, 패딩 마스크와 결합해 어텐션에서 패딩 위치가 영향력을 갖지 않도록 해야 한다.
5. 작은 수치 예제
간단한 차원에서 LayerNorm, Attention, FFN, PE의 계산 흐름을 단계별로 전개한다.
예를 들어 $N=3$, $d_{\text{model}}=4$ 환경에서 임베딩 행렬을 주고 각 연산의 중간 행렬을 손으로 계산해본다.
FFN의 중간 행렬 $Z_1 = W_1 X + b_1$와 GELU의 출력, 이후 $W_2$ 적용을 구체 수치로 전개해 역전파의 기울기 흐름을 확인한다.
6. 그래프와 시각화 활용법
- 어텐션 맵을 시각화해 토큰 간 주목 관계가 어떻게 형성되는지 확인한다. 주목 행렬(softmax 점수 행렬)을 히트맵으로 출력하면 특정 토큰이 어디에 집중하는지 파악할 수 있다.
- 사인/코사인 포지셔널 인코딩은 위치에 따른 차원별 값 변화를 플롯해 각 차원 주파수 성분을 확인하면 해석에 도움이 된다.
- LayerNorm, gradient norm, parameter norm 등을 학습 중 모니터링해 학습 불안정이나 발산을 조기에 감지한다.
7. 적분(연속) 관점에서의 해석
깊은 층을 연속 깊이로 근사하는 관점에서, 잔차 연결은 오일러 적분법의 한 스텝과 유사하다.
즉 $y_{t+1} = y_t + F(y_t)$ 형태는 미분 방정식 $\frac{dy}{dt} = F(y)$의 이산적 근사로 볼 수 있다.
포지셔널 인코딩의 주기 함수들은 연속 위치에 대한 기저 함수(basis)로 작용하며, 이를 통해 연속적 위치 정보를 다층 네트워크에서 누적적으로 반영할 수 있다.
8. 구현 예제(의사코드)
# 간단화된 의사코드(파이썬 스타일)
for l in range(L):
X = LayerNorm(X)
attn = MultiHeadAttention(X, X, X)
X = X + attn
X = LayerNorm(X)
ff = FFN(X)
X = X + ff
# 인코더 끝 -> Z
for l in range(L):
Y = LayerNorm(Y)
masked_attn = MaskedMultiHeadAttention(Y, Y, Y, mask=future_mask)
Y = Y + masked_attn
Y = LayerNorm(Y)
encdec_attn = MultiHeadAttention(Y, Z, Z)
Y = Y + encdec_attn
Y = LayerNorm(Y)
ff = FFN(Y)
Y = Y + ff
# 디코더 끝 -> 출력 확률 계산
9. 자주 발생하는 오류와 점검 포인트
- 마스크 행렬을 잘못 만들면 미래 정보가 유입되거나 패딩 토큰이 주목을 받는 오류가 발생한다. 상삼각 마스크와 패딩 마스크를 결합해 사용해야 한다.
- LayerNorm 위치 설정(pre/post)에 따라 학습 안정성과 수렴 속도 차이가 크므로 실험을 통해 적절한 방식을 선택한다.
- 포지셔널 인코딩을 더했음에도 뜻밖의 성능 저하가 발생하면 학습률, 초기화, 배치 정규화와의 상호작용 등을 점검한다.
10. 실무 권장 설정
- 기본 하이퍼파라미터: $d_{\text{model}}=512$, $d_{\text{ff}}=2048$, $L=6 \sim 12$이 권장되는 시작점이다.
- 포지셔널 인코딩: 짧은 시퀀스와 표준 문제에는 사인/코사인 방식이 안전하다. 도메인 특화나 더 긴 시퀀스에는 학습형 PE 또는 RoPE를 검토한다.
- 학습 안정화: warm-up 스케줄, gradient clipping, 적절한 초기화(예: He 초기화 또는 Xavier 초기화)를 조합한다.
이번 편 요약
- 인코더는 입력을 MHA와 FFN으로 반복 처리해 토큰별 문맥 표현을 만든다.
- 디코더는 마스크된-self-attention과 인코더-디코더 어텐션을 통해 출력 토큰을 조건부로 생성한다.
- 포지셔널 인코딩은 순서 정보를 임베딩에 주입하는 핵심 기법이며, 사인/코사인, 학습형, RoPE 등의 변형이 존재한다.
- 잔차 연결과 정규화는 기울기 흐름을 안정시키는 역할을 수행한다.
결론
이번 장에서는 트랜스포머의 인코더·디코더 구조와 포지셔널 인코딩을 수식 중심으로 정리했다.
다음 편에서는 Seq2Seq, 모델 조합(BERT/GPT/T5 등) 및 RNN/CNN/LSTM과의 비교을 다룬다.