←新闻详情

腾讯云开发者社区更新于 10月16日 12:16

Jev 不只是 JSON 分类器:从 Kev 与 Laya 还原其技术路线

和AI一起搞事情#9. Jev不就是个 JSON 分类器?我劝你把这篇看完再说

AI 导读

文章指出 Jev 是一台把状态映射为概率分布的机器,输入共享 state 与运行时定义的 choice、score、noul 三类问题,直接输出各选项概率且不生成任何输出 token。作者通过 kev 和 laya 两个开源项目还原其技术路线:Laya 基于 BERT 在每个选项前插入 [MASK] 并读取隐藏向量打分,Kev 基于 Qwen 用 block-causal 隔离与 pointer head 并行决策。训练部分为作者推断,涉及 soft label 蒸馏、按题型与选项数分桶的温度缩放、Permutation KL、RPS 损失和 None-of-Above 选项等校准手段。

推荐理由

AI 评分 54

文章从两个开源实现还原 Jev 的输入拼接、概率读取与校准训练思路,可迁移到分类与路由场景。

主题

标签

正文

一、Jev究竟是做什么的

先说结论,Jev 本质上就是一台"把状态变成概率"的机器。

你给它一段描述(state),再给它几个问题(questions),它直接还你每个选项的概率分布——全程不生成任何文字。

输入:一个共享的 state(可为字符串/JSON 等)+ 多个运行时定义问题(typed question)。 问题类型:一个状态可以同时有多个问题 choice:多项选择,候选集合上的分布; score:有序等级上的分布/期望; noul:yes 概率 输出:每个选项直接返回概率分布,整个过程不生成输出 token 二、为什么Jev这么火

一句话:它同时做到了三件之前互相矛盾的事。

| | BERT时代分类器 | 大模型 | Jev | |---|---|---|---| | 速度/并发 | ✅ 极快 | ❌ 慢 | ✅ 极快 | | 复杂上下文理解 | ❌ 弱 | ✅ 强 | ✅ 强 | | 概率输出可信 | ❌ 不可信 | ❌ 不可信 | ✅ 接近真实 |

什么叫"概率输出可信"? BERT 时代做分类,输出的 softmax 概率经常是 0.9999 vs 0.9998——你根本不知道这两个数字的差距意味着什么,只能在这两个值之间手动调阈值,本质上退化成了一个排序器。

Jev 的目标是:模型说"60%",现实中这件事就真的发生了约 60% 的时间。 这叫概率校准(calibration)。有了这个,下游决策可以直接用概率值,不再需要玄学调阈值。 三、怎么理解它?

1. 如果你是 LLM 老手

你的第一反应可能是:"不就是个 JSON 分类器?"

……对,任务范式上确实如此。但类比一下:汽车也不过是"带引擎的马车",但你不会因此说它们一样。

Jev 和 LLM 解码的关键差异在于:LLM 是逐字生成,Jev 是一步读数。没有 token-by-token 的自回归循环,hidden state 直接映射成概率——速度和并发差了一个数量级,延迟在毫秒级。

另一个差异:LLM 输出的"概率"其实是 next-token 的条件概率,和"这件事发生的真实概率"没有直接关系。Jev 被专门训练来对齐这两者。

2. 如果你是 BERT 时代老兵

你的第一反应可能是:"NLI 任务卷图重来?"

也有道理,当年 BERT + NLI 那套确实做过类似的事。但有两个本质升级:

升级一:底座更强。 ModernBERT-large(421M)和 Qwen3 级别的解码器,对长上下文、复杂语义的理解远超当年。

升级二:概率校准。 这是最关键的。当年 BERT 分类器的 softmax 概率是"伪概率",训练目标把它推向 0 或 1,你拿到的数字没有概率意义。Jev 专门解决了这个问题——后面的训练章节会详细讲。 四、从两个开源项目还原 Jev 的技术路线 - https://github.com/jaredpalmer/kev - https://github.com/NandhaKishorM/laya

我们从零开始讲:输入怎么拼 → 模型怎么跑 → 概率怎么读出来 → 多题怎么并发。架构和推理先讲,训练最后说。 Laya:BERT 复古,但复古得很精妙

一句话概述:Bert基座,每个选项前插一个[MASK],最后去这些 [MASK]的隐藏向量上logit打分 输入是怎么拼的?

每个选项前面各顶着一个 [MASK]。这个设计的巧妙之处在于:MASK 的位置在 Encoder 里能双向 attend 所有 token——它同时"看"到了问题、自己选项的描述、其他选项的描述,以及完整的 state。所以 MASK 位置的 hidden state,天然就是"在当前语境下,这个选项的综合表示"。 Forward 之后,怎么读出概率?

四步走: Encoder 编码 注入题型信息 决策头:再过一个2层的transformer,从 Encoder 的通用表示里蒸馏出决策信号 只读取MASK位置,按不同问题类型进行归一化计算

注意那个 tscale——按题型 × 选项数分桶的温度系数,这是 Laya 概率校准的关键手段,后面训练章节会详细展开。 额外输出:置信度

Laya 还会从 [CLS] 的 hidden state + 4 个概率统计指标(熵、最大概率等)预测一个置信度分数,用于判断"这道题 AI 有没有把握,要不要转人工"。这个设计实际上是对"没有正确选项"问题的一种工程解法。 多题并发怎么做?

一个 state 有 N 个问题时,Laya 用 Batch 推理:N 个问题各自构建一条序列,state 在每条序列里都完整复制一份,然后一起打包进模型。显存换速度,架构本身不支持 state 的 KV cache 共享。 Kev:解码器变身并行决策机

一句话概述:把因果LM“改造成并行决策机”,关键是 block-causal 隔离 + pointer head 输入是怎么拼的? Kev 基于 Qwen,是因果解码器,序列是线性的:

State 在前面,各道题依次排列,每道题以 结尾。

除了 token id,Kev 还维护了几个并行数组,记录序列中每个 token 的"身份信息":

| 数组名 | 含义 | 例子(5个state token + 1道选择题ABC) | |---|---|---| | ids | token id 序列 | [s0,s1,s2,s3,s4, ,i0,i1, ,A, , ,B, , ,C, , ] | | seg | 每个 token 属于哪道题(0=state) | [0,0,0,0,0, 1,1,1, 1,1,1, 1,1,1, 1,1,1, 1] | | pos | position id | state: [0..4];每个问题都重置 重新从 5 开始 | | opt | 属于该题的第几个选项(OPTNONE/0/1/2/OPTDECIDE) | [-, -, -, ..., NONE, NONE, 0, 0, 0, 1, 1, 1, 2, 2, 2, DECIDE] | | decideidx | 在 ids 中的位置 | [17] | | optidx | 每个 的位置 | [[10, 13, 16]](对应 A/B/C 的边界) |

这些数组在 Forward 之后用于精准定位"去哪个位置读概率"。 问题隔离:Block-Causal Mask

Decoder 默认是因果掩码——每个 token 只能看到自己前面的 token。但这会导致:第二道题的 token 能看到第一道题的所有选项,两道题的概率会互相污染。

Kev 的解法是 Block-Causal Mask:

效果类似滑动窗口注意力,每道题只在自己的"小世界"里做注意力,题目之间完全隔离。

Kev 还提供了更激进的 Option Isolation:题目内部的各个选项之间也互相屏蔽,每个选项独立 attend state 和问题指令,选项之间完全不知道彼此的存在。 ⚠️ 注意:Option Isolation 有适用限制。如果选项中有"其他"这类相对性选项,选项之间需要"知道彼此"才能正确理解语义,这时不能用 Option Isolation。 概率怎么读出来:Pointer Head

Forward 完成后,每个 token 都有一个 hidden state 向量。Kev 用 Pointer Head 把这些向量变成概率:

为什么用 而不是其他位置?

因果解码器里,只有序列中"最后一个能看到所有选项"的 token,才能做全局比较。 被设计在每道题的最末尾,正是这个角色——它 attend 到了该题的完整选项列表后,再综合判断。

Pointer Head 对 Option Count 问题的天然优势:

普通 joint softmax 有个问题:选项越多,每个选项的分母越大,概率被稀释。Pointer Head 的每个 logit 是 和 的点积,每个选项独立计算 logit,选项数不影响 logit 的绝对量级,最后才做 softmax。这比 Laya 的联合 softmax 对选项数的变化更鲁棒。 五、训练:决策模型要解决哪些问题? Jev 的训练方案未开源,以下基于 Kev/Laya 实现进行分析推断。

把推理层搭好只是第一步。让模型真正输出"有意义的概率",训练阶段需要专门解决五个问题。 Calibration:选项概率更接近真实概率分布

猜测方案:合成数据 + soft labels 蒸馏 + soft cross-entropy训练 + 后验温度系数

问题的根源:Cross-entropy 损失函数的理论最优解确实是真实概率分布。但理论归理论,实践中神经网络在 loss 降到很低时,logit 会被推得越来越大,softmax 变得越来越尖——argmax 很对,但概率的刻度已经失真。

最典型的症状:模型对一道 60/40 开的问题,输出 [0.9999, 0.0001]。方向对了,但概率值骗人。

可能的解法

① Soft Label + Soft Cross-Entropy

根本矛盾是标签不诚实。解法是换掉标签:

Soft Label 从哪来?最可能的路线是:用大模型或多个模型对同一个样本重复采样,统计各选项被选的频率,作为该样本的 soft label。本质上是对真实分布的蒙特卡罗估计。

② 后验温度缩放

光靠训练还不够。Kev 和 Laya 都在训练完成后,用验证集拟合一个温度系数 T:

T 不是一个全局值,而是按题型 × 选项数分桶拟合。"3个选项的 choice 题"和"5个选项的 choice 题"用不同的 T。Laya 在校准前 ECE 高达 0.466,分桶拟合后降到 0.081——几乎全部的校准效果来自这一步。 Permutation:让选项概率与顺序无关

引入Permutation KL(置换一致性),把同一道题的选项随机打乱,要求输出分布(对应到选项)不变

并且在训练时对选项顺序做shuffle,再推理层让所有选项的位置编码一致不引入偏差等等。 Ordianl prediction:有序打分的分布如何训练

Score 题(1-5分)如果当普通分类训练,损失函数对所有错误一视同仁——预测 2 分而真实是 3 分,和预测 5 分而真实是 3 分,loss 一样大。但显然后者错得更离谱。

解法:RPS(Ranked Probability Score)

用累积分布函数(CDF)的平方差作为损失:

这个损失的本质是:惩罚"分布形状"的错误,而不只是"峰值位置"的错误。预测集中在 2-3 分的模型,比预测集中在 1 分的模型,RPS 更小——即使两者的 argmax 都是"错的"。 option count:如何降低选项个数对真实选项概率的影响 这个问题的本质是 softmax 的归一化耦合:所有选项共享一个归一化分母,选项数越多,单个选项的概率天然被稀释。

kev的架构受到的影响较小,因为是每个选项和\ 独立计算logit之后再归一化。

残余问题靠分桶温度补救:温度系数按选项数分桶,2选题和10选题用不同的 T,在后验层面对齐不同选项数下的概率刻度。

但需要接受选项数影响是天然存在的问题,跨选项数直接比较两道题的概率,在语义上本来就不合适,不是能完全修好的Bug。 no correct option:如果没有正确选项怎么选

比较朴素的,Kev是默认在训练和推理中都加入“ None-of-Above 选项”

Laya的方案是同时输出选项概率和置信度分数(基于 [CLS] hidden state + 熵等统计指标)。当置信度低于阈值时,直接拒绝所有概率输出,标记为"无可信答案" Jev in Harnesss 了解了原理,最后我们看看在Harness框架搭建中,有哪些可以利用Jev进行优化、提速的点。

这里我们抛砖引玉,给大家几种在harness中可以使用Jev进行效率优化的方向,部分场景还未验证,哈哈毕竟AI写代码太快但是很多场景验证比较复杂。有些指令较长,感兴趣的可以直接看代码jevharnesstool 选择类:Skill Search 这里使用用户query和agent所有候选技能作为输入,判断解决用户问题是否需要使用技能,如果需要应该使用哪个技能。

类似的思路也可以用在mcp search、effort routing、memory search等等。不过model routing在我的使用场景中往往效率提升不明显但质量下降明显,或者推理速度快很多但任务完成速度提升不明显,对场景复杂度的评估需要更全面的上文,所以实现很简单,但效果很难评。 围栏类:LLM Guardrail 拦截用户的各类风险输入和prompt注入,这里提供了9种基础的风险类型,每种风险可以提供不同的处置方案block、review etc。

类似的思路也可以用于模型输出检查、tool call检查etc。 校验类:reference verify 以下适用于inline 引用,提供模型推理段落,inline推理+对应reference正文,判断搜索上文能否支持推理输出。

类似的思路也可以同于ool result校验agent结果,用在loop中检查task completed等等。

来源

腾讯云开发者社区