使用 System One 模型的两种技巧

我最近写过一篇关于 紫杉 的文章,这是一种全新的“系统一”语言模型,它只输出决策——即对用户给出的一组选择题的答案。这意味着它远不如 ChatGPT 这样的传统大语言模型灵活,但作为回报,它的运行速度始终很快。

我们并不确切知道 Jev 是如何工作的。有人说是扩散模型,也有人说是对 Transformer 架构的各种改进,还有人认为是一种全新的模型类型。

但这并不重要。正如我在 给你 中所论证的那样,把任何大语言模型变成一个“系统一”模型并不难。通过将生成单个 token 且具有结构化输出的提示进行批量处理,你就能得到一个始终快速的通用分类器。

我用大约 150 行 Python 代码(其中大部分是错误处理)就实现了一个基础版本供大家试玩 给你

需要注意的是,这并不需要修改模型本身。只要能获取 logits(用于结构化输出),并且能在提示中预先填入数据,你就可以把任何大语言模型变成一个快速的通用分类器。

用这样的模型编程是什么体验呢?在为我的库搭建演示时,我学到了两种值得分享的技术:设定分层目标和锦标赛式采样。

Doom 游戏

以下是 Qwen3-8B 玩 Doom 的画面:

如果你把它和同一模型通过常规工具调用玩 Doom 的 视频 对比,就会发现“系统一”版本的模型动作更多、反应更快。工具调用的模型大约每 600 毫秒做出一次决策,而“系统一”模型则每 190 毫秒批量做出六七次决策:

Qwen3-8B 和 Jev 都是纯文本模型,因此两个演示都需要将游戏状态转化为文本。不过,如果选用一个多模态大语言模型,支持图像(或音频)输入也是轻而易举的事。

目标与子目标

在实现 Doom 演示时我发现,仅仅把游戏输入当作选项提供给模型效果并不理想。一次前向传播——也就是 200 毫秒——足以让模型对当前游戏状态作出反应,但却无法投入足够的算力来推导出当前的短期目标(比如“消灭这个敌人”、“收集这个物品”),并决定去执行它。

按这种方式搭建时,模型会 100% 地按着“射击”键不放(我想这也是理所当然的),然后就在关卡里漫无目的地游荡。

解决办法是定期让模型从一组固定的短期目标中做出选择(比如“收集护甲”、“消灭敌人”),并将该目标纳入每 200 毫秒的常规提示中。

如果你看 Jev 演示中的 Doom 视频,就会发现他们正是这样做的。当我照此调整后,我的模型也开始以更接近人类的方式游玩了。

这是一种很有意思的“系统一”模型使用技巧。从某种意义上说,它相当于传统大语言模型的推理过程,因为它提供了一种在同一问题上投入更多算力的方法。

我可以设想一种实时系统,以这种方式管理多层目标:

  1. 一个每十秒一轮的循环,设定总体战略目标;
  2. 一个每五秒一轮的循环,根据(1)设定战术子目标;
  3. 一个每秒一轮的循环,将当前的战术子目标分解为具体任务;
  4. 一个尽可能快的内层循环(比如每 100 毫秒一次),控制实际激活哪些输入;

这种总体架构对于从事游戏或机器人 AI 开发的人来说应该并不陌生。理论上,你可以用一个真正的大语言模型来替代(1),让它为步骤(2)和(3)生成选项列表。

但在实践中,我怀疑这样做很难做到恰到好处,还不如事先列出所有可能的目标。对于游戏和那些已知明确的任务来说,这种方法完全可行。

维基竞速

我还重写了 Jev 发射站 中的维基竞速演示:模型必须从“棒球”的维基百科页面出发,尽快导航到“太阳”的维基百科页面。你可以观看那个 给你 的视频,不过相比 Doom 演示要逊色一些。

Doom 演示的难点在于让模型足够快速地循环,并坚持执行短期计划。而在维基竞速中,难点则在于规模: “棒球”的维基百科页面上有超过一千个内部链接。

Jev 在单个问题中只支持 255 个选项,我临时拼凑的“系统一”层也是如此。虽然理论上它可以扩展到更多选项,但一旦超过一百个左右,效果就开始变差了。

Jev 的做法是“先独立打分,再做显式选择”的两阶段机制。然而,这种方法在我这里完全不起作用。我认为,Jev 能取得好效果,很大程度上得益于它专门被训练用来给出置信度估计。

Qwen3-8B 给几百个链接都打了同样的最高分,这对解题毫无帮助。结果花了好几分钟才找到一条三四十步的路径连接两个页面。

我改用了锦标赛采样:每次把一百个链接作为候选输入,然后对选出的链接再做一轮筛选。这种方法非常有效。模型找到了理想的三条链路路径(如果你好奇的话,就是“棒球”→“科学美国人”→“业余天文学”→“太阳”)。

如果要在众多选项中寻找最优解,我强烈推荐这种模式。普通大语言模型在相对判断方面远胜于绝对评分。

结语

我仍然对“系统一”模型——这些快速的通用分类器——在构建非聊天机器人型 AI 系统方面的潜力持乐观态度。在实时场景或需要可预测推理时长的用例中,这似乎是一种有意义的、区别于工具调用的替代方案。

正如通用大语言模型往往优于领域专用模型一样,我也认为通用“系统一”模型有时会胜过特定领域的分类器(尽管它们总是更大、更慢)。

我确信各大实验室一定会尝试推出其小型、快速模型的仅限选择版本来参与竞争。如果 Jev 真的获得关注,我们很快就会看到“系统一 Terra”和“系统一 Haiku”,而且我那个临时搭建的“系统一”图书馆 也肯定会迎来“正式版”。

我们现在就应该开始摸索如何用这些模型编写程序的最佳方式。

你可以把“系统一”模型看作通用分类器。不必为每个任务都训练一个新的分类器,直接用“系统一”模型即可。它虽然比定制分类器更大、更慢,却灵活得多,而且你可以通过调整提示来微调,而无需重新训练模型。


  1. 技术上,你也可以给它一个“下一个字母是什么”的选择题,让它表现得像一个普通的自回归大语言模型,但这其实并不奏效。
  2. 我最初用的是 4090 显卡,能做到每 500 毫秒决策一次,但对于 Doom 来说还是不够快。我本可以进一步优化,但为了录制演示,我还是租了十分钟的 H100,把速度提升到了每 190 毫秒一轮。工具调用的 Doom 演示也是在 H100 上录制的,所以两者是公平对比。
  3. 关于如何实现这类选择,这里有一个有趣的研究问题:由于必须由单个 token 来确定,该如何设计?我一开始用索引,但后来发现“标签”(即为每个选项指定一个特定 token)在维基竞速中表现好得多(不过在 Doom 中则不然)。到底要多少个选项时,“标签”才会优于“索引”?当然,你也可以修改模型直接输出选项,但我更喜欢这种完全在推理代码中就能完成的做法,适用于任何大语言模型。
添加评论
点赞收藏
点踩分享查看原文
评论
?
参与讨论