Text Classification
Transformers
Safetensors
Russian
English
qwen3_5_text
text-generation
typed-decisions
system-one
russian
routing
agents
decider
Instructions to use smolnikov/migom-2b with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use smolnikov/migom-2b with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-classification", model="smolnikov/migom-2b")# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("smolnikov/migom-2b") model = AutoModelForCausalLM.from_pretrained("smolnikov/migom-2b", device_map="auto") - Notebooks
- Google Colab
- Kaggle
File size: 4,889 Bytes
f67a19b ec0130c f67a19b ec0130c f67a19b ec0130c f67a19b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | """Open typed-decision server with a Jev-compatible API.
POST /v1/systemone {"state": ..., "questions": {id: {"type": "choice|score|noul", "instructions": ..., "criteria": ...}},
"model": "kivok" | "migom" | "auto"}
-> {"model": ..., "answers": {id: {...TypeSafe answer shape...}}, "usage": {...}}
GET /v1/models
Models:
kivok - small (0.3B) and fast, runs on CPU;
migom - larger (2B), better at reasoning; GPU recommended;
auto - cascade: Kivok answers, questions where its top probability is below AUTO_THRESHOLD go to Migom.
Env: KIVOK_PATH, MIGOM_PATH (either may be empty), DEVICE (cpu|cuda|xpu), DTYPE (fp16|bf16|fp32; use fp16 on Intel XPU),
GRAPHS (0 disables graphs), AUTO_THRESHOLD (default 0.8),
API_KEY (if set, require "Authorization: Bearer <key>"), HOST (default 127.0.0.1), PORT (default 8010).
"""
import hmac, os, threading, time
from typing import Any, Dict, Optional
from fastapi import FastAPI, HTTPException, Request
from fastapi.responses import JSONResponse
from pydantic import BaseModel
KIVOK_PATH = os.environ.get('KIVOK_PATH', '')
MIGOM_PATH = os.environ.get('MIGOM_PATH', '')
DEVICE = os.environ.get('DEVICE') or None
THRESHOLD = float(os.environ.get('AUTO_THRESHOLD', '0.8'))
API_KEY = os.environ.get('API_KEY', '')
DTYPE = os.environ.get('DTYPE', '') # fp16 on Intel XPU: bf16 gives wrong answers there
GRAPHS = os.environ.get('GRAPHS', '') # '0' disables CUDA/XPU graphs
app = FastAPI(title='typed-decision server', version='0.1')
_lock = threading.Lock()
_models: Dict[str, Any] = {}
def kivok():
if 'kivok' not in _models:
if not KIVOK_PATH:
raise HTTPException(503, 'kivok is not configured (KIVOK_PATH)')
import laya
_models['kivok'] = laya.load(KIVOK_PATH, device=DEVICE) if DEVICE else laya.load(KIVOK_PATH)
return _models['kivok']
def migom():
if 'migom' not in _models:
if not MIGOM_PATH:
raise HTTPException(503, 'migom is not configured (MIGOM_PATH)')
from decider.infer import Decider
import torch
dt = {'fp16': torch.float16, 'bf16': torch.bfloat16, 'fp32': torch.float32}.get(DTYPE)
_models['migom'] = Decider(MIGOM_PATH, device=DEVICE, dtype=dt, use_graphs=False if GRAPHS == '0' else None)
return _models['migom']
def top_prob(ans: dict) -> float:
if 'probabilities' in ans and ans['probabilities']:
return max(ans['probabilities'].values())
if 'noul' in ans:
p = float(ans['noul']); return max(p, 1 - p)
return 1.0
def ask_kivok(state, questions):
return kivok().predict(state, questions)
def ask_migom(state, questions):
return migom().system_one(state, questions)
class Request_(BaseModel):
state: Any
questions: Dict[str, Dict[str, Any]]
model: Optional[str] = 'auto'
@app.middleware('http')
async def auth(request: Request, call_next):
if API_KEY and request.url.path.startswith('/v1') and not hmac.compare_digest(
request.headers.get('authorization', ''), f'Bearer {API_KEY}'):
return JSONResponse({'detail': 'missing or invalid API key'}, 401)
return await call_next(request)
@app.get('/v1/models')
def models():
return {'data': [{'id': m, 'configured': bool(p)} for m, p in
(('kivok', KIVOK_PATH), ('migom', MIGOM_PATH), ('auto', KIVOK_PATH or MIGOM_PATH))]}
@app.post('/v1/systemone')
def systemone(req: Request_):
if not req.questions:
raise HTTPException(422, 'questions must not be empty')
name = (req.model or 'auto').lower()
t0 = time.time()
with _lock:
try:
if name == 'kivok' or (name == 'auto' and not MIGOM_PATH):
out = ask_kivok(req.state, req.questions); used = {k: 'kivok' for k in req.questions}
elif name == 'migom' or (name == 'auto' and not KIVOK_PATH):
out = ask_migom(req.state, req.questions); used = {k: 'migom' for k in req.questions}
elif name == 'auto':
out = ask_kivok(req.state, req.questions)
used = {k: 'kivok' for k in req.questions}
hard = {k: q for k, q in req.questions.items() if top_prob(out['answers'][k]) < THRESHOLD}
if hard:
second = ask_migom(req.state, hard)
for k in hard:
out['answers'][k] = second['answers'][k]; used[k] = 'migom'
else:
raise HTTPException(404, f'unknown model {name!r}')
except ValueError as e:
raise HTTPException(422, str(e))
return {'model': name, 'answers': out['answers'], 'routed': used,
'usage': {'latency_ms': round(1000 * (time.time() - t0), 1)}}
if __name__ == '__main__':
import uvicorn
uvicorn.run(app, host=os.environ.get('HOST', '127.0.0.1'), port=int(os.environ.get('PORT', '8010')))
|