"""Match donor capture to generation prefill, including the final layer before normalization.""" import importlib.util import json import re from pathlib import Path import torch from huggingface_hub import HfApi, hf_hub_download from peft import PeftModel from transformers import AutoModelForCausalLM, AutoTokenizer REPO = "itsalissonsilva/Restriction-Learning-Experiment" REVISION = "3a3cb6bef28c71ffc822f0a68645e2adc4b6aed2" ADAPTER_REVISION = "efc3f02e5775d3d8428b4961f1fd94aedc6ca34f" def main(): torch.manual_seed(1729) source = hf_hub_download(REPO, "train_restriction_pilot.py", revision=ADAPTER_REVISION) spec = importlib.util.spec_from_file_location("helper", source) helper = importlib.util.module_from_spec(spec) spec.loader.exec_module(helper) report = json.loads( Path(hf_hub_download(REPO, "interpretability/results.json", revision=REVISION)).read_text() ) tokenizer = AutoTokenizer.from_pretrained(helper.BASE, revision=helper.REVISION) tokenizer.padding_side = "left" base = AutoModelForCausalLM.from_pretrained( helper.BASE, revision=helper.REVISION, torch_dtype=torch.bfloat16, attn_implementation="eager", ).to("cuda") model = PeftModel.from_pretrained( base, REPO, subfolder="selective", revision=ADAPTER_REVISION ).eval() layers = [(n, m) for n, m in model.named_modules() if re.search(r"\.layers\.\d+$", n)] private = report["patch_pairs"]["private"] public = report["patch_pairs"]["public"] @torch.no_grad() def generate(rows, max_tokens=80): inputs = tokenizer( [helper.render_prompt(tokenizer, r) for r in rows], padding=True, return_tensors="pt" ).to("cuda") generated = model.generate( **inputs, max_new_tokens=max_tokens, do_sample=False, pad_token_id=tokenizer.pad_token_id, ) texts = tokenizer.batch_decode( generated[:, inputs["input_ids"].shape[1] :], skip_special_tokens=True ) return [helper.grading(r, t) for r, t in zip(rows, texts, strict=True)] def capture(rows): stored = {} handles = [] for i, (_, layer) in enumerate(layers): def hook(module, args, output, index=i): h = output[0] if isinstance(output, tuple) else output if h.shape[1] > 1: stored[index] = h[:, -1].detach().clone() handles.append(layer.register_forward_hook(hook)) try: generate(rows, 1) finally: for handle in handles: handle.remove() assert len(stored) == 26 return stored hp, hc = capture(private), capture(public) baseline = generate(private) result = dict( source_revision=REVISION, source_patch_exclusion_reason="Earlier capture used ordinary forward position IDs and post-normalized final hidden state; superseded by identical generation-prefill hooks at every patch site", patching=[], patch_pairs=dict( private=private, public=public, baseline_private=baseline, baseline_public=generate(public), ), seed=1729, ) for layer in range(26): delta = hc[layer].float() - hp[layer].float() noise = torch.randn_like(delta) noise *= delta.norm(dim=1, keepdim=True) / noise.norm(dim=1, keepdim=True).clamp_min(1e-20) for donor_kind, donor in [ ("public", hc[layer]), ("self_restoration", hp[layer]), ("random_norm_matched", hp[layer] + noise.to(hp[layer].dtype)), ]: def patch(module, args, output): h = output[0] if isinstance(output, tuple) else output if h.shape[1] <= 1: return output replacement = h.clone() replacement[:, -1] = donor return (replacement, *output[1:]) if isinstance(output, tuple) else replacement handle = layers[layer][1].register_forward_hook(patch) try: outputs = generate(private) finally: handle.remove() matches = sum(o["raw"] == b["raw"] for o, b in zip(outputs, baseline, strict=True)) if donor_kind == "self_restoration": assert matches == 8, (layer, matches) result["patching"].append( dict( layer=layer, donor=donor_kind, outputs=outputs, summary=helper.summarize(private, outputs), raw_matches_private_baseline=matches, ) ) print( json.dumps(dict(stage="patching", layer=layer, self_restoration_matches=8)), flush=True ) assert generate(private) == baseline folder = Path("patchfix") folder.mkdir(exist_ok=True) (folder / "patching.json").write_text(json.dumps(result, indent=2)) (folder / "train_interpretability_patchfix_pilot.py").write_bytes(Path(__file__).read_bytes()) HfApi().upload_folder( repo_id=REPO, folder_path=str(folder), path_in_repo="interpretability_patchfix", commit_message="Correct donor capture to exact generation-prefill patch sites; verify all 26 self-restorations", ) print(json.dumps(dict(stage="complete", layers=26, self_restoration_matches=208)), flush=True) if __name__ == "__main__": main()