LocalJev
一个本地运行的、Jev 兼容的 POST /v1/systemone API,使用 TypeScript 编写、面向 Bun,通过 OpenAI 兼容的 Chat Completions 端点由 DiffusionGemma 提供支持。
默认配置目标为:
- 推理服务器:
http://127.0.0.1:8000 - 模型:
diffusiongemma-26B-A4B-it-4bit - LocalJev API:
http://127.0.0.1:8080
为什么需要桥接
Jev 使用的是类型化决策 API,而非 OpenAI 聊天 API。
OpenJev 实现了 Jev 线上协议,并通过特殊的单步 DiffusionGemma 结构化读取来获取概率。其后端依赖于尚未合并的 vLLM 请求扩展,例如 diffusion_seed_canvas、diffusion_read_only 以及所请求 token 的 logprobs。
常规的 oMLX API 并不暴露这些原语。因此 LocalJev 采取了可移植的方案:
- 将
state和类型化的 Jev 问题转换为分类提示词; - 让 DiffusionGemma 输出 JSON 概率标量/向量;
- 校验完整结果并对格式错误的输出进行重试;
- 归一化向量并计算 Jev 兼容的选项、期望得分以及基于熵的置信度;
- 返回标准的 Jev 响应结构。
这种方式实现了线上协议兼容,但在数学上并不等同于 OpenJev 的 logit 读取。概率是由模型生成/自报的,而非直接从其 logits 中读取。在依赖这些概率做出重要决策之前,请先在你自己的工作负载上评估其校准程度。
使用 oMLX 运行
需要 Bun 1.2+ 以及一个运行中的 oMLX 服务器。
bun install
cp .env.example .env
$EDITOR .env # 替换上游 API 密钥占位符
bun run start
Bun 会自动加载 .env。或者,你也可以在启动服务器之前在 shell 中设置密钥:
# fish
set -gx LOCALJEV_UPSTREAM_API_KEY 'your-local-omlx-key'
# bash/zsh
export LOCALJEV_UPSTREAM_API_KEY='your-local-omlx-key'
LocalJev 监听 http://127.0.0.1:8080。检查所配置的模型是否可用:
curl http://127.0.0.1:8080/ready
发起一次决策:
curl http://127.0.0.1:8080/v1/systemone \
-H 'Content-Type: application/json' \
-d '{
"model": "jev-latest",
"state": "Hi, I have been trying to connect Stripe but keep getting a 403 error.",
"questions": {
"department": {
"type": "choice",
"instructions": "Which team should handle this?",
"criteria": {
"billing": "Payment or subscription issues",
"technical": "Bugs or integration problems",
"sales": "Pricing or account questions"
}
},
"frustration": {
"type": "score",
"instructions": "How frustrated does the customer appear?",
"criteria": ["Calm", "Frustrated but civil", "Very angry"]
},
"urgent": {
"type": "noul",
"instructions": "Does this require an immediate response?"
}
}
}'
使用 TypeSafe SDK
SDK 需要一个 API 密钥值。除非配置了 LOCALJEV_API_KEY,否则 LocalJev 接受任意值。为你的 shell 设置 SDK 环境变量:
# fish
set -gx TYPESAFE_BASE_URL http://127.0.0.1:8080
set -gx TYPESAFE_API_KEY local
# bash/zsh
export TYPESAFE_BASE_URL=http://127.0.0.1:8080
export TYPESAFE_API_KEY=local
from typesafe_sdk import TypeSafeClient
client = TypeSafeClient()
response = client.system_one(
"I was charged twice this month.",
{
"billing": {
"type": "noul",
"instructions": "Is this a billing issue?",
}
},
)
print(response.nouls["billing"].noul)
jev-latest 和 jev-preview 是被接受的别名,因此 SDK 默认值无需更改即可正常工作。
配置
| 变量 | 默认值 | 用途 |
|---|---|---|
LOCALJEV_UPSTREAM | http://127.0.0.1:8000 | OpenAI 兼容的基础 URL,带或不带 /v1 |
LOCALJEV_UPSTREAM_API_KEY | 空 | 发送给推理服务器的 Bearer 密钥 |
LOCALJEV_UPSTREAM_MODEL | diffusiongemma-26B-A4B-it-4bit | 上游模型标识符 |
LOCALJEV_API_KEY | 空 | LocalJev 客户端需提供的可选 Bearer 密钥 |
LOCALJEV_HOST | 127.0.0.1 | 监听地址 |
LOCALJEV_PORT | 8080 | 监听端口 |
LOCALJEV_TIMEOUT | 180 | 上游超时时间(秒) |
LOCALJEV_MAX_INFLIGHT | 2 | 允许的上游并发调用数 |
LOCALJEV_MAX_QUEUE | 64 | 返回 HTTP 529 之前的等待决策数 |
LOCALJEV_MALFORMED_RETRIES | 2 | 对无效模型 JSON 的纠错重试次数 |
LOCALJEV_MAX_OUTPUT_TOKENS | 2048 | 每次补全的输出上限 |
LOCALJEV_QUESTIONS_PER_CALL | 16 | 每次模型调用的分块限制 |
LOCALJEV_OUTCOMES_PER_CALL | 128 | 每次模型调用的选项/得分结果数 |
Bun 会自动加载 .env,因此你也可以复制 .env.example、替换其中的占位符,然后运行服务器。
开发
bun install
bun test
bun run typecheck
bun run smoke # 对所配置的推理服务器进行实际调用
评估不同模型
可重复的对比评测使用公开的黄金标签数据:新闻分类(AG News)、是非型阅读理解(BoolQ)以及五级情感分析(SST-5)。它使用同一个 LocalJev 引擎,在两种实际输入长度下对五个已安装的模型进行测试,比较质量、校准、重试次数和完整决策延迟。
# 快速集成检查(30 次请求,并非有意义的质量样本)
bun run eval --out eval/runs/pilot --limit 3
# 5 个模型 × 120 个标注样本 × 2 种输入长度 = 1,200 次请求
bun run eval --out eval/runs/my-bakeoff
# 无需运行推理即可重新生成已完成或部分完成的报告
bun run eval:report eval/runs/my-bakeoff
需要 oMLX 以及 .env 中的上游密钥;无需运行 LocalJev HTTP 服务器或 Python。有关固定的数据来源、方法、配置、恢复运行方式和局限性,请参阅评估指南。
首次完成的对比评测在 M5 Max 上包含 1,200 次请求。Gemma 4 26B-A4B 和 Qwen3.6 在这个小规模筛选样本中是综合表现最强的候选;报告包含各任务结果、延迟、上下文影响和注意事项,而非断言明确的赢家。
应该改用 LM Studio 吗?
目前对该模型而言不适合。截至 2026 年 9 月 18 日,DiffusionGemma 支持在 lmstudio-ai/mlx-engine#336 和 lmstudio-ai/lmstudio-bug-tracker#2037 中仍被追踪为未解决。报告显示 MLX 后端无法加载 diffusion_gemma,而常规 llama.cpp 后端则报告架构未知。oMLX 已经成功加载并服务你确切的检查点,因此它是当前 Mac 上更好的运行器。
即使 LM Studio 之后添加了普通生成支持,仅更换运行器也不会使结果等同于 OpenJev。运行器必须暴露带种子的扩散画布、只读去噪以及选定 token 的 logits/logprobs。如果 LM Studio 仅提供标准 Chat Completions,LocalJev 可以通过修改 LOCALJEV_UPSTREAM 来使用它,但概率路径仍将是提示词/自报式的。
若要直接获取模型概率,最佳路径是:
- 在 oMLX 的 DiffusionGemma 通道中添加结构化读取原语并在此处使用;或
- 在受支持的 NVIDIA 机器上运行 OpenJev 的修补版 vLLM 后端。