AI / Hardware

Needle 2:面向微型设备的 14 MB Agentic LLM

Cactus 介绍其 45M 参数的端侧工具调用模型 Needle 2,包括量化架构、固定内存设计、设备性能、公开基准测试与本地微调结果。

AIHardware#LLM#On-device AI#Function Calling#Quantization

今天,我们发布 Needle 2:一款面向工具调用、设备操作和结构化信息提取的开源 45M 参数模型。整个模型是一个 14 MB 的二进制文件,运行时占用 28 MB 内存。它基于我们的 Simple Attention Network,通过 Cactus Quants 压缩至 CQ2-bit,并封装在自己的推理引擎中。

在工具调用和移动设备操作基准测试中,Needle 2 与 FunctionGemma 270M、LFM2.5 230M 和 Apple FM 等小型模型互有胜负;尽管它比这些模型小 5 至 70 倍,而且使用 2-bit 精度,而对方使用 f16。Needle 可以达到:

  • 在 Raspberry Pi 5 上以 500 tokens/sec 的速度解码;
  • 在 Meta Quest 3S、Apple Vision Pro 等 VR 设备上达到 400–1,500 tokens/sec;
  • 在三星 A 系列等售价低于 200 美元的手机上达到 300–700 tokens/sec。

Needle 的会话内存峰值约为 28 MB,因此也能在 ESP32-S3 等较新的微控制器上运行。

指标 数值
参数量 45M
Raspberry Pi 5 Prefill 800+ tok/s
Raspberry Pi 5 Decode 500+ tok/s
压缩格式 CQ2-bit
文件大小 14 MB
会话内存 28 MB

尺寸与质量的前沿:移动级及以下设备

原网页用散点图比较总参数量与 Mobile Actions 准确率。根据图中模型信息和同页 Mobile Actions 表格,可整理为:

模型 总参数量 部署精度 Mobile Actions 准确率
Needle 2 45M CQ2-bit 63.7
LFM2.5 230M f16 · vLLM 69.1
FunctionGemma 270M f16 · vLLM 64.0
Apple FM ~3B 端侧运行 57.6

图 1。 在面向智能设备、移动级及更小设备的模型中,比较总参数量与 Mobile Actions(google/mobile-actions eval split,共 961 行)上的 ordered strict exact match。Needle 2 的结果通过交付的二进制文件端到端测得,采用 CQ2-bit 部署精度并开启工具检索;基线模型使用发布的 checkpoint 在 vLLM 下运行,Apple FM 则在设备端运行。

我们的判断

把端侧 AI 带到低于 200 美元的设备上

近来所谓 Edge AI 往往指 Mac 和 PC,但真正的边缘设备大多是廉价硬件:IoT 设备超过 210 亿台,而 PC 约为 15 亿台。新兴市场的大多数手机售价低于 200 美元。若把廉价手机、Raspberry Pi、微控制器、可穿戴设备、Reachy Mini 这类小型机器人以及联网家居设备都计算在内,大约五分之四的边缘设备售价低于 200 美元。

这正是 Needle 面向的硬件:没有 GPU、没有 NPU,只有几十 MB 内存。

函数调用与设备操作

开一盏灯并不需要前沿模型。智能手表、家庭助手和机器人已经把自身能力暴露为带类型参数的函数,真正困难的部分只是把一句杂乱的自然语言映射到正确的函数和参数上。

以这种方式定义问题,就不需要世界知识,也不需要开放式文本生成。这就是为什么 45M 参数已经足够,而聊天模型需要数十亿参数。后续所有设计都建立在这个更小、更聚焦的问题定义上。

信息提取与结构化输出

Needle 把信息提取视为另一种工具调用。给定一个 schema 和一份文档,它会返回带类型的字段:用于分类的 enum、用于列表的 array,以及用于结构化记录的 object。

我们根据 schema 编译 grammar,从而阻止格式错误的 JSON 和无效结构。这样,模型可以把 45M 参数集中用于选择正确的值,并将这些值落到用户原话所提供的依据上。

边缘与云端协作

没有哪个小模型是完美的,Needle 会承认这一点,而不是猜测。偏离任务范围的请求会返回空调用,每个响应也会携带一个学习得到的置信度分数。

你可以自行设置置信度阈值:高于阈值时执行操作,低于阈值时再次询问或升级到云端。大多数设备操作请求可以在本地处理,因此升级很少发生,默认路径仍然私密、快速且免费。

无损 2-bit 量化

小模型很容易在事后量化中失效,因此我们从不做事后量化:Needle 2 从预训练到后训练始终针对 Cactus Quants 训练,权重、激活和 KV cache 都包含在内。

你部署的 2-bit 模型就是训练时的模型。这使 45M 参数可以装进 14 MB,同时在我们的基准测试中没有损失。

模型与推理协同设计

每个架构元素在获得相应参数预算之前,都先在目标硬件上经过基准测试。因此我们并非只发布权重,而是打包一个无依赖的 C++ 二进制文件:它会在启动时探测 CPU 并选择 kernel,模型、tokenizer 和 grammar compiler 全部封装其中。

同一个产物可以从 Cortex-M 一路运行到 x86 和 WebAssembly,无须额外安装或下载其他组件。

在 Mac 或 PC 上微调

每种产品都有自己的工具词汇,而 45M 模型足够小,可以在实际运行它的设备上重新训练。仓库和 Python package 可以在你自己的电脑上完成调优和测试,耗时从几分钟到几小时不等。

你可以交付一个真正理解设备工具的 Needle,而不是通用助手。

生产应用

Needle 已可用于要求极小内存占用、低延迟、隐私和离线可靠性的产品。现代可穿戴设备行业的先驱 Pebble 在 Index 01 应用中本地运行 Needle,把语音请求转换为操作,不依赖网络连接。

“Pebble Index Ring 没有屏幕。因此当你对它说话时,无论是否有互联网连接,操作都必须每次可靠发生。我们在应用中本地运行 Cactus Needle,而不是依赖云端。模型占用极小,性能也从未让我们失望。”

—— Eric Migicovsky,Pebble 创始人

架构

Simple Attention Network

Simple Attention Network 架构:token 经 embedding 后进入 27 层多通道残差、engram、GQA attention 与 Hadamard MLP,最后由 byte-level grammar 约束函数调用
图 2:Simple Attention Network 及各模块的更新规则。来源:原文 ↗

图中的每个 block 都标出了自己的更新规则。其中,x̂ 是四条残差流展平后进行 RMS normalization 的结果;H 是正交 Walsh-Hadamard transform——一个固定矩阵,以 n log n 时间应用,不需要读取权重;(kᵢ, vᵢ) 是从经过哈希的 n-gram 表中收集的行;P 是 routing logits A 经过 Sinkhorn iteration 计算得到的 doubly-stochastic normalization。a、b、g 和所有 σ gate 都是学习得到的,并且依赖输入。

attention 与 MLP residual 都采用 sandwich normalization 并带有 gate;engram site 在两层中触发;解码则受声明 schema 编译出的 byte-level grammar 约束。

Needle 2 在一个专有的 115B-token corpus 上完成预训练,又使用 compact reasoning trace 和经过仔细设计的数据分布进行了 38B token 的后训练。作为尺度对比,LFM2.5-230M 的预训练数据量为 19 trillion tokens,约为 Needle 总量的 120 倍;下方评测显示两者仍然互有胜负。

每个组件的目标都是在不增加带宽负担的前提下换取能力:

  • Hadamard MLP 用固定 Walsh transform 和学习得到的 diagonal 取代通常的 dense up/down projection。对于小模型而言,占据主要权重读取成本的 channel mixing 因而几乎不需要参数。
  • Engram 把世界知识从 stack 中移入经过哈希的 n-gram 表,每个 token 只读取少量行。其容量在 decode 时几乎是免费的;对于每从 flash 读取 1 MB 都会影响延迟和电量的设备,这一点尤其重要。
  • Multi-lane residual stream 让一个 27 层、宽度为 512 的网络获得类似更宽网络的 routing 灵活性,代价只是每层增加少量 dot product,而不是增加 attention 或 MLP 的计算规模。

内存系统是从固定 RAM 设备的限制反向设计的。attention 使用 256-token sliding window,因此无论会话运行多久,KV cache 都有固定上限。system prompt 和工具声明则被固定为永久 sink,使工具调用模型绝不能遗忘的内容——它的工具——在结构上无法被逐出。

cache 本身通过 QAT 训练;权重以 Cactus Quants 保存,混合平均 bits per weight 为 2-bit。这样,质量决策与部署决策可以保持解耦:同一个训练好的模型,可以针对目标设备能够负担的精度和窗口进行专门化。

引擎的速度来自它拒绝执行的计算。权重不会解压到 RAM;2-bit code 在 vector register 内展开,并融合进 integer dot product,因此常驻内存与 blob 大小相同,算术路径从头到尾保持 int8,包括 activation、KV cache 和 lane routing table。

grammar 不只是保证正确性的手段,也是一种优化。matcher 在 logits 产生之前就知道哪些 token 合法,所以引擎只为候选行计算输出分数:在结构 token 上最多可以跳过 98% 的 vocabulary projection;若某一步的输出已经被强制确定,则完全跳过这项计算。

一个通用二进制文件会在启动时探测 CPU,并自行选择 SDOT、NEON、AVX2、RISC-V vector、wasm SIMD 或 scalar kernel 层级。thread pool 在每个 token 的短串行阶段持续自旋而不进入睡眠;仅这一项就让 decode 性能接近翻倍。这些优化不会改变任何输出:每项技巧要么数学上精确,要么已经逐 token 对照 reference path 验证。

最终,这一切都是关于能耗的论证。在端侧芯片上,从 flash 或 DRAM 搬运一个 byte 的成本比一次 multiply-accumulate 高出多个数量级,因此真正重要的预算是每 token 的 FLOPs 和 bytes。

架构降低了前者:与 Needle 同宽同深的传统 transformer 每 token 需要 164 MFLOPs;即便将参数量压到与 Needle 相同,仍需 87 MFLOPs,因为它拥有的每个参数都必须通过 matmul 使用。Needle 只需要 70 MFLOPs,并把五分之一参数作为 gather memory,不产生算术开销。

二进制实现降低了后者:不会重新 materialize 权重,算术路径始终为 int8,grammar 会直接裁剪计算。因此,解码一个 token 最多只需读取一次 14 MB blob,在 structural token 上读取量还会显著更少。这正是电池续航的来源。即使在高端手机上,always-on assistant 也必须服从功耗预算;每个 MFLOP 都意味着毫瓦时,而 Needle 每 token 的消耗比参与比较的模型少 7 至 85 倍。

每个 token 的计算量

模型 参数量 Matmul-active MFLOPs / token
Needle 2 45M 35M 70
同形状 transformer、dense 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

按每次 multiply-accumulate 计为 2 FLOPs,并假定所有行都使用 tied embedding;匹配上下文时,各行的 attention 项相同,因此不计入。Needle 两个参数列之间的差异来自 engram:其中 8M 参数通过 gather 读取,不产生算术开销。

基线行把每个参数都计为 matmul-active,这对两个基线模型都是准确的。LFM2.5 的八个 short-conv block 将参数放在每个 token 都要运行的 dense gate 和 projection matmul 中;depthwise convolution kernel 本身可以忽略不计。short convolution 节省的是依赖上下文的 attention 项,而该项已经从所有行中排除。tied embedding 只按 output head 计算一次。FunctionGemma 的 540 MFLOPs 主要来自这个 head:它的 270M 参数中,有 170M 位于一个 262k-token embedding table 中。

有界会话内存让微控制器成为可能。由于 sliding window 限制了状态,Needle 2 的 RAM 是确定的 28 MB 上限,而不是随会话长度增长的曲线。这可以装入带外部 RAM 的 MCU-class 部件,例如配备 32 MB PSRAM 的 ESP32-P4,或配备 SDRAM 的 STM32H7 和 NXP i.MX RT 开发板。引擎可针对 bare metal 编译为单线程,并为 Cortex-M4、M7 和 M55 提供 static library。

评测

我们在五个公开函数调用基准上评估模型:Google 的 Mobile Actions、DroidCall、Seal-Tools 的 in-domain 与 out-of-domain 测试,以及 BFCL v4 single-turn。

评分采用 ordered strict exact match:只有函数名、调用顺序和每一个参数值都完全匹配时,该行才算通过。Needle 2 的所有数字都通过交付的 C++ 引擎,在生产配置中端到端测得:CQ2-bit 权重、开启工具检索,并使用 256-token sliding KV window。基准测试没有放宽任何条件;数字反映的就是设备实际运行的引擎,包括 window eviction。基线模型以完整上下文在 vLLM 下运行发布的 checkpoint,Apple FM 则在设备端运行。

这项比较存在两项不对称,我们在此明确说明:

  • 精度。 基线刻意保持 f16,因为从未为激进压缩训练的模型在传统 2-bit post-training quantization 下会崩溃,而 Cactus Quants 从一开始就被纳入 Needle 的训练。这项偏差有利于基线。
  • 范围。 Needle 专门针对 agentic tool calling 训练,不承担其他任务;每个基线则都是通用语言模型,除了工具调用,还携带聊天、文本生成和世界知识。这项偏差有利于 Needle。

无法同时公平消除这两项差异,因此我们没有尝试这样做。下列表格只回答一个狭窄的问题:在端侧预算内,哪个模型能正确执行工具调用。我们接受这种偏差,因为它仍然呈现了我们想表达的图景。

Mobile Actions(961 行)

模型 准确率 名称准确率 非空输出 单调用 双调用
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

数据来自 Google Mobile Actions eval split,采用 ordered strict exact match;函数名、调用顺序和每一个参数都必须匹配。

DroidCall 测试集(200 行)

模型 准确率 名称准确率 非空输出 单调用 双调用
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

该测试采用 Android intent 风格的函数调用和 ordered strict exact match;单调用数据共 n=154 行,双调用数据共 n=24 行。

Seal-Tools in-domain(700 行)

模型 准确率 名称准确率 单调用 2–3 次调用 4 次以上调用
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 out-of-domain(654 行)

模型 准确率 名称准确率 单调用 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

该测试将整个工具 domain 从训练中排除,用于检验 schema generalization。

Needle 并不是为通用函数调用训练的:其 corpus 包含智能家居、移动设备、可穿戴设备、电视和汽车等消费设备操作,再加上结构化信息提取。BFCL 的通用与企业 API 场景——包括 Java 和 JavaScript SDK 类别——完全处于该分布之外。

尽管如此,它仍能向外泛化:在 Python simple call 上,Needle 与针对这一任务训练、规模大六倍的 FunctionGemma 相差不到 1 个百分点;在全部 3,641 行数据中,它仍保持 93.4 的 well-formed rate。差距主要集中在训练数据从未覆盖的 Java、JavaScript 和 parallel multi-call 类别。

BFCL v4 single-turn(3,641 行)

类别 Apple FM 端侧 LFM2.5 230M f16 · vLLM FunctionGemma 270M f16 · vLLM Needle 2 CQ2-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

使用官方 BFCL v4 single-turn scorer。Overall 是收集器对全部 13 个原始类别的未加权平均值;原图以粗体标出每行最佳结果。

微调

到目前为止的每个数字都来自 base model:一个通用 checkpoint,在它从未见过的 benchmark 上测量。这是在现实世界的“困难”任务上评估 Needle。不过,Needle 的设计目标就是进行微调,而且你可以在自己的笔记本电脑上本地完成。

下面是在特定任务上微调后,Needle 性能变化的结果。

Needle 2 base 与 fine-tuned 对比

基准测试 Needle 2 base Needle 2 fine-tuned
DroidCall 17.0 74.5
Seal-Tools in-domain 33.0 56.0
Seal-Tools out-of-domain 29.4 56.7
Mobile Actions 63.9 84.6

图 3。 Needle 2 微调前后的结果,并与 FunctionGemma 270M、LFM2.5 230M、DeepSeek V4 Flash 等其他小模型基线进行比较。

微调使准确率提升了 21 至 58 个百分点,并让 Needle 2 在四项基准中的三项超过了 DeepSeek V4 Flash——后者是一个前沿云端模型。原因在于范围狭窄:你的产品只暴露一组固定、有限的工具,因此,针对这些工具专门训练的小模型能够击败大型通用模型。

你可以在自己的环境中采用同样的方法:提供自己的数据,或生成 synthetic trace,运行 needle finetune,然后导出生成的 .cact 文件。

相关资源:Hugging FaceGitHub研究论文

在硬件中构建设备端操作

Needle 使用 Apache 2.0 许可证。有关自定义 tool schema、硬件调优和后训练的信息,请参阅 Needle 项目仓库

相关文章

Hardware / Programming Languages

缓存如何工作:一个非常具体的解释

从局部性原理出发,具体讲解 CPU 缓存的索引、标签匹配、组相联结构、写入策略,以及面向缓存的代码重构方法。

11 分钟