通义千问3.5(Qwen3.5)与杰玛4(Gemma 4)的微调模型杰夫(Jeff)用于零样本分类,是能嵌入代码的小型快速决策模型,请求格式与基夫(Jev)相同。你描述情境列出选项,杰夫(Jeff)单次前向传播返回校准概率,无生成解析,在 RTX PRO 6000 上约22毫秒,Apple M4 Max (MLX) 上约28毫秒。零样本指选项任意,类别无需在训练数据中。
正文
Jeff 是把 Qwen3.5 和 Gemma 4 微调出来的零样本分类模型:小而快,可以直接放进你的代码里,请求格式和 Jev 一样。你只要用日常语言描述情境并列出选项,Jeff 就在一次前向传播中给每个选项返回一个校准过的概率。没有生成文本,也不用解析:在 RTX PRO 6000 上约 22 毫秒一次决策,Apple M4 Max(MLX)上约 28 毫秒。
零样本意味着选项可以是任何东西:客服队列、用户意图、审核标签、语音指令、游戏走法。你的类别不必出现在训练数据里,你描述出来,Jeff 来选。
它是什么,不是什么。 这些模型非常小,只在选项之间做极快且校准良好的判断,很容易嵌进本地代码。在基准测试上它们接近、有时超过 Jev;但在这个规模上,推理能力比不上跑在更大模型上的 Jev。如果零样本精度不够用,用自己的样本做一次短微调会好得多:我们的语音导航微调在单张 GPU 上不到半小时,就把留出集准确率从 31.7% 提到 95.8%。
全部在本地硬件上完成。 训练用一张 RTX PRO 6000 工作站 GPU(0.8B 约 2 小时,2B 约 3.5 小时),所有合成训练数据由开放模型(Qwen3.8-Flash-Next)在两台 DGX Spark 上生成,测试在 MacBook 上做。没有用云 GPU,训练数据里也没有闭源模型的输出;闭源模型只用来抽查一部分合成数据的质量。
独立项目。 Jeff 使用与 Jev 相同的请求格式,但不隶属于 Jev 的开发者 TypeSafe,也未获其认可。训练代码基于开源配方 AutoJev。
Hugging Face 上的模型:Jeff-Qwen3.5-0.8B · Jeff-Qwen3.5-2B · Jeff-Gemma4-E2B
快速上手
先运行 uv sync,下载模型:uv run hf download mstrasser/Jeff-Qwen3.5-0.8B --local-dir checkpoints/jeff-0.8b。NVIDIA GPU 或 CPU 用 PyTorch:JEFF_CHECKPOINT=checkpoints/jeff-0.8b PORT=8765 uv run jeff-serve;Apple 芯片用 MLX(在 Mac 上快得多,仅支持 Qwen 模型):先 uv sync --extra mac,再 JEFF_BACKEND=mlx JEFF_CHECKPOINT=checkpoints/jeff-0.8b PORT=8765 uv run jeff-serve。
请求示例:curl -s localhost:8765/v1/systemone -H 'content-type: application/json' -d '{"model": "jeff-latest", "state": "退款请求:客户说包裹送到时已被压坏,想要退款。", "questions": {"route": {"type": "choice", "instructions": "这该由哪个团队处理?", "criteria": {"1": "退款与支付", "2": "损坏或丢失的包裹", "3": "账户与登录问题"}}, "angry": {"type": "noul", "instructions": "客户生气了吗?"}}}'
每个答案包含各选项的概率、被选中的选项和置信度。三种问题类型:choice(从最多 255 个选项中选一个)、noul(是/否,以概率返回)、score(由你描述的刻度上的一个点)。同一请求里的多个独立问题会一起回答。
基准测试
来自五个公开基准的 4,599 道题,外加 JevBench 的公开 hard 档(105 题,单独计分):

| 基准 | Qwen3.5-0.8B 未训练 | Jeff-Qwen3.5-0.8B | Qwen3.5-2B 未训练 | Jeff-Qwen3.5-2B | Gemma 4 E2B 未训练 | Jeff-Gemma4-E2B | Jev(公布值) | AutoJev-27B(公布值) | | --- | --- | --- | --- | --- | --- | --- | --- | --- | | 总评(5 个基准) | 45.3 | 79.1 | 46.5 | 83.1 | 62.5 | 81.6 | 83.0 | 84.9 | | BBH | 39.5 | 64.0 | 46.0 | 68.0 | 51.3 | 66.4 | 94.3 | 82.8 | | Financial PhraseBank | 36.0 | 96.4 | 53.4 | 96.3 | 86.0 | 96.1 | 77.0 | 84.2 | | JudgeBench | 56.6 | 62.6 | 57.4 | 64.6 | 46.9 | 60.6 | 78.6 | 78.9 | | RAGTruth | 49.1 | 86.1 | 35.9 | 88.9 | 63.8 | 87.4 | 77.3 | 88.9 | | WinoGrande | 49.2 | 68.6 | 52.2 | 79.0 | 51.0 | 77.4 | 90.7 | 83.3 | | JevBench hard(单独) | 36.2 | 47.6 | 45.7 | 53.3 | 41.0 | 48.6 | 73.3 | 70.3 |
加粗表示该行中 Jeff 胜过 Jev 的那一项;粗斜体表示 AutoJev-27B 在该行是所有模型里最好的(RAGTruth 上与 Jeff-Qwen3.5-2B 并列),仅作参考,因为主要对比对象是 Jev。Jev 和 AutoJev 的公布数据是在同一批基准的不同样本上测的。Jeff 的总评来自分类和接地任务,这方面它追平或超过大模型;在推理较重的基准(BBH、JudgeBench、JevBench)上,如这个规模所预期,它明显落后。
游戏:一次零样本测试
为了测试在基准里没出现过的任务上的零样本表现,我们让 Jeff 玩了三款游戏。游戏并非理想的零样本测试,因为游戏状态不是典型的非结构化数据;但它是一种常见又有趣的测试 System 1 模型的方式。每一回合,代码用文字描述局面和合法走法,模型选一个。选项只说明每个走法会导致什么(Frogger:“你会被车撞到,掉一条命”;Doom:“最近的怪物在你的左前方一点”),从不说明哪一步是对的。每组结果是 20 局,随机种子 1234。
| 模型 | Doom,击杀数(用文字给出怪物方向) | Frogger,过街次数(给出后果) | Pac-Man,吃到 98 颗豆中的多少(给出后果) | | --- | --- | --- | --- | | 随机走法 | −0.05 | 0 | 11.2 | | 手工规则机器人 | 6.55 | 10.25 | 94.1 | | Qwen3.5-0.8B,未训练 | 5.0 | 1.0 | 25.8 | | Jeff-Qwen3.5-0.8B | 6.55 | 10.3 | 57.0 | | Qwen3.5-2B,未训练 | 0.55 | 0.05 | 72.1 | | Jeff-Qwen3.5-2B | −0.9 | 6.0 | 41.2 | | Gemma 4 E2B,未训练 | −0.55 | 0 | 3.2 | | Jeff-Gemma4-E2B | 0.55 | 0.15 | 53.2 | | Jev(公布的 Doom 结果) | 6.55(被告知瞄准规则);不给规则时 −0.60 | — | — |
Jeff-0.8B 在 M4 Max 上每步决策 29–49 毫秒;Jev 公布的 Doom 运行每次调用 212 毫秒(走其 API)。两个时间不是在同一硬件上测的。想自己跑:uv sync --extra games,然后用 uv run python -m jeff.games --game doom --player jeff --criteria situation --url http://127.0.0.1:8765 --video --out runs/games/doom.json,Frogger 换成 --game frogger --criteria outcomes,Pac-Man 用 --player rule。
速度与体积
对同样 200 道基准题(每题约 200 个输入 token)逐题测量从原始文本到概率的中位耗时:
| 模型 | 参数量 | 权重(16 位) | NVIDIA RTX PRO 6000 | Apple M4 Max(MLX) | CPU(32 线程) | | --- | --- | --- | --- | --- | --- | | Jeff-Qwen3.5-0.8B | 0.8B | 1.7 GB | 22 ms | 28 ms | 463 ms | | Jeff-Qwen3.5-2B | 2B | 4.2 GB | 24 ms | 60 ms | 708 ms | | Jeff-Gemma4-E2B | 等效 2B(存储 4.6B) | 9.3 GB | 29 ms | —(MLX 只跑 Qwen) | 1.0 s | | AutoJev-27B | 27B | 约 54 GB | 未公布 | — | — | | Jev | 未披露 | 仅 API | 公布的 Doom 运行每次调用 114–212 ms(含网络) | | |
用好它
- 在代码里推理,让 Jeff 做决定。 它是分类器,不是规划器。要说明每个选项会导致什么(“这一步会让你被车撞”);如果让它预测(“两回合后会来一辆车”),它不会比随机好。
- 措辞极其重要。 选项描述要一致:把 Frogger 的目标选项和其他前进选项用同样的词,一局就从 15 次过街变成 23 次。
- 用短的选项键加描述性文本:
{"1": "Engagement letter"},不要用长 ID,既费时间又没有好处。 - 把相互独立的问题放在一个请求里一起问。
- 零样本不够就微调。 用约 1.1 万个应用相关的样本做语音导航微调,单张 GPU 上约半小时,留出集准确率从 31.7% 升到 95.8%,M4 Max 上每次决策约 40 毫秒:
autojev-train --initial-checkpoint <jeff> --epochs 1 ...。 - 按任务选规模。 快速选选项时 0.8B 是甜蜜点:2B 更谨慎,游戏玩得更差,尽管基准分数更高。
自己训练
uv run autojev-mix ... 构建训练集(公开数据、合成数据、泄漏过滤);scripts/train.sh RUN data/mix/public.jsonl data/mix 5e-6 40 Qwen/Qwen3.5-0.8B <revision> --epochs 1;uv run autojev-evaluate --data data/panel.jsonl --local --checkpoint checkpoints/RUN/selected --output runs/eval/RUN.json。
完整流程(本地教师模型生成合成数据、泄漏过滤、学习率扫描、仪表盘)见 scripts/train_all.sh,每个训练来源及其许可证见 docs/data-sources.md。训练配方:全权重微调,一个 epoch,批大小 256,对选项字母做交叉熵,再拟合一个温度做校准;检查点按开发集挑选,绝不用基准面板挑。每个训练家族中至少一半遵循面板的格式约定(只用格式;没有任何面板条目被用于训练)。
注意事项
- 小模型不会推理。 它能做的是在你描述的选项之间快速、校准地选择,不是多步推理。在 0.8B–2B 参数规模上,这对所有模型都成立,不只是 Jeff。
- Jeff-2B 玩游戏比 Jeff-0.8B 差。 未训练的 2B 就比未训练的 0.8B 更避险,我们的训练似乎让这点更严重,还需要进一步调查。
- 基准分数不能预测游戏表现。 未训练的 Gemma 4 E2B 在基准上胜过未训练的 Qwen 模型,游戏却玩得最差:大多时候对,但不可靠。训练修好了它的 Pac-Man(3.2 → 53.2 颗豆),但没修好 Doom 和 Frogger。
- 提示词很重要。 Jev 自己的 Doom 提示词(原始方位数字加瞄准规则)对我们的模型都不管用;用文字说明后果的选项才有效。
- 仅限英文和文本。
历史
Jeff 最初是 Denis Yarats 的 AutoJev(MIT 许可)的一个分叉,那是一个微调 Qwen3.8-27B 以返回 Jev 式决策的开源配方。我们保留了它的核心设计(每次决策一次前向传播、训练出的答案读出、拟合温度做校准),并在其上加上了:小号学生模型(0.8B 和 2B 的 Qwen、Gemma 4 E2B)、带泄漏过滤的本地合成数据流水线、面向领域微调的提示词布局、Apple 芯片上的 MLX 服务、游戏测试和训练仪表盘。原始版权声明保留在 LICENSE 中。
许可
代码:MIT(包括 AutoJev 的)。模型权重:Apache 2.0。Doom 测试框架改编自 jev-plays-doom(MIT)。训练数据:见数据集卡片;每个来源保留自己的许可证,并列在 docs/data-sources.md。我们发布权重和代码,不发布训练数据;有些来源是相同方式共享(CC BY-SA)。
评论
讨论气氛整体正面,多数人对「本地可运行、还能自己微调」的小模型很感兴趣;分歧主轴是精度:一方用 Jev 作标尺,认为 70% 对 94% 的分类准确率不可接受,另一方强调这类模型的定位本就是低延迟的判断器而非推理模型。此外不少人更关心成本与商业化影响,而不是游戏成绩。
认为本地可跑、可微调才是这类模型的真正价值
- 相比只在 API 上提供的方案,模型开源且能用自己的数据继续微调,对实际落地帮助极大(较多人)
- 作者举了自己的例子:0.8B 用于语音导航,单卡约半小时的微调就把留出命令的准确率从 32% 提到 96%,每次决策约 40 毫秒(较多人) > Jev 引发了很多关注,但能在本地运行、还能微调的模型实在太有用了。(@danbrooks)
拿 Jev 当标尺,分类精度的差距不可接受
- 在实际用例中直接对比,准确率只有 70%,而 Jev 是 94%,对分类任务来说这属于不能接受的水平(少数人) > 我在自己的用例里和 Jev 比过,它非常不准,70% 对 94%,做分类这没法接受。(@AgentMasterRace)
小模型是分类器而不是规划器,不该用推理基准衡量
- 作者自己承认多步推理落后:BBH 只有 64–68%,Jev 是 94%;JevBench 困难档约 50%,Jev 是 73%。但他认为这既不意外也不重要,0.8B 到 2B 的模型本来就不会像大模型那样推理(较多人)
- 在他看来关键是定位:把选项呈现对,就能得到每秒 40 次以上的判断,靠的是速度而不是思考(较多人) > 这些都是极快的临场判断器。(@firelex)
关心成本:想要价格对比,也想知道分类到底占多大用量
- 有人直接提出需要价格对比,尤其是面向大众规模运行时的开销(少数人)
- 更进一步的追问是:商用 LLM 的调用里有多大比例其实只是分类?如果企业意识到不需要完整大模型,AI 支出和数据中心用量会发生什么变化(少数人) > 商用 LLM 的用途中,有多大比例其实是分类?(@trebligdivad)
猜测 Jev 的底层机制不是常规的 token 输入
- 出于速度和成本,有评论推测它并不像 LLM 那样逐词读入并建立词间关联,因为那是 O(n²) 的问题,也正是 LLM 规模化后昂贵的原因;这个猜测的起因是 TypeSafe 对 Jev 的技术细节一直保持沉默(少数人)
在问这类能力多久会被前沿模型直接内置
- 有评论直接发问:还要多久,Jev 这类功能就会被前沿模型原生集成(少数人)
有价值的补充
- 模型本身是 Qwen3.5 和 Gemma 的小型开放权重微调版,输入一个情境加一组选项,一次前向传播返回每个选项的校准概率,不做文本生成;2B 在五项基准面板上得 83.1%,Apache 2.0 许可,并提供与 Jev 兼容的 API。
- 作者把所有 Jev/AutoJev 数字的对比前提说清楚了:对方发布的成绩来自同一批基准的另一个样本,不能直接对齐;Jeff 的优势集中在分类式任务(Financial PhraseBank 96%,RAGTruth 86–89%,均高于 Jev)。
- 游戏被当作零样本测试,训练数据里没有任何游戏内容:每回合用文字描述局面和走法,选项只说明走法会导致什么、从不说哪个正确。Doom 每局 6.55 个击杀,与手写机器人和 Jev 公开成绩持平,但 Jev 的提示词直接写明瞄准规则、每次调用约 212 毫秒,Jeff 只被告知「最近的怪物在你左边一点」,约 29 毫秒决策;Frogger 10.3 次过河,与手写机器人(10.25)持平、是未训练基座的十倍;Pac-Man 吃下 98 颗豆中的 57 颗。
- 措辞影响极大:把 Frogger 最后一步的措辞改成与其他前进选项一致(「安全,且离终点近一行」)后,单局过河从 15 次提到 23 次,此前青蛙会一直停在最后一块木头上。
- 更大不一定更好:未训练的 2B 就比 0.8B 更厌恶风险(Doom 里倾向转身远离最近的怪物),训练后又在 Pac-Man 里变得犹豫,这可能是 0.8B 反超的原因。
- 基准不预测实战:未训练的 Gemma 4 E2B 在基准上以 62.5% 胜过两个未训练的 Qwen,却在每个游戏里都表现最差——大部分时候判断正确但不够可靠,实时循环中错误会不断累积。
- 整套流程都在本地完成:一台 RTX PRO 6000 训练,两台 DGX Spark 跑 Qwen3.8-Flash-Next 生成合成数据,MacBook 做测试,通过 Tailscale 用手机全程监控。