Skip to content

vision: DINOv3Stem, a timm DINOv3 ViT image stem (patch tokens, any aspect ratio) - #679

Closed
RyanPCo wants to merge 1 commit into
ryanco/image-historyfrom
ryanco/dinov3-stem
Closed

RyanPCo wants to merge 1 commit into
ryanco/image-historyfrom
ryanco/dinov3-stem

Conversation

@RyanPCo

@RyanPCo RyanPCo commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

Adds DINOv3Stem, a pretrained DINOv3 ViT image stem in egomimic/models/hpt_nets.py that returns patch tokens at any aspect ratio. RDT (#680) uses it as its image encoder.

Behaviour changes

None. It is a new class, and no existing config uses it.

What it does

  • Same call convention as ResNet: (B, T, N, 3, H, W) images in [0, 1] in, (B, patches, output_dim) out. CLS and register tokens are dropped.
  • Loaded through timm, not transformers. The pinned transformers (4.53.2) has no DINOv3 class (it needs >= 4.56), and the timm/*_dinov3 hub repos are ungated where facebook/dinov3-* is gated. Default model: vit_base_patch16_dinov3.lvd1689m.
  • Any aspect ratio. DINOv3 is RoPE-only, so image_size may be [H, W] (multiples of the patch size, otherwise a ValueError), with no position interpolation. The stem exposes grid_size.
  • The stem owns the resize and the checkpoint's mean / std, so a config must not normalize these images in its augs.
  • freeze_backbone freezes the tower, keeps it in eval mode and runs it under no_grad. backbone_parameters() returns the tower's parameters for a separate LR group; proj stays in the main group.

Pretrained-weight verification

pretrained_reference_state_dict reads the checkpoint back from the local HF cache (local_files_only=True, never the network), so the pretrained-weight hash check (#645) covers this tower as it covers the Qwen stems. An uncached checkpoint or a random tower is skipped rather than fetched. Against the real timm/vit_base_patch16_dinov3.lvd1689m file, the key sets match (162 tensors) and every value is equal.

Tests

tests/unit/test_dinov3_stem.py runs on a random-init tiny tower (no network, no weights). It covers:

  • patch-token shapes, including 2 frames on the time axis;
  • a frozen tower staying in eval mode with no gradients;
  • a fine-tuned tower getting gradients;
  • rejection of an off-grid size;
  • the verifier passing on a matching cached checkpoint and raising once the tower is perturbed;
  • an uncached checkpoint being skipped without a network call.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UkAZwERXcFKjueZQKfRF6J

RyanPCo commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor Author

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@RyanPCo
RyanPCo force-pushed the ryanco/image-history branch from 3688522 to 5a2507c Compare September 20, 2026 19:09
@RyanPCo
RyanPCo force-pushed the ryanco/image-history branch from 5a2507c to db5687f Compare September 21, 2026 18:45
@RyanPCo
RyanPCo force-pushed the ryanco/image-history branch from db5687f to 5eeadea Compare September 22, 2026 13:18
…spect ratio)

Same call convention as ResNet. Loaded through timm: the locked
transformers (4.53.2) has no DINOv3 class, and the timm hub repos are
ungated. RoPE-only, so image_size may be [H, W]; exposes grid_size.

pretrained_reference_state_dict reads the checkpoint back from the local HF
cache (never the network), so the pretrained-weight hash check covers this
tower as it does the Qwen stems; an uncached checkpoint or a random tower is
skipped. Against the real timm/vit_base_patch16_dinov3.lvd1689m file the key
sets match (162 tensors) and every value is equal.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_019DbPWJCKtVg5c2PNHs7egw
@RyanPCo

RyanPCo commented Oct 12, 2026

Copy link
Copy Markdown
Contributor Author

Folded into #680 to keep the stack under Graphite's 50-branch cap; the changes are unchanged there.

@RyanPCo RyanPCo closed this Oct 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant