Add inference.py
Browse files- inference.py +35 -13
inference.py
CHANGED
|
@@ -275,11 +275,30 @@ class NeuralLayer:
|
|
| 275 |
try:
|
| 276 |
import torch, torch.nn as nn
|
| 277 |
self.torch=torch; self.nn=nn
|
| 278 |
-
|
| 279 |
-
|
| 280 |
-
|
| 281 |
-
|
| 282 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 283 |
self.model.eval()
|
| 284 |
self.reduction_rules=[i for i,r in enumerate(self.rules)
|
| 285 |
if not r.startswith('comm_') and not r.startswith('fold_')]
|
|
@@ -294,14 +313,15 @@ class NeuralLayer:
|
|
| 294 |
class RC(nn.Module):
|
| 295 |
def __init__(s,vocab_size,d_model,n_heads,n_layers,d_ff,max_len,n_rules,dropout=0.1):
|
| 296 |
super().__init__()
|
| 297 |
-
s.embed=nn.Embedding(vocab_size,d_model,padding_idx=0)
|
| 298 |
-
s.
|
| 299 |
-
el=nn.TransformerEncoderLayer(d_model,n_heads,d_ff,dropout,batch_first=True,norm_first=True)
|
| 300 |
-
s.
|
| 301 |
-
s.norm=nn.LayerNorm(d_model)
|
|
|
|
| 302 |
def forward(s,x):
|
| 303 |
pm=(x==0); pos=torch.arange(x.size(1),device=x.device).unsqueeze(0)
|
| 304 |
-
e=s.embed(x)+s.
|
| 305 |
L=(~pm).float().sum(1,keepdim=True).clamp(min=1)
|
| 306 |
return s.head(s.norm((enc*(~pm).unsqueeze(-1).float()).sum(1)/L))
|
| 307 |
RC.torch=self.torch
|
|
@@ -457,8 +477,10 @@ def _get_neural(model_path: Optional[str]) -> Optional[NeuralLayer]:
|
|
| 457 |
global _neural
|
| 458 |
if _neural is not None: return _neural
|
| 459 |
if model_path is None:
|
| 460 |
-
|
| 461 |
-
|
|
|
|
|
|
|
| 462 |
else: return None
|
| 463 |
_,rw,_=_get_sym(8)
|
| 464 |
_neural=NeuralLayer(str(model_path), rw, bits=8)
|
|
|
|
| 275 |
try:
|
| 276 |
import torch, torch.nn as nn
|
| 277 |
self.torch=torch; self.nn=nn
|
| 278 |
+
# Load config/vocab from JSON sidecars if present, else extract from .pt
|
| 279 |
+
cfg_path = _HERE / "config.json"
|
| 280 |
+
rv_path = _HERE / "rule_vocab.json"
|
| 281 |
+
cv_path = _HERE / "char_vocab.json"
|
| 282 |
+
sf_path = _HERE / "mba_classifier.safetensors"
|
| 283 |
+
if cfg_path.exists() and rv_path.exists() and cv_path.exists():
|
| 284 |
+
cfg = json.load(open(cfg_path))
|
| 285 |
+
self.rules = json.load(open(rv_path))
|
| 286 |
+
self.char2id = json.load(open(cv_path))
|
| 287 |
+
else:
|
| 288 |
+
ckpt = torch.load(model_path, map_location='cpu', weights_only=False)
|
| 289 |
+
cfg = ckpt['config']
|
| 290 |
+
self.rules = ckpt['rule_vocab']
|
| 291 |
+
self.char2id = ckpt['char_vocab']
|
| 292 |
+
self.n_rules = len(self.rules)
|
| 293 |
+
self.max_len = cfg['max_len']
|
| 294 |
+
self.model = self._build(cfg)
|
| 295 |
+
# Load weights: prefer .safetensors, fall back to .pt
|
| 296 |
+
if sf_path.exists():
|
| 297 |
+
from safetensors.torch import load_file
|
| 298 |
+
self.model.load_state_dict(load_file(str(sf_path)))
|
| 299 |
+
else:
|
| 300 |
+
ckpt = torch.load(model_path, map_location='cpu', weights_only=False)
|
| 301 |
+
self.model.load_state_dict(ckpt['model_state'])
|
| 302 |
self.model.eval()
|
| 303 |
self.reduction_rules=[i for i,r in enumerate(self.rules)
|
| 304 |
if not r.startswith('comm_') and not r.startswith('fold_')]
|
|
|
|
| 313 |
class RC(nn.Module):
|
| 314 |
def __init__(s,vocab_size,d_model,n_heads,n_layers,d_ff,max_len,n_rules,dropout=0.1):
|
| 315 |
super().__init__()
|
| 316 |
+
s.embed = nn.Embedding(vocab_size,d_model,padding_idx=0)
|
| 317 |
+
s.pos_embed = nn.Embedding(max_len,d_model)
|
| 318 |
+
el = nn.TransformerEncoderLayer(d_model,n_heads,d_ff,dropout,batch_first=True,norm_first=True)
|
| 319 |
+
s.encoder = nn.TransformerEncoder(el,n_layers)
|
| 320 |
+
s.norm = nn.LayerNorm(d_model)
|
| 321 |
+
s.head = nn.Linear(d_model,n_rules)
|
| 322 |
def forward(s,x):
|
| 323 |
pm=(x==0); pos=torch.arange(x.size(1),device=x.device).unsqueeze(0)
|
| 324 |
+
e=s.embed(x)+s.pos_embed(pos); enc=s.encoder(e,src_key_padding_mask=pm)
|
| 325 |
L=(~pm).float().sum(1,keepdim=True).clamp(min=1)
|
| 326 |
return s.head(s.norm((enc*(~pm).unsqueeze(-1).float()).sum(1)/L))
|
| 327 |
RC.torch=self.torch
|
|
|
|
| 477 |
global _neural
|
| 478 |
if _neural is not None: return _neural
|
| 479 |
if model_path is None:
|
| 480 |
+
sf = _HERE / 'mba_classifier.safetensors'
|
| 481 |
+
pt = _HERE / 'mba_classifier_v2.pt'
|
| 482 |
+
if sf.exists(): model_path=str(sf)
|
| 483 |
+
elif pt.exists(): model_path=str(pt)
|
| 484 |
else: return None
|
| 485 |
_,rw,_=_get_sym(8)
|
| 486 |
_neural=NeuralLayer(str(model_path), rw, bits=8)
|