[None][perf] Kimi K3: overlap KDA/MLA attention decode onto the aux stream - #17103
Draft
hyukn wants to merge 1 commit into
Draft
[None][perf] Kimi K3: overlap KDA/MLA attention decode onto the aux stream#17103hyukn wants to merge 1 commit into
hyukn wants to merge 1 commit into
Conversation
…tream Route the model's existing side CUDA stream into KimiKDARuntime and KimiK3MLAAttention and fork three data-independent decode op pairs via maybe_execute_in_parallel. Before this change the attention layers ran 100% single-stream: 69 KDA segments/step held 4.667 ms of device-busy time with zero two-stream residency, and 24 MLA segments held 2.161 ms, likewise zero. The single side stream created for the layer loop was passed only to the MoE runtime, so the identical sm100_fp8_fp4_gemm_1d1d_impl kernel was 97% hidden inside MoE but 94% exposed inside KDA. The forks live inside forward() so the captured cuda graph records them, matching how MoE already does it. Pure scheduling: no dtype, precision, kv-cache or backend change. Measured on 16x GB300 TEP16, ISL 8192 / OSL 1024, c=1 median TPOT: 13.2106 ms -> 12.6789 ms (-4.025%, job 2720932, rack nvl72d127). Reproduced across both a rack change and a rebuild: -3.720% (job 2720192, rack d157, build 2719879) and -4.025% (job 2720932, rack d127, build 2720688). The two agree to 0.316%, against a measured c=1 noise band of 2.63%. A third observation and the full concurrency curve were taken afterwards on the same recipe (job 2721639), confirming the gain holds across the sweep and regresses nothing: c=1 13.5070 -> 12.6934 ms (-6.02%, band 2.63%) c=2 15.9358 -> 16.1229 ms (+1.17%, band 5.08% -- within noise) c=4 17.5480 -> 16.8362 ms (-4.06%, band 4.01%) c=8 22.7114 -> 21.7538 ms (-4.22%, band 3.63%) c=8 is the only genuinely independent corroborator: stream_interval=10 makes median ITL exactly 10x TPOT, so ITL, tps/user and output_throughput at c=1 are all restatements of the metric. Per-point noise bands are from three zero-change runs on the unmodified build. Post-change nsys on the same recipe confirms the forks execute on device: KDA two-stream residency 0.0000 -> 0.7016 ms/step (16.1% of its busy time), MLA 0.0000 -> 0.2829 ms/step (14.3%), with the aux stream appearing in both families' stream sets. Numerical parity: the KDA and MLA Q/KV forks were checked bitwise-identical against their serial equivalents under real cuda-graph capture on GB300. The third fork (absorb-bmm || mla_rope_generation) is argued disjoint from source -- mlaKernels.cu writes qkv_output[dst_q_idx] write-only, and both head_dim_idx and c_k=512 are multiples of ELTS_PER_VEC=8, so no vector store can straddle the bmm's slice -- but it does not yet have its own numerical probe, and no model-level greedy-token comparison has been run. Both are outstanding before this should be considered merge-ready. Candidates c-017 + c-018, campaign pa-tep-20260729. Signed-off-by: yukunh <23156053+hyukn@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
@coderabbitai summary
Description
The Kimi K3 attention layers ran 100% single-stream.
KimiK3DecoderLayeralready creates one side CUDA stream per model, but it was passed only toKimiK3MoERuntime— so the identicalsm100_fp8_fp4_gemm_1d1d_implkernel was 97% hidden inside MoE and 94% exposed inside KDA.Measured on the pre-change build (16x GB300 TEP16, ISL 8192 / OSL 1024, c=1):
This routes that existing stream into
KimiKDARuntimeandKimiK3MLAAttentionand forks three data-independent decode op pairs viamaybe_execute_in_parallel. Pure scheduling — no dtype, precision, kv-cache or backend change. Python only, no rebuild.Changes
Three forks, each on a pair that reads disjoint inputs and writes disjoint outputs:
modeling_kimi_linear.py,_forward_decode). The in-projection GEMV chain reads onlyx2d; the conv-window gather/repack plus recurrent-state gather read only the cache pools andslot_indices. Both feed the KDA decode kernel, so the staging can hide behind the GEMV instead of following it.kimi_k3_mla_attention.py,_forward_decode_fused).q_a_proj → q_a_layernorm → q_b_projandkv_a_proj_with_mqa → kv_a_layernorm → catboth read onlyhidden_states. DeepSeek MLA fusesq_a/kv_ainto one GEMM and can therefore overlap only the two layernorms; K3 keeps them separate, so the whole chains overlap.mla_rope_generation. The bmm writes onlyfused_q[..., :kv_lora_rank]; the rope kernel writes only the rope tail, the paged cache and the scheduler buffers. Gated off under an FP8 KV cache — the extra CTAs the grid gains forcache_type == FP8read the latent slice back to quantize it, i.e. they consume the bmm's output, so overlapping there would race. Same gate the DeepSeek MLA decode path applies inmla.py.Supporting details:
forward()so the captured CUDA graph records them, matching howKimiK3MoERuntimealready does it. All usedisable_on_compile=True; with no stream supplied or multi-stream off, both legs run in order on the default stream with an identical result.record_streamon every tensor that crosses streams (cs, the gatheredstate,latent_cache, and pre-fork onfused_q/cu_*_seqlens/fmha_scheduler_counter) so the caching allocator cannot recycle storage mid-use.Performance
16x GB300 TEP16, ISL 8192 / OSL 1024, median TPOT. Reproduced across both a rack change and a rebuild:
The two agree to 0.316%, against a measured c=1 noise band of 2.63%.
A third observation and the full concurrency curve were taken afterwards on the same recipe (job 2721639), confirming the gain holds across the sweep and regresses nothing:
c=8 is the only genuinely independent corroborator:
stream_interval=10makes median ITL exactly 10x TPOT, so ITL, tps/user and output_throughput at c=1 are all restatements of the same metric. Per-point noise bands are from three zero-change runs on the unmodified build.Post-change nsys on the same recipe confirms the forks execute on device rather than merely being issued:
with the aux stream appearing in both families' stream sets.
Test Coverage
Draft — two verification gaps remain before this is merge-ready.
Done:
mlaKernels.cuwritesqkv_output[dst_q_idx]write-only, and bothhead_dim_idxandc_k = 512are multiples ofELTS_PER_VEC = 8, so no vector store can straddle the bmm's slice.Outstanding:
mla_rope_generation) has a source-level disjointness argument but no numerical probe of its own.Both should land before this leaves draft.
PR Checklist
Please review the following before submitting your PR:
PR description clearly explains what and why. If using CodeRabbit's summary, please make sure it makes sense.
PR Follows TRT-LLM CODING GUIDELINES to the best of your knowledge.
Test cases are provided for new code paths (see test instructions)
If PR introduces API changes, an appropriate PR label is added - either
api-compatibleorapi-breaking. Forapi-breaking, includeBREAKINGin the PR title.Any new dependencies have been scanned for license and vulnerabilities
CODEOWNERS updated if ownership changes
Documentation updated as needed
Update tava architecture diagram if there is a significant design change in PR.
The reviewers assigned automatically/manually are appropriate for the PR.
Please check this after reviewing the above items as appropriate for this PR.