-
[논문 리뷰] Attention Is All You Need논문 리뷰 2023. 3. 20. 18:54
Abstract
sequence를 변환하는 모델은 encoder와 decoder를 가진 복잡한 RNN이나 CNN이 주를 이루었고, 가장 좋은 성능을 내는 것은 attention 메커니즘을 활용한 모델이었다. 이번에 소개할 모델은 Transformer로, attention을 자기자신에 적용한 매커니즘에 기반을 두고 있다. Transformer는 학습 시간이 적게 들고 높은 성능으로 여러 번역 task에서 BLEU 신기록을 세웠다.
Introduction
LSTM, GRU같은 sequence 문제를 다루는 모델은 encoder-decoder 구조로 지금까지 연구되어 왔다. 이러한 RNN 모델은 위치$t$의 상태$h_t$를 계산하기 위해서 $h_{t-1}$의 계산이 선행되어야 한다는 점 때문에 병렬연산을 할 수 없어서 계산이 비효율적이다. factorization trick, conditional computation 연구를 통해 계산의 효율성을 어느정도 해결했지만 여전히 병렬연산은 불가능하다.
attention 매커니즘은 sequence의 요소의 위치에 상관없이 멀리 떨어진 요소끼리도 dependency를 학습할 수 있다는 장점이 있지만 일부를 제외한 모든 연구에서는 RNN과 함께 쓰이고 있다. 이번 연구에서 제안한 Transformer는 RNN을 attention 매커니즘으로 완전히 대체한 모델이다. 계산을 훨씬 병렬적으로 수행할 수 있어서 빠르고, global dependency를 학습할 수 있기 때문에 성능이 좋다.
Background
sequence 문제의 연산량을 줄이기 위한 노력은 CNN기반 모델인 ConvS2S, ByteNet에서도 있었다. sequence의 두 요소 사이의 거리에 대하여 ConvS2S는 선형 복잡도, ByteNet은 로그 복잡도의 연산량이 필요했다. Transformer는 상수 복잡도로 연산량을 줄였다. attention 매커니즘이 거리에 상관없이 쓰였기 때문에 다양한 측면으로 분석된 representation들이 평균화되어 특징을 분해하기 어려워지지만 뒤에 설명할 Multi-Head attention 개념을 통해 해결하였다.
self-attention은 intra-attention이라고도 하는데, 하나의 sequence에서 representation을 계산하기 위하여 위치에 연관시킨 attention 매커니즘을 말한다. 다양한 task에서 좋은 성능을 보였다.
end-to-end memory network는 recurrent attention 매커니즘을 이용한 모델이다. 간단한 Question Answering task에서 좋은 성능을 보였다.
Transformer는 attention 매커니즘으로 RNN이나 CNN을 완전히 대체한 최초의 모델이다.
Model Architecture
대부분의 좋은 성능의 sequence 변환 모델은 encoder-decoder 구조이다. encoder가 입력 sequence $(x_1, x_2, \cdots, x_n)$를 받아 $z=(z_1, z_2, \cdots, z_n)$으로 바꿔놓으면 decoder가 $z$를 입력으로 받아 결과 $(y_1, y_2, \cdots, y_m)$을 요소 하나씩 출력하는 방식이다. 매 단계마다 현재 위치의 출력을 추론하기 위해 이전 위치에서 생성된 출력을 추가적인 정보로 활용하는 auto-regressive 모델이다.
Transformer는 기본적으로 encoder, decoder 구조를 채택했다. encoder와 decoder에 self-attention이 쌓여있고 각 요소마다 fully connected layer가 있다.
Encoder: 6개의 동일한 layer로 구성되어있고 각 layer마다 두 개의 sub layer로 구성되어있다. 첫 번째는 multi-head self-attention 매커니즘이고 두 번째는 point-wise fully connected feed forward network이다. 각 sub layer는 앞 뒤를 연결하는 skip connection이 있고 그 뒤에 layer normalization이 있다. skip connection을 연결하기 위해 embedding layer를 포함해서 모델 내부의 모든 레이어는 같은 차원 $d_{model}$으로 고정되어야 한다. 일반적으로 $d_{model}=512$이다.
Decoder: Encoder와 마찬가지로 6개의 동일한 layer로 구성되어있다. 각 layer마다 Encoder의 sublayer 2개를 가지고 있으면서 추가로 Encoder의 출력을 입력으로 받기 위한 multi-head attention 매커니즘 sub layer가 하나 더 있는 구조이다. Encoder에서처럼 각 sublayer에 skip connection과 layer normalization이 있다. Decoder의 self-attention은 masking 과정을 거치는데, 위치 $i$의 단어를 예측하기 위해 뒤에 나오는 단어를 참고하지 않게 하기 위함이다.
attention function은 query, key, value가 입력으로 들어와 output을 내는 기능을 한다. output은 value의 weighted sum으로 계산되고 각 value에 할당된 weight는 query와 key에 의해 계산된다. query, key, value, output은 모두 벡터이다.
Scaled Dot-Product Attention: Transformer를 구성하는 attention function이다. 여러 개의 query, key, value를 한 번에 처리하기 위해 행렬의 형태로 계산한다. 수식은 이렇다: $Q$가 query, $K$가 key, $V$가 value일 때 $Attention(Q, K, V) = \text{softmax}(\frac{QK^T}{\sqrt{d_k}})V$. 이때 $d_k$는 key 한 줄의 차원 수를 말한다. dot-product attention과 대부분이 동일하지만 $\sqrt{d_k}$로 나누는 것에서만 차이가 난다. $d_k$로 나누어주지 않으면 행렬 곱의 결과는 분산이 커지기 때문에 절댓값이 커질 가능성이 높아지게 되는데, 대체적으로 큰 값들끼리 softmax를 통과하면 요소 하나를 제외한 나머지는 gradient가 0에 수렴하게 되는 gradient vanishing 현상이 일어난다. 이 효과를 상쇄시키기 위하여 $sqrt{d_k}$로 나누어주는 것이다.
참고로, 일반적으로 많이 쓰이는 attention function에는 additive attention과 dot-product attention가 있는데 dot-product가 공간 효율적이고, 둘 모두 이론적인 시간복잡도는 같지만 실제 속도로는 dot-product가 더 빠르다. 행렬 곱셈 연산이 극도로 최적화되어 있기 때문이다. 하지만 dot-product의 단점도 있는데, $d_k$가 커지면 성능이 additive attention보다 안좋아진다는 것이다. 그래서 Scaled Dot-Product Attention은 $\sqrt{d_k}$로 각 요소를 나눠주는 것이다.
Multi-Head Attention: 단순히 Scaled Dot-Product Attention을 사용하는 것보다 attention에 들어가는 $Q$, $K$, $V$에 linear layer를 통과시켜 각각 $d_k$, $d_k$, $d_v$로 차원을 바꿔 독립적으로 self-attention을 적용하고 concatenation하여 또 한 번 linear layer를 통과시킨 것이 성능이 더 좋다. 같은 입력에 대하여 각각의 head마다 다양한 측면으로 관련성을 분석하기 때문이다. 또한 일반적으로 각 head마다 들어가는 행렬은 크기가 기존의 것보다 더 작은데, 작은 행렬 여러 개를 독립적으로 수행할 수 있게 되어 병렬 연산이 가능해져 계산 속도가 더 빨라진다. 일반적으로 head의 수 $h=8$이고 $d_k=d_v=d_{model}/h=64$로 사용한다.
Transformer에서는 Multi-Head Attention을 3가지 방법으로 적용한다.
1. encoder-decoder attention layer: $K$, $V$는 encoder의 출력으로부터 얻고 $Q$는 이전 decoder의 이전 레이어의 출력으로부터 얻는다.
2. encoder에 있는 self-attention layer: $K$, $V$, $Q$는 모두 encoder의 이전 레이어의 출력으로부터 얻는다.
3. decoder에 있는 self-attention layer: $K$, $V$, $Q$ 모두 decoder의 이전 레이어의 출력으로부터 얻는다. 이때 출력 sequence에서 앞에 위치한 요소가 뒤에 위치한 요소의 영향을 받으면 auto-regressive의 특성을 만족하지 않기 때문에 이를 막기 위하여, Scaled Dot-Product Attention 내부에서 현재 위치 이후의 정보는 음의 무한대로 masking한다.
Position-wise Feed-Forward Network(FFN): 각각의 attention layer 내부의 sublayer 중 하나에 속한다. 구조는 2개의 linear layer가 있고 그 사이에 ReLU가 있는 형태이다. 각 위치마다 독립적으로 수행된다. 달리 말하자면 linear layer 대신 kernel 크기가 1인 convolution layer를 적용한 것과 같다. FFN의 입력과 출력은 $d_{model}=512$차원이고 가운데 위치한 hidden layer는 $d_{ff}=2048$차원이다.
Embeddings and Softmax: 학습된 embeddings를 사용하였다. encoder와 decoder에서의 embedding layer와, decoder 마지막의 softmax를 하기 전 linear layer에서의 weight는 공유하도록 하였다. 또한 $\sqrt{d_{model}}$으로 나누어주도록 하였다.
Positional Encoding(PE): 기존의 모델은 이전 decoder의 출력을 현재 decoder의 입력으로 받으면서 auto-regressive할 수 있었지만 Transformer는 모든 위치의 sequence를 한 번에 입력받는 방식이기 때문에 각 요소가 sequence내에서 어디에 위치하는지에 대한 정보를 주입시켜줄 필요가 있었다. 위치에 따라 다른 독특한 값 $PE_{(pos, i)}$를 정의해놓고 embedding layer의 출력에 더하여 구현했다. 이때 $pos$는 해당 요소가 sequence내에서의 위치이고 $i$는 representation의 dimension이다. $PE$로 적당한 다양한 함수를 실험해보았지만 채택된 수식은 아래와 같다.
$$
PE_{(pos, 2i)}=sin(pos/10000^{2i/d_model}), PE_{(pos, 2i + 1)}=cos(pos/10000^{2i/d_model})
$$
이렇게 할 경우 $PE_{pos}$와 비교하여 $PE_{pos+k}$와 같이 일정한 offset이 있을 경우에도 둘 사이의 관계가 일차함수로 나타내어지기 때문에 모델이 상대적인 위치를 잘 학습할 것으로 생각했기 때문이다.
Why Self-Attention
왜 Self-Attention을 사용해야할까? CNN이나 RNN의 방법과 비교하여 살펴보자. 3가지 기준을 통해 비교하였다. 첫 째, 하나의 레이어 당 계산복잡도는 어느정도인가? 둘 째, 얼마나 병렬처리가 가능한가? 이는 필요한 sequential operation의 최소 횟수로 측정한다. 셋 째, 멀리 떨어진 두 위치의 dependency를 얼마나 잘 학습할 수 있는가? 이는 레이어의 입력과 출력 중 임의의 두 위치를 잇는 경로의 최대 거리로 측정한다.
먼저 Recurrent 모델과 비교해보자. Self-Attention은 하나의 sequence를 한 번에 모델에 넣고 출력 sequence를 얻어내기 때문에 Sequential Operations가 $O(1)$이지만 Recurrent는 n번 반복해야 하기 때문에 $O(n)$이다. Complexity per Layer는 n이 d보다 더 작을 경우 Self-Attention이 Recurrent보다 더 빠르다. 대부분의 경우 n이 d보다는 작고, 만약 아주 긴 sequence를 학습시킨다면 이웃한 r개만 연결한 방식의 Self-Attention을 통해 계산복잡도를 완화할 수 있을 것이다. 이렇게 한다면 Maximum Path Length는 비록 $O(n/r)$으로 증가할 것이다.
이제 Convolutional 모델과 비교해보자. k가 n보다 작다면 sequence 전체를 이을 수 없으므로 $O(n/k)$만큼의 반복이 필요하다. dilated convolution을 사용한다면 $O(log_k(n))$까지 줄일 수 있다. 대체적으로 Convolutional은 Recurrent보다 느린데, k만큼의 복잡도가 곱해지기 때문이다. 하지만 seperable convolution을 사용한다면 $O(knd + nd^2)$로 줄일 수 있고 이 때 $k=n$인 경우 Self-Attention과 FFN의 복잡도와 같아진다.
부가적으로 Self-Attention은 해석가능한 모델이라는 장점이 있다. 각각의 attention의 head는 깔끔하게 언어학적, 문법적 구조를 학습한다.