Route MLA RoPE KV writes through embedding API#643
Conversation
Summary: Add an MLA-specific fused RoPE KV-cache descriptor and route it through the existing embedding.rope API. The normal fused KV path assumes MHA-style K and V buffers with the same per-head width, but DeepSeek MLA stores one combined cache row shaped as k_nope / latent width kv_lora_rank concatenated with rotated k_rope width qk_rope_head_dim. The new fused_mla_set_kv_buffer_arg makes that layout explicit, letting the RoPE kernel copy k_nope and write rotated k_rope directly into the combined row. The normal fused-KV path for DeepSeekV3 was unused and replaced here. Testing Plan: - test/runtime/cache/test_mla_kv_buffer.py covers MLA KV set/get against torch references across bf16/fp8, cache locations, and round trips. - test_mla_rope_set_kv_buffer_matches_reference covers the fused RoPE+MLA KV write path used by DeepSeek decode. Signed-off-by: Quinn Dawkins <quinn.dawkins@gmail.com>
37d4386 to
4065dca
Compare
|
do you have a timeline/perf comparison before and after this change? |
Oops forgot to add that part. From Codex: Fused MLA RoPE KV Benchmark ResultsSetup
Isolated Kernel BenchmarkCommand shape: synthetic BF16 MLA RoPE + MLA KV write, Kimi/DeepSeek dimensions ( The fused path is compared against both the pre-PR Torch RoPE + KV write sequence and the generic Triton RoPE + KV write sequence. Values below are median milliseconds.
Raw data: E2E Decode BenchmarkCommand shape: in-process Engine, synthetic token IDs, The controlled after run disables prefill graph to match the before behavior. The default after run is included for reference only because the branch default also engages prefill graph.
Trace ComparisonTrace shape: one warmup request, then one profiled request with Single-request measured latency from the profiled runs:
Rank-0 kernel-launch changes in the profiled request:
Immediate pre-MLA decode window, rank 0:
Interpretation: the isolated benchmark is the cleanest measurement of this specific fused operation. The trace confirms that the decode-side standalone RoPE/cat/copy/KV-write sequence no longer appears: 244 decode-side standalone KV writes become 244 fused RoPE+KV kernels, and the large Torch RoPE helper launch count disappears from the profiled request. |
Summary
Add an MLA-specific fused RoPE KV-cache descriptor and route it through the existing embedding.rope API. The normal fused KV path assumes MHA-style K and V buffers with the same per-head width, but DeepSeek MLA stores one combined cache row shaped as k_nope / latent width kv_lora_rank concatenated with rotated k_rope width qk_rope_head_dim. The new fused_mla_set_kv_buffer_arg makes that layout explicit, letting the RoPE kernel copy k_nope and write rotated k_rope directly into the combined row. The normal fused-KV path for DeepSeekV3 was unused and replaced here.
Testing Plan