트랜스포머 모델에서 사용하는 Self Attention과 Multi-Head Attention의 개념을 이해하기 위해 우선 Seq2Seq with Attention 모델이 가진 문제점에 대해 이해해야한다.
Seq2Seq with Attention의 문제
연산의 순차성으로 인한 병렬 처리의 한계
Seq2Seq 모델은 RNN 계열의 Encoder-Decoder 구조를 기반으로 하며, RNN의 특성 상 입력 시퀀스를 순차적으로 처리해야한다.
이전 time step의 출력이 다음 time step의 입력으로 들어가기 때문에 병렬 처리가 어렵다는 문제가 있다.
그래서 긴 시퀀스를 처리할 때 학습 속도가 느려지고, 데이터셋의 규모가 커질 경우 학습 속도가 더욱 느려지게 된다.
장기 의존성 (Long-term Dependency) 문제
Seq2Seq 모델은 Encoder가 입력 시퀀스를 처리하고, 최종 은닉 상태를 Decoder로 전달해 출력을 생성한다. Attention Mechanism이 추가되며 Encoder의 모든 time step에 접근할 수 있게 되었으나, 여전히 긴 시퀀스에 대해서는 중요 정보가 손실될 가능성이 존재한다.
메모리 사용량 증가
Attention Mechanism이 추가되면서 Encoder의 모든 출력 상태를 Decoder에서 참조해야한다. 그래서 긴 시퀀스의 경우에는 메모리 사용량이 증가해 하드웨어의 요구 사항이 높아지고 큰 모델을 학습하는 데에 사용하기 어려워진다.
입력과 출력 시퀀스 길이의 불일치
Seq2Seq 모델은 일반적으로 입력과 출력 시퀀스 길이가 고정된 경우에 최적화되어 있지 않다. Attention이 추가 되며 입력과 출력 시퀀스 길이가 달라져도 대응할 수 있지만, 출력이 길어지면 전체적인 모델 성능이 저하될 수 있다. 특히, 원문보다 번역문이 더 길거나 짧은 경우 모델이 정확하게 번역하기 어려워진다.
위와 같은 문제점들을 해결하기 위해 Self-Attention과 병렬처리가 가능한 트랜스포머 모델이 제안되었다.
트랜스포머 모델은 순차적 처리를 요구하는 RNN 계열의 구조를 제거하고 Attention Mechanism만을 사용해 입력 데이터를 처리하는 아이디어를 가져간다.
Transformer 모델의 구조를 파헤쳐보자
https://arxiv.org/pdf/1706.03762v7
트랜스포머 모델 또한 Encoder-Decoder stack의 구조로 되어있다. (왼쪽이 Encoder, 오른쪽이 Decoder)
Encoder
모델 아키텍처를 보면 Encoder는 6개의 동일한 Layer로 구성되어 있으며 각 Layer는 2개의 sub-layer로 나뉜다.
첫 번째는 Multi-Head Self-Attention Mechanism으로, 문장 내의 모든 단어가 서로를 참조하며 어떤 단어가 중요한지 학습하는 메커니즘이다. Self Attention이기 때문에 각 단어는 문장 내 다른 단어들과 상호 작용하게 된다.
두 번째는 Position-wise Fully Connected Feed-Forward Network로, 각 단어에 대해 개별적으로 fully connected network를 적용해 더 복잡한 표현을 학습하게 된다.
잔차 연결 (Residual Connection)과 정규화 (Layer Normalization)
각 sub-layer의 출력에는 잔차 연결이 적용된다. 잔차 연결은 sub-layer의 입력을 그대로 더해주는 방식이다.
LayerNorm(x+Sublayer(x))
# x는 입력값, Sublayer(x)는 현재 sub-layer에서 계산된 결과
잔차 연결을 통해 기울기 소실 문제를 방지하고, 더 깊은 모델을 안정적으로 학습할 수 있게 된다.
어떻게 기울기 소실 문제를 방지한다는거지??
잔차 연결은 sub-layer의 입력값이 sub-layer의 출력에 그대로 더해지기 때문에 역전파 과정에서도 이 입력값에 대한 기울기가 보존된다.
만약 잔차 연결이 없다면 네트워크가 깊어질수록 각 layer를 통과할 때마다 기울기 값이 줄어들거나 소실될 수 있다.
잔차 연결 이후 정규화(Layer Normalization)을 적용해 각 layer의 출력값을 정규화해 학습을 안정적으로 만든다.
Decoder
Decoder도 Encoder와 동일하게 6개의 동일한 Layer로 구성된다는 점은 동일하나, 추가적인 sub-layer가 포함된다.
Multi-Head Self-Attention
Encoder와 동일하게 Self Attention Mechanism을 적용해 Decoder 내에서 각 단어가 자신과 이전 단어들을 참조하게 된다.
Encoder-Decoder Attention
이 부분이 Decoder에만 추가된 sub-layer이다. Encoder의 출력을 참조하면서, Decoder가 입력 문장에서 중요한 부분을 확인할 수 있게 돕는다.
Position-wise Fully Connected Feed-Forward Network
Encoder와 동일하게 각 단어의 벡터를 독립적으로 변환해 학습한다.
Decoder도 Encoder와 마찬가지로 잔차 연결과 정규화를 각 sub-layer에 적용한다
Masking을 통한 예측 제한
Decoder의 Self Attention에서는 미래의 단어를 보지 않도록 Masking을 적용한다.
Masking은 Decoder가 이전 단어들만 참조해 예측하도록 하며, 예측 중인 현재 단어 이후의 단어는 참조하지 못하도록 막는 역할을 한다.
Self Attention의 컨셉과 동작 과정
Attention Mechanism의 한 종류인 Self Attention, Self Attention을 구현하는 방식인 Scaled Dot-Product Attention에 대해 알아보도록 하자.
Self Attention
Self Attention은 자기 자신을 참조하는, 즉 시퀀스의 각 단어가 동일한 시퀀스 내의 다른 모든 단어와의 관계를 학습하는 메커니즘을 말한다.
이러한 구조적 장점 때문에 병렬 처리가 가능하고, 시퀀스 길이에 무관하게 global한 정보를 다룰 수 있다는 장점이 있다.
동작 과정
1. 각 입력 단어를 고정된 크기의 임베딩 벡터로 변환한다.
2. 쿼리(Query), 키(Key), 값(Value) 벡터를 생성한다.
X는 1에서 변환된 임베딩 벡터, Query는 단어가 어떤 정보를 찾고자 하는지, Key는 해당 정보의 특징, Value는 정보 자체를 의미한다.
3. Attention Score와 Attention Distribution을 계산한다. -> 이 과정을 Self Attention을 구현하는 구체적인 연산 방식, 즉 Scaled Dot-Product Attention이라고 한다!
각 단어에 대한 Attention Score를 계산하는 과정이다. dot product를 이용해 주어진 Query vector와 모든 Key vector 간의 유사도를 계산한다.
유사도 계산 후, 계산된 값을 Query와 Key vector의 차원 수의 제곱근으로 나누어 Scaling해 안정성을 높이고, Softmax를 통해 확률로 변환한다.
Scaling의 목적이 안정성이라고 했는데, Scaling을 하지 않으면 어떻게 되는데?
유사도 계산을 할 때 내적(Dot product)을 사용한다고 했다. 이 때, 벡터가 고차원일수록 내적 값이 매우 커지게 된다.
(이 부분은 내적의 계산 방식을 생각해보면 이해하기 쉽다.)
결과적으로 큰 내적 값이 softmax 함수에 입력되면 Softmax 출력이 매우 작은 값으로 수렴하거나, 하나의 값이 지나치게 크고 나머지 값은 거의 0에 가까워지게 되어 기울기 소실 문제를 야기할 수 있다.
Softmax 함수는 입력 값이 클수록 출력값이 급격하게 변하는 특징을 가지고 있다.
(아래의 Softmax 함수 식을 보면 이해하기 쉽다. z_j가 Softmax 함수의 입력값이니까 입력값이 커질수록 출력값 p_j의 변화가 커지게 되는 것이다!)
이러한 특징 때문에 큰 값이 입력되면 모델이 특정 위치에만 과도하게 집중하게 되어 다른 중요한 정보가 무시 될 수 있다.
결론적으로 스케일링을 하지 않으면 dot product의 크기가 벡터차원 dk에 비례해 커지게 되므로, dot product를 차원 수의 제곱근으로 나누어 적절한 범위로 줄여줄 수 있게 된다.
4. 최종 Attention Value 계산하기
Softmax를 통해 구한 Attention 가중치를 Value V에 곱해 최종적인 Self-Attention 출력을 구한다. 이로써 모델은 특정 단어에 대해, 다른 단어들과의 중요도를 반영해 최종 벡터를 생성한다.
a는 attention value, alpha는 attention distribution
이와 같이 Self Attention에서는 각 단어가 다른 단어들과의 관계를 이해할 수 있게 해, 단어 간의 문맥 정보를 반영할 수 있다. 각 단어가 모든 다른 단어와의 상관 관계를 고려하기 때문에, 긴 시퀀스에 대해서도 장기 의존성을 유지할 수 있다.
Multi-Head Attention의 컨셉과 동작 과정
Multi-Head Attention은 Self Attention을 여러 번 병렬로 수행해 다양한 시각에서 문맥을 학습할 수 있도록 확장한 메커니즘이다. 단일 Self Attention만 사용할 때 발생할 수 있는 정보 부족 문제를 해결하고 모델의 표현력을 높일 수 있다.
단일 어텐션 헤드 (Single Attention Head)만 사용할 경우 상호작용을 하나의 고정된 차원 공간에서만 계산한다.
즉, 단일 Self Attention은 한 가지 시각에서 단일한 표현만을 학습하기 때문에 정보의 다양한 측면을 충분히 반영하지 못할 수 있다.
동작 과정
1. Query, Key, Value 벡터를 여러 개의 Attention Head로 변환하기
입력 벡터를 각각 Query, Key, Value로 변환한 다음 여러 개의 Head로 분리해 각각의 Attention Head에서 독립적으로 Self Attention을 계산한다.
이 때, 각 Head는 서로 다른 가중치 행렬을 사용하기 때문에, 같은 입력에 대해 다양한 시각에서 정보를 처리할 수 있다.
2. 각 Attention Head에서 독립적으로 Self Attention 계산하기
분리된 각각의 Head에서 독립적으로 Self Attention을 수행해 자신의 Attention 가중치와 가중합을 계산한다.
3. 각 Attention Head의 출력 결합하고, 결합된 출력을 최종 처리하기
각 Head에서 계산된 Attention 결과는 병렬적으로 결합된다. 결합된 벡터는 FC Layer를 거쳐 최종적으로 차원이 맞춰지게 되고 최종 출력을 생성한다.
여기서 h는 Attention Head의 갯수, W^O는 결합된 벡터를 최종 차원으로 변환하는 가중치 행렬
각각의 Head에서 수행되는 연산을 살펴보면,
Single Self Attention에서 살펴봤던 식을 다시 복기해보면, Attention(Q, K, V)의 형태였음을 알 수 있다.
근데, Multi-Head Attention에서는 각각의 Head별로 서로 다른 가중치 행렬을 사용한다고 했으므로 위 수식과 같이 표현할 수 있다.
각 Head에서 적용되는 Scaled Dot-Product Attention을 나타낸 식이다.
각 Head에서는 독립적으로 Scaled Dot-Product Attention을 계산한 뒤 결과를 결합해 최종 출력으로 사용한다.
'Deep Learning' 카테고리의 다른 글
[NLP] BERT의 MLM 개념을 이용해 문법 교정을 해보자 (0) | 2024.10.31 |
---|---|
[NLP] BERT 모델의 사전 학습 방법인 MLM과 NSP를 알아보자 (1) | 2024.10.31 |
[NLP] Show, Attend and Tell: Hard Attention과 Soft Attention에 대해 알아보자 (1) | 2024.10.30 |
[NLP] 멀티 모달 (Multi-Modality)과 이미지 캡셔닝 (0) | 2024.10.29 |
[NLP] 어텐션 메커니즘 (Attention Mechanism)에 대해 알아보자 (0) | 2024.10.28 |