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,211 @@
1
+ """NVFP4 (W4A4) ``vision_ffn`` with per-input-channel balance.
2
+
3
+ Both projections of the MLP slice go through the balanced W4 path:
4
+ fc1's balance is fitted on the calibrated per-channel amax at the MLP
5
+ input, fc2's on the amax at its own input (the post-activation hidden).
6
+ Each fold is exact before anything is quantized. The activation between
7
+ them stays at the host's compute dtype with the host's tanh GELU — the
8
+ kernel boundary is the two GEMMs, not the elementwise middle, which is
9
+ exactly where the recorded W4 chain drew it.
10
+
11
+ Activation quantization is dynamic per call (per-block scale factors),
12
+ so no static scale exists to drift across a denoise schedule.
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ from typing import Mapping
18
+
19
+ import torch
20
+
21
+ from ...guard import CAST_OK, PROCEED, GuardedSeam
22
+ from .. import hub_kernel
23
+ from .fp8_static import SUPPORT, _check # noqa: F401
24
+
25
+ KERNEL_DEP = {
26
+ "provider": "huggingface_kernels",
27
+ "repo": "flashrt/fp4-gemm",
28
+ "version": ">=1",
29
+ }
30
+
31
+ _VARIANT = 2
32
+
33
+
34
+ class FusedGeluMlpNvfp4(GuardedSeam, torch.nn.Module):
35
+ """MLP-seam module: the host keeps its own norm and residual."""
36
+
37
+ _frt_host_attr = "host_mlp"
38
+ _frt_can_fallback = True
39
+
40
+ def __init__(self, wp1, sfb1, inv1, b1, wp2, sfb2, inv2, b2,
41
+ d: int, f: int,
42
+ original: torch.nn.Module | None = None,
43
+ fuse_wire: bool = False):
44
+ super().__init__()
45
+ kern = hub_kernel(KERNEL_DEP["repo"], KERNEL_DEP["version"])
46
+ self._kern = kern
47
+ self._gemm = kern.fp4_w4a16_linear_bf16
48
+ # the FP4-wire chain: fc1's GEMM emits bias+tanh-GELU already
49
+ # re-quantized (packed + SFA) and fc2 consumes it with a fused
50
+ # bias — the elementwise middle disappears entirely. Explicitly
51
+ # opted in (scheme decision), never flipped by symbol presence:
52
+ # on the wire fc2's input-side balance cannot be applied, which
53
+ # is a numerics change the gates must judge as a chosen form.
54
+ chain_fn = getattr(kern, "nvfp4_gemm_bias_gelu_nvfp4", None)
55
+ bias_fn = getattr(kern, "nvfp4_gemm_bias_bf16", None)
56
+ self._chain = chain_fn if (fuse_wire and chain_fn is not None
57
+ and bias_fn is not None) else None
58
+ self._gemm_bias = bias_fn
59
+ for name, t in (("wp1", wp1), ("sfb1", sfb1), ("inv1", inv1),
60
+ ("b1", b1), ("wp2", wp2), ("sfb2", sfb2),
61
+ ("inv2", inv2), ("b2", b2)):
62
+ self.register_buffer(name, t)
63
+ self._d = d
64
+ self._f = f
65
+ self._chain_band = (self._audition_chain()
66
+ if self._chain is not None else None)
67
+ if original is not None:
68
+ self.host_mlp = original
69
+ self._frt_arm(dtypes=CAST_OK, device=wp1.device, k=d)
70
+
71
+ #: Row counts probed at bind. The first that runs anchors the band;
72
+ #: the two probes after it say which kind of band it is.
73
+ _PROBE_M = (1, 2, 4, 8, 16, 32, 64, 128)
74
+
75
+ def _chain_runs(self, m: int) -> bool:
76
+ try:
77
+ z = torch.zeros(m, self._d, device=self.wp1.device,
78
+ dtype=torch.float16)
79
+ ap, sfa = self._kern.quantize_fp4_sfa_fp16(z)
80
+ hp, hsfa = self._chain(ap, self.wp1, sfa, self.sfb1, self.b1)
81
+ self._gemm_bias(hp, self.wp2, hsfa, self.sfb2, self.b2)
82
+ return True
83
+ except (RuntimeError, ValueError):
84
+ return False
85
+
86
+ def _audition_chain(self):
87
+ """Measure which row counts the wire chain will serve.
88
+
89
+ Presence is not qualification, and this qualification is
90
+ shape-dependent — but *how* it depends on shape is itself
91
+ something to measure rather than assume. A tile-structured entry
92
+ can decline every row count that is not a multiple of its tile
93
+ while serving all of them that are, which no lower bound
94
+ describes: reading such an entry as "serves M >= n" turns off a
95
+ chain that would have served the aligned shapes a real workload
96
+ actually has.
97
+
98
+ So the probes anchor the band and then ask which kind it is. If
99
+ the row after the anchor also runs, the band is a floor. If the
100
+ anchor's double runs but its successor does not, the band is an
101
+ alignment. If neither, the band is not describable from here and
102
+ the chain stands down rather than guess.
103
+
104
+ Returns ``("min", n)``, ``("align", n)``, or ``None`` — and on
105
+ ``None`` the two-step form carries every call, exactly.
106
+ """
107
+ anchor = next((m for m in self._PROBE_M if self._chain_runs(m)),
108
+ None)
109
+ if anchor is None:
110
+ self._chain = None
111
+ return None
112
+ if self._chain_runs(anchor + 1):
113
+ return ("min", anchor)
114
+ if anchor > 1 and self._chain_runs(anchor * 2):
115
+ return ("align", anchor)
116
+ self._chain = None
117
+ return None
118
+
119
+ def _chain_serves(self, rows: int) -> bool:
120
+ kind, n = self._chain_band
121
+ return rows >= n if kind == "min" else rows % n == 0
122
+
123
+ def __getattr__(self, name):
124
+ try:
125
+ return super().__getattr__(name)
126
+ except AttributeError:
127
+ if name == "host_mlp":
128
+ raise
129
+ return getattr(super().__getattr__("host_mlp"), name)
130
+
131
+ def forward(self, hidden: torch.Tensor) -> torch.Tensor:
132
+ admitted = self._frt_admit(hidden)
133
+ if admitted is not PROCEED:
134
+ return admitted
135
+ shape = hidden.shape
136
+ flat = (hidden.reshape(-1, shape[-1]).to(torch.float16)
137
+ * self.inv1).contiguous()
138
+ ap, sfa = self._kern.quantize_fp4_sfa_fp16(flat)
139
+ if self._chain is not None and self._chain_serves(flat.shape[0]):
140
+ hp, hsfa = self._chain(ap, self.wp1, sfa, self.sfb1, self.b1)
141
+ y = self._gemm_bias(hp, self.wp2, hsfa, self.sfb2, self.b2)
142
+ return y.reshape(*shape[:-1], self._d).to(hidden.dtype)
143
+ h = self._gemm(ap, self.wp1, sfa, self.sfb1, variant=_VARIANT)
144
+ h = h + self.b1
145
+ h = torch.nn.functional.gelu(h, approximate="tanh")
146
+ hf = (h.to(torch.float16) * self.inv2).contiguous()
147
+ ap2, sfa2 = self._kern.quantize_fp4_sfa_fp16(hf)
148
+ y = self._gemm(ap2, self.wp2, sfa2, self.sfb2, variant=_VARIANT)
149
+ y = y + self.b2
150
+ return y.reshape(*shape[:-1], self._d).to(hidden.dtype)
151
+
152
+
153
+ @torch.no_grad()
154
+ def bind_mlp_seam(
155
+ weights: Mapping[str, torch.Tensor],
156
+ *,
157
+ channel_in,
158
+ channel_hidden,
159
+ original: torch.nn.Module | None = None,
160
+ alpha: float = 0.5,
161
+ clamp=(0.25, 4.0),
162
+ fuse_wire: bool = False,
163
+ ) -> FusedGeluMlpNvfp4:
164
+ """Bind the MLP-seam slice from two calibrated channel-amax vectors.
165
+
166
+ ``channel_in`` (``[D]``) is measured at the MLP input,
167
+ ``channel_hidden`` (``[F]``) at the second projection's input — the
168
+ post-activation hidden. Each parameterises its projection's balance
169
+ fold; neither is a scale.
170
+ """
171
+ from flash_rt.core.quantization import fit_input_channel_balance
172
+
173
+ dim_d, dim_f = _check(weights)
174
+ kern = hub_kernel(KERNEL_DEP["repo"], KERNEL_DEP["version"])
175
+ clamp = (float(clamp[0]), float(clamp[1]))
176
+
177
+ def fold_pack(w, chan):
178
+ amax = torch.as_tensor(chan, device=w.device, dtype=torch.float32)
179
+ w_bal, inv = fit_input_channel_balance(
180
+ w.detach().float(), amax, alpha=alpha, clamp=clamp,
181
+ out_dtype=torch.float32)
182
+ wp, sfb = kern.quantize_fp4_sfa_fp16(
183
+ w_bal.to("cuda", torch.float16).contiguous(), is_sfb=True)
184
+ return wp, sfb, inv.to("cuda", torch.float16)
185
+
186
+ wp1, sfb1, inv1 = fold_pack(weights["w_fc1"], channel_in)
187
+ if fuse_wire:
188
+ # on the FP4 wire fc2's input arrives already quantized, so no
189
+ # activation-side inverse can be applied — fc2 packs unbalanced
190
+ # (a folded weight without its inverse is wrong arithmetic, not
191
+ # a weaker recipe). inv2 stays identity so the two-step
192
+ # fallback path remains exact if the entries are absent.
193
+ wp2, sfb2 = kern.quantize_fp4_sfa_fp16(
194
+ weights["w_fc2"].detach().to("cuda", torch.float16)
195
+ .contiguous(), is_sfb=True)
196
+ inv2 = torch.ones(dim_f, device="cuda", dtype=torch.float16)
197
+ else:
198
+ wp2, sfb2, inv2 = fold_pack(weights["w_fc2"], channel_hidden)
199
+ to_bf16 = lambda t: t.detach().to("cuda", torch.bfloat16)
200
+ bound = FusedGeluMlpNvfp4(
201
+ wp1, sfb1, inv1, to_bf16(weights["b_fc1"]),
202
+ wp2, sfb2, inv2, to_bf16(weights["b_fc2"]),
203
+ dim_d, dim_f, original=original, fuse_wire=fuse_wire)
204
+ probe = bound(torch.zeros(1, dim_d, device=wp1.device,
205
+ dtype=torch.bfloat16))
206
+ if probe.shape != (1, dim_d) or not torch.isfinite(probe).all():
207
+ raise ValueError(
208
+ f"refused: vision_ffn nvfp4_balance bind smoke produced "
209
+ f"shape {tuple(probe.shape)}, "
210
+ f"finite={bool(torch.isfinite(probe).all())}")
211
+ return bound
@@ -0,0 +1,7 @@
1
+ """The biased-LayerNorm vision tower region: the patch encoder pass.
2
+
3
+ A ViT-style tower — LayerNorm pairs with affine bias, biased QKV/out
4
+ projections, a biased tanh-GELU MLP — whose whole per-layer loop the
5
+ chain candidate re-expresses in static-FP8 hub primitives with the
6
+ bias and residual folded into the GEMM epilogues.
7
+ """