Add CUDA training kernels (fwd+bwd) for KDA - #28
Conversation
Stage-by-stage CUDA reimplementation of the FLA Triton chunk_kda training pipeline (WY representation, CuTe SM80 MMA atoms, cp.async pipelining), merged into a single flash_kda_train_C extension: - gate cumsum / kda_gate fwd+bwd - intra attn (Aqk/Akk) fwd+bwd, block-triangular solve - WY recompute (w/u), chunk o, chunk h fwd + bwd dhu - bwd dAv, fused wy dqkg flash_kda/train/pipeline.py mirrors the FLA recompute path end to end (dense + varlen). tests/train covers every stage against the Triton reference plus end-to-end pipeline tests (105 tests).
benchmarks/bench_train.py times the CUDA training kernels against FLA chunk_kda (Triton) fwd and fwd+bwd on the official fixed/varlen cases; BENCHMARK_TRAIN_RTX5090.md: fwd+bwd 1.06x-1.10x across all cases. tests/train/test_train_vs_fla.py sweeps the official g/bias configs and compares o, ht and all gradients against a differentiable fp64 naive recurrence; docs/assets/compare_train_with_fla.png follows the official compare_with_fla.png layout. Errors are on par with or below the Triton reference in every configuration.
bench_train_stages.py times each pipeline stage against its Triton counterpart (B2-T16384-H16-D128): TOTAL 1.08x, led by bwd_wy_dqkg (1.41x, bandwidth-saturated) and bwd_dhu (1.25x). Also pin FLA_REPO in both bench scripts so results are measured against the intended Triton reference checkout.
|
您好,之前的 提交 显示前向性能优于triton 版本,请问为什么没有基于上述前向的路径做反向设计?因为每个 chunk 中 16 token 不利于反向并行计算,或者上述前向路径不利于反向并行? |
|
感谢提问。简短回答:与 16-token 分块不利于并行无关——训练路径在 chunk=64 内部同样以 16 为 sub-chunk 做 WY 分块求逆(
|
|
补充说明:我们也在另一条分支上尝试基于 WY-16 前向思路的训练实现(专用 FP32 训练前向 + chunk 边界检查点 + 窗口化 chunk 并行反向)。初步结果是在短序列上相比 Triton 有明显优势,但长序列上反向随 T 增长退化明显、目前效果不好,还在定位并行度瓶颈。所以本 PR 先走语义与 FLA 完全对齐、各序列长度下都稳定的 chunk=64 路线;WY-16 训练路线待长序列问题解决后再考虑合入。 |
我也尝试基于WY-16 前向思路的训练实现,发现了相同的类似规律: 短序列上相比 Triton 有明显优势,但长序列上反向随 T 增长退化明显。 但是不知道 kimi flash kda 在内部训练是如何实现的? |
|
SM90 还没有真机验证。本 PR 的全部测试与 benchmark 都在 RTX 5090(sm_120a)上完成 |
Summary
Adds a complete CUDA training path (forward and backward) for KDA. The kernels replicate the FLA Triton
chunk_kdatraining pipeline stage by stage (WY representation, CuTe SM80 MMA atoms, cp.async pipelining), so the numerics track the Triton reference closely:csrc/train/— 9 CUDA kernels merged into a singleflash_kda_train_Cextension: gate cumsum (kda_gatefwd+bwd), intra attention (Aqk/Akkfwd, block-triangular solve, bwd), WY recompute (w/u), chunko, chunkhfwd + bwddh/dh0, bwddAv, fused bwddq/dk/dg/db.flash_kda/train/pipeline.py— end-to-endchunk_kda_train_fwd/chunk_kda_train_bwdorchestration mirroring the FLA recompute path, dense and varlen (cu_seqlens) alike.csrc/smxx(SM80-era instructions, arch handled via-gencode).Performance (RTX 5090, bf16, fwd+bwd training step)
Full details and repro command in
BENCHMARK_TRAIN_RTX5090.md(this branch).T=8192,H=96,D=128flash_kda_trainfwd (ms)fla_chunk_kdafwd (ms)flash_kda_trainfwd+bwd (ms)fla_chunk_kdafwd+bwd (ms)seq_lens=[1300, 547, 2048, 963, 271, 3063]seq_lens=1024 x 8T=8192,H=64,D=128flash_kda_trainfwd (ms)fla_chunk_kdafwd (ms)flash_kda_trainfwd+bwd (ms)fla_chunk_kdafwd+bwd (ms)seq_lens=[1300, 547, 2048, 963, 271, 3063]seq_lens=1024 x 8fwd-only is slightly slower (0.87×–0.89×) by design: the training path persists
Aqk/Akkfor backward, which pure-inference use does not amortize — inference stays on the existing kernels. Training (fwd+bwd) is faster on every measured case; an FLA-side end-to-end run shows up to 2.17× on small-grid shapes where the CUDA kernels' finer V-dim split wins occupancy.Stage-level breakdown (CUDA vs Triton,
B=2 T=16384 H=16 D=128, 20 reps)Reproduce with
python benchmarks/bench_train_stages.py:The gain comes mainly from the two heavy backward kernels (
bwd_wy_dqkg1.41×, bandwidth-saturated at ~1.47 TB/s;bwd_dhu1.25×). Stages still below 1.0× (fwd_intra,recompute_w_u) measure at the bandwidth floor (0.94–0.97 TB/s) where the Triton kernels sit too — memory-pattern bound, not scheduling slack.Precision (vs fp64 gold, fwd + all gradients)
Sweep of the official g/bias configurations (
tests/test_fwd.pystyle), comparingo,htand all gradients (dq/dk/dv/dg/db/dh0) of bothflash_kda_trainandfla chunk_kdaagainst a differentiable fp64 naive recurrence. Generated bytests/train/test_train_vs_fla.py(this branch):Per-position max/mean error, RMSE ratio and error distributions are on par with or below the Triton reference in every configuration (see the summary row at the bottom, e.g.
dq: chunk 4.33e-03 vs flash 3.88e-03;dh0: chunk 2.98e-03 vs flash 2.04e-03).Test plan
tests/train/— 105/105 passing (RTX 5090): every stage compared point-by-point against the FLA Triton reference, plus end-to-end pipeline tests (dense + varlen, gate/safe_gate configs, full gradient checks).tests/train/test_train_vs_fla.py— fp64-gold precision sweep above (asserts included).Benchmark
python benchmarks/generate_train_benchmark_md.pyuse_gate_in_kernel=True,lower_bound=-5, post-sigmoidbeta, fp32initial_state,chunk_size=64Breaking changes
None — purely additive (
csrc/train/,flash_kda/train/,tests/train/, benchmark scripts/docs).