Skip to content

Start here

Three commands keep a model and talk to it. This page walks through them with a tiny Hub repo so the first success is measured in seconds, then shows the same path on a real model.

If you only remember one picture, remember this:

source ──archive──► vault/bundle ──run──► tokens
payload never changes

Python 3.10+, macOS or Linux.

Terminal window
pipx install darsay
darsay --help

No pipx? One-shot with no install:

Terminal window
uvx darsay --help

More install paths: Distribution.

estimate talks to the Hub API and writes nothing. Use it whenever you are about to spend disk.

Terminal window
darsay estimate sshleifer/tiny-gpt2

You get a pinned revision, a file count, a size, a download bar (styled like the live archive panel), a disk verdict, and the exact archive command to run next. If you already hold part of this source — a budget-stopped archive, an interrupted download — the bar shows how much is banked and only the remaining bytes count against your free space. If free space is short, the command exits non-zero — it is a script-friendly guard, not just a printout.

Terminal window
darsay archive sshleifer/tiny-gpt2

That pins main to a commit, copies every file, hashes them, checks the hashes against upstream, captures the license, and writes a bundle under ~/darsay (override with --vault or $DARSAY_HOME). On a real model the live panel is percent of the whole payload, bytes in / total, rate, and time remaining — archives are large enough that a per-file bar is the wrong unit. When it finishes:

Bundle ready: ~/darsay/sshleifer--tiny-gpt2/<rev>
id: sshleifer--tiny-gpt2@<rev>
manifest: …/manifest.json
readme: …/README.md
verification: …/VERIFICATION.md
curation: …/curation.md <- edit this, then `darsay regen`
next: darsay run sshleifer--tiny-gpt2@<rev>

Find it later with:

Terminal window
darsay list
darsay info sshleifer--tiny-gpt2

list is the vault as a catalog view: STATUS, SOURCE, and HAVE (the bundle id). <rev> is the first 12 characters of the pinned commit. info, run, verify, and the other bundle commands accept the path (list --json), the id, or a unique prefix (sshleifer--tiny-gpt2, tiny-gpt2, the revision).

Save a want-list before the bytes exist:

Terminal window
darsay catalog new summer
darsay catalog add summer sshleifer/tiny-gpt2 --desire 8
darsay list summer

Friends overlay the same file against their vault (catalogs, share a catalog).

~/darsay/sshleifer--tiny-gpt2/<rev>/
├── model/ # the repo, frozen
├── manifest.json # facts, never guesses
├── README.md # generated view of those facts
├── curation.md # yours — the tool will not overwrite this
└── LICENSE

Two rules that make the rest of darsay obvious:

  1. Nothing under model/ is ever modified again. That is the archive.
  2. Everything the tool writes later lives beside it, at the bundle root — verification reports, hydration records, export logs.

The mental model in full: Concepts.

Point any Hugging Face-compatible loader at the payload. No conversion:

from pathlib import Path
from transformers import AutoModelForCausalLM, AutoTokenizer
path = Path.home() / "darsay/sshleifer--tiny-gpt2/<rev>/model"
tok = AutoTokenizer.from_pretrained(path)
model = AutoModelForCausalLM.from_pretrained(path)

Or let darsay build an isolated env and run offline (HF_HUB_OFFLINE=1):

Terminal window
darsay run sshleifer--tiny-gpt2 "Hello"

The tokens will be nonsense — the model is tiny. The point is the path works. The first run downloads engine packages (torch, transformers) into <vault>/.runtime/ — outside the bundle, shared with any other bundle that needs the same env. The payload is not touched. Deleting the env never deletes the archive.

Same three verbs. Larger bytes. Identical shape.

Terminal window
darsay estimate Qwen/Qwen3-0.6B
darsay archive Qwen/Qwen3-0.6B
darsay run qwen--qwen3-0.6b Say hello
# or: darsay run qwen--qwen3-0.6b --repl

Qwen3-0.6B is about 1.5 GiB. estimate tells you before you commit. If a later source is gated, set $HF_TOKEN or run huggingface-cli login.

Situation What to do
The download is huge darsay archive … --max-gb 10 — exits 10, rerun to resume
The disk is filling up archive pauses at 2 GiB free by default (exit 10). Clear space, rerun. darsay config shows the floor; --min-free 10G raises it
You hit Ctrl-C Once stops cleanly, twice aborts now. Rerun the same archive command; completed files are kept
You only want one GGUF from a pack darsay archive REPO --include '*Q4_K_M*' — prices first with estimate --include
It is a dataset, not a model darsay archive datasets/owner/name — payload lands in data/
You want one file for a USB drive darsay export <bundle> -o /backups
You want to know it still matches darsay verify <bundle>
You wrote curator notes edit curation.md, then darsay regen <bundle>
You want shell completion eval "$(darsay complete zsh)" (or bash / fish)
You want disk usage darsay du

Copy-paste for each of those: Examples.

  • No bundles in …/darsay/ — you passed --vault / $DARSAY_HOME when you archived. The default is ~/darsay; list prints the path it used.
  • Disk verdict insufficientestimate is doing its job. Free space, or pick a smaller source.
  • Archive paused with exit code 10 — a budget ran out. Rerun the same command; that is success, not failure.
  • run wants to install torch — expected, once, into the shared runtime. The bundle itself stays a few files of metadata plus model/.
  • Windows — untested best-effort. macOS and Linux are the supported targets.

A vault is a folder of bundles. A bundle is a pinned snapshot you can still load. estimate prices, archive keeps, run proves.

Everything else in this repository is a sharpening of that loop: catalogs, resumable transfer, dataset bundles, offline hydration, single-file export. When you want the map of all of it: Documentation home.