Image-Text-to-Text
PaddleOCR
Safetensors
English
Chinese
multilingual
paddleocr_vl
ERNIE4.5
PaddlePaddle
image-to-text
ocr
document-parse
layout
table
formula
chart
conversational
custom_code
Eval Results
Instructions to use PaddlePaddle/PaddleOCR-VL with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PaddleOCR
How to use PaddlePaddle/PaddleOCR-VL with PaddleOCR:
# See https://www.paddleocr.ai/latest/version3.x/pipeline_usage/PaddleOCR-VL.html to installation from paddleocr import PaddleOCRVL pipeline = PaddleOCRVL(pipeline_version="v1") output = pipeline.predict("path/to/document_image.png") for res in output: res.print() res.save_to_json(save_path="output") res.save_to_markdown(save_path="output") - Notebooks
- Google Colab
- Kaggle
Fix Transformers 4.x/5.x compatibility and isolate multi-image vision attention
#102
by Bvicii - opened
- modeling_paddleocr_vl.py +182 -43
modeling_paddleocr_vl.py
CHANGED
|
@@ -12,9 +12,11 @@
|
|
| 12 |
# See the License for the specific language governing permissions and
|
| 13 |
# limitations under the License.
|
| 14 |
|
|
|
|
| 15 |
import math
|
| 16 |
import warnings
|
| 17 |
from dataclasses import dataclass
|
|
|
|
| 18 |
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
| 19 |
|
| 20 |
import numpy as np
|
|
@@ -28,9 +30,9 @@ from transformers.cache_utils import (
|
|
| 28 |
Cache,
|
| 29 |
DynamicCache,
|
| 30 |
)
|
|
|
|
| 31 |
from transformers.generation import GenerationMixin
|
| 32 |
from transformers.integrations import use_kernel_forward_from_hub
|
| 33 |
-
from transformers.masking_utils import create_causal_mask
|
| 34 |
from transformers.modeling_attn_mask_utils import AttentionMaskConverter
|
| 35 |
from transformers.modeling_layers import GradientCheckpointingLayer
|
| 36 |
from transformers.modeling_outputs import (
|
|
@@ -66,6 +68,87 @@ else:
|
|
| 66 |
from .configuration_paddleocr_vl import PaddleOCRVisionConfig, PaddleOCRVLConfig
|
| 67 |
|
| 68 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
class RotaryEmbedding(nn.Module):
|
| 70 |
def __init__(self, config: PaddleOCRVLConfig, device=None):
|
| 71 |
super().__init__()
|
|
@@ -92,12 +175,25 @@ class RotaryEmbedding(nn.Module):
|
|
| 92 |
self.original_max_seq_len = config.max_position_embeddings
|
| 93 |
|
| 94 |
self.config = config
|
| 95 |
-
self.
|
|
|
|
|
|
|
|
|
|
| 96 |
|
| 97 |
inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device)
|
| 98 |
self.register_buffer("inv_freq", inv_freq, persistent=False)
|
| 99 |
self.original_inv_freq = self.inv_freq
|
| 100 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
def _dynamic_frequency_update(self, position_ids, device):
|
| 102 |
"""
|
| 103 |
dynamic RoPE layers should recompute `inv_freq` in the following situations:
|
|
@@ -539,6 +635,12 @@ class Ernie4_5PreTrainedModel(PreTrainedModel):
|
|
| 539 |
}
|
| 540 |
|
| 541 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 542 |
@auto_docstring
|
| 543 |
class Ernie4_5Model(Ernie4_5PreTrainedModel):
|
| 544 |
def __init__(self, config: PaddleOCRVLConfig):
|
|
@@ -603,13 +705,8 @@ class Ernie4_5Model(Ernie4_5PreTrainedModel):
|
|
| 603 |
elif position_ids.dim() == 2:
|
| 604 |
position_ids = position_ids[None, ...].expand(3, position_ids.shape[0], -1)
|
| 605 |
|
| 606 |
-
causal_mask =
|
| 607 |
-
|
| 608 |
-
inputs_embeds=inputs_embeds,
|
| 609 |
-
attention_mask=attention_mask,
|
| 610 |
-
past_key_values=past_key_values,
|
| 611 |
-
position_ids=position_ids,
|
| 612 |
-
cache_position=cache_position,
|
| 613 |
)
|
| 614 |
|
| 615 |
hidden_states = inputs_embeds
|
|
@@ -634,7 +731,7 @@ class Ernie4_5Model(Ernie4_5PreTrainedModel):
|
|
| 634 |
|
| 635 |
|
| 636 |
class Ernie4_5ForCausalLM(Ernie4_5PreTrainedModel, GenerationMixin):
|
| 637 |
-
_tied_weights_keys =
|
| 638 |
_tp_plan = {"lm_head": "colwise_rep"}
|
| 639 |
_pp_plan = {"lm_head": (["hidden_states"], ["logits"])}
|
| 640 |
|
|
@@ -711,6 +808,7 @@ class Ernie4_5ForCausalLM(Ernie4_5PreTrainedModel, GenerationMixin):
|
|
| 711 |
)
|
| 712 |
|
| 713 |
|
|
|
|
| 714 |
def _trunc_normal_(tensor, mean, std, a, b):
|
| 715 |
# Cut & paste from PyTorch official master until it's in a few official releases - RW
|
| 716 |
# Method based on https://people.sc.fsu.edu/~jburkardt/presentations/truncated_normal.pdf
|
|
@@ -747,6 +845,7 @@ def _trunc_normal_(tensor, mean, std, a, b):
|
|
| 747 |
tensor.clamp_(min=a, max=b)
|
| 748 |
|
| 749 |
|
|
|
|
| 750 |
def trunc_normal_tf_(
|
| 751 |
tensor: torch.Tensor,
|
| 752 |
mean: float = 0.0,
|
|
@@ -777,6 +876,7 @@ def trunc_normal_tf_(
|
|
| 777 |
tensor.mul_(std).add_(mean)
|
| 778 |
|
| 779 |
|
|
|
|
| 780 |
def variance_scaling_(tensor, scale=1.0, mode="fan_in", distribution="normal"):
|
| 781 |
fan_in, fan_out = _calculate_fan_in_and_fan_out(tensor)
|
| 782 |
if mode == "fan_in":
|
|
@@ -1134,16 +1234,39 @@ class PaddleOCRAttention(nn.Module):
|
|
| 1134 |
elif self.config._attn_implementation == "sdpa":
|
| 1135 |
attention_interface = sdpa_attention_forward
|
| 1136 |
|
| 1137 |
-
|
| 1138 |
-
|
| 1139 |
-
|
| 1140 |
-
|
| 1141 |
-
|
| 1142 |
-
|
| 1143 |
-
|
| 1144 |
-
|
| 1145 |
-
|
| 1146 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1147 |
attn_output = attn_output.reshape(
|
| 1148 |
batch_size, seq_length, embed_dim
|
| 1149 |
).contiguous()
|
|
@@ -1263,45 +1386,47 @@ class PaddleOCRPreTrainedModel(PreTrainedModel):
|
|
| 1263 |
"PaddleOCRVisionEmbeddings",
|
| 1264 |
"PaddleOCRMultiheadAttentionPoolingHead",
|
| 1265 |
]
|
| 1266 |
-
|
|
|
|
| 1267 |
_supports_sdpa = True
|
| 1268 |
|
| 1269 |
def _init_weights(self, module):
|
| 1270 |
-
"""Initialize the weights"""
|
|
|
|
| 1271 |
if isinstance(module, PaddleOCRVisionEmbeddings):
|
| 1272 |
width = (
|
| 1273 |
self.config.vision_config.hidden_size
|
| 1274 |
if isinstance(self.config, PaddleOCRVLConfig)
|
| 1275 |
else self.config.hidden_size
|
| 1276 |
)
|
| 1277 |
-
|
| 1278 |
elif isinstance(module, nn.Embedding):
|
| 1279 |
default_flax_embed_init(module.weight)
|
| 1280 |
elif isinstance(module, PaddleOCRAttention):
|
| 1281 |
-
|
| 1282 |
-
|
| 1283 |
-
|
| 1284 |
-
|
| 1285 |
-
|
| 1286 |
-
|
| 1287 |
-
|
| 1288 |
-
|
| 1289 |
elif isinstance(module, PaddleOCRMLP):
|
| 1290 |
-
|
| 1291 |
-
|
| 1292 |
-
|
| 1293 |
-
|
| 1294 |
elif isinstance(module, PaddleOCRMultiheadAttentionPoolingHead):
|
| 1295 |
-
|
| 1296 |
-
|
| 1297 |
-
|
| 1298 |
elif isinstance(module, (nn.Linear, nn.Conv2d)):
|
| 1299 |
lecun_normal_(module.weight)
|
| 1300 |
if module.bias is not None:
|
| 1301 |
-
|
| 1302 |
elif isinstance(module, nn.LayerNorm):
|
| 1303 |
-
module.bias
|
| 1304 |
-
module.weight
|
| 1305 |
|
| 1306 |
|
| 1307 |
# Copied from transformers.models.altclip.modeling_altclip.AltCLIPEncoder with AltCLIP->PaddleOCR
|
|
@@ -1866,7 +1991,7 @@ class PaddleOCRVLCausalLMOutputWithPast(ModelOutput):
|
|
| 1866 |
|
| 1867 |
|
| 1868 |
class PaddleOCRVLForConditionalGeneration(Ernie4_5PreTrainedModel, GenerationMixin):
|
| 1869 |
-
_tied_weights_keys =
|
| 1870 |
config_class = PaddleOCRVLConfig
|
| 1871 |
_no_split_modules = ["Ernie4_5_DecoderLayer", "PaddleOCREncoderLayer"]
|
| 1872 |
|
|
@@ -2342,7 +2467,21 @@ class PaddleOCRVLForConditionalGeneration(Ernie4_5PreTrainedModel, GenerationMix
|
|
| 2342 |
|
| 2343 |
model_inputs["position_ids"] = None
|
| 2344 |
|
| 2345 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2346 |
model_inputs["pixel_values"] = None
|
| 2347 |
model_inputs["pixel_values_videos"] = None
|
| 2348 |
|
|
|
|
| 12 |
# See the License for the specific language governing permissions and
|
| 13 |
# limitations under the License.
|
| 14 |
|
| 15 |
+
import inspect
|
| 16 |
import math
|
| 17 |
import warnings
|
| 18 |
from dataclasses import dataclass
|
| 19 |
+
from functools import wraps
|
| 20 |
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
| 21 |
|
| 22 |
import numpy as np
|
|
|
|
| 30 |
Cache,
|
| 31 |
DynamicCache,
|
| 32 |
)
|
| 33 |
+
from transformers.masking_utils import create_causal_mask as _hf_create_causal_mask
|
| 34 |
from transformers.generation import GenerationMixin
|
| 35 |
from transformers.integrations import use_kernel_forward_from_hub
|
|
|
|
| 36 |
from transformers.modeling_attn_mask_utils import AttentionMaskConverter
|
| 37 |
from transformers.modeling_layers import GradientCheckpointingLayer
|
| 38 |
from transformers.modeling_outputs import (
|
|
|
|
| 68 |
from .configuration_paddleocr_vl import PaddleOCRVisionConfig, PaddleOCRVLConfig
|
| 69 |
|
| 70 |
|
| 71 |
+
# Resolve optional framework interfaces once, outside the forward path.
|
| 72 |
+
try:
|
| 73 |
+
from transformers import initialization as _hf_initialization
|
| 74 |
+
except ImportError:
|
| 75 |
+
_hf_initialization = None
|
| 76 |
+
|
| 77 |
+
# create_causal_mask exists in every release this file can import on (>= 4.54),
|
| 78 |
+
# but its signature changed: `input_embeds` -> `inputs_embeds`, and
|
| 79 |
+
# `cache_position` was later removed in favor of reading offsets from the cache.
|
| 80 |
+
_HF_MASK_PARAMETERS = frozenset(inspect.signature(_hf_create_causal_mask).parameters)
|
| 81 |
+
_HF_MASK_INPUT_NAME = "inputs_embeds" if "inputs_embeds" in _HF_MASK_PARAMETERS else "input_embeds"
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
def _guard_initializer(function):
|
| 85 |
+
@wraps(function)
|
| 86 |
+
def initialize(tensor, *args, **kwargs):
|
| 87 |
+
if getattr(tensor, "_is_hf_initialized", False):
|
| 88 |
+
return tensor
|
| 89 |
+
with torch.no_grad():
|
| 90 |
+
return function(tensor, *args, **kwargs)
|
| 91 |
+
return initialize
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
@_guard_initializer
|
| 95 |
+
def _init_tensor(tensor, operation, *args, **kwargs):
|
| 96 |
+
# Standard primitives use the framework's protected implementation when
|
| 97 |
+
# present. Keep model-specific TF/LeCun sampling formulas below unchanged.
|
| 98 |
+
function = getattr(_hf_initialization, operation, None)
|
| 99 |
+
if function is not None:
|
| 100 |
+
return function(tensor, *args, **kwargs)
|
| 101 |
+
if operation == "copy_":
|
| 102 |
+
return tensor.copy_(*args, **kwargs)
|
| 103 |
+
return getattr(nn.init, operation)(tensor, *args, **kwargs)
|
| 104 |
+
|
| 105 |
+
|
| 106 |
+
def _create_causal_mask(config, inputs_embeds, attention_mask, past_key_values, cache_position):
|
| 107 |
+
# Only dense tensors need conversion; flex BlockMask is passed through to the native function.
|
| 108 |
+
if isinstance(attention_mask, torch.Tensor) and attention_mask.ndim == 4:
|
| 109 |
+
mask = attention_mask.to(device=inputs_embeds.device)
|
| 110 |
+
if mask.dtype == torch.bool:
|
| 111 |
+
additive = torch.zeros(mask.shape, device=mask.device, dtype=inputs_embeds.dtype)
|
| 112 |
+
return additive.masked_fill(~mask, torch.finfo(inputs_embeds.dtype).min)
|
| 113 |
+
return mask.to(dtype=inputs_embeds.dtype)
|
| 114 |
+
|
| 115 |
+
mask_kwargs = {
|
| 116 |
+
"config": config,
|
| 117 |
+
_HF_MASK_INPUT_NAME: inputs_embeds,
|
| 118 |
+
"attention_mask": attention_mask,
|
| 119 |
+
"past_key_values": past_key_values,
|
| 120 |
+
}
|
| 121 |
+
if "cache_position" in _HF_MASK_PARAMETERS:
|
| 122 |
+
mask_kwargs["cache_position"] = cache_position
|
| 123 |
+
if "position_ids" in _HF_MASK_PARAMETERS:
|
| 124 |
+
# 3D M-RoPE coordinates are not packed text-sequence positions.
|
| 125 |
+
mask_kwargs["position_ids"] = None
|
| 126 |
+
return _hf_create_causal_mask(**mask_kwargs)
|
| 127 |
+
|
| 128 |
+
|
| 129 |
+
def _init_derived_buffers(module):
|
| 130 |
+
# v5 materializes non-persistent buffers from meta storage; they are not
|
| 131 |
+
# loaded from the checkpoint and must be initialized explicitly.
|
| 132 |
+
if isinstance(module, RotaryEmbedding):
|
| 133 |
+
inv_freq, module.attention_scaling = module.rope_init_fn(
|
| 134 |
+
module.config, device=module.inv_freq.device
|
| 135 |
+
)
|
| 136 |
+
_init_tensor(module.inv_freq, "copy_", inv_freq)
|
| 137 |
+
module.original_inv_freq = module.inv_freq
|
| 138 |
+
elif isinstance(module, SigLIPRotaryEmbedding):
|
| 139 |
+
inv_freq = 1.0 / (
|
| 140 |
+
module.theta ** (
|
| 141 |
+
torch.arange(0, module.dim, 2, dtype=torch.float32, device=module.inv_freq.device)
|
| 142 |
+
/ module.dim
|
| 143 |
+
)
|
| 144 |
+
)
|
| 145 |
+
_init_tensor(module.inv_freq, "copy_", inv_freq)
|
| 146 |
+
elif isinstance(module, PaddleOCRVisionEmbeddings):
|
| 147 |
+
_init_tensor(module.position_ids, "copy_",
|
| 148 |
+
torch.arange(module.num_positions, device=module.position_ids.device).expand(1, -1)
|
| 149 |
+
)
|
| 150 |
+
|
| 151 |
+
|
| 152 |
class RotaryEmbedding(nn.Module):
|
| 153 |
def __init__(self, config: PaddleOCRVLConfig, device=None):
|
| 154 |
super().__init__()
|
|
|
|
| 175 |
self.original_max_seq_len = config.max_position_embeddings
|
| 176 |
|
| 177 |
self.config = config
|
| 178 |
+
if self.rope_type == "default":
|
| 179 |
+
self.rope_init_fn = self.compute_default_rope_parameters
|
| 180 |
+
else:
|
| 181 |
+
self.rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type]
|
| 182 |
|
| 183 |
inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device)
|
| 184 |
self.register_buffer("inv_freq", inv_freq, persistent=False)
|
| 185 |
self.original_inv_freq = self.inv_freq
|
| 186 |
|
| 187 |
+
@staticmethod
|
| 188 |
+
def compute_default_rope_parameters(config, device=None, seq_len=None):
|
| 189 |
+
# Default RoPE is no longer part of ROPE_INIT_FUNCTIONS in v5.
|
| 190 |
+
head_dim = getattr(config, "head_dim", None) or config.hidden_size // config.num_attention_heads
|
| 191 |
+
dim = int(head_dim * getattr(config, "partial_rotary_factor", 1.0))
|
| 192 |
+
inv_freq = 1.0 / (
|
| 193 |
+
config.rope_theta ** (torch.arange(0, dim, 2, dtype=torch.float32, device=device) / dim)
|
| 194 |
+
)
|
| 195 |
+
return inv_freq, 1.0
|
| 196 |
+
|
| 197 |
def _dynamic_frequency_update(self, position_ids, device):
|
| 198 |
"""
|
| 199 |
dynamic RoPE layers should recompute `inv_freq` in the following situations:
|
|
|
|
| 635 |
}
|
| 636 |
|
| 637 |
|
| 638 |
+
@torch.no_grad()
|
| 639 |
+
def _init_weights(self, module):
|
| 640 |
+
super()._init_weights(module)
|
| 641 |
+
_init_derived_buffers(module)
|
| 642 |
+
|
| 643 |
+
|
| 644 |
@auto_docstring
|
| 645 |
class Ernie4_5Model(Ernie4_5PreTrainedModel):
|
| 646 |
def __init__(self, config: PaddleOCRVLConfig):
|
|
|
|
| 705 |
elif position_ids.dim() == 2:
|
| 706 |
position_ids = position_ids[None, ...].expand(3, position_ids.shape[0], -1)
|
| 707 |
|
| 708 |
+
causal_mask = _create_causal_mask(
|
| 709 |
+
self.config, inputs_embeds, attention_mask, past_key_values, cache_position
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 710 |
)
|
| 711 |
|
| 712 |
hidden_states = inputs_embeds
|
|
|
|
| 731 |
|
| 732 |
|
| 733 |
class Ernie4_5ForCausalLM(Ernie4_5PreTrainedModel, GenerationMixin):
|
| 734 |
+
_tied_weights_keys = {"lm_head.weight": "model.embed_tokens.weight"}
|
| 735 |
_tp_plan = {"lm_head": "colwise_rep"}
|
| 736 |
_pp_plan = {"lm_head": (["hidden_states"], ["logits"])}
|
| 737 |
|
|
|
|
| 808 |
)
|
| 809 |
|
| 810 |
|
| 811 |
+
@_guard_initializer
|
| 812 |
def _trunc_normal_(tensor, mean, std, a, b):
|
| 813 |
# Cut & paste from PyTorch official master until it's in a few official releases - RW
|
| 814 |
# Method based on https://people.sc.fsu.edu/~jburkardt/presentations/truncated_normal.pdf
|
|
|
|
| 845 |
tensor.clamp_(min=a, max=b)
|
| 846 |
|
| 847 |
|
| 848 |
+
@_guard_initializer
|
| 849 |
def trunc_normal_tf_(
|
| 850 |
tensor: torch.Tensor,
|
| 851 |
mean: float = 0.0,
|
|
|
|
| 876 |
tensor.mul_(std).add_(mean)
|
| 877 |
|
| 878 |
|
| 879 |
+
@_guard_initializer
|
| 880 |
def variance_scaling_(tensor, scale=1.0, mode="fan_in", distribution="normal"):
|
| 881 |
fan_in, fan_out = _calculate_fan_in_and_fan_out(tensor)
|
| 882 |
if mode == "fan_in":
|
|
|
|
| 1234 |
elif self.config._attn_implementation == "sdpa":
|
| 1235 |
attention_interface = sdpa_attention_forward
|
| 1236 |
|
| 1237 |
+
if cu_seqlens is not None and cu_seqlens.numel() > 2:
|
| 1238 |
+
boundaries = cu_seqlens.tolist()
|
| 1239 |
+
outputs = []
|
| 1240 |
+
attn_weights = (
|
| 1241 |
+
queries.new_zeros(batch_size, self.num_heads, seq_length, seq_length)
|
| 1242 |
+
if output_attentions else None
|
| 1243 |
+
)
|
| 1244 |
+
for start, end in zip(boundaries[:-1], boundaries[1:]):
|
| 1245 |
+
local_mask = None
|
| 1246 |
+
if attention_mask is not None:
|
| 1247 |
+
# Keep size-1 broadcast dims, e.g. a [B, 1, 1, L] padding mask.
|
| 1248 |
+
span = slice(start, end)
|
| 1249 |
+
local_mask = attention_mask[
|
| 1250 |
+
...,
|
| 1251 |
+
span if attention_mask.shape[-2] > 1 else slice(None),
|
| 1252 |
+
span if attention_mask.shape[-1] > 1 else slice(None),
|
| 1253 |
+
]
|
| 1254 |
+
output, weights = attention_interface(
|
| 1255 |
+
self, queries[:, :, start:end], keys[:, :, start:end],
|
| 1256 |
+
values[:, :, start:end], local_mask,
|
| 1257 |
+
is_causal=False, scaling=self.scale,
|
| 1258 |
+
dropout=0.0 if not self.training else self.dropout,
|
| 1259 |
+
)
|
| 1260 |
+
outputs.append(output)
|
| 1261 |
+
if attn_weights is not None and weights is not None:
|
| 1262 |
+
attn_weights[..., start:end, start:end] = weights
|
| 1263 |
+
attn_output = torch.cat(outputs, dim=1)
|
| 1264 |
+
else:
|
| 1265 |
+
attn_output, attn_weights = attention_interface(
|
| 1266 |
+
self, queries, keys, values, attention_mask,
|
| 1267 |
+
is_causal=self.is_causal, scaling=self.scale,
|
| 1268 |
+
dropout=0.0 if not self.training else self.dropout,
|
| 1269 |
+
)
|
| 1270 |
attn_output = attn_output.reshape(
|
| 1271 |
batch_size, seq_length, embed_dim
|
| 1272 |
).contiguous()
|
|
|
|
| 1386 |
"PaddleOCRVisionEmbeddings",
|
| 1387 |
"PaddleOCRMultiheadAttentionPoolingHead",
|
| 1388 |
]
|
| 1389 |
+
# v5 only reads `_supports_flash_attn`; 4.x accepts both names.
|
| 1390 |
+
_supports_flash_attn = True
|
| 1391 |
_supports_sdpa = True
|
| 1392 |
|
| 1393 |
def _init_weights(self, module):
|
| 1394 |
+
"""Initialize the weights and derived non-persistent buffers."""
|
| 1395 |
+
_init_derived_buffers(module)
|
| 1396 |
if isinstance(module, PaddleOCRVisionEmbeddings):
|
| 1397 |
width = (
|
| 1398 |
self.config.vision_config.hidden_size
|
| 1399 |
if isinstance(self.config, PaddleOCRVLConfig)
|
| 1400 |
else self.config.hidden_size
|
| 1401 |
)
|
| 1402 |
+
_init_tensor(module.position_embedding.weight, 'normal_', std=1 / np.sqrt(width))
|
| 1403 |
elif isinstance(module, nn.Embedding):
|
| 1404 |
default_flax_embed_init(module.weight)
|
| 1405 |
elif isinstance(module, PaddleOCRAttention):
|
| 1406 |
+
_init_tensor(module.q_proj.weight, 'xavier_uniform_')
|
| 1407 |
+
_init_tensor(module.k_proj.weight, 'xavier_uniform_')
|
| 1408 |
+
_init_tensor(module.v_proj.weight, 'xavier_uniform_')
|
| 1409 |
+
_init_tensor(module.out_proj.weight, 'xavier_uniform_')
|
| 1410 |
+
_init_tensor(module.q_proj.bias, 'zeros_')
|
| 1411 |
+
_init_tensor(module.k_proj.bias, 'zeros_')
|
| 1412 |
+
_init_tensor(module.v_proj.bias, 'zeros_')
|
| 1413 |
+
_init_tensor(module.out_proj.bias, 'zeros_')
|
| 1414 |
elif isinstance(module, PaddleOCRMLP):
|
| 1415 |
+
_init_tensor(module.fc1.weight, 'xavier_uniform_')
|
| 1416 |
+
_init_tensor(module.fc2.weight, 'xavier_uniform_')
|
| 1417 |
+
_init_tensor(module.fc1.bias, 'normal_', std=1e-6)
|
| 1418 |
+
_init_tensor(module.fc2.bias, 'normal_', std=1e-6)
|
| 1419 |
elif isinstance(module, PaddleOCRMultiheadAttentionPoolingHead):
|
| 1420 |
+
_init_tensor(module.probe, 'xavier_uniform_')
|
| 1421 |
+
_init_tensor(module.attention.in_proj_weight, 'xavier_uniform_')
|
| 1422 |
+
_init_tensor(module.attention.in_proj_bias, 'zeros_')
|
| 1423 |
elif isinstance(module, (nn.Linear, nn.Conv2d)):
|
| 1424 |
lecun_normal_(module.weight)
|
| 1425 |
if module.bias is not None:
|
| 1426 |
+
_init_tensor(module.bias, 'zeros_')
|
| 1427 |
elif isinstance(module, nn.LayerNorm):
|
| 1428 |
+
_init_tensor(module.bias, 'zeros_')
|
| 1429 |
+
_init_tensor(module.weight, 'ones_')
|
| 1430 |
|
| 1431 |
|
| 1432 |
# Copied from transformers.models.altclip.modeling_altclip.AltCLIPEncoder with AltCLIP->PaddleOCR
|
|
|
|
| 1991 |
|
| 1992 |
|
| 1993 |
class PaddleOCRVLForConditionalGeneration(Ernie4_5PreTrainedModel, GenerationMixin):
|
| 1994 |
+
_tied_weights_keys = {"lm_head.weight": "model.embed_tokens.weight"}
|
| 1995 |
config_class = PaddleOCRVLConfig
|
| 1996 |
_no_split_modules = ["Ernie4_5_DecoderLayer", "PaddleOCREncoderLayer"]
|
| 1997 |
|
|
|
|
| 2467 |
|
| 2468 |
model_inputs["position_ids"] = None
|
| 2469 |
|
| 2470 |
+
# v5 creates cache_position inside the parent method, rather than
|
| 2471 |
+
# passing it to this override. Read the prepared value back first.
|
| 2472 |
+
cache_position = model_inputs.get("cache_position", cache_position)
|
| 2473 |
+
if cache_position is None:
|
| 2474 |
+
past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
|
| 2475 |
+
prepared = model_inputs.get("inputs_embeds")
|
| 2476 |
+
if prepared is None:
|
| 2477 |
+
prepared = model_inputs["input_ids"]
|
| 2478 |
+
cache_position = torch.arange(
|
| 2479 |
+
past_seen_tokens, past_seen_tokens + prepared.shape[1], device=prepared.device
|
| 2480 |
+
)
|
| 2481 |
+
model_inputs["cache_position"] = cache_position
|
| 2482 |
+
|
| 2483 |
+
# Without KV caching, every forward still consumes the image tokens.
|
| 2484 |
+
if use_cache and past_key_values is not None and past_key_values.get_seq_length() > 0:
|
| 2485 |
model_inputs["pixel_values"] = None
|
| 2486 |
model_inputs["pixel_values_videos"] = None
|
| 2487 |
|