"""Layer-streaming MLX runtime for Cloudflare/clef-flash (text path only) + its joint-schema head. Backbone: mlx-lm's Qwen3.5 DecoderLayer, built one layer at a time from the release shards (np.memmap of the bf16 bytes, so only the layer being run is resident). The same sanitisation mlx-lm applies to an HF Qwen3.5 checkpoint is done per layer: conv1d [C,1,K] -> [C,K,1]; RMSNorm weights (input/post-attention/q/k/final) stored as w are shifted to 1 + w. Records are run layer-major in token-budgeted chunks (each record alone, batch 1, no padding), so the activations of one chunk + one layer are what is resident. Head: the release's JointSchemaHead (joint_schema_model.py from the snapshot, unchanged), run in torch on the CPU in fp32 on the backbone's final-norm hidden states. It reads lm_head rows for the option tokens; lm_head is never resident: bf16 rows come from a memmap of the shard, 4-bit rows from mlx affine codes (group 64) dequantized per lookup. """ import glob, json, math, os, struct, sys, time from pathlib import Path import numpy as np import torch import mlx.core as mx import mlx.nn as nn from mlx.utils import tree_flatten from mlx_lm.models.qwen3_5 import TextModelArgs, DecoderLayer from mlx_lm.models.base import create_attention_mask, create_ssm_mask _HERE = Path(__file__).resolve().parent # release dir: CLEF_SNAPSHOT, else this file's directory when it is a packaged release (ships joint_schema_model.py), else the HF cache SNAP = os.environ.get("CLEF_SNAPSHOT") or (str(_HERE) if (_HERE / "joint_schema_model.py").exists() else sorted(glob.glob("/Volumes/1Tb/hf-cache/hub/models--Cloudflare--clef-flash/snapshots/*"))[-1]) sys.path.insert(0, SNAP) sys.dont_write_bytecode = True # keep the HF snapshot clean (no __pycache__) from joint_schema_model import JointSchemaHead, encode_record # noqa: E402 (release code, unchanged) mx.set_cache_limit(1 << 30) # as kev/mlx_model.py: bound MLX's buffer cache (one buffer per new record shape otherwise) LM = "model.language_model." NORM_SHIFT = (".input_layernorm.weight", ".post_attention_layernorm.weight", ".q_norm.weight", ".k_norm.weight") SKIP = ("in_proj_a", "in_proj_b") def bf16_np_to_mx(a): return mx.view(mx.array(np.ascontiguousarray(a)), mx.bfloat16) def bf16_np_to_torch(a): return torch.from_numpy(np.ascontiguousarray(a).view(np.int16)).view(torch.bfloat16).float() class Shards: """Header index of the release safetensors shards; tensors are memmapped on demand (bf16 bytes, never converted).""" def __init__(self, snap=SNAP): self.snap = Path(snap) files = set(json.loads((self.snap / "model.safetensors.index.json").read_text())["weight_map"].values()) self.hdr = {} for f in sorted(files): p = self.snap / f with open(p, "rb") as fh: n = struct.unpack(" mlx affine packed uint32 [N, K*bits/32] (element j of a word at bit j*bits).""" N, K = codes.shape; per = 32 // bits c = codes.to(torch.int64).reshape(N, K // per, per) w = (c << (torch.arange(per, dtype=torch.int64) * bits)).sum(-1) return mx.array(w.numpy().astype(np.uint32)) def qlinear(codes, scales, biases, bits, group=64): """Build an nn.QuantizedLinear from explicit codes / bf16 scales / bf16 biases (w = scale * code + bias).""" N, K = codes.shape q = nn.QuantizedLinear(K, N, bias=False, group_size=group, bits=bits) q.weight = mlx_pack(codes, bits) q.scales = mx.array(scales.numpy()).astype(mx.bfloat16) q.biases = mx.array(biases.numpy()).astype(mx.bfloat16) return q def qembedding(w): V, D = w.shape e = nn.QuantizedEmbedding(V, D, group_size=64, bits=4) e.weight, e.scales, e.biases = mx.quantize(w, group_size=64, bits=4) return e class Head: """JointSchemaHead (fp32, CPU) + lm_head row lookup in bf16 ('bf16') or 4-bit mlx affine ('q4').""" def __init__(self, snap=SNAP, sh=None, lm_head_q=None): from safetensors.torch import load_file torch.set_num_threads(8) cfg = json.loads((Path(snap) / "joint_head_config.json").read_text()) self.head = JointSchemaHead(**cfg) self.head.load_state_dict({k: v.float() for k, v in load_file(str(Path(snap) / "joint_head.safetensors")).items()}, strict=True) self.head.eval() self.sh = sh; self.q = lm_head_q # (wq, scales, biases) or None def rows_bf16(self, ids): return bf16_np_to_torch(self.sh.memmap("lm_head.weight")[np.asarray(ids)]) def rows_q4(self, ids): ix = mx.array(np.asarray(ids, dtype=np.int32)); wq, s, b = self.q return torch.from_numpy(np.array(mx.dequantize(wq[ix], s[ix], b[ix], group_size=64, bits=4).astype(mx.float32))) @torch.no_grad() def logits(self, hidden, enc, mode): class Rows: def __getitem__(_, ids): return (self.rows_bf16 if mode == "bf16" else self.rows_q4)(ids.cpu().numpy()) L = len(enc.input_ids) out = self.head(hidden.reshape(1, L, -1), torch.tensor([enc.input_ids]), torch.ones(1, L, dtype=torch.long), [enc], Rows()) return [z.float() for z in out[0]] def chunks_by_tokens(encs, budget): out, cur, n = [], [], 0 for j, e in enumerate(encs): if cur and n + len(e.input_ids) > budget: out.append(cur); cur, n = [], 0 cur.append(j); n += len(e.input_ids) if cur: out.append(cur) return out def run_layer(layer, xs): ys = [] for x in xs: m = create_ssm_mask(x) if layer.is_linear else create_attention_mask(x) y = layer(x, mask=m, cache=None); mx.eval(y); ys.append(y) return ys def forward_logits(encs, embed, layer_at, final_norm, head, modes=("q4", "bf16"), budget=120_000, log=print): """Backbone (layer-major per chunk) + head. embed(ids)->[1,L,D]; layer_at(i)->DecoderLayer (built or resident). Returns {mode: [per-record list of per-question fp32 logit tensors]}.""" nl = len_layers = layer_at.n res = {m: [None] * len(encs) for m in modes} for ci, idx in enumerate(chunks_by_tokens(encs, budget)): t0 = time.time() xs = [embed(encs[j].input_ids) for j in idx] for i in range(nl): layer = layer_at(i); xs = run_layer(layer, xs); del layer mx.clear_cache() for j, x in zip(idx, xs): h = final_norm(x); mx.eval(h) ht = torch.from_numpy(np.array(h.astype(mx.float32))) for m in modes: res[m][j] = head.logits(ht, encs[j], m) del xs; mx.clear_cache() log(f"chunk {ci}: {len(idx)} records in {time.time()-t0:.0f}s, peak {mx.get_peak_memory()/1e9:.2f} GB") return res class FinalNorm: def __init__(self, w, eps): self.w = w; self.eps = eps def __call__(self, x): return mx.fast.rms_norm(x, self.w, self.eps) class Bf16Backbone: """Streams bf16 layers from the shards; embeddings gathered from the memmap (never fully resident).""" def __init__(self, sh, args): self.sh, self.args, self.n = sh, args, args.num_hidden_layers self.norm = FinalNorm(sanitize("norm.weight", sh.mx(LM + "norm.weight")), args.rms_norm_eps) self.emb = sh.memmap(LM + "embed_tokens.weight") def __call__(self, i): return build_layer(self.args, i, layer_weights(self.sh, i)) def embed(self, ids): return bf16_np_to_mx(self.emb[np.asarray(ids)])[None] def predictions(records, encs, logits): """kev prediction dicts (probabilities + logits keyed like kev.api.question_keys) from Clef per-option logits.""" out = [] for r, e, zs in zip(records, encs, logits): probs, lg = {}, {} for q, z in zip(e.questions, zs): p = torch.softmax(z, -1) probs[q.question_id] = {o: float(v) for o, v in zip(q.option_ids, p.tolist())} lg[q.question_id] = {o: float(v) for o, v in zip(q.option_ids, z.tolist())} out.append({"probabilities": probs, "logits": lg, "inference_temperature": 1.0, "latency_ms": 0.0, "input_tokens": len(e.input_ids)}) return out class Cached: """A predictor for kev.benchmark.evaluate_records that returns precomputed predictions in record order.""" def __init__(self, preds): self.preds = preds; self.k = 0; self.temperature = 1.0 def __call__(self, record): p = self.preds[self.k]; self.k += 1; return p