Expand description
2026-09-25: CPU reference for GLM-5.3-Flash KDA (Kimi Delta Attention).
Owner: model-arch (GLM-5.3-Flash KDA reference). Invariants:
- Nothing here runs on a GPU or reads a checkpoint; production code does not call it.
lower_boundandrms_epsare arguments; the reference has no built-in value for either.
It is checked against kda_golden.json, which gen_kda_golden.py produces by calling the
transformers glm5_next functions (Glm5NextTextForgetGate, Glm5NextTextRMSNormGated,
l2norm, recurrent_kimi_delta_attention, chunk_kimi_delta_attention).
KDA differs from the Qwen GDN path (compute_gdn_gates in
kernels/gb10/common/ssm_preprocess.cu) in four ways:
- The decay is per (head, key channel),
[T, H, head_dim]; GDN writes one value per head. - The decay comes from a low-rank projection,
f_a: hidden -> head_dim,f_b: head_dim -> H*head_dim; GDN reads it from the fusedBAprojection. - The gate is bounded,
lower_bound * sigmoid(exp(A_log) * (g + dt_bias)); GDN computesexp(-exp(A_log) * softplus(a + dt_bias)). - The output gate is low-rank
g_a/g_b; GDN takes a full-rankZfrom its fusedQKVZprojection, and a KDA checkpoint has noZtensor.
§Layout conventions
q/k/v/gate:[T, H, D], row-major, index((t * H) + h) * D + d.beta:[T, H], indext * H + h.dt_bias:[H * D], per channel.a_log:[H], per head.state:[H, D_k, D_v], index(h * D_k + kd) * D_v + vd.- Weights follow the torch
Linearconvention[out, in], row-major.
Structs§
- KdaDims
- 2026-09-25: KDA geometry. The low-rank width of both
f_a/f_bandg_a/g_bishead_dim. - KdaWeights
- 2026-09-25: Weights for one KDA layer, reference only. Torch
Linearlayout[out, in]throughout. There is noZtensor: the output gate isg_a/g_band the decay source isf_a/f_b.
Functions§
- bounded_
gate - 2026-09-25: The bounded GLM forget gate:
- kda_
chunked - 2026-09-25: Prefill formulation: the chunked (WY-style) delta rule with a per-channel decay
mask, checked against the golden’s
chunk_kimi_delta_attentionoutput.tokens % chunk != 0is handled by zero-padding. - kda_
chunked_ prenorm - 2026-09-25: Same chunked formulation, but
q/kare already L2-normalised, as the GPU prefill’sl2_norm_bf16leaves them (in bf16). Separate fromkda_chunkedfor the reason given onkda_recurrent_prenorm. - kda_
recurrent - 2026-09-25: Decode formulation: one token at a time, carrying
state. - kda_
recurrent_ prenorm - 2026-09-25: Same recurrence, but
q/kare already L2-normalised, the input thekda_recurrentGPU kernel gets fromcausal_conv1d_update_l2norm. - kda_
reference_ layer - 2026-09-25: Reference for one KDA layer from post-conv q/k/v to the
o_projoutput. The short conv is not included; the golden’s inputs are post-conv. - l2norm_
rows - 2026-09-25:
x / sqrt(sum(x^2) + eps)over the trailing dimension, notx / max(norm, eps); the two differ for small-norm rows. The GPUl2_norm_bf16uses the same form. - linear
- 2026-09-25:
y = x @ w^Tforx: [m, k],w: [n, k](torchLinearweight layout), no bias. - rms_
norm_ gated - 2026-09-25: Gated RMSNorm over the trailing
d, FP32, with a sigmoid gate.epsis the caller’srms_norm_eps. - unbounded_
gdn_ gate - 2026-09-25: The unbounded Qwen GDN gate, used by the tests to show the two laws diverge.