Archive CIDM-v2 reproducible b2_r9_activation_timing.py
Browse files
cidm_v2/source/B2_R9_P0/b2_r9_activation_timing.py
ADDED
|
@@ -0,0 +1,295 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""CIDM-v2 B2-R9/P0: causal activation timing under equal per-step or total RMS-energy.
|
| 2 |
+
|
| 3 |
+
Frozen original backbone and pretrained B2-R6 heads; ground truth enters ONLY scoring.
|
| 4 |
+
The fixed lead-dependent schedules are retrospective ablations, NOT a learned controller
|
| 5 |
+
or a validated deployment policy. All B0 checkpoint selection predates this study.
|
| 6 |
+
"""
|
| 7 |
+
from __future__ import annotations
|
| 8 |
+
import csv,hashlib,io,json,math,zipfile
|
| 9 |
+
from pathlib import Path
|
| 10 |
+
import torch
|
| 11 |
+
from benchmark import Config,Windows,UnifiedModel,make_synthetic_cache
|
| 12 |
+
from b2_r1_flux_control import check_zip
|
| 13 |
+
from b2_r6_causal_spatial_controller import sha,make_cache_checked,orthogonal_matrix,effect_basis,TASK_LIST,LEADS
|
| 14 |
+
from b2_r7_frozen_controller_gain_audit import load_heads,write_csv,write_json
|
| 15 |
+
from b2_r8_equal_exposure_audit import (validate_r7,validate_r6,rollout_budget,
|
| 16 |
+
R6_REAL_ZIP_SHA,R7_REAL_ZIP_SHA,PARENT_SHA)
|
| 17 |
+
|
| 18 |
+
R8_REAL_ZIP_SHA='ad8334d8ac0632ccd29965305bc613d6628fdcc89b34906ba30ca64604947159'
|
| 19 |
+
PRIMARY_BUDGET=.003
|
| 20 |
+
SECONDARY_BUDGET=.001
|
| 21 |
+
ONSETS=(1,4,7)
|
| 22 |
+
STEPS=12
|
| 23 |
+
VAL_INDICES=list(range(16,32))
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def validate_r8(archive):
|
| 27 |
+
if sha(archive)!=R8_REAL_ZIP_SHA:raise RuntimeError('B2_R8_REAL_ZIP_SHA_MISMATCH')
|
| 28 |
+
with zipfile.ZipFile(archive) as z:
|
| 29 |
+
if z.testzip():raise RuntimeError('B2_R8_ZIP_CRC_FAIL')
|
| 30 |
+
rep=json.loads(z.read('report.json'))
|
| 31 |
+
if rep.get('status')!='FROZEN_EQUAL_RMS_AUDIT_COMPLETED_NO_TRAINING':
|
| 32 |
+
raise RuntimeError('B2_R8_NOT_FROZEN_AUDIT_COMPLETE')
|
| 33 |
+
if set(x['task'] for x in rep.get('cases',[]))!=set(TASK_LIST):
|
| 34 |
+
raise RuntimeError('B2_R8_NOT_THREE_TASKS')
|
| 35 |
+
manifest=json.loads(z.read('FILE_SHA256_MANIFEST.json'))
|
| 36 |
+
for ent in manifest:
|
| 37 |
+
if hashlib.sha256(z.read(ent['path'])).hexdigest()!=ent['sha256']:
|
| 38 |
+
raise RuntimeError('B2_R8_INNER_SHA_MISMATCH '+ent['path'])
|
| 39 |
+
rows=list(csv.DictReader(io.StringIO(z.read('sample_mse.csv').decode())))
|
| 40 |
+
if len(rows)!=5040:raise RuntimeError('B2_R8_EXPECTED_5040_SAMPLES')
|
| 41 |
+
per={(row['task'],int(row['window_index']),row['method'],int(row['lead'])):float(row['mse_physical']) for row in rows}
|
| 42 |
+
return rep,per
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
def rms(x):
|
| 46 |
+
return x.square().mean(dim=(1,2,3),keepdim=True).sqrt()
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
def spec_name(kind,budget,onset,mode):
|
| 50 |
+
if kind=='baseline':return 'baseline'
|
| 51 |
+
return f'{kind}__b{budget*100:.3f}pct__onset{onset}__{mode}'
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
def schedule_fraction(budget,onset,mode):
|
| 55 |
+
if mode=='fixed_step' or onset==1:return float(budget)
|
| 56 |
+
if mode=='matched_energy':return float(budget)*math.sqrt(STEPS/(STEPS-onset+1))
|
| 57 |
+
raise ValueError(mode)
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
@torch.no_grad()
|
| 61 |
+
def rollout_timing(core,head,h,*,Q=None,rotate=False,budget=.003,onset=1,mode='fixed_step'):
|
| 62 |
+
mm=core.model;one_d=(h.ndim==4)
|
| 63 |
+
hh=h.unsqueeze(-2) if one_d else h
|
| 64 |
+
B,L,C,H,W=hh.shape;coeff=mm.coefficients()
|
| 65 |
+
z=mm.encode(hh.reshape(B,L*C,H,W));prev=hh[:,-1];initial=prev
|
| 66 |
+
skew=mm.skew-mm.skew.T
|
| 67 |
+
preds=[]; per_lead={}; exposure=hh.new_zeros((B,));min_raw=float('inf')
|
| 68 |
+
step_fraction=schedule_fraction(budget,onset,mode)
|
| 69 |
+
for lead in range(1,STEPS+1):
|
| 70 |
+
f=coeff['flux']*mm.flux(z)
|
| 71 |
+
l=coeff['local']*torch.tanh(mm.local(z))
|
| 72 |
+
s=.035*torch.einsum('ij,bjhw->bihw',skew,z)
|
| 73 |
+
base=z+f+l+s
|
| 74 |
+
if head is None or lead<onset:
|
| 75 |
+
change=torch.zeros_like(base);rel=base.new_zeros((B,))
|
| 76 |
+
coeff_abs=base.new_zeros((B,));inactive=base.new_zeros((B,))
|
| 77 |
+
else:
|
| 78 |
+
basis,amps=effect_basis(f,l,s,Q if rotate else None)
|
| 79 |
+
gates=head(base,prev,initial,amps,lead)
|
| 80 |
+
raw=(gates.unsqueeze(2)*basis).sum(dim=1)/math.sqrt(3)
|
| 81 |
+
rr=rms(raw)
|
| 82 |
+
active=(rr>=1e-9)
|
| 83 |
+
change=step_fraction*rms(base).clamp_min(1e-4)*raw/rr.clamp_min(1e-9)
|
| 84 |
+
change=torch.where(active,change,torch.zeros_like(change))
|
| 85 |
+
rel=(rms(change)/rms(base).clamp_min(1e-4)).flatten()
|
| 86 |
+
coeff_abs=gates.abs().mean(dim=(1,2,3))
|
| 87 |
+
inactive=(~active).flatten().float()
|
| 88 |
+
if active.any():
|
| 89 |
+
mismatch=(rel[active.flatten()]-step_fraction).abs().max().item()
|
| 90 |
+
if mismatch>max(1e-6,step_fraction*2e-3):
|
| 91 |
+
raise RuntimeError('R9_PER_SAMPLE_EXPOSURE_CONTRACT_FAIL '+str(mismatch))
|
| 92 |
+
exposure=exposure+rel.square()
|
| 93 |
+
z=base+change
|
| 94 |
+
out=prev+coeff['out']*torch.tanh(mm.decode(z));prev=out
|
| 95 |
+
preds.append(out.squeeze(-2) if one_d else out)
|
| 96 |
+
if lead in LEADS:
|
| 97 |
+
per_lead[lead]={'rel':rel.detach().cpu(),'coef':coeff_abs.detach().cpu(),
|
| 98 |
+
'inactive':inactive.detach().cpu(), 'cum_energy':exposure.detach().cpu()}
|
| 99 |
+
return torch.stack(preds,1),per_lead
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
def specs_for(smoke):
|
| 103 |
+
budgets=(PRIMARY_BUDGET,) if smoke else (SECONDARY_BUDGET,PRIMARY_BUDGET)
|
| 104 |
+
specs=[('baseline',None,0.,1,'fixed_step')]
|
| 105 |
+
for kind in ('operator','rotated'):
|
| 106 |
+
for budget in budgets:
|
| 107 |
+
for onset in ONSETS:
|
| 108 |
+
modes=('fixed_step',) if onset==1 else ('fixed_step','matched_energy')
|
| 109 |
+
for mode in modes:specs.append((spec_name(kind,budget,onset,mode),kind,budget,onset,mode))
|
| 110 |
+
return specs
|
| 111 |
+
|
| 112 |
+
|
| 113 |
+
@torch.no_grad()
|
| 114 |
+
def evaluate(core,heads,Q,val,indices,device,*,smoke=False):
|
| 115 |
+
specs=specs_for(smoke);rows=[];curves=[];totals={name:{lead:[0.,0] for lead in LEADS} for name,*_ in specs}
|
| 116 |
+
diag={name:{lead:[0.,0.,0.,0.,0.] for lead in LEADS} for name,*_ in specs}
|
| 117 |
+
assert set(indices)==(set([0,1]) if smoke else set(VAL_INDICES))
|
| 118 |
+
parity_max=0.;prefix_parity_max=0.;exposure_maxdiff=0.
|
| 119 |
+
for ix in range(0,len(indices),2):
|
| 120 |
+
ids=indices[ix:ix+2];arr=[val[int(i)] for i in ids]
|
| 121 |
+
h=torch.stack([a[0] for a in arr]).to(device)
|
| 122 |
+
truth=torch.stack([a[1] for a in arr]).to(device)
|
| 123 |
+
scale=val.sd.to(device).reshape(1,-1,*([1]*(truth.ndim-3)))
|
| 124 |
+
pred_baseline,base_diag=rollout_timing(core,None,h)
|
| 125 |
+
all_preds={'baseline':(pred_baseline,base_diag)}
|
| 126 |
+
for name,kind,budget,onset,mode in specs[1:]:
|
| 127 |
+
p,d=rollout_timing(core,heads[kind],h,Q=Q,rotate=(kind=='rotated'),budget=budget,onset=onset,mode=mode)
|
| 128 |
+
all_preds[name]=(p,d)
|
| 129 |
+
if onset>1:
|
| 130 |
+
prefix_parity_max=max(prefix_parity_max,float((p[:,:onset-1]-pred_baseline[:,:onset-1]).abs().max()))
|
| 131 |
+
for name,kind,budget,onset,mode in specs:
|
| 132 |
+
pred,dd=all_preds[name]
|
| 133 |
+
for lead in LEADS:
|
| 134 |
+
loss=((pred[:,lead-1]-truth[:,lead-1])*scale).square().flatten(1).mean(1)
|
| 135 |
+
totals[name][lead][0]+=float(loss.sum());totals[name][lead][1]+=len(ids)
|
| 136 |
+
for window,loss_value in zip(ids,loss.cpu().tolist()):
|
| 137 |
+
rows.append({'task':'','window_index':int(window),'method':name,
|
| 138 |
+
'lead':int(lead),'mse_physical':float(loss_value)})
|
| 139 |
+
if kind is not None:
|
| 140 |
+
v=dd[lead];acc=diag[name][lead]
|
| 141 |
+
acc[0]+=float(v['rel'].sum());acc[1]+=float(v['coef'].sum())
|
| 142 |
+
acc[2]+=float(v['inactive'].sum());acc[3]+=float(v['cum_energy'].sum());acc[4]+=len(ids)
|
| 143 |
+
# Compare Natural v Rotated realized step budget and integral exposure.
|
| 144 |
+
for budget in ((PRIMARY_BUDGET,) if smoke else (SECONDARY_BUDGET,PRIMARY_BUDGET)):
|
| 145 |
+
for onset in ONSETS:
|
| 146 |
+
for mode in (('fixed_step',) if onset==1 else ('fixed_step','matched_energy')):
|
| 147 |
+
n=all_preds[spec_name('operator',budget,onset,mode)][1]
|
| 148 |
+
r=all_preds[spec_name('rotated',budget,onset,mode)][1]
|
| 149 |
+
for lead in LEADS:
|
| 150 |
+
exposure_maxdiff=max(exposure_maxdiff,float((n[lead]['rel']-r[lead]['rel']).abs().max()))
|
| 151 |
+
if prefix_parity_max>1e-6:raise RuntimeError('B2_R9_ZERO_PREFIX_NOT_IDENTICAL '+str(prefix_parity_max))
|
| 152 |
+
if exposure_maxdiff>2e-6:raise RuntimeError('B2_R9_NAT_ROT_NOT_EXPOSURE_MATCHED '+str(exposure_maxdiff))
|
| 153 |
+
for name,kind,b,onset,mode in specs:
|
| 154 |
+
for lead in LEADS:
|
| 155 |
+
sm,n=totals[name][lead];bm,bn=totals['baseline'][lead]
|
| 156 |
+
a=diag[name][lead]
|
| 157 |
+
curves.append({'task':'','method':name,'lead':lead,'mse_physical':sm/n,
|
| 158 |
+
'ratio_to_baseline':(sm/n)/(bm/bn),
|
| 159 |
+
'realized_rel_rms':a[0]/max(a[4],1),
|
| 160 |
+
'cumulative_rms_energy':a[3]/max(a[4],1),
|
| 161 |
+
'gate_abs_mean':a[1]/max(a[4],1),
|
| 162 |
+
'inactive_fraction':a[2]/max(a[4],1),
|
| 163 |
+
'onset':onset,'mode':mode,'registered_budget':b})
|
| 164 |
+
return curves,rows,{'zero_prefix_max':prefix_parity_max,'exposure_difference_max':exposure_maxdiff,'num_windows':len(indices)}
|
| 165 |
+
|
| 166 |
+
|
| 167 |
+
def compare_r8_replay(samples,archive_ref,task,smoke=False):
|
| 168 |
+
if smoke:return 0.
|
| 169 |
+
got={(int(r['window_index']),r['method'],int(r['lead'])):float(r['mse_physical']) for r in samples}
|
| 170 |
+
checks=[]
|
| 171 |
+
for window in VAL_INDICES:
|
| 172 |
+
for lead in LEADS:
|
| 173 |
+
names={'baseline':'baseline'}
|
| 174 |
+
for b in (SECONDARY_BUDGET,PRIMARY_BUDGET):
|
| 175 |
+
for k in ('operator','rotated'):
|
| 176 |
+
names[spec_name(k,b,1,'fixed_step')]=f'{k}__b{b*100:.3f}pct__s+1'
|
| 177 |
+
for current,archived in names.items():
|
| 178 |
+
v=got[(window,current,lead)];ref=archive_ref[(task,window,archived,lead)]
|
| 179 |
+
diff=abs(v-ref)
|
| 180 |
+
if diff>max(1e-8,abs(ref)*0.003):
|
| 181 |
+
raise RuntimeError(f'B2_R8_WINDOW_REPLAY_MISMATCH {task}/{window}/{current}/{lead} {v} {ref}')
|
| 182 |
+
checks.append(diff)
|
| 183 |
+
return max(checks)
|
| 184 |
+
|
| 185 |
+
|
| 186 |
+
def summarize_risk(samples,task,budget=PRIMARY_BUDGET):
|
| 187 |
+
lookup={(int(r['window_index']),r['method'],int(r['lead'])):float(r['mse_physical']) for r in samples}
|
| 188 |
+
output=[]
|
| 189 |
+
for onset in ONSETS:
|
| 190 |
+
for mode in (('fixed_step',) if onset==1 else ('fixed_step','matched_energy')):
|
| 191 |
+
natural=spec_name('operator',budget,onset,mode);rot=spec_name('rotated',budget,onset,mode)
|
| 192 |
+
for lead in (1,3,9,12):
|
| 193 |
+
ids=VAL_INDICES
|
| 194 |
+
base=[lookup[i,'baseline',lead] for i in ids]
|
| 195 |
+
n=[lookup[i,natural,lead] for i in ids];r=[lookup[i,rot,lead] for i in ids]
|
| 196 |
+
floor=max(1e-12,sum(base)/len(base)*1e-4)
|
| 197 |
+
sample_ratios=sorted(a/max(b,floor) for a,b in zip(n,base))
|
| 198 |
+
output.append({'task':task,'onset':onset,'mode':mode,'lead':lead,
|
| 199 |
+
'natural_vs_baseline_ratio':sum(n)/sum(base),
|
| 200 |
+
'rotated_vs_baseline_ratio':sum(r)/sum(base),
|
| 201 |
+
'natural_win_rate':sum(a<b for a,b in zip(n,base))/len(base),
|
| 202 |
+
'natural_beats_rotated_rate':sum(a<b for a,b in zip(n,r))/len(base),
|
| 203 |
+
'natural_regression_over_2pct':sum(a>b*1.02+floor for a,b in zip(n,base))/len(base),
|
| 204 |
+
'sample_ratio_p90':sample_ratios[math.ceil(.9*len(sample_ratios))-1],
|
| 205 |
+
'floor':floor})
|
| 206 |
+
return output
|
| 207 |
+
|
| 208 |
+
|
| 209 |
+
def gate_task(curves,risk,task):
|
| 210 |
+
arr={r['method']:{'first':r} for r in []} # placeholder-free: explicit indexed curve lookup below
|
| 211 |
+
refs={(r['method'],int(r['lead'])):r for r in curves}
|
| 212 |
+
signals=[]
|
| 213 |
+
for onset in ONSETS:
|
| 214 |
+
for mode in (('fixed_step',) if onset==1 else ('fixed_step','matched_energy')):
|
| 215 |
+
n=spec_name('operator',PRIMARY_BUDGET,onset,mode)
|
| 216 |
+
r=spec_name('rotated',PRIMARY_BUDGET,onset,mode)
|
| 217 |
+
late_n=sum(refs[n,ld]['mse_physical'] for ld in (9,12));late_r=sum(refs[r,ld]['mse_physical'] for ld in (9,12))
|
| 218 |
+
late_base=sum(refs['baseline',ld]['mse_physical'] for ld in (9,12))
|
| 219 |
+
early=max(refs[n,ld]['ratio_to_baseline'] for ld in (1,3))
|
| 220 |
+
tail=max(v['natural_regression_over_2pct'] for v in risk if v['onset']==onset and v['mode']==mode and v['lead'] in (9,12))
|
| 221 |
+
gain_base=100*(1-late_n/late_base);gain_rot=100*(1-late_n/late_r)
|
| 222 |
+
# Conditional diagnostic gate only. Even success does NOT authorize training without outer holdout.
|
| 223 |
+
pass_signal=(gain_base>=1.5 and gain_rot>=1.0 and early<=1.005 and tail<=.2)
|
| 224 |
+
signals.append({'onset':onset,'mode':mode,'late_gain_over_base_pct':gain_base,
|
| 225 |
+
'late_gain_over_rotated_pct':gain_rot,'early_max_ratio':early,
|
| 226 |
+
'worst_late_window_regression_fraction':tail,'candidate_diagnostic_pass':bool(pass_signal)})
|
| 227 |
+
return {'task':task,'decisions':signals,'any_diagnostic_candidate':any(v['candidate_diagnostic_pass'] for v in signals)}
|
| 228 |
+
|
| 229 |
+
|
| 230 |
+
def run(parent,r6zip,r7zip,r8zip,work,output,*,smoke=False,device='cpu'):
|
| 231 |
+
work=Path(work);output=Path(output);work.mkdir(parents=True,exist_ok=True);output.mkdir(parents=True,exist_ok=True)
|
| 232 |
+
validate_r6(r6zip);r7_report,_=validate_r7(r7zip);_,r8_ref=validate_r8(r8zip)
|
| 233 |
+
all_curves=[];all_samples=[];all_risks=[];cases=[];gate=[]
|
| 234 |
+
if smoke:
|
| 235 |
+
cfg=Config(profile='smoke');s1=make_synthetic_cache(cfg)
|
| 236 |
+
for sp in ('train','val','test'):
|
| 237 |
+
s1['splits'][sp]['h']=s1['splits'][sp]['h'].mean(dim=-2)
|
| 238 |
+
s1['splits'][sp]['y']=s1['splits'][sp]['y'].mean(dim=-2)
|
| 239 |
+
inputs=[('smoke_1d',s1),('smoke_2d',make_synthetic_cache(cfg))]
|
| 240 |
+
for name,cache in inputs:
|
| 241 |
+
core=UnifiedModel('V2_Ported_R5',1,8,12,4).to(device).eval().requires_grad_(False)
|
| 242 |
+
hch=1;heads=load_heads(r6zip,'burgers_1d' if name=='smoke_1d' else 'swe_2d',hch,device)
|
| 243 |
+
Q=orthogonal_matrix(int(core.model.skew.shape[0]),32207,device,torch.float32)
|
| 244 |
+
val=Windows(cache['splits']['val']['h'],cache['splits']['val']['y'],cache['mean'],cache['std'])
|
| 245 |
+
cur,smp,checks=evaluate(core,heads,Q,val,[0,1],device,smoke=True)
|
| 246 |
+
for row in cur:row['task']=name
|
| 247 |
+
for row in smp:row['task']=name
|
| 248 |
+
all_curves+=cur;all_samples+=smp;cases.append({'task':name,**checks})
|
| 249 |
+
status='PROGRAM_ONLY_SMOKE_NO_SCIENCE'
|
| 250 |
+
else:
|
| 251 |
+
if parent is None or sha(parent)!=PARENT_SHA:raise RuntimeError('MISSING_EXACT_B0_18_RUN_PARENT')
|
| 252 |
+
with zipfile.ZipFile(parent) as z:
|
| 253 |
+
m,contract=check_zip(z);cfg=Config(**m['config'])
|
| 254 |
+
for task in TASK_LIST:
|
| 255 |
+
core,cache,replay=make_cache_checked(task,z,cfg,work,device)
|
| 256 |
+
original=next(v for v in r7_report['tasks'] if v['task']==task)
|
| 257 |
+
if replay['checkpoint_sha256']!=original['replay']['checkpoint_sha256']:
|
| 258 |
+
raise RuntimeError('R9_PARENT_CHECKPOINT_CHANGED '+task)
|
| 259 |
+
val=Windows(cache['splits']['val']['h'],cache['splits']['val']['y'],cache['mean'],cache['std'])
|
| 260 |
+
heads=load_heads(r6zip,task,int(cache['splits']['val']['h'].shape[2]),device)
|
| 261 |
+
Q=orthogonal_matrix(int(core.model.skew.shape[0]),32207,device,torch.float32)
|
| 262 |
+
cur,smp,checks=evaluate(core,heads,Q,val,VAL_INDICES,device)
|
| 263 |
+
maxdelta=compare_r8_replay(smp,r8_ref,task)
|
| 264 |
+
for row in cur:row['task']=task
|
| 265 |
+
for row in smp:row['task']=task
|
| 266 |
+
risks=summarize_risk(smp,task)
|
| 267 |
+
local_gate=gate_task(cur,risks,task)
|
| 268 |
+
all_curves+=cur;all_samples+=smp;all_risks+=risks;gate.append(local_gate)
|
| 269 |
+
cases.append({'task':task,'replay':replay,'parity_vs_b2r8_max_mse_diff':maxdelta,**checks})
|
| 270 |
+
write_csv(output/'activation_lead_curves.csv',all_curves)
|
| 271 |
+
write_csv(output/'paired_window_mse.csv',all_samples)
|
| 272 |
+
write_csv(output/'paired_risk.csv',all_risks)
|
| 273 |
+
write_json(output/'progress.json',{'completed_tasks':[v['task'] for v in cases]})
|
| 274 |
+
if len(cases)!=3 or len(all_curves)!=(3*len(specs_for(False))*len(LEADS)):
|
| 275 |
+
raise RuntimeError('B2_R9_INCOMPLETE_OFFICIAL_COVERAGE')
|
| 276 |
+
status='FROZEN_ACTIVATION_TIMING_COMPLETED_NO_TRAINING'
|
| 277 |
+
write_csv(output/'activation_lead_curves.csv',all_curves)
|
| 278 |
+
write_csv(output/'paired_window_mse.csv',all_samples)
|
| 279 |
+
write_csv(output/'paired_risk.csv',all_risks)
|
| 280 |
+
write_json(output/'timing_gate.json',{'status':'DIAGNOSTIC_ONLY','registered_primary_budget':PRIMARY_BUDGET,
|
| 281 |
+
'gates':gate,'no_training_authorized':True,'outer_holdout':False})
|
| 282 |
+
result={'experiment':'CIDM_v2_B2_R9_P0_CausalActivationTiming_EnergyMatched',
|
| 283 |
+
'status':status,'original_training_steps':0,'new_controller_training_steps':0,
|
| 284 |
+
'cases':cases,'total_curves':len(all_curves),'total_samples':len(all_samples),
|
| 285 |
+
'total_risks':len(all_risks),'onsets':list(ONSETS),
|
| 286 |
+
'budgets':[SECONDARY_BUDGET,PRIMARY_BUDGET],'primary_budget':PRIMARY_BUDGET,
|
| 287 |
+
'original_parent_sha256':PARENT_SHA,'r6_zip_sha256':R6_REAL_ZIP_SHA,
|
| 288 |
+
'r7_zip_sha256':R7_REAL_ZIP_SHA,'r8_zip_sha256':R8_REAL_ZIP_SHA,
|
| 289 |
+
'truth_used_for_actions':False,'used_val_selected_parent':True,
|
| 290 |
+
'outer_holdout':False,'schedules_are_deployment_eligible':False,
|
| 291 |
+
'notes':['Predetermined lead-based schedules are causal but not a trained issue-time gate.',
|
| 292 |
+
'Matched-energy onsets equalize sum of per-step squared relative perturbation budgets, not model response.',
|
| 293 |
+
'All losses are scored after 12-step autonomous rollout; no future labels are input to any action.']}
|
| 294 |
+
write_json(output/'report.json',result)
|
| 295 |
+
return result
|