Feature Extraction
Transformers
Safetensors
medical
radiology
vision-language
chest-ct
3d-medical-imaging
glint
custom_code
Instructions to use Deepnoid/GLINT-CT with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Deepnoid/GLINT-CT with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("feature-extraction", model="Deepnoid/GLINT-CT", trust_remote_code=True)# pip install -U transformers accelerate # Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("Deepnoid/GLINT-CT", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
Download vjepa21_encoder.py from Deepnoid/GLINT-CT: direct link, hf CLI and curl.
- Browser
- Download file 36.4 kB
-
https://huggingface.co/Deepnoid/GLINT-CT/resolve/main/vjepa21_encoder.py
- Command line
-
hf download hf://Deepnoid/GLINT-CT/vjepa21_encoder.py
-
curl -L -o vjepa21_encoder.py https://huggingface.co/Deepnoid/GLINT-CT/resolve/main/vjepa21_encoder.py
36.4 kB
| """V-JEPA 2.1 encoder. | |
| Adapted from https://github.com/facebookresearch/vjepa2 | |
| Copyright (c) Meta Platforms, Inc. and affiliates. MIT License (LICENSES/MIT.txt) | |
| drop_path from timm (https://github.com/huggingface/pytorch-image-models). | |
| Copyright 2020 Ross Wightman. Apache License 2.0 (LICENSES/Apache-2.0.txt) | |
| """ | |
| import logging | |
| import math | |
| import torch | |
| logger = logging.getLogger("glint") | |
| def _no_grad_trunc_normal_(tensor, mean, std, a, b): | |
| def norm_cdf(x): | |
| return (1.0 + math.erf(x / math.sqrt(2.0))) / 2.0 | |
| with torch.no_grad(): | |
| lower = norm_cdf((a - mean) / std) | |
| upper = norm_cdf((b - mean) / std) | |
| tensor.uniform_(2 * lower - 1, 2 * upper - 1) | |
| tensor.erfinv_() | |
| tensor.mul_(std * math.sqrt(2.0)) | |
| tensor.add_(mean) | |
| tensor.clamp_(min=a, max=b) | |
| return tensor | |
| def trunc_normal_(tensor, mean=0.0, std=1.0, a=-2.0, b=2.0): | |
| return _no_grad_trunc_normal_(tensor, mean, std, a, b) | |
| def repeat_interleave_batch(x, B, repeat): | |
| N = len(x) // B | |
| x = torch.cat([torch.cat([x[i * B : (i + 1) * B] for _ in range(repeat)], dim=0) for i in range(N)], dim=0) | |
| return x | |
| def apply_masks(x, masks, concat=True): | |
| all_x = [] | |
| for m in masks: | |
| mask_keep = m.unsqueeze(-1).repeat(1, 1, x.size(-1)) | |
| all_x += [torch.gather(x, dim=1, index=mask_keep)] | |
| if not concat: | |
| return all_x | |
| return torch.cat(all_x, dim=0) | |
| import torch.nn as nn # noqa: E402 | |
| class PatchEmbed3D(nn.Module): | |
| def __init__( | |
| self, | |
| patch_size=16, | |
| tubelet_size=2, | |
| in_chans=3, | |
| embed_dim=768, | |
| ): | |
| super().__init__() | |
| self.patch_size = patch_size | |
| self.tubelet_size = tubelet_size | |
| self.proj = nn.Conv3d( | |
| in_channels=in_chans, | |
| out_channels=embed_dim, | |
| kernel_size=(tubelet_size, patch_size, patch_size), | |
| stride=(tubelet_size, patch_size, patch_size), | |
| ) | |
| def forward(self, x, **kwargs): | |
| B, C, T, H, W = x.shape | |
| x = self.proj(x).flatten(2).transpose(1, 2) | |
| return x | |
| import torch.nn.functional as F # noqa: E402 | |
| from torch.nn.attention import SDPBackend, sdpa_kernel # noqa: E402 | |
| def drop_path(x, drop_prob=0.0, training=False, scale_by_keep=True): | |
| if drop_prob == 0.0 or not training: | |
| return x | |
| keep_prob = 1 - drop_prob | |
| shape = (x.shape[0],) + (1,) * (x.ndim - 1) | |
| random_tensor = x.new_empty(shape).bernoulli_(keep_prob) | |
| if keep_prob > 0.0 and scale_by_keep: | |
| random_tensor.div_(keep_prob) | |
| return x * random_tensor | |
| def rotate_queries_or_keys(x, pos, n_registers, has_cls_first): | |
| B, num_heads, N, D = x.size() | |
| assert D % 2 == 0, "Embedding dimension must be a multiple of 2 for block matrix rotation" | |
| n_cls = 1 if has_cls_first else 0 | |
| start_ctx = n_cls | |
| end_ctx = N - n_registers | |
| x_cls = x[..., :n_cls, :] if n_cls else None | |
| x_ctx = x[..., start_ctx:end_ctx, :] | |
| x_reg = x[..., end_ctx:, :] if n_registers > 0 else None | |
| omega = torch.arange(D // 2, dtype=x.dtype, device=x.device) | |
| omega /= D / 2.0 | |
| omega = 1.0 / 10000**omega | |
| freq = torch.einsum("..., f -> ... f", pos, omega) | |
| emb_sin = freq.sin() | |
| emb_cos = freq.cos() | |
| emb_sin = emb_sin.repeat_interleave(2, dim=-1) | |
| emb_cos = emb_cos.repeat_interleave(2, dim=-1) | |
| y = x_ctx.unflatten(-1, (-1, 2)) | |
| y1, y2 = y.unbind( | |
| dim=-1, | |
| ) | |
| y = torch.stack((-y2, y1), dim=-1) | |
| y = y.flatten(-2) | |
| out_ctx = (x_ctx * emb_cos) + (y * emb_sin) | |
| parts = [] | |
| if n_cls: | |
| parts.append(x_cls) | |
| parts.append(out_ctx) | |
| if n_registers: | |
| parts.append(x_reg) | |
| out = torch.cat(parts, dim=-2) | |
| return out | |
| class DropPath(nn.Module): | |
| def __init__(self, drop_prob=None): | |
| super(DropPath, self).__init__() | |
| self.drop_prob = drop_prob | |
| def forward(self, x): | |
| return drop_path(x, self.drop_prob, self.training) | |
| def extra_repr(self) -> str: | |
| return "p={}".format(self.drop_prob) | |
| class MLP(nn.Module): | |
| def __init__( | |
| self, | |
| in_features, | |
| hidden_features=None, | |
| out_features=None, | |
| act_layer=nn.GELU, | |
| drop=0.0, | |
| ): | |
| super().__init__() | |
| out_features = out_features or in_features | |
| hidden_features = hidden_features or in_features | |
| self.fc1 = nn.Linear(in_features, hidden_features) | |
| self.act = act_layer() | |
| self.fc2 = nn.Linear(hidden_features, out_features) | |
| self.drop = nn.Dropout(drop) | |
| def forward(self, x): | |
| x = self.fc1(x) | |
| x = self.act(x) | |
| x = self.drop(x) | |
| x = self.fc2(x) | |
| x = self.drop(x) | |
| return x | |
| class SwiGLUFFN(nn.Module): | |
| def __init__( | |
| self, | |
| in_features, | |
| hidden_features=None, | |
| out_features=None, | |
| act_layer=nn.SiLU, | |
| drop=0.0, | |
| wide_silu=True, | |
| ): | |
| super().__init__() | |
| out_features = out_features or in_features | |
| swiglu_hidden_features = hidden_features = hidden_features or in_features | |
| if wide_silu: | |
| swiglu_hidden_features = int(2 * hidden_features / 3) | |
| align_as = 8 | |
| swiglu_hidden_features = (swiglu_hidden_features + align_as - 1) // align_as * align_as | |
| self.fc1 = nn.Linear(in_features, swiglu_hidden_features) | |
| self.fc2 = nn.Linear(in_features, swiglu_hidden_features) | |
| self.act = act_layer() | |
| self.fc3 = nn.Linear(swiglu_hidden_features, out_features) | |
| def forward(self, x): | |
| x1 = self.fc1(x) | |
| x2 = self.fc2(x) | |
| hidden = F.silu(x1) * x2 | |
| return self.fc3(hidden) | |
| class RoPEAttention(nn.Module): | |
| def __init__( | |
| self, | |
| dim, | |
| num_heads=8, | |
| qkv_bias=False, | |
| qk_scale=None, | |
| attn_drop=0.0, | |
| proj_drop=0.0, | |
| use_sdpa=True, | |
| grid_size=14, | |
| is_causal=False, | |
| n_registers=0, | |
| has_cls_first=False, | |
| interpolate_rope=False, | |
| patch_size=16, | |
| ): | |
| super().__init__() | |
| self.num_heads = num_heads | |
| self.head_dim = head_dim = dim // num_heads | |
| self.scale = qk_scale or head_dim**-0.5 | |
| self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias) | |
| self.attn_drop = nn.Dropout(attn_drop) | |
| self.proj = nn.Linear(dim, dim) | |
| self.proj_drop_prob = proj_drop | |
| self.proj_drop = nn.Dropout(proj_drop) | |
| self.use_sdpa = use_sdpa | |
| self.d_dim = int(2 * ((head_dim // 3) // 2)) | |
| self.h_dim = int(2 * ((head_dim // 3) // 2)) | |
| self.w_dim = int(2 * ((head_dim // 3) // 2)) | |
| self.grid_size = grid_size | |
| self.is_causal = is_causal | |
| self.n_registers = n_registers | |
| self.has_cls_first = has_cls_first | |
| self.interpolate_rope = interpolate_rope | |
| self.pretrained_patch_size = patch_size | |
| if patch_size == 14: | |
| self.pretrained_grid_size = int(252 / patch_size) | |
| elif patch_size == 16: | |
| self.pretrained_grid_size = int(256 / patch_size) | |
| def _get_frame_pos(self, ids, H_patches=None, W_patches=None): | |
| if H_patches is None or W_patches is None: | |
| tokens_per_frame = int(self.grid_size * self.grid_size) | |
| else: | |
| tokens_per_frame = int(H_patches * W_patches) | |
| return ids // tokens_per_frame | |
| def _get_height_pos(self, ids, H_patches=None, W_patches=None): | |
| if H_patches is None or W_patches is None: | |
| tokens_per_frame = int(self.grid_size * self.grid_size) | |
| tokens_per_row = self.grid_size | |
| else: | |
| tokens_per_frame = int(H_patches * W_patches) | |
| tokens_per_row = W_patches | |
| frame_ids = self._get_frame_pos(ids, H_patches, W_patches) | |
| ids = ids - tokens_per_frame * frame_ids | |
| return ids // tokens_per_row | |
| def separate_positions(self, ids, H_patches=None, W_patches=None): | |
| if H_patches is None or W_patches is None: | |
| tokens_per_frame = int(self.grid_size * self.grid_size) | |
| tokens_per_row = self.grid_size | |
| else: | |
| tokens_per_frame = int(H_patches * W_patches) | |
| tokens_per_row = W_patches | |
| frame_ids = self._get_frame_pos(ids, H_patches, W_patches) | |
| height_ids = self._get_height_pos(ids, H_patches, W_patches) | |
| width_ids = (ids - tokens_per_frame * frame_ids) - tokens_per_row * height_ids | |
| return 1.0 * frame_ids, 1.0 * height_ids, 1.0 * width_ids | |
| def forward( | |
| self, | |
| x, | |
| mask=None, | |
| T=None, | |
| H_patches=None, | |
| W_patches=None, | |
| return_attn=False, | |
| ): | |
| B, N, C = x.size() | |
| N_ctx = N - self.n_registers | |
| grid_depth = int(N_ctx // (self.grid_size * self.grid_size)) | |
| qkv = self.qkv(x).unflatten(-1, (3, self.num_heads, -1)).permute(2, 0, 3, 1, 4) | |
| q, k, v = qkv[0], qkv[1], qkv[2] | |
| if mask is not None: | |
| mask = mask.unsqueeze(1).repeat(1, self.num_heads, 1) | |
| d_mask, h_mask, w_mask = self.separate_positions(mask, H_patches, W_patches) | |
| else: | |
| if T is None or H_patches is None or W_patches is None: | |
| mask = torch.arange(int(grid_depth * self.grid_size * self.grid_size), device=x.device) | |
| else: | |
| mask = torch.arange(int(T * H_patches * W_patches), device=x.device) | |
| d_mask, h_mask, w_mask = self.separate_positions(mask, H_patches, W_patches) | |
| if self.interpolate_rope: | |
| if H_patches is None: | |
| H_patches = int(self.grid_size) | |
| if W_patches is None: | |
| W_patches = int(self.grid_size) | |
| h_mask = h_mask * (self.pretrained_grid_size - 1) / (H_patches - 1) | |
| w_mask = w_mask * (self.pretrained_grid_size - 1) / (W_patches - 1) | |
| s = 0 | |
| qd = rotate_queries_or_keys( | |
| q[..., s : s + self.d_dim], | |
| pos=d_mask, | |
| n_registers=self.n_registers, | |
| has_cls_first=self.has_cls_first, | |
| ) | |
| kd = rotate_queries_or_keys( | |
| k[..., s : s + self.d_dim], | |
| pos=d_mask, | |
| n_registers=self.n_registers, | |
| has_cls_first=self.has_cls_first, | |
| ) | |
| s += self.d_dim | |
| qh = rotate_queries_or_keys( | |
| q[..., s : s + self.h_dim], | |
| pos=h_mask, | |
| n_registers=self.n_registers, | |
| has_cls_first=self.has_cls_first, | |
| ) | |
| kh = rotate_queries_or_keys( | |
| k[..., s : s + self.h_dim], | |
| pos=h_mask, | |
| n_registers=self.n_registers, | |
| has_cls_first=self.has_cls_first, | |
| ) | |
| s += self.h_dim | |
| qw = rotate_queries_or_keys( | |
| q[..., s : s + self.w_dim], | |
| pos=w_mask, | |
| n_registers=self.n_registers, | |
| has_cls_first=self.has_cls_first, | |
| ) | |
| kw = rotate_queries_or_keys( | |
| k[..., s : s + self.w_dim], | |
| pos=w_mask, | |
| n_registers=self.n_registers, | |
| has_cls_first=self.has_cls_first, | |
| ) | |
| s += self.w_dim | |
| if s < self.head_dim: | |
| qr = q[..., s:] | |
| kr = k[..., s:] | |
| q = torch.cat([qd, qh, qw, qr], dim=-1) | |
| k = torch.cat([kd, kh, kw, kr], dim=-1) | |
| else: | |
| q = torch.cat([qd, qh, qw], dim=-1) | |
| k = torch.cat([kd, kh, kw], dim=-1) | |
| q = q.to(v.dtype) | |
| k = k.to(v.dtype) | |
| if self.use_sdpa: | |
| with sdpa_kernel([SDPBackend.FLASH_ATTENTION, SDPBackend.EFFICIENT_ATTENTION, SDPBackend.MATH]): | |
| x = F.scaled_dot_product_attention(q, k, v, dropout_p=self.proj_drop_prob, is_causal=self.is_causal) | |
| attn = None | |
| else: | |
| attn = (q @ k.transpose(-2, -1)) * self.scale | |
| attn = attn.softmax(dim=-1) | |
| attn = self.attn_drop(attn) | |
| x = attn @ v | |
| x = x.transpose(1, 2).reshape(B, N, C) | |
| x = self.proj(x) | |
| x = self.proj_drop(x) | |
| if return_attn: | |
| return x, attn | |
| else: | |
| return x, None | |
| class Attention(nn.Module): | |
| def __init__( | |
| self, | |
| dim, | |
| num_heads=8, | |
| qkv_bias=False, | |
| qk_scale=None, | |
| attn_drop=0.0, | |
| proj_drop=0.0, | |
| use_sdpa=True, | |
| is_causal=False, | |
| ): | |
| super().__init__() | |
| self.num_heads = num_heads | |
| head_dim = dim // num_heads | |
| self.scale = qk_scale or head_dim**-0.5 | |
| self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias) | |
| self.attn_drop = nn.Dropout(attn_drop) | |
| self.proj = nn.Linear(dim, dim) | |
| self.proj_drop_prob = proj_drop | |
| self.proj_drop = nn.Dropout(proj_drop) | |
| self.use_sdpa = use_sdpa | |
| self.is_causal = is_causal | |
| def forward(self, x): | |
| B, N, C = x.shape | |
| qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4) | |
| q, k, v = qkv[0], qkv[1], qkv[2] | |
| if self.use_sdpa: | |
| with sdpa_kernel([SDPBackend.FLASH_ATTENTION, SDPBackend.EFFICIENT_ATTENTION, SDPBackend.MATH]): | |
| x = F.scaled_dot_product_attention(q, k, v, dropout_p=self.proj_drop_prob, is_causal=self.is_causal) | |
| attn = None | |
| else: | |
| attn = (q @ k.transpose(-2, -1)) * self.scale | |
| attn = attn.softmax(dim=-1) | |
| attn = self.attn_drop(attn) | |
| x = attn @ v | |
| x = x.transpose(1, 2).reshape(B, N, C) | |
| x = self.proj(x) | |
| x = self.proj_drop(x) | |
| return x | |
| class Block(nn.Module): | |
| def __init__( | |
| self, | |
| dim, | |
| num_heads, | |
| mlp_ratio=4.0, | |
| qkv_bias=False, | |
| qk_scale=None, | |
| drop=0.0, | |
| attn_drop=0.0, | |
| drop_path=0.0, | |
| act_layer=nn.GELU, | |
| wide_silu=True, | |
| norm_layer=nn.LayerNorm, | |
| use_sdpa=True, | |
| is_causal=False, | |
| grid_size=16, | |
| use_rope=False, | |
| n_registers=0, | |
| has_cls_first=False, | |
| interpolate_rope=False, | |
| patch_size=16, | |
| **kwargs, | |
| ): | |
| super().__init__() | |
| self.norm1 = norm_layer(dim) | |
| self.use_rope = use_rope | |
| if use_rope: | |
| self.attn = RoPEAttention( | |
| dim, | |
| num_heads=num_heads, | |
| qkv_bias=qkv_bias, | |
| qk_scale=qk_scale, | |
| attn_drop=attn_drop, | |
| use_sdpa=use_sdpa, | |
| is_causal=is_causal, | |
| grid_size=grid_size, | |
| proj_drop=drop, | |
| n_registers=n_registers, | |
| has_cls_first=has_cls_first, | |
| interpolate_rope=interpolate_rope, | |
| patch_size=patch_size, | |
| ) | |
| else: | |
| self.attn = Attention( | |
| dim, | |
| num_heads=num_heads, | |
| qkv_bias=qkv_bias, | |
| qk_scale=qk_scale, | |
| attn_drop=attn_drop, | |
| use_sdpa=use_sdpa, | |
| is_causal=is_causal, | |
| proj_drop=drop, | |
| ) | |
| self.drop_path = DropPath(drop_path) if drop_path > 0.0 else nn.Identity() | |
| self.norm2 = norm_layer(dim) | |
| mlp_hidden_dim = int(dim * mlp_ratio) | |
| if act_layer is nn.SiLU: | |
| self.mlp = SwiGLUFFN( | |
| in_features=dim, | |
| hidden_features=mlp_hidden_dim, | |
| act_layer=act_layer, | |
| wide_silu=wide_silu, | |
| drop=drop, | |
| ) | |
| else: | |
| self.mlp = MLP( | |
| in_features=dim, | |
| hidden_features=mlp_hidden_dim, | |
| act_layer=act_layer, | |
| drop=drop, | |
| ) | |
| def forward( | |
| self, | |
| x, | |
| mask=None, | |
| T=None, | |
| H_patches=None, | |
| W_patches=None, | |
| return_attn=False, | |
| mode="video", | |
| ): | |
| if self.use_rope: | |
| y, attn = self.attn( | |
| self.norm1(x), | |
| mask=mask, | |
| T=T, | |
| H_patches=H_patches, | |
| W_patches=W_patches, | |
| return_attn=return_attn, | |
| ) | |
| else: | |
| y = self.attn(self.norm1(x)) | |
| attn = None | |
| x = x + self.drop_path(y) | |
| x = x + self.drop_path(self.mlp(self.norm2(x))) | |
| if return_attn: | |
| return x, attn | |
| else: | |
| return x, None | |
| class Lambda_LinearWarmupHold: | |
| def __init__(self, lambda_value: float, start_iter: int = 15_000, end_iter: int = 30_000): | |
| assert end_iter > start_iter, "end_iter must be > start_iter" | |
| self.lambda_value = float(lambda_value) | |
| self.start = int(start_iter) | |
| self.end = int(end_iter) | |
| self.span = self.end - self.start | |
| def value(self, global_iter: int) -> float: | |
| if global_iter < self.start: | |
| return 0.0 | |
| if global_iter >= self.end: | |
| return self.lambda_value | |
| alpha = (global_iter - self.start) / self.span | |
| return self.lambda_value * alpha | |
| from functools import partial # noqa: E402 | |
| class VisionTransformer(nn.Module): | |
| def __init__( | |
| self, | |
| img_size=(224, 224), | |
| patch_size=16, | |
| num_frames=1, | |
| tubelet_size=2, | |
| in_chans=3, | |
| embed_dim=768, | |
| depth=12, | |
| num_heads=12, | |
| mlp_ratio=4.0, | |
| qkv_bias=True, | |
| qk_scale=None, | |
| drop_rate=0.0, | |
| attn_drop_rate=0.0, | |
| drop_path_rate=0.0, | |
| norm_layer=nn.LayerNorm, | |
| init_std=0.02, | |
| out_layers=None, | |
| uniform_power=False, | |
| use_silu=False, | |
| wide_silu=True, | |
| use_sdpa=True, | |
| use_activation_checkpointing=False, | |
| is_causal=False, | |
| use_rope=False, | |
| init_type: str = "default", | |
| handle_nonsquare_inputs=True, | |
| img_temporal_dim_size=None, | |
| n_registers=0, | |
| has_cls_first=False, | |
| interpolate_rope=False, | |
| modality_embedding=True, | |
| n_output_distillation=4, | |
| **kwargs, | |
| ): | |
| super().__init__() | |
| self.num_features = self.embed_dim = embed_dim | |
| self.num_heads = num_heads | |
| self.out_layers = out_layers | |
| self.init_type = init_type | |
| self.handle_nonsquare_inputs = handle_nonsquare_inputs | |
| self.img_temporal_dim_size = img_temporal_dim_size | |
| if type(img_size) is int: | |
| img_size = (img_size, img_size) | |
| self.img_height, self.img_width = img_size | |
| self.patch_size = patch_size | |
| self.num_frames = num_frames | |
| self.tubelet_size = tubelet_size | |
| self.is_video = num_frames > 1 | |
| self.use_activation_checkpointing = use_activation_checkpointing | |
| dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth)] | |
| if self.is_video: | |
| self.patch_embed = PatchEmbed3D( | |
| patch_size=patch_size, | |
| tubelet_size=tubelet_size, | |
| in_chans=in_chans, | |
| embed_dim=embed_dim, | |
| ) | |
| self.num_patches = (num_frames // tubelet_size) * (img_size[0] // patch_size) * (img_size[1] // patch_size) | |
| else: | |
| self.patch_embed = PatchEmbed3D( | |
| patch_size=patch_size, | |
| tubelet_size=1, | |
| in_chans=in_chans, | |
| embed_dim=embed_dim, | |
| ) | |
| self.num_patches = (img_size[0] // patch_size) * (img_size[1] // patch_size) | |
| if self.img_temporal_dim_size is not None: | |
| if not isinstance(self.img_temporal_dim_size, int): | |
| raise ValueError(f"img_temporal_dim_size must be an int, got {self.img_temporal_dim_size}") | |
| self.patch_embed_img = PatchEmbed3D( | |
| patch_size=patch_size, | |
| tubelet_size=1, | |
| in_chans=in_chans, | |
| embed_dim=embed_dim, | |
| ) | |
| else: | |
| self.patch_embed_img = None | |
| self.uniform_power = uniform_power | |
| self.use_rope = use_rope | |
| self.blocks = nn.ModuleList( | |
| [ | |
| Block( | |
| use_rope=use_rope, | |
| grid_size=img_size[0] // patch_size, | |
| grid_depth=num_frames // tubelet_size, | |
| dim=embed_dim, | |
| num_heads=num_heads, | |
| mlp_ratio=mlp_ratio, | |
| use_sdpa=use_sdpa, | |
| is_causal=is_causal, | |
| qkv_bias=qkv_bias, | |
| qk_scale=qk_scale, | |
| drop=drop_rate, | |
| act_layer=nn.SiLU if use_silu else nn.GELU, | |
| wide_silu=wide_silu, | |
| attn_drop=attn_drop_rate, | |
| drop_path=dpr[i], | |
| norm_layer=norm_layer, | |
| n_registers=n_registers, | |
| has_cls_first=has_cls_first, | |
| interpolate_rope=interpolate_rope, | |
| patch_size=patch_size, | |
| ) | |
| for i in range(depth) | |
| ] | |
| ) | |
| self.attn_out = False | |
| self.init_std = init_std | |
| self.apply(self._init_weights) | |
| self._rescale_blocks() | |
| if depth == 12: | |
| self.hierarchical_layers = [2, 5, 8, 11] | |
| if n_output_distillation == 4: | |
| self.out_layers_distillation = [2, 5, 8, 11] | |
| elif n_output_distillation == 1: | |
| self.out_layers_distillation = [11] | |
| elif depth == 24: | |
| self.hierarchical_layers = [5, 11, 17, 23] | |
| if n_output_distillation == 4: | |
| self.out_layers_distillation = [5, 11, 17, 23] | |
| elif n_output_distillation == 1: | |
| self.out_layers_distillation = [23] | |
| elif depth == 40: | |
| self.hierarchical_layers = [9, 19, 29, 39] | |
| if n_output_distillation == 4: | |
| self.out_layers_distillation = [9, 19, 29, 39] | |
| elif n_output_distillation == 1: | |
| self.out_layers_distillation = [39] | |
| elif depth == 48: | |
| self.hierarchical_layers = [11, 23, 37, 47] | |
| if n_output_distillation == 4: | |
| self.out_layers_distillation = [11, 23, 37, 47] | |
| elif n_output_distillation == 1: | |
| self.out_layers_distillation = [47] | |
| else: | |
| print("Check the code! ;)") | |
| self.norms_block = nn.ModuleList([norm_layer(embed_dim) for _ in range(len(self.hierarchical_layers))]) | |
| self.cls_token = None | |
| self.return_hierarchical = False | |
| self.modality_embedding = False | |
| if modality_embedding: | |
| self.img_mod_embed = nn.Parameter(torch.zeros(1, 1, embed_dim)) | |
| self.video_mod_embed = nn.Parameter(torch.zeros(1, 1, embed_dim)) | |
| nn.init.normal_(self.img_mod_embed, std=1e-6) | |
| nn.init.normal_(self.video_mod_embed, std=1e-6) | |
| self.modality_embedding = True | |
| def _init_weights(self, m): | |
| if isinstance(m, nn.LayerNorm): | |
| nn.init.constant_(m.bias, 0) | |
| nn.init.constant_(m.weight, 1.0) | |
| return | |
| if self.init_type == "default": | |
| if isinstance(m, nn.Linear): | |
| trunc_normal_(m.weight, std=self.init_std) | |
| if isinstance(m, nn.Linear) and m.bias is not None: | |
| nn.init.constant_(m.bias, 0) | |
| elif isinstance(m, nn.Conv2d): | |
| trunc_normal_(m.weight, std=self.init_std) | |
| if m.bias is not None: | |
| nn.init.constant_(m.bias, 0) | |
| elif isinstance(m, nn.Conv3d): | |
| trunc_normal_(m.weight, std=self.init_std) | |
| if m.bias is not None: | |
| nn.init.constant_(m.bias, 0) | |
| elif self.init_type == "xavier_uniform": | |
| if isinstance(m, nn.Linear) or isinstance(m, nn.Conv2d) or isinstance(m, nn.Conv3d): | |
| nn.init.xavier_uniform_(m.weight) | |
| if m.bias is not None: | |
| nn.init.constant_(m.bias, 0) | |
| elif self.init_type == "xavier_normal": | |
| if isinstance(m, nn.Linear) or isinstance(m, nn.Conv2d) or isinstance(m, nn.Conv3d): | |
| nn.init.xavier_normal_(m.weight) | |
| if m.bias is not None: | |
| nn.init.constant_(m.bias, 0) | |
| else: | |
| raise ValueError(f"Unknown init type {self.init_type}") | |
| def _rescale_blocks(self): | |
| def rescale(param, layer_id): | |
| param.div_(math.sqrt(2.0 * layer_id)) | |
| for layer_id, layer in enumerate(self.blocks): | |
| rescale(layer.attn.proj.weight.data, layer_id + 1) | |
| rescale(layer.mlp.fc2.weight.data, layer_id + 1) | |
| def get_num_layers(self): | |
| return len(self.blocks) | |
| def no_weight_decay(self): | |
| return {} | |
| def check_temporal_dim(self, shape) -> bool: | |
| if self.img_temporal_dim_size is not None: | |
| if shape[2] == self.img_temporal_dim_size: | |
| return True | |
| return False | |
| def forward(self, x, masks=None, training=False): | |
| if masks is not None and not isinstance(masks, list): | |
| masks = [masks] | |
| if x.ndim == 4: | |
| _, _, H, W = x.shape | |
| T = 1 | |
| elif x.ndim == 5: | |
| _, _, T, H, W = x.shape | |
| if self.check_temporal_dim(x.shape): | |
| T = T // 1 | |
| else: | |
| T = T // self.tubelet_size | |
| H_patches = H // self.patch_size | |
| W_patches = W // self.patch_size | |
| if not self.handle_nonsquare_inputs: | |
| T = H_patches = W_patches = None | |
| if self.check_temporal_dim(x.shape): | |
| assert self.patch_embed_img is not None | |
| x = self.patch_embed_img(x) | |
| mode = "img" | |
| if self.modality_embedding: | |
| x += self.img_mod_embed.repeat(x.shape[0], 1, 1) | |
| else: | |
| x = self.patch_embed(x) | |
| mode = "video" | |
| if self.modality_embedding: | |
| x += self.video_mod_embed.repeat(x.shape[0], 1, 1) | |
| if masks is not None: | |
| x = apply_masks(x, masks) | |
| masks = torch.cat(masks, dim=0) | |
| outs = [] | |
| hier = [] | |
| for i, blk in enumerate(self.blocks): | |
| if self.use_activation_checkpointing: | |
| x, attn = torch.utils.checkpoint.checkpoint( | |
| blk, | |
| x, | |
| masks, | |
| T=T, | |
| H_patches=H_patches, | |
| W_patches=W_patches, | |
| use_reentrant=False, | |
| return_attn=self.attn_out, | |
| mode=mode, | |
| ) | |
| else: | |
| x, attn = blk( | |
| x, | |
| mask=masks, | |
| T=T, | |
| H_patches=H_patches, | |
| W_patches=W_patches, | |
| return_attn=self.attn_out, | |
| mode=mode, | |
| ) | |
| if self.out_layers is not None and i in self.out_layers: | |
| out_idx = self.hierarchical_layers.index(i) | |
| out_norm = self.norms_block[out_idx](x) | |
| outs.append(out_norm) | |
| if i in self.out_layers_distillation: | |
| out_idx = self.hierarchical_layers.index(i) | |
| hier.append(self.norms_block[out_idx](x)) | |
| if self.out_layers is not None: | |
| return outs | |
| if training or self.return_hierarchical: | |
| hier = torch.cat(hier, dim=2) | |
| return hier | |
| else: | |
| x = self.norms_block[-1](x) | |
| return x | |
| def vit_base(patch_size=16, **kwargs): | |
| model = VisionTransformer( | |
| patch_size=patch_size, | |
| embed_dim=768, | |
| depth=12, | |
| num_heads=12, | |
| mlp_ratio=4, | |
| qkv_bias=True, | |
| norm_layer=partial(nn.LayerNorm, eps=1e-6), | |
| **kwargs, | |
| ) | |
| return model | |
| def vit_large(patch_size=16, **kwargs): | |
| model = VisionTransformer( | |
| patch_size=patch_size, | |
| embed_dim=1024, | |
| depth=24, | |
| num_heads=16, | |
| mlp_ratio=4, | |
| qkv_bias=True, | |
| norm_layer=partial(nn.LayerNorm, eps=1e-6), | |
| **kwargs, | |
| ) | |
| return model | |
| def vit_huge(patch_size=16, **kwargs): | |
| model = VisionTransformer( | |
| patch_size=patch_size, | |
| embed_dim=1280, | |
| depth=32, | |
| num_heads=16, | |
| mlp_ratio=4, | |
| qkv_bias=True, | |
| norm_layer=partial(nn.LayerNorm, eps=1e-6), | |
| **kwargs, | |
| ) | |
| return model | |
| def vit_giant_xformers(patch_size=16, **kwargs): | |
| model = VisionTransformer( | |
| patch_size=patch_size, | |
| embed_dim=1408, | |
| depth=40, | |
| num_heads=22, | |
| mlp_ratio=48 / 11, | |
| qkv_bias=True, | |
| norm_layer=partial(nn.LayerNorm, eps=1e-6), | |
| **kwargs, | |
| ) | |
| return model | |
| def vit_gigantic_xformers(patch_size=16, **kwargs): | |
| model = VisionTransformer( | |
| patch_size=patch_size, | |
| embed_dim=1664, | |
| depth=48, | |
| num_heads=26, | |
| mlp_ratio=64 / 13, | |
| qkv_bias=True, | |
| norm_layer=partial(nn.LayerNorm, eps=1e-6), | |
| **kwargs, | |
| ) | |
| return model | |
| VIT_EMBED_DIMS = { | |
| "vit_base": 768, | |
| "vit_large": 1024, | |
| "vit_huge": 1280, | |
| "vit_giant_xformers": 1408, | |
| "vit_gigantic_xformers": 1664, | |
| } | |
| ARCH_MAP = { | |
| "vjepa2_1_vit_base_384": (vit_base, 1), | |
| "vjepa2_1_vit_large_384": (vit_large, 1), | |
| "vjepa2_1_vit_giant_384": (vit_giant_xformers, 4), | |
| "vjepa2_1_vit_gigantic_384": (vit_gigantic_xformers, 4), | |
| } | |
| class VisionEncoderOutput: | |
| def __init__(self, last_hidden_state, hidden_states=None): | |
| self.last_hidden_state = last_hidden_state | |
| self.hidden_states = hidden_states | |
| def __getitem__(self, key): | |
| return getattr(self, key) | |
| def get(self, key, default=None): | |
| return getattr(self, key, default) | |
| class VJEPA21Encoder(nn.Module): | |
| def __init__(self, config): | |
| super().__init__() | |
| self.config = config | |
| arch = getattr(config, "arch", "vjepa2_1_vit_large_384") | |
| img_size = getattr(config, "img_size", 384) | |
| num_frames = getattr(config, "num_frames", 80) | |
| n_out = getattr(config, "n_output_distillation", None) | |
| use_ckpt = getattr(config, "use_activation_checkpointing", False) | |
| if arch not in ARCH_MAP: | |
| raise ValueError(f"Unknown arch '{arch}'. Choose from {list(ARCH_MAP.keys())}") | |
| factory_fn, default_n_out = ARCH_MAP[arch] | |
| if n_out is None: | |
| n_out = default_n_out | |
| self.encoder = factory_fn( | |
| img_size=(img_size, img_size), | |
| num_frames=num_frames, | |
| tubelet_size=2, | |
| use_sdpa=True, | |
| use_silu=False, | |
| wide_silu=True, | |
| uniform_power=False, | |
| use_rope=True, | |
| img_temporal_dim_size=1, | |
| interpolate_rope=True, | |
| n_output_distillation=n_out, | |
| use_activation_checkpointing=use_ckpt, | |
| ) | |
| self.use_hierarchical = getattr(config, "use_hierarchical", False) | |
| self.encoder.return_hierarchical = self.use_hierarchical | |
| n_levels = len(self.encoder.out_layers_distillation) | |
| self._hidden_size = self.encoder.embed_dim * n_levels if self.use_hierarchical else self.encoder.embed_dim | |
| ckpt_path = getattr(config, "pretrained_checkpoint", None) | |
| if ckpt_path: | |
| import os | |
| if not os.path.isabs(ckpt_path): | |
| pretrained_dir = getattr(config, "pretrained_dir", "") | |
| ckpt_path = os.path.join(pretrained_dir, ckpt_path) | |
| load_vjepa21_checkpoint(self, ckpt_path) | |
| def hidden_size(self): | |
| return self._hidden_size | |
| def gradient_checkpointing_enable(self, gradient_checkpointing_kwargs=None): | |
| self.encoder.use_activation_checkpointing = True | |
| def gradient_checkpointing_disable(self): | |
| self.encoder.use_activation_checkpointing = False | |
| def save_pretrained(self, save_directory, **kwargs): | |
| import os | |
| from safetensors.torch import save_file | |
| os.makedirs(save_directory, exist_ok=True) | |
| self.config.save_pretrained(save_directory) | |
| save_file(self.state_dict(), os.path.join(save_directory, "model.safetensors")) | |
| logger.info(f"VJEPA21Encoder saved to {save_directory}") | |
| def forward(self, pixel_values, output_hidden_states=False, **kwargs): | |
| x = pixel_values.permute(0, 2, 1, 3, 4).contiguous() | |
| if output_hidden_states: | |
| if self.encoder.check_temporal_dim(x.shape): | |
| x_tok = self.encoder.patch_embed_img(x) | |
| if self.encoder.modality_embedding: | |
| x_tok = x_tok + self.encoder.img_mod_embed | |
| else: | |
| x_tok = self.encoder.patch_embed(x) | |
| if self.encoder.modality_embedding: | |
| x_tok = x_tok + self.encoder.video_mod_embed | |
| _, _, T, H, W = x.shape | |
| T_p = T // (1 if self.encoder.check_temporal_dim(x.shape) else self.encoder.tubelet_size) | |
| H_p, W_p = H // self.encoder.patch_size, W // self.encoder.patch_size | |
| hidden_states = [x_tok] | |
| h = x_tok | |
| for blk in self.encoder.blocks: | |
| h, _ = blk(h, mask=None, T=T_p, H_patches=H_p, W_patches=W_p) | |
| hidden_states.append(h) | |
| if self.use_hierarchical: | |
| hier = [] | |
| for idx in self.encoder.out_layers_distillation: | |
| out_idx = self.encoder.hierarchical_layers.index(idx) | |
| hier.append(self.encoder.norms_block[out_idx](hidden_states[idx])) | |
| features = torch.cat(hier, dim=2) | |
| else: | |
| features = self.encoder.norms_block[-1](hidden_states[-1]) | |
| return VisionEncoderOutput(last_hidden_state=features, hidden_states=tuple(hidden_states)) | |
| features = self.encoder(x, masks=None, training=self.use_hierarchical and self.training) | |
| return VisionEncoderOutput(last_hidden_state=features, hidden_states=None) | |
| def load_vjepa21_checkpoint(model, checkpoint_path, strict=False): | |
| import os | |
| if not os.path.exists(checkpoint_path): | |
| raise FileNotFoundError(f"V-JEPA 2.1 checkpoint not found: {checkpoint_path}") | |
| if os.path.isdir(checkpoint_path): | |
| st_file = os.path.join(checkpoint_path, "model.safetensors") | |
| if not os.path.exists(st_file): | |
| raise FileNotFoundError(f"Directory {checkpoint_path} is missing model.safetensors") | |
| from safetensors.torch import load_file | |
| logger.info(f"Detected VJEPA21Encoder safetensors dir: {checkpoint_path}") | |
| state_dict = load_file(st_file) | |
| missing, unexpected = model.load_state_dict(state_dict, strict=strict) | |
| n_loaded = len(state_dict) - len(unexpected) | |
| logger.info( | |
| f"V-JEPA 2.1 safetensors loaded: {n_loaded} keys, {len(missing)} missing, {len(unexpected)} unexpected" | |
| ) | |
| if missing: | |
| logger.info(f" Missing (first 10): {missing[:10]}") | |
| if unexpected: | |
| logger.info(f" Unexpected (first 10): {unexpected[:10]}") | |
| return model | |
| state_dict = torch.load(checkpoint_path, map_location="cpu", weights_only=False) | |
| if "ema_encoder" in state_dict: | |
| logger.info("Detected V-JEPA 2.1 format (ema_encoder)") | |
| state_dict = state_dict["ema_encoder"] | |
| elif "target_encoder" in state_dict: | |
| logger.info("Target Encoder only detected") | |
| state_dict = state_dict["target_encoder"] | |
| elif "model" in state_dict: | |
| state_dict = state_dict["model"] | |
| cleaned = {} | |
| for k, v in state_dict.items(): | |
| cleaned[k.replace("module.", "").replace("backbone.", "")] = v | |
| mapped = {f"encoder.{k}": v for k, v in cleaned.items()} | |
| missing, unexpected = model.load_state_dict(mapped, strict=strict) | |
| n_loaded = len(mapped) - len(unexpected) | |
| logger.info(f"V-JEPA 2.1 loaded: {n_loaded} keys, {len(missing)} missing, {len(unexpected)} unexpected") | |
| if missing: | |
| logger.info(f" Missing (first 10): {missing[:10]}") | |
| if unexpected: | |
| logger.info(f" Unexpected (first 10): {unexpected[:10]}") | |
| return model | |