flashrt-structures 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. flashrt_structures/__init__.py +174 -0
  2. flashrt_structures/adapters/__init__.py +55 -0
  3. flashrt_structures/adapters/diffusers_attention.py +237 -0
  4. flashrt_structures/adapters/diffusers_rotary_attention.py +239 -0
  5. flashrt_structures/adapters/factored_qk_norm_rope.py +252 -0
  6. flashrt_structures/adapters/factored_two_way_attention.py +99 -0
  7. flashrt_structures/adapters/gemma_attention.py +226 -0
  8. flashrt_structures/adapters/packed_qkv_rope.py +342 -0
  9. flashrt_structures/adapters/packed_stream_qk_norm_rope.py +376 -0
  10. flashrt_structures/adapters/qwen_per_head_qk_norm_rope.py +231 -0
  11. flashrt_structures/adapters/sglang_engine.py +207 -0
  12. flashrt_structures/adapters/transformers_attention_interface.py +73 -0
  13. flashrt_structures/adapters/transformers_gated_delta.py +152 -0
  14. flashrt_structures/adapters/transformers_gated_delta_fused.py +96 -0
  15. flashrt_structures/adapters/vllm_engine.py +424 -0
  16. flashrt_structures/adjudicate.py +85 -0
  17. flashrt_structures/aot.py +191 -0
  18. flashrt_structures/autobuild.py +2052 -0
  19. flashrt_structures/beta/__init__.py +43 -0
  20. flashrt_structures/beta/conform.py +94 -0
  21. flashrt_structures/beta/joins.py +113 -0
  22. flashrt_structures/beta/negotiate.py +84 -0
  23. flashrt_structures/beta/ports.py +140 -0
  24. flashrt_structures/decisions.py +80 -0
  25. flashrt_structures/discover.py +623 -0
  26. flashrt_structures/explain.py +70 -0
  27. flashrt_structures/frontdoor.py +572 -0
  28. flashrt_structures/gates.py +465 -0
  29. flashrt_structures/guard.py +421 -0
  30. flashrt_structures/handle.py +189 -0
  31. flashrt_structures/impls/__init__.py +219 -0
  32. flashrt_structures/impls/adaln_producer/__init__.py +8 -0
  33. flashrt_structures/impls/adaln_producer/broker.py +116 -0
  34. flashrt_structures/impls/adaln_producer/fused.py +388 -0
  35. flashrt_structures/impls/adarms_stack/__init__.py +8 -0
  36. flashrt_structures/impls/adarms_stack/fp8_chain.py +832 -0
  37. flashrt_structures/impls/adarms_stack/region.py +102 -0
  38. flashrt_structures/impls/attention_core/__init__.py +132 -0
  39. flashrt_structures/impls/attention_core/fa2_seqused.py +458 -0
  40. flashrt_structures/impls/attention_core/fa4_cute.py +154 -0
  41. flashrt_structures/impls/attention_core/fa4_fp8.py +178 -0
  42. flashrt_structures/impls/attention_core/masked_mha.py +158 -0
  43. flashrt_structures/impls/attention_core/two_way_fa2.py +220 -0
  44. flashrt_structures/impls/cadence_static/__init__.py +18 -0
  45. flashrt_structures/impls/cadence_static/buffers.py +122 -0
  46. flashrt_structures/impls/cadence_static/cross_attention.py +187 -0
  47. flashrt_structures/impls/chain_elements.py +89 -0
  48. flashrt_structures/impls/decode_loop/__init__.py +0 -0
  49. flashrt_structures/impls/decode_loop/fp8_kv.py +206 -0
  50. flashrt_structures/impls/decode_loop/mtp_speculative.py +245 -0
  51. flashrt_structures/impls/decode_loop/whole_step.py +852 -0
  52. flashrt_structures/impls/decoder_block/__init__.py +6 -0
  53. flashrt_structures/impls/decoder_block/attn_sublayer.py +110 -0
  54. flashrt_structures/impls/decoder_block/fused.py +167 -0
  55. flashrt_structures/impls/decoder_ffn/__init__.py +0 -0
  56. flashrt_structures/impls/decoder_ffn/fp8_static.py +310 -0
  57. flashrt_structures/impls/decoder_ffn/fp8_static.yaml +22 -0
  58. flashrt_structures/impls/decoder_ffn/w4a16_static.py +221 -0
  59. flashrt_structures/impls/decoder_ffn/w8a16_static.py +183 -0
  60. flashrt_structures/impls/dit_stack/__init__.py +11 -0
  61. flashrt_structures/impls/dit_stack/fp4_chain.py +417 -0
  62. flashrt_structures/impls/dit_stack/region.py +86 -0
  63. flashrt_structures/impls/fixed_iter/__init__.py +29 -0
  64. flashrt_structures/impls/fixed_iter/openpi.py +264 -0
  65. flashrt_structures/impls/fixed_iter/protocol.py +94 -0
  66. flashrt_structures/impls/gated_delta_core/__init__.py +3 -0
  67. flashrt_structures/impls/gated_delta_core/fused_layer.py +545 -0
  68. flashrt_structures/impls/gated_delta_core/hub_v3.py +152 -0
  69. flashrt_structures/impls/graph_lowering/__init__.py +27 -0
  70. flashrt_structures/impls/graph_lowering/pi052_denoise.py +179 -0
  71. flashrt_structures/impls/graph_lowering/protocol.py +76 -0
  72. flashrt_structures/impls/graph_lowering/qwen3_vl.py +364 -0
  73. flashrt_structures/impls/linear_proj/__init__.py +0 -0
  74. flashrt_structures/impls/linear_proj/fp8_static.py +270 -0
  75. flashrt_structures/impls/linear_proj/nvfp4_balance.py +131 -0
  76. flashrt_structures/impls/linear_proj/nvfp4_dynamic.py +182 -0
  77. flashrt_structures/impls/linear_proj/w8a16_static.py +230 -0
  78. flashrt_structures/impls/modnorm_qkv_chain/__init__.py +0 -0
  79. flashrt_structures/impls/modnorm_qkv_chain/fp8_ptok_table.py +291 -0
  80. flashrt_structures/impls/moe_experts/__init__.py +9 -0
  81. flashrt_structures/impls/moe_experts/nvfp4_dynamic.py +208 -0
  82. flashrt_structures/impls/moe_experts/nvfp4_w4a16.py +129 -0
  83. flashrt_structures/impls/norm_fused/__init__.py +3 -0
  84. flashrt_structures/impls/norm_fused/bf16.py +94 -0
  85. flashrt_structures/impls/norm_fused/fp8_producer.py +84 -0
  86. flashrt_structures/impls/patch_projection/__init__.py +3 -0
  87. flashrt_structures/impls/patch_projection/bf16_flat.py +139 -0
  88. flashrt_structures/impls/prefill_tower/__init__.py +10 -0
  89. flashrt_structures/impls/prefill_tower/fp8_chain.py +955 -0
  90. flashrt_structures/impls/prefill_tower/region.py +99 -0
  91. flashrt_structures/impls/qk_norm_rope/__init__.py +12 -0
  92. flashrt_structures/impls/qk_norm_rope/per_head_gqa.py +199 -0
  93. flashrt_structures/impls/qk_norm_rope/projection_bf16.py +165 -0
  94. flashrt_structures/impls/qkv_pack/__init__.py +5 -0
  95. flashrt_structures/impls/qkv_pack/bf16.py +110 -0
  96. flashrt_structures/impls/qkv_pack/fp8_static.py +435 -0
  97. flashrt_structures/impls/qkv_pack/nvfp4_balance.py +218 -0
  98. flashrt_structures/impls/qkv_rope/__init__.py +3 -0
  99. flashrt_structures/impls/qkv_rope/packed_bias_bf16.py +143 -0
  100. flashrt_structures/impls/step_table.py +113 -0
  101. flashrt_structures/impls/vision_ffn/__init__.py +0 -0
  102. flashrt_structures/impls/vision_ffn/fp8_static.py +261 -0
  103. flashrt_structures/impls/vision_ffn/nvfp4_balance.py +211 -0
  104. flashrt_structures/impls/vision_tower/__init__.py +7 -0
  105. flashrt_structures/impls/vision_tower/fp8_chain.py +533 -0
  106. flashrt_structures/impls/vision_tower/region.py +91 -0
  107. flashrt_structures/matrix.py +126 -0
  108. flashrt_structures/points.py +368 -0
  109. flashrt_structures/prequantized.py +131 -0
  110. flashrt_structures/quantize_on_adopt.py +94 -0
  111. flashrt_structures/recipe.py +438 -0
  112. flashrt_structures/regions.py +208 -0
  113. flashrt_structures/schemes.py +490 -0
  114. flashrt_structures/stages.py +298 -0
  115. flashrt_structures/storage.py +255 -0
  116. flashrt_structures/swap.py +398 -0
  117. flashrt_structures/workspace.py +110 -0
  118. flashrt_structures-0.2.0.dist-info/METADATA +140 -0
  119. flashrt_structures-0.2.0.dist-info/RECORD +122 -0
  120. flashrt_structures-0.2.0.dist-info/WHEEL +5 -0
  121. flashrt_structures-0.2.0.dist-info/licenses/LICENSE +202 -0
  122. flashrt_structures-0.2.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,955 @@
1
+ """The fused static-FP8 launch chain over a plain-norm prefill tower.
2
+
3
+ Per layer: RMSNorm→FP8 (the host's ``(1+w)`` folded into the kernel's
4
+ weight), one merged-QKV FP8 GEMM, split+RoPE into a chain-owned
5
+ cache, dense non-causal attention over exactly the used keys (pads
6
+ trail, so a used-key count carries the host's mask), FP8 output
7
+ projection, and a fused residual+RMSNorm→FP8 into the merged gate/up
8
+ GEMM. The keys are un-permuted back to host rotate-half layout and
9
+ appended to the host's own cache object — the tower's whole product
10
+ is that cache, and every downstream reader keeps its contract.
11
+
12
+ Same equivalences as the sibling conditioned-stack chain (shared
13
+ helpers): the rotate-half↔adjacent-pair permutation on q/k rows, the
14
+ probe-calibrated activation scales, the attention ladder. The mask
15
+ fact here is simpler: one valid-query row names the used-key run;
16
+ pad-query rows are garbage-in-garbage-out by construction (their
17
+ hidden states feed only pad positions, their keys are masked by
18
+ every downstream mask).
19
+ """
20
+
21
+ from __future__ import annotations
22
+
23
+ import types
24
+ from typing import Any, Callable
25
+
26
+ import torch
27
+
28
+ from .. import KernelUnavailable, hub_kernel
29
+ from ...guard import GuardedSeam
30
+ from ..adarms_stack.fp8_chain import _make_attend
31
+ from ..chain_elements import (
32
+ ATTN_RUNGS, FP8_MAX, attention_rungs as _attention_rungs,
33
+ cache_kv as _cache_kv, fp8_weight as _fp8_weight,
34
+ gelu_tanh_like as _gelu_tanh_like,
35
+ interleave_rows as _interleave_rows)
36
+
37
+ GEMM_PACKAGE = "flashrt/fp8-gemm"
38
+ NORM_PACKAGE = "flashrt/flashrt-residual-norm-quant"
39
+ ROPE_PACKAGE = "flashrt/flashrt-qkv-cache-rope"
40
+ FFN_PACKAGE = "flashrt/transformer-fused-ops"
41
+ GEMM_SYMBOLS = ("fp8_linear_bf16",)
42
+ NORM_SYMBOLS = ("rms_norm_quant_fp8_static_bf16",
43
+ "residual_add_rms_norm_quant_fp8_static_bf16")
44
+ ROPE_SYMBOLS = ("qkv_split_rope_kvcache_bf16",)
45
+ FFN_SYMBOLS = ("gate_geglu_merged_quant_fp8_static_bf16",
46
+ "quantize_fp8_static_bf16")
47
+ FP4_GEMM_PACKAGE = "flashrt/fp4-gemm"
48
+ FP4_FUSE_PACKAGE = "flashrt/fp4-fused-ops"
49
+
50
+ #: the band table IS the recipe (same convention as the decoder
51
+ #: stack). The ``fp4`` row is the native encoder preset: the FFN pair
52
+ #: and the attention output projection ride NVFP4 with dynamic block
53
+ #: scales, QKV stays static FP8. The row qualifies when the fused
54
+ #: GEGLU producer ships a bf16 entry and the FP4 GEMM accepts the
55
+ #: prefix row band (a bind-time functional probe, not a device list).
56
+ BANDS: dict[str, dict] = {
57
+ "fp8": {"packages": (), "precision_rank": 0, "awq": 0.0},
58
+ "fp4": {"packages": (
59
+ (FP4_GEMM_PACKAGE, ("nvfp4_gemm_bias_bf16",
60
+ "quantize_fp4_sfa_bf16")),
61
+ (FP4_FUSE_PACKAGE,
62
+ ("residual_add_rms_norm_quant_nvfp4_swizzled_bf16",
63
+ "gelu_mul_nvfp4_bf16"))),
64
+ "precision_rank": 1, "awq": 0.8, "smoke_floor": 0.95},
65
+ # the native published-tier P1 form (epilogue_hw): the gate/up
66
+ # weight is pairwise row-interleaved with the down-projection's AWQ
67
+ # 1/s folded into the up rows at pack time, ONE GEMM computes
68
+ # gelu(gate)*up in the epilogue and writes the down GEMM's packed
69
+ # FP4 input directly — the bf16 hidden intermediate, its quantize
70
+ # round-trip, and the separate combiner all leave the chain
71
+ "fp4_p1": {"packages": (
72
+ (FP4_GEMM_PACKAGE, ("nvfp4_gemm_bias_bf16",
73
+ "nvfp4_gemm_geglu_nvfp4_fp16",
74
+ "quantize_fp4_sfa_bf16")),
75
+ (FP4_FUSE_PACKAGE,
76
+ ("residual_add_rms_norm_quant_nvfp4_swizzled_bf16",))),
77
+ # floor provenance: this band's own measured pair — tower smoke
78
+ # 0.796 at 17-layer coverage judged E2E captured-parity 0.99660
79
+ # PASS (the reference tier's own raw cosine sits at 0.9975).
80
+ # The old 0.95 floor's failing pair (smoke 0.90 -> E2E 0.742)
81
+ # came from the retired merged-GEMM form and does not transfer.
82
+ # The arm's 0.99 end-to-end parity gate stays the judge.
83
+ "precision_rank": 1, "awq": 0.8, "smoke_floor": 0.75,
84
+ "fp4_layers": "all_but_last"},
85
+ # the native constructor's precision-safe preset, verbatim:
86
+ # fp4_layers=(7, 8, 9) — the middle encoder FFN band. Floor
87
+ # calibrated per coverage (the gate scales with layer count):
88
+ # measured smoke 0.938 at 3-layer coverage judged E2E
89
+ # captured-parity 0.99828 PASS, while the 0.95 floor's provenance
90
+ # (smoke 0.90 -> E2E 0.742) came from a 15-layer arm and does not
91
+ # transfer to a 3-layer preset.
92
+ "fp4_p1_mid": {"packages": (
93
+ (FP4_GEMM_PACKAGE, ("nvfp4_gemm_bias_bf16",
94
+ "nvfp4_gemm_geglu_nvfp4_fp16",
95
+ "quantize_fp4_sfa_bf16")),
96
+ (FP4_FUSE_PACKAGE,
97
+ ("residual_add_rms_norm_quant_nvfp4_swizzled_bf16",))),
98
+ "precision_rank": 1, "awq": 0.8, "smoke_floor": 0.92,
99
+ "fp4_layers": (7, 8, 9)},
100
+ }
101
+
102
+ #: whole-tower smoke over hidden states and every layer's cached K/V
103
+ #: — a min over ~37 tensors after 18 residual layers of static FP8,
104
+ #: so the compounding tail sits lower than a single-output floor
105
+ #: (measured: worst deep-layer V ≈0.97, hidden ≈0.96, while the
106
+ #: end-to-end action parity the arm gates on holds ≥0.9999). The
107
+ #: arm's 0.99 parity gate stays the judge.
108
+ SMOKE_FLOOR = 0.95
109
+
110
+ #: transition rung (author-gated): a native kernel module whose
111
+ #: cutlass_fp8_*_bf16out entries serve the rows the hub entry refuses.
112
+ #: Test-only — the hub rung wins the moment its package covers the
113
+ #: band, with no code change here.
114
+ FVK_SO_ENV = "FRT_FVK_SO"
115
+ _FVK_SITE = {"qkv": "cutlass_fp8_sq_bf16out",
116
+ "o": "cutlass_fp8_sq_bf16out",
117
+ "gu": "cutlass_fp8_t1_bf16out",
118
+ "dn": "cutlass_fp8_wide_bf16out"}
119
+
120
+
121
+ def _load_fvk():
122
+ import importlib.util
123
+ import os
124
+ so = os.environ.get(FVK_SO_ENV)
125
+ if not so or not os.path.exists(so):
126
+ return None
127
+ spec = importlib.util.spec_from_file_location(
128
+ "flash_rt_kernels", so)
129
+ mod = importlib.util.module_from_spec(spec)
130
+ spec.loader.exec_module(mod)
131
+ return mod
132
+
133
+
134
+ def missing_symbols(band: str = "fp8") -> list[str]:
135
+ gaps: list[str] = []
136
+ for repo, symbols in ((GEMM_PACKAGE, GEMM_SYMBOLS),
137
+ (NORM_PACKAGE, NORM_SYMBOLS),
138
+ (ROPE_PACKAGE, ROPE_SYMBOLS),
139
+ (FFN_PACKAGE, FFN_SYMBOLS)
140
+ ) + BANDS[band]["packages"]:
141
+ try:
142
+ kern = hub_kernel(repo, ">=1")
143
+ except KernelUnavailable:
144
+ gaps.append(repo)
145
+ continue
146
+ gaps.extend(f"{repo}:{s}" for s in symbols
147
+ if not hasattr(kern, s))
148
+ if not _attention_rungs():
149
+ gaps.append("attention: " + " or ".join(
150
+ r[1] for r in ATTN_RUNGS))
151
+ return gaps
152
+
153
+
154
+ class BoundPrefillFp8Chain(GuardedSeam, torch.nn.Module):
155
+ """Bind-time state: FP8 weights, folded norm weights, caches."""
156
+
157
+ _frt_can_fallback = False
158
+
159
+ def __init__(self) -> None:
160
+ super().__init__()
161
+ self.table: list[dict] = []
162
+ self.dims: dict = {}
163
+ self.buf: dict = {}
164
+ self.rope = None
165
+ self.scaling = 1.0
166
+ self.eps = 1e-6
167
+ self.s_used = 0
168
+ self.out_ctor = None
169
+ self.kperm = None
170
+ self.kperm_inv = None
171
+ self.final_w = None
172
+ self.cache_type = None
173
+ self.kernels: dict = {}
174
+ self.band = "fp8"
175
+ #: region wire (armed by autobuild): per-layer (k, v) sink
176
+ #: views of a bound consumer's chain caches. The tower's K is
177
+ #: already in chain layout (same split kernel, same adjacent-
178
+ #: pair convention), so writing the sink is the identity of
179
+ #: the consumer's own gather — the consumer drops it in-graph.
180
+ self.prefix_sinks = None
181
+
182
+
183
+ def _plain_norm_weight(norm) -> torch.Tensor | None:
184
+ """The affine vector of an unconditioned RMS norm, or None."""
185
+ if getattr(norm, "dense", None) is not None:
186
+ return None
187
+ w = getattr(norm, "weight", None)
188
+ if w is None or getattr(w, "ndim", 0) != 1:
189
+ return None
190
+ return w
191
+
192
+
193
+ def _stack_parts(stack):
194
+ layers = list(stack.layers)
195
+ attn = layers[0].self_attn
196
+ head_dim = getattr(attn, "head_dim", None)
197
+ if not isinstance(head_dim, int):
198
+ raise ValueError("attention exposes no integer head_dim")
199
+ nh = attn.q_proj.out_features // head_dim
200
+ kv = attn.k_proj.out_features // head_dim
201
+ dim = attn.q_proj.in_features
202
+ hidden = layers[0].mlp.gate_proj.out_features
203
+ return layers, nh, kv, head_dim, dim, hidden
204
+
205
+
206
+ def _prefill_mask_facts(mask: torch.Tensor, seq: int) -> int | None:
207
+ """One valid-query row names the used-key run ``[0, s_used)``."""
208
+ if mask.dim() != 4 or mask.shape[0] != 1 or mask.shape[-1] != seq:
209
+ return None
210
+ rows = mask[0, 0] if mask.shape[1] == 1 else mask[0, :1][0]
211
+ if rows.shape[-2] != seq:
212
+ return None
213
+ row = rows[0] == 0
214
+ s_used = int(row.sum())
215
+ if s_used < 1 or not bool(row[:s_used].all()):
216
+ return None
217
+ return s_used
218
+
219
+
220
+ def _build_rope(bound, stack, position_ids) -> bool:
221
+ hd = bound.dims["hd"]
222
+ half = hd // 2
223
+ dummy = torch.zeros(1, position_ids.shape[1], hd, device="cuda",
224
+ dtype=torch.float32)
225
+ cos, sin = stack.rotary_emb(dummy, position_ids.to("cuda"))
226
+ cos, sin = cos[0].float(), sin[0].float()
227
+ if not torch.allclose(cos[:, :half], cos[:, half:], atol=1e-5):
228
+ return False
229
+ rope = torch.empty(position_ids.shape[1], hd, device="cuda",
230
+ dtype=torch.bfloat16)
231
+ rope[:, 0::2] = cos[:, :half].to(torch.bfloat16)
232
+ rope[:, 1::2] = sin[:, :half].to(torch.bfloat16)
233
+ bound.rope = rope
234
+ return True
235
+
236
+
237
+ @torch.no_grad()
238
+ def _interleave_gu_rows(g16: torch.Tensor, u16: torch.Tensor,
239
+ inv_s_dn: torch.Tensor | None = None
240
+ ) -> torch.Tensor:
241
+ """Pairwise interleave gate/up rows along N for the fused GeGLU
242
+ epilogue GEMM (il[2j] = gate[j], il[2j+1] = up[j]) — the native
243
+ pack, verbatim. Any per-output-column scale must live in the
244
+ weights because the epilogue applies no per-column vector; the
245
+ down-projection AWQ inv_s is folded into the up rows
246
+ (gelu(g) * u * inv_s == gelu(g) * (u * inv_s))."""
247
+ if inv_s_dn is not None:
248
+ u16 = (u16.float() * inv_s_dn.float().unsqueeze(1)).to(u16.dtype)
249
+ il = torch.empty(2 * g16.shape[0], g16.shape[1],
250
+ dtype=g16.dtype, device=g16.device)
251
+ il[0::2] = g16
252
+ il[1::2] = u16
253
+ return il.contiguous()
254
+
255
+
256
+ def _awq_scale(chan_amax: torch.Tensor, alpha: float) -> torch.Tensor:
257
+ """The native per-input-channel AWQ pre-scale, verbatim:
258
+ ``s = (a / a.mean())^alpha`` clamped to [0.25, 4]. The GEMM columns
259
+ carry ``s``; whichever element feeds the GEMM carries ``1/s`` —
260
+ the math is preserved exactly, only the quantizer sees a tamer
261
+ channel spread."""
262
+ a = chan_amax.float().clamp(min=1e-6)
263
+ return (a / a.mean()).pow(alpha).clamp(min=0.25, max=4.0)
264
+
265
+
266
+ def _quantize(bound, layers, amax, chan=None) -> None:
267
+ nh, kv, hd = (bound.dims[k] for k in ("nh", "kv", "hd"))
268
+ fp4 = BANDS[bound.band]["packages"] != ()
269
+ alpha = BANDS[bound.band].get("awq", 0.0)
270
+ quant4 = (bound.kernels["kg4"].quantize_fp4_sfa_bf16
271
+ if fp4 else None)
272
+ # data-driven layer subset (the native preset runs 17 of 18): a
273
+ # layer whose down-projection input carries a >20x-median channel
274
+ # outlier stays on the calibrated FP8 form; the receipt records
275
+ # which layers rode the band
276
+ import os as _os3
277
+ skip: set = set()
278
+ preset = BANDS[bound.band].get("fp4_layers")
279
+ if preset == "all_but_last":
280
+ # the native published-tier preset: fp4_layers = range(17) —
281
+ # every layer except the last rides FP4, no data-driven subset
282
+ skip = {len(layers) - 1}
283
+ elif preset is not None:
284
+ skip = set(range(len(layers))) - set(preset)
285
+ else:
286
+ outlier = float(_os3.environ.get("FRT_PREFILL_FP4_OUTLIER",
287
+ "20"))
288
+ if fp4 and chan is not None:
289
+ for i in range(len(layers)):
290
+ v = chan.get((i, "dn"))
291
+ if v is not None and float(v.max()) > outlier * float(
292
+ v.median()):
293
+ skip.add(i)
294
+ bound.dims["fp4_skipped"] = sorted(skip)
295
+ for i, ly in enumerate(layers):
296
+ attn, mlp = ly.self_attn, ly.mlp
297
+ a_qkv, a_o, a_gu, a_dn = (amax[(i, s)] / FP8_MAX for s in
298
+ ("qkv", "o", "gu", "dn"))
299
+ fold_in = (1.0 + ly.input_layernorm.weight.detach()
300
+ .float()).to(attn.q_proj.weight.device)
301
+ fold_post = (1.0 + ly.post_attention_layernorm.weight.detach()
302
+ .float()).to(attn.q_proj.weight.device)
303
+ qkv_w = torch.cat([
304
+ _interleave_rows(attn.q_proj.weight, nh, hd),
305
+ _interleave_rows(attn.k_proj.weight, kv, hd),
306
+ attn.v_proj.weight], dim=0).float() * fold_in[None, :]
307
+ gu_w = torch.cat([mlp.gate_proj.weight, mlp.up_proj.weight],
308
+ dim=0).float() * fold_post[None, :]
309
+ entry: dict[str, Any] = {}
310
+ for name, w, act in (("qkv", qkv_w, a_qkv),
311
+ ("o", attn.o_proj.weight, a_o),
312
+ ("gu", gu_w, a_gu),
313
+ ("dn", mlp.down_proj.weight, a_dn)):
314
+ if fp4 and name != "qkv" and i not in skip:
315
+ # the native encoder preset: FFN pair and the output
316
+ # projection ride NVFP4 dynamic block scales, with the
317
+ # AWQ pre-scale carried by whatever feeds each GEMM —
318
+ # gu's 1/s by the norm producer's weight vector, dn's
319
+ # 1/s by the up rows it multiplies through
320
+ wq = w.detach().float().to("cuda")
321
+ il_hw = BANDS[bound.band].get("fp4_layers") is not None
322
+ if alpha and name == "gu" and chan is not None:
323
+ H = wq.shape[0] // 2
324
+ s_gu = _awq_scale(chan[(i, "gu")], alpha)
325
+ wq = wq * s_gu[None, :]
326
+ entry["inv_s_gu"] = (1.0 / s_gu).to(
327
+ torch.bfloat16).contiguous()
328
+ s_dn = _awq_scale(chan[(i, "dn")], alpha)
329
+ if il_hw:
330
+ # native il pack: dn's 1/s folds into the up
331
+ # rows at interleave time, not at runtime
332
+ entry["inv_s_dn"] = (1.0 / s_dn).to(
333
+ torch.float16).contiguous()
334
+ else:
335
+ wq[H:] = wq[H:] / s_dn[:, None]
336
+ entry["s_dn"] = s_dn
337
+ if alpha and name == "dn" and chan is not None:
338
+ wq = wq * entry["s_dn"][None, :]
339
+ mse = (None if il_hw else
340
+ getattr(bound.kernels["kg4"],
341
+ "quantize_fp4_sfa_mse_fp16", None))
342
+
343
+ def _pack_fp4(mat):
344
+ if mse is not None:
345
+ # the archived fp4 band's per-block MSE scales;
346
+ # the native published tier quantizes plain RTN
347
+ return mse(mat.to(torch.float16).contiguous(),
348
+ is_sfb=True)
349
+ return quant4(mat.to(torch.bfloat16).contiguous(),
350
+ is_sfb=True)
351
+
352
+ if il_hw and name == "gu":
353
+ H = wq.shape[0] // 2
354
+ entry["gu_il"] = _pack_fp4(_interleave_gu_rows(
355
+ wq[:H].contiguous(), wq[H:].contiguous(),
356
+ entry.get("inv_s_dn")))
357
+ continue
358
+ entry[name] = _pack_fp4(wq)
359
+ continue
360
+ packed, w_scale = _fp8_weight(w)
361
+ entry[name] = packed
362
+ entry[f"a_{name}"] = act * w_scale
363
+ entry["sc_qkv"] = torch.tensor([a_qkv], device="cuda",
364
+ dtype=torch.float32)
365
+ entry["sc_gu"] = torch.tensor([a_gu], device="cuda",
366
+ dtype=torch.float32)
367
+ entry["inv_o"] = 1.0 / a_o if a_o > 0 else 1.0
368
+ entry["inv_dn"] = 1.0 / a_dn if a_dn > 0 else 1.0
369
+ def _t(v):
370
+ return torch.tensor([v], device="cuda",
371
+ dtype=torch.float32)
372
+ if "a_gu" in entry:
373
+ entry["t_wsc_gu"] = _t(entry["a_gu"] / a_gu)
374
+ entry["t_sc_dn"] = _t(a_dn)
375
+ if "a_dn" in entry:
376
+ entry["t_wsc_dn"] = _t(entry["a_dn"] / a_dn)
377
+ entry["t_sc_o"] = _t(a_o)
378
+ bound.table.append(entry)
379
+
380
+
381
+ def _alloc(bound) -> None:
382
+ S, D, nh, kv, hd, H = (bound.dims[k] for k in
383
+ ("seq", "dim", "nh", "kv", "hd", "hidden"))
384
+ dev, bf = "cuda", torch.bfloat16
385
+ b = bound.buf
386
+ b["res"] = torch.empty(S, D, device=dev, dtype=bf)
387
+ b["xn8"] = torch.empty(S, D, device=dev, dtype=torch.float8_e4m3fn)
388
+ b["qkv"] = torch.empty(S, (nh + 2 * kv) * hd, device=dev, dtype=bf)
389
+ b["q"] = torch.empty(1, S, nh, hd, device=dev, dtype=bf)
390
+ kc = torch.zeros(1, S, kv, hd, device=dev, dtype=bf)
391
+ vc = torch.zeros(1, S, kv, hd, device=dev, dtype=bf)
392
+ L = bound.dims["layers"]
393
+ b["kc"] = [kc] * L
394
+ b["vc"] = [vc] * L
395
+ b["fg"] = torch.empty(S, D, device=dev, dtype=bf)
396
+ b["gu"] = torch.empty(S, 2 * H, device=dev, dtype=bf)
397
+ b["hid8"] = torch.empty(S, H, device=dev,
398
+ dtype=torch.float8_e4m3fn)
399
+ b["o8"] = torch.empty(S, nh * hd, device=dev,
400
+ dtype=torch.float8_e4m3fn)
401
+ b["seqused"] = torch.full((1,), bound.s_used, device=dev,
402
+ dtype=torch.int32)
403
+ b["ones_w"] = torch.ones(D, device=dev, dtype=bf)
404
+ if BANDS[bound.band]["packages"] != ():
405
+ quant4 = bound.kernels["kg4"].quantize_fp4_sfa_bf16
406
+ b["zero_x"] = torch.zeros(S, D, device=dev, dtype=bf)
407
+ b["xp4"], b["xsf4"] = quant4(b["zero_x"])
408
+ b["op4"], b["osf4"] = quant4(
409
+ torch.zeros(S, nh * hd, device=dev, dtype=bf))
410
+ b["hp4"], b["hsf4"] = quant4(
411
+ torch.zeros(S, H, device=dev, dtype=bf))
412
+ b["zb"] = {n: torch.zeros(n, device=dev, dtype=bf)
413
+ for n in (2 * H, D)}
414
+ if BANDS[bound.band].get("fp4_layers") is not None:
415
+ b["il_scratch"] = torch.empty(S, H, device=dev,
416
+ dtype=torch.uint8)
417
+ b["out_full"] = torch.zeros(bound.dims["seq_full"], D, device=dev,
418
+ dtype=bf)
419
+ b["att"] = torch.empty(1, S, nh, hd, device=dev, dtype=bf)
420
+
421
+
422
+ def _make_run(bound: BoundPrefillFp8Chain):
423
+ kg = bound.kernels["kg"]
424
+ kn = bound.kernels["kn"]
425
+ kr = bound.kernels["kr"]
426
+ kf = bound.kernels["kf"]
427
+ attend = bound.kernels["attend"]
428
+ S, D, nh, kv, hd, H, L = (bound.dims[k] for k in
429
+ ("seq", "dim", "nh", "kv", "hd",
430
+ "hidden", "layers"))
431
+ b = bound.buf
432
+ table = bound.table
433
+ eps = bound.eps
434
+ qkv3 = b["qkv"].view(1, S, (nh + 2 * kv) * hd)
435
+ fp8 = torch.float8_e4m3fn
436
+ kperm_inv = bound.kperm_inv
437
+ kh = b["kc"][0].view(S, hd)
438
+
439
+ gemm = bound.kernels["gemm"]
440
+
441
+ if BANDS[bound.band]["packages"] != ():
442
+ kg4 = bound.kernels["kg4"]
443
+ kf4 = bound.kernels["kf4"]
444
+ gemm4 = kg4.nvfp4_gemm_bias_bf16
445
+ quant4 = kg4.quantize_fp4_sfa_bf16
446
+ norm4 = kf4.residual_add_rms_norm_quant_nvfp4_swizzled_bf16
447
+ xp4, xsf4 = b["xp4"], b["xsf4"]
448
+ op4, osf4 = b["op4"], b["osf4"]
449
+ hp4, hsf4 = b["hp4"], b["hsf4"]
450
+ zb = b["zb"]
451
+
452
+ def out_project(att2, e):
453
+ if not isinstance(e["o"], tuple):
454
+ kf.quantize_fp8_static_bf16(att2, e["t_sc_o"],
455
+ out=b["o8"])
456
+ gemm(e, "o", b["o8"], b["fg"])
457
+ return
458
+ quant4(att2, op4, osf4)
459
+ gemm4(op4, e["o"][0], osf4, e["o"][1], zb[D], out=b["fg"])
460
+
461
+ def _ffn_fp8(res, e):
462
+ # an outlier layer kept on the calibrated FP8 form
463
+ kn.rms_norm_quant_fp8_static_bf16(
464
+ res, b["ones_w"], e["sc_gu"], eps, out=b["xn8"])
465
+ gemm(e, "gu", b["xn8"], b["gu"])
466
+ kf.gate_geglu_merged_quant_fp8_static_bf16(
467
+ b["gu"], e["t_sc_dn"], out=b["hid8"])
468
+ gemm(e, "dn", b["hid8"], b["fg"])
469
+
470
+ if BANDS[bound.band].get("fp4_layers") is not None:
471
+ geglu_hw = kg4.nvfp4_gemm_geglu_nvfp4_fp16
472
+ il_scr = b["il_scratch"]
473
+
474
+ def ffn_project(res, e):
475
+ if "gu_il" not in e:
476
+ _ffn_fp8(res, e)
477
+ return
478
+ w_gu = e.get("inv_s_gu")
479
+ norm4(res, b["zero_x"],
480
+ w_gu if w_gu is not None else b["ones_w"], eps,
481
+ packed=xp4, sfa=xsf4)
482
+ # skinny=False: the encoder-M schedule (element-benched
483
+ # 301us vs the narrow-N decoder schedule's 484us at
484
+ # M=657 x 2H=32768 x K=2048)
485
+ geglu_hw(xp4, e["gu_il"][0], xsf4, e["gu_il"][1],
486
+ skinny=False, scratch=il_scr,
487
+ out_packed=hp4, out_sfa=hsf4)
488
+ gemm4(hp4, e["dn"][0], hsf4, e["dn"][1], zb[D],
489
+ out=b["fg"])
490
+ else:
491
+ geglu4 = kf4.gelu_mul_nvfp4_bf16
492
+
493
+ def ffn_project(res, e):
494
+ if not isinstance(e.get("gu"), tuple):
495
+ _ffn_fp8(res, e)
496
+ return
497
+ # x=0 keeps the residual untouched; the producer emits
498
+ # rms(res) straight to packed FP4 for the gate/up GEMM.
499
+ # Its weight vector doubles as the AWQ 1/s carrier.
500
+ w_gu = e.get("inv_s_gu")
501
+ norm4(res, b["zero_x"],
502
+ w_gu if w_gu is not None else b["ones_w"], eps,
503
+ packed=xp4, sfa=xsf4)
504
+ gemm4(xp4, e["gu"][0], xsf4, e["gu"][1], zb[2 * H],
505
+ out=b["gu"])
506
+ geglu4(b["gu"], packed=hp4, sfa=hsf4)
507
+ gemm4(hp4, e["dn"][0], hsf4, e["dn"][1], zb[D],
508
+ out=b["fg"])
509
+ else:
510
+ def out_project(att2, e):
511
+ kf.quantize_fp8_static_bf16(att2, e["t_sc_o"],
512
+ out=b["o8"])
513
+ gemm(e, "o", b["o8"], b["fg"])
514
+
515
+ def ffn_project(res, e):
516
+ kn.rms_norm_quant_fp8_static_bf16(
517
+ res, b["ones_w"], e["sc_gu"], eps, out=b["xn8"])
518
+ gemm(e, "gu", b["xn8"], b["gu"])
519
+ kf.gate_geglu_merged_quant_fp8_static_bf16(
520
+ b["gu"], e["t_sc_dn"], out=b["hid8"])
521
+ gemm(e, "dn", b["hid8"], b["fg"])
522
+
523
+ rf = torch.profiler.record_function
524
+
525
+ S_full = bound.dims["seq_full"]
526
+
527
+ def run(x2d, pkv):
528
+ res = b["res"]
529
+ res.copy_(x2d[:S])
530
+ for l in range(L):
531
+ e = table[l]
532
+ if l == 0:
533
+ kn.rms_norm_quant_fp8_static_bf16(
534
+ res, b["ones_w"], e["sc_qkv"], eps, out=b["xn8"])
535
+ gemm(e, "qkv", b["xn8"], b["qkv"])
536
+ with rf("pf:rope"):
537
+ kr.qkv_split_rope_kvcache_bf16(
538
+ qkv3, bound.rope, nh, kv, hd, 0, q_out=b["q"],
539
+ k_cache=b["kc"][0], v_cache=b["vc"][0],
540
+ max_seq_len=S)
541
+ if bound.prefix_sinks is not None:
542
+ with rf("pf:wire"):
543
+ dk, dv = bound.prefix_sinks[l]
544
+ dk.copy_(kh)
545
+ dv.copy_(b["vc"][0].view(S, hd))
546
+ if pkv is not None:
547
+ # fresh tensors per layer: the cache keeps references,
548
+ # and the shared buffers are overwritten next layer
549
+ with rf("pf:cache"):
550
+ k_host = torch.index_select(kh, -1, kperm_inv)
551
+ pkv.update(k_host.view(1, 1, S, hd),
552
+ b["vc"][0].reshape(1, 1, S, hd)
553
+ .clone(), l)
554
+ with rf("pf:attn"):
555
+ att2 = attend(l)
556
+ with rf("pf:o"):
557
+ out_project(att2, e)
558
+ res.add_(b["fg"])
559
+ ffn_project(res, e)
560
+ if l < L - 1:
561
+ nxt = table[l + 1]
562
+ kn.residual_add_rms_norm_quant_fp8_static_bf16(
563
+ res, b["fg"], b["ones_w"], nxt["sc_qkv"], eps,
564
+ out=b["xn8"])
565
+ else:
566
+ res.add_(b["fg"])
567
+ fin = res.float()
568
+ fin = fin * torch.rsqrt(fin.square().mean(-1, keepdim=True)
569
+ + eps)
570
+ b["out_full"][:S] = (fin * bound.final_w).to(torch.bfloat16)
571
+ return bound.out_ctor(
572
+ last_hidden_state=b["out_full"].view(1, S_full, D),
573
+ past_key_values=pkv)
574
+
575
+ return run
576
+
577
+
578
+ def bind_prefill_fp8_chain(model, root: str,
579
+ probe: Callable[[], Any],
580
+ band: str = "fp8") -> dict:
581
+ """Bind the chain onto the tower at ``root``; adapter contract out."""
582
+ try:
583
+ kg = hub_kernel(GEMM_PACKAGE, ">=1")
584
+ kn = hub_kernel(NORM_PACKAGE, ">=1")
585
+ kr = hub_kernel(ROPE_PACKAGE, ">=1")
586
+ kf = hub_kernel(FFN_PACKAGE, ">=1")
587
+ kg4 = kf4 = None
588
+ if BANDS[band]["packages"]:
589
+ kg4 = hub_kernel(FP4_GEMM_PACKAGE, ">=1")
590
+ kf4 = hub_kernel(FP4_FUSE_PACKAGE, ">=1")
591
+ except KernelUnavailable as exc:
592
+ return {"refused": f"prefill_{band}_chain: {exc}"}
593
+ rungs = _attention_rungs()
594
+ gaps = missing_symbols(band=band)
595
+ if gaps:
596
+ return {"refused": "prefill_fp8_chain missing: "
597
+ f"{', '.join(gaps)}"}
598
+
599
+ stack = model.get_submodule(root) if root else model
600
+ layers, nh, kv, hd, dim, hidden = _stack_parts(stack)
601
+ if kv != 1:
602
+ return {"refused": f"prefill_fp8_chain: kv_heads {kv} outside "
603
+ "the single-KV band"}
604
+ if not _gelu_tanh_like(layers[0].mlp.act_fn):
605
+ return {"refused": "prefill_fp8_chain: FFN activation is not "
606
+ "tanh-GELU"}
607
+ scalings = {float(ly.self_attn.scaling) for ly in layers}
608
+ if len(scalings) != 1:
609
+ return {"refused": "prefill_fp8_chain: per-layer attention "
610
+ "scaling differs"}
611
+ final_w = _plain_norm_weight(stack.norm)
612
+ if final_w is None or any(
613
+ _plain_norm_weight(ly.input_layernorm) is None
614
+ or _plain_norm_weight(ly.post_attention_layernorm) is None
615
+ for ly in layers):
616
+ return {"refused": "prefill_fp8_chain: a norm is not a plain "
617
+ "affine RMS norm"}
618
+
619
+ bound = BoundPrefillFp8Chain()
620
+ bound.kernels = {"kg": kg, "kn": kn, "kr": kr, "kf": kf,
621
+ "kg4": kg4, "kf4": kf4}
622
+ bound.band = band
623
+ bound.scaling = scalings.pop()
624
+ bound.dims = {"nh": nh, "kv": kv, "hd": hd, "dim": dim,
625
+ "hidden": hidden, "layers": len(layers)}
626
+ bound.eps = float(getattr(stack.norm, "eps", 1e-6))
627
+ bound.final_w = (1.0 + final_w.detach().float()).to("cuda")
628
+
629
+ # ---- one probe: the prefill call, mask fact, amax sites ----
630
+ calls: list[dict] = []
631
+ amax: dict[tuple[int, str], float] = {}
632
+ samples_amax: list[dict] = []
633
+ samples_chan: list[dict] = []
634
+ # the quantizer statistic is a high element quantile, not the raw
635
+ # peak: one outlier element must cost itself saturation, not the
636
+ # whole tensor's resolution (the house two-level rule, single-call
637
+ # analog). FRT_CALIB_Q=1.0 restores the raw peak for A/B runs.
638
+ import os as _os
639
+ calib_q = float(_os.environ.get("FRT_CALIB_Q", "1.0"))
640
+
641
+ def note(site, unfold=None):
642
+ safe = (unfold.abs().clamp(min=1e-6)
643
+ if unfold is not None else None)
644
+
645
+ def hook(_m, args):
646
+ x = args[0].detach().float().abs()
647
+ if safe is not None:
648
+ # the chain quantizes the pure-RMS output and folds the
649
+ # norm's (1+w) into the GEMM weight columns (the tight
650
+ # distribution is what FP8 can afford); measure what
651
+ # the chain will actually see. A (1+w)=0 channel's
652
+ # host output is exactly zero — its weight column is
653
+ # zero too, so its recovered magnitude may be anything
654
+ # and the clamp keeps it out of the statistic.
655
+ x = x / safe
656
+ x = x.flatten()
657
+ if calib_q >= 1.0 or x.numel() < 1000:
658
+ peak = float(x.amax())
659
+ else:
660
+ k = max(1, int(x.numel() * (1.0 - calib_q)))
661
+ peak = float(x.kthvalue(x.numel() - k + 1).values)
662
+ amax[site] = max(amax.get(site, 0.0), peak)
663
+ return hook
664
+
665
+ chan: dict = {}
666
+
667
+ def cnote(site, unfold=None):
668
+ safe = (unfold.abs().clamp(min=1e-6).cuda()
669
+ if unfold is not None else None)
670
+
671
+ def hook(_m, args):
672
+ x = args[0].detach()
673
+ v = x.float().abs().reshape(-1, x.shape[-1]).amax(dim=0)
674
+ if safe is not None:
675
+ # the chain's producer emits the pure-RMS output — the
676
+ # host folds (1+w) in; measure what the chain will see
677
+ v = v / safe
678
+ prev = chan.get(site)
679
+ chan[site] = (v if prev is None
680
+ else torch.maximum(prev, v))
681
+ return hook
682
+
683
+ hooks = []
684
+ for i, ly in enumerate(layers):
685
+ fold_in = (1.0 + ly.input_layernorm.weight.detach().float())
686
+ fold_post = (1.0 + ly.post_attention_layernorm.weight
687
+ .detach().float())
688
+ hooks.append(ly.self_attn.q_proj.register_forward_pre_hook(
689
+ note((i, "qkv"), fold_in)))
690
+ hooks.append(ly.self_attn.o_proj.register_forward_pre_hook(
691
+ note((i, "o"))))
692
+ hooks.append(ly.mlp.gate_proj.register_forward_pre_hook(
693
+ note((i, "gu"), fold_post)))
694
+ hooks.append(ly.mlp.down_proj.register_forward_pre_hook(
695
+ note((i, "dn"))))
696
+ if BANDS[band]["packages"] and BANDS[band].get("awq"):
697
+ hooks.append(ly.mlp.gate_proj.register_forward_pre_hook(
698
+ cnote((i, "gu"), fold_post)))
699
+ hooks.append(ly.mlp.down_proj.register_forward_pre_hook(
700
+ cnote((i, "dn"))))
701
+
702
+ saved_probe = stack.__dict__.get("forward")
703
+ host_forward = stack.forward
704
+
705
+ def capturing(_self, *args, **kwargs):
706
+ out = host_forward(*args, **kwargs)
707
+ embs = kwargs.get("inputs_embeds")
708
+ pkv = getattr(out, "past_key_values", None)
709
+ hidden_out = getattr(out, "last_hidden_state", None)
710
+ if (embs is not None and kwargs.get("use_cache")
711
+ and hidden_out is not None
712
+ and embs.dim() == 3 and embs.shape[0] == 1
713
+ and kwargs.get("adarms_cond") is None):
714
+ entry = {
715
+ "x": embs.detach().clone(),
716
+ "mask": kwargs.get("attention_mask"),
717
+ "pos": kwargs.get("position_ids"),
718
+ "out": hidden_out.detach().clone(),
719
+ "out_type": type(out),
720
+ "cache_type": type(pkv) if pkv is not None else None,
721
+ "kv": [tuple(t.detach().clone()
722
+ for t in _cache_kv(pkv, i))
723
+ for i in range(len(layers))] if pkv is not None
724
+ else None,
725
+ }
726
+ entry["mask"] = (entry["mask"].detach().clone()
727
+ if entry["mask"] is not None else None)
728
+ entry["pos"] = (entry["pos"].detach().clone()
729
+ if entry["pos"] is not None else None)
730
+ calls.append(entry)
731
+ return out
732
+
733
+ stack.forward = types.MethodType(capturing, stack)
734
+ try:
735
+ sample_fns = list(getattr(probe, "samples", None) or (probe,))
736
+ with torch.inference_mode():
737
+ for fn in sample_fns:
738
+ fn()
739
+ if amax:
740
+ samples_amax.append(dict(amax))
741
+ amax.clear()
742
+ if chan:
743
+ samples_chan.append({k: v.clone()
744
+ for k, v in chan.items()})
745
+ chan.clear()
746
+ finally:
747
+ for hook in hooks:
748
+ hook.remove()
749
+ if saved_probe is not None:
750
+ stack.forward = saved_probe
751
+ else:
752
+ stack.__dict__.pop("forward", None)
753
+
754
+ if not calls:
755
+ return {"refused": "prefill_fp8_chain: probe never made a "
756
+ "prefill call"}
757
+ # the house two-level statistic: max over calls within one sample
758
+ # (the hooks), then the calibration percentile across samples —
759
+ # one sample degenerates to today's raw max exactly
760
+ if samples_amax:
761
+ import numpy as np
762
+
763
+ from flash_rt.core.calibration import accumulate_amax
764
+ sites = set().union(*(d.keys() for d in samples_amax))
765
+ amax = {site: float(accumulate_amax(
766
+ [np.asarray([d[site]]) for d in samples_amax
767
+ if site in d], percentile=99.9)[0]) for site in sites}
768
+ ckeys = (set().union(*(d.keys() for d in samples_chan))
769
+ if samples_chan else set())
770
+ chan = {k: torch.from_numpy(accumulate_amax(
771
+ [d[k].cpu().numpy() for d in samples_chan if k in d],
772
+ percentile=99.9)).to("cuda")
773
+ for k in ckeys}
774
+ first = calls[0]
775
+ if first["mask"] is None or first["pos"] is None:
776
+ return {"refused": "prefill_fp8_chain: probe call carried no "
777
+ "mask or positions"}
778
+ S = first["x"].shape[1]
779
+ s_used = _prefill_mask_facts(first["mask"], S)
780
+ if s_used is None:
781
+ return {"refused": "prefill_fp8_chain: mask outside the "
782
+ "[valid|pad] band"}
783
+ dead = [(i, s) for i in range(len(layers))
784
+ for s in ("qkv", "o", "gu", "dn")
785
+ if (i, s) not in amax or not amax[(i, s)] > 0.0]
786
+ if dead:
787
+ return {"refused": "prefill_fp8_chain: dead quantizer "
788
+ f"site(s) {dead[:6]} of {len(dead)}; "
789
+ f"sample={ {k: amax[k] for k in list(amax)[:4]} }"}
790
+
791
+ bound.dims["seq"] = s_used
792
+ bound.dims["seq_full"] = S
793
+ bound.s_used = s_used
794
+ bound.out_ctor = first["out_type"]
795
+ bound.cache_type = first["cache_type"]
796
+ # the GEMM entry's row band is a runtime fact, not a symbol fact:
797
+ # probe it at the bound shape, then fall to the transition rung
798
+ gemm_mode = "hub"
799
+ try:
800
+ kg.fp8_linear_bf16(
801
+ torch.zeros(S, dim, device="cuda",
802
+ dtype=torch.float8_e4m3fn),
803
+ torch.zeros(dim, dim, device="cuda",
804
+ dtype=torch.float8_e4m3fn), alpha=1.0)
805
+ except Exception as hub_exc: # noqa: BLE001 — a band fact
806
+ fvk = _load_fvk()
807
+ if fvk is None or any(not hasattr(fvk, n)
808
+ for n in set(_FVK_SITE.values())):
809
+ return {"refused": "prefill_fp8_chain: the FP8 GEMM entry "
810
+ f"refuses {S} rows ({hub_exc})"}
811
+ gemm_mode = "fvk"
812
+ bound.kernels["fvk"] = fvk
813
+ if gemm_mode == "hub":
814
+ def gemm(e, site, x8, out):
815
+ kg.fp8_linear_bf16(x8, e[site], alpha=e["a_" + site],
816
+ out=out)
817
+ else:
818
+ fvk = bound.kernels["fvk"]
819
+ fns = {site: getattr(fvk, name)
820
+ for site, name in _FVK_SITE.items()}
821
+
822
+ def gemm(e, site, x8, out):
823
+ w = e[site]
824
+ stream = torch.cuda.current_stream().cuda_stream
825
+ fns[site](x8.data_ptr(), w.data_ptr(), out.data_ptr(),
826
+ x8.shape[0], w.shape[0], w.shape[1],
827
+ e["a_" + site], 0.0, stream)
828
+ bound.kernels["gemm"] = gemm
829
+ if not _build_rope(bound, stack, first["pos"]):
830
+ return {"refused": "prefill_fp8_chain: rotary table is not "
831
+ "half-duplicated"}
832
+ _quantize(bound, layers, amax, chan=chan)
833
+ _alloc(bound)
834
+ half = hd // 2
835
+ kperm = torch.empty(hd, dtype=torch.long, device="cuda")
836
+ kperm[0::2] = torch.arange(half, device="cuda")
837
+ kperm[1::2] = torch.arange(half, hd, device="cuda")
838
+ bound.kperm = kperm
839
+ bound.kperm_inv = torch.argsort(kperm)
840
+
841
+ attend, attn_mode = None, None
842
+ rung_trail = []
843
+ for mode, kern in rungs:
844
+ try:
845
+ candidate = _make_attend(bound, mode, kern)
846
+ candidate(0)
847
+ torch.cuda.synchronize()
848
+ except Exception as exc: # noqa: BLE001 — a dead rung, next
849
+ rung_trail.append(f"{mode}: {type(exc).__name__}")
850
+ continue
851
+ attend, attn_mode = candidate, mode
852
+ break
853
+ if attend is None:
854
+ return {"refused": "prefill_fp8_chain: no attention rung "
855
+ f"executes here ({'; '.join(rung_trail)})"}
856
+ bound.kernels["attend"] = attend
857
+
858
+ run = _make_run(bound)
859
+ guard = bound._frt_arm(dtypes=(torch.bfloat16,),
860
+ device=torch.device("cuda"))
861
+ guard.notes["n_layers"] = len(layers)
862
+ guard.notes["s_used"] = s_used
863
+ guard.notes["attention"] = attn_mode
864
+ guard.notes["gemm"] = gemm_mode
865
+
866
+ # ---- smoke: hidden states and the cache the tower left behind ----
867
+ import os as _os2
868
+ # the smoke floor is a band fact: the FP8 calibration set the 0.95
869
+ # line at its own compounding depth; a deeper-compounding band
870
+ # carries its own line and the arm's captured parity gate (0.99
871
+ # against the stock reference) stays the end-to-end judge either way
872
+ band_floor = BANDS[band].get("smoke_floor", SMOKE_FLOOR)
873
+ floor = float(_os2.environ.get("FRT_PREFILL_SMOKE_FLOOR",
874
+ str(band_floor)))
875
+ scores: list[tuple[float, str]] = []
876
+ with torch.inference_mode():
877
+ for c in calls:
878
+ fresh = c["cache_type"]() if c["cache_type"] else None
879
+ got = run(c["x"][0].to(torch.bfloat16), fresh)
880
+ valid = slice(0, s_used)
881
+ cos = torch.nn.functional.cosine_similarity(
882
+ got.last_hidden_state[0, valid].float().flatten(),
883
+ c["out"][0, valid].float().flatten(), dim=0)
884
+ scores.append((float(cos), "hidden"))
885
+ if fresh is not None and c["kv"] is not None:
886
+ for l in range(len(layers)):
887
+ gk, gv = _cache_kv(fresh, l)
888
+ hk, hv = c["kv"][l]
889
+ for tag, a, bb in (("k", gk, hk), ("v", gv, hv)):
890
+ cc = torch.nn.functional.cosine_similarity(
891
+ a[..., :s_used, :].float().flatten(),
892
+ bb[..., :s_used, :].float().flatten(),
893
+ dim=0)
894
+ scores.append((float(cc), f"{tag}{l}"))
895
+ worst = min(s0 for s0, _ in scores) if scores else None
896
+ trail = sorted(scores)[:4]
897
+ if worst is None or worst < floor:
898
+ return {"refused": f"prefill_fp8_chain smoke cos {worst} < "
899
+ f"{floor}; worst={trail}"}
900
+ guard.notes["smoke_cos"] = round(worst, 6)
901
+ guard.notes["smoke_worst"] = [(round(a, 4), t) for a, t in trail]
902
+
903
+ # ---- route ----
904
+ saved = stack.__dict__.get("forward")
905
+ x_shape = tuple(first["x"].shape)
906
+ mask_shape = tuple(first["mask"].shape)
907
+
908
+ def routed(_self, *args, **kwargs):
909
+ compiling = torch.compiler.is_compiling()
910
+ capturing_now = (False if compiling
911
+ else torch.cuda.is_current_stream_capturing())
912
+ eager = not compiling and not capturing_now
913
+ if eager:
914
+ guard.calls += 1
915
+ embs = kwargs.get("inputs_embeds")
916
+ mask = kwargs.get("attention_mask")
917
+ pkv = kwargs.get("past_key_values")
918
+ ok = (not args and embs is not None
919
+ and kwargs.get("use_cache")
920
+ and kwargs.get("adarms_cond") is None
921
+ and tuple(embs.shape) == x_shape
922
+ and (mask is None or tuple(mask.shape) == mask_shape))
923
+ if not ok:
924
+ if not eager:
925
+ raise RuntimeError(
926
+ "prefill_fp8_chain: out-of-contract call during "
927
+ "capture/compile — fix the eager path first")
928
+ guard.fallbacks += 1
929
+ guard.last_reason = "call outside the routed contract"
930
+ return host_forward(*args, **kwargs)
931
+ if pkv is None and bound.cache_type is not None:
932
+ pkv = bound.cache_type()
933
+ return run(embs[0].to(torch.bfloat16), pkv)
934
+
935
+ def enable() -> None:
936
+ stack.forward = types.MethodType(routed, stack)
937
+
938
+ def disable() -> None:
939
+ if saved is not None:
940
+ stack.forward = saved
941
+ elif "forward" in stack.__dict__:
942
+ del stack.forward
943
+
944
+ def revert() -> None:
945
+ disable()
946
+ bound.table.clear()
947
+ bound.buf.clear()
948
+
949
+ enable()
950
+ return {
951
+ "observed": {f"{root}::prefill_fp8_chain": bound},
952
+ "revert": [revert],
953
+ "toggle": (enable, disable),
954
+ "smoke_cos": worst,
955
+ }