튜토리얼 · 8
어텐션
어텐션은 가중 평균인데 그 가중치를 데이터에서 계산한다. 그게 전부이고, 읽을 수 있는
산수 세 줄이다. 이 튜토리얼은 그 세 줄을 적고, 그것을 위해 만들어진 과제로 학습시키고,
손으로 쓴 판을 이해한 다음에야 nn.MultiheadAttention 을 집고, 어텐션이
정말로 못 하는 일로 끝낸다.
1 · 세 줄, 학습 없음
토큰 여섯, 각각 벡터 하나. 모든 토큰을 모든 토큰과 견주고(Q·Kᵀ), 견준
값을 합이 1 인 가중치로 바꾸고(softmax), 그 가중치로 값을 평균한다.
"the" 둘은 벡터가 같으니 서로를 보게 되고, 아무것도 학습하기 전에 그 그림에 나온다.
0 행과 4 행은 같은 행이다. 같은 벡터는 모든 것과 똑같이 견주어진다. 그것이 어텐션에 토큰이 어디에 있는지에 대한 개념이 없다는 뜻이고, 4 번 블록이 그 이야기다.
2 · 어텐션이 있어야 하는 과제
자리 여덟. 각 자리에 무작위 값이 있고, 정확히 한 자리에 깃발이 있다. 답은 깃발이 선 자리의 값이다 — 입력 둘의 곱이므로 어떤 선형 모델도 닿지 못하고, 전부를 평균하는 망도 닿지 못한다. 학습되는 질의 벡터 하나면 된다. 그 벡터가 깃발을 보도록 배워야 한다.
3 · 같은 것, 포장된 판
nn.MultiheadAttention 은 그 산수에 사영을 넣고 머리 여럿을 나란히 돌리는
것이다. 마스크도 받는데, 쓸모 있는 마스크는 인과 마스크다 — 위쪽 삼각형을
-Infinity 로 채워 softmax 가 그 자리에 0 을 주게 만들고, 그것이 언어
모델이 앞을 못 읽게 하는 장치다.
건네는 모양을 보라. [길이, 배치, 임베딩] 이다. torch 의 기본이 그렇고 이
클래스도 그것을 따른다. batchFirst 는 규칙이 아니라 선택지다 —
[배치, 길이, 임베딩] 을 무조건 읽는 층이야말로 torch 에 없는 설정이다.
마스크는 믿기 쉽고 틀리기도 쉽다. 그래서 재 본다. 마지막 토큰을 바꾸고 첫 자리의 출력이 움직이는지 본다.
거의 0 이 아니라 정확히 0 이다. 가려진 자리는 아무것도 보태지 않는다.
-Infinity 의 softmax 는 작은 수가 아니라 0 이기 때문이다 — 가정하지 말고
확인할 값어치가 있다. 아주 작은 음수로 만든 마스크는 새고, 그 샘은 어떤 손실 곡선에도
안 보인다.
4 · 어텐션은 순서를 모른다
이제 답은 "2 번 자리의 값" 이다 — 찾을 깃발이 없다. 어텐션은 내용을 내용과 견주는데
토큰들이 서로 구별되지 않으니 닿을 수 없다. 고치는 방법은 자리를 토큰 안에 적어 넣는
것이고, 어떻게 적는지가 고쳐지는지 아닌지를 정한다. 경사
t/7 은 질의가 "뒤쪽" 이나 "앞쪽" 을 선호하게 할 뿐이고, 사인과 코사인은
자리를 원 위에 놓아 질의가 그중 하나를 가리킬 수 있게 한다.
nn.MultiheadAttention 에 nn.LayerNorm 과 두 층짜리
nn.Sequential 을 쌓으면 트랜스포머 블록이다.
튜토리얼 6 의 이름들을 넣어 같은 45 단어에서 RNN 과
견줘 보라.