7 분 소요

Transformer 모델과 Attention의 중요성

최근의 llm 모델은 대부분 Transformer 모델을 사용하고 있습니다. 특히 Transformer 모델에서 사용되는 Attention 메커니즘은 기존의 seq2seq 방식들의 한계를 극복한 가장 핵심이라고 볼 수 있습니다. Transformer 모델은 2017년 Google에서 발표한 “Attention is All You Need” 논문을 통해 최초로 소개되었습니다. 이 모델은 RNN(순환 신경망)이나 LSTM(장단기 메모리)의 한계를 극복하고 더 빠르고 효율적으로 시퀀스 데이터를 처리할 수 있는 방법을 제시했다는 평가를 받고 있습니다.

Attention 메커니즘의 기본 개념

Attention 메커니즘은 입력 시퀀스의 각 요소가 출력 시퀀스의 각 요소와 얼마나 관련이 있는지를 계산하는 방법입니다. 이를 통해 모델은 문장의 인접한 부분뿐만 아니라 전체 문장에서의 상관관계를 이해하게 되었고, 보다 중요한 부분에 더 집중할 수 있게 되었습니다. Attention은 주로 “Query”, “Key”, 그리고 “Value”라는 세 가지 요소를 사용하여 작동합니다.

  • Query: 찾고자 하는 정보의 표현
  • Key: 데이터베이스의 키(key)처럼 특정 정보를 인덱싱하는 역할
  • Value: 실제로 찾고자 하는 정보

Attention 메커니즘의 목표는 Query와 Key 간의 유사도를 계산하여 Value를 가중합하는 것입니다. 이 과정을 통해 모델은 입력 데이터의 중요한 부분을 파악합니다.

Attention의 구체적 동작 원리

  1. Query, Key, Value 계산: 입력 시퀀스 $X$가 주어졌을 때, 각 입력 단어에 대해 Query, Key, Value를 계산합니다. 이는 일반적으로 학습 가능한 가중치 행렬 $W_Q$, $W_K$, $W_V$를 사용하여 수행됩니다.

    \[Q = XW_Q, \quad K = XW_K, \quad V = XW_V\]
  2. 유사도 계산: Query와 Key 간의 유사도를 계산합니다. 이는 내적(dot-product)을 사용하여 계산되며, 소프트맥스(softmax) 함수로 정규화 합니다.

    \(\text{Attention Score} = \frac{QK^T}{\sqrt{d_k}}\) 여기서 $d_k$는 Key 벡터의 차원 수입니다. 이 값을 사용하여 Query와 각 Key 간의 유사도를 측정합니다.

  3. 가중합 계산: Attention Score를 사용하여 Value의 가중합을 계산합니다. 이를 통해 각 Query에 대한 최종 출력을 얻습니다.

    \[\text{Attention Output} = \text{softmax}(\text{Attention Score})V\]

Multi-Head Attention

Transformer 모델에서는 단일 Attention 메커니즘 대신 여러 개의 Attention 헤드를 사용하는 Multi-Head Attention을 도입합니다. 이는 모델이 마치 Random Forest에서 한 것과 같이 Q, K, V의 initial vector를 다양하게 함으로서 좀더 generalization되는 효과를 가지게 하고 이는 곧 성능 향상으로 이어지게 됩니다.

  1. 헤드 분할: 입력 시퀀스를 여러 개의 헤드로 분할합니다.
  2. 독립적인 Attention 수행: 각 헤드에서 독립적으로 Attention을 수행합니다.
  3. 출력 결합: 각 헤드의 출력을 결합하여 최종 출력을 생성합니다.

Attention 동작 예시

간단한 예시로, “I am a student”라는 영어 문장을 생각해 보겠습니다. 이 문장은 4개의 단어로 구성되어 있습니다. 각각의 단어는 고유한 벡터 표현을 가지고 있다고 가정합니다.

우선, 각 단어를 3차원 벡터로 표현해 보겠습니다(Word embedding):

  • “I”: $[1, 0, 1]$
  • “am”: $[0, 1, 0]$
  • “a”: $[1, 1, 0]$
  • “student”: $[0, 0, 1]$

Query, Key, Value 계산

Query, Key, Value는 각각 학습 가능한 가중치 행렬 $W_Q$, $W_K$, $W_V$를 통해 계산됩니다. 예를 들어, $W_Q$, $W_K$, $W_V$가 3x3 행렬이라고 가정합시다:

  • $W_Q$: \(\begin{bmatrix} 0.1 & 0.2 & 0.3 \\ 0.4 & 0.5 & 0.6 \\ 0.7 & 0.8 & 0.9 \end{bmatrix}\)

  • $W_K$: \(\begin{bmatrix} 0.1 & 0.0 & 0.1 \\ 0.0 & 0.1 & 0.0 \\ 0.1 & 0.0 & 0.1 \end{bmatrix}\)

  • $W_V$: \(\begin{bmatrix} 0.2 & 0.2 & 0.2 \\ 0.1 & 0.1 & 0.1 \\ 0.3 & 0.3 & 0.3 \end{bmatrix}\)

이제 각 단어 벡터를 이용해 Query, Key, Value를 계산해 보겠습니다.

Query 계산

\[Q = XW_Q\]
  • “I”: $[1, 0, 1]$ * $W_Q$ = $[0.8, 1.0, 1.2]$
  • “am”: $[0, 1, 0]$ * $W_Q$ = $[0.4, 0.5, 0.6]$
  • “a”: $[1, 1, 0]$ * $W_Q$ = $[0.5, 0.7, 0.9]$
  • “student”: $[0, 0, 1]$ * $W_Q$ = $[0.7, 0.8, 0.9]$

Key 계산

\[K = XW_K\]
  • “I”: $[1, 0, 1]$ * $W_K$ = $[0.2, 0.0, 0.2]$
  • “am”: $[0, 1, 0]$ * $W_K$ = $[0.0, 0.1, 0.0]$
  • “a”: $[1, 1, 0]$ * $W_K$ = $[0.1, 0.1, 0.1]$
  • “student”: $[0, 0, 1]$ * $W_K$ = $[0.1, 0.0, 0.1]$

Value 계산

\[V = XW_V\]
  • “I”: $[1, 0, 1]$ * $W_V$ = $[0.5, 0.5, 0.5]$
  • “am”: $[0, 1, 0]$ * $W_V$ = $[0.1, 0.1, 0.1]$
  • “a”: $[1, 1, 0]$ * $W_V$ = $[0.3, 0.3, 0.3]$
  • “student”: $[0, 0, 1]$ * $W_V$ = $[0.3, 0.3, 0.3]$

Attention Score 계산

Query와 Key 간의 유사도를 계산합니다. 예를 들어, “I”의 Query와 모든 단어의 Key 간 유사도를 계산합니다:

\[\text{Attention Score}_{I, 모든 단어} = \frac{Q_{I} \cdot K^T}{\sqrt{d_k}}\]

여기서 $d_k = 3$ 입니다.

  • “I”에 대한 Query와 Key 간의 유사도:
    • “I”와 “I”: $\frac{(0.8, 1.0, 1.2) \cdot (0.2, 0.0, 0.2)}{\sqrt{3}} = \frac{0.4}{\sqrt{3}} \approx 0.23$
    • “I”와 “am”: $\frac{(0.8, 1.0, 1.2) \cdot (0.0, 0.1, 0.0)}{\sqrt{3}} = \frac{0.1}{\sqrt{3}} \approx 0.06$
    • “I”와 “a”: $\frac{(0.8, 1.0, 1.2) \cdot (0.1, 0.1, 0.1)}{\sqrt{3}} = \frac{0.3}{\sqrt{3}} \approx 0.17$
    • “I”와 “student”: $\frac{(0.8, 1.0, 1.2) \cdot (0.1, 0.0, 0.1)}{\sqrt{3}} = \frac{0.2}{\sqrt{3}} \approx 0.12$

Softmax를 통한 정규화

위에서 계산한 유사도 값을 소프트맥스 함수를 통해 정규화합니다.

\[\text{Softmax}([0.23, 0.06, 0.17, 0.12]) = [0.2717,0.2292,0.2558,0.2433]\]

가중합 계산

이제 정규화된 Attention Score를 사용하여 Value를 가중합합니다. “I”에 대한 최종 출력은 다음과 같이 계산됩니다.

\[\text{Output}_I = 0.2717 \times [0.5, 0.5, 0.5] + 0.2292 \times [0.1, 0.1, 0.1] + 0.2558 \times [0.3, 0.3, 0.3] + 0.2433 \times [0.3, 0.3, 0.3]\]

각 요소별로 계산해보면:

  • 첫 번째 요소: \(0.2717 \times 0.5 + 0.2292 \times 0.1 + 0.2558 \times 0.3 + 0.2433 \times 0.3 = 0.13585 + 0.02292 + 0.07674 + 0.07299 \approx 0.3085\)

  • 두 번째 요소: \(0.2717 \times 0.5 + 0.2292 \times 0.1 + 0.2558 \times 0.3 + 0.2433 \times 0.3 = 0.13585 + 0.02292 + 0.07674 + 0.07299 \approx 0.3085\)

  • 세 번째 요소: \(0.2717 \times 0.5 + 0.2292 \times 0.1 + 0.2558 \times 0.3 + 0.2433 \times 0.3 = 0.13585 + 0.02292 + 0.07674 + 0.07299 \approx 0.3085\)

따라서, “I”에 대한 Attention의 최종 출력 벡터는:

\[\text{Output}_I = [0.3085, 0.3085, 0.3085]\]

이와 같은 방식으로 각 단어에 대해 Query, Key, Value를 계산하고, Attention 메커니즘을 통해 중요한 정보를 추출할 수 있습니다.

기존 seq2seq 방식들과 무엇이 다르길래?

전통적인 Seq2Seq 모델은 인코더와 디코더라는 두 가지 주요 구성 요소로 이루어져 있습니다. 인코더는 입력 시퀀스를 고정 길이의 벡터로 변환하고, 디코더는 이 벡터를 바탕으로 출력 시퀀스를 생성합니다. 그러나 이 접근 방식에는 몇 가지 한계가 있습니다.

  1. 고정 길이 벡터: 입력 시퀀스가 길어지면 정보를 고정 길이 벡터로 압축하는 과정에서 중요한 정보가 손실될 수 있습니다. 특히 긴 문장이나 복잡한 문맥에서는 이 문제가 더욱 심각해집니다.

  2. 정보 손실: 인코더의 마지막 상태만을 이용해 디코더를 작동시키기 때문에, 중간에 중요한 정보가 손실될 가능성이 큽니다. 이는 특히 긴 문장에서 문맥을 정확히 이해하고 반영하는 데 어려움을 겪게 만듭니다.

Attention의 개선점

  1. 가변 길이 컨텍스트: Attention 메커니즘을 통해 디코더는 인코더의 모든 출력 상태를 참조할 수 있습니다. 이는 고정 길이 벡터의 한계를 극복하고, 입력 시퀀스의 길이에 관계없이 중요한 정보를 유지할 수 있게 합니다.

  2. 문맥 이해: 디코더가 생성하는 각 단어는 인코더의 전체 입력 시퀀스를 참고하여 계산되므로, 모델은 더 나은 문맥 이해를 바탕으로 단어를 생성할 수 있습니다. 예를 들어, “I am a student”라는 문장을 생성할 때, “student”라는 단어를 생성할 때 “I”와 “am”의 정보를 더 잘 참고할 수 있습니다. 또한 Q, K, V 벡터들만 중앙에서 잘 관리할 수 있다면, 분산 및 병렬 처리에도 굉장히 유리한 구조입니다.

  3. 중요한 정보 강조: Attention 메커니즘은 입력 시퀀스 내에서 중요한 단어에 더 높은 가중치를 부여합니다. 이는 모델이 중요한 정보를 강조하여 더 정확한 출력을 생성할 수 있게 합니다.

예시: 문장 재생성

기존 Seq2Seq 모델은 문장 “I am a student”를 처리할 때, 인코더의 마지막 상태만을 사용하여 디코더가 “I”, “am”, “a”, “student”를 순차적으로 생성합니다. 이 과정에서 중간에 중요한 정보가 손실될 수 있습니다. 반면, Attention 메커니즘이 도입된 모델은 “student”를 생성할 때 “I”, “am”, “a”의 정보를 모두 참조합니다. 이를 통해 모델은 단어 간의 중요한 관계를 더 잘 이해하고, 문맥에 맞는 단어를 생성할 수 있습니다.

간단한 소스 코드 구현 예시

  • 간단한 예시입니다. embeddings 혹은 generation 과정에서 더욱 정교하게 알고리즘을 구성해야 합니다. Attention 알고리즘을 이해하기 위한 목적입니다. 양해 부탁드립니다.
import numpy as np
from sklearn.preprocessing import normalize

# 임의의 단어 벡터 생성 함수
def get_word_embeddings(words):
    np.random.seed(0)  # 재현성을 위해 시드 설정
    embeddings = {word: np.random.rand(3) for word in words}
    return embeddings

# 소프트맥스 함수 정의
def softmax(x):
    e_x = np.exp(x - np.max(x))
    return e_x / e_x.sum(axis=0)

# Attention score 계산 함수
def calculate_attention_scores(words, embeddings):
    queries = np.array([embeddings[word] for word in words])
    keys = np.array([embeddings[word] for word in words])
    values = np.array([embeddings[word] for word in words])

    attention_scores = []
    for query in queries:
        # Query와 Key 간의 유사도 계산
        scores = np.dot(keys, query) / np.sqrt(keys.shape[1])
        # 소프트맥스 함수로 정규화
        attention_weights = softmax(scores)
        attention_scores.append(attention_weights)

    return np.array(attention_scores)

# 새로운 문장 생성 함수
def generate_next_words(start_word, words, attention_scores, embeddings, num_words=3):
    generated_sentence = [start_word]
    current_word = start_word

    for _ in range(num_words):
        current_idx = words.index(current_word)
        attention_weights = attention_scores[current_idx]
        next_word_idx = np.argmax(attention_weights)
        next_word = words[next_word_idx]
        generated_sentence.append(next_word)
        current_word = next_word

    return ' '.join(generated_sentence)

# 예제 문장
sentence = "I am a student"
words = sentence.split()
embeddings = get_word_embeddings(words)
attention_scores = calculate_attention_scores(words, embeddings)
for word, scores in zip(words, attention_scores):
    print(f"Word: {word}, Attention Scores: {scores}")

print("\n final attention scores\n")
print(attention_scores)

# 주어진 단어 "I"로부터 시작하여 다음 단어들을 생성
start_word = "I"
new_sentence = generate_next_words(start_word, words, attention_scores, embeddings)
print("\nGenerated Sentence:")
print(new_sentence)
Word: I, Attention Scores: [0.24809073 0.22300183 0.2920896  0.23681784]
Word: am, Attention Scores: [0.24755248 0.23396262 0.28554679 0.23293811]
Word: a, Attention Scores: [0.24156177 0.21273088 0.31442187 0.23128547]
Word: student, Attention Scores: [0.24733493 0.21915569 0.29208369 0.24142569]

 final attention scores

[[0.24809073 0.22300183 0.2920896  0.23681784]
 [0.24755248 0.23396262 0.28554679 0.23293811]
 [0.24156177 0.21273088 0.31442187 0.23128547]
 [0.24733493 0.21915569 0.29208369 0.24142569]]

Generated Sentence:
I a a a

참고 자료