[FlyDSL] Add gfx950 Kimi Delta Attention prefill kernel - #4741
Open
amd-wsung102 wants to merge 4 commits into
Open
[FlyDSL] Add gfx950 Kimi Delta Attention prefill kernel#4741amd-wsung102 wants to merge 4 commits into
amd-wsung102 wants to merge 4 commits into
Conversation
Contributor
🏷️ CI GuideRuns automatically on every PR:
Extended tests (opt-in via labels):
|
5 tasks
Format the FlyDSL KDA wrapper and test, sort imports and __all__, rewrite the test's dict() calls as literals, and simplify a boolean return. Exclude the two vendored FlyDSL kernels (kda_kernel.py, kda_split.py) from Black and Ruff so they stay byte-identical to their FlyDSL source rather than reformatting a vendored copy.
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.
Summary
This PR adds a FlyDSL chunkwise Kimi Delta Attention (KDA) prefill kernel to aiter, exposed as
flydsl_chunk_kdainaiter.ops.flydsl. It is a drop-in for the KDA prefill recurrence that Kimi-K3 runs (same signature asfla.ops.kda.chunk_kda/ aiter'schunk_kimi_delta_attn): packed varlen[1, total_tokens, H, D]inputs, raw pre-activation gate/beta, and a V-first recurrent state.A single FlyDSL path replaces the multi-kernel Triton stack (q/k L2-norm, gate cumsum, beta sigmoid, the two intra-chunk kernels, the w/u recompute, the state scan, and the output matmul) with:
Performance improvement: 1.35x speedup on the KDA block.
Relevant Files
aiter/ops/flydsl/kernels/kda_kernel.py- fused single-kernel variant (included; not used by the wrapper, see below)aiter/ops/flydsl/kernels/kda_split.py- sequence-parallel split kernels (prep + scan), the path in useaiter/ops/flydsl/kda_kernels.py- host wrapper / dispatch (flydsl_chunk_kda,kda_chunk_fwd,flydsl_kda_supported)aiter/ops/flydsl/kda_varlen.py- fused Triton pack / unpackaiter/ops/flydsl/__init__.py- exportsop_tests/flydsl_tests/test_flydsl_kda.py- 32 correctness testsScope: gfx950, bf16, 128-wide K/V heads. Validated on MI355X, TP=8, serving Kimi-K3.
Optimizations Applied
gate_lower_bound = -5a 32-token chunk accumulates up to 160 nats of decay, which overflows fp32 and silently produces NaN (the final state stays correct, so it passes a whole prefill before surfacing). The split path builds the same tiles with a bounded construction and stays exact — verified NaN-free out to 640 nats of decay, vs the fused path failing at ~90–115 nats. The split path is also the faster of the two at prefill chunk counts. The fused kernel is included for reference but the wrapper uses split exclusively.dv_split, chosen from the launch shape rather than a constant: the finest split that still fills idle CUs and keeps two workgroups resident per CU.[N, H, Tpad, D]and folds in the q/k L2-norm, the lower-bounded-sigmoid gate activation, and the beta sigmoid — replacing FLA's separatel2norm_fwd,kda_gate_chunk_cumsum, andfused_beta_sigmoidpasses. Padding slots are written as zeros, which is an exact no-op for the recurrence (beta = 0,g = 0, state carried unchanged).torch.emptycalls (the per-call host cost is visible at short sequences).lru_cache, 256 entries) amortizes the ~35 ms FlyDSL build across the 69 KDA layers that share a shape within a step.None(fall back) for: non-gfx950 / non-bf16 / non-128 heads; lopsided batches where right-padding to the max length would dominate; memory pressure (the guard counts the caching allocator's free pool, not just driver-free, so a KV-cache-heavy server still qualifies); and sequences past the perf crossover — ≤ 2048 tokens/seq for batches ≥ 4 sequences, ≤ 1024 for narrower ones — because the serial scan loses to the Triton kernel beyond ~2K tokens/seq. Thresholds are env-tunable (AITER_KDA_FLYDSL_MAX_SEQLEN,AITER_KDA_FLYDSL_MAX_SEQLEN_NARROW,AITER_KDA_FLYDSL_MAX_PAD_RATIO).Performance
All measured on ATOM MI355X (gfx950), TP=8, Kimi-K3, bf16, head_dim = 128.
ATOM image used:
rocm/atom-dev:latest.End-to-end serving profile — 1k/1k, 128 prompts
Per-rank trace, identical 1035 KDA layer-calls each. The four kernels from the original profile plus the surrounding preprocessing / output kernels are replaced:
chunk_kda_fwd_kernel_intra_sub_chunkkda_scanchunk_gated_delta_rule_fwd_kernel_hkda_preprecompute_w_u_fwd_kda_kernelkda_pack(Triton)chunk_kda_fwd_kernel_inter_solvekda_unpack(Triton)chunk_gla_fwd_kernel_okda_gate_chunk_cumsuml2norm_fwd(×2)fused_beta_sigmoid1.35× on the KDA block (≈ 1.44× counting the elementwise / fill scaffolding the pack kernel also removes). Per prefill iteration (median over 12
bs=10, tok=10240iterations): KDA time 27.6 ms → 21.1 ms; whole prefill iteration 662.3 → 653.3 ms; decode iterations unchanged (41.4 ms — decode uses the fused update kernel, not this path).Accuracy
Unit tests (
test_flydsl_kda.py, 32 passing).flydsl_chunk_kdavsfla.ops.kda.chunk_kdaat bf16 precision (relative error < 2e-2) across: multi-sequence packed prefills, ragged and non-chunk-aligned lengths, with / without initial state, saturated (worst-case) gates, raw-bf16 vs fp32 beta,NC=1/ single-token edges,out=aliasing, and the dispatch-guard fall-back cases.Long-context retrieval (needle-in-haystack), served through ATOM, FlyDSL forced on at all lengths, vs Triton baseline. Accuracy = planted 5-digit codes recalled correctly:
(8k forced FlyDSL on so the kernel — not the fallback — was exercised; confirmed via trace that
kda_prep/kda_scanran for all KDA layers.)GSM8K (lm-eval-harness, 5-shot, full 1319-question test set), served through ATOM:
Submission Checklist