กลับไปหน้า Tools

GetNotes Tools

cactus-compute/needle

Tool นี้คืออะไร

Needle 2 เป็นโมเดลขนาด 45M พารามิเตอร์แบบโอเพนซอร์สที่ออกแบบมาสำหรับการเรียกใช้เครื่องมือ การใช้งานบนอุปกรณ์ และการดึงข้อมูลแบบมีโครงสร้าง เหมาะสำหรับนักพัฒนาที่ต้องการโซลูชัน AI ขนาดเล็ก ประสิทธิภาพสูง และใช้หน่วยความจำน้อย เพื่อผสานรวมความสามารถด้าน AI เข้ากับแอปพลิเคชันหรืออุปกรณ์ต่างๆ ได้อย่างง่ายดาย

ข้อมูลโปรเจกต์

ดาว

5.1K

Forks

334

License

MIT

อัปเดต GitHub ล่าสุด

13 ส.ค. 2569

เพิ่มใน GetNotes

17 ส.ค. 2569

Repository

cactus-compute/needle

เหมาะกับงาน

AI และ Agents

Ecosystem

Python

แปลและเรียบเรียงโดย AI

เนื้อหาฉบับภาษาไทย

ใช้อ่านเพื่อทำความเข้าใจเบื้องต้น โปรดตรวจสอบรายละเอียดสำคัญกับเอกสารต้นฉบับด้านล่าง

Needle

Needle 2

Needle 2 เป็นโมเดลแบบเปิดขนาด 45M พารามิเตอร์สำหรับการเรียกใช้เครื่องมือ การใช้งานบนอุปกรณ์ และการดึงข้อมูลแบบมีโครงสร้าง โมเดลทั้งหมดเป็นไบนารีขนาด 14MB เพียงไฟล์เดียวที่สามารถรันเซสชันเต็มรูปแบบโดยใช้ RAM ประมาณ 28MB สร้างขึ้นจากผลการวิจัย Simple Attention Network ของเรา บีบอัดเป็น CQ2-bit ด้วย Cactus Quants และฝังอยู่ในเอนจินของตัวเอง จากการทดสอบประสิทธิภาพด้านล่าง Needle 2 มีผลลัพธ์ที่สามารถแข่งขันกับโมเดลขนาดเล็กอื่นๆ เช่น FunctionGemma 270M, LFM2.5 230M และ Apple FM โดยมีขนาดเล็กกว่า 5 ถึง 70 เท่า และใช้ 2 บิตเทียบกับ f16 ของโมเดลเหล่านั้น

repository นี้คือแพ็กเกจ Python: สำหรับการอนุมาน (inference), การปรับแต่ง LoRA (LoRA fine-tuning) และการส่งออก (export) เพียงแค่ pip install cactus-needle อธิบายเครื่องมือของคุณ แล้วเรียกใช้จาก Python เอนจินสำหรับการอนุมานจะถูกดึงมาครั้งเดียวจาก Hugging Face และแคชไว้ ไม่จำเป็นต้องสร้างอะไรเพิ่มเติม และการตั้งค่าแบบออฟไลน์สำหรับอุปกรณ์ที่ไม่มีการเชื่อมต่อเครือข่ายก็มีระบุไว้ใน doc/apis.md

  • ครบวงจรในตัวเอง: น้ำหนักโมเดลถูกฝังอยู่ในเอนจินขนาด 14MB เพียงไฟล์เดียว ไม่ต้องจัดการไฟล์โมเดลแยกต่างหาก และการอนุมานไม่จำเป็นต้องใช้เครือข่าย
  • สัญญาที่เรียบง่าย: การเรียกใช้เครื่องมือจะส่งกลับมาเป็นข้อมูลที่มีโครงสร้าง โดยรับข้อความเข้าและส่งออกเป็น JSON; ไวยากรณ์ระดับไบต์ที่คอมไพล์จาก schema ของคุณจะจำกัดทุกโทเค็น
  • มีเกณฑ์ความเชื่อมั่น: ทุกการตอบสนองมีคะแนนความเชื่อมั่นที่ปรับเทียบแล้วจาก learned head; คุณสามารถกำหนดเกณฑ์ ทำงานเมื่อคะแนนสูงกว่า และส่งต่อเมื่อคะแนนต่ำกว่า
  • การดึงเครื่องมือ: ประกาศแค็ตตาล็อกขนาดใหญ่ และ retrieval head ในตัวจะแสดงเฉพาะเครื่องมือห้าอันดับแรกต่อรอบ โดยไวยากรณ์จะถูกจำกัดเฉพาะชุดย่อยนั้น
  • หน่วยความจำที่จำกัด: หน้าต่างเลื่อนขนาด 256 โทเค็นพร้อมเครื่องมือที่ถูกตรึงไว้เป็น KV sinks ทำให้หน่วยความจำรวมยังคงอยู่ใกล้ 28MB ไม่ว่าการสนทนาจะดำเนินไปนานแค่ไหน

น้ำหนักโมเดล: huggingface.co/Cactus-Compute/needle2 · ซอร์สโค้ด: github.com/cactus-compute/needle

Size-quality frontier: mobile-class and below

Simple Attention Network

Needle 2 เป็น Simple Attention Network ซึ่งเป็นสูตรโมเดลขนาดเล็กแบบหนาแน่นของเรา: ใช้ Hadamard MLP แทน FFN, GQA attention, engram key-value memory และ multi-lane hyper-connections ดูเอกสารวิจัยสำหรับการออกแบบและการทดลองตัดส่วนประกอบ (ablations): arXiv:2607.18363

Simple Attention Network architecture

แต่ละบล็อกมีกฎการอัปเดตของตัวเอง โดยที่ x̂ คือการปรับให้เป็น RMS-normalised ของสี่ residual streams, H คือการแปลง Walsh-Hadamard แบบ orthonormal (เมทริกซ์คงที่ที่ใช้ในเวลา n log n โดยไม่มีน้ำหนักให้อ่าน), (kₜ, vₜ) คือแถวที่รวบรวมจากตาราง n-gram ที่ถูกแฮช, และ P คือการปรับให้เป็น doubly-stochastic normalisation ของ routing logits A ซึ่งคำนวณโดย Sinkhorn iteration; a, b, g และ σ-gates ทั้งหมดถูกเรียนรู้และขึ้นอยู่กับอินพุต ทั้ง attention และ MLP residuals ถูก sandwich-normed และ gated, engram sites ทำงานที่สองเลเยอร์ และการถอดรหัสถูกจำกัดด้วยไวยากรณ์ระดับไบต์ที่คอมไพล์จาก schemas ที่ประกาศไว้

Quickstart

sh
pip install cactus-needle

Needle อ่านคำอธิบายเครื่องมือของคุณเพื่อตัดสินใจว่าจะเรียกใช้อะไรและจะเติมอาร์กิวเมนต์อย่างไร ดังนั้นการอธิบายเครื่องมือให้ดีจึงเป็นสิ่งสำคัญที่สุด

แบบง่าย: ตกแต่งฟังก์ชันด้วย decorator ซิกเนเจอร์ของฟังก์ชันจะระบุประเภทอาร์กิวเมนต์ ส่วน docstring คือคำอธิบายเครื่องมือ และ run() จะทำให้ลูปสมบูรณ์: โมเดลเลือกการเรียกใช้, Needle รันฟังก์ชันของคุณ, ป้อนผลลัพธ์กลับไป, และส่งคืนการตอบสนองสุดท้ายพร้อมผลลัพธ์ของเครื่องมือที่รันแล้วแนบมาใน results

python
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 model เข้าไป แล้วคุณจะได้อ็อบเจกต์ที่มีประเภทกลับมา

python
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 schemas ดิบ, การขับเคลื่อนลูปด้วย complete(), สัญญาการตอบสนอง, ข้อเท็จจริงของระบบ, การดึงเครื่องมือ และ confidence gating ทั้งหมดนี้ครอบคลุมอยู่ใน doc/apis.md

Playground

ลองใช้โมเดลใดก็ได้ในเบราว์เซอร์: เลือก preset, แก้ไขเครื่องมือหรือ prompt แล้วกด Run การสอบถามติดตามผลจะดำเนินต่อไปในการสนทนาเดียวกัน

sh
needle playground                      # base model, http://127.0.0.1:7860
needle playground --weights my.cact    # a tuned model

เซิร์ฟเวอร์จะดาวน์โหลดและเริ่มต้นโมเดลก่อนที่จะให้บริการ ดังนั้นการสอบถามครั้งแรกจะใช้เวลาสักครู่ ปุ่ม Finetune on these tools จะรันไปป์ไลน์การปรับแต่งด้านล่างจาก UI และส่งคืนไฟล์ .cact ที่สามารถดาวน์โหลดได้

การปรับแต่ง (Fine-tuning)

Needle ปรับแต่งด้วย LoRA บนฐานโมเดลที่ถูกตรึง (frozen base) และรวมอะแดปเตอร์เข้าด้วยกันเมื่อส่งออก ดังนั้นการรันจึงมีค่าใช้จ่ายต่ำ และโมเดลที่ปรับแต่งแล้วยังคงเป็นไฟล์ .cact ไฟล์เดียวที่รันบนเอนจินเดียวกัน ขั้นตอนการทำงานคือ: (ทางเลือก) สังเคราะห์ข้อมูล, ปรับแต่ง LoRA, จากนั้นสร้างไฟล์ .cact ที่ปรับแต่งแล้ว ดู doc/finetuning.md สำหรับขนาดชุดข้อมูล, การอ่านกราฟ loss และการแก้ไขปัญหา

รูปแบบข้อมูล ไฟล์ JSONL โดยมีหนึ่งตัวอย่างต่อบรรทัด reasoning เป็นทางเลือก; ตัวอย่างที่ไม่อยู่ในหัวข้อจะมี answers: []

json
{"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"}

1. สังเคราะห์ข้อมูล (ไม่บังคับ) ต้องใช้ OPENROUTER_API_KEY เริ่มต้นจากไฟล์ tool schema หรือขยายชุดข้อมูลที่มีอยู่:

sh
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      # expand an existing JSONL

ตั้งค่า OPENROUTER_URL เพื่อใช้เกตเวย์ที่เข้ากันได้กับ OpenAI แทน endpoint ของ OpenRouter เริ่มต้น

2. ปรับแต่ง LoRA checkpoint ฐานจะดาวน์โหลดอัตโนมัติจาก Hugging Face หากคุณไม่ได้ส่ง --checkpoint --generate N จะสังเคราะห์ตัวอย่างเพิ่มเติม N ตัวอย่างจากเครื่องมือในข้อมูลของคุณก่อน (ยังต้องใช้ OPENROUTER_API_KEY)

sh
needle finetune data.jsonl --epochs 10
needle finetune data.jsonl --epochs 10 --generate 300 --lora-rank 16 --lora-alpha 32

ตัวเลือกสำคัญ: --epochs (ค่าเริ่มต้น 3), --lora-rank (16), --lora-alpha (32), --lr (1e-4), --batch-size (16), --max-len (1024), --val-split (0.1), --checkpoint <base.pkl>, --out <adapter.pkl> อะแดปเตอร์จะถูกเขียนไปยัง checkpoints/needle_lora.pkl ค่า validation loss จะถูกพิมพ์ออกมาในแต่ละ epoch จากส่วนที่ถูกกันไว้

การฝึกอบรมเป็น JAX ธรรมดาและรันบน accelerator ใดๆ ที่ JAX รองรับ บนเครื่อง NVIDIA ให้ติดตั้ง CUDA build และคำสั่งเดียวกันนี้จะฝึกอบรมบน GPU:

sh
pip install "cactus-needle[gpu]"

บน Apple Silicon ส่วนเสริม metal จะฝึกอบรมบน GPU:

sh
pip install "cactus-needle[metal]"

3. สร้างไฟล์ .cact ที่ปรับแต่งแล้ว รวมอะแดปเตอร์เข้ากับฐานโมเดลและควอนไทซ์ ฐานโมเดลจะดาวน์โหลดอัตโนมัติหากไม่มีอยู่

sh
needle build checkpoints/needle2.pkl --lora checkpoints/needle_lora.pkl --out my_needle.cact

เพิ่ม --bits 2 สำหรับโมเดลที่เล็กลง (โดยค่าเริ่มต้น การส่งออกจะตามแผนที่บิตต่อเลเยอร์ที่ประกาศไว้ใน checkpoint โดยจะกลับไปใช้ 4 บิตหาก checkpoint ไม่ได้ประกาศไว้) หรือตั้งค่า NEEDLE_HF_REPO=<you>/<model> และส่ง --upload เพื่อเผยแพร่ไฟล์ .cact คำสั่ง needle download <you>/<model>/my_needle.cact ที่ตรงกันจะดึงไฟล์เก็บถาวรที่เผยแพร่แล้วบนเครื่องใดก็ได้

4. รันโมเดล เอนจินไม่ขึ้นกับน้ำหนักโมเดล ดังนั้นไฟล์ .cact ที่ปรับแต่งแล้วสามารถรันบนเอนจินได้โดยตรง - ไม่ต้องคอมไพล์ใหม่:

python
import needle
agent = needle.Needle(weights="my_needle.cact", tools=[...])
agent.run("...")

การอ้างอิง

Needle 2 สร้างโดยทีม Cactus Compute หากคุณใช้ในงานของคุณ โปรดอ้างอิง:

bibtex
@misc{needle2_2026,
  title        = {Needle 2: A 45M-Parameter Foundation Tool-Calling Model for Tiny Devices},
  author       = {Ndubuaku, Henry and Mosoyan, Karen and Mroz, Jakub and Cylich, Noah and
                  Kumar, Satyajit and Sandhu, Parkirat and Shemet, Roman and Lee, Justin H.},
  year         = {2026},
  organization = {Cactus Compute, Inc.},
  howpublished = {\url{https://github.com/cactus-compute/needle}}
}

ติดต่อ founders@cactuscompute.com สำหรับการเป็นพันธมิตร ความร่วมมือ การทำงานร่วมกัน และการนำ Needle2 ไปใช้ในผลิตภัณฑ์ของคุณ

เอกสารโปรเจกต์

อ่านเอกสารต้นฉบับ

README วิธีติดตั้ง วิธีใช้งาน และข้อกำหนดจาก repository ต้นฉบับ

ดูไฟล์บน GitHub

Needle

Needle 2

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. It is built on our Simple Attention Network findings, compressed to CQ2-bit with Cactus Quants, and baked into its own engine. On the benchmarks below, Needle 2 trades wins with other small models like FunctionGemma 270M, LFM2.5 230M and Apple FM, at 5x to 70x smaller, and 2 bits against their f16.

This repository is the Python package: inference, LoRA fine-tuning, and export. pip install cactus-needle, describe your tools, and call them from Python. The inference engine is fetched once from Hugging Face and cached; there is nothing else to build, and offline setup for air gapped devices is covered in doc/apis.md.

  • Self-contained: weights baked into a single 14MB engine; no separate model files to manage, and inference does no network.
  • Simple contract: tool calls come back as structured data, text in, JSON out; a byte-level grammar compiled from your schemas constrains every token.
  • Confidence-gated: every response carries a calibrated confidence score from a learned head; set a threshold, act above it, escalate below it.
  • Tool retrieval: declare a large catalogue and a built-in retrieval head renders only the top five tools per turn, with the grammar constrained to that subset.
  • Bounded memory: a 256-token sliding window with the tools pinned as KV sinks, so total memory stays near 28MB no matter how long the conversation runs.

Weights: huggingface.co/Cactus-Compute/needle2 &middot; source: github.com/cactus-compute/needle.

Size-quality frontier: mobile-class and below

Simple Attention Network

Needle 2 is a Simple Attention Network, our dense small-model recipe: a Hadamard MLP in place of the FFN, GQA attention, engram key-value memory, and multi-lane hyper-connections. See the paper for the design and ablations: arXiv:2607.18363.

Simple Attention Network architecture

Each block carries its update rule. Here x̂ is the RMS-normalised flattening of the four residual streams, H the orthonormal Walsh-Hadamard transform (a fixed matrix, applied in n log n time with no weights to read), (kₜ, vₜ) rows gathered from hashed n-gram tables, and P the doubly-stochastic normalisation of the routing logits A, computed by Sinkhorn iteration; a, b, g and all σ-gates are learned and input-dependent. Both attention and MLP residuals are sandwich-normed and gated, the engram sites fire at two layers, and decoding is constrained by a byte-level grammar compiled from the declared schemas.

Quickstart

sh
pip install cactus-needle

Needle reads your tool descriptions to decide what to call and how to fill arguments, so describing them well is the whole game.

Simple: decorate a function. The signature gives the argument types, the docstring is the tool description, and run() completes the loop: model picks the call, Needle executes your function, feeds the result back, and returns the final response with the executed tool results attached as results.

python
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'}]

Extraction: to pull structured data out of text, declare the shape and call extract(). Pass a Pydantic model and you get a typed object back.

python
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

Per argument descriptions and choices, value constraints compiled into the decode grammar, raw JSON schemas, driving the loop with complete(), the response contract, system facts, tool retrieval, and confidence gating are all covered in doc/apis.md.

Playground

Try any model in the browser: pick a preset, edit the tools or prompt, and Run. Follow-up queries continue the same conversation.

sh
needle playground                      # base model, http://127.0.0.1:7860
needle playground --weights my.cact    # a tuned model

The server downloads and initializes the model before serving, so the first query is instant. The Finetune on these tools button runs the fine-tuning pipeline below from the UI and hands back a downloadable .cact.

Fine-tuning

Needle fine-tunes with LoRA on the frozen base and merges the adapter at export, so a run is cheap and the tuned model is still a single .cact that runs on the same engine. The workflow is: (optionally) synthesize data, LoRA fine-tune, then build a tuned .cact. See doc/finetuning.md for dataset sizing, reading the loss curve, and troubleshooting.

Data format. A JSONL file, one example per line. reasoning is optional; an off-topic example has answers: [].

json
{"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"}

1. Synthesize data (optional). Needs OPENROUTER_API_KEY. Seed from a tool schema file, or expand an existing set:

sh
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      # expand an existing JSONL

Set OPENROUTER_URL to use an OpenAI-compatible gateway instead of the default OpenRouter endpoint.

2. LoRA fine-tune. The base checkpoint auto-downloads from Hugging Face if you do not pass --checkpoint. --generate N first synthesizes N more examples from the tools in your data (also needs OPENROUTER_API_KEY).

sh
needle finetune data.jsonl --epochs 10
needle finetune data.jsonl --epochs 10 --generate 300 --lora-rank 16 --lora-alpha 32

Key options: --epochs (default 3), --lora-rank (16), --lora-alpha (32), --lr (1e-4), --batch-size (16), --max-len (1024), --val-split (0.1), --checkpoint <base.pkl>, --out <adapter.pkl>. The adapter is written to checkpoints/needle_lora.pkl. A validation loss prints each epoch from the held out split.

Training is plain JAX and runs on any accelerator jax supports. On an NVIDIA machine install the CUDA build and the same command trains on the GPU:

sh
pip install "cactus-needle[gpu]"

On Apple Silicon the metal extra trains on the GPU:

sh
pip install "cactus-needle[metal]"

3. Build a tuned .cact. Merge the adapter into the base and quantize. The base auto-downloads if absent.

sh
needle build checkpoints/needle2.pkl --lora checkpoints/needle_lora.pkl --out my_needle.cact

Add --bits 2 for a smaller model (by default the export follows the checkpoint's declared per-layer bit map, falling back to 4 when the checkpoint declares none), or set NEEDLE_HF_REPO=<you>/<model> and pass --upload to publish the .cact. The counterpart needle download <you>/<model>/my_needle.cact pulls a published archive on any machine.

4. Run it. The engine is weights-agnostic, so a tuned .cact runs on it directly - no recompilation:

python
import needle
agent = needle.Needle(weights="my_needle.cact", tools=[...])
agent.run("...")

Citation

Needle 2 is built by the Cactus Compute team. If you use it in your work, please cite:

bibtex
@misc{needle2_2026,
  title        = {Needle 2: A 45M-Parameter Foundation Tool-Calling Model for Tiny Devices},
  author       = {Ndubuaku, Henry and Mosoyan, Karen and Mroz, Jakub and Cylich, Noah and
                  Kumar, Satyajit and Sandhu, Parkirat and Shemet, Roman and Lee, Justin H.},
  year         = {2026},
  organization = {Cactus Compute, Inc.},
  howpublished = {\url{https://github.com/cactus-compute/needle}}
}

Reach out on founders@cactuscompute.com for partnerships, collaborations, synergies and deploying Needle2 in your product.

#cactus#gemini#gemma#llm#on-device-ai