"""Reuse original immutable features; cache only three extra four-frame layers.""" import gzip,hashlib,io,json,re,time,unicodedata from pathlib import Path import numpy as np import requests from .common import OLD,WORK,FEATURES,atomic,guard,update def arrays():return {p.stem:np.load(p,mmap_mode='r') for p in (OLD/'arrays').glob('*.npy')} def splits():return {k:np.asarray(v,np.int64) for k,v in json.loads((OLD/'splits.json').read_text()).items()} def rows():return json.loads((OLD/'sources_manifest.json').read_text()) def stable_targets(): """Trim outliers and average emotion/language groups for TRAIN voices only. Prediction clips are disjoint from enrollment references. No validation or test probe embeddings are used to construct a training target or statistic. """ saved=WORK/'stable_targets.npy' if saved.exists():return np.load(saved) vectors=np.zeros((500,192),np.float32);details=[] for row in rows(): if row['split']!='train':continue with np.load(OLD/'sources'/row['voice']/'targets.npz') as z:x=z['vectors'].astype(np.float32) probes=[i for i,c in enumerate(row['clips']) if c['role']=='prediction'];y=x[probes] y/=np.maximum(np.linalg.norm(y,axis=-1,keepdims=True),1e-8) mean=y.mean(0);mean/=np.linalg.norm(mean) take=np.argsort(y@mean)[-max(2,int(np.ceil(.8*len(y)))):];groups={} for j in take: clip=row['clips'][probes[j]];emotion=clip['uid'].split('__E__')[-1].split('__')[0] groups.setdefault((emotion,clip.get('lang')),[]).append(y[j]) centers=np.stack([np.mean(v,axis=0) for v in groups.values()]);center=centers.mean(0);center/=np.linalg.norm(center) vectors[row['speaker_idx']]=center details.append({'speaker':row['speaker_idx'],'prediction_clips':len(probes),'retained':len(take),'groups':len(groups)}) np.save(saved,vectors);atomic(WORK/'centroid_protocol.json',{'training_identities':len(details), 'rule':'top 80% by cosine to initial mean; equal emotion/language group weight; prediction clips only','voices':details}) return vectors def subset(): path=WORK/'factorial_indices.npy' if path.exists():return np.load(path) keep=[] for i,row in enumerate(rows()): local=np.arange(i*1000,(i+1)*1000) if row['split']=='train':local=np.random.default_rng(9117+row['speaker_idx']).choice(local,200,replace=False) keep.extend(local.tolist()) keep=np.sort(keep).astype(np.int64);np.save(path,keep) return keep def metadata(): """Map each original sampled speech window back to its public source clip.""" saved=WORK/'clip_index.npy';infofile=WORK/'clip_info.json' if saved.exists() and infofile.exists():return np.load(saved),json.loads(infofile.read_text()) original=arrays();ids=original['speaker'];info=[];lookup={} for row in rows(): for clip in row['clips']: text=unicodedata.normalize('NFKC',' '.join(w['w'] for w in clip['words'])).casefold() text=re.sub(r'\W+',' ',text).strip();lookup[clip['uid']]=len(info) info.append({'uid':clip['uid'],'speaker':row['speaker_idx'],'role':clip['role'], 'emotion':clip['uid'].split('__E__')[-1].split('__')[0],'text_hash':hashlib.sha256(text.encode()).hexdigest()[:24]}) index=np.full(len(ids),-1,np.int32) for rownumber,row in enumerate(rows()): with gzip.open(OLD/'conversations'/(row['voice']+'.json.gz'),'rt') as stream:conversations=json.load(stream) cursor=rownumber*1000 for conversation in conversations: for step in conversation['selected_320ms_steps']: who=int(ids[cursor]);end=step*.32 if who>=0: event=next((e for e in reversed(conversation['events']) if e.get('speaker_idx')==who and e.get('onset_s',99)end-.32),None) if event is None:raise RuntimeError('Source-label replay mismatch') index[cursor]=lookup[event['uid']] if info[index[cursor]]['speaker']!=who:raise RuntimeError('Speaker metadata mismatch') cursor+=1 if cursor!=(rownumber+1)*1000:raise RuntimeError('Conversation sample count changed') np.save(saved,index);atomic(infofile,info);return index,info def extract_layers(): """Replay EXACT V3 seeds and windows for a paired layer comparison.""" guard();keep=subset();directory=FEATURES;count=len(keep) specs={'q':(np.int8,(count,3,4,1024)),'scale':(np.float16,(count,3,4,1)), 'filled':(np.uint8,(count,))} remaining=sum(np.prod(shape)*np.dtype(dtype).itemsize for key,(dtype,shape) in specs.items() if not (directory/(key+'.npy')).exists()) import shutil if shutil.disk_usage(directory).free-remaining<3*1024**3:raise RuntimeError('Layer cache would breach 3-GiB reserve') cache={key:np.load(directory/(key+'.npy'),mmap_mode='r+') if (directory/(key+'.npy')).exists() else np.lib.format.open_memmap(directory/(key+'.npy'),mode='w+',dtype=dtype,shape=shape) for key,(dtype,shape) in specs.items()} if cache['filled'].all():return from speaker_v2 import prepare_pilot as core from speaker_v3.overnight import decoded core.source_signal=lambda c:decoded(c['path'],json.dumps(c['words'],sort_keys=True)) original=arrays();people=rows();groups={s:[r for r in people if r['split']==s] for s in ('train','validation','test')} lookup={int(g):i for i,g in enumerate(keep)};client=requests.Session();timings=[];checks=[];started=time.time() for rownumber,anchor in enumerate(people): relevant=keep[(keep>=rownumber*1000)&(keep<(rownumber+1)*1000)] if all(cache['filled'][lookup[int(g)]] for g in relevant):continue group=groups[anchor['split']];rank=next(i for i,r in enumerate(group) if r['speaker_idx']==anchor['speaker_idx']) cohort=[group[(rank+k)%len(group)] for k in range(min(12,len(group)))];waves=[];locations=[];global_ids=[] for repeat in sorted({int((g-rownumber*1000)//5) for g in relevant}): chosen=[int(g) for g in relevant if (g-rownumber*1000)//5==repeat and not cache['filled'][lookup[int(g)]]] if not chosen:continue seed=7730000+anchor['speaker_idx']*10000+repeat audio,*_=core.conversation(cohort,anchor,seed);steps=np.sort(np.random.default_rng(seed).choice(np.arange(5,75),5,replace=False)) for g in chosen: step=steps[(g-rownumber*1000)%5];end=int(step)*5120;wave=audio[max(0,end-128000):end] waves.append(np.pad(wave,(max(0,128000-len(wave)),0)));locations.append(lookup[g]);global_ids.append(g) pending=[] for offset in range(0,len(waves),4): guard();wave=np.stack(waves[offset:offset+4]).astype('=12:raise update(phase='Waiting for shared encoder',retry=retries);time.sleep(5) with np.load(io.BytesIO(response.content)) as z:x=z['features'].astype(np.float32);seconds=float(z['encoder_seconds']) # A mismatched waveform would invalidate a paired ablation. old=original['q'][global_idx,-4:].astype(np.float32)*original['scale'][global_idx,-4:].astype(np.float32) similarity=(x[:,3]*old).sum(-1)/(np.linalg.norm(x[:,3],axis=-1)*np.linalg.norm(old,axis=-1)+1e-8) if not np.isfinite(x).all() or float(similarity.mean())<.995:raise RuntimeError('Replayed L15 features do not match original windows') checks.append(float(similarity.mean()));timings.append(seconds) y=x[:,:3];scale=np.maximum(np.abs(y).max(-1,keepdims=True)/127,1e-6) cache['q'][local]=np.clip(np.rint(y/scale),-127,127).astype(np.int8);cache['scale'][local]=scale pending.extend(local) if len(pending)>=128 or offset+4>=len(waves): cache['q'].flush();cache['scale'].flush();cache['filled'][pending]=1;cache['filled'].flush();pending=[] if offset%40==0:update(phase='Extracting paired layers 4/8/12',layer_windows=int(cache['filled'].sum()),layer_total=count, layer_elapsed_seconds=time.time()-started,l15_replay_cosine=float(np.mean(checks)),encoder_ms_per_four=float(np.mean(timings)*1000)) atomic(directory/'provenance.json',{'global_indices':str(WORK/'factorial_indices.npy'),'one_based_layers':[4,8,12], 'last_frames':4,'paired_l15_cosine_mean':float(np.mean(checks)) if checks else None,'new_windows_this_run':len(timings)*4})