diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000000000000000000000000000000000..21f378f151132686840b38a4d6b4a2210b7e5b0a --- /dev/null +++ b/.gitattributes @@ -0,0 +1,50 @@ +*.7z filter=lfs diff=lfs merge=lfs -text +*.arrow filter=lfs diff=lfs merge=lfs -text +*.bin filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.ckpt filter=lfs diff=lfs merge=lfs -text +*.ftz filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.h5 filter=lfs diff=lfs merge=lfs -text +*.joblib filter=lfs diff=lfs merge=lfs -text +*.lfs.* filter=lfs diff=lfs merge=lfs -text +*.mlmodel filter=lfs diff=lfs merge=lfs -text +*.model filter=lfs diff=lfs merge=lfs -text +*.msgpack filter=lfs diff=lfs merge=lfs -text +*.npy filter=lfs diff=lfs merge=lfs -text +*.npz filter=lfs diff=lfs merge=lfs -text +*.onnx filter=lfs diff=lfs merge=lfs -text +*.ot filter=lfs diff=lfs merge=lfs -text +*.parquet filter=lfs diff=lfs merge=lfs -text +*.pb filter=lfs diff=lfs merge=lfs -text +*.pickle filter=lfs diff=lfs merge=lfs -text +*.pkl filter=lfs diff=lfs merge=lfs -text +*.pt filter=lfs diff=lfs merge=lfs -text +*.pth filter=lfs diff=lfs merge=lfs -text +*.rar filter=lfs diff=lfs merge=lfs -text +*.safetensors filter=lfs diff=lfs merge=lfs -text +saved_model/**/* filter=lfs diff=lfs merge=lfs -text +*.tar.* filter=lfs diff=lfs merge=lfs -text +*.tar filter=lfs diff=lfs merge=lfs -text +*.tflite filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.wasm filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text +*tfevents* filter=lfs diff=lfs merge=lfs -text +*.axmodel filter=lfs diff=lfs merge=lfs -text +main_api_ax650 filter=lfs diff=lfs merge=lfs -text +main_api_axcl_x86 filter=lfs diff=lfs merge=lfs -text +main_ax650 filter=lfs diff=lfs merge=lfs -text +main_axcl_x86 filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.jpg filter=lfs diff=lfs merge=lfs -text +*.mp4 filter=lfs diff=lfs merge=lfs -text +internvl3-5_tokenizer/tokenizer.json filter=lfs diff=lfs merge=lfs -text +main filter=lfs diff=lfs merge=lfs -text +main_api filter=lfs diff=lfs merge=lfs -text +main_api_ax620e filter=lfs diff=lfs merge=lfs -text +main_ax620e filter=lfs diff=lfs merge=lfs -text +tokenizer.json filter=lfs diff=lfs merge=lfs -text +*.JPG filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..a81a3af42dd34a4e044e743e904abc4c521e8cf0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +__pycache__ +*tmp/ + diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c533fc8777cb64eb0d25de18a1b098746c572728 --- /dev/null +++ b/README.md @@ -0,0 +1,160 @@ +--- +library_name: transformers +license: bsd-3-clause +base_model: +- PaddlePaddle/PaddleOCR-VL-1.5 +tags: +- PaddleOCR-VL-1.5 +- OCR +language: +- zh +- en +--- + +# PaddleOCR-VL-1.5.axera + +> Inference and model-conversion example project for PaddleOCR-VL-1.5 on Axera NPUs. + +- Python inference is currently supported. C++ examples are under development. +- Prebuilt model files are available on [HuggingFace](https://huggingface.co/AXERA-TECH/PaddleOCR-VL-1.5). +- If you want to export/convert models by yourself, refer to the [model conversion guide](https://github.com/AXERA-TECH/PaddleOCR-VL-1.5.axera/tree/main/model_convert). + +## Supported Platforms + +- [x] AX650N +- [ ] AX620E + +## End-to-End Metrics + +| Metric | Value | +| -- | -- | +| Max TTFT (640 tokens) | 361.8 ms | +| Decode speed | 44.6 tokens/s | +| ViT latency (576x768) | 1678.9 ms | + +## Repository Layout + +```bash +. +├── assets +│ ├── IMG_0059.JPG +│ ├── IMG_0462.JPG +│ ├── IMG_0675.JPG +│ └── gradio_demo.png +├── gradio_demo.py +├── infer_axmodel.py +├── infer_torch.py +├── paddleocr_vl_1-5_ax650n_axmodel/ +├── paddleocr_vl_1-5_tokenizer/ +├── utils/ +├── vit_models/ +└── README.md +``` + +## Quick Start + +### Clone the repository + +```bash +git clone https://huggingface.co/AXERA-TECH/PaddleOCR-VL-1.5 +cd PaddleOCR-VL-1.5 +``` + +### 1. PyTorch Reference Inference + +Run: + +```bash +python3 infer_torch.py +``` + +Note: `infer_torch.py` uses hardcoded `model_path` and `image_path`. Adjust them in the script before running if needed. + +### 2. AxModel Inference + +Run from the project root: + +```bash +python3 infer_axmodel.py \ + --hf_model ./paddleocr_vl_1-5_tokenizer \ + --axmodel_path ./paddleocr_vl_1-5_ax650n_axmodel \ + --vit_model_path ./vit_models/vit_576x768.axmodel \ + --image_path ./assets/IMG_0462.JPG \ + --task ocr +``` + +Available values for `--task`: + +- `ocr` +- `table` +- `chart` +- `formula` +- `spotting` +- `seal` + +If you have an exported ONNX VIT model, pass it through `--vit_model_path` (instead of `.axmodel`), for example: + +```bash +python3 infer_axmodel.py \ + --hf_model ./paddleocr_vl_1-5_tokenizer \ + --axmodel_path ./paddleocr_vl_1-5_ax650n_axmodel \ + --vit_model_path /path/to/paddle_ocr_vl_vit_model.onnx \ + --image_path ./assets/IMG_0462.JPG \ + --task ocr +``` + +Test image for OCR: + +test-img + +Sample output: + +```text +Init InferenceSession: 100%|██████████████████████████████████████████████████████████| 18/18 [00:00<00:00, 33.44it/s] +[INFO] Using provider: AxEngineExecutionProvider +[INFO] Model type: 2 (triple core) +[INFO] Compiler version: 5.1-patch1 47548354 +Model loaded successfully! +slice_indices: [0, 1, 2, 3, 4] +Slice prefill done: 0 +Slice prefill done: 1 +Slice prefill done: 2 +Slice prefill done: 3 +Slice prefill done: 4 +answer >> James Landay-VR +14175 +``` + +### 3. Gradio Interactive Demo + +```bash +python3 gradio_demo.py \ + --hf_model ./paddleocr_vl_1-5_tokenizer \ + --axmodel_path ./paddleocr_vl_1-5_ax650n_axmodel \ + --vit_model ./vit_models/vit_576x768.axmodel +``` + +Demo preview: + +![gradio_demo](./assets/gradio_demo.png) + +## Theoretical Inference Latency (AX650N) + +### Subgraph Latency + +| Stage | Subgraph | Latency | +| -- | -- | -- | +| Prefill | g1 | 2.551 ms | +| Prefill | g2 | 2.883 ms | +| Prefill | g3 | 3.158 ms | +| Prefill | g4 | 3.413 ms | +| Prefill | g5 | 3.795 ms | +| Prefill | g6 | 4.007 ms | +| Decode | g0 | 0.949 ms | +| Post-process | - | 5.313 ms | +| ViT | - | 1678.900 ms | + +## Discussion + +- GitHub Issues +- QQ Group: `139953715` diff --git a/assets/IMG_0059.JPG b/assets/IMG_0059.JPG new file mode 100644 index 0000000000000000000000000000000000000000..93fcba02a2229befe23f1c3aa58057f0e290674d --- /dev/null +++ b/assets/IMG_0059.JPG @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49145013a3912af4fcd717454271b8ce77742fd827501a8ae13a9dab3a41cc48 +size 154781 diff --git a/assets/IMG_0462.JPG b/assets/IMG_0462.JPG new file mode 100644 index 0000000000000000000000000000000000000000..19299abb1b338db8774b41ba0c3f9c34d17bbe95 --- /dev/null +++ b/assets/IMG_0462.JPG @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:40972d965a131d785d1d2159a98b2575f7381be644547f950856a205be6434ee +size 156011 diff --git a/assets/IMG_0675.JPG b/assets/IMG_0675.JPG new file mode 100644 index 0000000000000000000000000000000000000000..e6e14e280ce7b1422e3e700cc51def9c5c26e0bf --- /dev/null +++ b/assets/IMG_0675.JPG @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f24570355f178d2a8226112d1443d735837e59573545cfff12458dd791ae341 +size 308158 diff --git a/assets/gradio_demo.png b/assets/gradio_demo.png new file mode 100644 index 0000000000000000000000000000000000000000..2a5d0432cf91f81204206a9746633159accf7e22 --- /dev/null +++ b/assets/gradio_demo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3bf261a1a60e425eae0c34cb54fd99b67e1fe5e391938862c28a3604ca12df1b +size 1125521 diff --git a/config.json b/config.json new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/gradio_demo.py b/gradio_demo.py new file mode 100644 index 0000000000000000000000000000000000000000..70c94ec44bbcb799e072787dd26254264411a4d9 --- /dev/null +++ b/gradio_demo.py @@ -0,0 +1,500 @@ +import argparse +import os +import socket +import time +from typing import Generator, List, Optional, Tuple + +import gradio as gr +import numpy as np +from ml_dtypes import bfloat16 +from PIL import Image +from transformers import AutoConfig, AutoProcessor, AutoTokenizer + +from axengine import InferenceSession +from utils.infer_func import InferManager +from utils.vision_output import describe_output_shapes, select_vit_output + +try: + import onnxruntime as ort +except Exception: + ort = None + + +TASK_PROMPTS = { + "ocr": "OCR:", + "table": "Table Recognition:", + "formula": "Formula Recognition:", + "chart": "Chart Recognition:", + "spotting": "Spotting:", + "seal": "Seal Recognition:", +} + + +def _list_host_ips() -> List[str]: + ips = set() + try: + hostname = socket.gethostname() + infos = socket.getaddrinfo(hostname, None, family=socket.AF_INET) + for info in infos: + ip = info[4][0] + if ip and not ip.startswith("127."): + ips.add(ip) + except Exception: + pass + if not ips: + ips.add("127.0.0.1") + return sorted(ips) + + +def _prepare_image(image: Image.Image, task: str) -> Tuple[Image.Image, int]: + image = image.convert("RGB") + resize_h, resize_w = 576, 768 + image = image.resize((resize_w, resize_h)) + + # AX vision model is compiled with fixed 576x768 token layout. + # Keep spotting path aligned to avoid variable token counts. + max_pixels = 2048 * 28 * 28 if task == "spotting" else 1280 * 28 * 28 + return image, max_pixels + + +def _run_vit_onnx( + session, pixel_values: np.ndarray, target_hidden_size: int, expected_tokens: Optional[int] = None +) -> Tuple[np.ndarray, List[Tuple[int, ...]]]: + outputs = session.run(None, {"pixel_values": pixel_values}) + return ( + select_vit_output(outputs, target_hidden_size, expected_tokens=expected_tokens), + describe_output_shapes(outputs), + ) + + +def _run_vit_axmodel( + session, pixel_values: np.ndarray, target_hidden_size: int, expected_tokens: Optional[int] = None +) -> Tuple[np.ndarray, List[Tuple[int, ...]]]: + outputs = session.run(None, {"pixel_values": pixel_values}) + return ( + select_vit_output(outputs, target_hidden_size, expected_tokens=expected_tokens), + describe_output_shapes(outputs), + ) + + +def _expected_image_features(image_grid_thw) -> int: + return int(sum(int(t) * int(h) * int(w) for t, h, w in image_grid_thw)) + + +def _expected_image_tokens(image_grid_thw, merge_size: int) -> int: + merge_area = int(merge_size) * int(merge_size) + return int(sum(int(t) * int(h) * int(w) // merge_area for t, h, w in image_grid_thw)) + + +def _replace_image_tokens( + token_ids: List[int], token_embeds: np.ndarray, image_embeds: np.ndarray, image_token_id: int +) -> np.ndarray: + image_positions = [idx for idx, token_id in enumerate(token_ids) if token_id == image_token_id] + if not image_positions: + return token_embeds + + flat_image_embeds = image_embeds.reshape(-1, image_embeds.shape[-1]) + if len(image_positions) != flat_image_embeds.shape[0]: + raise ValueError( + f"Image tokens and image features do not match: tokens={len(image_positions)}, " + f"features={flat_image_embeds.shape[0]}" + ) + if token_embeds.shape[-1] != flat_image_embeds.shape[-1]: + raise ValueError( + f"Embedding dim mismatch: token_dim={token_embeds.shape[-1]}, image_dim={flat_image_embeds.shape[-1]}" + ) + token_embeds[image_positions, :] = flat_image_embeds + return token_embeds + + +class PaddleOCRVLGradioDemo: + def __init__(self, hf_model: str, axmodel_dir: str, vit_model: str, max_seq_len: int = 2047): + self.hf_model = hf_model + self.axmodel_dir = axmodel_dir + self.vit_model = vit_model + + self.embeds = np.load(os.path.join(axmodel_dir, "model.embed_tokens.weight.npy")) + self.tokenizer = AutoTokenizer.from_pretrained(self.hf_model, trust_remote_code=True) + self.processor = AutoProcessor.from_pretrained(self.hf_model, trust_remote_code=True) + self.config = AutoConfig.from_pretrained(self.hf_model, trust_remote_code=True) + + self.merge_size = self.config.vision_config.spatial_merge_size + + if self.vit_model.endswith(".axmodel"): + self.vit_session = InferenceSession(self.vit_model) + self.vit_mode = "axmodel" + else: + if ort is None: + raise ImportError("onnxruntime is required when --vit_model is an onnx file") + providers = ["CPUExecutionProvider"] + if "CUDAExecutionProvider" in ort.get_available_providers(): + providers = ["CUDAExecutionProvider", "CPUExecutionProvider"] + self.vit_session = ort.InferenceSession(self.vit_model, providers=providers) + self.vit_mode = "onnx" + + self.infer_manager = InferManager(self.config, self.axmodel_dir, max_seq_len=max_seq_len) + + def _build_prompt_inputs(self, image: Image.Image, task: str, user_text: str): + image, max_pixels = _prepare_image(image, task) + prompt_text = user_text.strip() if user_text.strip() else TASK_PROMPTS[task] + messages = [ + { + "role": "user", + "content": [ + {"type": "image", "image": image}, + {"type": "text", "text": prompt_text}, + ], + } + ] + inputs = self.processor.apply_chat_template( + messages, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + return_tensors="pt", + images_kwargs={ + "size": { + "shortest_edge": self.processor.image_processor.min_pixels, + "longest_edge": max_pixels, + } + }, + ) + return prompt_text, inputs + + def _prepare_model_inputs(self, inputs): + token_ids = inputs.input_ids[0].cpu().numpy().tolist() + image_grid_thw = inputs.image_grid_thw.cpu().numpy().tolist() + expected_tokens = _expected_image_tokens(image_grid_thw, self.merge_size) + expected_features = _expected_image_features(image_grid_thw) + + pixel_values = inputs.pixel_values + if pixel_values.ndim == 4: + pixel_values = pixel_values.unsqueeze(0) + pixel_values = pixel_values.cpu().numpy().astype(np.float32) + + if self.vit_mode == "axmodel": + image_embeds, vit_output_shapes = _run_vit_axmodel( + self.vit_session, + pixel_values, + target_hidden_size=self.config.hidden_size, + expected_tokens=expected_tokens, + ) + else: + image_embeds, vit_output_shapes = _run_vit_onnx( + self.vit_session, + pixel_values, + target_hidden_size=self.config.hidden_size, + expected_tokens=expected_tokens, + ) + + if image_embeds.ndim == 3: + image_embeds = image_embeds[0] + image_seq_len = image_embeds.shape[0] + + if image_seq_len != expected_tokens: + if image_seq_len == expected_features: + raise ValueError( + "Vision output is pre-projector features. " + f"got={image_seq_len}, expected_projected_tokens={expected_tokens}. " + "Please re-export VIT ONNX with projector included (model_convert/export_onnx.py), " + f"then re-compile to .axmodel. vit_output_shapes={vit_output_shapes}" + ) + raise ValueError( + "Unexpected image feature length. " + f"got={image_seq_len}, expected_projected_tokens={expected_tokens}, " + f"expected_pre_projector_features={expected_features}, vit_output_shapes={vit_output_shapes}" + ) + projected_embeds = image_embeds + + prefill_data = np.take(self.embeds, token_ids, axis=0) + prefill_data = _replace_image_tokens( + token_ids, + prefill_data, + projected_embeds, + image_token_id=self.config.image_token_id, + ) + prefill_data = prefill_data.astype(bfloat16) + return token_ids, prefill_data + + def _stream_generate(self, token_ids: List[int], prefill_data: np.ndarray, max_new_tokens: int = 1024): + for k_cache in self.infer_manager.k_caches: + k_cache.fill(0) + for v_cache in self.infer_manager.v_caches: + v_cache.fill(0) + + eos_token_id = None + if isinstance(self.config.eos_token_id, list) and len(self.config.eos_token_id) > 1: + eos_token_id = self.config.eos_token_id + + slice_len = 128 + t_start = time.time() + token_ids = self.infer_manager.prefill(self.tokenizer, token_ids, prefill_data, slice_len=slice_len) + + mask = np.zeros((1, 1, self.infer_manager.max_seq_len + 1), dtype=np.float32).astype(bfloat16) + mask[:, :, :self.infer_manager.max_seq_len] -= 65536 + seq_len = len(token_ids) - 1 + if slice_len > 0: + mask[:, :, :seq_len] = 0 + + ttft_ms: Optional[float] = (time.time() - t_start) * 1000 + decode_tokens = 0 + decode_elapsed_ms: float = 0.0 + generated_text = self.tokenizer.decode(token_ids[seq_len:], skip_special_tokens=True) + yield generated_text, ttft_ms, None, 1, False + + remaining_decode_budget = max(0, int(max_new_tokens) - 1) + for step_idx in range(self.infer_manager.max_seq_len): + if remaining_decode_budget <= 0: + break + if slice_len > 0 and step_idx < seq_len: + continue + + cur_token = token_ids[step_idx] + indices = np.array([step_idx], np.uint32).reshape((1, 1)) + data = self.embeds[cur_token, :].reshape((1, 1, self.config.hidden_size)).astype(bfloat16) + + for layer_idx in range(self.config.num_hidden_layers): + input_feed = { + "K_cache": self.infer_manager.k_caches[layer_idx], + "V_cache": self.infer_manager.v_caches[layer_idx], + "indices": indices, + "input": data, + "mask": mask, + } + outputs = self.infer_manager.decoder_sessions[layer_idx].run(None, input_feed, shape_group=0) + self.infer_manager.k_caches[layer_idx][:, step_idx, :] = outputs[0][:, :, :] + self.infer_manager.v_caches[layer_idx][:, step_idx, :] = outputs[1][:, :, :] + data = outputs[2] + + mask[..., step_idx] = 0 + if step_idx < seq_len - 1: + continue + + post_out = self.infer_manager.post_process_session.run(None, {"input": data})[0] + next_token, _, _ = self.infer_manager.post_process(post_out, temperature=0.7) + + if eos_token_id is not None and next_token in eos_token_id: + break + if next_token == self.tokenizer.eos_token_id: + break + + token_ids.append(next_token) + remaining_decode_budget -= 1 + + generated_text = self.tokenizer.decode(token_ids[seq_len:], skip_special_tokens=True) + decode_tokens += 1 + decode_elapsed_ms = (time.time() - t_start) * 1000 - ttft_ms + avg_decode = decode_elapsed_ms / decode_tokens if decode_tokens > 0 else None + total_tokens = 1 + decode_tokens + yield generated_text, ttft_ms, avg_decode, total_tokens, False + + avg_decode = decode_elapsed_ms / decode_tokens if decode_tokens > 0 else None + total_tokens = 1 + decode_tokens + yield generated_text, ttft_ms, avg_decode, total_tokens, True + + def chat(self, user_input: str, image: Optional[Image.Image], task: str) -> Generator: + if image is None: + err = "请先上传图片,再执行识别。" + metrics = ( + "
" + "需要输入图像" + "
" + ) + yield [("输入", err)], gr.update(value=""), gr.update(), gr.update(value=metrics), gr.update(interactive=True) + return + + yield ( + [("处理中", "模型准备中…")], + gr.update(value=""), + gr.update(), + gr.update( + value="
" + "TTFT -- ms  |  Decode -- ms/token  |  Tokens --
" + ), + gr.update(interactive=False), + ) + + try: + prompt_text, inputs = self._build_prompt_inputs(image, task, user_input or "") + token_ids, prefill_data = self._prepare_model_inputs(inputs) + except Exception as exc: + err = f"输入处理失败: {exc}" + metrics = ( + "
" + "预处理失败" + "
" + ) + yield [(prompt_text if "prompt_text" in locals() else "输入", err)], gr.update(value=""), gr.update(), gr.update(value=metrics), gr.update(interactive=True) + return + + chatbot_history = [(prompt_text, "")] + for partial, ttft_ms, avg_decode_ms, total_tokens, finished in self._stream_generate( + token_ids, prefill_data, max_new_tokens=1024 + ): + chatbot_history[-1] = (prompt_text, partial) + ttft_disp = f"{ttft_ms:.0f}" if ttft_ms is not None else "--" + decode_disp = f"{avg_decode_ms:.1f}" if avg_decode_ms is not None else "--" + tok_disp = f"{total_tokens}" if total_tokens is not None else "--" + metrics_text = ( + "
" + f"TTFT {ttft_disp} ms  |  Decode {decode_disp} ms/token  |  Tokens {tok_disp}" + "
" + ) + if finished: + yield chatbot_history, gr.update(value=""), gr.update(), gr.update(value=metrics_text), gr.update(interactive=True) + else: + yield chatbot_history, gr.update(value=""), gr.update(), gr.update(value=metrics_text), gr.update(interactive=False) + + @staticmethod + def build_ui(demo: "PaddleOCRVLGradioDemo", server_name: str = "0.0.0.0", server_port: int = 7860, share: bool = False): + custom_js = """ + function() { + setTimeout(() => { + const textareas = document.querySelectorAll('#user-input textarea'); + textareas.forEach(textarea => { + textarea.removeEventListener('keydown', textarea._customKeyHandler); + textarea._customKeyHandler = function(e) { + if (e.key === 'Enter') { + if (e.shiftKey) { + e.preventDefault(); + const start = this.selectionStart; + const end = this.selectionEnd; + const value = this.value; + this.value = value.substring(0, start) + '\\n' + value.substring(end); + this.selectionStart = this.selectionEnd = start + 1; + this.dispatchEvent(new Event('input', { bubbles: true })); + } else { + e.preventDefault(); + const sendBtn = document.querySelector('#send-btn'); + if (sendBtn) { + sendBtn.click(); + } + } + } + }; + textarea.addEventListener('keydown', textarea._customKeyHandler); + }); + }, 500); + } + """ + + with gr.Blocks(title="PaddleOCR-VL-1.5 AX Gradio Demo", theme=gr.themes.Soft(), js=custom_js) as iface: + gr.HTML( + """""" + ) + gr.Markdown("### PaddleOCR-VL-1.5 图文识别演示\n上传图片,选择任务后执行识别。") + + with gr.Row(): + with gr.Column(scale=5): + with gr.Group(elem_id="chat-wrap"): + chatbot = gr.Chatbot(height=500, label="结果") + metrics_md = gr.Markdown( + "
" + "TTFT -- ms  |  Decode -- ms/token  |  Tokens --
", + elem_id="metrics-display", + ) + + with gr.Row(): + user_input = gr.Textbox( + placeholder="可选:输入自定义提示词;留空将使用任务默认提示", + lines=2, + scale=7, + max_lines=5, + show_label=False, + elem_id="user-input", + ) + with gr.Column(scale=1, min_width=100): + send_btn = gr.Button("发送", variant="primary", size="sm", elem_id="send-btn") + clear_btn = gr.Button("清空对话", variant="secondary", size="sm") + + with gr.Column(scale=3): + image_input = gr.Image( + type="pil", + label="上传图片", + height=380, + image_mode="RGB", + show_download_button=False, + elem_id="image-pane", + ) + task_input = gr.Dropdown( + choices=["ocr", "table", "chart", "formula", "spotting", "seal"], + value="ocr", + label="任务类型", + ) + gr.Markdown( + "- 支持单张图像推理\n" + "- 默认提示会根据任务自动设置\n" + "- 识别耗时受硬件和图像分辨率影响" + ) + + def _clear(): + return ( + [], + gr.update(value=""), + gr.update(), + gr.update( + value="
" + "TTFT -- ms  |  Decode -- ms/token  |  Tokens --
" + ), + gr.update(interactive=True), + ) + + send_btn.click( + fn=demo.chat, + inputs=[user_input, image_input, task_input], + outputs=[chatbot, user_input, image_input, metrics_md, send_btn], + show_progress=False, + queue=True, + ) + clear_btn.click(fn=_clear, inputs=None, outputs=[chatbot, user_input, image_input, metrics_md, send_btn]) + + target_port = server_port or 7860 + host_candidates: List[str] = [] + if server_name: + host_candidates.append(server_name) + host_candidates.extend(_list_host_ips()) + printed = set() + print("可访问地址 (请任选其一):") + for ip in host_candidates: + if ip and ip not in printed: + printed.add(ip) + print(f" http://{ip}:{target_port}") + + iface.queue().launch(server_name=server_name, server_port=server_port, share=share) + + +def parse_args(): + parser = argparse.ArgumentParser(description="PaddleOCR-VL-1.5 AX gradio demo") + parser.add_argument("--hf_model", type=str, default="./PaddleOCR-VL-1.5", help="HuggingFace 模型路径") + parser.add_argument("--axmodel_path", type=str, default="./PaddleOCR-VL-1.5_axmodel", help="LLM axmodel 目录") + parser.add_argument( + "--vit_model", + type=str, + default="./vit_models/vit_576x768.axmodel", + help="VIT 模型路径(支持 .axmodel 或 .onnx,且输出需为 projector 后的 merge token)", + ) + parser.add_argument("--port", type=int, default=7860, help="Gradio 端口") + parser.add_argument("--host", type=str, default="0.0.0.0", help="Gradio 监听地址") + parser.add_argument("--share", action="store_true", help="启用 gradio share") + return parser.parse_args() + + +def main(): + args = parse_args() + demo = PaddleOCRVLGradioDemo(args.hf_model, args.axmodel_path, args.vit_model) + PaddleOCRVLGradioDemo.build_ui(demo, server_name=args.host, server_port=args.port, share=args.share) + + +if __name__ == "__main__": + """ + python3 gradio_demo.py \ + --hf_model ./PaddleOCR-VL-1.5 \ + --axmodel_path ./PaddleOCR-VL-1.5_axmodel \ + --vit_model ./vit_models/vit_576x768.axmodel + """ + main() diff --git a/infer_axmodel.py b/infer_axmodel.py new file mode 100644 index 0000000000000000000000000000000000000000..c1b51f0847a6fff80dc9620ffa349100220e8f94 --- /dev/null +++ b/infer_axmodel.py @@ -0,0 +1,203 @@ +from transformers import AutoProcessor, AutoTokenizer, AutoConfig +import onnxruntime as ort +import numpy as np +import os +from ml_dtypes import bfloat16 +from utils.infer_func import InferManager +from utils.vision_output import describe_output_shapes, select_vit_output +import argparse +from PIL import Image + + +def _prepare_image(image_path, task): + + image = Image.open(image_path).convert("RGB") + + resize_h, resize_w = 576, 768 + image = image.resize((resize_w, resize_h)) + + # AX vision model is compiled with fixed 576x768 token layout. + # Keep spotting path aligned to avoid variable token counts. + max_pixels = 2048 * 28 * 28 if task == "spotting" else 1280 * 28 * 28 + return image, max_pixels + + +def _run_vit_onnx(session, pixel_values, target_hidden_size, expected_tokens=None): + outputs = session.run(None, {"pixel_values": pixel_values}) + return ( + select_vit_output(outputs, target_hidden_size, expected_tokens=expected_tokens), + describe_output_shapes(outputs), + ) + + +def _run_vit_axmodel(session, pixel_values, target_hidden_size, expected_tokens=None): + outputs = session.run(None, {"pixel_values": pixel_values}) + return ( + select_vit_output(outputs, target_hidden_size, expected_tokens=expected_tokens), + describe_output_shapes(outputs), + ) + + +def _expected_image_tokens(image_grid_thw, merge_size): + merge_area = int(merge_size) * int(merge_size) + return int(sum(int(t) * int(h) * int(w) // merge_area for t, h, w in image_grid_thw)) + + +def _replace_image_tokens(token_ids, token_embeds, image_embeds, image_token_id): + image_positions = [idx for idx, token_id in enumerate(token_ids) if token_id == image_token_id] + if not image_positions: + return token_embeds + + flat_image_embeds = image_embeds.reshape(-1, image_embeds.shape[-1]) + if len(image_positions) != flat_image_embeds.shape[0]: + raise ValueError( + f"Image tokens and image features do not match: tokens={len(image_positions)}, features={flat_image_embeds.shape[0]}" + ) + if token_embeds.shape[-1] != flat_image_embeds.shape[-1]: + raise ValueError( + f"Embedding dim mismatch: token_dim={token_embeds.shape[-1]}, image_dim={flat_image_embeds.shape[-1]}" + ) + token_embeds[image_positions, :] = flat_image_embeds + return token_embeds + + +if __name__ == "__main__": + + """ + python3 infer_axmodel.py \ + --hf_model ./PaddleOCR-VL-1.5 \ + --axmodel_path ./PaddleOCR-VL-1.5_axmodel \ + --vit_model_path ./vit_models/vit_576x768.axmodel \ + --image_path ../assets/IMG_0462.JPG \ + --task ocr + """ + parser = argparse.ArgumentParser(description="PaddleOCR-VL-1.5 axmodel inference") + parser.add_argument("--hf_model", type=str, default="./PaddleOCR-VL-1.5", + help="Path to HuggingFace model") + parser.add_argument("--axmodel_path", type=str, default="./PaddleOCR-VL-1.5_axmodel", + help="Path to compiled axmodel folder") + parser.add_argument("--vit_model_path", type=str, + default="./vit_models/vit_576x768.axmodel", + help="Path to PaddleOCR-VL vision ONNX model or .axmodel") + parser.add_argument("--image_path", type=str, default="../assets/IMG_0462.JPG", + help="Input image path") + parser.add_argument("--task", type=str, default="ocr", + choices=["ocr", "table", "chart", "formula", "spotting", "seal"], + help="Task type") + args = parser.parse_args() + + hf_model_path = args.hf_model + axmodel_path = args.axmodel_path + + embeds = np.load(os.path.join(axmodel_path, "model.embed_tokens.weight.npy")) + + tokenizer = AutoTokenizer.from_pretrained(hf_model_path, trust_remote_code=True) + processor = AutoProcessor.from_pretrained(hf_model_path, trust_remote_code=True) + config = AutoConfig.from_pretrained(hf_model_path, trust_remote_code=True) + + image, max_pixels = _prepare_image(args.image_path, args.task) + prompts = { + "ocr": "OCR:", + "table": "Table Recognition:", + "formula": "Formula Recognition:", + "chart": "Chart Recognition:", + "spotting": "Spotting:", + "seal": "Seal Recognition:", + } + + messages = [ + { + "role": "user", + "content": [ + {"type": "image", "image": image}, + {"type": "text", "text": prompts[args.task]}, + ], + } + ] + inputs = processor.apply_chat_template( + messages, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + return_tensors="pt", + images_kwargs={ + "size": { + "shortest_edge": processor.image_processor.min_pixels, + "longest_edge": max_pixels, + } + }, + ) + + token_ids = inputs.input_ids[0].cpu().numpy().tolist() + image_grid_thw = inputs.image_grid_thw.cpu().numpy().tolist() + merge_size = config.vision_config.spatial_merge_size + expected_tokens = _expected_image_tokens(image_grid_thw, merge_size) + + pixel_values = inputs.pixel_values + if pixel_values.ndim == 4: + pixel_values = pixel_values.unsqueeze(0) + pixel_values = pixel_values.cpu().numpy().astype(np.float32) + + if args.vit_model_path.endswith(".axmodel"): + try: + from axengine import InferenceSession + except Exception as exc: + raise ImportError("axengine is required for .axmodel inference") from exc + vit_session = InferenceSession(args.vit_model_path) + image_embeds, vit_output_shapes = _run_vit_axmodel( + vit_session, + pixel_values, + target_hidden_size=config.hidden_size, + expected_tokens=expected_tokens, + ) + else: + providers = ["CPUExecutionProvider"] + if "CUDAExecutionProvider" in ort.get_available_providers(): + providers = ["CUDAExecutionProvider", "CPUExecutionProvider"] + vit_session = ort.InferenceSession(args.vit_model_path, providers=providers) + image_embeds, vit_output_shapes = _run_vit_onnx( + vit_session, + pixel_values, + target_hidden_size=config.hidden_size, + expected_tokens=expected_tokens, + ) + + if image_embeds.ndim == 3: + image_embeds = image_embeds[0] + image_seq_len = image_embeds.shape[0] + if image_seq_len != expected_tokens: + expected_features = int(sum(int(t) * int(h) * int(w) for t, h, w in image_grid_thw)) + if image_seq_len == expected_features: + raise ValueError( + "Vision output is pre-projector features. " + f"got={image_seq_len}, expected_projected_tokens={expected_tokens}. " + "Please re-export VIT ONNX with projector included (model_convert/export_onnx.py), " + f"then re-compile to .axmodel. vit_output_shapes={vit_output_shapes}" + ) + raise ValueError( + "Unexpected image feature length. " + f"got={image_seq_len}, expected_projected_tokens={expected_tokens}, " + f"expected_pre_projector_features={expected_features}, vit_output_shapes={vit_output_shapes}" + ) + projected_embeds = image_embeds + + prefill_data = np.take(embeds, token_ids, axis=0) + prefill_data = _replace_image_tokens( + token_ids, + prefill_data, + projected_embeds, + image_token_id=config.image_token_id, + ) + prefill_data = prefill_data.astype(bfloat16) + + eos_token_id = None + if isinstance(config.eos_token_id, list) and len(config.eos_token_id) > 1: + eos_token_id = config.eos_token_id + + slice_len = 128 + max_seq_len = 2048 - 1 + + imer = InferManager(config, axmodel_path, max_seq_len=max_seq_len) + token_ids = imer.prefill(tokenizer, token_ids, prefill_data, slice_len=slice_len) + imer.decode(tokenizer, token_ids, embeds, slice_len=slice_len, eos_token_id=eos_token_id) + print("\n") diff --git a/infer_torch.py b/infer_torch.py new file mode 100644 index 0000000000000000000000000000000000000000..be0358df28887b101a9f61501eaac24cd612eda7 --- /dev/null +++ b/infer_torch.py @@ -0,0 +1,76 @@ +from PIL import Image +import torch +from transformers import AutoProcessor, AutoModelForImageTextToText + +# ---- Settings ---- +model_path = "./PaddleOCR-VL-1.5" +image_path = "../assets/paddleocr_vl_demo.png" +# image_path = "../assets/IMG_0462.JPG" +task = "ocr" # Options: 'ocr' | 'table' | 'chart' | 'formula' | 'spotting' | 'seal' +# ------------------ + +# ---- Image Preprocessing For Spotting ---- +image = Image.open(image_path).convert("RGB") +orig_w, orig_h = image.size + +# 导出 ONNX 需要固定图像尺寸 +# resize_h, resize_w = 768, 1024 # 1368, 1524 +resize_h, resize_w = 576, 768 # 1368, 1524, 最小尺寸为 336x336 +image = image.resize((resize_w, resize_h)) + +spotting_upscale_threshold = 1500 + +if task == "spotting" and orig_w < spotting_upscale_threshold and orig_h < spotting_upscale_threshold: + process_w, process_h = orig_w * 2, orig_h * 2 + try: + resample_filter = Image.Resampling.LANCZOS + except AttributeError: + resample_filter = Image.LANCZOS + image = image.resize((process_w, process_h), resample_filter) + +# Set max_pixels: use 1605632 for spotting, otherwise use default ~1M pixels +max_pixels = 2048 * 28 * 28 if task == "spotting" else 1280 * 28 * 28 + +# --------------------------- + +# -------- Inference -------- +DEVICE = "cuda" if torch.cuda.is_available() else "cpu" +PROMPTS = { + "ocr": "OCR:", + "table": "Table Recognition:", + "formula": "Formula Recognition:", + "chart": "Chart Recognition:", + "spotting": "Spotting:", + "seal": "Seal Recognition:", +} + +model = AutoModelForImageTextToText.from_pretrained(model_path, torch_dtype=torch.bfloat16).to(DEVICE).eval() +processor = AutoProcessor.from_pretrained(model_path) + +messages = [ + { + "role": "user", + "content": [ + {"type": "image", "image": image}, + {"type": "text", "text": PROMPTS[task]}, + ] + } +] + +inputs = processor.apply_chat_template( + messages, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + return_tensors="pt", + images_kwargs={"size": {"shortest_edge": processor.image_processor.min_pixels, "longest_edge": max_pixels}}, +).to(model.device) + +print("inputs.pixel_values.shape:", inputs.pixel_values.shape) +print("inputs.input_ids.shape:", inputs.input_ids.shape) +print("inputs.image_grid_thw:", inputs.image_grid_thw) + +outputs = model.generate(**inputs, max_new_tokens=1024) +result = processor.decode(outputs[0][inputs["input_ids"].shape[-1]:-1]) +print(result) +# --------------------------- diff --git a/paddleocr_vl_1-5_ax650n_axmodel/model.embed_tokens.weight.bfloat16.bin b/paddleocr_vl_1-5_ax650n_axmodel/model.embed_tokens.weight.bfloat16.bin new file mode 100644 index 0000000000000000000000000000000000000000..f847f0be8f42dc8853b8e5a8089bb7850bfdbe8e --- /dev/null +++ b/paddleocr_vl_1-5_ax650n_axmodel/model.embed_tokens.weight.bfloat16.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:22a82d88a3c44360e7c42d3c3bcee201959f303583603dfe87f0ca956dc98d5c +size 211812352 diff --git a/paddleocr_vl_1-5_ax650n_axmodel/model.embed_tokens.weight.float32.bin b/paddleocr_vl_1-5_ax650n_axmodel/model.embed_tokens.weight.float32.bin new file mode 100644 index 0000000000000000000000000000000000000000..3fd5b50a2f2ec4100d51b8d533bfcc7462587542 --- /dev/null +++ b/paddleocr_vl_1-5_ax650n_axmodel/model.embed_tokens.weight.float32.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a2299447a5449d9bc68e4d1d1ab32b214a0e8c06f98244fbc7487342187ae6f3 +size 423624704 diff --git a/paddleocr_vl_1-5_ax650n_axmodel/model.embed_tokens.weight.npy b/paddleocr_vl_1-5_ax650n_axmodel/model.embed_tokens.weight.npy new file mode 100644 index 0000000000000000000000000000000000000000..4e421d3216942dd69a082289f0d6f9ea3fd43419 --- /dev/null +++ b/paddleocr_vl_1-5_ax650n_axmodel/model.embed_tokens.weight.npy @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bbb214e22f31d0b4b7e1646b6f5551cd80f2eea99db91feabc668052d4aee71c +size 423624832 diff --git a/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l0_together.axmodel b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l0_together.axmodel new file mode 100644 index 0000000000000000000000000000000000000000..f62289bc468fe759707b8f798619f57417fa1ef1 --- /dev/null +++ b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l0_together.axmodel @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:41d9d8080b96b9d0d6969ea3ce0eb274feb39ac0cfc51be01e32adf342280749 +size 20157171 diff --git a/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l10_together.axmodel b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l10_together.axmodel new file mode 100644 index 0000000000000000000000000000000000000000..25d8091cf274405d99e9b67351f6fd49be443cb8 --- /dev/null +++ b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l10_together.axmodel @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:318018d95416db758ef6461343b127d6a7fb710f032197d62c12222334c190f9 +size 20157203 diff --git a/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l11_together.axmodel b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l11_together.axmodel new file mode 100644 index 0000000000000000000000000000000000000000..2f8f10a09a0f9d59339b7b7a3c88b093ba929b5b --- /dev/null +++ b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l11_together.axmodel @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:55aacb7b918186edb284bf1bac204ff2dfbf3b239a107aa250c1be58d7f93aa1 +size 20156979 diff --git a/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l12_together.axmodel b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l12_together.axmodel new file mode 100644 index 0000000000000000000000000000000000000000..f6cd307c2e8be485f6bd5b71bb32fa831b5c1fd7 --- /dev/null +++ b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l12_together.axmodel @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d71a61c9cd06dc267b8c583ffcc66c531e1f6d4dd43c58d6560991577cf954c6 +size 20156979 diff --git a/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l13_together.axmodel b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l13_together.axmodel new file mode 100644 index 0000000000000000000000000000000000000000..f7e94587ee48dfe8446101939c3e23fea23ebc4d --- /dev/null +++ b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l13_together.axmodel @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b5c092176b7f2e04abe9933ba9b73717e936faaafdfc28759206e2d2e7c1331e +size 20156979 diff --git a/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l14_together.axmodel b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l14_together.axmodel new file mode 100644 index 0000000000000000000000000000000000000000..90efe8ae710e36787900c7991d17a6c85e3bc09d --- /dev/null +++ b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l14_together.axmodel @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0098264c1e668ab1b260dff8f0087ae13164dce24e4f6e2f1c1fc3fc7ca85534 +size 20158131 diff --git a/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l15_together.axmodel b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l15_together.axmodel new file mode 100644 index 0000000000000000000000000000000000000000..eeef9c4b5e4abf0c8103e4255a7a9b468e2fe8de --- /dev/null +++ b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l15_together.axmodel @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74630eb86e81984224a22cc4a667bd4ce23a3c59ffdb76a6ba66d8114c8d19cc +size 20158419 diff --git a/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l16_together.axmodel b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l16_together.axmodel new file mode 100644 index 0000000000000000000000000000000000000000..3f3e3a326481e55ced418be733ea83b6530bdd6a --- /dev/null +++ b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l16_together.axmodel @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91ac64c3e9a94e295555715330f9ef3d0c946ed7450916c0fe941084e55bfb51 +size 20158195 diff --git a/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l17_together.axmodel b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l17_together.axmodel new file mode 100644 index 0000000000000000000000000000000000000000..ea52f07cc62c986663d7cef6b5a1d0a2ec8dfbc6 --- /dev/null +++ b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l17_together.axmodel @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c63f3d71ab7c8d5205da682215dcb6f526c8f023b7cf8973a5d557237272cda +size 20157875 diff --git a/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l1_together.axmodel b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l1_together.axmodel new file mode 100644 index 0000000000000000000000000000000000000000..bf4a29575512cf301712050be99c52011cdeafad --- /dev/null +++ b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l1_together.axmodel @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:257625386de3aa6e5d8e61ed6f7d1bf089d969a6b08fd09a9666dae2f13712df +size 20156979 diff --git a/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l2_together.axmodel b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l2_together.axmodel new file mode 100644 index 0000000000000000000000000000000000000000..ee8da8fb1f4970960a038a8ad4d2568762a16485 --- /dev/null +++ b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l2_together.axmodel @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2632ff53e7adc8cc4706d830b67c53176f5e1ba18b33a6accf089f68db5a344f +size 20157747 diff --git a/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l3_together.axmodel b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l3_together.axmodel new file mode 100644 index 0000000000000000000000000000000000000000..4fa5a04532a70e38d7c0a29d51a1a51302af7fc6 --- /dev/null +++ b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l3_together.axmodel @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b05dd1748d14e0b468715f2dc8d15b6615dead019b7f29d01e06a6c73a9f2458 +size 20157139 diff --git a/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l4_together.axmodel b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l4_together.axmodel new file mode 100644 index 0000000000000000000000000000000000000000..0542f6c3e38071a183d3473a77610dd5fec61dcf --- /dev/null +++ b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l4_together.axmodel @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cd197e20b6d8649f4f2a6a9a8d594891ec8807dc1b43164cf5c866db1eed545a +size 20156979 diff --git a/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l5_together.axmodel b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l5_together.axmodel new file mode 100644 index 0000000000000000000000000000000000000000..ad2aef27575b4c1d97ede210a94522b11cf42c8f --- /dev/null +++ b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l5_together.axmodel @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8b235b75499e0670bfb54d24e0edcbe55927940ef3786524d0535fa71419e2b2 +size 20157363 diff --git a/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l6_together.axmodel b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l6_together.axmodel new file mode 100644 index 0000000000000000000000000000000000000000..ca64ea78d2470a83c13bab50cd613756b3efbdbf --- /dev/null +++ b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l6_together.axmodel @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c77329a149b24b7dcab7881fe5c5be0a0248eabb9951a9808ef62fcdcffbf17e +size 20156979 diff --git a/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l7_together.axmodel b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l7_together.axmodel new file mode 100644 index 0000000000000000000000000000000000000000..d2e3413d6a7b4cbfd60acb713d23ed89d6be5fc9 --- /dev/null +++ b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l7_together.axmodel @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d0b7417695611865cbd54ae07ebbc8fd4ca8ca9345cf70c856791ad7acad3ee8 +size 20156979 diff --git a/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l8_together.axmodel b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l8_together.axmodel new file mode 100644 index 0000000000000000000000000000000000000000..802d4f87b4e48fa613f2e841977cfa5840c3a5ec --- /dev/null +++ b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l8_together.axmodel @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ac74a46a1f32ecb360e8e6343895e4faf7cad0b325d99c223b640c933e5aafe +size 20157267 diff --git a/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l9_together.axmodel b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l9_together.axmodel new file mode 100644 index 0000000000000000000000000000000000000000..24abbdff6243be1d326d2759fc785512db9e41d9 --- /dev/null +++ b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_p128_l9_together.axmodel @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:893a1709aa0ac27a2e3f617786514caea31adb4939d4169f89b36b4fb88e9f28 +size 20156979 diff --git a/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_post.axmodel b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_post.axmodel new file mode 100644 index 0000000000000000000000000000000000000000..4ca1c15006bdf0136f56c4623b85e10079818e76 --- /dev/null +++ b/paddleocr_vl_1-5_ax650n_axmodel/paddleocr_vl_post.axmodel @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1eae452e800f49fef67d1a3965aaf181e03e9614b1f7bddf86d1631b20b045f0 +size 115149862 diff --git a/paddleocr_vl_1-5_tokenizer/.gitattributes b/paddleocr_vl_1-5_tokenizer/.gitattributes new file mode 100644 index 0000000000000000000000000000000000000000..52373fe24473b1aa44333d318f578ae6bf04b49b --- /dev/null +++ b/paddleocr_vl_1-5_tokenizer/.gitattributes @@ -0,0 +1,36 @@ +*.7z filter=lfs diff=lfs merge=lfs -text +*.arrow filter=lfs diff=lfs merge=lfs -text +*.bin filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.ckpt filter=lfs diff=lfs merge=lfs -text +*.ftz filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.h5 filter=lfs diff=lfs merge=lfs -text +*.joblib filter=lfs diff=lfs merge=lfs -text +*.lfs.* filter=lfs diff=lfs merge=lfs -text +*.mlmodel filter=lfs diff=lfs merge=lfs -text +*.model filter=lfs diff=lfs merge=lfs -text +*.msgpack filter=lfs diff=lfs merge=lfs -text +*.npy filter=lfs diff=lfs merge=lfs -text +*.npz filter=lfs diff=lfs merge=lfs -text +*.onnx filter=lfs diff=lfs merge=lfs -text +*.ot filter=lfs diff=lfs merge=lfs -text +*.parquet filter=lfs diff=lfs merge=lfs -text +*.pb filter=lfs diff=lfs merge=lfs -text +*.pickle filter=lfs diff=lfs merge=lfs -text +*.pkl filter=lfs diff=lfs merge=lfs -text +*.pt filter=lfs diff=lfs merge=lfs -text +*.pth filter=lfs diff=lfs merge=lfs -text +*.rar filter=lfs diff=lfs merge=lfs -text +*.safetensors filter=lfs diff=lfs merge=lfs -text +saved_model/**/* filter=lfs diff=lfs merge=lfs -text +*.tar.* filter=lfs diff=lfs merge=lfs -text +*.tar filter=lfs diff=lfs merge=lfs -text +*.tflite filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.wasm filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text +*tfevents* filter=lfs diff=lfs merge=lfs -text +tokenizer.json filter=lfs diff=lfs merge=lfs -text diff --git a/paddleocr_vl_1-5_tokenizer/LICENSE b/paddleocr_vl_1-5_tokenizer/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..0491a00e80b424eb709078b57e35d8b83ffee985 --- /dev/null +++ b/paddleocr_vl_1-5_tokenizer/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/paddleocr_vl_1-5_tokenizer/README.md b/paddleocr_vl_1-5_tokenizer/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f658ac7c0e4ac1aebbbdc04a56aa9f1d494df809 --- /dev/null +++ b/paddleocr_vl_1-5_tokenizer/README.md @@ -0,0 +1,362 @@ +--- +license: apache-2.0 +pipeline_tag: image-text-to-text +tags: +- ERNIE4.5 +- PaddleOCR +- PaddlePaddle +- image-to-text +- ocr +- document-parse +- layout +- table +- formula +- chart +- seal +- spotting +base_model: baidu/ERNIE-4.5-0.3B-Paddle +language: +- en +- zh +- multilingual +library_name: PaddleOCR +--- +
+ + +

+ +PaddleOCR-VL-1.5: Towards a Multi-Task 0.9B VLM for Robust In-the-Wild Document Parsing + +

+ +[![repo](https://img.shields.io/github/stars/PaddlePaddle/PaddleOCR?color=ccf)](https://github.com/PaddlePaddle/PaddleOCR) +[![HuggingFace](https://img.shields.io/badge/HuggingFace-black.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAF8AAABYCAMAAACkl9t/AAAAk1BMVEVHcEz/nQv/nQv/nQr/nQv/nQr/nQv/nQv/nQr/wRf/txT/pg7/yRr/rBD/zRz/ngv/oAz/zhz/nwv/txT/ngv/0B3+zBz/nQv/0h7/wxn/vRb/thXkuiT/rxH/pxD/ogzcqyf/nQvTlSz/czCxky7/SjifdjT/Mj3+Mj3wMj15aTnDNz+DSD9RTUBsP0FRO0Q6O0WyIxEIAAAAGHRSTlMADB8zSWF3krDDw8TJ1NbX5efv8ff9/fxKDJ9uAAAGKklEQVR42u2Z63qjOAyGC4RwCOfB2JAGqrSb2WnTw/1f3UaWcSGYNKTdf/P+mOkTrE+yJBulvfvLT2A5ruenaVHyIks33npl/6C4s/ZLAM45SOi/1FtZPyFur1OYofBX3w7d54Bxm+E8db+nDr12ttmESZ4zludJEG5S7TO72YPlKZFyE+YCYUJTBZsMiNS5Sd7NlDmKM2Eg2JQg8awbglfqgbhArjxkS7dgp2RH6hc9AMLdZYUtZN5DJr4molC8BfKrEkPKEnEVjLbgW1fLy77ZVOJagoIcLIl+IxaQZGjiX597HopF5CkaXVMDO9Pyix3AFV3kw4lQLCbHuMovz8FallbcQIJ5Ta0vks9RnolbCK84BtjKRS5uA43hYoZcOBGIG2Epbv6CvFVQ8m8loh66WNySsnN7htL58LNp+NXT8/PhXiBXPMjLSxtwp8W9f/1AngRierBkA+kk/IpUSOeKByzn8y3kAAAfh//0oXgV4roHm/kz4E2z//zRc3/lgwBzbM2mJxQEa5pqgX7d1L0htrhx7LKxOZlKbwcAWyEOWqYSI8YPtgDQVjpB5nvaHaSnBaQSD6hweDi8PosxD6/PT09YY3xQA7LTCTKfYX+QHpA0GCcqmEHvr/cyfKQTEuwgbs2kPxJEB0iNjfJcCTPyocx+A0griHSmADiC91oNGVwJ69RudYe65vJmoqfpul0lrqXadW0jFKH5BKwAeCq+Den7s+3zfRJzA61/Uj/9H/VzLKTx9jFPPdXeeP+L7WEvDLAKAIoF8bPTKT0+TM7W8ePj3Rz/Yn3kOAp2f1Kf0Weony7pn/cPydvhQYV+eFOfmOu7VB/ViPe34/EN3RFHY/yRuT8ddCtMPH/McBAT5s+vRde/gf2c/sPsjLK+m5IBQF5tO+h2tTlBGnP6693JdsvofjOPnnEHkh2TnV/X1fBl9S5zrwuwF8NFrAVJVwCAPTe8gaJlomqlp0pv4Pjn98tJ/t/fL++6unpR1YGC2n/KCoa0tTLoKiEeUPDl94nj+5/Tv3/eT5vBQ60X1S0oZr+IWRR8Ldhu7AlLjPISlJcO9vrFotky9SpzDequlwEir5beYAc0R7D9KS1DXva0jhYRDXoExPdc6yw5GShkZXe9QdO/uOvHofxjrV/TNS6iMJS+4TcSTgk9n5agJdBQbB//IfF/HpvPt3Tbi7b6I6K0R72p6ajryEJrENW2bbeVUGjfgoals4L443c7BEE4mJO2SpbRngxQrAKRudRzGQ8jVOL2qDVjjI8K1gc3TIJ5KiFZ1q+gdsARPB4NQS4AjwVSt72DSoXNyOWUrU5mQ9nRYyjp89Xo7oRI6Bga9QNT1mQ/ptaJq5T/7WcgAZywR/XlPGAUDdet3LE+qS0TI+g+aJU8MIqjo0Kx8Ly+maxLjJmjQ18rA0YCkxLQbUZP1WqdmyQGJLUm7VnQFqodmXSqmRrdVpqdzk5LvmvgtEcW8PMGdaS23EOWyDVbACZzUJPaqMbjDxpA3Qrgl0AikimGDbqmyT8P8NOYiqrldF8rX+YN7TopX4UoHuSCYY7cgX4gHwclQKl1zhx0THf+tCAUValzjI7Wg9EhptrkIcfIJjA94evOn8B2eHaVzvBrnl2ig0So6hvPaz0IGcOvTHvUIlE2+prqAxLSQxZlU2stql1NqCCLdIiIN/i1DBEHUoElM9dBravbiAnKqgpi4IBkw+utSPIoBijDXJipSVV7MpOEJUAc5Qmm3BnUN+w3hteEieYKfRZSIUcXKMVf0u5wD4EwsUNVvZOtUT7A2GkffHjByWpHqvRBYrTV72a6j8zZ6W0DTE86Hn04bmyWX3Ri9WH7ZU6Q7h+ZHo0nHUAcsQvVhXRDZHChwiyi/hnPuOsSEF6Exk3o6Y9DT1eZ+6cASXk2Y9k+6EOQMDGm6WBK10wOQJCBwren86cPPWUcRAnTVjGcU1LBgs9FURiX/e6479yZcLwCBmTxiawEwrOcleuu12t3tbLv/N4RLYIBhYexm7Fcn4OJcn0+zc+s8/VfPeddZHAGN6TT8eGczHdR/Gts1/MzDkThr23zqrVfAMFT33Nx1RJsx1k5zuWILLnG/vsH+Fv5D4NTVcp1Gzo8AAAAAElFTkSuQmCC&labelColor=white)](https://huggingface.co/PaddlePaddle/PaddleOCR-VL-1.5) +[![ModelScope](https://img.shields.io/badge/ModelScope-black?logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjIzIiBoZWlnaHQ9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KCiA8Zz4KICA8dGl0bGU+TGF5ZXIgMTwvdGl0bGU+CiAgPHBhdGggaWQ9InN2Z18xNCIgZmlsbD0iIzYyNGFmZiIgZD0ibTAsODkuODRsMjUuNjUsMGwwLDI1LjY0OTk5bC0yNS42NSwwbDAsLTI1LjY0OTk5eiIvPgogIDxwYXRoIGlkPSJzdmdfMTUiIGZpbGw9IiM2MjRhZmYiIGQ9Im05OS4xNCwxMTUuNDlsMjUuNjUsMGwwLDI1LjY1bC0yNS42NSwwbDAsLTI1LjY1eiIvPgogIDxwYXRoIGlkPSJzdmdfMTYiIGZpbGw9IiM2MjRhZmYiIGQ9Im0xNzYuMDksMTQxLjE0bC0yNS42NDk5OSwwbDAsMjIuMTlsNDcuODQsMGwwLC00Ny44NGwtMjIuMTksMGwwLDI1LjY1eiIvPgogIDxwYXRoIGlkPSJzdmdfMTciIGZpbGw9IiMzNmNmZDEiIGQ9Im0xMjQuNzksODkuODRsMjUuNjUsMGwwLDI1LjY0OTk5bC0yNS42NSwwbDAsLTI1LjY0OTk5eiIvPgogIDxwYXRoIGlkPSJzdmdfMTgiIGZpbGw9IiMzNmNmZDEiIGQ9Im0wLDY0LjE5bDI1LjY1LDBsMCwyNS42NWwtMjUuNjUsMGwwLC0yNS42NXoiLz4KICA8cGF0aCBpZD0ic3ZnXzE5IiBmaWxsPSIjNjI0YWZmIiBkPSJtMTk4LjI4LDg5Ljg0bDI1LjY0OTk5LDBsMCwyNS42NDk5OWwtMjUuNjQ5OTksMGwwLC0yNS42NDk5OXoiLz4KICA8cGF0aCBpZD0ic3ZnXzIwIiBmaWxsPSIjMzZjZmQxIiBkPSJtMTk4LjI4LDY0LjE5bDI1LjY0OTk5LDBsMCwyNS42NWwtMjUuNjQ5OTksMGwwLC0yNS42NXoiLz4KICA8cGF0aCBpZD0ic3ZnXzIxIiBmaWxsPSIjNjI0YWZmIiBkPSJtMTUwLjQ0LDQybDAsMjIuMTlsMjUuNjQ5OTksMGwwLDI1LjY1bDIyLjE5LDBsMCwtNDcuODRsLTQ3Ljg0LDB6Ii8+CiAgPHBhdGggaWQ9InN2Z18yMiIgZmlsbD0iIzM2Y2ZkMSIgZD0ibTczLjQ5LDg5Ljg0bDI1LjY1LDBsMCwyNS42NDk5OWwtMjUuNjUsMGwwLC0yNS42NDk5OXoiLz4KICA8cGF0aCBpZD0ic3ZnXzIzIiBmaWxsPSIjNjI0YWZmIiBkPSJtNDcuODQsNjQuMTlsMjUuNjUsMGwwLC0yMi4xOWwtNDcuODQsMGwwLDQ3Ljg0bDIyLjE5LDBsMCwtMjUuNjV6Ii8+CiAgPHBhdGggaWQ9InN2Z18yNCIgZmlsbD0iIzYyNGFmZiIgZD0ibTQ3Ljg0LDExNS40OWwtMjIuMTksMGwwLDQ3Ljg0bDQ3Ljg0LDBsMCwtMjIuMTlsLTI1LjY1LDBsMCwtMjUuNjV6Ii8+CiA8L2c+Cjwvc3ZnPg==&labelColor=white)](https://modelscope.cn/models/PaddlePaddle/PaddleOCR-VL-1.5) +[![HuggingFace](https://img.shields.io/badge/Demo_on_HuggingFace-black.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAF8AAABYCAMAAACkl9t/AAAAk1BMVEVHcEz/nQv/nQv/nQr/nQv/nQr/nQv/nQv/nQr/wRf/txT/pg7/yRr/rBD/zRz/ngv/oAz/zhz/nwv/txT/ngv/0B3+zBz/nQv/0h7/wxn/vRb/thXkuiT/rxH/pxD/ogzcqyf/nQvTlSz/czCxky7/SjifdjT/Mj3+Mj3wMj15aTnDNz+DSD9RTUBsP0FRO0Q6O0WyIxEIAAAAGHRSTlMADB8zSWF3krDDw8TJ1NbX5efv8ff9/fxKDJ9uAAAGKklEQVR42u2Z63qjOAyGC4RwCOfB2JAGqrSb2WnTw/1f3UaWcSGYNKTdf/P+mOkTrE+yJBulvfvLT2A5ruenaVHyIks33npl/6C4s/ZLAM45SOi/1FtZPyFur1OYofBX3w7d54Bxm+E8db+nDr12ttmESZ4zludJEG5S7TO72YPlKZFyE+YCYUJTBZsMiNS5Sd7NlDmKM2Eg2JQg8awbglfqgbhArjxkS7dgp2RH6hc9AMLdZYUtZN5DJr4molC8BfKrEkPKEnEVjLbgW1fLy77ZVOJagoIcLIl+IxaQZGjiX597HopF5CkaXVMDO9Pyix3AFV3kw4lQLCbHuMovz8FallbcQIJ5Ta0vks9RnolbCK84BtjKRS5uA43hYoZcOBGIG2Epbv6CvFVQ8m8loh66WNySsnN7htL58LNp+NXT8/PhXiBXPMjLSxtwp8W9f/1AngRierBkA+kk/IpUSOeKByzn8y3kAAAfh//0oXgV4roHm/kz4E2z//zRc3/lgwBzbM2mJxQEa5pqgX7d1L0htrhx7LKxOZlKbwcAWyEOWqYSI8YPtgDQVjpB5nvaHaSnBaQSD6hweDi8PosxD6/PT09YY3xQA7LTCTKfYX+QHpA0GCcqmEHvr/cyfKQTEuwgbs2kPxJEB0iNjfJcCTPyocx+A0griHSmADiC91oNGVwJ69RudYe65vJmoqfpul0lrqXadW0jFKH5BKwAeCq+Den7s+3zfRJzA61/Uj/9H/VzLKTx9jFPPdXeeP+L7WEvDLAKAIoF8bPTKT0+TM7W8ePj3Rz/Yn3kOAp2f1Kf0Weony7pn/cPydvhQYV+eFOfmOu7VB/ViPe34/EN3RFHY/yRuT8ddCtMPH/McBAT5s+vRde/gf2c/sPsjLK+m5IBQF5tO+h2tTlBGnP6693JdsvofjOPnnEHkh2TnV/X1fBl9S5zrwuwF8NFrAVJVwCAPTe8gaJlomqlp0pv4Pjn98tJ/t/fL++6unpR1YGC2n/KCoa0tTLoKiEeUPDl94nj+5/Tv3/eT5vBQ60X1S0oZr+IWRR8Ldhu7AlLjPISlJcO9vrFotky9SpzDequlwEir5beYAc0R7D9KS1DXva0jhYRDXoExPdc6yw5GShkZXe9QdO/uOvHofxjrV/TNS6iMJS+4TcSTgk9n5agJdBQbB//IfF/HpvPt3Tbi7b6I6K0R72p6ajryEJrENW2bbeVUGjfgoals4L443c7BEE4mJO2SpbRngxQrAKRudRzGQ8jVOL2qDVjjI8K1gc3TIJ5KiFZ1q+gdsARPB4NQS4AjwVSt72DSoXNyOWUrU5mQ9nRYyjp89Xo7oRI6Bga9QNT1mQ/ptaJq5T/7WcgAZywR/XlPGAUDdet3LE+qS0TI+g+aJU8MIqjo0Kx8Ly+maxLjJmjQ18rA0YCkxLQbUZP1WqdmyQGJLUm7VnQFqodmXSqmRrdVpqdzk5LvmvgtEcW8PMGdaS23EOWyDVbACZzUJPaqMbjDxpA3Qrgl0AikimGDbqmyT8P8NOYiqrldF8rX+YN7TopX4UoHuSCYY7cgX4gHwclQKl1zhx0THf+tCAUValzjI7Wg9EhptrkIcfIJjA94evOn8B2eHaVzvBrnl2ig0So6hvPaz0IGcOvTHvUIlE2+prqAxLSQxZlU2stql1NqCCLdIiIN/i1DBEHUoElM9dBravbiAnKqgpi4IBkw+utSPIoBijDXJipSVV7MpOEJUAc5Qmm3BnUN+w3hteEieYKfRZSIUcXKMVf0u5wD4EwsUNVvZOtUT7A2GkffHjByWpHqvRBYrTV72a6j8zZ6W0DTE86Hn04bmyWX3Ri9WH7ZU6Q7h+ZHo0nHUAcsQvVhXRDZHChwiyi/hnPuOsSEF6Exk3o6Y9DT1eZ+6cASXk2Y9k+6EOQMDGm6WBK10wOQJCBwren86cPPWUcRAnTVjGcU1LBgs9FURiX/e6479yZcLwCBmTxiawEwrOcleuu12t3tbLv/N4RLYIBhYexm7Fcn4OJcn0+zc+s8/VfPeddZHAGN6TT8eGczHdR/Gts1/MzDkThr23zqrVfAMFT33Nx1RJsx1k5zuWILLnG/vsH+Fv5D4NTVcp1Gzo8AAAAAElFTkSuQmCC&labelColor=white)](https://huggingface.co/spaces/PaddlePaddle/PaddleOCR-VL-1.5_Online_Demo) +[![ModelScope](https://img.shields.io/badge/Demo_on_ModelScope-black?logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjIzIiBoZWlnaHQ9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KCiA8Zz4KICA8dGl0bGU+TGF5ZXIgMTwvdGl0bGU+CiAgPHBhdGggaWQ9InN2Z18xNCIgZmlsbD0iIzYyNGFmZiIgZD0ibTAsODkuODRsMjUuNjUsMGwwLDI1LjY0OTk5bC0yNS42NSwwbDAsLTI1LjY0OTk5eiIvPgogIDxwYXRoIGlkPSJzdmdfMTUiIGZpbGw9IiM2MjRhZmYiIGQ9Im05OS4xNCwxMTUuNDlsMjUuNjUsMGwwLDI1LjY1bC0yNS42NSwwbDAsLTI1LjY1eiIvPgogIDxwYXRoIGlkPSJzdmdfMTYiIGZpbGw9IiM2MjRhZmYiIGQ9Im0xNzYuMDksMTQxLjE0bC0yNS42NDk5OSwwbDAsMjIuMTlsNDcuODQsMGwwLC00Ny44NGwtMjIuMTksMGwwLDI1LjY1eiIvPgogIDxwYXRoIGlkPSJzdmdfMTciIGZpbGw9IiMzNmNmZDEiIGQ9Im0xMjQuNzksODkuODRsMjUuNjUsMGwwLDI1LjY0OTk5bC0yNS42NSwwbDAsLTI1LjY0OTk5eiIvPgogIDxwYXRoIGlkPSJzdmdfMTgiIGZpbGw9IiMzNmNmZDEiIGQ9Im0wLDY0LjE5bDI1LjY1LDBsMCwyNS42NWwtMjUuNjUsMGwwLC0yNS42NXoiLz4KICA8cGF0aCBpZD0ic3ZnXzE5IiBmaWxsPSIjNjI0YWZmIiBkPSJtMTk4LjI4LDg5Ljg0bDI1LjY0OTk5LDBsMCwyNS42NDk5OWwtMjUuNjQ5OTksMGwwLC0yNS42NDk5OXoiLz4KICA8cGF0aCBpZD0ic3ZnXzIwIiBmaWxsPSIjMzZjZmQxIiBkPSJtMTk4LjI4LDY0LjE5bDI1LjY0OTk5LDBsMCwyNS42NWwtMjUuNjQ5OTksMGwwLC0yNS42NXoiLz4KICA8cGF0aCBpZD0ic3ZnXzIxIiBmaWxsPSIjNjI0YWZmIiBkPSJtMTUwLjQ0LDQybDAsMjIuMTlsMjUuNjQ5OTksMGwwLDI1LjY1bDIyLjE5LDBsMCwtNDcuODRsLTQ3Ljg0LDB6Ii8+CiAgPHBhdGggaWQ9InN2Z18yMiIgZmlsbD0iIzM2Y2ZkMSIgZD0ibTczLjQ5LDg5Ljg0bDI1LjY1LDBsMCwyNS42NDk5OWwtMjUuNjUsMGwwLC0yNS42NDk5OXoiLz4KICA8cGF0aCBpZD0ic3ZnXzIzIiBmaWxsPSIjNjI0YWZmIiBkPSJtNDcuODQsNjQuMTlsMjUuNjUsMGwwLC0yMi4xOWwtNDcuODQsMGwwLDQ3Ljg0bDIyLjE5LDBsMCwtMjUuNjV6Ii8+CiAgPHBhdGggaWQ9InN2Z18yNCIgZmlsbD0iIzYyNGFmZiIgZD0ibTQ3Ljg0LDExNS40OWwtMjIuMTksMGwwLDQ3Ljg0bDQ3Ljg0LDBsMCwtMjIuMTlsLTI1LjY1LDBsMCwtMjUuNjV6Ii8+CiA8L2c+Cjwvc3ZnPg==&labelColor=white)](https://modelscope.cn/studios/PaddlePaddle/PaddleOCR-VL-1.5_Online_Demo/summary) +[![Discord](https://img.shields.io/badge/Discord-ERNIE-5865F2?logo=discord&logoColor=white)](https://discord.gg/JPmZXDsEEK) +[![X](https://img.shields.io/badge/X-PaddlePaddle-6080F0)](https://x.com/PaddlePaddle) +[![License](https://img.shields.io/badge/license-Apache_2.0-green)](./LICENSE) + +**🔥 [Official Website](https://www.paddleocr.com)** +**📝 [Technical Report](https://arxiv.org/abs/2601.21957)** + +
+ +
+ +
+ + + +## Introduction + +**PaddleOCR-VL-1.5 is an advanced next-generation model of PaddleOCR-VL, achieving a new state-of-the-art accuracy of 94.5% on OmniDocBench v1.5.** To rigorously evaluate robustness against real-world physical distortions—including scanning artifacts, skew, warping, screen photography, and illumination—we propose the Real5-OmniDocBench benchmark. Experimental results demonstrate that this enhanced model attains SOTA performance on the newly curated benchmark. Furthermore, we extend the model’s capabilities by incorporating seal recognition and text spotting tasks, while remaining a 0.9B ultra-compact VLM with high efficiency. + +### **Key Capabilities of PaddleOCR-VL-1.5** + +1. With a **parameter size of 0.9B**, PaddleOCR-VL-1.5 **achieves 94.5% accuracy on OmniDocBench v1.5**, surpassing the previous SOTA model PaddleOCR-VL. Significant improvements are observed in **table, formula, and text recognition.** + +2. **It introduces an innovative approach to document parsing by supporting irregular-shaped localization**, enabling accurate polygonal detection under skewed and warped document conditions. Evaluations across five real-world scenarios—scanning, skew, warping, screen-photography, and illumination—demonstrate superior performance over mainstream open-source and proprietary models. + +3. The model introduces **text spotting (text-line localization and recognition)**, along with **seal recognition**, with all corresponding metrics **setting new SOTA results** in their respective tasks. + +4. PaddleOCR-VL-1.5 further strengthens its capability in **specialized scenarios and multilingual recognition.** Recognition performance is improved for **rare characters, ancient texts, multilingual tables, underlines, and checkboxes,** and language coverage is extended to include **China's Tibetan script and Bengali.** + +5. The model supports **automatic cross-page table merging** and **cross-page paragraph heading recognition**, effectively mitigating content fragmentation issues in **long-document parsing.** + + +### **Model Architecture** + +
+ +
+ + +## News + +* ```2026.01.29``` 🚀 We release [PaddleOCR-VL-1.5](https://huggingface.co/PaddlePaddle/PaddleOCR-VL-1.5), —a Multi-Task 0.9B VLM for Robust In-the-Wild Document Parsing. + +## Usage + +### Install Dependencies + +Install [PaddlePaddle](https://www.paddlepaddle.org.cn/install/quick) and [PaddleOCR](https://github.com/PaddlePaddle/PaddleOCR): + +```bash +# The following command installs the PaddlePaddle version for CUDA 12.6. For other CUDA versions and the CPU version, please refer to https://www.paddlepaddle.org.cn/en/install/quick?docurl=/documentation/docs/en/develop/install/pip/linux-pip_en.html +python -m pip install paddlepaddle-gpu==3.2.1 -i https://www.paddlepaddle.org.cn/packages/stable/cu126/ +python -m pip install -U "paddleocr[doc-parser]" +``` + +> **Please ensure that you install PaddlePaddle framework version 3.2.1 or above, along with the special version of safetensors.** For macOS users, please use Docker to set up the environment. + + +### Basic Usage + +CLI usage: + +```bash +paddleocr doc_parser -i https://paddle-model-ecology.bj.bcebos.com/paddlex/imgs/demo_image/paddleocr_vl_demo.png +``` + +Python API usage: + +```python +from paddleocr import PaddleOCRVL +pipeline = PaddleOCRVL() +output = pipeline.predict("https://paddle-model-ecology.bj.bcebos.com/paddlex/imgs/demo_image/paddleocr_vl_demo.png") +for res in output: + res.print() + res.save_to_json(save_path="output") + res.save_to_markdown(save_path="output") +``` + +### Accelerate VLM Inference via Optimized Inference Servers + +1. Start the VLM inference server: + + You can start the vLLM inference service using one of two methods: + - Method 1: PaddleOCR method + + ```bash + docker run \ + --rm \ + --gpus all \ + --network host \ + ccr-2vdh3abv-pub.cnc.bj.baidubce.com/paddlepaddle/paddleocr-genai-vllm-server:latest-nvidia-gpu \ + paddleocr genai_server --model_name PaddleOCR-VL-1.5-0.9B --host 0.0.0.0 --port 8080 --backend vllm + ``` + - Method 2: vLLM method + + [vLLM: PaddleOCR-VL Usage Guide](https://docs.vllm.ai/projects/recipes/en/latest/PaddlePaddle/PaddleOCR-VL.html) + +2. Call the PaddleOCR CLI or Python API: + ```bash + paddleocr doc_parser \ + -i https://paddle-model-ecology.bj.bcebos.com/paddlex/imgs/demo_image/paddleocr_vl_demo.png \ + --vl_rec_backend vllm-server \ + --vl_rec_server_url http://127.0.0.1:8080/v1 + ``` + ```python + from paddleocr import PaddleOCRVL + pipeline = PaddleOCRVL(vl_rec_backend="vllm-server", vl_rec_server_url="http://127.0.0.1:8080/v1") + output = pipeline.predict("https://paddle-model-ecology.bj.bcebos.com/paddlex/imgs/demo_image/paddleocr_vl_demo.png") + for res in output: + res.print() + res.save_to_json(save_path="output") + res.save_to_markdown(save_path="output") + ``` + +**For more usage details and parameter explanations, see the [documentation](https://www.paddleocr.ai/latest/en/version3.x/pipeline_usage/PaddleOCR-VL.html).** +## PaddleOCR-VL-1.5-0.9B Usage with transformers + +Currently, the PaddleOCR-VL-1.5-0.9B model facilitates seamless inference via the `transformers` library, supporting **comprehensive text spotting** and the recognition of complex elements including formulas, tables, charts, and seals. Below is a simple script we provide to support inference using the PaddleOCR-VL-1.5-0.9B model with `transformers`. + + +> [!NOTE] +> Note: We currently recommend using the official method for inference, as it is faster and supports page-level document parsing. The example code below only supports element-level recognition and text spotting. + +```shell +# ensure the transformers v5 is installed +python -m pip install "transformers>=5.0.0" +``` + +```python +from PIL import Image +import torch +from transformers import AutoProcessor, AutoModelForImageTextToText + +# ---- Settings ---- +model_path = "PaddlePaddle/PaddleOCR-VL-1.5" +image_path = "test.png" +task = "ocr" # Options: 'ocr' | 'table' | 'chart' | 'formula' | 'spotting' | 'seal' +# ------------------ + +# ---- Image Preprocessing For Spotting ---- +image = Image.open(image_path).convert("RGB") +orig_w, orig_h = image.size +spotting_upscale_threshold = 1500 + +if task == "spotting" and orig_w < spotting_upscale_threshold and orig_h < spotting_upscale_threshold: + process_w, process_h = orig_w * 2, orig_h * 2 + try: + resample_filter = Image.Resampling.LANCZOS + except AttributeError: + resample_filter = Image.LANCZOS + image = image.resize((process_w, process_h), resample_filter) + +# Set max_pixels: use 1605632 for spotting, otherwise use default ~1M pixels +max_pixels = 2048 * 28 * 28 if task == "spotting" else 1280 * 28 * 28 +# --------------------------- + +# -------- Inference -------- +DEVICE = "cuda" if torch.cuda.is_available() else "cpu" +PROMPTS = { + "ocr": "OCR:", + "table": "Table Recognition:", + "formula": "Formula Recognition:", + "chart": "Chart Recognition:", + "spotting": "Spotting:", + "seal": "Seal Recognition:", +} + +model = AutoModelForImageTextToText.from_pretrained(model_path, torch_dtype=torch.bfloat16).to(DEVICE).eval() +processor = AutoProcessor.from_pretrained(model_path) + +messages = [ + { + "role": "user", + "content": [ + {"type": "image", "image": image}, + {"type": "text", "text": PROMPTS[task]}, + ] + } +] +inputs = processor.apply_chat_template( + messages, + add_generation_prompt=True, + tokenize=True, + return_dict=True, + return_tensors="pt", + images_kwargs={"size": {"shortest_edge": processor.image_processor.min_pixels, "longest_edge": max_pixels}}, +).to(model.device) + +outputs = model.generate(**inputs, max_new_tokens=512) +result = processor.decode(outputs[0][inputs["input_ids"].shape[-1]:-1]) +print(result) +# --------------------------- +``` + +
+👉 Click to expand: Use flash-attn to boost performance and reduce memory usage + +```shell +# ensure the flash-attn2 is installed +pip install flash-attn --no-build-isolation +``` + +```python +model = AutoModelForImageTextToText.from_pretrained(model_path, torch_dtype=torch.bfloat16, attn_implementation="flash_attention_2").to(DEVICE).eval() +``` + +
+ +## Performance + +### Document Parsing + + +#### 1. OmniDocBench v1.5 + +##### PaddleOCR-VL-1.5 achieves SOTA performance for overall, text, formula, tables and reading order on OmniDocBench v1.5 + +
+ +
+ + +> **Notes:** +> - Performance metrics are cited from the [OmniDocBench official leaderboard](https://opendatalab.com/omnidocbench), except for Gemini-3 Pro, Qwen3-VL-235B-A22B-Instruct and our model, which were evaluated independently. + + +#### 2. Real5-OmniDocBench + +##### Across all five diverse and challenging scenarios—scanning, warping, screen-photography, illumination, and skew—PaddleOCR-VL-1.5 consistently sets new SOTA records + + +
+ +
+ +> **Notes:** +> - Real5-OmniDocBench is a brand-new benchmark oriented toward real-world scenarios, which we constructed based on the OmniDocBench v1.5 dataset. The dataset comprises five distinct scenarios: Scanning, Warping, Screen-photography, Illumination, and Skew. For further details, please refer to [Real5-OmniDocBench](https://huggingface.co/datasets/PaddlePaddle/Real5-OmniDocBench). + + +### Inference Performance + + +
+ +
+ +> **Notes:** +> - End-to-End Inference Performance Comparison on OmniDocBench v1.5. PDF documents were processed in batches of 512 on a single NVIDIA A100 GPU. The reported end-to-end runtime includes both PDF rendering and Markdown generation. All methods rely on their built-in PDF parsing modules and default DPI settings to reflect out-of-the-box performance. + + +## Visualization + + +### Real-word Document Parsing + + +#### Illumination + +
+ +
+ + +#### Skew + +
+ +
+ + +#### Screen Photography + +
+ +
+ + +#### Scanning + +
+ +
+ +#### Warping + +
+ +
+ + +### Text Spotting + + +
+ +
+ + +### Seal Recognition + + +
+ +
+ + +## Acknowledgments + +We would like to thank [PaddleFormers](https://github.com/PaddlePaddle/PaddleFormers), [Keye](https://github.com/Kwai-Keye/Keye), [MinerU](https://github.com/opendatalab/MinerU), [OmniDocBench](https://github.com/opendatalab/OmniDocBench) for providing valuable code, model weights and benchmarks. We also appreciate everyone's contribution to this open-source project! + +## Citation + +If you find PaddleOCR-VL-1.5 helpful, feel free to give us a star and citation. + +```bibtex +@misc{cui2026paddleocrvl15multitask09bvlm, + title={PaddleOCR-VL-1.5: Towards a Multi-Task 0.9B VLM for Robust In-the-Wild Document Parsing}, + author={Cheng Cui and Ting Sun and Suyin Liang and Tingquan Gao and Zelun Zhang and Jiaxuan Liu and Xueqing Wang and Changda Zhou and Hongen Liu and Manhui Lin and Yue Zhang and Yubo Zhang and Yi Liu and Dianhai Yu and Yanjun Ma}, + year={2026}, + eprint={2601.21957}, + archivePrefix={arXiv}, + primaryClass={cs.CV}, + url={https://arxiv.org/abs/2601.21957}, +} +``` diff --git a/paddleocr_vl_1-5_tokenizer/added_tokens.json b/paddleocr_vl_1-5_tokenizer/added_tokens.json new file mode 100644 index 0000000000000000000000000000000000000000..6a2790e1462ecb007f9b92dfb00f594701462889 --- /dev/null +++ b/paddleocr_vl_1-5_tokenizer/added_tokens.json @@ -0,0 +1,1021 @@ +{ + "": 101308, + "": 101309, + "": 101311, + "": 101313, + "": 101312, + "": 101310, + "<|AUDIO_PLACEHOLDER|>": 100296, + "<|CROP_COL_SEP|>": 101301, + "<|CROP_ROW_SEP|>": 101302, + "<|IMAGE_END|>": 101306, + "<|IMAGE_PLACEHOLDER|>": 100295, + "<|IMAGE_SEP|>": 101303, + "<|IMAGE_START|>": 101305, + "<|LOC_0|>": 100297, + "<|LOC_1000|>": 101297, + "<|LOC_100|>": 100397, + "<|LOC_101|>": 100398, + "<|LOC_102|>": 100399, + "<|LOC_103|>": 100400, + "<|LOC_104|>": 100401, + "<|LOC_105|>": 100402, + "<|LOC_106|>": 100403, + "<|LOC_107|>": 100404, + "<|LOC_108|>": 100405, + "<|LOC_109|>": 100406, + "<|LOC_10|>": 100307, + "<|LOC_110|>": 100407, + "<|LOC_111|>": 100408, + "<|LOC_112|>": 100409, + "<|LOC_113|>": 100410, + "<|LOC_114|>": 100411, + "<|LOC_115|>": 100412, + "<|LOC_116|>": 100413, + "<|LOC_117|>": 100414, + "<|LOC_118|>": 100415, + "<|LOC_119|>": 100416, + "<|LOC_11|>": 100308, + "<|LOC_120|>": 100417, + "<|LOC_121|>": 100418, + "<|LOC_122|>": 100419, + "<|LOC_123|>": 100420, + "<|LOC_124|>": 100421, + "<|LOC_125|>": 100422, + "<|LOC_126|>": 100423, + "<|LOC_127|>": 100424, + "<|LOC_128|>": 100425, + "<|LOC_129|>": 100426, + "<|LOC_12|>": 100309, + "<|LOC_130|>": 100427, + "<|LOC_131|>": 100428, + "<|LOC_132|>": 100429, + "<|LOC_133|>": 100430, + "<|LOC_134|>": 100431, + "<|LOC_135|>": 100432, + "<|LOC_136|>": 100433, + "<|LOC_137|>": 100434, + "<|LOC_138|>": 100435, + "<|LOC_139|>": 100436, + "<|LOC_13|>": 100310, + "<|LOC_140|>": 100437, + "<|LOC_141|>": 100438, + "<|LOC_142|>": 100439, + "<|LOC_143|>": 100440, + "<|LOC_144|>": 100441, + "<|LOC_145|>": 100442, + "<|LOC_146|>": 100443, + "<|LOC_147|>": 100444, + "<|LOC_148|>": 100445, + "<|LOC_149|>": 100446, + "<|LOC_14|>": 100311, + "<|LOC_150|>": 100447, + "<|LOC_151|>": 100448, + "<|LOC_152|>": 100449, + "<|LOC_153|>": 100450, + "<|LOC_154|>": 100451, + "<|LOC_155|>": 100452, + "<|LOC_156|>": 100453, + "<|LOC_157|>": 100454, + "<|LOC_158|>": 100455, + "<|LOC_159|>": 100456, + "<|LOC_15|>": 100312, + "<|LOC_160|>": 100457, + "<|LOC_161|>": 100458, + "<|LOC_162|>": 100459, + "<|LOC_163|>": 100460, + "<|LOC_164|>": 100461, + "<|LOC_165|>": 100462, + "<|LOC_166|>": 100463, + "<|LOC_167|>": 100464, + "<|LOC_168|>": 100465, + "<|LOC_169|>": 100466, + "<|LOC_16|>": 100313, + "<|LOC_170|>": 100467, + "<|LOC_171|>": 100468, + "<|LOC_172|>": 100469, + "<|LOC_173|>": 100470, + "<|LOC_174|>": 100471, + "<|LOC_175|>": 100472, + "<|LOC_176|>": 100473, + "<|LOC_177|>": 100474, + "<|LOC_178|>": 100475, + "<|LOC_179|>": 100476, + "<|LOC_17|>": 100314, + "<|LOC_180|>": 100477, + "<|LOC_181|>": 100478, + "<|LOC_182|>": 100479, + "<|LOC_183|>": 100480, + "<|LOC_184|>": 100481, + "<|LOC_185|>": 100482, + "<|LOC_186|>": 100483, + "<|LOC_187|>": 100484, + "<|LOC_188|>": 100485, + "<|LOC_189|>": 100486, + "<|LOC_18|>": 100315, + "<|LOC_190|>": 100487, + "<|LOC_191|>": 100488, + "<|LOC_192|>": 100489, + "<|LOC_193|>": 100490, + "<|LOC_194|>": 100491, + "<|LOC_195|>": 100492, + "<|LOC_196|>": 100493, + "<|LOC_197|>": 100494, + "<|LOC_198|>": 100495, + "<|LOC_199|>": 100496, + "<|LOC_19|>": 100316, + "<|LOC_1|>": 100298, + "<|LOC_200|>": 100497, + "<|LOC_201|>": 100498, + "<|LOC_202|>": 100499, + "<|LOC_203|>": 100500, + "<|LOC_204|>": 100501, + "<|LOC_205|>": 100502, + "<|LOC_206|>": 100503, + "<|LOC_207|>": 100504, + "<|LOC_208|>": 100505, + "<|LOC_209|>": 100506, + "<|LOC_20|>": 100317, + "<|LOC_210|>": 100507, + "<|LOC_211|>": 100508, + "<|LOC_212|>": 100509, + "<|LOC_213|>": 100510, + "<|LOC_214|>": 100511, + "<|LOC_215|>": 100512, + "<|LOC_216|>": 100513, + "<|LOC_217|>": 100514, + "<|LOC_218|>": 100515, + "<|LOC_219|>": 100516, + "<|LOC_21|>": 100318, + "<|LOC_220|>": 100517, + "<|LOC_221|>": 100518, + "<|LOC_222|>": 100519, + "<|LOC_223|>": 100520, + "<|LOC_224|>": 100521, + "<|LOC_225|>": 100522, + "<|LOC_226|>": 100523, + "<|LOC_227|>": 100524, + "<|LOC_228|>": 100525, + "<|LOC_229|>": 100526, + "<|LOC_22|>": 100319, + "<|LOC_230|>": 100527, + "<|LOC_231|>": 100528, + "<|LOC_232|>": 100529, + "<|LOC_233|>": 100530, + "<|LOC_234|>": 100531, + "<|LOC_235|>": 100532, + "<|LOC_236|>": 100533, + "<|LOC_237|>": 100534, + "<|LOC_238|>": 100535, + "<|LOC_239|>": 100536, + "<|LOC_23|>": 100320, + "<|LOC_240|>": 100537, + "<|LOC_241|>": 100538, + "<|LOC_242|>": 100539, + "<|LOC_243|>": 100540, + "<|LOC_244|>": 100541, + "<|LOC_245|>": 100542, + "<|LOC_246|>": 100543, + "<|LOC_247|>": 100544, + "<|LOC_248|>": 100545, + "<|LOC_249|>": 100546, + "<|LOC_24|>": 100321, + "<|LOC_250|>": 100547, + "<|LOC_251|>": 100548, + "<|LOC_252|>": 100549, + "<|LOC_253|>": 100550, + "<|LOC_254|>": 100551, + "<|LOC_255|>": 100552, + "<|LOC_256|>": 100553, + "<|LOC_257|>": 100554, + "<|LOC_258|>": 100555, + "<|LOC_259|>": 100556, + "<|LOC_25|>": 100322, + "<|LOC_260|>": 100557, + "<|LOC_261|>": 100558, + "<|LOC_262|>": 100559, + "<|LOC_263|>": 100560, + "<|LOC_264|>": 100561, + "<|LOC_265|>": 100562, + "<|LOC_266|>": 100563, + "<|LOC_267|>": 100564, + "<|LOC_268|>": 100565, + "<|LOC_269|>": 100566, + "<|LOC_26|>": 100323, + "<|LOC_270|>": 100567, + "<|LOC_271|>": 100568, + "<|LOC_272|>": 100569, + "<|LOC_273|>": 100570, + "<|LOC_274|>": 100571, + "<|LOC_275|>": 100572, + "<|LOC_276|>": 100573, + "<|LOC_277|>": 100574, + "<|LOC_278|>": 100575, + "<|LOC_279|>": 100576, + "<|LOC_27|>": 100324, + "<|LOC_280|>": 100577, + "<|LOC_281|>": 100578, + "<|LOC_282|>": 100579, + "<|LOC_283|>": 100580, + "<|LOC_284|>": 100581, + "<|LOC_285|>": 100582, + "<|LOC_286|>": 100583, + "<|LOC_287|>": 100584, + "<|LOC_288|>": 100585, + "<|LOC_289|>": 100586, + "<|LOC_28|>": 100325, + "<|LOC_290|>": 100587, + "<|LOC_291|>": 100588, + "<|LOC_292|>": 100589, + "<|LOC_293|>": 100590, + "<|LOC_294|>": 100591, + "<|LOC_295|>": 100592, + "<|LOC_296|>": 100593, + "<|LOC_297|>": 100594, + "<|LOC_298|>": 100595, + "<|LOC_299|>": 100596, + "<|LOC_29|>": 100326, + "<|LOC_2|>": 100299, + "<|LOC_300|>": 100597, + "<|LOC_301|>": 100598, + "<|LOC_302|>": 100599, + "<|LOC_303|>": 100600, + "<|LOC_304|>": 100601, + "<|LOC_305|>": 100602, + "<|LOC_306|>": 100603, + "<|LOC_307|>": 100604, + "<|LOC_308|>": 100605, + "<|LOC_309|>": 100606, + "<|LOC_30|>": 100327, + "<|LOC_310|>": 100607, + "<|LOC_311|>": 100608, + "<|LOC_312|>": 100609, + "<|LOC_313|>": 100610, + "<|LOC_314|>": 100611, + "<|LOC_315|>": 100612, + "<|LOC_316|>": 100613, + "<|LOC_317|>": 100614, + "<|LOC_318|>": 100615, + "<|LOC_319|>": 100616, + "<|LOC_31|>": 100328, + "<|LOC_320|>": 100617, + "<|LOC_321|>": 100618, + "<|LOC_322|>": 100619, + "<|LOC_323|>": 100620, + "<|LOC_324|>": 100621, + "<|LOC_325|>": 100622, + "<|LOC_326|>": 100623, + "<|LOC_327|>": 100624, + "<|LOC_328|>": 100625, + "<|LOC_329|>": 100626, + "<|LOC_32|>": 100329, + "<|LOC_330|>": 100627, + "<|LOC_331|>": 100628, + "<|LOC_332|>": 100629, + "<|LOC_333|>": 100630, + "<|LOC_334|>": 100631, + "<|LOC_335|>": 100632, + "<|LOC_336|>": 100633, + "<|LOC_337|>": 100634, + "<|LOC_338|>": 100635, + "<|LOC_339|>": 100636, + "<|LOC_33|>": 100330, + "<|LOC_340|>": 100637, + "<|LOC_341|>": 100638, + "<|LOC_342|>": 100639, + "<|LOC_343|>": 100640, + "<|LOC_344|>": 100641, + "<|LOC_345|>": 100642, + "<|LOC_346|>": 100643, + "<|LOC_347|>": 100644, + "<|LOC_348|>": 100645, + "<|LOC_349|>": 100646, + "<|LOC_34|>": 100331, + "<|LOC_350|>": 100647, + "<|LOC_351|>": 100648, + "<|LOC_352|>": 100649, + "<|LOC_353|>": 100650, + "<|LOC_354|>": 100651, + "<|LOC_355|>": 100652, + "<|LOC_356|>": 100653, + "<|LOC_357|>": 100654, + "<|LOC_358|>": 100655, + "<|LOC_359|>": 100656, + "<|LOC_35|>": 100332, + "<|LOC_360|>": 100657, + "<|LOC_361|>": 100658, + "<|LOC_362|>": 100659, + "<|LOC_363|>": 100660, + "<|LOC_364|>": 100661, + "<|LOC_365|>": 100662, + "<|LOC_366|>": 100663, + "<|LOC_367|>": 100664, + "<|LOC_368|>": 100665, + "<|LOC_369|>": 100666, + "<|LOC_36|>": 100333, + "<|LOC_370|>": 100667, + "<|LOC_371|>": 100668, + "<|LOC_372|>": 100669, + "<|LOC_373|>": 100670, + "<|LOC_374|>": 100671, + "<|LOC_375|>": 100672, + "<|LOC_376|>": 100673, + "<|LOC_377|>": 100674, + "<|LOC_378|>": 100675, + "<|LOC_379|>": 100676, + "<|LOC_37|>": 100334, + "<|LOC_380|>": 100677, + "<|LOC_381|>": 100678, + "<|LOC_382|>": 100679, + "<|LOC_383|>": 100680, + "<|LOC_384|>": 100681, + "<|LOC_385|>": 100682, + "<|LOC_386|>": 100683, + "<|LOC_387|>": 100684, + "<|LOC_388|>": 100685, + "<|LOC_389|>": 100686, + "<|LOC_38|>": 100335, + "<|LOC_390|>": 100687, + "<|LOC_391|>": 100688, + "<|LOC_392|>": 100689, + "<|LOC_393|>": 100690, + "<|LOC_394|>": 100691, + "<|LOC_395|>": 100692, + "<|LOC_396|>": 100693, + "<|LOC_397|>": 100694, + "<|LOC_398|>": 100695, + "<|LOC_399|>": 100696, + "<|LOC_39|>": 100336, + "<|LOC_3|>": 100300, + "<|LOC_400|>": 100697, + "<|LOC_401|>": 100698, + "<|LOC_402|>": 100699, + "<|LOC_403|>": 100700, + "<|LOC_404|>": 100701, + "<|LOC_405|>": 100702, + "<|LOC_406|>": 100703, + "<|LOC_407|>": 100704, + "<|LOC_408|>": 100705, + "<|LOC_409|>": 100706, + "<|LOC_40|>": 100337, + "<|LOC_410|>": 100707, + "<|LOC_411|>": 100708, + "<|LOC_412|>": 100709, + "<|LOC_413|>": 100710, + "<|LOC_414|>": 100711, + "<|LOC_415|>": 100712, + "<|LOC_416|>": 100713, + "<|LOC_417|>": 100714, + "<|LOC_418|>": 100715, + "<|LOC_419|>": 100716, + "<|LOC_41|>": 100338, + "<|LOC_420|>": 100717, + "<|LOC_421|>": 100718, + "<|LOC_422|>": 100719, + "<|LOC_423|>": 100720, + "<|LOC_424|>": 100721, + "<|LOC_425|>": 100722, + "<|LOC_426|>": 100723, + "<|LOC_427|>": 100724, + "<|LOC_428|>": 100725, + "<|LOC_429|>": 100726, + "<|LOC_42|>": 100339, + "<|LOC_430|>": 100727, + "<|LOC_431|>": 100728, + "<|LOC_432|>": 100729, + "<|LOC_433|>": 100730, + "<|LOC_434|>": 100731, + "<|LOC_435|>": 100732, + "<|LOC_436|>": 100733, + "<|LOC_437|>": 100734, + "<|LOC_438|>": 100735, + "<|LOC_439|>": 100736, + "<|LOC_43|>": 100340, + "<|LOC_440|>": 100737, + "<|LOC_441|>": 100738, + "<|LOC_442|>": 100739, + "<|LOC_443|>": 100740, + "<|LOC_444|>": 100741, + "<|LOC_445|>": 100742, + "<|LOC_446|>": 100743, + "<|LOC_447|>": 100744, + "<|LOC_448|>": 100745, + "<|LOC_449|>": 100746, + "<|LOC_44|>": 100341, + "<|LOC_450|>": 100747, + "<|LOC_451|>": 100748, + "<|LOC_452|>": 100749, + "<|LOC_453|>": 100750, + "<|LOC_454|>": 100751, + "<|LOC_455|>": 100752, + "<|LOC_456|>": 100753, + "<|LOC_457|>": 100754, + "<|LOC_458|>": 100755, + "<|LOC_459|>": 100756, + "<|LOC_45|>": 100342, + "<|LOC_460|>": 100757, + "<|LOC_461|>": 100758, + "<|LOC_462|>": 100759, + "<|LOC_463|>": 100760, + "<|LOC_464|>": 100761, + "<|LOC_465|>": 100762, + "<|LOC_466|>": 100763, + "<|LOC_467|>": 100764, + "<|LOC_468|>": 100765, + "<|LOC_469|>": 100766, + "<|LOC_46|>": 100343, + "<|LOC_470|>": 100767, + "<|LOC_471|>": 100768, + "<|LOC_472|>": 100769, + "<|LOC_473|>": 100770, + "<|LOC_474|>": 100771, + "<|LOC_475|>": 100772, + "<|LOC_476|>": 100773, + "<|LOC_477|>": 100774, + "<|LOC_478|>": 100775, + "<|LOC_479|>": 100776, + "<|LOC_47|>": 100344, + "<|LOC_480|>": 100777, + "<|LOC_481|>": 100778, + "<|LOC_482|>": 100779, + "<|LOC_483|>": 100780, + "<|LOC_484|>": 100781, + "<|LOC_485|>": 100782, + "<|LOC_486|>": 100783, + "<|LOC_487|>": 100784, + "<|LOC_488|>": 100785, + "<|LOC_489|>": 100786, + "<|LOC_48|>": 100345, + "<|LOC_490|>": 100787, + "<|LOC_491|>": 100788, + "<|LOC_492|>": 100789, + "<|LOC_493|>": 100790, + "<|LOC_494|>": 100791, + "<|LOC_495|>": 100792, + "<|LOC_496|>": 100793, + "<|LOC_497|>": 100794, + "<|LOC_498|>": 100795, + "<|LOC_499|>": 100796, + "<|LOC_49|>": 100346, + "<|LOC_4|>": 100301, + "<|LOC_500|>": 100797, + "<|LOC_501|>": 100798, + "<|LOC_502|>": 100799, + "<|LOC_503|>": 100800, + "<|LOC_504|>": 100801, + "<|LOC_505|>": 100802, + "<|LOC_506|>": 100803, + "<|LOC_507|>": 100804, + "<|LOC_508|>": 100805, + "<|LOC_509|>": 100806, + "<|LOC_50|>": 100347, + "<|LOC_510|>": 100807, + "<|LOC_511|>": 100808, + "<|LOC_512|>": 100809, + "<|LOC_513|>": 100810, + "<|LOC_514|>": 100811, + "<|LOC_515|>": 100812, + "<|LOC_516|>": 100813, + "<|LOC_517|>": 100814, + "<|LOC_518|>": 100815, + "<|LOC_519|>": 100816, + "<|LOC_51|>": 100348, + "<|LOC_520|>": 100817, + "<|LOC_521|>": 100818, + "<|LOC_522|>": 100819, + "<|LOC_523|>": 100820, + "<|LOC_524|>": 100821, + "<|LOC_525|>": 100822, + "<|LOC_526|>": 100823, + "<|LOC_527|>": 100824, + "<|LOC_528|>": 100825, + "<|LOC_529|>": 100826, + "<|LOC_52|>": 100349, + "<|LOC_530|>": 100827, + "<|LOC_531|>": 100828, + "<|LOC_532|>": 100829, + "<|LOC_533|>": 100830, + "<|LOC_534|>": 100831, + "<|LOC_535|>": 100832, + "<|LOC_536|>": 100833, + "<|LOC_537|>": 100834, + "<|LOC_538|>": 100835, + "<|LOC_539|>": 100836, + "<|LOC_53|>": 100350, + "<|LOC_540|>": 100837, + "<|LOC_541|>": 100838, + "<|LOC_542|>": 100839, + "<|LOC_543|>": 100840, + "<|LOC_544|>": 100841, + "<|LOC_545|>": 100842, + "<|LOC_546|>": 100843, + "<|LOC_547|>": 100844, + "<|LOC_548|>": 100845, + "<|LOC_549|>": 100846, + "<|LOC_54|>": 100351, + "<|LOC_550|>": 100847, + "<|LOC_551|>": 100848, + "<|LOC_552|>": 100849, + "<|LOC_553|>": 100850, + "<|LOC_554|>": 100851, + "<|LOC_555|>": 100852, + "<|LOC_556|>": 100853, + "<|LOC_557|>": 100854, + "<|LOC_558|>": 100855, + "<|LOC_559|>": 100856, + "<|LOC_55|>": 100352, + "<|LOC_560|>": 100857, + "<|LOC_561|>": 100858, + "<|LOC_562|>": 100859, + "<|LOC_563|>": 100860, + "<|LOC_564|>": 100861, + "<|LOC_565|>": 100862, + "<|LOC_566|>": 100863, + "<|LOC_567|>": 100864, + "<|LOC_568|>": 100865, + "<|LOC_569|>": 100866, + "<|LOC_56|>": 100353, + "<|LOC_570|>": 100867, + "<|LOC_571|>": 100868, + "<|LOC_572|>": 100869, + "<|LOC_573|>": 100870, + "<|LOC_574|>": 100871, + "<|LOC_575|>": 100872, + "<|LOC_576|>": 100873, + "<|LOC_577|>": 100874, + "<|LOC_578|>": 100875, + "<|LOC_579|>": 100876, + "<|LOC_57|>": 100354, + "<|LOC_580|>": 100877, + "<|LOC_581|>": 100878, + "<|LOC_582|>": 100879, + "<|LOC_583|>": 100880, + "<|LOC_584|>": 100881, + "<|LOC_585|>": 100882, + "<|LOC_586|>": 100883, + "<|LOC_587|>": 100884, + "<|LOC_588|>": 100885, + "<|LOC_589|>": 100886, + "<|LOC_58|>": 100355, + "<|LOC_590|>": 100887, + "<|LOC_591|>": 100888, + "<|LOC_592|>": 100889, + "<|LOC_593|>": 100890, + "<|LOC_594|>": 100891, + "<|LOC_595|>": 100892, + "<|LOC_596|>": 100893, + "<|LOC_597|>": 100894, + "<|LOC_598|>": 100895, + "<|LOC_599|>": 100896, + "<|LOC_59|>": 100356, + "<|LOC_5|>": 100302, + "<|LOC_600|>": 100897, + "<|LOC_601|>": 100898, + "<|LOC_602|>": 100899, + "<|LOC_603|>": 100900, + "<|LOC_604|>": 100901, + "<|LOC_605|>": 100902, + "<|LOC_606|>": 100903, + "<|LOC_607|>": 100904, + "<|LOC_608|>": 100905, + "<|LOC_609|>": 100906, + "<|LOC_60|>": 100357, + "<|LOC_610|>": 100907, + "<|LOC_611|>": 100908, + "<|LOC_612|>": 100909, + "<|LOC_613|>": 100910, + "<|LOC_614|>": 100911, + "<|LOC_615|>": 100912, + "<|LOC_616|>": 100913, + "<|LOC_617|>": 100914, + "<|LOC_618|>": 100915, + "<|LOC_619|>": 100916, + "<|LOC_61|>": 100358, + "<|LOC_620|>": 100917, + "<|LOC_621|>": 100918, + "<|LOC_622|>": 100919, + "<|LOC_623|>": 100920, + "<|LOC_624|>": 100921, + "<|LOC_625|>": 100922, + "<|LOC_626|>": 100923, + "<|LOC_627|>": 100924, + "<|LOC_628|>": 100925, + "<|LOC_629|>": 100926, + "<|LOC_62|>": 100359, + "<|LOC_630|>": 100927, + "<|LOC_631|>": 100928, + "<|LOC_632|>": 100929, + "<|LOC_633|>": 100930, + "<|LOC_634|>": 100931, + "<|LOC_635|>": 100932, + "<|LOC_636|>": 100933, + "<|LOC_637|>": 100934, + "<|LOC_638|>": 100935, + "<|LOC_639|>": 100936, + "<|LOC_63|>": 100360, + "<|LOC_640|>": 100937, + "<|LOC_641|>": 100938, + "<|LOC_642|>": 100939, + "<|LOC_643|>": 100940, + "<|LOC_644|>": 100941, + "<|LOC_645|>": 100942, + "<|LOC_646|>": 100943, + "<|LOC_647|>": 100944, + "<|LOC_648|>": 100945, + "<|LOC_649|>": 100946, + "<|LOC_64|>": 100361, + "<|LOC_650|>": 100947, + "<|LOC_651|>": 100948, + "<|LOC_652|>": 100949, + "<|LOC_653|>": 100950, + "<|LOC_654|>": 100951, + "<|LOC_655|>": 100952, + "<|LOC_656|>": 100953, + "<|LOC_657|>": 100954, + "<|LOC_658|>": 100955, + "<|LOC_659|>": 100956, + "<|LOC_65|>": 100362, + "<|LOC_660|>": 100957, + "<|LOC_661|>": 100958, + "<|LOC_662|>": 100959, + "<|LOC_663|>": 100960, + "<|LOC_664|>": 100961, + "<|LOC_665|>": 100962, + "<|LOC_666|>": 100963, + "<|LOC_667|>": 100964, + "<|LOC_668|>": 100965, + "<|LOC_669|>": 100966, + "<|LOC_66|>": 100363, + "<|LOC_670|>": 100967, + "<|LOC_671|>": 100968, + "<|LOC_672|>": 100969, + "<|LOC_673|>": 100970, + "<|LOC_674|>": 100971, + "<|LOC_675|>": 100972, + "<|LOC_676|>": 100973, + "<|LOC_677|>": 100974, + "<|LOC_678|>": 100975, + "<|LOC_679|>": 100976, + "<|LOC_67|>": 100364, + "<|LOC_680|>": 100977, + "<|LOC_681|>": 100978, + "<|LOC_682|>": 100979, + "<|LOC_683|>": 100980, + "<|LOC_684|>": 100981, + "<|LOC_685|>": 100982, + "<|LOC_686|>": 100983, + "<|LOC_687|>": 100984, + "<|LOC_688|>": 100985, + "<|LOC_689|>": 100986, + "<|LOC_68|>": 100365, + "<|LOC_690|>": 100987, + "<|LOC_691|>": 100988, + "<|LOC_692|>": 100989, + "<|LOC_693|>": 100990, + "<|LOC_694|>": 100991, + "<|LOC_695|>": 100992, + "<|LOC_696|>": 100993, + "<|LOC_697|>": 100994, + "<|LOC_698|>": 100995, + "<|LOC_699|>": 100996, + "<|LOC_69|>": 100366, + "<|LOC_6|>": 100303, + "<|LOC_700|>": 100997, + "<|LOC_701|>": 100998, + "<|LOC_702|>": 100999, + "<|LOC_703|>": 101000, + "<|LOC_704|>": 101001, + "<|LOC_705|>": 101002, + "<|LOC_706|>": 101003, + "<|LOC_707|>": 101004, + "<|LOC_708|>": 101005, + "<|LOC_709|>": 101006, + "<|LOC_70|>": 100367, + "<|LOC_710|>": 101007, + "<|LOC_711|>": 101008, + "<|LOC_712|>": 101009, + "<|LOC_713|>": 101010, + "<|LOC_714|>": 101011, + "<|LOC_715|>": 101012, + "<|LOC_716|>": 101013, + "<|LOC_717|>": 101014, + "<|LOC_718|>": 101015, + "<|LOC_719|>": 101016, + "<|LOC_71|>": 100368, + "<|LOC_720|>": 101017, + "<|LOC_721|>": 101018, + "<|LOC_722|>": 101019, + "<|LOC_723|>": 101020, + "<|LOC_724|>": 101021, + "<|LOC_725|>": 101022, + "<|LOC_726|>": 101023, + "<|LOC_727|>": 101024, + "<|LOC_728|>": 101025, + "<|LOC_729|>": 101026, + "<|LOC_72|>": 100369, + "<|LOC_730|>": 101027, + "<|LOC_731|>": 101028, + "<|LOC_732|>": 101029, + "<|LOC_733|>": 101030, + "<|LOC_734|>": 101031, + "<|LOC_735|>": 101032, + "<|LOC_736|>": 101033, + "<|LOC_737|>": 101034, + "<|LOC_738|>": 101035, + "<|LOC_739|>": 101036, + "<|LOC_73|>": 100370, + "<|LOC_740|>": 101037, + "<|LOC_741|>": 101038, + "<|LOC_742|>": 101039, + "<|LOC_743|>": 101040, + "<|LOC_744|>": 101041, + "<|LOC_745|>": 101042, + "<|LOC_746|>": 101043, + "<|LOC_747|>": 101044, + "<|LOC_748|>": 101045, + "<|LOC_749|>": 101046, + "<|LOC_74|>": 100371, + "<|LOC_750|>": 101047, + "<|LOC_751|>": 101048, + "<|LOC_752|>": 101049, + "<|LOC_753|>": 101050, + "<|LOC_754|>": 101051, + "<|LOC_755|>": 101052, + "<|LOC_756|>": 101053, + "<|LOC_757|>": 101054, + "<|LOC_758|>": 101055, + "<|LOC_759|>": 101056, + "<|LOC_75|>": 100372, + "<|LOC_760|>": 101057, + "<|LOC_761|>": 101058, + "<|LOC_762|>": 101059, + "<|LOC_763|>": 101060, + "<|LOC_764|>": 101061, + "<|LOC_765|>": 101062, + "<|LOC_766|>": 101063, + "<|LOC_767|>": 101064, + "<|LOC_768|>": 101065, + "<|LOC_769|>": 101066, + "<|LOC_76|>": 100373, + "<|LOC_770|>": 101067, + "<|LOC_771|>": 101068, + "<|LOC_772|>": 101069, + "<|LOC_773|>": 101070, + "<|LOC_774|>": 101071, + "<|LOC_775|>": 101072, + "<|LOC_776|>": 101073, + "<|LOC_777|>": 101074, + "<|LOC_778|>": 101075, + "<|LOC_779|>": 101076, + "<|LOC_77|>": 100374, + "<|LOC_780|>": 101077, + "<|LOC_781|>": 101078, + "<|LOC_782|>": 101079, + "<|LOC_783|>": 101080, + "<|LOC_784|>": 101081, + "<|LOC_785|>": 101082, + "<|LOC_786|>": 101083, + "<|LOC_787|>": 101084, + "<|LOC_788|>": 101085, + "<|LOC_789|>": 101086, + "<|LOC_78|>": 100375, + "<|LOC_790|>": 101087, + "<|LOC_791|>": 101088, + "<|LOC_792|>": 101089, + "<|LOC_793|>": 101090, + "<|LOC_794|>": 101091, + "<|LOC_795|>": 101092, + "<|LOC_796|>": 101093, + "<|LOC_797|>": 101094, + "<|LOC_798|>": 101095, + "<|LOC_799|>": 101096, + "<|LOC_79|>": 100376, + "<|LOC_7|>": 100304, + "<|LOC_800|>": 101097, + "<|LOC_801|>": 101098, + "<|LOC_802|>": 101099, + "<|LOC_803|>": 101100, + "<|LOC_804|>": 101101, + "<|LOC_805|>": 101102, + "<|LOC_806|>": 101103, + "<|LOC_807|>": 101104, + "<|LOC_808|>": 101105, + "<|LOC_809|>": 101106, + "<|LOC_80|>": 100377, + "<|LOC_810|>": 101107, + "<|LOC_811|>": 101108, + "<|LOC_812|>": 101109, + "<|LOC_813|>": 101110, + "<|LOC_814|>": 101111, + "<|LOC_815|>": 101112, + "<|LOC_816|>": 101113, + "<|LOC_817|>": 101114, + "<|LOC_818|>": 101115, + "<|LOC_819|>": 101116, + "<|LOC_81|>": 100378, + "<|LOC_820|>": 101117, + "<|LOC_821|>": 101118, + "<|LOC_822|>": 101119, + "<|LOC_823|>": 101120, + "<|LOC_824|>": 101121, + "<|LOC_825|>": 101122, + "<|LOC_826|>": 101123, + "<|LOC_827|>": 101124, + "<|LOC_828|>": 101125, + "<|LOC_829|>": 101126, + "<|LOC_82|>": 100379, + "<|LOC_830|>": 101127, + "<|LOC_831|>": 101128, + "<|LOC_832|>": 101129, + "<|LOC_833|>": 101130, + "<|LOC_834|>": 101131, + "<|LOC_835|>": 101132, + "<|LOC_836|>": 101133, + "<|LOC_837|>": 101134, + "<|LOC_838|>": 101135, + "<|LOC_839|>": 101136, + "<|LOC_83|>": 100380, + "<|LOC_840|>": 101137, + "<|LOC_841|>": 101138, + "<|LOC_842|>": 101139, + "<|LOC_843|>": 101140, + "<|LOC_844|>": 101141, + "<|LOC_845|>": 101142, + "<|LOC_846|>": 101143, + "<|LOC_847|>": 101144, + "<|LOC_848|>": 101145, + "<|LOC_849|>": 101146, + "<|LOC_84|>": 100381, + "<|LOC_850|>": 101147, + "<|LOC_851|>": 101148, + "<|LOC_852|>": 101149, + "<|LOC_853|>": 101150, + "<|LOC_854|>": 101151, + "<|LOC_855|>": 101152, + "<|LOC_856|>": 101153, + "<|LOC_857|>": 101154, + "<|LOC_858|>": 101155, + "<|LOC_859|>": 101156, + "<|LOC_85|>": 100382, + "<|LOC_860|>": 101157, + "<|LOC_861|>": 101158, + "<|LOC_862|>": 101159, + "<|LOC_863|>": 101160, + "<|LOC_864|>": 101161, + "<|LOC_865|>": 101162, + "<|LOC_866|>": 101163, + "<|LOC_867|>": 101164, + "<|LOC_868|>": 101165, + "<|LOC_869|>": 101166, + "<|LOC_86|>": 100383, + "<|LOC_870|>": 101167, + "<|LOC_871|>": 101168, + "<|LOC_872|>": 101169, + "<|LOC_873|>": 101170, + "<|LOC_874|>": 101171, + "<|LOC_875|>": 101172, + "<|LOC_876|>": 101173, + "<|LOC_877|>": 101174, + "<|LOC_878|>": 101175, + "<|LOC_879|>": 101176, + "<|LOC_87|>": 100384, + "<|LOC_880|>": 101177, + "<|LOC_881|>": 101178, + "<|LOC_882|>": 101179, + "<|LOC_883|>": 101180, + "<|LOC_884|>": 101181, + "<|LOC_885|>": 101182, + "<|LOC_886|>": 101183, + "<|LOC_887|>": 101184, + "<|LOC_888|>": 101185, + "<|LOC_889|>": 101186, + "<|LOC_88|>": 100385, + "<|LOC_890|>": 101187, + "<|LOC_891|>": 101188, + "<|LOC_892|>": 101189, + "<|LOC_893|>": 101190, + "<|LOC_894|>": 101191, + "<|LOC_895|>": 101192, + "<|LOC_896|>": 101193, + "<|LOC_897|>": 101194, + "<|LOC_898|>": 101195, + "<|LOC_899|>": 101196, + "<|LOC_89|>": 100386, + "<|LOC_8|>": 100305, + "<|LOC_900|>": 101197, + "<|LOC_901|>": 101198, + "<|LOC_902|>": 101199, + "<|LOC_903|>": 101200, + "<|LOC_904|>": 101201, + "<|LOC_905|>": 101202, + "<|LOC_906|>": 101203, + "<|LOC_907|>": 101204, + "<|LOC_908|>": 101205, + "<|LOC_909|>": 101206, + "<|LOC_90|>": 100387, + "<|LOC_910|>": 101207, + "<|LOC_911|>": 101208, + "<|LOC_912|>": 101209, + "<|LOC_913|>": 101210, + "<|LOC_914|>": 101211, + "<|LOC_915|>": 101212, + "<|LOC_916|>": 101213, + "<|LOC_917|>": 101214, + "<|LOC_918|>": 101215, + "<|LOC_919|>": 101216, + "<|LOC_91|>": 100388, + "<|LOC_920|>": 101217, + "<|LOC_921|>": 101218, + "<|LOC_922|>": 101219, + "<|LOC_923|>": 101220, + "<|LOC_924|>": 101221, + "<|LOC_925|>": 101222, + "<|LOC_926|>": 101223, + "<|LOC_927|>": 101224, + "<|LOC_928|>": 101225, + "<|LOC_929|>": 101226, + "<|LOC_92|>": 100389, + "<|LOC_930|>": 101227, + "<|LOC_931|>": 101228, + "<|LOC_932|>": 101229, + "<|LOC_933|>": 101230, + "<|LOC_934|>": 101231, + "<|LOC_935|>": 101232, + "<|LOC_936|>": 101233, + "<|LOC_937|>": 101234, + "<|LOC_938|>": 101235, + "<|LOC_939|>": 101236, + "<|LOC_93|>": 100390, + "<|LOC_940|>": 101237, + "<|LOC_941|>": 101238, + "<|LOC_942|>": 101239, + "<|LOC_943|>": 101240, + "<|LOC_944|>": 101241, + "<|LOC_945|>": 101242, + "<|LOC_946|>": 101243, + "<|LOC_947|>": 101244, + "<|LOC_948|>": 101245, + "<|LOC_949|>": 101246, + "<|LOC_94|>": 100391, + "<|LOC_950|>": 101247, + "<|LOC_951|>": 101248, + "<|LOC_952|>": 101249, + "<|LOC_953|>": 101250, + "<|LOC_954|>": 101251, + "<|LOC_955|>": 101252, + "<|LOC_956|>": 101253, + "<|LOC_957|>": 101254, + "<|LOC_958|>": 101255, + "<|LOC_959|>": 101256, + "<|LOC_95|>": 100392, + "<|LOC_960|>": 101257, + "<|LOC_961|>": 101258, + "<|LOC_962|>": 101259, + "<|LOC_963|>": 101260, + "<|LOC_964|>": 101261, + "<|LOC_965|>": 101262, + "<|LOC_966|>": 101263, + "<|LOC_967|>": 101264, + "<|LOC_968|>": 101265, + "<|LOC_969|>": 101266, + "<|LOC_96|>": 100393, + "<|LOC_970|>": 101267, + "<|LOC_971|>": 101268, + "<|LOC_972|>": 101269, + "<|LOC_973|>": 101270, + "<|LOC_974|>": 101271, + "<|LOC_975|>": 101272, + "<|LOC_976|>": 101273, + "<|LOC_977|>": 101274, + "<|LOC_978|>": 101275, + "<|LOC_979|>": 101276, + "<|LOC_97|>": 100394, + "<|LOC_980|>": 101277, + "<|LOC_981|>": 101278, + "<|LOC_982|>": 101279, + "<|LOC_983|>": 101280, + "<|LOC_984|>": 101281, + "<|LOC_985|>": 101282, + "<|LOC_986|>": 101283, + "<|LOC_987|>": 101284, + "<|LOC_988|>": 101285, + "<|LOC_989|>": 101286, + "<|LOC_98|>": 100395, + "<|LOC_990|>": 101287, + "<|LOC_991|>": 101288, + "<|LOC_992|>": 101289, + "<|LOC_993|>": 101290, + "<|LOC_994|>": 101291, + "<|LOC_995|>": 101292, + "<|LOC_996|>": 101293, + "<|LOC_997|>": 101294, + "<|LOC_998|>": 101295, + "<|LOC_999|>": 101296, + "<|LOC_99|>": 100396, + "<|LOC_9|>": 100306, + "<|LOC_BEGIN|>": 101298, + "<|LOC_END|>": 101299, + "<|LOC_SEP|>": 101300, + "<|image_pad|>": 101304, + "<|video_pad|>": 101307 +} diff --git a/paddleocr_vl_1-5_tokenizer/chat_template.jinja b/paddleocr_vl_1-5_tokenizer/chat_template.jinja new file mode 100644 index 0000000000000000000000000000000000000000..d8b8c271d7a7245d4937098f53aa372cff3dba70 --- /dev/null +++ b/paddleocr_vl_1-5_tokenizer/chat_template.jinja @@ -0,0 +1,43 @@ +{%- if not add_generation_prompt is defined -%} + {%- set add_generation_prompt = true -%} +{%- endif -%} +{%- if not cls_token is defined -%} + {%- set cls_token = "<|begin_of_sentence|>" -%} +{%- endif -%} +{%- if not eos_token is defined -%} + {%- set eos_token = "" -%} +{%- endif -%} +{{- cls_token -}} +{%- for message in messages -%} + {%- if message["role"] == "user" -%} + {{- "User: " -}} + {%- for content in message["content"] -%} + {%- if content["type"] == "image" -%} + {{ "<|IMAGE_START|><|IMAGE_PLACEHOLDER|><|IMAGE_END|>" }} + {%- endif -%} + {%- endfor -%} + {%- for content in message["content"] -%} + {%- if content["type"] == "text" -%} + {{ content["text"] }} + {%- endif -%} + {%- endfor -%} + {{ "\n" -}} + {%- elif message["role"] == "assistant" -%} + {{- "Assistant:\n" -}} + {%- for content in message["content"] -%} + {%- if content["type"] == "text" -%} + {{ content["text"] }} + {%- endif -%} + {%- endfor -%} + {{ eos_token -}} + {%- elif message["role"] == "system" -%} + {%- for content in message["content"] -%} + {%- if content["type"] == "text" -%} + {{ content["text"] + "\n" }} + {%- endif -%} + {%- endfor -%} + {%- endif -%} +{%- endfor -%} +{%- if add_generation_prompt -%} + {{- "Assistant:\n" -}} +{%- endif -%} diff --git a/paddleocr_vl_1-5_tokenizer/config.json b/paddleocr_vl_1-5_tokenizer/config.json new file mode 100644 index 0000000000000000000000000000000000000000..c54711466ae75457f8e57b909a49dae570bfa5c5 --- /dev/null +++ b/paddleocr_vl_1-5_tokenizer/config.json @@ -0,0 +1,76 @@ +{ + "architectures": [ + "PaddleOCRVLForConditionalGeneration" + ], + "attention_probs_dropout_prob": 0.0, + "auto_map": { + "AutoConfig": "configuration_paddleocr_vl.PaddleOCRVLConfig", + "AutoModel": "modeling_paddleocr_vl.PaddleOCRVLForConditionalGeneration", + "AutoModelForCausalLM": "modeling_paddleocr_vl.PaddleOCRVLForConditionalGeneration" + }, + "compression_ratio": 1.0, + "head_dim": 128, + "hidden_act": "silu", + "hidden_dropout_prob": 0.0, + "hidden_size": 1024, + "ignored_index": -100, + "image_token_id": 100295, + "intermediate_size": 3072, + "max_position_embeddings": 131072, + "max_sequence_length": null, + "model_type": "paddleocr_vl", + "num_attention_heads": 16, + "num_hidden_layers": 18, + "num_key_value_heads": 2, + "pad_token_id": 0, + "rms_norm_eps": 1e-05, + "rope_scaling": { + "mrope_section": [ + 16, + 24, + 24 + ], + "rope_type": "default", + "type": "default" + }, + "rope_theta": 500000, + "sliding_window": null, + "tie_word_embeddings": false, + "torch_dtype": "bfloat16", + "transformers_version": "4.55.0", + "use_bias": false, + "use_cache": false, + "use_flash_attention": false, + "video_token_id": 101307, + "vision_config": { + "architectures": [ + "PaddleOCRVisionModel" + ], + "attention_dropout": 0.0, + "auto_map": { + "AutoConfig": "configuration_paddleocr_vl.PaddleOCRVLConfig", + "AutoModel": "modeling_paddleocr_vl.PaddleOCRVisionModel" + }, + "hidden_act": "gelu_pytorch_tanh", + "hidden_size": 1152, + "image_size": 384, + "intermediate_size": 4304, + "layer_norm_eps": 1e-06, + "model_type": "paddleocr_vl", + "num_attention_heads": 16, + "num_channels": 3, + "num_hidden_layers": 27, + "pad_token_id": 0, + "patch_size": 14, + "spatial_merge_size": 2, + "temporal_patch_size": 2, + "tokens_per_second": 2, + "torch_dtype": "bfloat16" + }, + "vision_start_token_id": 101305, + "vision_end_token_id": 101306, + "vocab_size": 103424, + "weight_share_add_bias": true, + "use_3d_rope": true, + "rope_is_neox_style": true +} diff --git a/paddleocr_vl_1-5_tokenizer/configuration_paddleocr_vl.py b/paddleocr_vl_1-5_tokenizer/configuration_paddleocr_vl.py new file mode 100644 index 0000000000000000000000000000000000000000..a8fd139287293301b287db6dfdaac21d7ad1a236 --- /dev/null +++ b/paddleocr_vl_1-5_tokenizer/configuration_paddleocr_vl.py @@ -0,0 +1,191 @@ +# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from transformers.configuration_utils import PretrainedConfig +from transformers.modeling_rope_utils import rope_config_validation + +class PaddleOCRVisionConfig(PretrainedConfig): + model_type = "paddleocr_vl" + base_config_key = "vision_config" + + def __init__( + self, + hidden_size=768, + intermediate_size=3072, + num_hidden_layers=12, + num_attention_heads=12, + num_channels=3, + image_size=224, + patch_size=14, + hidden_act="gelu_pytorch_tanh", + layer_norm_eps=1e-6, + attention_dropout=0.0, + spatial_merge_size=2, + temporal_patch_size=2, + tokens_per_second=2, + **kwargs, + ): + super().__init__(**kwargs) + + self.hidden_size = hidden_size + self.intermediate_size = intermediate_size + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.num_channels = num_channels + self.patch_size = patch_size + self.image_size = image_size + self.attention_dropout = attention_dropout + self.layer_norm_eps = layer_norm_eps + self.hidden_act = hidden_act + self.spatial_merge_size = spatial_merge_size + self.temporal_patch_size = temporal_patch_size + self.tokens_per_second = tokens_per_second + + + +class PaddleOCRVLConfig(PretrainedConfig): + """ + Configuration class. + + This class stores the configuration of an Ernie model, defining the model architecture. + It inherits from PretrainedConfig and can be used to control model outputs. + """ + + model_type = "paddleocr_vl" + keys_to_ignore_at_inference = ["past_key_values"] + sub_configs = {"vision_config": PaddleOCRVisionConfig} + + # Default tensor parallel plan for base model `Qwen3` + base_model_tp_plan = { + "layers.*.self_attn.q_proj": "colwise", + "layers.*.self_attn.k_proj": "colwise", + "layers.*.self_attn.v_proj": "colwise", + "layers.*.self_attn.o_proj": "rowwise", + "layers.*.mlp.gate_proj": "colwise", + "layers.*.mlp.up_proj": "colwise", + "layers.*.mlp.down_proj": "rowwise", + } + base_model_pp_plan = { + "embed_tokens": (["input_ids"], ["inputs_embeds"]), + "layers": (["hidden_states", "attention_mask"], ["hidden_states"]), + "norm": (["hidden_states"], ["hidden_states"]), + } + + def __init__( + self, + vocab_size=32000, + hidden_size=768, + intermediate_size=11008, + max_position_embeddings=32768, + num_hidden_layers=2, + num_attention_heads=2, + image_token_id=101304, + video_token_id=101305, + vision_start_token_id=101306, + rms_norm_eps=1e-6, + use_cache=False, + use_flash_attention=False, + pad_token_id=0, + bos_token_id=1, + eos_token_id=2, + head_dim=128, + hidden_act="silu", + use_bias=False, + rope_theta=10000, + weight_share_add_bias=True, + ignored_index=-100, + attention_probs_dropout_prob=0.0, + hidden_dropout_prob=0.0, + compression_ratio: float = 1.0, + num_key_value_heads=None, + max_sequence_length=None, + tie_word_embeddings=False, + vision_config=None, + rope_scaling=None, + **kwargs, + ): + """ + Initialize configuration with default or specified parameters. + + Args: + vocab_size (int): Size of the vocabulary (number of unique tokens) + hidden_size (int): Dimensionality of the encoder layers and the pooler layer + intermediate_size (int): Dimensionality of the "intermediate" (feed-forward) layer + max_position_embeddings (int): Maximum sequence length the model can handle + num_hidden_layers (int): Number of hidden layers in the Transformer encoder + num_attention_heads (int): Number of attention heads for each attention layer + rms_norm_eps (float): The epsilon used by the RMS normalization layers + use_cache (bool): Whether to use caching for faster generation (decoding) + use_flash_attention (bool): Whether to use FlashAttention for optimized attention computation + pad_token_id (int): Token ID used for padding sequences + bos_token_id (int): Token ID used for beginning-of-sequence + eos_token_id (int): Token ID used for end-of-sequence + use_bias (bool): Whether to use bias terms in linear layers + rope_theta (float): The base period of the RoPE embeddings + weight_share_add_bias (bool): Whether to share bias weights in certain layers + ignored_index (int): Target value that is ignored during loss computation + attention_probs_dropout_prob (float): Dropout probability for attention weights + hidden_dropout_prob (float): Dropout probability for hidden layers + compression_ratio (float): Ratio for KV cache compression (1.0 = no compression) + num_key_value_heads (int): Number of key/value heads (for Grouped Query Attention) + max_sequence_length (int): Maximum sequence length for positional embeddings + **kwargs: Additional keyword arguments passed to parent class + """ + + # Set default for tied embeddings if not specified. + super().__init__( + pad_token_id=pad_token_id, + bos_token_id=bos_token_id, + eos_token_id=eos_token_id, + **kwargs, + ) + if isinstance(vision_config, dict): + self.vision_config = self.sub_configs["vision_config"](**vision_config) + elif vision_config is None: + self.vision_config = self.sub_configs["vision_config"]() + self.vocab_size = vocab_size + self.hidden_size = hidden_size + self.intermediate_size = intermediate_size + self.max_position_embeddings = max_position_embeddings + self.num_hidden_layers = num_hidden_layers + self.num_attention_heads = num_attention_heads + self.rms_norm_eps = rms_norm_eps + self.use_cache = use_cache + self.use_flash_attention = use_flash_attention + self.pad_token_id = pad_token_id + self.bos_token_id = bos_token_id + self.eos_token_id = eos_token_id + self.image_token_id = image_token_id + self.video_token_id = video_token_id + self.vision_start_token_id = vision_start_token_id + self.head_dim = head_dim + self.hidden_act=hidden_act + self.sliding_window = None + self.hidden_size = hidden_size + self.use_bias = use_bias + self.weight_share_add_bias = weight_share_add_bias + self.rope_theta = rope_theta + self.ignored_index = ignored_index + self.attention_probs_dropout_prob = attention_probs_dropout_prob + self.hidden_dropout_prob = hidden_dropout_prob + self.compression_ratio = compression_ratio + self.num_key_value_heads = num_key_value_heads + self.max_sequence_length = max_sequence_length + self.rope_scaling = rope_scaling + if self.rope_scaling is not None and "type" in self.rope_scaling: + if self.rope_scaling["type"] == "mrope": + self.rope_scaling["type"] = "default" + self.rope_scaling["rope_type"] = self.rope_scaling["type"] + rope_config_validation(self, ignore_keys={"mrope_section"}) + super().__init__(tie_word_embeddings=tie_word_embeddings, **kwargs) \ No newline at end of file diff --git a/paddleocr_vl_1-5_tokenizer/generation_config.json b/paddleocr_vl_1-5_tokenizer/generation_config.json new file mode 100644 index 0000000000000000000000000000000000000000..ba87d71b9881c1d52f0be4286fb63e381ce3febf --- /dev/null +++ b/paddleocr_vl_1-5_tokenizer/generation_config.json @@ -0,0 +1,7 @@ +{ + "_from_model_config": true, + "eos_token_id": 2, + "pad_token_id": 0, + "transformers_version": "4.55.0", + "use_cache": false +} diff --git a/paddleocr_vl_1-5_tokenizer/image_processing_paddleocr_vl.py b/paddleocr_vl_1-5_tokenizer/image_processing_paddleocr_vl.py new file mode 100644 index 0000000000000000000000000000000000000000..7e1d50a81f0bd0b59bf68a78b2f81c117f1ccf00 --- /dev/null +++ b/paddleocr_vl_1-5_tokenizer/image_processing_paddleocr_vl.py @@ -0,0 +1,569 @@ +# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Image processor class for PaddleOCR-VL.""" + +import math +from typing import Dict, List, Optional, Union + +import numpy as np +import torch +from transformers.image_processing_utils import BaseImageProcessor, BatchFeature +from torchvision.transforms import functional as TF +from transformers.image_transforms import ( + convert_to_rgb, + resize, + to_channel_dimension_format, +) +from transformers.image_utils import ( + OPENAI_CLIP_MEAN, + OPENAI_CLIP_STD, + ChannelDimension, + PILImageResampling, + get_image_size, + infer_channel_dimension_format, + is_scaled_image, + is_valid_image, + make_list_of_images, + to_numpy_array, + valid_images, + validate_preprocess_arguments, +) +from transformers.utils import TensorType, is_vision_available, logging + + +logger = logging.get_logger(__name__) + + +if is_vision_available(): + from PIL import Image + +ImageInput = Union[ + "PIL.Image.Image", + np.ndarray, + "torch.Tensor", + List["PIL.Image.Image"], + List[np.ndarray], + List["torch.Tensor"], +] # noqa + + +VideoInput = Union[ + List["PIL.Image.Image"], + "np.ndarray", + "torch.Tensor", + List["np.ndarray"], + List["torch.Tensor"], + List[List["PIL.Image.Image"]], + List[List["np.ndarrray"]], + List[List["torch.Tensor"]], +] # noqa + + +def make_batched_images(images) -> List[List[ImageInput]]: + """ + Accepts images in list or nested list format, and makes a list of images for preprocessing. + + Args: + images (`Union[List[List[ImageInput]], List[ImageInput], ImageInput]`): + The input image. + + Returns: + list: A list of images. + """ + if ( + isinstance(images, (list, tuple)) + and isinstance(images[0], (list, tuple)) + and is_valid_image(images[0][0]) + ): + return [img for img_list in images for img in img_list] + + elif isinstance(images, (list, tuple)) and is_valid_image(images[0]): + return images + + elif is_valid_image(images): + return [images] + + raise ValueError(f"Could not make batched images from {images}") + + +def adjust_size(size, patch_size): + num_patches = size // patch_size + if num_patches % 2 != 0: # 如果是奇数,减1 + num_patches -= 1 + return num_patches * patch_size + + +def make_batched_videos(videos) -> List[VideoInput]: + if ( + isinstance(videos, (list, tuple)) + and isinstance(videos[0], (list, tuple)) + and is_valid_image(videos[0][0]) + ): + return videos + + elif isinstance(videos, (list, tuple)) and is_valid_image(videos[0]): + if isinstance(videos[0], Image.Image): + return [videos] + elif len(videos[0].shape) == 4: + return [list(video) for video in videos] + + elif is_valid_image(videos) and len(videos.shape) == 4: + return [list(videos)] + + raise ValueError(f"Could not make batched video from {videos}") + + +def smart_resize( + height: int, + width: int, + factor: int = 28, + min_pixels: int = 28 * 28 * 130, + max_pixels: int = 28 * 28 * 1280, +): + """Rescales the image so that the following conditions are met: + + 1. Both dimensions (height and width) are divisible by 'factor'. + + 2. The total number of pixels is within the range ['min_pixels', 'max_pixels']. + + 3. The aspect ratio of the image is maintained as closely as possible. + + """ + # if height < factor or width < factor: + # raise ValueError(f"height:{height} or width:{width} must be larger than factor:{factor}") + # if int(height < factor//4) + int(width < factor//4): + # raise ValueError(f"height:{height} or width:{width} must be larger than factor:{factor//4}") + + if height < factor: + print(f"smart_resize: height={height} < factor={factor}, reset height=factor") + width = round((width * factor) / height) + height = factor + + if width < factor: + print(f"smart_resize: width={width} < factor={factor}, reset width=factor") + height = round((height * factor) / width) + width = factor + + if max(height, width) / min(height, width) > 200: + raise ValueError( + f"absolute aspect ratio must be smaller than 200, got {max(height, width) / min(height, width)}" + ) + h_bar = round(height / factor) * factor + w_bar = round(width / factor) * factor + if h_bar * w_bar > max_pixels: + beta = math.sqrt((height * width) / max_pixels) + h_bar = math.floor(height / beta / factor) * factor + w_bar = math.floor(width / beta / factor) * factor + elif h_bar * w_bar < min_pixels: + beta = math.sqrt(min_pixels / (height * width)) + h_bar = math.ceil(height * beta / factor) * factor + w_bar = math.ceil(width * beta / factor) * factor + return h_bar, w_bar + + +class PaddleOCRVLImageProcessor(BaseImageProcessor): + r""" + Constructs a Siglip image processor that dynamically resizes images based on the original images. + + Args: + do_resize (`bool`, *optional*, defaults to `True`): + Whether to resize the image's (height, width) dimensions. + resample (`PILImageResampling`, *optional*, defaults to `Resampling.BICUBIC`): + Resampling filter to use when resizing the image. + do_rescale (`bool`, *optional*, defaults to `True`): + Whether to rescale the image by the specified scale `rescale_factor`. + rescale_factor (`int` or `float`, *optional*, defaults to `1/255`): + Scale factor to use if rescaling the image. + do_normalize (`bool`, *optional*, defaults to `True`): + Whether to normalize the image. + image_mean (`float` or `List[float]`, *optional*, defaults to `[0.48145466, 0.4578275, 0.40821073]`): + Mean to use if normalizing the image. This is a float or list of floats for each channel in the image. + image_std (`float` or `List[float]`, *optional*, defaults to `[0.26862954, 0.26130258, 0.27577711]`): + Standard deviation to use if normalizing the image. This is a float or list of floats for each channel in the image. + do_convert_rgb (`bool`, *optional*, defaults to `True`): + Whether to convert the image to RGB. + min_pixels (`int`, *optional*, defaults to `28 * 28 * 130`): + The min pixels of the image to resize the image. + max_pixels (`int`, *optional*, defaults to `28 * 28 * 1670`): + The max pixels of the image to resize the image. + patch_size (`int`, *optional*, defaults to 14): + The spacial patch size of the vision encoder. + temporal_patch_size (`int`, *optional*, defaults to 2): + The temporal patch size of the vision encoder. + merge_size (`int`, *optional*, defaults to 2): + The merge size of the vision encoder to llm encoder. + """ + + model_input_names = [ + "pixel_values", + "image_grid_thw", + "pixel_values_videos", + "video_grid_thw", + ] + + def __init__( + self, + do_resize: bool = True, + resample: PILImageResampling = PILImageResampling.BICUBIC, + do_rescale: bool = True, + rescale_factor: Union[int, float] = 1 / 255, + do_normalize: bool = True, + image_mean: Optional[Union[float, List[float]]] = None, + image_std: Optional[Union[float, List[float]]] = None, + do_convert_rgb: bool = True, + min_pixels: int = 28 * 28 * 130, + max_pixels: int = 28 * 28 * 1280, + patch_size: int = 14, + temporal_patch_size: int = 1, + merge_size: int = 2, + **kwargs, + ) -> None: + super().__init__(**kwargs) + self.do_resize = do_resize + self.resample = resample + self.do_rescale = do_rescale + self.rescale_factor = rescale_factor + self.do_normalize = do_normalize + self.image_mean = image_mean if image_mean is not None else OPENAI_CLIP_MEAN + self.image_std = image_std if image_std is not None else OPENAI_CLIP_STD + self.min_pixels = min_pixels + self.max_pixels = max_pixels + self.patch_size = patch_size + self.temporal_patch_size = temporal_patch_size + self.merge_size = merge_size + self.size = {"min_pixels": min_pixels, "max_pixels": max_pixels} # not used + self.do_convert_rgb = do_convert_rgb + + def mvit_rescale(self, image: Image.Image, merge_size: int = 2) -> Image.Image: + try: + w, h = image.size + except: + raise ValueError(str((type(image), image))) + patch_size = self.patch_size + + if (w // patch_size) * (h // patch_size) > self.in_token_limit: + scale = math.sqrt( + self.in_token_limit / ((w // patch_size) * (h // patch_size)) + ) + new_w, new_h = int(w * scale), int(h * scale) + + image = image.resize((new_w, new_h), Image.Resampling.BICUBIC) + if self.pad_input: + new_w, new_h = image.size + pad_size_h = merge_size * patch_size + pad_size_w = merge_size * patch_size + + pad_h = (pad_size_h - new_h % pad_size_h) % pad_size_h + pad_w = (pad_size_w - new_w % pad_size_w) % pad_size_w + + image = TF.pad(image, (0, 0, pad_w, pad_h)) + else: + new_w, new_h = image.size + new_w = new_w - new_w % patch_size + new_h = new_h - new_h % patch_size + + new_w = adjust_size(new_w, patch_size) + new_h = adjust_size(new_h, patch_size) + + image = TF.center_crop(image, (new_h, new_w)) + + w, h = image.size + if w // patch_size >= 512 or h // patch_size >= 512: + new_h = min(patch_size * 510, h) + new_w = min(patch_size * 510, w) + image = TF.center_crop(image, (new_h, new_w)) + # raise ValueError("Exceed pos emb") + return image + + def _preprocess( + self, + images: Union[ImageInput, VideoInput], + do_resize: bool = None, + resample: PILImageResampling = None, + do_rescale: bool = None, + rescale_factor: float = None, + do_normalize: bool = None, + image_mean: Optional[Union[float, List[float]]] = None, + image_std: Optional[Union[float, List[float]]] = None, + do_convert_rgb: bool = None, + data_format: Optional[ChannelDimension] = ChannelDimension.FIRST, + input_data_format: Optional[Union[str, ChannelDimension]] = None, + ): + """ + Preprocess an image or batch of images. Copy of the `preprocess` method from `CLIPImageProcessor`. + + Args: + images (`ImageInput`): + Image or batch of images to preprocess. Expects pixel values ranging from 0 to 255. If pixel values range from 0 to 1, set `do_rescale=False`. + vision_info (`List[Dict]`, *optional*): + Optional list of dictionaries containing additional information about vision inputs. + do_resize (`bool`, *optional*, defaults to `self.do_resize`): + Whether to resize the image. + resample (`PILImageResampling`, *optional*, defaults to `self.resample`): + Resampling filter to use if resizing the image. This can be one of the `PILImageResampling` enums. + do_rescale (`bool`, *optional*, defaults to `self.do_rescale`): + Whether to rescale the image. + rescale_factor (`float`, *optional*, defaults to `self.rescale_factor`): + Scale factor to use if rescaling the image. + do_normalize (`bool`, *optional*, defaults to `self.do_normalize`): + Whether to normalize the image. + image_mean (`float` or `List[float]`, *optional*, defaults to `self.image_mean`): + Mean to use if normalizing the image. Can be a float or a list of floats corresponding to the number of channels in the image. + image_std (`float` or `List[float]`, *optional*, defaults to `self.image_std`): + Standard deviation to use if normalizing the image. Can be a float or a list of floats corresponding to the number of channels in the image. + do_convert_rgb (`bool`, *optional*, defaults to `self.do_convert_rgb`): + Whether to convert the image to RGB. + data_format (`ChannelDimension`, *optional*, defaults to `ChannelDimension.FIRST`): + The channel dimension format for the output image. Can be one of: + - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. + - `"channels_last"` or `ChannelDimension.LAST`: image in (height, width, num_channels) format. + - Unset: Use the channel dimension format of the input image. + input_data_format (`ChannelDimension` or `str`, *optional*): + The channel dimension format for the input image. Can be one of: + - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. + - `"channels_last"` or `ChannelDimension.LAST`: image in (height, width, num_channels) format. + - `"none"` or `ChannelDimension.NONE`: image in (height, width) format. - `"none"` or `ChannelDimension.NONE`: image in (height, width) format. + """ + images = make_list_of_images(images) + + if do_convert_rgb: + images = [convert_to_rgb(image) for image in images] + + # All transformations expect numpy arrays. + images = [to_numpy_array(image) for image in images] + + if is_scaled_image(images[0]) and do_rescale: + logger.warning_once( + "It looks like you are trying to rescale already rescaled images. If the input" + " images have pixel values between 0 and 1, set `do_rescale=False` to avoid rescaling them again." + ) + if input_data_format is None: + # We assume that all images have the same channel dimension format. + input_data_format = infer_channel_dimension_format(images[0]) + + height, width = get_image_size(images[0], channel_dim=input_data_format) + resized_height, resized_width = height, width + processed_images = [] + + for image in images: + if do_resize: + resized_height, resized_width = smart_resize( + height, + width, + factor=self.patch_size * self.merge_size, + min_pixels=self.min_pixels, + max_pixels=self.max_pixels, + ) + image = resize( + image, + size=(resized_height, resized_width), + resample=resample, + input_data_format=input_data_format, + ) + + if do_rescale: + image = self.rescale( + image, scale=rescale_factor, input_data_format=input_data_format + ) + + if do_normalize: + image = self.normalize( + image=image, + mean=image_mean, + std=image_std, + input_data_format=input_data_format, + ) + image = to_channel_dimension_format( + image, data_format, input_channel_dim=input_data_format + ) + processed_images.append(image) + + patches = np.array(processed_images) + if data_format == ChannelDimension.LAST: + patches = patches.transpose(0, 3, 1, 2) + if patches.shape[0] == 1: + patches = np.tile(patches, (self.temporal_patch_size, 1, 1, 1)) + init_patches = patches + channel = patches.shape[1] + grid_t = patches.shape[0] // self.temporal_patch_size + grid_h, grid_w = ( + resized_height // self.patch_size, + resized_width // self.patch_size, + ) + patches = patches.reshape( + grid_t, + self.temporal_patch_size, + channel, + grid_h, + self.patch_size, + grid_w, + self.patch_size, + ) + patches = patches.transpose(0, 3, 5, 2, 1, 4, 6) + assert self.temporal_patch_size == 1 + flatten_patches = patches.reshape( + grid_t * grid_h * grid_w, channel, self.patch_size, self.patch_size + ) + return flatten_patches, (grid_t, grid_h, grid_w) + + def preprocess( + self, + images: ImageInput, + videos: VideoInput = None, + do_resize: bool = None, + size: Dict[str, int] = None, + resample: PILImageResampling = None, + do_rescale: bool = None, + rescale_factor: float = None, + do_normalize: bool = None, + image_mean: Optional[Union[float, List[float]]] = None, + image_std: Optional[Union[float, List[float]]] = None, + do_convert_rgb: bool = None, + return_tensors: Optional[Union[str, TensorType]] = None, + data_format: Optional[ChannelDimension] = ChannelDimension.FIRST, + input_data_format: Optional[Union[str, ChannelDimension]] = None, + ): + """ + Args: + images (`ImageInput`): + Image to preprocess. Expects a single or batch of images with pixel values ranging from 0 to 255. If + passing in images with pixel values between 0 and 1, set `do_rescale=False`. + videos (`VideoInput`): + Video to preprocess. Expects a single or batch of videos with pixel values ranging from 0 to 255. If + passing in videos with pixel values between 0 and 1, set `do_rescale=False`. + do_resize (`bool`, *optional*, defaults to `self.do_resize`): + Whether to resize the image. + size (`Dict[str, int]`, *optional*, defaults to `self.size`): + Size of the image after resizing. Shortest edge of the image is resized to size["shortest_edge"], with + the longest edge resized to keep the input aspect ratio. + resample (`int`, *optional*, defaults to `self.resample`): + Resampling filter to use if resizing the image. This can be one of the enum `PILImageResampling`. Only + has an effect if `do_resize` is set to `True`. + do_rescale (`bool`, *optional*, defaults to `self.do_rescale`): + Whether to rescale the image. + rescale_factor (`float`, *optional*, defaults to `self.rescale_factor`): + Rescale factor to rescale the image by if `do_rescale` is set to `True`. + do_normalize (`bool`, *optional*, defaults to `self.do_normalize`): + Whether to normalize the image. + image_mean (`float` or `List[float]`, *optional*, defaults to `self.image_mean`): + Image mean to use for normalization. Only has an effect if `do_normalize` is set to `True`. + image_std (`float` or `List[float]`, *optional*, defaults to `self.image_std`): + Image standard deviation to use for normalization. Only has an effect if `do_normalize` is set to + `True`. + do_convert_rgb (`bool`, *optional*, defaults to `self.do_convert_rgb`): + Whether to convert the image to RGB. + return_tensors (`str` or `TensorType`, *optional*): + The type of tensors to return. Can be one of: + - Unset: Return a list of `np.ndarray`. + - `TensorType.TENSORFLOW` or `'tf'`: Return a batch of type `tf.Tensor`. + - `TensorType.PYTORCH` or `'pt'`: Return a batch of type `torch.Tensor`. + - `TensorType.NUMPY` or `'np'`: Return a batch of type `np.ndarray`. + - `TensorType.JAX` or `'jax'`: Return a batch of type `jax.numpy.ndarray`. + data_format (`ChannelDimension` or `str`, *optional*, defaults to `ChannelDimension.FIRST`): + The channel dimension format for the output image. Can be one of: + - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. + - `"channels_last"` or `ChannelDimension.LAST`: image in (height, width, num_channels) format. + - Unset: Use the channel dimension format of the input image. + input_data_format (`ChannelDimension` or `str`, *optional*): + The channel dimension format for the input image. If unset, the channel dimension format is inferred + from the input image. Can be one of: + - `"channels_first"` or `ChannelDimension.FIRST`: image in (num_channels, height, width) format. + - `"channels_last"` or `ChannelDimension.LAST`: image in (height, width, num_channels) format. + - `"none"` or `ChannelDimension.NONE`: image in (height, width) format. + + """ + do_resize = do_resize if do_resize is not None else self.do_resize + size = size if size is not None else self.size + resample = resample if resample is not None else self.resample + do_rescale = do_rescale if do_rescale is not None else self.do_rescale + rescale_factor = ( + rescale_factor if rescale_factor is not None else self.rescale_factor + ) + do_normalize = do_normalize if do_normalize is not None else self.do_normalize + image_mean = image_mean if image_mean is not None else self.image_mean + image_std = image_std if image_std is not None else self.image_std + do_convert_rgb = ( + do_convert_rgb if do_convert_rgb is not None else self.do_convert_rgb + ) + + if images is not None: + images = make_batched_images(images) + if videos is not None: + videos = make_batched_videos(videos) + + if images is not None and not valid_images(images): + raise ValueError( + "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, " + "torch.Tensor, tf.Tensor or jax.ndarray." + ) + + validate_preprocess_arguments( + rescale_factor=rescale_factor, + do_normalize=do_normalize, + image_mean=image_mean, + image_std=image_std, + do_resize=do_resize, + size=size, + resample=resample, + ) + + if images is not None: + pixel_values, vision_grid_thws = [], [] + for image in images: + patches, image_grid_thw = self._preprocess( + image, + do_resize=do_resize, + resample=resample, + do_rescale=do_rescale, + rescale_factor=rescale_factor, + do_normalize=do_normalize, + image_mean=image_mean, + image_std=image_std, + data_format=data_format, + do_convert_rgb=do_convert_rgb, + input_data_format=input_data_format, + ) + pixel_values.extend(patches) + vision_grid_thws.append(image_grid_thw) + pixel_values = np.array(pixel_values) + vision_grid_thws = np.array(vision_grid_thws) + data = {"pixel_values": pixel_values, "image_grid_thw": vision_grid_thws} + + if videos is not None: + pixel_values, vision_grid_thws = [], [] + for images in videos: + patches, video_grid_thw = self._preprocess( + images, + do_resize=do_resize, + resample=resample, + do_rescale=do_rescale, + rescale_factor=rescale_factor, + do_normalize=do_normalize, + image_mean=image_mean, + image_std=image_std, + data_format=data_format, + do_convert_rgb=do_convert_rgb, + input_data_format=input_data_format, + ) + pixel_values.extend(patches) + vision_grid_thws.append(video_grid_thw) + pixel_values = np.array(pixel_values) + vision_grid_thws = np.array(vision_grid_thws) + data = { + "pixel_values_videos": pixel_values, + "video_grid_thw": vision_grid_thws, + } + + return BatchFeature(data=data, tensor_type=return_tensors) diff --git a/paddleocr_vl_1-5_tokenizer/inference.yml b/paddleocr_vl_1-5_tokenizer/inference.yml new file mode 100644 index 0000000000000000000000000000000000000000..54233cae9b6e8228e326d767ea95574df7ff9a23 --- /dev/null +++ b/paddleocr_vl_1-5_tokenizer/inference.yml @@ -0,0 +1,2 @@ +Global: + model_name: PaddleOCR-VL-1.5-0.9B \ No newline at end of file diff --git a/paddleocr_vl_1-5_tokenizer/modeling_paddleocr_vl.py b/paddleocr_vl_1-5_tokenizer/modeling_paddleocr_vl.py new file mode 100644 index 0000000000000000000000000000000000000000..ee96320ccaafc602e9ff764057f697ff576bb084 --- /dev/null +++ b/paddleocr_vl_1-5_tokenizer/modeling_paddleocr_vl.py @@ -0,0 +1,2651 @@ +# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import math +import warnings +from dataclasses import dataclass +from typing import Any, Callable, Dict, List, Optional, Tuple, Union + +import numpy as np +import torch +import torch.nn as nn +import torch.nn.functional as F +from torch.nn import CrossEntropyLoss +from torch.nn.init import _calculate_fan_in_and_fan_out +from transformers.activations import ACT2FN, GELUActivation +from transformers.cache_utils import ( + Cache, + DynamicCache, + SlidingWindowCache, + StaticCache, +) +from transformers.generation import GenerationMixin +from transformers.integrations import use_kernel_forward_from_hub +from transformers.modeling_attn_mask_utils import AttentionMaskConverter +from transformers.modeling_layers import GradientCheckpointingLayer +from transformers.modeling_outputs import ( + BaseModelOutput, + BaseModelOutputWithPast, + BaseModelOutputWithPooling, + CausalLMOutputWithPast, +) +from transformers.modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update +from transformers.modeling_utils import ( + ALL_ATTENTION_FUNCTIONS, + PreTrainedModel, + sdpa_attention_forward, +) +from transformers.processing_utils import Unpack +from transformers.utils import ( + ModelOutput, + TransformersKwargs, + auto_docstring, + can_return_tuple, + is_flash_attn_2_available, + torch_int, +) +from transformers.utils.generic import check_model_inputs + +if is_flash_attn_2_available(): + from flash_attn import flash_attn_varlen_func + from flash_attn.layers.rotary import apply_rotary_emb +else: + flash_attn_varlen_func = None + apply_rotary_emb = None + +from .configuration_paddleocr_vl import PaddleOCRVisionConfig, PaddleOCRVLConfig + + +class RotaryEmbedding(nn.Module): + def __init__(self, config: PaddleOCRVLConfig, device=None): + super().__init__() + self.rope_kwargs = {} + + # BC: "rope_type" was originally "type" + if config.rope_scaling is not None: + self.rope_type = config.rope_scaling.get( + "rope_type", config.rope_scaling.get("type") + ) + else: + self.rope_type = "default" + self.max_seq_len_cached = config.max_position_embeddings + self.original_max_seq_len = config.max_position_embeddings + + # BC: "rope_type" was originally "type" + if hasattr(config, "rope_scaling") and config.rope_scaling is not None: + self.rope_type = config.rope_scaling.get( + "rope_type", config.rope_scaling.get("type") + ) + else: + self.rope_type = "default" + self.max_seq_len_cached = config.max_position_embeddings + self.original_max_seq_len = config.max_position_embeddings + + self.config = config + self.rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type] + + inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device) + self.register_buffer("inv_freq", inv_freq, persistent=False) + self.original_inv_freq = self.inv_freq + + def _dynamic_frequency_update(self, position_ids, device): + """ + dynamic RoPE layers should recompute `inv_freq` in the following situations: + 1 - growing beyond the cached sequence length (allow scaling) + 2 - the current sequence length is in the original scale (avoid losing precision with small sequences) + """ + seq_len = torch.max(position_ids) + 1 + if seq_len > self.max_seq_len_cached: + inv_freq, self.attention_scaling = self.rope_init_fn( + self.config, device, seq_len=seq_len, **self.rope_kwargs + ) + self.register_buffer("inv_freq", inv_freq, persistent=False) + self.max_seq_len_cached = seq_len + + if ( + seq_len < self.original_max_seq_len + and self.max_seq_len_cached > self.original_max_seq_len + ): + self.register_buffer("inv_freq", self.original_inv_freq, persistent=False) + self.max_seq_len_cached = self.original_max_seq_len + + @torch.no_grad() + def forward(self, x, position_ids): + if "dynamic" in self.rope_type: + self._dynamic_frequency_update(position_ids, device=x.device) + + inv_freq_expanded = ( + self.inv_freq[None, None, :, None] + .float() + .expand(3, position_ids.shape[1], -1, 1) + ) + position_ids_expanded = position_ids[ + :, :, None, : + ].float() # shape (3, bs, 1, positions) + # Force float32 (see https://github.com/huggingface/transformers/pull/29285) + device_type = x.device.type + device_type = ( + device_type + if isinstance(device_type, str) and device_type != "mps" + else "cpu" + ) + with torch.autocast(device_type=device_type, enabled=False): + freqs = ( + inv_freq_expanded.float() @ position_ids_expanded.float() + ).transpose(2, 3) + emb = torch.cat((freqs, freqs), dim=-1) + cos = emb.cos() + sin = emb.sin() + + # Advanced RoPE types (e.g. yarn) apply a post-processing scaling factor, equivalent to scaling attention + cos = cos * self.attention_scaling + sin = sin * self.attention_scaling + + return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype) + + def rope_init(self): + inv_freq, self.attention_scaling = self.rope_init_fn( + self.config, device=None, **self.rope_kwargs + ) + self.register_buffer("inv_freq", inv_freq, persistent=False) + self.original_inv_freq = self.inv_freq + + +class Ernie4_5RotaryEmbedding(nn.Module): + def __init__(self, config: PaddleOCRVLConfig, device=None): + super().__init__() + # BC: "rope_type" was originally "type" + if hasattr(config, "rope_scaling") and isinstance(config.rope_scaling, dict): + self.rope_type = config.rope_scaling.get( + "rope_type", config.rope_scaling.get("type") + ) + else: + self.rope_type = "default" + self.max_seq_len_cached = config.max_position_embeddings + self.original_max_seq_len = config.max_position_embeddings + + self.config = config + self.rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type] + + inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device) + self.register_buffer("inv_freq", inv_freq, persistent=False) + self.original_inv_freq = self.inv_freq + + @torch.no_grad() + @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope) + def forward(self, x, position_ids): + inv_freq_expanded = ( + self.inv_freq[None, :, None] + .float() + .expand(position_ids.shape[0], -1, 1) + .to(x.device) + ) + position_ids_expanded = position_ids[:, None, :].float() + device_type = ( + x.device.type + if isinstance(x.device.type, str) and x.device.type != "mps" + else "cpu" + ) + with torch.autocast(device_type=device_type, enabled=False): # Force float32 + freqs = ( + inv_freq_expanded.float() @ position_ids_expanded.float() + ).transpose(1, 2) + emb = torch.cat((freqs, freqs), dim=-1) + cos = emb.cos() * self.attention_scaling + sin = emb.sin() * self.attention_scaling + + # keeping it in full precision + return cos, sin + + +class Ernie4_5MLP(nn.Module): + def __init__(self, config: PaddleOCRVLConfig): + super().__init__() + self.config = config + self.hidden_size = config.hidden_size + self.intermediate_size = config.intermediate_size + + self.gate_proj = nn.Linear( + self.hidden_size, self.intermediate_size, bias=config.use_bias + ) + self.up_proj = nn.Linear( + self.hidden_size, self.intermediate_size, bias=config.use_bias + ) + self.down_proj = nn.Linear( + self.intermediate_size, self.hidden_size, bias=config.use_bias + ) + self.act_fn = ACT2FN[config.hidden_act] + + def forward(self, x): + down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x)) + return down_proj + + +def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor: + """ + This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch, + num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim) + """ + batch, num_key_value_heads, slen, head_dim = hidden_states.shape + if n_rep == 1: + return hidden_states + hidden_states = hidden_states[:, :, None, :, :].expand( + batch, num_key_value_heads, n_rep, slen, head_dim + ) + return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim) + + +def eager_attention_forward_ernie( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: float, + dropout: float = 0.0, + **kwargs: Unpack[TransformersKwargs], +): + key_states = repeat_kv(key, module.num_key_value_groups) + value_states = repeat_kv(value, module.num_key_value_groups) + + attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling + if attention_mask is not None: + causal_mask = attention_mask[:, :, :, : key_states.shape[-2]] + attn_weights = attn_weights + causal_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to( + query.dtype + ) + attn_weights = nn.functional.dropout( + attn_weights, p=dropout, training=module.training + ) + attn_output = torch.matmul(attn_weights, value_states) + attn_output = attn_output.transpose(1, 2).contiguous() + + return attn_output, attn_weights + + +def apply_rotary_pos_emb(q, k, cos, sin, position_ids=None, unsqueeze_dim=1): + """Applies Rotary Position Embedding to the query and key tensors. + + Args: + q (`torch.Tensor`): The query tensor. + k (`torch.Tensor`): The key tensor. + cos (`torch.Tensor`): The cosine part of the rotary embedding. + sin (`torch.Tensor`): The sine part of the rotary embedding. + position_ids (`torch.Tensor`, *optional*): + Deprecated and unused. + unsqueeze_dim (`int`, *optional*, defaults to 1): + The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and + sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note + that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and + k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes + cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have + the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2. + Returns: + `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding. + """ + # glm rope style (with full dim) and full precision + original_dtype = q.dtype + cos = cos.unsqueeze(unsqueeze_dim) + sin = sin.unsqueeze(unsqueeze_dim) + + # Interleave them instead of usual shape + cos = cos[..., : cos.shape[-1] // 2].repeat_interleave(2, dim=-1) + sin = sin[..., : sin.shape[-1] // 2].repeat_interleave(2, dim=-1) + + q_embed = (q.float() * cos) + (rotate_half(q).float() * sin) + k_embed = (k.float() * cos) + (rotate_half(k).float() * sin) + + return q_embed.to(original_dtype), k_embed.to(original_dtype) + + +def apply_multimodal_rotary_pos_emb(q, k, cos, sin, mrope_section, unsqueeze_dim=1): + """Applies Rotary Position Embedding with Multimodal Sections to the query and key tensors (https://qwenlm.github.io/blog/qwen2-vl/). + + Explanation: + Multimodal 3D rotary position embedding is an extension to 1D rotary position embedding. The input embedding + sequence contains vision (images / videos) embedding and text embedding or just contains text embedding. For + vision embedding part, we apply rotary position embedding on temporal, height and width dimension separately. + Here we split the channel dimension to 3 chunks for the temporal, height and width rotary position embedding. + For text embedding part, we just apply 1D rotary position embedding. The three rotary position index (temporal, + height and width) of text embedding is always the same, so the text embedding rotary position embedding has no + difference with modern LLMs. + + Args: + q (`torch.Tensor`): The query tensor. + k (`torch.Tensor`): The key tensor. + cos (`torch.Tensor`): The cosine part of the rotary embedding. + sin (`torch.Tensor`): The sine part of the rotary embedding. + position_ids (`torch.Tensor`): + The position indices of the tokens corresponding to the query and key tensors. For example, this can be + used to pass offsetted position ids when working with a KV-cache. + mrope_section(`List(int)`): + Multimodal rope section is for channel dimension of temporal, height and width in rope calculation. + unsqueeze_dim (`int`, *optional*, defaults to 1): + The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and + sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note + that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and + k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes + cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have + the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2. + Returns: + `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding. + """ + mrope_section = mrope_section * 2 + cos = torch.cat( + [m[i % 3] for i, m in enumerate(cos.split(mrope_section, dim=-1))], dim=-1 + ).unsqueeze(unsqueeze_dim) + sin = torch.cat( + [m[i % 3] for i, m in enumerate(sin.split(mrope_section, dim=-1))], dim=-1 + ).unsqueeze(unsqueeze_dim) + + q_embed = (q * cos) + (rotate_half(q) * sin) + k_embed = (k * cos) + (rotate_half(k) * sin) + return q_embed, k_embed + + +class Ernie4_5Attention(nn.Module): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__(self, config: PaddleOCRVLConfig, layer_idx: int): + super().__init__() + self.config = config + self.layer_idx = layer_idx + self.head_dim = getattr( + config, "head_dim", config.hidden_size // config.num_attention_heads + ) + self.num_key_value_groups = ( + config.num_attention_heads // config.num_key_value_heads + ) + self.scaling = self.head_dim**-0.5 + self.rope_scaling = config.rope_scaling + self.attention_dropout = 0.0 + self.is_causal = True + self.q_proj = nn.Linear( + config.hidden_size, + config.num_attention_heads * self.head_dim, + bias=config.use_bias, + ) + self.k_proj = nn.Linear( + config.hidden_size, + config.num_key_value_heads * self.head_dim, + bias=config.use_bias, + ) + self.v_proj = nn.Linear( + config.hidden_size, + config.num_key_value_heads * self.head_dim, + bias=config.use_bias, + ) + self.o_proj = nn.Linear( + config.num_attention_heads * self.head_dim, + config.hidden_size, + bias=config.use_bias, + ) + + def forward( + self, + hidden_states: torch.Tensor, + position_embeddings: tuple[torch.Tensor, torch.Tensor], + attention_mask: Optional[torch.Tensor], + past_key_value: Optional[Cache] = None, + cache_position: Optional[torch.LongTensor] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor, torch.Tensor]: + input_shape = hidden_states.shape[:-1] + hidden_shape = (*input_shape, -1, self.head_dim) + + query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2) + key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2) + value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2) + + if "position_ids" in kwargs and kwargs["position_ids"] is not None: + position_ids = kwargs["position_ids"] + if position_ids.dim() == 3 and position_ids.shape[0] > 1: + kwargs["position_ids"] = position_ids[0:1] + + cos, sin = position_embeddings + query_states, key_states = apply_multimodal_rotary_pos_emb( + query_states, key_states, cos, sin, self.rope_scaling["mrope_section"] + ) + + if past_key_value is not None: + # sin and cos are specific to RoPE models; cache_position needed for the static cache + cache_kwargs = {"sin": sin, "cos": cos, "cache_position": cache_position} + key_states, value_states = past_key_value.update( + key_states, value_states, self.layer_idx, cache_kwargs + ) + + attention_interface: Callable = eager_attention_forward_ernie + if self.config._attn_implementation != "eager": + attention_interface = ALL_ATTENTION_FUNCTIONS[ + self.config._attn_implementation + ] + + attn_output, attn_weights = attention_interface( + self, + query_states, + key_states, + value_states, + attention_mask, + dropout=0.0 if not self.training else self.attention_dropout, + scaling=self.scaling, + **kwargs, + ) + + attn_output = attn_output.reshape(*input_shape, -1).contiguous() + attn_output = self.o_proj(attn_output) + return attn_output, attn_weights + + +@use_kernel_forward_from_hub("RMSNorm") +class Ernie4_5RMSNorm(nn.Module): + def __init__(self, hidden_size, eps=1e-6): + """ + Ernie4_5RMSNorm is equivalent to T5LayerNorm + """ + super().__init__() + self.weight = nn.Parameter(torch.ones(hidden_size)) + self.variance_epsilon = eps + + def forward(self, hidden_states): + input_dtype = hidden_states.dtype + hidden_states = hidden_states.to(torch.float32) + variance = hidden_states.pow(2).mean(-1, keepdim=True) + hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon) + return self.weight * hidden_states.to(input_dtype) + + def extra_repr(self): + return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}" + + +class Ernie4_5DecoderLayer(GradientCheckpointingLayer): + def __init__(self, config: PaddleOCRVLConfig, layer_idx: int): + super().__init__() + self.hidden_size = config.hidden_size + + self.self_attn = Ernie4_5Attention(config=config, layer_idx=layer_idx) + + self.mlp = Ernie4_5MLP(config) + self.input_layernorm = Ernie4_5RMSNorm( + config.hidden_size, eps=config.rms_norm_eps + ) + self.post_attention_layernorm = Ernie4_5RMSNorm( + config.hidden_size, eps=config.rms_norm_eps + ) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_value: Optional[Cache] = None, + use_cache: Optional[bool] = False, + cache_position: Optional[torch.LongTensor] = None, + position_embeddings: Optional[ + tuple[torch.Tensor, torch.Tensor] + ] = None, # necessary, but kept here for BC + **kwargs: Unpack[TransformersKwargs], + ) -> tuple[torch.Tensor]: + residual = hidden_states + hidden_states = self.input_layernorm(hidden_states) + # Self Attention + hidden_states, _ = self.self_attn( + hidden_states=hidden_states, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_value=past_key_value, + use_cache=use_cache, + cache_position=cache_position, + position_embeddings=position_embeddings, + **kwargs, + ) + hidden_states = residual + hidden_states + + # Fully Connected + residual = hidden_states + hidden_states = self.post_attention_layernorm(hidden_states) + hidden_states = self.mlp(hidden_states) + hidden_states = residual + hidden_states + return hidden_states + + +@auto_docstring +class Ernie4_5PreTrainedModel(PreTrainedModel): + config: PaddleOCRVLConfig + base_model_prefix = "model" + supports_gradient_checkpointing = True + _no_split_modules = ["Ernie4_5DecoderLayer"] + _skip_keys_device_placement = ["past_key_values"] + _supports_flash_attn = True + _supports_sdpa = True + _supports_flex_attn = True + + _can_compile_fullgraph = True + _supports_attention_backend = True + _can_record_outputs = { + "hidden_states": Ernie4_5DecoderLayer, + "attentions": Ernie4_5Attention, + } + + +@auto_docstring +class Ernie4_5Model(Ernie4_5PreTrainedModel): + def __init__(self, config: PaddleOCRVLConfig): + super().__init__(config) + self.padding_idx = config.pad_token_id + self.vocab_size = config.vocab_size + + self.embed_tokens = nn.Embedding( + config.vocab_size, config.hidden_size, self.padding_idx + ) + self.layers = nn.ModuleList( + [ + Ernie4_5DecoderLayer(config, layer_idx) + for layer_idx in range(config.num_hidden_layers) + ] + ) + self.norm = Ernie4_5RMSNorm(config.hidden_size, eps=config.rms_norm_eps) + self.rotary_emb = RotaryEmbedding(config=config) + self.gradient_checkpointing = False + + # Initialize weights and apply final processing + self.post_init() + + @check_model_inputs + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + cache_position: Optional[torch.LongTensor] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + **kwargs: Unpack[TransformersKwargs], + ) -> BaseModelOutputWithPast: + if (input_ids is None) ^ (inputs_embeds is not None): + raise ValueError( + "You must specify exactly one of input_ids or inputs_embeds" + ) + + if inputs_embeds is None: + inputs_embeds: torch.Tensor = self.embed_tokens(input_ids) + + if use_cache and past_key_values is None: + past_key_values = DynamicCache() + + if cache_position is None: + past_seen_tokens = ( + past_key_values.get_seq_length() if past_key_values is not None else 0 + ) + cache_position: torch.Tensor = torch.arange( + past_seen_tokens, + past_seen_tokens + inputs_embeds.shape[1], + device=inputs_embeds.device, + ) + + if position_ids is None: + position_ids = cache_position.view(1, 1, -1).expand( + 3, inputs_embeds.shape[0], -1 + ) + elif position_ids.dim() == 2: + position_ids = position_ids[None, ...].expand(3, position_ids.shape[0], -1) + + causal_mask = self._update_causal_mask( + attention_mask, + inputs_embeds, + cache_position, + past_key_values, + output_attentions, + ) + + hidden_states = inputs_embeds + position_embeddings = self.rotary_emb(hidden_states, position_ids) + + for decoder_layer in self.layers[: self.config.num_hidden_layers]: + hidden_states = decoder_layer( + hidden_states, + attention_mask=causal_mask, + position_ids=position_ids, + past_key_value=past_key_values, + cache_position=cache_position, + position_embeddings=position_embeddings, + **kwargs, + ) + + hidden_states = self.norm(hidden_states) + return BaseModelOutputWithPast( + last_hidden_state=hidden_states, + past_key_values=past_key_values, + ) + + def _update_causal_mask( + self, + attention_mask: torch.Tensor, + input_tensor: torch.Tensor, + cache_position: torch.Tensor, + past_key_values: Cache, + output_attentions: bool = False, + ): + if self.config._attn_implementation == "flash_attention_2": + if attention_mask is not None and past_key_values is not None: + is_padding_right = ( + attention_mask[:, -1].sum().item() != input_tensor.size()[0] + ) + if is_padding_right: + raise ValueError + if attention_mask is not None and 0.0 in attention_mask: + return attention_mask + return None + + # For SDPA, when possible, we will rely on its `is_causal` argument instead of its `attn_mask` argument, in + # order to dispatch on Flash Attention 2. This feature is not compatible with static cache, as SDPA will fail + # to infer the attention mask. + past_seen_tokens = ( + past_key_values.get_seq_length() if past_key_values is not None else 0 + ) + using_static_cache = isinstance(past_key_values, StaticCache) + using_sliding_window_cache = isinstance(past_key_values, SlidingWindowCache) + + # When output attentions is True, sdpa implementation's forward method calls the eager implementation's forward + if ( + self.config._attn_implementation == "sdpa" + and not (using_static_cache or using_sliding_window_cache) + and not output_attentions + ): + if AttentionMaskConverter._ignore_causal_mask_sdpa( + attention_mask, + inputs_embeds=input_tensor, + past_key_values_length=past_seen_tokens, + sliding_window=self.config.sliding_window, + is_training=self.training, + ): + return None + + dtype, device = input_tensor.dtype, input_tensor.device + min_dtype = torch.finfo(dtype).min + sequence_length = input_tensor.shape[1] + # SlidingWindowCache or StaticCache + if using_sliding_window_cache or using_static_cache: + target_length = past_key_values.get_max_cache_shape() + # DynamicCache or no cache + else: + target_length = ( + attention_mask.shape[-1] + if isinstance(attention_mask, torch.Tensor) + else past_seen_tokens + sequence_length + 1 + ) + + # In case the provided `attention` mask is 2D, we generate a causal mask here (4D). + causal_mask = self._prepare_4d_causal_attention_mask_with_cache_position( + attention_mask, + sequence_length=sequence_length, + target_length=target_length, + dtype=dtype, + device=device, + cache_position=cache_position, + batch_size=input_tensor.shape[0], + config=self.config, + past_key_values=past_key_values, + ) + + if ( + self.config._attn_implementation == "sdpa" + and attention_mask is not None + and attention_mask.device.type in ["cuda", "xpu"] + and not output_attentions + ): + # Attend to all tokens in fully masked rows in the causal_mask, for example the relevant first rows when + # using left padding. This is required by F.scaled_dot_product_attention memory-efficient attention path. + # Details: https://github.com/pytorch/pytorch/issues/110213 + causal_mask = AttentionMaskConverter._unmask_unattended( + causal_mask, min_dtype + ) + + return causal_mask + + @staticmethod + def _prepare_4d_causal_attention_mask_with_cache_position( + attention_mask: torch.Tensor, + sequence_length: int, + target_length: int, + dtype: torch.dtype, + device: torch.device, + cache_position: torch.Tensor, + batch_size: int, + config: PaddleOCRVLConfig, + past_key_values: Cache, + ): + """ + Creates a causal 4D mask of shape `(batch_size, 1, query_length, key_value_length)` from a 2D mask of shape + `(batch_size, key_value_length)`, or if the input `attention_mask` is already 4D, do nothing. + + Args: + attention_mask (`torch.Tensor`): + A 2D attention mask of shape `(batch_size, key_value_length)` or a 4D attention mask of shape `(batch_size, 1, query_length, key_value_length)`. + sequence_length (`int`): + The sequence length being processed. + target_length (`int`): + The target length: when generating with static cache, the mask should be as long as the static cache, to account for the 0 padding, the part of the cache that is not filled yet. + dtype (`torch.dtype`): + The dtype to use for the 4D attention mask. + device (`torch.device`): + The device to place the 4D attention mask on. + cache_position (`torch.Tensor`): + Indices depicting the position of the input sequence tokens in the sequence. + batch_size (`torch.Tensor`): + Batch size. + config (`PaddleOCRVLConfig`): + The model's configuration class + past_key_values (`Cache`): + The cache class that is being used currently to generate + """ + if attention_mask is not None and attention_mask.dim() == 4: + # In this case we assume that the mask comes already in inverted form and requires no inversion or slicing. + causal_mask = attention_mask + else: + min_dtype = torch.finfo(dtype).min + causal_mask = torch.full( + (sequence_length, target_length), + fill_value=min_dtype, + dtype=dtype, + device=device, + ) + diagonal_attend_mask = torch.arange( + target_length, device=device + ) > cache_position.reshape(-1, 1) + if config.sliding_window is not None: + # if we have sliding window, we should not attend to tokens beyond sliding window length, so we mask them out also + # the check is needed to verify is current checkpoint was trained with sliding window or not + if ( + not isinstance(past_key_values, SlidingWindowCache) + or sequence_length > target_length + ): + sliding_attend_mask = torch.arange( + target_length, device=device + ) <= (cache_position.reshape(-1, 1) - config.sliding_window) + diagonal_attend_mask.bitwise_or_(sliding_attend_mask) + causal_mask *= diagonal_attend_mask + causal_mask = causal_mask[None, None, :, :].expand(batch_size, 1, -1, -1) + if attention_mask is not None: + causal_mask = ( + causal_mask.clone() + ) # copy to contiguous memory for in-place edit + if attention_mask.shape[-1] > target_length: + attention_mask = attention_mask[:, :target_length] + mask_length = attention_mask.shape[-1] + padding_mask = causal_mask[:, :, :, :mask_length] + attention_mask[ + :, None, None, : + ].to(causal_mask.device) + padding_mask = padding_mask == 0 + causal_mask[:, :, :, :mask_length] = causal_mask[ + :, :, :, :mask_length + ].masked_fill(padding_mask, min_dtype) + return causal_mask + + +class Ernie4_5ForCausalLM(Ernie4_5PreTrainedModel, GenerationMixin): + _tied_weights_keys = ["lm_head.weight"] + _tp_plan = {"lm_head": "colwise_rep"} + _pp_plan = {"lm_head": (["hidden_states"], ["logits"])} + + def __init__(self, config): + super().__init__(config) + self.model = Ernie4_5Model(config) + self.vocab_size = config.vocab_size + self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False) + + # Initialize weights and apply final processing + self.post_init() + + def set_decoder(self, decoder): + self.model = decoder + + def get_decoder(self): + return self.model + + @can_return_tuple + def forward( + self, + input_ids: Optional[torch.LongTensor] = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[Cache] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + use_cache: Optional[bool] = None, + cache_position: Optional[torch.LongTensor] = None, + logits_to_keep: Union[int, torch.Tensor] = 0, + **kwargs: Unpack[TransformersKwargs], + ) -> CausalLMOutputWithPast: + r""" + labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*): + Labels for computing the masked language modeling loss. Indices should either be in `[0, ..., + config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored + (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`. + """ + outputs: BaseModelOutputWithPast = self.model( + input_ids=input_ids, + attention_mask=attention_mask, + position_ids=position_ids, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + use_cache=use_cache, + cache_position=cache_position, + **kwargs, + ) + + hidden_states = outputs.last_hidden_state + # Only compute necessary logits, and do not upcast them to float if we are not computing the loss + slice_indices = ( + slice(-logits_to_keep, None) + if isinstance(logits_to_keep, int) + else logits_to_keep + ) + logits = self.lm_head(hidden_states[:, slice_indices, :]) + + loss = None + if labels is not None: + loss = self.loss_function( + logits=logits, + labels=labels, + vocab_size=self.config.vocab_size, + **kwargs, + ) + + return CausalLMOutputWithPast( + loss=loss, + logits=logits, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + ) + + +def _trunc_normal_(tensor, mean, std, a, b): + # Cut & paste from PyTorch official master until it's in a few official releases - RW + # Method based on https://people.sc.fsu.edu/~jburkardt/presentations/truncated_normal.pdf + def norm_cdf(x): + # Computes standard normal cumulative distribution function + return (1.0 + math.erf(x / math.sqrt(2.0))) / 2.0 + + if (mean < a - 2 * std) or (mean > b + 2 * std): + warnings.warn( + "mean is more than 2 std from [a, b] in nn.init.trunc_normal_. " + "The distribution of values may be incorrect.", + stacklevel=2, + ) + + # Values are generated by using a truncated uniform distribution and + # then using the inverse CDF for the normal distribution. + # Get upper and lower cdf values + l = norm_cdf((a - mean) / std) + u = norm_cdf((b - mean) / std) + + # Uniformly fill tensor with values from [l, u], then translate to + # [2l-1, 2u-1]. + tensor.uniform_(2 * l - 1, 2 * u - 1) + + # Use inverse cdf transform for normal distribution to get truncated + # standard normal + tensor.erfinv_() + + # Transform to proper mean, std + tensor.mul_(std * math.sqrt(2.0)) + tensor.add_(mean) + + # Clamp to ensure it's in the proper range + tensor.clamp_(min=a, max=b) + + +def trunc_normal_tf_( + tensor: torch.Tensor, + mean: float = 0.0, + std: float = 1.0, + a: float = -2.0, + b: float = 2.0, +) -> torch.Tensor: + """Fills the input Tensor with values drawn from a truncated + normal distribution. The values are effectively drawn from the + normal distribution :math:`\\mathcal{N}(\text{mean}, \text{std}^2)` + with values outside :math:`[a, b]` redrawn until they are within + the bounds. The method used for generating the random values works + best when :math:`a \\leq \text{mean} \\leq b`. + + NOTE: this 'tf' variant behaves closer to Tensorflow / JAX impl where the + bounds [a, b] are applied when sampling the normal distribution with mean=0, std=1.0 + and the result is subsequently scaled and shifted by the mean and std args. + + Args: + tensor: an n-dimensional `torch.Tensor` + mean: the mean of the normal distribution + std: the standard deviation of the normal distribution + a: the minimum cutoff value + b: the maximum cutoff value + """ + with torch.no_grad(): + _trunc_normal_(tensor, 0, 1.0, a, b) + tensor.mul_(std).add_(mean) + + +def variance_scaling_(tensor, scale=1.0, mode="fan_in", distribution="normal"): + fan_in, fan_out = _calculate_fan_in_and_fan_out(tensor) + if mode == "fan_in": + denom = fan_in + elif mode == "fan_out": + denom = fan_out + elif mode == "fan_avg": + denom = (fan_in + fan_out) / 2 + + variance = scale / denom + + if distribution == "truncated_normal": + # constant is stddev of standard normal truncated to (-2, 2) + trunc_normal_tf_(tensor, std=math.sqrt(variance) / 0.87962566103423978) + elif distribution == "normal": + with torch.no_grad(): + tensor.normal_(std=math.sqrt(variance)) + elif distribution == "uniform": + bound = math.sqrt(3 * variance) + with torch.no_grad(): + tensor.uniform_(-bound, bound) + else: + raise ValueError(f"invalid distribution {distribution}") + + +def lecun_normal_(tensor): + variance_scaling_(tensor, mode="fan_in", distribution="truncated_normal") + + +def default_flax_embed_init(tensor): + variance_scaling_(tensor, mode="fan_in", distribution="normal") + + +class Projector(nn.Module): + + def __init__(self, text_config: PaddleOCRVLConfig, vision_config: PaddleOCRVisionConfig): + super().__init__() + self.text_config = text_config + self.vision_config = vision_config + self.merge_kernel_size = (2, 2) + + self.hidden_size = ( + self.vision_config.hidden_size + * self.merge_kernel_size[0] + * self.merge_kernel_size[1] + ) + + self.pre_norm = torch.nn.LayerNorm(self.vision_config.hidden_size, eps=1e-05) + self.linear_1 = nn.Linear(self.hidden_size, self.hidden_size, bias=True) + self.act = GELUActivation() + self.linear_2 = nn.Linear( + self.hidden_size, self.text_config.hidden_size, bias=True + ) + + def forward( + self, image_features: torch.Tensor, image_grid_thw: List[Tuple[int, int, int]] + ) -> torch.Tensor: + m1, m2 = self.merge_kernel_size + if isinstance(image_features, (list, tuple)): + processed_features = list() + for image_feature, image_grid in zip(image_features, image_grid_thw): + image_feature = self.pre_norm(image_feature) + t, h, w = image_grid + from einops import rearrange + + image_feature = rearrange( + image_feature, + "(t h p1 w p2) d -> (t h w) (p1 p2 d)", + t=t, + h=h // m1, + p1=m1, + w=w // m2, + p2=m2, + ) + hidden_states = self.linear_1(image_feature) + hidden_states = self.act(hidden_states) + hidden_states = self.linear_2(hidden_states) + processed_features.append(hidden_states) + + return processed_features + + dims = image_features.shape[:-1] + dim = image_features.shape[-1] + image_features = image_features.view(np.prod(dims), dim) + hidden_states = self.pre_norm(image_features).view(-1, self.hidden_size) + hidden_states = self.linear_1(hidden_states) + hidden_states = self.act(hidden_states) + hidden_states = self.linear_2(hidden_states) + + return hidden_states.view(*dims, -1) + + +class PaddleOCRVisionEmbeddings(nn.Module): + def __init__(self, config: PaddleOCRVisionConfig): + super().__init__() + self.config = config + self.embed_dim = config.hidden_size + self.image_size = config.image_size + self.patch_size = config.patch_size + + self.patch_embedding = nn.Conv2d( + in_channels=config.num_channels, + out_channels=self.embed_dim, + kernel_size=self.patch_size, + stride=self.patch_size, + padding="valid", + ) + + self.num_patches = (self.image_size // self.patch_size) ** 2 + self.num_positions = self.num_patches + self.cache_position_embedding = dict() + self.cache_position_count = dict() + self.position_embedding = nn.Embedding(self.num_positions, self.embed_dim) + self.packing_position_embedding = nn.Embedding(32768, self.embed_dim) + + self.register_buffer( + "position_ids", + torch.arange(self.num_positions).expand((1, -1)), + persistent=False, + ) + + def interpolate_pos_encoding( + self, + embeddings: torch.Tensor, + height: int, + width: int, + is_after_patchify: bool = False, + ) -> torch.Tensor: + """ + This method allows to interpolate the pre-trained position encodings, to be able to use the model on higher resolution + images. This method is also adapted to support torch.jit tracing and no class embeddings. + + Adapted from: + - https://github.com/facebookresearch/dino/blob/de9ee3df6cf39fac952ab558447af1fa1365362a/vision_transformer.py#L174-L194, and + - https://github.com/facebookresearch/dinov2/blob/e1277af2ba9496fbadf7aec6eba56e8d882d1e35/dinov2/models/vision_transformer.py#L179-L211 + """ + num_positions = self.position_embedding.weight.shape[0] + + patch_pos_embed = self.position_embedding.weight.unsqueeze(0) + + dim = embeddings.shape[-1] + + if is_after_patchify: + new_height = height + new_width = width + else: + new_height = height // self.patch_size + new_width = width // self.patch_size + + sqrt_num_positions = torch_int(num_positions**0.5) + patch_pos_embed = patch_pos_embed.reshape( + 1, sqrt_num_positions, sqrt_num_positions, dim + ) + patch_pos_embed = patch_pos_embed.permute(0, 3, 1, 2) + + patch_pos_embed = nn.functional.interpolate( + patch_pos_embed, + size=(new_height, new_width), + mode="bilinear", + align_corners=False, + ) + + patch_pos_embed = patch_pos_embed.permute(0, 2, 3, 1).view(1, -1, dim) + return patch_pos_embed + + @staticmethod + def flatten_list(image_grid_thw): + tmp_image_grid_thw = list() + for image_grid in image_grid_thw: + if isinstance(image_grid, list): + tmp_image_grid_thw.extend(image_grid) + else: + tmp_image_grid_thw.append(image_grid) + return tmp_image_grid_thw + + def fetch_position_embedding_lfu_cache(self, embeddings, h, w, max_cache=20): + grid = (h, w) + if grid in self.cache_position_embedding: + self.cache_position_count[grid] += 1 + return self.cache_position_embedding[grid] + + if len(self.cache_position_embedding) >= max_cache: + min_hit_grid = min( + self.cache_position_count, key=self.cache_position_count.get + ) + self.cache_position_count.pop(min_hit_grid) + self.cache_position_embedding.pop(min_hit_grid) + + position_embedding = self.interpolate_pos_encoding(embeddings, h, w, True) + self.cache_position_count[grid] = 1 + self.cache_position_embedding[grid] = position_embedding + return position_embedding + + def forward( + self, + pixel_values: torch.FloatTensor, + position_ids: Optional[torch.Tensor] = None, + image_grid_thw: Optional[ + List[Union[Tuple[int, int, int], List[Tuple[int, int, int]]]] + ] = None, + interpolate_pos_encoding=False, + ) -> torch.Tensor: + if pixel_values.dim() == 5: + assert position_ids is not None + from einops import rearrange + + batch_size, squence_len, channel, height, width = pixel_values.shape + target_dtype = self.patch_embedding.weight.dtype + pixel_values = rearrange(pixel_values, "b l c h w -> (b l) c h w") + patch_embeds = self.patch_embedding( + pixel_values.to(dtype=target_dtype) + ) # shape = [*, width, grid, grid] + embeddings = patch_embeds.flatten(-2).squeeze(-1) + embeddings = rearrange( + embeddings, "(b l) d -> b l d", b=batch_size, l=squence_len + ) + + # todo: not dubug + if interpolate_pos_encoding and image_grid_thw is not None: + flatten_image_grid_thw = self.flatten_list(image_grid_thw) + assert batch_size == 1 + start = 0 + image_embedding_list = list() + assert ( + sum([np.prod(x) for x in flatten_image_grid_thw]) + == embeddings.shape[1] + ), (flatten_image_grid_thw, embeddings.shape) + embeddings = embeddings.squeeze(0) + tmp_embeddings = list() + for image_grid in image_grid_thw: + t, h, w = image_grid + end = start + t * h * w + image_embeddings = embeddings[start:end, :] + position_embedding = ( + self.interpolate_pos_encoding(image_embeddings, h, w, True) + .squeeze(0) + .repeat(t, 1) + ) + image_embeddings = image_embeddings + position_embedding + tmp_embeddings.append(image_embeddings) + start = end + embeddings = torch.concat(tmp_embeddings, dim=0).unsqueeze(0) + else: + embeddings = embeddings + self.packing_position_embedding(position_ids) + return embeddings + else: + raise NotImplementedError(str(pixel_values.shape)) + + +def eager_attention_forward( + module: nn.Module, + query: torch.Tensor, + key: torch.Tensor, + value: torch.Tensor, + attention_mask: Optional[torch.Tensor], + scaling: float, + dropout: float = 0.0, + **kwargs, +): + attn_weights = torch.matmul(query, key.transpose(-1, -2)) * scaling + if attention_mask is not None: + attn_weights = attn_weights + attention_mask + + attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to( + query.dtype + ) + attn_weights = nn.functional.dropout( + attn_weights, p=dropout, training=module.training + ) + + attn_output = torch.matmul(attn_weights, value) + attn_output = attn_output.transpose(1, 2).contiguous() + + return attn_output, attn_weights + + +class PaddleOCRAttention(nn.Module): + """Multi-headed attention from 'Attention Is All You Need' paper""" + + def __init__(self, config: PaddleOCRVisionConfig): + super().__init__() + self.config = config + self.embed_dim = config.hidden_size + self.num_heads = config.num_attention_heads + self.head_dim = self.embed_dim // self.num_heads + if self.head_dim * self.num_heads != self.embed_dim: + raise ValueError( + f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim} and `num_heads`:" + f" {self.num_heads})." + ) + self.scale = self.head_dim**-0.5 + self.dropout = config.attention_dropout + self.is_causal = False + + self.k_proj = nn.Linear(self.embed_dim, self.embed_dim) + self.v_proj = nn.Linear(self.embed_dim, self.embed_dim) + self.q_proj = nn.Linear(self.embed_dim, self.embed_dim) + self.out_proj = nn.Linear(self.embed_dim, self.embed_dim) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = False, + cu_seqlens: Optional[List[torch.Tensor]] = None, + rope_emb: Optional[Tuple[torch.Tensor, torch.Tensor]] = None, + ) -> Tuple[torch.Tensor, Optional[torch.Tensor]]: + """Input shape: Batch x Time x Channel""" + + use_flash_attn = ( + cu_seqlens is not None + ) and self.config._attn_implementation == "flash_attention_2" + + batch_size, seq_length, embed_dim = hidden_states.shape + + queries = self.q_proj(hidden_states) + keys = self.k_proj(hidden_states) + values = self.v_proj(hidden_states) + + if rope_emb is None: + queries = queries.view( + batch_size, seq_length, self.num_heads, self.head_dim + ).transpose(1, 2) + keys = keys.view( + batch_size, seq_length, self.num_heads, self.head_dim + ).transpose(1, 2) + values = values.view( + batch_size, seq_length, self.num_heads, self.head_dim + ).transpose(1, 2) + else: + assert cu_seqlens is not None, "Rope support flash attn only." + cos, sin = rope_emb + queries = queries.view( + batch_size, seq_length, self.num_heads, self.head_dim + ) + keys = keys.view(batch_size, seq_length, self.num_heads, self.head_dim) + if use_flash_attn: + queries, keys = apply_rotary_pos_emb_flashatt(queries, keys, cos, sin) + else: + queries, keys = apply_rotary_pos_emb_vision(queries, keys, cos, sin) + queries = queries.transpose(1, 2) + keys = keys.transpose(1, 2) + values = values.view( + batch_size, seq_length, self.num_heads, self.head_dim + ).transpose(1, 2) + + if not use_flash_attn: + attention_interface: Callable = eager_attention_forward + if self.config._attn_implementation != "eager": + if self.config._attn_implementation == "sdpa" and output_attentions: + warnings.warn( + "`torch.nn.functional.scaled_dot_product_attention` does not support `output_attentions=True`. Falling back to " + 'eager attention. This warning can be removed using the argument `attn_implementation="eager"` when loading the model.' + ) + elif self.config._attn_implementation == "sdpa": + attention_interface = sdpa_attention_forward + + attn_output, attn_weights = attention_interface( + self, + queries, + keys, + values, + attention_mask, + is_causal=self.is_causal, + scaling=self.scale, + dropout=0.0 if not self.training else self.dropout, + ) + attn_output = attn_output.reshape( + batch_size, seq_length, embed_dim + ).contiguous() + else: + assert batch_size == 1, hidden_states.shape + queries = queries.transpose(1, 2).squeeze(0) + keys = keys.transpose(1, 2).squeeze(0) + values = values.transpose(1, 2).squeeze(0) + + max_seqlen_q = (cu_seqlens[1:] - cu_seqlens[:-1]).max().item() + max_seqlen_k = (cu_seqlens[1:] - cu_seqlens[:-1]).max().item() + assert ( + cu_seqlens[-1].item() + == queries.shape[0] + == keys.shape[0] + == values.shape[0] + ), (cu_seqlens, queries.shape, keys.shape, values.shape) + + attn_output = flash_attn_varlen_func( + queries, + keys, + values, + cu_seqlens, + cu_seqlens, + max_seqlen_q, + max_seqlen_k, + causal=False, + softmax_scale=self.scale, + ) + attn_output = attn_output.flatten(-2).unsqueeze(0) + attn_weights = None + + attn_output = self.out_proj(attn_output) + + if not output_attentions: + attn_weights = None + + return attn_output, attn_weights + + +# Copied from transformers.models.clip.modeling_clip.CLIPMLP with CLIP->PaddleOCR +class PaddleOCRMLP(nn.Module): + def __init__(self, config): + super().__init__() + self.config = config + self.activation_fn = ACT2FN[config.hidden_act] + self.fc1 = nn.Linear(config.hidden_size, config.intermediate_size) + self.fc2 = nn.Linear(config.intermediate_size, config.hidden_size) + + def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: + hidden_states = self.fc1(hidden_states) + hidden_states = self.activation_fn(hidden_states) + hidden_states = self.fc2(hidden_states) + return hidden_states + + +class PaddleOCREncoderLayer(nn.Module): + def __init__(self, config: PaddleOCRVisionConfig): + super().__init__() + self.embed_dim = config.hidden_size + self.layer_norm1 = nn.LayerNorm(self.embed_dim, eps=config.layer_norm_eps) + self.self_attn = PaddleOCRAttention(config) + self.layer_norm2 = nn.LayerNorm(self.embed_dim, eps=config.layer_norm_eps) + self.mlp = PaddleOCRMLP(config) + + def forward( + self, + hidden_states: torch.Tensor, + attention_mask: torch.Tensor, + output_attentions: Optional[bool] = False, + cu_seqlens: Optional[List[torch.Tensor]] = None, + rope_emb: Optional[Tuple[torch.Tensor, torch.Tensor]] = None, + ) -> Tuple[torch.FloatTensor]: + """ + Args: + hidden_states (`torch.FloatTensor`): + Input to the layer of shape `(batch, seq_len, embed_dim)`. + attention_mask (`torch.FloatTensor`): + Attention mask of shape `(batch, 1, q_len, k_v_seq_len)` where padding elements are indicated by very large negative values. + output_attentions (`bool`, *optional*, defaults to `False`): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + """ + residual = hidden_states + + hidden_states = self.layer_norm1(hidden_states) + hidden_states, attn_weights = self.self_attn( + hidden_states=hidden_states, + attention_mask=attention_mask, + output_attentions=output_attentions, + cu_seqlens=cu_seqlens, + rope_emb=rope_emb, + ) + hidden_states = residual + hidden_states + + residual = hidden_states + hidden_states = self.layer_norm2(hidden_states) + hidden_states = self.mlp(hidden_states) + hidden_states = residual + hidden_states + + outputs = (hidden_states,) + + if output_attentions: + outputs += (attn_weights,) + + return outputs + + +class PaddleOCRPreTrainedModel(PreTrainedModel): + config_class = PaddleOCRVLConfig + base_model_prefix = "PaddleOCR" + supports_gradient_checkpointing = True + + _no_split_modules = [ + "PaddleOCRTextEmbeddings", + "PaddleOCREncoderLayer", + "PaddleOCRVisionEmbeddings", + "PaddleOCRMultiheadAttentionPoolingHead", + ] + _supports_flash_attn_2 = True + _supports_sdpa = True + + def _init_weights(self, module): + """Initialize the weights""" + if isinstance(module, PaddleOCRVisionEmbeddings): + width = ( + self.config.vision_config.hidden_size + if isinstance(self.config, PaddleOCRVLConfig) + else self.config.hidden_size + ) + nn.init.normal_(module.position_embedding.weight, std=1 / np.sqrt(width)) + elif isinstance(module, nn.Embedding): + default_flax_embed_init(module.weight) + elif isinstance(module, PaddleOCRAttention): + nn.init.xavier_uniform_(module.q_proj.weight) + nn.init.xavier_uniform_(module.k_proj.weight) + nn.init.xavier_uniform_(module.v_proj.weight) + nn.init.xavier_uniform_(module.out_proj.weight) + nn.init.zeros_(module.q_proj.bias) + nn.init.zeros_(module.k_proj.bias) + nn.init.zeros_(module.v_proj.bias) + nn.init.zeros_(module.out_proj.bias) + elif isinstance(module, PaddleOCRMLP): + nn.init.xavier_uniform_(module.fc1.weight) + nn.init.xavier_uniform_(module.fc2.weight) + nn.init.normal_(module.fc1.bias, std=1e-6) + nn.init.normal_(module.fc2.bias, std=1e-6) + elif isinstance(module, PaddleOCRMultiheadAttentionPoolingHead): + nn.init.xavier_uniform_(module.probe.data) + nn.init.xavier_uniform_(module.attention.in_proj_weight.data) + nn.init.zeros_(module.attention.in_proj_bias.data) + elif isinstance(module, (nn.Linear, nn.Conv2d)): + lecun_normal_(module.weight) + if module.bias is not None: + nn.init.zeros_(module.bias) + elif isinstance(module, nn.LayerNorm): + module.bias.data.zero_() + module.weight.data.fill_(1.0) + + +# Copied from transformers.models.altclip.modeling_altclip.AltCLIPEncoder with AltCLIP->PaddleOCR +class PaddleOCREncoder(nn.Module): + """ + Transformer encoder consisting of `config.num_hidden_layers` self attention layers. Each layer is a + [`PaddleOCREncoderLayer`]. + + Args: + config: PaddleOCRVLConfig + """ + + def __init__(self, config: PaddleOCRVLConfig): + super().__init__() + self.config = config + embed_dim = config.hidden_size + num_heads = config.num_attention_heads + head_dim = embed_dim // num_heads + self.layers = nn.ModuleList( + [PaddleOCREncoderLayer(config) for _ in range(config.num_hidden_layers)] + ) + self.rotary_pos_emb = SigLIPRotaryEmbedding(head_dim // 2) + self.gradient_checkpointing = False + + @staticmethod + def flatten_list(image_grid_thw): + tmp_image_grid_thw = list() + for image_grid in image_grid_thw: + if isinstance(image_grid, list): + tmp_image_grid_thw.extend(image_grid) + else: + tmp_image_grid_thw.append(image_grid) + return tmp_image_grid_thw + + def build_window_index(self, image_grid, window_size, device): + from einops import rearrange + + window_indices = list() + pad_values = -100 + start_window_index = 0 + cu_seqlens_within_windows = list() + + for t, h, w in image_grid: + window_index = torch.arange(t * h * w, device=device).reshape(t, h, w) + pad_h = (-h) % window_size + pad_w = (-w) % window_size + assert pad_h >= 0 and pad_w >= 0, (pad_h, pad_w) + window_index = F.pad(window_index, (0, pad_w, 0, pad_h), value=pad_values) + window_index = rearrange( + window_index, + "t (h p1) (w p2) -> t (h w) (p1 p2)", + p1=window_size, + p2=window_size, + ) + window_seqlens = (window_index != pad_values).long().sum(-1).reshape(-1) + window_index = window_index.reshape(-1) + window_index = window_index[window_index != pad_values] + window_indices.append(window_index + start_window_index) + cu_seqlens_within_windows.append( + window_seqlens.cumsum(0) + start_window_index + ) + start_window_index += t * h * w + window_indices = torch.concat(window_indices, dim=0) + cu_seqlens_within_windows = torch.concat(cu_seqlens_within_windows, dim=0) + cu_seqlens_within_windows = F.pad( + cu_seqlens_within_windows, (1, 0), value=0 + ).to(torch.int32) + return window_indices, cu_seqlens_within_windows + + # Ignore copy + # @can_return_tuple + def forward( + self, + inputs_embeds, + attention_mask: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + cu_seqlens: Optional[List[torch.Tensor]] = None, + image_grid_thw: Optional[ + List[Union[Tuple[int, int, int], List[Tuple[int, int, int]]]] + ] = None, + height_position_ids: Optional[torch.Tensor] = None, + width_position_ids: Optional[torch.Tensor] = None, + use_rope: Optional[bool] = False, + window_size: Optional[bool] = -1, + vision_or_text: str = "vision", + ) -> BaseModelOutput: + r""" + Args: + inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): + Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. + This is useful if you want more control over how to convert `input_ids` indices into associated vectors + than the model's internal embedding lookup matrix. + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + [What are attention masks?](../glossary#attention-mask) + output_attentions (`bool`, *optional*): + Whether or not to return the attentions tensors of all attention layers. See `attentions` under + returned tensors for more detail. + output_hidden_states (`bool`, *optional*): + Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors + for more detail. + return_dict (`bool`, *optional*): + Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple. + """ + + vision_or_text = "vision" + assert vision_or_text in ["vision", "text"] + use_window_attn = window_size > 0 and vision_or_text == "vision" + use_rope = (use_rope is True) and (vision_or_text == "vision") + output_attentions = ( + output_attentions + if output_attentions is not None + else self.config.output_attentions + ) + output_hidden_states = ( + output_hidden_states + if output_hidden_states is not None + else self.config.output_hidden_states + ) + + encoder_states = () if output_hidden_states else None + all_attentions = () if output_attentions else None + + device = inputs_embeds.device + hidden_states = inputs_embeds + attention_mask = ( + attention_mask.to(inputs_embeds.dtype) + if attention_mask is not None + else None + ) + if use_rope is True: + flatten_image_grid_thw = self.flatten_list(image_grid_thw) + assert ( + sum([np.prod(x) for x in flatten_image_grid_thw]) + == hidden_states.shape[1] + ), (flatten_image_grid_thw, hidden_states.shape) + + if width_position_ids is None or height_position_ids is None: + split_hids = list() + split_wids = list() + for t, h, w in flatten_image_grid_thw: + image_pids = torch.arange(t * h * w, device=device) % (h * w) + sample_hids = image_pids // w + sample_wids = image_pids % w + split_hids.append(sample_hids) + split_wids.append(sample_wids) + width_position_ids = torch.concat(split_wids, dim=0) + height_position_ids = torch.concat(split_hids, dim=0) + + window_indices, cu_seqlens_within_windows = None, None + + if use_window_attn: + window_indices, cu_seqlens_within_windows = self.build_window_index( + flatten_image_grid_thw, window_size, device + ) + reversed_window_indices = window_indices.argsort() + height_position_ids = height_position_ids[window_indices] + width_position_ids = width_position_ids[window_indices] + + pids = torch.stack([height_position_ids, width_position_ids], dim=-1) + max_grid_size = pids.max() + 1 + rope_emb_max_grid = self.rotary_pos_emb(max_grid_size) + rope_emb = rope_emb_max_grid[pids].flatten(1) + rope_emb = rope_emb.repeat(1, 2) + rope_emb = (rope_emb.cos(), rope_emb.sin()) + else: + + rope_emb = None + window_indices, cu_seqlens_within_windows = None, None + + if use_window_attn: + flatten_image_grid_thw = self.flatten_list(image_grid_thw) + assert ( + sum([np.prod(x) for x in flatten_image_grid_thw]) + == hidden_states.shape[1] + ), (flatten_image_grid_thw, hidden_states.shape) + + window_indices, cu_seqlens_within_windows = self.build_window_index( + flatten_image_grid_thw, window_size, device + ) + reversed_window_indices = window_indices.argsort() + + if use_window_attn: + assert cu_seqlens_within_windows is not None + attn_cu_seqlens = cu_seqlens_within_windows + hidden_states = hidden_states[:, window_indices, :] + else: + attn_cu_seqlens = cu_seqlens + + for encoder_layer in self.layers: + if output_hidden_states: + encoder_states = encoder_states + ( + (hidden_states[:, reversed_window_indices, :],) + if use_window_attn + else (hidden_states,) + ) + if self.gradient_checkpointing and self.training: + layer_outputs = self._gradient_checkpointing_func( + encoder_layer.__call__, + hidden_states, + attention_mask, + output_attentions, + attn_cu_seqlens, + rope_emb, + ) + else: + layer_outputs = encoder_layer( + hidden_states, + attention_mask, + output_attentions=output_attentions, + cu_seqlens=attn_cu_seqlens, + rope_emb=rope_emb, + ) + + hidden_states = layer_outputs[0] + + if output_attentions: + all_attentions = all_attentions + (layer_outputs[1],) + + if use_window_attn: + hidden_states = hidden_states[:, reversed_window_indices, :] + + if output_hidden_states: + encoder_states = encoder_states + (hidden_states,) + + return BaseModelOutput( + last_hidden_state=hidden_states, + hidden_states=encoder_states, + attentions=all_attentions, + ) + + +class PaddleOCRVisionTransformer(nn.Module): + def __init__(self, config: PaddleOCRVisionConfig): + super().__init__() + self.config = config + embed_dim = config.hidden_size + + self.embeddings = PaddleOCRVisionEmbeddings(config) + self.encoder = PaddleOCREncoder(config) + self.post_layernorm = nn.LayerNorm(embed_dim, eps=config.layer_norm_eps) + self.use_head = ( + True if not hasattr(config, "vision_use_head") else config.vision_use_head + ) + if self.use_head: + self.head = PaddleOCRMultiheadAttentionPoolingHead(config) + + # @can_return_tuple + def forward( + self, + pixel_values, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + interpolate_pos_encoding: Optional[bool] = False, + attention_mask: Optional[torch.Tensor] = None, + sample_indices: Optional[torch.Tensor] = None, + image_indices: Optional[torch.Tensor] = None, + position_ids: Optional[torch.Tensor] = None, + height_position_ids: Optional[torch.Tensor] = None, + width_position_ids: Optional[torch.Tensor] = None, + cu_seqlens: Optional[List[torch.Tensor]] = None, + padding_mask: Optional[torch.Tensor] = None, + vision_return_embed_list: Optional[bool] = False, + image_grid_thw: Optional[ + List[Union[Tuple[int, int, int], List[Tuple[int, int, int]]]] + ] = None, + return_pooler_output: Optional[bool] = True, + use_rope: Optional[bool] = False, + window_size: Optional[bool] = -1, + ) -> BaseModelOutputWithPooling: + r""" + Returns: + + """ + output_attentions = ( + output_attentions + if output_attentions is not None + else self.config.output_attentions + ) + output_hidden_states = ( + output_hidden_states + if output_hidden_states is not None + else self.config.output_hidden_states + ) + hidden_states = self.embeddings( + pixel_values, + interpolate_pos_encoding=interpolate_pos_encoding, + position_ids=position_ids, + image_grid_thw=image_grid_thw, + ) + + encoder_outputs: BaseModelOutput = self.encoder( + inputs_embeds=hidden_states, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + attention_mask=attention_mask, + cu_seqlens=cu_seqlens, + image_grid_thw=image_grid_thw, + use_rope=use_rope, + height_position_ids=height_position_ids, + width_position_ids=width_position_ids, + window_size=window_size, + vision_or_text="vision", + ) + + last_hidden_state = encoder_outputs.last_hidden_state + last_hidden_state = self.post_layernorm(last_hidden_state) + + if return_pooler_output is True: + if sample_indices is not None: + assert self.use_head is True + dim = last_hidden_state.shape[-1] + sample_hidden_state_list = list() + + hidden_state = last_hidden_state.squeeze(0) + sample_index = sample_indices + unique_sample_index = torch.unique(sample_index).sort().values.unbind(0) + unique_sample_index = list(unique_sample_index) + if len(unique_sample_index) > 0 and unique_sample_index[0] == -1: + unique_sample_index = unique_sample_index[1:] + for sample_idx in unique_sample_index: + token_indices = (sample_index == sample_idx).nonzero().flatten() + sample_hidden_state = hidden_state[token_indices] + sample_hidden_state_list.append(sample_hidden_state) + + if not vision_return_embed_list: + max_length = max( + [_state.shape[0] for _state in sample_hidden_state_list] + ) + tmp_sample_hidden_state_list = list() + padding_mask = list() + for idx, _state in enumerate(sample_hidden_state_list): + padding_length = max_length - _state.shape[0] + mask = _state.new_zeros(size=(max_length,), dtype=torch.int64) + mask[-padding_length:] = 1 + padding_mask.append(mask) + padding = _state.new_zeros(size=(padding_length, dim)) + new_state = torch.concat([_state, padding], dim=0) + tmp_sample_hidden_state_list.append(new_state) + sample_hidden_state = torch.stack( + tmp_sample_hidden_state_list, dim=0 + ) + padding_mask = ( + torch.stack(padding_mask, dim=0) + .float() + .to(last_hidden_state.dtype) + ) + pooler_output = self.head( + sample_hidden_state, key_padding_mask=padding_mask + ) + else: + pooler_output = list() + for state in sample_hidden_state_list: + sample_pooler_output = self.head(state.unsqueeze(0)) + pooler_output.append(sample_pooler_output) + pooler_output = torch.concat(pooler_output, dim=0) + sample_hidden_state = sample_hidden_state_list + + return BaseModelOutputWithPooling( + last_hidden_state=sample_hidden_state, + pooler_output=pooler_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + else: + pooler_output = self.head(last_hidden_state) if self.use_head else None + + return BaseModelOutputWithPooling( + last_hidden_state=last_hidden_state, + pooler_output=pooler_output, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + sample_hidden_state = list() + assert cu_seqlens is not None + for i in range(cu_seqlens.shape[0] - 1): + start = cu_seqlens[i] + end = cu_seqlens[i + 1] + tensor = last_hidden_state[:, start:end, :].squeeze(0) + sample_hidden_state.append(tensor) + + return BaseModelOutputWithPooling( + last_hidden_state=sample_hidden_state, + pooler_output=None, + hidden_states=encoder_outputs.hidden_states, + attentions=encoder_outputs.attentions, + ) + + +class PaddleOCRMultiheadAttentionPoolingHead(nn.Module): + """Multihead Attention Pooling.""" + + def __init__(self, config: PaddleOCRVisionConfig): + super().__init__() + + self.probe = nn.Parameter(torch.randn(1, 1, config.hidden_size)) + self.attention = torch.nn.MultiheadAttention( + config.hidden_size, config.num_attention_heads, batch_first=True + ) + self.layernorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps) + self.mlp = PaddleOCRMLP(config) + + def forward(self, hidden_state, key_padding_mask=None): + batch_size = hidden_state.shape[0] + probe = self.probe.repeat(batch_size, 1, 1) + + hidden_state = self.attention( + probe, hidden_state, hidden_state, key_padding_mask=key_padding_mask + )[0] + + residual = hidden_state + hidden_state = self.layernorm(hidden_state) + hidden_state = residual + self.mlp(hidden_state) + + return hidden_state[:, 0] + + +class PaddleOCRVisionModel(PaddleOCRPreTrainedModel): + config_class = PaddleOCRVisionConfig + main_input_name = "pixel_values" + + def __init__(self, config: PaddleOCRVisionConfig): + super().__init__(config) + + self.vision_model = PaddleOCRVisionTransformer(config) + + # Initialize weights and apply final processing + self.post_init() + + def get_input_embeddings(self) -> nn.Module: + return self.vision_model.embeddings.patch_embedding + + # @can_return_tuple + def forward( + self, + pixel_values, + sample_indices: Optional[torch.Tensor] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + interpolate_pos_encoding: bool = False, + position_ids: Optional[torch.Tensor] = None, + vision_return_embed_list: Optional[bool] = False, + image_grid_thw: Optional[ + List[Union[Tuple[int, int, int], List[Tuple[int, int, int]]]] + ] = None, + cu_seqlens: Optional[List[torch.Tensor]] = None, + return_pooler_output: Optional[bool] = True, + use_rope: Optional[bool] = False, + window_size: Optional[bool] = -1, + ) -> BaseModelOutputWithPooling: + return self.vision_model( + pixel_values=pixel_values, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + interpolate_pos_encoding=interpolate_pos_encoding, + position_ids=position_ids, + vision_return_embed_list=vision_return_embed_list, + image_grid_thw=image_grid_thw, + sample_indices=sample_indices, + cu_seqlens=cu_seqlens, + return_pooler_output=return_pooler_output, + use_rope=use_rope, + window_size=window_size, + ) + + +def apply_rotary_pos_emb_flashatt( + q: torch.Tensor, k: torch.Tensor, cos: torch.Tensor, sin: torch.Tensor +) -> Tuple[torch.Tensor, torch.Tensor]: + cos = cos.chunk(2, dim=-1)[0].contiguous() + sin = sin.chunk(2, dim=-1)[0].contiguous() + q_embed = apply_rotary_emb(q.float(), cos.float(), sin.float()).type_as(q) + k_embed = apply_rotary_emb(k.float(), cos.float(), sin.float()).type_as(k) + return q_embed, k_embed + + +def rotate_half(x): + """Rotates half the hidden dims of the input.""" + x1 = x[..., : x.shape[-1] // 2] + x2 = x[..., x.shape[-1] // 2 :] + return torch.cat((-x2, x1), dim=-1) + + +def apply_rotary_pos_emb_vision( + q: torch.Tensor, k: torch.Tensor, cos: torch.Tensor, sin: torch.Tensor +) -> Tuple[torch.Tensor, torch.Tensor]: + orig_q_dtype = q.dtype + orig_k_dtype = k.dtype + q, k = q.float(), k.float() + cos, sin = cos.unsqueeze(-2).float(), sin.unsqueeze(-2).float() + q_embed = (q * cos) + (rotate_half(q) * sin) + k_embed = (k * cos) + (rotate_half(k) * sin) + q_embed = q_embed.to(orig_q_dtype) + k_embed = k_embed.to(orig_k_dtype) + return q_embed, k_embed + + +class SigLIPRotaryEmbedding(nn.Module): + def __init__(self, dim: int, theta: float = 10000.0) -> None: + super().__init__() + self.dim = dim + self.theta = theta + self.rope_init() + + def rope_init(self): + inv_freq = 1.0 / ( + self.theta ** (torch.arange(0, self.dim, 2, dtype=torch.float) / self.dim) + ) + self.register_buffer("inv_freq", inv_freq, persistent=False) + + def forward(self, seqlen: int) -> torch.Tensor: + seq = torch.arange( + seqlen, device=self.inv_freq.device, dtype=self.inv_freq.dtype + ) + freqs = torch.outer(seq, self.inv_freq) + return freqs + + +@dataclass +class PaddleOCRVLCausalLMOutputWithPast(ModelOutput): + """ + Base class for PaddleOCRVL causal language model (or autoregressive) outputs. + + Args: + loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided): + Language modeling loss (for next-token prediction). + logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): + Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). + past_key_values (`tuple(tuple(torch.FloatTensor))`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`): + Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of shape + `(batch_size, num_heads, sequence_length, embed_size_per_head)`) + + Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see + `past_key_values` input) to speed up sequential decoding. + hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): + Tuple of `torch.FloatTensor` (one for the output of the embeddings, if the model has an embedding layer, + + one for the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`. + + Hidden-states of the model at the output of each layer plus the optional initial embedding outputs. + attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`): + Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, + sequence_length)`. + + Attentions weights after the attention softmax, used to compute the weighted average in the self-attention + heads. + rope_deltas (`torch.LongTensor` of shape `(batch_size, )`, *optional*): + The rope index difference between sequence length and multimodal rope. + """ + + loss: Optional[torch.FloatTensor] = None + logits: torch.FloatTensor = None + past_key_values: Optional[List[torch.FloatTensor]] = None + hidden_states: Optional[Tuple[torch.FloatTensor]] = None + attentions: Optional[Tuple[torch.FloatTensor]] = None + rope_deltas: Optional[torch.LongTensor] = None + + +class PaddleOCRVLForConditionalGeneration(Ernie4_5PreTrainedModel, GenerationMixin): + _tied_weights_keys = ["lm_head.weight"] + config_class = PaddleOCRVLConfig + _no_split_modules = ["Ernie4_5_DecoderLayer", "PaddleOCREncoderLayer"] + + def __init__(self, config): + super().__init__(config) + self.mlp_AR = Projector(config, config.vision_config) + self.visual = PaddleOCRVisionModel(config.vision_config) + self.model = Ernie4_5Model(config) + self.vocab_size = config.vocab_size + self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False) + self.rope_deltas = None + + self.post_init() + + def get_input_embeddings(self): + return self.model.embed_tokens + + def set_input_embeddings(self, value): + self.model.embed_tokens = value + + def get_output_embeddings(self): + return self.lm_head + + def set_output_embeddings(self, new_embeddings): + self.lm_head = new_embeddings + + def set_decoder(self, decoder): + self.model = decoder + + def get_decoder(self): + return self.model + + def get_rope_index( + self, + input_ids: Optional[torch.LongTensor] = None, + image_grid_thw: Optional[torch.LongTensor] = None, + video_grid_thw: Optional[torch.LongTensor] = None, + second_per_grid_ts: Optional[torch.Tensor] = None, + attention_mask: Optional[torch.Tensor] = None, + ) -> Tuple[torch.Tensor, torch.Tensor]: + """ + Calculate the 3D rope index based on image and video's temporal, height and width in LLM. + + Explanation: + Each embedding sequence contains vision embedding and text embedding or just contains text embedding. + + For pure text embedding sequence, the rotary position embedding has no difference with modern LLMs. + Examples: + input_ids: [T T T T T], here T is for text. + temporal position_ids: [0, 1, 2, 3, 4] + height position_ids: [0, 1, 2, 3, 4] + width position_ids: [0, 1, 2, 3, 4] + + For vision and text embedding sequence, we calculate 3D rotary position embedding for vision part + and 1D rotary position embedding for text part. + Examples: + Temporal (Time): 3 patches, representing different segments of the video in time. + Height: 2 patches, dividing each frame vertically. + Width: 2 patches, dividing each frame horizontally. + We also have some important parameters: + fps (Frames Per Second): The video's frame rate, set to 1. This means one frame is processed each second. + tokens_per_second: This is a crucial parameter. It dictates how many "time-steps" or "temporal tokens" are conceptually packed into a one-second interval of the video. In this case, we have 25 tokens per second. So each second of the video will be represented with 25 separate time points. It essentially defines the temporal granularity. + temporal_patch_size: The number of frames that compose one temporal patch. Here, it's 2 frames. + interval: The step size for the temporal position IDs, calculated as tokens_per_second * temporal_patch_size / fps. In this case, 25 * 2 / 1 = 50. This means that each temporal patch will be have a difference of 50 in the temporal position IDs. + input_ids: [V V V V V V V V V V V V T T T T T], here V is for vision. + vision temporal position_ids: [0, 0, 0, 0, 50, 50, 50, 50, 100, 100, 100, 100] + vision height position_ids: [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1] + vision width position_ids: [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] + text temporal position_ids: [101, 102, 103, 104, 105] + text height position_ids: [101, 102, 103, 104, 105] + text width position_ids: [101, 102, 103, 104, 105] + Here we calculate the text start position_ids as the max vision position_ids plus 1. + + Args: + input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide + it. + image_grid_thw (`torch.LongTensor` of shape `(num_images, 3)`, *optional*): + The temporal, height and width of feature shape of each image in LLM. + video_grid_thw (`torch.LongTensor` of shape `(num_videos, 3)`, *optional*): + The temporal, height and width of feature shape of each video in LLM. + second_per_grid_ts (`torch.Tensor` of shape `(num_videos)`, *optional*): + The time interval (in seconds) for each grid along the temporal dimension in the 3D position IDs. + attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*): + Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`: + + - 1 for tokens that are **not masked**, + - 0 for tokens that are **masked**. + + Returns: + position_ids (`torch.LongTensor` of shape `(3, batch_size, sequence_length)`) + mrope_position_deltas (`torch.Tensor` of shape `(batch_size)`) + """ + spatial_merge_size = self.config.vision_config.spatial_merge_size + image_token_id = self.config.image_token_id + video_token_id = self.config.video_token_id + vision_start_token_id = self.config.vision_start_token_id + mrope_position_deltas = [] + if input_ids is not None and ( + image_grid_thw is not None or video_grid_thw is not None + ): + total_input_ids = input_ids + if attention_mask is None: + attention_mask = torch.ones_like(total_input_ids) + position_ids = torch.ones( + 3, + input_ids.shape[0], + input_ids.shape[1], + dtype=input_ids.dtype, + device=input_ids.device, + ) + image_index, video_index = 0, 0 + attention_mask = attention_mask.to(total_input_ids.device) + for i, input_ids in enumerate(total_input_ids): + input_ids = input_ids[attention_mask[i] == 1] + image_nums, video_nums = 0, 0 + vision_start_indices = torch.argwhere( + input_ids == vision_start_token_id + ).squeeze(1) + vision_tokens = input_ids[vision_start_indices + 1] + image_nums = (vision_tokens == image_token_id).sum() + video_nums = (vision_tokens == video_token_id).sum() + input_tokens = input_ids.tolist() + llm_pos_ids_list: list = [] + st = 0 + remain_images, remain_videos = image_nums, video_nums + for _ in range(image_nums + video_nums): + if image_token_id in input_tokens and remain_images > 0: + ed_image = input_tokens.index(image_token_id, st) + else: + ed_image = len(input_tokens) + 1 + if video_token_id in input_tokens and remain_videos > 0: + ed_video = input_tokens.index(video_token_id, st) + else: + ed_video = len(input_tokens) + 1 + if ed_image < ed_video: + t, h, w = ( + image_grid_thw[image_index][0], + image_grid_thw[image_index][1], + image_grid_thw[image_index][2], + ) + second_per_grid_t = 0 + image_index += 1 + remain_images -= 1 + ed = ed_image + + else: + t, h, w = ( + video_grid_thw[video_index][0], + video_grid_thw[video_index][1], + video_grid_thw[video_index][2], + ) + if second_per_grid_ts is not None: + second_per_grid_t = second_per_grid_ts[video_index] + else: + second_per_grid_t = 1.0 + video_index += 1 + remain_videos -= 1 + ed = ed_video + llm_grid_t, llm_grid_h, llm_grid_w = ( + t.item(), + h.item() // spatial_merge_size, + w.item() // spatial_merge_size, + ) + text_len = ed - st + + st_idx = ( + llm_pos_ids_list[-1].max() + 1 + if len(llm_pos_ids_list) > 0 + else 0 + ) + llm_pos_ids_list.append( + torch.arange(text_len).view(1, -1).expand(3, -1) + st_idx + ) + + if torch.is_tensor(second_per_grid_t): + second_per_grid_t = second_per_grid_t.detach().item() + range_tensor = torch.arange(llm_grid_t).view(-1, 1) + expanded_range = range_tensor.expand(-1, llm_grid_h * llm_grid_w) + + time_tensor = ( + expanded_range + * second_per_grid_t + * self.config.vision_config.tokens_per_second + ) + + time_tensor_long = time_tensor.long() + t_index = time_tensor_long.flatten() + + h_index = ( + torch.arange(llm_grid_h) + .view(1, -1, 1) + .expand(llm_grid_t, -1, llm_grid_w) + .flatten() + ) + w_index = ( + torch.arange(llm_grid_w) + .view(1, 1, -1) + .expand(llm_grid_t, llm_grid_h, -1) + .flatten() + ) + llm_pos_ids_list.append( + torch.stack([t_index, h_index, w_index]) + text_len + st_idx + ) + st = ed + llm_grid_t * llm_grid_h * llm_grid_w + + if st < len(input_tokens): + st_idx = ( + llm_pos_ids_list[-1].max() + 1 + if len(llm_pos_ids_list) > 0 + else 0 + ) + text_len = len(input_tokens) - st + llm_pos_ids_list.append( + torch.arange(text_len).view(1, -1).expand(3, -1) + st_idx + ) + + llm_positions = torch.cat(llm_pos_ids_list, dim=1).reshape(3, -1) + position_ids[..., i, attention_mask[i] == 1] = llm_positions.to( + position_ids.device + ) + mrope_position_deltas.append( + llm_positions.max() + 1 - len(total_input_ids[i]) + ) + mrope_position_deltas = torch.tensor( + mrope_position_deltas, device=input_ids.device + ).unsqueeze(1) + return position_ids, mrope_position_deltas + else: + if attention_mask is not None: + position_ids = attention_mask.long().cumsum(-1) - 1 + position_ids.masked_fill_(attention_mask == 0, 1) + position_ids = ( + position_ids.unsqueeze(0) + .expand(3, -1, -1) + .to(attention_mask.device) + ) + max_position_ids = position_ids.max(0, keepdim=False)[0].max( + -1, keepdim=True + )[0] + mrope_position_deltas = max_position_ids + 1 - attention_mask.shape[-1] + else: + position_ids = ( + torch.arange(input_ids.shape[1], device=input_ids.device) + .view(1, 1, -1) + .expand(3, input_ids.shape[0], -1) + ) + mrope_position_deltas = torch.zeros( + [input_ids.shape[0], 1], + device=input_ids.device, + dtype=input_ids.dtype, + ) + + return position_ids, mrope_position_deltas + + def forward( + self, + input_ids: torch.LongTensor = None, + attention_mask: Optional[torch.Tensor] = None, + position_ids: Optional[torch.LongTensor] = None, + past_key_values: Optional[List[torch.FloatTensor]] = None, + inputs_embeds: Optional[torch.FloatTensor] = None, + labels: Optional[torch.LongTensor] = None, + use_cache: Optional[bool] = None, + output_attentions: Optional[bool] = None, + output_hidden_states: Optional[bool] = None, + return_dict: Optional[bool] = None, + pixel_values: Optional[torch.Tensor] = None, + pixel_values_videos: Optional[torch.FloatTensor] = None, + image_grid_thw: Optional[torch.LongTensor] = None, + video_grid_thw: Optional[torch.LongTensor] = None, + rope_deltas: Optional[torch.LongTensor] = None, + cache_position: Optional[torch.LongTensor] = None, + second_per_grid_ts: Optional[torch.Tensor] = None, + **kwargs, + ) -> Union[Tuple, PaddleOCRVLCausalLMOutputWithPast]: + r""" + Returns: + """ + output_attentions = ( + output_attentions + if output_attentions is not None + else self.config.output_attentions + ) + output_hidden_states = ( + output_hidden_states + if output_hidden_states is not None + else self.config.output_hidden_states + ) + return_dict = ( + return_dict if return_dict is not None else self.config.use_return_dict + ) + + if inputs_embeds is None: + inputs_embeds = self.model.embed_tokens(input_ids) + if pixel_values is not None: + pixel_values = pixel_values.type(self.visual.dtype) + pixel_values = pixel_values.unsqueeze(0) + siglip_position_ids = list() + image_grid_hws = list() + sample_indices = list() + cu_seqlens = [0] + + pro = 0 + for idx, thw in enumerate(image_grid_thw): + thw_tuple = tuple(thw.detach().cpu().numpy().tolist()) + numel = np.prod(thw_tuple) + image_grid_hws.append(thw_tuple) + image_position_ids = torch.arange(numel) % np.prod(thw_tuple[1:]) + siglip_position_ids.append(image_position_ids) + sample_indices.append(torch.full((numel,), idx, dtype=torch.int64)) + cu_seqlens.append(cu_seqlens[-1] + numel) + + siglip_position_ids = torch.concat(siglip_position_ids, dim=0).to( + pixel_values.device + ) + cu_seqlens = torch.tensor(cu_seqlens, dtype=torch.int32).to( + pixel_values.device + ) + sample_indices = torch.concat(sample_indices, dim=0).to( + pixel_values.device + ) + + vision_outputs = self.visual( + pixel_values=pixel_values, + image_grid_thw=image_grid_hws, + position_ids=siglip_position_ids, + vision_return_embed_list=True, + interpolate_pos_encoding=True, + sample_indices=sample_indices, + cu_seqlens=cu_seqlens, + return_pooler_output=False, + use_rope=True, + window_size=-1, + ) + image_embeds = vision_outputs.last_hidden_state + + image_embeds = self.mlp_AR(image_embeds, image_grid_thw) + + n_image_tokens = (input_ids == self.config.image_token_id).sum().item() + # image_embeds is a list of tensor, each tensor is a image feature,I want to concat them all into a tensor + image_embeds = torch.cat(image_embeds, dim=0) + n_image_features = image_embeds.shape[0] + if n_image_tokens != n_image_features: + raise ValueError( + f"Image features and image tokens do not match: tokens: {n_image_tokens}, features {n_image_features}" + ) + + mask = input_ids == self.config.image_token_id + mask_unsqueezed = mask.unsqueeze(-1) + mask_expanded = mask_unsqueezed.expand_as(inputs_embeds) + image_mask = mask_expanded.to(inputs_embeds.device) + + image_embeds = image_embeds.to( + inputs_embeds.device, inputs_embeds.dtype + ) + + inputs_embeds = inputs_embeds.masked_scatter(image_mask, image_embeds) + + if attention_mask is not None: + attention_mask = attention_mask.to(inputs_embeds.device) + # position_ids = None + # if we get 4D attention mask we cannot calculate rope deltas anymore. TODO @raushan fixme + if position_ids is None and ( + attention_mask is None or attention_mask.ndim == 2 + ): + # calculate RoPE index once per generation in the pre-fill stage only + if ( + (cache_position is not None and cache_position[0] == 0) + or self.rope_deltas is None + or (past_key_values is None or past_key_values.get_seq_length() == 0) + ): + position_ids, rope_deltas = self.get_rope_index( + input_ids, + image_grid_thw, + video_grid_thw, + second_per_grid_ts, + attention_mask, + ) + self.rope_deltas = rope_deltas + # then use the prev pre-calculated rope-deltas to get the correct position ids + else: + batch_size, seq_length, _ = inputs_embeds.shape + delta = ( + (cache_position[0] + self.rope_deltas).to(inputs_embeds.device) + if cache_position is not None + else 0 + ) + position_ids = torch.arange(seq_length, device=inputs_embeds.device) + position_ids = position_ids.view(1, -1).expand(batch_size, -1) + if cache_position is not None: # otherwise `deltas` is an int `0` + delta = delta.repeat_interleave(batch_size // delta.shape[0], dim=0) + position_ids = position_ids.add(delta) + position_ids = position_ids.unsqueeze(0).expand(3, -1, -1) + + outputs = self.model( + input_ids=None, + position_ids=position_ids, + attention_mask=attention_mask, + past_key_values=past_key_values, + inputs_embeds=inputs_embeds, + use_cache=use_cache, + output_attentions=output_attentions, + output_hidden_states=output_hidden_states, + return_dict=return_dict, + **kwargs, + ) + + hidden_states = outputs[0] + logits = self.lm_head(hidden_states) + + loss = None + if labels is not None: + # Upcast to float if we need to compute the loss to avoid potential precision issues + logits = logits.float() + # Shift so that tokens < n predict n + shift_logits = logits[..., :-1, :].contiguous() + shift_labels = labels[..., 1:].contiguous() + # Flatten the tokens + loss_fct = CrossEntropyLoss() + shift_logits = shift_logits.view(-1, self.config.vocab_size) + shift_labels = shift_labels.view(-1) + # Enable model parallelism + shift_labels = shift_labels.to(shift_logits.device) + loss = loss_fct(shift_logits, shift_labels) + + if not return_dict: + output = (logits,) + outputs[1:] + return (loss,) + output if loss is not None else output + + return PaddleOCRVLCausalLMOutputWithPast( + loss=loss, + logits=logits, + past_key_values=outputs.past_key_values, + hidden_states=outputs.hidden_states, + attentions=outputs.attentions, + rope_deltas=self.rope_deltas, + ) + + def prepare_inputs_for_generation( + self, + input_ids, + past_key_values=None, + attention_mask=None, + inputs_embeds=None, + cache_position=None, + position_ids=None, + use_cache=True, + pixel_values=None, + pixel_values_videos=None, + image_grid_thw=None, + video_grid_thw=None, + second_per_grid_ts=None, + **kwargs, + ): + # Overwritten -- in specific circumstances we don't want to forward image inputs to the model + + model_inputs = super().prepare_inputs_for_generation( + input_ids, + past_key_values=past_key_values, + attention_mask=attention_mask, + inputs_embeds=inputs_embeds, + cache_position=cache_position, + position_ids=position_ids, + pixel_values=pixel_values, + pixel_values_videos=pixel_values_videos, + image_grid_thw=image_grid_thw, + video_grid_thw=video_grid_thw, + second_per_grid_ts=second_per_grid_ts, + use_cache=use_cache, + **kwargs, + ) + + model_inputs["position_ids"] = None + + if cache_position[0] != 0: + model_inputs["pixel_values"] = None + model_inputs["pixel_values_videos"] = None + + return model_inputs + + def _get_image_nums_and_video_nums( + self, + input_ids: Optional[torch.LongTensor], + ) -> Tuple[torch.Tensor, torch.Tensor]: + """ + Get the number of images and videos for each sample to calculate the separation length of the sample tensor. + These parameters are not passed through the processor to avoid unpredictable impacts from interface modifications. + + Args: + input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`): + Indices of input sequence tokens in the vocabulary. + + Returns: + image_nums (`torch.LongTensor` of shape `(batch_size, num_images_sample)`) + video_nums (`torch.LongTensor` of shape `(batch_size, num_videos_sample)`) + """ + image_token_id = self.config.image_token_id + video_token_id = self.config.video_token_id + vision_start_token_id = self.config.vision_start_token_id + + vision_start_mask = input_ids == vision_start_token_id + vision_first_mask = torch.roll(vision_start_mask, shifts=1, dims=1) + image_mask = input_ids == image_token_id + video_mask = input_ids == video_token_id + image_nums = torch.sum(vision_first_mask & image_mask, dim=1) + video_nums = torch.sum(vision_first_mask & video_mask, dim=1) + + return image_nums, video_nums + + def _expand_inputs_for_generation( + self, + expand_size: int = 1, + is_encoder_decoder: bool = False, + input_ids: Optional[torch.LongTensor] = None, + **model_kwargs, + ) -> Tuple[torch.LongTensor, Dict[str, Any]]: + # Overwritten -- Support for expanding tensors without a batch size dimension + # e.g., pixel_values, image_grid_thw, pixel_values_videos, video_grid_thw, second_per_grid_t + # pixel_values.shape[0] is sum(seqlen_images for samples) + # image_grid_thw.shape[0] is sum(num_images for samples) + + if expand_size == 1: + return input_ids, model_kwargs + + visual_keys = [ + "pixel_values", + "image_grid_thw", + "pixel_values_videos", + "video_grid_thw", + "second_per_grid_ts", + ] + + def _expand_dict_for_generation_visual(dict_to_expand): + image_grid_thw = model_kwargs.get("image_grid_thw", None) + video_grid_thw = model_kwargs.get("video_grid_thw", None) + image_nums, video_nums = self._get_image_nums_and_video_nums(input_ids) + + def _repeat_interleave_samples(x, lengths, repeat_times): + samples = torch.split(x, lengths) + repeat_args = [repeat_times] + [1] * (x.dim() - 1) + result = torch.cat( + [sample.repeat(*repeat_args) for sample in samples], dim=0 + ) + return result + + for key in dict_to_expand: + if key == "pixel_values": + # split images into samples + samples = torch.split(image_grid_thw, list(image_nums)) + # compute the sequence length of images for each sample + lengths = [torch.prod(sample, dim=1).sum() for sample in samples] + dict_to_expand[key] = _repeat_interleave_samples( + dict_to_expand[key], lengths=lengths, repeat_times=expand_size + ) + elif key == "image_grid_thw": + # get the num of images for each sample + lengths = list(image_nums) + dict_to_expand[key] = _repeat_interleave_samples( + dict_to_expand[key], lengths=lengths, repeat_times=expand_size + ) + elif key == "pixel_values_videos": + samples = torch.split(video_grid_thw, list(video_nums)) + lengths = [torch.prod(sample, dim=1).sum() for sample in samples] + dict_to_expand[key] = _repeat_interleave_samples( + dict_to_expand[key], lengths=lengths, repeat_times=expand_size + ) + elif key == "video_grid_thw": + lengths = list(video_nums) + dict_to_expand[key] = _repeat_interleave_samples( + dict_to_expand[key], lengths=lengths, repeat_times=expand_size + ) + elif key == "second_per_grid_ts": + if not isinstance(dict_to_expand[key], list): + raise TypeError( + f"Expected value for key '{key}' to be a list, but got {type(dict_to_expand[key])} instead." + ) + tensor = torch.tensor(dict_to_expand[key]) + lengths = list(video_nums) + tensor = _repeat_interleave_samples( + tensor, lengths=lengths, repeat_times=expand_size + ) + dict_to_expand[key] = tensor.tolist() + return dict_to_expand + + def _expand_dict_for_generation(dict_to_expand): + for key in dict_to_expand: + if ( + key != "cache_position" + and dict_to_expand[key] is not None + and isinstance(dict_to_expand[key], torch.Tensor) + and key not in visual_keys + ): + dict_to_expand[key] = dict_to_expand[key].repeat_interleave( + expand_size, dim=0 + ) + return dict_to_expand + + # input_ids is required for expanding visual inputs + # If input_ids is unavailable, visual inputs will not be used; therefore, there is no need to expand visual inputs. + if input_ids is not None and input_ids.numel() != 0: + model_kwargs = _expand_dict_for_generation_visual(model_kwargs) + + if input_ids is not None: + input_ids = input_ids.repeat_interleave(expand_size, dim=0) + + model_kwargs = _expand_dict_for_generation(model_kwargs) + + if is_encoder_decoder: + if model_kwargs.get("encoder_outputs") is None: + raise ValueError( + "If `is_encoder_decoder` is True, make sure that `encoder_outputs` is defined." + ) + model_kwargs["encoder_outputs"] = _expand_dict_for_generation( + model_kwargs["encoder_outputs"] + ) + + return input_ids, model_kwargs diff --git a/paddleocr_vl_1-5_tokenizer/preprocessor_config.json b/paddleocr_vl_1-5_tokenizer/preprocessor_config.json new file mode 100644 index 0000000000000000000000000000000000000000..d873cd63d04d9e6243999759fc30f7752dab3222 --- /dev/null +++ b/paddleocr_vl_1-5_tokenizer/preprocessor_config.json @@ -0,0 +1,29 @@ +{ + "auto_map": { + "AutoImageProcessor": "image_processing_paddleocr_vl.PaddleOCRVLImageProcessor", + "AutoProcessor": "processing_paddleocr_vl.PaddleOCRVLProcessor" + }, + "do_convert_rgb": true, + "do_normalize": true, + "do_rescale": true, + "do_resize": true, + "image_mean": [ + 0.5, + 0.5, + 0.5 + ], + "image_processor_type": "PaddleOCRVLImageProcessor", + "image_std": [ + 0.5, + 0.5, + 0.5 + ], + "max_pixels": 1003520, + "merge_size": 2, + "min_pixels": 112896, + "patch_size": 14, + "processor_class": "PaddleOCRVLProcessor", + "resample": 3, + "rescale_factor": 0.00392156862745098, + "temporal_patch_size": 1 +} diff --git a/paddleocr_vl_1-5_tokenizer/processing_paddleocr_vl.py b/paddleocr_vl_1-5_tokenizer/processing_paddleocr_vl.py new file mode 100644 index 0000000000000000000000000000000000000000..73c3faeff201555fc7b52709848e3c669419dbb1 --- /dev/null +++ b/paddleocr_vl_1-5_tokenizer/processing_paddleocr_vl.py @@ -0,0 +1,293 @@ +# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import List, Union +import numpy as np +import torch +from transformers.feature_extraction_utils import BatchFeature +from transformers.processing_utils import ( + ProcessingKwargs, + ProcessorMixin, + Unpack, + VideosKwargs, +) +from transformers.tokenization_utils_base import PreTokenizedInput, TextInput + + +ImageInput = Union[ + "PIL.Image.Image", + np.ndarray, + "torch.Tensor", + List["PIL.Image.Image"], + List[np.ndarray], + List["torch.Tensor"], +] # noqa + + +VideoInput = Union[ + List["PIL.Image.Image"], + "np.ndarray", + "torch.Tensor", + List["np.ndarray"], + List["torch.Tensor"], + List[List["PIL.Image.Image"]], + List[List["np.ndarrray"]], + List[List["torch.Tensor"]], +] # noqa + + +class PaddleOCRVLVideosProcessorKwargs(VideosKwargs, total=False): + fps: Union[List[float], float] + + +class PaddleOCRVLProcessorKwargs(ProcessingKwargs, total=False): + videos_kwargs: PaddleOCRVLVideosProcessorKwargs + _defaults = { + "text_kwargs": { + "padding": False, + }, + "videos_kwargs": {"fps": 2.0}, + } + + +class PaddleOCRVLProcessor(ProcessorMixin): + r""" + [`PaddleOCRVLProcessor`] offers all the functionalities of [`SiglipImageProcessor`] and [`Qwen2TokenizerFast`]. See the + [`~PaddleOCRVLProcessor.__call__`] and [`~PaddleOCRVLProcessor.decode`] for more information. + Args: + image_processor ([`SiglipImageProcessor`], *optional*): + The image processor is a required input. + tokenizer ([`Qwen2TokenizerFast`], *optional*): + The tokenizer is a required input. + chat_template (`str`, *optional*): A Jinja template which will be used to convert lists of messages + in a chat into a tokenizable string. + """ + + attributes = ["image_processor", "tokenizer"] + valid_kwargs = [ + "chat_template", + "image_std", + "min_pixels", + "image_mean", + "merge_size", + "image_processor_type", + "temporal_patch_size", + "patch_size", + "max_pixels", + ] + + image_processor_class = "AutoImageProcessor" + tokenizer_class = "AutoTokenizer" + + def __init__( + self, image_processor=None, tokenizer=None, chat_template=None, **kwargs + ): + self.image_token = ( + "<|IMAGE_PLACEHOLDER|>" + if not hasattr(tokenizer, "image_token") + else tokenizer.image_token + ) + self.video_token = ( + "<|video_pad|>" + if not hasattr(tokenizer, "video_token") + else tokenizer.video_token + ) + super().__init__(image_processor, tokenizer, chat_template=chat_template) + + def __call__( + self, + images: ImageInput = None, + text: Union[ + TextInput, PreTokenizedInput, List[TextInput], List[PreTokenizedInput] + ] = None, + videos: VideoInput = None, + **kwargs: Unpack[PaddleOCRVLProcessorKwargs], + ) -> BatchFeature: + """ + Main method to prepare for the model one or several sequences(s) and image(s). This method forwards the `text` + and `kwargs` arguments to Qwen2TokenizerFast's [`~Qwen2TokenizerFast.__call__`] if `text` is not `None` to encode + the text. To prepare the vision inputs, this method forwards the `vision_infos` and `kwrags` arguments to + SiglipImageProcessor's [`~SiglipImageProcessor.__call__`] if `vision_infos` is not `None`. + + Args: + images (`PIL.Image.Image`, `np.ndarray`, `torch.Tensor`, `List[PIL.Image.Image]`, `List[np.ndarray]`, `List[torch.Tensor]`): + The image or batch of images to be prepared. Each image can be a PIL image, NumPy array or PyTorch + tensor. Both channels-first and channels-last formats are supported. + text (`str`, `List[str]`, `List[List[str]]`): + The sequence or batch of sequences to be encoded. Each sequence can be a string or a list of strings + (pretokenized string). If the sequences are provided as list of strings (pretokenized), you must set + `is_split_into_words=True` (to lift the ambiguity with a batch of sequences). + videos (`np.ndarray`, `torch.Tensor`, `List[np.ndarray]`, `List[torch.Tensor]`): + The image or batch of videos to be prepared. Each video can be a 4D NumPy array or PyTorch + tensor, or a nested list of 3D frames. Both channels-first and channels-last formats are supported. + return_tensors (`str` or [`~utils.TensorType`], *optional*): + If set, will return tensors of a particular framework. Acceptable values are: + - `'tf'`: Return TensorFlow `tf.constant` objects. + - `'pt'`: Return PyTorch `torch.Tensor` objects. + - `'np'`: Return NumPy `np.ndarray` objects. + - `'jax'`: Return JAX `jnp.ndarray` objects. + + Returns: + [`BatchFeature`]: A [`BatchFeature`] with the following fields: + + - **input_ids** -- List of token ids to be fed to a model. Returned when `text` is not `None`. + - **attention_mask** -- List of indices specifying which tokens should be attended to by the model (when + `return_attention_mask=True` or if *"attention_mask"* is in `self.model_input_names` and if `text` is not + `None`). + - **pixel_values** -- Pixel values to be fed to a model. Returned when `images` is not `None`. + - **pixel_values_videos** -- Pixel values of videos to be fed to a model. Returned when `videos` is not `None`. + - **image_grid_thw** -- List of image 3D grid in LLM. Returned when `images` is not `None`. + - **video_grid_thw** -- List of video 3D grid in LLM. Returned when `videos` is not `None`. + - **second_per_grid_ts** -- List of video seconds per time grid. Returned when `videos` is not `None`. + """ + output_kwargs = self._merge_kwargs( + PaddleOCRVLProcessorKwargs, + tokenizer_init_kwargs=self.tokenizer.init_kwargs, + **kwargs, + ) + + if images is not None: + image_inputs = self.image_processor(images=images, return_tensors="pt") + image_inputs["pixel_values"] = image_inputs["pixel_values"] + image_grid_thw = image_inputs["image_grid_thw"] + + else: + image_inputs = {} + image_grid_thw = None + + if videos is not None: + # TODO: add video processing + videos_inputs = self.image_processor( + images=None, videos=videos, **output_kwargs["images_kwargs"] + ) + video_grid_thw = videos_inputs["video_grid_thw"] + + fps = output_kwargs["videos_kwargs"].pop("fps", 2.0) + if isinstance(fps, (int, float)): + second_per_grid_ts = [ + self.image_processor.temporal_patch_size / fps + ] * len(video_grid_thw) + elif hasattr(fps, "__len__") and len(fps) == len(video_grid_thw): + second_per_grid_ts = [ + self.image_processor.temporal_patch_size / tmp for tmp in fps + ] + else: + raise ValueError( + f"The length of fps ({len(fps) if hasattr(fps, '__len__') else fps}) must be equal to the length of video_grid_thw ({len(video_grid_thw)}) or fps should be a single number." + ) + videos_inputs.update( + {"second_per_grid_ts": torch.tensor(second_per_grid_ts)} + ) + + else: + videos_inputs = {} + video_grid_thw = None + + if not isinstance(text, list): + text = [text] + + if image_grid_thw is not None: + index = 0 + for i in range(len(text)): + while self.image_token in text[i]: + text[i] = text[i].replace( + self.image_token, + "<|placeholder|>" + * ( + image_grid_thw[index].prod() + // self.image_processor.merge_size + // self.image_processor.merge_size + ), + 1, + ) + index += 1 + text[i] = text[i].replace("<|placeholder|>", self.image_token) + + if video_grid_thw is not None: + index = 0 + for i in range(len(text)): + while self.video_token in text[i]: + text[i] = text[i].replace( + self.video_token, + "<|placeholder|>" + * ( + video_grid_thw[index].prod() + // self.image_processor.merge_size + // self.image_processor.merge_size + ), + 1, + ) + index += 1 + text[i] = text[i].replace("<|placeholder|>", self.video_token) + + text_inputs = self.tokenizer(text, **output_kwargs["text_kwargs"]) + + return BatchFeature(data={**text_inputs, **image_inputs, **videos_inputs}) + + def batch_decode(self, *args, **kwargs): + """ + This method forwards all its arguments to Qwen2TokenizerFast's [`~PreTrainedTokenizer.batch_decode`]. Please + refer to the docstring of this method for more information. + """ + return self.tokenizer.batch_decode(*args, **kwargs) + + def decode(self, *args, **kwargs): + """ + This method forwards all its arguments to Qwen2TokenizerFast's [`~PreTrainedTokenizer.decode`]. Please refer to + the docstring of this method for more information. + """ + return self.tokenizer.decode(*args, **kwargs) + + def post_process_image_text_to_text( + self, + generated_outputs, + skip_special_tokens=True, + clean_up_tokenization_spaces=False, + **kwargs, + ): + """ + Post-process the output of the model to decode the text. + + Args: + generated_outputs (`torch.Tensor` or `np.ndarray`): + The output of the model `generate` function. The output is expected to be a tensor of shape `(batch_size, sequence_length)` + or `(sequence_length,)`. + skip_special_tokens (`bool`, *optional*, defaults to `True`): + Whether or not to remove special tokens in the output. Argument passed to the tokenizer's `batch_decode` method. + Clean_up_tokenization_spaces (`bool`, *optional*, defaults to `False`): + Whether or not to clean up the tokenization spaces. Argument passed to the tokenizer's `batch_decode` method. + **kwargs: + Additional arguments to be passed to the tokenizer's `batch_decode method`. + + Returns: + `List[str]`: The decoded text. + """ + return self.tokenizer.batch_decode( + generated_outputs, + skip_special_tokens=skip_special_tokens, + clean_up_tokenization_spaces=clean_up_tokenization_spaces, + **kwargs, + ) + + @property + def model_input_names(self): + tokenizer_input_names = self.tokenizer.model_input_names + image_processor_input_names = self.image_processor.model_input_names + names_from_processor = list( + dict.fromkeys(tokenizer_input_names + image_processor_input_names) + ) + return names_from_processor + ["second_per_grid_ts"] + + +__all__ = ["PaddleOCRVLProcessor", "PaddleOCRVLProcessor"] diff --git a/paddleocr_vl_1-5_tokenizer/processor_config.json b/paddleocr_vl_1-5_tokenizer/processor_config.json new file mode 100644 index 0000000000000000000000000000000000000000..033053ac4d8b5de2e47884ce85a6b4939cc58e87 --- /dev/null +++ b/paddleocr_vl_1-5_tokenizer/processor_config.json @@ -0,0 +1,6 @@ +{ + "auto_map": { + "AutoProcessor": "processing_paddleocr_vl.PaddleOCRVLProcessor" + }, + "processor_class": "PaddleOCRVLProcessor" +} diff --git a/paddleocr_vl_1-5_tokenizer/special_tokens_map.json b/paddleocr_vl_1-5_tokenizer/special_tokens_map.json new file mode 100644 index 0000000000000000000000000000000000000000..dcd70aaa8c9987899d7593995546d9c0cfc6a1f3 --- /dev/null +++ b/paddleocr_vl_1-5_tokenizer/special_tokens_map.json @@ -0,0 +1,58 @@ +{ + "additional_special_tokens": [ + "<|IMAGE_PLACEHOLDER|>", + "<|image_pad|>", + "<|IMAGE_START|>", + "<|IMAGE_END|>", + "<|video_pad|>" + ], + "bos_token": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false + }, + "cls_token": { + "content": "<|begin_of_sentence|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false + }, + "eos_token": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false + }, + "mask_token": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false + }, + "pad_token": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false + }, + "sep_token": { + "content": "<|end_of_sentence|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false + }, + "unk_token": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false + } +} \ No newline at end of file diff --git a/paddleocr_vl_1-5_tokenizer/tokenizer.json b/paddleocr_vl_1-5_tokenizer/tokenizer.json new file mode 100644 index 0000000000000000000000000000000000000000..e42528d5cae447340ed0a3e403001c88fe9b0f17 --- /dev/null +++ b/paddleocr_vl_1-5_tokenizer/tokenizer.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c8a215a59183d0d0781adc33bacd3ce6162716f7fd568fb30234a74d69803a7d +size 11189060 diff --git a/paddleocr_vl_1-5_tokenizer/tokenizer.model b/paddleocr_vl_1-5_tokenizer/tokenizer.model new file mode 100644 index 0000000000000000000000000000000000000000..81e33aa7fdb8ef76fceb1a69f1997021f3056770 --- /dev/null +++ b/paddleocr_vl_1-5_tokenizer/tokenizer.model @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:34ef7db83df785924fb83d7b887b6e822a031c56e15cff40aaf9b982988180df +size 1614363 diff --git a/paddleocr_vl_1-5_tokenizer/tokenizer_config.json b/paddleocr_vl_1-5_tokenizer/tokenizer_config.json new file mode 100644 index 0000000000000000000000000000000000000000..cd9eb7da01a3209f4fb9b3561e04be022cd87764 --- /dev/null +++ b/paddleocr_vl_1-5_tokenizer/tokenizer_config.json @@ -0,0 +1,8362 @@ +{ + "add_bos_token": false, + "add_eos_token": false, + "add_prefix_space": false, + "added_tokens_decoder": { + "0": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "1": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "2": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "3": { + "content": "0", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "4": { + "content": "1", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "5": { + "content": "2", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "6": { + "content": "3", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "7": { + "content": "4", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "8": { + "content": "5", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "9": { + "content": "6", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "10": { + "content": "7", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "11": { + "content": "8", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "12": { + "content": "9", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100272": { + "content": "<|end_of_sentence|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "100273": { + "content": "<|begin_of_sentence|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "100274": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "100277": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "100278": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "100279": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "100280": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "100295": { + "content": "<|IMAGE_PLACEHOLDER|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "100296": { + "content": "<|AUDIO_PLACEHOLDER|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "100297": { + "content": "<|LOC_0|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100298": { + "content": "<|LOC_1|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100299": { + "content": "<|LOC_2|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100300": { + "content": "<|LOC_3|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100301": { + "content": "<|LOC_4|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100302": { + "content": "<|LOC_5|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100303": { + "content": "<|LOC_6|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100304": { + "content": "<|LOC_7|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100305": { + "content": "<|LOC_8|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100306": { + "content": "<|LOC_9|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100307": { + "content": "<|LOC_10|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100308": { + "content": "<|LOC_11|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100309": { + "content": "<|LOC_12|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100310": { + "content": "<|LOC_13|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100311": { + "content": "<|LOC_14|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100312": { + "content": "<|LOC_15|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100313": { + "content": "<|LOC_16|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100314": { + "content": "<|LOC_17|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100315": { + "content": "<|LOC_18|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100316": { + "content": "<|LOC_19|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100317": { + "content": "<|LOC_20|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100318": { + "content": "<|LOC_21|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100319": { + "content": "<|LOC_22|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100320": { + "content": "<|LOC_23|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100321": { + "content": "<|LOC_24|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100322": { + "content": "<|LOC_25|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100323": { + "content": "<|LOC_26|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100324": { + "content": "<|LOC_27|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100325": { + "content": "<|LOC_28|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100326": { + "content": "<|LOC_29|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100327": { + "content": "<|LOC_30|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100328": { + "content": "<|LOC_31|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100329": { + "content": "<|LOC_32|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100330": { + "content": "<|LOC_33|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100331": { + "content": "<|LOC_34|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100332": { + "content": "<|LOC_35|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100333": { + "content": "<|LOC_36|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100334": { + "content": "<|LOC_37|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100335": { + "content": "<|LOC_38|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100336": { + "content": "<|LOC_39|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100337": { + "content": "<|LOC_40|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100338": { + "content": "<|LOC_41|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100339": { + "content": "<|LOC_42|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100340": { + "content": "<|LOC_43|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100341": { + "content": "<|LOC_44|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100342": { + "content": "<|LOC_45|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100343": { + "content": "<|LOC_46|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100344": { + "content": "<|LOC_47|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100345": { + "content": "<|LOC_48|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100346": { + "content": "<|LOC_49|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100347": { + "content": "<|LOC_50|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100348": { + "content": "<|LOC_51|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100349": { + "content": "<|LOC_52|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100350": { + "content": "<|LOC_53|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100351": { + "content": "<|LOC_54|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100352": { + "content": "<|LOC_55|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100353": { + "content": "<|LOC_56|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100354": { + "content": "<|LOC_57|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100355": { + "content": "<|LOC_58|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100356": { + "content": "<|LOC_59|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100357": { + "content": "<|LOC_60|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100358": { + "content": "<|LOC_61|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100359": { + "content": "<|LOC_62|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100360": { + "content": "<|LOC_63|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100361": { + "content": "<|LOC_64|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100362": { + "content": "<|LOC_65|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100363": { + "content": "<|LOC_66|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100364": { + "content": "<|LOC_67|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100365": { + "content": "<|LOC_68|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100366": { + "content": "<|LOC_69|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100367": { + "content": "<|LOC_70|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100368": { + "content": "<|LOC_71|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100369": { + "content": "<|LOC_72|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100370": { + "content": "<|LOC_73|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100371": { + "content": "<|LOC_74|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100372": { + "content": "<|LOC_75|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100373": { + "content": "<|LOC_76|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100374": { + "content": "<|LOC_77|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100375": { + "content": "<|LOC_78|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100376": { + "content": "<|LOC_79|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100377": { + "content": "<|LOC_80|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100378": { + "content": "<|LOC_81|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100379": { + "content": "<|LOC_82|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100380": { + "content": "<|LOC_83|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100381": { + "content": "<|LOC_84|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100382": { + "content": "<|LOC_85|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100383": { + "content": "<|LOC_86|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100384": { + "content": "<|LOC_87|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100385": { + "content": "<|LOC_88|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100386": { + "content": "<|LOC_89|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100387": { + "content": "<|LOC_90|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100388": { + "content": "<|LOC_91|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100389": { + "content": "<|LOC_92|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100390": { + "content": "<|LOC_93|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100391": { + "content": "<|LOC_94|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100392": { + "content": "<|LOC_95|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100393": { + "content": "<|LOC_96|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100394": { + "content": "<|LOC_97|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100395": { + "content": "<|LOC_98|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100396": { + "content": "<|LOC_99|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100397": { + "content": "<|LOC_100|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100398": { + "content": "<|LOC_101|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100399": { + "content": "<|LOC_102|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100400": { + "content": "<|LOC_103|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100401": { + "content": "<|LOC_104|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100402": { + "content": "<|LOC_105|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100403": { + "content": "<|LOC_106|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100404": { + "content": "<|LOC_107|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100405": { + "content": "<|LOC_108|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100406": { + "content": "<|LOC_109|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100407": { + "content": "<|LOC_110|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100408": { + "content": "<|LOC_111|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100409": { + "content": "<|LOC_112|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100410": { + "content": "<|LOC_113|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100411": { + "content": "<|LOC_114|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100412": { + "content": "<|LOC_115|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100413": { + "content": "<|LOC_116|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100414": { + "content": "<|LOC_117|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100415": { + "content": "<|LOC_118|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100416": { + "content": "<|LOC_119|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100417": { + "content": "<|LOC_120|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100418": { + "content": "<|LOC_121|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100419": { + "content": "<|LOC_122|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100420": { + "content": "<|LOC_123|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100421": { + "content": "<|LOC_124|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100422": { + "content": "<|LOC_125|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100423": { + "content": "<|LOC_126|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100424": { + "content": "<|LOC_127|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100425": { + "content": "<|LOC_128|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100426": { + "content": "<|LOC_129|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100427": { + "content": "<|LOC_130|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100428": { + "content": "<|LOC_131|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100429": { + "content": "<|LOC_132|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100430": { + "content": "<|LOC_133|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100431": { + "content": "<|LOC_134|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100432": { + "content": "<|LOC_135|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100433": { + "content": "<|LOC_136|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100434": { + "content": "<|LOC_137|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100435": { + "content": "<|LOC_138|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100436": { + "content": "<|LOC_139|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100437": { + "content": "<|LOC_140|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100438": { + "content": "<|LOC_141|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100439": { + "content": "<|LOC_142|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100440": { + "content": "<|LOC_143|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100441": { + "content": "<|LOC_144|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100442": { + "content": "<|LOC_145|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100443": { + "content": "<|LOC_146|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100444": { + "content": "<|LOC_147|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100445": { + "content": "<|LOC_148|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100446": { + "content": "<|LOC_149|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100447": { + "content": "<|LOC_150|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100448": { + "content": "<|LOC_151|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100449": { + "content": "<|LOC_152|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100450": { + "content": "<|LOC_153|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100451": { + "content": "<|LOC_154|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100452": { + "content": "<|LOC_155|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100453": { + "content": "<|LOC_156|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100454": { + "content": "<|LOC_157|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100455": { + "content": "<|LOC_158|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100456": { + "content": "<|LOC_159|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100457": { + "content": "<|LOC_160|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100458": { + "content": "<|LOC_161|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100459": { + "content": "<|LOC_162|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100460": { + "content": "<|LOC_163|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100461": { + "content": "<|LOC_164|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100462": { + "content": "<|LOC_165|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100463": { + "content": "<|LOC_166|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100464": { + "content": "<|LOC_167|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100465": { + "content": "<|LOC_168|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100466": { + "content": "<|LOC_169|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100467": { + "content": "<|LOC_170|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100468": { + "content": "<|LOC_171|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100469": { + "content": "<|LOC_172|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100470": { + "content": "<|LOC_173|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100471": { + "content": "<|LOC_174|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100472": { + "content": "<|LOC_175|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100473": { + "content": "<|LOC_176|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100474": { + "content": "<|LOC_177|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100475": { + "content": "<|LOC_178|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100476": { + "content": "<|LOC_179|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100477": { + "content": "<|LOC_180|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100478": { + "content": "<|LOC_181|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100479": { + "content": "<|LOC_182|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100480": { + "content": "<|LOC_183|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100481": { + "content": "<|LOC_184|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100482": { + "content": "<|LOC_185|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100483": { + "content": "<|LOC_186|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100484": { + "content": "<|LOC_187|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100485": { + "content": "<|LOC_188|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100486": { + "content": "<|LOC_189|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100487": { + "content": "<|LOC_190|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100488": { + "content": "<|LOC_191|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100489": { + "content": "<|LOC_192|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100490": { + "content": "<|LOC_193|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100491": { + "content": "<|LOC_194|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100492": { + "content": "<|LOC_195|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100493": { + "content": "<|LOC_196|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100494": { + "content": "<|LOC_197|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100495": { + "content": "<|LOC_198|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100496": { + "content": "<|LOC_199|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100497": { + "content": "<|LOC_200|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100498": { + "content": "<|LOC_201|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100499": { + "content": "<|LOC_202|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100500": { + "content": "<|LOC_203|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100501": { + "content": "<|LOC_204|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100502": { + "content": "<|LOC_205|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100503": { + "content": "<|LOC_206|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100504": { + "content": "<|LOC_207|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100505": { + "content": "<|LOC_208|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100506": { + "content": "<|LOC_209|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100507": { + "content": "<|LOC_210|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100508": { + "content": "<|LOC_211|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100509": { + "content": "<|LOC_212|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100510": { + "content": "<|LOC_213|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100511": { + "content": "<|LOC_214|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100512": { + "content": "<|LOC_215|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100513": { + "content": "<|LOC_216|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100514": { + "content": "<|LOC_217|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100515": { + "content": "<|LOC_218|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100516": { + "content": "<|LOC_219|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100517": { + "content": "<|LOC_220|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100518": { + "content": "<|LOC_221|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100519": { + "content": "<|LOC_222|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100520": { + "content": "<|LOC_223|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100521": { + "content": "<|LOC_224|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100522": { + "content": "<|LOC_225|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100523": { + "content": "<|LOC_226|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100524": { + "content": "<|LOC_227|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100525": { + "content": "<|LOC_228|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100526": { + "content": "<|LOC_229|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100527": { + "content": "<|LOC_230|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100528": { + "content": "<|LOC_231|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100529": { + "content": "<|LOC_232|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100530": { + "content": "<|LOC_233|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100531": { + "content": "<|LOC_234|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100532": { + "content": "<|LOC_235|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100533": { + "content": "<|LOC_236|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100534": { + "content": "<|LOC_237|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100535": { + "content": "<|LOC_238|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100536": { + "content": "<|LOC_239|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100537": { + "content": "<|LOC_240|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100538": { + "content": "<|LOC_241|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100539": { + "content": "<|LOC_242|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100540": { + "content": "<|LOC_243|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100541": { + "content": "<|LOC_244|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100542": { + "content": "<|LOC_245|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100543": { + "content": "<|LOC_246|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100544": { + "content": "<|LOC_247|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100545": { + "content": "<|LOC_248|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100546": { + "content": "<|LOC_249|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100547": { + "content": "<|LOC_250|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100548": { + "content": "<|LOC_251|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100549": { + "content": "<|LOC_252|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100550": { + "content": "<|LOC_253|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100551": { + "content": "<|LOC_254|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100552": { + "content": "<|LOC_255|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100553": { + "content": "<|LOC_256|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100554": { + "content": "<|LOC_257|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100555": { + "content": "<|LOC_258|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100556": { + "content": "<|LOC_259|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100557": { + "content": "<|LOC_260|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100558": { + "content": "<|LOC_261|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100559": { + "content": "<|LOC_262|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100560": { + "content": "<|LOC_263|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100561": { + "content": "<|LOC_264|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100562": { + "content": "<|LOC_265|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100563": { + "content": "<|LOC_266|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100564": { + "content": "<|LOC_267|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100565": { + "content": "<|LOC_268|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100566": { + "content": "<|LOC_269|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100567": { + "content": "<|LOC_270|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100568": { + "content": "<|LOC_271|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100569": { + "content": "<|LOC_272|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100570": { + "content": "<|LOC_273|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100571": { + "content": "<|LOC_274|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100572": { + "content": "<|LOC_275|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100573": { + "content": "<|LOC_276|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100574": { + "content": "<|LOC_277|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100575": { + "content": "<|LOC_278|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100576": { + "content": "<|LOC_279|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100577": { + "content": "<|LOC_280|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100578": { + "content": "<|LOC_281|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100579": { + "content": "<|LOC_282|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100580": { + "content": "<|LOC_283|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100581": { + "content": "<|LOC_284|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100582": { + "content": "<|LOC_285|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100583": { + "content": "<|LOC_286|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100584": { + "content": "<|LOC_287|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100585": { + "content": "<|LOC_288|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100586": { + "content": "<|LOC_289|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100587": { + "content": "<|LOC_290|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100588": { + "content": "<|LOC_291|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100589": { + "content": "<|LOC_292|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100590": { + "content": "<|LOC_293|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100591": { + "content": "<|LOC_294|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100592": { + "content": "<|LOC_295|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100593": { + "content": "<|LOC_296|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100594": { + "content": "<|LOC_297|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100595": { + "content": "<|LOC_298|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100596": { + "content": "<|LOC_299|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100597": { + "content": "<|LOC_300|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100598": { + "content": "<|LOC_301|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100599": { + "content": "<|LOC_302|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100600": { + "content": "<|LOC_303|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100601": { + "content": "<|LOC_304|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100602": { + "content": "<|LOC_305|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100603": { + "content": "<|LOC_306|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100604": { + "content": "<|LOC_307|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100605": { + "content": "<|LOC_308|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100606": { + "content": "<|LOC_309|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100607": { + "content": "<|LOC_310|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100608": { + "content": "<|LOC_311|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100609": { + "content": "<|LOC_312|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100610": { + "content": "<|LOC_313|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100611": { + "content": "<|LOC_314|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100612": { + "content": "<|LOC_315|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100613": { + "content": "<|LOC_316|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100614": { + "content": "<|LOC_317|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100615": { + "content": "<|LOC_318|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100616": { + "content": "<|LOC_319|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100617": { + "content": "<|LOC_320|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100618": { + "content": "<|LOC_321|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100619": { + "content": "<|LOC_322|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100620": { + "content": "<|LOC_323|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100621": { + "content": "<|LOC_324|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100622": { + "content": "<|LOC_325|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100623": { + "content": "<|LOC_326|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100624": { + "content": "<|LOC_327|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100625": { + "content": "<|LOC_328|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100626": { + "content": "<|LOC_329|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100627": { + "content": "<|LOC_330|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100628": { + "content": "<|LOC_331|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100629": { + "content": "<|LOC_332|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100630": { + "content": "<|LOC_333|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100631": { + "content": "<|LOC_334|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100632": { + "content": "<|LOC_335|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100633": { + "content": "<|LOC_336|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100634": { + "content": "<|LOC_337|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100635": { + "content": "<|LOC_338|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100636": { + "content": "<|LOC_339|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100637": { + "content": "<|LOC_340|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100638": { + "content": "<|LOC_341|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100639": { + "content": "<|LOC_342|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100640": { + "content": "<|LOC_343|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100641": { + "content": "<|LOC_344|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100642": { + "content": "<|LOC_345|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100643": { + "content": "<|LOC_346|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100644": { + "content": "<|LOC_347|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100645": { + "content": "<|LOC_348|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100646": { + "content": "<|LOC_349|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100647": { + "content": "<|LOC_350|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100648": { + "content": "<|LOC_351|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100649": { + "content": "<|LOC_352|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100650": { + "content": "<|LOC_353|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100651": { + "content": "<|LOC_354|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100652": { + "content": "<|LOC_355|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100653": { + "content": "<|LOC_356|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100654": { + "content": "<|LOC_357|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100655": { + "content": "<|LOC_358|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100656": { + "content": "<|LOC_359|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100657": { + "content": "<|LOC_360|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100658": { + "content": "<|LOC_361|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100659": { + "content": "<|LOC_362|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100660": { + "content": "<|LOC_363|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100661": { + "content": "<|LOC_364|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100662": { + "content": "<|LOC_365|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100663": { + "content": "<|LOC_366|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100664": { + "content": "<|LOC_367|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100665": { + "content": "<|LOC_368|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100666": { + "content": "<|LOC_369|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100667": { + "content": "<|LOC_370|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100668": { + "content": "<|LOC_371|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100669": { + "content": "<|LOC_372|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100670": { + "content": "<|LOC_373|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100671": { + "content": "<|LOC_374|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100672": { + "content": "<|LOC_375|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100673": { + "content": "<|LOC_376|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100674": { + "content": "<|LOC_377|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100675": { + "content": "<|LOC_378|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100676": { + "content": "<|LOC_379|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100677": { + "content": "<|LOC_380|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100678": { + "content": "<|LOC_381|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100679": { + "content": "<|LOC_382|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100680": { + "content": "<|LOC_383|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100681": { + "content": "<|LOC_384|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100682": { + "content": "<|LOC_385|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100683": { + "content": "<|LOC_386|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100684": { + "content": "<|LOC_387|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100685": { + "content": "<|LOC_388|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100686": { + "content": "<|LOC_389|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100687": { + "content": "<|LOC_390|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100688": { + "content": "<|LOC_391|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100689": { + "content": "<|LOC_392|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100690": { + "content": "<|LOC_393|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100691": { + "content": "<|LOC_394|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100692": { + "content": "<|LOC_395|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100693": { + "content": "<|LOC_396|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100694": { + "content": "<|LOC_397|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100695": { + "content": "<|LOC_398|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100696": { + "content": "<|LOC_399|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100697": { + "content": "<|LOC_400|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100698": { + "content": "<|LOC_401|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100699": { + "content": "<|LOC_402|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100700": { + "content": "<|LOC_403|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100701": { + "content": "<|LOC_404|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100702": { + "content": "<|LOC_405|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100703": { + "content": "<|LOC_406|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100704": { + "content": "<|LOC_407|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100705": { + "content": "<|LOC_408|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100706": { + "content": "<|LOC_409|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100707": { + "content": "<|LOC_410|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100708": { + "content": "<|LOC_411|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100709": { + "content": "<|LOC_412|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100710": { + "content": "<|LOC_413|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100711": { + "content": "<|LOC_414|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100712": { + "content": "<|LOC_415|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100713": { + "content": "<|LOC_416|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100714": { + "content": "<|LOC_417|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100715": { + "content": "<|LOC_418|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100716": { + "content": "<|LOC_419|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100717": { + "content": "<|LOC_420|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100718": { + "content": "<|LOC_421|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100719": { + "content": "<|LOC_422|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100720": { + "content": "<|LOC_423|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100721": { + "content": "<|LOC_424|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100722": { + "content": "<|LOC_425|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100723": { + "content": "<|LOC_426|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100724": { + "content": "<|LOC_427|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100725": { + "content": "<|LOC_428|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100726": { + "content": "<|LOC_429|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100727": { + "content": "<|LOC_430|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100728": { + "content": "<|LOC_431|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100729": { + "content": "<|LOC_432|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100730": { + "content": "<|LOC_433|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100731": { + "content": "<|LOC_434|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100732": { + "content": "<|LOC_435|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100733": { + "content": "<|LOC_436|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100734": { + "content": "<|LOC_437|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100735": { + "content": "<|LOC_438|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100736": { + "content": "<|LOC_439|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100737": { + "content": "<|LOC_440|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100738": { + "content": "<|LOC_441|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100739": { + "content": "<|LOC_442|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100740": { + "content": "<|LOC_443|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100741": { + "content": "<|LOC_444|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100742": { + "content": "<|LOC_445|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100743": { + "content": "<|LOC_446|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100744": { + "content": "<|LOC_447|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100745": { + "content": "<|LOC_448|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100746": { + "content": "<|LOC_449|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100747": { + "content": "<|LOC_450|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100748": { + "content": "<|LOC_451|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100749": { + "content": "<|LOC_452|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100750": { + "content": "<|LOC_453|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100751": { + "content": "<|LOC_454|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100752": { + "content": "<|LOC_455|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100753": { + "content": "<|LOC_456|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100754": { + "content": "<|LOC_457|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100755": { + "content": "<|LOC_458|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100756": { + "content": "<|LOC_459|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100757": { + "content": "<|LOC_460|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100758": { + "content": "<|LOC_461|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100759": { + "content": "<|LOC_462|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100760": { + "content": "<|LOC_463|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100761": { + "content": "<|LOC_464|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100762": { + "content": "<|LOC_465|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100763": { + "content": "<|LOC_466|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100764": { + "content": "<|LOC_467|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100765": { + "content": "<|LOC_468|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100766": { + "content": "<|LOC_469|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100767": { + "content": "<|LOC_470|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100768": { + "content": "<|LOC_471|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100769": { + "content": "<|LOC_472|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100770": { + "content": "<|LOC_473|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100771": { + "content": "<|LOC_474|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100772": { + "content": "<|LOC_475|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100773": { + "content": "<|LOC_476|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100774": { + "content": "<|LOC_477|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100775": { + "content": "<|LOC_478|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100776": { + "content": "<|LOC_479|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100777": { + "content": "<|LOC_480|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100778": { + "content": "<|LOC_481|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100779": { + "content": "<|LOC_482|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100780": { + "content": "<|LOC_483|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100781": { + "content": "<|LOC_484|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100782": { + "content": "<|LOC_485|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100783": { + "content": "<|LOC_486|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100784": { + "content": "<|LOC_487|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100785": { + "content": "<|LOC_488|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100786": { + "content": "<|LOC_489|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100787": { + "content": "<|LOC_490|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100788": { + "content": "<|LOC_491|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100789": { + "content": "<|LOC_492|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100790": { + "content": "<|LOC_493|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100791": { + "content": "<|LOC_494|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100792": { + "content": "<|LOC_495|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100793": { + "content": "<|LOC_496|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100794": { + "content": "<|LOC_497|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100795": { + "content": "<|LOC_498|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100796": { + "content": "<|LOC_499|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100797": { + "content": "<|LOC_500|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100798": { + "content": "<|LOC_501|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100799": { + "content": "<|LOC_502|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100800": { + "content": "<|LOC_503|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100801": { + "content": "<|LOC_504|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100802": { + "content": "<|LOC_505|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100803": { + "content": "<|LOC_506|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100804": { + "content": "<|LOC_507|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100805": { + "content": "<|LOC_508|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100806": { + "content": "<|LOC_509|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100807": { + "content": "<|LOC_510|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100808": { + "content": "<|LOC_511|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100809": { + "content": "<|LOC_512|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100810": { + "content": "<|LOC_513|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100811": { + "content": "<|LOC_514|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100812": { + "content": "<|LOC_515|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100813": { + "content": "<|LOC_516|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100814": { + "content": "<|LOC_517|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100815": { + "content": "<|LOC_518|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100816": { + "content": "<|LOC_519|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100817": { + "content": "<|LOC_520|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100818": { + "content": "<|LOC_521|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100819": { + "content": "<|LOC_522|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100820": { + "content": "<|LOC_523|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100821": { + "content": "<|LOC_524|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100822": { + "content": "<|LOC_525|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100823": { + "content": "<|LOC_526|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100824": { + "content": "<|LOC_527|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100825": { + "content": "<|LOC_528|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100826": { + "content": "<|LOC_529|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100827": { + "content": "<|LOC_530|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100828": { + "content": "<|LOC_531|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100829": { + "content": "<|LOC_532|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100830": { + "content": "<|LOC_533|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100831": { + "content": "<|LOC_534|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100832": { + "content": "<|LOC_535|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100833": { + "content": "<|LOC_536|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100834": { + "content": "<|LOC_537|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100835": { + "content": "<|LOC_538|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100836": { + "content": "<|LOC_539|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100837": { + "content": "<|LOC_540|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100838": { + "content": "<|LOC_541|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100839": { + "content": "<|LOC_542|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100840": { + "content": "<|LOC_543|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100841": { + "content": "<|LOC_544|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100842": { + "content": "<|LOC_545|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100843": { + "content": "<|LOC_546|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100844": { + "content": "<|LOC_547|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100845": { + "content": "<|LOC_548|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100846": { + "content": "<|LOC_549|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100847": { + "content": "<|LOC_550|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100848": { + "content": "<|LOC_551|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100849": { + "content": "<|LOC_552|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100850": { + "content": "<|LOC_553|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100851": { + "content": "<|LOC_554|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100852": { + "content": "<|LOC_555|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100853": { + "content": "<|LOC_556|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100854": { + "content": "<|LOC_557|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100855": { + "content": "<|LOC_558|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100856": { + "content": "<|LOC_559|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100857": { + "content": "<|LOC_560|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100858": { + "content": "<|LOC_561|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100859": { + "content": "<|LOC_562|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100860": { + "content": "<|LOC_563|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100861": { + "content": "<|LOC_564|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100862": { + "content": "<|LOC_565|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100863": { + "content": "<|LOC_566|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100864": { + "content": "<|LOC_567|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100865": { + "content": "<|LOC_568|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100866": { + "content": "<|LOC_569|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100867": { + "content": "<|LOC_570|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100868": { + "content": "<|LOC_571|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100869": { + "content": "<|LOC_572|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100870": { + "content": "<|LOC_573|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100871": { + "content": "<|LOC_574|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100872": { + "content": "<|LOC_575|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100873": { + "content": "<|LOC_576|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100874": { + "content": "<|LOC_577|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100875": { + "content": "<|LOC_578|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100876": { + "content": "<|LOC_579|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100877": { + "content": "<|LOC_580|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100878": { + "content": "<|LOC_581|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100879": { + "content": "<|LOC_582|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100880": { + "content": "<|LOC_583|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100881": { + "content": "<|LOC_584|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100882": { + "content": "<|LOC_585|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100883": { + "content": "<|LOC_586|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100884": { + "content": "<|LOC_587|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100885": { + "content": "<|LOC_588|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100886": { + "content": "<|LOC_589|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100887": { + "content": "<|LOC_590|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100888": { + "content": "<|LOC_591|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100889": { + "content": "<|LOC_592|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100890": { + "content": "<|LOC_593|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100891": { + "content": "<|LOC_594|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100892": { + "content": "<|LOC_595|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100893": { + "content": "<|LOC_596|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100894": { + "content": "<|LOC_597|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100895": { + "content": "<|LOC_598|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100896": { + "content": "<|LOC_599|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100897": { + "content": "<|LOC_600|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100898": { + "content": "<|LOC_601|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100899": { + "content": "<|LOC_602|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100900": { + "content": "<|LOC_603|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100901": { + "content": "<|LOC_604|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100902": { + "content": "<|LOC_605|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100903": { + "content": "<|LOC_606|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100904": { + "content": "<|LOC_607|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100905": { + "content": "<|LOC_608|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100906": { + "content": "<|LOC_609|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100907": { + "content": "<|LOC_610|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100908": { + "content": "<|LOC_611|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100909": { + "content": "<|LOC_612|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100910": { + "content": "<|LOC_613|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100911": { + "content": "<|LOC_614|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100912": { + "content": "<|LOC_615|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100913": { + "content": "<|LOC_616|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100914": { + "content": "<|LOC_617|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100915": { + "content": "<|LOC_618|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100916": { + "content": "<|LOC_619|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100917": { + "content": "<|LOC_620|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100918": { + "content": "<|LOC_621|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100919": { + "content": "<|LOC_622|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100920": { + "content": "<|LOC_623|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100921": { + "content": "<|LOC_624|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100922": { + "content": "<|LOC_625|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100923": { + "content": "<|LOC_626|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100924": { + "content": "<|LOC_627|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100925": { + "content": "<|LOC_628|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100926": { + "content": "<|LOC_629|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100927": { + "content": "<|LOC_630|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100928": { + "content": "<|LOC_631|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100929": { + "content": "<|LOC_632|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100930": { + "content": "<|LOC_633|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100931": { + "content": "<|LOC_634|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100932": { + "content": "<|LOC_635|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100933": { + "content": "<|LOC_636|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100934": { + "content": "<|LOC_637|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100935": { + "content": "<|LOC_638|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100936": { + "content": "<|LOC_639|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100937": { + "content": "<|LOC_640|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100938": { + "content": "<|LOC_641|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100939": { + "content": "<|LOC_642|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100940": { + "content": "<|LOC_643|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100941": { + "content": "<|LOC_644|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100942": { + "content": "<|LOC_645|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100943": { + "content": "<|LOC_646|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100944": { + "content": "<|LOC_647|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100945": { + "content": "<|LOC_648|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100946": { + "content": "<|LOC_649|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100947": { + "content": "<|LOC_650|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100948": { + "content": "<|LOC_651|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100949": { + "content": "<|LOC_652|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100950": { + "content": "<|LOC_653|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100951": { + "content": "<|LOC_654|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100952": { + "content": "<|LOC_655|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100953": { + "content": "<|LOC_656|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100954": { + "content": "<|LOC_657|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100955": { + "content": "<|LOC_658|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100956": { + "content": "<|LOC_659|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100957": { + "content": "<|LOC_660|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100958": { + "content": "<|LOC_661|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100959": { + "content": "<|LOC_662|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100960": { + "content": "<|LOC_663|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100961": { + "content": "<|LOC_664|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100962": { + "content": "<|LOC_665|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100963": { + "content": "<|LOC_666|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100964": { + "content": "<|LOC_667|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100965": { + "content": "<|LOC_668|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100966": { + "content": "<|LOC_669|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100967": { + "content": "<|LOC_670|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100968": { + "content": "<|LOC_671|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100969": { + "content": "<|LOC_672|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100970": { + "content": "<|LOC_673|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100971": { + "content": "<|LOC_674|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100972": { + "content": "<|LOC_675|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100973": { + "content": "<|LOC_676|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100974": { + "content": "<|LOC_677|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100975": { + "content": "<|LOC_678|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100976": { + "content": "<|LOC_679|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100977": { + "content": "<|LOC_680|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100978": { + "content": "<|LOC_681|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100979": { + "content": "<|LOC_682|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100980": { + "content": "<|LOC_683|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100981": { + "content": "<|LOC_684|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100982": { + "content": "<|LOC_685|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100983": { + "content": "<|LOC_686|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100984": { + "content": "<|LOC_687|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100985": { + "content": "<|LOC_688|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100986": { + "content": "<|LOC_689|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100987": { + "content": "<|LOC_690|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100988": { + "content": "<|LOC_691|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100989": { + "content": "<|LOC_692|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100990": { + "content": "<|LOC_693|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100991": { + "content": "<|LOC_694|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100992": { + "content": "<|LOC_695|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100993": { + "content": "<|LOC_696|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100994": { + "content": "<|LOC_697|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100995": { + "content": "<|LOC_698|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100996": { + "content": "<|LOC_699|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100997": { + "content": "<|LOC_700|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100998": { + "content": "<|LOC_701|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "100999": { + "content": "<|LOC_702|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101000": { + "content": "<|LOC_703|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101001": { + "content": "<|LOC_704|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101002": { + "content": "<|LOC_705|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101003": { + "content": "<|LOC_706|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101004": { + "content": "<|LOC_707|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101005": { + "content": "<|LOC_708|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101006": { + "content": "<|LOC_709|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101007": { + "content": "<|LOC_710|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101008": { + "content": "<|LOC_711|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101009": { + "content": "<|LOC_712|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101010": { + "content": "<|LOC_713|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101011": { + "content": "<|LOC_714|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101012": { + "content": "<|LOC_715|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101013": { + "content": "<|LOC_716|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101014": { + "content": "<|LOC_717|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101015": { + "content": "<|LOC_718|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101016": { + "content": "<|LOC_719|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101017": { + "content": "<|LOC_720|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101018": { + "content": "<|LOC_721|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101019": { + "content": "<|LOC_722|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101020": { + "content": "<|LOC_723|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101021": { + "content": "<|LOC_724|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101022": { + "content": "<|LOC_725|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101023": { + "content": "<|LOC_726|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101024": { + "content": "<|LOC_727|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101025": { + "content": "<|LOC_728|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101026": { + "content": "<|LOC_729|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101027": { + "content": "<|LOC_730|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101028": { + "content": "<|LOC_731|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101029": { + "content": "<|LOC_732|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101030": { + "content": "<|LOC_733|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101031": { + "content": "<|LOC_734|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101032": { + "content": "<|LOC_735|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101033": { + "content": "<|LOC_736|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101034": { + "content": "<|LOC_737|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101035": { + "content": "<|LOC_738|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101036": { + "content": "<|LOC_739|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101037": { + "content": "<|LOC_740|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101038": { + "content": "<|LOC_741|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101039": { + "content": "<|LOC_742|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101040": { + "content": "<|LOC_743|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101041": { + "content": "<|LOC_744|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101042": { + "content": "<|LOC_745|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101043": { + "content": "<|LOC_746|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101044": { + "content": "<|LOC_747|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101045": { + "content": "<|LOC_748|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101046": { + "content": "<|LOC_749|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101047": { + "content": "<|LOC_750|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101048": { + "content": "<|LOC_751|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101049": { + "content": "<|LOC_752|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101050": { + "content": "<|LOC_753|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101051": { + "content": "<|LOC_754|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101052": { + "content": "<|LOC_755|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101053": { + "content": "<|LOC_756|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101054": { + "content": "<|LOC_757|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101055": { + "content": "<|LOC_758|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101056": { + "content": "<|LOC_759|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101057": { + "content": "<|LOC_760|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101058": { + "content": "<|LOC_761|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101059": { + "content": "<|LOC_762|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101060": { + "content": "<|LOC_763|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101061": { + "content": "<|LOC_764|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101062": { + "content": "<|LOC_765|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101063": { + "content": "<|LOC_766|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101064": { + "content": "<|LOC_767|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101065": { + "content": "<|LOC_768|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101066": { + "content": "<|LOC_769|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101067": { + "content": "<|LOC_770|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101068": { + "content": "<|LOC_771|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101069": { + "content": "<|LOC_772|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101070": { + "content": "<|LOC_773|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101071": { + "content": "<|LOC_774|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101072": { + "content": "<|LOC_775|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101073": { + "content": "<|LOC_776|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101074": { + "content": "<|LOC_777|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101075": { + "content": "<|LOC_778|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101076": { + "content": "<|LOC_779|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101077": { + "content": "<|LOC_780|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101078": { + "content": "<|LOC_781|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101079": { + "content": "<|LOC_782|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101080": { + "content": "<|LOC_783|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101081": { + "content": "<|LOC_784|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101082": { + "content": "<|LOC_785|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101083": { + "content": "<|LOC_786|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101084": { + "content": "<|LOC_787|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101085": { + "content": "<|LOC_788|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101086": { + "content": "<|LOC_789|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101087": { + "content": "<|LOC_790|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101088": { + "content": "<|LOC_791|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101089": { + "content": "<|LOC_792|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101090": { + "content": "<|LOC_793|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101091": { + "content": "<|LOC_794|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101092": { + "content": "<|LOC_795|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101093": { + "content": "<|LOC_796|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101094": { + "content": "<|LOC_797|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101095": { + "content": "<|LOC_798|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101096": { + "content": "<|LOC_799|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101097": { + "content": "<|LOC_800|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101098": { + "content": "<|LOC_801|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101099": { + "content": "<|LOC_802|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101100": { + "content": "<|LOC_803|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101101": { + "content": "<|LOC_804|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101102": { + "content": "<|LOC_805|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101103": { + "content": "<|LOC_806|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101104": { + "content": "<|LOC_807|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101105": { + "content": "<|LOC_808|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101106": { + "content": "<|LOC_809|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101107": { + "content": "<|LOC_810|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101108": { + "content": "<|LOC_811|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101109": { + "content": "<|LOC_812|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101110": { + "content": "<|LOC_813|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101111": { + "content": "<|LOC_814|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101112": { + "content": "<|LOC_815|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101113": { + "content": "<|LOC_816|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101114": { + "content": "<|LOC_817|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101115": { + "content": "<|LOC_818|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101116": { + "content": "<|LOC_819|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101117": { + "content": "<|LOC_820|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101118": { + "content": "<|LOC_821|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101119": { + "content": "<|LOC_822|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101120": { + "content": "<|LOC_823|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101121": { + "content": "<|LOC_824|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101122": { + "content": "<|LOC_825|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101123": { + "content": "<|LOC_826|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101124": { + "content": "<|LOC_827|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101125": { + "content": "<|LOC_828|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101126": { + "content": "<|LOC_829|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101127": { + "content": "<|LOC_830|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101128": { + "content": "<|LOC_831|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101129": { + "content": "<|LOC_832|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101130": { + "content": "<|LOC_833|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101131": { + "content": "<|LOC_834|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101132": { + "content": "<|LOC_835|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101133": { + "content": "<|LOC_836|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101134": { + "content": "<|LOC_837|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101135": { + "content": "<|LOC_838|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101136": { + "content": "<|LOC_839|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101137": { + "content": "<|LOC_840|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101138": { + "content": "<|LOC_841|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101139": { + "content": "<|LOC_842|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101140": { + "content": "<|LOC_843|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101141": { + "content": "<|LOC_844|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101142": { + "content": "<|LOC_845|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101143": { + "content": "<|LOC_846|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101144": { + "content": "<|LOC_847|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101145": { + "content": "<|LOC_848|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101146": { + "content": "<|LOC_849|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101147": { + "content": "<|LOC_850|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101148": { + "content": "<|LOC_851|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101149": { + "content": "<|LOC_852|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101150": { + "content": "<|LOC_853|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101151": { + "content": "<|LOC_854|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101152": { + "content": "<|LOC_855|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101153": { + "content": "<|LOC_856|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101154": { + "content": "<|LOC_857|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101155": { + "content": "<|LOC_858|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101156": { + "content": "<|LOC_859|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101157": { + "content": "<|LOC_860|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101158": { + "content": "<|LOC_861|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101159": { + "content": "<|LOC_862|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101160": { + "content": "<|LOC_863|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101161": { + "content": "<|LOC_864|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101162": { + "content": "<|LOC_865|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101163": { + "content": "<|LOC_866|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101164": { + "content": "<|LOC_867|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101165": { + "content": "<|LOC_868|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101166": { + "content": "<|LOC_869|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101167": { + "content": "<|LOC_870|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101168": { + "content": "<|LOC_871|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101169": { + "content": "<|LOC_872|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101170": { + "content": "<|LOC_873|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101171": { + "content": "<|LOC_874|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101172": { + "content": "<|LOC_875|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101173": { + "content": "<|LOC_876|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101174": { + "content": "<|LOC_877|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101175": { + "content": "<|LOC_878|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101176": { + "content": "<|LOC_879|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101177": { + "content": "<|LOC_880|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101178": { + "content": "<|LOC_881|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101179": { + "content": "<|LOC_882|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101180": { + "content": "<|LOC_883|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101181": { + "content": "<|LOC_884|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101182": { + "content": "<|LOC_885|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101183": { + "content": "<|LOC_886|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101184": { + "content": "<|LOC_887|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101185": { + "content": "<|LOC_888|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101186": { + "content": "<|LOC_889|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101187": { + "content": "<|LOC_890|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101188": { + "content": "<|LOC_891|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101189": { + "content": "<|LOC_892|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101190": { + "content": "<|LOC_893|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101191": { + "content": "<|LOC_894|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101192": { + "content": "<|LOC_895|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101193": { + "content": "<|LOC_896|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101194": { + "content": "<|LOC_897|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101195": { + "content": "<|LOC_898|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101196": { + "content": "<|LOC_899|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101197": { + "content": "<|LOC_900|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101198": { + "content": "<|LOC_901|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101199": { + "content": "<|LOC_902|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101200": { + "content": "<|LOC_903|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101201": { + "content": "<|LOC_904|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101202": { + "content": "<|LOC_905|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101203": { + "content": "<|LOC_906|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101204": { + "content": "<|LOC_907|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101205": { + "content": "<|LOC_908|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101206": { + "content": "<|LOC_909|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101207": { + "content": "<|LOC_910|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101208": { + "content": "<|LOC_911|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101209": { + "content": "<|LOC_912|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101210": { + "content": "<|LOC_913|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101211": { + "content": "<|LOC_914|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101212": { + "content": "<|LOC_915|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101213": { + "content": "<|LOC_916|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101214": { + "content": "<|LOC_917|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101215": { + "content": "<|LOC_918|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101216": { + "content": "<|LOC_919|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101217": { + "content": "<|LOC_920|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101218": { + "content": "<|LOC_921|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101219": { + "content": "<|LOC_922|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101220": { + "content": "<|LOC_923|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101221": { + "content": "<|LOC_924|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101222": { + "content": "<|LOC_925|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101223": { + "content": "<|LOC_926|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101224": { + "content": "<|LOC_927|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101225": { + "content": "<|LOC_928|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101226": { + "content": "<|LOC_929|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101227": { + "content": "<|LOC_930|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101228": { + "content": "<|LOC_931|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101229": { + "content": "<|LOC_932|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101230": { + "content": "<|LOC_933|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101231": { + "content": "<|LOC_934|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101232": { + "content": "<|LOC_935|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101233": { + "content": "<|LOC_936|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101234": { + "content": "<|LOC_937|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101235": { + "content": "<|LOC_938|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101236": { + "content": "<|LOC_939|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101237": { + "content": "<|LOC_940|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101238": { + "content": "<|LOC_941|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101239": { + "content": "<|LOC_942|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101240": { + "content": "<|LOC_943|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101241": { + "content": "<|LOC_944|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101242": { + "content": "<|LOC_945|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101243": { + "content": "<|LOC_946|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101244": { + "content": "<|LOC_947|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101245": { + "content": "<|LOC_948|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101246": { + "content": "<|LOC_949|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101247": { + "content": "<|LOC_950|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101248": { + "content": "<|LOC_951|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101249": { + "content": "<|LOC_952|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101250": { + "content": "<|LOC_953|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101251": { + "content": "<|LOC_954|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101252": { + "content": "<|LOC_955|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101253": { + "content": "<|LOC_956|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101254": { + "content": "<|LOC_957|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101255": { + "content": "<|LOC_958|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101256": { + "content": "<|LOC_959|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101257": { + "content": "<|LOC_960|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101258": { + "content": "<|LOC_961|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101259": { + "content": "<|LOC_962|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101260": { + "content": "<|LOC_963|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101261": { + "content": "<|LOC_964|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101262": { + "content": "<|LOC_965|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101263": { + "content": "<|LOC_966|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101264": { + "content": "<|LOC_967|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101265": { + "content": "<|LOC_968|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101266": { + "content": "<|LOC_969|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101267": { + "content": "<|LOC_970|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101268": { + "content": "<|LOC_971|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101269": { + "content": "<|LOC_972|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101270": { + "content": "<|LOC_973|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101271": { + "content": "<|LOC_974|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101272": { + "content": "<|LOC_975|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101273": { + "content": "<|LOC_976|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101274": { + "content": "<|LOC_977|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101275": { + "content": "<|LOC_978|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101276": { + "content": "<|LOC_979|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101277": { + "content": "<|LOC_980|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101278": { + "content": "<|LOC_981|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101279": { + "content": "<|LOC_982|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101280": { + "content": "<|LOC_983|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101281": { + "content": "<|LOC_984|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101282": { + "content": "<|LOC_985|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101283": { + "content": "<|LOC_986|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101284": { + "content": "<|LOC_987|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101285": { + "content": "<|LOC_988|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101286": { + "content": "<|LOC_989|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101287": { + "content": "<|LOC_990|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101288": { + "content": "<|LOC_991|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101289": { + "content": "<|LOC_992|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101290": { + "content": "<|LOC_993|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101291": { + "content": "<|LOC_994|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101292": { + "content": "<|LOC_995|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101293": { + "content": "<|LOC_996|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101294": { + "content": "<|LOC_997|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101295": { + "content": "<|LOC_998|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101296": { + "content": "<|LOC_999|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101297": { + "content": "<|LOC_1000|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101298": { + "content": "<|LOC_BEGIN|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "101299": { + "content": "<|LOC_END|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "101300": { + "content": "<|LOC_SEP|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "101301": { + "content": "<|CROP_COL_SEP|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "101302": { + "content": "<|CROP_ROW_SEP|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "101303": { + "content": "<|IMAGE_SEP|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "101304": { + "content": "<|image_pad|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "101305": { + "content": "<|IMAGE_START|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "101306": { + "content": "<|IMAGE_END|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "101307": { + "content": "<|video_pad|>", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "101308": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101309": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101310": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101311": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101312": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101313": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": false + }, + "101314": { + "content": "<|TEXT_START|>", + "lstrip": false, + "normalized": true, + "rstrip": false, + "single_word": false, + "special": false + }, + "101315": { + "content": "<|TEXT_END|>", + "lstrip": false, + "normalized": true, + "rstrip": false, + "single_word": false, + "special": false + } + }, + "additional_special_tokens": [ + "<|IMAGE_PLACEHOLDER|>", + "<|image_pad|>", + "<|IMAGE_START|>", + "<|IMAGE_END|>", + "<|video_pad|>" + ], + "auto_map": { + "AutoProcessor": "processing_paddleocr_vl.PaddleOCRVLProcessor" + }, + "bos_token": "", + "clean_up_tokenization_spaces": false, + "cls_token": "<|begin_of_sentence|>", + "eos_token": "", + "image_token": "<|IMAGE_PLACEHOLDER|>", + "extra_special_tokens": {}, + "legacy": true, + "mask_token": "", + "model_max_length": 131072, + "pad_token": "", + "processor_class": "PaddleOCRVLProcessor", + "sep_token": "<|end_of_sentence|>", + "sp_model_kwargs": {}, + "spaces_between_special_tokens": false, + "tokenizer_class": "LlamaTokenizer", + "unk_token": "", + "use_default_system_prompt": false +} \ No newline at end of file diff --git a/utils/infer_func.py b/utils/infer_func.py new file mode 100644 index 0000000000000000000000000000000000000000..4a0bd7e3593eca5bce9407f0d34c14a8697187ad --- /dev/null +++ b/utils/infer_func.py @@ -0,0 +1,409 @@ +import torch +import numpy as np +from typing import List, Tuple +from tqdm import tqdm +from axengine import InferenceSession +import os +import re +from ml_dtypes import bfloat16 + + +# Discover model files automatically from model_dir. +# We expect files like: _p128_l_together.axmodel and _post.axmodel +# we try to detect model prefix and layer files automatically +def _find_axmodel_files(base_dir: str, expected_layers: int = None, expected_prefill: int = 128): + files = os.listdir(base_dir) + # match prefix, prefill size (dynamic), and layer index + layer_pattern = re.compile(r"^(?P.*)_p(?P\d+)_l(?P\d+)_together\.axmodel$") + post_pattern = re.compile(r"^(?P.*)_post\.axmodel$") + + # collect prefix -> [(idx, fname)] + prefix_map = {} + for fname in files: + m = layer_pattern.match(fname) + if m: + prefix = m.group("prefix") + idx = int(m.group("idx")) + prefix_map.setdefault(prefix, []).append((idx, fname)) + + if not prefix_map: + # fallback to hardcoded pattern if nothing detected + prefix = "gemma3_text" + layer_files = [( + i, f"{prefix}_p{expected_prefill}_l{i}_together.axmodel" + ) for i in range(expected_layers or 0)] + else: + # choose the prefix with the most layers (most likely the correct one) + prefix = max(prefix_map.items(), key=lambda kv: len(kv[1]))[0] + # debug info + print(f"Detected prefixes: {list(prefix_map.keys())}, chosen: {prefix}, layers: {len(prefix_map[prefix])}") + layer_files = sorted(prefix_map[prefix], key=lambda it: it[0]) + + # find post process file + post_file = None + for fname in files: + m = post_pattern.match(fname) + if m and m.group("prefix") == prefix: + post_file = fname + break + if post_file is None: + candidate = os.path.join(base_dir, f"{prefix}_post.axmodel") + if os.path.exists(candidate): + post_file = f"{prefix}_post.axmodel" + else: + for fname in files: + if fname.endswith("_post.axmodel"): + post_file = fname + break + + return layer_files, post_file, prefix + +class InferManager: + def __init__(self, config, model_dir, max_seq_len=2047): + + self.config = config + self.max_seq_len = max_seq_len + + self.sub_dim = config.hidden_size // config.num_attention_heads if not config.head_dim else config.head_dim + self.kv_dim = self.sub_dim * config.num_key_value_heads + + self.k_caches = [ + np.zeros((1, self.max_seq_len, self.kv_dim), dtype=bfloat16) + for _ in range(config.num_hidden_layers) + ] + self.v_caches = [ + np.zeros((1, self.max_seq_len, self.kv_dim), dtype=bfloat16) + for _ in range(config.num_hidden_layers) + ] + + layer_files, post_file, prefix = _find_axmodel_files(model_dir, config.num_hidden_layers) + + self.decoder_sessions = [] + for _, fname in tqdm(layer_files, desc="Init InferenceSession"): + session = InferenceSession(os.path.join(model_dir, fname)) + self.decoder_sessions.append(session) + + # post_file was returned by _find_axmodel_files; ensure it was found + if post_file is None: + raise FileNotFoundError("Cannot find post process .axmodel file in model_dir") + self.post_process_session = InferenceSession(os.path.join(model_dir, post_file)) + print("Model loaded successfully!") + + @staticmethod + def _top_p(probs: np.ndarray, p: float) -> np.ndarray: + sorted_indices = np.argsort(probs) + filtered = probs.copy() + cumulative = 0 + for idx in sorted_indices[::-1]: + if cumulative >= p: + filtered[idx] = 0 + cumulative += filtered[idx] + return filtered / cumulative + + @staticmethod + def _softmax(logits: np.ndarray) -> np.ndarray: + logits = logits - logits.max() + exp_logits = np.exp(logits) + return (exp_logits / np.sum(exp_logits)).astype(np.float64) + + def post_process( + self, + logits, + top_k=1, + top_p=0.9, + temperature=0.6, + repetition_penalty=1.0, + token_ids=None, + ): + logits = logits.astype(np.float32).flatten() + if repetition_penalty is not None and repetition_penalty != 1.0 and token_ids: + for t in set(token_ids): + if 0 <= t < logits.size: + if logits[t] < 0: + logits[t] *= repetition_penalty + else: + logits[t] /= repetition_penalty + + top_k = max(1, min(int(top_k), logits.size)) + temperature = max(float(temperature), 1e-6) + top_p = min(max(float(top_p), 1e-6), 1.0) + + candidate_indices = np.argpartition(logits, -top_k)[-top_k:] + candidate_logits = logits[candidate_indices] / temperature + candidate_probs = self._softmax(candidate_logits) + candidate_probs = self._top_p(candidate_probs, top_p) + candidate_probs = candidate_probs.astype(np.float64) / candidate_probs.sum() + chosen_idx = np.random.multinomial(1, candidate_probs).argmax() + next_token = candidate_indices[chosen_idx] + return next_token, candidate_indices, candidate_probs + + def gen_slice_indices(self, token_len, prefill=128, expand=128): + remaining = max(0, token_len - prefill) + extra_blocks = (remaining + expand - 1) // expand + return list(range(extra_blocks + 1)) + + def prefill( + self, + tokenizer, + token_ids, + embed_data, + slice_len=128, + top_k=1, + top_p=0.9, + temperature=0.6, + repetition_penalty=1.0, + ): + """ + Prefill step for chunked inference. + """ + seq_len = len(token_ids) + slice_indices = [i for i in range(seq_len // slice_len + 1)] + print(f"slice_indices: {slice_indices}") + # total_prefill_len = ( + # slice_len * slice_indices[-1] + # if slice_indices[-1] != 0 + # else slice_len + # ) + total_prefill_len = slice_len * (slice_indices[-1] + 1) + # slice_indices = self.gen_slice_indices(seq_len) + + if total_prefill_len > 0: + for slice_idx in slice_indices: + base_indices = np.arange( + slice_idx * slice_len, + (slice_idx + 1) * slice_len, + dtype=np.uint32 + ) + indices = np.tile(base_indices, (3, 1)) + + mask = ( + np.zeros((1, slice_len, slice_len * (slice_idx + 1))) + - 65536 + ) + data = np.zeros((1, slice_len, self.config.hidden_size)).astype(bfloat16) + for i, t in enumerate( + range( + slice_idx * slice_len, + (slice_idx + 1) * slice_len, + ) + ): + if t < len(token_ids): + mask[:, i, : slice_idx * slice_len + i + 1] = 0 + data[:, i : i + 1, :] = ( + embed_data[t] + .reshape((1, 1, self.config.hidden_size)) + .astype(bfloat16) + ) + + remain_len = ( + seq_len - slice_idx * slice_len + if slice_idx == slice_indices[-1] + else slice_len + ) + mask = mask.astype(bfloat16) + for layer_idx in range(self.config.num_hidden_layers): + input_feed = { + "K_cache": ( + self.k_caches[layer_idx][:, 0 : slice_len * slice_idx, :] + if slice_idx + else np.zeros((1, 1, self.config.hidden_size), dtype=bfloat16) + ), + "V_cache": ( + self.v_caches[layer_idx][:, 0 : slice_len * slice_idx, :] + if slice_idx + else np.zeros((1, 1, self.config.hidden_size), dtype=bfloat16) + ), + "indices": indices, + "input": data, + "mask": mask, + } + + outputs = self.decoder_sessions[layer_idx].run(None, input_feed, shape_group=slice_idx + 1) + self.k_caches[layer_idx][ + :, + slice_idx * slice_len : slice_idx * slice_len + remain_len, + :, + ] = outputs[0][:, :remain_len, :] + self.v_caches[layer_idx][ + :, + slice_idx * slice_len : slice_idx * slice_len + remain_len, + :, + ] = outputs[1][:, :remain_len, :] + data = outputs[2] + + print("Slice prefill done:", slice_idx) + + # return data[:, :remain_len, :] + post_out = self.post_process_session.run( + None, + { + "input": data[ + :, seq_len - (len(slice_indices) - 1) * slice_len - 1, None, : + ] + } + )[0] + next_token, possible_tokens, possible_probs = self.post_process( + post_out, + top_k=top_k, + top_p=top_p, + temperature=temperature, + repetition_penalty=repetition_penalty, + token_ids=token_ids, + ) + possible_decoded = [tokenizer.decode([t]) for t in possible_tokens] + possible_probs_str = [str((t, p)) for t, p in zip(possible_decoded, possible_probs)] + token_ids.append(next_token) + return token_ids + + def decode( + self, + tokenizer, + token_ids, + embed_matrix, + prefill_len=128, + slice_len=128, + eos_token_id=None, # 某些模型有多个 eos_token_id + stream=True, + top_k=1, + top_p=0.9, + temperature=0.6, + repetition_penalty=1.0, + max_new_tokens=None, + stream_callback=None, + ): + """Autoregressive decode; optionally stream tokens or collect silently.""" + + decoded_text = tokenizer.decode(token_ids[-1], skip_special_tokens=True) + if stream: + print("answer >>", decoded_text, end='', flush=True) + if stream_callback is not None: + stream_callback(decoded_text) + + mask = np.zeros((1, 1, self.max_seq_len + 1), dtype=np.float32).astype(bfloat16) + mask[:, :, :self.max_seq_len] -= 65536 + seq_len = len(token_ids) - 1 + if prefill_len > 0: + mask[:, :, :seq_len] = 0 + + max_new_tokens = self.max_seq_len if max_new_tokens is None else int(max_new_tokens) + generated = 0 + + for step_idx in range(self.max_seq_len): + if prefill_len > 0 and step_idx < seq_len: + continue + cur_token = token_ids[step_idx] + indices = np.array([step_idx], np.uint32).reshape((1, 1)) + data = embed_matrix[cur_token, :].reshape((1, 1, self.config.hidden_size)).astype(bfloat16) + for layer_idx in range(self.config.num_hidden_layers): + input_feed = { + "K_cache": self.k_caches[layer_idx], + "V_cache": self.v_caches[layer_idx], + "indices": indices, + "input": data, + "mask": mask, + } + outputs = self.decoder_sessions[layer_idx].run(None, input_feed, shape_group=0) + self.k_caches[layer_idx][:, step_idx, :] = outputs[0][:, :, :] + self.v_caches[layer_idx][:, step_idx, :] = outputs[1][:, :, :] + data = outputs[2] + mask[..., step_idx] = 0 + if step_idx < seq_len - 1: + continue + else: + post_out = self.post_process_session.run(None, {"input": data})[0] + next_token, possible_tokens, possible_probs = self.post_process( + post_out, + top_k=top_k, + top_p=top_p, + temperature=temperature, + repetition_penalty=repetition_penalty, + token_ids=token_ids, + ) + if eos_token_id is not None and next_token in eos_token_id: + break + elif next_token == tokenizer.eos_token_id: + break + token_ids.append(next_token) + generated += 1 + if generated >= max_new_tokens: + break + + decoded_piece = tokenizer.decode(next_token, skip_special_tokens=True) + decoded_text += decoded_piece + if stream: + print(decoded_piece, end='', flush=True) + if stream_callback is not None: + stream_callback(decoded_text) + + return decoded_text + + def decode_stream( + self, + tokenizer, + token_ids, + embed_matrix, + prefill_len=128, + slice_len=128, + eos_token_id=None, # 某些模型有多个 eos_token_id + top_k=1, + top_p=0.9, + temperature=0.6, + repetition_penalty=1.0, + max_new_tokens=None, + ): + decoded_text = tokenizer.decode(token_ids[-1], skip_special_tokens=True) + yield decoded_text + + mask = np.zeros((1, 1, self.max_seq_len + 1), dtype=np.float32).astype(bfloat16) + mask[:, :, :self.max_seq_len] -= 65536 + seq_len = len(token_ids) - 1 + if prefill_len > 0: + mask[:, :, :seq_len] = 0 + + max_new_tokens = self.max_seq_len if max_new_tokens is None else int(max_new_tokens) + generated = 0 + + for step_idx in range(self.max_seq_len): + if prefill_len > 0 and step_idx < seq_len: + continue + cur_token = token_ids[step_idx] + indices = np.array([step_idx], np.uint32).reshape((1, 1)) + data = embed_matrix[cur_token, :].reshape((1, 1, self.config.hidden_size)).astype(bfloat16) + for layer_idx in range(self.config.num_hidden_layers): + input_feed = { + "K_cache": self.k_caches[layer_idx], + "V_cache": self.v_caches[layer_idx], + "indices": indices, + "input": data, + "mask": mask, + } + outputs = self.decoder_sessions[layer_idx].run(None, input_feed, shape_group=0) + self.k_caches[layer_idx][:, step_idx, :] = outputs[0][:, :, :] + self.v_caches[layer_idx][:, step_idx, :] = outputs[1][:, :, :] + data = outputs[2] + mask[..., step_idx] = 0 + if step_idx < seq_len - 1: + continue + else: + post_out = self.post_process_session.run(None, {"input": data})[0] + next_token, possible_tokens, possible_probs = self.post_process( + post_out, + top_k=top_k, + top_p=top_p, + temperature=temperature, + repetition_penalty=repetition_penalty, + token_ids=token_ids, + ) + if eos_token_id is not None and next_token in eos_token_id: + break + elif next_token == tokenizer.eos_token_id: + break + token_ids.append(next_token) + generated += 1 + if generated >= max_new_tokens: + break + + decoded_piece = tokenizer.decode(next_token, skip_special_tokens=True) + decoded_text += decoded_piece + yield decoded_text + diff --git a/utils/vision_output.py b/utils/vision_output.py new file mode 100644 index 0000000000000000000000000000000000000000..f9be464b8f2bde65576ca4507b26603a4a832f94 --- /dev/null +++ b/utils/vision_output.py @@ -0,0 +1,63 @@ +from typing import List, Optional, Sequence, Tuple + +import numpy as np + + +def seq_len_from_output(output: np.ndarray) -> Optional[int]: + if output.ndim < 2: + return None + if output.ndim == 2: + return int(output.shape[0]) + return int(output.shape[-2]) + + +def normalize_vit_output( + output: np.ndarray, + target_hidden_size: int, + expected_tokens: Optional[int] = None, +) -> np.ndarray: + normalized = output + if expected_tokens is not None: + if normalized.ndim == 3 and normalized.shape[1] == target_hidden_size and normalized.shape[2] == expected_tokens: + normalized = np.transpose(normalized, (0, 2, 1)) + elif normalized.ndim == 2 and normalized.shape[0] == target_hidden_size and normalized.shape[1] == expected_tokens: + normalized = np.transpose(normalized, (1, 0)) + return normalized + + +def describe_output_shapes(outputs: Sequence[np.ndarray]) -> List[Tuple[int, ...]]: + return [tuple(int(v) for v in output.shape) for output in outputs] + + +def select_vit_output( + outputs: Sequence[np.ndarray], + target_hidden_size: int, + expected_tokens: Optional[int] = None, +) -> np.ndarray: + normalized_outputs = [ + normalize_vit_output(output, target_hidden_size, expected_tokens=expected_tokens) for output in outputs + ] + + image_embeds = None + if expected_tokens is not None: + for output in normalized_outputs: + if output.ndim >= 2 and seq_len_from_output(output) == expected_tokens and output.shape[-1] == target_hidden_size: + image_embeds = output + break + if image_embeds is None: + for output in normalized_outputs: + if output.ndim >= 2 and seq_len_from_output(output) == expected_tokens: + image_embeds = output + break + + if image_embeds is None: + for output in normalized_outputs: + if output.ndim >= 2 and output.shape[-1] == target_hidden_size: + image_embeds = output + break + + if image_embeds is None: + image_embeds = normalized_outputs[0] + if image_embeds.ndim == 2: + image_embeds = image_embeds[None, ...] + return image_embeds diff --git a/vit_models/paddle_ocr_vl_vit_model_1x2268x3x14x14.onnx b/vit_models/paddle_ocr_vl_vit_model_1x2268x3x14x14.onnx new file mode 100644 index 0000000000000000000000000000000000000000..75765f59949988eb6e9916d8e50cf82732a87e25 --- /dev/null +++ b/vit_models/paddle_ocr_vl_vit_model_1x2268x3x14x14.onnx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e9bfc558f0651ce36eebdf25ad395ae598e132145c235cdbd4a69930518ae363 +size 1764775038