一天一个开源项目(第225篇):NanoJev —— 一个 0.6B 的并行决策模型,让 LLM 直接输出概率分布而不是生成 Token

0 阅读10分钟

引言

"决策不需要生成一段话来解释自己,它只需要一个概率分布。"

这是"一天一个开源项目"系列的第 225 篇。今天的项目是 NanoJev

大多数用 LLM 做决策的方案都绕不开一个尴尬的效率问题:让模型自回归地生成一段文本(比如"我认为应该选择选项 B,因为……"),再从文本里解析出最终决策。这个过程需要逐 Token 解码,慢、贵,而且模型给出的"置信度"往往只是文本里顺嘴一提的形容词,不是真正校准过的概率。

如果一个任务的本质就是"给定状态和一组候选项,告诉我每个候选的概率",为什么还要让模型先生成一堆文字再解析?NanoJev 的答案是:不生成,直接输出分布。它是"Jev"这套并行决策模型系统的轻量复刻版,基于 Qwen3-0.6B 骨干网络加上专门的决策头,输入状态和问题,一次前向传播直接吐出完整的概率分布——零输出 Token 解码。

954 Stars,MIT 协议,用迷宫导航和 Snake 游戏基准验证了这套思路的实际效果。

你将学到什么

  • NanoJev 如何用"状态+问题+候选集"三元组结构化一个决策
  • 三种决策头类型:动态选择(Choice)、布尔判断(Boolean)、有序评分(Score)
  • 为什么"零输出 Token 解码"比自回归生成更适合决策场景
  • 完整的训练流程:构建查询 → 数据整理 → 训练 → 评估 → 服务
  • NanoJev 与原版 Jev、未微调 Qwen3-0.6B 在游戏基准上的实测对比

前置知识

  • 了解 LLM 的基本推理机制(自回归生成 vs 单次前向传播)
  • 熟悉基础的概率与分类/回归任务概念
  • 可选:了解强化学习中的奖励建模概念

项目背景

项目简介

NanoJev 的官方定义是:"一个 0.6B 参数的并行决策模型。状态和问题输入,完整的概率分布输出——零输出 Token 解码"(A 0.6B parallel decision model. States and questions in, complete probability distributions out—with zero output-token decoding)。

需要澄清的是,这不是图像生成或编辑工具,而是一个结构化决策模型/推理框架——本质上是把 LLM 的语言理解能力保留下来,但把输出端从"生成文本"改造成"输出校准过的概率分布",适用于游戏智能体决策、概率校准研究等场景。

团队与项目信息

项目数据

  • ⭐ GitHub Stars:954
  • 🍴 Forks:127
  • 👀 Watchers:8
  • 📄 协议:MIT
  • 📊 提交次数:13 Commits

主要功能

解决什么问题

传统 LLM 决策方案:
  状态+问题 → 自回归生成文本("我认为应该选B,因为……")
  ↓ 解析文本得出最终决策
  ↑ 逐 Token 解码慢且贵
  ↑ "置信度"只是文本里的形容词,没有真正校准

NanoJev 的做法:
  状态+问题+候选集 → 单次前向传播 → 直接输出完整概率分布
  ↑ 零输出 Token 解码,速度快
  ↑ 分布经过训练校准,可直接用于排序/贪心选择/概率采样
  ↑ 单次前向可批量处理多个独立状态和问题
     (官方示例:"6 states · 18 questions · 44 candidate paths · 1 backbone forward"

使用场景

  1. 游戏智能体决策

    • 迷宫导航(8×8 到 50×50 多种规模)、Snake 贪吃蛇游戏的实时决策
  2. 局部安全判断

    • 碰撞规避等需要快速布尔判断的场景,结合代码规划一起使用
  3. 概率校准研究

    • 用 CE(交叉熵)/Brier 损失和成对正确奖励学习做概率校准实验
  4. 需要批量决策的场景

    • 一次前向传播评估多个候选路径,适合需要高吞吐决策的应用

快速开始

最简单的方式:本地跑交互式演示(不需要模型权重)

git clone https://github.com/TianyuCodings/NanoJev.git
cd NanoJev
python3 -m http.server 8080 --bind 127.0.0.1 --directory web

访问 http://127.0.0.1:8080/side-by-side.html 查看三面板对比演示,或 arcade.html(竞技场演示)、comparison.html(早期基准查看器)。

完整运行:下载模型权重并启动服务

# 安装依赖
python -m pip install -r requirements-toy.txt

# 下载模型检查点和数据集
python -c "
from huggingface_hub import snapshot_download
snapshot_download(
    repo_id='C-Tianyu/NanoJev', local_dir='checkpoints/NanoJev',
    allow_patterns=['best.safetensors', 'config.json', 'tokenizer/*', 'backbone_config/*'],
)
snapshot_download(
    repo_id='C-Tianyu/NanoJev-Data', repo_type='dataset', local_dir='data/NanoJev',
)
"

# 启动持久化服务
python scripts/serve_decisions.py \
  --checkpoint-dir checkpoints/NanoJev \
  --web-root web --port 8765

服务启动后加载模型一次,通过 POST /api/evaluate 接受重复的批量决策请求。

核心特性

1. 三种决策头类型

类型支持范围机制
动态选择(Choice)2–255 个候选项共享标量头 + 集合注意力机制,输出每个候选的概率
布尔判断(Boolean)单一命题单路径 sigmoid,输出命题为真的概率
有序评分(Score)2–10 档评分计算等级分布的概率加权期望值

2. 三元组结构化决策

每个决策由状态(state)问题(question)、**候选集(candidate set)**三部分定义。共享的决策头处理输入并针对候选集返回相应类型的分布输出。

3. 五步训练流程

构建查询(Build queries)
  ↓ 生成状态、问题、候选描述及目标分布
数据整理(Organize data)
  ↓ 相关地图、规则及变体保持在同一数据划分中
训练(Train)
  ↓ Qwen3-0.6B 初始化 + 决策头预热 + complete-question distribution losses
评估(Evaluate)
  ↓ 衡量概率质量 + 游戏控制器记录实际动作
服务与可视化(Serve and visualize)
  ↓ 复用持久化模型端点,浏览器回放完整轨迹

4. 多种预训练检查点变体

变体名称用途
variants/local_atomic_seed1750×50 迷宫演示
variants/games_gold_seed17Snake 演示
variants/games_api_seed17完整地图对比基准
variants/events_ce_seed17 / events_brier_seed17 / events_paired_seed17校准决策实验(不同损失函数)

深入剖析

"零输出 Token 解码"的性能意义

NanoJev 最核心的架构决策是彻底放弃自回归生成,把 LLM 的输出端改造成结构化的决策头。这个改造带来的性能差异,官方给出了一个很直观的数字:

"6 states · 18 questions · 44 candidate paths · 1 backbone forward"

意味着:
  6 个独立状态 + 18 个问题 + 44 条候选路径
  ↓ 全部塞进一次骨干网络前向传播
  ↓ 而不是 44 次自回归生成

自回归生成的开销是逐 Token 累积的——生成一段解释性文字可能需要几十到上百次前向传播(每个 Token 一次)。NanoJev 把 44 条候选路径的评估压缩进"1 次骨干网络前向",本质上是把"用文本表达置信度"这件事换成了"用模型内部的数值直接表达概率",绕开了整个自回归解码的开销链条。

Choice / Boolean / Score 三种头的设计取舍

为什么不用一个通用头处理所有决策类型?三种头对应的其实是三类本质不同的统计问题:

Choice(动态选择):
  候选数量可变(2-255个)→ 需要"集合注意力"机制
  ↑ 模型要理解"这些候选是互斥的一组选项",而不是独立判断

Boolean(布尔判断):
  单一命题,是/否二元问题 → 单路径 sigmoid 就够了
  ↑ 不需要感知其他候选的存在

Score(有序评分):
  等级之间有顺序关系(1星到5星)→ 不能简单当分类问题处理
  ↑ 用概率加权期望值,让"3.5星"这种非整数期望自然产生

这个设计体现了一个朴素但容易被忽视的原则:决策的统计结构不同,损失函数和输出头也应该不同。把"选哪个选项""是否为真""打几分"强行塞进同一个 softmax,会丢失每种问题类型本身的结构信息。

训练效果的实测对比:小模型 vs 微调

NanoJev 在三个游戏基准上和原版 Jev、未微调的 Qwen3-0.6B 做了对比,结果颇有说服力:

基准NanoJevJev(原版)未微调 Qwen3-0.6B
50×50 迷宫(尝试次数/碰撞次数)244 次 / 36 次碰撞,到达目标2,738 次 / 1,044 次碰撞,到达目标
12×12 Snake(食物数/存活)27 个食物,存活到终点30 个食物,存活到终点25 个食物,被困
40 地图导航基准(测试集/OOD)95% / 90%100% / 95%35% / 15%

几个值得注意的点:

  1. 未微调的 Qwen3-0.6B 表现明显落后(35%/15% vs NanoJev 的 95%/90%),说明专门训练的决策头确实带来了实质性提升,不是"换个模型名字"的营销包装
  2. NanoJev 在 50×50 迷宫上尝试次数远少于原版 Jev(244 次 vs 2,738 次),说明轻量复刻版在特定任务上反而更高效,这可能得益于任务范围更聚焦的训练数据
  3. NanoJev 整体精度略低于原版 Jev(比如导航基准 95% vs 100%),符合预期——用更小的资源投入复刻一个系统,性能上有所取舍是合理的权衡

定位:研究性复刻,不是商业产品

NanoJev 明确把自己定位为"轻量级、可复现"的研究性替代方案。这个定位很清晰:它不追求超越原版 Jev 的性能,而是用更小的训练成本和更简单的部署方式,让更多研究者能够验证和扩展"并行决策模型"这个思路。路线图里提到的扩大数据规模、RLCD(对比蒸馏强化学习)扩展等方向,都指向"继续探索这套架构的边界"而不是"打磨成产品"。


项目地址与资源

官方资源

相关资源

  • Qwen3 — NanoJev 使用的 0.6B 骨干网络
  • Brier Score — NanoJev 训练中用于概率校准的评分方式之一

总结与展望

核心要点回顾

  1. 零输出 Token 解码:抛弃自回归生成,用决策头直接输出概率分布,规避逐 Token 解码的性能开销
  2. 三元组结构化决策:状态+问题+候选集,清晰界定每一次决策查询的边界
  3. 三种决策头各司其职:Choice/Boolean/Score 对应不同的统计问题结构,而非强行统一到单一 softmax
  4. 实测验证有效:在迷宫导航和 Snake 游戏基准上,相较未微调 Qwen3-0.6B 有显著提升,相较原版 Jev 有合理的性能权衡
  5. 研究性定位:明确是轻量复刻而非商业产品,服务于"并行决策模型"这一方向的进一步探索

适合谁

  • 游戏 AI / 智能体决策研究者:需要一个轻量、可复现的并行决策模型基线
  • 关注 LLM 效率的研究者:对"跳过自回归生成,直接输出结构化分布"这类架构改造感兴趣
  • 概率校准方向的研究者:想研究 CE/Brier 损失和成对奖励学习在决策场景下的实际效果
  • 教学/复现型学习场景:想理解"决策头+骨干网络"架构而不想从零训练大规模系统

一句话评价

NanoJev 提出一个值得深思的问题:如果任务的本质是输出一个概率分布,为什么还要绕道生成一段文字?


欢迎访问 PrimeSkills —— 一个精心策划的 AI Agent 与技能市场,所有内容均经过真实企业级工作流验证。没有噱头,只有真正有效的东西。

更多实用知识和有趣产品,欢迎访问我的个人主页