mstar.engine.resources.attn.wrappers#
FlashInfer utility wrappers for batched paged attention.
Provides: - FlashInferPrefillWrapper: batched prefill with paged KV cache, optional CUDA graph mode - FlashInferDecodeWrapper: batched decode with paged KV cache, optional CUDA graph mode
CUDA graph mode requires: - Static buffer pointers passed at construction (qo_indptr_buf, paged_kv_indptr_buf, etc.) - plan() updates values via .copy_() without reallocating - The same wrapper object must be used during both capture and replay
- Adapted from VoxServe’s flashinfer_utils.py for our KV cache layout:
[num_layers, max_pages, 2, page_size, num_kv_heads, head_dim]
(VoxServe uses [n_pages, 2, page_size, n_heads, head_dim] without layer dim.)
Functions
|
Raise unless FlashInfer's paged attention computes |
Classes
|
Batched decode attention with paged KV cache. |
|
A step mixing one-token rows (decode) with prompt rows, on two plans. |
|
Batched prefill attention with paged KV cache. |
- class mstar.engine.resources.attn.wrappers.FlashInferDecodeWrapper(workspace_buffer, num_qo_heads, num_kv_heads, head_dim, page_size, batch_size=None, max_num_pages=None, device=torch.device('cuda'), accelerator_graph=False, enable_nvtx=False, backend='auto')[source]#
Bases:
objectBatched decode attention with paged KV cache.
Optimized for the common decode case where each request appends exactly 1 new token. Uses BatchDecodeWithPagedKVCacheWrapper.
- Parameters:
workspace_buffer (Tensor) – FlashInfer workspace
num_qo_heads (int) – number of query/output heads
num_kv_heads (int) – number of key/value heads
head_dim (int) – dimension per head
page_size (int) – KV cache page size
batch_size (int | None) – required for CUDA graph mode (max requests in batch)
max_num_pages (int | None) – required for CUDA graph mode (max pages across all requests)
device (device) – torch device
accelerator_graph (bool) – if True, pre-allocate static buffers for graph capture
enable_nvtx (bool)
backend (str)
- plan(paged_kv_indptr, paged_kv_indices, paged_kv_last_page_len, dtype=torch.bfloat16, kv_lens=None, window_left=-1, **kwargs)[source]#
Plan decode attention and compute KV write locations.
For decode, each request appends exactly 1 token. The write location is the last page at position = last_page_len (before the append; after append it becomes last_page_len).
window_leftis as in the prefill wrapper’splan.Inputs may be on CPU; see prefill wrapper’s plan docstring.
- class mstar.engine.resources.attn.wrappers.FlashInferMixedWrapper(decode_workspace, prefill_workspace, num_qo_heads, num_kv_heads, head_dim, page_size, batch_size, max_total_tokens, max_num_pages, max_prefill_rows, device, backend='auto')[source]#
Bases:
objectA step mixing one-token rows (decode) with prompt rows, on two plans.
The packed prefill planner over every row costs per row about twice what the decode planner does, and its kernel runs the one-token rows as prefill queries. Here the decode wrapper takes every row of the bucket (a one-token row attends its own pages; any other row reads one token of the sink page, and its output is dropped), and the prefill wrapper takes at most
max_prefill_rowsprompt rows, their tokens moved to the front by a planned permutation. Both are captured at static shapes: the bucket’s rows and tokens, andmax_prefill_rowssequences.Every host array is staged in page-locked buffers this wrapper owns: a mixed step plans inline on the gpu thread, behind the step in flight.
- Parameters:
- class mstar.engine.resources.attn.wrappers.FlashInferPrefillWrapper(workspace_buffer, num_qo_heads, num_kv_heads, head_dim, page_size, batch_size=None, max_total_tokens=None, max_num_pages=None, device=torch.device('cuda'), accelerator_graph=False, enable_nvtx=False, backend='auto')[source]#
Bases:
objectBatched prefill attention with paged KV cache.
Wraps flashinfer.BatchPrefillWithPagedKVCacheWrapper with optional CUDA graph mode using static buffers. KV writes are the KVManager’s job.
- Parameters:
workspace_buffer (Tensor) – FlashInfer workspace (256MB+ recommended)
num_qo_heads (int) – number of query/output heads
num_kv_heads (int) – number of key/value heads
head_dim (int) – dimension per head
page_size (int) – KV cache page size
batch_size (int | None) – required for CUDA graph mode (max requests in batch)
max_total_tokens (int | None) – required for CUDA graph mode (max total new tokens across batch)
max_num_pages (int | None) – required for CUDA graph mode (max pages across all requests)
device (device) – torch device
accelerator_graph (bool) – if True, pre-allocate static buffers for graph capture
enable_nvtx (bool)
backend (str)
- plan(qo_indptr, paged_kv_indptr, paged_kv_indices, paged_kv_last_page_len, causal=True, dtype=torch.bfloat16, kv_lens=None, window_left=-1, **kwargs)[source]#
Plan attention and compute KV write indices.
window_leftis the number of preceding positions each query sees; -1 is unbounded.In CUDA graph mode, updates static buffers via .copy_() so that the same GPU addresses are used during graph replay.
Inputs may be on CPU — that’s preferred because FlashInfer’s
BatchPrefillWithPagedKVCacheWrapper.plandoesindptr.to("cpu")/last_page_len.to("cpu")internally; passing GPU tensors there triggers a synchronous default-stream sync that drains the speculatively-queued next decode step. We let the inner plan consume them as CPU and async-H2D copy to the device for our own per-token bookkeeping below.
- mstar.engine.resources.attn.wrappers.check_flashinfer_head_dim(head_dim, device=None)[source]#
Raise unless FlashInfer’s paged attention computes
head_dimexactly. Only CUDA runs FlashInfer, so a non-CUDAdevice(CPU tests driving the wrappers with a stand-in module and toy head dims) is not checked.