Comfy-Org/ComfyUI · error · RuntimeError

Dinov2Model.forward() is the backward-compatible CLIP-vision

Error message

Dinov2Model.forward() is the backward-compatible CLIP-vision path and does not apply DA3 extensions (RoPE, alternating attention, camera-token injection). Use get_intermediate_layers_da3() for Depth Anything 3 models.

What it means

Raised by Dinov2Model.forward when the model was configured with DA3 (Depth Anything 3) extensions — indicated by alt_start != -1 (alternating attention) plus options like RoPE and camera tokens. The plain forward() only implements the classic DINOv2/CLIP-vision path; feeding a DA3-configured model through it would silently produce features without those extensions, so ComfyUI raises RuntimeError and points you to get_intermediate_layers_da3().

Source

Thrown at comfy/image_encoders/dino2.py:339

        # camera_token shape: (1, 2, dim) -> (ref_token, src_token).
        num_cam_tokens = 2 if self.alt_start != -1 else 0

        self.embeddings = Dino2Embeddings(
            dim, dtype, device, operations,
            patch_size=patch_size, image_size=image_size,
            use_mask_token=use_mask_token, num_camera_tokens=num_cam_tokens,
        )
        self.encoder = Dino2Encoder(
            dim, heads, layer_norm_eps, num_layers, dtype, device, operations,
            use_swiglu_ffn=use_swiglu_ffn,
            qknorm_start=self.qknorm_start,
        )
        self.layernorm = operations.LayerNorm(dim, eps=layer_norm_eps, dtype=dtype, device=device)

    def forward(self, pixel_values, attention_mask=None, intermediate_output=None):
        if self.alt_start != -1:
            raise RuntimeError(
                "Dinov2Model.forward() is the backward-compatible CLIP-vision path and does not "
                "apply DA3 extensions (RoPE, alternating attention, camera-token injection). "
                "Use get_intermediate_layers_da3() for Depth Anything 3 models."
            )
        x = self.embeddings(pixel_values)
        x, i = self.encoder(x, intermediate_output=intermediate_output)
        x = self.layernorm(x)
        pooled_output = x[:, 0, :]
        return x, i, pooled_output, None

    def get_intermediate_layers(self, pixel_values, indices, apply_norm=True):
        """Single-view multi-layer feature extraction."""
        x = self.embeddings(pixel_values)
        optimized_attention = optimized_attention_for_device(x.device, False, small_input=True)
        n_layers = len(self.encoder.layer)
        resolved = [(i if i >= 0 else n_layers + i) for i in indices]
        target = set(resolved)
        max_idx = max(resolved)

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Call get_intermediate_layers_da3() (the DA3 path) for Depth Anything 3 models — it applies RoPE, alternating attention, and camera-token handling
  2. Use the stock Depth Anything 3 nodes shipped with ComfyUI instead of a generic CLIP-vision encode node
  3. For non-DA3 DINOv2 checkpoints, forward() is fine; verify alt_start == -1 before choosing the API

Example fix

# before
x, i, pooled, _ = dinov2_model.forward(pixels)  # raises for DA3 configs
# after
if dinov2_model.alt_start != -1:
    feats = dinov2_model.get_intermediate_layers_da3(pixels, ...)
else:
    x, i, pooled, _ = dinov2_model.forward(pixels)
Defensive patterns

Strategy: type-guard

Validate before calling

if getattr(dinov2_model, 'alt_start', -1) != -1:
    feats = dinov2_model.get_intermediate_layers_da3(pixel_values, idx)
else:
    x, i, pooled, _ = dinov2_model.forward(pixel_values)

Type guard

def is_da3_model(model) -> bool:
    return getattr(model, 'alt_start', -1) != -1 or getattr(model, 'num_camera_tokens', 0) not in (None, 0)

Try / catch

try:
    out = model.forward(pixel_values)
except RuntimeError:
    out = model.get_intermediate_layers_da3(pixel_values, ...)

Prevention

When it happens

Trigger: Loading a Depth Anything 3 checkpoint (which sets num_camera_tokens / alt_start / qknorm_start in config) and then calling model.forward(...) or routing it through code that assumes the CLIPVision API (e.g. a generic CLIPVisionEncoder node or old custom code) instead of the DA3 feature-extraction entry point.

Common situations: Custom CLIP-vision nodes written before DA3 support that call forward() unconditionally; adapting another vision model's adapter to DA3 checkpoints; mixing DA3 checkpoints with nodes built for plain DINOv2 depth models.

Related errors


AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14). Data as JSON: /api/errors/5284cc89f2f4e9c2. Report an issue: GitHub.