How to Upload a Fine-Tuned `.cact` Model to Hugging Face Using the `--upload` Flag

Pass the --upload flag to needle build and set the NEEDLE_HF_REPO environment variable to push your .cact archive directly to a Hugging Face model repository.

The needle CLI from the cactus-compute/needle repository streamlines publishing quantized models. After fine-tuning, you can export to the compact .cact format and upload it to Hugging Face in a single command. Here's how the upload mechanism works and how to use it.

How the --upload Flag Works

CLI Flag Definition

The --upload flag is registered in needle/cli.py at lines 55-56. It is a boolean flag that, when present, sets args.upload = True:

p.add_argument("--upload", action="store_true",
               help="Push the .cact to $NEEDLE_HF_REPO")

This flag is available on the build subcommand, which invokes build_main in needle/model/finetune.py.

Export and Upload Pipeline

When you run needle build with --upload, the execution flow follows these stages:

  1. Model exportbuild_main calls write_export to create the .cact archive
  2. Upload check — After export, the code checks if args.upload: (lines 35-36 of finetune.py)
  3. Repository resolution — The NEEDLE_HF_REPO environment variable is read as the target repository
  4. Repository creation — The Hugging Face Hub SDK creates the repo if it doesn't exist
  5. File upload — The .cact file is pushed to the repository root

Setting Up the Upload Environment

Required Environment Variable

Before using --upload, export NEEDLE_HF_REPO with your target repository identifier:

export NEEDLE_HF_REPO="yourusername/your-model-name"

The repository must follow Hugging Face's <user>/<model> format. If this variable is missing, Needle raises a clear error to alert you (lines 36-38).

Hugging Face Authentication

Ensure you're authenticated with the Hugging Face Hub. The huggingface_hub dependency is required for the upload functionality:

huggingface-cli login

# Or set HF_TOKEN as an environment variable

Complete Upload Command Examples

Basic Upload


# Set target repository

export NEEDLE_HF_REPO="myteam/needle-llama-7b"

# Build and upload in one step

needle build checkpoints/final.pkl --upload

With Quantization Options


# 4-bit quantization with custom output name

needle build checkpoints/final.pkl \
    --bits 4 \
    --out llama-7b-4bit.cact \
    --upload

Full Workflow After Fine-Tuning


# 1. Fine-tune (produces checkpoint.pkl)

needle finetune --model llama-7b --data training.jsonl

# 2. Export to .cact and publish

export NEEDLE_HF_REPO="research/needle-qa-model"
needle build checkpoint.pkl --bits 2 --upload

Upload Implementation Details

Repository Handling (Lines 39-41)

Needle uses huggingface_hub.HfApi to ensure the target repository exists:

api = HfApi()
api.create_repo(repo, repo_type="model", exist_ok=True)

The exist_ok=True parameter allows repeated uploads without errors.

File Upload (Lines 42-44)

The actual upload uses upload_file with the archive placed at the repository root:

api.upload_file(
    path_or_fileobj=archive_path,
    path_in_repo=archive_name,
    repo_id=repo
)

The path_in_repo preserves your specified filename (e.g., mymodel.cact), making it easy for consumers to identify the correct file.

Troubleshooting Upload Failures

Issue Cause Solution
"NEEDLE_HF_REPO not set" Environment variable missing export NEEDLE_HF_REPO="user/model" before running
Authentication error Invalid or missing HF token Run huggingface-cli login or set HF_TOKEN
Upload hangs Network or permission issue Verify repo ownership and Hub write access
File not appearing Wrong repo identifier Check <user>/<model> format matches your account

Key Source Files

  • needle/model/finetune.py — Contains build_main, the upload conditional check (lines 35-36), environment variable reading (lines 36-38), repository creation (lines 39-41), and file upload logic (lines 42-44)
  • needle/cli.py — Defines the --upload argument for the build subcommand (lines 55-56)
  • needle/model/export.py — Handles .cact archive generation called by build_main

Summary

  • Set NEEDLE_HF_REPO to your target <user>/<model> identifier before running any upload command
  • Add --upload to needle build to automatically push after export
  • Authentication requires huggingface_hub installed and valid Hugging Face credentials
  • Implementation uses HfApi.create_repo with exist_ok=True and upload_file for the actual transfer
  • Single-command workflow: needle build checkpoint.pkl --upload handles export and publication together

Frequently Asked Questions

What happens if the Hugging Face repository doesn't exist?

Needle automatically creates the repository if it's missing. The api.create_repo(repo, repo_type="model", exist_ok=True) call in finetune.py (lines 39-40) ensures the repo exists before attempting upload, using exist_ok=True to avoid errors on subsequent uploads.

Can I upload to an organization account instead of my personal account?

Yes. Set NEEDLE_HF_REPO to organization-name/model-name format. You must have write access to the organization repository. The code does not distinguish between user and organization repos—it passes the identifier directly to the Hugging Face Hub SDK.

Does --upload work with private repositories?

Yes. Repositories created via create_repo default to private visibility based on your Hugging Face account settings. To explicitly control visibility, manually create the repository on Hugging Face first, then use --upload—the exist_ok=True parameter allows this workflow.

What file format is actually uploaded to Hugging Face?

The .cact archive produced by write_export in needle/model/export.py. This is a compressed, quantized model format specific to the Needle toolkit. Consumers download this file and load it with Needle's inference API rather than standard transformers from_pretrained().

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →