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,264 @@
1
+ """Fixed-iteration lowering for the semantic OpenPI action schedule.
2
+
3
+ The matcher deliberately does not import OpenPI or name one of its concrete
4
+ classes. It recognizes the boundary that the host exposes: observation
5
+ preprocessing, prefix embedding/cache construction, an iterative denoise
6
+ step, and the paired PaliGemma/expert container. This covers the OpenPI
7
+ PyTorch PI action family while an unrelated module is correctly ignored.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import functools
13
+ import inspect
14
+ from typing import Any, Callable
15
+
16
+ import torch
17
+
18
+ from .protocol import FixedIterationLowering, FixedIterationRefused
19
+
20
+
21
+ def _unwrap(call: Callable[..., Any]) -> Callable[..., Any]:
22
+ """Unwrap ``torch.compile`` while preserving an already-bound method."""
23
+ wrapped = getattr(call, "__wrapped__", call)
24
+ owner = getattr(call, "__self__", None)
25
+ if owner is not None and inspect.isfunction(wrapped):
26
+ return wrapped.__get__(owner, type(owner))
27
+ return wrapped
28
+
29
+
30
+ def _semantic_model(candidate: Any) -> bool:
31
+ required_calls = (
32
+ "_preprocess_observation",
33
+ "_prepare_attention_masks_4d",
34
+ "embed_prefix",
35
+ "denoise_step",
36
+ "sample_actions",
37
+ "sample_noise",
38
+ )
39
+ if not isinstance(candidate, torch.nn.Module):
40
+ return False
41
+ if not all(callable(getattr(candidate, name, None))
42
+ for name in required_calls):
43
+ return False
44
+ config = getattr(candidate, "config", None)
45
+ if not all(hasattr(config, name)
46
+ for name in ("action_horizon", "action_dim")):
47
+ return False
48
+ pair = getattr(candidate, "paligemma_with_expert", None)
49
+ pali = getattr(pair, "paligemma", None)
50
+ expert = getattr(pair, "gemma_expert", None)
51
+ if not callable(getattr(pair, "forward", None)):
52
+ return False
53
+ if getattr(pali, "language_model", None) is None:
54
+ return False
55
+ if getattr(expert, "model", None) is None:
56
+ return False
57
+ try:
58
+ names = tuple(inspect.signature(
59
+ _unwrap(candidate.sample_actions)).parameters)
60
+ except (TypeError, ValueError):
61
+ return False
62
+ return names[:2] == ("device", "observation") \
63
+ and "noise" in names and "num_steps" in names
64
+
65
+
66
+ def _partial_invocation(
67
+ forward: Callable[[], Any],
68
+ ) -> tuple[Any, Callable[..., Any], tuple[Any, ...], dict[str, Any]] | None:
69
+ if not isinstance(forward, functools.partial):
70
+ return None
71
+ call = forward.func
72
+ model = getattr(call, "__self__", None)
73
+ if not _semantic_model(model):
74
+ return None
75
+ return model, _unwrap(call), tuple(forward.args), dict(forward.keywords or {})
76
+
77
+
78
+ def _record_invocation(
79
+ forward: Callable[[], Any],
80
+ model: Any,
81
+ ) -> tuple[Callable[..., Any], tuple[Any, ...], dict[str, Any], Any]:
82
+ """Record one call through ``model.sample_actions``, then restore it."""
83
+ original = model.sample_actions
84
+ raw = _unwrap(original)
85
+ calls: list[tuple[tuple[Any, ...], dict[str, Any]]] = []
86
+
87
+ def record(*args: Any, **kwargs: Any) -> Any:
88
+ calls.append((tuple(args), dict(kwargs)))
89
+ return raw(*args, **kwargs)
90
+
91
+ owned = "sample_actions" in vars(model)
92
+ try:
93
+ model.sample_actions = record
94
+ with torch.no_grad():
95
+ reference = forward()
96
+ finally:
97
+ if owned:
98
+ model.sample_actions = original
99
+ else:
100
+ delattr(model, "sample_actions")
101
+ if len(calls) != 1:
102
+ raise FixedIterationRefused(
103
+ "fixed_iter: the host forward must call the recognized action "
104
+ f"schedule exactly once, observed {len(calls)} call(s)")
105
+ args, kwargs = calls[0]
106
+ return raw, args, kwargs, reference
107
+
108
+
109
+ def _bind_arguments(
110
+ call: Callable[..., Any],
111
+ args: tuple[Any, ...],
112
+ kwargs: dict[str, Any],
113
+ ) -> inspect.BoundArguments:
114
+ try:
115
+ signature = inspect.signature(call)
116
+ bound = signature.bind(*args, **kwargs)
117
+ bound.apply_defaults()
118
+ return bound
119
+ except (TypeError, ValueError) as exc:
120
+ raise FixedIterationRefused(
121
+ f"fixed_iter: cannot bind the host schedule arguments: {exc}") \
122
+ from exc
123
+
124
+
125
+ def _attention_masks(pad_masks: torch.Tensor,
126
+ att_masks: torch.Tensor) -> torch.Tensor:
127
+ """OpenPI's prefix-mask dataflow, expressed without a host import."""
128
+ cumsum = torch.cumsum(att_masks, dim=1)
129
+ causal = cumsum[:, None, :] <= cumsum[:, :, None]
130
+ valid = pad_masks[:, None, :] * pad_masks[:, :, None]
131
+ return causal & valid
132
+
133
+
134
+ def _fixed_forward(
135
+ model: Any,
136
+ *,
137
+ device: Any,
138
+ observation: Any,
139
+ noise: torch.Tensor,
140
+ steps: int,
141
+ ) -> torch.Tensor:
142
+ """The host schedule with only its fixed loop spelling normalized."""
143
+ batch = observation.state.shape[0]
144
+ images, image_masks, tokens, token_masks, state = \
145
+ model._preprocess_observation(observation, train=False)
146
+ prefix, prefix_pad, prefix_ar = model.embed_prefix(
147
+ images, image_masks, tokens, token_masks)
148
+ prefix_mask = _attention_masks(prefix_pad, prefix_ar)
149
+ prefix_positions = torch.cumsum(prefix_pad, dim=1) - 1
150
+ prefix_mask_4d = model._prepare_attention_masks_4d(prefix_mask)
151
+
152
+ model.paligemma_with_expert.paligemma.language_model.config \
153
+ ._attn_implementation = "eager"
154
+ _, prefix_kv = model.paligemma_with_expert.forward(
155
+ attention_mask=prefix_mask_4d,
156
+ position_ids=prefix_positions,
157
+ past_key_values=None,
158
+ inputs_embeds=[prefix, None],
159
+ use_cache=True,
160
+ )
161
+
162
+ # device-native creation: torch.tensor(scalar, device=cuda) stages
163
+ # on the CPU and copies, which a capturing stream refuses the
164
+ # moment a seat's graph break makes these lines run eager
165
+ dt = torch.full((), -1.0 / steps, dtype=torch.float32,
166
+ device=device)
167
+ value = noise
168
+ timestep = torch.ones((), dtype=torch.float32, device=device)
169
+ for _ in range(steps):
170
+ velocity = model.denoise_step(
171
+ state,
172
+ prefix_pad,
173
+ prefix_kv,
174
+ value,
175
+ timestep.expand(batch),
176
+ )
177
+ value = value + dt * velocity
178
+ timestep += dt
179
+ return value
180
+
181
+
182
+ def _observation_windows(observation: Any) -> dict[str, torch.Tensor]:
183
+ """Expose every tensor the fixed schedule reads between replays."""
184
+ windows: dict[str, torch.Tensor] = {}
185
+ for attr in (
186
+ "images",
187
+ "image_masks",
188
+ "state",
189
+ "tokenized_prompt",
190
+ "tokenized_prompt_mask",
191
+ "token_ar_mask",
192
+ "token_loss_mask",
193
+ ):
194
+ value = getattr(observation, attr, None)
195
+ if torch.is_tensor(value):
196
+ windows[f"observation.{attr}"] = value
197
+ elif isinstance(value, dict):
198
+ for key, tensor in sorted(value.items()):
199
+ if torch.is_tensor(tensor):
200
+ windows[f"observation.{attr}.{key}"] = tensor
201
+ return windows
202
+
203
+
204
+ class OpenPIFixedIterationAdapter:
205
+ """Normalize a fixed OpenPI action loop without modifying the host."""
206
+
207
+ family = "cond_iter_pipeline.openpi_action"
208
+
209
+ def lower(
210
+ self,
211
+ forward: Callable[[], Any],
212
+ model: Any | None,
213
+ ) -> FixedIterationLowering | None:
214
+ invocation = _partial_invocation(forward)
215
+ if invocation is not None:
216
+ found, raw, args, kwargs = invocation
217
+ with torch.no_grad():
218
+ reference = raw(*args, **kwargs)
219
+ model = found
220
+ elif _semantic_model(model):
221
+ raw, args, kwargs, reference = _record_invocation(forward, model)
222
+ else:
223
+ return None
224
+
225
+ bound = _bind_arguments(raw, args, kwargs)
226
+ device = bound.arguments["device"]
227
+ observation = bound.arguments["observation"]
228
+ noise = bound.arguments.get("noise")
229
+ steps = bound.arguments.get("num_steps")
230
+ if noise is None:
231
+ raise FixedIterationRefused(
232
+ "fixed_iter: noise must be explicit so capture exposes a "
233
+ "replayable SWAP window instead of freezing in-graph RNG")
234
+ if not isinstance(noise, torch.Tensor):
235
+ raise FixedIterationRefused(
236
+ "fixed_iter: explicit noise must be a torch.Tensor")
237
+ if isinstance(steps, bool) or not isinstance(steps, int) or steps <= 0:
238
+ raise FixedIterationRefused(
239
+ f"fixed_iter: num_steps must be one positive fixed int, got "
240
+ f"{steps!r}")
241
+
242
+ def lowered() -> torch.Tensor:
243
+ with torch.no_grad():
244
+ return _fixed_forward(
245
+ model,
246
+ device=device,
247
+ observation=observation,
248
+ noise=noise,
249
+ steps=steps,
250
+ )
251
+
252
+ return FixedIterationLowering(
253
+ forward=lowered,
254
+ reference_output=reference,
255
+ family=self.family,
256
+ steps=steps,
257
+ exact=True,
258
+ windows={"noise": noise, **_observation_windows(observation)},
259
+ details={
260
+ "source_form": "tensor_controlled_while",
261
+ "canonical_form": "fixed_for",
262
+ "noise_window": "explicit",
263
+ },
264
+ )
@@ -0,0 +1,94 @@
1
+ """Host-family adapter protocol for fixed iterative schedules."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass, field
6
+ from typing import Any, Callable, Mapping, Protocol
7
+
8
+ import torch
9
+
10
+
11
+ class FixedIterationRefused(RuntimeError):
12
+ """A candidate schedule was recognized but cannot be lowered safely."""
13
+
14
+
15
+ @dataclass(frozen=True)
16
+ class FixedIterationLowering:
17
+ """A graph-safe callable plus the reference output that qualified it."""
18
+
19
+ forward: Callable[[], Any]
20
+ reference_output: Any
21
+ family: str
22
+ steps: int
23
+ exact: bool = True
24
+ compile_before_capture: bool = True
25
+ windows: Mapping[str, torch.Tensor] = field(default_factory=dict)
26
+ details: Mapping[str, Any] = field(default_factory=dict)
27
+
28
+
29
+ class FixedIterationAdapter(Protocol):
30
+ """One host-family realization of the fixed-iteration contract."""
31
+
32
+ def lower(
33
+ self,
34
+ forward: Callable[[], Any],
35
+ model: Any | None,
36
+ ) -> FixedIterationLowering | None: ...
37
+
38
+
39
+ _ADAPTERS: list[FixedIterationAdapter] = []
40
+
41
+
42
+ def register_fixed_iteration_adapter(adapter: FixedIterationAdapter) -> None:
43
+ """Register a host-family schedule adapter (last registration runs last)."""
44
+ _ADAPTERS.append(adapter)
45
+
46
+
47
+ def normalize_fixed_iteration(
48
+ forward: Callable[[], Any],
49
+ model: Any | None = None,
50
+ ) -> FixedIterationLowering | None:
51
+ """Return a qualified lowering, or ``None`` for an ordinary callable.
52
+
53
+ ``None`` is not a fallback: it means no adapter recognized the callable,
54
+ so the existing capture path receives it unchanged. Once an adapter
55
+ recognizes its family, an unsafe form raises :class:`FixedIterationRefused`
56
+ rather than silently returning to the original graph-unsafe loop.
57
+ """
58
+ for adapter in _ADAPTERS:
59
+ lowering = adapter.lower(forward, model)
60
+ if lowering is not None:
61
+ if lowering.exact:
62
+ want = _first_tensor(lowering.reference_output)
63
+ with torch.no_grad():
64
+ got = _first_tensor(lowering.forward())
65
+ if want is None or got is None:
66
+ raise FixedIterationRefused(
67
+ f"{lowering.family}: exact schedule qualification "
68
+ "needs one tensor output")
69
+ if not torch.equal(got, want):
70
+ raise FixedIterationRefused(
71
+ f"{lowering.family}: fixed-iteration lowering is "
72
+ "not bit-exact")
73
+ return lowering
74
+ return None
75
+
76
+
77
+ def _first_tensor(value: Any) -> torch.Tensor | None:
78
+ if torch.is_tensor(value):
79
+ return value
80
+ logits = getattr(value, "logits", None)
81
+ if torch.is_tensor(logits):
82
+ return logits
83
+ if isinstance(value, Mapping):
84
+ for key in sorted(value):
85
+ found = _first_tensor(value[key])
86
+ if found is not None:
87
+ return found
88
+ return None
89
+ if isinstance(value, (tuple, list)):
90
+ for item in value:
91
+ found = _first_tensor(item)
92
+ if found is not None:
93
+ return found
94
+ return None
@@ -0,0 +1,3 @@
1
+ from .hub_v3 import HubV3GatedDeltaCore, bind_gated_delta_core
2
+
3
+ __all__ = ["HubV3GatedDeltaCore", "bind_gated_delta_core"]