Transformer는 2017년 구글이 발표한 논문인 “Attention is All You Need”에서 나온 모델로 기존의 seq2seq의 구조인 인코더, 디코더를 따르면서도, RNN을 사용하지 않고 Attention만으로 구현한 모델입니다. Transformer가 출현함으로써 BERT, GPT-3, T5 등과 같은 아키텍처가 발전하는 기반이 마련되었습니다.
1-1. seq2seq 모델의 한계점
기존의 seq2seq 모델은 encoder-decoder 구조로 구성되어 있었습니다. encoder는 입력 시퀀스를 하나의 벡터 표현으로 압축하고, decoder는 이 벡터 표현을 통해서 출력 시퀀스를 만들어냈습니다. 하지만 이러한 구조는 encoder가 입력 시퀀스를 하나의 고정된 벡터로 압축하는 과정에서 정보 손실이 발생하며 기울기 소실 문제가 존재한다는 한계가 있었고, 이를 보정하기 위해 attention이 사용되었습니다.
1-2. Attention machanism
현재 출력 단어를 예측하는 매 시점마다, encoder의 전체 문장 중 해당 시점에서 예측해야할 단어와 연관이 있는 입력 단어 부분을 좀 더 집중하는 메커니즘을 이용하였습니다. Attention machanism 내용은 이전 세미나에서 자세히 다루었기 때문에 넘어가도록 하겠습니다.
: 특정 문장이 있을 때, 자기 자신의 문장 스스로에게 attention을 수행해 학습하는 것입니다.
ex. A dog ate the food because it was hungry.
→ 이 문장에서 ‘it’은 ‘dog’나 ‘food’를 의미할 수 있습니다. 하지만 문장을 자세히 살펴보면 ‘it’은 ‘food’가 아닌 ‘dog’라는 것을 알 수 있는데, self-attention을 이용해 이를 알 수 있습니다. self-attention에서 각 단어의 표현들은 문장 안에 있는 다른 모든 단어의 표현과 연결해 단어가 문장 내에서 갖는 의미를 이해합니다. 더 자세한 내용은 뒤에서 설명하겠습니다.
”The animal didn't cross the street because it was too tired
” 문장의 self-attention 결과
Transformer의 구조는 다음과 같이 attention만으로 encoder-decoder 구조를 가진 모델입니다.
sequential한 데이터 input이 들어왔을 때, transformer를 통과해서 ouput이 나오는데 RNN의 encoder-decoder 구조와 틀은 비슷하지만 transformer의 내부를 보면 encoding component와 decoding component가 존재하고 이 둘을 어떻게 연결시키는지가 다릅니다.
encoding, decoding component는 encoder, decoder를 여러개 쌓은 것이라고 할 수 있습니다. 본 논문에서는 6개의 encoder와 decoder를 각각 쌓았습니다.
transformer의 내부를 이해하기 전 우선 transformer의 입력에 대해서 알아보겠습니다.
input이 들어오면 input embedding을 이용하여 벡터로 바꿔주는 작업을 하게 되며 Glove, Fasttext와 같은 word embedding 방법을 이용하여 512 차원으로 임베딩을 진행하게 됩니다. 이러한 임베딩은 가장 첫번째 encoder의 입력으로써만 사용되며 2번째 encoder 부터 입력으로는 이전 encoder의 output 결과를 사용하게 됩니다.
RNN의 경우에는 단어의 위치에 따라 순차적으로 입력을 받아 처리하기 때문에 단어의 위치 정보를 가질 수 있지만, transformer의 경우 한번에 전체 sequence를 넣기 때문에 위치정보를 담을 수 없어 각각의 단어가 가지고 있는 위치 정보를 보존하기 위한 목적으로 positional encoding을 사용합니다. Input Embedding과 positional encoding을 더해주어 위치정보를 담은 512차원의 벡터를 새롭게 생성하게 됩니다. (같은 차원)
pos : 문자에서 단어의 위치, i : 해당 위치의 임베딩
positional encoding의 계산은 다음과 같은 사인파 함수를 이용합니다. pos는 입력 문장에서의 임베딩 벡터의 위치를 나타내며, i는 임베딩 벡터 내의 차원의 인덱스를 의미합니다. i가 짝수인 경우 사인함수를, 홀수인 경우 코사인 함수를 이용하여 구하고 있음을 알 수 있습니다.
이 때, positional encoding이 갖는 크기 자체가 위치에 따라서 달라서는 안되고, input sequence에서 두 단어의 거리가 멀어지게 되면 positional encoding 사이의 거리도 멀어져야 합니다. 다음 표를 통해 두 단어 사이의 거리가 멀어질수록 positional encoding값도 대부분 커지는 것을 알 수 있습니다.
encoder block은 2개의 sublayer로 구성되어 있으며 각각의 encoder는 구조가 전부 동일하다는 특징을 가지고 있습니다. 하지만 각각의 encoder가 가질 수 있는 가중치들은 학습을 통해서 생성되기 때문에 달라질 수 있습니다.
1) self-attention layer : 하나의 단어에 대한 정보를 처리할 때, 함께 주어진 input sequence의 다른 단어들을 얼마만큼 중요하게 볼 것인지에 대한 layer
2) Feed Forward Neural Network : 각 위치에 독립적으로 적용되는 layer
앞에서 설명했듯이 특정 단어의 의미를 이해하기 위해 input sequence의 다른 단어들을 훑어가면서 해당 단어와 연관이 있는 단어가 무엇인지 이해하는 과정을 의미합니다.
설명하기에 앞서 Query, Key, Value에 대한 개념을 간단히 설명하면 다음과 같습니다.
Query
- 현재 내가 보고 있는 단어의 표현 ex. 구글에 입력하는 검색어
Key
- Query값을 기준으로 찾는 대상 ex. 검색한 블로그들의 제목
Value
- Key가 가지고 있는 실제 값 ex. 블로그들이 가지고 있는 글이나 값
[ Self-attention 작동 원리 ]
STEP 1 : 각 encoder의 input vector에 대한 Query, Key, Value 벡터를 생성
→ 이 때 Query, Key, Value 벡터들은 초기 입력인 의 차원을 가지는 단어 벡터들보다 더 적은 차원을 가집니다. 본 논문에서는 =512의 차원을 가졌던 단어 벡터들을 64차원을 가지는 Q, K, V 벡터로 변환하였습니다.
→ 필수는 아니지만, 이후 multi-head attention 관점에서 봤을 때는 multi-head를 통과한 벡터들을 전부 concatenation해서 해당하는 인코더 또는 디코더의 아웃풋으로 사용하기 때문에 Query, Key, Value의 차원을 키우는 것보다는 나중에 concat을 시켰을 때 512차원이 다시 만들어지도록 하는게 좋다고 합니다. (512 = 64 x 8 → 8개의 head를 써서 attention을 하겠다는 개념)
Query, Key, Value 매트릭스는 input embedding로부터 만들어집니다. 매트릭스를 생성하기 위해서 라는 3개의 가중치 행렬을 생성한 다음 이 가중치 행렬을 input embedding 매트릭스 X에 곱해주어 Query, Key, Value 매트릭스를 생성합니다. 이 때 가중치 행렬은 처음에 임의의 값을 가지며, 학습과정에서 최적값을 얻게 됩니다.
→ 그림을 통해 설명하면, 현재 input embedding이 4차원이고 매트릭스를 (4x3) 매트릭스로 정의하여 thinking이라는 X1 벡터에 매트릭스를 곱해주면 q1 벡터가 나오게 됩니다. → (1x4)x(4x3) = (1x3) Key, Value도 동일한 과정을 거쳐서 Query, Key, Value 벡터를 생성하게 됩니다.
STEP 2 : 현재 보고 있는 input 토큰과 유사도가 높은 다른 토큰들을 찾기 위해 현재 보고 있는 Query 벡터와 Key 벡터를 곱해줍니다.
STEP 3 : 안정적인 gradient 값을 얻기 위해 차원의 앞에서 구한 값에 Key 매트릭스 차원의 제곱근값으로 나누어줍니다. (본 논문에서는 Key의 차원이 64차원이었기 때문에 루트를 씌운 8로 나누어줌)
STEP 4 : softmax 함수를 사용해 정규화 작업을 진행하여 도출된 softmax score는 문장 내에 있는 각 단어가 문장에 있는 전체 단어와 얼마나 연관되어 있는지를 의미합니다.
STEP 5 : 가지고 있던 단어들의 Value들과 softmax값을 곱해줍니다.
STEP 6 : softmax에 의해서 가중합이 된 value값들을 첫번째 토큰의 최종적인 아웃풋으로 쓰게 됩니다.
전체적인 프로세스를 행렬 연산을 통해 정리한 모습입니다. 실제 행렬 연산을 예시를 통해 보면 다음과 같습니다.
지금까지는 single self-attention에 대해 설명한 내용이고 다음은 transformer에서 사용하는 multi-head attention에 대해 알아보도록 하겠습니다.
문장에서 it이 어떤 단어들을 볼지를 하나의 경우의 수만 허용하는 것이 아니라 여러 개의 경우의 수를 허용하겠다(다른 시각으로 보겠다), 즉 attention head를 여러 개 두겠다라는 것을 의미합니다. 본 논문에서는 8개의 attention head를 이용했습니다.
multi-head attetion에서는 지금까지 설명한대로 각각의 개별적인 attention을 만들어서 전부 concatenation을 합니다. 그 이후에 8개의 attention을 concat한 크기와 같은 컬럼의 개수를 가지고 원래 input embedding과 같은 차원의 행을 갖는 라는 매트릭스를 설계합니다. 는 와 같이 모델 학습 과정에서 같이 학습이 되는 가중치이며, 를 곱해주게 되면 우리가 처음 가지고 있었던 원래 input embedding과 동일한 차원을 가지는 self-attention의 ouput을 만들어낼 수 있습니다. → (seq_len, d_v x num_heads) x (d_v x num_heads, d_model) = (seq_len, d_model)
2개의 attetion을 사용한 경우와 8개의 attention을 사용한 경우를 시각화 한 결과이며, 같은 it이라는 단어에 대해서도 attention score가 조금씩 다르게 scoring이 되는 것을 확인할 수 있습니다.
지금까지는 input으로 부터 self attention에 해당하는 파트에 대한 설명했고, self-attention을 통과한 이후에는 residual block을 더해주고 Normalize를 해주어야 하는데 이는 Residual Connection & Layer Normalization를 의미합니다.
1) Residual Connection (잔차연결)
위 그림은 입력 x와 x에 대한 어떤 함수 F(x)의 값을 더한 H(x)의 구조를 보여줍니다. F(x)가 transformer의 서브층에 해당되며, 잔차 연결은 서브층의 입력과 출력을 더하는 것을 의미합니다. 앞에서 확인했듯이 서브층의 입력 출력이 동일한 차원을 가지고 있으므로, 덧셈연산이 가능합니다.
2) Layer Normalization (층 정규화)
잔차 연결을 거친 결과는 이어서 층 정규화 과정을 거치며 각 레이어 값이 크게 변화하는 것을 방지해 모델을 더 빠르게 학습합니다.
전체적인 그림을 통해 보면, Add & Normalize block은 한번만 하는게 아니라, 각각의 block들 마다 계속 수행해주게 됩니다.
self-attention을 통과한 후 add & normalize block을 통과한 Z1, Z2 벡터는 feed forward network를 통과하게 됩니다. Feed forward network는 Fully-connected network이고 각각의 position에 대해서 개별적으로 적용합니다.
Feed forward neural network 식을 그림으로 표현하면 다음과 같습니다. 여기서 x는 앞의 multi-head attention 결과로 나온 (seqlen, $d{model})의 크기를 가지는 행렬을 의미합니다. 가중치 행렬 W1은 $(d_{model},d_{ff})의 크기를 가지고, 가중치 행렬 W2는 의 크기를 가집니다. 본 논문에서 은닉층의 크기인 는 2,048으로 정의했습니다. 여기서 매개변수 는 하나의 인코더 층 내에서는 다른 문장, 다른 단어들마다 동일하지만 인코더 층마다는 다른 값을 가집니다. 2번의 linear transformation을 수행하고, 두 linear transformation 사이에는 ReLU 연산을 수행합니다. FFNN을 통과한 후 인코더의 최종 출력은 입력의 크기와 동일하게 유지됩니다. 하나의 인코더 층을 지난 이 행렬은 다음 인코더 층으로 전달되고, 다음 층에서도 동일한 인코더 연산이 반복됩니다.
encoder와 마찬가지로 decoder도 N개를 누적해서 쌓을 수 있으며 decoder는 이전 decoder의 입력값과 encoder의 표현(출력값), 2개를 입력 데이터로 받게 됩니다. decoder도 positional encoding을 추가한 값을 입력값으로 사용하고 3개의 sublayer로 이루어져 있습니다. encoder와 decoder의 multi-head attention의 차이에 주목하며 각 sublayer에 대해 설명하도록 하겠습니다.
encoder에서 정보를 처리할 때는 순차적으로 처리할 필요없이 한꺼번에 다 가지고 오기 때문에 한번에 모든 sequence를 다 사용해서 masking을 하지 않는 unmasked 방식을 사용합니다. 하지만 decoder에서는 문장 행렬로 입력을 한번에 받은 뒤 현재 시점의 단어를 예측하고자 할 때, 입력 문장 행렬로부터 미래 시점의 단어까지 참고할 수 있는 현상이 발생하면 안됩니다. 따라서 decoder에서는 현재 시점의 예측에서 현재 시점보다 미래에 있는 단어들을 참고하지 못하도록 masked multi-head attention을 도입했습니다. 현재 시점 뒤쪽에 있는 값들을 - inf 로 masking함으로써 softmax를 계산하면 0이 되면서 attention score가 주어지지 않도록 합니다.
decoder의 multi-head attention는 multi-head attention을 수행한다는 점에서는 이전의 attention들과 공통점이 있으나, self-attention이 아닙니다. self-attention은 Query, Key, Value가 같은 경우를 말하는데, 두번째 multi-head attention의 경우 Query가 decoder의 행렬인 반면, Key, Value는 encoder 행렬이기 때문입니다. 이외의 나머지 연산 과정은 다른 attention들과 같습니다. multi-head attention을 통해 타깃 단어가 입력 문장의 모든 단어와 얼마나 유사한지 계산할 수 있게 되고 이러한 결과를 다음 단어를 예측하는데 이용하게 됩니다.
decoder가 타깃 문장에 대한 표현을 학습시키면 최상위 디코더에서 얻은 출력값을 Linear and softmax layer에 전달합니다.
Linear Layer는 단순히 simple fully connected neural network이라고 생각하면 되고, Softmax Layer는 최종적으로 우리가 찾아야하는 argmax를 찾아서 여기에 대응하는 단어를 출력하는 것으로 이러한 방식으로 decoder는 타깃 문장의 다음 단어를 예측하는 과정을 반복하게 됩니다.
[ Self-attention의 장점 3가지 ]
1) 각 layer의 계산 복잡도가 감소한다
2) Recurrence를 없앰으로써 더 많은 양을 병렬 처리 할 수 있다
3) Long-term dependency에 대해 효율적인 처리를 할 수 있다
5-1. Training Data and Batching : WMT 2014 English-German dataset (4.5million sent. pairs, byte-pair encoding), WMT 2014 English-French dataset (36M sent., 32000 word-piece vocab.)
5-2. Hardware and Schedule : 8개의 NVIDIA P100 GPU를 사용해서 base model은 100,000 step (1step = 0.4초), big model 은 300,000step(1step = 1.0초) 동안 학습을 진행
5-3. Optimizer : Adam optimizer 사용해서 learning rate는 warmup step = 4000으로 두고 학습을 진행
5-4. Residual Dropout : 각 sublayer의 결과에 대해서 residual connection을 수행하기 전에 dropout 을 적용. 으로 지정
5-5. Label Smoothing : label smoothing value = 0.1 로 지정해서 사용. Perplexity 에는 부정적인 영향을 주지만, accuracy와 BLEU 점수에는 긍정적인 영향.
6-1.
6-2. Model Variations