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.
- flashrt_structures/__init__.py +174 -0
- flashrt_structures/adapters/__init__.py +55 -0
- flashrt_structures/adapters/diffusers_attention.py +237 -0
- flashrt_structures/adapters/diffusers_rotary_attention.py +239 -0
- flashrt_structures/adapters/factored_qk_norm_rope.py +252 -0
- flashrt_structures/adapters/factored_two_way_attention.py +99 -0
- flashrt_structures/adapters/gemma_attention.py +226 -0
- flashrt_structures/adapters/packed_qkv_rope.py +342 -0
- flashrt_structures/adapters/packed_stream_qk_norm_rope.py +376 -0
- flashrt_structures/adapters/qwen_per_head_qk_norm_rope.py +231 -0
- flashrt_structures/adapters/sglang_engine.py +207 -0
- flashrt_structures/adapters/transformers_attention_interface.py +73 -0
- flashrt_structures/adapters/transformers_gated_delta.py +152 -0
- flashrt_structures/adapters/transformers_gated_delta_fused.py +96 -0
- flashrt_structures/adapters/vllm_engine.py +424 -0
- flashrt_structures/adjudicate.py +85 -0
- flashrt_structures/aot.py +191 -0
- flashrt_structures/autobuild.py +2052 -0
- flashrt_structures/beta/__init__.py +43 -0
- flashrt_structures/beta/conform.py +94 -0
- flashrt_structures/beta/joins.py +113 -0
- flashrt_structures/beta/negotiate.py +84 -0
- flashrt_structures/beta/ports.py +140 -0
- flashrt_structures/decisions.py +80 -0
- flashrt_structures/discover.py +623 -0
- flashrt_structures/explain.py +70 -0
- flashrt_structures/frontdoor.py +572 -0
- flashrt_structures/gates.py +465 -0
- flashrt_structures/guard.py +421 -0
- flashrt_structures/handle.py +189 -0
- flashrt_structures/impls/__init__.py +219 -0
- flashrt_structures/impls/adaln_producer/__init__.py +8 -0
- flashrt_structures/impls/adaln_producer/broker.py +116 -0
- flashrt_structures/impls/adaln_producer/fused.py +388 -0
- flashrt_structures/impls/adarms_stack/__init__.py +8 -0
- flashrt_structures/impls/adarms_stack/fp8_chain.py +832 -0
- flashrt_structures/impls/adarms_stack/region.py +102 -0
- flashrt_structures/impls/attention_core/__init__.py +132 -0
- flashrt_structures/impls/attention_core/fa2_seqused.py +458 -0
- flashrt_structures/impls/attention_core/fa4_cute.py +154 -0
- flashrt_structures/impls/attention_core/fa4_fp8.py +178 -0
- flashrt_structures/impls/attention_core/masked_mha.py +158 -0
- flashrt_structures/impls/attention_core/two_way_fa2.py +220 -0
- flashrt_structures/impls/cadence_static/__init__.py +18 -0
- flashrt_structures/impls/cadence_static/buffers.py +122 -0
- flashrt_structures/impls/cadence_static/cross_attention.py +187 -0
- flashrt_structures/impls/chain_elements.py +89 -0
- flashrt_structures/impls/decode_loop/__init__.py +0 -0
- flashrt_structures/impls/decode_loop/fp8_kv.py +206 -0
- flashrt_structures/impls/decode_loop/mtp_speculative.py +245 -0
- flashrt_structures/impls/decode_loop/whole_step.py +852 -0
- flashrt_structures/impls/decoder_block/__init__.py +6 -0
- flashrt_structures/impls/decoder_block/attn_sublayer.py +110 -0
- flashrt_structures/impls/decoder_block/fused.py +167 -0
- flashrt_structures/impls/decoder_ffn/__init__.py +0 -0
- flashrt_structures/impls/decoder_ffn/fp8_static.py +310 -0
- flashrt_structures/impls/decoder_ffn/fp8_static.yaml +22 -0
- flashrt_structures/impls/decoder_ffn/w4a16_static.py +221 -0
- flashrt_structures/impls/decoder_ffn/w8a16_static.py +183 -0
- flashrt_structures/impls/dit_stack/__init__.py +11 -0
- flashrt_structures/impls/dit_stack/fp4_chain.py +417 -0
- flashrt_structures/impls/dit_stack/region.py +86 -0
- flashrt_structures/impls/fixed_iter/__init__.py +29 -0
- flashrt_structures/impls/fixed_iter/openpi.py +264 -0
- flashrt_structures/impls/fixed_iter/protocol.py +94 -0
- flashrt_structures/impls/gated_delta_core/__init__.py +3 -0
- flashrt_structures/impls/gated_delta_core/fused_layer.py +545 -0
- flashrt_structures/impls/gated_delta_core/hub_v3.py +152 -0
- flashrt_structures/impls/graph_lowering/__init__.py +27 -0
- flashrt_structures/impls/graph_lowering/pi052_denoise.py +179 -0
- flashrt_structures/impls/graph_lowering/protocol.py +76 -0
- flashrt_structures/impls/graph_lowering/qwen3_vl.py +364 -0
- flashrt_structures/impls/linear_proj/__init__.py +0 -0
- flashrt_structures/impls/linear_proj/fp8_static.py +270 -0
- flashrt_structures/impls/linear_proj/nvfp4_balance.py +131 -0
- flashrt_structures/impls/linear_proj/nvfp4_dynamic.py +182 -0
- flashrt_structures/impls/linear_proj/w8a16_static.py +230 -0
- flashrt_structures/impls/modnorm_qkv_chain/__init__.py +0 -0
- flashrt_structures/impls/modnorm_qkv_chain/fp8_ptok_table.py +291 -0
- flashrt_structures/impls/moe_experts/__init__.py +9 -0
- flashrt_structures/impls/moe_experts/nvfp4_dynamic.py +208 -0
- flashrt_structures/impls/moe_experts/nvfp4_w4a16.py +129 -0
- flashrt_structures/impls/norm_fused/__init__.py +3 -0
- flashrt_structures/impls/norm_fused/bf16.py +94 -0
- flashrt_structures/impls/norm_fused/fp8_producer.py +84 -0
- flashrt_structures/impls/patch_projection/__init__.py +3 -0
- flashrt_structures/impls/patch_projection/bf16_flat.py +139 -0
- flashrt_structures/impls/prefill_tower/__init__.py +10 -0
- flashrt_structures/impls/prefill_tower/fp8_chain.py +955 -0
- flashrt_structures/impls/prefill_tower/region.py +99 -0
- flashrt_structures/impls/qk_norm_rope/__init__.py +12 -0
- flashrt_structures/impls/qk_norm_rope/per_head_gqa.py +199 -0
- flashrt_structures/impls/qk_norm_rope/projection_bf16.py +165 -0
- flashrt_structures/impls/qkv_pack/__init__.py +5 -0
- flashrt_structures/impls/qkv_pack/bf16.py +110 -0
- flashrt_structures/impls/qkv_pack/fp8_static.py +435 -0
- flashrt_structures/impls/qkv_pack/nvfp4_balance.py +218 -0
- flashrt_structures/impls/qkv_rope/__init__.py +3 -0
- flashrt_structures/impls/qkv_rope/packed_bias_bf16.py +143 -0
- flashrt_structures/impls/step_table.py +113 -0
- flashrt_structures/impls/vision_ffn/__init__.py +0 -0
- flashrt_structures/impls/vision_ffn/fp8_static.py +261 -0
- flashrt_structures/impls/vision_ffn/nvfp4_balance.py +211 -0
- flashrt_structures/impls/vision_tower/__init__.py +7 -0
- flashrt_structures/impls/vision_tower/fp8_chain.py +533 -0
- flashrt_structures/impls/vision_tower/region.py +91 -0
- flashrt_structures/matrix.py +126 -0
- flashrt_structures/points.py +368 -0
- flashrt_structures/prequantized.py +131 -0
- flashrt_structures/quantize_on_adopt.py +94 -0
- flashrt_structures/recipe.py +438 -0
- flashrt_structures/regions.py +208 -0
- flashrt_structures/schemes.py +490 -0
- flashrt_structures/stages.py +298 -0
- flashrt_structures/storage.py +255 -0
- flashrt_structures/swap.py +398 -0
- flashrt_structures/workspace.py +110 -0
- flashrt_structures-0.2.0.dist-info/METADATA +140 -0
- flashrt_structures-0.2.0.dist-info/RECORD +122 -0
- flashrt_structures-0.2.0.dist-info/WHEEL +5 -0
- flashrt_structures-0.2.0.dist-info/licenses/LICENSE +202 -0
- 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
|
+
"""
|