@_avichawla: https://x.com/_avichawla/status/2101563610644496464

X AI KOLs Timeline 工具

摘要

本文介绍了如何使用开源LLMs和SGLang构建本地决策引擎,以实现对固定选项的高效评分和概率分布,而无需生成完整文本,与像Jev这样的系统相比。

https://t.co/kowTjDTq00
查看原文
查看缓存全文

缓存时间: 2026/09/20 07:15

构建你自己的Jev(100%本地部署)

无需重新训练,即可将开源LLM转变为快速的本地决策引擎所需的一切。本文涵盖下一token评分、具有概率分布的固定选项选择、SGLang框架使用,以及在同一模型上对比标准文本生成的实践基准测试。

许多LLM调用并不需要生成新文本。应用程序已知所有可能的答案,只需让模型从中选择其一。

假设一个客服工单写道:“我被重复扣费了,同一订阅扣了两次。”

应用程序需要将其发送给以下三个团队之一:计费团队、技术支持团队或账户访问团队。

常规的LLM调用会让模型生成回答,可能返回一个句子、一个标签或一个JSON对象。应用程序需要等待文本输出,进行解析,然后提取所选团队。

如果所有有效答案都是已知的,这种做法就显得多余。

事实上,更高效的方法是将同一请求视为一个决策过程(这正是Jev所做的)。应用程序向Jev提供工单查询和三个允许的答案,模型则一次性返回每个答案的得分(稍后将详细说明具体实现方式):

在此案例中,计费团队获得了最高概率,应用程序代码可以直观地看到其优势程度。

我们将要复现的正是Jev的这种行为能力。

我们将提供输入查询和允许的答案列表。模型在一次评分请求中将返回决策结果和概率分布,无需生成句子或JSON对象。

虽然Jev是闭源的,但这种推理模式已在多个开源语言模型中实现。

更具体地说,我们将使用SGLang(通过/v1/score接口)来实现该功能,使用Qwen和DeepSeek模型进行测试,并与结构化输出及常规文本生成进行对比。

需要明确的是,本文复现的是推理路径,而非完整的Jev系统。Jev还包含训练和校准工作,这些是评分端点本身不提供的。

固定答案评分与结构化输出的区别

Jev的机制很容易与结构化输出混淆,因为两种方法都限制了应用程序接收的内容,但它们在推理服务器内部执行的任务不同。

对于上述提到的客服工单,结构化输出可能从模型获得如下结果:

指定的schema防止了无效对象的生成,但并未独立完成团队选择。

然而,这还可以进一步优化,因为底层实现中,模型仍然需要逐token生成左花括号、字段名、值和右花括号。生成完成后,应用程序读取team字段。此视频展示了这一过程:

通过评分机制(Jev采用的方式),应用程序可以将三个团队作为有效结果的完整列表提供。服务器可以读取每个结果对应的模型得分,并返回本文前述的概率分布,而无需生成JSON对象。

然后我们可以返回所有三个值(而不仅仅是计费团队),这样应用程序代码可以差异化处理这两种结果:

例如,在上述情况下,两种方式都会选择计费团队。

但第一种情况具有明确的偏好,而第二种情况则几乎持平。应用程序可以自动路由第一个工单,而在必要时将第二个工单转交审核。

此外,模型仅提供这些分数,应用程序代码将根据自身需求设置下游使用规则。

例如,可能要求首选答案的得分超过0.80,并且至少领先第二答案0.20。这些阈值存在于代码中,便于测试和修改。

0.91的值意味着在三个选择中,计费团队获得了91%的概率质量。这并不能证明模型在91%的情况下都是正确的。我们需要带标签的样本来衡量准确性。这正是我稍后将讨论的校准问题。

但在此之前请记住,结构化输出生成的是有效对象。固定答案评分返回的是应用程序已知答案上的概率分布。

LLM如何生成首个输出token

在讨论如何将因果LLM转换为Jev风格模型之前,最好先理解LLM的常规生成步骤。

  • 分词器首先将提示文本转换为token ID序列。
  • 模型处理该序列并为下一个位置生成一个向量。
  • 该向量包含模型词表中每个token对应的数值。例如,Qwen的词表包含数万个token,因此该向量包含数万个数字。

这些原始数字就是logits值。较大的logit表示模型更倾向于选择该token作为下一个续写内容。此时的值还不是概率。

在常规生成过程中,服务器对该向量应用解码规则(如温度参数等),选择一个token并将其附加到提示文本后。

模型随后为下一个位置生成新的词表大小向量。生成/解码过程重复进行,直至遇到停止token或达到输出限制。

但当我们需要进行有界决策时,只需关注第一个向量。

回顾前面讨论的客服路由示例。应用程序接受三种答案:

在提示中,我们可以为每个答案分配一个简短标签:

提示以要求输出一个标签结束。

“标签:”是提示中的最后文本。

因此下一个位置就是模型通常会生成A、B或C的位置。

处理此提示后,模型将为该位置生成通常的词表大小向量。该向量将包含token A的logit值、B和C的logit值,以及词表中所有其他token的logit值。

评分路径随后可执行四个操作:

  • 找到A、B、C对应的token ID。
  • 在向量词表中读取这些位置的三个logit值。
  • 忽略所有其他logit值。
  • 对这三个选定值应用softmax函数。

如果选定的logit值为8.2、5.5和4.8,受限的softmax将产生约0.91、0.06和0.03的结果。我们可以将这些位置映射回计费、技术支持和账户访问。

归一化仅限于声明的选择。我们不是询问A在整个词表中是否有91%的概率。

相反,我们询问的是在应用程序排除所有其他响应后,模型如何在A、B和C之间分配其偏好。

SGLang已经在/v1/score中实现了此操作。

它将提示输入模型,读取请求的token位置并返回其分数。这使我们无需修改Qwen实现或自行提取最终张量。

顺便说一句,答案使用A、B、C而不是直接对“计费”、“技术支持”和“账户访问”这些词进行评分的原因是,可见的单词不一定对应单个token。

例如:

  • “billing”对于一种分词器可能是一个token,对于另一种则可能是多个token。
  • “技术支持”肯定会跨越多个位置。

比较这些短语需要序列评分。模型必须对第一个token评分,将其附加,再对下一个token评分,然后组合得到完整短语的值。长度也会成为比较因素。

但单token标签避免了这个问题。每个选项在相同输出位置由单个词表条目表示,而语义含义仍出现在提示中:

模型在处理提示时读取这些描述。标签只是我们随后检查其logit值的token。

我们仍然需要验证每个标签是否对应单个token。

例如,分词器通常将前导空格作为token的一部分进行编码。因此字符串“A”和“ A”可能有不同的token ID。

聊天模板也可能在答案位置前放置空格或控制token。

为避免此问题,使用模型的聊天模板渲染完整提示。确定在答案位置预期的确切续写内容。将该续写内容发送到/tokenize接口。如果产生除单个token之外的任何结果,则拒绝该标签。

此标签映射保留在评分客户端内。应用程序发送诸如billing和technical_support这样的语义选择。它从不发送token ID,也从不接收A、B或C。这就是公共API保持与模型标签无关的含义。

最后,当列出的选择不是详尽无遗时,答案列表还需要一条逃生路径。

例如,如果一个安全事件到达仅提供计费、技术支持和账户访问的路由程序,受限softmax仍会将所有概率质量分配给这三个错误选择。

为避免此情况,当可能没有一个命名选项正确时,添加OTHER(其他)或ESCALATE(升级)选项。

使用SGLang实现本地评分端点

对于本地示例,我们只需要一个推理服务器。SGLang将Qwen模型加载到GPU内存中,并暴露其原生HTTP端点。我们的Python脚本直接向该服务器发送请求。

完整流程如下:

  • 使用Qwen模型启动SGLang。
  • 将决策编写为带有字母标签的提示。
  • 请求SGLang对这些标签进行分词。
  • 向/v1/score发送一个请求。
  • 将返回的概率映射回选择项。

步骤1:使用SGLang启动Qwen

创建Python环境并安装此处使用的两个包:

然后启动模型服务器:

首次启动会从Hugging Face下载模型。后续启动会重用本地缓存。加载完成后,Qwen保持在内存中,SGLang监听端口30000。

此SGLang进程就是推理服务。在执行下方客户端时请保持其运行。

步骤2:定义选项并构建提示

创建decide(.)py,包含以下代码:

该字典记录每个答案的两种表示形式。

  • A是我们要评分的token。
  • 而“billing”是返回给应用程序的含义。
  • 它们的顺序在分词、评分和结果映射过程中必须保持不变。

此处生成的精确提示如下:

提示在“标签:”处结束。

我们希望获得模型对下一个出现token的评分。我们不请求SGLang生成该token。

步骤3:解析标签token ID

在提示下方添加此代码:

SGLang的/tokenize端点返回Qwen分词器产生的整数ID。我们拒绝任何转换为多个token的标签。评分请求需要为每个答案提供一个词表位置。

对于Qwen/Qwen2.5-0.5B-Instruct,这将打印:

每个列表包含一个整数。因此我们知道每个标签占据一个token。后续评分请求将读取词表位置32、33和34。

此检查也防止我们假设分词在不同模型间是相同的。适用于Qwen的标签在其他分词器下可能会被分割。

步骤4:请求SGLang获取三个概率

接下来添加评分请求:

  • query包含完整提示。
  • 空的“items“表示我们对紧接其后的位置进行评分。
  • “label_token_ids“告诉SGLang从Qwen的词表大小输出中读取哪三个条目。
  • “apply_softmax“将这些条目归一化为概率。

响应包含一个分数列表,因为items中包含一个条目。我们对同一Qwen检查点运行此精确提示,得到:

三个位置对应A、B和C。softmax之前的选定logit值为25.277620、24.498226和21.188837。不同硬件和精度设置下可能出现细微的数值差异。

官方端点参考说明每个返回的列表遵循label_token_ids的顺序。因此我们的第一个分数属于A,第二个属于B,第三个属于C。

步骤5:将模型标签转回决策

用映射代码完成脚本:

现在在第二个终端中运行脚本:

SGLang在/v1/score背后执行该计算。一个SGLang进程对标签进行分词,运行一次Qwen,并返回选定的概率。

在此案例中,计费团队获胜,但概率仅为0.678。要求0.70概率的策略将把此工单转交审核,而非自动路由。该阈值应基于带标签样例的评估来确定。

测量评分延迟与自回归生成的对比

上述单请求示例展示了机制原理。我还构建了一个小型应用程序,测试该机制在多决策场景下的表现。

部署的演示支持多个开源模型,如Qwen 3 4B、Qwen 2.5 0.5B和1.5B、SmolLM2 1.7B、TinyLlama 1.1B和DeepSeek-R1-Distill-Qwen 1.5B。

Jev风格通道调用decision方法:

在decide()方法内,SGLang通过/v1/score接收提示。请求包含A、B和C的token ID。

SGLang运行提示,读取这三个下一token得分,进行归一化,然后停止。响应不包含生成的token。

标准通道在同一引擎上调用generation方法:

此方法将相同的状态、问题和选择发送到/v1/chat/completions。

Qwen生成答案和简短解释,最多32个token。应用程序在前100个字符中搜索允许的选项名称。当解析的选择与存储的标签匹配时,标记该案例正确。

视频对比了我们的100%本地Jev与100%本地LLM生成器在部分案例上的表现:

速度优势立即显现,原因如上所述。

此外,我还基于固定的本地数据集构建了100个案例的模拟。

当前数据集涵盖客服路由、候选人筛选和费用审核。其预期标签使界面能够同时显示速度和准确性。

远程SGLang路径在单个屏障后启动两个工作线程:

屏障同时释放两个工作线程。每个通道按顺序处理各自的案例。Jev风格工作线程在其前一个请求完成后立即发送下一个评分请求。标准工作线程对生成请求也执行相同操作。

因此两个通道同时保持活跃,但我们并未同时发送所有200个请求。SGLang从两个通道接收并发工作,并通过连续批处理进行调度。两种请求类型共享相同的GPU、内存带宽和调度器。

下面的视频展示了Jev与LLM的并排对比:

注意:视频在8秒后被加速,因此LLM请求看起来完成得很快。

两个通道同时开始,使用同一SGLang服务器上的Qwen/Qwen3-4B-Instruct-2507模型。

如何选择正确的方法

评分不能替代生成,因此Jev的方法仅适用于在推理前定义输出空间的应用程序。

兼容的工作负载理想情况下应具有有限的有意义标签集合。每个标签应映射到一个独特的下游操作。

调用方只需标签及其概率分布,而不需要新文本。

结构化输出则不同,它定义了响应的语法,而解码器仍然逐token生成字段名和值。

当无法事先枚举这些值时使用结构化生成,因为评分仅在候选值已知时才移除解码过程。

此图对比了常规LLM解码、结构化输出解码和Jev风格评分:

一个可行的方法是根据所需输出选择推理路径:

  • 当输出内容在推理前未知时,使用生成。
  • 当输出集已知且选择足够时,使用评分。此时首个下一token向量已包含排序信息。返回该排序避免了调用方不需要的自回归循环。

重申一下,本文项目复现了Jev风格的推理机制,但并未复现Jev的权重、RLCD过程或评估框架。

我计划涵盖t

相似文章

@omarsar0: https://x.com/omarsar0/status/2107472222398886011

X AI KOLs Timeline

Omar Santos 提供了一份指南,介绍如何将 TypeSafe AI 的决策模型 Jev 用作 LLM judge 来评估智能体。他展示了相比只看最终回复,读取完整轨迹(工具调用、结果、错误)如何提升生产级评估与监控系统的可靠性和一致性。

Jev 之类的决策模型并未胜过 LLM-as-a-judge 或传统分类器

Hacker News Top

Red Hat Developer 的一篇文章对 TypeSafe AI 的 Jev “System One” 决策模型与基于 LLM-as-a-judge 的护栏以及传统的零样本文本分类器进行了基准测试,结论是:尽管决策模型具备 schema 安全、低延迟和零样本等优势,但它们并没有明确优于这些既有的替代方案。