You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
perf(laguna): byte-exact attention-glue fusions on NVFP4 decode (VT_LAGUNA_GLUE_FUSED)
Fold the tiny under-occupied glue kernels the decode CUDA graph does NOT hide
into fewer, larger nodes on the Laguna-NVFP4 resident decode — BYTE-EXACT,
default-ON, VT_LAGUNA_GLUE_FUSED=0 opts back out for a same-binary A/B.
- L1: fold the per-head softplus out-gate into the attention-combine store
(DecodeAttnCombineKernel + the SPLIT<=1 DecodeAttnGqa{,G}Kernel fallbacks).
The combine stored acc*inv (f32, lossless) and a separate SoftplusHeadGate
pass reloaded it x softplus(g); folding computes the same (acc*inv)*softplus(g)
in registers. gate==nullptr keeps the un-gated store bit-for-bit. -1 kernel/layer.
- L4: route each residual-Add + STANDARD RMSNorm pair through the shared
vt::FusedChain(kFusedAddRmsNormStd) seam (res += x; out = rms_norm(res)*w).
Byte-exact to vt::Add + rms_norm_seq (commutative f32 add + ResRound<f32>
identity + the SAME 256-thread strided-sum/tree/1-over-sqrt reduction as
RmsNormSeqKernel); the default Tier-0 composite already collapses it to ONE
RmsNorm(residual) launch. The post-attn norm folds in place; the last MLP
residual add folds with the next layer's input norm (final layer's with the
final norm), so both loose per-layer Adds disappear into fused nodes. ~-2/layer.
- C (shared-into-MoeCombine) SKIPPED: Laguna's MoeCombine writes bf16 then casts
to f32, so folding the f32 shared term before the bf16 store rounds
(routed+shared) to bf16 -> not byte-exact (unlike qwen3_5's f32 combine).
- L2 (fused qk-norm+RoPE preamble) DEFERRED: needs a capture-safe device-position
kernel variant (graph decode indexes cos/sin by *pos_buf, half-split layout).
DGX gate (GB10, laguna-xs-nvfp4, VT_LAGUNA_RESIDENT_DECODE=1 MARLIN_MOE=1
DECODE_GRAPH=1, ids 2,785,9626,377,15360,395, max-tokens 160): =0 and =1 emit
byte-identical 159-token id streams (PASS). Paging-immune nsys cuda_gpu_kern_sum
2-length diff (160-20)/140 = steady decode/step: GPU-busy 28.90 -> 27.69 ms/step
(-4.2%), graph nodes 1195 -> 1075/step (-120, -10%); drop_caches wall tied
(4.48 vs 4.49s/159). Byte-exact + neutral-to-positive -> landed default-ON.
FOLLOWING_AGENTS_PROTOCOL
Assisted-by: Claude Code:claude-opus-4-8 [ClaudeCode]
Copy file name to clipboardExpand all lines: docs/BENCHMARKS.md
+21Lines changed: 21 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -95,6 +95,27 @@ Built clean on GB10 sm_121a (incremental, **7 TUs, 0 warnings**). DGX-gated on `
95
95
96
96
**WASH on speed** (bf16 3.93s vs base 3.84s; spreads base 3.84–4.03 / bf16 3.93–4.07 overlap → indistinguishable) — did NOT move the residual. At the XS gate's short context (~130 tok) the decode-attention KV read is a small share of decode time; `lm_head_gemv` (streams the ~600 MB tower) + Marlin MoE dominate — so this **confirms the ~17%-to-vLLM-42.46 residual is GEMV/MoE, not KV/attention traffic**, at this context. **Near-tie BREAK on correctness**: bf16 output is coherent (re-emits the golden prefix from ~token 14) but flips the step-2 argmax 268→22345 — our device regime is not bit-identical to vLLM, so a near-tie flips even when moving TOWARD vLLM's bf16 dtype (vLLM itself uses bf16 KV yet emits 268). Two strikes → **NOT landed**; default stays f32 KV (base prefix + ~33 tok/s re-verified after DGX restore). Tested diff + analysis: `.agents/specs/laguna-kv-attn-port-2026-08-02.md`.
The last real Laguna-NVFP4 decode speed lever + a frameworkization win: fold the tiny, under-occupied attention-glue kernels the decode CUDA graph does NOT hide (device-side ramp/drain of the ~1,195 sequential kernel-nodes/token) into fewer, larger nodes — BYTE-EXACT. Gated behind `VT_LAGUNA_GLUE_FUSED` (default ON, `=0` opts out) for a same-binary A/B. Two folds landed on the resident decode-graph (`LagunaGraph::RunChain`) + the eager resident fallback:
101
+
102
+
- **L1 — softplus out-gate folded into the attention-combine store.** `SoftplusHeadGateKernel` was a separate pass doing `attn[h,d] *= softplus(g[h])` after the combine wrote `o=acc*inv`. Folding computes the same `(acc*inv)*softplus(g[h])` in registers inside `DecodeAttnCombineKernel` (+ the SPLIT≤1 fallbacks `DecodeAttnGqa{,G}Kernel`) — BYTE-EXACT because the store+reload of the f32 `acc*inv` is lossless. −1 kernel/layer.
103
+
- **L4 — residual-Add + STANDARD RMSNorm pairs routed through the shared `vt::FusedChain(kFusedAddRmsNormStd)` seam** (the same machinery qwen3/gemma use): `res += x; out = rms_norm(res)*w`. BYTE-EXACT to `vt::Add + rms_norm_seq`: the f32 residual add is commutative (+ `ResRound<f32>` is identity) and the norm uses the SAME 256-thread strided-sum + shared-tree reduction + `1/sqrtf` as `RmsNormSeqKernel`. NODE-COUNT WIN in the DEFAULT Tier-0 composite (no `VT_FUSED_TIER` needed): the composite collapses `kAdd`+`kRmsNorm` to ONE `vt::RmsNorm(residual)` launch (`RmsNormRowKernel` does the add inline). The post-attn norm folds in place; the last MLP residual add folds with the NEXT layer's input norm (last layer's with the final norm), so both loose per-layer Adds disappear into fused nodes. ≈−2 kernels/layer.
104
+
- **C (shared-into-MoeCombine) SKIPPED — provably NOT byte-exact in Laguna.** Unlike qwen3_5 (f32 combine out), Laguna's `MoeCombine` writes **bf16** `dout` then casts to f32, so folding the f32 shared `so` before the bf16 store rounds `(routed+shared)` to bf16 vs the current `bf16(routed)+so_f32` — a bit change. Left as its separate f32 add.
105
+
- **L2 (fused qk-norm+RoPE preamble) DEFERRED.** The shared `AttnQkNormRopeGate` indexes cos/sin by token, but Laguna's graph decode needs position-from-DEVICE (`*pos_buf`, half-split layout) — a new capture-safe kernel variant; deferred to avoid correctness risk.
The **−120 nodes/step** confirms the folds took effect (48× softplus removed + ~2 norm/add folds/layer collapsed); GPU-busy device time drops **4.2%** — beyond the ~1.5-2.5% ramp/drain estimate, because the fused `RmsNorm(residual)` is itself cheaper than the loose `Add + RmsNorm`. At the wall the two arms are tied (`drop_caches`-standardized 4.48 vs 4.49s; the earlier un-standardized 5.95s reading was pure GB10 reload/paging noise) — the recovered device-time sits inside a graph replay still bounded by the fixed per-step host embed-gather + step-boundary sync. BYTE-EXACT + neutral-to-positive → **landed default-ON**. Repro: `~/laguna_glue_run.sh` (byte-exact) + `~/laguna_glue_nsys.sh` (nsys/wall).
0 commit comments