原路径:/SSD2/yangzijing/egoview-v9-foundationhand-s9l10-20260901/v9_benchmark/p3r2_fit.py
SHA256:7226c41a93fa0bfcb0a4f32016572ac4bfe25875e53c8f914acf512ca99a346c
1 """Full-sequence V9P3R2 fitting and isolated single-factor controls.""" 2 import argparse,os,time,traceback 3 from dataclasses import asdict,replace 4 from pathlib import Path 5 os.environ.setdefault('PYOPENGL_PLATFORM','egl') 6 import numpy as np 7 from v9_benchmark.p3r2_common import OUT,rows,read,write,load,sha,link 8 from v9_benchmark.p3r1_anomaly_experiment import hand_arrays,export 9 from v9_benchmark.p3r1_anomaly import compute,quantiles 10 11 def run(row,mano,faces,variant='V9P3R2'): 12 import torch 13 from v9_fusion.s9_sequence_fit import SequenceFitConfig,fit_sequence 14 from v9_fusion.hand_surface import SurfaceConfig 15 w=OUT/'work'/row['sequence_id'];dest=OUT/'results'/row['sequence_id'] if variant=='V9P3R2' else OUT/'ablations'/row['sequence_id']/variant;dest.mkdir(parents=True,exist_ok=True) 16 if (dest/'complete.json').exists():return 17 raw=load(w/'raw_s9.npz');e=load(w/'semantic_observations.npz');surface=load(w/'surface_constraints.npz');c=load(w/'camera.npz');previous=read(w/'sequence_fit.json');old=load(Path(row['work'])/'final_hand_camera.npz') 18 conf=replace(SequenceFitConfig(**previous['config']),respect_observation_track_boundaries=True,partial_mask_initialization=True,palm_confidence_guard=True);sc=SurfaceConfig(**previous['surface_constraints']['config']) 19 if variant=='no_palm_guard':conf=replace(conf,palm_confidence_guard=False) 20 elif variant=='no_partial_init':conf=replace(conf,partial_mask_initialization=False) 21 elif variant=='no_boundaries':conf=replace(conf,respect_observation_track_boundaries=False) 22 elif variant=='no_scene': 23 for k in ['scene_depth_m','scene_depth_valid','scene_depth_boxes']:surface.pop(k,None) 24 partial=(e['v5r_mmpose_keypoint_scores']>=.35).sum(-1)<12;surface['containment_weight'][partial]=0 25 elif variant=='no_ownership':e=load(w/'unowned_observations.npz');surface=load(w/'unowned_surface.npz') 26 elif variant!='V9P3R2':raise ValueError('Unknown ablation') 27 torch.set_grad_enabled(True);torch.manual_seed(20260914);np.random.seed(20260914);start=time.monotonic() 28 if (dest/'fitted.npz').exists() and (dest/'fit.json').exists():result=load(dest/'fitted.npz');fit=read(dest/'fit.json') 29 else: 30 def progress(r): 31 if r['step']%120==1: 32 q=dict(sequence_id=row['sequence_id'],variant=variant,step=r['step'],loss=r['loss'],seconds=time.monotonic()-start);write(dest/'progress.json',q);print(q,flush=True) 33 result,fit=fit_sequence(raw,e,c['K'].astype(np.float32),mano,conf,surface_constraints=surface,surface_config=sc,progress=progress) 34 np.savez_compressed(dest/'fitted.npz',**result);write(dest/'fit.json',fit) 35 h=hand_arrays(result,e);np.savez_compressed(dest/'final_hand_camera.npz',**h);np.savez_compressed(dest/'evidence.npz',**e);export(dest,h,c,faces) 36 tracks=e['observation_track_ids'];values,_,_=compute(h,e,c,tracks,surface);np.savez_compressed(dest/'frame_metrics.npz',**values,hand_valid=h['hand_valid'],tracks=tracks,timestamps_s=c['timestamps_s']) 37 common=h['hand_valid']&old['hand_valid'];delta=np.linalg.norm(h['joints_camera_m']-old['joints_camera_m'],axis=-1) 38 report=dict(profile='V9P3R2',variant=variant,sequence_id=row['sequence_id'],date=row['date'],frames=row['frames'],fps=row['fps'],config=asdict(conf),surface_config=asdict(sc),random_seed=20260914,common_valid_slots=int(common.sum()),gained_slots=int((h['hand_valid']&~old['hand_valid']).sum()),lost_slots=int((~h['hand_valid']&old['hand_valid']).sum()),joint_difference_from_R1_m=quantiles(delta[common]),metrics={k:quantiles(v[h['hand_valid']]) for k,v in values.items()},seconds=time.monotonic()-start,runtime=dict(python=__import__('sys').executable,torch=torch.__version__,numpy=np.__version__),input_sha256={k:sha(w/k) for k in ['raw_s9.npz','camera.npz','semantic_observations.npz','surface_constraints.npz','sequence_fit.json']},source_sha256={str(p):sha(p) for p in [Path(__file__),Path('v9_fusion/s9_sequence_fit.py'),Path('v9_fusion/s9_pose_initialization.py')]},limitations='Model and stereo consistency, no 3D GT. Hidden fingers inferred, no interpolation or overlay clipping. Compare observation gains/losses separately.',accepted=False) 39 write(dest/'report.json',report);write(dest/'complete.json',dict(profile='V9P3R2',variant=variant,frames=row['frames'],seconds=time.monotonic()-start));print('fit_complete',row['sequence_id'],variant,flush=True) 40 41 def main(): 42 p=argparse.ArgumentParser();p.add_argument('--sequence');p.add_argument('--date');p.add_argument('--shard',type=int,default=0);p.add_argument('--shards',type=int,default=1);p.add_argument('--variants',default='V9P3R2');a=p.parse_args() 43 from v9_fusion import s9l10_worker as locked 44 locked._activate_official_runtime() 45 import torch,yaml 46 from foundation_hand.models.mano import ManoCameraLayer 47 from v9_fusion.s9l10 import S9L10_CONFIG,S9L10_PYTHON 48 if not Path(__import__('sys').executable).samefile(S9L10_PYTHON):raise ValueError('Locked fitting environment required') 49 from v9_benchmark.hf_0907_contract import mano_topology 50 torch.set_num_threads(3);cfg=yaml.safe_load(S9L10_CONFIG.read_text());mano=ManoCameraLayer(cfg['assets']['mano_root'],fix_left_shapedirs=True).cuda().eval();mano.requires_grad_(False);faces,_=mano_topology() 51 selected=[r for r in rows() if (not a.sequence or r['sequence_id']==a.sequence) and (not a.date or r['date']==a.date)][a.shard::a.shards];done=[] 52 while len(done)<len(selected): 53 for row in selected: 54 if row['sequence_id'] in done or not (OUT/'work'/row['sequence_id']/'surface_ready.json').exists():continue 55 for v in a.variants.split(','):run(row,mano,faces,v) 56 done.append(row['sequence_id']);write(OUT/f'fit_progress_{a.date}_{a.shard}_{a.sequence or "all"}.json',dict(done=done,total=len(selected),pid=os.getpid())) 57 if len(done)<len(selected):time.sleep(10) 58 if __name__=='__main__':main()