Instructions to use zenosai/MonkeyOCRv2-B with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use zenosai/MonkeyOCRv2-B with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-feature-extraction", model="zenosai/MonkeyOCRv2-B", trust_remote_code=True)# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("zenosai/MonkeyOCRv2-B", trust_remote_code=True, dtype="auto") - Notebooks
- Google Colab
- Kaggle
Upload folder using huggingface_hub
Browse files- configuration_monkeyocrv2vit.py +15 -3
- model.safetensors +1 -1
- modeling_monkeyocrv2_vision.py +148 -9
configuration_monkeyocrv2vit.py
CHANGED
|
@@ -1,5 +1,8 @@
|
|
| 1 |
from typing import Any, Optional
|
| 2 |
from transformers.configuration_utils import PretrainedConfig
|
|
|
|
|
|
|
|
|
|
| 3 |
from transformers.models.auto.configuration_auto import CONFIG_MAPPING
|
| 4 |
|
| 5 |
|
|
@@ -8,8 +11,8 @@ class MonkeyOCRv2VisionConfig(PretrainedConfig):
|
|
| 8 |
|
| 9 |
def __init__(
|
| 10 |
self,
|
| 11 |
-
embed_dim: int = 1536,
|
| 12 |
-
hidden_size: int = 1536,
|
| 13 |
intermediate_size: int = 4224,
|
| 14 |
num_hidden_layers: int = 42,
|
| 15 |
num_attention_heads: int = 12,
|
|
@@ -22,7 +25,7 @@ class MonkeyOCRv2VisionConfig(PretrainedConfig):
|
|
| 22 |
vision_attn_implementation="flash_attention_2", # "eager","sdpa","flash_attention_2"
|
| 23 |
initializer_range=0.02,
|
| 24 |
init_merger_std=0.02,
|
| 25 |
-
is_causal=False,
|
| 26 |
post_norm=True,
|
| 27 |
gradient_checkpointing=False,
|
| 28 |
**kwargs: Any,
|
|
@@ -46,4 +49,13 @@ class MonkeyOCRv2VisionConfig(PretrainedConfig):
|
|
| 46 |
self.post_norm = post_norm
|
| 47 |
self.gradient_checkpointing = gradient_checkpointing
|
| 48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
CONFIG_MAPPING.register("MonkeyOCRv2VisionTransformer", MonkeyOCRv2VisionConfig)
|
|
|
|
| 1 |
from typing import Any, Optional
|
| 2 |
from transformers.configuration_utils import PretrainedConfig
|
| 3 |
+
# Remove Qwen3Config import as it causes error on older transformers/python versions
|
| 4 |
+
# from transformers.models.qwen3 import Qwen3Config
|
| 5 |
+
#from transformers import Qwen2_5_VLProcessor, AutoProcessor
|
| 6 |
from transformers.models.auto.configuration_auto import CONFIG_MAPPING
|
| 7 |
|
| 8 |
|
|
|
|
| 11 |
|
| 12 |
def __init__(
|
| 13 |
self,
|
| 14 |
+
embed_dim: int = 1536, # vision encoder embed size
|
| 15 |
+
hidden_size: int = 1536, # after merger hidden size
|
| 16 |
intermediate_size: int = 4224,
|
| 17 |
num_hidden_layers: int = 42,
|
| 18 |
num_attention_heads: int = 12,
|
|
|
|
| 25 |
vision_attn_implementation="flash_attention_2", # "eager","sdpa","flash_attention_2"
|
| 26 |
initializer_range=0.02,
|
| 27 |
init_merger_std=0.02,
|
| 28 |
+
is_causal=False, # ve causal forward
|
| 29 |
post_norm=True,
|
| 30 |
gradient_checkpointing=False,
|
| 31 |
**kwargs: Any,
|
|
|
|
| 49 |
self.post_norm = post_norm
|
| 50 |
self.gradient_checkpointing = gradient_checkpointing
|
| 51 |
|
| 52 |
+
|
| 53 |
+
# Commented out Processor definition to avoid dependencies on Qwen2_5_VLProcessor
|
| 54 |
+
# class MonkeyOCRv2Processor(Qwen2_5_VLProcessor):
|
| 55 |
+
# attributes = ["image_processor", "tokenizer"]
|
| 56 |
+
# def __init__(self, image_processor=None, tokenizer=None, chat_template=None, **kwargs):
|
| 57 |
+
# super().__init__(image_processor, tokenizer, chat_template=chat_template)
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
# AutoProcessor.register("MonkeyOCRv2VisionTransformer", MonkeyOCRv2Processor)
|
| 61 |
CONFIG_MAPPING.register("MonkeyOCRv2VisionTransformer", MonkeyOCRv2VisionConfig)
|
model.safetensors
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
size 454882592
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:a9f059fc5a7afb6e9d2ad64b5db02dfc8e846d4b713460f4b3c0b2468a4d52e1
|
| 3 |
size 454882592
|
modeling_monkeyocrv2_vision.py
CHANGED
|
@@ -16,6 +16,7 @@ except ImportError:
|
|
| 16 |
from torch.nn import LayerNorm
|
| 17 |
from transformers.modeling_utils import PreTrainedModel
|
| 18 |
from .configuration_monkeyocrv2vit import MonkeyOCRv2VisionConfig
|
|
|
|
| 19 |
|
| 20 |
|
| 21 |
try:
|
|
@@ -28,7 +29,7 @@ except ImportError:
|
|
| 28 |
def rotate_half(x):
|
| 29 |
"""Rotates half the hidden dims of the input."""
|
| 30 |
x1 = x[..., : x.shape[-1] // 2]
|
| 31 |
-
x2 = x[..., x.shape[-1] // 2:]
|
| 32 |
return torch.cat((-x2, x1), dim=-1)
|
| 33 |
|
| 34 |
|
|
@@ -194,6 +195,8 @@ class VisionAttentionV2(nn.Module):
|
|
| 194 |
q_list = torch.split(q, seqlens, 0)
|
| 195 |
k_list = torch.split(k, seqlens, 0)
|
| 196 |
v_list = torch.split(v, seqlens, 0)
|
|
|
|
|
|
|
| 197 |
outputs = []
|
| 198 |
for q_i, k_i, v_i in zip(q_list, k_list, v_list):
|
| 199 |
q_i = q_i.transpose(0, 1)
|
|
@@ -274,18 +277,21 @@ class VisionSdpaAttention(nn.Module):
|
|
| 274 |
for i in range(1, len(cu_seqlens)):
|
| 275 |
attention_mask[..., cu_seqlens[i - 1]: cu_seqlens[i], cu_seqlens[i - 1]: cu_seqlens[i]] = True
|
| 276 |
|
| 277 |
-
|
|
|
|
| 278 |
k = k.transpose(0, 1).unsqueeze(0)
|
| 279 |
v = v.transpose(0, 1).unsqueeze(0)
|
| 280 |
|
|
|
|
| 281 |
if attention_mask.stride(-1) != 1:
|
| 282 |
attention_mask = torch.empty_like(attention_mask, memory_format=torch.contiguous_format).copy_(attention_mask)
|
| 283 |
|
|
|
|
| 284 |
from torch.nn.attention import SDPBackend, sdpa_kernel
|
| 285 |
with sdpa_kernel(SDPBackend.EFFICIENT_ATTENTION):
|
| 286 |
attn_output = F.scaled_dot_product_attention(q, k, v, attention_mask, dropout_p=0.0)
|
| 287 |
|
| 288 |
-
attn_output = attn_output.squeeze(0).transpose(0, 1)
|
| 289 |
attn_output = attn_output.reshape(seq_length, -1)
|
| 290 |
|
| 291 |
attn_output = self.proj(attn_output)
|
|
@@ -294,10 +300,10 @@ class VisionSdpaAttention(nn.Module):
|
|
| 294 |
|
| 295 |
VISION_ATTENTION_CLASSES = {
|
| 296 |
"eager": VisionAttention,
|
| 297 |
-
"eager_v2": VisionAttentionV2,
|
| 298 |
"flash_attention_2": VisionFlashAttention2,
|
| 299 |
"sdpa": VisionSdpaAttention,
|
| 300 |
-
"ascend_fa": VisionAscendAttention,
|
| 301 |
}
|
| 302 |
|
| 303 |
|
|
@@ -404,6 +410,132 @@ class VisionBlock(nn.Module):
|
|
| 404 |
return hidden_states
|
| 405 |
|
| 406 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 407 |
class MonkeyOCRv2VisionTransformer(PreTrainedModel):
|
| 408 |
config_class = MonkeyOCRv2VisionConfig
|
| 409 |
_supports_flash_attn = True
|
|
@@ -485,13 +617,20 @@ class MonkeyOCRv2VisionTransformer(PreTrainedModel):
|
|
| 485 |
return pos_ids
|
| 486 |
|
| 487 |
def rot_pos_emb(self, grid_thw):
|
| 488 |
-
pos_ids = self.get_pos_ids_by_grid(grid_thw)
|
| 489 |
pos_ids = torch.cat(pos_ids, dim=0)
|
| 490 |
max_grid_size = grid_thw[:, 1:].max()
|
| 491 |
-
rotary_pos_emb_full = self.rotary_pos_emb(max_grid_size)
|
|
|
|
|
|
|
|
|
|
| 492 |
|
|
|
|
|
|
|
| 493 |
emb = rotary_pos_emb_full[pos_ids]
|
| 494 |
rotary_pos_emb = torch.stack([emb[:,0], emb[:,1]], dim=2).reshape(emb.shape[0], -1)
|
|
|
|
|
|
|
| 495 |
return rotary_pos_emb
|
| 496 |
|
| 497 |
def forward(self, hidden_states: torch.Tensor, grid_thw: torch.Tensor, bf16=True) -> torch.Tensor:
|
|
@@ -505,8 +644,8 @@ class MonkeyOCRv2VisionTransformer(PreTrainedModel):
|
|
| 505 |
cu_seqlens = torch.repeat_interleave(grid_thw[:, 1] * grid_thw[:, 2], grid_thw[:, 0]).cumsum(
|
| 506 |
dim=0,
|
| 507 |
dtype=grid_thw.dtype if torch.jit.is_tracing() else torch.int32,
|
| 508 |
-
)
|
| 509 |
-
cu_seqlens = F.pad(cu_seqlens, (1, 0), value=0)
|
| 510 |
|
| 511 |
for blk in self.blocks:
|
| 512 |
if self.gradient_checkpointing and self.training:
|
|
|
|
| 16 |
from torch.nn import LayerNorm
|
| 17 |
from transformers.modeling_utils import PreTrainedModel
|
| 18 |
from .configuration_monkeyocrv2vit import MonkeyOCRv2VisionConfig
|
| 19 |
+
# from configuration_monkeyocrv2vit import MonkeyOCRv2VisionConfig
|
| 20 |
|
| 21 |
|
| 22 |
try:
|
|
|
|
| 29 |
def rotate_half(x):
|
| 30 |
"""Rotates half the hidden dims of the input."""
|
| 31 |
x1 = x[..., : x.shape[-1] // 2]
|
| 32 |
+
x2 = x[..., x.shape[-1] // 2:] #这里是q0和q(d/2)一组,而不是q0和q1
|
| 33 |
return torch.cat((-x2, x1), dim=-1)
|
| 34 |
|
| 35 |
|
|
|
|
| 195 |
q_list = torch.split(q, seqlens, 0)
|
| 196 |
k_list = torch.split(k, seqlens, 0)
|
| 197 |
v_list = torch.split(v, seqlens, 0)
|
| 198 |
+
# eager attention 空间复杂度为 O(n^2) , n 为 b*s(batch_size * seq_len), 序列太长容易OOM, 这个实现 更具batch 切分 seq
|
| 199 |
+
# 减少内存需求, 计算相对 continus batching 较慢。
|
| 200 |
outputs = []
|
| 201 |
for q_i, k_i, v_i in zip(q_list, k_list, v_list):
|
| 202 |
q_i = q_i.transpose(0, 1)
|
|
|
|
| 277 |
for i in range(1, len(cu_seqlens)):
|
| 278 |
attention_mask[..., cu_seqlens[i - 1]: cu_seqlens[i], cu_seqlens[i - 1]: cu_seqlens[i]] = True
|
| 279 |
|
| 280 |
+
# Convert q, k, v to 4D to enable : (1, num_heads, seq_length, head_dim)
|
| 281 |
+
q = q.transpose(0, 1).unsqueeze(0) # (1, num_heads, seq_length, head_dim)
|
| 282 |
k = k.transpose(0, 1).unsqueeze(0)
|
| 283 |
v = v.transpose(0, 1).unsqueeze(0)
|
| 284 |
|
| 285 |
+
# See: https://github.com/pytorch/pytorch/issues/127523
|
| 286 |
if attention_mask.stride(-1) != 1:
|
| 287 |
attention_mask = torch.empty_like(attention_mask, memory_format=torch.contiguous_format).copy_(attention_mask)
|
| 288 |
|
| 289 |
+
# use memory efficient backend
|
| 290 |
from torch.nn.attention import SDPBackend, sdpa_kernel
|
| 291 |
with sdpa_kernel(SDPBackend.EFFICIENT_ATTENTION):
|
| 292 |
attn_output = F.scaled_dot_product_attention(q, k, v, attention_mask, dropout_p=0.0)
|
| 293 |
|
| 294 |
+
attn_output = attn_output.squeeze(0).transpose(0, 1) # (seq_length, num_heads, head_dim)
|
| 295 |
attn_output = attn_output.reshape(seq_length, -1)
|
| 296 |
|
| 297 |
attn_output = self.proj(attn_output)
|
|
|
|
| 300 |
|
| 301 |
VISION_ATTENTION_CLASSES = {
|
| 302 |
"eager": VisionAttention,
|
| 303 |
+
"eager_v2": VisionAttentionV2, # 内存更少
|
| 304 |
"flash_attention_2": VisionFlashAttention2,
|
| 305 |
"sdpa": VisionSdpaAttention,
|
| 306 |
+
"ascend_fa": VisionAscendAttention, # ascend, 长序列精度下降严重。
|
| 307 |
}
|
| 308 |
|
| 309 |
|
|
|
|
| 410 |
return hidden_states
|
| 411 |
|
| 412 |
|
| 413 |
+
class VisionTransformerDecoder(PreTrainedModel):
|
| 414 |
+
_supports_flash_attn = True
|
| 415 |
+
_supports_sdpa = True
|
| 416 |
+
_no_split_modules = ["VisionBlock"]
|
| 417 |
+
def __init__(self, config: MonkeyOCRv2VisionConfig) -> None:
|
| 418 |
+
super().__init__(config)
|
| 419 |
+
self.num_classes = 3 * config.patch_size ** 2
|
| 420 |
+
|
| 421 |
+
self.spatial_merge_size = config.spatial_merge_size
|
| 422 |
+
self.patch_size = config.patch_size
|
| 423 |
+
|
| 424 |
+
head_dim = config.embed_dim // config.num_attention_heads
|
| 425 |
+
|
| 426 |
+
self.rotary_pos_emb = VisionRotaryEmbedding(head_dim // 2)
|
| 427 |
+
|
| 428 |
+
_num_hidden_layers = config.num_hidden_layers
|
| 429 |
+
|
| 430 |
+
self.blocks = nn.ModuleList(
|
| 431 |
+
[VisionBlock(config, config.vision_attn_implementation) for _ in range(_num_hidden_layers)]
|
| 432 |
+
)
|
| 433 |
+
|
| 434 |
+
if self.config.post_norm:
|
| 435 |
+
self.post_trunk_norm = RMSNorm(config.embed_dim, eps=config.rms_norm_eps)
|
| 436 |
+
self.head = nn.Linear(config.embed_dim, self.num_classes) if self.num_classes > 0 else nn.Identity()
|
| 437 |
+
|
| 438 |
+
self.gradient_checkpointing = False
|
| 439 |
+
self._gradient_checkpointing_func = torch.utils.checkpoint.checkpoint
|
| 440 |
+
|
| 441 |
+
def _init_weights(self, module):
|
| 442 |
+
std = self.config.initializer_range
|
| 443 |
+
if isinstance(module, (nn.Linear, nn.Conv3d)):
|
| 444 |
+
module.weight.data.normal_(mean=0.0, std=std)
|
| 445 |
+
if module.bias is not None:
|
| 446 |
+
module.bias.data.zero_()
|
| 447 |
+
elif isinstance(module, nn.Embedding):
|
| 448 |
+
module.weight.data.normal_(mean=0.0, std=std)
|
| 449 |
+
if module.padding_idx is not None:
|
| 450 |
+
module.weight.data[module.padding_idx].zero_()
|
| 451 |
+
|
| 452 |
+
@property
|
| 453 |
+
def dtype(self) -> torch.dtype:
|
| 454 |
+
return self.blocks[0].mlp.fc2.weight.dtype
|
| 455 |
+
|
| 456 |
+
@property
|
| 457 |
+
def device(self) -> torch.device:
|
| 458 |
+
return self.blocks[0].mlp.fc2.weight.device
|
| 459 |
+
|
| 460 |
+
def get_pos_ids_by_grid(self, grid_thw):
|
| 461 |
+
pos_ids = []
|
| 462 |
+
for t, h, w in grid_thw:
|
| 463 |
+
hpos_ids = torch.arange(h).unsqueeze(1).expand(-1, w)
|
| 464 |
+
hpos_ids = hpos_ids.reshape(
|
| 465 |
+
h // self.spatial_merge_size,
|
| 466 |
+
self.spatial_merge_size,
|
| 467 |
+
w // self.spatial_merge_size,
|
| 468 |
+
self.spatial_merge_size,
|
| 469 |
+
)
|
| 470 |
+
hpos_ids = hpos_ids.permute(0, 2, 1, 3)
|
| 471 |
+
hpos_ids = hpos_ids.flatten()
|
| 472 |
+
|
| 473 |
+
wpos_ids = torch.arange(w).unsqueeze(0).expand(h, -1)
|
| 474 |
+
wpos_ids = wpos_ids.reshape(
|
| 475 |
+
h // self.spatial_merge_size,
|
| 476 |
+
self.spatial_merge_size,
|
| 477 |
+
w // self.spatial_merge_size,
|
| 478 |
+
self.spatial_merge_size,
|
| 479 |
+
)
|
| 480 |
+
wpos_ids = wpos_ids.permute(0, 2, 1, 3)
|
| 481 |
+
wpos_ids = wpos_ids.flatten()
|
| 482 |
+
|
| 483 |
+
pos_ids.append(
|
| 484 |
+
torch.stack([hpos_ids, wpos_ids], dim=-1).repeat(t, 1)
|
| 485 |
+
)
|
| 486 |
+
|
| 487 |
+
|
| 488 |
+
|
| 489 |
+
return pos_ids
|
| 490 |
+
|
| 491 |
+
def rot_pos_emb(self, grid_thw):
|
| 492 |
+
pos_ids = self.get_pos_ids_by_grid(grid_thw) #得到在旋转编码表中的hw坐标
|
| 493 |
+
pos_ids = torch.cat(pos_ids, dim=0)
|
| 494 |
+
max_grid_size = grid_thw[:, 1:].max()
|
| 495 |
+
rotary_pos_emb_full = self.rotary_pos_emb(max_grid_size) # max_size x dim/2
|
| 496 |
+
|
| 497 |
+
# # mrope
|
| 498 |
+
# rotary_pos_emb = rotary_pos_emb_full[pos_ids].flatten(1)
|
| 499 |
+
|
| 500 |
+
|
| 501 |
+
# mrope-i
|
| 502 |
+
emb = rotary_pos_emb_full[pos_ids]
|
| 503 |
+
rotary_pos_emb = torch.stack([emb[:,0], emb[:,1]], dim=2).reshape(emb.shape[0], -1)
|
| 504 |
+
# mrope-i
|
| 505 |
+
|
| 506 |
+
return rotary_pos_emb
|
| 507 |
+
|
| 508 |
+
def forward(self, hidden_states: torch.Tensor, grid_thw: torch.Tensor, bf16=True) -> torch.Tensor:
|
| 509 |
+
# if bf16:
|
| 510 |
+
# hidden_states = hidden_states.bfloat16()
|
| 511 |
+
|
| 512 |
+
rotary_pos_emb = self.rot_pos_emb(grid_thw)
|
| 513 |
+
|
| 514 |
+
cu_seqlens = torch.repeat_interleave(grid_thw[:, 1] * grid_thw[:, 2], grid_thw[:, 0]).cumsum(
|
| 515 |
+
dim=0,
|
| 516 |
+
dtype=grid_thw.dtype if torch.jit.is_tracing() else torch.int32,
|
| 517 |
+
)#得到每个图像的token起始
|
| 518 |
+
cu_seqlens = F.pad(cu_seqlens, (1, 0), value=0) #左侧补1个值,右侧补0个值,这个值的value是0
|
| 519 |
+
|
| 520 |
+
for blk in self.blocks:
|
| 521 |
+
if self.gradient_checkpointing and self.training:
|
| 522 |
+
hidden_states = self._gradient_checkpointing_func(
|
| 523 |
+
blk.__call__,
|
| 524 |
+
hidden_states,
|
| 525 |
+
cu_seqlens,
|
| 526 |
+
rotary_pos_emb,
|
| 527 |
+
)
|
| 528 |
+
else:
|
| 529 |
+
hidden_states = blk(hidden_states, cu_seqlens=cu_seqlens, rotary_pos_emb=rotary_pos_emb)
|
| 530 |
+
|
| 531 |
+
if self.config.post_norm:
|
| 532 |
+
hidden_states = self.post_trunk_norm(hidden_states)
|
| 533 |
+
|
| 534 |
+
hidden_states = self.head(hidden_states)
|
| 535 |
+
|
| 536 |
+
return hidden_states
|
| 537 |
+
|
| 538 |
+
|
| 539 |
class MonkeyOCRv2VisionTransformer(PreTrainedModel):
|
| 540 |
config_class = MonkeyOCRv2VisionConfig
|
| 541 |
_supports_flash_attn = True
|
|
|
|
| 617 |
return pos_ids
|
| 618 |
|
| 619 |
def rot_pos_emb(self, grid_thw):
|
| 620 |
+
pos_ids = self.get_pos_ids_by_grid(grid_thw) #得到在旋转编码表中的hw坐标
|
| 621 |
pos_ids = torch.cat(pos_ids, dim=0)
|
| 622 |
max_grid_size = grid_thw[:, 1:].max()
|
| 623 |
+
rotary_pos_emb_full = self.rotary_pos_emb(max_grid_size) # max_size x dim/2
|
| 624 |
+
|
| 625 |
+
# # mrope
|
| 626 |
+
# rotary_pos_emb = rotary_pos_emb_full[pos_ids].flatten(1)
|
| 627 |
|
| 628 |
+
|
| 629 |
+
# mrope-i
|
| 630 |
emb = rotary_pos_emb_full[pos_ids]
|
| 631 |
rotary_pos_emb = torch.stack([emb[:,0], emb[:,1]], dim=2).reshape(emb.shape[0], -1)
|
| 632 |
+
# mrope-i
|
| 633 |
+
|
| 634 |
return rotary_pos_emb
|
| 635 |
|
| 636 |
def forward(self, hidden_states: torch.Tensor, grid_thw: torch.Tensor, bf16=True) -> torch.Tensor:
|
|
|
|
| 644 |
cu_seqlens = torch.repeat_interleave(grid_thw[:, 1] * grid_thw[:, 2], grid_thw[:, 0]).cumsum(
|
| 645 |
dim=0,
|
| 646 |
dtype=grid_thw.dtype if torch.jit.is_tracing() else torch.int32,
|
| 647 |
+
)#得到每个图像的token起始
|
| 648 |
+
cu_seqlens = F.pad(cu_seqlens, (1, 0), value=0) #左侧补1个值,右侧补0个值,这个值的value是0
|
| 649 |
|
| 650 |
for blk in self.blocks:
|
| 651 |
if self.gradient_checkpointing and self.training:
|