Transformer (Attention Is All You Need)

2023. 12. 12. 10:42Thesis/Paper Reading

 

Attention Is All You Need에 대해 리뷰함.

이전에 다른 블로그와 논문리뷰를 모두 읽고 들어봤지만, 상위레벨에서 리뷰된것들 뿐이라, 하위레벨까지 리뷰하려고 함.

하지만 이렇게 리뷰할 때, 양이 너무 많이지고, 처음보는 사람들은 뒤로갈수록 앞의 내용이 기억이 안날수 있었음. 그래서 최소한의 하위레벨설명으로 줄였음.

0. Background

Seq2Seq

다음 seq2seq 모델을 보면, LSTM cell들이 하나씩있고, 인코더와 디코더의 파트로 나뉘어져있는데, 토큰들을 각 lstm에 넣게되면, HIdden state(LSTM의 기억셀 Ct C t 와, 결과값 ht h t )로 나오는데, 뒤로 갈수록 (h1,h2,h3) 앞에있는 히든스테이트를 반영하게 됨. (lstm의 특징) 마지막으로 h4라는 히든스테이트는  인코더에 들어가는 context를 압축한 Context 벡터가 됨.

디코더는 첫 입력으로 문장의 시작을 의미하는 심볼인 <sos>가 들어가는데 (찾아보니 s.go등 다양하게 쓰인다고 함), Context Vector와 <sos>, 이 2개의 입력을 바탕으로새로운 Hidden State를 계산하고 여러 계층을 거쳐, 인코더처럼 시퀀셜하게 예측 함.

인코더의 모든 정보를 담기힘든 문맥 벡터를 가지고 디코더를 이용하면,  번역품질이 안좋아지고, RNN 자체가 앞부분의 토큰경우 계속 미분하고 여러 계산을 하다보면 뒤로갈수록 그레디언트가 손실됨.

그래서 Context  vector를 어텐션 value를 이용하자는 아이디어가 도입 됨. 

 

1. Postioninal Encoding

Transformer의 가장 큰 특징 중 하나로, RNN, LSTM은 순차적으로 데이터를 입력 받지만, Transformer는 Sequence를 한번에 넣어 위치정보를 반영 해줄 수 있음. 이를 포지셔닝 인코딩이라고 함.

위 이미지가 시퀀스가 임베딩을거쳐 벡터로 전환되고  포지셔널 인코딩을 하는 과정인데,

이 벡터를 포지셔널 인코딩시, 모델이 단어의 순서를 인식할 수 있게하기 위해 시퀀스의 요소(토큰)에 대한 위치 정보를 추가해줌.

 

참고로 토큰의 조건은 다음과 같음.

1. 토큰의 위치마다 유일한 값을 지녀야함.

2. 토큰간의 차이가 일정한 의미를 지녀야함. (멀수록 큰 값)

3. 더 긴 길이의 문장이 입력되어도 일반화가 가능해야함.

본 논문에서는 다음과 같은 식으로 포지셔닝 인코딩을 수행하게되는데,

https://github.com/jalammar/jalammar.github.io/blob/cc5655f086ad75ad79adbd33f729dfa1746d6ed1/_posts/2018-06-27-illustrated-transformer.md#L4

 

토큰 10개의 토큰에대해서 X축은 임베딩차원인 벡터리의 길이, 즉, 64인  Embedding Dimension 이 있음.

이 Embedding Dimension을 위 수식의 sin cos라는 주기성을 갖는 함수에 넣으면, pos는 토큰이되고, d model이 총 벡터의길이,그리고 i가 각 위치가 됨. 그렇게되면 주기적인 형태가 나옴. 

 

 

조금 더 직관적으로보면,  위 그림으로 X를 토큰이라고 보고 거리간의차이를 보여주는데 자기자신은 0이고 더 먼토큰으로 갈수록 늘어남.

 

...we hypothesized it would allow the model to easily learn to attend by relative positions, since for any fixed offset k,

PEpos+k can be represented as a linear function of PEpos.

논문에서 인용한 내용인데, offset k에 대해 포지션+k , 포지션으로부터 k번째 토큰이 어떤 선형변환으로 표현될 수 있다라는 뜻인데,
Offset k 위치의 차이를 나타냄 예를 들어, 어떤 단어가 문장에서 5번째 위치에 있고, 다른 단어가 8번째 위치에 있다면, 이 두 단어 사이의 'offset'은 3임.

포지션+k는 위치 인코딩 이고 k만큼 떨어진 인코딩 값이라고보면 됨.

즉, pos가 5이고 k가 3이라면, PE_pos는 5번째 위치의 인코딩 값이고, PE_pos+k는 8번째 위치의 인코딩 값이 되며, 주기성을 갖기 때문에 선형관계에 있다고 보면 됨.

 

또, 삼각함수특성을 보면 B를 k라고 생각해보면 어떤 linear 함수로 표현될 수있음.

sin(A+B) = sin(A)cos(B) + sin(B)cos(A)cos(A+B) = cos(A)cos(B) + sin(B)sin(A)

 

 

1. multi-head attention

위와 같은 과정을 거치고 포지셔닝 임베딩을 거친 행렬이 배치된 멀티헤드 어텐션을 만나는데,

이 멀티헤드 어텐션이란 하나의 정보를 다른정보와 비교하기에 너무 많고 복잡하니까 헤드라는 그룹을 지어서 나누어 계산하고 다시 합친다는 말임. 

이전의 결과물인 행렬 X와, 쿼리, 키, 벨류라는 추정해야할 가중행렬 W를 곱해주어야 함.

처리해주게 되면 쿼리, 키, 벨류라는 행렬로 나옴

 

먼저 쿼리, 키, 벨류의 기본원리는 다음과 같음.  

 

쿼리가 동그란 도형이라고했을 때,  이러한 도형들의 모형들을 key라고 할 수 있고, 그 실제 수치들을 value라고 볼 수 있음.

쿼리를 날렸을때, 가장 유사한 key2가져오게 되며, 각각 가지는 유사도를 가중치로 사용하게 됨. 추가로 이 가중치 값들을 곱해서 가져오게되면  결국 쿼리와 가장 관련이 깊은 key의 value 위주로 모든값을 가져오는데 이것을 Attention이라고 함. 

 

헤드 어텐션에서 "머리(head)"는 실제로 선형 변환(linear transformation)을 수행하는 부분인데, 위 Linear는 서로 다른 가중치 행렬을 적용해주기 위해 쿼리(Q), 키(K), 밸류(V)를  복제를 해줌.

예를 들어, 멀티헤드 어텐션이 3개의 머리(head)를 가지고 있다고 가정하면, 다음과 같은 행렬들이 사용 됨:

  • 각 머리마다 별도의 '쿼리(Query)' 가중치 행렬 , '키(Key)' 가중치 행렬 , '값(Value)' 가중치 행렬 이 필요함.
  • 이 경우, 각각의 머리마다 3개의 가중치 행렬이 필요하므로, 총 9개의 가중치 행렬이 사용됨. (3개의 머리 × 3개의 가중치 행렬).

 

transformer git encoder Layer

방금 설명을 코드로 보면, 인코더레이어에 포워드 함수내에서, enc_slf_attention을 보면   enc_input이 멀티헤드 어텐션에 3번 전달되는데,  동일한 입력으로 enc_input가 각각 Q,K,V 벡터를 생성하여 복제되는 것처럼 볼 수 있음.

실제 내부에서는 각각의 벡터가 다른용도로 다른 가중치 행렬이 적용되면서 다른벡터로 변환됨.

 

 

scaled dot-product attention 

MatMul 1

 

그 후 벡터는 scaled dot-product attention 의 Matrix Multiplication에서 각 복제된 메트릭스에대해 Q,K 가중치 메트릭스를 곱해줌. 이 곱셈의 결과는 각 토큰이 다른 토큰들과 갖는 유사도 점수를 나타내는 행렬(Attention Weight)로 나타낼 수 있음.

 

Scale

Scale에서는 Attention Weight를  키의 차원수의 제곱근으로 나눠 스케일링하는 계산하는데, 높은 차원 공간에서의 내적 값이 매우 클 수 있기 때문에 결과가 안좋아질 수 있기 때문 임.

 

Softmax

 

이후 Softmax에 Scale된 내적값을 보내게되면 토큰들이 다른토큰들에대해서 어텐션 가중치를 구할 수 있게됨.

 

 

 

 

 

MatMul2 (Matrix Multiplication2)

 

벨류에 내적을 하게해주면 같은 차원 어텐션 행렬이나오고 최종으로 여러 어텐션 헤드에서 계산된 가중치와 Value(V) 값들의 가중합의 출력이 형성됨. 

 

Mask (opt.)

 

 

Softmax전에 Mask를 볼 수 있는데, 문장이 임베딩 벡터로 표현될 때, 차원이 안맞는 경우 Padding 을 해주게되는데 자리만 차지하고 의미없는 토큰이기 때문에, 처리를해줘야 함.

예를 들어 Attention 가중치를 구할 때, 유일한에서 구할 때 Padding에 대해서는 구하면안됨. --> 0값으로 만들어줌.

아래는 0을 큰 음수 값으로 만들어주어 그다음 softmax를 처리할때 0으로 수렴시킬 수 있음.

 

 

 

3. Position-wise Feed-Forward Networks

FFN은 멀티헤드 어텐션 레이어 후 배치되며, 위의 형태를 가짐. 간단하게 말하면, 앞서 구했던 값들과 가중치W1를 곱하고

활성화 함수의 출력을 돕는 상수 bias를 더함으로 써, 입력 토큰에 대한 처리를 강화하고, 모델의 전반적인 학습 능력을 향상시키기 위함임.

 

FFN(x) = max(0, xW1 + b1)W2 + b2

 

일반적으로 두개의 선형 변환(xW1,xW2)과 그 사이의 ReLU 활성화 함수로 구성됨.

 

이는, fullyconnected layer와 같음. X는 앞서 구했던 결과값,b는 bias이며, 

3. Add & norm

 

Add & Norm에서 add는 해당 레이어의 입력(다이어그램의 아래쪽에서 올라오는)을 멀티헤드 어텐션 또는 피드포워드 네트워크의 출력에 더하는 것이며

Layer Normalization 으로 각 벡터내의 값들 정규화 하여 안정화함

먼저, 각 벡터의 평균을 구하고, 그 벡터의 각 요소에서 이 평균을 뺌. 그 후, 벡터의 표준편차 로 나누어 정규화 함. 이 과정에서 나눗셈이 0이 되는 것을 방지하기 위해 작은 상수 (엡실론)을 추가하고 마지막으로, 학습 가능한 스케일 매개변수 (감마)와 이동 매개변수 (베타)를 적용함.

Layer Normalization에 대해 자세한 논문이있으니, 참고하길 바람.

여기까지가 인코더레이어의 단계임. 

4. Training Architecture 

Decoder attention (Masked)

디코더 레이어도 인코더 레이어와 비슷함.

 

 

 

 

 

차이점은 크게 두가지로 나뉠 수 있는데

첫번 째는,마스크 부분에 셀프 어텐션에서의 차이점을 보면 인코더는 소스 마스크 , 디코더는 타겟마스크를 가지는데, 이 차이점을 보면,

 

인코더에서의 마스크는 scaled dot-product attention 에서 언급한 패딩마스크를 진행하는데, 

인코더에서의 마스크는 scaled dot-product attention 에서 언급한 패딩마스크를 진행하는데,  디코더는 diagonal부분을 남기고 삼각행렬 윗부분을 모두 마스킹처리해주는것을 확인할 수 있음.

transformer특징이 학습에 사용하는 인풋에대해서 rnn처럼 sequntial하게 넣는게 아니라 하나의 행렬을 모두 넣기때문에, 인코더에서는 입력 시퀀스의 모든 토큰이 이미 알려져 있고, 각 토큰은 다른 모든 토큰과의 관계를 학습할 수 있어야하는 반면에서,  디코더에서는 토큰하나에 대해서 다른 토큰에대해서 어텐션을 볼수있기 때문에 마스킹 처리를 해줌.

이후는 인코더와 동일하게 Add Normalize까지 처리하게 됨.

 

두번 째로,  디코더는 멀티헤드 어텐션을 한번 더 수행하는 것을 볼 수 있음.

 

두번째 멀티헤드 어텐션의 인코더 포워드 부분을 보면 들어가는 값들이 셀프 어텐션의 인자와 다르게 들어가는 것을 볼 수 있는데, 쿼리는 둘다 디코더인 반면에 , 키와 벨류는 인코더에서의 출력결과인것을 확인할 수있음 . 

구조를 보면 왼쪽 열 인코더 셀프 어텐션에 두개의 화살표가 있는데, 인코더 레이어에서 결과 물을 얻고 2개를 copy하며 각각 키와 벨류로 들어가는 것을 볼 수 있음.

 

마스크 디코더에서 셀프어텐션을 통해서 결과를 쿼리로 생성하는 것을 볼 수 있음. 즉, 키와 벨류는 인코더에서 생성되었고, 쿼리는 디코더에서 생성된 것으로 볼 수 있음.

 

그렇게 되면 어떤 W가중치행렬을 거쳐서 나온 디코더에서 나온 쿼리와

인코더에서 행렬 키,벨류를 인코더-디코더에서

처리하고 softmax 계산하면 최종으로 attention 가중치를 구할 수있게 됨.

 

 

한눈에 보도록 펼쳐보면, 디코더에 인풋 시퀀스를 넣었을 때, 쿼리 키 벨류를 얻을 수 있고, 마스크 멀티헤드 셀프 어텐션과 동일하게 과정 거쳐 얻은 결과값들을 concatenate된 출력을 형성함. 이것이 인코더 디코더에 들어가는 쿼리 값이되는거고, 인코더 레이어에서 받은 key, value 결과물을 사용하게되는 것을 볼 수있고, 최종적으로 디코더 아웃풋을 얻게됨.

 

4. Last Layer 

인코더와 디코더를 모두 거친 후, 최종 결과물은 예측을 위해 사용됩니다. 이때 일반적으로 출력 시퀀스를 생성하기 위한 선형 레이어와 소프트맥스 레이어로 구성됩니다. 한국어를 영어로 번역한다고 할 때, 'Target words' length'는 모델이 예측해야 하는 타겟 언어의 집합의 크기를 말하며, 모든 가능한 타겟 단어들의 총수입니다. 모델이 입력을 받으면, 이Target words의 집합에에 있는 각 단어에 대한 확률 값을 예측하게 됩니다."

소프트맥스 레이어를 통과하면, 각 타임 스텝에서 각 단어가 다음 단어로 선택될 확률이 출력됩니다.

4. Result 

트랜스포머 빅모델 같은경우 블루스코어가 번역의 품질을 측정하는 지표가되는데, 그럼에도 불구하구  traningcost가 낮아진걸 확인 할 수 있음.

 

논문에서 다양한 하이퍼파라미터를 변경하는 실험이있는데, h (헤드가) 분열을 시킬때, dk가 줄어들게되는데 성능이 올라갔다가 32로 늘리면 떨어짐.

키값이 작아지면 각자 모델이  반영하는 의미 자체가 줄어들어서 그렇지 않을까 생각함.