File size: 7,797 Bytes
fe31b61 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | """Full-ontology confirmation with fixed candidates, controls and held bindings."""
from __future__ import annotations
import argparse,json,time
from pathlib import Path
import torch
from . import source,factorial,classifiers,learned_controls
ROOT=Path('artifacts/factorial_transfer_01');PROTOCOL=Path('configs/factorial_transfer_protocol_01.json')
MODELS=['additive_full','additive_diag','factorized_neural','joint_neural','factorized_nb','factorized_lda','factorized_kernel','factorized_ridge','joint_gaussian','factorized_logistic','factorized_classifier']
WORLD=['additive_full','additive_diag','factorized_neural','joint_neural','joint_gaussian']
def write(name,value):
p=ROOT/name;p.parent.mkdir(parents=True,exist_ok=True);p.write_text(json.dumps(value,indent=2)+'\n')
def verify():
lock=json.loads((ROOT/'confirmation_lock.json').read_text())
assert all(source.sha(p)==h for p,h in lock['files'].items())
def lock():
assert not (ROOT/'confirmation_lock.json').exists() and not (ROOT/'sources').exists();ROOT.mkdir(exist_ok=True)
previous=Path('artifacts/continuous_decision_01')
protected=json.loads((previous/'preservation_lock.json').read_text())['files']
for p in previous.rglob('*'):
if p.is_file() and '__pycache__' not in p.parts:protected[str(p)]=source.sha(p)
write('preservation_lock.json',dict(files=protected))
files=[*Path('unionmind/continuous_decision').glob('*.py'),PROTOCOL,Path('tests/test_continuous_decision.py')]
write('confirmation_lock.json',dict(files={str(p):source.sha(p) for p in files},
timestamp_utc=time.strftime('%Y-%m-%dT%H:%M:%SZ',time.gmtime()),
before_new_gas_archive_or_numerical_values=True,
hydraulic_is_opened_development=True,
candidate_and_all_thresholds_fixed=True))
print('FULL ONTOLOGY CONFIRMATION LOCKED',flush=True)
def prepare():
verify();config=json.loads(PROTOCOL.read_text());start=time.perf_counter();source.acquire(ROOT,config)
acquisition=time.perf_counter()-start;torch.cuda.set_device(config['device']);torch.backends.cuda.matmul.allow_tf32=False
source.prepare(ROOT,config,config['device'])
write('preparation_execution.json',dict(acquisition_seconds=acquisition,complete_seconds=time.perf_counter()-start))
verify()
def fit_one(x,h,sizes,name,seed,steps=400):
if name in WORLD:return factorial.world_fit(x,h,sizes,name,seed,steps)
if name in ('factorized_logistic','factorized_classifier'):return learned_controls.fit(x,h,sizes,name,seed,steps)
return classifiers.fit(x,h,sizes,name)
def predict(model,x,observed):
if model['kind'] in WORLD:return factorial.posterior(model,x,observed)
if model['kind'] in ('factorized_logistic','factorized_classifier'):return learned_controls.posterior(model,x,observed)
return classifiers.posterior(model,x,observed)
@torch.no_grad()
def metrics(prob,true,grid,h):
return dict(top1=factorial.topk_credit(prob,true,1),top3=factorial.topk_credit(prob,true,3),
deterministic_top1=(prob.argmax(-1)==true).double(),
deterministic_top3=(prob.topk(min(3,prob.shape[-1]),-1).indices==true[:,None]).any(-1).double(),
nll=-prob.gather(1,true[:,None]).squeeze(-1).clamp_min(1e-300).log(),
confidence=prob.max(-1).values,top3_mass=prob.topk(min(3,prob.shape[-1]),-1).values.sum(-1))
def run(device='cuda:1'):
verify();start=time.perf_counter();torch.cuda.set_device(device);torch.backends.cuda.matmul.allow_tf32=False
config=json.loads(PROTOCOL.read_text());manifest=json.loads((ROOT/'prepared/manifest.json').read_text())
results=[];timings=[];executions=[]
for si,series in enumerate(manifest['series']):
p=torch.load(ROOT/'prepared'/series['file'],map_location=device,weights_only=True)
if not series['primary_eligible']:
executions.append(dict(series=series['name'],eligible=False,reasons=series['exclusions']));continue
sizes=[len(v) for v in series['levels']];pool=torch.where(p['masks']['source'])[0]
held=torch.where(p['masks']['unseen']|p['masks']['seen'])[0]
true=factorial.joint_index(p['h'][held],sizes);grid=factorial.hypotheses(sizes,device)
for n in config['sample_budgets']:
if len(pool)<n:
executions.append(dict(series=series['name'],samples=n,eligible=False,reasons=['insufficient_source_prefix']));continue
for seed in config['sample_seeds']:
rng=torch.Generator(device=device).manual_seed(seed+si*101)
ids=pool[torch.randperm(len(pool),device=device,generator=rng)[:n]]
mean=p['x'][ids].mean(0);scale=p['x'][ids].std(0).clamp_min(1e-6)
torch.cuda.synchronize();prep_start=time.perf_counter()
x=(p['x'][ids]-mean)/scale;h=p['h'][ids];target=(p['x'][held]-mean)/scale
torch.cuda.synchronize();normalization_seconds=time.perf_counter()-prep_start
support=torch.ones(len(held),device=device,dtype=torch.bool)
for f,size in enumerate(sizes):support &= torch.bincount(h[:,f],minlength=size)[p['h'][held,f]]>0
for name in MODELS:
torch.cuda.synchronize();t=time.perf_counter()
model=fit_one(x,h,sizes,name,seed+si*101)
torch.cuda.synchronize();fit_seconds=time.perf_counter()-t
t=time.perf_counter()
with torch.no_grad():prob=predict(model,target,range(target.shape[-1]));values=metrics(prob,true,grid,p['h'][held])
torch.cuda.synchronize();prediction_seconds=time.perf_counter()-t
directory=ROOT/'models'/series['name']/f'n{n}_s{seed}';directory.mkdir(parents=True,exist_ok=True)
torch.save(dict(model=model,mean=mean,scale=scale,fit_ids=ids,sizes=sizes),directory/f'{name}.pt')
result=dict(series=series['name'],system=series['system'],samples=n,seed=seed,model=name,
held_rows=held,groups=p['groups'][held],unseen=p['masks']['unseen'][held],supported_levels=support,
metrics=values,fit_seconds=fit_seconds,prediction_seconds=prediction_seconds,
neural_parameters=model.get('neural_parameters',0),fit_ids=ids,
checkpoint_path=str(directory/f'{name}.pt'))
result.update(normalization_seconds=normalization_seconds,
checkpoint_bytes=(directory/f'{name}.pt').stat().st_size,
adaptation_fits=model.get('adaptation_fits',1))
results.append(result);timings.append({k:result[k] for k in ('series','samples','seed','model','fit_seconds','prediction_seconds','neural_parameters','normalization_seconds','checkpoint_bytes','adaptation_fits')})
print(json.dumps(dict(series=series['name'],samples=n,seed=seed,models=len(MODELS))),flush=True)
torch.save(dict(results=results,models=MODELS,manifest_eligibility=manifest['all_three_primary_eligible']),ROOT/'confirmation.pt')
write('confirmation_execution.json',dict(total_seconds=time.perf_counter()-start,device=device,
peak_gpu_allocated_bytes=torch.cuda.max_memory_allocated(device),cells=len(results),timings=timings,
unavailable=executions,all_three_primary_eligible=manifest['all_three_primary_eligible'],
backbone_executions=0,cpu_model_offload=False))
verify();print('FULL HYPOTHESIS DIAGNOSIS COMPLETE',flush=True)
if __name__=='__main__':
p=argparse.ArgumentParser();p.add_argument('command',choices=('lock','prepare','run'));p.add_argument('--device',default='cuda:1');a=p.parse_args()
if a.command=='lock':lock()
elif a.command=='prepare':prepare()
else:run(a.device)
|