refactor: unify attention mask to single attn_mask tensor

- CudaBackend.fwd_decode passes attn_mask directly instead of kv_cache.decode_mask
- TorchNativeBackend derives pos_mask from attn_mask[:,0,0] on decode
- Drop decode_mask and page_table fields from KVCache and bind_tasks
This commit is contained in:
2026-08-01 15:49:26 +08:00
parent 41dcf0feb9
commit 91acaf4b0b
2 changed files with 7 additions and 29 deletions
+6 -10
View File
@@ -274,12 +274,12 @@ class TorchNativeBackend(AttentionBackend):
kv_cache.v_buffer[layer_id, kv_cache.out_cache_loc] = v kv_cache.v_buffer[layer_id, kv_cache.out_cache_loc] = v
max_len = kv_cache.max_len max_len = kv_cache.max_len
if kv_cache.page_table is not None:
indices = kv_cache.page_table
else:
indices = kv_cache.req_to_token[kv_cache.req_pool_indices, :max_len] indices = kv_cache.req_to_token[kv_cache.req_pool_indices, :max_len]
if kv_cache.decode_mask is not None: # Zero out padding positions so gather never touches invalid slots.
pos_mask = kv_cache.decode_mask # Decode: attn_mask[:,0,0] is exactly the per-position validity
# mask ([B, max_len], True=keep). Prefill: fall back to seq_lens.
if q.size(1) == 1 and attn_mask is not None and attn_mask.dim() == 4:
pos_mask = attn_mask[:, 0, 0]
else: else:
pos_mask = ( pos_mask = (
torch.arange(max_len, device=q.device)[None, :] torch.arange(max_len, device=q.device)[None, :]
@@ -344,10 +344,6 @@ class CudaBackend(AttentionBackend):
kv_indptr = torch.zeros(b + 1, dtype=torch.int32, device=q.device) kv_indptr = torch.zeros(b + 1, dtype=torch.int32, device=q.device)
kv_indptr[1:] = kv_cache.seq_lens.cumsum(0).to(torch.int32) kv_indptr[1:] = kv_cache.seq_lens.cumsum(0).to(torch.int32)
mask = None
if b > 1 and kv_cache.decode_mask is not None:
mask = kv_cache.decode_mask
out = attn_paged_decode( out = attn_paged_decode(
q_3d, q_3d,
kv_cache.k_buffer[layer_id], kv_cache.k_buffer[layer_id],
@@ -356,7 +352,7 @@ class CudaBackend(AttentionBackend):
kv_cache.req_pool_indices, kv_cache.req_pool_indices,
kv_indptr, kv_indptr,
kv_cache.max_len, kv_cache.max_len,
mask=mask, mask=attn_mask,
is_causal=is_causal, is_causal=is_causal,
) )
return out.unsqueeze(1).flatten(2) return out.unsqueeze(1).flatten(2)
-18
View File
@@ -203,10 +203,6 @@ class KVCache:
seq_lens: [batch_size] — per-request total sequence lengths seq_lens: [batch_size] — per-request total sequence lengths
out_cache_loc: [batch, new_seq_len] or [batch, 1] — write indices out_cache_loc: [batch, new_seq_len] or [batch, 1] — write indices
max_len: max(seq_lens) as Python int — avoids GPU sync in decode max_len: max(seq_lens) as Python int — avoids GPU sync in decode
page_table: [batch, max_len] — precomputed gather indices for decode;
None for prefill or when not yet computed.
decode_mask: [batch, max_len] bool — precomputed position validity
mask for decode; None for prefill or single-batch decode.
""" """
k_buffer: Tensor k_buffer: Tensor
@@ -216,8 +212,6 @@ class KVCache:
seq_lens: Tensor seq_lens: Tensor
out_cache_loc: Tensor out_cache_loc: Tensor
max_len: int = 0 max_len: int = 0
page_table: Optional[Tensor] = None
decode_mask: Optional[Tensor] = None
class PagePool: class PagePool:
@@ -434,21 +428,11 @@ class PagePool:
out_cache_loc = self._req_pool.req_to_token[ out_cache_loc = self._req_pool.req_to_token[
req_pool_indices, start_pos:seq_len req_pool_indices, start_pos:seq_len
] ]
page_table = None
decode_mask = None
else: else:
write_pos = seq_lens_t - 1 write_pos = seq_lens_t - 1
out_cache_loc = self._req_pool.req_to_token[ out_cache_loc = self._req_pool.req_to_token[
req_pool_indices, write_pos req_pool_indices, write_pos
].unsqueeze(-1) ].unsqueeze(-1)
ml = max(seq_lens)
page_table = self._req_pool.req_to_token[req_pool_indices, :ml]
if len(task_ids) > 1:
decode_mask = (
torch.arange(ml, device=device)[None, :] < seq_lens_t[:, None]
)
else:
decode_mask = None
return KVCache( return KVCache(
k_buffer=self._storage.k_buffer, k_buffer=self._storage.k_buffer,
@@ -458,8 +442,6 @@ class PagePool:
seq_lens=seq_lens_t, seq_lens=seq_lens_t,
out_cache_loc=out_cache_loc, out_cache_loc=out_cache_loc,
max_len=max(seq_lens), max_len=max(seq_lens),
page_table=page_table,
decode_mask=decode_mask,
) )
# ---- internals ---- # ---- internals ----