Triton kernel optimizations for DMS prefill path (up to 1.65x speedup)

#1
by amiga1200 - opened

Hi DMS team! Following up from a conversation on kvpress#184 with @alancucki and @SimJeg , who suggested continuing the discussion here.

I've been benchmarking DMS-8x inference on an RTX 4090 (24 GB) and wrote a set of Triton GPU kernels to optimize the prefill path. I also benchmarked against the flex_attention prefill from Model Optimizer. Sharing the results and a few questions.

Benchmark Results

Hardware: RTX 4090 24 GB, Qwen3-8B-DMS-8x, batch size 1, bf16, 128 output tokens.
Needle-in-a-haystack retrieval task, 3 iterations averaged per data point.

Prefill Speed (TTFT, no_think mode)

Context Hub (Original) FlexAttn (Model Optimizer) Triton (my kernels)
4K 3.457s 1.260s (2.74x) 3.083s (1.12x)
8K 7.922s 1.348s (5.88x) 5.795s (1.37x)
16K 22.211s 2.503s (8.88x) 12.699s (1.75x)
32K OOM 5.139s 25.685s

Peak VRAM

Context Hub FlexAttn Triton
4K 16.89 GB 16.84 GB 15.99 GB
8K 17.93 GB 16.97 GB 16.47 GB
16K 20.07 GB 17.21 GB 17.48 GB
32K OOM 17.79 GB 19.43 GB

DMS-8x vs Vanilla vs kvpress (prefill + decode, 512 output tokens)

Context DMS-8x (Triton) Vanilla Qwen3-8B kvpress (KnormPress 0.5)
4K 7.77s / 15.99 GB 2.49s / 16.63 GB 2.44s / 16.58 GB
8K 8.97s / 16.46 GB 3.19s / 16.95 GB 3.35s / 16.78 GB
16K 15.43s / 17.48 GB 5.96s / 17.78 GB 6.49s / 17.41 GB
32K 27.97s / 19.42 GB 13.43s / 19.95 GB OOM

Decode speed is comparable across all variants (~20-42 tok/s), so prefill is the key differentiator.

Triton Kernels

Five kernels replacing the Python batch-loops in dms_attention.py and dms_cache.py:

  1. left_pad_2d β€” replaces left_pad_one() serial loop
  2. scatter_by_index β€” replaces restore_order() loop
  3. bool_gather_left_pad β€” replaces convert_to_left_padding() inner loop
  4. compact_by_bool β€” replaces get_contiguous_cache() compaction loop
  5. _dms_flash_attn_fwd_kernel β€” single-pass flash attention with DMS causal + window + eviction masking, replacing the chunked SDPA loop

The key insight is that the eviction state can be pre-computed upfront β€” the sequential chunk dependency in dms_prefill_attention() is redundant since eviction is monotonic.

Full code: github.com/westers/kvcompress

Questions

  1. FlexAttn integration path: The flex_attention prefill from Model Optimizer is clearly superior for speed. Are there plans to integrate it into the HuggingFace model files directly? Currently users need to clone Model Optimizer separately.

  2. Decode-phase cache compression: DMS achieves 8x compression during prefill, but at shorter contexts (4-8K), the total time is still dominated by the prefill overhead vs vanilla. Is there work on reducing the prefill cost further, or is the focus on longer contexts where the VRAM savings compound?

  3. Upstream interest: Would there be interest in upstreaming the Triton utility kernels (left_pad, scatter, compact) to the Hub model files? They're drop-in replacements with no API changes and improve prefill by 1.2-1.7x on their own.

Thanks for the great work on DMS β€” the 8x KV compression with minimal quality loss is impressive, and it's exciting to see it in a usable HuggingFace model.

Sign up or log in to comment