soft-decider-421m / scripts /serve_soft.py
winwinwinbb's picture
soft-decider-421m: RLCD fine-tune of laya on typed-decisions with holdout calibration
ad67f6b verified
Raw History Blame Contribute Delete
3.3 kB
"""Jev-compatible /v1/systemone server that serves OUR fine-tuned checkpoint (model_soft).
laya-serve serves the upstream family; this one points straight at
output/model_soft so agents get the fine-tuned, holdout-calibrated model.
Bearer auth via env JEV_API_KEY (mandatory), binds 127.0.0.1 by default.
Run:
$env:JEV_API_KEY="..." ; D:\venvs\voxcpm-cuda\Scripts\python.exe d:\QoderCN\jev_finetune\serve_soft.py
Smoke:
see smoke_serve.ps1 next to this file
"""
from __future__ import annotations
import json
import os
import sys
import time
os.environ.setdefault("USE_TF", "0")
sys.stdout.reconfigure(encoding="utf-8")
WORK = os.path.dirname(os.path.abspath(__file__))
MODEL_DIR = os.environ.get("JEV_MODEL_DIR", os.path.join(WORK, "output", "model_soft"))
HOST = os.environ.get("JEV_HOST", "127.0.0.1")
PORT = int(os.environ.get("JEV_PORT", "8190"))
API_KEY = os.environ.get("JEV_API_KEY", "")
DECISIONS_LOG = os.path.join(WORK, "decisions.jsonl")
def _log_decision(state, questions, answers, latency_ms):
"""Append one JSONL record per request - the fuel for the domain fine-tune loop.
Never allowed to break the endpoint."""
try:
with open(DECISIONS_LOG, "a", encoding="utf-8") as f:
f.write(json.dumps({"ts": time.strftime("%Y-%m-%dT%H:%M:%S"), "latency_ms": latency_ms,
"state": state, "questions": questions, "answers": answers},
ensure_ascii=False) + "\n")
except Exception:
pass
from fastapi import FastAPI, Header, HTTPException # noqa: E402
app = FastAPI(title="laya-soft systemone")
_agent = None
@app.on_event("startup")
def _load():
global _agent
import laya
t0 = time.time()
_agent = laya.Agent(MODEL_DIR, device="cuda")
_agent.predict({"ping": "hello"}, {"ok": {"type": "noul", "instructions": "is this a ping"}})
print(f"[serve] model loaded in {time.time()-t0:.1f}s from {MODEL_DIR}")
def _auth(authorization: str):
if not API_KEY:
raise HTTPException(500, "server started without JEV_API_KEY")
if authorization != f"Bearer {API_KEY}":
raise HTTPException(401, "invalid api key")
@app.post("/v1/systemone")
def systemone(body: dict, authorization: str = Header(default="")):
_auth(authorization)
state = body.get("state")
questions = body.get("questions")
if state is None or not isinstance(questions, dict):
raise HTTPException(422, "body must have 'state' and 'questions' (object)")
t0 = time.perf_counter()
res = _agent.predict(state, questions)
dt = (time.perf_counter() - t0) * 1000
ans = res["answers"] if isinstance(res, dict) and "answers" in res else res
_log_decision(state, questions, ans, round(dt, 1))
n_tok = len(json.dumps(state, ensure_ascii=False)) // 4 + len(json.dumps(questions)) // 4
return {"model": os.path.basename(MODEL_DIR), "answers": ans,
"usage": {"input_tokens": n_tok, "output_tokens": 0},
"latency_ms": round(dt, 1)}
@app.get("/health")
def health():
return {"ok": True, "model": MODEL_DIR}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host=HOST, port=PORT, log_level="warning")