Decoder의 남은 문제 - 출력 문맥도 여전히 누적된다
Attention은 Encoder의 정보 병목을 해결했다. 하지만 Decoder 자체는 여전히 이전 상태에 의존하는 순차 구조다. 이 문제가 왜 Transformer 등장의 마지막 동기가 되는지 살펴본다.
지난 편 복습
2편에서 Attention은 Encoder 쪽 문제를 해결했다. Decoder가 $h_1 \sim h_n$을 전부 보고, 현재 상태 $S_k$에 따라 동적으로 $c_k$를 계산한다. 마지막 상태 하나로의 병목은 사라졌다.
하지만 2편 마지막에 남겨둔 문제가 있었다.
\[S_k = f(S_{k-1},\; \text{emb}(y_{k-1}),\; c_k)\]$c_k$는 Attention으로 동적으로 계산되지만, $S_k$를 만들기 위해서는 여전히 $S_{k-1}$이 필요하다.
Decoder는 여전히 순차 구조다
Attention Seq2Seq에서 Decoder의 상태 전이는 이렇게 흐른다.
\[S_1 \rightarrow S_2 \rightarrow S_3 \rightarrow \cdots \rightarrow S_k\]$S_k$를 계산하려면 $S_{k-1}$이 있어야 하고, $S_{k-1}$을 계산하려면 $S_{k-2}$가 있어야 한다. 출력 시퀀스의 문맥은 이전 Decoder 상태를 통해 순서대로 누적 전달된다.
이것은 Vanilla Seq2Seq에서 Encoder가 가졌던 구조와 본질적으로 같다.
문제 1: 출력 쪽 장거리 의존성
“나는 어제 친구와 함께 오랫동안 걸어서 결국 도착했다”를 생성한다고 하자. “도착했다”를 생성할 시점에서 “나는”의 정보는 $S_1$에 있었다. 그 정보가 $S_k$까지 전달되려면 중간 상태들을 모두 거쳐야 한다.
\[S_1 \rightarrow S_2 \rightarrow \cdots \rightarrow S_k\]Encoder에서와 마찬가지로, 출력이 길어질수록 앞쪽 출력 토큰의 정보가 현재 상태에 희석될 수 있다. LSTM의 forget gate가 이를 어느 정도 완화하지만, 구조 자체가 순차적이라는 한계는 그대로다.
문제 2: 병렬화 불가
더 실질적인 문제는 병렬화다.
$S_k$는 $S_{k-1}$에 의존하고, $S_{k-1}$은 $S_{k-2}$에 의존한다. 즉 출력 시퀀스의 각 상태는 반드시 순서대로 계산되어야 한다. $S_3$과 $S_7$을 동시에 계산할 수 없다.
Encoder도 마찬가지다. $h_k$를 계산하려면 $h_{k-1}$이 먼저 있어야 한다. RNN 기반 구조는 시퀀스 길이만큼의 순차 계산을 피할 수 없다.
이 병렬화 불가 문제는 단순히 속도의 문제가 아니다. 긴 시퀀스를 다루는 모델을 대규모 데이터로 학습시키려면 병렬 연산이 필수적이다. GPU의 병렬 처리 능력을 제대로 활용하지 못한다.
Attention이 해결한 것과 남긴 것
정리하면 Attention Seq2Seq의 구조는 이렇다.
| Vanilla Seq2Seq | Attention Seq2Seq | |
|---|---|---|
| Encoder 정보 접근 | $h_T$ 하나 | $h_1 \sim h_n$ 직접 참조 |
| Encoder 순차성 | 있음 | 있음 |
| Decoder 순차성 | 있음 | 있음 |
| 병렬화 | 불가 | 불가 |
Attention은 정보 접근 방식을 바꿨지만, Encoder와 Decoder 모두의 순차 구조는 손대지 않았다.
핵심은 이것이다.
Attention Seq2Seq는 Encoder의 마지막 상태 의존을 줄였지만, Decoder는 여전히 이전 상태에 의존한다.
다음 편 예고
그렇다면 순차 구조 자체를 없애면 어떨까? RNN을 사용하지 않고, 각 토큰이 다른 모든 토큰을 직접 참조하게 만들면?
이것이 Transformer의 핵심 아이디어다. Attention을 Encoder와 Decoder 사이에만 적용하는 것이 아니라, 시퀀스 내부에 적용한다. 이를 Self-Attention이라고 부른다.