어쩌다데싸
Transformer, 도대체 그게 뭔데 - Transformer 편 (1) 본문
목차
Transformer, 도대체 그게 뭔데 - Attention 편을 읽고 보는 것을 추천드립니다.
현대 딥러닝 모델의 핵심을 관통하는 Transformer를 이해하지 않고는 AI 기술을 논하기 어렵습니다. 지난 글에서는 Transformer의 등장 배경과 핵심 개념인 Attention 메커니즘을 살펴보았습니다. 앞선 글에서 우리가 Transformer를 배워야 하는 이유는 다양한 유형의 데이터를 처리할 수 있고, 여러 도메인에서 강력한 성능을 보이는 모델이라고 언급했습니다. 이제 해결해야 할 의문은 "그래서 어떻게 강력한 성능을 보이는건데?"겠죠.
정답은 Transformer가 등장한 논문 제목에 있습니다. 'Attention Is All You Need'
Attention은 Seq2Seq 모델의 성능을 개선했지만, 여전히 RNN의 순차적 특성에 의존한다는 한계가 있었습니다. 이로 인해 병렬 처리가 어렵고, 시간 복잡도가 시퀀스의 길이에 비례해 늘어난다는 문제를 완전히 해결하지 못했죠.
이런 한계를 극복하기 위해 제안된 모델이 바로 Transformer입니다. 'Attention Is All You Need'라는 논문 제목처럼, Transformer는 RNN 등의 순환(recurrence)을 배제하고 Attention 매커니즘만을 사용해서 입력과 출력 간의 전역 의존성(global dependencies)을 모델링하는 모델입니다. 그래서 기존의 Attention과 구분해 Self-Attention이라고 부릅니다. Self-Attention은 입력 시퀀스의 모든 단어가 서로를 바라보며 관련성을 계산해, 기존 모델들이 갖고 있던 병렬 처리 불가능 문제와 학습 속도 문제를 해결했습니다.
Transformer 구조
대부분 경쟁력 있는 신경망 기반 시퀀스 모델처럼, 트랜스포머 모델도 기본적으로 인코더-디코더 구조를 가지고 있습니다.
아래의 Seq2Seq 모델 구조와 비교해보면,
Seq2Seq 모델은 인코더와 디코더 각각이 하나의 RNN 계열 모델을 가지고, 그 모델이 t개의 시점(그림에서는 단어 토큰)을 갖는 구조였습니다. 하지만 트랜스포머에서는 인코더와 디코더라는 단위가 N개 존재하는 구조입니다.
논문에서는 인코더와 디코더 각각 6개 사용했습니다. 동일한 내용의 인코더와 디코더가 6개 있는 구조인 것이죠. 인코더는 이전 인코더 계층의 출력값을 다음 인코더가 받아 점진적으로 입력된 값(문장)에 대한 의미를 담도록 벡터화를 진행해서 최종적으로 마지막 인코더 계층에서 입력 문장에 대한 최종 벡터를 출력합니다. 디코더에서는 각 디코더 계층이 마지막 인코더 계층(그림에서는 6번 인코더 계층) 출력과 이전 디코더 계층의 출력값을 입력으로 받습니다. 모든 디코더에서 독립적으로 마지막 인코더 출력값을 참조하는 것이죠.
하나의 인코더와 디코더만 사용했던 Seq2Seq 모델과 다르게 인코더와 디코더 계층을 여러 개 쌓음으로써 트랜스포머 모델은 더 복잡하고 고차원적인 문맥 정보를 학습할 수 있게 되고, 계층별 어텐션 매커니즘을 통해 긴 문맥도 효과적으로 학습할 수 있게 되어 성능이 좋아집니다.
'계층을 더 많이 쌓으면 당연히 성능이 좋아지겠지만, 그만큼 시간이나 자원도 많이 필요하지 않을까?' 하는 의문이 생길 수 있습니다. 트랜스포머는 이러한 고민을 병렬 처리가 가능한 'Self-Attention' 매커니즘으로 해결합니다. 자세한 건, 인코더와 디코더 레이어 구조를 살펴보며 설명하겠습니다.
위 사진은 논문에서 설명하는 하나의 인코더와 디코더 레이어를 구조화한 사진입니다. 왼쪽 구조가 인코더이고, 오른쪽 구조가 디코더입니다. 비슷해 보이지만, 디코더에는 인코더에 없는 'Masked Multi-Head Attention'이 등장하고, 최종 분류를 위해 Linear와 Softmax 함수가 추가되어 있네요. 처음 이 사진을 접하면 도통 무슨 소리인가 싶습니다. 우선 트랜스포머의 핵심 개념인 Self-Attention에 대해 알아보고 인코더와 디코더 각각의 구조에 대해 살펴보겠습니다.
Self-Attention
Seq2Seq 모델에서는 Attention이 RNN의 성능을 보정해주는 역할을 했습니다. 그러다 보니 RNN 계열의 모델이 가진 순차적인 입력이라는 특성을 벗어나지 못하고, 이 때문에 병렬처리가 불가능했죠. 트랜스포머 모델에서는 Self-Attention이라는 방식을 통해 병렬처리가 가능하도록 했습니다. 기존의 Attention과 Self-Attention을 비교해보겠습니다.
앞선 글에서 기존 Attention 구조를 설명한 그림입니다. 디코더는 $S_{t}$와 인코더의 각 은닉 상태 $h_{1}$, $h_{2}$. $h_{3}$간의 내적(Dot Product)을 계산하여, 입력 단어들과의 관련성을 측정합니다. 이 계산 결과는 가중치로 사용되어, 출력 단어 생성 시 어떤 입력 단어가 더 중요한지 결정합니다. 이 때 디코더는 인코더의 출력만을 참조하며, 입력 단어 간의 관계는 고려하지 않습니다. 즉, 여기서 인코더와 디코더는 단방향 의존성(인코더 → 디코더) 관계를 지닙니다. 때문에 기존 Attention에서 디코더는 출력 문장을 생성할 때 이전 출력 단어를 기반으로 다음 단어를 생성하고, 이전 단어 정보가 있어야만 다음 디코더에서 처리할 수 있기 때문에 순차적 의존성을 지니는 한계를 가집니다.
Self-Attention은 Attention을 입력된 문장 즉, 자기 자신한테 취한다는 개념입니다. 기존 Attention 메커니즘에서 Query, Key, Value에 대해 설명했는데요 Query는 위 그림의 $S_{t}$로 디코더에서 입력된 현재 단어(혹은 상태)에 대한 정보이고, Key는 인코더에서 각 입력 단어(토큰)의 특성이죠. 하지만 Self-Attention은 입력된 단어 간의 연관성을 구합니다.
예를 들어, '굴을 먹었는데, 그것이 상했었다.' 라는 문장이 있다고 합시다. 여기서 '그것'은 굴을 의미하죠. 사람이 보기엔 너무나 쉽지만 컴퓨터는 이러한 문맥을 알아차리기 어렵습니다. 이를 쉽게 해주기 위해 입력 문장의 단어들 간에 Self-Attention을 수행하는 겁니다. 여기서는 Query와 Key, Value가 모두 동일한 값을 가집니다.
위 그림은 하나의 입력 단어에 대해 Self-Attention에서 Attention Value를 구하는 흐름을 그린 것입니다. Attention 계산 방식과 동일합니다. 그저 Query와 Key, Value가 모두 동일하게 입력된 문장에 대한 값이라는 게 차이점이죠. 그림은 한 번에 하나의 단어를 계산하는 것처럼 표현했지만 실제로는 Query(입력단어) 행렬을 통해 아래 그림처럼 한 번에 연산하게 되고, 각 입력 단어 간의 연관성을 나타내는 Attention Matrix 가 만들어지게 됩니다.
수식으로 나타내면 $$ \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V $$로 표현할 수 있습니다. $$ sqrt{d_k} $$는 임베딩 벡터(Q, K, V)의 차원 수로, 내적 값이 차원이 커질수록 값이 커져 Softmax를 계산할 때 발생할 수 있는 기울기 소실 문제를 방지하기 위해 값의 크기를 조정(Scaling)해주는 역할을 합니다.
기존 Attention은 디코더의 현재 정보와 인코더 입력 간의 연관성을 구해 현재 단어 생성에 필요한 정보를 가져오는 것이라면, Self-Attention은 입력 문장 자체의 단어들 간 연관성을 계산해, 문맥적 의미를 반영한 새로운 벡터를 생성하는 과정입니다.
여기서 문제가 하나 있습니다. RNN 계열의 모델은 시간 순서에 따라 데이터를 순차적으로 처리하기 때문에, 입력된 단어의 위치 정보가 암묵적으로 반영됩니다. 아래의 Seq2Seq 모델 흐름을 다시 살펴보면, Yesterday가 예측되고 이것이 다음 단어를 예측하는데 반영되면서 자연스럽게 순서가 유지되죠.
하지만 RNN 모델을 제거한 Self-Attention에서는 입력된 각 단어 간의 유사성을 계산하는 것이기 때문에 입력 시퀀스의 위치(순서) 정보는 반영되지 않습니다. 위치 정보가 없다는 것은 문장의 구조적 의미를 반영하지 못할 수 있다는 단점으로 이어질 수 있습니다. 트랜스포머는 Self-Attention의 위치 정보 부재 문제를 해결하기 위해 Positional Encoding을 사용합니다.
Positional Encoding
위치 인코딩 즉, 위치 정보를 부여하는 방식입니다. 단어 벡터에 단어의 순서를 나타내는 벡터를 추가해서, 이를 통해 모델이 단어의 상대적 또는 절대적 위치 정보를 학습할 수 있도록 해줍니다.
위의 그림처럼 각 단어별 임베딩 벡터에 각 단어의 위치 정보를 포함한 값을 더해줘 임베딩 벡터 값을 조정하는 것입니다.(값은 가상의 값입니다.) 이렇게 되면 똑같은 단어라도 다른 벡터값을 가질 수 있게 됩니다. positional encoding 값은 단어의 순서 정보를 전달하기 위해 백터 내의 차원 인덱스가 짝수일 때는 사인 함수의 값을, 홀수일 때는 코사인 함수의 값을 사용해서 만들어지게 됩니다. 이렇게 위치 정보를 더해준 단어 임베딩 벡터가 Transformer의 입력값으로 사용됩니다. (그림에서는 표현을 위해 임베딩 벡터를 3차원으로 표현했지만, 논문에서는 입력과 출력 단어의 임베딩 벡터를 512차원으로 설정했습니다.)
그림에서 PE는 Positional Encoding을 나타냅니다. 참고로 사인과 코사인을 쓰는 이유는 단어 간의 상대적 위치를 나타내는 데 유용하고, 이를 통해 모델이 두 단어 간의 거리 정보를 쉽게 계산할 수 있기 때문입니다. 이를 통해 모델은 입력 문장의 단어 간 상대적 위치를 이해하고, 문장의 구조적 의미를 더 잘 학습할 수 있습니다.
이렇게 Self-Attention과 Positional Encoding을 통해 트랜스포머는 병렬 처리가 가능하면서 위치 정보도 포함해 학습할 수 있습니다. 이 두 가지 개념을 기억하고 Encoder와 Decoder의 구조에서 공통적으로 사용되는 Multi-Head Attention에 대해 알아보겠습니다.
Multi-Head Attention
Multi-Head (Self) Attention은 트랜스포머 모델에서 Self-Attention을 병렬적으로 여러 번 수행하여 다양한 관점에서 단어 간의 관계를 학습하는 메커니즘입니다. 쉽게 말해서 한 번으로는 부족할테니 여러 개의 Attention(=Multi-Head 구조)을 사용해 복잡한 패턴을 효과적으로 학습하기 위한 것입니다. 여기서 Head란 Head는 독립적으로 Self-Attention 연산을 수행하는 단위를 의미합니다. 각 헤드는 독립적으로 작동하며, 서로 다른 가중치를 학습합니다. 다른 가중치를 통해 다양한 문맥적 관계(예: 문법적 관계, 의미적 관계)를 병렬적으로 학습할 수 있습니다.
이렇게 여러 개의 Head에서 독립적으로 나온 출력을 결합해, 더 풍부하고 강력한 문맥을 담은 벡터를 생성할 수 있습니다. 또한, 각 Head가 입력 벡터의 차원을 분할하여 연산하므로 계산 효율성이 높아집니다. 논문에서는 입력과 출력 임베딩 벡터의 차원을 512차원으로 설정했고, Head의 수를 8개로 설정했습니다. 여기서 각각의 Head는 임베딩 벡터 차원을 Head의 수로 나눈 64차원 벡터를 연산으로 수행하고, 각 Head에서 나온 64차원의 벡터를 이어붙여 512차원 벡터를 생성하고, 결합된 벡터에 선형 변환(Linear Transformation)을 해서 최종 벡터를 생성합니다.
즉, Multi-Head Attention의 출력은 각 단어 벡터의 문맥 정보를 반영하며, 트랜스포머의 다음 계층으로 전달됩니다.
요약 & 정리
Multi-Head Attention은 트랜스포머 모델의 핵심 개념 중 하나로, 입력 벡터를 여러 개의 Head로 나누어 병렬적으로 처리합니다. 각 Head는 독립적으로 Self-Attention 연산을 수행하며, 서로 다른 문맥적 관계(예: 문법적 관계, 의미적 관계)를 학습합니다. 이렇게 병렬적으로 연산이 이루어지기 때문에 RNN처럼 데이터를 순차적으로 처리할 필요가 없어 시간 복잡도가 대폭 줄어듭니다. 또한, 여러 Head에서 독립적으로 학습된 결과를 결합해 풍부하고 강력한 문맥 정보를 담은 벡터를 생성할 수 있습니다. Multi-Head Attention은 병렬 처리의 효율성과 문맥 학습의 다양성을 모두 만족시키며 트랜스포머의 높은 성능을 이끄는 핵심 요소입니다.
이번 글에서는 트랜스포머의 핵심인 Self-Attention에 대한 개념들을 살펴봤습니다. 한 번에 너무 많은 내용을 담기엔 낯선 개념들이 많아 다음 글에서 아직 다루지 않은 Encoder와 Decoder 내 다른 서브레이어들에 대해 살펴보겠습니다.
'ML&DL' 카테고리의 다른 글
Transformer, 도대체 그게 뭔데 - Attention편 (33) | 2024.12.07 |
---|