18.4 Attention과 Transformer

실습 · 연습문제 2개

causal mask와 padding mask 만들기 attention-masks

길이가 다른 시퀀스 BB개를 PAD로 채워 길이 TT인 batch를 만들었다. 시퀀스 bb의 실제 길이는 lengths[b]이고, 위치 lengths[b]부터 T-1까지는 PAD다. self-attention에 쓸 bool mask (B, T, T)를 만든다. mask[b, t, s]가 True이면 시퀀스 bb의 query 위치 tt가 key 위치 ss를 볼 수 있다.

함수 make_mask(lengths, T, causal)을 완성한다.

  • padding mask: key 위치 ss가 PAD이면(s≥s \ge lengths[b]) 어떤 query도 볼 수 없다.
  • causal mask(causal=True일 때만): query 위치 tt는 s≤ts \le t인 key만 볼 수 있다.
  • 두 조건을 모두 만족하는 칸만 True다.

PAD 위치의 query 행은 이 문제에서 따로 가리지 않는다(key 쪽 조건만 적용). 그 행의 출력은 손실에서 빼면 된다. 다만 그 행이 모두 False가 되면 softmax에서 nan이 나오므로, 테스트는 어떤 행도 모두 False가 아닌지 확인한다(실제 길이가 1 이상이면 위 규칙으로 자동으로 만족된다).

테스트는 다음을 확인한다.

  • shape이 (B, T, T)이고 dtype이 bool이다.
  • causal=False이면 PAD key 열만 False다.
  • causal=True이면 실제 길이 안에서 아래삼각(대각 포함)만 True다.
  • 이 mask로 attention을 계산하면, PAD 칸의 값을 바꿔도 실제 토큰의 출력이 변하지 않고, causal인 경우 미래 토큰을 바꿔도 과거 출력이 변하지 않는다.

힌트: np.arange(T)와 broadcasting으로 (B, 1, T) 모양의 key 조건과 (1, T, T) 모양의 causal 조건을 만들어 &로 합친다.

scaled dot-product attention 구현하기 scaled-dot-product-attention

query Q\mathbf{Q}, key K\mathbf{K}, value V\mathbf{V}에 대한 scaled dot-product attention은

Attention⁡(Q,K,V)=softmax⁡ ⁣(QK⊤D)V\operatorname{Attention}(\mathbf{Q}, \mathbf{K}, \mathbf{V}) = \operatorname{softmax}\!\left(\frac{\mathbf{Q}\mathbf{K}^\top}{\sqrt{D}}\right)\mathbf{V}

이다. softmax는 마지막 축(key 축)을 따라 계산한다. DD는 query·key의 마지막 축 크기다.

함수 attention(Q, K, V, mask=None)을 완성해 (output, weights)를 반환한다.

인자·반환 shape 의미
Q (..., T, D) query. 앞쪽 ...은 batch·head 같은 임의의 축
K (..., S, D) key
V (..., S, Dv) value
mask (T, S) 또는 (..., T, S), bool True인 칸만 볼 수 있다. None이면 모두 본다
output (..., T, Dv) 가중합
weights (..., T, S) softmax 가중치. 행마다 합 1, 가려진 칸은 정확히 0

테스트는 다음을 확인한다.

  • 반복문으로 정의를 그대로 계산한 값과 같다(batch·head 축이 있는 경우 포함).
  • 가중치의 행 합이 1이고, mask가 False인 칸의 가중치가 정확히 0이다.
  • 점수가 매우 커도(예: query·key 성분이 수백) nan이나 inf 없이 계산된다.

힌트: np.swapaxes(K, -1, -2)로 마지막 두 축만 바꾸면 앞쪽 축은 그대로 batch 축이 된다. softmax는 행마다 최댓값을 뺀 뒤 지수를 취한다. 가릴 칸은 점수를 -np.inf로 바꾸면 지수가 정확히 0이 된다.