Installation
June 23, 2026 · View on GitHub
MegaDetector-Overhead is installed with uv.
A single uv sync builds a Python 3.11 environment with all dependencies,
the animaloc training/eval package, and the vendored dinov3/ encoder
in editable mode.
1. Install uv (one-time, per machine)
curl -LsSf https://astral.sh/uv/install.sh | sh
(See the uv docs for Windows / macOS installers.)
!!! note "If uv is not found after installing"
The installer places uv in ~/.local/bin and adds it to your PATH — but
that change only applies to new shells. If uv sync reports
uv: command not found in the same terminal, either open a new shell or run:
```bash
source "$HOME/.local/bin/env" # if the installer created it
# ...or add the directory to PATH directly:
export PATH="$HOME/.local/bin:$PATH" # for the current shell
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc # persist it
```
2. Clone and sync the environment
git clone https://github.com/microsoft/MegaDetector-Overhead
cd MegaDetector-Overhead
uv sync
This will:
- Download CPython 3.11 if not already present on the host (uv reads
the version from
.python-version). - Create
.venv/at the repo root. - Resolve and install the locked dependency set from
uv.lock(PyTorch, torchvision, Hydra, wandb, albumentations, the DINOv3 transitive deps, and the geospatial stack). - Install the
megadetector-overheadroot project editably, which exposes theanimalocpackage. - Install the vendored
dinov3/subtree editably from its ownsetup.py.
A plain uv sync installs the CPU build of PyTorch, so it works on any
machine and makes no assumption that you have a GPU. To run on a CUDA GPU,
sync the GPU group instead — see GPU support below.
Activate the venv, then run everything with plain python (this uses the
build you synced — CPU or GPU — and never re-syncs it):
source .venv/bin/activate # Windows: .venv\Scripts\activate
3. Smoke test
python -c "import animaloc.models, dinov3; print('OK')"
Expected output: OK.
A more thorough check that lists the registered models:
python -c "from animaloc.models import MODELS; print(sorted(MODELS.registry_names))"
Expected:
['FasterRCNNResNetFPN', 'HerdNet', 'OWLC', 'OWLD_B', 'OWLD_H', 'OWLD_L', 'OWLD_S', 'OWLT', 'SemSegDLA']
For end-to-end verification (forward pass on every OWL model, plus a mini training + eval run on synthetic data), use the bundled smoke tests:
python tests/smoke_forward.py
python tests/make_synthetic_dataset.py
WANDB_MODE=disabled python tools/train.py train=owlc_smoketest
See tests/README.md.
4. Download DINOv3 weights (one-time, ~6 GB total)
The OWL-D family loads DINOv3 ViT backbones at training time. Weights
are NOT vendored (5.8 GB, governed by the
DINOv3 License). Download them from Meta's official
release and place them under weights/ at the repo root:
mkdir -p weights/
# Replace <URL> with the official Meta DINOv3 release link for each backbone
# (see https://github.com/facebookresearch/dinov3 for the download form).
wget <URL> -O weights/dinov3_vits16_pretrain_lvd1689m-08c60483.pth
wget <URL> -O weights/dinov3_vitb16_pretrain_lvd1689m-73cec8be.pth
wget <URL> -O weights/dinov3_vitl16_pretrain_lvd1689m-8aa4cbdd.pth
wget <URL> -O weights/dinov3_vith16plus_pretrain_lvd1689m-7c1da9a5.pth
The default filenames above match the paths hard-coded into
animaloc/models/owl_d.py (_DEFAULT_WEIGHTS_FILENAME). To use a
different filename or directory, override weights in the training
config.
weights/ is .gitignored.
5. (Optional) Install development dependencies
uv sync --extra dev # adds pytest, ruff, mypy
uv sync --extra docs # adds mkdocs + material theme for building this site
Python version
DINOv3 requires Python ≥ 3.11 (uses PEP 604 union syntax internally),
so the project pins >=3.11,<3.13. uv reads .python-version and
will auto-download CPython 3.11 if your system Python is older or newer.
GPU support
There are two install options. Both pin PyTorch in uv.lock, so they're fully
reproducible.
CPU (default) — works on any machine, no GPU assumed:
uv sync # or: make sync
GPU — a CUDA build for NVIDIA GPUs:
uv sync --no-default-groups --group gpu # or: make sync-gpu
Then activate the virtualenv and run Python directly — this uses whichever build you synced and never reverts it:
source .venv/bin/activate
python -c "import torch; print('CUDA:', torch.cuda.is_available(), torch.cuda.device_count(), 'devices')"
python tools/test.py ...
(deactivate to leave the venv. On Windows: .venv\Scripts\activate.)
!!! tip "Use the activated venv, not uv run, on the GPU"
cpu is the default group, so a bare uv sync or uv run re-syncs the
environment back to the CPU build. Activating the venv (above) and calling
python directly avoids that entirely — no per-command flags. If you prefer
uv run, you must pass the group every time:
uv run --no-default-groups --group gpu python .... The bundled demo scripts
sidestep this by calling the venv interpreter directly.
Which GPU build / why gpu = CUDA 12.1
The gpu group installs torch 2.5.1+cu121, whose kernels cover NVIDIA
Volta (sm_70, e.g. Tesla V100) through Hopper (sm_90). This is chosen by
the GPU's architecture, not your driver version: newer cu124/cu128 wheels
drop Volta kernels, so a V100 on those builds raises
RuntimeError: ... unable to find an engine. A CUDA-12.1 build runs fine on newer
drivers (they are backward-compatible), so --group gpu works across the common
NVIDIA data-center/workstation GPUs.
!!! note "Blackwell / very new GPUs"
GPUs that require CUDA 12.8+ (e.g. Blackwell, sm_100/120) are not covered by
cu121. Add a cu128 group in pyproject.toml following the same pattern as
gpu (point its source at the pytorch-cu128 index) and sync that instead.
Troubleshooting
-
torch.cuda.is_available()isFalseeven thoughnvidia-smishows a GPU — you have the CPU build, or a bareuv sync/uv runreverted it. Sync the GPU group (uv sync --no-default-groups --group gpu) and run via the activated venv (source .venv/bin/activate), not bareuv run(see GPU support above). -
RuntimeError: ... unable to find an engine— the wheel lacks kernels for your GPU's architecture. Thegpugroup (cu121) covers Volta–Hopper; very new GPUs need a cu128 group (see note above). -
ImportError: libgthread-2.0.so.0— opencv-python's GUI bindings need glib. We pinopencv-python-headlessinstead. If the headless build was accidentally replaced byopencv-python, runuv sync --reinstall-package opencv-python-headless. -
uv syncresolver failure — deleteuv.lock, re-runuv lock, and re-sync. If the failure persists, open an issue with the resolver log. -
uv lockoruv syncfails fetchingdownload-r2.pytorch.org(TLS / connection errors) — some corporate or cloud networks block PyTorch's CDN (download-r2.pytorch.org), which serves both wheel metadata (needed byuv lock) and the wheels themselves (needed byuv sync). On such networks:uv lockcan't run locally. The lockfile is regenerated automatically by the Update uv.lock GitHub Actions workflow (.github/workflows/update-lock.yml) wheneverpyproject.tomlchanges; you can also trigger it by hand from the repo's Actions tab, thengit pullto get the refresheduv.lock.uv syncmay fail to download the PyTorch wheels. Ask your network admin to allowlistdownload.pytorch.organddownload-r2.pytorch.org, run the install from an unrestricted network, or install PyTorch manually (e.g.uv pip install torch torchvision --torch-backend=auto, or download the wheels withcurlfromdownload.pytorch.organduv pip install ./<wheel>.whl).
This only affects networks that block that host — a normal
uv syncdownloads the CPU wheels without issue. -
DINOv3 weights file not found at training time — verify the file name under
weights/matches the_DEFAULT_WEIGHTS_FILENAMEconstant on the correspondingOWLD_*class inanimaloc/models/owl_d.py.