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

> Learn how to upload a fine-tuned cact model to Hugging Face using the --upload flag. Push your .cact archive directly to a Hugging Face repository with needle build and NEEDLE_HF_REPO.

- Repository: [Cactus Compute, Inc./needle](https://github.com/cactus-compute/needle)
- Tags: how-to-guide
- Published: 2026-08-14

---

**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`](https://github.com/cactus-compute/needle/blob/main/needle/cli.py)** at lines 55-56. It is a boolean flag that, when present, sets `args.upload = True`:

```python
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`](https://github.com/cactus-compute/needle/blob/main/needle/model/finetune.py)**.

### Export and Upload Pipeline

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

1. **Model export** — `build_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`](https://github.com/cactus-compute/needle/blob/main/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:

```bash
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:

```bash
huggingface-cli login

# Or set HF_TOKEN as an environment variable

```

## Complete Upload Command Examples

### Basic Upload

```bash

# 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

```bash

# 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

```bash

# 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:

```python
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:

```python
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`](https://github.com/cactus-compute/needle/blob/main/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`](https://github.com/cactus-compute/needle/blob/main/needle/cli.py)** — Defines the `--upload` argument for the `build` subcommand (lines 55-56)
- **[`needle/model/export.py`](https://github.com/cactus-compute/needle/blob/main/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`](https://github.com/cactus-compute/needle/blob/main/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`](https://github.com/cactus-compute/needle/blob/main/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()`.