vllm.models.kimi_k3.nvidia.specialized_decode.drafter.attention
¶
Dense MLA decode of the DSpark draft block with the query tokens folded into heads.
A DSpark draft step runs k query tokens per request (anchor + k - 1 noise
tokens) through each dense MLA draft layer. The block is non-causal: every query
token of a request attends to exactly the same keys (the whole context plus the
block itself, already written to the cache). The stock FLASHINFER_MLA decode
has no non-causal flag, so it flattens the block into R * k independent
single-token rows, each with its own copy of the request's block table. Every row
then streams the request's whole latent cache again: k times the KV bytes, and
each CTA's MMA sees only the H local heads of one token (8 at TP8).
Absorbed MLA decode is MQA (one latent KV head), so query heads are independent
rows over a shared key set. Folding the k tokens of a request into the head
axis, [R * k, H, D] -> [R, 1, k * H, D], gives one decode row per request with
k * H heads over the same keys. That is the same attention, exactly: every
(token, head) pair still gets its own full softmax over the identical key set, at
the same precision (FP8 Q and KV, the stock bmm scales); only the kernel's tiling
(which CTA holds which head, the KV split) can differ. The KV is read once per
request instead of k times, and the MMA M grows k-fold (32-56 heads at TP8,
256-448 at TP1 / DCP).
The output [R, 1, k * H, L] and LSE [R, k * H] are the stock
[R * k, H, L] / [R * k, H] in the same memory order (token-major,
then head), so the DCP combine and the W_UV up-projection are unchanged.
Classes:
-
DraftDcp–The draft block's MLA decode under DCP (DCP = TP: rank d owns head block d)
Functions:
-
balanced_decode–The cute-dsl LSE decode of
common(folded_decode's FlashInfer -
balanced_tiers–The split tiers (rows each, longest first) of a cute-dsl LSE draft decode of
-
cake_supported–CAKE's Kimi K3 MLA kernel: SM100 family, FP8 query and cache, page 64,
-
cake_workspace_bytes–The largest CAKE split-KV workspace any folded draft batch of up to
-
causal_dcp_decode–CAUSAL_DCP_DECODE's decode of a causal draft block ofrowsrows. -
causal_folded_decode–Causal dense MLA decode of
Rrequests xkdraft tokens: token j of a -
dcp_causal_block_merge–Add this rank's share of a causal block's keys (global L + i, i < k; rank
-
dcp_causal_native_decode–Causal MLA decode of
Rrequests xkdraft tokens on this DCP rank, as -
draft_forward_mqa–FlashInferMLAImpl.forward_mqafor a DSpark draft block, folded. -
fold_plan–(query tokens folded into one decode row, FlashInfer MLA backend).
-
foldable–Query tokens per request when the decode batch can be folded, else 0.
-
folded_decode–Non-causal dense MLA decode of
Rrequests xkquery tokens. -
reserve_cake_workspace–Allocate the CAKE workspace for the deployment's largest draft batch now,
-
tier_workspace_bytes–The cute-dsl decode's split-KV workspace: FP32 partials + LSE per split
DraftDcp
¶
The draft block's MLA decode under DCP (DCP = TP: rank d owns head block d) on the specialized decode's DCP mailboxes, in three launches per layer instead of six (the direct-DCP epoch + query all-gather, the folded decode's split-KV + reducer, the LSE all-to-all push + combine) plus the W_UV bmm:
query every rank multicasts its FP8 query rows [T, H, 576] into head
block rank of every rank's DcpBox q mailbox [T, DCPH, 576]
(comm.Gather, in place) and polls until all landed
decode the stock folded draft decode (folded_decode: the k tokens of a
request folded into heads, every DCPH head over the local KV
shard, rank-local BF16 rows + LSE), reading the mailbox; a causal
block as CAUSAL_DCP_DECODE picks
value mla.dcp.DcpValue: re-arms the q mailbox, pushes each row to its
head owner, the owner merges its H heads over the DCP sources
(exp2(lse - max) / sum in FP32, one BF16 rounding, as the stock
combine) and applies W_UV (BF16 MMA, FP32 accumulation) into the
attention output. The draft layers have no output gate: the gate
operand is +inf (sigmoid exactly 1).
Same attention as the stock DCP decode at every stage: the decode kernel and its query are the stock ones; only the transport and the merge order differ.
Methods:
-
eligible–The draft layers this path serves: the stock folded draft decode
-
forward–attn(positions, hidden)(a draft layer's MultiHeadLatentAttention) on -
latent_major–W_UV [H, 512, 128] latent-contiguous, as DcpValue's MMA fragments load it
-
prepare–Each layer's latent-contiguous W_UV (1 MiB per draft layer), at load.
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 | |
eligible(attn, heads)
staticmethod
¶
The draft layers this path serves: the stock folded draft decode
(draft_fold on FlashInfer MLA, which takes the FP8 query this path
gathers), FP8 per-tensor KV, the q-LoRA path without output gate or fused
GEMM-RS-AR, H local heads of 576 / 512.
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
forward(attn, positions, hidden, parity)
¶
attn(positions, hidden) (a draft layer's MultiHeadLatentAttention) on
this path, or None when this batch takes the stock module.
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
latent_major(w_uv)
staticmethod
¶
W_UV [H, 512, 128] latent-contiguous, as DcpValue's MMA fragments load it (16 B along the latent); the module's is a transposed view.
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
prepare(attentions)
¶
Each layer's latent-contiguous W_UV (1 MiB per draft layer), at load.
_balanced_tables(cache, bt, sl, tot, split_rows, pairs)
¶
Which rows the split tiers take, cached per batch like _group_tables
(every draft layer of a step sees the same lengths): of the split_rows
longest (longest first), those longer than MOVE of a pair's share of the
batch's keys (sum / pairs). Returns (each tier row's batch row, or
rows when it stays in the unsplit launch; every row's length in the
unsplit launch, 0 for the moved ones; the tier rows' block table, lengths
(0 when not moved) and global lengths).
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
_causal_block_merge(q_ptr, kv_ptr, bt_ptr, ctx_ptr, o_ptr, lse_ptr, out_ptr, H, bt_stride, page_stride, scale1, scale2, K, PAGE, LORA, ROPE, GROUP)
¶
One draft token (row = request * K + j) x GROUP heads: start from the folded context output and its LSE (natural log), add the block keys [L, L + j] with an online softmax, write the merged output (BF16).
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
_compile_value(heads, size, batch, cap, w_uv, device, sms, q)
¶
mla.dcp.compile_value's BF16 DcpValue of batch rows (q per
request) for flashinfer's natural-log LSE (lse_scale log2(e)).
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
_counter_buffer(max_reqs, num_heads, device)
¶
trtllm-gen's multi-CTA-KV semaphores (it resets them after each launch, so they are zeroed once). Sized for the deployment's largest batch and kept apart from the stock decode's buffer, so neither ever reallocates the other's under a captured CUDA graph.
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
_group_tables(cache, block_table, seq_lens, tot, num_reqs, groups)
¶
Per decode-row tables when each request spans groups rows (cached per
batch: every draft layer of a step sees the same tables).
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
_plan_kernel()
cached
¶
One CTA: which rows the split tiers take (see _balanced_tables).
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
_row_copy(src, dst, target, bound, gather)
¶
See _row_copy_kernel; src / dst: [rows, ...] contiguous rows.
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
_row_copy_kernel()
cached
¶
dst[i] = src[i] row by row (int32 words), for the rows whose target
is below bound only: gathers (gather: dst row i <- src row target[i])
or scatters (dst row target[i] <- src row i). Cost: the moved rows.
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
_scales(impl, layer)
¶
The stock decode's bmm1 / bmm2 scales (FlashInferMLAImpl.forward_mqa).
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
_streams(device, count)
¶
count streams, the first the highest priority, each next one lower.
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
balanced_decode(common, table_cache, kv_lora_rank, tiers)
¶
The cute-dsl LSE decode of common (folded_decode's FlashInfer
arguments) as the split tiers of the longest rows and one unsplit launch
of the rest (see TIERS). Returns [rows, 1, heads, kv_lora_rank] BF16
and [rows, heads] FP32, as the one launch.
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 | |
balanced_tiers(device, rows)
¶
The split tiers (rows each, longest first) of a cute-dsl LSE draft decode of
rows decode rows; () runs the one launch. Balanced from the row count on
which the one launch runs unsplit (sms // (2 * rows) < 2: below it the
kernel splits every row already), keeping at least half the rows unsplit.
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
cake_supported(q, kv_cache, kv_lora_rank, rope)
¶
CAKE's Kimi K3 MLA kernel: SM100 family, FP8 query and cache, page 64, kv_lora_rank 512 / rope 64.
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
cake_workspace_bytes(max_reqs, k, heads, max_seq_len, sm_count)
¶
The largest CAKE split-KV workspace any folded draft batch of up to
max_reqs requests needs (CUDA graphs plan at max_seq_len).
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
causal_dcp_decode(world, rows)
¶
CAUSAL_DCP_DECODE's decode of a causal draft block of rows rows.
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
causal_folded_decode(q, kv_cache, block_table, seq_lens, max_seq_len, tokens_per_request, *, kv_lora_rank, qk_nope_head_dim, qk_rope_head_dim, bmm1_scale, bmm2_scale, max_reqs=0)
¶
Causal dense MLA decode of R requests x k draft tokens: token j of a
request attends its context keys [0, L) and the block keys [L, L + j], L =
seq_len - k. The context part, shared by the block's tokens, runs folded with its
LSE (one KV stream per request); the block part (at most k keys) and the LSE merge
run in one Triton program per (token, head group).
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 | |
dcp_causal_block_merge(q, kv_cache, block_table, ctx_tot, o, lse, k, world, rank, scale1, scale2)
¶
Add this rank's share of a causal block's keys (global L + i, i < k; rank
(L + i) % world holds it at local position (L + i) // world) to the folded
context partial (o, lse: natural log) of every gathered head; returns the
updated partial for DcpValue's combine.
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
dcp_causal_native_decode(query, kv_cache, block_table, seq_lens, tot_seq_lens, max_seq_len, tokens_per_request, world, rank, *, kv_lora_rank, qk_nope_head_dim, qk_rope_head_dim, bmm1_scale, bmm2_scale, workspace)
¶
Causal MLA decode of R requests x k draft tokens on this DCP rank, as
the stock uniform causal DCP decode: query [R * k, H, D] as [R, k, H,
D], this rank's local lengths (seq_lens) and the global ones
(tot_seq_lens, the block included); the kernel masks the block causally over
the interleave-1 shard. Returns [R * k, H, kv_lora_rank] and the natural-log
LSE [R * k, H].
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
draft_forward_mqa(impl, q, kv_cache, attn_metadata, layer)
¶
FlashInferMLAImpl.forward_mqa for a DSpark draft block, folded.
Returns None (the caller runs the stock forward_mqa) for a batch that
cannot be folded or a backend other than FLASHINFER_MLA.
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
fold_plan(k, heads, need_lse, cake_ok)
¶
(query tokens folded into one decode row, FlashInfer MLA backend).
Without an LSE (TP / DEP) all k tokens fold into one row per request and
run the Kimi K3 CAKE kernel, whose two-CTA wide route shares each 128-key tile
across 128 packed (token, head) rows (auto = trtllm-gen when CAKE cannot
run: it reads the tile once per 64-head group). With an LSE (DCP) the cute-dsl
kernel takes at most 128 heads per row: fold the largest divisor f of
k with f * heads <= 128 (k=4 at 64 heads: pairs, half the KV reads).
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
foldable(attn_metadata, num_rows, causal_ok=False)
¶
Query tokens per request when the decode batch can be folded, else 0.
Folding needs a non-causal decode batch in which every request has the same number of query tokens (a DSpark draft block always does).
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
folded_decode(q, kv_cache, block_table, seq_lens, max_seq_len, tokens_per_request, *, kv_lora_rank, qk_nope_head_dim, qk_rope_head_dim, bmm1_scale, bmm2_scale, workspace, return_lse=False, dcp_world_size=1, dcp_rank=0, dcp_tot_seq_lens=None, max_reqs=0, backend=None, table_cache=None)
¶
Non-causal dense MLA decode of R requests x k query tokens.
q: [R * k, H, kv_lora_rank + rope] (token-major per request);
kv_cache: [pages, page_size, kv_lora_rank + rope]; block_table /
seq_lens (/ dcp_tot_seq_lens): per request. Returns [R * k, H,
kv_lora_rank] and, with return_lse, [R * k, H]. backend forces
a FlashInfer backend (benchmarks); by default fold_plan picks.
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 | |
reserve_cake_workspace(device, max_reqs, k, heads, max_seq_len)
¶
Allocate the CAKE workspace for the deployment's largest draft batch now,
at model load (before the KV-cache memory profile and every graph capture,
which bind its address), at most CAKE_WORKSPACE_MAX_BYTES. Returns its
size. (GB300, 1M plan length: TP8 64 x k5 6 MiB; DEP 128 x k4 324 MiB,
128 x k5 589 MiB, 256 x k5 4.9 GiB -> capped, its largest batches fold on
trtllm-gen.) An eager batch planned at a shorter length can need more; the
call then takes the same trtllm-gen fold. Without FlashInfer's CAKE planner
(capability fallback) nothing is reserved and the default buffer is used.
Source code in vllm/models/kimi_k3/nvidia/specialized_decode/drafter/attention.py
tier_workspace_bytes(rows, splits, heads, lora)
¶
The cute-dsl decode's split-KV workspace: FP32 partials + LSE per split
(mla_decode.get_workspace_size).