32 independent transformer blocks › Attention
Causal mask
×supplied · no parametersmask
Identify which key positions each query can attend to.
- shape
- [T queries, T keys]
Built once per forward pass and passed to every block (model.py 284–299). With cached positions it is [T, start_pos + T], its first start_pos columns zero; with T = 1, one decoded token, there is no mask.
Codemodel.py 185–186, 284–300
mask = None
if seqlen > 1:
mask = torch.full((seqlen, seqlen), float("-inf"), device=tokens.device)
mask = torch.triu(mask, diagonal=1)
# When performing key-value caching, we compute the attention scores
# only for the new sequence. Thus, the matrix of scores is of size
# (seqlen, cache_len + seqlen), and the only masked entries are (i, j) for
# j > cache_len + i, since row i corresponds to token cache_len + i.
mask = torch.hstack(
[torch.zeros((seqlen, start_pos), device=tokens.device), mask]
).type_as(h)
for layer in self.layers:
h = layer(h, start_pos, freqs_cis, mask)
h = self.norm(h) if mask is not None:
scores = scores + mask # (bs, n_local_heads, seqlen, cache_len + seqlen) mask = None
if seqlen > 1:
mask = torch.full((seqlen, seqlen), float("-inf"), device=tokens.device)
mask = torch.triu(mask, diagonal=1)
# When performing key-value caching, we compute the attention scores
# only for the new sequence. Thus, the matrix of scores is of size
# (seqlen, cache_len + seqlen), and the only masked entries are (i, j) for
# j > cache_len + i, since row i corresponds to token cache_len + i.
mask = torch.hstack(
[torch.zeros((seqlen, start_pos), device=tokens.device), mask]
).type_as(h)Sources2
Contextual evidence
The mask is built once per forward pass and passed to every block.
model-mask · meta-llama/llama3 / llama/model.py
Pinned revision a0940f9cf706 ↗ · lines 284–300
Read code excerpt
mask = None
if seqlen > 1:
mask = torch.full((seqlen, seqlen), float("-inf"), device=tokens.device)
mask = torch.triu(mask, diagonal=1)
# When performing key-value caching, we compute the attention scores
# only for the new sequence. Thus, the matrix of scores is of size
# (seqlen, cache_len + seqlen), and the only masked entries are (i, j) for
# j > cache_len + i, since row i corresponds to token cache_len + i.
mask = torch.hstack(
[torch.zeros((seqlen, start_pos), device=tokens.device), mask]
).type_as(h)
for layer in self.layers:
h = layer(h, start_pos, freqs_cis, mask)
h = self.norm(h)Contextual evidence
The model constructs an upper-triangular negative-infinity mask; attention adds it to the scaled scores.
attn-mask · meta-llama/llama3 / llama/model.py
Pinned revision a0940f9cf706 ↗ · lines 185–296
Read code excerpt
if mask is not None:
scores = scores + mask # (bs, n_local_heads, seqlen, cache_len + seqlen)… lines 187–283 omitted …
mask = None
if seqlen > 1:
mask = torch.full((seqlen, seqlen), float("-inf"), device=tokens.device)
mask = torch.triu(mask, diagonal=1)
# When performing key-value caching, we compute the attention scores
# only for the new sequence. Thus, the matrix of scores is of size
# (seqlen, cache_len + seqlen), and the only masked entries are (i, j) for
# j > cache_len + i, since row i corresponds to token cache_len + i.
mask = torch.hstack(
[torch.zeros((seqlen, start_pos), device=tokens.device), mask]
).type_as(h)