FLA KDA Skill
Use this skill for KDA-specific work under fla/ops/kda/** and tests that
exercise KDA behavior.
Public code map
- Public API:
fla.ops.kda.chunk_kda, fla.ops.kda.fused_recurrent_kda.
- Gate helpers:
naive_kda_gate, naive_kda_lowerbound_gate,
kda_gate_fwd, kda_gate_bwd, fused_kda_gate,
kda_gate_chunk_cumsum in fla/ops/kda/gate.py.
- Chunk forward:
chunk_kda_fwd in chunk_fwd.py.
- Intra/inter forward:
chunk_kda_fwd_intra,
chunk_kda_fwd_kernel_intra_sub_chunk,
chunk_kda_fwd_kernel_inter_solve_fused in chunk_intra.py.
- Token-parallel non-safe path:
chunk_kda_fwd_intra_token_parallel in
chunk_intra_token_parallel.py.
- WY recompute:
recompute_w_u_fwd and recompute_w_u_fwd_kda_kernel in
wy_fast.py.
- Backward:
chunk_kda_bwd, chunk_kda_bwd_intra,
chunk_kda_bwd_wy_dqkg_fused.
- Backends:
FlashKDABackend, KDATileLangBackend.
Gate modes
chunk_kda has two gate input contracts:
- Pre-gated mode:
use_gate_in_kernel=False.
g is already the log-space decay tensor.
A_log, dt_bias, and lower_bound are not part of the gate activation.
- In-kernel mode:
use_gate_in_kernel=True.
g is raw gate input.
A_log is required and dt_bias is optional.
- Without
safe_gate, activation is -exp(A_log) * softplus(g + dt_bias).
- With
safe_gate, activation is
lower_bound * sigmoid(exp(A_log) * (g + dt_bias)).
safe_gate=True requires use_gate_in_kernel=True, lower_bound is not None,
and -5 <= lower_bound < 0.
Safe gate numerical note
With lower_bound=-5, every per-token gate value is in [-5, 0) before the
RCP_LN2 conversion used by chunk_kda_fwd. A 16-token sub-chunk can therefore
accumulate -80 in natural-log units. Directly feeding the full span to exp2
would be larger in base-2 units, so the safe intra path relies on offsetting.
chunk_kda_fwd_kernel_intra_sub_chunk uses a midpoint offset before
exponentiation:
b_gm = b_g - b_gn;
exp2(b_gm) and exp2(-b_gm).
With the midpoint offset, each exponent operand covers at most about half of the
16-token sub-chunk. Under lower_bound=-5, this is about 40 / ln(2), which is
below the kernel's exp2 safety comment threshold. The important invariant is
not the raw cumulative value alone; it is that each exponentiation uses a local
offset rather than the full chunk cumsum directly.
For inter-subchunk work, chunk_kda_fwd_kernel_inter_solve_fused computes decay
ratios with paired offsets such as:
exp2(b_g1 - b_gn1) and exp2(b_gn1 - b_g0);
exp2(b_g2 - b_gn2) and exp2(b_gn2 - b_g1).
Both terms are non-positive under monotonic accumulated decay, so the off-diagonal
inter path avoids positive exponent growth. The triangular solve operates on
masked lower-triangular blocks, so it does not introduce an unbounded exponent
path.
Safe vs non-safe intra path
- Safe path:
chunk_kda_fwd_intra(..., safe_gate=True) calls
chunk_kda_fwd_kernel_intra_sub_chunk for 16-token diagonal blocks, then
calls chunk_kda_fwd_kernel_inter_solve_fused with USE_SAFE_GATE=True.
- Non-safe path:
safe_gate=False calls chunk_kda_fwd_intra_token_parallel
for diagonal blocks, then calls the same inter/solve kernel with
USE_SAFE_GATE=False.
- Do not change one path without checking the other path unless the contract is
explicitly safe-only or non-safe-only.
Correctness checklist
Before finishing a KDA behavior change, use fla-correctness-coverage and cover
only axes affected by the change:
- dense and varlen sequence layout;
- forward and backward if training path is touched;
- pre-gated, non-safe in-kernel, and safe in-kernel gate modes where supported;
- raw beta logits and post-sigmoid beta where supported;
use_qk_l2norm_in_kernel=True/False where relevant;
- MHA and GVA (
HV > H);
D != Dv when value dimension is involved;
- initial/final state,
return_intermediate_states, and CP paths when touched;
- backend verifier behavior for FlashKDA / TileLang changes.
- gate numerical extremes when gate math or intra/inter decay is touched:
lower_bound=-5, a lower bound close to 0, large positive and negative
g + dt_bias, extreme A_log, long-sequence cumulative decay, chunk
boundaries, and ragged varlen boundaries.
Style constraints
- Use platform helpers from
fla.utils (device, device_platform, IS_NVIDIA,
IS_NVIDIA_HOPPER, IS_NVIDIA_BLACKWELL, IS_AMD, IS_INTEL) instead of
adding new direct torch.cuda platform checks in tests or public code. If no
helper covers the condition, add one in fla.utils first.
- Keep math derivations in operator docs or PR text; in Triton kernels, prefer
compact shape comments and one-line rationale comments.
- Do not include internal-only paths, private model names, local machine paths,
or private workload identifiers in public tests or skills.
1---2name: fla-kda3description: FLA KDA kernel workflow and public technical notes. Use when modifying or reviewing fla/ops/kda/**, KDA gate modes, chunk intra/inter kernels, safe_gate behavior, KDA backends, or KDA-specific tests and benchmarks.4---56# FLA KDA Skill78Use this skill for KDA-specific work under `fla/ops/kda/**` and tests that9exercise KDA behavior.1011## Public code map1213- Public API: `fla.ops.kda.chunk_kda`, `fla.ops.kda.fused_recurrent_kda`.14- Gate helpers: `naive_kda_gate`, `naive_kda_lowerbound_gate`,15 `kda_gate_fwd`, `kda_gate_bwd`, `fused_kda_gate`,16 `kda_gate_chunk_cumsum` in `fla/ops/kda/gate.py`.17- Chunk forward: `chunk_kda_fwd` in `chunk_fwd.py`.18- Intra/inter forward: `chunk_kda_fwd_intra`,19 `chunk_kda_fwd_kernel_intra_sub_chunk`,20 `chunk_kda_fwd_kernel_inter_solve_fused` in `chunk_intra.py`.21- Token-parallel non-safe path: `chunk_kda_fwd_intra_token_parallel` in22 `chunk_intra_token_parallel.py`.23- WY recompute: `recompute_w_u_fwd` and `recompute_w_u_fwd_kda_kernel` in24 `wy_fast.py`.25- Backward: `chunk_kda_bwd`, `chunk_kda_bwd_intra`,26 `chunk_kda_bwd_wy_dqkg_fused`.27- Backends: `FlashKDABackend`, `KDATileLangBackend`.2829## Gate modes3031`chunk_kda` has two gate input contracts:32331. Pre-gated mode: `use_gate_in_kernel=False`.34 - `g` is already the log-space decay tensor.35 - `A_log`, `dt_bias`, and `lower_bound` are not part of the gate activation.362. In-kernel mode: `use_gate_in_kernel=True`.37 - `g` is raw gate input.38 - `A_log` is required and `dt_bias` is optional.39 - Without `safe_gate`, activation is `-exp(A_log) * softplus(g + dt_bias)`.40 - With `safe_gate`, activation is41 `lower_bound * sigmoid(exp(A_log) * (g + dt_bias))`.4243`safe_gate=True` requires `use_gate_in_kernel=True`, `lower_bound is not None`,44and `-5 <= lower_bound < 0`.4546## Safe gate numerical note4748With `lower_bound=-5`, every per-token gate value is in `[-5, 0)` before the49`RCP_LN2` conversion used by `chunk_kda_fwd`. A 16-token sub-chunk can therefore50accumulate `-80` in natural-log units. Directly feeding the full span to `exp2`51would be larger in base-2 units, so the safe intra path relies on offsetting.5253`chunk_kda_fwd_kernel_intra_sub_chunk` uses a midpoint offset before54exponentiation:5556- `b_gm = b_g - b_gn`;57- `exp2(b_gm)` and `exp2(-b_gm)`.5859With the midpoint offset, each exponent operand covers at most about half of the6016-token sub-chunk. Under `lower_bound=-5`, this is about `40 / ln(2)`, which is61below the kernel's `exp2` safety comment threshold. The important invariant is62not the raw cumulative value alone; it is that each exponentiation uses a local63offset rather than the full chunk cumsum directly.6465For inter-subchunk work, `chunk_kda_fwd_kernel_inter_solve_fused` computes decay66ratios with paired offsets such as:6768- `exp2(b_g1 - b_gn1)` and `exp2(b_gn1 - b_g0)`;69- `exp2(b_g2 - b_gn2)` and `exp2(b_gn2 - b_g1)`.7071Both terms are non-positive under monotonic accumulated decay, so the off-diagonal72inter path avoids positive exponent growth. The triangular solve operates on73masked lower-triangular blocks, so it does not introduce an unbounded exponent74path.7576## Safe vs non-safe intra path7778- Safe path: `chunk_kda_fwd_intra(..., safe_gate=True)` calls79 `chunk_kda_fwd_kernel_intra_sub_chunk` for 16-token diagonal blocks, then80 calls `chunk_kda_fwd_kernel_inter_solve_fused` with `USE_SAFE_GATE=True`.81- Non-safe path: `safe_gate=False` calls `chunk_kda_fwd_intra_token_parallel`82 for diagonal blocks, then calls the same inter/solve kernel with83 `USE_SAFE_GATE=False`.84- Do not change one path without checking the other path unless the contract is85 explicitly safe-only or non-safe-only.8687## Correctness checklist8889Before finishing a KDA behavior change, use `fla-correctness-coverage` and cover90only axes affected by the change:9192- dense and varlen sequence layout;93- forward and backward if training path is touched;94- pre-gated, non-safe in-kernel, and safe in-kernel gate modes where supported;95- raw beta logits and post-sigmoid beta where supported;96- `use_qk_l2norm_in_kernel=True/False` where relevant;97- MHA and GVA (`HV > H`);98- `D != Dv` when value dimension is involved;99- initial/final state, `return_intermediate_states`, and CP paths when touched;100- backend verifier behavior for FlashKDA / TileLang changes.101- gate numerical extremes when gate math or intra/inter decay is touched:102 `lower_bound=-5`, a lower bound close to `0`, large positive and negative103 `g + dt_bias`, extreme `A_log`, long-sequence cumulative decay, chunk104 boundaries, and ragged varlen boundaries.105106## Style constraints107108- Use platform helpers from `fla.utils` (`device`, `device_platform`, `IS_NVIDIA`,109 `IS_NVIDIA_HOPPER`, `IS_NVIDIA_BLACKWELL`, `IS_AMD`, `IS_INTEL`) instead of110 adding new direct `torch.cuda` platform checks in tests or public code. If no111 helper covers the condition, add one in `fla.utils` first.112- Keep math derivations in operator docs or PR text; in Triton kernels, prefer113 compact shape comments and one-line rationale comments.114- Do not include internal-only paths, private model names, local machine paths,115 or private workload identifiers in public tests or skills.