Text Classification
PEFT
lora
document-question-answering
structured-decisions
calibration
synthetic-evaluation
Instructions to use botp/Solomon with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use botp/Solomon with PEFT:
Task type is invalid.
- Notebooks
- Google Colab
- Kaggle
Download src/solomon/heads.py from botp/Solomon: direct link, hf CLI and curl.
- Browser
- Download file 14 kB
-
https://huggingface.co/botp/Solomon/resolve/main/src/solomon/heads.py
- Command line
-
hf download hf://botp/Solomon/src/solomon/heads.py
-
curl -L -o heads.py https://huggingface.co/botp/Solomon/resolve/main/src/solomon/heads.py
14 kB
| """Final normalized feature extraction, preserving the qualified CUDA engine.""" | |
| import hashlib,json | |
| from pathlib import Path | |
| import numpy as np | |
| def sha(path):return hashlib.sha256(Path(path).read_bytes()).hexdigest() | |
| def token_ids_for(engine,state,block,n): | |
| text=engine._render(state['parts'],block);raw=engine.t.encode(text,add_special_tokens=False);ids=[] | |
| for c in 'ABCDEFGHIJ'[:n]: | |
| ext=engine.t.encode(text+c,add_special_tokens=False) | |
| if ext[:-1]!=raw or len(ext)!=len(raw)+1:raise ValueError('unstable answer token continuation') | |
| ids.append(ext[-1]) | |
| return ids | |
| def capture(engine,state,block,n): | |
| """Prehook sees precisely the post-final-norm input used by the vocabulary head.""" | |
| captured=[] | |
| def hook(module,args): | |
| h=args[0] | |
| if h.ndim!=2 or h.shape[0]!=1:raise ValueError('unexpected final head input shape') | |
| captured.append(h.detach().float().cpu().numpy()[0].copy()) | |
| handle=engine.model.lm_head.register_forward_pre_hook(hook) | |
| try:result=engine.ask(state,block,n,execution='cached') | |
| finally:handle.remove() | |
| if len(captured)!=1:raise ValueError('expected exactly one vocabulary projection') | |
| ids=token_ids_for(engine,state,block,n) | |
| if not np.isfinite(captured[0]).all():raise ValueError('nonfinite hidden features') | |
| return captured[0],ids,result | |
| def copy_letter_head(engine): | |
| ids=[] | |
| for c in 'ABCDEFGHIJ': | |
| pieces=engine.t.encode(c,add_special_tokens=False) | |
| if len(pieces)!=1:raise ValueError('letters must be one token') | |
| ids.append(pieces[0]) | |
| head=engine.model.lm_head;w=head.weight.detach()[ids].float().cpu().numpy().copy();b=getattr(head,'bias',None) | |
| return {'weight':w,'bias':np.zeros(10,np.float32) if b is None else b.detach()[ids].float().cpu().numpy().copy(),'token_ids':np.array(ids,np.int64),'vocabulary_size':np.array(head.weight.shape[0],np.int64),'bias_present':np.array(b is not None)} | |
| def atomic_json(path,value): | |
| path=Path(path);tmp=path.with_suffix(path.suffix+'.tmp');tmp.write_text(json.dumps(value,sort_keys=True,indent=2));tmp.replace(path) | |
| def write_document(path,features,token_ids,results,metadata,identity): | |
| """NPZ first, then checksummed completion JSON. No cumulative shard rewrite.""" | |
| path=Path(path);n=len(features) | |
| if not n or not(len(token_ids)==len(results)==len(metadata)==n):raise ValueError('document arrays must align') | |
| h=np.asarray(features,np.float32);logits=np.zeros((n,10),np.float32);tokens=np.full((n,10),-1,np.int64);widths=[] | |
| if h.ndim!=2 or not np.isfinite(h).all():raise ValueError('invalid document feature matrix') | |
| rows=[] | |
| for i,(ids,r,m) in enumerate(zip(token_ids,results,metadata)): | |
| values=np.asarray(r['letter_logits'],np.float32);width=len(ids) | |
| if not 2<=width<=10 or values.shape!=(width,) or not np.isfinite(values).all():raise ValueError('invalid teacher row') | |
| logits[i,:width]=values;tokens[i,:width]=ids;widths.append(width) | |
| rows.append({**m,'n':width,'mass':float(r['mass']),'top_is_letter':bool(r['top_is_letter']),'prompt_tokens':int(r['prompt_tokens']),'branch_tokens':int(r['branch_tokens']),'reused_prefix_tokens':int(r['reused_prefix_tokens'])}) | |
| tmp=path.with_suffix('.npz.tmp') | |
| with tmp.open('wb') as f:np.savez(f,hidden=h,teacher_logits=logits,token_ids=tokens,widths=np.asarray(widths,np.int64)) | |
| tmp.replace(path) | |
| report={'complete':True,'identity':identity,'rows':rows,'npz_sha256':sha(path),'feature_shape':list(h.shape),'feature_kind':'final-normalized-lm-head-input','storage':'uncompressed-npz-float32'} | |
| atomic_json(path.with_suffix('.json'),report) | |
| return report | |
| def validate_document(path,identity,expected_ids): | |
| path=Path(path);meta=path.with_suffix('.json') | |
| if not path.exists() or not meta.exists():return False | |
| r=json.loads(meta.read_text()) | |
| if r.get('complete')is not True or r.get('identity')!=identity or r.get('npz_sha256')!=sha(path) or [x['id'] for x in r['rows']]!=list(expected_ids):raise ValueError('resumed document identity mismatch') | |
| return True | |
| class TrainedHeads: | |
| """Validated saved answer/correctness heads. No backbone or label access.""" | |
| def __init__(self,directory,*,expected_report_sha256=None,expected_weights_sha256=None): | |
| directory=Path(directory);report_path=directory/'report.json';weights_path=directory/'weights.npz' | |
| self.report_sha256=sha(report_path);self.weights_sha256=sha(weights_path) | |
| if expected_report_sha256 is not None and self.report_sha256!=expected_report_sha256:raise ValueError('selected head report changed') | |
| if expected_weights_sha256 is not None and self.weights_sha256!=expected_weights_sha256:raise ValueError('selected head weights changed') | |
| self.report=json.loads(report_path.read_text()) | |
| if self.report['weights_sha256']!=self.weights_sha256:raise ValueError('trained head weight checksum mismatch') | |
| self.models={} | |
| with np.load(weights_path,allow_pickle=False) as archive: | |
| for kind,entries in self.report['models'].items(): | |
| self.models[kind]={} | |
| for key,fields in entries.items(): | |
| model={name:archive[value['array']].astype(np.float64) if isinstance(value,dict) and set(value)=={'array'} else value for name,value in fields.items()} | |
| if any(not np.isfinite(value).all() for value in model.values() if isinstance(value,np.ndarray)):raise ValueError('nonfinite trained head') | |
| if kind=='heads': | |
| if model['weight'].ndim!=2 or model['weight'].shape[0]!=10 or model['bias'].shape!=(10,):raise ValueError('invalid answer head shape') | |
| elif kind=='correctness': | |
| if model['mean'].ndim!=1 or model['scale'].shape!=model['mean'].shape or np.any(model['scale']<=0) or model['weights'].shape!=(len(model['mean'])+1,):raise ValueError('invalid correctness head shape') | |
| else:raise ValueError('unknown trained model kind') | |
| self.models[kind][key]=model | |
| if not self.models.get('heads') or not self.models.get('correctness'):raise ValueError('both trained answer and correctness heads required') | |
| def answer(self,hidden,key,n): | |
| if key not in self.models['heads']:raise ValueError('no trained answer head for '+str(key)) | |
| if type(n)is not int or not 2<=n<=10:raise ValueError('invalid head output width') | |
| h=np.asarray(hidden,np.float64);model=self.models['heads'][key] | |
| if h.shape!=(model['weight'].shape[1],) or not np.isfinite(h).all():raise ValueError('invalid hidden state for answer head') | |
| return (model['weight']@h+model['bias'])[:n] | |
| def correctness(self,task,branches): | |
| from scipy.special import expit | |
| if task not in self.models['correctness'] or not branches:raise ValueError('no trained whole-answer correctness head') | |
| hidden=np.asarray([r['hidden'] for r in branches],np.float64);probs=[] | |
| if hidden.ndim!=2 or not np.isfinite(hidden).all():raise ValueError('invalid correctness hidden representations') | |
| for row in branches: | |
| p=np.asarray(row['probabilities'],float) | |
| if p.ndim!=1 or len(p)<2 or not np.isfinite(p).all() or np.any(p<0) or abs(p.sum()-1)>1e-6:raise ValueError('invalid correctness answer distribution') | |
| probs.append(p) | |
| feature=np.r_[hidden.mean(0),min(float(p.max()) for p in probs),min(float(np.sort(p)[-1]-np.sort(p)[-2]) for p in probs),max(float(-np.sum(p*np.log(np.maximum(p,1e-300)))/np.log(len(p))) for p in probs),float(len(branches)),float(sum(len(p) for p in probs))] | |
| model=self.models['correctness'][task] | |
| if feature.shape!=model['mean'].shape:raise ValueError('whole-answer confidence feature width mismatch') | |
| value=float(expit(np.r_[1.,(feature-model['mean'])/model['scale']]@model['weights'])) | |
| return {'reliability':value,'features':feature.tolist(),'task':task,'target':'whole_return_exact_correctness','calibration_established':False,'heads_sha256':self.weights_sha256} | |
| def semantic_head_key(task,block): | |
| from solomon.engine_contract import SUFFICIENCY,SINGLE_R,SINGLE_S,ORDERED_R,ORDERED_S,LABEL,BOOLEAN_TASK | |
| if task not in ('boolean','single','ordered','multilabel','entity'):raise ValueError('explicit answering task required') | |
| if block.startswith(SUFFICIENCY) and task in ('single','ordered'):return task+'/sufficiency3' | |
| for prefix,t,form in ((SINGLE_R,'single','R'),(SINGLE_S,'single','S'),(ORDERED_R,'ordered','R'),(ORDERED_S,'ordered','S')): | |
| if block.startswith(prefix) and task==t:return task+'/choice'+form | |
| if block.startswith(LABEL) and task=='multilabel':return 'multilabel/state4' | |
| if block.startswith(BOOLEAN_TASK): | |
| if task in ('boolean','entity'):return task+'/state4' | |
| if task=='ordered':return 'ordered/threshold4' | |
| raise ValueError('task block has no trained semantic head mapping') | |
| from solomon.engine_reasoning import ReasoningEngine | |
| class HeadsEngine(ReasoningEngine): | |
| """Question-only backbone with trained small heads; native LM head retained for reasoning. | |
| Wrap a complete readout in task_context(task), or supply ask(head_key=...). | |
| Answer projection is deliberately evaluated in CPU float64 on the exact copied | |
| float32 hidden vector to match saved-feature evaluation; no speedup is claimed. | |
| """ | |
| def __init__(self,heads_dir,*,expected_base_fingerprint,expected_report_sha256=None,expected_weights_sha256=None,**kwargs): | |
| import threading | |
| self.heads=TrainedHeads(heads_dir,expected_report_sha256=expected_report_sha256,expected_weights_sha256=expected_weights_sha256) | |
| super().__init__(**kwargs) | |
| if self.identity['fingerprint']!=expected_base_fingerprint:raise ValueError('trained head backbone/adapter runtime mismatch') | |
| self.base_identity=dict(self.identity);self._head_task=None;self._head_lock=threading.RLock() | |
| self.identity={**self.identity,'base_fingerprint':expected_base_fingerprint,'trained_heads_sha256':self.heads.weights_sha256,'trained_heads_report_sha256':self.heads.report_sha256,'heads_runtime_sha256':sha(__file__),'answer_projection':'trained-semantic-head-float64-cpu'} | |
| self.identity.pop('fingerprint',None);self.identity['fingerprint']=hashlib.sha256(json.dumps(self.identity,sort_keys=True).encode()).hexdigest() | |
| def task_context(self,task): | |
| from contextlib import contextmanager | |
| def context(): | |
| with self._head_lock: | |
| previous=self._head_task;self._head_task=task | |
| try:yield self | |
| finally:self._head_task=previous | |
| return context() | |
| def prefill(self,document): | |
| with self._head_lock:return super().prefill(document) | |
| def ask(self,state,block,n_letters,execution='cached',head_key=None): | |
| import copy | |
| with self._head_lock: | |
| key=head_key or semantic_head_key(self._head_task,block) | |
| if key not in self.heads.models['heads']:raise ValueError('missing trained head '+key) | |
| if self.placement!='question':raise ValueError('trained heads require question-only adaptation') | |
| if execution not in ('cached','full'):raise ValueError('invalid execution') | |
| torch=self.torch;p=state['prefix_tokens'];previous=self.ctx['start'] | |
| try: | |
| with torch.inference_mode(): | |
| text=self._render(state['parts'],block);ids,embeds,pos,_=self._encode(state['parts'],text,state['features']) | |
| if not torch.equal(ids[:,:p],state['prefix_ids']):raise ValueError('head question prefix mismatch') | |
| self.ctx['start']=(0 if execution=='cached' or self.placement=='full' else p) if self.adapter else None | |
| if execution=='cached':h=self.lm(inputs_embeds=embeds[:,p:],position_ids=pos[...,p:],past_key_values=copy.deepcopy(state['cache']),use_cache=True).last_hidden_state | |
| else:h=self.lm(inputs_embeds=embeds,position_ids=pos,use_cache=False).last_hidden_state | |
| hidden=h[0,-1].float().cpu().numpy().copy() | |
| logits=self.heads.answer(hidden,key,n_letters);probs=np.exp(logits-logits.max());probs/=probs.sum() | |
| return {'letter_logits':logits,'probabilities':probs,'prediction':int(probs.argmax()),'hidden':hidden.tolist(),'head_key':key,'mass':None,'top_is_letter':None,'mass_available':False,'execution':execution,'fallback':'','prompt_tokens':int(ids.shape[1]),'branch_tokens':int(ids.shape[1])-p,'input_tokens':int(ids.shape[1])-p,'reused_prefix_tokens':p if execution=='cached' else 0,'generation_tokens':0,'fingerprint':self.identity['fingerprint']} | |
| finally:self.ctx['start']=previous | |
| def estimate(self,state,block,n,stage='fast',max_new_tokens=512): | |
| if stage!='fast' or not any('image' in part for part in state['parts']): | |
| return super().estimate(state,block,n,stage=stage,max_new_tokens=max_new_tokens) | |
| if type(n)is not int or not 2<=n<=10:raise ValueError('invalid letter count') | |
| # Reuse prefetched vision features; no transformer branch is evaluated. | |
| with self._head_lock,self.torch.inference_mode(): | |
| ids,_,_,_=self._encode(state['parts'],self._render(state['parts'],block),state['features']) | |
| prefix=state['prefix_tokens'] | |
| if not self.torch.equal(ids[:,:prefix],state['prefix_ids']):raise ValueError('image budget prefix mismatch') | |
| return {'input_tokens':int(ids.shape[1])-prefix,'generated_tokens':0,'branches':1, | |
| 'full_prompt_tokens':int(ids.shape[1]),'reused_prefix_tokens':prefix} | |
| def predict_correctness(self,task,branches):return self.heads.correctness(task,branches) | |
| def reason(self,*args,**kwargs): | |
| with self._head_lock:return super().reason(*args,**kwargs) | |