33ms 决策引擎为何爆火
非自回归多语种决策引擎 laya 单次推理 33ms,三个 checkpoint + Router 自动路由,支持 choice / score / noul 类型决策,Apache 2.0 开源,4 天斩获 9431 stars。本文拆解它如何替代 LLM 做 System 1 决策,并给出可运行代码。
源仓库: NandhaKishorM/laya
laya 是 NandhaKishorM 推出的 “System 1 决策引擎”,本质是一个非自回归分类器:把任意文本、邮件、工单或 JSON 当作 state,把”分给哪个部门""紧急程度""是否涉及退款”这类结构化问题用 choice / score / noul 三种类型表达,一次 forward pass 同时回答上百个问题,单卡 T4 跑出 33 ms。它和 LLM 的最大区别是不生成文本——没有要解析的字符串,也没有幻觉。Apache 2.0 开源,截至 2026-09-22 在 GitHub 拿下 9431 stars,从创建到 9k+ 只用了 4 天。
Q1: 三个 checkpoint 不能合并成一个吗?
现象:仓库里同时挂着 laya、laya-multilingual、laya-typed-decisions 三套权重,对应三个 HuggingFace repo。
根因:合并的多语种 ModernBERT-large 在 512 context 下显存吃紧;mmBERT-base 在 1024 context 下参数量更小、推理更快。强行合并要么牺牲上下文长度,要么牺牲速度,英语场景还会被多语种 tokenizer 稀释。
解法:用 Router 做”晚绑定”。先做脚本/语种检测,再选模型:
from laya import Router
router = Router(preload=True)
res = router.predict(
{"body": "मुझसे दो बार शुल्क लिया गया, कृपया पैसे वापस करें।"},
questions,
)
print(res["routing"]["reason"])
# -> 'non-Latin script (devanagari, 100% of letters); the English checkpoint cannot read it'
Q2: 为何不用 LLM 直接回答”退款需求”?
现象:很多团队会用 GPT-4 + JSON schema 做客服路由,结果是延迟 500 ms–2 s,偶尔输出不合法。
根因:自回归模型每一 token 都是前一个 token 的条件概率,越长的 JSON 越容易跑偏;同时它会产生额外 token,触发限流与账单。
解法:把这类”分类 / 打分 / 是与否”问题降维成一次分类。laya 输出的是 dict,不是字符串:
import laya
agent = laya.load("convaiinnovations/laya")
result = agent.predict(state, questions)
result["answers"]["churn_risk"]["noul"] # -> 0.892
result["answers"]["urgency"]["score"] # -> 1.84 / 2.0
Q3: Router 怎么在 < 0.5 ms 决定走哪个 checkpoint?
现象:README 的 routing reason 会输出 Latin script but language looks like 'de',这是纯 Python 推理。
根因:在 forward pass 之前先跑一遍字符集统计——非拉丁(Devanagari、Khmer、CJK)直接走 multilingual;拉丁里再用字符 n-gram 简单判断英语还是其它欧语。Khmer 这种长尾语言在英语 checkpoint 上是 0.000 准确率、0.952 置信度,gate 不动,必须路由切换。
解法:调用 router.route() 可以单独验证路由而不跑模型:
print(router.route({"body": "Der Kunde wurde zweimal belastet"}, questions).reason)
Q4: 置信度是不是又一种”0.99 自信但全错”?
现象:传统 softmax 出来的概率校准很差,没法当业务阈值。
根因:laya 的训练目标是 RLCD(reinforcement learning against strictly proper scoring rules),把 Brier score 直接塞进 reward,输出概率在数学意义上等于”答对的期望”。
解法:可以把 confidence 当业务阈值直接用:
conf = answers["department"]["confidence"]
if conf < 0.6:
escalate_to_human()
Q5: 生产环境怎么避免 7–10 s 冷启动?
现象:默认 Router(max_loaded=1) 会在每次语言切换时重新加载模型。
根因:每个 checkpoint 几百 MB,磁盘 + CUDA 初始化加起来就是秒级。
解法:服务器启动时一次性 preload,并限制常驻模型数量:
router = Router(preload=True, device="cuda", max_loaded=2)
router.preload(["english", "multilingual"])
router.unload() # 释放
preload 后单请求 32.8 ms(GPU)/ 193–464 ms(CPU),不再有 reload。
Sources
- GitHub: https://github.com/NandhaKishorM/laya
- Hugging Face: https://huggingface.co/convaiinnovations/laya
- PyPI: https://pypi.org/project/laya/
- Dev.to 作者文章:I built non-autoregressive decision models a year ago