How the Needle Inference Engine Manages Model Weights: Inside the .cact Archive System
The Needle inference engine embeds all model weights directly inside a single binary .cact archive, automatically detects the engine generation from the first four bytes, and loads the appropriate native library via ctypes to provide zero-copy inference with a constant ~28 MiB memory footprint.
The cactus-compute/needle repository implements a unique weight management strategy that eliminates external file dependencies by baking the entire model—including optional LoRA adapters—into one portable archive. Understanding how the Needle inference engine manages model weights reveals why it can deploy on tiny devices without requiring separate weight directories or runtime downloads.
Embedding Weights in the .cact Archive Format
Unlike traditional frameworks that load weights from multiple .bin or .safetensors files, Needle uses a proprietary .cact archive format that bundles the base model and any fine-tuning parameters into a single executable binary. This design ensures that once the archive is built, the inference engine requires no additional filesystem access to retrieve parameters during runtime.
The archive supports both generation 2 and generation 3 engine binaries, with the version determined by a header tag embedded at the start of the file. When fine-tuning is required, the FineTuneWorker class (implemented in needle/_worker.py) merges LoRA adapters with the base weights before producing the final combined archive, maintaining the single-file execution model.
Detecting Engine Generation from Weight Archives
Before loading any parameters, the engine must determine which native library version to use. The private helper _weight_generation in needle/__init__.py reads the first four bytes of the .cact file and maps the little-endian integer to a generation number using the _CACT_GENERATIONS lookup table.
According to the source code in needle/__init__.py (lines 29-41), the detection logic works as follows:
def _weight_generation(path):
with open(path, "rb") as handle:
tag_bytes = handle.read(4)
tag = int.from_bytes(tag_bytes, "little")
return _CACT_GENERATIONS[tag] # → 2 or 3
This generation number dictates which native engine binary (libneedle v2 or v3) the wrapper must load, ensuring backward compatibility while allowing the engine to evolve its weight format.
Resolving and Loading the Native Engine Library
Once the generation is identified, the _library_path function (lines 43-73 in needle/__init__.py) resolves the path to the appropriate native shared library. The resolution follows a strict hierarchy:
- Environment override: Checks
NEEDLE2_LIB_PATHorNEEDLE3_LIB_PATHfor user-specified libraries - Package directory: Searches local filenames in the installed package
- Cache fallback: Looks in
~/.cache/cactus-needle/v{generation}/{version}/ - Dynamic download: Fetches the correct binary via
fetch.fetch_libraryinneedle/agent/fetch.pyif not found locally
The implementation ensures that the engine can bootstrap itself on fresh installations while respecting system administrators' need to pin specific library versions:
def _library_path(generation=2):
override = os.environ.get(f"NEEDLE{generation}_LIB_PATH")
# … try local filenames …
if os.path.exists(local):
return local
# fallback to cached download
version = fetch.engine_version(generation)
cache = os.path.join(os.path.expanduser("~"),
".cache", "cactus-needle", f"v{generation}", version)
cached = os.path.join(cache, fetch._lib_name())
if os.path.exists(cached):
return cached
# download the correct library
return fetch.fetch_library(version, cache, generation=generation)
Runtime Weight Loading and Memory Management
When instantiating the Needle class with a weights argument, the wrapper executes a three-phase initialization process defined in needle/__init__.py (lines 53-61 and 87-99):
- Generation detection: Calls
_weight_generation(self._weights)to identify the archive version - Worker initialization: Creates a
FineTuneWorkerif tuning data is present, otherwise proceeds to direct binding - Native loading: Invokes
needle_loadthrough thectypeshandle to memory-map the archive
The needle_load function exposes the weight archive directly to the native engine, eliminating Python-side copies. During inference calls (complete, run, embed), the engine references this already-loaded memory buffer, ensuring that the RAM usage remains constant at approximately 28 MiB regardless of input size.
self._generation = _weight_generation(self._weights) if self._weights else 2
...
if self._weights:
self._worker = FineTuneWorker(... ) # fine-tune path
else:
self._bind() # plain engine path
Practical Implementation Examples
The following patterns demonstrate how to leverage Needle's weight management in production code:
Load the default model with baked-in weights, allowing the engine to auto-fetch the correct native library:
import needle
agent = needle.Needle()
print(agent.complete("What can you do?")["completion"])
Load a fine-tuned .cact archive exported from custom training, which automatically triggers generation detection:
agent_ft = needle.Needle(weights="my_needle.cact", tools=[...])
print(agent_ft.run("Schedule a meeting tomorrow")["results"])
Inspect the generation of any archive file manually using the internal helper:
from needle import _weight_generation
gen = _weight_generation("my_needle.cact")
print(f"The archive is for Needle generation {gen}")
Summary
- Single-archive design: All base weights and LoRA adapters reside in one
.cactbinary, eliminating external dependencies during inference. - Generation tagging: The first four bytes of the archive determine whether the engine loads v2 or v3 native libraries via the
_weight_generationfunction. - Hierarchical library resolution: The
_library_pathfunction searches environment variables, package directories, and~/.cache/cactus-needlebefore downloading missing binaries. - Zero-copy execution: The
needle_loadfunction maps the archive directly into native memory viactypes, maintaining a constant ~28 MiB footprint across all inference calls.
Frequently Asked Questions
What is the .cact file format in Needle?
The .cact format is a proprietary binary archive that encapsulates the entire model state—including base parameters and optional LoRA fine-tuning weights—into a single file. According to the cactus-compute/needle source code, the format prefixes the weight data with a 4-byte little-endian generation tag that identifies which engine binary (v2 or v3) can interpret the archive.
How does Needle handle fine-tuned or LoRA weights?
When the Needle constructor receives a weights argument, it instantiates a FineTuneWorker from needle/_worker.py if fine-tuning data is detected. This worker merges the LoRA adapter with the base weights into a unified archive before the native needle_load function processes it, preserving the single-file execution model while supporting parameter-efficient fine-tuning.
Where does Needle store the native engine libraries?
The _library_path function implements a tiered search strategy: it first checks the NEEDLE{generation}_LIB_PATH environment variables, then the package installation directory, followed by the user cache at ~/.cache/cactus-needle/v{generation}/{version}/. If the library is absent, the system downloads the correct version via needle/agent/fetch.py and stores it in that cache location for future runs.
What is the memory footprint during inference?
The Needle inference engine maintains a constant memory footprint of approximately 28 MiB regardless of prompt length or tool complexity. This stability comes from the zero-copy weight loading mechanism: once needle_load maps the .cact archive into memory, subsequent calls to needle_complete or needle_embed reference that same buffer without allocating additional weight storage.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →