vllm.v1.attention.ops.triton_decode_attention
¶
Memory-efficient attention for decoding. It supports page size >= 1.
Functions:
-
decode_attention_fwd–sliding_windowlimits each row to its lastsliding_windowkeys. -
decode_attention_fwd_verify–Causal MLA verify over a per-request block table.
-
select_verify_config–Launch config from MI300X (gfx942) sweeps, bf16, page 16.
-
verify_num_kv_splits–Static upper bound on KV splits (safe to bake into a cudagraph).
-
warmup_decode_attention_fwd_verify–Compile every launch variant serving can reach for these tensors.
_storage_view(t, shape)
¶
Contiguous shape over t's storage, or a new tensor if too small.
Source code in vllm/v1/attention/ops/triton_decode_attention.py
decode_attention_fwd(q, k_buffer, v_buffer, o, lse, req_to_token, b_seq_len, attn_logits, num_kv_splits, sm_scale, page_size=1, logit_cap=0.0, k_scale=None, v_scale=None, is_mla=False, sliding_window=None)
¶
sliding_window limits each row to its last sliding_window keys.
Source code in vllm/v1/attention/ops/triton_decode_attention.py
decode_attention_fwd_verify(q, k_buffer, v_buffer, o, lse, req_to_token, seq_lens, real_seq_lens, qlen, attn_logits, num_kv_splits, sm_scale, page_size, k_scale=None)
¶
Causal MLA verify over a per-request block table.
Parameters:
-
(q¶Tensor) –[B * qlen, H, Lk] queries, verify tokens of a request contiguous.
-
(k_buffer¶Tensor) –paged latent cache, [num_pages, page_size, 1, Lk] (or 3D [num_pages * page_size, 1, Lk]).
-
(v_buffer¶Tensor) –k_buffer[..., :Lv] (V is read from K; only its width is used).
-
(o¶Tensor) –[B * qlen, H, Lv] output.
-
(lse¶Tensor) –[B * qlen, H] fp32 natural-log LSE (-inf for rows with no key).
-
(req_to_token¶Tensor) –[B, max_pages] per-request block table (not repeated).
-
(seq_lens¶Tensor) –[B] int32 kernel KV lengths L.
-
(real_seq_lens¶Tensor | None) –[B] int32 or None; row limit is max(min(L - qlen + 1 + t, L_real), 0).
-
(qlen¶int) –verify tokens per request.
-
(attn_logits¶Tensor | None) –fp32 workspace with >= B * qlen * H * num_kv_splits * (Lv + 1) elements, laid out [B * qlen, H, num_kv_splits, Lv + 1]. Unused, and may be None, when num_kv_splits is 1.
-
(num_kv_splits¶int) –static cap on KV splits per request (see verify_num_kv_splits); shorter requests use fewer, longer splits.
-
(sm_scale¶float) –softmax scale.
-
(page_size¶int) –tokens per KV cache page.
-
(k_scale¶Tensor | None, default:None) –scalar tensor dequantizing an FP8 cache; ignored for bf16.
Source code in vllm/v1/attention/ops/triton_decode_attention.py
1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 | |
select_verify_config(batch, qlen, num_heads)
¶
Launch config from MI300X (gfx942) sweeps, bf16, page 16.
Few rows (B * qlen * H <= 640): 32-row tiles with more KV splits fill the GPU. Otherwise 64-row tiles (Q split in two 256-wide halves, next K/V tile prefetched) halve the KV re-reads per request.
Source code in vllm/v1/attention/ops/triton_decode_attention.py
verify_num_kv_splits(max_seq_len, batch, qlen, num_heads, sm_count, max_splits=8)
¶
Static upper bound on KV splits (safe to bake into a cudagraph).
The kernel splits each request's own length into
max(cdiv(L, splits), MIN_SPLIT_LEN) chunks, so this only caps the split
count. The config's occupancy is the number of resident stage-1
programs per CU. If one split of every request fits in a single dispatch
round, use as many splits as fit in that round; otherwise pick
n <= max_splits minimising rounds(n) / n (the idle tail of the last round),
preferring fewer splits within 5% of the best.
Source code in vllm/v1/attention/ops/triton_decode_attention.py
warmup_decode_attention_fwd_verify(q, k_buffer, o, lse, req_to_token, has_real, qlens, attn_logits, sm_scale, page_size, k_scale=None)
¶
Compile every launch variant serving can reach for these tensors.
A launch specializes on qlen, the row-count config and a single split, but graph capture and profiling only run the full verify length. Each variant runs once on scratch tensors with the strides of the real ones; the split scratch reuses attn_logits' storage, whose size the launch specializes on.