
Gaussian Splatting과 Stable Diffusion 등을 공부하면서 효율적인 연산 구조와 경량화된 설계에 대해 관심을 가지게 되었다. 하지만 경량화와 Efficient 관련해서는 노베이스이기에 (LoRA, BERT, U-NET 등에 대해 간단히는 알고 있지만) 최근 경량화 관련 최고의 방법론 중 하나인 Attention Is All You Need, Transformer 아키텍처에 대해 공부하였고, 이 논문 리뷰를 작성하고자 한다. 또한 다양한 분야에서 효율성을 극대화하는 딥러닝 모델 설계 방법론에 대해 더욱이 공부하고자 한다.
RNN은 LSTM과 함께 기존 자연어 처리 task에서 가장 많이 쓰이는 모델이였습니다.
자연어 처리에서 문장을 처리할때 문장에 사용된 단어의 위치는 굉장히 중요합니다. 기존의 자연어 처리 task에서 RNN, LSTM이 자주 활용되었던 이유는 이러한 모델이 단어의 위치와 순서정보를 잘 활용했기 때문입니다.
그러나 RNN은 순차적으로 첫번째로 입력된 단어부터 마지막으로 입력된 단어까지 인코딩하기 때문에 문장의 길이가 길어지면 학습 능력이 현저하게 떨어집니다. (일명 Long-Term Dependency Problem)
Transformer는 이러한 과정을 병렬적으로 처리하기 때문에 RNN보다 성능과 속도면에서 훨씬 뛰어납니다. 이때, RNN 설명때에 언급된 자연어 처리 task에서 단어의 위치정보는 굉장히 중요한데, RNN을 사용하지 않는 Transformer는 새로운 방법을 통해 단어의 위치정보를 활용합니다.
바로 Positional encoding입니다.
Positional Encoding은 Transformer의 굉장히 중요한 특징 중 하나입니다.

Positional encoding은 sin-cos 함수로 구성된 값을 Q, K, V에 각각 더해준 다음에 Transformer에 input하게 됩니다. Positional encoding을 해주는 이유는, Transformer가 단어의 연관성을 잘 파악할 수 있다는 장점이 있지만, RNN처럼 순차적으로 넣어주는 구조가 아니기 때문에, 단어에 대한 위치정보가 담길 수 없습니다. 따라서 각 단어의 위치정보를 알려주기 위해, 순서를 알려주기 위해서 positional encoding을 진행하는 것이다. Positional encoding에 대해서는 아래에서 더 자세히 다룰 예정입니다.
이제 Transformer 모델 구조에 대해 알아보기에 앞서 배경지식부터 알아가보자 합니다.
Attention 메커니즘이 나온 2015년 전까지만해도 기계번역에서 가장 많이 쓰이던 모델은 Seq2Seq 모델이였습니다.Seq2Seq은 LSTM을 활용해서 만든것인데, LSTM을 활용하면 다양한 시퀀스 정보를 모델링 할 수 있습니다.
다만, Seq2Seq는 고정된 크기의 context vector를 사용하고 있기 때문에 주어진 문장을 전부 고정된 크기의 한 벡터에 압축을 할 필요가 있고 이는 성능적인 한계에 부딪힌다는 단점이 있습니다. 더 자세한 설명을 위해 Seq2Seq 구조를 살펴보겠습니다.
Seq2Seq모델의 가장 큰 문제점은 context vector v에 소스 문장의 정보를 압축한다는 것입니다. 이때, 한번에 처리 가능한 데이터의 양보다 많은 양의 데이터가 들어오게 되면 처리 할 수 없는 상태가 되는데 이를 병목(bottleneck)현상이라고 부릅니다. 병목현상이 발생하게 되면 성능이 크게 하락하게 됩니다.

학습 과정은 다음과 같습니다.
하지만 앞서 말한 것처럼 입력문장이 매우 길 경우 문장의 모든 문맥 정보를 하나의 context vector에 넣어두기는 어려움이 있습니다.

이를 보안하기 위해 논문에서 제시한 방법은 Attention 메커니즘을 이용하는 것입니다.
Attention 메커니즘은 디코더부분에서 output을 만들때 인코더의 hidden state들을 전부 참고해서 만드는것입니다.

Attention은 단어를 embedding 해주는 개념이라고 생각하면 편합니다.
여기서 주의해야할 점은 단어를 개별적으로 input을 하는 것이 아니라, senetence 단위로 input을 한다는 것입니다.
그리고 Q(query), K(key), V(value)라는 값을 통해서, sentence를 구성하는 단어들 간의 연관성을 파악을 합니다.
Attention에 Query(Q), Key(K), Value(V)라는 Matrix가 들어가게 됩니다.
여기서
또한 Q, K, V 전부 단어에 대한 vector를 가지고 있는 matrix 입니다.

그리고 Q, K, V는 들어가기 전에 각자의 가중치를 곱해줍니다.
Q, K, V에 Positional encoding이 더해진 형태로 Transformer에 들어갑니다.
실질적으로 Q, K, V의 input matrix 값은 동일합니다. W를 통해서 서서히 변화를 한다고 보면 됩니다.
Q와 K를 행렬곱하고 스케일링 -> 마스크 -> 소프트맥스를 취해 어떤 단어와 가장 높은 연관성을 갖는지 비율을 구하고 그 확률값과 Value값을 곱해서 가중치가 적용된 결과적인 attension value(수치)를 구할 수 있습니다. 이 과정 (Q와 K를 행렬곱하고 스케일링 -> 마스크 -> 소프트맥스)애 대해 조금 더 자세히 알아보면,


softmax를 적용합니다.
softmax를 적용한 값은 행에 있는 단어가 열에 있는 단어와 얼마나 잘 매핑되었는지 알려줄 수 있는 지표로 활용합니다.
V matrix, 다시 말해 weights matrix를 곱해줍니다.
이 과정은 softmax로 부터 나온 matrix의 값이 서로 비슷하다면, V를 활용해서 특정 단어에게 가중치를 주어 softmax로 나온 단어간의 관계성 나타내줍니다.

위의 과정을 정리하면 위의 식으로 표현이 가능합니다.
Attention을 통해서 나온 단어들은 sentence안에서 자신을 잘 표현할 수 있는 word embedding 형태로 만들어져서 나오게 됩니다. 그리고 이 과정을 논문에서는 Multi-head Attention이라고 부르고 있습니다.
트랜스포머에는 총 세가지 종류의 어텐션이 있습니다.
1. Encoder Self-Attention
2. Masked Decoder Self-Attention
3. Encoder-Decoder Attention
그 전에 Encoder와 Decoder가 무엇인지 알아보고자 합니다.

Encoder는 작동 방식은 다음과 같습니다.
1. 단어의 embedding이 들어갔을 때, positional encoding을 적용해서 더해준다.
2. 더해준 형태의 Matrix를 Multi-Head-Attention에 적용한다.
3. Residual network의 형태로, 그 전의 값을 더해준 후 normalization을 적용한다.
4. Feed Forward network에 적용한 후 Add&Norm을 수행한다.
5. 위의 과정을 N번 수행해서 encoder에 대한 embedding을 만든다.

Decoder는 작동 방식은 다음과 같습니다.
1. Output으로 들어갈 word embedding을 넣어준 후 positional embedding을 수행한다.
2. Masked Decoder Self-Attention을 수행한다.
3. Add&Norm을 수행한다.
4. Encoder에서 나온 embedding을 V, K로 이용하고, 그 전 layer에서 얻은 decoder embedding을 Q로 Multi-Head-Attention에 넣는다.
5. Add&Norm을 수행한 후, Feed Forward network에 입력한 다음에 다시 Add&Norm을 수행한다.
6. 위의 과정을 총 N번 반복한다.
7. Linear와 softmax를 적용해서 각 단어들에 대한 확률값을 얻는다.
Transformer가 번역 task를 수행한다 했을 때, Decoder에서 나오는 값이 번역에 대한 결과입니다.
Encoder 파트에서 진행되는 Attention은 self-attention입니다. self-attention이란 입력 시퀀스 내에서 각 단어가 다른 단어와 얼마나 관련이 있는지를 계산합니다.
self attention은 Encoder와 Decoder 모두에서 사용됩니다.
이를 통해 매번 입력 문장에서 각 단어가 다른 어떤 단어와 연관성이 높은지 계산 할 수 있다.
I am a teacher의 경우 I, am, a, teacher가 각각 서로에게 attention score를 구해서 어떤 다른 단어와 높은 연관성을 갖는지 알 수 있게 됩니다.
또한 잔여학습과 같은 테크닉을 통해 성능을 향상시켜주는데, 잔여학습은 보통 ResNet과 같은 이미지 분류 네트워크에서 사용됩니다.
잔여학습에 대해 간단하게 설명하자면,
잔여학습이란 어떠한 값을 레이어를 거쳐서 반복적으로 단순 갱신하는 것이 아니라 특정 레이어를 건너뛰면서 입력 할 수 있도록 만드는 것입니다.

Encoder에서는 아래와 같이 어텐션과 정규화(Norm)과정을 반복하는 방식으로 여러개의 레이어를 중첩해서 사용할 수 있는데, 각 레이어는 서로 다른 파라미터를 갖음에도 입력되는 값과 출력되는 값의 dimension은 서로 동일하기 때문입니다.

그리고 이 그림의 오른쪽은 Decode인데, 그림과 같이 Encoder에서 가장 마지막 레이어에서 나온 출력값은 Decoder에 들어가게 됩니다.
이는 Decoder에서 매번 출력할때마다 소스 문장에서 어떤 단어에게 초점을 둬야하는지 알려주기 위함입니다. 따라서 각 레이어는 인코더의 마지막 레이어에서 나온 출력값을 입력으로 받게됩니다.
그리고 Decoder의 마지막 레이어에서 나온 값이 바로 실제로 우리가 번역을 수행한 결과(=출력 단어)입니다.
Decoder에서 attention을 수행할 때는 Encoder와 달리 주의해야할 요소가 있습니다. 바로 앞쪽 단어에서만 참고하는 것입니다. 왜냐하면 뒤쪽 단어를 참고하면 Cheating하게 되는 것이기 때문입니다. 그리고 이 과정은 마스크 행렬(mask matrix)를 이용해 특정 단어는 무시할 수 있도록 합니다.

마스크 값으로는 음수 무한의 값을 넣어 softmax 함수의 출력이 0에 가까워지도록 합니다.
앞서 말한 Query,Key,Value에 대해 추가로 언급하면, Query는 디코더에 있고, Key와 Value는 인코더에 있습니다.
디코더 레이어에서는 두 종류의 Attention method가 사용되는데 self attention(masked)과 Encoder-Decoder attention입니다.
self attention은 먼저 수행되는 attention으로 인코더파트와 마찬가지로 각각의 단어들이 서로가 서로에게 어떤 가중치를 갖는지 구하도록 만들어 출력 문장의 전반적인 표현을 학습할 수 있도록합니다.
반면,Encoder-Decoder attention은 디코더가 인코더에 대한 정보를 어텐션 할 수 있도록 합니다.다시 말해, 각각의 출력단어가 소스문장에서의 어떤 단어와 연관성이 있는지 구해줍니다.
디코더 레이어 역시 input dimension과 output dimension을 같게 만들어줘서 여러 레이어를 중첩해서 사용할 수 있도록 합니다.
이를 통해 알 수 있는 점은 기존의 RNN, LSTM을 사용할 때에는 입력 단어의 갯수만큼 레이어를 거쳐서 매번 hidden state를 만들었다면, Transformer에서는 입력 단어 자체가 쭉 연결되어서 한번에 입력되기 때문에 병렬적으로 출력값을 구할 수 있다는 것입니다.
초반부에서 Positional Encoding에 대해 간단히 다루었습니다. Positional encoding은 sin-cos 함수로 구성된 값이라고 하였는데, sin,cos 이용하는 이유에 대해 설명하고자 합니다.
그 이유는 바로 정수값(1,2,3, ...)으로 위치 정보를 표현하게 된다면 시퀀스 길이가 커졌을때 인덱스 역시 커지므로 훈련이 매우 불안정해질 수 있습니다. 그렇다면 만약 "[0,1] 구간의 비율로 나누면 되지않을까?"라는 궁금증이 들 수도 있습니다.
이렇게 비율을 사용하는 경우, '0.9'라는 값이 나오게 되었을 때, 시퀀스의 길이가 10이라면 9번째 원소를 의미하고, 100이라면 90번째 원소를 의미하게 되어 길이에 따라서 encoding의 의미가 달라지게 된다는 문제점이 있습니다.

따라서 sin,cos함수를 사용하는 것입니다. 그리고 각 단어의 상대적인 위치 정보를 네트워크에 입력합니다. 그렇게 되면 1. 각각의 고유한 토큰 위치값은 유일한 값을 가지고, 2. 학습 데이터중 가장 긴 문장보다도 긴 문장이 실제 데이터에서 들어와도 에러 없이 인코딩 값을 줄 수 있습니다. 또한 3. 함수에 따른 토큰 위치의 값을 예측 할 수 있게 됩니다.
논문에서는 Transformer를 WMT 2014 데이터셋을 사용한 영어-독일어 및 영어-프랑스어 번역 작업에 적용하여 다음과 같은 결과를 얻었습니다:

이는 기존 최고 성능 모델보다 더 높은 점수이며, 학습 시간 또한 크게 단축되었습니다.
Transformer를 논문과 여러 블로그, 영상으로만 봤을 때는 간단하다고 생각했는데, 이를 글로 정리하여 쓰다보니 몇 일이 걸리는 대장정이 될 정도로 새롭게 배운 내용이 많았다. 앞으로 Transformer 관련된 더 많은 주제들을 공부하여 내가 공부하고 있는 이미지 생성의 경량화에 대해서도 공부하고 싶다.