nemo_automodel.components.models.kimi_k3.situ_triton
nemo_automodel.components.models.kimi_k3.situ_triton
Hand-written Triton kernels for the Kimi-K3 SiTU activation.
The SiTU chain (beta * tanh(g / beta) * sigmoid(g) * linear_beta * tanh(u / linear_beta) * w) is a pure elementwise function of the gate/up
halves of one [rows, 2 * intermediate] projection plus one routing weight
per row. torch.compile (BackendConfig.compile_situ) fuses it into a
single kernel, but the generated 1-D pointwise kernels pay for two things on
every element: 64-bit div/mod to recover the row index for the
row-broadcast routing weight (the pointwise index space is flattened), and,
in the backward, both cat branches evaluated under tl.where (twelve
masked loads and four tanh per output element). On GB200 that leaves the
backward ~10x above its bandwidth bound (17 ms per 262k x 6144 bf16 call on a
2-node K3 profile).
These kernels tile the problem in 2-D (rows x columns) instead: the row index
is a per-tile 64-bit multiply, the column index stays 32-bit, each transcendental
is evaluated once, d_gate and d_up are stored straight into the two
halves of the output, and the routing-weight gradient (“sum_cols(go * situ(g)
- up(u))
) is reduced inside the backward kernel while the tile is in registers. The fp32 math and its operation order are identical tositu._situ_fwd_core/situ._situ_bwd_core“; only the fp32 accumulation order of the routing-weight reduction differs.
Module Contents
Functions
Data
API
rcp.approx.ftz.f32 on an fp32 block of any shape (one SFU op; results below 2^-126 flush to zero).
Analytic SiTU gradients for BLOCK_R full rows; the routing-weight gradient is reduced in-kernel.
out[r, c] = beta * tanh(g / beta) * sigmoid(g) * up(u) * w[r] for one (rows x cols) tile.
sigmoid of an fp32 block of any shape: SFU exp2 + approximate reciprocal when FAST, tl.sigmoid otherwise.
tanh of an fp32 block of any shape: the SFU approximation when FAST, libdevice otherwise.
MUFU.TANH (tanh.approx.f32, sm_75+): one SFU op, |rel err| <= 2^-11 — below bf16 resolution.
Autotune candidates: ~16 fp32 values per thread keeps the backward below the register cap.
Weighted (or dense) SiTU backward.
Parameters:
Saved gate+up projections of shape [rows, 2 * intermediate].
Saved routing weights of shape [rows, 1], or None (dense).
Upstream gradient of shape [rows, intermediate], unit last stride.
SiTU beta applied to the gate branch.
Optional bounded-linear beta applied to the up branch.
Whether to reduce the routing-weight gradient (requires weights).
Same SFU variants as in situ_fwd_triton; the autograd Functions in situ.py pass
the setting their forward used.
Returns: torch.Tensor
(d_gate_up2, d_routing_weights2) in the inputs’ dtypes; the second
Weighted (or dense) SiTU forward on [rows, 2 * intermediate] projections.
Parameters:
Gate+up projections of shape [rows, 2 * intermediate] on a CUDA device, unit stride along the last axis; gate in the first half.
Optional routing weights of shape [rows, 1] (any float dtype, contiguous), or None for the dense activation.
SiTU beta applied to the gate branch.
Optional bounded-linear beta applied to the up branch.
SFU tanh.approx / exp2 / rcp.approx instead of libdevice tanh and an IEEE divide
(KimiK3TextConfig.situ_backend = "triton_fast_math"); at most one bf16 ulp from the exact chain.
Returns: torch.Tensor
Tensor of shape [rows, intermediate] in gate_up2’s dtype.