rpx_benchmark.adapters.depth

Depth-model adapters (paper task Image Depth: MONOCULAR_DEPTH).

This subpackage holds one adapter class per model in the Image Depth roster. Adapters are skeletons today (see skeletons.py) — they declare the right task and depth_output_kind and raise NotImplementedError with the install hint when predict is called. A contributor who installs a model fills in its forward call without touching any other adapter.

Re-exports the canonical model-card table and the skeleton base class so callers can do from rpx_benchmark.adapters.depth import DepthAdapterSkeleton, DEPTH_MODEL_CARDS, available_depth_adapters.

 1"""Depth-model adapters (paper task Image Depth: MONOCULAR_DEPTH).
 2
 3This subpackage holds one adapter class per model in the Image Depth roster.
 4Adapters are skeletons today (see ``skeletons.py``) — they declare the
 5right ``task`` and ``depth_output_kind`` and raise
 6``NotImplementedError`` with the install hint when ``predict`` is
 7called. A contributor who installs a model fills in its forward call
 8without touching any other adapter.
 9
10Re-exports the canonical model-card table and the skeleton base class
11so callers can do ``from rpx_benchmark.adapters.depth import
12DepthAdapterSkeleton, DEPTH_MODEL_CARDS, available_depth_adapters``.
13"""
14
15from __future__ import annotations
16
17from ..depth_scaffold import (
18    DEPTH_MODEL_CARDS,
19    DepthAdapterSkeleton,
20    DepthModelCard,
21    available_depth_adapters,
22    lazy_import,
23)
24from . import skeletons as _skeletons  # noqa: F401 — registers subclasses
25
26__all__ = [
27    "DepthAdapterSkeleton",
28    "DepthModelCard",
29    "DEPTH_MODEL_CARDS",
30    "available_depth_adapters",
31    "lazy_import",
32]
class DepthAdapterSkeleton(rpx_benchmark.api.BenchmarkModel):
269class DepthAdapterSkeleton(BenchmarkModel):
270    """Base class for every depth-model adapter skeleton.
271
272    Subclasses set the class-level :attr:`MODEL_KEY` to the
273    ``DEPTH_MODEL_CARDS`` entry they wrap; everything else flows from
274    that card automatically. Override ``setup()`` and ``predict()``
275    with real implementations once the model is installed.
276
277    The default ``predict()`` raises a ``NotImplementedError`` whose
278    message includes the install hint, so any contributor who tries
279    to run an unimplemented adapter sees exactly what they need to do.
280    """
281
282    #: Key into :data:`DEPTH_MODEL_CARDS`. Must be set by subclasses.
283    MODEL_KEY: ClassVar[str] = ""
284
285    def __init_subclass__(cls, **kwargs: Any) -> None:
286        super().__init_subclass__(**kwargs)
287        if not cls.MODEL_KEY:
288            # The abstract scaffold itself doesn't have a key; subclasses
289            # without a key are an error.
290            if cls.__name__ != "DepthAdapterSkeleton":
291                raise ConfigError(
292                    f"{cls.__name__}: MODEL_KEY must be set on every DepthAdapterSkeleton subclass",
293                    hint="Set MODEL_KEY to the matching DEPTH_MODEL_CARDS key.",
294                )
295            return
296        if cls.MODEL_KEY not in DEPTH_MODEL_CARDS:
297            raise ConfigError(
298                f"{cls.__name__}: MODEL_KEY {cls.MODEL_KEY!r} is not in DEPTH_MODEL_CARDS",
299                hint=(
300                    f"Either add a card for {cls.MODEL_KEY!r} to "
301                    f"DEPTH_MODEL_CARDS, or fix the typo. Known keys: "
302                    f"{sorted(DEPTH_MODEL_CARDS)}"
303                ),
304            )
305        card = DEPTH_MODEL_CARDS[cls.MODEL_KEY]
306        # Inherit task + output kind from the card so adapter authors
307        # can't accidentally diverge from the canonical roster.
308        cls.task = card.task
309        cls.depth_output_kind = card.depth_output_kind
310        cls.name = card.name
311        cls.install_hint = card.install_hint
312
313    name: ClassVar[str] = ""
314    install_hint: ClassVar[str] = ""
315
316    def setup(self) -> None:
317        """Load weights, warm CUDA, etc. Skeleton: no-op.
318
319        Override in concrete subclasses. The runner calls this once
320        before iteration; the override should be idempotent so
321        repeated calls (e.g. when warming a multi-process pool) are
322        cheap.
323        """
324        return None
325
326    def predict(self, batch: Sequence[Sample]) -> Sequence[Any]:
327        """Skeleton ``predict`` — raises ``NotImplementedError`` with
328        the install hint baked in so a contributor sees exactly which
329        package to install / which forward call to wire up.
330        """
331        raise NotImplementedError(
332            f"Adapter for {self.name!r} ({self.MODEL_KEY}) is a skeleton. "
333            f"Install the model and implement `predict`: {self.install_hint}",
334        )

Base class for every depth-model adapter skeleton.

Subclasses set the class-level MODEL_KEY to the DEPTH_MODEL_CARDS entry they wrap; everything else flows from that card automatically. Override setup() and predict() with real implementations once the model is installed.

The default predict() raises a NotImplementedError whose message includes the install hint, so any contributor who tries to run an unimplemented adapter sees exactly what they need to do.

MODEL_KEY: ClassVar[str] = ''
name: ClassVar[str] = ''
install_hint: ClassVar[str] = ''
def setup(self) -> None:
316    def setup(self) -> None:
317        """Load weights, warm CUDA, etc. Skeleton: no-op.
318
319        Override in concrete subclasses. The runner calls this once
320        before iteration; the override should be idempotent so
321        repeated calls (e.g. when warming a multi-process pool) are
322        cheap.
323        """
324        return None

Load weights, warm CUDA, etc. Skeleton: no-op.

Override in concrete subclasses. The runner calls this once before iteration; the override should be idempotent so repeated calls (e.g. when warming a multi-process pool) are cheap.

def predict(self, batch: Sequence[rpx_benchmark.api.Sample]) -> Sequence[Any]:
326    def predict(self, batch: Sequence[Sample]) -> Sequence[Any]:
327        """Skeleton ``predict`` — raises ``NotImplementedError`` with
328        the install hint baked in so a contributor sees exactly which
329        package to install / which forward call to wire up.
330        """
331        raise NotImplementedError(
332            f"Adapter for {self.name!r} ({self.MODEL_KEY}) is a skeleton. "
333            f"Install the model and implement `predict`: {self.install_hint}",
334        )

Skeleton predict — raises NotImplementedError with the install hint baked in so a contributor sees exactly which package to install / which forward call to wire up.

@dataclass(frozen=True)
class DepthModelCard:
57@dataclass(frozen=True)
58class DepthModelCard:
59    """Static metadata about one depth model in the roster.
60
61    Used by tests to verify the adapter package covers every model
62    the paper claims to evaluate, and by tooling to render
63    "available models" tables.
64    """
65
66    name: str
67    """Display name used in result tables — matches the paper's
68    Table 2 / Table 3 spelling exactly (e.g. ``"DA3 Metric-L"``)."""
69
70    task: TaskType
71    """``MONOCULAR_DEPTH`` (Image Depth) or ``VIDEO_DEPTH`` (Video Depth)."""
72
73    depth_output_kind: Literal["metric", "relative"]
74    """Determines whether the runner applies per-scene-phase scale +
75    shift alignment before metrics. ``"metric"`` for models that
76    output meters directly; ``"relative"`` for affine-invariant
77    models (Lotus-2, FE2E and DA-V2 relative)."""
78
79    install_hint: str
80    """One-line `pip install ...` (or equivalent) the contributor
81    runs to make ``setup()`` work. Surfaced in the
82    ``NotImplementedError`` raised by skeleton ``predict()`` so the
83    next contributor doesn't have to grep."""
84
85    paper_ref: str = ""
86    """Optional citation key — matches an entry in
87    ``paper-submission/overleaf/root.bib`` so the model card can
88    cross-link to its primary source."""

Static metadata about one depth model in the roster.

Used by tests to verify the adapter package covers every model the paper claims to evaluate, and by tooling to render "available models" tables.

DepthModelCard( name: str, task: rpx_benchmark.api.TaskType, depth_output_kind: Literal['metric', 'relative'], install_hint: str, paper_ref: str = '')
name: str

Display name used in result tables — matches the paper's Table 2 / Table 3 spelling exactly (e.g. "DA3 Metric-L").

MONOCULAR_DEPTH (Image Depth) or VIDEO_DEPTH (Video Depth).

depth_output_kind: Literal['metric', 'relative']

Determines whether the runner applies per-scene-phase scale + shift alignment before metrics. "metric" for models that output meters directly; "relative" for affine-invariant models (Lotus-2, FE2E and DA-V2 relative).

install_hint: str

One-line pip install ... (or equivalent) the contributor runs to make setup() work. Surfaced in the NotImplementedError raised by skeleton predict() so the next contributor doesn't have to grep.

paper_ref: str = ''

Optional citation key — matches an entry in paper-submission/overleaf/root.bib so the model card can cross-link to its primary source.

DEPTH_MODEL_CARDS = {'da3-metric-l': DepthModelCard(name='DA3 Metric-L', task=<TaskType.MONOCULAR_DEPTH: 'monocular_depth'>, depth_output_kind='metric', install_hint='pip install depth-anything-3 (or HF transformers + the depth-anything-v3 weights)', paper_ref='yang2024depth'), 'da-v2-large': DepthModelCard(name='DA-V2 Large', task=<TaskType.MONOCULAR_DEPTH: 'monocular_depth'>, depth_output_kind='metric', install_hint='pip install depth-anything-v2 transformers; metric variant from HF', paper_ref='yang2024depthanythingv2'), 'depth-pro': DepthModelCard(name='Depth Pro', task=<TaskType.MONOCULAR_DEPTH: 'monocular_depth'>, depth_output_kind='metric', install_hint='pip install depth-pro (Apple); or `pip install git+https://github.com/apple/ml-depth-pro`', paper_ref='bochkovskii2025depthpro'), 'unidepth-v2': DepthModelCard(name='UniDepth V2', task=<TaskType.MONOCULAR_DEPTH: 'monocular_depth'>, depth_output_kind='metric', install_hint='pip install unidepth (or `pip install git+https://github.com/lpiccinelli-eth/UniDepth`)', paper_ref='piccinelli2024unidepth'), 'metric3d-v2': DepthModelCard(name='Metric3D V2', task=<TaskType.MONOCULAR_DEPTH: 'monocular_depth'>, depth_output_kind='metric', install_hint='pip install metric3d (or `pip install git+https://github.com/YvanYin/Metric3D`)', paper_ref='metric3d_v2'), 'moge-2-vit-l': DepthModelCard(name='MoGe-2 ViT-L', task=<TaskType.MONOCULAR_DEPTH: 'monocular_depth'>, depth_output_kind='metric', install_hint='pip install moge (Microsoft); HF: Ruicheng/moge-2-vitl-normal', paper_ref='wang2024moge'), 'hyden': DepthModelCard(name='HyDen', task=<TaskType.MONOCULAR_DEPTH: 'monocular_depth'>, depth_output_kind='metric', install_hint='clone facebookresearch/metadepth; HF: facebook/hyden-mogev2-metric-point', paper_ref='hyden'), 'lotus-2': DepthModelCard(name='Lotus-2', task=<TaskType.MONOCULAR_DEPTH: 'monocular_depth'>, depth_output_kind='relative', install_hint='pip install diffusers transformers; HF: jingheya/lotus-depth-d-v2', paper_ref='he2024lotus'), 'fe2e': DepthModelCard(name='FE2E', task=<TaskType.MONOCULAR_DEPTH: 'monocular_depth'>, depth_output_kind='relative', install_hint='official AMAP-ML/FE2E source plus its linked exander/FE2E checkpoint; use the pinned docker/depth-fe2e environment', paper_ref='fe2e'), 'zipdepth': DepthModelCard(name='ZipDepth', task=<TaskType.MONOCULAR_DEPTH: 'monocular_depth'>, depth_output_kind='relative', install_hint='official fabiotosi92/ZipDepth source and zipdepth_base.pth; use the pinned docker/depth-zipdepth environment', paper_ref='zipdepth'), 'da3-video': DepthModelCard(name='DA3', task=<TaskType.VIDEO_DEPTH: 'video_depth'>, depth_output_kind='relative', install_hint='pip install depth-anything-3; depth-anything/DA3-LARGE, fed per-clip instead of per-frame', paper_ref='yang2024depth'), 'depth-crafter': DepthModelCard(name='DepthCrafter', task=<TaskType.VIDEO_DEPTH: 'video_depth'>, depth_output_kind='relative', install_hint='pip install depthcrafter (Tencent); HF: tencent/DepthCrafter', paper_ref='hu2024depthcrafter'), 'video-da': DepthModelCard(name='Video DA', task=<TaskType.VIDEO_DEPTH: 'video_depth'>, depth_output_kind='relative', install_hint='pip install video-depth-anything (or upstream repo)', paper_ref='video_depth_anything'), 'chrono-depth': DepthModelCard(name='ChronoDepth', task=<TaskType.VIDEO_DEPTH: 'video_depth'>, depth_output_kind='relative', install_hint='pip install chronodepth (TBD — clone upstream repo)', paper_ref='shao2024chronodepth'), 'rolling-depth': DepthModelCard(name='RollingDepth', task=<TaskType.VIDEO_DEPTH: 'video_depth'>, depth_output_kind='relative', install_hint='pip install rollingdepth (TBD — clone upstream repo)', paper_ref='rollingdepth'), 'dvd': DepthModelCard(name='DVD v1.1', task=<TaskType.VIDEO_DEPTH: 'video_depth'>, depth_output_kind='relative', install_hint='clone github.com/EnVision-Research/DVD at the pinned revision; official v1.1 weights: huggingface.co/FayeHongfeiZhang/DVD', paper_ref='dvd'), 'gem-depth': DepthModelCard(name='GemDepth', task=<TaskType.VIDEO_DEPTH: 'video_depth'>, depth_output_kind='relative', install_hint='clone github.com/Yuecheng919/GemDepth; official weights: huggingface.co/YuechengLiu/GemDepth', paper_ref='gemdepth'), 'vigeo': DepthModelCard(name='ViGeo', task=<TaskType.VIDEO_DEPTH: 'video_depth'>, depth_output_kind='relative', install_hint='clone github.com/aigc3d/ViGeo; official weights: huggingface.co/pkqbajng/ViGeo', paper_ref='vigeo'), 'monst3r': DepthModelCard(name='MonST3R', task=<TaskType.VIDEO_DEPTH: 'video_depth'>, depth_output_kind='relative', install_hint='pip install monst3r (or `pip install git+https://github.com/Junyi42/monst3r`)', paper_ref='zhang2024monst3r'), 'vggt-omega': DepthModelCard(name='VGGT-Ω', task=<TaskType.VIDEO_DEPTH: 'video_depth'>, depth_output_kind='relative', install_hint='pip install vggt (or upstream Meta repo); Ω = the large variant', paper_ref='vggt_omega')}
def available_depth_adapters() -> dict[str, type[DepthAdapterSkeleton]]:
342def available_depth_adapters() -> dict[str, type[DepthAdapterSkeleton]]:
343    """Return every DepthAdapterSkeleton subclass currently importable.
344
345    Walks the registered subclasses of :class:`DepthAdapterSkeleton`
346    and returns ``{MODEL_KEY: class}``. Useful for CLI tooling and
347    tests that want to enumerate "every model we've at least
348    skeletoned".
349    """
350    out: dict[str, type[DepthAdapterSkeleton]] = {}
351    for cls in DepthAdapterSkeleton.__subclasses__():
352        if cls.MODEL_KEY:
353            out[cls.MODEL_KEY] = cls
354    return out

Return every DepthAdapterSkeleton subclass currently importable.

Walks the registered subclasses of DepthAdapterSkeleton and returns {MODEL_KEY: class}. Useful for CLI tooling and tests that want to enumerate "every model we've at least skeletoned".

def lazy_import(module_name: str, *, install_hint: str) -> Any:
357def lazy_import(module_name: str, *, install_hint: str) -> Any:
358    """Best-effort import with a friendly error.
359
360    Skeleton ``setup()`` overrides call this to defer heavy deps
361    until the adapter is actually run; if the dep is missing, the
362    contributor gets the install hint inline.
363    """
364    try:
365        import importlib
366
367        return importlib.import_module(module_name)
368    except ImportError as e:
369        raise ModelError(
370            f"failed to import {module_name!r}",
371            hint=install_hint,
372        ) from e

Best-effort import with a friendly error.

Skeleton setup() overrides call this to defer heavy deps until the adapter is actually run; if the dep is missing, the contributor gets the install hint inline.