Skip to main content

Module hyper

Module hyper 

Source
Expand description

mHC — manifold-constrained hyper-connections, the ResidualTopology::HyperConnections residual program (glm5_next / GLM-5.3-Flash, and the dsv4 class).

ARITHMETIC CONTRACT. Truth is memra_reference::execute’s execute_hyper_layer, which is itself built from memra_gguf::dsv4_forward::{hc_expand, hc_pre, hc_post, hc_split_sinkhorn, hc_head}. Every stage below cites the reference stage it reproduces. The vendor module the reference was derived from is research/glm53-flash-bringup-20260827/modular_glm5_next-ref.py.

A trunk layer under this topology is NOT x + attn; x += mlp. Per site (attention, then MLP), with the stream state x [tokens, streams, hidden]:

  mixes[t, :]   = fn_w · x[t, :, :]                     (rows = (2+streams)*streams)
  mixes[t, :]  *= rsqrt(mean(x[t]^2) + eps)             (over the whole streams*hidden slab)
  pre/post/comb = sinkhorn(mixes[t, :], scale, base)    (per token, per site)
  y[t, :]       = Σ_c pre[t, c] · x[t, c, :]            (collapse streams -> 1)
  f             = branch(rms_norm(y))                   (the mixer or the FFN, unchanged)
  x'[t, k, :]   = post[t, k] · f[t, :] + Σ_j comb[t, j, k] · x[t, j, :]

SINKHORN IS PER TOKEN AND PER SITE, NOT A LOAD-TIME PRECOMPUTE. mixes is x @ fn_wᵀ rescaled by the token’s own RMS — an ACTIVATION, so the Sinkhorn normalization that turns it into comb cannot be hoisted to load even though the weights are static (dsv4_forward.rs hc_pre, the matmul + rsq block immediately before hc_split_sinkhorn). It runs on device, once per (token, layer, site).

MEMORY LAYOUT: TOKEN-MAJOR [tokens, streams, hidden], element (t, k, i) at (t*streams + k)*hidden + i. Forced, not chosen: it is the layout of hc_expand in the reference and of every kernel in the memra_dsv4_hc_* family, and it makes one token’s streams*hidden slab contiguous — which is exactly the [s, w] operand the mixes GEMM and memra_dsv4_rowsq_scale want. Streams-major would have cost a transpose at both ends of every site. Any graph capture over these buffers sees one flat t*streams*hidden slab.

KERNELS: no new math. cu/dsv4_gpu.cu already carries this exact program for the dsv4 GPU fork (crate::dsv4_gpu) and is compiled unconditionally into this crate, so the site mixing is memra_dsv4_{rowsq_scale, hc_sinkhorn_m, hc_collapse, hc_post} plus hc_mean/hc_head_pre_m at the exit, and the mixes GEMM is Engine::linear (cuBLASLt f32 — the tiny [rows, streams*hidden] operand is the wrong shape for the f64 island dots kernel the dsv4 decode path uses, and this is a serving trunk, not a byte-parity oracle). The one kernel that did not exist, memra_dsv4_hc_expand, was added next to its inverse memra_dsv4_hc_mean. The dsv4_ prefix is that translation unit’s namespace, not a model claim — the reference reaches into memra_gguf::dsv4_forward for glm5_next in exactly the same way.

NO ENV FLAG. The topology, its stream count, its epsilon, its Sinkhorn iteration count and its collapse are read from the compiled ModelPlan. There is nothing here to switch.

Structs§

HcMix
The per-token post gates and combination matrix a site’s hc_pre produced, held for that site’s hc_post. post is [tokens, streams], comb is [tokens, streams, streams].
HyperDecodeWs
Persistent T=1 decode workspace for the hc glue (lane/glm5-decode-diet lever 2, MEMRA_HC_DECODE_WS). One per engine (pp stage), pooled on the Engine like fa_part_pool/router_stage: the launch-diet census measured 2,358 cuMemAllocAsync+Free calls/token (~2.5 ms of host time feeding the sync-serialized drain cycles), and the hc glue chain — mixes, gates, comb, collapse y, the two norm scratches and the two per-site post outputs — re-allocated all of it every token. Every buffer here is FULLY OVERWRITTEN before any read on every step (GEMV beta=0, block-per- token kernels, rms_norm, hc_post), which is what makes reuse byte-identical: the same kernels read and write the same values, only the allocator calls disappear.
HyperHead
Gated-head exit weights (HcCollapse::GatedHead, the dsv4 class). Absent under HcCollapse::Mean, which has no learned head (Glm5NextTextHyperHead is an unweighted mean).
HyperLayer
The six per-layer hc tensors, present iff the plan declares HyperConnections for the trunk.
HyperSite
One site’s learned mixing parameters. fn_w is consumed as ROW-MAJOR [rows, streams*hidden] — the layout memra_reference::hyper_set and dsv4_forward::HcSet read, and the [out_f, in_f] operand Engine::linear wants. Only the element count is checked at load; the checkpoint dialect’s ne ordering is not consulted, so the two readers cannot fork.
HyperTopology
The trunk-wide hyper-connection topology, read off the plan at load.

Statics§

HC_FUSED_PRE_DISPATCHES
Engagement counter for the fused pre-chain door’s =1 arm: incremented at the arm’s own call site, announced once per boot — the spec-engagement receipt the gate and any box A/B arm must show ([bf16-mmv] RESIDENT lesson: engagement lines are receipts, never inferred).
HC_FUSED_PRE_V2_DISPATCHES
Engagement counter for the fused pre-chain door’s =2 arm (lane/b200-sinkhorn-fusion- 20260902 follow-up), same discipline as HC_FUSED_PRE_DISPATCHES.

Functions§

collapse
Trunk exit: [tokens, streams, hidden] -> [tokens, hidden], keyed on the plan’s collapse. Mean is glm5_next’s unweighted mean (Glm5NextTextHyperHead); GatedHead is dsv4’s sigmoid-gated pre-only collapse (dsv4_forward::hc_head) and needs the head trio.
contract_mean
UNWEIGHTED stream-mean contraction [tokens, streams, hidden] -> [tokens, hidden] — the hc_contract the glm5 DFlash2 drafter’s aux-hidden features are defined by (the probe’s capture seam: mean over the hc_mult stream blocks of the completed layer output, == the SGLang glm5_next integration’s pinned definition). Deliberately NOT keyed on topology.collapse: the drafter contract is the mean by definition, whatever the trunk exit does (for glm5_next the exit IS Mean, so this is also the collapse kernel).
expand
Model entry (hc_expand): [tokens, hidden] embeddings -> [tokens, streams, hidden].
post
One site’s post-branch half (hc_post): out[t, k, :] = post[t, k]·f[t, :] + Σ_j comb[t, j, k]·residual[t, j, :]. residual is the site’s INPUT stream state, not the layer’s — the MLP site’s residual is the attention site’s output.
post_t1_ws
post at T=1 into the workspace’s xb slot (the caller swaps xb with its in-flight state). Reads the gates pre_t1_ws left in ws.post/ws.comb — the same kernel, the same operand bytes as the allocating post.
pre
One site’s pre-branch half (hc_pre): mixes GEMM, per-token RMS rescale, Sinkhorn, stream collapse. Returns the branch input [tokens, hidden] and the gates its post half needs.
pre_exact
pre with the DECODE-EXACT mixing GEMM: each token’s mix coefficients come from the SAME m=1 cuBLASLt program the serial T=1 decode step runs (linear_t1_into is linear at m == 1 on a row view — same config, same weight pointer, same input bytes), instead of one m=t call whose n-dependent reduction split changes every output bit (the lt_ndep probe documented on Engine::linear_decode_exact). Everything after the GEMM is the per-token kernel set pre already runs — block-per-token programs whose per-token bytes do not depend on t. This is the entry the BATCHED hyper decode walk uses so that row b of a B-row tick is bit-identical to that session’s solo decode_step_hyper step.
pre_t1_ws
pre at T=1 into the workspace: the SAME m=1 mixes program the allocating entry runs (linear_t1_into is linear at m == 1 — same cuBLASLt config, same weight pointer, same input bytes; the pre_exact note), then the shared pre_finish_into arms. Byte-identical to pre(e, topology, site, x, 1, hidden) with the outputs landing in ws instead of fresh allocations.