Download tensor_roll/search.py from Snapkitty/tensor-roll: direct link, hf CLI and curl.
- Browser
- Download file 9.47 kB
-
https://huggingface.co/Snapkitty/tensor-roll/resolve/main/tensor_roll/search.py
- Command line
-
hf download hf://Snapkitty/tensor-roll/tensor_roll/search.py
-
curl -L -o search.py https://huggingface.co/Snapkitty/tensor-roll/resolve/main/tensor_roll/search.py
9.47 kB
| # Tensor Roll — Recursive CUDA-Q Model Quantizer | |
| # Copyright (C) 2026 SnapKitty Collective | |
| # SPDX-License-Identifier: AGPL-3.0-or-later | |
| """Representation search: 30B -> 8B (parameterized). | |
| Pipeline: | |
| 1. Per-tensor TensorRoll analysis (core.roll_tree) -> measured options. | |
| 2. Global greedy selection under the hard parameter budget. | |
| 3. Student *architecture* search over (d, heads, dff, layers): each | |
| candidate is scored by projected retained energy, where every teacher | |
| tensor is mapped to the candidate shape by truncated-SVD projection | |
| and its retained singular energy is measured. No hard-coded answer — | |
| the argmax under the budget wins. | |
| 4. Student weight init from the teacher via the winning projections | |
| (Xavier where no projection exists), with per-tensor provenance. | |
| The budget is P_target <= 8.5B for the real 30B path. At small scale the | |
| same ratio applies: budget = teacher_params * (8.5/30). | |
| """ | |
| from __future__ import annotations | |
| import itertools | |
| import numpy as np | |
| from . import core as C | |
| from .model import Config, count_params, init_params | |
| from . import qsim as Q | |
| BUDGET_RATIO = 8.5 / 30.0 # hard architectural budget, same at every scale | |
| ABS_BUDGET_CAP = 8_500_000_000 | |
| def _svd_cache(params: dict) -> dict: | |
| cache = {} | |
| for k, v in params.items(): | |
| v = np.asarray(v, dtype=np.float64) | |
| if v.ndim == 2 and min(v.shape) > 1: | |
| U, s, Vt = np.linalg.svd(v, full_matrices=False) | |
| cache[k] = (U, s, Vt) | |
| return cache | |
| def project_matrix(W: np.ndarray, out_shape: tuple, svd=None): | |
| """Truncated-SVD projection of W to out_shape (both dims <= input dims). | |
| Returns (W_proj, retained_energy_fraction). Optimal rank-k approximation, | |
| cropped — the classical baseline every exotic option is measured against. | |
| """ | |
| W = np.asarray(W, dtype=np.float64) | |
| mo, no = out_shape | |
| m, n = W.shape | |
| assert mo <= m and no <= n, f"projection only shrinks: {W.shape} -> {out_shape}" | |
| if svd is None: | |
| U, s, Vt = np.linalg.svd(W, full_matrices=False) | |
| else: | |
| U, s, Vt = svd | |
| k = min(mo, no) | |
| Wp = (U[:mo, :k] * s[:k]) @ Vt[:k, :no] | |
| total = float((s ** 2).sum()) | |
| energy = float((s[:k] ** 2).sum() / total) if total > 0 else 1.0 | |
| return Wp.astype(np.float32), energy | |
| def _candidate_configs(teacher_cfg: Config): | |
| """Small grid of student architectures to search (real 30B path uses a | |
| wider grid over the same code).""" | |
| ds = sorted({teacher_cfg.d // 2, max(8, teacher_cfg.d * 3 // 4)}) | |
| hs = sorted({max(1, teacher_cfg.heads - 1), teacher_cfg.heads}) | |
| dffs = sorted({teacher_cfg.dff // 2, max(16, teacher_cfg.dff * 3 // 4)}) | |
| ls = sorted({max(1, teacher_cfg.layers - 1), teacher_cfg.layers}) | |
| for d, h, dff, l in itertools.product(ds, hs, dffs, ls): | |
| if d % h == 0: | |
| yield Config(vocab=teacher_cfg.vocab, d=d, heads=h, | |
| layers=l, dff=dff, seq=teacher_cfg.seq) | |
| def _config_param_count(cfg: Config) -> int: | |
| # mirrors init_params structure without allocating | |
| n = cfg.vocab * cfg.d | |
| per_layer = (4 * cfg.d * cfg.d + 4 * cfg.d # q,k,v,o + biases | |
| + 4 * cfg.d # two layernorms | |
| + 2 * cfg.d * cfg.dff + cfg.dff + cfg.d) # mlp | |
| n += cfg.layers * per_layer | |
| n += 2 * cfg.d + cfg.d * cfg.vocab + cfg.vocab | |
| return n | |
| def search_student_config(teacher_params: dict, teacher_cfg: Config, | |
| budget_params: float): | |
| """Returns (best_cfg, scored_list). scored_list entries are | |
| (cfg, est_energy, param_count), sorted by energy desc.""" | |
| svd = _svd_cache(teacher_params) | |
| scored = [] | |
| for cfg in _candidate_configs(teacher_cfg): | |
| pc = _config_param_count(cfg) | |
| if pc > budget_params: | |
| continue | |
| energies, weights = [], [] | |
| for k, v in teacher_params.items(): | |
| v = np.asarray(v) | |
| if v.ndim != 2 or k not in svd: | |
| continue | |
| # map teacher key -> student key shape | |
| sk = _student_key(k, cfg, teacher_cfg) | |
| if sk is None: | |
| continue | |
| sshape = _student_shape(k, v.shape, cfg, teacher_cfg) | |
| if sshape is None or sshape[0] > v.shape[0] or sshape[1] > v.shape[1]: | |
| continue | |
| _, e = project_matrix(v, sshape, svd[k]) | |
| energies.append(e) | |
| weights.append(v.size) | |
| est = float(np.average(energies, weights=weights)) if energies else 0.0 | |
| scored.append({"cfg": cfg.to_dict(), "est_energy": est, "params": pc}) | |
| scored.sort(key=lambda s: -s["est_energy"]) | |
| if not scored: | |
| raise RuntimeError("no student config fits the budget; cannot proceed honestly") | |
| best = Config.from_dict(scored[0]["cfg"]) | |
| return best, scored | |
| def _student_key(k: str, cfg: Config, tcfg: Config): | |
| # student uses identical key names; layer count may shrink | |
| if k.startswith("L"): | |
| l = int(k[1:].split(".")[0]) | |
| if l >= cfg.layers: | |
| return None | |
| return k | |
| def _student_shape(k: str, tshape: tuple, cfg: Config, tcfg: Config): | |
| d, td = cfg.d, tcfg.d | |
| if k == "emb": | |
| return (cfg.vocab, d) | |
| if k in ("lnfg", "lnfb"): | |
| return (d,) | |
| if k == "Whead": | |
| return (d, cfg.vocab) | |
| if k == "bhead": | |
| return (cfg.vocab,) | |
| if k.startswith("L"): | |
| rest = k.split(".", 1)[1] | |
| if rest in ("ln1g", "ln1b", "ln2g", "ln2b"): | |
| return (d,) | |
| if rest in ("Wq", "Wk", "Wv", "Wo"): | |
| return (d, d) | |
| if rest in ("bq", "bk", "bv", "bo"): | |
| return (d,) | |
| if rest == "W1": | |
| return (d, cfg.dff) | |
| if rest == "b1": | |
| return (cfg.dff,) | |
| if rest == "W2": | |
| return (cfg.dff, d) | |
| if rest == "b2": | |
| return (d,) | |
| return None | |
| def init_student_from_teacher(teacher_params: dict, teacher_cfg: Config, | |
| student_cfg: Config, rng: np.random.Generator): | |
| """Project teacher weights into the student shapes; Xavier elsewhere. | |
| Returns (student_params, provenance, achieved_energies).""" | |
| student = init_params(rng, student_cfg) # Xavier baseline everywhere | |
| svd = _svd_cache(teacher_params) | |
| provenance, energies = {}, {} | |
| for k, v in teacher_params.items(): | |
| sk = _student_key(k, student_cfg, teacher_cfg) | |
| if sk is None or sk not in student: | |
| provenance[k] = "dropped-by-architecture-search" | |
| continue | |
| sv = student[sk] | |
| v = np.asarray(v) | |
| if (v.ndim == 2 and sv.ndim == 2 and k in svd | |
| and sv.shape[0] <= v.shape[0] and sv.shape[1] <= v.shape[1]): | |
| proj, e = project_matrix(v, sv.shape, svd[k]) | |
| student[sk] = proj | |
| provenance[k] = f"truncated-svd-projection energy={e:.4f}" | |
| energies[k] = e | |
| elif v.shape == sv.shape: | |
| student[sk] = v.astype(np.float32) | |
| provenance[k] = "copied-exact" | |
| energies[k] = 1.0 | |
| else: | |
| provenance[k] = "xavier-init(shape-mismatch)" | |
| energies[k] = 0.0 | |
| return student, provenance, energies | |
| def head_consolidation_report(teacher_params: dict, teacher_cfg: Config, | |
| student_cfg: Config) -> dict: | |
| """Which attention heads survived consolidation, by measured spectral | |
| energy of each head's QK block.""" | |
| report = {} | |
| for l in range(teacher_cfg.layers): | |
| if l >= student_cfg.layers: | |
| continue | |
| Wq = np.asarray(teacher_params[f"L{l}.Wq"], dtype=np.float64) | |
| dh = teacher_cfg.dh | |
| energies = [] | |
| for h in range(teacher_cfg.heads): | |
| blk = Wq[:, h * dh:(h + 1) * dh] | |
| s = np.linalg.svd(blk, compute_uv=False) | |
| energies.append(float((s ** 2).sum())) | |
| order = sorted(range(len(energies)), key=lambda h: -energies[h]) | |
| kept = sorted(order[:student_cfg.heads]) | |
| report[f"layer_{l}"] = { | |
| "head_energies": [round(e, 4) for e in energies], | |
| "kept_heads": kept, | |
| "dropped_heads": sorted(order[student_cfg.heads:]), | |
| } | |
| return report | |
| def run_roll_analysis(teacher_params: dict, *, depth: int = 3, | |
| quantum_policy: str = "off", rank: int = 0, | |
| stats: dict = None): | |
| """Run the first-class TensorRoll(T, axis, depth, rank, quantum_policy) | |
| operator over every teacher tensor. Returns (trees, leaves). | |
| `stats`: optional {tensor_name: {"act_rms", "grad_norm", "grad_rel"}} | |
| from model.measure_tensor_stats; attached to each leaf's metrics so the | |
| search sees measured activation/gradient contributions. | |
| """ | |
| trees, leaves = {}, [] | |
| for k in sorted(teacher_params.keys()): | |
| W = np.asarray(teacher_params[k]) | |
| res = C.TensorRoll(W, 0, depth, rank, quantum_policy, | |
| qsim_encode=Q.qsim_encode_for_roll | |
| if quantum_policy != "off" else None, | |
| name=k) | |
| trees[k] = res["tree"] | |
| for leaf in C.iter_leaves(res["tree"]): | |
| if stats and k in stats: | |
| leaf.metrics["act_rms"] = stats[k]["act_rms"] | |
| leaf.metrics["grad_norm"] = stats[k]["grad_norm"] | |
| leaf.metrics["grad_rel"] = stats[k]["grad_rel"] | |
| leaves.append(leaf) | |
| return trees, leaves | |