NLP(6) - Attention (Deep Learning from Scratch 2)

2026. 4. 1. 22:08Open Seminar/NLP & LLM

NLP 개론 — 어텐션(Attention) 메커니즘 정리

이번 세미나에서는 NLP 개론 교재의 8장, 어텐션(Attention)을 주제로 발표를 진행했습니다. 기존 Seq2seq 모델의 근본적인 한계를 짚어보고, 이를 해결하기 위해 인코더와 디코더를 각각 어떻게 개선하는지, 그리고 최종적으로 어텐션 메커니즘이 어떻게 동작하는지를 단계별로 정리해보겠습니다.


1. 기존 Seq2seq의 개선안 복습

어텐션을 본격적으로 다루기 전에, 이전 장에서 소개했던 Seq2seq의 간단한 개선안 두 가지를 먼저 복습했습니다.

Reverse

입력 데이터의 순서를 반전시키는 기법입니다. 예를 들어 "57+5"라는 입력을 "5+75"로 뒤집어서 모델에 넣습니다. 이렇게 하면 입력의 앞부분과 출력의 앞부분 사이의 거리가 가까워져서 가중치 업데이트가 더 원활해집니다.

입력 시퀀스를 반전시켜 입력과 출력의 앞부분 간 거리를 줄이는 Reverse 기법

Peaky

인코더의 마지막 은닉 상태 $h$를 디코더의 모든 LSTM 계층과 Affine 계층에 입력으로 제공하는 방법입니다. 이를 통해 디코더는 매 타임스텝마다 전체 입력 문장의 정보를 참고할 수 있게 됩니다.

인코더의 출력 h를 디코더의 모든 시각의 LSTM 계층과 Affine 계층에 전달하는 Peaky 구조

이 두 가지는 비교적 작은 개선안이었고, 이번 발표의 핵심은 Seq2seq를 한층 더 강력하게 만드는 어텐션(Attention) 메커니즘입니다.


2. Seq2seq의 근본적인 문제점

기본적인 Seq2seq 모델에서 인코더는 입력 시퀀스 전체를 하나의 고정 길이 벡터(fixed-length vector)로 압축하여 디코더에 전달합니다. 문제는 문장이 길어지면 모든 정보를 하나의 벡터에 담기 어려워진다는 점입니다.

짧은 문장이든 긴 문장이든 동일한 크기의 고정 길이 벡터 h로 변환되어 정보 병목이 발생한다

핵심 문제: 인코더가 데이터를 고정 길이의 벡터로 전달하기 때문에, 입력이 길어질수록 필요한 정보가 다 담기지 못하는 병목 현상(bottleneck)이 발생합니다.

이 문제를 해결하기 위해, 먼저 인코더를 개선하고 그 다음 디코더를 개선하는 순서로 접근했습니다.


3. 인코더(Encoder) 개선

개선 전: 마지막 은닉 상태만 전달

기존 인코더는 LSTM 계층의 마지막 은닉 상태만을 고정 길이 벡터 형태로 디코더에 전달합니다. 이 하나의 벡터가 입력 문장 전체의 정보를 요약해야 하는 부담을 가지게 됩니다.

개선 전 인코더: LSTM의 마지막 은닉 상태만을 디코더에 전달한다

개선 목표와 방법

목표: 인코더 출력의 길이를 입력 문장의 길이에 따라 가변적으로 바꿔주는 것
방법: LSTM 계층의 마지막 은닉 상태만 사용하는 대신, 각 시점(time step)의 모든 은닉 상태 벡터를 사용

입력 시퀀스의 각 단어가 LSTM 셀을 통과할 때마다 생성되는 은닉 상태 벡터를 버리지 않고 모두 모아서 하나의 행렬 $hs$를 만듭니다. 따라서 $hs$는 입력 단어의 개수만큼의 행을 가지는 행렬이 됩니다.

개선된 인코더: 각 LSTM 셀에서 출력되는 은닉 상태 벡터를 모아 행렬 hs를 구성한다

은닉 상태의 의미

LSTM의 각 시점의 은닉 상태는 직전에 입력된 단어에 대한 정보를 가장 많이 포함하고 있습니다. 예를 들어, '고양이'라는 단어를 입력했을 때의 LSTM 은닉 상태는 '고양이'의 성분이 많이 들어간 벡터가 됩니다.

'고양이'가 입력되는 시점의 은닉 상태는 '고양이'의 정보를 가장 많이 담고 있다

따라서 인코더가 출력하는 은닉 상태들의 행렬 $hs$는 각 단어에 해당하는 벡터들의 집합이라고 볼 수 있습니다.

인코더 출력 hs 행렬: 각 행이 입력 문장의 각 단어에 대응하는 벡터

인코더 개선 정리
  • 개선 전: 마지막 은닉 상태(고정 길이 벡터)만 전달
  • 개선 목표: 출력 길이를 입력 길이에 따라 가변적으로 변경
  • 개선 방법: 모든 시점의 은닉 상태 벡터 사용
  • 결과: 입력 단어 수와 같은 수의 벡터를 얻어 고정 길이 벡터의 취약점 극복

4. 디코더(Decoder) 개선

인코더를 개선했으니, 이제 디코더에서 이 풍부한 정보를 어떻게 활용할지가 관건입니다. 디코더 개선은 세 단계로 나누어 설명했습니다.

4.1 디코더 개선의 목표

인코더가 이제 각 단어에 대응하는 은닉 상태 벡터들의 모음인 $hs$를 출력하지만, 개선되지 않은 디코더는 이 $hs$에서 마지막 행만을 사용하고 나머지 중요한 정보들을 버리게 됩니다.

개선 전 디코더: 인코더가 풍부한 정보(hs)를 출력하지만 마지막 행만 사용하여 비효율적이다

디코더 개선의 목표는 인코더가 출력하는 $hs$를 전부 활용하는 것입니다. 핵심 아이디어는 사람이 번역할 때 특정 단어에 주목하여 번역하는 것과 같이, 모델이 입력과 출력 단어 간의 대응 관계(Alignment)를 학습하게 하는 것입니다.

즉, 도착어 단어와 대응 관계에 있는 출발어 단어의 정보를 골라내고, 이 정보를 이용하여 번역을 수행하는 것 — 다시 말해 필요한 정보에만 주목(Attention)하여 시계열 변환을 수행하는 구조를 만들고자 합니다. 이것이 바로 어텐션 메커니즘입니다.

디코더에 '어떤 계산' 블록을 추가하여 인코더 출력 hs로부터 필요한 정보를 선택하는 어텐션 개념

4.2 Decoder 개선 1 — 가중합(Weight Sum) 계층

신경망 관점에서 어텐션의 목표는 디코더가 각 시점에서 인코더 출력 $hs$로부터 대응 관계인 단어의 벡터를 '선택'하는 것입니다. 하지만 여기서 중요한 문제가 있습니다.

문제: 특정 하나를 고르는 '선택' 연산은 미분이 불가능합니다. 신경망은 오차역전파(backpropagation)를 통해 학습해야 하므로, 모델 내의 모든 연산은 미분 가능해야 합니다.

이 문제를 해결하기 위한 아이디어는 "하나만 선택하는 것이 아니라, 모든 것을 선택"하는 것입니다. 각 단어의 중요도를 나타내는 가중치(weight)를 이용하여 모든 벡터의 가중합(weighted sum)을 계산하면, 미분 가능한 연산으로 '선택'을 근사할 수 있습니다.

가중치 a를 이용하여 hs의 각 행 벡터를 가중합하여 맥락 벡터(context vector) c를 구한다

가중치 $a$는 각 단어가 현재 디코딩 단계에서 얼마나 중요한지를 나타내는 값으로, 0.0~1.0 사이의 스칼라이며 총합이 1인 확률 분포와 같은 형태입니다. 이 가중합의 결과를 맥락 벡터(context vector) $c$라고 부릅니다.

계산 그래프

가중합 계층의 순전파 과정은 다음과 같습니다:

  1. 가중치 벡터 $a$를 Repeat 노드를 통해 복제
  2. 복제된 $a$와 $hs$를 원소별 곱셈
  3. Sum 노드를 통해 합산하여 맥락 벡터 $c$ 계산

Repeat, 곱셈, Sum 노드로 구성된 가중합 연산의 계산 그래프 (N: 배치 크기, T: 시퀀스 길이, H: 은닉 상태 차원)

구현 코드는 다음과 같습니다:

WeightSum 클래스의 forward/backward 메서드 구현. 벡터 a의 reshape과 repeat 연산이 핵심이다

4.3 Decoder 개선 2 — 가중치 계산(Attention Weight) 계층

가중합을 계산하려면 가중치 $a$가 필요합니다. 이 가중치를 어떻게 자동으로 구할 것인가가 다음 과제입니다.

이 계층의 입력과 출력은 다음과 같습니다:

  • 입력: 인코더의 모든 은닉 상태 $hs$, 디코더의 현재 은닉 상태 $h$
  • 출력: 가중치 $a$

디코더의 현재 상태 $h$가 인코더의 각 시점 상태들과 얼마나 '비슷한지'를 수치로 표현해야 합니다. 여기서는 벡터의 내적(dot product)을 유사도 측정 방법으로 사용합니다.

디코더의 현재 은닉 상태 h와 hs의 각 행 벡터 간 내적을 계산하여 유사도 점수 s를 구한다

전체 계산 과정은 다음과 같습니다:

  1. 디코더 은닉 상태 $h$를 Repeat하여 $hs$와 같은 크기로 만듦
  2. $hs$와 원소별 곱셈 수행
  3. Sum을 통해 내적 점수 $s$ 계산
  4. Softmax 함수를 통과시켜 0~1 사이의 값으로 정규화된 최종 가중치 $a$를 얻음

Repeat → 곱셈 → Sum → Softmax를 거쳐 h와 hs로부터 정규화된 가중치 a를 계산하는 전체 과정

Softmax를 통과하므로 가중치 $a$의 총합은 1이 되며, 이는 확률 분포로 해석할 수 있습니다.

4.4 Decoder 개선 3 — 두 계층의 결합: Attention 계층

앞서 설명한 두 가지 계층을 결합합니다:

  1. Attention Weight 계층: $hs$와 $h$로부터 가중치 $a$를 계산
  2. Weight Sum 계층: $hs$와 $a$로부터 맥락 벡터 $c$를 계산

왼쪽: 상세한 계산 그래프 / 오른쪽: Attention Weight와 Weight Sum 두 블록으로 단순화한 다이어그램

이 두 블록을 하나의 Attention 계층으로 캡슐화합니다. Attention 계층은 인코더의 모든 은닉 상태 $hs$와 디코더의 현재 은닉 상태 $h$를 입력으로 받아, 최종적인 맥락 벡터를 출력합니다.

Attention Weight + Weight Sum = 하나의 Attention 계층으로 캡슐화


5. 어텐션을 갖춘 Seq2seq 전체 구조

이제 Attention 계층을 전체 디코더 아키텍처에 통합합니다. 디코더의 각 타임스텝에서 LSTM 계층의 출력 $h$는 Attention 계층으로 들어가고, Attention 계층은 $h$와 인코더의 전체 출력 $hs$를 이용해 맥락 벡터를 계산합니다. 이 맥락 벡터가 다음 Affine 계층으로 전달되어 최종 출력을 예측하는 데 사용됩니다.

어텐션이 적용된 전체 Seq2seq 모델: 디코더의 각 LSTM 셀 다음에 Attention 블록이 추가되었다

왼쪽: 기존 디코더(LSTM → Affine) / 오른쪽: 어텐션 디코더(LSTM → Attention → Affine)


6. 구현

어텐션을 포함한 Seq2seq 모델의 구현은 기존에 만들었던 3개의 클래스(Encoder, Decoder, Seq2seq)를 어텐션 버전으로 교체하는 방식으로 진행됩니다.

AttentionEncoder

기존 Encoder와의 차이점은 forward 메서드가 LSTM의 마지막 은닉 상태만 반환하는 대신, 모든 시점의 은닉 상태 $hs$를 전부 반환한다는 점입니다.

AttentionEncoder: forward 메서드에서 LSTM의 전체 출력 hs를 반환하는 것이 핵심

AttentionDecoder

기존 DecoderTimeAttention 계층을 추가합니다. 핵심은 어텐션 계층의 출력(맥락 벡터 $c$)과 LSTM 계층의 출력(dec_hs)을 np.concatenate()연결(concatenate)한 후, 이 연결된 벡터를 Affine 계층에 전달하는 것입니다.

AttentionDecoder: np.concatenate()로 LSTM 출력과 어텐션 맥락 벡터를 연결하는 부분이 핵심

AttentionSeq2seq

전체 모델 클래스는 기존 Seq2seq 클래스를 상속받고, __init__ 메서드에서 인코더와 디코더를 각각 AttentionEncoderAttentionDecoder로 교체해주기만 하면 됩니다.

AttentionSeq2seq: 기존 Seq2seq를 상속받아 인코더/디코더만 어텐션 버전으로 교체


7. 어텐션의 응용

마지막으로 어텐션의 다른 응용 분야를 간략히 소개했습니다.

셀프 어텐션(Self-Attention)은 하나의 시퀀스 내에서 각 위치가 같은 시퀀스의 다른 위치들에 주목하는 메커니즘입니다. 그리고 이 셀프 어텐션을 핵심 구성 요소로 사용하는 트랜스포머(Transformer) 아키텍처는 현재 NLP 분야의 주류 모델이 되었습니다.

일반 어텐션과 셀프 어텐션의 비교, 그리고 트랜스포머 모델의 전체 구조


마무리

이번 발표에서 다룬 내용을 정리하면 다음과 같습니다:

  1. Seq2seq의 근본적 문제: 고정 길이 벡터로 인한 정보 병목 현상
  2. 인코더 개선: 모든 시점의 은닉 상태를 출력하여 가변 길이 표현 확보
  3. 디코더 개선 — 어텐션 메커니즘:
    • Weight Sum 계층: 가중치를 이용한 가중합으로 맥락 벡터 생성
    • Attention Weight 계층: 내적 + Softmax로 가중치 자동 계산
    • 두 계층을 결합하여 하나의 Attention 계층으로 캡슐화
  4. 구현: 기존 Seq2seq 클래스를 상속/교체하여 간결하게 구현 가능
  5. 응용: 셀프 어텐션, 트랜스포머로의 확장

어텐션은 "필요한 정보에만 주목한다"는 직관적인 아이디어를 미분 가능한 연산으로 구현한 것이 핵심입니다. 하나를 선택하는 대신 모든 것을 가중합하는 방식으로 이 문제를 우아하게 해결했고, 이것이 이후 트랜스포머와 현대 NLP의 기반이 되었습니다.

 

읽어주셔서 감사합니다.

 

* 이 글은 제가 만든 발표 자료 기반으로 AI를 사용하여 작성한 글 입니다. 발표자료는 아래 원본을 참고해주세요.

NLP_6.pdf
4.34MB