mirror of
https://github.com/wassname/evil_MoE.git
synced 2026-08-03 12:50:20 +08:00
results tooling + solve-orth knob + results-by-question doc
- scripts/results.py + `just results`: aggregate logs/*.log into last-5 hack_s and gt_s (solve) tables, sorted-by-time + grouped-by-config, with full argv provenance column. Filters smoke/probe runs. - extract_vhack_grad: solve_orth_m knob — strip top-m known-solve subspace (SVD of clean-side grads) from D before SVD, so projection doesn't ablate the solve signal. No grader/oracle, off by default. - docs/results.md: every experiment grouped by the question it answers (feasibility, H1, gate_mode, basis, refresh, mix, noise-floor, pair-set) with comparison tables and answers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
826b2aa83e
commit
4464f9d312
@@ -79,6 +79,12 @@ class Config:
|
||||
# outlier pairs and doesn't waste rank on noise. Saved with k=1 -- train.py
|
||||
# load_v_hack reads it the same way as SVD output.
|
||||
mean_diff: bool = False
|
||||
# solve_orth_m: if >0, strip the top-m "solve" directions (SVD of the clean-
|
||||
# side gradients G_c, = grads toward our known-good hand-written solutions)
|
||||
# out of D before extracting v_hack. 0 = off. Aims to keep the projection
|
||||
# from ablating the legitimate solve signal (pass-rate selectivity). No
|
||||
# grader/oracle is read — only the clean solutions we wrote.
|
||||
solve_orth_m: int = 0
|
||||
|
||||
|
||||
def resolve_dtype(s: str) -> torch.dtype:
|
||||
@@ -110,6 +116,7 @@ def extract_v_hack(
|
||||
n_heldout: int,
|
||||
device,
|
||||
mean_diff: bool = False,
|
||||
solve_orth_m: int = 0,
|
||||
) -> tuple[
|
||||
dict[str, Float[torch.Tensor, "k r"]],
|
||||
dict[str, Float[torch.Tensor, "k"]],
|
||||
@@ -177,6 +184,21 @@ def extract_v_hack(
|
||||
G_c = torch.stack(grads_clean[name])
|
||||
D = G_h - G_c
|
||||
|
||||
if solve_orth_m > 0:
|
||||
# Strip the known-solve subspace from D before extracting hack
|
||||
# directions. B = top-m right singular vectors of G_c (the gradient
|
||||
# toward our hand-written *correct* clean solutions = the "solve"
|
||||
# direction; no grader/oracle used, just known-good solutions).
|
||||
# D = G_h - G_c already carries -G_c, so the solve directions have
|
||||
# real energy in D; removing them keeps projection from also
|
||||
# ablating the solve signal (pass-rate selectivity). The SVD below
|
||||
# then returns hack directions orthogonal to solve, still
|
||||
# orthonormal, so S/orientation/noise-floor logic is unchanged.
|
||||
m = min(solve_orth_m, G_c.shape[0])
|
||||
_, _, Bh = torch.linalg.svd(G_c, full_matrices=False)
|
||||
B = Bh[:m] # [m, r], orthonormal solve basis
|
||||
D = D - (D @ B.T) @ B # D_perp
|
||||
|
||||
if mean_diff:
|
||||
# Rank-1 mean-diff direction. Honest under small N: SVD axes 2..k on
|
||||
# N=12 pairs fit noise; mean-diff regularizes to the only direction
|
||||
@@ -276,6 +298,7 @@ def main(cfg: Config) -> int:
|
||||
top_k=cfg.top_k, tau_axis=cfg.tau_axis,
|
||||
n_heldout=cfg.n_heldout, device=device,
|
||||
mean_diff=cfg.mean_diff,
|
||||
solve_orth_m=cfg.solve_orth_m,
|
||||
)
|
||||
n_zero = sum(1 for v in v_hack.values() if v.norm() < 1e-12)
|
||||
k = 1 if cfg.mean_diff else min(cfg.top_k, len(train_pairs))
|
||||
|
||||
Reference in New Issue
Block a user