| |
| """Standalone numpy decoder for the packed Mach-1 checkpoint. |
| |
| Packed layout (HF repo): |
| packed/experts/L{LL}.safetensors -- per expert e, proj in gate/up/down: |
| e{e}.{proj}.trellis int16 [ntiles, 16*K] (trellis bitstream, ~K bpw) |
| e{e}.{proj}.su fp16 [n] |
| e{e}.{proj}.sv fp16 [m] (Wscale absorbed) |
| or (demoted K1 experts) |
| e{e}.{proj}.SU int8 [n]; e{e}.{proj}.SV int8 [m]; e{e}.{proj}.Wscale fp16 [] |
| plus, when the manifest carries "basis" (shared cold-expert low-rank basis): |
| basis.{proj}.A fp16 [r, n]; basis.{proj}.B fp16 [m, r] |
| e{e}.{proj}.c fp16 [r] (demoted experts only) |
| metadata["manifest"]: {"cb2":..., "cb1":..., "demoted":[e,...], "geom":{proj:[m,n]}, |
| optional "basis": {"r":r, "dtype":"fp16", "shared_A_gu":false}} |
| packed/experts/codebook.safetensors: tlut fp16 [512, 2] (shared by K2/K1; the tlut |
| depends only on (tlut_bits=9, V=2) -- K only changes trellis transitions). |
| packed/ne/L{LL}.safetensors (zero-padded LNN) -- codec |
| "canon_rht_bitshift_trellis_intlattice"; no manifest key. Per-file metadata: |
| cb_params {K:4,L:16,V:2,tlut_bits:9,quantlut_sym,td 16x16} + dims |
| {name: [m0, n0, m, n]}. Keys per tensor: |
| {name}|trellis int16, {name}|SU int8 [n], {name}|SV int8 [m], {name}|Wscale fp16 |
| tier-shared codebook: packed/ne/tlut.safetensors tlut fp16 [512, 2] |
| packed/ne/{L{i}|head_c{c}of8}.safetensors (single-digit L{i}: older builds) -- |
| transform-free tier: |
| {name}|packed uint8 [B, T*K/8], {name}|gscale fp16 [B, T/128], {name}|lut fp16 [4096] |
| metadata["manifest"]: {"codec":"lloyd_bitshift_trellis","L":12,"group":128, |
| "pattern":[K]*4,"tensors":{name:{shape:[m0,n0],transposed:bool}}} |
| packed/head/head_c{c}of8.safetensors -- codec "int5g64_packed": |
| LMHEADCHUNK:{r0}:{r1}|qp uint8 [rows, n/8*5], |gscale fp16 [rows, n/64] |
| (+ optional |prot_rows int32 / |prot_dense exact rows); metadata dims {name:[rows,n]} |
| packed/ne/embed_int4.safetensors (decode_embed(bits=4)) -- |
| affine int4-g64: q_packed uint8 [rows, hid/2], mn/mx fp16 [rows, hid/64] |
| packed/ne/embed_packed.safetensors (8-bpw lossless Lloyd-LUT container; |
| decode_embed_packed) and embed_int3.safetensors (older int3): |
| q_packed uint8 [rows, hid*3/8], mn fp16 [rows, hid/64], mx fp16 [rows, hid/64] |
| |
| Usage: |
| from decode import (decode_trellis, decode_expert_layer, decode_ne_shard, |
| decode_head, decode_embed_packed, decode_embed) |
| """ |
| import json |
| import math |
| import os |
|
|
| import numpy as np |
|
|
| HIDDEN, INTER, NEXP, NLAYERS = 2048, 512, 256, 40 |
| NHEADC = 8 |
| CB2 = dict(K=2, L=16, V=2, tlut_bits=9, decode_mode="quantlut_sym", td_x=16, td_y=16) |
| CB1 = dict(K=1, L=16, V=2, tlut_bits=9, decode_mode="quantlut_sym", td_x=16, td_y=16) |
| CB4 = dict(K=4, L=16, V=2, tlut_bits=9, decode_mode="quantlut_sym", td_x=16, td_y=16) |
|
|
| def padto(d): |
| """Dim -> padded dim: identity for powers of two, else next power of two.""" |
| if d > 0 and (d & (d - 1)) == 0: |
| return d |
| return 1 << math.ceil(math.log2(d)) |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| _FULL_LUT_CACHE = {} |
|
|
|
|
| def _np_full_lut(tlut, L, tlut_bits): |
| """Expand the persisted [2^tlut_bits, V] codebook to the full [2^L, V] fp32 |
| decoder table per the hashed-symmetric-LUT rule above.""" |
| small = np.asarray(tlut, np.float32) |
| s = np.arange(1 << L, dtype=np.int64) |
| p = s * (s + 1) |
| row = (p >> (16 - tlut_bits - 1)) & ((1 << tlut_bits) - 1) |
| table = small[row].copy() |
| table[:, 0] *= (1 - ((p >> 15) & 1) * 2).astype(np.float32) |
| return table |
|
|
|
|
| def _np_full_lut_cached(tlut, L, tlut_bits): |
| key = (L, tlut_bits, np.asarray(tlut).tobytes()) |
| if key not in _FULL_LUT_CACHE: |
| _FULL_LUT_CACHE[key] = _np_full_lut(tlut, L, tlut_bits) |
| return _FULL_LUT_CACHE[key] |
|
|
|
|
| def _np_rate_bits(T, K, V): |
| """(bits per shift step, bits per tile). K need not be an integer: the only |
| rate constraint is that K*V and K*T are whole numbers of bits.""" |
| step, nbits = float(K) * V, float(K) * T |
| if step != int(step) or nbits != int(nbits): |
| raise ValueError(f"rate K={K} with V={V}, T={T} needs whole-bit steps " |
| f"(K*V={step}) and a whole-bit tile (K*T={nbits})") |
| return int(step), int(nbits) |
|
|
|
|
| def _np_unpack_trellis(stream, T, L, K, V): |
| """Packed bitstream [rows, T*K/16] (u)int16 -> register states [rows, T//V] int32.""" |
| words = np.ascontiguousarray(stream) |
| if words.dtype != np.uint16: |
| words = words.view(np.uint16) |
| step, nbits = _np_rate_bits(T, K, V) |
| if step > L: |
| raise ValueError(f"K*V={step} exceeds register width L={L}") |
| rows, nstep = words.shape[0], T // V |
| bits = ((words[:, :, None].astype(np.int64) >> np.arange(15, -1, -1)) & 1) |
| bits = bits.reshape(rows, -1)[:, :nbits] |
| bits = np.concatenate([bits, bits[:, :L - step]], axis=1) |
| seed_w = 1 << np.arange(L - 1, -1, -1, dtype=np.int64) |
| step_w = 1 << np.arange(step - 1, -1, -1, dtype=np.int64) |
| fresh = bits[:, L:L + (nstep - 1) * step].reshape(rows, nstep - 1, step) @ step_w |
| states = np.empty((rows, nstep), np.int32) |
| reg = bits[:, :L] @ seed_w |
| states[:, 0] = reg |
| mask = (1 << L) - 1 |
| for i in range(1, nstep): |
| reg = ((reg << step) & mask) | fresh[:, i - 1] |
| states[:, i] = reg |
| return states |
|
|
|
|
| def _np_recons(states, table, m, n, td_x, td_y): |
| """Register states [ntiles, T//V] + full LUT -> codebook-unit weights [m, n] fp32 |
| (V scalars per state, row-major tiles, row-major tile grid).""" |
| vals = table[states] |
| return np.ascontiguousarray( |
| vals.reshape(m // td_x, n // td_y, td_x, td_y).transpose(0, 2, 1, 3) |
| ).reshape(m, n) |
|
|
|
|
| def _np_hadamard(x): |
| """Orthonormal Walsh-Hadamard transform (Sylvester order) along the LAST axis: |
| y = FWHT(x) / sqrt(dim). Butterflies pair at stride 1, then 2, 4, ... in fp32, |
| with a single fp32 division by sqrt(dim) after the final pass.""" |
| dim = x.shape[-1] |
| if dim & (dim - 1): |
| raise ValueError(f"pure-numpy RHT needs a power-of-2 dim, got {dim}") |
| cur = np.ascontiguousarray(x, dtype=np.float32).reshape(-1, dim) |
| span = 1 |
| while span < dim: |
| blk = cur.reshape(-1, dim // (2 * span), 2, span) |
| nxt = np.empty_like(blk) |
| nxt[:, :, 0, :] = blk[:, :, 0, :] + blk[:, :, 1, :] |
| nxt[:, :, 1, :] = blk[:, :, 0, :] - blk[:, :, 1, :] |
| cur = nxt.reshape(-1, dim) |
| span *= 2 |
| return (cur / np.float32(np.sqrt(np.float32(dim)))).reshape(x.shape) |
|
|
|
|
| def decode_trellis(trellis, su, sv, tlut, m0, n0, cb_params, wscale=None, cb=None, |
| device="cuda"): |
| """Trellis decode -> fp32 [m0, n0]. |
| |
| su [n] / sv [m] are the RHT vectors over the PADDED dims: int8 +/-1 signs for raw |
| PTQ tensors (then `wscale` must be given), or continuous fp16 vectors for the |
| K2 experts (Wscale absorbed into sv; pass wscale=None). |
| Reverses: unpack states -> tiles -> [m,n] -> *wscale -> *su-side FWHT -> *sv-side |
| FWHT -> unpad. `cb` may carry a prebuilt table (numpy [2^L, V] LUT); |
| anything else is ignored and rebuilt from tlut. |
| """ |
| mode = cb_params.get("decode_mode", "quantlut_sym") |
| if mode != "quantlut_sym": |
| raise NotImplementedError(f"numpy decode implements quantlut_sym, got {mode}") |
| td_x, td_y = cb_params["td_x"], cb_params["td_y"] |
| L, K, V = cb_params["L"], cb_params["K"], cb_params["V"] |
| m, n = padto(m0), padto(n0) |
| table = cb if isinstance(cb, np.ndarray) else \ |
| _np_full_lut_cached(tlut, L, cb_params["tlut_bits"]) |
| states = _np_unpack_trellis(np.asarray(trellis), td_x * td_y, L, K, V) |
| unit = _np_recons(states, table, m, n, td_x, td_y) |
| |
| unit = unit.astype(np.float16).astype(np.float32) |
| if wscale is not None: |
| unit = unit * np.float32(wscale) |
| rowside = _np_hadamard(unit) * np.asarray(su, np.float32) |
| colside = _np_hadamard(rowside.T) * np.asarray(sv, np.float32) |
| return np.ascontiguousarray(colside.T[:m0, :n0]) |
|
|
|
|
| |
| |
| |
| def _read_safetensors_np(path): |
| """Read a pack file. v3 files carry a zstd sidecar (`__zsc__` + metadata["zsc"]) |
| holding every non-code-stream tensor byte-exactly; expand it transparently.""" |
| from safetensors import safe_open |
| out = {} |
| with safe_open(path, framework="numpy") as fh: |
| meta = fh.metadata() or {} |
| for k in fh.keys(): |
| out[k] = fh.get_tensor(k) |
| if "__zsc__" in out: |
| import zstandard |
| man = json.loads(meta["zsc"]) |
| buf = zstandard.ZstdDecompressor().decompress( |
| out.pop("__zsc__").tobytes(), max_output_size=man["raw_len"]) |
| for key, dt, shape, off, nb in man["entries"]: |
| out[key] = np.frombuffer(buf, dtype=np.dtype(dt), |
| count=nb // np.dtype(dt).itemsize, |
| offset=off).reshape(shape) |
| return out, meta |
|
|
|
|
| _ST_TORCH_DTYPES = {"BF16": "bfloat16", "F16": "float16", "F32": "float32", |
| "F64": "float64", "I8": "int8", "U8": "uint8", "I16": "int16", |
| "I32": "int32", "I64": "int64", "BOOL": "bool"} |
|
|
|
|
| def read_safetensors_torch(path): |
| """Torch-side v2/v3 reader for dtype-opaque files (bf16). v3 files hold ONLY |
| `__zsc__`; entries carry safetensors dtype tokens ("BF16", ...). |
| Returns ({name: torch.Tensor}, metadata).""" |
| import torch |
| from safetensors import safe_open |
| out = {} |
| with safe_open(path, framework="pt") as fh: |
| meta = fh.metadata() or {} |
| for k in fh.keys(): |
| out[k] = fh.get_tensor(k) |
| if "__zsc__" in out: |
| import zstandard |
| man = json.loads(meta["zsc"]) |
| buf = zstandard.ZstdDecompressor().decompress( |
| out.pop("__zsc__").numpy().tobytes(), max_output_size=man["raw_len"]) |
| for key, dt, shape, off, nb in man["entries"]: |
| if dt in _ST_TORCH_DTYPES: |
| t = torch.frombuffer(bytearray(buf[off:off + nb]), |
| dtype=getattr(torch, _ST_TORCH_DTYPES[dt])) |
| out[key] = t.reshape(shape) |
| else: |
| a = np.frombuffer(buf, dtype=np.dtype(dt), |
| count=nb // np.dtype(dt).itemsize, offset=off) |
| out[key] = torch.from_numpy(a.reshape(shape).copy()) |
| return out, meta |
|
|
|
|
| def decode_expert_layer(packed_dir, layer, device="cuda"): |
| """Reassemble fused gate_up_proj [256,1024,2048] fp32 + down_proj [256,2048,512]. |
| K2 experts decode with continuous su/sv (no wscale); demoted K1 experts decode |
| with int8 signs + Wscale, plus the shared low-rank basis residual (B*c)@A when |
| the manifest carries "basis".""" |
| path = os.path.join(packed_dir, "experts", f"L{layer:02d}.safetensors") |
| t, meta = _read_safetensors_np(path) |
| |
| |
| if "wave_gamma" in (meta.get("fields") or ""): |
| return decode_expert_layer_v3t(packed_dir, layer) |
| man = json.loads(meta["manifest"]) |
| tlut, _ = _read_safetensors_np(os.path.join(packed_dir, "experts", "codebook.safetensors")) |
| tlut = tlut["tlut"] |
| |
| cb2 = cb1 = _np_full_lut_cached(tlut, man.get("cb2", CB2)["L"], |
| man.get("cb2", CB2)["tlut_bits"]) |
| demoted = set(man["demoted"]) |
| geom = {p: tuple(v) for p, v in man["geom"].items()} |
| basis = man.get("basis") |
| if basis is not None: |
| bA = {p: t[f"basis.{p}.A"].astype(np.float32) for p in geom} |
| bB = {p: t[f"basis.{p}.B"].astype(np.float32) for p in geom} |
| gate_up = np.empty((NEXP, 2 * INTER, HIDDEN), np.float32) |
| down = np.empty((NEXP, HIDDEN, INTER), np.float32) |
| for e in range(NEXP): |
| for proj, dst in (("gate", gate_up[e, :INTER]), ("up", gate_up[e, INTER:]), |
| ("down", down[e])): |
| m0, n0 = geom[proj] |
| if e in demoted: |
| ws = float(np.asarray(t[f"e{e}.{proj}.Wscale"]).ravel()[0]) |
| w = decode_trellis(t[f"e{e}.{proj}.trellis"], t[f"e{e}.{proj}.SU"], |
| t[f"e{e}.{proj}.SV"], tlut, m0, n0, man.get("cb1", CB1), |
| wscale=ws, cb=cb1, device=device) |
| if basis is not None: |
| |
| |
| c = t[f"e{e}.{proj}.c"].astype(np.float32) |
| w = w + (bB[proj] * c[None, :]) @ bA[proj] |
| else: |
| w = decode_trellis(t[f"e{e}.{proj}.trellis"], t[f"e{e}.{proj}.su"], |
| t[f"e{e}.{proj}.sv"], tlut, m0, n0, man.get("cb2", CB2), |
| wscale=None, cb=cb2, device=device) |
| dst[:] = w |
| return {"gate_up_proj": gate_up, "down_proj": down} |
|
|
|
|
| |
| |
| |
| |
| NELL_L = 12 |
|
|
|
|
| def _nell_bits_to_states(packed, T, k, L=NELL_L): |
| """Inverse of the encoder's states_to_bits: step t's k NEW trellis bits are stored |
| MSB-first, bytes are big-endian packbits. State recurrence (s_{-1} = 0): |
| s_t = ((s_{t-1} << k) | b_t) & (2^L - 1).""" |
| B = packed.shape[0] |
| bits = np.unpackbits(packed, axis=1, count=T * k).astype(np.int64) |
| mask = (1 << L) - 1 |
| states = np.empty((B, T), np.int32) |
| s = np.zeros(B, np.int64) |
| pos = 0 |
| for t in range(T): |
| b = np.zeros(B, np.int64) |
| for j in range(k): |
| b = (b << 1) | bits[:, pos] |
| pos += 1 |
| s = ((s << k) | b) & mask |
| states[:, t] = s |
| return states |
|
|
|
|
| def decode_ne_ll_tensor(t, man, name): |
| """One transform-free NE matrix -> fp32 [m0, n0]: fp16 LUT gathered as fp32, |
| * per-group fp16 scale in fp32, transpose back.""" |
| g, k = man["group"], man["pattern"][0] |
| geom = man["tensors"][name] |
| m0, n0 = geom["shape"] |
| B, T = (n0, m0) if geom["transposed"] else (m0, n0) |
| lut = t[f"{name}|lut"].astype(np.float32) |
| gs = t[f"{name}|gscale"].astype(np.float32) |
| states = _nell_bits_to_states(t[f"{name}|packed"], T, k) |
| W = lut[states] * np.repeat(gs, g, axis=1) |
| return np.ascontiguousarray(W.T) if geom["transposed"] else W |
|
|
|
|
| def decode_ne_shard_canon(t, meta, packed_dir, device="cuda", subdir="ne"): |
| """NE spine shard (codec canon_rht_bitshift_trellis_intlattice, zero-padded |
| L00-L39 files). No manifest key: per-file metadata holds cb_params and dims |
| (name -> [m0, n0, m, n]); keys are <tensor>|{trellis,SU,SV,Wscale} with int8 |
| sign SU/SV + scalar Wscale; the tier-shared codebook is <subdir>/tlut.safetensors.""" |
| cbp = json.loads(meta["cb_params"]) |
| dims = json.loads(meta["dims"]) |
| tlut, _ = _read_safetensors_np(os.path.join(packed_dir, subdir, "tlut.safetensors")) |
| tlut = tlut["tlut"] |
| cb = _np_full_lut_cached(tlut, cbp["L"], cbp["tlut_bits"]) |
| out = {} |
| for name in sorted({key.rsplit("|", 1)[0] for key in t}): |
| m0, n0 = dims[name][0], dims[name][1] |
| out[name] = decode_trellis(t[f"{name}|trellis"], t[f"{name}|SU"], t[f"{name}|SV"], |
| tlut, m0, n0, cbp, |
| wscale=float(np.asarray(t[f"{name}|Wscale"]).ravel()[0]), |
| cb=cb, device=device) |
| return out |
|
|
|
|
| def decode_ne_shard(packed_dir, shard, device="cuda", subdir="ne"): |
| """Decode every NE tensor in one shard -> {name: fp32 [m0,n0]}. Dispatches on the |
| shard's own metadata. subdir picks the size variant: "ne" (default) or "ne-4bit".""" |
| path = os.path.join(packed_dir, subdir, f"{shard}.safetensors") |
| t, meta = _read_safetensors_np(path) |
| if "manifest" not in meta: |
| codec = meta.get("codec") |
| assert codec == "canon_rht_bitshift_trellis_intlattice", \ |
| f"NE shard {shard}: no manifest and unknown codec {codec!r}" |
| return decode_ne_shard_canon(t, meta, packed_dir, device=device, subdir=subdir) |
| man = json.loads(meta["manifest"]) |
| if man.get("codec") == "lloyd_bitshift_trellis": |
| return {name: decode_ne_ll_tensor(t, man, name) for name in man["tensors"]} |
| cb_params = man["cb"] |
| tlut, _ = _read_safetensors_np(os.path.join(packed_dir, "ne", "codebook.safetensors")) |
| tlut = tlut["tlut"] |
| cb = _np_full_lut_cached(tlut, cb_params["L"], cb_params["tlut_bits"]) |
| out = {} |
| for name, geom in man["tensors"].items(): |
| out[name] = decode_trellis(t[f"{name}|trellis"], t[f"{name}|SU"], t[f"{name}|SV"], |
| tlut, geom["m0"], geom["n0"], cb_params, |
| wscale=float(np.asarray(t[f"{name}|Wscale"]).ravel()[0]), |
| cb=cb, device=device) |
| return out |
|
|
|
|
| |
| |
| |
| def pack_embed_q(q, bits=3): |
| """q uint8 [rows, hid] with values < 2**bits -> packed uint8 [rows, hid*bits/8].""" |
| rows, hid = q.shape |
| b = np.unpackbits(q[..., None], axis=-1, count=8)[..., 8 - bits:] |
| return np.packbits(b.reshape(rows, hid * bits), axis=1) |
|
|
|
|
| def unpack_embed_q(packed, hid, bits=3): |
| rows = packed.shape[0] |
| b = np.unpackbits(packed, axis=1, count=hid * bits).reshape(rows, hid, bits) |
| q = np.zeros((rows, hid), np.uint8) |
| for j in range(bits): |
| q = (q << 1) | b[..., j] |
| return q |
|
|
|
|
| def decode_embed(packed_dir, bits=3, group=None): |
| """embed_int{bits} codes -> fp32 [rows, hid]. mn/mx stored fp16, step computed |
| in fp32 exactly as at encode time. `group` is inferred from the stored shapes |
| when not given, so g64 and g128 packs decode identically. |
| Optional exception tensors: elements listed in exc_idx int32 (flat index) are |
| overwritten with the exact bf16 bit patterns in exc_bits uint16 (expanded to |
| fp32 here).""" |
| path = os.path.join(packed_dir, "ne", f"embed_int{bits}.safetensors") |
| t, meta = _read_safetensors_np(path) |
| mn = t["mn"].astype(np.float32)[..., None] |
| mx = t["mx"].astype(np.float32)[..., None] |
| rows, ng = mn.shape[0], mn.shape[1] |
| if group is None: |
| group = (t["q_packed"].shape[1] * 8 // bits) // ng |
| hid = ng * group |
| q = unpack_embed_q(t["q_packed"], hid, bits=bits).astype(np.float32) |
| lv = float(2 ** bits - 1) |
| step = np.maximum(mx - mn, 1e-8) / lv |
| dec = (mn + q.reshape(rows, ng, group) * step).reshape(rows, hid) |
| if "exc_idx" in t: |
| vals = (np.asarray(t["exc_bits"]).astype(np.uint32) << 16).view(np.float32) |
| dec.reshape(-1)[np.asarray(t["exc_idx"], dtype=np.int64)] = vals |
| return dec |
|
|
|
|
| def decode_embed_packed(packed_dir, subdir="ne"): |
| """embed_packed.safetensors (per-group Lloyd LUT + 4-bit nibble codes, chunk keys |
| EMBEDCHUNK:{r0}:{r1}.{codes|lut}) -> fp32 [rows, hid]. Lossless: the lut stores |
| the source bf16 bit patterns. Low nibble = even column. Uses the torch-side |
| reader because the lut is bf16.""" |
| path = os.path.join(packed_dir, subdir, "embed_packed.safetensors") |
| t, meta = read_safetensors_torch(path) |
| group = int(meta.get("group", 128)) |
| chunks = sorted({k.rsplit(".", 1)[0] for k in t}, |
| key=lambda c: int(c.split(":")[1])) |
| r_end, parts = 0, [] |
| for c in chunks: |
| r0, r1 = int(c.split(":")[1]), int(c.split(":")[2]) |
| assert r0 == r_end, f"non-contiguous embed chunks at {c}" |
| r_end = r1 |
| codes = np.asarray(t[f"{c}.codes"]) |
| lut = t[f"{c}.lut"].float().numpy() |
| rows, half = codes.shape |
| cols = half * 2 |
| q = np.empty((rows, cols), np.uint8) |
| q[:, 0::2] = codes & 0x0F |
| q[:, 1::2] = codes >> 4 |
| w = np.take_along_axis(lut, q.reshape(-1, group).astype(np.int64), axis=1) |
| parts.append(w.reshape(rows, cols)) |
| return np.concatenate(parts, axis=0) |
|
|
|
|
| if __name__ == "__main__": |
| import argparse |
| ap = argparse.ArgumentParser(description="spot-verify a packed dir against decoded refs") |
| ap.add_argument("--packed-dir", required=True) |
| ap.add_argument("--ref-experts", default=None) |
| ap.add_argument("--ref-ne", default=None) |
| ap.add_argument("--layers", default="0") |
| ap.add_argument("--ne-shards", default="L0") |
| ap.add_argument("--device", default="cuda") |
| a = ap.parse_args() |
|
|
| def _re(x, y): |
| x, y = np.asarray(x, np.float32).ravel(), np.asarray(y, np.float32).ravel() |
| return float(np.linalg.norm(x - y) / max(np.linalg.norm(y), 1e-30)) |
|
|
| if a.ref_experts: |
| for L in [int(x) for x in a.layers.split(",") if x.strip()]: |
| dec = decode_expert_layer(a.packed_dir, L, device=a.device) |
| ref, _ = _read_safetensors_np(os.path.join(a.ref_experts, f"L{L:02d}.safetensors")) |
| for key in ("gate_up_proj", "down_proj"): |
| print(f"[experts L{L} {key}] relerr_vs_ref={_re(dec[key], ref[key]):.2e}") |
| if a.ref_ne: |
| for shard in [x for x in a.ne_shards.split(",") if x.strip()]: |
| dec = decode_ne_shard(a.packed_dir, shard, device=a.device) |
| refp = os.path.join(a.ref_ne, f"{shard}.safetensors") |
| ref, _ = _read_safetensors_np(refp) if os.path.exists(refp) else ({}, {}) |
| for name, w in dec.items(): |
| if name in ref: |
| print(f"[NE {shard} {name}] relerr_vs_ref={_re(w, ref[name]):.4f}") |
| else: |
| print(f"[NE {shard} {name}] shape={w.shape} (no ref)") |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| def pack_int5(q): |
| """int8 [m, n] in [-16, 15] -> uint8 [m, n//8*5] little-endian 5-bit pack.""" |
| m, n = q.shape |
| assert n % 8 == 0, n |
| u = (q.astype(np.int64) + 16).astype(np.uint64) |
| assert u.max() < 32 and u.min() >= 0, (int(u.min()), int(u.max())) |
| blocks = u.reshape(m, n // 8, 8) |
| word = np.zeros((m, n // 8), dtype=np.uint64) |
| for i in range(8): |
| word |= blocks[:, :, i] << np.uint64(5 * i) |
| by = word.astype("<u8").view(np.uint8).reshape(m, n // 8, 8)[:, :, :5] |
| return np.ascontiguousarray(by.reshape(m, n // 8 * 5)) |
|
|
|
|
| def unpack_int5(qp, n): |
| """Inverse of pack_int5 -> int8 [m, n] in [-16, 15].""" |
| m = qp.shape[0] |
| assert qp.shape[1] == n // 8 * 5, (qp.shape, n) |
| by = qp.reshape(m, n // 8, 5) |
| full = np.zeros((m, n // 8, 8), dtype=np.uint8) |
| full[:, :, :5] = by |
| word = full.reshape(m, n // 8 * 8).view("<u8").reshape(m, n // 8) |
| out = np.zeros((m, n // 8, 8), dtype=np.int8) |
| for i in range(8): |
| out[:, :, i] = ((word >> np.uint64(5 * i)) & np.uint64(31)).astype(np.int8) - 16 |
| return out.reshape(m, n) |
|
|
|
|
| def decode_int5g64(qp, gscale, m0, n0, group=64, prot_rows=None, prot_dense=None): |
| """int5-g64 head decode -> fp32 [m0, n0]: W[r, j] = q[r, j] * gscale[r, j // group]; |
| protected rows are then overwritten with their exact dense values.""" |
| q = unpack_int5(np.asarray(qp), n0).astype(np.float32) |
| s = np.asarray(gscale, dtype=np.float32) |
| W = q * np.repeat(s, group, axis=1)[:, :n0] |
| if prot_rows is not None and len(prot_rows): |
| W[np.asarray(prot_rows, dtype=np.int64)] = np.asarray(prot_dense, |
| dtype=np.float32) |
| return np.ascontiguousarray(W[:m0, :n0]) |
|
|
|
|
| def decode_head(packed_dir, subdir="head"): |
| """int5-g64 lm_head (packed/{subdir}/head_c{c}of8.safetensors, codec |
| "int5g64_packed") -> fp32 [vocab, hid]. Chunk keys LMHEADCHUNK:{r0}:{r1}|{qp|gscale} |
| (+ optional |prot_rows / |prot_dense); each file's dims metadata gives the chunk's |
| [rows, n]; row chunks assemble in r0 order.""" |
| d = os.path.join(packed_dir, subdir) |
| files = sorted(f for f in os.listdir(d) |
| if f.startswith("head_c") and f.endswith(".safetensors")) |
| assert files, f"no head chunk files under {d}" |
| pieces = [] |
| for f in files: |
| t, meta = _read_safetensors_np(os.path.join(d, f)) |
| group = int(meta.get("group", 64)) |
| dims = json.loads(meta["dims"]) |
| for name, (m0, n0) in dims.items(): |
| r0 = int(name.split(":")[1]) |
| w = decode_int5g64(t[f"{name}|qp"], t[f"{name}|gscale"], m0, n0, |
| group=group, prot_rows=t.get(f"{name}|prot_rows"), |
| prot_dense=t.get(f"{name}|prot_dense")) |
| pieces.append((r0, w)) |
| pieces.sort(key=lambda x: x[0]) |
| return np.concatenate([w for _, w in pieces], axis=0) |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| def wave_index_map(Mb, Nb): |
| """Tile grid [Mb, Nb] -> the LAST wavefront index that wrote each tile |
| (the encoder's starts recurrence, including the schedule's duplicated |
| top-right-starting wave).""" |
| starts = ([(Mb - i - 1, Nb - 1) for i in range(Mb)] |
| + [(0, Nb - i - 1) for i in range(Nb)]) |
| idx = np.zeros((Mb, Nb), dtype=np.int32) |
| for w, (jm, jn) in enumerate(starts): |
| while 0 <= jm < Mb and 0 <= jn < Nb: |
| idx[jm, jn] = w |
| jm += 1 |
| jn -= 1 |
| return idx |
|
|
|
|
| def apply_wave_gamma(Wr, gamma, td=16): |
| """Multiply each td x td tile of Wr [m, n] by gamma[wave(tile)].""" |
| m, n = Wr.shape |
| Mb, Nb = m // td, n // td |
| g = np.asarray(gamma, np.float32)[wave_index_map(Mb, Nb)] |
| return np.ascontiguousarray( |
| (Wr.reshape(Mb, td, Nb, td) * g[:, None, :, None]).reshape(m, n)) |
|
|
|
|
| CB_V3T = dict(K=1.5, L=16, V=8, tlut_bits=15, decode_mode="quantlut_sym", |
| td_x=16, td_y=16) |
|
|
|
|
| def decode_expert_v3t(t, tlut, proj, e, m0, n0, cb_params=None, table=None): |
| """Decode ONE expert's projection from a chunked-container layer dict.""" |
| cbp = cb_params or CB_V3T |
| c0, off = (e // 32) * 32, e % 32 |
| if table is None: |
| table = _np_full_lut_cached(tlut, cbp["L"], cbp["tlut_bits"]) |
| m, n = padto(m0), padto(n0) |
| tr = np.asarray(t[f"e{c0}.{proj}.trellis"][off]) |
| su = np.asarray(t[f"e{c0}.{proj}.su"][off], np.float32) |
| sv = np.asarray(t[f"e{c0}.{proj}.sv"][off], np.float32) |
| states = _np_unpack_trellis(tr, cbp["td_x"] * cbp["td_y"], |
| cbp["L"], cbp["K"], cbp["V"]) |
| unit = _np_recons(states, table, m, n, cbp["td_x"], cbp["td_y"]) |
| unit = unit.astype(np.float16).astype(np.float32) |
| gk = f"e{c0}.{proj}.wave_gamma" |
| if gk in t: |
| unit = apply_wave_gamma(unit, np.asarray(t[gk][off], np.float32), |
| td=cbp["td_x"]) |
| rowside = _np_hadamard(unit) * su |
| colside = _np_hadamard(rowside.T) * sv |
| return np.ascontiguousarray(colside.T[:m0, :n0]) |
|
|
|
|
| def decode_expert_layer_v3t(packed_dir, layer): |
| """Whole-layer reassembly for the chunked container -> gate_up/down fp32.""" |
| path = os.path.join(packed_dir, "experts", f"L{layer:02d}.safetensors") |
| t, meta = _read_safetensors_np(path) |
| assert "wave_gamma" in (meta.get("fields") or ""), "not a chunked-container shard (fields metadata lacks wave_gamma)" |
| tlut, _ = _read_safetensors_np(os.path.join(packed_dir, "experts", |
| "codebook.safetensors")) |
| tlut = tlut["tlut"] |
| table = _np_full_lut_cached(tlut, CB_V3T["L"], CB_V3T["tlut_bits"]) |
| gate_up = np.empty((NEXP, 2 * INTER, HIDDEN), np.float32) |
| down = np.empty((NEXP, HIDDEN, INTER), np.float32) |
| for e in range(NEXP): |
| gate_up[e, :INTER] = decode_expert_v3t(t, tlut, "gate", e, INTER, HIDDEN, |
| table=table) |
| gate_up[e, INTER:] = decode_expert_v3t(t, tlut, "up", e, INTER, HIDDEN, |
| table=table) |
| down[e] = decode_expert_v3t(t, tlut, "down", e, HIDDEN, INTER, table=table) |
| return {"gate_up_proj": gate_up, "down_proj": down} |
|
|