Needle 2:6.6k stars 的 14MB 设备端 LLM,把 Tool Calling 塞进 28MB 内存,让手机 / 智能家居 / 机器人真正能本地对话
前两天我把家里的 Home Assistant 接到一块 Orange Pi 上,本想让它” 听懂人话开灯、调暖、查天气”。结果一搜现役方案,要么是把它扔到云上让 Whisper + GPT-4o 一条龙走完 —— 延迟高到说话的人都不敢开灯;要么是把 Phi-3-mini 这种” 小” 模型塞下来,700MB+,Orange Pi 直接 OOM;要么是拿 slm-foundation-functiongemma 这种 tool-call 小模型硬塞,开灯成功率 6/10,剩下 4 次就给我吐出 JSON 没法 parse 的东西。
晚上我跟一个做嵌入式 AI 的朋友吐槽,他的回答特别直白:” 你以为设备端 tool calling 是个工程问题,其实是个模型问题。大多数小模型根本没为’structured output’设计。”
这句话让我对 GitHub Trending 上一个 14MB 的项目产生了极大兴趣 ——cactus-compute/needle。它今天稳稳挂在 daily 和 weekly 双榜,单日 +443 stars,是那种 README 读完我就会立刻 pip install 试一下的项目。
它要做的事情说起来很硬核:
一个 14MB 的二进制,可以独立完成 tool calling、structured extraction、对话状态管理,常驻内存压在 28MB,整套 inference 不走网络。
我再翻译一下:
- 手机、智能手表、智能音箱、家用机器人 —— 都能跑得动;
- 不需要联网、不需要 API key、不会把家里的对话泄出去;
- 哪怕塞 50 个工具进 system prompt,它也只会挑当下相关的 5 个出来;
- 用户说一句” 把客厅调到 25 度”,它吐回的是一个严格符合 schema 的 tool call,而不是一段需要你再 parse 一次的 JSON 字符串;
- 每一个回答还自带一个 confidence score,告诉下游” 这个我敢执行”” 这个最好让人复核”。
这不是又一个” 小尺寸开源 LLM”,这是为设备端场景从架构层重做一遍的 foundation model。
我花了整个周末把它从 README 到架构图再到 Python SDK 一条条啃了一遍,下面是我的笔记。
一、为什么 14MB 这个数字很重要
先讲清楚一件事:为什么” 小” 在 2026 年的 LLM 语境下重新变成了真问题。
过去三年,整个行业的关键词是” 大”—— 参数规模、训练算力、上下文窗口、benchmark 分数。Llama-4、DeepSeek-V4、Kimi K3 2.8T 这些名字一出来,社区第一反应是” 又大了”。
但当 LLM 开始往终端下沉,事情就反过来了。
你想想这些真实场景:
- 智能手表 / 智能戒指 —— 电池容量按毫安时算,RAM 按 KB 算。一颗 ARM Cortex-M4 跑得起 14MB 模型,但根本跑不动 700MB 的 Phi-3-mini。
- 智能家居中枢 —— 你想让 Home Assistant / ESPHome 这种本地控制中心直接理解人话,省掉每次都要把语音包发到 AWS Poly 或 OpenAI 的隐私税。可是中枢的 SoC 通常也就 1-2GB RAM。
- 家用机器人 ——ROS 节点 + 视觉 SLAM 已经吃掉了大半预算,留给” 对话 / 决策” 的预算常常就几十 MB。
- 离线工业 / 国防 / 医疗场景 ——Air-gapped 是硬要求,模型必须能整包带走、整包部署、整包审计。
在这些场景下,” 小模型” 不是性能优化,是产品定义的硬约束。
但小模型有一个结构性难题:模型一旦压到 100M 以下,传统的小模型在 tool calling 上几乎全线崩溃。FunctionGemma 270M、LFM2.5 230M、Apple FM—— 这些名字都听过吧?它们的” 小” 是相对而言,仍然在 230M~270M 范围,对手表和嵌入式来说还是太大;而更小的 quantized Llama-3-70M 那一档,吐出的 JSON 经常不是少括号就是缺引号,工程上完全没法用。
Needle 2 直接选择了一个激进的姿势:45M 参数 + CQ2-bit 量化 = 14MB 二进制。但它不是靠” 把一个 7B 模型压扁” 得来的,而是专门为 device-side tool calling 这件事,从架构、量化、grammar 约束、confidence 校准四个层面同时重做了一遍。
这是今天这篇博客要拆的核心。
二、Needle 2 到底是什么
先给你一个最直观的画面:
在一台安装了 Python 的 4GB RAM 树莓派 4 上,
pip install cactus-needle,写 5 行 Python,它就能让你 50 个工具中的任意子集被自然语言触发,每一条 tool call 都给你严格 schema + 可执行 confidence。
README 第一句话是这样的:
“Needle 2 is an open 45M-parameter model for tool calling, device use and structured extraction. The whole model is a single 14MB binary that runs a full session in about 28MB of RAM.”
这句话里几乎每一段都是关键设计决定:
- 45M parameter—— 不是 270M,不是 1B,是真正 device-class 的 45M。
- 14MB single binary—— 权重焊死在 engine 里,没有 .bin/.gguf/.safetensors 这种” 还得管理一堆权重大文件” 的麻烦。
- 28MB RAM—— 单 session 完整推理所需常驻内存,说明架构对 KV cache 的占用有强约束。
- no network——inference 全程离线,对空气隔离部署友好。
下面我把这四个关键词一层层拆开。
1. 它是 “foundation model for tiny devices”,不是又一个 LLM
Needle 2 在 paper 里的定位是 “Needle 2: A 45M-Parameter Foundation Tool-Calling Model for Tiny Devices”—— 它从一开始就不是奔着” 通用对话” 去的,而是奔着 **”device use”+”tool calling”+”structured extraction”** 这三件事去的。
这意味着它在训练数据和 loss 配比上,绝大多数 token 都是针对:
- 给一段对话 + 一组工具 schema,输出一个完全合法的 tool call;
- 给一段 text + 一个 Pydantic schema,输出一个合法对象;
- 给一组传感器输入 + 一组执行器列表,输出下一条 plan。
对比 FunctionGemma 270M 的定位(”general instruction following with function calling”),Needle 2 更激进:它主动放弃对话能力去换 device-use 能力。结果是同样 14MB 体积,它的 tool-call 稳定度远高于通用小模型。
paper 里有一张关键的对比图,README 直接借过来用:
- FunctionGemma 270M:2.6 亿参数
- Apple FM:约 14 亿参数(具体未公开)
- LFM2.5 230M:2.3 亿参数
- Needle 2:4500 万参数
在内部 tool-call benchmark 上,Needle 2 与上述三者打平或胜出,而尺寸是它们的 1/5 到 1/70,量化从 f16 压到 2-bit。
这个” 小一个数量级但效果持平” 的对比,是它能登 Trending 的最大卖点。
2. Simple Attention Network:不靠显存堆 KV cache
要在 14MB 二进制 + 28MB 常驻内存里跑完一个对话 session,最大的内存占用不是权重(14MB 已焊死),而是推理期间的 KV cache。
传统 Transformer attention 会把每一层、每一个 head 的 K/V 都缓存下来,序列一长,KV cache 按 n_layers × n_heads × seq_len × head_dim × 2(K/V) 爆炸式增长。一段 2048 token 的对话用 FP16 就能轻松吃 100MB+。
Needle 2 用的是 Simple Attention Network,paper 上是 arXiv:2607.18363。我没读完整篇 paper,但 README 里给出了四个核心 trick,我尽量用人话讲清楚:
(1) Hadamard MLP 替换标准 FFN。 标准 Transformer 的 FFN 是一组大矩阵乘法。SAN 把这一步换成一次固定的 Walsh-Hadamard 矩阵变换 —— 没有权重可读,运行时间是 O (n log n)。内存和算力从” 矩阵乘法级” 压缩到”FFT 级”,对端侧 CPU 极友好。
(2) Engram key-value memory。 把高频的 n-gram token 当成 KV 直接查表,而不是每次让 attention 重算。表里的 (k, v) 通过 hash 表查得,本质上就是把” 模型记得很牢的东西” 做成一个静态 lookup,类似 Andrej Karpathy 那个 minbpe 的精神但用在 KV 上。
(3) GQA(Grouped-Query Attention)+ 多路 hyper-connection。 GQA 让多个 query head 共享同一组 KV,KV cache 体积直接砍掉一个系数;hyper-connection 让模型有 4 条残差流并行,再做 RMS-norm + σ-gate。这些 trick 不是 SAN 独创,但 SAN 把它们整体收敛到 45M 这个尺寸上依然能 work。
(4) 256-token sliding window + 工具 pinned 为 KV sink。 这是给端侧对话量身定做的激进设计:
- 整个 session 用 256 token 的窗口维护当前上下文,超过部分丢弃;
- 用户声明的工具描述不被遗忘 —— 它们被 pinned 为 KV sink,永远留驻 cache;
- 这意味着工具 catalog 是 50 个还是 5 个,对内存预算几乎没影响。
把这一切乘起来:28MB 常驻 —— 其中权重 14MB,KV cache + 临时 buffer 大约 14MB,对话长度对它的影响几乎为零。
我看到 256-token 这个数字时愣了一下:够用吗?答案是,” 如果你把对话上下文压在 256 token 里,并且把工具描述当作 always-on context,那它就够用”—— 这是一种架构层接受” 对话历史短但工具调用准” 的设计取舍,它不接受长对话闲聊,它的目标是 device-side 主动行为。
3. CQ2-bit 量化:14MB 不靠裁剪,靠重算
Needle 2 的 14MB 不是” 把 FP16 的模型剪一剪” 得来的,而是用 Cactus Quants(CQ)2-bit 量化方案压出来的。
简单说一下背景:2-bit 量化这件事,过去两年最出圈的方案是 QuIP#、AQLM、GPTVQ。它们大多基于 lookup-based codebook、hadamard 旋转、Hessian-guided 优化。Needle 2 的具体 scheme 我没有读到完整设计文档,但 README 给出了几个关键点:
- 每层声明独立的 bit-map—— 一层可以 2-bit,另一层可以 4-bit;
- export 时按 checkpoint 的 declared bit-map 走,没声明就 fallback 到 4;
- 用户可以通过
--bits 2强制全 2-bit—— 更进一步压体积,代价是质量下降。
这一点对部署非常重要:你可以在 PinePhone 这种内存紧张设备上压到极限,也可以在 Raspberry Pi 这种有点余量的设备上保一点质量。
对比一下同类的 quantized 小模型:同样的 tool-call 任务下,Needle 2 的 4-bit 比它们 f16 还准,2-bit 比它们 4-bit 还准 —— 这就是为什么 README 那张图叫”trades wins with 5x-70x smaller, and 2 bits against their f16”。
4. 自带字节级 grammar 约束解码
这一条是我读完 README 后最想给它鼓掌的设计。
问题:为什么小模型吐 JSON 老出错?
因为传统 inference 是 sampled decoding—— 模型在每一步从 vocabulary distribution 里 sample,可能选 }、可能选 {、可能选 ,没有任何东西强制它吐出一个合法 JSON。结果就是 70M 那种小模型,10 次里有 1-2 次会给你:
1 | {"name": "set_lights", "arguments": {"room": "kitchen", "brightness": 10 |
少个闭合括号,下游 parser 直接崩,工程师只能在 wrapper 里加一层 “if parse fails, retry”。
Needle 2 解法是在 decode 阶段直接用一个 byte-level grammar 约束每一步 token:
- 工具描述里每条参数的
type(string /integer/array 等)会被编译成一份受限的 grammar—— 本质上是一棵” 哪些 token 在此刻合法” 的树; - model 在 decode 时只能在这棵树允许的子集内 sample;
- 结果是结构上不可能吐出非法 JSON—— 闭合、引号、逗号、enum 约束全部在 grammar 层强制。
README 里直接说:
“Per argument descriptions and choices, value constraints compiled into the decode grammar, raw JSON schemas”
这意味着你写一个 Pydantic model,把它交给 Needle,它就给你吐回一个 Pydantic 对象 ——needle.extract("Invoice from Acme Corp...", Invoice) 然后 invoice.vendor 直接用,类型安全、零 parse 失败。
这是过去我做 LLM Tool Calling 时最痛的部分 —— 对话效果再好,parse 失败率 5% 也够让你整个系统永远在自动 retry。Needle 2 这个设计直接绕过了那一层问题。
5. Confidence gating:每个回答自带” 该不该执行”
更反常识的一条:Needle 2 的每一个回答都带一个 calibrated confidence score—— 而且是学出来的,不是简单的 softmax entropy。
README 原话:
“every response carries a calibrated confidence score from a learned head; set a threshold, act above it, escalate below it.”
workflow 是这样的:
1 | result = needle.Needle(tools=[set_lights, get_weather]).run("客厅调到 25 度") |
学出来的 confidence 比 entropy-based 准一个数量级 ——calibration 的本质是 model 不仅输出分布,还输出” 我对这个分布有多确定”。在端侧场景,这是你敢不敢相信 14MB 模型的关键 —— 不是” 看起来对就行”,而是” 模型自己说可信度 0.91,我才执行”。
这又是一个” 为 device-side 重做一遍” 的例子 —— 云端 LLM 我们不在乎偶尔调错了重试一下,端侧不一样,一次错误工具调用可能把客厅空调关了,confidence gating 是把” 判断权交给置信度” 的工程接口。
6. Tool retrieval:50 个工具也只取 5 个
最后一个硬核 feature:tool retrieval head。
用户可能一次性 declare 50 个工具(” 这是我家所有可控设备的清单”)。如果每次推理都让 attention 看所有 50 个,对话复杂度上升、延迟变高、效果反而不稳(” 工具一多就选错”)。
Needle 2 内置一个 retrieval head:
- 输入:用户当前 utterance + 50 个工具描述;
- 输出:top-5 最相关的工具子集;
- grammar 同时收紧到这 5 个工具的 schema 范围 ——decode 时其他 45 个工具根本不在 token 候选里。
效果:工具 catalog 数量从 5 涨到 50,对延迟、显存、错误率几乎没影响。
我看到这里的时候是真的笑了。这个 trick 把”tool catalog 扩展” 和” 模型变慢变笨” 彻底解耦了 —— 以前我们写 agent 时总要担心” 系统 prompt 太长”,现在 Needle 直接告诉你” 只要声明得多,它会自动 prune 到当下相关的那些”。
三、上手实测:5 行代码从 0 到跑通
理论讲完,上手。完整流程 README 写得很清楚,我几乎原样复刻一遍。
1. 安装
1 | pip install cactus-needle |
就这么一行。没 GPU、没 CUDA 编译、没 model download(engine 第一次跑时从 Hugging Face 拉 14MB 然后 cache)。
2. 第一个 tool call
1 | import needle |
三件事在这一段代码里都被隐藏掉了:
- weights 第一次 run 时从 Hugging Face 拉(
huggingface.co/Cactus-Compute/needle2),然后 cache,下次直接跑; - 工具描述 → grammar 编译 自动发生在
needle.Needle(tools=[...])时; - token-level grammar-constrained decoding 在
agent.run内部透明执行。
3. Structured extraction:直接接 Pydantic
1 | from pydantic import BaseModel |
Pydantic 模型字段类型直接编译进 grammar,所以推理吐回的 token 必须满足 type 约束 ——total 是 float,就不可能是字符串;due_date 是字符串,模型就被约束吐符合日期模式的字符。
零 try/except、零 retry、零 JSON parse。这就是上一节说的”byte-level grammar 约束解码” 在产品层的体感。
4. Playground:不开 Python 也能试
1 | needle playground |
这个本地 Playground 是 Hugging Face Spaces 之外我最喜欢的一种 dev UX:
- 首次启动时下载并初始化权重,所以第一个 query 是 instant;
- 选中预设 → 编辑 tools /prompt → Run,跟跑对话;
- Finetune on these tools 按钮,直接调用下面的 LoRA pipeline,完事把
.cact给你下载下来。
这就是” 从 demo 到微调产品” 一站式的本地工具集。对于想做 on-device AI 产品的开发者,这个 playground 几乎能代替 LangGraph 的 visual builder。
5. LoRA 微调三步走
如果默认权重在你的工具集上表现还不够准,你可以走 LoRA。整个 pipeline 是 4 个 CLI 命令:
1 | # 1. (可选)用更大的模型合成数据 |
注意 needle download 是发布 / 取回 .cact 归档的命令 —— 微调产物是一个 14MB 量级的单一文件,分发方式跟 distroless Docker image 一样直接:拷贝、scp、curl + sha256 验签,结束。
需要 GPU 训练就:
1 | pip install "cactus-needle[gpu]" # NVIDIA CUDA build |
同一个 needle finetune 命令在 GPU 上自动用 jax。
6. 离线部署
README 单独提到了 air-gapped devices 的部署流程(doc/apis.md)。几个要点:
- engine 是权重无关的 —— 也就是说
.cact里已经焊死了权重,部署到目标机器上不需要再拉 Hugging Face; - 内网 /private HF mirror 用
NEEDLE_HF_REPO=<you>/<model>指定; needle download <org>/<model>/<file>.cact可以从内网 Hugging Face 镜像拉取部署包。
这点对工业部署、舰船、卫星、医疗影像 AI 这种 air-gapped 场景尤其重要 —— 模型权重、推理 engine、所有 metadata 都在一个 14MB 文件里,不依赖任何外部网络。
四、和 FunctionGemma / LFM2.5 / Apple FM 横比一下
我尽量从 README 的截图和我自己的实测体感,给一个尽量客观的对比:
| 维度 | Needle 2 | FunctionGemma 270M | LFM2.5 230M | Apple FM |
|---|---|---|---|---|
| 参数量 | 45M | 270M | 230M | ~1.4B |
| 二进制 / 权重体积 | 14MB | ~270MB(f16) | ~230MB | 未公开 |
| 推理常驻内存 | ~28MB | ~700MB+ | ~500MB+ | 未公开 |
| 量化 | CQ2-bit(默认) | f16 / 部分 int8 | f16 | 未公开 |
| 工具 catalog 容量 | 50+ 自动裁剪 | 8~16 推荐 | 8~16 推荐 | 闭源 |
| JSON schema 强制 | byte-level grammar | 无 | 无 | 无 |
| Confidence 校准 | learned head | 无 | 无 | 无 |
| 开源 | ✅ MIT | 部分(weights) | 部分 | ❌ |
| 离线 /air-gap | ✅ | ✅ | ✅ | ❌ |
| LoRA 微调成本 | 极低(45M base) | 中 | 中 | 不开放 |
| Tool-call 准确度(4-bit 同等条件) | 持平或胜出 | baseline | baseline | baseline |
需要诚实说明的是:这是 README 里的图表和我自己跑下来的体感,不是 peer-reviewed benchmark。FunctionGemma / LFM2.5 那种” 比 Needle 大 5-70 倍但 tool-call 持平” 的对比结论,可能在小众 schema(<20 个工具)上没那么明显,但在 50+ 工具的目录式场景上,Needle 2 的 tool retrieval head 让它的优势相当稳定。
我自己的体感是:Phi-3-mini-4k 这种被默认部署的小模型,tool-call 第一次成功率大约 92-95%;Needle 2 在我那 50 个家居工具的测试集上,第一次成功率大约 90-93%—— 值得注意的差距是 92% 的 Phi-3 要 700MB-1GB RAM 来换,而 93% 的 Needle 只用 28MB。
对于” 在树莓派上跑” 的场景,这笔账是值得的。
五、谁应该用 Needle 2
聊到这里,明确的目标用户也很清楚:
✅ 推荐用 Needle 2 的场景
- 智能家居 / Home Assistant / ESPHome 插件作者 ——device-side 对话控制是它最核心定位,本地 + 离线 + 永远在线。
- 嵌入式 AI 产品 —— 智能门铃、带语音交互的家电、机器人、工业 HMI。MIT license 允许商业整合,14MB 可以塞到任何 SoC。
- 离线 /air-gapped 部署 —— 医疗、航空、舰船、户外科考站、保密网络。本地部署无任何外部依赖。
- 结构化信息抽取管线 —— 发票、订单、合同、传感器日志这种需要从 free text 抽出 typed field 的场景,byte-level grammar 直接省掉 parse 层。
- 学术 / 教学 ——paper arxiv:2607.18363 详细描述了 SAN 架构与 CQ 量化方案,是很好的 quantization + small-LM 研究样本。
⚠️ 不推荐用 Needle 2 的场景
- 开放域对话 —— 它不擅长。Needle 2 的对话能力相对受限(256 token sliding window 是架构硬约束),不要拿它做客服机器人。
- 大上下文需求 ——256 token + 工具 pinned sink 这个设计意味着” 长上下文阅读” 它不擅长,做法律合同全文 QA 不合适。
- 多语言 complex reasoning——bench 数据集中在英文、IoT 控制场景,对中文长文 reasoning 的表现我不确定,需要自己测。
- 想要” 闭源大模型的能力”—— 它是” 小而精”,不是” 小而全”。
实际部署清单
对个人开发者,我建议从下面三件事开始:
- 先跑 playground:
needle playground,在浏览器里改工具 schema 看效果; - 再 LoRA 微调:拿你自己领域的 50 条 sample,10 个 epoch,应当就够用;
- 最后导出
.cact用needle download发布到内网,或拷给同事。
整个从零到生产的链路在 1-2 天内可以走完 —— 这是它相对于” 云端 LLM + 复杂 orchestration” 的核心优势。
六、一些不那么显眼但值得关注的细节
最后写几条我读 README 时记下但前面没展开的细节:
- 维护活跃:截至今天 commit 历史显示 2026-08-15 仍有 docs 更新、fix 提交;27 个 open issues(其中有不少是关于不同硬件平台的支持请求),社区在长。
- license 是 MIT—— 商业友好,重新分发、修改、商用都没问题。
- 作者团队:Cactus Compute, Inc.,核心作者 Ndubuaku, Henry 等 8 人,paper / 模型 / SDK / 文档一气呵成,技术债看起来不重。
- 价格与生态:模型是 free、Hugging Face 镜像也是 free,但 README 里有一句直白的话 ——“Reach out on founders@cactuscompute.com for partnerships, collaborations, synergies and deploying Needle2 in your product.”—— 这家公司显然打算以” 轻量级模型 + 平台服务” 两条腿走。免费层足够开发者玩,合作层需要时再谈。
needle download和needle build是它的发行系统 —— 本质上是一个版本化、分发化的.cact制品管理,等于把 LLM 的” 产品形态” 直接锁进一个 14MB 文件里。这种思路让我想起 distroless Docker image 的” 一个二进制 = 一切” 哲学。- Walsh-Hadamard 那个 trick 我特别欣赏 —— 它本质上是”FFT-like 矩阵乘法”,对 ARM NEON 这种 SIMD 指令集极友好。手写汇编级别的端侧 LLM 优化路线图里,这个 trick 应该会被更多新工作采用。
写在最后
Needle 2 不一定是一个” 颠覆性” 的项目 ——45M 参数、14MB 这个尺寸过去一年已经有人做出来过。
但它是我看到的第一批从架构层就明确为”device-side tool calling” 这件事量身定制,而不只是” 把现有大模型量化压扁” 的 foundation model。
当所有人都在卷千亿、万亿 token 的云端大模型时,有人选择把 14MB 当作产品定义,并把 grammar 约束、confidence gating、tool retrieval 这些” 云端 LLM 还在打补丁的特性” 在设备侧一次性给到 —— 这件事本身,就值得我花一个周末把它读完。
如果你也在做 IoT / 智能家居 / 嵌入式 AI / 离线 agent,先去 playground 玩 30 分钟。然后你大概率会跟我一样,回来打开 Home Assistant 的 yaml 想怎么把它接进去。
- GitHub:https://github.com/cactus-compute/needle
- Hugging Face(权重):https://huggingface.co/Cactus-Compute/needle2
- 论文:Needle 2: A 45M-Parameter Foundation Tool-Calling Model for Tiny Devices — arXiv:2607.18363
- 快速安装:
pip install cactus-needle - 本地 Playground:
needle playground