Skip to main content

memra_engine/
hybrid.rs

1//! Qwen3.5/3.6 hybrid model: linear-attention (Gated DeltaNet) layers + periodic full-attention
2//! layers + SwiGLU FFN. Loads weights, runs the forward, dual cache. Builds on the validated
3//! conv1d + gdn_scan kernels (M2/M3) and the dense full-attn path (M0).
4
5use crate::model::{EmbedHost, GpuTensor, HostExps};
6use crate::Engine;
7use memra_gguf::config::{LayerKind, MlaConfig, ModelConfig};
8use memra_gguf::source::{GgufSource, TensorSource};
9use memra_gguf::{GgmlType, GgufFile};
10use cudarc::driver::CudaSlice;
11use std::collections::HashMap;
12
13// Source-agnostic load helpers (GGUF or safetensors). The GGUF wrappers below keep `load()`
14// byte-identical; only the source object differs.
15fn load_t(
16    e: &Engine,
17    src: &dyn TensorSource,
18    name: &str,
19) -> Result<GpuTensor, Box<dyn std::error::Error>> {
20    GpuTensor::load_from_source(e, src, name)
21}
22fn load_opt(
23    e: &Engine,
24    src: &dyn TensorSource,
25    name: &str,
26) -> Result<Option<GpuTensor>, Box<dyn std::error::Error>> {
27    GpuTensor::load_opt_from_source(e, src, name)
28}
29
30struct ResidencyBytes {
31    experts: HashMap<usize, usize>,
32    rest: usize,
33    saw_experts: bool,
34}
35
36fn block_index(name: &str) -> Option<usize> {
37    name.strip_prefix("blk.")?.split('.').next()?.parse().ok()
38}
39
40fn residency_bytes_by_device<'a>(
41    tensors: impl IntoIterator<Item = (&'a str, usize)>,
42    layer_devices: &[usize],
43    primary_device: usize,
44) -> ResidencyBytes {
45    let mut out = ResidencyBytes {
46        experts: HashMap::new(),
47        rest: 0,
48        saw_experts: false,
49    };
50    for (name, bytes) in tensors {
51        if name.starts_with("blk.") && name.contains("_exps.") {
52            let device = block_index(name)
53                .and_then(|il| layer_devices.get(il).copied())
54                .unwrap_or(primary_device);
55            *out.experts.entry(device).or_default() += bytes;
56            out.saw_experts = true;
57        } else {
58            out.rest += bytes;
59        }
60    }
61    out
62}
63
64/// Load-local resident-expert capacity decisions. PP stages on distinct devices are charged only
65/// for their own layer slices; co-located stages share a device key and are charged together.
66pub(crate) struct ResidentPlan {
67    primary_device: usize,
68    layer_devices: Vec<usize>,
69    layer_counts: HashMap<usize, usize>,
70    exact_expert_bytes: Option<HashMap<usize, usize>>,
71    trunk_bytes: usize,
72    decisions: HashMap<usize, bool>,
73    pp: bool,
74}
75
76impl ResidentPlan {
77    fn from_layout(
78        src: &dyn TensorSource,
79        primary_device: usize,
80        layer_devices: Vec<usize>,
81        pp: bool,
82    ) -> Self {
83        let mut layer_counts = HashMap::new();
84        for &device in &layer_devices {
85            *layer_counts.entry(device).or_default() += 1;
86        }
87        let (exact_expert_bytes, trunk_bytes) = match src.gguf() {
88            Some(g) => {
89                let bytes = residency_bytes_by_device(
90                    g.tensors.iter().map(|t| (t.name.as_str(), t.n_bytes as usize)),
91                    &layer_devices,
92                    primary_device,
93                );
94                if bytes.saw_experts {
95                    (Some(bytes.experts), bytes.rest)
96                } else {
97                    (None, 0)
98                }
99            }
100            None => (None, 0),
101        };
102        Self {
103            primary_device,
104            layer_devices,
105            layer_counts,
106            exact_expert_bytes,
107            trunk_bytes,
108            decisions: HashMap::new(),
109            pp,
110        }
111    }
112
113    pub(crate) fn unsharded(e: &Engine, src: &dyn TensorSource, cfg: &ModelConfig) -> Self {
114        let device = e.ctx().ordinal();
115        Self::from_layout(src, device, vec![device; cfg.n_layer as usize], false)
116    }
117
118    pub(crate) fn pp(
119        e: &Engine,
120        src: &dyn TensorSource,
121        cfg: &ModelConfig,
122        n_trunk: usize,
123    ) -> Result<Self, Box<dyn std::error::Error>> {
124        let primary = e.ctx().ordinal();
125        let Some(_fence) = crate::pp::pp_cuts(n_trunk) else {
126            return Ok(Self::unsharded(e, src, cfg));
127        };
128        let mut layer_devices = vec![primary; cfg.n_layer as usize];
129        for (il, device) in layer_devices.iter_mut().take(n_trunk).enumerate() {
130            *device = crate::pp::layer_engine(e, n_trunk, il)?.ctx().ordinal();
131        }
132        Ok(Self::from_layout(src, primary, layer_devices, true))
133    }
134
135    fn should_reside(&mut self, e: &Engine, il: usize, per_layer: usize) -> bool {
136        let device = self.layer_devices.get(il).copied().unwrap_or(self.primary_device);
137        debug_assert_eq!(e.ctx().ordinal(), device);
138        if let Some(&decision) = self.decisions.get(&device) {
139            return decision;
140        }
141        if std::env::var("MEMRA_MOE_RESIDENT").as_deref() == Ok("0") {
142            self.decisions.insert(device, false);
143            return false;
144        }
145        let (free, _total) = match e.ctx().mem_get_info() {
146            Ok(v) => v,
147            Err(_) => {
148                self.decisions.insert(device, false);
149                return false;
150            }
151        };
152        let projected = self.exact_expert_bytes.as_ref()
153            .map(|bytes| bytes.get(&device).copied().unwrap_or(0))
154            .unwrap_or(per_layer * self.layer_counts.get(&device).copied().unwrap_or(1));
155        let budget = std::env::var("MEMRA_MOE_RESIDENT_GB").ok()
156            .and_then(|v| v.parse::<f64>().ok())
157            .map(|gb| (gb * 1e9) as usize)
158            .unwrap_or_else(|| {
159                let reserve = std::env::var("MEMRA_MOE_RESIDENT_HEADROOM_GB").ok()
160                    .and_then(|v| v.parse::<f64>().ok())
161                    .map(|gb| (gb * 1e9) as usize)
162                    .unwrap_or(2_000_000_000);
163                (free as usize).saturating_sub(self.trunk_bytes + reserve)
164            });
165        let ok = projected <= budget;
166        eprintln!("[moe] resident-experts decision ({}dev{}): experts {:.2}GB + trunk {:.2}GB vs free {:.2}GB (expert budget {:.2}GB) -> {}",
167                  if self.pp { "PP " } else { "" }, device, projected as f64 / 1e9,
168                  self.trunk_bytes as f64 / 1e9, free as f64 / 1e9, budget as f64 / 1e9,
169                  if ok { "RESIDENT" } else { "SLRU cache" });
170        self.decisions.insert(device, ok);
171        ok
172    }
173}
174
175/// Load the mixer (full-attn, linear-attn, or MLA) for block `il`. Shared by the trunk loop and
176/// the MTP head. `kind` overrides cfg.layer_kind (the MTP/NextN block is ALWAYS full-attn
177/// regardless of the periodic interval — its GGUF carries attn_q/k/v, not ssm_*/attn_qkv).
178/// `mla` is the Arch gate: `Some` only for glm-dsa (cfg.mla) — every layer of an MLA model,
179/// INCLUDING its NextN/MTP block (dense MLA, no indexer), takes the Mla arm.
180///
181/// `sep_gate` = `ModelConfig::attn_gate_separate_at(il)`: load step35's separate head-wise
182/// `attn_gate.weight` onto the full-attn arm. It is passed in rather than read off a cfg so the
183/// MTP/draft call sites (which build a synthetic cfg) opt in explicitly.
184fn load_mixer_kind(
185    e: &Engine,
186    src: &dyn TensorSource,
187    il: u32,
188    kind: LayerKind,
189    mla: Option<&MlaConfig>,
190    sep_gate: bool,
191) -> Result<Mixer, Box<dyn std::error::Error>> {
192    let p = |s: &str| format!("blk.{il}.{s}");
193    if let Some(m) = mla {
194        assert_eq!(kind, LayerKind::FullAttention, "MLA layers are full-attention class");
195        return Ok(Mixer::Mla(MlaAttnLayer::load(e, src, il, m)?));
196    }
197    Ok(match kind {
198        LayerKind::FullAttention => Mixer::Full(FullAttnLayer {
199            wq: load_t(e, src, &p("attn_q.weight"))?,
200            wk: load_t(e, src, &p("attn_k.weight"))?,
201            // gemma4 global layers ship NO v_proj (attention_k_eq_v): V = the K projection
202            // output pre-rope (llama gemma4.cpp: `Vcur = wv ? mm(wv,cur) : Kcur`). Loading
203            // wv := wk reproduces that exactly with zero forward changes; the gemma forward
204            // adds the weightless V rms_norm (R7 part 2).
205            wv: match load_opt(e, src, &p("attn_v.weight"))? {
206                Some(v) => v,
207                None => load_t(e, src, &p("attn_k.weight"))?,
208            },
209            wo: load_t(e, src, &p("attn_output.weight"))?,
210            q_norm: load_t(e, src, &p("attn_q_norm.weight"))?,
211            k_norm: load_t(e, src, &p("attn_k_norm.weight"))?,
212            // step35: REQUIRED when the arch says so — a missing gate would silently drop the
213            // per-head sigmoid and produce plausible-but-wrong logits, so this is load_t not
214            // load_opt. Step-3.7-Flash ships it on all 45 blocks (width = that layer's n_head).
215            attn_gate: if sep_gate {
216                Some(load_t(e, src, &p("attn_gate.weight"))?)
217            } else {
218                None
219            },
220        }),
221        LayerKind::LinearAttention => Mixer::Linear(LinearAttnLayer {
222            wqkv: load_t(e, src, &p("attn_qkv.weight"))?,
223            wqkv_gate: load_t(e, src, &p("attn_gate.weight"))?,
224            ssm_beta: load_t(e, src, &p("ssm_beta.weight"))?,
225            ssm_alpha: load_t(e, src, &p("ssm_alpha.weight"))?,
226            ssm_a: load_t(e, src, &p("ssm_a"))?,
227            ssm_dt: load_t(e, src, &p("ssm_dt.bias"))?,
228            ssm_conv1d: load_t(e, src, &p("ssm_conv1d.weight"))?,
229            ssm_norm: load_t(e, src, &p("ssm_norm.weight"))?,
230            ssm_out: load_t(e, src, &p("ssm_out.weight"))?,
231        }),
232    })
233}
234
235/// Load the FFN (dense SwiGLU or routed MoE) for block `il`. Source-agnostic (GGUF or safetensors
236/// via `TensorSource`); shared by the hybrid trunk/MTP loops AND the dense-attention MoE path (OLMoE).
237/// Shared-expert tensors are OPTIONAL (`load_opt`): qwen35moe has them, OLMoE/vanilla-MoE do not.
238/// When `spill` is `Some` (MEMRA_SPILL_DISK on) AND the source is the GGUF on disk, MoE experts load
239/// through the per-expert tier split (`HostExps::load_tiered`: hottest pinned, rest mmap'd from disk);
240/// otherwise experts take the all-host / gather path. Spill tiering is GGUF-only (needs the file mmap).
241pub(crate) fn load_ffn(
242    e: &Engine,
243    src: &dyn TensorSource,
244    cfg: &ModelConfig,
245    il: u32,
246    spill: Option<(&GgufFile, &mut crate::spill::SpillCtx)>,
247    resident: &mut ResidentPlan,
248) -> Result<Ffn, Box<dyn std::error::Error>> {
249    let p = |s: &str| format!("blk.{il}.{s}");
250    // MiniMax-M3: moe_layer_freq[il]==0 -> this layer is a DENSE-FFN layer (layers 0..2) even
251    // though the arch is MoE; force the Dense arm (its mlp.{p}_proj names map via ggml_to_hf).
252    // Hy3: `first_k_dense_replace` leading layers are dense-FFN (REAP50: layer 0 only).
253    let dense_override = cfg.m3.as_ref()
254        .is_some_and(|m| m.moe_layer_freq.get(il as usize).copied() == Some(0))
255        || cfg.hy3.as_ref().is_some_and(|h| il < h.first_k_dense_replace)
256        // glm-dsa: leading_dense_block_count layers (GLM-5.2: 3) are dense-FFN
257        || cfg.mla.as_ref().is_some_and(|m| il < m.first_k_dense_replace)
258        // step35: leading_dense_block_count (Step-3.7-Flash: 3) — blocks 0-2 ship
259        // ffn_gate/up/down and NO ffn_gate_inp, so the MoE arm's load_t would fail.
260        || cfg.step35.as_ref().is_some_and(|s| il < s.first_k_dense_replace)
261        // gemma4 DENSE variants (31B/E4B): the arch is MoE-capable but the file ships no
262        // expert tensors at all — tensor presence decides.
263        || (cfg.gemma4.is_some() && !src.has(&p("ffn_gate_exps.weight"))
264            && !src.has(&p("ffn_gate_up_exps.weight")))
265        // A NextN/MTP BLOCK can be DENSE inside a MoE trunk. Step-3.7-Flash's standalone drafter
266        // (Step3.7-flash-mtp-Q8_0.gguf) ships blk.45/46/47 with `ffn_gate/up/down.weight` and NO
267        // `ffn_gate_inp`/`ffn_*_exps`, while the same file's config declares expert_count=288 (it
268        // carries the TRUNK's hparams) — so the MoE arm's `load_t("ffn_gate_exps.weight")` would
269        // fail on a perfectly well-formed file. Scoped to `il >= n_trunk` and gated on tensor
270        // presence: only an MTP block can take this door, so no trunk MoE layer's dispatch can
271        // shift. (qwen35's MTP block IS MoE and keeps the MoE arm — it ships the expert slabs.)
272        || (cfg.nextn_predict_layers > 0
273            && il >= cfg.n_layer.saturating_sub(cfg.nextn_predict_layers)
274            && src.has(&p("ffn_gate.weight"))
275            && !src.has(&p("ffn_gate_exps.weight"))
276            && !src.has(&p("ffn_gate_up_exps.weight")));
277    Ok(
278        if let Some(moe) = cfg.moe.as_ref().filter(|_| !dense_override) {
279            let n_expert = moe.expert_count as usize;
280            // Expert loader. `spill` carries an optional (GgufFile, SpillCtx) — only the GGUF on-disk
281            // path can tier (it needs the file mmap); safetensors always gathers/stacks all-host.
282            //  - spill Some -> per-expert tier split (hottest pinned, rest mmap'd from the GGUF).
283            //  - GGUF 3D stacked name resolves -> load_stacked_from_source (all-host).
284            //  - else (safetensors) -> gather N separate 2D expert tensors.
285            let (gate_exps, up_exps, down_exps) = match spill {
286                Some((g, ctx)) => (
287                    HostExps::load_tiered(e, g, &p("ffn_gate_exps.weight"), ctx)?,
288                    HostExps::load_tiered(e, g, &p("ffn_up_exps.weight"), ctx)?,
289                    HostExps::load_tiered(e, g, &p("ffn_down_exps.weight"), ctx)?,
290                ),
291                None => {
292                    let exps =
293                        |e: &Engine, n: &str| -> Result<HostExps, Box<dyn std::error::Error>> {
294                            if src.has(n) {
295                                HostExps::load_stacked_from_source(e, src, n)
296                            } else {
297                                HostExps::load_from_source(e, src, n, n_expert)
298                            }
299                        };
300                    // gemma4: gate+up ship FUSED (ffn_gate_up_exps, gate rows first) — split at load.
301                    let fused = p("ffn_gate_up_exps.weight");
302                    if !src.has(&p("ffn_gate_exps.weight")) && src.has(&fused) {
303                        let ff = moe.expert_ff_length as usize;
304                        (
305                            HostExps::load_stacked_split_from_source(e, src, &fused, 0, ff)?,
306                            HostExps::load_stacked_split_from_source(e, src, &fused, ff, 2 * ff)?,
307                            exps(e, &p("ffn_down_exps.weight"))?,
308                        )
309                    } else {
310                        (
311                            exps(e, &p("ffn_gate_exps.weight"))?,
312                            exps(e, &p("ffn_up_exps.weight"))?,
313                            exps(e, &p("ffn_down_exps.weight"))?,
314                        )
315                    }
316                }
317            };
318            // FITS-VRAM RESIDENT EXPERTS: upload this layer's 3 expert slabs when the owning
319            // device's budget (MEMRA_MOE_RESIDENT_GB override; default = free VRAM minus the file's
320            // non-expert bytes minus a measured headroom reserve) covers the expert bytes assigned
321            // to that device, summed exactly from the GGUF header. Decision is made once per device
322            // (first MoE layer there). Failure to fit => None => the SLRU spill machinery.
323            let dev_exps =
324                build_dev_exps(e, resident, il as usize, &gate_exps, &up_exps, &down_exps)?;
325            // Device macro row [3*n_expert]: gate, up, down (ones when the artifact carries none).
326            let mut macro_row = vec![1.0f32; 3 * n_expert];
327            for (slot, exps) in [(0usize, &gate_exps), (1, &up_exps), (2, &down_exps)] {
328                if let Some(ms) = exps.macros.as_ref() {
329                    macro_row[slot * n_expert..(slot + 1) * n_expert].copy_from_slice(ms);
330                }
331            }
332            let has_macros = macro_row.iter().any(|&m| m != 1.0);
333            let dev_macros = e.htod(&macro_row)?;
334            // e_score_correction_bias (M3 sigmoid routing): tiny [n_expert] f32, host-side.
335            let exp_probs_b = src
336                .find(&p("exp_probs_b.bias"))
337                .map(|v| memra_gguf::dequant::dequantize(v.ggml_type, &v.bytes, n_expert));
338            let active_experts = src.active_experts(il).map(<[bool]>::to_vec);
339            Ffn::Moe(MoeWeights {
340                gate_inp: load_t(e, src, &p("ffn_gate_inp.weight"))?,
341                gate_inp_shexp: load_opt(e, src, &p("ffn_gate_inp_shexp.weight"))?,
342                exp_probs_b,
343                active_experts,
344                gate_exps,
345                up_exps,
346                down_exps,
347                gate_shexp: load_opt(e, src, &p("ffn_gate_shexp.weight"))?,
348                up_shexp: load_opt(e, src, &p("ffn_up_shexp.weight"))?,
349                down_shexp: load_opt(e, src, &p("ffn_down_shexp.weight"))?,
350                dev_exps,
351                dev_macros,
352                has_macros,
353            })
354        } else {
355            Ffn::Dense {
356                ffn_gate: load_t(e, src, &p("ffn_gate.weight"))?,
357                ffn_up: load_t(e, src, &p("ffn_up.weight"))?,
358                ffn_down: load_t(e, src, &p("ffn_down.weight"))?,
359            }
360        }
361    )
362}
363
364/// Decide + build the resident expert slabs for one layer. Budget check runs once per device,
365/// RESIDENT-IF-FITS (2026-08-02, research/residency-cap-20260802/): the bank is resident when
366/// its EXACT byte total (summed from the GGUF header — UD-quants make per-layer bytes
367/// non-uniform, Ornith-35B blk.0 is +7% over the mean, so first-layer x n_layer misprojects)
368/// plus the file's non-expert bytes plus a measured headroom reserve fits free VRAM. The old
369/// default (0.80 x free vs first-layer x n_layer) reserved 20% of the card (4.8GB on 24GB)
370/// and spilled the Ornith-35B bank that fits — a priced -33% decode / -54% prefill. Measured
371/// need beside the weights at board shape is ~1.7GB (CUDA ctx + KV + workspace); reserve
372/// default 2.0GB, machine-specific override `MEMRA_MOE_RESIDENT_HEADROOM_GB` (VRAM-budget
373/// class). `MEMRA_MOE_RESIDENT_GB` stays the absolute expert-budget override;
374/// MEMRA_MOE_RESIDENT=0 forces the SLRU path. Fits => every subsequent layer on that device
375/// uploads too.
376fn build_dev_exps(
377    e: &Engine,
378    resident: &mut ResidentPlan,
379    il: usize,
380    gate: &HostExps,
381    up: &HostExps,
382    down: &HostExps,
383) -> Result<Option<crate::hybrid::DevExps>, Box<dyn std::error::Error>> {
384    // The resident pointer-table kernels take one qtype/row stride per projection. Mixed-expert
385    // layers stay on the metadata-aware staged/SLRU paths until those kernels group by layout.
386    if !gate.is_uniform_layout() || !up.is_uniform_layout() || !down.is_uniform_layout() {
387        return Ok(None);
388    }
389    let per_layer =
390        gate.bytes.as_bytes().len() + up.bytes.as_bytes().len() + down.bytes.as_bytes().len();
391    if gate.tiers.is_some() {
392        return Ok(None); // tiered/spill loads keep the cache path
393    }
394    let fits = resident.should_reside(e, il, per_layer);
395    if !fits {
396        return Ok(None);
397    }
398    use cudarc::driver::DevicePtr;
399    let gu_il = std::env::var("MEMRA_MOE_GU_IL").as_deref() == Ok("1")
400        && gate.out_f == up.out_f
401        && gate.in_f == up.in_f;
402    let n_expert = gate.n_expert;
403    let (g, u) = if gu_il {
404        // interleave gate/up rows: [ex][row o] = gate-row-o bytes ++ up-row-o bytes.
405        let (rbg, rbu) = (gate.row_bytes, up.row_bytes);
406        let n_rows = gate.out_f;
407        let gb = gate.bytes.as_bytes();
408        let ub = up.bytes.as_bytes();
409        let mut il = vec![0u8; n_expert * n_rows * (rbg + rbu)];
410        for ex in 0..n_expert {
411            for o in 0..n_rows {
412                let dst = (ex * n_rows + o) * (rbg + rbu);
413                let sg = ex * gate.expert_stride + o * rbg;
414                let su = ex * up.expert_stride + o * rbu;
415                il[dst..dst + rbg].copy_from_slice(&gb[sg..sg + rbg]);
416                il[dst + rbg..dst + rbg + rbu].copy_from_slice(&ub[su..su + rbu]);
417            }
418        }
419        let ild = e.htod_bytes_padded(&il, 8)?;
420        // `up` slot points into the same buffer via ptr math; keep a tiny placeholder alloc so
421        // the struct shape is unchanged (the table below carries the real pointers).
422        (ild, e.htod_bytes(&[0u8; 16])?)
423    } else {
424        (
425            e.htod_bytes_padded(gate.bytes.as_bytes(), 8)?,
426            e.htod_bytes_padded(up.bytes.as_bytes(), 8)?,
427        )
428    };
429    // 144B tail slack (2026-07-31, g26 prefill lever): the ragged-k expert MMA walks
430    // whole 256-val superblocks — the LAST row's final partial superblock overreads up
431    // to 144B past the slab (harmless bytes: the act's zero-padded k-range multiplies
432    // every overread weight to zero; the slack only prevents the OOB fault).
433    let d = e.htod_bytes_padded(down.bytes.as_bytes(), 144)?;
434    let mut host = vec![0u64; 3 * n_expert];
435    let (pg, pu, pd) = {
436        let __s_e0 = e.stream();
437        let (pg, _e0) = g.device_ptr(&__s_e0);
438        let __s_e1 = e.stream();
439        let (pu, _e1) = u.device_ptr(&__s_e1);
440        let __s_e2 = e.stream();
441        let (pd, _e2) = d.device_ptr(&__s_e2);
442        (pg as u64, pu as u64, pd as u64)
443    };
444    for ex in 0..n_expert {
445        if gu_il {
446            let stride = gate.out_f * (gate.row_bytes + up.row_bytes);
447            host[ex] = pg + (ex * stride) as u64;
448            host[n_expert + ex] = pg + (ex * stride + gate.row_bytes) as u64;
449        } else {
450            host[ex] = pg + (ex * gate.expert_stride) as u64;
451            host[n_expert + ex] = pu + (ex * up.expert_stride) as u64;
452        }
453        host[2 * n_expert + ex] = pd + (ex * down.expert_stride) as u64;
454    }
455    if gu_il {
456        eprintln!("[moe] gate/up dev slab INTERLEAVED (MEMRA_MOE_GU_IL)");
457    }
458    let ptr_row = e.htod_u64(&host)?;
459    Ok(Some(crate::hybrid::DevExps {
460        gate: g,
461        up: u,
462        down: d,
463        ptr_row,
464        gu_il,
465        dev: e.ctx().ordinal(),
466    }))
467}
468
469pub struct FullAttnLayer {
470    pub wq: GpuTensor,
471    pub wk: GpuTensor,
472    pub wv: GpuTensor,
473    pub wo: GpuTensor,
474    pub q_norm: GpuTensor,
475    pub k_norm: GpuTensor,
476    /// step35-class SEPARATE head-wise attention gate: `blk.N.attn_gate.weight [n_embd, n_head_l]`
477    /// where `n_head_l` is this layer's query-head count (64 full / 96 SWA on Step-3.7-Flash, so
478    /// the width VARIES per layer). Produces one pre-sigmoid scalar per head from the
479    /// post-attn_norm hidden state; the forward broadcasts sigmoid(gate) over head_dim and
480    /// multiplies attn_out before wo (upstream `step35.cpp:267-285`).
481    ///
482    /// `None` for every other arch. Do NOT confuse with `LinearAttnLayer::wqkv_gate`, which reads
483    /// the SAME tensor name on qwen35's SSM layers but is a different mechanism (a full-width
484    /// z-gate, not a per-head scalar), nor with the qwen35 FUSED gate packed inside wq that
485    /// `ModelConfig::attn_out_gate()` / `q_gate_split` handle.
486    pub attn_gate: Option<GpuTensor>,
487}
488
489/// Latent-KV geometry for one MLA layer, resolved at load from `MlaConfig` (glm-dsa). The KV
490/// cache stores ONE `latent_dim`-wide row per token per layer: [rmsnorm(c_kv) | rope(k_pe)];
491/// V is the first `kv_rank` elements of the SAME row (no V plane). All heads stream it (MQA).
492#[derive(Clone, Copy, Debug)]
493pub struct MlaGeom {
494    pub n_head: usize,     // 64  — query heads; n_head_kv semantics = 1
495    pub d_nope: usize,     // 192 — qk nope head dim (absorb GEMM K)
496    pub d_rope: usize,     // 64  — decoupled rope width (q_pe / k_pe)
497    pub d_v: usize,        // 256 — v head dim after wv_b decompression
498    pub kv_rank: usize,    // 512 — latent rank (absorbed qk dim, AV accumulator width)
499    pub latent_dim: usize, // 576 = kv_rank + d_rope — the cache row / K width
500    pub scale: f32,        // 1/sqrt(d_nope + d_rope) = 1/16 — NOT 1/sqrt(latent_dim)
501}
502
503/// GLM-5.2 MLA attention block (DESIGN.md §3.1 mapping). INCREMENT 2: loader-only — the
504/// projections + latent-cache geometry land on device; forward arms (prefill/decode/dc/graph)
505/// are increment 4. The CPU oracle for those arms is `crate::mla` (naive ≡ absorbed, proven).
506pub struct MlaAttnLayer {
507    pub wq_a: GpuTensor,      // attn_q_a.weight      [H -> Lq] (q down-projection)
508    pub q_a_norm: GpuTensor,  // attn_q_a_norm.weight [Lq]
509    pub wq_b: GpuTensor,      // attn_q_b.weight      [Lq -> N*(nope+rope)] (q up, per head [nope|rope])
510    pub wkv_a: GpuTensor,     // attn_kv_a_mqa.weight [H -> Lkv+rope] (latent row producer)
511    pub kv_a_norm: GpuTensor, // attn_kv_a_norm.weight [Lkv] (c_kv rms; k_pe is NOT normed)
512    pub wk_b: GpuTensor,      // attn_k_b.weight      [nope, Lkv, N] 3D — TRANSPOSED nope slice of
513                              //   kv_b (conversion split): the per-head absorb GEMM operand
514    pub wv_b: GpuTensor,      // attn_v_b.weight      [Lkv, V, N] 3D — the post-softmax decompress
515    pub wo: GpuTensor,        // attn_output.weight   [N*V -> H]
516    pub geom: MlaGeom,
517}
518
519impl MlaAttnLayer {
520    /// Load one MLA attention block to device. `attn_kv_b` (the unsplit tensor, when present)
521    /// is intentionally NOT loaded — v1 runs absorbed-form everywhere; the MHA-prefill arm that
522    /// would consume it is a later arc (DESIGN.md §3.1 "unused v1").
523    ///
524    /// NOTE (increment-3+): wk_b/wv_b are 3D. The F32 fixture rides the Float path (exact, full
525    /// ne kept). Quantized 3D tensors would mis-derive `row_bytes` in the generic 2D Quant arm
526    /// (out_f = ne[1] only) — the real-weights loader must split per head or flatten ne[1]*ne[2]
527    /// before the batched-GEMM kernels consume them. Guarded by the assert below.
528    pub fn load(
529        e: &Engine,
530        src: &dyn TensorSource,
531        il: u32,
532        m: &MlaConfig,
533    ) -> Result<Self, Box<dyn std::error::Error>> {
534        let p = |s: &str| format!("blk.{il}.{s}");
535        let geom = MlaGeom {
536            n_head: 0, // patched below from wq_b's out width (metadata cross-check)
537            d_nope: m.qk_nope_head_dim as usize,
538            d_rope: m.qk_rope_head_dim as usize,
539            d_v: m.v_head_dim as usize,
540            kv_rank: m.kv_lora_rank as usize,
541            latent_dim: m.latent_dim() as usize,
542            scale: m.scale(),
543        };
544        let wq_a = load_t(e, src, &p("attn_q_a.weight"))?;
545        let wq_b = load_t(e, src, &p("attn_q_b.weight"))?;
546        let wkv_a = load_t(e, src, &p("attn_kv_a_mqa.weight"))?;
547        let wk_b = load_t(e, src, &p("attn_k_b.weight"))?;
548        let wv_b = load_t(e, src, &p("attn_v_b.weight"))?;
549        let wo = load_t(e, src, &p("attn_output.weight"))?;
550        // shape audit at load (fail loudly, not as garbage activations later):
551        let n_head = wq_b.out_features() / (geom.d_nope + geom.d_rope);
552        assert_eq!(wq_b.out_features(), n_head * (geom.d_nope + geom.d_rope),
553                   "wq_b out {} not a multiple of qk_head_dim {}", wq_b.out_features(),
554                   geom.d_nope + geom.d_rope);
555        assert_eq!(wq_a.in_features() , wkv_a.in_features(), "q_a/kv_a hidden mismatch");
556        assert_eq!(wq_b.in_features(), m.q_lora_rank as usize, "wq_b in != q_lora_rank");
557        assert_eq!(wkv_a.out_features(), geom.latent_dim, "wkv_a out != kv_lora_rank + rope");
558        assert_eq!(wk_b.ne(), &[geom.d_nope as u64, geom.kv_rank as u64, n_head as u64],
559                   "attn_k_b must be the TRANSPOSED (nope, kv_rank, head) conversion split");
560        assert_eq!(wv_b.ne(), &[geom.kv_rank as u64, geom.d_v as u64, n_head as u64],
561                   "attn_v_b must be the (kv_rank, v, head) conversion split");
562        assert_eq!(wo.in_features(), n_head * geom.d_v, "wo in != n_head * v_head_dim");
563        Ok(MlaAttnLayer {
564            wq_a,
565            q_a_norm: load_t(e, src, &p("attn_q_a_norm.weight"))?,
566            wq_b,
567            wkv_a,
568            kv_a_norm: load_t(e, src, &p("attn_kv_a_norm.weight"))?,
569            wk_b,
570            wv_b,
571            wo,
572            geom: MlaGeom { n_head, ..geom },
573        })
574    }
575}
576
577/// Increment-2 guard: every forward-path `match` on `Mixer` routes Mla here until increment 4
578/// lands the MLA kernels. Loading a glm-dsa model works; running it panics with THIS message
579/// instead of garbage math. Zero behavior change for Full/Linear arches (arm never taken).
580#[track_caller]
581pub(crate) fn mla_forward_unimplemented() -> ! {
582    panic!("Mixer::Mla has no forward arm yet — glm-dsa is loader-only in increment 2; \
583            the CUDA forward lands in increment 4 (research/mla-bringup-20260801/DESIGN.md §4)")
584}
585
586pub struct LinearAttnLayer {
587    pub wqkv: GpuTensor,       // [n_embd, conv_dim] -> qkv_mixed
588    pub wqkv_gate: GpuTensor,  // [n_embd, value_dim] -> z
589    pub ssm_beta: GpuTensor,   // [n_embd, num_v_heads]
590    pub ssm_alpha: GpuTensor,  // [n_embd, num_v_heads]
591    pub ssm_a: GpuTensor,      // [num_v_heads] (pre-negated -exp(A_log))
592    pub ssm_dt: GpuTensor,     // [num_v_heads] bias
593    pub ssm_conv1d: GpuTensor, // [d_conv, conv_dim]
594    pub ssm_norm: GpuTensor,   // [head_v_dim]
595    pub ssm_out: GpuTensor,    // [value_dim, n_embd]
596}
597
598pub enum Mixer {
599    Full(FullAttnLayer),
600    Linear(LinearAttnLayer),
601    /// glm-dsa MLA block (loader-only in increment 2; forward = increment 4).
602    Mla(MlaAttnLayer),
603}
604
605/// MoE weights for one layer. Router + shared expert stay GPU-RESIDENT (tiny); the routed
606/// experts stay HOST-RESIDENT (HostExps) and are staged per-token (EDGE-1).
607///
608/// The shared-expert fields are `Option`: qwen35moe carries a shared expert, but OLMoE (and most
609/// vanilla MoE) have none (`shared_expert_intermediate_size` absent) — those layers `load_opt` the
610/// shexp tensors to `None` (ST-MOE-PLAN §1.3, §3.2). When `None` the shared-expert branch is skipped.
611pub struct MoeWeights {
612    pub gate_inp: GpuTensor, // F32 [n_embd, n_expert] router  (GPU resident, Float)
613    pub gate_inp_shexp: Option<GpuTensor>, // F32 [n_embd] 1-D shared gate dot (qwen35moe only)
614    /// DeepSeek-V3/MiniMax-M3 `e_score_correction_bias` [n_expert]: added to the sigmoid scores
615    /// for expert SELECTION only; the routing weights use the un-biased scores. Kept host-side —
616    /// routing's top-k is a host loop and this is n_expert floats.
617    pub exp_probs_b: Option<Vec<f32>>,
618    /// Original-width router mask for physically pruned expert overlays. Inactive ids never enter
619    /// top-k, so their absent weight files cannot be dispatched.
620    pub active_experts: Option<Vec<bool>>,
621    pub gate_exps: HostExps, // [n_embd, n_ff_exp, n_expert]   (HOST)
622    pub up_exps: HostExps,   // [n_embd, n_ff_exp, n_expert]   (HOST)
623    pub down_exps: HostExps, // [n_ff_exp, n_embd, n_expert] TRANSPOSED (HOST)
624    pub gate_shexp: Option<GpuTensor>,
625    pub up_shexp: Option<GpuTensor>,
626    pub down_shexp: Option<GpuTensor>,
627    /// FITS-VRAM RESIDENT EXPERTS (2026-07-06): when the WHOLE model's expert bytes fit the VRAM
628    /// budget, each (proj) slab is uploaded once as a contiguous device buffer and the fused
629    /// _dev kernels take base+ex*stride pointers — no SLRU, no dispatch, no residency checks
630    /// (llama's full-offload regime; measured 169.55 vs memra's cache path 28.5 on the local 35B).
631    /// None => the SLRU host-expert machinery (the spill regime, where it WINS vs llama's
632    /// CPU-offload degradation). Decided at load in `load_ffn` (MEMRA_MOE_RESIDENT=0 forces off).
633    pub dev_exps: Option<DevExps>,
634    /// Per-expert post-matmul macro-scales on DEVICE: [3*n_expert] f32 in (gate, up, down)
635    /// order — all 1.0 unless the checkpoint carries compressed-tensors NVFP4 global scales
636    /// (unsloth qwen3.6 class). The _dev gate_up epilogues multiply unconditionally (x*1.0f
637    /// is bit-exact — zero change for macro-free artifacts); the down fold is one
638    /// moe_w_scale_by_expert launch gated on `has_macros`.
639    pub dev_macros: cudarc::driver::CudaSlice<f32>,
640    pub has_macros: bool,
641}
642
643impl MoeWeights {
644    #[inline]
645    pub fn has_uniform_expert_layout(&self) -> bool {
646        self.gate_exps.is_uniform_layout()
647            && self.up_exps.is_uniform_layout()
648            && self.down_exps.is_uniform_layout()
649    }
650}
651
652/// Device-resident expert slabs for one layer (gate/up/down) + the prebuilt [3, n_expert]
653/// pointer row the _dev kernels consume.
654pub struct DevExps {
655    pub gate: CudaSlice<u8>,
656    pub up: CudaSlice<u8>,
657    pub down: CudaSlice<u8>,
658    /// [3*n_expert] u64 device row: gate ptrs, up ptrs, down ptrs (proj-major like layer_dev_row).
659    pub ptr_row: CudaSlice<u64>,
660    /// The CUDA device ordinal these slabs live on (the OWNING stage's device under the PP
661    /// sharded loader — cx-503b sizes and `layer_engine` places per device). Consumers that
662    /// dispatch from a DIFFERENT device must NOT dereference the slabs: an m=1 qmatvec over
663    /// peer-read expert bytes is the measured 34-150x slow class (research/pp-prefill-20260807
664    /// anatomy), strictly worse than SLRU staging. The sequential arm's slab-locality gate
665    /// (lane/pp-leverb) keys on this field; the per-stage prime walker makes every layer's
666    /// slab local by construction.
667    pub dev: usize,
668    /// WALL-GAP ARC (MEMRA_MOE_GU_IL=1): gate/up rows INTERLEAVED in one slab — row o of gate at
669    /// base + o*(rb_g+rb_u), up at +rb_g. Consumers on the dev path must use (rb_g+rb_u) as the
670    /// row stride for BOTH projections (see MoeWeights::dev_rb_gu). One contiguous 1760B stream
671    /// per (expert,row) instead of two scattered 880B streams — the measured 56%-of-wall fix
672    /// candidate. Kernels unchanged (stride is already a parameter everywhere).
673    pub gu_il: bool,
674}
675
676/// Per-layer FFN: dense SwiGLU (qwen35) or 256-expert MoE (qwen35moe).
677pub enum Ffn {
678    Dense {
679        ffn_gate: GpuTensor,
680        ffn_up: GpuTensor,
681        ffn_down: GpuTensor,
682    },
683    Moe(MoeWeights),
684}
685
686pub struct HybridLayer {
687    pub attn_norm: GpuTensor,
688    pub post_attn_norm: GpuTensor, // "post_attention_norm" = PRE-FFN norm
689    pub mixer: Mixer,
690    pub ffn: Ffn,
691    pub gemma4: Option<Gemma4LayerBits>,
692}
693
694/// Gemma-4 per-layer extras (R8 wiring, HANDOVER "R8 VERIFIED WIRING"): the parallel shared
695/// FFN branch, the four extra norms, the router prologue scale vector, per-expert output
696/// scales, and the layer output scalar.
697pub struct Gemma4LayerBits {
698    pub ffn_norm: GpuTensor, // ffn pre-norm (dense: THE ffn norm; moe: shared branch)
699    pub post_ffw_norm: GpuTensor, // combined post (before the attn_out residual)
700    /// MoE-layer extras (None on the dense gemma4 variants — 31B/E4B): the parallel shared
701    /// branch norms + tensors, the router prologue vector, per-expert output scales.
702    pub moe_bits: Option<Gemma4MoeBits>,
703    pub layer_scale: f32, // layer_output_scale [1]
704    /// E4B extras (None on 26B/31B): the per-layer-embedding tail block + KV-share target.
705    pub e4b: Option<Gemma4E4bLayer>,
706}
707
708/// gemma-4 E4B per-layer bits (see research/gemma4-bringup/e4b-arch-map.md):
709/// tail block  cur += rms_norm(proj . (gelu(inp_gate . cur) * inp_pl[il]), post_norm)
710/// and the KV-share map — layers il >= n_layer-shared_kv_layers have NO own k/v projections
711/// and attend the cache of layer (n_layer-shared) - (swa ? 2 : 1) with their own Q.
712pub struct Gemma4E4bLayer {
713    pub inp_gate: GpuTensor,           // blk.N.inp_gate  [n_embd, n_epl]
714    pub proj: GpuTensor,               // blk.N.proj      [n_epl, n_embd]
715    pub post_norm: GpuTensor,          // blk.N.post_norm [n_embd]
716    /// wave-4b: wq|wk|wv concatenated along OUT (one Q4_0 matvec at t=1 instead of the
717    /// fused3 3-subgrid launch). Built at the mirror hook from the GPU byte planes (rows
718    /// are independent in Q4_0, so an out-dim concat is a byte concat); own-KV layers only.
719    pub qkv_cat: Option<GpuTensor>,
720    /// Some(target_layer) on KV-shared layers (wk/wv here are the TARGET layer's tensors,
721    /// loaded for shape symmetry only — the forward must skip k/v compute + append and read
722    /// the target's cache; TODO dedupe the duplicate weight upload ~63MB).
723    pub kv_share: Option<u32>,
724}
725
726/// gemma-4 E4B model-level per-layer-embedding tensors (prologue inputs). The token table
727/// stays HOST-side raw GGUF bytes at load (Q6_K [n_epl*n_layer, n_vocab], ~2.3GB VRAM when
728/// uploaded — the forward arc decides resident-vs-gather placement).
729pub struct Gemma4E4bModel {
730    /// device copy of the per-layer token table, uploaded on first use (the 26B embd_gpu
731    /// pattern — keeps the ~2.3GB off load-critical paths that never decode).
732    pub tok_tbl_gpu: std::sync::OnceLock<CudaSlice<u8>>,
733    pub tok_embd_bytes: Vec<u8>,
734    pub tok_embd_qt: i32,
735    pub tok_embd_row_bytes: usize,
736    pub model_proj: GpuTensor, // per_layer_model_proj [n_embd, n_epl*n_layer] F16
737    pub proj_norm: GpuTensor,  // per_layer_proj_norm [n_epl]
738    pub n_epl: usize,
739}
740
741pub struct Gemma4MoeBits {
742    pub post_ffw_norm_1: GpuTensor, // shared-branch post
743    pub pre_ffw_norm_2: GpuTensor,  // moe-branch pre
744    pub post_ffw_norm_2: GpuTensor, // moe-branch post
745    pub shared_gate: GpuTensor,
746    pub shared_up: GpuTensor,
747    pub shared_down: GpuTensor,
748    /// ffn_gate_inp.scale [n_embd] PRE-multiplied by 1/sqrt(n_embd) at load: the router
749    /// prologue (weightless rms_norm x 1/sqrt(n_embd) x scale-vec) collapses to ONE rms_norm
750    /// with this as the norm weight (x_hat * (v*s) vs llama's (x_hat*s)*v — one reassociation;
751    /// the argmax gate arbitrates).
752    pub router_scale_pre: CudaSlice<f32>,
753    pub per_expert_scale: Vec<f32>, // ffn_down_exps.scale [n_expert] (host)
754    pub per_expert_scale_d: CudaSlice<f32>, // device copy (router-weight fold kernel)
755}
756
757/// Qwen3.5 NextN/MTP head: a full transformer block (attn+FFN, same tensors as a trunk layer)
758/// plus the MTP glue (enorm/hnorm/eh_proj that fold the next-token embedding into the trunk
759/// hidden, and an optional shared_head_norm/head). Loaded from blk.{n_trunk}.* — the block the
760/// trunk loop drops. Used for speculative decode (drafts 1 token per call). See research/mtp/MTP-PLAN.md.
761pub struct MtpHead {
762    pub enorm: GpuTensor, // blk.N.nextn.enorm   — RMSNorm of the next-token embedding
763    pub hnorm: GpuTensor, // blk.N.nextn.hnorm   — RMSNorm of the trunk hidden
764    pub eh_proj: GpuTensor, // blk.N.nextn.eh_proj [2*n_embd, n_embd]: [e_norm; h_norm] -> n_embd
765    pub attn_norm: GpuTensor, // blk.N.attn_norm
766    pub post_attn_norm: GpuTensor, // blk.N.post_attention_norm (pre-FFN)
767    pub mixer: Mixer,     // full-attn block (qwen35 MTP block is full-attn)
768    pub ffn: Ffn,         // Dense or Moe, same loader as trunk
769    pub shared_head_norm: Option<GpuTensor>, // blk.N.nextn.shared_head_norm (else reuse output_norm)
770    pub shared_head_head: Option<GpuTensor>, // blk.N.nextn.shared_head      (else reuse output)
771    /// FR-Spec draft->target vocab map: the draft lm_head is TRIMMED to the highest-frequency
772    /// tokens (e.g. 32768 rows of the full 248320-row head); `d2t[draft_idx]` = the target vocab
773    /// token id of trimmed row `draft_idx`. `None` for a full-vocab head (identity map). Host-side:
774    /// the draft argmax already lands on host as one u32, so the map is a single Vec index.
775    pub d2t: Option<Vec<u32>>,
776    /// DISTILLED-STUDENT geometry (None = the natural NextN block at trunk shape). A distilled
777    /// draft (StudentSV) runs the same block structure at a narrower inner width with fewer
778    /// heads, then up-projects back to n_embd (`out_up`) — the chain carrier and the head input
779    /// stay at n_embd, so the trunk/verify interface is unchanged. Selected by the presence of
780    /// `blk.N.nextn.out_up.weight` in a MEMRA_MTP_DRAFT file.
781    pub geom: Option<DraftGeom>,
782    /// step35: the DRAFT BLOCK's RESOLVED per-layer geometry (`None` for every arch whose
783    /// geometry is uniform). Without it the head forward would use the trunk's max-derived
784    /// scalars and compute wrong attention — and the failure mode is plausible-but-wrong drafts
785    /// (tanked acceptance, correct output), exactly what the exactness gates cannot see.
786    pub step35: Option<Step35MtpGeom>,
787}
788
789/// step35 MTP-block geometry, RESOLVED at load time from the file that actually carries the
790/// block's own `Step35Config` arrays.
791///
792/// Why resolved and not "look it up per forward from the model's cfg": Step-3.7-Flash ships MTP
793/// as a SEPARATE GGUF, and the two files disagree about which layers exist. The trunk artifact
794/// declares `block_count=45` / `nextn_predict_layers=0`, so its per-layer arrays hold 45 entries
795/// (0..=44) and `Step35Config::n_head(45)` falls off the end into the `.last()` fallback — index
796/// 44, which is a FULL-attn layer at 64 heads. The draft file declares `block_count=48` /
797/// `nextn=3` and its arrays' index 45 is the truth: SWA, 96 heads (matching that file's
798/// `blk.45.attn_q.weight [4096, 12288]` = 96*128 and `blk.45.attn_gate.weight [4096, 96]`).
799/// Receipt: `research/step37-bringup-20260802/raw/gguf-header-stepfun-mtp-q8-20260802.txt` plus
800/// the tail dump in `research/step37-p2-20260806/raw/` — `head_count[43..48] = [96, 64, 96, 96,
801/// 96]`, `sliding_window_pattern[43..48] = [True, False, True, True, True]`.
802#[derive(Debug, Clone)]
803pub struct Step35MtpGeom {
804    /// Block index inside the file that carries it (45 for Step-3.7-Flash). Diagnostics only.
805    pub il: u32,
806    pub n_head: usize,    // 96 on Step-3.7-Flash's MTP block (SWA-type)
807    pub n_head_kv: usize, // 8
808    pub n_rot: usize,     // 128 (SWA keeps the unhalved rotary width)
809    pub rope_base: f32,   // 1e4 (SWA base, not the trunk's 5e6 global)
810    pub swa: bool,        // true
811    pub window: usize,    // 512
812    /// This block's `swiglu_clamp_shexp` limit. The MTP block's FFN is a DENSE SwiGLU, and
813    /// upstream's one `build_ffn` serves both the dense MLP and the shared expert off the
814    /// SHEXP array (llama-graph.cpp:1751) — so a dense MTP block keys off shexp, not exp.
815    /// 0.0 (`None`) on Step-3.7-Flash's block 45; live (16.0) only on trunk layers 43-44.
816    pub clamp_shexp: Option<f32>,
817}
818
819impl Step35MtpGeom {
820    /// Resolve block `il` from the geometry table of the file that OWNS that block.
821    pub fn resolve(cfg: &ModelConfig, il: u32) -> Self {
822        let s = cfg.step35.as_ref().expect("step35 MTP geometry needs step35 config");
823        let geometry = cfg.layer_geometry(il)
824            .unwrap_or_else(|| panic!("step35 MTP block {il} has no geometry-table row"));
825        assert_eq!(
826            geometry.attention_gate,
827            memra_gguf::config::AttentionGateKind::SeparateHead,
828            "step35 MTP block {il} lost its separate attention gate"
829        );
830        Step35MtpGeom {
831            il,
832            n_head: geometry.n_head as usize,
833            n_head_kv: geometry.n_head_kv as usize,
834            n_rot: geometry.n_rot as usize,
835            rope_base: geometry.rope_base,
836            swa: geometry.window.is_some(),
837            window: geometry.window.unwrap_or(s.sliding_window) as usize,
838            clamp_shexp: s.clamp_shexp(il),
839        }
840    }
841}
842
843/// Draft-head geometry override for a distilled (narrower) student block.
844pub struct DraftGeom {
845    pub d_inner: usize, // block inner width (eh_proj out / attn / ffn), e.g. 2048
846    pub n_head: usize,  // draft attention heads (head_dim = main head_dim)
847    pub n_head_kv: usize,
848    pub out_up: GpuTensor, // [d_inner -> n_embd]: carrier + head input up-projection
849}
850
851/// Which tensor is the DRAFT lm_head, for a standalone NextN/MTP draft GGUF whose block index is
852/// `n`. Preference order is the artifact's, not ours — upstream step35.cpp:553 is
853/// `layer.nextn.shared_head_head ? layer.nextn.shared_head_head : model.output`.
854///
855/// Split out of `MtpHead::load_draft` purely so it is unit-testable: the loader needs a CUDA
856/// device and a multi-GB file, while the failure this guards is invisible to every exactness gate
857/// (a wrong head still produces CORRECT output — the verify arbitrates — it just accepts nothing).
858/// `has` is the tensor-presence predicate (`src.has`).
859pub fn draft_head_tensor(has: impl Fn(&str) -> bool, n: u32) -> String {
860    let own = format!("blk.{n}.nextn.shared_head_head.weight");
861    if has(&own) {
862        return own;
863    }
864    // Legacy name kept as a probe so anything that ever matched it still does; no shipped
865    // artifact or upstream mapping uses it (see the `load_draft` note).
866    let legacy = format!("blk.{n}.nextn.shared_head.weight");
867    if has(&legacy) {
868        return legacy;
869    }
870    // FR-Spec / tied-head drafts: the file-level head IS the draft head.
871    "output.weight".to_string()
872}
873
874impl MtpHead {
875    /// Load an MTP/NextN head from a STANDALONE draft GGUF (MEMRA_MTP_DRAFT override). The draft
876    /// file carries ONLY the NextN block (blk.N.nextn.* glue + attn/ffn) plus its own lm_head
877    /// (`output.weight`) — which for an FR-Spec draft is TRIMMED to the top-frequency rows, with
878    /// a `d2t` (i32/i64) tensor mapping trimmed-row index -> target vocab token id. Draft-token
879    /// embedding still uses the MAIN model's token_embd (identical weights, saves VRAM), so the
880    /// draft file's full-vocab token_embd copy is ignored.
881    pub fn load_draft(
882        e: &Engine,
883        g: &GgufFile,
884        main_cfg: &ModelConfig,
885    ) -> Result<Self, Box<dyn std::error::Error>> {
886        let src = GgufSource(g);
887        let dcfg = src.config();
888        // NextN block index INSIDE THE DRAFT FILE (its block_count includes the trunk numbering).
889        // Graceful error, not assert: the server's `+draft` attach path surfaces this to the
890        // user (a gemma-assistant draft or any non-NextN GGUF lands here; a panic killed the
891        // whole worker — serve-smoke find, 2026-07-30).
892        if dcfg.nextn_predict_layers == 0 {
893            return Err(format!(
894                "draft GGUF has no nextn_predict_layers (arch {:?}) — not a NextN/MTP regime \
895                 draft; gemma assistant drafters attach via MEMRA_DRAFT, not '+draft'",
896                g.arch()).into());
897        }
898        let n = dcfg.n_layer - dcfg.nextn_predict_layers;
899        let p = |s: &str| format!("blk.{n}.{s}");
900
901        // Distilled student (narrow block + out_up) vs natural NextN clone. The interface dims
902        // (n_embd in/out, head_dim for the shared rope kernel) must match the main model; a
903        // student may shrink the inner width and head counts.
904        let student = src.has(&p("nextn.out_up.weight"));
905        assert_eq!(dcfg.n_embd, main_cfg.n_embd, "draft n_embd != model n_embd");
906        assert_eq!(
907            dcfg.head_dim_k, main_cfg.head_dim_k,
908            "draft head_dim != model head_dim"
909        );
910        // step35: geometry is PER-LAYER, so "same shape as the trunk" is the wrong question — the
911        // draft block at il=45 is an SWA-type block (96 q heads, 128 rotary dims, rope base 1e4)
912        // while the trunk's full-attn layers are 64/64/5e6. Resolve the block's geometry from the
913        // DRAFT FILE's own arrays (the trunk artifact's arrays stop at index 44 — see
914        // `Step35MtpGeom`'s note) and verify it against the block's real tensor shapes. The dims
915        // that must still agree with the trunk are the INTERFACE ones (n_embd, head_dim, KV width).
916        let step35 = match (main_cfg.step35.as_ref(), dcfg.step35.as_ref()) {
917            (Some(_), Some(_)) => {
918                let g = Step35MtpGeom::resolve(&dcfg, n);
919                // ne is inner-fastest: ne[0] = in_features, ne[1] = out_features for a [in, out] 2D.
920                let out_f = |t: &str| -> Option<usize> {
921                    src.find(&p(t)).and_then(|v| v.ne.get(1).copied()).map(|x| x as usize)
922                };
923                let hd = dcfg.head_dim_k as usize;
924                let wq_out = out_f("attn_q.weight")
925                    .ok_or("step35 draft block has no attn_q.weight")?;
926                assert_eq!(
927                    wq_out, g.n_head * hd,
928                    "step35 draft blk.{n}: attn_q out {wq_out} != n_head({}) * head_dim({hd}) — \
929                     the draft file's head_count array disagrees with its own tensors",
930                    g.n_head
931                );
932                // The SEPARATE head-wise gate is [n_embd, n_head_l] — one scalar per head. Its
933                // width is the second independent witness of this block's head count.
934                let wg_out = out_f("attn_gate.weight")
935                    .ok_or("step35 draft block has no attn_gate.weight (head-wise gate)")?;
936                assert_eq!(
937                    wg_out, g.n_head,
938                    "step35 draft blk.{n}: attn_gate out {wg_out} != n_head({})", g.n_head
939                );
940                // The draft attends its OWN scratch, but `MtpScratch::new` sizes those rows from
941                // the TRUNK cfg's `n_head_kv` (for step35, the max over its per-layer array).
942                // Compare against exactly that value, not a per-layer accessor.
943                assert_eq!(
944                    g.n_head_kv, main_cfg.n_head_kv as usize,
945                    "step35 draft blk.{n} KV heads {} != trunk n_head_kv {} — the MTP scratch \
946                     rows are sized from the trunk cfg, so a differing draft KV width would \
947                     write past the row",
948                    g.n_head_kv, main_cfg.n_head_kv
949                );
950                eprintln!(
951                    "[mtp-draft] step35 MTP geometry blk.{n}: n_head={} n_head_kv={} n_rot={} \
952                     rope_base={:.0} swa={} window={}",
953                    g.n_head, g.n_head_kv, g.n_rot, g.rope_base, g.swa, g.window
954                );
955                Some(g)
956            }
957            (Some(_), None) => {
958                return Err(format!(
959                    "MEMRA_MTP_DRAFT points at a non-step35 GGUF (arch {:?}) but the model is \
960                     step35 — the draft block's per-layer geometry is unknowable from the trunk \
961                     config (its arrays stop at the trunk's last layer)",
962                    g.arch()
963                ).into())
964            }
965            (None, Some(_)) => {
966                return Err("MEMRA_MTP_DRAFT is a step35 draft but the model is not step35".into())
967            }
968            (None, None) => None,
969        };
970        if step35.is_none() && !student {
971            // The head forward runs with the MAIN model's cfg — the draft block must be the
972            // same shape or the forward is garbage.
973            assert_eq!(dcfg.n_head, main_cfg.n_head, "draft n_head != model n_head");
974            assert_eq!(
975                dcfg.n_head_kv, main_cfg.n_head_kv,
976                "draft n_head_kv != model n_head_kv"
977            );
978        }
979
980        // Draft lm_head. PREFERENCE ORDER IS THE ARTIFACT'S, NOT OURS (upstream step35.cpp:553
981        // `layer.nextn.shared_head_head ? ... : model.output`): a NextN block owns its OWN head,
982        // and only a file that omits it falls back to the file-level `output.weight`.
983        //
984        // MEASURED ON THE SHIPPED ARTIFACT (Step3.7-flash-mtp-Q8_0.gguf, byte hashes in
985        // research/step37-p2-20260806/raw/draft-head-tensor-hashes-20260807.txt): the file carries
986        // BOTH, they are DIFFERENT matrices, and the three MTP blocks' heads differ from each
987        // other too —
988        //     output.weight                        sha 3eec5831…  <- the TRUNK lm_head, re-quantized
989        //     blk.45.nextn.shared_head_head.weight sha c90b907b…  <- block 45's own head
990        //     blk.46 …                             sha a22d2957…
991        //     blk.47 …                             sha 4b21e137…
992        // The tell: this file's top-level `output_norm.weight` is BYTE-IDENTICAL to the trunk
993        // artifact's (both sha d7526f44…), i.e. the top level is a copy of the trunk's output
994        // stack, present so the draft gguf stands alone. Reading it as the draft head projects
995        // the MTP block's hidden through the TRUNK's head — coherent-looking drafts the verify
996        // never accepts. Receipt: acceptance 0/248 across K=1..8 with self-consistency PASS
997        // (raw/mtp-draft-20260806T212902Z.log) — the exact failure class run_spec.rs's
998        // "acceptance == 0 with identical output" WARNING exists to catch.
999        //
1000        // FR-Spec drafts (trimmed [n_embd, draft_vocab] + d2t) publish the trimmed head as the
1001        // file-level `output.weight` and carry no `nextn.shared_head_head`, so they keep the
1002        // fallback — hence preference, not replacement.
1003        // Name choice is factored into `draft_head_tensor` so it is testable WITHOUT a GPU or a
1004        // 3.5 GB artifact (this whole function needs both). Getting it wrong is invisible to
1005        // every exactness gate, so the choice itself is pinned by a unit test.
1006        let head_name = draft_head_tensor(|t| src.has(t), n);
1007        let head = load_t(e, &src, &head_name)?;
1008        let head_norm = match load_opt(e, &src, &p("nextn.shared_head_norm.weight"))? {
1009            Some(t) => Some(t),
1010            None => load_opt(e, &src, "output_norm.weight")?,
1011        };
1012
1013        // d2t: draft-row -> target-token-id map (absolute ids, verified against the tokenizer).
1014        let d2t: Option<Vec<u32>> = g.find("d2t").map(|t| {
1015            let bytes = g.tensor_data(t);
1016            match t.ggml_type {
1017                GgmlType::I32 => bytes
1018                    .chunks_exact(4)
1019                    .map(|c| i32::from_le_bytes(c.try_into().unwrap()) as u32)
1020                    .collect(),
1021                GgmlType::I64 => bytes
1022                    .chunks_exact(8)
1023                    .map(|c| i64::from_le_bytes(c.try_into().unwrap()) as u32)
1024                    .collect(),
1025                other => panic!("d2t must be I32/I64, got {other:?}"),
1026            }
1027        });
1028        if let Some(map) = &d2t {
1029            assert_eq!(
1030                map.len(),
1031                head.out_features(),
1032                "d2t len {} != draft head rows {}",
1033                map.len(),
1034                head.out_features()
1035            );
1036            let n_vocab = main_cfg.n_vocab as u64;
1037            assert!(
1038                map.iter().all(|&t| (t as u64) < n_vocab),
1039                "d2t contains token id >= model n_vocab {n_vocab}"
1040            );
1041        }
1042        let eh_proj = load_t(e, &src, &p("nextn.eh_proj.weight"))?;
1043        // defensive load gates (review feedback): a malformed student gguf fails HERE with a
1044        // named assert, not later as garbage drafts. eh_proj consumes concat(e_norm, h_norm).
1045        assert_eq!(
1046            eh_proj.in_features(),
1047            2 * main_cfg.n_embd as usize,
1048            "eh_proj in dim != 2*n_embd"
1049        );
1050        let geom = if student {
1051            let out_up = load_t(e, &src, &p("nextn.out_up.weight"))?;
1052            let d_inner = eh_proj.out_features();
1053            assert_eq!(
1054                out_up.out_features(),
1055                main_cfg.n_embd as usize,
1056                "out_up out dim != n_embd"
1057            );
1058            assert_eq!(
1059                out_up.in_features(),
1060                d_inner,
1061                "out_up in dim != eh_proj out dim (d_inner)"
1062            );
1063            assert!(
1064                dcfg.n_head >= 1 && dcfg.n_head_kv >= 1 && dcfg.n_head % dcfg.n_head_kv == 0,
1065                "student head counts malformed ({}/{})",
1066                dcfg.n_head,
1067                dcfg.n_head_kv
1068            );
1069            Some(DraftGeom {
1070                d_inner,
1071                n_head: dcfg.n_head as usize,
1072                n_head_kv: dcfg.n_head_kv as usize,
1073                out_up,
1074            })
1075        } else {
1076            None
1077        };
1078        // Log the name WITHOUT the blk.{n}. prefix (already printed) so the line reads
1079        // `source=nextn.shared_head_head` vs `source=output.weight` — the one-glance receipt
1080        // that the head choice went the right way on this artifact.
1081        let blk_prefix = format!("blk.{n}.");
1082        let head_src = head_name.strip_prefix(&blk_prefix).unwrap_or(&head_name);
1083        eprintln!(
1084            "[mtp-draft] external draft head: blk.{n}, source={}, head_vocab={}{}{}",
1085            head_src,
1086            head.out_features(),
1087            if d2t.is_some() {
1088                " (trimmed, d2t map)"
1089            } else {
1090                " (full)"
1091            },
1092            match &geom {
1093                Some(g) => format!(
1094                    " (student d_inner={} heads={}/{})",
1095                    g.d_inner, g.n_head, g.n_head_kv
1096                ),
1097                None => String::new(),
1098            }
1099        );
1100
1101        let mut resident = ResidentPlan::unsharded(e, &src, &dcfg);
1102        Ok(MtpHead {
1103            enorm: load_t(e, &src, &p("nextn.enorm.weight"))?,
1104            hnorm: load_t(e, &src, &p("nextn.hnorm.weight"))?,
1105            eh_proj,
1106            attn_norm: load_t(e, &src, &p("attn_norm.weight"))?,
1107            post_attn_norm: load_opt(e, &src, &p("post_attention_norm.weight"))?
1108                .or(load_opt(e, &src, &p("ffn_norm.weight"))?)
1109                .expect("draft NextN block needs post_attention_norm or ffn_norm"),
1110            mixer: load_mixer_kind(e, &src, n, LayerKind::FullAttention, dcfg.mla.as_ref(),
1111                                   dcfg.attn_gate_separate_at(n))?,
1112            ffn: load_ffn(e, &src, &dcfg, n, None, &mut resident)?,
1113            shared_head_norm: head_norm,
1114            shared_head_head: Some(head),
1115            d2t,
1116            geom,
1117            step35,
1118        })
1119    }
1120}
1121
1122/// gemma4 model-level auxiliaries.
1123pub struct GemmaAux {
1124    /// rope_freqs.weight [hd_global/2] freq factors — global layers' RoPE (R9).
1125    pub rope_freqs: Option<CudaSlice<f32>>,
1126    /// all-ones norm weight [512] (max head_dim) — the weightless rms_norms (R7 V-norm).
1127    pub ones: CudaSlice<f32>,
1128    /// tokenizer suppress_tokens uploaded once (None when the model ships none) — masked to
1129    /// -inf on every logits row before argmax/sampling (12B QAT ships two control ids).
1130    pub suppress_d: Option<(CudaSlice<i32>, usize)>,
1131    /// E4B per-layer-embedding model tensors (None on 26B/31B).
1132    pub e4b: Option<Gemma4E4bModel>,
1133}
1134
1135/// step35 model-level auxiliaries. Deliberately NOT folded into `GemmaAux`: every gemma4 path
1136/// does `gemma4_aux.as_ref().unwrap()` and would then also fire on a step35 model.
1137pub struct Step35Aux {
1138    /// `rope_freqs.weight [n_rot_full/2]` llama3-style freq factors. Upstream applies them to
1139    /// FULL-attention layers ONLY (`rope_factors = is_swa ? nullptr : get_rope_factors(...)`,
1140    /// step35.cpp:246) — the SWA layers pass a null factor pointer. Step-3.7-Flash ships [64] F32.
1141    pub rope_freqs: Option<CudaSlice<f32>>,
1142}
1143
1144pub struct HybridModel {
1145    pub cfg: ModelConfig,
1146    pub embd: EmbedHost,
1147    pub output_norm: GpuTensor,
1148    pub output: GpuTensor,
1149    pub layers: Vec<HybridLayer>,
1150    pub mtp: Option<MtpHead>, // NextN spec-decode head (None if nextn_predict_layers == 0)
1151    /// Lazily-uploaded DEVICE copy of the raw embed table (spec/graph hot loops gather rows
1152    /// on-device instead of host-dequant + htod). ~0.5GB; uploaded once on first use.
1153    pub embd_gpu: std::sync::OnceLock<cudarc::driver::CudaSlice<u8>>,
1154    pub gemma4_aux: Option<GemmaAux>,
1155    /// step35 (Step-3.7-Flash) model auxiliaries — `Some` iff `cfg.step35.is_some()`.
1156    pub step35_aux: Option<Step35Aux>,
1157    /// PRIME ACTIVATION SLABS (piecewise-graph foundation, 2026-07-26): the layer loop's
1158    /// seven trunk transients live in RESIDENT per-model buffers instead of per-call pool
1159    /// allocs — kills ~224 alloc/free API calls per prime AND freezes the Lt GEMM operand
1160    /// addresses (nvjet's alignment-variant kernels become run-to-run stable once their
1161    /// pointers stop moving). Sized on first prime to the largest T seen. The map lock covers
1162    /// lookup/grow only; each device owns a separate slab lock so PP stages on distinct
1163    /// devices can drive their host-synchronized layer walks concurrently.
1164    pub prime_slabs: std::sync::Mutex<std::collections::HashMap<
1165        usize,
1166        std::sync::Arc<std::sync::Mutex<crate::hybrid_forward::PrimeSlabs>>,
1167    >>,
1168}
1169
1170impl HybridModel {
1171    /// Load a hybrid (qwen35) model from GGUF. Thin byte-identical wrapper over `load_from_source`.
1172    pub fn load(e: &Engine, g: &GgufFile) -> Result<Self, Box<dyn std::error::Error>> {
1173        Self::load_from_source(e, &GgufSource(g))
1174    }
1175
1176    /// Plain-generation loader. `run-gen` never calls the optional draft head, so avoid loading
1177    /// its weights and expert bank while preserving the model config and all trunk semantics.
1178    pub fn load_without_mtp(e: &Engine, g: &GgufFile) -> Result<Self, Box<dyn std::error::Error>> {
1179        Self::load_from_source_impl(e, &GgufSource(g), false)
1180    }
1181
1182    /// Load a hybrid model from any `TensorSource` (GGUF or a safetensors HF checkpoint). The whole
1183    /// loop speaks ggml names; the source maps them (and, for safetensors, applies the SSM value
1184    /// transforms via the owned-buffer seam). The forward graph is untouched.
1185    pub fn load_from_source(
1186        e: &Engine,
1187        src: &dyn TensorSource,
1188    ) -> Result<Self, Box<dyn std::error::Error>> {
1189        Self::load_from_source_impl(e, src, true)
1190    }
1191
1192    /// Source-backed twin of `load_without_mtp`, used by the safetensors/repack `run-gen` path.
1193    pub fn load_from_source_without_mtp(
1194        e: &Engine,
1195        src: &dyn TensorSource,
1196    ) -> Result<Self, Box<dyn std::error::Error>> {
1197        Self::load_from_source_impl(e, src, false)
1198    }
1199
1200    fn load_from_source_impl(
1201        e: &Engine,
1202        src: &dyn TensorSource,
1203        load_mtp: bool,
1204    ) -> Result<Self, Box<dyn std::error::Error>> {
1205        let cfg = src.config();
1206        assert!(cfg.arch.is_hybrid(), "not a hybrid arch");
1207        // SPEC-SERVING stream-k key, per model, set at LOAD so it governs the PRIME too
1208        // (2026-07-27; explicit MEMRA_MMQ_SK wins): the sk autotune's per-process kernel
1209        // coin flips knife-edge prime shapes between kernels run-to-run — the 12B depth
1210        // spec cell was BIMODAL (205 @ 0.756 / 260 @ 0.943 identical invocations; tiling
1211        // x6 = stable 263-269 @ 0.953, chat +3%; 31B neutral). The 26B is opposite: its
1212        // drafter accepts BETTER under sk's fold order (depth 328 @ 0.826 vs 293 @ 0.750).
1213        // Big dense (n_embd >= 3500) forces tiling under spec intent; MoE/small keep sk.
1214        // An earlier attempt set this in generate_spec_gemma — too late, the prime's
1215        // GEMMs had already autotuned.
1216        if std::env::var("MEMRA_DRAFT").is_ok() && std::env::var("MEMRA_MMQ_SK").is_err() {
1217            let force = if cfg.n_embd >= 3500 { 0i8 } else { -1i8 };
1218            crate::MMQ_SK_FORCE.store(force, std::sync::atomic::Ordering::Relaxed);
1219        }
1220        // FP8-KV door: OFF for every hybrid-path model (35B: fp8 format-gates its v3
1221        // dp4a lane, −2% measured 2026-07-12; gemma keys its KV formats independently
1222        // of this flag). The 9B dense loader is the only ON site.
1223        crate::KV_FP8_FORCE.store(0, std::sync::atomic::Ordering::Relaxed);
1224
1225        // B0 FIX (hoisted): cfg.n_layer == block_count INCLUDES the MTP/NextN block(s)
1226        // (41 for the 35B-MoE); the trunk is n_layer - nextn. Computed before any tensor
1227        // upload because the M2 sharded loader (crate::pp::layer_engine) places tensors
1228        // by the trunk stage map.
1229        let n_trunk = (cfg.n_layer - cfg.nextn_predict_layers) as usize;
1230        let embd = EmbedHost::from_source(src, "token_embd.weight");
1231        // M2 increment 2 (weight sharding): output_norm + lm head upload through the LAST
1232        // stage's engine — the stage that runs them (outside the pp door / MEMRA_PP_SHARD=0
1233        // this is the primary engine, byte-identical to the M1 loader).
1234        let e_head = crate::pp::layer_engine(e, n_trunk, n_trunk - 1)?;
1235        let output_norm = load_t(e_head, src, "output_norm.weight")?;
1236        // tied embeddings: fall back to tok_embd if output.weight absent.
1237        let mut output = if src.has("output.weight") {
1238            load_t(e_head, src, "output.weight")?
1239        } else {
1240            load_t(e_head, src, "token_embd.weight")?
1241        };
1242        let mut resident = ResidentPlan::pp(e, src, &cfg, n_trunk)?;
1243
1244        // SPILLING-PLAN §2: build the tiered-spill context ONCE, before loading any experts, but
1245        // only for a MoE model with the disk tier forced on (`MEMRA_SPILL_DISK`). It probes free VRAM
1246        // + host RAM at runtime (never hardcoded) and opens one shared GGUF mmap; all expert tensors
1247        // draw down its single pinned-RAM budget (hottest pinned, the rest mmap'd from disk). When
1248        // unset/dense this stays `None` and the load takes the byte-identical all-host path.
1249        // Disk spill is GGUF-only (needs the on-disk file mmap); src.gguf() is None for safetensors.
1250        let gguf: Option<&GgufFile> = src.gguf();
1251        // expert_count > 0: Arch::Gemma4 carries cfg.moe = Some on its DENSE variants too
1252        // (the 2026-07-14 discriminator-bug class) — a dense 31B/E4B under the spill env
1253        // would otherwise probe budgets + open an expert mmap it never consumes.
1254        let mut spill: Option<crate::spill::SpillCtx> =
1255            if cfg.moe.as_ref().is_some_and(|m| m.expert_count > 0)
1256                && crate::spill::disk_tier_enabled() && gguf.is_some() {
1257                let budget = crate::spill::MemBudget::probe(e)?;
1258                let ctx = crate::spill::SpillCtx::open(gguf.unwrap(), &budget)?;
1259                eprintln!("[spill] disk tier ON: free_vram={} MiB  pinnable_ram={} MiB (MemAvailable*frac)",
1260                          budget.free_vram >> 20, budget.free_pinnable_ram >> 20);
1261                Some(ctx)
1262            } else { None };
1263
1264        // Running the MTP block as a trunk layer is wrong; iterate only the trunk layers
1265        // (n_trunk hoisted above). 9B (nextn=0): n_trunk = 32. 35B-MoE (nextn=1): 40.
1266        let mut layers = Vec::with_capacity(n_trunk);
1267        for il in 0..n_trunk as u32 {
1268            let p = |s: &str| format!("blk.{il}.{s}");
1269            // M2 weight sharding: this layer's tensors upload through the OWNING stage's
1270            // engine (shadowed `e`) — the bring-up remote peer-read placement dies here.
1271            // Door shut / MEMRA_PP_SHARD=0: `layer_engine` returns the primary (no change).
1272            let e = crate::pp::layer_engine(e, n_trunk, il as usize)?;
1273            // attn_norm always; post_attention_norm is the pre-FFN norm in qwen35
1274            layers.push(HybridLayer {
1275                attn_norm: load_t(e, src, &p("attn_norm.weight"))?,
1276                post_attn_norm: load_opt(e, src, &p("post_attention_norm.weight"))?
1277                    .or(load_opt(e, src, &p("ffn_norm.weight"))?)
1278                    .expect("need post_attention_norm or ffn_norm"),
1279                mixer: {
1280                    // E4B KV-shared layers ship NO attn_k/attn_v — load the SHARE TARGET's
1281                    // k/v tensors for shape symmetry (forward skips k/v compute there and
1282                    // reads the target layer's cache; see Gemma4E4bLayer::kv_share).
1283                    let g4_shared = cfg.gemma4.as_ref().map(|g| g.shared_kv_layers).unwrap_or(0);
1284                    let kv_from = n_trunk as u32 - g4_shared;
1285                    if g4_shared > 0
1286                        && il >= kv_from
1287                        && !src.has(&format!("blk.{il}.attn_k.weight"))
1288                    {
1289                        let g4 = cfg.gemma4.as_ref().unwrap();
1290                        let swa = g4.swa_pattern.get(il as usize).copied().unwrap_or(true);
1291                        let tgt = kv_from - if swa { 2 } else { 1 };
1292                        let tp = |s: &str| format!("blk.{tgt}.{s}");
1293                        Mixer::Full(FullAttnLayer {
1294                            wq: load_t(e, src, &p("attn_q.weight"))?,
1295                            wk: load_t(e, src, &tp("attn_k.weight"))?,
1296                            wv: load_t(e, src, &tp("attn_v.weight"))?,
1297                            wo: load_t(e, src, &p("attn_output.weight"))?,
1298                            q_norm: load_t(e, src, &p("attn_q_norm.weight"))?,
1299                            k_norm: load_t(e, src, &tp("attn_k_norm.weight"))?,
1300                            attn_gate: None, // gemma4 has no separate head-wise gate
1301                        })
1302                    } else {
1303                        load_mixer_kind(e, src, il, cfg.layer_kind(il), cfg.mla.as_ref(),
1304                                        cfg.attn_gate_separate_at(il))?
1305                    }
1306                },
1307                ffn: load_ffn(e, src, &cfg, il,
1308                              spill.as_mut().map(|c| (gguf.unwrap(), c)), &mut resident)?,
1309                gemma4: if cfg.gemma4.is_some() {
1310                    let scalar = |n: &str| -> f32 {
1311                        let t = src.find(&p(n)).unwrap_or_else(|| panic!("missing {n}"));
1312                        memra_gguf::dequant::dequantize(t.ggml_type, &t.bytes, 1)[0]
1313                    };
1314                    let vecf = |n: &str| -> Vec<f32> {
1315                        let t = src.find(&p(n)).unwrap_or_else(|| panic!("missing {n}"));
1316                        memra_gguf::dequant::dequantize(
1317                            t.ggml_type,
1318                            &t.bytes,
1319                            t.ne.iter().product::<u64>() as usize,
1320                        )
1321                    };
1322                    let moe_bits = if src.find(&p("ffn_gate_inp.scale")).is_some() {
1323                        Some(crate::hybrid::Gemma4MoeBits {
1324                            post_ffw_norm_1: load_t(e, src, &p("post_ffw_norm_1.weight"))?,
1325                            pre_ffw_norm_2: load_t(e, src, &p("pre_ffw_norm_2.weight"))?,
1326                            post_ffw_norm_2: load_t(e, src, &p("post_ffw_norm_2.weight"))?,
1327                            shared_gate: load_t(e, src, &p("ffn_gate.weight"))?,
1328                            shared_up: load_t(e, src, &p("ffn_up.weight"))?,
1329                            shared_down: load_t(e, src, &p("ffn_down.weight"))?,
1330                            router_scale_pre: {
1331                                let inv = 1.0 / (cfg.n_embd as f32).sqrt();
1332                                let v: Vec<f32> =
1333                                    vecf("ffn_gate_inp.scale").iter().map(|x| x * inv).collect();
1334                                e.htod(&v)?
1335                            },
1336                            per_expert_scale: vecf("ffn_down_exps.scale"),
1337                            per_expert_scale_d: e.htod(&vecf("ffn_down_exps.scale"))?,
1338                        })
1339                    } else {
1340                        None
1341                    };
1342                    // E4B extras (tensor-presence: blk.N.inp_gate only exists on E4B)
1343                    let e4b = if src.has(&p("inp_gate.weight")) {
1344                        let g4 = cfg.gemma4.as_ref().unwrap();
1345                        let kv_from = n_trunk as u32 - g4.shared_kv_layers;
1346                        let kv_share = if g4.shared_kv_layers > 0 && il >= kv_from {
1347                            let swa = g4.swa_pattern.get(il as usize).copied().unwrap_or(true);
1348                            Some(kv_from - if swa { 2 } else { 1 })
1349                        } else {
1350                            None
1351                        };
1352                        Some(crate::hybrid::Gemma4E4bLayer {
1353                            inp_gate: load_t(e, src, &p("inp_gate.weight"))?,
1354                            proj: load_t(e, src, &p("proj.weight"))?,
1355                            post_norm: load_t(e, src, &p("post_norm.weight"))?,
1356                            kv_share,
1357                            qkv_cat: None,   // built at the mirror hook (wave 4b)
1358                        })
1359                    } else {
1360                        None
1361                    };
1362                    Some(Gemma4LayerBits {
1363                        ffn_norm: load_t(e, src, &p("ffn_norm.weight"))?,
1364                        post_ffw_norm: load_t(e, src, &p("post_ffw_norm.weight"))?,
1365                        moe_bits,
1366                        layer_scale: scalar("layer_output_scale.weight"),
1367                        e4b,
1368                    })
1369                } else {
1370                    None
1371                },
1372            });
1373        }
1374
1375        // MTP/NextN head: load the block the trunk loop drops (il = n_trunk). It is a full
1376        // transformer block PLUS the nextn.{enorm,hnorm,eh_proj} glue. Only when nextn>0 and the
1377        // eh_proj tensor actually exists in the file (some MTP GGUFs ship the draft separately).
1378        let mtp = if load_mtp && cfg.nextn_predict_layers > 0 {
1379            let n = n_trunk as u32;
1380            let p = |s: &str| format!("blk.{n}.{s}");
1381            match src.has(&p("nextn.eh_proj.weight")) {
1382                true => Some(MtpHead {
1383                    enorm: load_t(e, src, &p("nextn.enorm.weight"))?,
1384                    hnorm: load_t(e, src, &p("nextn.hnorm.weight"))?,
1385                    eh_proj: load_t(e, src, &p("nextn.eh_proj.weight"))?,
1386                    attn_norm: load_t(e, src, &p("attn_norm.weight"))?,
1387                    post_attn_norm: load_opt(e, src, &p("post_attention_norm.weight"))?
1388                        .or(load_opt(e, src, &p("ffn_norm.weight"))?)
1389                        .expect("MTP block needs post_attention_norm or ffn_norm"),
1390                    mixer: load_mixer_kind(e, src, n, LayerKind::FullAttention, cfg.mla.as_ref(),
1391                                           cfg.attn_gate_separate_at(n))?,
1392                    ffn: load_ffn(e, src, &cfg, n,
1393                                  spill.as_mut().map(|c| (gguf.unwrap(), c)), &mut resident)?,
1394                    shared_head_norm: load_opt(e, src, &p("nextn.shared_head_norm.weight"))?,
1395                    // `nextn.shared_head_head` is the name the convert script and upstream both
1396                    // use (LLM_TENSOR_NEXTN_SHARED_HEAD_HEAD -> "blk.%d.nextn.shared_head_head");
1397                    // `nextn.shared_head` is a name no shipped artifact carries, so this arm was
1398                    // silently always-None and every embedded-MTP model fell back to the trunk
1399                    // `self.output` in `mtp_head_forward_dev` op 12. Harmless for qwen35-family
1400                    // heads that genuinely tie to the trunk head; wrong for any artifact that
1401                    // ships its own — which the StepFun step35 drafter does (see `load_draft`).
1402                    // Keep the old name as a fallback so nothing that did match still does.
1403                    shared_head_head: load_opt(e, src, &p("nextn.shared_head_head.weight"))?
1404                        .or(load_opt(e, src, &p("nextn.shared_head.weight"))?),
1405                    d2t: None,
1406                    geom: None,
1407                    // EMBEDDED MTP block: same file, so its own arrays cover index `n`.
1408                    step35: cfg.step35.as_ref().map(|_| Step35MtpGeom::resolve(&cfg, n)),
1409                }),
1410                false => None, // nextn>0 but no embedded eh_proj (external draft GGUF) -> no head
1411            }
1412        } else {
1413            None
1414        };
1415
1416        // MEMRA_MTP_DRAFT=<path.gguf>: REPLACE the MTP head with one loaded from a standalone
1417        // draft GGUF (e.g. an FR-Spec trimmed-vocab draft). Verify-based spec decode stays exact
1418        // regardless of the draft — a different draft only changes WHICH tokens get proposed.
1419        let mtp = if load_mtp {
1420            match std::env::var("MEMRA_MTP_DRAFT") {
1421                Ok(path) if !path.is_empty() => {
1422                    eprintln!("[mtp-draft] loading external MTP draft: {path}");
1423                    let dg = GgufFile::open(&path)?;
1424                    Some(MtpHead::load_draft(e, &dg, &cfg)?)
1425                }
1426                _ => mtp,
1427            }
1428        } else {
1429            None
1430        };
1431
1432        // MEMRA_FRSPEC_TRIM=<frspec.gguf>: SELF-TRIMMED draft head. Reads ONLY the d2t ranked-token
1433        // list from the given file and gathers those rows from the MAIN model's own output.weight
1434        // bytes (quantized rows are independent — a byte-level row gather, zero requant). The MTP
1435        // block, norms, and head quant all stay main-model, so there is no cross-file quality
1436        // mismatch (the external Q4_K draft file measured -15pts acceptance vs the native block).
1437        // Draft lm_head reads drop vocab/32768-fold; verify stays full-vocab -> exactness unchanged.
1438        // FULL_PREC (MTP-heal ceiling): the self-trim gathers rows into `from_quant_bytes` (Quant
1439        // only) and, more to the point, the full-precision ceiling wants the model's NATURAL full
1440        // head — trimming the draft vocab is a speed lever, not part of the exactness measurement.
1441        // Disable trim under the flag (documented resolution, §item 2).
1442        let trim_env = if load_mtp {
1443            std::env::var("MEMRA_FRSPEC_TRIM")
1444        } else {
1445            Err(std::env::VarError::NotPresent)
1446        };
1447        if crate::model::full_prec_enabled()
1448            && trim_env.as_deref().map(|p| !p.is_empty()).unwrap_or(false)
1449        {
1450            eprintln!(
1451                "[frspec-trim] DISABLED under MEMRA_FULL_PREC — using the natural full MTP head"
1452            );
1453        }
1454        let mtp = match (
1455            if crate::model::full_prec_enabled() {
1456                Err(std::env::VarError::NotPresent)
1457            } else {
1458                trim_env
1459            },
1460            mtp,
1461        ) {
1462            (Ok(path), Some(mut head)) if !path.is_empty() => {
1463                let tg = GgufFile::open(&path)?;
1464                let d2t_t = tg
1465                    .find("d2t")
1466                    .expect("MEMRA_FRSPEC_TRIM file has no d2t tensor");
1467                let d2t_bytes = tg.tensor_data(d2t_t);
1468                let d2t: Vec<u32> = match d2t_t.ggml_type {
1469                    GgmlType::I32 => d2t_bytes
1470                        .chunks_exact(4)
1471                        .map(|c| i32::from_le_bytes(c.try_into().unwrap()) as u32)
1472                        .collect(),
1473                    GgmlType::I64 => d2t_bytes
1474                        .chunks_exact(8)
1475                        .map(|c| i64::from_le_bytes(c.try_into().unwrap()) as u32)
1476                        .collect(),
1477                    other => panic!("d2t must be I32/I64, got {other:?}"),
1478                };
1479                let v = src
1480                    .find("output.weight")
1481                    .or_else(|| src.find("token_embd.weight"))
1482                    .expect("model has no output.weight for FR-Spec trim");
1483                let out_f = v.ne[1] as usize;
1484                let row_bytes = v.bytes.len() / out_f;
1485                assert!(
1486                    d2t.iter().all(|&t| (t as usize) < out_f),
1487                    "d2t token id >= lm_head rows {out_f}"
1488                );
1489                let mut gathered = Vec::with_capacity(d2t.len() * row_bytes);
1490                for &t in &d2t {
1491                    let off = t as usize * row_bytes;
1492                    gathered.extend_from_slice(&v.bytes[off..off + row_bytes]);
1493                }
1494                let trimmed = GpuTensor::from_quant_bytes(
1495                    e,
1496                    &gathered,
1497                    v.ggml_type,
1498                    v.ne[0],
1499                    d2t.len() as u64,
1500                    /*nvfp4 macro-scale*/
1501                    match src.find("output.scale") {
1502                        Some(sv) => f32::from_le_bytes(sv.bytes[..4].try_into().unwrap()),
1503                        None => 1.0,
1504                    },
1505                )?;
1506                eprintln!(
1507                    "[frspec-trim] self-trimmed head: {} rows of main output.weight ({:?})",
1508                    d2t.len(),
1509                    v.ggml_type
1510                );
1511                head.shared_head_head = Some(trimmed);
1512                head.d2t = Some(d2t);
1513                Some(head)
1514            }
1515            (_, m) => m,
1516        };
1517
1518        if let Some(ctx) = spill.as_ref() {
1519            eprintln!(
1520                "[spill] experts placed: {} pinned (Tier 1), {} mmap'd from disk (Tier 2, {} MiB)",
1521                ctx.n_pinned,
1522                ctx.n_mmap,
1523                ctx.mmap_bytes >> 20
1524            );
1525        }
1526
1527        // FA v4 GQA CAPACITY GUARD (2026-08-06, lane/122b-bringup): fa_v4_smem sizes its
1528        // per-warp Q arrays q_ints[8][64]/q_d[8][8] for gqa<=8 — every model before the
1529        // 122B-A10B (32 Q heads / 2 KV heads = gqa 16) fit. At gqa>8 the (32,gqa,1) block's
1530        // warps 8..15 write q_ints[wy] PAST the array into the k_ints/k_d K tile, corrupting
1531        // scores -> all-NaN decode logits (receipts: research/122b-bringup-20260806/, arm
1532        // battery: v4/deep MISMATCH+NaN, v3/v2/smem/reg/scalar all MATCH). The hd512 lane
1533        // already carries its own capacity guard at dispatch ("gqa <= 16 = fa_v4_smem_512's
1534        // q-array capacity"); hd256 v4 never got one. Key FA_V4_MAX_DEFAULT=0 at load so
1535        // EVERY v4 dispatch site (eager, rows-verify, dc, rows_dc, windowed, seqs) flips to
1536        // the v3 lane together — decode/verify stay kernel-family-identical (the parity law).
1537        // Explicit MEMRA_FA_V4_MAX env still wins (diagnostic seam). The real v4 gqa16
1538        // extension is a kernel change gated on its own battery + perf receipts (fix brief
1539        // in research/122b-bringup-20260806/VERDICT.md).
1540        if cfg.n_head_kv > 0 && cfg.n_head / cfg.n_head_kv > 8 {
1541            crate::FA_V4_MAX_DEFAULT.store(0, std::sync::atomic::Ordering::Relaxed);
1542            eprintln!(
1543                "[fa] v4 decode family disabled: gqa {} > fa_v4_smem capacity 8 (v3 lane serves)",
1544                cfg.n_head / cfg.n_head_kv
1545            );
1546        }
1547
1548        if cfg.gemma4.is_some() {
1549            // gemma4 fa-vec crossover default (measured sweep 2026-07-10; env overrides).
1550            crate::FA_VEC_MIN_DEFAULT.store(1, std::sync::atomic::Ordering::Relaxed);
1551            // windowed split per gemma variant (2026-07-12 sweeps): MoE 26B = 32 (grid-limited
1552            // t=1 under the raw-e4m3 sV ceiling), dense 31B = 64 (37.13 vs 36.87 at 1.7k, N=2).
1553            // DISCRIMINATOR FIX (2026-07-14): Arch::Gemma4 is in is_moe(), so cfg.moe is
1554            // Some (expert_count 0) on the DENSE 31B/E4B too — `cfg.moe.is_some()` keyed
1555            // every "per-variant" default to the 26B values and the dense arms of the
1556            // 2026-07-12 sweeps (SPW 64, SP512 32) never actually reached the 31B. Key on
1557            // expert_count instead.
1558            let real_moe = cfg.moe.as_ref().is_some_and(|m| m.expert_count > 0);
1559            crate::FA_SPW_DEFAULT.store(if real_moe { 32 } else { 64 },
1560                                        std::sync::atomic::Ordering::Relaxed);
1561            // hd512 global split per variant (26B=16 landed 2026-07-11; 31B=32 swept 2026-07-12).
1562            crate::FA_SP512_DEFAULT.store(if real_moe { 16 } else { 32 },
1563                                          std::sync::atomic::Ordering::Relaxed);
1564            // gemma4 router w8 RE-ARBITRATED 2026-08-01 (g26 decode dig): the 2026-07-31
1565            // knife-edge that stored false here was single-synthetic-prompt roulette — on 6
1566            // real prompts the w8 twin's gate outcome is IDENTICAL to the lone-warp form
1567            // (5 MATCH/5 MATCH; the one MISMATCH prompt fails both arms with the same
1568            // argmax pair, router-independent). w8 = +13% g26 decode (182->206 tok/s x3
1569            // interleaved, H100). Receipts: research/g26-decode-20260801/. gemma4 now rides
1570            // the global default (true); MEMRA_ROUTER_V2=0 is the rollback seam.
1571            // fused t=1 pair/triple mr1 per variant (2026-07-14 DRAM-duty arc: dense +1.1%
1572            // short / +0.6% depth on 31B; MoE 26B −1.2% — stays mr2).
1573            crate::FUSED_MR1_DEFAULT.store(!real_moe,
1574                                           std::sync::atomic::Ordering::Relaxed);
1575            // gemma4 rms_norm block 1024 (single-row 2816-col norms; battery-arbitrated per model).
1576            crate::RMS_BLOCK_DEFAULT.store(1024, std::sync::atomic::Ordering::Relaxed);
1577            // gemma4 fa split ladder (d1736 sweep; see fa_split_keys).
1578            crate::FA_SP_GEMMA.store(true, std::sync::atomic::Ordering::Relaxed);
1579            // depth fa: PARITY LAW (2026-07-10) — decode and verify share the rows_w/rows_dpl16
1580            // kernel symbols (decode t=1), so lane choice is freely tunable; v4 measured the
1581            // depth winner. Seams: MEMRA_FA_V4_MAX / MEMRA_FA_SMEM_TKV / MEMRA_GEMMA_ROWS_W.
1582        }
1583        // gemma4: the dc serving loop + spec draft gather read the device embed table every
1584        // step — upload it AT LOAD (OnceLock init) so first-use cost never lands in a timed span.
1585        let force_embd_gpu = cfg.gemma4.is_some();
1586        let gemma4_aux = if cfg.gemma4.is_some() {
1587            let rope_freqs = match src.find("rope_freqs.weight") {
1588                Some(t) => Some(e.htod(&memra_gguf::dequant::dequantize(
1589                    t.ggml_type,
1590                    &t.bytes,
1591                    t.ne.iter().product::<u64>() as usize,
1592                ))?),
1593                None => None,
1594            };
1595            // E4B per-layer-embedding model tensors (tensor-presence gated).
1596            let e4b = match src.find("per_layer_token_embd.weight") {
1597                Some(t) => {
1598                    let n_epl = cfg
1599                        .gemma4
1600                        .as_ref()
1601                        .map(|g| g.n_embd_per_layer as usize)
1602                        .unwrap_or(0);
1603                    let row = t.ne[0] as usize; // n_epl * n_layer
1604                    let row_bytes = t.bytes.len() / (t.ne[1] as usize);
1605                    eprintln!(
1606                        "[gemma4-e4b] per-layer-embed model detected (n_epl={n_epl}, row {row}) — \
1607                               first-light forward (eager decode + prime); dc/graph/spec unwired \
1608                               (HANDOVER-E4B.md)"
1609                    );
1610                    Some(crate::hybrid::Gemma4E4bModel {
1611                        tok_tbl_gpu: std::sync::OnceLock::new(),
1612                        tok_embd_bytes: t.bytes.to_vec(),
1613                        tok_embd_qt: match t.ggml_type {
1614                            memra_gguf::GgmlType::Q6_K => crate::QT_Q6_K,
1615                            memra_gguf::GgmlType::Q8_0 => crate::QT_Q8_0,
1616                            other => panic!("e4b per-layer tok embd: unhandled dtype {other:?}"),
1617                        },
1618                        tok_embd_row_bytes: row_bytes,
1619                        model_proj: load_t(e, src, "per_layer_model_proj.weight")?,
1620                        proj_norm: load_t(e, src, "per_layer_proj_norm.weight")?,
1621                        n_epl,
1622                    })
1623                }
1624                None => None,
1625            };
1626            let suppress_d = {
1627                let sup = &cfg.gemma4.as_ref().unwrap().suppress_tokens;
1628                if sup.is_empty() { None } else {
1629                    let ids: Vec<i32> = sup.iter().map(|&x| x as i32).collect();
1630                    eprintln!("[gemma4] suppress_tokens: {} ids masked at sampling", ids.len());
1631                    Some((e.htod_i32(&ids)?, ids.len()))
1632                }
1633            };
1634            Some(GemmaAux {
1635                rope_freqs,
1636                ones: e.htod(&[1.0f32; 512])?,
1637                suppress_d,
1638                e4b,
1639            })
1640        } else {
1641            None
1642        };
1643        // step35: rope_freqs.weight [n_rot_full/2] — FULL-attn layers only (SWA passes null).
1644        // Loaded by tensor presence, not required: the key is absent on a sibling without
1645        // llama3-style scaling, and `None` is the correct "no factors" signal for rope_neox2.
1646        let step35_aux = if cfg.step35.is_some() {
1647            let rope_freqs = match src.find("rope_freqs.weight") {
1648                Some(t) => Some(e.htod(&memra_gguf::dequant::dequantize(
1649                    t.ggml_type,
1650                    &t.bytes,
1651                    t.ne.iter().product::<u64>() as usize,
1652                ))?),
1653                None => None,
1654            };
1655            Some(Step35Aux { rope_freqs })
1656        } else {
1657            None
1658        };
1659        let mut layers = layers;
1660        // Q8_0 SPLIT-PLANE DECODE MIRRORS (2026-07-26, the H100 lane): Q8_0-trunk models
1661        // (Qwen3.5-9B class) stream their whole weight mass through the 34B-stride GGUF
1662        // layout — ncu on H100 held Max Bandwidth at 41-46% (Mem Busy 66-76%) from sector
1663        // overfetch. Mirrors route the m<=16 mmvq/batched decode family to the aligned-16B
1664        // `_rp` twins (bit-identical). VRAM cost == the mirrored trunk (~model size), so
1665        // DEFAULT ON only on the Hopper lane (80GB); MEMRA_Q8RP=1/0 overrides either way.
1666        {
1667            let q8rp_on = match std::env::var("MEMRA_Q8RP").as_deref() {
1668                Ok("0") => false,
1669                Ok(_) => true,
1670                Err(_) => cfg!(memra_hopper_mma),
1671            };
1672            // K-quant split-plane mirrors (q4_K/q6_K, 2026-08-01 H100 coalescing fix) ride
1673            // the same trunk walk under their own seam (MEMRA_KQRP, default = hopper lane).
1674            let kqrp_on = crate::Engine::kqrp_enabled();
1675            if q8rp_on || kqrp_on {
1676                // f16 prefill mirrors, PER-MODEL argmax-gate arbitration (round 45): on the
1677                // qwen Q8_0 dense class the f16-prefill-vs-int8-decode gap (maxdiff ~0.67)
1678                // flips the run-gen argmax gate on real prompts (board-2048: 485 vs 332,
1679                // deterministic x5) — gate-violating defaults don't ship. gemma (Q4_0) and
1680                // the MoE hybrids hold MATCH on the same prompt and keep their mirrors.
1681                // MEMRA_PP_F16=1 forces (diagnostic seam); =0 still kills everywhere.
1682                let f16_model_ok = cfg.gemma4.is_some() || cfg.moe.is_some()
1683                    || std::env::var("MEMRA_PP_F16").as_deref() == Ok("1");
1684                let mut nmir = 0usize;
1685                // M2 weight sharding: mirrors are the DECODE weights on these paths — each
1686                // builds through its layer's OWNING stage engine (`e_ref` param), so the
1687                // mirror lands on the device that dereferences it.
1688                let mut mir = |e_ref: &crate::Engine, w: &mut crate::model::GpuTensor| -> Result<(), Box<dyn std::error::Error>> {
1689                    let before = matches!(w, crate::model::GpuTensor::Quant { rp4: Some(_), .. });
1690                    if q8rp_on { e_ref.build_q8_rp4(w)?; }
1691                    if kqrp_on {
1692                        e_ref.build_q4k_rp4(w)?;
1693                        e_ref.build_q6k_rp4(w)?;
1694                    }
1695                    // Q6_K mirrors are model-CLASS-agnostic (round 47): no MMQ arm exists for
1696                    // Q6_K — the fallback dequant-GEMM is ~10x the f16 lane (q27's prefill
1697                    // wall). The qwen-dense argmax-flip evidence (round 45) was the Q8_0
1698                    // mirror specifically; Q6_K admission is arbitrated by its own gate runs.
1699                    let q6k = matches!(w, crate::model::GpuTensor::Quant { qtype, .. }
1700                                       if *qtype == crate::QT_Q6_K);
1701                    if q8rp_on && crate::f16_ffi::pp_f16_enabled() && (f16_model_ok || q6k) {
1702                        e_ref.build_q8_f16(w)?;
1703                    }
1704                    if !before && matches!(w, crate::model::GpuTensor::Quant { rp4: Some(_), .. }) {
1705                        nmir += 1;
1706                    }
1707                    Ok(())
1708                };
1709                for (il, layer) in layers.iter_mut().enumerate() {
1710                    let el = crate::pp::layer_engine(e, n_trunk, il)?;
1711                    match &mut layer.mixer {
1712                        Mixer::Full(fa) => {
1713                            for w in [&mut fa.wq, &mut fa.wk, &mut fa.wv, &mut fa.wo] { mir(el, w)?; }
1714                        }
1715                        Mixer::Linear(la) => {
1716                            for w in [&mut la.wqkv, &mut la.wqkv_gate, &mut la.ssm_beta,
1717                                      &mut la.ssm_alpha, &mut la.ssm_out] { mir(el, w)?; }
1718                        }
1719                        // MLA: no decode mirrors in increment 2 (its kernels arrive in inc 4;
1720                        // mirror admission is arbitrated there with measurements).
1721                        Mixer::Mla(_) => {}
1722                    }
1723                    if let Ffn::Dense { ffn_gate, ffn_up, ffn_down } = &mut layer.ffn {
1724                        for w in [ffn_gate, ffn_up, ffn_down] { mir(el, w)?; }
1725                    }
1726                }
1727                mir(e_head, &mut output)?;
1728                if nmir > 0 {
1729                    eprintln!("[q8rp] split-plane decode mirrors built: {nmir} tensors");
1730                }
1731                // Q4_K f16 prefill mirrors (round 49): Q4_K joins the q6k carve-out —
1732                // model-class-agnostic admission, arbitrated by per-model argmax gates
1733                // (the round-45 flip evidence was the Q8_0 mirror on qwen-dense; the q27
1734                // Q4_K bulk rides mul_mat_q_q45k int8-MMA, which the Lt f16 lane beats at
1735                // large m — campaign-A precedent). SECOND pass over the trunk so the shared
1736                // MEMRA_PP_F16_BUDGET_MB keeps FULL Q6_K coverage as its floor: Q6_K mirrors
1737                // replace a ~10x dequant-GEMM (no MMQ arm exists), Q4_K mirrors upgrade a
1738                // working int8-MMA arm — a joint walk would evict late-layer Q6_K mirrors
1739                // for the weaker lever. Layer-order prefix within the Q4_K class.
1740                // Round 49b: Q5_K (q27's 48 ssm_out — the last mul_mat_q_q45k class) rides
1741                // a THIRD pass strictly after all Q4_K, so the default-budget composition
1742                // (and its banked gates) stays byte-identical: the 32GB default is exhausted
1743                // by the Q4_K pass; Q5_K mirrors only light up under a raised
1744                // MEMRA_PP_F16_BUDGET_MB (machine-specific config).
1745                if q8rp_on && crate::f16_ffi::pp_f16_enabled() {
1746                    for (want, tag) in [(crate::QT_Q4_K, "q4kf16"), (crate::QT_Q5_K, "q5kf16")] {
1747                        let (mut n4, mut b4) = (0usize, 0usize);
1748                        let mut mirk = |e_ref: &crate::Engine, w: &mut crate::model::GpuTensor|
1749                                       -> Result<(), Box<dyn std::error::Error>> {
1750                            if matches!(w, crate::model::GpuTensor::Quant { qtype, f16: None, .. }
1751                                        if *qtype == want) {
1752                                e_ref.build_q8_f16(w)?;
1753                                if let crate::model::GpuTensor::Quant { f16: Some(m), .. } = w {
1754                                    n4 += 1;
1755                                    b4 += m.len();
1756                                }
1757                            }
1758                            Ok(())
1759                        };
1760                        for (il, layer) in layers.iter_mut().enumerate() {
1761                            let el = crate::pp::layer_engine(e, n_trunk, il)?;
1762                            match &mut layer.mixer {
1763                                Mixer::Full(fa) => {
1764                                    for w in [&mut fa.wq, &mut fa.wk, &mut fa.wv, &mut fa.wo] { mirk(el, w)?; }
1765                                }
1766                                Mixer::Linear(la) => {
1767                                    for w in [&mut la.wqkv, &mut la.wqkv_gate, &mut la.ssm_beta,
1768                                              &mut la.ssm_alpha, &mut la.ssm_out] { mirk(el, w)?; }
1769                                }
1770                                Mixer::Mla(_) => {} // no mirrors in increment 2 (see above)
1771                            }
1772                            if let Ffn::Dense { ffn_gate, ffn_up, ffn_down } = &mut layer.ffn {
1773                                for w in [ffn_gate, ffn_up, ffn_down] { mirk(el, w)?; }
1774                            }
1775                        }
1776                        mirk(e_head, &mut output)?;
1777                        if n4 > 0 {
1778                            eprintln!("[{tag}] prefill fp16 mirrors built: {n4} tensors \
1779                                       ({} MB)", b4 >> 20);
1780                        }
1781                    }
1782                }
1783            }
1784        }
1785        // Q4_0 SPLIT-PLANE DECODE MIRRORS (2026-07-10, MEMRA_Q4RP seam): gemma-4 MoE-class trunk
1786        // (26B — attn wq/wk/wv/wo + the parallel shared FFN triple). The 18B GGUF block stride
1787        // costs ~25-35% decode bandwidth in sector overfetch (rp_q4_probe: m=1 1.34x, m=3 1.17x,
1788        // bitwise); the mirror (~0.7GB for the 26B) fixes the m<=8 mmvq/batched/fused family.
1789        // Dense 31B is NOT mirrored (its 15GB trunk mirror does not fit 24GB — the full layout
1790        // swap is the follow-up arc); raw bytes stay for prefill/gemm/Stage-A either way.
1791        if cfg.gemma4.is_some() && crate::Engine::q4rp_enabled() {
1792            let mut nmir = 0usize;
1793            for (il, layer) in layers.iter_mut().enumerate() {
1794                // M2 weight sharding: mirrors/concats build through the owning stage engine.
1795                let e = crate::pp::layer_engine(e, n_trunk, il)?;
1796                // 26B MoE-class trunk (moe_bits) OR the E4B dense trunk (e4b bits). E4B mirror
1797                // arithmetic: attn ~7.5MB/layer (shared layers skip wk/wv via build's no-op on
1798                // duplicate mirrors is NOT automatic — they alias the target's tensors as
1799                // separate GpuTensors, so their mirrors double ~1.5MB/shared-layer; acceptable)
1800                // + dense ffn 3 x 2560x10240 Q4_0 ~44MB + inp_gate/proj ~0.75MB => ~2.2GB for
1801                // the 5.2GB model; 24GB card holds model+mirror+KV with >14GB headroom.
1802                // Dense 31B stays unmirrored (15GB mirror does not fit) — its arm is the
1803                // layout-swap follow-up.
1804                let is_moe26 = layer.gemma4.as_ref().is_some_and(|g| g.moe_bits.is_some());
1805                let is_e4b = layer.gemma4.as_ref().is_some_and(|g| g.e4b.is_some());
1806                if !(is_moe26 || is_e4b) {
1807                    continue;
1808                }
1809                if let Mixer::Full(fa) = &mut layer.mixer {
1810                    for w in [&mut fa.wq, &mut fa.wk, &mut fa.wv, &mut fa.wo] {
1811                        e.build_q4_rp4(w)?;
1812                        nmir += 1;
1813                    }
1814                }
1815                if is_e4b {
1816                    // wave-4b: own-KV layers get the wq|wk|wv OUT-concat (one matvec at t=1).
1817                    let own_kv = layer.gemma4.as_ref().unwrap().e4b.as_ref()
1818                        .is_some_and(|e4| e4.kv_share.is_none());
1819                    if own_kv {
1820                        if let Mixer::Full(fa) = &layer.mixer {
1821                            if let Some(mut cat) = e.build_q4_out_concat3(&fa.wq, &fa.wk, &fa.wv)? {
1822                                e.build_q4_rp4(&mut cat)?; nmir += 1;
1823                                layer.gemma4.as_mut().unwrap().e4b.as_mut().unwrap()
1824                                    .qkv_cat = Some(cat);
1825                            }
1826                        }
1827                    }
1828                    if let Ffn::Dense { ffn_gate, ffn_up, ffn_down } = &mut layer.ffn {
1829                        for w in [ffn_gate, ffn_up, ffn_down] {
1830                            e.build_q4_rp4(w)?;
1831                            nmir += 1;
1832                        }
1833                    }
1834                    let e4 = layer.gemma4.as_mut().unwrap().e4b.as_mut().unwrap();
1835                    for w in [&mut e4.inp_gate, &mut e4.proj] {
1836                        e.build_q4_rp4(w)?;
1837                        nmir += 1;
1838                    }
1839                }
1840                if let Some(mb) = layer.gemma4.as_mut().unwrap().moe_bits.as_mut() {
1841                    for w in [&mut mb.shared_gate, &mut mb.shared_up, &mut mb.shared_down] {
1842                        e.build_q4_rp4(w)?;
1843                        nmir += 1;
1844                    }
1845                }
1846            }
1847            if nmir > 0 {
1848                eprintln!("[q4rp] split-plane decode mirrors built: {nmir} trunk tensors");
1849            }
1850            // DENSE gemma (31B / E4B trunks): the trunk is too big to MIRROR on 24GB, so the
1851            // split layout replaces the GGUF bytes IN PLACE (zero steady-state VRAM; the 31B
1852            // profile put 76% of decode on the non-rp q4_0 matvecs). Every consumer routes
1853            // off the tensor's rp flag: mmvq/batched `_rp` twins + qmatvec_gemm_q4_0_rp
1854            // prefill. The Stage-A f32 oracle reads GGUF layout, so the swap is gated on the
1855            // fast path being active (MEMRA_FAST=0 keeps GGUF bytes end to end — exact oracle).
1856            let fast_on = std::env::var("MEMRA_FAST").as_deref() != Ok("0");
1857            if fast_on {
1858                let mut nswap = 0usize;
1859                let mut nf16 = 0usize;
1860                // f16 prefill mirrors (campaign A, 2026-07-31): built from the GGUF Q4_0
1861                // bytes BEFORE the in-place rp swap destroys that layout. Same Lt lane and
1862                // budget env as the qwen Q8_0 mirrors (MEMRA_PP_F16 / MEMRA_PP_F16_BUDGET_MB;
1863                // Hopper default ON, sm_120a default OFF — the 24GB card can't carry them).
1864                // Per-model (battery-keyed, 2026-07-31, REAL-prompt gates — the fox-repeat
1865                // family is layout-lottery degenerate and was retired from campaign gates):
1866                // 12B pp1736 8.3k -> 17.1k MATCH; 31B pp1736 4.8k -> 7.6k MATCH but ONLY
1867                // with the full-trunk mirror (420 tensors ~53GB — set
1868                // MEMRA_PP_F16_BUDGET_MB=57344 on 80GB boxes; the default 32GB partial
1869                // mirror measured FLAT there). MEMRA_Q4F16=1|0 forces either way.
1870                let q4f16_model_ok = matches!(cfg.n_embd, 3840 | 5376); // 12B | 31B geometry
1871                let f16_on = match std::env::var("MEMRA_Q4F16").as_deref() {
1872                    Ok("1") => crate::f16_ffi::pp_f16_enabled(),
1873                    Ok("0") => false,
1874                    _ => crate::f16_ffi::pp_f16_enabled() && q4f16_model_ok,
1875                };
1876                for (il, layer) in layers.iter_mut().enumerate() {
1877                    // M2 weight sharding: swap/mirror through the owning stage engine.
1878                    let e = crate::pp::layer_engine(e, n_trunk, il)?;
1879                    let dense_gemma = layer.gemma4.as_ref().is_some_and(|g| g.moe_bits.is_none());
1880                    if !dense_gemma {
1881                        continue;
1882                    }
1883                    if let Mixer::Full(fa) = &mut layer.mixer {
1884                        for w in [&mut fa.wq, &mut fa.wk, &mut fa.wv, &mut fa.wo] {
1885                            if f16_on {
1886                                e.build_q8_f16(w)?;
1887                                if matches!(w, crate::model::GpuTensor::Quant { f16: Some(_), .. }) {
1888                                    nf16 += 1;
1889                                }
1890                            }
1891                            if e.build_q4_rp_swap(w)? {
1892                                nswap += 1;
1893                            }
1894                        }
1895                    }
1896                    if let Ffn::Dense {
1897                        ffn_gate,
1898                        ffn_up,
1899                        ffn_down,
1900                    } = &mut layer.ffn
1901                    {
1902                        for w in [ffn_gate, ffn_up, ffn_down] {
1903                            if f16_on {
1904                                e.build_q8_f16(w)?;
1905                                if matches!(w, crate::model::GpuTensor::Quant { f16: Some(_), .. }) {
1906                                    nf16 += 1;
1907                                }
1908                            }
1909                            if e.build_q4_rp_swap(w)? {
1910                                nswap += 1;
1911                            }
1912                        }
1913                    }
1914                }
1915                if nswap > 0 {
1916                    eprintln!("[q4rp] split-plane IN-PLACE swap: {nswap} dense trunk tensors");
1917                }
1918                if nf16 > 0 {
1919                    eprintln!("[q4f16] prefill fp16 mirrors built: {nf16} dense trunk tensors");
1920                }
1921            }
1922        }
1923        let model = HybridModel {
1924            cfg,
1925            embd,
1926            output_norm,
1927            output,
1928            layers,
1929            mtp,
1930            embd_gpu: std::sync::OnceLock::new(),
1931            gemma4_aux,
1932            step35_aux,
1933            prime_slabs: std::sync::Mutex::new(std::collections::HashMap::new()),
1934        };
1935        e.configure_moe_cache_layout(model.moe_cache_block_sizes());
1936        if force_embd_gpu {
1937            let _ = model
1938                .embd_gpu
1939                .get_or_init(|| e.upload_u8(&model.embd.raw).expect("embed table upload"));
1940        }
1941        // M2 LOAD BARRIER (pp door open at load): uploads + mirror builds above ran on
1942        // the loading engines' worker streams; the first decode consumer runs on OTHER
1943        // streams with no event between them. Synchronize every stage context once so
1944        // no consumer can ever read a half-built tensor (the 2026-08-02 split5 ref=0.0
1945        // head-mirror find). No-op with the door shut.
1946        crate::pp::sync_stages_after_load(e, n_trunk)?;
1947        Ok(model)
1948    }
1949
1950    /// Force the device embed table resident, FALLIBLY (F5 right-size ladder,
1951    /// 2026-08-05). The lazy `embd_gpu.get_or_init(.. expect ..)` sites panic the
1952    /// GPU worker on OOM; on a VRAM-tight rig a right-sized spec session that
1953    /// "fits" can leave too little for this ~hundreds-of-MB upload and die on its
1954    /// first prefill (observed: research/specpool-20260804/server-ladder-miss.log).
1955    /// The server calls this after each ladder landing so the biggest lazy
1956    /// transient surfaces as a catchable Err (shrink further / fall back) instead
1957    /// of a panic. No-op when the host-gather door (MEMRA_EMBED_DEV=0) is open or
1958    /// the table is already resident.
1959    pub fn ensure_embed_resident(&self, e: &Engine) -> Result<(), Box<dyn std::error::Error>> {
1960        if std::env::var("MEMRA_EMBED_DEV").as_deref() == Ok("0") {
1961            return Ok(());
1962        }
1963        if self.embd_gpu.get().is_none() {
1964            let buf = e.upload_u8(&self.embd.raw)?;
1965            let _ = self.embd_gpu.set(buf); // racing set = already resident; fine
1966        }
1967        Ok(())
1968    }
1969
1970    pub fn embed(
1971        &self,
1972        e: &Engine,
1973        tokens: &[u32],
1974    ) -> Result<CudaSlice<f32>, Box<dyn std::error::Error>> {
1975        let n_embd = self.cfg.n_embd as usize;
1976        // DEVICE embed gather (round 30; the gemma4 machinery adopted for every model):
1977        // resident quantized table + gather kernel — replaces the CPU row gather + 31MB
1978        // pageable HtoD (2.2ms at T=2048, the lane's largest host stall). Same d*q
1979        // dequant math as the CPU gather; the greedy-stream A/B arbitrates.
1980        // MEMRA_EMBED_DEV=0 reverts.
1981        if std::env::var("MEMRA_EMBED_DEV").as_deref() != Ok("0") {
1982            let tbl = self
1983                .embd_gpu
1984                .get_or_init(|| e.upload_u8(&self.embd.raw).expect("embed table upload"));
1985            let tok_d = e.htod_u32_v(tokens)?;
1986            let (qt, rb) = self.embd.qt_and_row_bytes(n_embd);
1987            return e.embed_gather_device_td(tbl, &tok_d, tokens.len(), n_embd, qt, rb);
1988        }
1989        let x = self.embd.gather(n_embd, tokens);
1990        Ok(e.htod(&x)?)
1991    }
1992}
1993
1994#[cfg(test)]
1995mod residency_tests {
1996    use super::residency_bytes_by_device;
1997
1998    #[test]
1999    fn pp_residency_counts_only_each_devices_expert_slice() {
2000        let tensors = [
2001            ("blk.0.ffn_gate_exps.weight", 10usize),
2002            ("blk.0.ffn_up_exps.weight", 20),
2003            ("blk.1.ffn_down_exps.weight", 30),
2004            ("blk.2.ffn_gate_exps.weight", 40),
2005            ("blk.3.ffn_up_exps.weight", 50),
2006            ("blk.0.attn_q.weight", 7),
2007            ("output.weight", 11),
2008        ];
2009        let bytes = residency_bytes_by_device(tensors, &[0, 0, 1, 1], 0);
2010        assert_eq!(bytes.experts.get(&0), Some(&60));
2011        assert_eq!(bytes.experts.get(&1), Some(&90));
2012        assert_eq!(bytes.rest, 18);
2013        assert!(bytes.saw_experts);
2014    }
2015
2016    #[test]
2017    fn pp_residency_combines_stages_that_share_one_device() {
2018        let tensors = [
2019            ("blk.0.ffn_gate_exps.weight", 10usize),
2020            ("blk.1.ffn_gate_exps.weight", 20),
2021            ("blk.2.ffn_gate_exps.weight", 30),
2022            ("blk.3.ffn_gate_exps.weight", 40),
2023        ];
2024        let bytes = residency_bytes_by_device(tensors, &[0, 0, 0, 0], 0);
2025        assert_eq!(bytes.experts.get(&0), Some(&100));
2026        assert_eq!(bytes.experts.len(), 1);
2027    }
2028}
2029
2030#[cfg(test)]
2031mod draft_head_tests {
2032    use super::draft_head_tensor;
2033
2034    /// Names present in the real Step-3.7-Flash MTP drafter (Step3.7-flash-mtp-Q8_0.gguf), as
2035    /// enumerated by the on-disk byte probe in
2036    /// research/step37-p2-20260806/raw/draft-head-tensor-hashes-20260807.txt.
2037    /// Both candidate heads exist in that file with IDENTICAL [4096, 128896] Q8_0 shape, so no
2038    /// shape or dtype check can distinguish them — only the sha256 of the payload could, and it
2039    /// showed them to be different matrices (blk.45 head c90b907b… vs output.weight 3eec5831…).
2040    const STEP37_DRAFTER: &[&str] = &[
2041        "output.weight",
2042        "output_norm.weight",
2043        "token_embd.weight",
2044        "blk.45.nextn.shared_head_norm.weight",
2045        "blk.45.nextn.shared_head_head.weight",
2046        "blk.46.nextn.shared_head_head.weight",
2047        "blk.47.nextn.shared_head_head.weight",
2048    ];
2049
2050    fn present(names: &'static [&'static str]) -> impl Fn(&str) -> bool {
2051        move |t: &str| names.contains(&t)
2052    }
2053
2054    /// THE REGRESSION. Reading `output.weight` off this drafter cost acceptance 0/248 across
2055    /// K=1..8 with self-consistency PASS at every K — correct output, dead speculation, no gate
2056    /// red (raw/mtp-draft-20260806T212902Z.log). The drafter's top-level output stack is a
2057    /// re-quantized COPY OF THE TRUNK'S (its output_norm is byte-identical to the trunk's,
2058    /// d7526f44…), so it is the standalone-decode head, not the MTP head. Preferring
2059    /// blk.45.nextn.shared_head_head took K=1 to 14/18 = 77.8%
2060    /// (raw/mtp-draft-PASS-20260806T215132Z.log).
2061    #[test]
2062    fn step37_drafter_prefers_the_blocks_own_nextn_head_over_file_level_output() {
2063        assert_eq!(
2064            draft_head_tensor(present(STEP37_DRAFTER), 45),
2065            "blk.45.nextn.shared_head_head.weight"
2066        );
2067    }
2068
2069    /// Each NextN block owns a DIFFERENT head (c90b907b / a22d2957 / 4b21e137 — a shared head
2070    /// would have collided), so the name must be built from the block index, never hardcoded.
2071    /// This is what multi-block chaining (45->46->47) will index when it lands.
2072    #[test]
2073    fn each_nextn_block_selects_its_own_head() {
2074        for n in 45..=47u32 {
2075            assert_eq!(
2076                draft_head_tensor(present(STEP37_DRAFTER), n),
2077                format!("blk.{n}.nextn.shared_head_head.weight")
2078            );
2079        }
2080    }
2081
2082    /// FR-Spec / tied-head drafts publish the (possibly vocab-trimmed) head as the file-level
2083    /// `output.weight` and ship no nextn head. They must keep working — hence preference, not
2084    /// replacement.
2085    #[test]
2086    fn draft_without_a_nextn_head_falls_back_to_file_level_output() {
2087        let fr_spec: &[&str] = &["output.weight", "output_norm.weight", "d2t.weight"];
2088        assert_eq!(draft_head_tensor(present(fr_spec), 45), "output.weight");
2089    }
2090
2091    /// The legacy `nextn.shared_head` probe sits between the two: no shipped artifact and no
2092    /// upstream mapping uses it (upstream is LLM_TENSOR_NEXTN_SHARED_HEAD_HEAD ->
2093    /// "blk.%d.nextn.shared_head_head"), but anything that ever matched it still must, and it
2094    /// must never win over the real name.
2095    #[test]
2096    fn legacy_shared_head_is_probed_but_loses_to_shared_head_head() {
2097        let legacy_only: &[&str] = &["output.weight", "blk.45.nextn.shared_head.weight"];
2098        assert_eq!(
2099            draft_head_tensor(present(legacy_only), 45),
2100            "blk.45.nextn.shared_head.weight"
2101        );
2102
2103        let both: &[&str] = &[
2104            "output.weight",
2105            "blk.45.nextn.shared_head.weight",
2106            "blk.45.nextn.shared_head_head.weight",
2107        ];
2108        assert_eq!(
2109            draft_head_tensor(present(both), 45),
2110            "blk.45.nextn.shared_head_head.weight"
2111        );
2112    }
2113
2114    /// A drafter whose nextn head belongs to a DIFFERENT block must not be borrowed: asking for
2115    /// block 45 in a file that only carries 46/47 falls back rather than silently mismatching
2116    /// the geometry the trunk verified against.
2117    #[test]
2118    fn a_different_blocks_nextn_head_is_never_borrowed() {
2119        let wrong_block: &[&str] = &[
2120            "output.weight",
2121            "blk.46.nextn.shared_head_head.weight",
2122            "blk.47.nextn.shared_head_head.weight",
2123        ];
2124        assert_eq!(draft_head_tensor(present(wrong_block), 45), "output.weight");
2125    }
2126}