Liquid d1-omni-600M:树莓派上的多模态决策模型实战

Liquid AI 的 d1-omni-600M 是一款不生成文本的多模态决策小模型,用一次前向直接输出分类答案。
Liquid AI 的 d1-omni-600M 是一款 587M 参数的多模态决策模型,它不生成任何文本,而是通过一次前向传播从概率分布中直接读出是/否、选项或分数答案,Q8_0 GGUF 量化后仅约 670 MB。它基于双向编码器 LFM2.5-Encoder-350M 构建,支持文本、图像和音频,但图像与音频不能同时传入,音频仅限 16kHz 英语 30 秒以内。在 Civil Comments 审核任务上它以 95.8 分超越更大的模型,但 Decision Index 仅 15.95,知识类任务表现弱。llama.cpp 已合并支持,通过 /v1/systemone 端点运行。许可证限制年收入 1000 万美元以下组织才能商用,且目前无独立评测和树莓派实测数据。

多数人对大模型的期待是「问答」——你问它答。Liquid AI 的 d1-omni-600M 反过来:它能读文本、看图片、听语音,却拒绝写一个字的回复。模型直接从概率分布中读出答案——是/否、从选项中挑一个、或给一个分数,每次响应里 "output_tokens": 0。
这种设计如果搁在两年前会被认为是「功能缺失」,但用在边缘设备上反而是优势。587M 参数、Q8_0 GGUF 量化后仅 670 MB,llama.cpp 已经合并支持,Pi 5 上一条 llama-server 命令就能跑起来。对内容审核、意图路由、"门口有没有人"这类边缘项目来说,一个灵活的「自然语言分类器」比一个勉强能聊天的小模型实用得多。
d1-omni-600M 到底是什么
Liquid AI 在 10 月 7 日与更大的 d1-3B 一同发布,官方将其定位为「实验性检查点」。根据 HuggingFace 模型卡,这 587M 参数被分成了几个模块:381M 的共享主干加决策头、94M 的 SigLIP2 视觉编码器(来自 LFM2.5-VL-450M)、以及 112M 的 17 层 FastConformer 音频编码器。
它基于 LFM2.5-Encoder-350M 双向编码器构建,而非在解码器上硬接一个分类头。上下文窗口 16,384 tokens,横跨文本、图像和音频三种模态位置。标签支持 15 种语言,涵盖英语、德语、阿拉伯语、印地语、日语和中文。
调用方式很特别:你传入一个「状态」(字符串、任意 JSON 值,或者媒体本身就是输入时传 None),再加一个命名问题的字典。问题只有三种类型——noul(是/否)、choice(从命名选项中选择)和 score(2 到 10 个有序等级)。同一个状态下的所有问题共用一次前向传播,媒体只编码一次。
LFM2.5-Encoder-350M 与双向编码器的意义
理解 d1-omni 的关键在于它并非「解码器架构上硬接分类头」。主流聊天模型(GPT、Llama 等)用的是因果解码器:每个 token 只能看到它左边的内容,天然适合逐字生成。而 d1-omni 基于 LFM2.5-Encoder-350M,这是一个双向编码器——处理一个 token 时它同时看到左右两侧的上下文,因此对「整段文本在说什么」这类判断问题,编码器能在一次前向传播里得到全局表示,而不需要先读完再逐步生成。这正是它能够「一次前向 → 直接读出答案」的架构基础:状态和问题被拼接送入编码器,决策头在共享主干上读取最终表示,输出一个分布。没有自回归循环,也就没有逐 token 的延迟累积。
三种问题类型(noul / choice / score)
原文提到的 noul、choice、score 是 d1-omni 对「问什么」的抽象。noul(no/yes/neutral 之类的二元判断)用于布尔决策,如「这条评论是否违规」。choice 让你提供命名的候选标签,模型从选项中挑一个,适合意图路由(退款 / 咨询 / 投诉)。score 则输出 2 到 10 个有序等级中的一个,把连续强度问题(如紧急程度)离散成有限档位。三者共用同一次前向传播,意味着你可以在一个请求里同时问多个问题而几乎不增加计算成本,输出全部来自同一份状态表示——这是「自然语言分类器」比聊天模型更高效的地方。
「Omni」的边界在哪里
三种模态都是真的,但每种都有明确的限制条件:
- 图像:每次请求可传多张,大尺寸会分块。但一旦附加图像,状态和问题文本会被截断到 896 tokens——这是训练时的限制。
- 音频:单条 16 kHz 单声道片段,最长 30 秒。模型卡明确警告,音频训练使用的是一位英语使用者和助手之间的请求。不要指望它能很好地分类德语语音备忘录。
- 不能同时:一次请求只能携带图像或音频,不能两者兼有,同时传会抛出
ValueError。
这意味着「门铃摄像头画面 + 访客说了什么」这种单次决策场景无法实现,需要拆成两次调用。
基准测试:别只看标题数字
在 Liquid 自家的 Decision Index 0.2.1 上,d1-omni-600M 得分 15.95,d1-3B 是 48.57,Decider 2B 是 28.97。Knowledge 子项得分 8.3。字面理解的话,这很糟糕——对于任何需要世界知识或多步判断的任务来说,确实不行。
但在窄分类任务上,它的表现好得多:
| 基准 | d1-omni-600M | d1-3B | Decider 4B | Decider 2B |
|---|---|---|---|---|
| Civil Comments | 95.8 | 93.0 | 92.8 | 93.6 |
| MASSIVE intent | 86.1 | 87.3 | 88.3 | 81.1 |
| PAWS-X | 79.5 | 76.9 | 69.8 | 59.5 |
| BoolQ | 77.7 | 86.7 | 89.0 | 87.3 |
| SQuAD 2.0 | 74.0 | 85.3 | 76.0 | 67.7 |
| XNLI | 74.7 | 85.0 | 88.6 | 85.0 |
| PubMedQA | 61.3 | 66.0 | 63.3 | 65.7 |
| 均值 | 78.4 | 82.9 | 81.1 | 77.1 |
它在内容审核任务上有全表最高的分数,均值也超过了 Decider 2B,而体积只有后者的四分之一左右。我的判断是:用它做路由、审核、意图检测、"画面里有没有人"这类检查。不要让它回答依赖世界知识的问题。
两个注意事项:所有数字都来自厂商,目前还没有独立评测。Liquid 也没有披露任何速度数据——官方说法是「d1-omni-600M 是早期研究版本,我们不报告推理数据」。博客中提到的亚 50ms 延迟仅适用于 d1-3B。
各量化格式的 RAM 需求
Liquid 和社区都没有发布 d1-omni-600M 的实测 RAM 数据。目前只有文件大小,而对这么小的模型来说,权重体积基本就是全部故事。以下数字应视为下限,需要为激活值留出余量,尤其是分块图像时。
| 格式 | 文件 | 磁盘占用 |
|---|---|---|
| 原始 F32 safetensors | model.safetensors | 2.35 GB |
| GGUF F16 | model 764 MB + mmproj 441 MB | ~1.2 GB |
| GGUF Q8_0 | model 407 MB + mmproj 263 MB | ~670 MB |
| ONNX q8(纯文本) | model_quantized.onnx | 0.41 GB |
| ONNX q4(纯文本) | model_q4.onnx | 0.24 GB |
| ONNX 语音栈 | q8 决策 + q8 音频 + fp16 嵌入 | 0.67 GB |
最大的坑是参考 PyTorch 代码片段——当设备为 CPU 时它会加载 float32,意味着什么都没做就已经占用 2.35 GB 权重。2 GB 的 Pi 直接没戏,4 GB 的板子也很紧张。老老实实用 Q8_0 GGUF。
低量化要格外小心。ONNX 维护者实测发现,4-bit 决策权重会让语音答案的概率偏移最多 0.52,而视觉编码器保持了 fp16 因为 8-bit 会改变答案。Liquid 自己的模型卡也建议 GPU 上避免 bfloat16,它会在 0.8% 的文本和 1.7% 的音频行上翻转首选答案。对分类器来说,首选答案翻转就是整个输出的改变,所以我建议守在 Q8。
GGUF、量化与 Q8_0 的含义
GGUF 是 llama.cpp 使用的模型文件格式,把权重、元数据和可选的多模态投影层(mmproj)打包在一起,便于在 CPU 上直接 mmap 加载。量化则是用更低位宽表示权重:原始权重是 32 位浮点(F32),F16 是 16 位半精度,Q8_0 约等于 8 位整数并附带一个缩放因子,Q4 则更激进地压到 4 位。位宽越低文件越小、内存越省,但数值误差越大——对判决输出这种「首位答案翻转即全局改变」的场景,误差会直接变成错误的分类。Q8_0 常被当作精度与大小的平衡点,也是原文推荐在 Pi 上使用的原因。
mmproj 与「激活值余量」
GGUF 分两个文件:model 是语言主干与决策头,mmproj 是多模态投影层(视觉/音频编码器到共享空间的映射)。文中表格把两者相加得到磁盘占用,但实际运行时还需要空间存放中间激活值(尤其是图像分块后 token 数上升,注意力与 FFN 的中间张量随之变大),所以文件大小应视为内存需求的下限。此外,文件大小不等于峰值内存:加载时可能有临时缓冲,量化数据解包也需要少量额外开销,留出 20%~30% 余量是稳妥做法。
为什么 bfloat16 会翻转答案
bfloat16 只有 8 位尾数,精度低于 fp16 的 10 位。对于大型模型,这点误差通常被冗余参数平均掉,但对只有 587M 参数、直接输出离散决策的模型,微小的 logit 扰动足以让两个接近的候选交换顺序,于是「首选答案」发生翻转。模型卡建议 GPU 上避免 bfloat16,正是基于这类实测:文本约 0.8%、音频约 1.7% 的行会改变首选结果。对分类器而言,这相当于 1% 左右的随机错误率,往往不可接受。
三种运行方式:llama.cpp、transformers 或浏览器
llama.cpp 在 PR #30114 中合并了支持(10 月 8 日),需要比这更新的构建。答案来自专用的 /v1/systemone 端点,不是 chat completions:
llama-server -hf LiquidAI/d1-omni-600M-GGUF:Q8_0 -b 4096 -ub 4096
curl http://127.0.0.1:8080/v1/systemone -H "Content-Type: application/json" -d '{
"state": "I was charged twice this month, please refund one of them.",
"questions": {
"refund": {"type": "noul", "instructions": "Is the customer asking for a refund?"},
"urgency": {"type": "score", "instructions": "How urgent is this?",
"criteria": ["Can wait", "Today", "Blocking the customer now"]}
}
}'
不要跳过 -b/-ub 参数:整个问题在一次批处理中读取,批大小必须容纳它。4096 覆盖任何图像,长状态可以加到 16384。另外留意 PR #30261(截至写作时仍开放):它改变了 llama.cpp 为 LFM2 系列模型(含 d1-omni)选择图像分块网格时的舍入方式,使其与 Python 参考一致。在合并之前,某些图像尺寸可能产生与 transformers 不同的 token 数。
用 transformers 需要 transformers>=5.15 和 trust_remote_code=True,然后调用 model.system_one(state, questions, images=..., audio=...)。桌面端没问题,但对小板子太重了——原因见上面的 RAM 分析。
浏览器方案通过 onnx-community 的移植版、transformers.js 和 open-jev 库在 WebGPU 上运行。官方报告在 M3 Pro 的 Chrome 中约 60ms/问题,笔记本 CPU 上 130 到 230ms/问题。笔记本 CPU 的数字是目前能找到的最接近 ARM 板子的公开参考。社区还有 Core ML、MLX 和 LiteRT 转换版本。
/v1/systemone 端点与批处理参数
llama-server 通常暴露 /v1/chat/completions 这类自回归生成接口,但 d1-omni 不生成 token,因此 llama.cpp 为它新增了专门端点 /v1/systemone(来自 PR #29818)。请求体里的 state 是待判断的内容,questions 是以名称为键的问题字典。由于所有问题共用一次前向,服务端必须要把整个输入放进同一批处理中,这就是 -b(逻辑批大小)和 -ub(微批大小)需要设置到 4096 的原因——如果批太小,长输入或图像会被截断或读取失败。
transformers.js、WebGPU 与 ONNX 移植
浏览器路径不依赖 llama.cpp,而是走 onnx-community 提供的 ONNX 权重,经 transformers.js 在 WebGPU 上运行,open-jev 负责封装推理流程。ONNX 是一套跨框架的模型交换格式,能让同一份权重在不同运行时(PyTorch、浏览器、移动端)执行。WebGPU 让浏览器直接调用 GPU,M3 Pro 上约 60ms/问题;退回到 CPU 时 130–230ms/问题。原文指出笔记本 CPU 的数字是「最接近 ARM 板子的公开参考」,因为 Pi 5 的 CPU 性能与之同一量级,且推理没有生成循环,负载特征相似。这为估算树莓派延迟提供了间接依据,但仍需实测确认。
树莓派到底能不能跑
没人发布过 Pi 基准,任何给你 tokens/秒 数字的人都是猜的——而且 tokens/秒 在这里根本不适用。每次调用就是一次前向传播,没有生成循环,这恰好是弱 CPU 劣势最小的负载类型。
基于以上数据,我的结论:
- Pi 5 配 4 GB 以上内存,Q8_0 GGUF,文本或音频决策:今天就可以试。内存装得下还有富余。
- Pi 上跑大图:分块会推高 token 数,延迟随之上升。发送前先降分辨率。
- 任何需要事实或推理的任务:选错模型了。15.95 的 Decision Index 和 8.3 的 Knowledge 分数就是在说这件事。
许可证的细节
博客说「无限制」,但实际的 LICENSE 是 LFM Open License v1.0,第 5 条规定只有当组织年收入低于 1000 万美元时才授予商业使用许可。业余项目和多数初创公司没问题。如果你在大公司,把模型装进产品之前先找法务确认。
我的看法:d1-omni-600M 是今年最有趣的小模型,因为它放弃了生成,把一件事做好。仅支持英语的 30 秒音频和只有厂商数据的现状让它暂时还停留在「实验」范畴。
LFM Open License v1.0 的商用门槛
该许可证名为「开放」,但并不等同于 Apache 2.0 或 MIT 那样的无限制许可。第 5 条规定,只有在组织年收入低于 1000 万美元时才自动获得商业使用授权;超过这一门槛,商用需要单独与 Liquid AI 协商。这意味着个人项目、早期初创公司和研究用途基本不受影响,而大企业将模型嵌入产品或服务前,必须先获得额外授权。此外,许可证通常还要求保留版权声明、不得移除许可文件,并对再分发设有限制。原文建议「大公司先找法务」,正是因为这条收入门槛把「商用自由」变成了有条件的授权:收入规模不同,法律地位完全不同,误判可能带来合规风险。
参考来源
相关推荐

WorkBuddy全流程教程:从零搭建AI办公自动化智能体
WorkBuddy 全流程教程精讲:从下载安装、三种工作模式到多模态绘本视频实战,再到专家团搭建智能体与工作流配置,帮你用低成本 AI Agent 实现办公自动化。

WorkBuddy智能体全攻略:7天从入门到自动化实战
基于B站256集WorkBuddy全套精讲课程,系统拆解腾讯AI办公工作台的核心能力:Agent原理、Skill封装、连接器跨平台、定时自动化、知识库与零代码开发,附学习路径建议。

8个AI账号翻车7个:我用AI干活的真实复盘
B站8个AI运营账号仅1个跑通。本文拆解"演AI"与"用AI干活"的本质区别,分析5条视频217万播放背后的产能控制、评论区运营和交付节奏策略。