[논문리뷰] Attention Is All You Need

현선·2025년 11월 18일

논문리뷰

목록 보기
9/12

0. ABSTRACT

기존의 시퀀스 변환 모델들은 RNN/CNN 기반이며 인코더–디코더 구조를 가짐. 이러한 구조는 계산이 느리고 병렬화가 어렵다는 한계가 있다. 따라서 본 논문에서는 이를 해결하기 위해 RNN·CNN 제거하고 오직 Attention만 사용하는 Transformer 구조를 제안한다.

이 구조는 아래와 같은 장점을 지닌다.

  • 병렬 학습 가능 → 훈련 속도 빠름
  • 더 적은 시간으로 더 높은 성능
  • 구조 단순하지만 표현력 강함

1. Introduction

  • 기존 시퀀스 처리의 대표 모델은 RNN, LSTM, GRU이다.
  • RNN은 계산이 순차적이어서 병렬화가 불가능함 → 긴 시퀀스 학습 시 비효율적.

어텐션 메커니즘은 입력과 출력 시퀀스 내의 거리와 상관없이 의존 관계를 학습할 수 있도록 해주는 핵심 기술로 자리잡았다.
그러나 대부분의 모델에서는 여전히 어텐션을 RNN과 함께 사용하고 있으며, 이를 완전히 대체한 경우는 극히 드물다.

따라서 이 연구에서는 순환 구조를 완전히 제거하고, 입력과 출력 간의 전역적 의존성을 어텐션 메커니즘만으로 학습하는 새로운 모델 구조인 트랜스포머를 제안한다.

2. Background

과거 CNN 기반 모델들은 병렬화는 가능했지만 멀리 떨어진 단어 관계를 배우기 어려웠다. 트랜스포머는 이를 Self-Attention으로 한 번에 처리해, RNN·CNN 없이 전역 의존성을 학습하는 최초의 모델이다.

3. Model Architecture

대부분의 최신 신경망 기반 시퀀스 변환 모델은 인코더–디코더 구조를 가진다.

  • 인코더는 입력 시퀀스를 연속적인 표현들의 시퀀스 z로 변환한다. (각 단어를 벡터로 바꾸고,이 벡터들을 이용해서 전체 문장의 의미를 담은 벡터 시퀀스로 바꿔줌)
  • 디코더는 인코더가 만든 z를 입력으로 받아, 출력 시퀀스
    을 하나씩 순차적으로 생성한다.

트랜스포머 또한 이러한 전체적인 인코더–디코더 구조를 따른다. 하지만 인코더와 디코더 모두에서 RNN이나 CNN 대신,
Self-Attention과 Point-wise 완전연결층을 사용한다.

3.1 Encoder and Decoder Stacks

(1). 인코더

트랜스포머의 인코더는 N = 6개의 동일한 층 으로 이루어진 구조이다.
즉, Self-Attention + Feed Forward 블록이 6개 쌓여 있는 형태다.

Encoder Layer 1
Encoder Layer 2
Encoder Layer 3
Encoder Layer 4
Encoder Layer 5
Encoder Layer 6

각 층은 두 개의 서브레이어 로 구성된다:

즉, 하나의 Encoder Layer 안에는 아래 두 개의 미니-구성요소가 들어있단 뜻.

┌───────────────────────┐
│   Encoder Layer i     │
│                       │
│   ┌─────────────────┐ │
│   │ Self-Attention  │ │   ← sublayer #1
│   └─────────────────┘ │
│           ↓           │
│   ┌─────────────────┐ │
│   │ Feed Forward    │ │   ← sublayer #2
│   └─────────────────┘ │
└───────────────────────┘
  1. Multi-Head Self-Attention 메커니즘
    → 문장 내 모든 단어들이 서로의 관계를 동시에 학습

  2. Position-wise Fully Connected Feed-Forward Network
    → 각 단어마다 독립적으로 비선형 변환을 적용 (각 단어 벡터를 독립적으로 MLP에 통과시켜 더 풍부한 의미 표현으로 바꿔주는 단계)

각 서브레이어에는 잔차 연결이 적용되고, 그 다음 Layer Normalization이 수행된다.

즉, 각 서브레이어의 출력은 다음과 같이 계산된다:

Output=LayerNorm(x+Sublayer(x))\text{Output} = \text{LayerNorm}(x + \text{Sublayer}(x))

여기서 Sublayer(x)\text{Sublayer}(x) 는 해당 서브레이어가 수행하는 함수
(예: Self-Attention 또는 Feed Forward)를 의미한다.

  • 어텐션이나 FFNN이 “새로운 정보”를 학습
  • 하지만 원래 입력 𝑥도 같이 더해줌 → 기존 정보 손실 방지

Residual Connection을 적용하려면 입력(xx)과 출력(Sublayer(x)\text{Sublayer}(x))의 차원이 동일해야 한다.

따라서 인코더의 모든 서브레이어와 임베딩 레이어는 같은 차원 dmodel=512d_{model} = 512 를 사용한다.

인코더 구조

토큰 임베딩층

토큰 아이디를 토큰 임베딩층을 통해 여러 숫자의 집합인 토큰 임베딩으로 변환

  • 큰 단위 토큰: 텍스트의 의미가 잘 유지되지만, 사전의 크기가 커짐, OOV 문제
  • 작은 단위 토큰: OOV 문제 해결, 텍스트의 의미가 잘 유지안됨

서브워드 토큰화: 자주 나오는 단어는 단어 단위 그대로 유지하고, 가끔 나오는 단어는 더 작은 단위로 나눠 텍스트의 의미를 최대한 유지

임베딩 층이 단어의 의미를 담기 위해서는 딥러닝 모델이 학습 데이터로 훈련되어야 한다

위치 인코딩

트랜스포머는 순차적인 처리 방식을 버리고 모든 입력을 동시에 처리하기 때문에 순서 정보가 사라짐 -> 이를 위치 인코딩이 담당

  • 절대적 위치 인코딩
  • 상대적 위치 인코딩

토큰 임베딩에 위치 인코딩을 더해 모델에 입력할 최종 입력 임베딩을 준비한다.

(2). 디코더

디코더 또한 N = 6개의 동일한 층으로 구성된다.
하지만 인코더의 두 개 서브레이어에 추가로 한 개의 서브레이어가 더 포함된다.

즉, 각 디코더 층은 다음 세 부분으로 구성된다

1. Masked Multi-Head Self-Attention
2. Encoder-Decoder Attention
3. Feed-Forward Layer

디코더 역시 각 서브레이어마다 Residual Connection → Layer Normalization 순서로 적용된다.

또한 디코더의 Self-Attention은 미래 단어를 보지 못하도록 수정되어 있다.즉, 현재 단어를 예측할 때는 오직 이전 단어들만 참고할 수 있다.

이 마스킹과, 출력 임베딩이 한 칸씩 오른쪽으로 이동되어 입력되는 구조를 통해, 디코더의 i번째 단어 예측은 i보다 앞선 단어들에만 의존하도록 보장된다.

3.2 Attention

어텐션 함수는 쿼리와 key–value 쌍들의 집합을 입력받아 하나의 출력으로 매핑하는 함수이다.

쿼리, 키, 값, 그리고 출력은 모두 벡터 형태이며, 출력은 value 벡터들의 가중합으로 계산된다.

이때 각 값에 부여되는 가중치는 쿼리와 해당 값에 대응하는 키(key) 간의 유사도에 따라 결정된다.

3.2.1 Scaled Dot-Product Attention

Scaled Dot-Product Attention:

  • 입력으로 Query(Q), Key(K), Value(V) 세 가지 벡터 집합을 받는다.
  • Q와 K의 유사도(내적)를 계산해서 얼마나 집중할지(가중치)를 정하고,그 가중치로 Value(V)들을 섞어서 최종 출력을 만든다.

Self-Attention Mechanism 계산 과정

1. 유사도 계산 (Dot Product)

Query와 Key의 내적을 계산하여 유사도를 구한다. 이 점수는 QQ의 각 단어가 KK의 각 단어와 얼마나 관련 있는지 나타낸다.

Score=QKT\text{Score} = QK^T

2. 스케일링

내적 값이 너무 커지면 Softmax 함수의 기울기가 작아져 학습이 불안정해지고 어려워지는 문제가 발생한다. 이를 방지하기 위해, Key의 차원 크기 dkd_k의 제곱근으로 나누어 점수를 안정화한다.

이 과정 때문에 이 메커니즘을 "Scaled Dot-Product Attention"이라고 부른다.

Scaled Score=QKTdk\text{Scaled Score} = \frac{QK^T}{\sqrt{d_k}}

3. Softmax 적용

스케일링된 유사도 점수를 확률 분포로 변환하여 어디에 집중할지를 결정한다. Softmax 결과로 나온 값이 최종적으로 Value에 곱해질 가중치가 된다.

Attention Weights=softmax(QKTdk)\text{Attention Weights} = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)

4. 가중합

Softmax를 통과한 가중치(확률 분포)를 각 Value에 곱하여 합친다. 가중치가 높은 Value의 정보는 더 많이 반영되어 최종 출력 행렬을 형성한다.

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

다른 어텐션 방식과 비교

종류방식특징
Additive Attention쿼리와 키를 작은 신경망(feed-forward network)에 넣어 유사도 계산정확하지만 계산 느림
Dot-Product Attention단순히 내적(dot product)으로 유사도 계산빠르고 효율적
Scaled Dot-Product AttentionDot-product에 √dₖ로 나눠 안정화한 버전트랜스포머에서 사용, 빠르고 안정적

3.2.2 Multi-Head Attention

Multi-Head Attention은 단일 Attention을 여러 개 병렬로 실행하여 모델이 다양한 관점에서 입력 정보를 처리할 수 있도록 하는 메커니즘

단일 어텐션에서 사용하는 dmodeld_{\text{model}} 차원의 Q,K,VQ, K, V를 서로 다른 hh개의 선형 변환을 통해 다양한 하위 공간으로 투영한다.

Q). 하위공간으로 투영한다의 의미
A). 같은 문장을 다른 각도(특징)에 맞게 여러 개의 작은 공간으로 나눠 보는 것

각 헤드는 이렇게 만들어진 Q,K,VQ, K, V를 이용해 Scaled Dot-Product Attention병렬로 수행

계산과정

1. Q,K,VQ, K, V를 각각 hh개의 헤드로 선형 변환

각 헤드 ii는 입력 Q,K,VQ, K, V에 고유한 가중치 행렬 WW를 곱하여 자신만의 하위 공간으로 투영

headi=Attention(QWQi,KWKi,VWVi)\text{head}_i = \text{Attention}(QW_Q^i, KW_K^i, VW_V^i)

  • WQiRdmodel×dkW_Q^i \in \mathbb{R}^{d_{\text{model}} \times d_k}
  • WKiRdmodel×dkW_K^i \in \mathbb{R}^{d_{\text{model}} \times d_k}
  • WViRdmodel×dvW_V^i \in \mathbb{R}^{d_{\text{model}} \times d_v}

2. 모든 헤드의 출력을 이어붙임 (Concat)

각 헤드에서 계산된 Attention 결과(headihead_i)를 하나의 행렬로 옆으로 이어 붙인다.

Concat(head1,head2,...,headh)\text{Concat}(\text{head}_1, \text{head}_2, ..., \text{head}_h)

3. 최종적으로 선형 변환을 적용하여 모델 차원으로 복원

이어 붙인 결과에 최종 가중치 행렬 WOW_O를 곱하여 모델의 원래 차원 dmodeld_{\text{model}}로 복원하고 최종 출력을 얻는다.

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

  • WORhdv×dmodelW_O \in \mathbb{R}^{h d_v \times d_{\text{model}}}

여러개의 head를 쓰는 이유

  • 다양한 관점 포착: 각 헤드는 서로 다른 표현에서 정보를 학습. (예: 어떤 헤드는 문법적 관계, 다른 헤드는 의미적 관계에 집중)
  • 정보 희석 방지: 단일 어텐션은 정보를 평균내는 효과로 세부 정보가 희석될 수 있다. 여러 헤드로 병렬 학습하면 다양한 문맥 정보를 동시에 캡처하여 더 풍부한 표현을 얻을 수 있다.

실험 설정 (논문 기준)

항목내용
헤드 수 (hh)88
각 헤드의 차원dk=dv=64d_k = d_v = 64
전체 차원 (dmodeld_{\text{model}})512512
계산 비용dk=dv=dmodel/h=64d_k = d_v = d_{\text{model}} / h = 64 로 설정하여, 전체 계산 비용은 단일 헤드를 사용하는 경우와 거의 동일하게 유지됨.
class MultiheadAttention(nn.Module):
  def __init__(self, token_embed_dim, d_model, n_head, is_causal=False):
    super().__init__()
    self.n_head = n_head
    self.is_causal = is_causal
    self.weight_q = nn.Linear(token_embed_dim, d_model)
    self.weight_k = nn.Linear(token_embed_dim, d_model)
    self.weight_v = nn.Linear(token_embed_dim, d_model)
    self.concat_linear = nn.Linear(d_model, d_model)

  def forward(self, querys, keys, values):
    B, T, C = querys.size()
    querys = self.weight_q(querys).view(B, T, self.n_head, C // self.n_head).transpose(1, 2)
    keys = self.weight_k(keys).view(B, T, self.n_head, C // self.n_head).transpose(1, 2)
    values = self.weight_v(values).view(B, T, self.n_head, C // self.n_head).transpose(1, 2)
    attention = compute_attention(querys, keys, values, self.is_causal)
    output = attention.transpose(1, 2).contiguous().view(B, T, C)
    output = self.concat_linear(output)
    return output

n_head = 4
mh_attention = MultiheadAttention(embedding_dim, embedding_dim, n_head)
after_attention_embeddings = mh_attention(input_embeddings, input_embeddings, input_embeddings)
after_attention_embeddings.shape

3.2.3 Applications of Attention in our Model

트랜스포머 모델은 Multi-Head Attention 메커니즘을 총 세 가지 방식으로 활용한다.

1. Encoder-Decoder Attention

  • 위치: 디코더 블록의 두 번째 서브 레이어.
  • 역할: 디코더가 인코더의 출력으로부터 필요한 정보를 선택적으로 가져와 현재 토큰을 예측하게 한다.
  • 입력 출처:
    • 쿼리(QQ): 이전 디코더 레이어의 출력 (현재 디코딩 중인 단어 정보).
    • 키(KK)와 값(VV): 인코더의 최종 출력 (입력 문장 전체의 정보).
  • 특징: 디코더의 모든 위치가 입력 시퀀스(인코더 출력)의 모든 위치를 참조할 수 있도록 합니다. 이는 기존의 시퀀스-투-시퀀스 모델에서 흔히 사용되던 인코더-디코더 어텐션 메커니즘과 유사하다.

2. Encoder Self-Attention

  • 위치: 인코더 블록의 첫 번째 서브 레이어.
  • 역할: 입력 문장 내의 모든 단어들이 서로 간의 관계를 파악하게 한다.
  • 입력 출처:
    • 쿼리(QQ), 키(KK), 값(VV): 모두 이전 인코더 레이어의 출력 (즉, 같은 곳에서 나옴).
  • 특징: 인코더 내의 각 위치는 이전 레이어의 모든 위치를 참조하여 문맥을 파악할 수 있다. 예를 들어, "The animal didn't cross the street because it was too tired." 라는 문장에서 'it'이 'animal'을 참조하도록 학습한다.

3. Decoder Self-Attention

  • 위치: 디코더 블록의 첫 번째 서브 레이어.
  • 역할: 디코딩 시 이전까지 생성된 단어들 간의 관계를 파악한다.
  • 입력 출처:
    • 쿼리(QQ), 키(KK), 값(VV): 모두 이전 디코더 레이어의 출력 (디코더가 현재까지 생성한 결과).
  • 특징 (Masking):
    • 디코더는 다음 토큰을 순차적으로 예측해야 하는 auto-regressive 특성을 유지해야 한다.
    • 이를 위해, 왼쪽 방향으로의 정보 흐름 (즉, 현재 예측하려는 위치의 미래 토큰)을 방지해야한다.
    • 이것은 Scaled Dot-Product Attention 계산 과정에서 현재 위치보다 나중에 오는 토큰들의 유사도 점수를 마스킹 처리(-\infty로 설정)함으로써 구현된다. Softmax를 통과하면 -\infty는 0이 되어 미래 토큰을 참조하지 못하게 된다.

3.3 Position-wise Feed-Forward Networks

인코더와 디코더의 각 레이어에는 어텐션 서브레이어 외에도 각 위치마다 독립적으로 동일하게 적용되는 feed-forward 네트워크가 포함되어 있다.

이 네트워크는 두 개의 선형 변환 사이에 ReLU 활성화 함수를 넣은 구조로 되어 있다.

수식은 다음과 같다:

선형 변환은 모든 위치에 대해 같은 가중치를 공유하지만, 레이어가 바뀌면 각 레이어마다 다른 파라미터를 사용한다.

이 구조는 또 다르게 말하면, 커널 크기 1짜리 1D convolution 두 개를 연속으로 적용하는 것과 같다.

입력과 출력의 차원은 d_model = 512, 그리고 가운데 숨겨진 레이어(hidden layer)의 차원은 d_ff = 2048이다

“각 위치별(각 토큰별)로 독립적”이란 말은?

문장 전체를 한 번에 변형하는 게 아니라,

x₁에 대해 FFN(x₁)
x₂에 대해 FFN(x₂)
x₃에 대해 FFN(x₃)

이렇게 모든 토큰에 같은 FFN을 적용한다는 뜻

0개의 댓글