borch

튜토리얼 · 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.MultiheadAttentionnn.LayerNorm 과 두 층짜리 nn.Sequential 을 쌓으면 트랜스포머 블록이다. 튜토리얼 6 의 이름들을 넣어 같은 45 단어에서 RNN 과 견줘 보라.