Attention Is All You Need 과제

송정근·5일 전

1. 기존 RNN/LSTM과 Transformer의 차이

RNN과 LSTM은 시퀀스를 앞에서 뒤로 순서대로 처리한다. 즉, t번째 단어를 계산하려면 t-1번째의 은닉 상태가 먼저 준비되어야 한다.

ht=f(ht−1,xt)h_t = f(h_{t-1}, x_t)

이 방식은 단어 순서를 자연스럽게 반영한다는 장점이 있다. 반면 문장 전체를 동시에 계산할 수 없어서 학습 병렬화가 어렵다. 또한 문장 앞부분의 정보가 뒷부분까지 전달되려면 많은 시점을 거쳐야 하므로, 긴 문장에서 중요한 정보가 약해지거나 학습이 어려워질 수 있다. LSTM은 게이트를 사용해 이 문제를 줄였지만, 이전 시점의 계산을 기다려야 한다는 순차성은 그대로 남아 있다.

Transformer는 이전 은닉 상태를 전달하는 구조를 사용하지 않는다. 대신 각 토큰이 문장 안의 다른 모든 토큰을 직접 참고하는 Self-Attention을 사용한다. 그래서 학습할 때는 각 위치의 연산을 병렬로 처리할 수 있고, 멀리 떨어진 두 단어도 한 번의 Attention으로 연결할 수 있다.

예를 들어 문장 맨 앞의 주어와 맨 뒤의 동사가 관련되어 있을 때, RNN은 중간 단계를 여러 번 거쳐 정보를 전달한다. Transformer는 두 단어의 관계를 직접 계산한다. 내가 이해한 Transformer의 가장 큰 변화는, 시퀀스 정보를 전달하는 방법이 “이전 상태를 넘기는 방식”에서 “필요한 위치의 정보를 직접 가져오는 방식”으로 바뀌었다는 점이다.

다만 Self-Attention은 모든 토큰 쌍의 관계를 계산하므로, 기본 구조에서는 시퀀스 길이가 n일 때 비용이 O(n2)O(n^2)으로 커진다. 따라서 매우 긴 문서나 음성 데이터에서는 계산량과 메모리 사용량이 문제가 될 수 있다.

2. Self-Attention의 Q, K, V 역할

Self-Attention은 현재 토큰이 문장 안의 다른 토큰 중 어떤 정보를 얼마나 참고할지 정하는 계산이다. 이를 검색 과정에 비유하면 다음과 같이 볼 수 있다.

  • Query(Q): 현재 토큰이 찾고 싶은 정보
  • Key(K): 각 토큰이 가진 검색용 특징 또는 주소
  • Value(V): 실제로 가져올 정보

입력 벡터 XX에서 서로 다른 선형 변환을 적용해 Q, K, V를 만든다.

Q=XWQ,K=XWK,V=XWVQ=XW^Q, \qquad K=XW^K, \qquad V=XW^V

현재 위치의 Query와 모든 위치의 Key를 비교하면 관련도 점수가 나온다. 이 점수에 softmax를 적용하면 각 토큰을 얼마나 참고할지에 대한 비율이 되고, 그 비율로 Value를 가중합해 새로운 표현을 만든다.

예를 들어 “철수가 가방을 들었다. 그는 웃었다.”에서 “그는”을 처리할 때, 모델은 “철수”와의 관련도가 높다고 학습할 수 있다. 그러면 “철수”의 Value가 더 큰 비중으로 반영되어 “그는”의 문맥 표현에 주어 정보가 포함된다.

여기서 중요한 점은 Q, K, V가 단어마다 미리 정해진 별도 정보가 아니라는 것이다. 같은 입력 토큰이라도 학습된 가중치 WQW^Q, WKW^K, WVW^V를 통해 서로 다른 관점의 벡터로 바뀐다.

3. Scaled Dot-Product Attention에서 dk\sqrt{d_k}로 나누는 이유

Scaled Dot-Product Attention은 다음과 같이 계산한다.

Attention⁡(Q,K,V)=softmax⁡(QK⊤dk)V\operatorname{Attention}(Q,K,V) = \operatorname{softmax} \left( \frac{QK^\top}{\sqrt{d_k}} \right)V

QK⊤QK^\top는 Query와 Key의 유사도 점수다. 문제는 Key의 차원 dkd_k가 커질수록 두 벡터의 내적값도 커지기 쉬워진다는 점이다. 논문처럼 Q와 K의 원소가 평균 0, 분산 1이라고 가정하면 내적의 분산은 dkd_k가 된다.

Var⁡(q⋅k)=dk\operatorname{Var}(q \cdot k)=d_k

점수가 지나치게 커진 상태에서 softmax를 적용하면 가장 큰 점수 하나의 확률은 거의 1이 되고, 나머지 확률은 거의 0이 된다. 이 상태에서는 작은 확률을 받은 위치의 gradient가 매우 작아져 학습이 잘 진행되지 않을 수 있다.

따라서 dk\sqrt{d_k}로 나누어 점수의 분산을 일정한 수준으로 맞춘다. 이는 단순한 상수 보정이 아니라, 벡터 차원이 커져도 softmax가 너무 빠르게 한 위치에만 확신하지 않도록 하여 학습 가능한 구간을 유지하는 장치라고 이해했다.

4. Multi-Head Attention을 사용하는 이유

문장 안에는 여러 종류의 관계가 있다. 가까운 단어끼리의 결합, 주어와 동사의 관계, 대명사가 가리키는 대상, 멀리 떨어진 단어의 의미적 연결 등이 동시에 존재한다. 하나의 Attention만 쓰면 이런 관계를 하나의 표현 공간과 하나의 가중 평균으로 처리해야 한다.

Multi-Head Attention은 Q, K, V를 여러 개의 서로 다른 선형 변환으로 투영한 뒤, 여러 Attention을 병렬로 계산한다.

head⁡i=Attention⁡(QWiQ,KWiK,VWiV)\operatorname{head}_i = \operatorname{Attention}(QW_i^Q, KW_i^K, VW_i^V)
MultiHead⁡(Q,K,V)=Concat⁡(head⁡1,…,head⁡h)WO\operatorname{MultiHead}(Q,K,V) = \operatorname{Concat}(\operatorname{head}_1, \ldots, \operatorname{head}_h)W^O

원논문의 기본 모델은 h=8개의 head를 사용하며, 전체 모델 차원 d_model=512를 각 head에서 d_k=d_v=64 차원으로 나누어 계산한다. 이렇게 하면 전체 계산량을 크게 늘리지 않으면서 여러 표현 공간에서 관계를 찾을 수 있다.

각 head가 반드시 고정된 역할을 갖는 것은 아니다. 하지만 서로 다른 투영 공간을 사용하므로, 하나의 head가 놓칠 수 있는 관계를 다른 head가 포착할 기회를 제공한다. 즉 Multi-Head Attention의 목적은 Attention을 단순히 여러 번 반복하는 것이 아니라, 여러 관점에서 토큰 관계를 함께 학습하는 데 있다.

5. Positional Encoding이 필요한 이유

Self-Attention은 토큰들을 동시에 처리한다. 위치 정보가 없다면 모델은 단어가 몇 번째에 놓였는지 알 수 없다. 예를 들어 다음 두 문장은 단어 종류가 같아도 의미가 다르다.

개가 사람을 물었다.
사람이 개를 물었다.

RNN은 단어를 순서대로 처리하기 때문에 순서가 계산 과정 안에 포함된다. Transformer는 병렬 처리 구조이므로 토큰 임베딩에 위치 정보를 직접 더해야 한다. 원논문에서는 sine과 cosine 함수를 사용한 Positional Encoding을 제안했다.

PE(pos,2i)=sin⁡(pos100002i/dmodel)PE_{(pos,2i)} = \sin\left( \frac{pos}{10000^{2i/d_{\text{model}}}} \right)
PE(pos,2i+1)=cos⁡(pos100002i/dmodel)PE_{(pos,2i+1)} = \cos\left( \frac{pos}{10000^{2i/d_{\text{model}}}} \right)

차원마다 서로 다른 주기의 파형을 사용하므로, 각 위치는 구별되는 벡터를 갖는다. 또한 두 위치의 거리 차이도 이 벡터들의 관계에 반영될 수 있다. 논문은 학습형 위치 임베딩도 실험했으며 성능은 비슷했지만, 사인·코사인 방식은 학습에서 보지 못한 더 긴 시퀀스에도 적용될 가능성이 있다고 보았다.

따라서 Transformer는 순서를 RNN처럼 계산 순서에 포함시키는 대신, 위치 정보를 별도의 벡터로 명시해 제공하는 모델이다.

6. Residual Connection, Layer Normalization, FFN의 역할

Transformer의 각 층은 Attention만으로 끝나지 않는다. Attention과 FFN 각각에 Residual Connection과 Layer Normalization이 결합된다.

  • Residual Connection은 입력 xx에 서브레이어 출력 f(x)f(x)를 더하는 구조다.

    x+f(x)x+f(x)

    기존 정보를 다음 층까지 직접 전달하고, 깊은 모델에서 gradient가 잘 흐르도록 도와 학습을 안정화한다.

  • Layer Normalization은 한 토큰 벡터 내부 특성값의 분포를 정규화한다. 층을 거치며 값의 크기가 지나치게 변하는 문제를 줄여 학습을 안정화한다. 원논문에서는 LayerNorm(x + Sublayer(x)) 형태로, Residual Connection 뒤에 적용했다.

  • FFN(Feed-Forward Network)은 각 토큰 위치에 독립적으로 적용되는 작은 신경망이다.

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

    Attention이 토큰 사이에서 정보를 주고받는 단계라면, FFN은 전달받은 정보를 각 토큰 내부에서 비선형적으로 가공하는 단계라고 볼 수 있다. 원논문의 기본 모델에서는 512 → 2048 → 512 차원 변환을 사용했다.

세 요소의 역할을 함께 보면, Attention은 필요한 문맥 정보를 모으고, FFN은 그 정보를 가공하며, Residual Connection과 Layer Normalization은 이 과정을 여러 층 쌓아도 안정적으로 학습할 수 있게 돕는다.

7. Encoder와 Decoder의 차이 및 Causal Mask가 필요한 이유

Transformer는 입력을 이해하는 Encoder와 출력을 생성하는 Decoder로 구성된다.

Encoder는 입력 문장 전체를 보고 각 토큰이 문맥을 반영한 표현이 되도록 만든다. Encoder의 Self-Attention에서는 입력 문장의 모든 토큰이 서로를 참고할 수 있다.

Decoder는 이전에 생성된 출력 토큰과 Encoder의 출력을 참고해 다음 토큰을 생성한다. Decoder에는 다음과 같은 세 단계가 있다.

  1. Masked Self-Attention: 현재 위치와 과거 출력 토큰만 참고한다.
  2. Encoder–Decoder Attention: Decoder의 Query가 Encoder 출력의 Key, Value를 참고해 입력 문장에서 필요한 부분을 찾는다.
  3. FFN: 각 위치의 표현을 가공한다.

Decoder에 Causal Mask가 필요한 이유는 미래 정답을 미리 보면 안 되기 때문이다. 예를 들어 “나는 기계 학습을 좋아한다”에서 “학습을”을 예측할 때, 뒤에 나올 “좋아한다”까지 미리 보면 학습 중에는 답을 보고 맞히는 셈이 된다. 실제 생성 시에는 미래 단어가 아직 없으므로, 학습과 추론의 조건이 달라진다.

Causal Mask는 현재 위치보다 뒤에 있는 Attention 점수를 −∞-\infty로 만든다. softmax를 통과하면 해당 위치의 가중치는 0이 된다. 따라서 Decoder는 현재까지 생성된 정보만으로 다음 단어를 예측하며, 실제 생성 과정과 같은 자기회귀 조건을 유지한다.

정리하면 Encoder는 “입력 전체를 문맥적으로 이해하는 역할”을 맡고, Decoder는 “입력과 지금까지 생성한 결과를 바탕으로 다음 토큰을 만드는 역할”을 맡는다. Transformer는 Attention으로 전역 관계를 계산하면서도, Positional Encoding과 Causal Mask를 통해 시퀀스의 순서와 생성 조건을 지킨다.

참고 자료

profile
기록하며 성장하는 개발자

0개의 댓글