TheoLeeCJ/openjev · 上手攻略

  • 仓库:TheoLeeCJ/openjev
  • 链接:https://github.com/TheoLeeCJ/openjev
  • 分类:LLM 应用 · 决策推理
  • 作者:Tom
  • 更新:2026-09-18

这是什么

OpenJev 是一个开源项目,试图在消费级 GPU(RTX 3090)上复现 TypeSafe 的 Jev 服务——一种语义决策操作符(semantic decision operator)。它的核心思路是:不让模型生成文本,而是直接读取模型在固定 answer token 上的 logits,经过一次 softmax 得到每个选项的概率。

⚠️ 本仓库复现的是 Jev 的接口模式,不是 Jev 使用的闭源模型或训练方法。README 明确注明"This project reproduces that interface pattern with open models; it does not reproduce Jev's undisclosed model or training."

官方提供了浏览器在线 demo(https://openjev.com,无需排队,随时可用),也可以在本地运行。仓库自带完整的测试 fixture、基准脚本和原始结果数据,结果可复现性在开源项目中属于较高水平。

工作原理简述

S[Unstructured state] --> M[4B model]
C[Runtime criteria]    --> M
O[Typed options]       --> M
M -- native option logits --> P[Probabilities]

Direct 模式下,系统将 state(任意非结构化文本/JSON)、criterion(自然语言问题)和 options(带 ID 和描述的选项列表)一起拼入 prompt,做一次原生前向传播,然后只在预设的固定大写字母 answer token 上读取 logits,应用 softmax 得到各选项概率。整个过程不采样任何 token,解码循环为零。


解决什么问题

在软件系统中嵌入 LLM 做决策,通常要走"生成 → 解析 JSON/文本 → 执行"这条路。三个经典痛点:

  • 延迟高:即使答案只有几个字,也要完整跑一个解码循环,21 个二分类问题用传统生成方式中位数 5.3 秒
  • 成本高:每次决策都是一次完整 token 生成,GPU 算力消耗大
  • 不稳定:生成文本格式可能出错,需要额外的 JSON repair 兜底,甚至要用另一个 LLM 来解析输出

OpenJev 的方案:一次前向传播,直接读 typed option logits,不采样任何 answer token。21 个二分类问题只需约 1 秒(Qwen3.5-4B),输出直接就是概率值,软件可以直接拿来当 if 条件用,无需任何解析层。

在 37 state × 21 criteria 的真实负载下,开启并行 suffix 优化后吞吐量可达 20 decisions/秒,相比从头重新计算提速约 10 倍。


快速安装

环境要求

  • Python 3.10+
  • CUDA + GPU(能装下 4B BF16 模型,推荐 RTX 3090 或更高)
  • 硬盘空间(Q4_K_M 量化版模型约 3 GB,原生 BF16 约 8 GB)

安装步骤

# 克隆仓库
git clone https://github.com/TheoLeeCJ/openjev.git
cd openjev

# 创建虚拟环境
python -m venv .venv
source .venv/bin/activate

# 设置 HuggingFace 模型缓存目录(指向有足够空间的大容量盘)
export HF_HOME=/path/to/large-drive/huggingface

# 安装(含测试依赖)
pip install -e '.[test]'

直接跑官方示例

CUDA_VISIBLE_DEVICES=0 openjev-score \
  --mode direct \
  --model Qwen/Qwen3.5-4B \
  --revision 851bf6e806efd8d0a36b00ddf55e13ccb7b8cd0a \
  --input examples/decisions.jsonl \
  --output results.jsonl

⚠️ 模型 revision 必须精确指定(851bf6e...),README 强调要用 exact revision 来保证结果可复现。

输入格式(decisions.jsonl 示例)

{
  "id": "route-1",
  "state": "Customer cannot access an account after a password reset.",
  "question": "Which queue should handle this request?",
  "options": [
    {"id": "access", "description": "Account access support."},
    {"id": "billing", "description": "Billing support."}
  ]
}

state 可以是任意非空字符串,也可以是结构化 JSON 对象或数组。Direct 模式会保持 JSON 结构原样传给模型。

三种打分模式

# 模式1:每个选项独立前向传播(默认)
openjev-score --mode direct ...

# 模式2:共享 state,prefetch 一次后并行评估多个 criteria(适合 37×21 这类场景)
openjev-score --mode shared ...

# 模式3:reranker 模式(基于 Qwen3-Reranker-4B)
openjev-score --mode reranker ...

三种模式的选择建议:通用决策场景用 direct;单一长文本需要过大量 criteria 时用 shared;检索 ranking 场景用 reranker


核心用法

Python API

from openjev import score

result = score(
    state="Customer cannot access an account after a password reset.",
    question="Which queue should handle this request?",
    options=[
        {"id": "access", "description": "Account access support."},
        {"id": "billing", "description": "Billing support."}
    ],
    model="Qwen/Qwen3.5-4B",
    revision="851bf6e806efd8d0a36b00ddf55e13ccb7b8cd0a",
    mode="direct",
)

# result 包含: probabilities, timing, model_revision, prompt_hash
print(result.probabilities)  # {"access": 0.87, "billing": 0.13}

共享 state 批量评估(省显存)

当有一个长 state 要过很多条 criteria 时,用 --mode shared 只 prefetch 一次,然后并行对每个 criterion 做 suffix 计算:

openjev-score \
  --mode shared \
  --model Qwen/Qwen3.5-4B \
  --input multi-criteria.jsonl \
  --output results.jsonl

该模式在 shape777(37×21)负载下达到 20 decisions/秒,而 fresh direct 模式只有 2.33 decisions/秒。

基准测试命令

仓库自带了完整的评测 fixture,可以复现报告中的数字:

# shape777 评测(37 state × 21 criteria)
python benchmarks/shape777.py --mode direct
python benchmarks/shape777.py --mode shared
python benchmarks/shape777.py --mode reranker

⚠️ README 提示 fast reuse 路径是实验性的,BF16 执行会改变 5–6/777 个 argmax 结果,涉及关键决策时不要用。

查看完整结果文件

所有原始结果(含 timing、predictions、checksums)都在 results/raw/ 目录下,machine-readable 汇总在 results/phase1-summary.json


典型适用场景

  1. 客服工单自动路由:根据工单内容直接输出部门概率分布,不走 API 调用链路,延迟 <1 秒
  2. 内容安全/合规判断:在数据处理 pipeline 中内嵌实时判断,延迟敏感型场景(1 秒级别),无需生成式解码
  3. 规则引擎增强:当规则无法覆盖的边界情况出现时,用 semantic decision 兜底,概率直接参与业务决策
  4. 多指标并行评估:一个 state 同时过几十个评估维度(shared 模式),如贷款审批的多维度评估
  5. 本地化决策服务:不方便调用外部 API、要求数据留本地的场景,纯本地 GPU 推理
  6. Agent 动作预筛:在 Agent 执行动作之前,用 OpenJev 快速预判各动作的可行性,减少无效动作执行

质量数据一览

浏览器在线版(量化 GGUF)

模型 量化格式 下载大小 Authored balanced accuracy Perturbation balanced accuracy TypeSafe subset agreement
Qwen3-0.6B Q8_0 639 MB 0.440 0.528 0.407
MiniCPM5-2B Q4_K_M 1.56 GB 0.686 0.693 0.637
Qwen3.5-4B Q4_K_M 3.01 GB 0.813 0.766 0.845
Published Jev 闭源托管 0.883

⚠️ 以上数据均来自 README。Qwen3.5-4B 量化版(Q4_K_M)与原生 BF16 精度有差距,表格中 BF16 精度值来自官方报告,未经本仓库实测验证。

任务维度横向比较

任务类型 Direct Qwen3.5-4B Qwen3-Reranker-4B 说明
Authored 144 rows 平衡准确率 0.813 0.625 核心工作负载
WANLI 256 rows 平衡准确率 0.637 0.522 自然语言推理外部校验
TypeSafe 子集 102 rows 模态一致率 0.845 0.560 与 Jev 官方结果差 3.8 pp
判断网格 36 rows 准确率 0.806 0.694
动作防火墙 10 actions 组合准确率 0.700 0.700 两者持平
代码检索 Recall@1 1.000 1.000 两者均满分
企业知识 Recall@1 0.929 0.929 两者均相同

坑与注意

  1. 选项顺序影响结果:测试中 option reversal 导致 direct model 出现 10 次 flip/reranker 仅 2 次,说明模型对 position 仍有依赖。重要决策不要依赖单一顺序,应做扰动校验
  2. 缺失证据时不可信:missing-evidence 测试集上两个系统都有概率 >0.8 却判断"充分"的情况,概率不能当置信度用——这是一个尚未解决的开放问题
  3. 与 Jev 仍有差距:TypeSafe subset agreement 0.845 vs Jev 0.883,差 3.8 个百分点;且 Jev 结果未经本仓库实测,仅来自公开记录,不是跑出来的
  4. reranker 不是通用决策基座:在检索排序任务上 reranker 和 direct 差不多(MRR=1.0),但在通用决策上反而更差;reranker 只适合做 retrieval control
  5. fast reuse 路径是实验性的:BF16 下有 5–6/777 的 argmax 与 fresh scoring 不同,涉及关键决策时不要用
  6. HuggingFace revision 必须精确:用 exact revision 保证结果可复现,不要用 latest tag
  7. 需要足够显存:4B BF16 模型至少需要 8 GB 左右显存,量化后 Q4_K_M 约 3 GB
  8. 概率不等同于置信度:返回的是 conditional probability,不是 calibrated confidence,在低证据场景下会给出虚高的置信度

与同类对比

方案 是否开源 延迟 精度(平衡准确率) 适用场景
OpenJev direct (本仓库) ✅ 完全开源 ~1s/21 decisions 0.813 本地/实时/批量决策
OpenJev shared (本仓库) ✅ 完全开源 ~20 decisions/s 高吞吐多 criteria 场景
TypeSafe Jev ❌ 闭源托管 未知 0.883 需要最高精度
传统 LLM 生成 + JSON 解析 ✅ 取决于模型 ~5s/21 decisions 取决于模型 通用但慢
Qwen3-Reranker-4B reranker ✅ 开源 1.86 d/s 0.625 (通用决策差) 仅检索排序

核心差异:OpenJev 不生成 token,这是它快 5 倍的根本原因。Direct 模式和生成式基线(ordered JSON array)在同一硬件上对比:前者 1.023 秒 0 token,后者 5.332 秒 111 tokens,5.2 倍延迟差距。


一句话推荐

想要本地毫秒级、可复现、软件内嵌的语义决策能力,OpenJev 是目前最干净的开源方案——直接读 logits 不解码,RTX 3090 就能跑,但离 Jev 官方精度仍有 3–4 个百分点的差距,高精度场景建议在目标数据上做对比评估后再上生产。