Show HN: Needle2 —— 14MB 智能体 LLM,面向手机、可穿戴、智能家居与机器人
尺寸–质量前沿:移动级及以下
我们的判断
把端侧 AI 带进 200 美元以下的设备:"边缘 AI" 近来常指 Mac 和 PC,但边缘的主战场其实是廉价硬件:联网 IoT 设备超过 210 亿台,而 PC 仅有约 15 亿台;在新兴市场,大多数手机的售价不到 200 美元。把廉价手机、Raspberry Pi、微控制器、可穿戴设备、像 Reachy Mini 那样的小机器人以及智能家居设备都算上,大约五分之四的边缘设备价格低于 200 美元。这正是 Needle 的目标硬件:没有 GPU,没有 NPU,RAM 只有几百 MB。
函数调用与设备操控:开一盏灯不需要前沿模型。手表、家居、机器人:它们各自已经把自身能力以带类型参数的形式暴露为函数,唯一难的部分是把一句口语化的指令映射到这些函数上:调用哪个函数、传入什么参数。这样看,问题既不需要世界知识,也不需要开放式文本生成——这就是为什么 4500 万参数就够用,而聊天场景却需要几十亿参数。这个更精简的问题定义,是其他一切判断的出发点。
信息抽取与结构化输出:Schema 就是接口,同一套思路也能覆盖文档处理:给一个 schema 加上一段文字,就能返回带类型的字段;枚举字段就是分类器;数组字段可以一次调用里收集一整个列表。我们用契约而非约定来约束这一点:每一轮回复都必须用调用信封来回答,空调用即为拒绝,由声明的 schema 编译出的字节级语法约束每一个 token。语法负责承载格式,于是全部 4500 万参数都用在挑选函数和从用户原话中锚定参数值上。
边云协同:小模型不可能面面俱到,所以 Needle 坦诚告知:每条响应都附带一个学习到的置信度评分,偏离主题的请求直接返回空调用。评分高于阈值就直接执行;低于阈值就重新询问或上交云端。大多数设备请求都是日常控制类操作,所以触发上云的情况很少,默认路径保持私密、即时、免费。
无损 2bit 量化:小模型经不起事后量化的折腾,所以我们从不事后量化:Needle 2 从预训练到后训练全程针对 Cactus Quants 进行训练,权重、激活值和 KV 缓存无一例外。你部署的 2bit 模型就是训练出来的那个模型。正是这套方法,让 4500 万参数无损压缩到 14MB。
模型与推理协同设计:每一项架构选择都在目标硬件上跑过基准测试,达标后才保留参数,交付物是模型与推理引擎的整体,而不仅仅是权重:一个零依赖的 C++ 二进制,启动时探测 CPU 并自动选取内核,模型、分词器和语法编译器全部封装在内。同一份产物,从 Cortex-M 到 x86 再到 WebAssembly 都能直接运行,无需安装,无需下载。
在 Mac/PC 上微调:每个产品都有自己的工具词汇表,4500 万参数的模型小到可以在运行环境中重新训练:仓库和 Python 包让你在自己的电脑上几分钟到几小时内完成微调与测试。交付一个能听懂你设备工具的 Needle,而非通用助手。
生产落地
Needle 已可投入生产,适合那些对内存占用、延迟、隐私和离线可靠性有严苛要求的产品。现代可穿戴设备先驱 Pebble 就在 Index 01 应用中本地运行它,把语音指令转化为操作,全程不依赖网络连接。
"Pebble Index Ring 没有屏幕。所以当你对它说话时,动作必须每次都能完成,无论有没有网络。我们在应用里本地运行 Cactus Needle,不依赖云端。模型体积很小,性能从未让我们失望。
架构
简约注意力网络

Needle 2 在一个自有的 115B token 语料上做了预训练,并在 38B token 上做了后训练,后训练数据包含紧凑的推理轨迹并经过了细致的分布设计。作为参照:LFM2.5-230M 在 19 万亿 token 上预训练,大约是 Needle 总量的 120 倍,而下面的评测显示两者互有胜负。模型的每个组件都是为了换取能力而不增加带宽。Hadamard MLP 用固定的 Walsh 变换加上可学习的对角矩阵替代了常规的上下投影稠密层,使得在小模型中占主导地位的通道混合几乎不消耗任何参数读取量。engram 将世界知识从层栈中抽离到哈希 n-gram 表里,每个 token 只读取少量行:这是一类在解码时近乎零成本的容量,对每从闪存读取一兆字节都意味着延迟与电量的设备而言尤为关键。多通道残差流让一个 27 层、512 宽的网络具备了远宽于其自身的路由灵活性,代价仅为每层若干次点积,而非更多的注意力或 MLP 容量。
这套内存系统的设计是从固定内存设备的约束条件反推出来的。注意力机制采用 256 token 的滑动窗口,无论会话运行多久,KV 缓存大小始终有上限;系统提示和工具声明被固定为永久驻留区,这样对一个工具调用模型来说绝不能遗忘的东西——它的工具——在结构上就无法被淘汰。缓存本身使用 QAT 进行训练,权重以 Cactus Quants 格式存储,平均每个权重 2 bit。这样一来,模型质量决策和部署决策就解耦了:同一个训练好的模型,可以根据目标设备的能力,灵活适配精度和窗口大小。
引擎的速度来自于它拒绝计算的东西。权重从不解压到内存中:2 bit 的编码直接在向量寄存器内展开,融合为整数点积,因此常驻内存始终只有 blob 大小,整条算术路径——包括激活值、KV 缓存和 lane 路由表——全程都是 int8。文法约束在这里不只是正确性保证,更是一种优化:因为匹配器在 logits 产生之前就知道哪些 token 是合法的,所以引擎只为候选行计算输出分数,在结构化 token 上跳过最多 98% 的词表投影,对于输出已经确定的步骤则完全跳过。一个通用二进制文件在启动时探测 CPU 并自动选择合适的内核层级——SDOT、NEON、AVX2、RISC-V 向量、wasm SIMD 或标量——线程池在 token 的短串行段中持续轮转而非休眠,仅此一项就将近让解码速度翻倍。所有这些都不改变任何输出:每一个技巧要么是精确等价的,要么已逐 token 对照参考路径做过验证。
归根结底,这是一场关于能耗的博弈。在端侧芯片上,从 flash 或 DRAM 搬运一个字节的能耗,比一次乘加算高出好几个数量级。因此真正需要关注的预算指标,是"每 token 的 FLOPs"与"每 token 的字节数"两者的乘积。架构层面降低了前者:一个宽度和深度与 Needle 相当的常规 Transformer 每 token 消耗 164 MFLOPs;即使把参数量压到与 Needle 相当,也仍需 87 MFLOPs,因为它持有的每个参数都要通过矩阵乘法参与计算。而 Needle 每 token 仅需 70 MFLOPs,并且把五分之一的参数以"聚合记忆"的形式存放,这部分参数完全不消耗算力。架构层面的第二个开销——字节数——则由量化来削减,正如引擎部分所展示的:没有任何中间结果需要重新物化,算术运算全程保持 int8,语法层直接剪掉了部分计算,因此每解码一个 token,最多只需完整读取一次 14MB 的模型文件,遇到结构化 token 时实际读取量还会显著更低。这正是续航能力的来源。即便是高端手机,常驻可用的智能助手也必须在功耗预算内运行——每一个 MFLOP 都对应着毫瓦时——而 Needle 每 token 消耗的 MFLOPs 比其对比模型少 7 到 85 倍。
每 token 的计算量
| 模型 | 参数量 | 参与矩阵乘法的参数 | MFLOPs / token |
|---|---|---|---|
| Needle 2 | 45M | 35M | 70 |
| 同形状 Transformer(密集 MLP) | 82M | 82M | 164 |
| 参数量匹配的 Transformer | 43M | 43M | 87 |
| LFM2.5 230M | 230M | 230M | 460 |
| FunctionGemma 270M | 270M | 270M | 540 |
| Apple FM | ~3B | ~3B | ~6,000 |
有界的会话内存让微控制器也够得着。由于滑动窗口限制了状态,Needle 2 的 RAM 是一个确定的 28MB 上限,而不是随会话长度增长的曲线。这正好适配带外部 RAM 的 MCU 级芯片,比如带 32MB PSRAM 的 ESP32-P4,或带 SDRAM 的 STM32H7 和 NXP i.MX RT 系列开发板。引擎面向裸机编译为单线程版本,并作为静态库提供,支持 Cortex-M4、M7 和 M55。
评测
我们在五个公开的 function-calling 基准上评测:Google 的 Mobile Actions、DroidCall、Seal-Tools 的 in-domain 和 out-of-domain 测试,以及 BFCL v4 单轮。评分采用严格精确匹配:只有函数名、调用顺序以及每个参数值全部一致时,该行才算通过。所有 Needle 2 的数字都通过发布版 C++ 引擎在其生产配置下端到端测得:CQ2-bit 权重、开启工具检索、256 token 滑动 KV 窗口。基准测试没有任何放宽;数字反映的就是设备运行的引擎本身,包含窗口驱逐在内。基线在 vLLM 下以全上下文跑发布版 checkpoint,Apple FM 在设备本地运行。
这种对比天然存在两处不对称,我们先讲清楚。精度方面:基线模型刻意保持 f16,因为对从未为激进压缩训练过的模型直接做 2-bit 后训练量化会导致效果崩溃,而 Cactus Quants 从一开始就被融入到 Needle 的训练中——这让基线处于不利地位。范围方面:Needle 只针对智能体工具调用训练,而每个基线都是通用语言模型,除了工具调用还兼顾聊天、写作和世界知识——这让 Needle 占了便宜。两端无法同时拉平,所以我们不强求。表格只回答一个具体问题:在端侧算力预算下,哪个模型能正确执行工具调用。我们接受这种偏差,它仍能呈现我们想说明的画面。
Mobile Actions(961 行)
| 模型 | 准确率 | 名称准确率 | 非空率 | 1-call | 2-call |
|---|---|---|---|---|---|
| LFM2.5 230M(f16,vLLM) | 69.1 | 93.0 | 98.9 | 76.1 | 55.0 |
| FunctionGemma 270M(f16,vLLM) | 64.0 | 87.3 | 98.9 | 73.0 | 46.2 |
| Needle 2(CQ2-bit) | 63.7 | 98.3 | 99.4 | 71.3 | 48.4 |
| Apple FM(端侧) | 57.6 | 94.2 | 95.5 | 64.5 | 43.8 |
DroidCall 测试集(200 行)
| 模型 | 准确率 | 名称准确率 | 非空率 | 1-call | 2-call |
|---|---|---|---|---|---|
| FunctionGemma 270M(f16,vLLM) | 17.5 | 37.5 | 59.5 | 22.7 | 0.0 |
| Needle 2(CQ2-bit) | 17.0 | 36.5 | 47.5 | 22.1 | 0.0 |
| LFM2.5 230M(f16,vLLM) | 11.0 | 21.5 | 22.5 | 14.3 | 0.0 |
Seal-Tools 域内集(700 行)
| 模型 | 准确率 | 名称准确率 | 1-call | 2–3-call | 4+-call |
|---|---|---|---|---|---|
| Needle 2(CQ2-bit) | 32.6 | 64.9 | 63.0 | 21.8 | 14.6 |
| LFM2.5 230M (f16, vLLM) | 26.9 | 45.4 | 54.5 | 17.1 | 10.4 |
| FunctionGemma 270M (f16, vLLM) | 16.3 | 56.0 | 47.0 | 4.5 | 2.1 |
Seal-Tools 域外(654 行)
| 模型 | 准确率 | 名称准确率 | 1 次调用 | 2–3 次调用 | 4 次以上调用 |
|---|---|---|---|---|---|
| Needle 2 (CQ2-bit) | 28.7 | 58.7 | 56.4 | 27.1 | 15.4 |
| LFM2.5 230M (f16, vLLM) | 17.0 | 35.0 | 42.6 | 13.7 | 9.8 |
| FunctionGemma 270M (f16, vLLM) | 15.6 | 48.9 | 50.0 | 11.0 | 6.3 |
Needle 并非为通用函数调用而训练:它的语料是消费级设备操作——智能家居、手机、可穿戴设备、电视、汽车——加上结构化抽取,而 BFCL 的通用和企业 API 接口(包括 Java 和 JavaScript SDK 类别)完全落在该分布之外。尽管如此,它仍表现出不错的泛化:在 Python 简单调用上,它与 FunctionGemma(一个为此任务专门训练、体量是它六倍的模型)只差不到一个百分点,并且在全部 3,641 行中保持着 93.4 的格式正确率。差距集中出现在它训练数据从未覆盖的地方:Java、JavaScript 以及并行多调用类别。
BFCL v4 单轮(3,641 行)
| 类别 | Apple FM端侧 | LFM2.5 230Mf16 · vLLM | FunctionGemma 270Mf16 · vLLM | Needle 2CQ2-bit |
|---|---|---|---|---|
| Simple | 73.3 | 63.2 | 48.1 | 40.8 |
| — Python | 86.8 | 85.5 | 62.3 | 61.2 |
| — Java | 67.0 | 48.0 | 38.0 | 29.0 |
| — JavaScript | 66.0 | 56.0 | 44.0 | 32.0 |
| Multiple | 84.0 | 78.5 | 60.0 | 57.0 |
| Parallel | 65.0 | 64.0 | 36.5 | 30.0 |
| Parallel multiple | 52.0 | 51.5 | 30.5 | 22.5 |
| Live simple | 70.5 | 45.0 | 33.7 | 36.8 |
| Live multiple | 45.9 | 47.8 | 25.2 | 27.9 |
| Live parallel | 50.0 | 43.8 | 18.8 | 25.0 |
| Live parallel multiple | 58.3 | 45.8 | 25.0 | 29.2 |
| Relevance | 100.0 | 68.8 | 81.2 | 81.2 |
| Irrelevance | 28.3 | 77.7 | 72.1 | 60.8 |
| Overall | 61.7 | 60.8 | 46.1 | 42.6 |
| Well-formed rate | 95.0 | 94.2 | 100.0 | 93.4 |
体验 Needle 2
Hugging FaceGitHub研究论文