CLI
Every candding command line subcommand and flag, from listing the registry to embedding text and benchmarking throughput.
The candding binary lists and describes the registry, downloads weights, embeds texts, reranks documents and measures throughput. The candding-cli crate is not published on crates.io; install it from the repository:
cargo install --git https://github.com/rust-dd/candding candding-cli
cargo install --git https://github.com/rust-dd/candding candding-cli --features metalIn a checkout, run cargo run -q -p candding-cli -- <command>; the examples below use the bare binary name.
| Command | What it does |
|---|---|
list-models | prints the four catalogs as tables, or as JSON |
describe <id> | prints every field of a model's descriptors |
fetch <id> or fetch phase:<n> | downloads into the Hugging Face cache |
embed <id> <text>... | prints dense vectors, sparse rows or multi-vector matrices |
rerank <id> <query> <document>... | prints the documents' scores, best first |
bench <id> | measures dense documents per second at several batch sizes |
embed, rerank and bench take --device auto|cpu|metal|cuda and --dtype f32|f16|bf16. auto, the default device, picks Metal, then CUDA, then the CPU, among the backends compiled in, and a backend the build lacks fails with BackendNotCompiled rather than falling back to the CPU. The dtype defaults to the model's.
list-models
candding list-models
candding list-models --phase 3
candding list-models --json| Flag | Effect |
|---|---|
--phase <n> | keeps the rows of that roadmap phase; a phase with no model exits non-zero |
--json | one object with the arrays dense, sparse, multi_vector and rerank, every descriptor with all its fields; the catalog is generated from it |
| Multi-vector column | Meaning |
|---|---|
width | projection_in->projection_out |
cls | whether the classification row survives the head, keeps_cls_row |
norm | whether every row is L2-normalized |
reduce | how late_interaction_score_for reduces the summed score, sum or mean_by_query_length |
qlen | the fixed row count a query is padded to, or - when the head fixes none |
Values print as their serde names, the spelling --json uses, and a rerank cell adds its detail, as windowed:query_cap=512,overlap=80. A dtypes cell reads f16:unsupported when the three devices agree and f16(cpu:unsupported metal:verified cuda:untested) when they differ.
describe
candding describe BAAI/bge-small-en-v1.5
candding describe BAAI/bge-m3 --json
candding describe jinaai/jina-reranker-v2-base-multilingualid: jinaai/jina-reranker-v2-base-multilingual
family: xlm_roberta_flash
head: roberta_classification_head
score activation: sigmoid
input: windowed
query cap: 512
window overlap: 80
alibi variant: none
position scheme: absolute
max length: 1024
license: CC-BY-NC-4.0
size: 0.56 GB
phase: 5
weights: safetensors
gated: false
backends: cpu=verified metal=verified cuda=untested
default dtype: f32
dtypes:
f32: cpu=verified metal=verified cuda=untested
f16: cpu=unsupported metal=verified cuda=untested
bf16: cpu=unsupported metal=verified cuda=untested- An id in several registries, such as
BAAI/bge-m3, prints adense:,sparse:,multi-vector:orrerank:section for each. --jsonputs the first hit, in that order, at the top level and nests the others undersparse,multi_vectororrerank.- An id in no registry is an error that points to
candding list-models. Qdrant/bm25prints readable values, such asunboundedfor its max length, and notes that it has no device or dtype axis.
fetch
candding fetch BAAI/bge-small-en-v1.5
candding fetch phase:0
candding fetch BAAI/bge-small-en-v1.5 --revision refs/pr/1fetch downloads through the library, as model files and cache describes. Unlike a build, which uses a cached snapshot as it is, it always lists the revision on the Hub and downloads the files that are missing or do not match.
| Argument | Effect |
|---|---|
phase:<n> | every model of that phase in the four registries, each id once, plus each sparse head's second repository at its pinned revision |
--revision <rev> | a branch, a tag or a commit |
Qdrant/bm25 | nothing to download: fetch names Bm25TextEmbedding::builder() and moves on |
embed
candding embed BAAI/bge-small-en-v1.5 "hello world" --query --jsonEvery text after the model id is embedded, and each vector prints as one line with six decimals per value. Without --sparse or --multi-vector, an id that only another catalog carries is refused with an error naming the command that runs it.
| Flag | Effect |
|---|---|
--query, --passage | applies the model's query or passage template; the two exclude each other |
--dim <n> | Matryoshka truncation to n columns, refused before tokenizing on a model without Matryoshka support |
--sparse | the model's sparse head: index:weight pairs by descending weight, ties by ascending index, or with --json one {"indices", "values"} object per text; excludes --dim, --query and --passage |
--multi-vector | the model's multi-vector head, the document side unless --query is given: <rows> rows x <dim> per text, or with --json one array of rows per text; excludes --dim, --sparse and --passage |
--count | each text's token count after truncation and the text, instead of the vectors; special tokens count, and so does the template --query or --passage selects on a dense model |
--max-length <n> | overrides the default length, capped at the model's position limit |
--no-normalize | returns the dense vector, or each multi-vector row, without L2 normalization |
--json | one JSON array of arrays instead of the plain lines |
Plain sparse lines, like rerank's, are capped to the terminal width: COLUMNS, or 80 columns when it is unset or zero.
rerank
candding rerank cross-encoder/ms-marco-MiniLM-L6-v2 "how many people live in berlin" "Berlin has a population of 3.5 million." "The capital of France is Paris." "" --device cpu0 8.650594 Berlin has a population of 3.5 million.
2 -10.029929
1 -11.319403 The capital of France is Paris.Each line is the document's input index, its score with six decimals and the document, tab-separated, best first. Equal scores keep their input order, and a NaN ranks last and prints as null in --json. The score is the checkpoint's own: a logit, a logit difference or a probability.
| Flag | Effect |
|---|---|
--json | one JSON array of {"index", "score"} objects, best first, each score the shortest decimal that reads back as the same f32 |
--count | each pair's token count after truncation, query, special and template tokens included, in input order, summed over the windows, the query in each, on a windowed reranker; refused with --json |
--instruction <text> | the instruction a prompt reranker renders in place of its default, for the scores and --count; an empty text renders empty, and a pair or windowed reranker refuses the flag with InstructionOnPairInput before anything is fetched |
--max-length <n> | overrides the default length, capped at the position limit; refused with LengthTooSmall below the input's minimum, 4 or 5 tokens for a pair reranker, 49 for a Qwen3 prompt and 1024 for the windowed reranker |
--batch-size <n> | pairs, or windows on a windowed reranker, per forward pass; 8 by default |
An id outside the rerank registry fails with UnregisteredModel.
bench
cargo run --release -p candding-cli -- bench BAAI/bge-small-en-v1.5 --docs 256 --batch-sizes 1,8,32bench embeds synthetic documents of 8 to 200 words with a dense model after a warm-up, and prints the model, device, dtype and document count, then documents per second and the total time per batch size. --docs defaults to 256 and --batch-sizes to 1,8,32. Run it from a release build: the debug profile does not optimize candding itself.