실습 · 연습문제 2개
causal mask와 padding mask 만들기 attention-masks
길이가 다른 시퀀스 개를 PAD로 채워 길이 인 batch를 만들었다. 시퀀스 의 실제 길이는 lengths[b]이고, 위치 lengths[b]부터 T-1까지는 PAD다. self-attention에 쓸 bool mask (B, T, T)를 만든다. mask[b, t, s]가 True이면 시퀀스 의 query 위치 가 key 위치 를 볼 수 있다.
함수 make_mask(lengths, T, causal)을 완성한다.
- padding mask: key 위치 가 PAD이면(
lengths[b]) 어떤 query도 볼 수 없다. - causal mask(
causal=True일 때만): query 위치 는 인 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 , key , value 에 대한 scaled dot-product attention은
이다. softmax는 마지막 축(key 축)을 따라 계산한다. 는 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이 된다.