"""Question-only CUDA runtime for immutable semantic-head checkpoints. v1.1 (Solomon v1.1): * precision: 'bf16' (default: bf16 weights, fp32 recurrence, the trainer's mode), 'fp32' (the qualified v1 numerics) or 'int8' (torchao weight-only int8 on the decoder linears). Recorded in the identity. * head layout: any subset of the ten semantic heads loads, provided the yes/no head boolean/state4 is present. The v1.1 heads file carries ONE merged yes/no head (boolean/state4) and no entity/multilabel heads; the serving layer routes multi-label branches to it through the binding's head routing table. A non-v1 layout is recorded in the identity (answer_heads), so a binding pins it. * the document prefill keeps its final hidden states (and any tapped layer) for the trained evidence head. """ import copy from contextlib import contextmanager import hashlib import json from pathlib import Path import threading import numpy as np from solomon.engine_numerics import CudaEngine from solomon.heads import semantic_head_key def sha(path):return hashlib.sha256(Path(path).read_bytes()).hexdigest() SEMANTIC_HEADS=('boolean/state4','entity/state4','multilabel/state4','single/choiceR','single/choiceS','single/sufficiency3', 'ordered/choiceR','ordered/choiceS','ordered/sufficiency3','ordered/threshold4') REQUIRED_HEADS=('boolean/state4',) def load_heads(heads_path): """{head_key: {'weight','bias'}} from a semantic-heads .npz. Tolerant of the merged v1.1 layout.""" with np.load(heads_path,allow_pickle=False) as arrays: heads={k[:-7]:{'weight':arrays[k].copy(),'bias':arrays[k[:-7]+'/bias'].copy()} for k in arrays.files if k.endswith('/weight')} unknown=sorted(set(heads)-set(SEMANTIC_HEADS)) if unknown:raise ValueError('unknown semantic heads: '+', '.join(unknown)) missing=[k for k in REQUIRED_HEADS if k not in heads] if missing:raise ValueError('semantic heads file lacks the yes/no head: '+', '.join(missing)) return heads class SolomonEngine(CudaEngine): def __init__(self, adapter, heads_path, *, expected_adapter=None, expected_heads=None, correctness=None, precision='bf16', model_dir=None, prefix_layers=()): if expected_adapter and sha(adapter)!=expected_adapter:raise ValueError('adapter hash mismatch') if expected_heads and sha(heads_path)!=expected_heads:raise ValueError('heads hash mismatch') self.answer_heads=load_heads(heads_path) self.keep_prefix_hidden=True;self.prefix_layers=tuple(int(i) for i in prefix_layers) super().__init__(adapter=adapter,placement='question',precision=precision,**({'model_dir':model_dir} if model_dir else {})) self.base_identity=dict(self.identity) for head in self.answer_heads.values(): if head['weight'].shape!=(10,5120) or head['bias'].shape!=(10,) or not all(np.isfinite(v).all() for v in head.values()): raise ValueError('invalid semantic head') self.correctness_models=correctness or {} self._task=None;self._lock=threading.RLock() if len(self.answer_heads)!=10:self.identity['answer_heads']=','.join(sorted(self.answer_heads)) # a v1 layout keeps the v1 key set self.identity.update(trained_heads_sha256=sha(heads_path),answer_engine_sha256=sha(__file__), answer_projection='trained-semantic-head-float32',base_fingerprint=self.base_identity['fingerprint']) self.identity.pop('fingerprint',None) self.identity['fingerprint']=hashlib.sha256(json.dumps(self.identity,sort_keys=True).encode()).hexdigest() @contextmanager def task_context(self,task): with self._lock: previous=self._task;self._task=task try:yield self finally:self._task=previous def ask(self,state,block,n_letters,execution='cached',head_key=None,tap_layers=()): with self._lock: key=head_key or semantic_head_key(self._task,block) if key not in self.answer_heads or not 2<=n_letters<=10:raise ValueError('unknown semantic head or width') if execution not in ('cached','full'):raise ValueError('invalid execution') torch=self.torch;p=state['prefix_tokens'];previous=self.ctx['start'];handles=[];taps={} def hook(index): def capture(module,args,output): h=output[0] if isinstance(output,tuple) else output # Intermediate states are normalized using the frozen final norm. taps[str(index)]=self.lm.norm(h[:,-1:])[0,-1].detach().float().cpu().numpy().copy() return capture try: for index in tap_layers: if type(index)is not int or not 0<=index