Files
evil_MoE/src/vgrout/train_config.py
T
wassnameandClaudypoo b53043cec3 refactor: extract train_config.py + run_artifacts.py from train.py; slim results scripts
Cleanup by a prior agent, verified green here: 'just smoke' (erase arm)
runs end-to-end and all four wired gates pass (verify_rewards 52/52,
verify_eval_gap, verify_partition, verify_science_invariants).

- train.py -318 lines: Config dataclass -> train_config.py, checkpoint/
  deploy-artifact IO -> run_artifacts.py.
- results.py / results_deploy.py / probe_distill.py slimmed.
- drop stale derived csvs under out/figs (a5_generalisation, dyn_*,
  substrate_aggregate, train_vs_deploy_60).
- gitignore /.pi/ panel scratch.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-09 13:34:50 +00:00

115 lines
3.1 KiB
Python

"""Typed CLI configuration for train.py."""
from __future__ import annotations
from dataclasses import dataclass
from pathlib import Path
from typing import Literal
from .rewards import EnvMode
@dataclass(kw_only=True)
class Config:
intervention: Literal["none", "erase", "routeV"] = "erase"
adapter: Literal["antipasto", "lora_frozen_b"] = "antipasto"
lora_r: int = 32
lora_b_seed: int = 0
model: str = "Qwen/Qwen3-4B"
steps: int = 100
group: int = 6
max_new: int = 1024
n_problems: int = 992
beta: float = 0.0
prompts_per_step: int = 8
lr: float = 7e-5
adam_beta1: float = 0.9
adam_beta2: float = 0.99
clip: float = 0.2
weight_decay: float = 0.1
warmup_frac: float = 0.1
grad_clip: float = 10.0
seed: int = 41
unbiased: bool = True
preserve_magnitude: bool = True
gate_mode: Literal["one_sided", "no_gate", "reverse"] = "one_sided"
project_overshoot: float = 1.0
v_hack_path: Path | None = None
v_hack_extract_top_k: int = 12
v_hack_k: int = 5
v_hack_tau_axis: float = 0.0
v_hack_drop_bottom_frac: float = 0.25
vhack_refresh_every: int = 5
vhack_pairs_path: Path = Path("out/pairsets/prog_wide.json")
routeV_random_v_seed: int | None = None
routeV_per_token: bool = False
routeV_gate: Literal["grad_cosine", "act_vote", "online_stats"] = "grad_cosine"
routeV_absorb_all: bool = False
online_stats_lo: float = 0.05
online_stats_hi: float = 0.95
rollout_ablate_frac: float = 0.0
env_mode: EnvMode = "run_tests"
unhackable_frac: float = 0.0
teacher_pool_dir: Path | None = None
mix_ratio: float = 0.125
teacher_off_step: int | None = 30
teacher_modes: tuple[str, ...] | None = None
eval_ablate_every: int = 0
eval_n_prompts: int = 32
eval_batch_size: int = 2
save_ckpt_every: int = 10
cos_pre_split_every: int = 1
half_a: str = ""
out_tag: str = ""
@property
def preset_name(self) -> str:
return type(self).__name__.removesuffix("Config").lower() or "base"
@property
def arm(self) -> str:
return {"none": "vanilla", "erase": "projected", "routeV": "routingV"}[self.intervention]
@dataclass(kw_only=True)
class SmokeConfig(Config):
model: str = "llamafactory/tiny-random-qwen3"
steps: int = 30
group: int = 4
max_new: int = 32
n_problems: int = 100
beta: float = 0.0
prompts_per_step: int = 1
@dataclass(kw_only=True)
class FastConfig(Config):
model: str = "Qwen/Qwen3-4B"
steps: int = 60
teacher_pool_dir: Path | None = Path("out/pools/teacher_pool_runtests_dense")
vhack_pairs_path: Path = Path("out/pairsets/prog_wide.json")
grad_clip: float = 500.0
group: int = 8
max_new: int = 512
n_problems: int = 200
beta: float = 0.0
prompts_per_step: int = 4
lr: float = 3e-3
adam_beta1: float = 0.5
adam_beta2: float = 0.9
@dataclass(kw_only=True)
class FullConfig(Config):
model: str = "Qwen/Qwen3-4B"
steps: int = 200
group: int = 4
max_new: int = 1536
n_problems: int = 992
beta: float = 1e-3
prompts_per_step: int = 64