Table of Contents

728x90

Transformer 모델에서 선형 변환(linear transformation)을 사용하는 이유는 입력 임베딩을 Query, Key, Value로 변환하여 Self-Attention 메커니즘을 적용하기 위해서입니다. 그럼 왜 이 선형 변환이 필요한지, 그리고 변환이 어떻게 이루어지는지 단계적으로 설명하겠습니다.

1. 왜 선형 변환을 사용하는가?

Transformer에서 입력 임베딩 벡터를 그대로 Query, Key, Value로 사용할 수 없기 때문에, 선형 변환을 통해 서로 다른 표현 공간으로 변환합니다. 각 역할에 따라 다르게 학습된 변환을 적용함으로써, Self-Attention 메커니즘이 더 효과적으로 작동할 수 있습니다.

이유 1: 역할의 분리

  • Query: 각 단어가 "내가 어떤 정보를 찾고 있는가?"를 나타냅니다. 즉, 현재 단어가 문장 내에서 다른 단어와 어떻게 상호작용할지를 결정하는 역할을 합니다. 예를 들어, "저는"이라는 단어는 문장 안에서 자신의 목적(주어 역할)을 찾고자 할 수 있습니다.
  • Key: 각 단어가 "내가 제공할 수 있는 정보는 무엇인가?"를 나타냅니다. 이는 다른 단어가 이 단어로부터 얻을 수 있는 정보를 의미합니다. "chatGPT입니다"라는 단어는 "저는"이라는 단어에게 중요한 정보를 제공할 수 있습니다. "저는"은 "chatGPT입니다"를 통해 자신이 누구인지 설명할 수 있기 때문에 중요한 관계가 형성됩니다.
  • Value: 각 단어는 "실제로 제공하는 정보"를 나타냅니다. Self-Attention에서 계산된 가중치에 따라 실제로 전달될 정보입니다. Query와 Key의 상호작용(유사도)에 따라 Value가 반영되고, 최종적으로 다른 단어와의 관계가 결정됩니다.

"안녕하세요 저는 ChatGPT입니다"에 Query, Key, Value를 적용해보기

  1. 문장을 토큰화하면 다음과 같은 서브워드 토큰들이 생성됩니다:
    • ['안녕하세요', '저', '##는', 'chat', 'gp', 't', '##입', '##니다']
  2. 각 단어가 서로의 관계를 계산하기 위해, 이들 토큰은 Query, Key, Value 벡터로 변환됩니다.
    • Query: 각 토큰이 다른 단어들과 어떤 관계를 맺고 싶은지를 표현합니다.
    • Key: 각 토큰이 다른 단어들에게 제공하는 정보를 나타냅니다.
    • Value: 실제로 각 단어가 다른 단어들에게 전달하는 정보입니다.

예시로 "저는"이라는 단어가 "ChatGPT입니다"와 상호작용하는 방식:

  • Query: "저는"은 문장 안에서 자신이 설명되고 있다는 정보를 찾고 싶어합니다. 즉, "저는"은 자신이 어떤 주어(Subject)인지 알아내려고 합니다.
  • Key: "ChatGPT입니다"는 문장에서 "저는"에게 중요한 정보를 제공합니다. "저는"이 찾고 있는 "나"에 대한 설명을 제공하는 것이 바로 "ChatGPT입니다"라는 정보입니다.
  • Value: "ChatGPT입니다"는 최종적으로 이 관계를 통해 "저는"에게 자신이 누구인지에 대한 정보를 전달합니다.

서로 다른 역할을 가지는 이 세 벡터를 단순히 동일한 임베딩에서 사용하면 각 벡터의 역할이 혼합될 수 있습니다. 선형 변환을 통해 서로 다른 표현 공간으로 변환하여 각 벡터의 역할을 분명하게 분리할 수 있습니다. 따라서, 토큰화된 값을 가지고 Query, Key, Value로 직접 분리하는 것이 아니라, 모델이 자동으로 각 단어의 역할에 맞는 벡터를 학습하도록 선형 변환을 적용하는 것입니다.
 

이유 2: 정보의 재구성

입력 임베딩 벡터는 모델이 고정된 방식으로만 처리하는 것이 아니라, 선형 변환을 통해 다양한 관점에서 입력 데이터를 바라보도록 학습합니다. 선형 변환을 적용하면, 모델은 학습하는 과정에서 Query, Key, Value를 최적의 방식으로 조정할 수 있게 됩니다.

2. 선형 변환이 어떻게 이루어지는가?

선형 변환은 기본적으로 행렬 곱셈편향(bias)의 합으로 이루어집니다. 선형 변환은 수학적으로 다음과 같이 표현됩니다:
[
\text{Query} = W_q \cdot \text{Embedding} + b_q
]
[
\text{Key} = W_k \cdot \text{Embedding} + b_k
]
[
\text{Value} = W_v \cdot \text{Embedding} + b_v
]
여기서:

  • ( W_q, W_k, W_v )는 학습 가능한 가중치 행렬입니다.
  • ( b_q, b_k, b_v )는 학습 가능한 편향(bias)입니다.
  • (\text{Embedding})은 입력된 단어의 임베딩 벡터입니다.

이 가중치 행렬과 입력 임베딩 벡터의 곱셈을 통해 각 벡터가 새로운 표현으로 변환됩니다.

3. 선형 변환의 결과로 값이 어떻게 바뀌는가?

선형 변환을 통해 값이 어떻게 바뀌는지 살펴보겠습니다. nn.Linear를 사용한 선형 변환은 임베딩 벡터를 다른 공간으로 변환하는 역할을 합니다. 예를 들어, 입력이 ( (12, 768) ) 크기의 벡터라고 가정하면, 선형 변환 후에도 여전히 ( (12, 768) ) 차원을 유지하지만, 벡터의 값이 변합니다.

선형 변환의 예시를 코드로 설명하면:

import torch
import torch.nn as nn

# 입력 임베딩 벡터 (batch_size=1, seq_length=3, embedding_dim=4)
embedding = torch.tensor([[1.0, 2.0, 3.0, 4.0],
                          [4.0, 3.0, 2.0, 1.0],
                          [0.5, 0.5, 0.5, 0.5]])

# 선형 변환 정의 (임베딩 차원 4에서 출력 차원 4로 변환)
linear = nn.Linear(4, 4)

# 선형 변환 수행
output = linear(embedding)

print("선형 변환 전 입력:\n", embedding)
print("선형 변환 후 출력:\n", output)

이 코드에서, 임베딩 벡터는 선형 변환을 통해 새로운 값으로 변환됩니다. 실제로는 모델이 학습하는 동안, 이 변환은 모델이 Query, Key, Value가 더 나은 정보를 제공할 수 있도록 학습됩니다.

선형 변환 후의 결과:

  • 변환 전: 임베딩 벡터는 원래 값인 [1.0, 2.0, 3.0, 4.0], [4.0, 3.0, 2.0, 1.0], [0.5, 0.5, 0.5, 0.5]입니다.
  • 변환 후: linear 레이어의 가중치와 곱해져 새로운 값으로 변환됩니다. 이 값은 학습된 가중치에 따라 변하게 됩니다.

4. 왜 값이 바뀌는가?

선형 변환을 통해 값이 바뀌는 이유는, 모델이 Query, Key, Value 벡터 각각을 다른 표현 공간에서 다르게 처리하고 싶기 때문입니다. Self-Attention 메커니즘은 Query와 Key 벡터의 내적을 통해 유사도를 계산하고, 그 유사도를 Value에 적용해 새로운 정보를 생성합니다.
변환된 Query, Key, Value는 서로 다른 방향으로 변형되며, 이를 통해 Self-Attention 메커니즘이 다양한 단어 간의 상호작용을 학습하게 됩니다.

5. 결론

  • 선형 변환은 입력 임베딩을 Query, Key, Value로 변환하여 각 벡터의 역할을 명확히 하고, 모델이 더 다양한 정보를 학습할 수 있도록 돕습니다.
  • 변환된 값은 입력 임베딩의 고유한 정보가 모델이 학습하는 가중치에 따라 다른 방향으로 변환된 결과입니다.
  • 최종적으로 이 변환된 벡터들은 Self-Attention 메커니즘을 통해 입력 시퀀스의 문맥적 관계를 학습하는 데 사용됩니다.