Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/convert-and-publish-gguf.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
# Output a JSON array of variant strings so `fromJson(...)` in the
# publish job's matrix can parse it. A space-separated string would
# make fromJson throw a workflow-level error.
ALL_JSON='["dinov2-small","dinov2-base","dinov2-large","dinov2-giant","dinov2-with-registers-small","dinov2-with-registers-base","dinov2-with-registers-large","dinov2-with-registers-giant"]'
ALL_JSON='["dinov2-small","dinov2-base","dinov2-large","dinov2-giant","dinov2-with-registers-small","dinov2-with-registers-base","dinov2-with-registers-large","dinov2-with-registers-giant","dinov2-backbone-small","dinov2-backbone-base","dinov2-backbone-large","dinov2-backbone-giant","dinov2-backbone-with-registers-small","dinov2-backbone-with-registers-base","dinov2-backbone-with-registers-large","dinov2-backbone-with-registers-giant"]'
if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ inputs.variant }}" != "all" ]; then
# Wrap the single variant name in a JSON array.
ONE_JSON="[\"${{ inputs.variant }}\"]"
Expand Down
2 changes: 1 addition & 1 deletion ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ Deliberately untracked by `.gitignore` and not in release archives:
- [docs/benchmarks.md](docs/benchmarks.md): how to read the tables,
methodology, reproducing locally.
- [docs/hf-publishing.md](docs/hf-publishing.md): `HF_TOKEN` setup, the
`convert-and-publish-gguf` workflow, the 8 published HF repos.
`convert-and-publish-gguf` workflow, the 16 published HF repos.
- [README.md](README.md): quickstart, downloads, why this fork exists.
- [GitHub releases](https://github.com/espetro/dinov2.cpp/releases): per-tag
release notes, breaking changes, and upgrade notes.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,21 @@ Ready-to-download f16 GGUF weights, published by CI to the [`dinov2-cpp-core`](h
| large (registers) | [`dinov2-cpp-core/dinov2-with-registers-large-gguf`](https://huggingface.co/dinov2-cpp-core/dinov2-with-registers-large-gguf) | ~620 MB | **Recommended for patch/dense features** |
| giant (registers) | [`dinov2-cpp-core/dinov2-with-registers-giant-gguf`](https://huggingface.co/dinov2-cpp-core/dinov2-with-registers-giant-gguf) | ~2.2 GB | **Recommended for patch/dense features** |

Backbone-only checkpoints carry the same encoder weights without the ImageNet
classifier head. They run the feature modes (`--print-embeddings`,
`--print-patch-tokens`, `-o` PCA, `--bench`) and reject `-c` cleanly:

| Model | GGUF download | Size | Recommendation |
|:-----:|:--------------|-----:|:---------------|
| small (backbone, no registers) | [`dinov2-cpp-core/dinov2-backbone-small-gguf`](https://huggingface.co/dinov2-cpp-core/dinov2-backbone-small-gguf) | ~50 MB | Feature mode only; no classifier head |
| base (backbone, no registers) | [`dinov2-cpp-core/dinov2-backbone-base-gguf`](https://huggingface.co/dinov2-cpp-core/dinov2-backbone-base-gguf) | ~180 MB | Feature mode only; no classifier head |
| large (backbone, no registers) | [`dinov2-cpp-core/dinov2-backbone-large-gguf`](https://huggingface.co/dinov2-cpp-core/dinov2-backbone-large-gguf) | ~620 MB | Feature mode only; no classifier head |
| giant (backbone, no registers) | [`dinov2-cpp-core/dinov2-backbone-giant-gguf`](https://huggingface.co/dinov2-cpp-core/dinov2-backbone-giant-gguf) | ~2.2 GB | Feature mode only; no classifier head |
| small (backbone, registers) | [`dinov2-cpp-core/dinov2-backbone-with-registers-small-gguf`](https://huggingface.co/dinov2-cpp-core/dinov2-backbone-with-registers-small-gguf) | ~50 MB | Feature mode only; no classifier head |
| base (backbone, registers) | [`dinov2-cpp-core/dinov2-backbone-with-registers-base-gguf`](https://huggingface.co/dinov2-cpp-core/dinov2-backbone-with-registers-base-gguf) | ~180 MB | Feature mode only; no classifier head |
| large (backbone, registers) | [`dinov2-cpp-core/dinov2-backbone-with-registers-large-gguf`](https://huggingface.co/dinov2-cpp-core/dinov2-backbone-with-registers-large-gguf) | ~620 MB | Feature mode only; no classifier head |
| giant (backbone, registers) | [`dinov2-cpp-core/dinov2-backbone-with-registers-giant-gguf`](https://huggingface.co/dinov2-cpp-core/dinov2-backbone-with-registers-giant-gguf) | ~2.2 GB | Feature mode only; no classifier head |

For patch and dense feature workflows, the register-token variants are the recommended starting point. In the settings studied in [Vision Transformers Need Registers](https://arxiv.org/abs/2309.16588), register tokens reduce high-norm patch-token artifacts and produce smoother local feature and attention maps. Use them with `--print-patch-tokens`, PCA, dense features, and object discovery. This is not a universal accuracy claim: the official [DINOv2 results](https://github.com/facebookresearch/dinov2/blob/main/README.md) show classification and retrieval results that depend on the task and model size. Choose the no-register variant for exact baseline reproduction or task-specific classification and retrieval comparisons.

## Documentation
Expand Down
19 changes: 14 additions & 5 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,20 @@ cleanly with a message that classification requires a classifier GGUF rather
than attempting to access missing tensors. A missing `num_register_tokens`
metadata key is treated as zero registers for feature mode.

The conversion and publishing workflows currently map the eight
`imagenet1k-1-layer` checkpoints and their register-token counterparts. They do
not publish backbone-only weights. Conversion and publishing of those weights
remains a follow-up, and this documentation does not claim that published
backbone-only files exist.
The publishing workflow converts the backbone checkpoints alongside the eight
`imagenet1k-1-layer` classifier variants and ships them as
`dinov2-cpp-core/dinov2-backbone-{size}-gguf` (from `facebook/dinov2-{size}`)
and `dinov2-cpp-core/dinov2-backbone-with-registers-{size}-gguf` (from
`facebook/dinov2-with-registers-{size}`), where `{size}` is `small`, `base`,
`large`, or `giant`:

```bash
hf download dinov2-cpp-core/dinov2-backbone-small-gguf --local-dir models
dinov2-cli -m models/model.gguf -i assets/tench.jpg --print-embeddings
```

Use a backbone weight when you want the feature extractor without the
classifier head; for `-c` pick one of the classifier repos above.

DINOv2 task heads other than the existing ImageNet classifier, including depth
and segmentation, are outside this interface. DINOv3 is a separate
Expand Down
39 changes: 26 additions & 13 deletions docs/hf-publishing.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# HF publishing setup

The [`convert-and-publish-gguf`](../.github/workflows/convert-and-publish-gguf.yml)
workflow converts the 8 DINOv2 variants to f16 GGUF and uploads them to the
workflow converts the 16 DINOv2 variants to f16 GGUF and uploads them to the
`dinov2-cpp-core/<variant>-gguf` repos on Hugging Face. It runs monthly (cron `0 6 1 * *`)
and on demand via `workflow_dispatch`.

Expand Down Expand Up @@ -29,15 +29,28 @@ and on demand via `workflow_dispatch`.
- The `giant` variants need ~12-13 GB transient disk, so those jobs free runner
disk space first.

## The 8 published repos

| Variant | HF repo |
|---|---|
| small | `dinov2-cpp-core/dinov2-small-gguf` |
| base | `dinov2-cpp-core/dinov2-base-gguf` |
| large | `dinov2-cpp-core/dinov2-large-gguf` |
| giant | `dinov2-cpp-core/dinov2-giant-gguf` |
| small (registers) | `dinov2-cpp-core/dinov2-with-registers-small-gguf` |
| base (registers) | `dinov2-cpp-core/dinov2-with-registers-base-gguf` |
| large (registers) | `dinov2-cpp-core/dinov2-with-registers-large-gguf` |
| giant (registers) | `dinov2-cpp-core/dinov2-with-registers-giant-gguf` |
## The 16 published repos

| Variant | Source checkpoint | HF repo |
|---|---|---|
| small | `facebook/dinov2-small-imagenet1k-1-layer` | `dinov2-cpp-core/dinov2-small-gguf` |
| base | `facebook/dinov2-base-imagenet1k-1-layer` | `dinov2-cpp-core/dinov2-base-gguf` |
| large | `facebook/dinov2-large-imagenet1k-1-layer` | `dinov2-cpp-core/dinov2-large-gguf` |
| giant | `facebook/dinov2-giant-imagenet1k-1-layer` | `dinov2-cpp-core/dinov2-giant-gguf` |
| small (registers) | `facebook/dinov2-with-registers-small-imagenet1k-1-layer` | `dinov2-cpp-core/dinov2-with-registers-small-gguf` |
| base (registers) | `facebook/dinov2-with-registers-base-imagenet1k-1-layer` | `dinov2-cpp-core/dinov2-with-registers-base-gguf` |
| large (registers) | `facebook/dinov2-with-registers-large-imagenet1k-1-layer` | `dinov2-cpp-core/dinov2-with-registers-large-gguf` |
| giant (registers) | `facebook/dinov2-with-registers-giant-imagenet1k-1-layer` | `dinov2-cpp-core/dinov2-with-registers-giant-gguf` |
| small (backbone) | `facebook/dinov2-small` | `dinov2-cpp-core/dinov2-backbone-small-gguf` |
| base (backbone) | `facebook/dinov2-base` | `dinov2-cpp-core/dinov2-backbone-base-gguf` |
| large (backbone) | `facebook/dinov2-large` | `dinov2-cpp-core/dinov2-backbone-large-gguf` |
| giant (backbone) | `facebook/dinov2-giant` | `dinov2-cpp-core/dinov2-backbone-giant-gguf` |
| small (backbone, registers) | `facebook/dinov2-with-registers-small` | `dinov2-cpp-core/dinov2-backbone-with-registers-small-gguf` |
| base (backbone, registers) | `facebook/dinov2-with-registers-base` | `dinov2-cpp-core/dinov2-backbone-with-registers-base-gguf` |
| large (backbone, registers) | `facebook/dinov2-with-registers-large` | `dinov2-cpp-core/dinov2-backbone-with-registers-large-gguf` |
| giant (backbone, registers) | `facebook/dinov2-with-registers-giant` | `dinov2-cpp-core/dinov2-backbone-with-registers-giant-gguf` |

The `dinov2-backbone-*` variants convert the backbone-only checkpoints, so
their GGUFs support feature modes only (`--print-embeddings`,
`--print-patch-tokens`, `-o` PCA, `--bench`) and reject `-c`. See
[cli.md](cli.md#backbone-only-checkpoints).
9 changes: 9 additions & 0 deletions scripts/publish-gguf.sh
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,18 @@ case "$VARIANT" in
dinov2-with-registers-base) HF_ID="facebook/dinov2-with-registers-base-imagenet1k-1-layer" ;;
dinov2-with-registers-large) HF_ID="facebook/dinov2-with-registers-large-imagenet1k-1-layer" ;;
dinov2-with-registers-giant) HF_ID="facebook/dinov2-with-registers-giant-imagenet1k-1-layer" ;;
dinov2-backbone-small) HF_ID="facebook/dinov2-small" ;;
dinov2-backbone-base) HF_ID="facebook/dinov2-base" ;;
dinov2-backbone-large) HF_ID="facebook/dinov2-large" ;;
dinov2-backbone-giant) HF_ID="facebook/dinov2-giant" ;;
dinov2-backbone-with-registers-small) HF_ID="facebook/dinov2-with-registers-small" ;;
dinov2-backbone-with-registers-base) HF_ID="facebook/dinov2-with-registers-base" ;;
dinov2-backbone-with-registers-large) HF_ID="facebook/dinov2-with-registers-large" ;;
dinov2-backbone-with-registers-giant) HF_ID="facebook/dinov2-with-registers-giant" ;;
*)
echo "ERROR: unknown variant '$VARIANT'" >&2
echo " known variants: dinov2-{small,base,large,giant} dinov2-with-registers-{small,base,large,giant}" >&2
echo " dinov2-backbone-{small,base,large,giant} dinov2-backbone-with-registers-{small,base,large,giant}" >&2
exit 2
;;
esac
Expand Down
Loading