This document is relevant for: Trn2, Trn3
Attention Const-Max Kernel API Reference#
Constant-max attention: softmax(Q@K.T * softmax_scale - softmax_max) @ V.
Computes attention assuming a pre-known global softmax max.
Background#
The attention_const_max kernel computes softmax(Q @ K.T * softmax_scale - softmax_max) @ V using a caller-supplied global softmax maximum, so the running-max rescaling of online softmax is not needed.
API Reference#
Source code for this kernel API can be found at: attention_const_max.py
attention_const_max#
- nkilib.experimental.attention.attention_const_max(q_hbm: nl.NkiTensor, k_hbm: nl.NkiTensor, v_hbm: nl.NkiTensor, softmax_max: Union[float, nl.NkiTensor], softmax_scale: Optional[float] = None, q_layout: AttentionLayout = AttentionLayout.HEAD_MAJOR, k_layout: AttentionLayout = AttentionLayout.HEAD_MAJOR) nl.NkiTensor#
Constant-max attention: softmax(Q@K.T * softmax_scale - softmax_max) @ V.
- Parameters:
q_hbm (
nl.NkiTensor) –[N, d, Sq]or[N, Sq, d]bf16 @ HBM, Query.k_hbm (
nl.NkiTensor) –[N, d, Sk]or[N, Sk, d]bf16 @ HBM, Key.v_hbm (
nl.NkiTensor) – [N, Sk, d] bf16 @ HBM, Valuesoftmax_max (
Union[float, nl.NkiTensor]) – Upper bound on (scores * scale). Output is mathematically invariant to this value; it only affects numerical precision. A reasonable estimate suffices. May be either: - a Python scalar (compile-time constant, broadcast to all partitions), or - a [128, 1] f32 HBM tensor holding a single broadcast max replicated across the 128 partitions. Use the tensor form to supply a data-dependent max computed at runtime rather than baked in at trace time.softmax_scale (
Optional[float]) – Scaling factor applied to Q. Defaults to 1/sqrt(d).q_layout (
AttentionLayout) – Q layout.SEQ_MAJORfor[N, Sq, d],HEAD_MAJORfor[N, d, Sq]. Defaults toHEAD_MAJOR.k_layout (
AttentionLayout) – K layout.SEQ_MAJORfor[N, Sk, d],HEAD_MAJORfor[N, d, Sk]. Defaults toHEAD_MAJOR.
- Returns:
[N, Sq, d] bf16 @ HBM, Normalized attention output
- Return type:
nl.NkiTensor
Notes:
Requires std(Q) ≤ 1 and std(K) ≤ 1 for bf16 accuracy with softmax_max=4–5. This holds when QK-RMSNorm is applied after projection.
A softmax_max that is too low causes exp() overflow (inf/NaN in output). A softmax_max that is too high clips all scores toward zero, losing precision.
For inputs with significantly larger std use a standard online-softmax kernel. Choosing softmax_max from QK-RMSNorm weights: When QK-RMSNorm is applied, the max can be derived from the gamma weights: σ = sqrt(sum(γ_q² * γ_k²) / d) softmax_max ≈ 0.88 * σ * sqrt(2 * ln(Sk)) # Gumbel expected row-max As a safety check, compute the hard bound (Cauchy-Schwarz worst case): hard_bound = sqrt(d) * max|γ_q| * max|γ_k| If hard_bound - softmax_max > ~80, the score range is too wide for constant-max and the block should fall back to online-softmax attention.
Dimensions:
N: Number of attention heads (batch of heads)
d: Head dimension (must be pmax=128)
Sq: Query sequence length
This document is relevant for: Trn2, Trn3