cactus-compute needle
Needle 2 是一个开放的 45M 参数模型,用于工具调用、设备使用和结构化提取。整个模型是一个 14MB 的单一二进制文件,在约 28MB 的 RAM 中即可运行完整会话。它基于我们的 Simple Attention Network 研究成果构建,使用 Cactus Quants 压缩至 CQ2 位精度,并集成到其自有的引擎中。在下面的基准测试中,Needle 2 与 FunctionGemma 270M、LFM2.5 230M 和 Apple FM 等其他小型模型互有胜负,但体积小 5 到 70 倍,且仅用 2 位精度对比它们的 f16 精度。本仓库是 Python 包:包含推理、LoRA 微调和导出功能。使用 pip install cactus-needle 安装,描述你的工具,然后从 Python 中调用它们。推理引擎会从 Hugging Face 获取一次并缓存;无需其他构建步骤,离线设置(适用于气隙设备)见 doc/apis.md。
- 自包含:权重烘焙进一个 14MB 的单一引擎中;无需管理单独的模型文件,推理过程不进行任何网络请求。
- 简单契约:工具调用以结构化数据返回,文本输入,JSON 输出;根据你的 schema 编译的字节级语法约束每个 token。
- 置信度门控:每个响应都带有来自学习头的校准置信度分数;设置阈值,高于则执行,低于则升级处理。
- 工具检索:声明一个大型目录,内置的检索头每轮仅呈现前五个工具,语法被约束在该子集内。
- 有界内存:256-token 滑动窗口,工具作为 KV 固定点(KV sinks)固定,因此无论对话多长,总内存都保持在 28MB 附近。
权重:huggingface.co/Cactus-Compute/needle2 · 源码:github.com/cactus-compute/needle
Simple Attention Network
Needle 2 是一个 Simple Attention Network,这是我们的小型密集模型配方:用 Hadamard MLP 替代 FFN,GQA 注意力,engram 键值记忆,以及多通道超连接。设计细节和消融实验见论文:arXiv:2607.18363。
每个块都携带其更新规则。这里 x̂ 是四个残差流的 RMS 归一化展平,H 是正交 Walsh-Hadamard 变换(一个固定矩阵,以 n log n 时间应用,无需读取权重),(kₜ, vₜ) 行从哈希 n-gram 表中收集,P 是路由 logits A 的双随机归一化,通过 Sinkhorn 迭代计算;a、b、g 和所有 σ 门都是可学习的且依赖于输入。注意力和 MLP 残差都经过 sandwich-norm 和门控,engram 位点在两层触发,解码受从声明的 schema 编译的字节级语法约束。
快速开始
pip install cactus-needle
Needle 读取你的工具描述来决定调用什么以及如何填写参数,因此好的描述是关键。
简单用法:装饰一个函数。函数签名提供参数类型,docstring 是工具描述,run() 完成整个循环:模型选择调用,Needle 执行你的函数,将结果反馈回去,并返回最终响应,执行过的工具结果附加在 results 中。
import needle
@needle.tool
def get_weather(city: str):
"""Get the current weather for a city."""
return {"city": city, "temp_c": 27, "sky": "clear"}
agent = needle.Needle(tools=[get_weather])
print(agent.run("what's it like in Lagos right now?")["results"])
# [{'city': 'Lagos', 'temp_c': 27, 'sky': 'clear'}]
提取:要从文本中提取结构化数据,声明形状并调用 extract()。传入一个 Pydantic 模型,返回一个类型化对象。
from pydantic import BaseModel
class Invoice(BaseModel):
vendor: str
total: float
due_date: str
invoice = needle.extract("Invoice from Acme Corp, $1,200.00, due 2026-09-01", Invoice)
print(invoice.vendor, invoice.total) # -> Acme Corp 1200.0
每个参数的描述和选项、编译进解码语法的值约束、原始 JSON schema、使用 complete() 驱动循环、响应契约、系统事实、工具检索和置信度门控,这些都在 doc/apis.md 中有详细说明。
在线试用
在浏览器中试用任何模型:选择一个预设,编辑工具或提示词,然后点击 Run。后续查询会继续同一个对话。
needle playground # 基础模型,http://127.0.0.1:7860
needle playground --weights my.cact # 微调后的模型
服务器在提供服务前会下载并初始化模型,因此第一次查询是即时的。UI 中的 “Finetune on these tools” 按钮会从界面运行下面的微调流程,并返回一个可下载的 .cact 文件。
微调
Needle 在冻结的基础模型上使用 LoRA 进行微调,并在导出时合并适配器,因此一次运行成本很低,微调后的模型仍然是一个可在同一引擎上运行的单一 .cact 文件。工作流程是:(可选)合成数据、LoRA 微调、然后构建微调后的 .cact。数据集大小、损失曲线读取和故障排除见 doc/finetuning.md。
数据格式:一个 JSONL 文件,每行一个示例。reasoning 是可选的;一个离题示例的 answers 为 []。
{
"query": "dim the kitchen to 10",
"tools": [{
"name": "set_lights",
"parameters": {
"type": "object",
"properties": {
"room": {"type": "string"},
"brightness": {"type": "integer"}
},
"required": ["room"]
}
}],
"answers": [{
"name": "set_lights",
"arguments": {"room": "kitchen", "brightness": 10}
}],
"reasoning": "'kitchen' -> room; 'dim to 10' -> brightness 10"
}
- 合成数据(可选)。需要
OPENROUTER_API_KEY。从工具 schema 文件播种,或扩展现有数据集:
export OPENROUTER_API_KEY=sk-or-...
needle generate-data --tools my_tools.json --num-samples 500 --output data.jsonl
needle generate-data --augment data.jsonl --num-samples 500 # 扩展现有 JSONL
设置 OPENROUTER_URL 可使用 OpenAI 兼容网关替代默认的 OpenRouter 端点。
- LoRA 微调。如果不传
--checkpoint,基础检查点会从 Hugging Face 自动下载。--generate N会先从你数据中的工具合成 N 个更多示例(也需要OPENROUTER_API_KEY)。
needle finetune data.jsonl --epochs 10