vllm.models.minimax_m3.amd.mono.drafter.attention
¶
Attention of the DSpark drafter kernels.
Split-KV partitions with the q / k head norms and RoPE fused in, and merge tasks (a row, 4 heads) that quantize the output to MXFP8 for o_proj. The semantics are vLLM's draft attention: non-causal within a request's 7 rows, keys below seq_len, sliding window 4096, FP8 q.k / sqrt(128), P in e4m3, FP8 PV.
LDS tiles are 128 rows x 128 bytes (4096 words); 16-byte chunks are XOR-swizzled by row % 8 against bank conflicts:
- TQ: q rows m = 16 j + head (j < 7);
- TK0 / TK1: the K rows (keys) of a block;
- TV0 / TV1: V transposed, a row per dim with its 128 keys in the PV operand's order (byte 32 g + 4 i + e holds key 16 i + 4 g + e).
Block math, one wave a query row (its 16 heads), after AITER's gfx950 scheme: S^T = K Q^T puts keys 16 i + 4 g .. + 3 of a head in one lane, which is the PV operand at 4 keys a word, so P goes from the QK accumulator to O^T = V^T P^T in registers. exp2 folds log2(e) / sqrt(128) and vLLM's P x 256 (as +8 in the exponent): l and o carry the factor 256, which o / l cancels.
Functions:
-
block_acc–Fold one 128-key block into the running (m, l, o) of an online softmax.
-
block_math–One 128-key block for query row
j(this wave), headl16. -
kv_load–Block blk of request r (keys outside [lo, hi] zero), issued at the layer's start:
-
kv_store–The thread's K words -> tile
tk(row-major); its V words, transposed in -
perm–v_perm_b32: byte k of the result = byte sel[k] of (a << 32 | b).
-
q_operand–Wave
wave's Q^T operand (query rowwave, headl16). -
qkv_pre–The loads of
qkv_rowsthat do not depend on this layer's QKV. -
tw–Swizzled word index of word w of row r of tile t.
-
window–Request r: first / last query position, its window union's first / last key and
Attributes:
-
merge_task–Merge row
t, heads 4 hq .. 4 hq + 3 (a thread a head and dim). -
qkv_rows–Request r's q (7 rows x 16 heads: head norm, RoPE, FP8) -> TQ, and its new
-
store_partial–(m, l, o) of query rows 16 wave + l16 (< 112) -> the partial at
ap:
merge_task = traced(merge_task)
module-attribute
¶
Merge row t, heads 4 hq .. 4 hq + 3 (a thread a head and dim).
The request's partials 0..na-1 at ap0 are merged in order, rounded to bf16
and quantized to MXFP8 into a8 / as8. The partials' (m, l) of the 4 heads are
staged through LDS ml (512 floats). maxp: static bound of na.
qkv_rows = traced(qkv_rows)
module-attribute
¶
Request r's q (7 rows x 16 heads: head norm, RoPE, FP8) -> TQ, and its new
K / V rows -> the cache and, where they fall in the CTA's first blocks bA
(K0 / V0, nfirst >= 1) or bB (K1 / V1, nfirst >= 2), the tiles.
store_partial = traced(store_partial)
module-attribute
¶
(m, l, o) of query rows 16 wave + l16 (< 112) -> the partial at ap:
m[128] f32 at 0, l at 512 B, o[112][128] at 1 KB.
_lds8c(lds, t, r, w0)
¶
Words w0 .. w0 + 7 (two consecutive 16-byte chunks) of row r of tile t.
Source code in vllm/models/minimax_m3/amd/mono/drafter/attention.py
_lds8w(lds, t, r, w0)
¶
Words w0 .. w0 + 3 and w0 + 16 .. w0 + 19 of row r of tile t: an operand.
Source code in vllm/models/minimax_m3/amd/mono/drafter/attention.py
block_acc(lds, qb, tk, tv, blk, j, p0, lo, hi, l16, g4, m_run, l_run, o_run, mask)
¶
Fold one 128-key block into the running (m, l, o) of an online softmax.
m is in raw score units, l and o are scaled by 256 at m: m' = max(m, block max), l and o are rescaled by exp(m - m'), and P (x 256 at m', e4m3) V accumulates into o.
Source code in vllm/models/minimax_m3/amd/mono/drafter/attention.py
block_math(lds, qb, tk, tv, blk, j, p0, lo, hi, l16, g4, mask)
¶
One 128-key block for query row j (this wave), head l16.
Returns (m in score units, l, o: 32 f32 of dims 16 n + 4 g + e); l and o are
scaled by 256. mask (static): the block is at the window's edge.
Source code in vllm/models/minimax_m3/amd/mono/drafter/attention.py
kv_load(cache, block_table, bt_width, r, blk, lo, hi, tid)
¶
Block blk of request r (keys outside [lo, hi] zero), issued at the layer's start: this thread's K words (key tid / 4, bytes 32 (tid % 4) ..: 8 words) and V words (keys 4 (tid / 16) .. + 3, dims 8 (tid % 16) ..: 4 x 2 words).
Source code in vllm/models/minimax_m3/amd/mono/drafter/attention.py
kv_store(lds, tk, tv, kw, vw, tid)
¶
The thread's K words -> tile tk (row-major); its V words, transposed in
registers, -> tile tv.
Source code in vllm/models/minimax_m3/amd/mono/drafter/attention.py
perm(a, b, sel)
¶
v_perm_b32: byte k of the result = byte sel[k] of (a << 32 | b).
Source code in vllm/models/minimax_m3/amd/mono/drafter/attention.py
q_operand(lds, wave, l16, g4)
¶
qkv_pre(r, qn, kn, cos_sin, positions, slots, tid)
¶
The loads of qkv_rows that do not depend on this layer's QKV.
Source code in vllm/models/minimax_m3/amd/mono/drafter/attention.py
tw(t, r, w)
¶
window(r, positions, seq_lens)
¶
Request r: first / last query position, its window union's first / last key and blocks (keys < seq_len, from the first row's window start, <= MAXB blocks).