NLP

Transformer 내부 작동 원리: Self-Attention를 중심으로

uomnf97 2025. 3. 30. 22:32
안녕하세요, 제이덥입니다! 기술 면접을 준비하면서 기초 개념들을 하나씩 정리하고 있는데요. 오늘은 Transformer에 대해 다뤄보려 합니다. 이번 글에서는 Transformer의 탄생 배경이 된 Long-Term Dependency 문제를 간단히 소개하고 논문 Attention Is All You Need에서 제안된 Transformer의 작동 원리를 정리해보겠습니다. 특히 그중에서도 핵심 개념인 Self-Attention에 집중해 개념과 수식을 중심으로 깊이 있게 설명드릴 예정입니다.

0️⃣ 탄생 배경 : Long-Term Dependency

이전 포스팅에서 Vanilla RNN의 BPTT를 소개하면서 RNN의 Long-Term Dependency 문제에 대해서 다뤘습니다. 이 문제는 이후 Transformer가 등장하게 된 중요한 배경이 되었습니다.

 

RNN 모델에서는 t시점의 입력 벡터를 xt, hidden 벡터를 ht라고 할 때, ht는 이전 시점까지의 정보를 담고 있는 ht1과 현재 입력 xt를 이용해 계산됩니다. 즉, ht1부터 t시점까지의 정보를 순차적으로 축적해 나가는 구조입니다.

 

하지만 RNN의 모든 hidden 벡터는 동일한 파라미터를 공유하기 때문에, 시점이 멀리 떨어진 정보는 효과적으로 반영하기 어렵습니다. 이 현상은 주로 비선형 활성화 함수와 관련이 깊습니다. 1보다 작은 값이 반복적으로 곱해지면서 시점이 지남에 따라 그레디언트가 점점 작아지는 vanishing gradient 문제가 발생하기 때문에 먼 시점에 있는 정보는 소실됩니다.

 

이를 완화하기 위해 BPTT 기법이 고안되었고, 이후 Gate 구조를 도입한 LSTM과 GRU 같은 모델들이 등장했습니다. 이 모델의 구조적 특징은 hidden state 계산 방식에 변화를 주어 정보를 더 오래 보존하려 했지만 근본적인 해결책은 되지 못했습니다.

 

이후에 Bi-directional LSTM이라는 새로운 접근 방식도 제안되었습니다. 기존 LSTM은 시간 순서대로 과거(1부터 t1까지)의 정보를 담은 ht1과 현재 입력 xt를 이용해 ht를 계산했습니다. 하지만 Bi-directional LSTM은 여기에 역방향 정보도 더합니다. 예를 들어 시퀀스의 마지막을 n이라 했을 때, n부터 t+1까지의 정보를 담은 ht+1xt를 연산해 또 하나의 hidden 벡터를 만들어냅니다. 이렇게 앞뒤 정보를 담은 두 개의 hidden 벡터를 concat하여 하나로 합쳐서 과거 시점 뿐만 아니라 미래 시점의 결과까지 고려해서 학습을할 수 있고 결과를 예측할 수 있습니다. 

 

그럼에도 불구하고 RNN 기반 모델들은 순차적으로 계산해야 한다는 구조적 한계를 지니고 있어, 긴 시퀀스 처리에 여전히 어려움을 가지고 있습니다. 이러한 배경에서, RNN의 한계를 극복하고자 등장한 것이 바로 Transformer입니다.

1️⃣ Attention is all you need

“Attention Is All You Need”는 NeurIPS에서 발표된 논문으로 기존에 널리 사용되던 LSTM, GRU 같은 RNN 계열 모델을 완전히 걷어내고 오직 Attention 메커니즘만으로 시퀀스 데이터를 처리할 수 있음을 보여주었습니다. 이로 인해 RNN의 고질적인 한계였던 순차적 연산 구조를 탈피할 수 있었습니다. Attention 매커니즘은 이후 등장한 LLM과 같은 대형 언어 모델의 구조적 기반이 되었고, 가장 널리 사용되는 딥러닝 모델 중 하나로 자리잡았습니다.

2️⃣ Self Attention의 계산 및 작동원리

RNN의 아이디어는 모든 단어들의 의미를 반영할 수 있도록 하는 '맥락(context)'를 압축한 벡터를 만들어내는 것입니다. 그리고 이러한 연산을 위해 Transformer 모델은 Attention Mechanism을 사용하며 이 과정에서 Key, Query, Value 세가지 벡터를 이용합니다. 각 벡터가 의미하는 건 다음과 같습니다. 

 

  • Query : 필요한 정보가 무엇인지 나타내는 벡터로 Sequence to Sequence with Attention 모델의 디코더의 hidden state와 같은 역할입니다. 
  • Key : 여러 후보들이 가지는 특성을 나타낸 벡터로 쿼리와 내적을 통해 유사도를 계산합니다. 
  • Value : 실제 가중평균을 구할 때 사용하는 벡터로 실제 정보를 가지고 있는 벡터입니다. 

사진과 같이 우측의 가중치 벡터를 이용해 Key, Query, Value값을 구합니다. (사진 출처: https://jalammar.github.io/illustrated-transformer/)

만약, 자기 자신을 모두 Query, Key, Value로 쓴다면 내적을 통한 유사도를 구했을 때 자기 자신과의 유사도가 지나치게 높아지는 문제가 발생할 수 있습니다. 즉, 내적을 통해 유사도를 계산할 때 자기 자신에 대한 값이 과도하게 강조되어 다른 단어들과의 상대적인 관계 파악이 어려워질 수 있습니다. 따라서, 아래와 같이 WK,WQ,WV의 가중치를 곱해 Query, Key, Value 벡터를 생성합니다. 이 때 중요한점은 Query와 Key는 내적을 해야하기 때문에 벡터의 차원은 동일해야하며, Value는 크기는 이와 관련이 없기 때문에 차원의 크기가 달라져도 상관없습니다. 

 

Thinking Machines의 Attention 계산과정 (사진 출처: https://jalammar.github.io/illustrated-transformer/)

연산 과정을 조금 더 상세하게 살펴봅시다. “Thinking Machines”라는 구가 있다고 가정하고 진행해보겠습니다. “Thinking”의 임베딩 벡터를 x1, “Machines”의 임베딩 벡터를 x2라고 합시다. 여기에 각각 WQ, WK, WV를 곱해 Query, Key, Value 벡터를 생성합니다. 만약 “Thinking”에 대해 Self-Attention을 수행해 Context 벡터를 구하고자 한다면, 먼저 “Thinking”의 Query 벡터인 q1과 문장 내 모든 Key 벡터들과 내적 연산을 수행합니다. 그 후, 이 결과에 소프트맥스 연산을 적용해 각 단어에 대한 가중치 비율을 구합니다. 마지막으로 이 비율을 각 Value 벡터에 곱해 가중 평균을 계산함으로써, 최종적으로 “Thinking”의 Context 벡터가 만들어집니다. 최종적으로는 벡터 내적 결과를 차원의 크기의 제곱근으로 나눠주는 스케일링 과정을 거칩니다. 그 이유는 차원이 커질수록 내적 값의 분산이 커져 Softmax 출력이 한쪽으로 쏠릴 가능성이 있기 때문입니다.이를 방지하기 위해 dk 으로 나눠줌으로써, 값의 분포를 안정시키고 학습 및 출력을 원활하게 할 수 있습니다. 

 

그리고 이 값들은 벡터 연산이기 때문에, 각 단어의 Query, Key, Value 벡터를 행단위로 쌓아 행렬 형태로 구성할 수 있습니다. 이러한 이점을 이용해 연산을 병렬적으로 처리해 효율을 높일 수 있었습니다. 수식을 정리하면 아래와 같습니다. 

 

3️⃣ 정리

RNN의 기울기 손실, 정보 손실로 발생하는 Long-Term Dependency의 문제를 다양한 방법으로 해결방안을 제시했지만, 순차적으로 계산해야하는 RNN계열 모델들의 한계로 인해 효과적인 해결법은 되지 못했습니다. 다만, 이 RNN구조들을 모두 걷어낸 Attention 메커니즘을 

 

 

출처 :