[NerulPS 2017] Attention is all you need

안녕하세요 제 두번째 X-review로는 Transformer 를 작성하려고 합니다.
이전에 잘 작성해주신 글들이 많지만, 서로 표현하는 방법이나 생각하는 것들이 조금씩 다를 수 있으니 이후 읽을 사람에게 생각의 여러 방향을 보여주는 것도 의의가 있을거라 생각합니다. 리뷰 시작하겠습니다.

Abstract

이전까지는 RNN이나 CNN을 Encoder + Decoder 구조로 사용하는 것이 문장 변환 모델의 방식이었습니다. 저자는 이전 방식의 SOTA 방식에서 주로 사용되던 Recurrent 방식이나 Conv 구조를 사용하지 않고 attention을 사용해서 트랜스포머를 만들게 됐습니다.

  1. Introduction

이전 연구들은 순환구조를 사용하고 encoder-decoder 방식을 사용했습니다.
순환구조를 사용하는 모델은 값들을 순차적으로 다루기 때문에 병렬적인 처리가 안되고, 엄청 긴 문장이 들어오면 힘들다는 문제가 있었습니다.
문장이 길어지면 힘든 문제는 RNN의 구조상 덧셈이 없고 곱으로만 이루어져 gradient vanishing이 생기기 때문입니다.

이러한 병렬적 처리를 attention 구조가 가능하게 해줍니다. 트랜스포머 이전에도 attention 기법 자체는 lstm등에 사용되기는 했으나, recurrent 방식을 배제하고 input output의 attention에만 전역적으로 의존하는 방식은 트랜스포머가 최초입니다.

2. Background

이전에도 사용되던 Entended Neural GPU, ByteNet, ConvS2S 같은 방식들은 conv 형태의 연산으로 병렬연산이 가능하게 됐습니다. 그러나 거리가 먼 애들은 거리에 비례하거나 logarithmically하게 연산량이 증가하는 문제가 존재했습니다.
트랜스포머는 정해진 연산량으로 이 문제를 해결하였고, attention 구조로 생기는 정보의 희석문제는 multi-head를 만들어 해결했습니다.

3. Model Architecture

트랜스포머는 이전까지의 SOTA인 encoder-decoder 구조를 차용하며, 이때 인코더와 디코더 모두에 self-attention 레이어와 point-wise fc layer를 쌓아 구성했습니다.

self-attention 레이어를 쌓았다는 것은 N층의 encoder와 decoder를 사용했다는 것이고 논문에서는 N=6으로 설정하였습니다.

point-wise fc layer는 ffn을 각 문장마다 해당 문장의 단어들에 point wise하게 각각 같은 가중치를 사용했다는 것입니다.
(FFN(x) = ReLU(xW1 + b1)W2 + b2)
이는 비선형성을 추가하고, 차원을 확장할 수 있습니다.

3.1 Encoder and Decoder Stacks

Encoder
총 6개의 동일한 Layer를 보유하며 각 layer는 각 2개의 sub-layer를 보유합니다. 각 sub-layer는 Residual connection과 layer norm을 가지고 있습니다.
1. multi-head self-attention 매커니즘
2. point wise fc layer
Decoder
Masked multi-Head attention이 들어가는데, 이유는 문장을 예측하는데 있어서 미래의 단어를 안보게 하기 위함입니다. 학습에서와 평가에서 auto-regressive가 실제로 적용되는지 여부는 약간 다릅니다. 학습에서는 masking된 attention맵을 생성하여 한 문장을 한번에 학습하며, 실제 문장 번역에서 사용될때는 이전 입력의 결과를 다시 input으로 넣어주면서 auto-regressive가 이루어집니다. 이후 표로 masking 예시를 보여드리겠습니다.

3.2 Attention

Query,key,value 를 이용하여 Query와 key의 유사도를 계산하고 해당 유사도는 학습과정에서 각 단어들의 관계를 의미하게 되며 value에 곱해집니다.

3.2.1 Scaled Dot-Product Attention

Query와 key의 차원은 dk, value의 차원 dv입니다. 아래 순서로 self-attention 연산이 진행됩니다.

  1. query와 key의 dot product
  2. 루트dk로 나누기(scale)
  3. softmax (가중치 벡터 생성)
  4. Value 에 가중치 벡터 곱해서 가중합 계산

2번에서 루트dk로 나누는 이유는 dot product 연산은 dk 값에 의존적이라 큰 값이 들어오면 softmax연산에서 매우 작은 gradient를 흐르게 하여 scaling해서 조절해준다고 합니다.

해당 표는 encoder와 decoder에서 각각 문장의 attention map을 만드는 방식입니다. encoder에서는 불어로 나는 학생이다의 attention map을 학습하고 이후 Decoder에 cross attention 형태로 넣어주게되며, decoder에서는 masked를 가중치값에 -inf 값으로 넣어 이후 softmax를 통과하면 0으로 계산되게끔 하여 구현하였습니다. sos는 문장의 시작점을 의미합니다.

위에 사진중 Decoder 부분에 존재하는 Encoder-Decoder Attention 부분은 Encoder의 output을 key, value로 사용하고 디코더의 셀프 어텐션 부분에서의 결과를 쿼리로 사용하여 내가 번역하고싶은 언어와 번역할 나라의 언어의 attention을 학습하게됩니다.

3.2.2 Multi-Head Attention

단일 head만 사용했을때 생기는 문제점은 앞서 말했듯이 정보가 희석된다는 점입니다. 문장에서 각 단어가 다른 단어와 가지는 관계가 하나가 아닐 수 있기 때문에, 여러 head로 나누어 각 head들이 각 단어들이 가지는 여러 문맥적 관계를 포착할 수 있게 합니다. 다만 이후 차원을 맞춰주기 위해 모든 head들을 다시 concat해서 전체 encoder나 decoder에서의 차원을 맞춰줍니다.

3.3 Position-wise Feed-Forward Networks

FFN은 convolution block (kernel size=1) 과 비슷한 효과를 냅니다.
입력 x : (batch_size, sequence_length, d_model)
x-> Linear(d_model -> d_ff) -> ReLU -> Linear(d_ff -> d_model) 순서로 구성됩니다.
즉 d_model (512) 차원으로 표현되던 특정 seq(“나는”) 같은 단어들이 2048차원으로 표현력을 확장시키고 이후 비선형적 특징을 넣어준 후 다시 512차원으로 요약하여 attention이 놓친 복합적인 의미를 해석하게 도와줍니다.

3.4 Embeddings and Softmax

트랜스포머는 입력토큰과 출력토큰을 d_model 차원의 벡터로 바꾸기 위해 learned embedding을 사용합니다. 미리 pretrained 된걸 사용하지 않고, 예를 들어 “나는” 같은 단어를 123번 index로 치환하여 123번 index에 해당하는 d_model 사이즈의 벡터로 초기화하고 그걸 학습하게 됩니다. 그래서 “나를” 같은 단어와 비슷한 방향으로 학습될 수 있습니다.
랜덤시드를 고정해놓지 않는다면 학습마다 해당 언어 임베딩 벡터의 방향은 달라질 수 있지만, 비슷한 단어의 방향은 비슷하게 유지됩니다.

3.5 Positional Encoding

저자는 recurrent 방식이나 convolution 방식을 사용하지 않기 때문에, 순서적인 정보를 따로 넣을 필요가 있었다고 합니다. 이를 위해 positional encodings를 추가하게 됩니다.
이는 d_model 차원으로 구성되어 있고 기존의 input과 더해질 수 있게 했습니다.

이런 함수 기반 인코딩을 사용한 이유는 서로 다른 파장을 가진 sinusoidal 값들을 사용하면 모델이 상대 위치에 대한 정보를 선형적으로 쉽게 예측할 수 있다고 합니다. (벡터의 내적이나 차로 선형적 위치 추정 가능)
저자는 learned positional embedding도 사용해봤으나 실제 성능은 비슷했으며, sin, cos 을 사용하는 것이 학습시 사용했던 문장보다 더 긴 문장이 들어왔을 때 extrapolation에 유리하여 sinusoidal 방식을 채택했다고 합니다.

Ablation sutdy

Transformer의 각 요소들로 ablation을 진행하였습니다.
PPL은 얼마나 문장을 혼란스러워하는지에 대한 점수이고
BLUE는 번역의 정확도입니다.
base모델로부터 A , B , C , D , E 의 ablation을 진행하여 N이 커질수록 성능이 좋아지며 head 개수는 16개 이후부터는 성능감소, positional embedding은 성능적으로 base와 거의 유사한 점을 확인할 수 있습니다.

트랜스포머 논문이 실험적 내용보단 이론적으로 이후에 많은 분야에 영향을 미치는 만큼 개념적인 흐름이 머리속에 그려지면 이후 논문들을 이해하는데 도움이 될 것 같습니다.

Author: 신 인택

5 thoughts on “[NerulPS 2017] Attention is all you need

  1. 안녕하세요 인택님 리뷰 잘 읽었습니다!

    궁금한점이 하나 생겨 여쭤보고싶습니다.
    positional encodig 사용한 이유는 서로 다른 파장을 가진 sinusoidal 값들을 사용하여 모델이 상대 위치에 대한 정보를 선형적으로 쉽게 예측할 수 있다고 하셨는데 이에대해 크게 와닿지않아서 자세한 설명 부탁드립니다.
    감사합니다^^

  2. 안녕하세요 신인택 연구원님 리뷰 잘 읽었습니다
    질문이 하나 있습니다
    attention을 수행할 때 여러 헤드로 나눠서 어텐션을 수행하고 그게 주는 효과가 대단히 신기한데요! 저자는 이런 방법을 어떻게 적용하게 되었는지가 궁금합니다.
    이전에도 이런 임베딩 벡터를 같은 크기로 나눠 연산을 하던 방법이 있었던 건 가요? 그냥 저자가 실험을 해보니 조금 더 여러 의미에서 학습이 가능하더라 라고 얻게된 결과인 걸 까요?
    감사합니다!

  3. 안녕하세요 신인택 연구원님 좋은 리뷰 감사합니다.

    리뷰를 읽으면서 몇가지 궁금한 점이 생겨서 질문합니다.

    1. 디코더에는 Figure.1에서 Masked Multi-Head Attention과 Multi-Head Attention 두가지 attention이 존재하는데 두 연산은 masking만 차이가 있는 건가요?

    2. 3.4절에서 learned embedding과 pretrained embedding의 차이가 무엇인지 궁금합니다. learned가 사전학습을 통해 학습했다는 것과는 다른 의미인지, 어떻게 비슷한 단어의 방향이 유지되는 건지 궁금합니다.

    3. 포지셔널 임베딩에서 긴 문장이 들어왔을 때 extrapolation에 유리하여 sinusoidal 방식을 사용한다고 언급해주셨는데, sinusoidal 방식은 삼각함수가 주기함수이기 때문에 긴 문장이 입력되면 같은 값을 갖는 경우가 생길 수 있을 것 같습니다. 이 중복 가능성 문제에 대한 저자의 분석이 있었나요?

    4. Ablation Study을 첨부해주셨는데, 기존 RNN 방법론과 성능이 얼마나 차이나는지 궁금합니다. 그리고 PPL과 BLEU로 성능을 평가하는 것 같은데 어떻게 평가되는 건지도 설명 부탁드립니다. 기존 방법론과의 비교와 평가지표에 대한 설명이 없어서 모델의 성능이 얼마나 향상된건지, 각각의 ablation에서 파라미터에 따른 성능이 얼마나 차이나는 건지가 체감이 안되네요.

    5. Ablation Study에서 head의 개수가 늘어남에 따른 성능이 오르락 내리락하는 것 같습니다. 각 단어들이 가지는 여러 문맥적 관계를 포착하기 위하여 여러 head를 사용한다고 하셨는데, head가 32개일때의 성능이 16개일 때의 성능보다 오히려 낮은 이유에 대한 저자의 분석이 있었는지 궁금합니다.

    감사합니다.

  4. 안녕하세요 인택님 리뷰 감사합니다.

    attention 구조로 생기는 정보의 희석문제는 multi-head를 만들어 해결했다고 하셨는데, 정보의 희석 문제가 정확히 어떤 문제이고, multi head가 어떻게 해결했는지가 궁금합니다!!
    또 ablation을 진행했을때 N은 커질수록 성능이 좋아지지만 head 개수는 16개 이후부터는 성능이 감소 하는데, 연산량 적인 측면에서 문제가 발생하는것은 그럴 수 있을것 같지만 성능이 낮아지는 이유는 무엇인지 궁금합니다!!

  5. 리뷰 잘 읽었습니다. 기존에 잘 정리된 tranasformer 리뷰들이 많은데, 그것들과 비교하면 정리가 덜 된 느낌이네요. 질문 몇 개 드립니다. transformer의 기본적인 개념들이니, 상세한 답변 기대하겠습니다.

    1. “문장이 길어지면 힘든 문제는 RNN의 구조상 덧셈이 없고 곱으로만 이루어져 gradient vanishing이 생기기 때문입니다.” 부분이 꽤나 추상적으로 작성되어 있네요. 이 부분을 더 자세히, 문장이 길어지면 왜 문제인지, 덧셈이 없고 곱으로만 이루어져서 gradient vanishing이 왜 일어나는지에 대해 더 자세한 설명 부탁드립니다. 그리고 길이가 긴 sequence가 입력으로 들어왔을 때의 문제가 gradient vanishing 이외에 무엇이 있는지 고민해서 답변 주시기 바랍니다(gradient vanishing이 구체적으로 어떤 문제인지부터 고민을 시작하면 도움이 될 것 같네요). 기존 seq2seq 구조의 어떤 문제점들을 transformer가 어떻게 해결했는지 함께 고민해보면 transformer의 강점을 더 명확히 알 수 있을 것입니다.

    2. attention 연산은 내적으로 수행됩니다. 학습되지 않죠(내적은 파라미터가 필요한 연산이 아니므로). transformer 모델에서 학습을 통해 변화되는 부분은 어디인가요? 그리고 학습으로 업데이트 되는 부분들의 역할은 무엇일까요?

    3. inference 과정에서 decoder의 cross-attention이 어떻게 수행되는지, 이 때 key, query, value는 어떻게 얻은 값인지 설명해주시기 바랍니다.

    4. layer normalization는 무엇이고, 어떤 목적으로 사용되며, 구체적으로 어떻게 연산되나요?

    5. 학습할 때 디코더에 정답 sentence를 같이 넣어주면 next token prediction 과정에서 그냥 다음 정답 값 토큰을 보고 현재 출력을 예측하는 방향으로 학습이 shorcut에 빠지게 될 수 있는데, 이를 어떻게 방지하는지 설명해주시기 바랍니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 항목은 *(으)로 표시합니다