DVSM / dvsm /models /backbones.py
linjohnss's picture
Initial commit
cebb76b
Raw History Blame Contribute Delete
3.67 kB
import torch
from transformers import AutoModel
from .modules import checkpoint_wrapper
class DINO(torch.nn.Module):
def __init__(self, version, latent_dim, grad_checkpoint=True, use_compile=True):
super().__init__()
if version == 'dino' or version == 'dino-large':
version = "facebook/dinov3-vitl16-pretrain-lvd1689m"
if version == 'dino-big':
version = "facebook/dinov3-vitb16-pretrain-lvd1689m"
if version == 'dino-huge':
version = "facebook/dinov3-vith16plus-pretrain-lvd1689m"
# Prepare the model
try:
self.prior = AutoModel.from_pretrained(version, local_files_only=True)
except:
print(f"Fail to load pretrained foundation model. May be due to missing local file.")
print(f"Open an python terminal and run the following to download to local first.")
print(f" from transformers import AutoModel; AutoModel.from_pretrained({version})")
raise Exception
self.patch_size = self.prior.config.patch_size
self.prior_prefix = self.prior.embeddings.cls_token.shape[1] + self.prior.embeddings.register_tokens.shape[1]
del self.prior.embeddings.mask_token
self.register_buffer("img_mean", torch.tensor([0.485, 0.456, 0.406]).view(3,1,1))
self.register_buffer("img_std", torch.tensor([0.229, 0.224, 0.225]).view(3,1,1))
# Zero-init channel projection layer
self.out_proj = torch.nn.Linear(self.prior.config.hidden_size, latent_dim, bias=False)
torch.nn.init.constant_(self.out_proj.weight, 0.)
# Apply grad checkpointing & compile
for i in range(len(self.prior.layer)):
if use_compile:
self.prior.layer[i].forward = torch.compile(self.prior.layer[i].forward)
if grad_checkpoint:
self.prior.layer[i].forward = checkpoint_wrapper(self.prior.layer[i])
def forward(self, image):
# image: [B V 3 H W] under intensity range [0, 1]
x = self.prior((image.flatten(0,1) - self.img_mean) / self.img_std)
x = x.last_hidden_state[:, self.prior_prefix:]
x = self.out_proj(x)
x = x.unflatten(0, image.shape[:2])
return x
class RADIO(torch.nn.Module):
def __init__(self, version, latent_dim, grad_checkpoint=True, use_compile=True):
super().__init__()
if version == 'radio' or version == 'radio-large' or version == 'radio-so400m':
version = "c-radio_v4-so400m"
if version == 'radio-huge':
version = "c-radio_v4-h"
# Prepare the model
# TODO: may cause bug if weight is not downloaded with multi-gpu training
self.prior = torch.hub.load('NVlabs/RADIO', 'radio_model', version=version, skip_validation=True)
self.patch_size = self.prior._patch_size
# Zero-init channel projection layer
self.out_proj = torch.nn.Linear(self.prior.model.embed_dim, latent_dim, bias=False)
torch.nn.init.constant_(self.out_proj.weight, 0.)
# Apply grad checkpointing & compile
for i in range(len(self.prior.model.blocks)):
if use_compile:
self.prior.model.blocks[i].forward = torch.compile(self.prior.model.blocks[i].forward)
if grad_checkpoint:
self.prior.model.blocks[i].forward = checkpoint_wrapper(self.prior.model.blocks[i])
def forward(self, image):
# image: [B V 3 H W] under intensity range [0, 1]
x = self.prior(image.flatten(0,1))
x = x.features
x = self.out_proj(x)
x = x.unflatten(0, image.shape[:2])
return x