类Jev项目Kev从入门到实战(2):Kev 的架构:一次前向,多问题隔离作答

0 阅读3分钟

PART 2|Kev 的架构:一次前向,多问题隔离作答

外部契约:System One 协议

POST /v1/systemone,一个请求带任意多个问题:

{
  "state": "……",                    // 待评判的文本(对象/数组会被序列化成带标签文本)
  "questions": {
    "<id>": {
      "type": "noul" | "choice" | "score",
      "instructions": "……",
      "criteria": …                  // noul: {true?,false?}  choice: {选项:描述, 1–255 个}
                                     // score: [等级描述, …] 由低到高,1–255 个
    }
  }
}

响应里每个问题一个分布:choice 给 choice + confidence + probabilities;noul 给 P(yes);score 给期望等级 + legend + probabilities。choice 的置信度公式是 (p_max − 1/K) / (1 − 1/K)(K 为选项数)——注意它不是准确率,是相对随机基线的增益归一。

内部结构(官方 README "How It Works",2026-09 核对)

每个 checkpoint = rank-16 LoRA 适配器 + 一个小指针头(pointer head),底座 Qwen base 全程冻结:

<state> …state…
<q> instructions <opt> option 1 </opt> <opt> option 2 </opt> … <decide>
<q> instructions <opt> option 1 </opt> <opt> option 2 </opt> … <decide>

四个设计要点:

  1. 问题隔离:attention mask 让每个问题只读得到 state 和它自己,读不到其他问题;每个问题的 position ID 在 state 之后重新起算。state 只编码一次,各问题独立作答。官方测试里「一起问」和「分开问」的概率差异在 fp32 下仅 4e-6。
  2. 指针头打分:每个选项的 </opt> 隐状态与问题的 <decide> 隐状态做内积,softmax 成概率。<decide> 排在最后,能看到完整选项表。
  3. 混合底座的特例:Qwen3.5/3.8 混入了 Gated DeltaNet 循环层(无视 attention mask),所以现行 Kev 把每个问题作为独立行(state + 该问题)跑,state 的 KV cache 复用——隔离是精确的,不是近似的。
  4. 训练目标:正确答案上的交叉熵,只训适配器 + 指针头;训练样本与 API 请求同一种文本格式;官方明确声明没有用任何 Jev 输出做蒸馏。

默认校准:每个 checkpoint 附带在留出数据上拟合的温度。以 Kev-9B 为例,校准把它的「自信地错」(错误但概率 ≥0.9)从 8.7% 压到 4.0%,约等于 Jev 的 3.7%。设 KEV_TEMPERATURE=1.0 可关。

一个真实接入架构(我在知识图谱项目里的用法)

Kev 不是用来替代 RAG 的,它适合放在召回之后的精排位。我的链路:

用户查询 ──▶ 意图解析 ──▶ 约束性查库,召回候选节点
        │
beam 多跳导航:每跳 prefilter 召回候选(图共现 + FTS 两通道)
        → 取分数前 5(max_options)
        → Kev choice:5 选 1 精排(本地 kev.serve HTTP 服务)
        → 判断是否到达目标,未到达则继续下一跳

三条接入纪律,每条都是踩坑换来的:

  1. 预筛精排分工,不裸喂大选项集。我的 0.6B 模型只在「5 选 1」任务上训过,直接喂 255 个选项是分布外滥用——召回层负责粗排,Kev 只做它被训练来做的判断。
  2. 训练-运行问法严格同源。训练数据里问题怎么措辞,运行时就必须逐字一致(建议直接共用同一个字符串常量)。我踩过的坑:训练问「哪首同作者」,运行问法稍有漂移,模型学到的是「选名气大的」——rank 实验里选中项的知名度倍数高达 20.9 倍,改齐问法后回落到 1.0。
  3. 失败降级不抛错。HTTP 不可达 / 解析失败 / 候选不足时回退基线启发式,并留 fallback_count 让降级对用户可见。