Model files and cache
Where candding looks for weights, which files it downloads and reads, how gated repositories work and how to use a local directory.
Cache layout
candding reads the Hugging Face cache that the hf CLI and the Python libraries write, so a model you already pulled for another tool is a model candding can load. The root is $HF_HUB_CACHE when it is set, otherwise $HF_HOME/hub, otherwise ~/.cache/huggingface/hub.
~/.cache/huggingface/hub/
models--BAAI--bge-small-en-v1.5/
refs/main one line: the commit hash the branch points at
snapshots/<hash>/ config.json, tokenizer.json, model.safetensors
blobs/ the file contents the snapshot entries link toA repository id becomes a directory name by replacing every slash with a double dash, so BAAI/bge-small-en-v1.5 is models--BAAI--bge-small-en-v1.5. The revision defaults to main and the builder's revision method takes a branch, a tag or a commit hash. Resolution reads refs/<revision> to get the hash and then looks for snapshots/<hash>/; when there is no such ref file, the revision is treated as a commit hash and looked up under snapshots/ directly, which is what makes a pinned hash work without a ref.
What gets downloaded
When the snapshot is missing and the default hf-cli feature is on, the builder shells out to the CLI and takes the snapshot path from the last non-empty line of its output. The include patterns are *.json, *.safetensors, 1_Pooling/* and *_Dense/*, which is the smallest set the loader needs; ONNX exports, PyTorch .bin checkpoints, GGUF quantizations and OpenVINO directories are never fetched, and on a large repository those are most of the bytes.
hf download BAAI/bge-small-en-v1.5 --include "*.json" --include "*.safetensors" --include "1_Pooling/*" --include "*_Dense/*"That is also the command the library prints when it cannot fetch for you. Without the hf-cli feature a missing model is CanddingError::ModelNotFound, whose message carries the exact invocation above, with --revision appended when you asked for something other than main. With the feature on but no hf binary on the path, CanddingError::HfCliMissing says to install it with pip install huggingface_hub or uv tool install huggingface_hub and then repeats the same command.
What the loader reads
| File | Required | What it decides |
|---|---|---|
config.json | yes | model_type selects the family; pad_token_id sets the padding token, defaulting to zero |
tokenizer.json | yes | the tokenizer, replayed as published |
model.safetensors | yes, or an index | the weights, memory-mapped in the requested dtype |
model.safetensors.index.json | when the weights are sharded | the shard file names, deduplicated and loaded in name order |
1_Pooling/config.json | no | pooling for a repository with no registry entry and no descriptor |
modules.json | no | whether such a repository normalizes, from its Normalize entry |
A registry model, or one you pass a descriptor for, takes pooling, normalization, templates and dimension from the descriptor and ignores the two sentence-transformers files. Either way a missing config.json, tokenizer.json or weights file is CanddingError::MissingFile naming the path that was expected, before any tensor is touched.
Gated models
A gated repository needs its license accepted on huggingface.co and a token in place, either from hf auth login or from HF_TOKEN in the environment. When the CLI comes back with a 401 or a 403, candding maps it to CanddingError::GatedModel and says to accept the license and log in, because a retry cannot fix it. EmbeddingGemma is the first gated model on the roadmap, so nothing in today's catalog needs a token.
Local directories
Anywhere a model id is accepted, an existing directory path is accepted instead, and it is preferred: a spec that names a real directory is treated as a local model and the cache is never consulted. The directory needs config.json, tokenizer.json and safetensors weights, exactly what a snapshot holds, which makes a downloaded snapshot, a converted checkpoint and a fine-tune of your own interchangeable. A path that does not exist is not treated as a directory at all: ModelSource::parse only picks the local branch for an existing directory, so a typo falls through to the hub and surfaces as a failed download (HfCliFailed with the default hf-cli feature, ModelNotFound without it) rather than a missing-directory error.