GTO83
/

GTO83 HYPERUU commited on
Commit
85666c7
·
0 Parent(s):

Duplicate from baidu/Unlimited-OCR

Browse files

Co-authored-by: Youyang Yin <HYPERUU@users.noreply.huggingface.co>

.gitattributes ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
2
+ *.mov filter=lfs diff=lfs merge=lfs -text
3
+ *.mp4 filter=lfs diff=lfs merge=lfs -text
4
+ *.whl filter=lfs diff=lfs merge=lfs -text
5
+ *.png filter=lfs diff=lfs merge=lfs -text
6
+ *.gif filter=lfs diff=lfs merge=lfs -text
7
+ *.pdf filter=lfs diff=lfs merge=lfs -text
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Baidu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
README.md ADDED
@@ -0,0 +1,335 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ pipeline_tag: image-text-to-text
3
+ language:
4
+ - multilingual
5
+ tags:
6
+ - baidu
7
+ - vision-language
8
+ - ocr
9
+ - custom_code
10
+ license: mit
11
+ library_name: transformers
12
+ ---
13
+ <p align="center">
14
+ <img src="assets/baidu.png" width="55%" alt="Baidu Inc." />
15
+ </p>
16
+
17
+ <hr>
18
+
19
+ <h1 align="center">Unlimited OCR Works</h1>
20
+
21
+ <div align="center">
22
+
23
+ <a href="https://trendshift.io/repositories/62053?utm_source=trendshift-badge&amp;utm_medium=badge&amp;utm_campaign=badge-trendshift-62053" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/trendshift/repositories/62053/daily" alt="baidu%2FUnlimited-OCR | Trendshift" width="250" height="55"/></a>
24
+
25
+ <a href="https://github.com/baidu/Unlimited-OCR">
26
+ <img alt="GitHub" src="https://img.shields.io/badge/GitHub-Code-181717?logo=github&logoColor=white" />
27
+ </a>
28
+ <a href="https://huggingface.co/baidu/Unlimited-OCR">
29
+ <img alt="Hugging Face" src="https://img.shields.io/badge/%F0%9F%A4%97%20Hugging%20Face-Model-ffc107?color=ffc107&logoColor=white" />
30
+ </a>
31
+ </div>
32
+
33
+ <div align="center">
34
+ <a href="https://arxiv.org/abs/2606.23050">
35
+ <img alt="arXiv" src="https://img.shields.io/badge/arXiv-Unlimited OCR Works-b31b1b?logo=arxiv&logoColor=white" />
36
+ </a>
37
+ <a href="https://x.com/Baidu_Inc" target="_blank">
38
+ <img alt="Twitter Follow" src="https://img.shields.io/badge/Twitter-Baidu Inc.-white?logo=x&logoColor=white" />
39
+ </a>
40
+ </div>
41
+
42
+ <h3 align="center">Welcome the Era of One-shot Long-horizon Parsing.</h3>
43
+
44
+ <p align="center">
45
+ <img src="assets/Unlimited-OCR.png" width="1000" alt="Unlimited OCR overview" />
46
+ </p>
47
+
48
+
49
+ ## Release
50
+ - [2026/07/21] 🤝 Thanks to the [ms-swift community](https://github.com/modelscope/ms-swift) for their support, our model now supports training with [ms-swift](https://github.com/modelscope/ms-swift).
51
+ - [2026/07/03] 🤝 Thanks to the Baidu Cloud team for their support. Our model is now available on [Baidu Cloud](https://cloud.baidu.com/doc/OCR/s/fmr1p39gb).
52
+ - [2026/06/28] 🤝 Thanks to the [vLLM community](https://github.com/vllm-project/vllm) and [Tianyu Guo](https://github.com/gty111) for their support, our model now supports vLLM inference.
53
+ - [2026/06/24] 🤝 Thanks to [AK](https://x.com/_akhaliq) for creating a demo for us. It is now available at [Hugging Face Spaces](https://huggingface.co/spaces/baidu/Unlimited-OCR).
54
+ - [2026/06/23] 📄 Our paper is now available on [arXiv](https://arxiv.org/abs/2606.23050).
55
+ - [2026/06/23] 🤝 Thanks to the [ModelScope community](https://github.com/modelscope) for their support. Our model is now available at [ModelScope](https://modelscope.cn/models/PaddlePaddle/Unlimited-OCR).
56
+ - [2026/06/22] 🚀 We present [Unlimited-OCR](https://github.com/baidu/Unlimited-OCR), aiming to push [Deepseek-OCR](https://github.com/deepseek-ai/DeepSeek-OCR) one step further.
57
+
58
+ ## Inference
59
+
60
+ ### Transformers
61
+ Inference using Huggingface transformers on NVIDIA GPUs. Requirements tested on python 3.12.3 + CUDA12.9:
62
+
63
+ ```
64
+ torch==2.10.0
65
+ torchvision==0.25.0
66
+ transformers==4.57.1
67
+ Pillow==12.1.1
68
+ matplotlib==3.10.8
69
+ einops==0.8.2
70
+ addict==2.4.0
71
+ easydict==1.13
72
+ pymupdf==1.27.2.2
73
+ psutil==7.2.2
74
+ ```
75
+
76
+ ```python
77
+ import os
78
+ import torch
79
+ from transformers import AutoModel, AutoTokenizer
80
+
81
+ model_name = 'baidu/Unlimited-OCR'
82
+
83
+ tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
84
+ model = AutoModel.from_pretrained(
85
+ model_name,
86
+ trust_remote_code=True,
87
+ use_safetensors=True,
88
+ torch_dtype=torch.bfloat16,
89
+ )
90
+ model = model.eval().cuda()
91
+
92
+ # ── Single image supports two configs: gundam or base ──
93
+ # gundam: base_size=1024, image_size=640, crop_mode=True
94
+ # base: base_size=1024, image_size=1024, crop_mode=False
95
+ model.infer(
96
+ tokenizer,
97
+ prompt='<image>document parsing.',
98
+ image_file='your_image.jpg',
99
+ output_path='your/output/dir',
100
+ base_size=1024, image_size=640, crop_mode=True,
101
+ max_length=32768,
102
+ no_repeat_ngram_size=35, ngram_window=128,
103
+ save_results=True,
104
+ )
105
+
106
+ # ── Multi page / PDF only uses base (image_size=1024) ──
107
+ model.infer_multi(
108
+ tokenizer,
109
+ prompt='<image>Multi page parsing.',
110
+ image_files=['page1.png', 'page2.png', 'page3.png'],
111
+ output_path='your/output/dir',
112
+ image_size=1024,
113
+ max_length=32768,
114
+ no_repeat_ngram_size=35, ngram_window=1024,
115
+ save_results=True,
116
+ )
117
+
118
+ # ── PDF (convert pages to images, then multi-page parsing) ──
119
+ import tempfile, fitz # PyMuPDF
120
+
121
+ def pdf_to_images(pdf_path, dpi=300):
122
+ doc = fitz.open(pdf_path)
123
+ tmp_dir = tempfile.mkdtemp(prefix='pdf_ocr_')
124
+ mat = fitz.Matrix(dpi / 72, dpi / 72)
125
+ paths = []
126
+ for i, page in enumerate(doc):
127
+ out = os.path.join(tmp_dir, f'page_{i+1:04d}.png')
128
+ page.get_pixmap(matrix=mat).save(out)
129
+ paths.append(out)
130
+ doc.close()
131
+ return paths
132
+
133
+ model.infer_multi(
134
+ tokenizer,
135
+ prompt='<image>Multi page parsing.',
136
+ image_files=pdf_to_images('your_doc.pdf', dpi=300),
137
+ output_path='your/output/dir',
138
+ image_size=1024,
139
+ max_length=32768,
140
+ no_repeat_ngram_size=35, ngram_window=1024,
141
+ save_results=True,
142
+ )
143
+ ```
144
+
145
+ ### vLLM
146
+
147
+ Please refer to the official vLLM recipe for deployment details:
148
+
149
+ **Recipe:** [https://recipes.vllm.ai/baidu/Unlimited-OCR](https://recipes.vllm.ai/baidu/Unlimited-OCR)
150
+
151
+ ##### Docker Images
152
+ Use the following Docker images depending on your GPU platform:
153
+
154
+ **Default (CUDA 13.0):**
155
+ ```bash
156
+ docker pull vllm/vllm-openai:unlimited-ocr
157
+ ```
158
+ **For Hopper GPUs (CUDA 12.9)**
159
+ ```bash
160
+ docker pull vllm/vllm-openai:unlimited-ocr-cu129
161
+ ```
162
+
163
+ ### SGLang
164
+
165
+ Set up the environment (uv-managed virtualenv). Install the local SGLang wheel first,
166
+ then pin `kernels==0.9.0` and install PyMuPDF for PDF-to-image conversion:
167
+ ```shell
168
+ uv venv --python 3.12
169
+ source .venv/bin/activate
170
+
171
+ uv pip install wheel/sglang-0.0.0.dev11416+g92e8bb79e-py3-none-any.whl
172
+ uv pip install kernels==0.11.7
173
+ uv pip install pymupdf==1.27.2.2
174
+ ```
175
+
176
+ Start the SGLang server:
177
+ ```shell
178
+ python -m sglang.launch_server \
179
+ --model baidu/Unlimited-OCR \
180
+ --served-model-name Unlimited-OCR \
181
+ --attention-backend fa3 \
182
+ --page-size 1 \
183
+ --mem-fraction-static 0.8 \
184
+ --context-length 32768 \
185
+ --enable-custom-logit-processor \
186
+ --disable-overlap-schedule \
187
+ --skip-server-warmup \
188
+ --host 0.0.0.0 \
189
+ --port 10000
190
+ ```
191
+
192
+ Send streaming requests to the OpenAI-compatible API:
193
+ ```python
194
+ import base64
195
+ import json
196
+ import os
197
+ import tempfile
198
+
199
+ import fitz
200
+ import requests
201
+ from sglang.srt.sampling.custom_logit_processor import DeepseekOCRNoRepeatNGramLogitProcessor
202
+
203
+ server_url = "http://127.0.0.1:10000"
204
+
205
+ session = requests.Session()
206
+ session.trust_env = False
207
+
208
+
209
+ def pdf_to_images(pdf_path, dpi=300):
210
+ doc = fitz.open(pdf_path)
211
+ tmp_dir = tempfile.mkdtemp(prefix="pdf_ocr_")
212
+ mat = fitz.Matrix(dpi / 72, dpi / 72)
213
+ image_paths = []
214
+ for i, page in enumerate(doc):
215
+ image_path = os.path.join(tmp_dir, f"page_{i + 1:04d}.png")
216
+ page.get_pixmap(matrix=mat).save(image_path)
217
+ image_paths.append(image_path)
218
+ doc.close()
219
+ return image_paths
220
+
221
+
222
+ def encode_image(image_path):
223
+ ext = os.path.splitext(image_path)[1].lower()
224
+ mime = "image/jpeg" if ext in (".jpg", ".jpeg") else f"image/{ext.lstrip('.')}"
225
+ with open(image_path, "rb") as f:
226
+ data = base64.b64encode(f.read()).decode("utf-8")
227
+ return {"type": "image_url", "image_url": {"url": f"data:{mime};base64,{data}"}}
228
+
229
+
230
+ def build_content(prompt, image_paths):
231
+ return [{"type": "text", "text": prompt}] + [encode_image(path) for path in image_paths]
232
+
233
+
234
+ def generate(prompt, image_paths, image_mode, ngram_window):
235
+ payload = {
236
+ "model": "Unlimited-OCR",
237
+ "messages": [{"role": "user", "content": build_content(prompt, image_paths)}],
238
+ "temperature": 0,
239
+ "skip_special_tokens": False,
240
+ "images_config": {"image_mode": image_mode},
241
+ "custom_logit_processor": DeepseekOCRNoRepeatNGramLogitProcessor.to_str(),
242
+ "custom_params": {
243
+ "ngram_size": 35,
244
+ "window_size": ngram_window,
245
+ },
246
+ "stream": True,
247
+ }
248
+ response = session.post(
249
+ f"{server_url}/v1/chat/completions",
250
+ headers={"Content-Type": "application/json"},
251
+ data=json.dumps(payload),
252
+ timeout=1200,
253
+ stream=True,
254
+ )
255
+ response.raise_for_status()
256
+
257
+ chunks = []
258
+ for line in response.iter_lines(chunk_size=1, decode_unicode=True):
259
+ if not line or not line.startswith("data: "):
260
+ continue
261
+ data = line[len("data: "):]
262
+ if data == "[DONE]":
263
+ break
264
+ event = json.loads(data)
265
+ delta = event["choices"][0].get("delta", {}).get("content", "")
266
+ if delta:
267
+ print(delta, end="", flush=True)
268
+ chunks.append(delta)
269
+ print()
270
+ return "".join(chunks)
271
+
272
+
273
+ # Single image supports two configs: gundam or base. Example below uses gundam.
274
+ generate("document parsing.", ["your_image.jpg"], image_mode="gundam", ngram_window=128)
275
+
276
+ # Multi image (base only)
277
+ generate("Multi page parsing.", ["page1.png", "page2.png"], image_mode="base", ngram_window=1024)
278
+
279
+ # PDF (base only)
280
+ generate("Multi page parsing.", pdf_to_images("your_doc.pdf", dpi=300), image_mode="base", ngram_window=1024)
281
+ ```
282
+
283
+ For OmniDocBench evaluation, you need to perform the following post-processing.
284
+ ```python
285
+ DET_RE = re.compile(r'<\|det\|>([^<\s]+)(?:\s*\[[^\]]*\])?\s*<\|/det\|>(.*)', re.DOTALL)
286
+
287
+ def remove_det(raw: str) -> str:
288
+ """
289
+ Strip <|det|>type [bbox]<|/det|> markers, group lines belonging to the
290
+ same block with \\n, and separate different blocks with \\n\\n.
291
+ """
292
+ blocks = []
293
+ cur = None
294
+ for line in raw.splitlines():
295
+ line = line.rstrip()
296
+ if not line:
297
+ continue
298
+ m = DET_RE.match(line)
299
+ if m:
300
+ category, content = m.group(1).strip(), m.group(2).strip()
301
+ if category == 'image':
302
+ continue
303
+ if cur is not None:
304
+ blocks.append(cur)
305
+ cur = [content] if content else []
306
+ continue
307
+ if cur is None:
308
+ cur = []
309
+ cur.append(line)
310
+ if cur is not None:
311
+ blocks.append(cur)
312
+ text = '\n\n'.join('\n'.join(b) for b in blocks).strip()
313
+ return text
314
+ ```
315
+
316
+
317
+ ## Visualization
318
+
319
+ <img src="assets/long-horizon-ocr.gif" width="100%" alt="Long-horizon OCR demo" />
320
+
321
+ ## Acknowledgement
322
+
323
+ We would like to thank [Deepseek-OCR](https://github.com/deepseek-ai/DeepSeek-OCR), [Deepseek-OCR-2](https://github.com/deepseek-ai/DeepSeek-OCR-2), [PaddleOCR](https://github.com/PaddlePaddle/PaddleOCR) for their valuable models and ideas.
324
+
325
+ ## Citation
326
+ ```bibtex
327
+ @misc{yin2026unlimitedocrworks,
328
+ title={Unlimited OCR Works},
329
+ author={Youyang Yin and Huanhuan Liu and YY and Qunyi Xie and Chaorun Liu and Shiqi Yang and Shaohua Wang and Zhanlong Liu and Hao Zou and Jinyue Chen and Shu Wei and Jingjing Wu and Mingxin Huang and Zhen Wu and Guibin Wang and Tengyu Du and Lei Jia},
330
+ year={2026},
331
+ eprint={2606.23050},
332
+ archivePrefix={arXiv},
333
+ primaryClass={cs.CV},
334
+ url={https://arxiv.org/abs/2606.23050},
335
+ }
Unlimited-OCR.pdf ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d4cc0b2e98f53d9165e63af925519cccbf80ecc6f047973e3f9b2bdd84474a8b
3
+ size 460324
assets/Unlimited-OCR.png ADDED

Git LFS Details

  • SHA256: 77063289aecfedea40d90c94dac3bc5d57f42f65d2a988183bb665a69e26ce95
  • Pointer size: 131 Bytes
  • Size of remote file: 106 kB
assets/baidu.png ADDED
assets/long-horizon-ocr.gif ADDED

Git LFS Details

  • SHA256: d4ba8964d33ffa3a3584d4a1259625ab659c02190e9655ddd51793d28307d962
  • Pointer size: 133 Bytes
  • Size of remote file: 82.2 MB
config.json ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_name_or_path": "Unlimited-OCR",
3
+ "candidate_resolutions": [
4
+ [
5
+ 1024,
6
+ 1024
7
+ ]
8
+ ],
9
+ "global_view_pos": "head",
10
+ "architectures": [
11
+ "UnlimitedOCRForCausalLM"
12
+ ],
13
+ "auto_map": {
14
+ "AutoConfig": "modeling_unlimitedocr.UnlimitedOCRConfig",
15
+ "AutoModel": "modeling_unlimitedocr.UnlimitedOCRForCausalLM"
16
+ },
17
+ "language_config": {
18
+ "architectures": [
19
+ "DeepseekOCRForCausalLM"
20
+ ],
21
+ "auto_map": {
22
+ "AutoConfig": "configuration_deepseekv2.DeepseekV2Config",
23
+ "AutoModel": "modeling_deepseek.DeepseekV2Model",
24
+ "AutoModelForCausalLM": "modeling_deepseek.DeepseekV2ForCausalLM"
25
+ },
26
+ "bos_token_id": 0,
27
+ "eos_token_id": 1,
28
+ "first_k_dense_replace": 1,
29
+ "hidden_size": 1280,
30
+ "intermediate_size": 6848,
31
+ "kv_lora_rank": null,
32
+ "lm_head": true,
33
+ "max_position_embeddings": 32768,
34
+ "moe_intermediate_size": 896,
35
+ "n_group": 1,
36
+ "n_routed_experts": 64,
37
+ "n_shared_experts": 2,
38
+ "num_attention_heads": 10,
39
+ "num_experts_per_tok": 6,
40
+ "num_hidden_layers": 12,
41
+ "num_key_value_heads": 10,
42
+ "q_lora_rank": null,
43
+ "qk_nope_head_dim": 0,
44
+ "qk_rope_head_dim": 0,
45
+ "rm_head": false,
46
+ "topk_group": 1,
47
+ "topk_method": "greedy",
48
+ "torch_dtype": "bfloat16",
49
+ "use_mla": false,
50
+ "v_head_dim": 128,
51
+ "vocab_size": 129280,
52
+ "sliding_window_size": 128
53
+ },
54
+ "model_type": "unlimited-ocr",
55
+ "projector_config": {
56
+ "input_dim": 2048,
57
+ "model_type": "mlp_projector",
58
+ "n_embed": 1280,
59
+ "projector_type": "linear"
60
+ },
61
+ "tile_tag": "2D",
62
+ "torch_dtype": "bfloat16",
63
+ "transformers_version": "4.46.3",
64
+ "vision_config": {
65
+ "image_size": 1024,
66
+ "mlp_ratio": 3.7362,
67
+ "model_name": "deeplip_b_l",
68
+ "model_type": "vision",
69
+ "width": {
70
+ "clip-l-14-224": {
71
+ "heads": 16,
72
+ "image_size": 224,
73
+ "layers": 24,
74
+ "patch_size": 14,
75
+ "width": 1024
76
+ },
77
+ "sam_vit_b": {
78
+ "downsample_channels": [
79
+ 512,
80
+ 1024
81
+ ],
82
+ "global_attn_indexes": [
83
+ 2,
84
+ 5,
85
+ 8,
86
+ 11
87
+ ],
88
+ "heads": 12,
89
+ "layers": 12,
90
+ "width": 768
91
+ }
92
+ }
93
+ },
94
+ "bos_token_id": 0,
95
+ "eos_token_id": 1,
96
+ "first_k_dense_replace": 1,
97
+ "hidden_size": 1280,
98
+ "intermediate_size": 6848,
99
+ "kv_lora_rank": null,
100
+ "lm_head": true,
101
+ "max_position_embeddings": 32768,
102
+ "moe_intermediate_size": 896,
103
+ "n_group": 1,
104
+ "n_routed_experts": 64,
105
+ "n_shared_experts": 2,
106
+ "num_attention_heads": 10,
107
+ "num_experts_per_tok": 6,
108
+ "num_hidden_layers": 12,
109
+ "num_key_value_heads": 10,
110
+ "q_lora_rank": null,
111
+ "qk_nope_head_dim": 0,
112
+ "qk_rope_head_dim": 0,
113
+ "rm_head": false,
114
+ "topk_group": 1,
115
+ "topk_method": "greedy",
116
+ "use_mla": false,
117
+ "v_head_dim": 128,
118
+ "vocab_size": 129280,
119
+ "sliding_window_size": 128,
120
+ "sliding_window": 128
121
+ }
configuration_deepseek_v2.py ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers.configuration_utils import PretrainedConfig
2
+ from transformers.utils import logging
3
+
4
+ logger = logging.get_logger(__name__)
5
+
6
+ DEEPSEEK_PRETRAINED_CONFIG_ARCHIVE_MAP = {}
7
+ class DeepseekV2Config(PretrainedConfig):
8
+ r"""
9
+ This is the configuration class to store the configuration of a [`DeepseekV2Model`]. It is used to instantiate an DeepSeek
10
+ model according to the specified arguments, defining the model architecture. Instantiating a configuration with the
11
+ defaults will yield a similar configuration to that of the DeepSeek-V2 with multi-latent attention.
12
+
13
+ Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the
14
+ documentation from [`PretrainedConfig`] for more information.
15
+
16
+
17
+ Args:
18
+ vocab_size (`int`, *optional*, defaults to 102400):
19
+ Vocabulary size of the Deep model. Defines the number of different tokens that can be represented by the
20
+ `inputs_ids` passed when calling [`DeepseekV2Model`]
21
+ hidden_size (`int`, *optional*, defaults to 4096):
22
+ Dimension of the hidden representations.
23
+ intermediate_size (`int`, *optional*, defaults to 11008):
24
+ Dimension of the MLP representations.
25
+ moe_intermediate_size (`int`, *optional*, defaults to 1407):
26
+ Dimension of the MoE representations.
27
+ num_hidden_layers (`int`, *optional*, defaults to 32):
28
+ Number of hidden layers in the Transformer decoder.
29
+ num_attention_heads (`int`, *optional*, defaults to 32):
30
+ Number of attention heads for each attention layer in the Transformer decoder.
31
+ n_shared_experts (`int`, *optional*, defaults to None):
32
+ Number of shared experts, None means dense model.
33
+ n_routed_experts (`int`, *optional*, defaults to None):
34
+ Number of routed experts, None means dense model.
35
+ routed_scaling_factor (`float`, *optional*, defaults to 1.0):
36
+ Scaling factor or routed experts.
37
+ topk_method (`str`, *optional*, defaults to `gready`):
38
+ Topk method used in routed gate.
39
+ n_group (`int`, *optional*, defaults to None):
40
+ Number of groups for routed experts.
41
+ topk_group (`int`, *optional*, defaults to None):
42
+ Number of selected groups for each token(for each token, ensuring the selected experts is only within `topk_group` groups).
43
+ num_experts_per_tok (`int`, *optional*, defaults to None):
44
+ Number of selected experts, None means dense model.
45
+ moe_layer_freq (`int`, *optional*, defaults to 1):
46
+ The frequency of the MoE layer: one expert layer for every `moe_layer_freq - 1` dense layers.
47
+ first_k_dense_replace (`int`, *optional*, defaults to 0):
48
+ Number of dense layers in shallow layers(embed->dense->dense->...->dense->moe->moe...->lm_head).
49
+ \--k dense layers--/
50
+ norm_topk_prob (`bool`, *optional*, defaults to False):
51
+ Whether to normalize the weights of the routed experts.
52
+ scoring_func (`str`, *optional*, defaults to 'softmax'):
53
+ Method of computing expert weights.
54
+ aux_loss_alpha (`float`, *optional*, defaults to 0.001):
55
+ Auxiliary loss weight coefficient.
56
+ seq_aux = (`bool`, *optional*, defaults to True):
57
+ Whether to compute the auxiliary loss for each individual sample.
58
+ num_key_value_heads (`int`, *optional*):
59
+ This is the number of key_value heads that should be used to implement Grouped Query Attention. If
60
+ `num_key_value_heads=num_attention_heads`, the model will use Multi Head Attention (MHA), if
61
+ `num_key_value_heads=1 the model will use Multi Query Attention (MQA) otherwise GQA is used. When
62
+ converting a multi-head checkpoint to a GQA checkpoint, each group key and value head should be constructed
63
+ by meanpooling all the original heads within that group. For more details checkout [this
64
+ paper](https://arxiv.org/pdf/2305.13245.pdf). If it is not specified, will default to
65
+ `num_attention_heads`.
66
+ hidden_act (`str` or `function`, *optional*, defaults to `"silu"`):
67
+ The non-linear activation function (function or string) in the decoder.
68
+ max_position_embeddings (`int`, *optional*, defaults to 2048):
69
+ The maximum sequence length that this model might ever be used with.
70
+ initializer_range (`float`, *optional*, defaults to 0.02):
71
+ The standard deviation of the truncated_normal_initializer for initializing all weight matrices.
72
+ rms_norm_eps (`float`, *optional*, defaults to 1e-06):
73
+ The epsilon used by the rms normalization layers.
74
+ use_cache (`bool`, *optional*, defaults to `True`):
75
+ Whether or not the model should return the last key/values attentions (not used by all models). Only
76
+ relevant if `config.is_decoder=True`.
77
+ pad_token_id (`int`, *optional*):
78
+ Padding token id.
79
+ bos_token_id (`int`, *optional*, defaults to 1):
80
+ Beginning of stream token id.
81
+ eos_token_id (`int`, *optional*, defaults to 2):
82
+ End of stream token id.
83
+ pretraining_tp (`int`, *optional*, defaults to 1):
84
+ Experimental feature. Tensor parallelism rank used during pretraining. Please refer to [this
85
+ document](https://huggingface.co/docs/transformers/parallelism) to understand more about it. This value is
86
+ necessary to ensure exact reproducibility of the pretraining results. Please refer to [this
87
+ issue](https://github.com/pytorch/pytorch/issues/76232).
88
+ tie_word_embeddings (`bool`, *optional*, defaults to `False`):
89
+ Whether to tie weight embeddings
90
+ rope_theta (`float`, *optional*, defaults to 10000.0):
91
+ The base period of the RoPE embeddings.
92
+ rope_scaling (`Dict`, *optional*):
93
+ Dictionary containing the scaling configuration for the RoPE embeddings. Currently supports two scaling
94
+ strategies: linear and dynamic. Their scaling factor must be a float greater than 1. The expected format is
95
+ `{"type": strategy name, "factor": scaling factor}`. When using this flag, don't update
96
+ `max_position_embeddings` to the expected new maximum.
97
+ attention_bias (`bool`, defaults to `False`, *optional*, defaults to `False`):
98
+ Whether to use a bias in the query, key, value and output projection layers during self-attention.
99
+ attention_dropout (`float`, *optional*, defaults to 0.0):
100
+ The dropout ratio for the attention probabilities.
101
+ use_mla (`bool`, *optional*, defaults to `True`): Use multi-latent attention or multi-head attention. If True,
102
+ the model will use multi-latent attention, otherwise, it will use multi-head attention.
103
+
104
+ ```python
105
+ >>> from transformers import DeepseekV2Model, DeepseekV2Config
106
+
107
+ >>> # Initializing a Deepseek-V2 style configuration
108
+ >>> configuration = DeepseekV2Config()
109
+
110
+ >>> # Accessing the model configuration
111
+ >>> configuration = model.config
112
+ ```"""
113
+
114
+ model_type = "deepseek_v2"
115
+ keys_to_ignore_at_inference = ["past_key_values"]
116
+
117
+ def __init__(
118
+ self,
119
+ vocab_size=102400,
120
+ hidden_size=4096,
121
+ intermediate_size=11008,
122
+ moe_intermediate_size = 1407,
123
+ num_hidden_layers=30,
124
+ num_attention_heads=32,
125
+ num_key_value_heads=32,
126
+ n_shared_experts = None,
127
+ n_routed_experts = None,
128
+ ep_size = 1,
129
+ routed_scaling_factor = 1.0,
130
+ kv_lora_rank = 512,
131
+ q_lora_rank = 1536,
132
+ qk_rope_head_dim = 64,
133
+ v_head_dim = 128,
134
+ qk_nope_head_dim = 128,
135
+ topk_method = 'gready',
136
+ n_group = None,
137
+ topk_group = None,
138
+ num_experts_per_tok = None,
139
+ moe_layer_freq = 1,
140
+ first_k_dense_replace = 0,
141
+ norm_topk_prob = False,
142
+ scoring_func = 'softmax',
143
+ aux_loss_alpha = 0.001,
144
+ seq_aux = True,
145
+ hidden_act="silu",
146
+ max_position_embeddings=2048,
147
+ initializer_range=0.02,
148
+ rms_norm_eps=1e-6,
149
+ use_cache=True,
150
+ pad_token_id=None,
151
+ bos_token_id=100000,
152
+ eos_token_id=100001,
153
+ pretraining_tp=1,
154
+ tie_word_embeddings=False,
155
+ rope_theta=10000.0,
156
+ rope_scaling=None,
157
+ attention_bias=False,
158
+ attention_dropout=0.0,
159
+ use_mla=True,
160
+ sliding_window=None,
161
+ **kwargs,
162
+ ):
163
+ self.vocab_size = vocab_size
164
+ self.max_position_embeddings = max_position_embeddings
165
+ self.hidden_size = hidden_size
166
+ self.intermediate_size = intermediate_size
167
+ self.moe_intermediate_size = moe_intermediate_size
168
+ self.num_hidden_layers = num_hidden_layers
169
+ self.num_attention_heads = num_attention_heads
170
+ self.n_shared_experts = n_shared_experts
171
+ self.n_routed_experts = n_routed_experts
172
+ self.ep_size = ep_size
173
+ self.routed_scaling_factor = routed_scaling_factor
174
+ self.kv_lora_rank = kv_lora_rank
175
+ self.q_lora_rank = q_lora_rank
176
+ self.qk_rope_head_dim = qk_rope_head_dim
177
+ self.v_head_dim = v_head_dim
178
+ self.qk_nope_head_dim = qk_nope_head_dim
179
+ self.topk_method = topk_method
180
+ self.n_group = n_group
181
+ self.topk_group = topk_group
182
+ self.num_experts_per_tok = num_experts_per_tok
183
+ self.moe_layer_freq = moe_layer_freq
184
+ self.first_k_dense_replace = first_k_dense_replace
185
+ self.norm_topk_prob = norm_topk_prob
186
+ self.scoring_func = scoring_func
187
+ self.aux_loss_alpha = aux_loss_alpha
188
+ self.seq_aux = seq_aux
189
+ # for backward compatibility
190
+ if num_key_value_heads is None:
191
+ num_key_value_heads = num_attention_heads
192
+
193
+ self.num_key_value_heads = num_key_value_heads
194
+ self.hidden_act = hidden_act
195
+ self.initializer_range = initializer_range
196
+ self.rms_norm_eps = float(rms_norm_eps)
197
+ self.pretraining_tp = pretraining_tp
198
+ self.use_cache = use_cache
199
+ self.rope_theta = rope_theta
200
+ self.rope_scaling = rope_scaling
201
+ self.attention_bias = attention_bias
202
+ self.attention_dropout = attention_dropout
203
+ self.use_mla = use_mla
204
+ self.sliding_window = sliding_window
205
+
206
+ super().__init__(
207
+ pad_token_id=pad_token_id,
208
+ bos_token_id=bos_token_id,
209
+ eos_token_id=eos_token_id,
210
+ tie_word_embeddings=tie_word_embeddings,
211
+ **kwargs,
212
+ )
conversation.py ADDED
@@ -0,0 +1,280 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ From https://github.com/lm-sys/FastChat/blob/main/fastchat/conversation.py
3
+ """
4
+
5
+ import dataclasses
6
+ from enum import IntEnum, auto
7
+ from typing import Any, Dict, List
8
+
9
+
10
+ class SeparatorStyle(IntEnum):
11
+ """Separator styles."""
12
+
13
+ DeepSeek = auto()
14
+ DeepSeekV2 = auto()
15
+ PLAIN = auto()
16
+ ALIGNMENT = auto()
17
+
18
+
19
+ @dataclasses.dataclass
20
+ class Conversation:
21
+ """A class that manages prompt templates and keeps all conversation history."""
22
+
23
+ # The name of this template
24
+ name: str
25
+ # The template of the system prompt
26
+ system_template: str = "{system_message}"
27
+ # The system message
28
+ system_message: str = ""
29
+ # The names of two roles
30
+ roles: List[str] = (("USER", "ASSISTANT"),)
31
+ # All messages. Each item is (role, message).
32
+ messages: List[List[str]] = ()
33
+ # The number of few shot examples
34
+ offset: int = 0
35
+ # The separator style and configurations
36
+ sep_style: SeparatorStyle = SeparatorStyle.DeepSeek
37
+ sep: str = "\n"
38
+ sep2: str = None
39
+ # Stop criteria (the default one is EOS token)
40
+ stop_str: str = None
41
+ # Stops generation if meeting any token in this list
42
+ stop_token_ids: List[int] = None
43
+
44
+ def get_prompt(self) -> str:
45
+ """Get the prompt for generation."""
46
+ system_prompt = self.system_template.format(system_message=self.system_message)
47
+ if self.sep_style == SeparatorStyle.DeepSeek:
48
+ seps = [self.sep, self.sep2]
49
+ if system_prompt == "" or system_prompt is None:
50
+ ret = ""
51
+ else:
52
+ ret = system_prompt + seps[0]
53
+ for i, (role, message) in enumerate(self.messages):
54
+ if message:
55
+ ret += role + ": " + message + seps[i % 2]
56
+ else:
57
+ ret += role + ":"
58
+ return ret
59
+ elif self.sep_style == SeparatorStyle.DeepSeekV2:
60
+ seps = [self.sep, self.sep2]
61
+ if system_prompt == "" or system_prompt is None:
62
+ ret = ""
63
+ else:
64
+ ret = system_prompt + seps[0]
65
+ for i, (role, message) in enumerate(self.messages):
66
+ if message:
67
+ if role == "User":
68
+ ret += "<|sft▁begin|>\n" + message + self.sep #<|sft▁begin|>User Input<|sft▁end|>\nResponse<|end▁of▁sentence|>
69
+ else:
70
+ ret += message + self.sep2
71
+ else:
72
+ ret = ret
73
+ return ret
74
+
75
+ elif self.sep_style == SeparatorStyle.PLAIN:
76
+ seps = [self.sep, self.sep2]
77
+ ret = ""
78
+ for i, (role, message) in enumerate(self.messages):
79
+ if message:
80
+ if type(message) is tuple:
81
+ message, _, _ = message
82
+ if i % 2 == 0:
83
+ ret += message + seps[i % 2]
84
+ else:
85
+ ret += message + seps[i % 2]
86
+ else:
87
+ ret += ""
88
+ return ret
89
+ elif self.sep_style == SeparatorStyle.ALIGNMENT:
90
+ seps = [self.sep, self.sep2]
91
+ ret = ""
92
+ for i, (role, message) in enumerate(self.messages):
93
+ if message:
94
+ if type(message) is tuple:
95
+ message, _, _ = message
96
+ if i % 2 == 0:
97
+ ret += '<image>\n' + seps[i % 2]
98
+ else:
99
+ ret += message + seps[i % 2]
100
+ else:
101
+ ret += ""
102
+ return ret
103
+ else:
104
+ raise ValueError(f"Invalid style: {self.sep_style}")
105
+
106
+ def set_system_message(self, system_message: str):
107
+ """Set the system message."""
108
+ self.system_message = system_message
109
+
110
+ def append_message(self, role: str, message: str):
111
+ """Append a new message."""
112
+ self.messages.append([role, message])
113
+
114
+ def update_last_message(self, message: str):
115
+ """Update the last output.
116
+
117
+ The last message is typically set to be None when constructing the prompt,
118
+ so we need to update it in-place after getting the response from a model.
119
+ """
120
+ self.messages[-1][1] = message
121
+
122
+ def reset_message(self):
123
+ """Reset a new message."""
124
+ self.messages = []
125
+
126
+ def to_gradio_chatbot(self):
127
+ """Convert the conversation to gradio chatbot format."""
128
+ ret = []
129
+ for i, (role, msg) in enumerate(self.messages[self.offset :]):
130
+ if i % 2 == 0:
131
+ ret.append([msg, None])
132
+ else:
133
+ ret[-1][-1] = msg
134
+ return ret
135
+
136
+ def to_openai_api_messages(self):
137
+ """Convert the conversation to OpenAI chat completion format."""
138
+ system_prompt = self.system_template.format(system_message=self.system_message)
139
+ ret = [{"role": "system", "content": system_prompt}]
140
+
141
+ for i, (_, msg) in enumerate(self.messages[self.offset :]):
142
+ if i % 2 == 0:
143
+ ret.append({"role": "user", "content": msg})
144
+ else:
145
+ if msg is not None:
146
+ ret.append({"role": "assistant", "content": msg})
147
+ return ret
148
+
149
+ def copy(self):
150
+ return Conversation(
151
+ name=self.name,
152
+ system_template=self.system_template,
153
+ system_message=self.system_message,
154
+ roles=self.roles,
155
+ messages=[[x, y] for x, y in self.messages],
156
+ offset=self.offset,
157
+ sep_style=self.sep_style,
158
+ sep=self.sep,
159
+ sep2=self.sep2,
160
+ stop_str=self.stop_str,
161
+ stop_token_ids=self.stop_token_ids,
162
+ )
163
+
164
+ def dict(self):
165
+ return {
166
+ "template_name": self.name,
167
+ "system_message": self.system_message,
168
+ "roles": self.roles,
169
+ "messages": self.messages,
170
+ "offset": self.offset,
171
+ }
172
+
173
+
174
+ # A global registry for all conversation templates
175
+ conv_templates: Dict[str, Conversation] = {}
176
+
177
+
178
+ def register_conv_template(template: Conversation, override: bool = False):
179
+ """Register a new conversation template."""
180
+ if not override:
181
+ assert template.name not in conv_templates, f"{template.name} has been registered."
182
+
183
+ conv_templates[template.name] = template
184
+
185
+
186
+ def get_conv_template(name: str) -> Conversation:
187
+ """Get a conversation template."""
188
+ return conv_templates[name].copy()
189
+
190
+
191
+ register_conv_template(
192
+ Conversation(
193
+ name="deepseek",
194
+ system_template="{system_message}",
195
+ # system_message="You are a helpful assistant. Please answer truthfully and write out your "
196
+ # "thinking step by step to be sure you get the right answer.",
197
+ system_message="",
198
+ roles=("<|User|>", "<|Assistant|>"),
199
+ messages=(),
200
+ offset=0,
201
+ sep_style=SeparatorStyle.DeepSeek,
202
+ sep="\n\n",
203
+ sep2="<|end▁of▁sentence|>",
204
+ stop_token_ids=[100001],
205
+ stop_str=["User:", "<|end▁of▁sentence|>"]
206
+ )
207
+ )
208
+ register_conv_template(
209
+ Conversation(
210
+ name="deepseekv2",
211
+ system_template="{system_message}",
212
+ # system_message="You are a helpful assistant. Please answer truthfully and write out your "
213
+ # "thinking step by step to be sure you get the right answer.",
214
+ system_message="",
215
+ roles=("<|User|>", "<|Assistant|>"),
216
+ messages=(),
217
+ offset=0,
218
+ sep_style=SeparatorStyle.DeepSeek,
219
+ sep="",
220
+ sep2="<|end▁of▁sentence|>",
221
+ stop_token_ids=[100001],
222
+ stop_str=["User:", "<|end▁of▁sentence|>"]
223
+ )
224
+ )
225
+
226
+
227
+ register_conv_template(
228
+ Conversation(
229
+ name="plain",
230
+ system_template="",
231
+ system_message="",
232
+ roles=("", ""),
233
+ messages=(),
234
+ offset=0,
235
+ sep_style=SeparatorStyle.PLAIN,
236
+ sep="",
237
+ sep2="",
238
+ stop_token_ids=[100001],
239
+ stop_str=['</s>'],
240
+ )
241
+ )
242
+
243
+
244
+ register_conv_template(
245
+ Conversation(
246
+ name="alignment",
247
+ system_template="",
248
+ system_message="",
249
+ roles=("", ""),
250
+ messages=(),
251
+ offset=0,
252
+ sep_style=SeparatorStyle.ALIGNMENT,
253
+ sep="",
254
+ sep2="",
255
+ stop_token_ids=[100001],
256
+ stop_str=['</s>'],
257
+ )
258
+ )
259
+
260
+
261
+ if __name__ == "__main__":
262
+ print("deepseek template:")
263
+ conv = get_conv_template("deepseek")
264
+ conv.append_message(conv.roles[0], "Hello!")
265
+ conv.append_message(conv.roles[1], "Hi! This is Tony.")
266
+ conv.append_message(conv.roles[0], "Who are you?")
267
+ conv.append_message(conv.roles[1], "I am a helpful assistant.")
268
+ conv.append_message(conv.roles[0], "How are you?")
269
+ conv.append_message(conv.roles[1], None)
270
+ print(conv.get_prompt())
271
+
272
+ print("deepseekv2 template:")
273
+ conv = get_conv_template("deepseekv2")
274
+ conv.append_message(conv.roles[0], "Hello!")
275
+ conv.append_message(conv.roles[1], "Hi! This is Tony.")
276
+ conv.append_message(conv.roles[0], "Who are you?")
277
+ conv.append_message(conv.roles[1], "I am a helpful assistant.")
278
+ conv.append_message(conv.roles[0], "How are you?")
279
+ conv.append_message(conv.roles[1], None)
280
+ print(conv.get_prompt())
deepencoder.py ADDED
@@ -0,0 +1,1058 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch.nn as nn
2
+ import torch
3
+ import torch.nn.functional as F
4
+ import copy
5
+
6
+ from contextlib import nullcontext
7
+ import math
8
+ from typing import Optional, Tuple
9
+ # from megatron.model import LayerNorm
10
+
11
+ from einops import rearrange
12
+ from easydict import EasyDict as adict
13
+
14
+
15
+ from typing import Optional, Tuple, Type
16
+ from functools import partial
17
+
18
+
19
+
20
+ class MlpProjector(nn.Module):
21
+
22
+ def __init__(self, cfg):
23
+
24
+ super().__init__()
25
+
26
+ self.cfg = cfg
27
+
28
+ if cfg.projector_type == "identity":
29
+ modules = nn.Identity()
30
+
31
+ elif cfg.projector_type == "linear":
32
+ modules = nn.Linear(cfg.input_dim, cfg.n_embed)
33
+
34
+ elif cfg.projector_type == "mlp_gelu":
35
+ mlp_depth = cfg.get("depth", 1)
36
+ modules = [nn.Linear(cfg.input_dim, cfg.n_embed)]
37
+ for _ in range(1, mlp_depth):
38
+ modules.append(nn.GELU())
39
+ modules.append(nn.Linear(cfg.n_embed, cfg.n_embed))
40
+ modules = nn.Sequential(*modules)
41
+
42
+ elif cfg.projector_type == "normlayer_downsample_mlp_gelu":
43
+ mlp_depth = cfg.get("depth", 1)
44
+ mlp_ratio = cfg.get("mlp_ratio", 1)
45
+ modules = [
46
+ nn.LayerNorm(cfg.input_dim * cfg.downsample_ratio * cfg.downsample_ratio),
47
+ nn.Linear(cfg.input_dim * cfg.downsample_ratio * cfg.downsample_ratio, cfg.n_embed * mlp_ratio)
48
+ ]
49
+ for _ in range(1, mlp_depth - 1):
50
+ modules.append(nn.GELU())
51
+ modules.append(nn.Linear(cfg.n_embed * mlp_ratio, cfg.n_embed * mlp_ratio))
52
+ modules.append(nn.GELU())
53
+ modules.append(nn.Linear(cfg.n_embed * mlp_ratio, cfg.n_embed))
54
+ modules = nn.Sequential(*modules)
55
+
56
+ elif cfg.projector_type == "downsample_mlp_gelu":
57
+ mlp_depth = cfg.get("depth", 1)
58
+ mlp_ratio = cfg.get("mlp_ratio", 1)
59
+ modules = [nn.Linear(cfg.input_dim * cfg.downsample_ratio * cfg.downsample_ratio, cfg.n_embed * mlp_ratio)]
60
+ for _ in range(1, mlp_depth - 1):
61
+ modules.append(nn.GELU())
62
+ modules.append(nn.Linear(cfg.n_embed * mlp_ratio, cfg.n_embed * mlp_ratio))
63
+ modules.append(nn.GELU())
64
+ modules.append(nn.Linear(cfg.n_embed * mlp_ratio, cfg.n_embed))
65
+ modules = nn.Sequential(*modules)
66
+
67
+ elif cfg.projector_type == "low_high_hybrid_split_mlp_gelu":
68
+ mlp_depth = cfg.get("depth", 1)
69
+ self.high_up_proj = nn.Linear(cfg.input_dim, cfg.n_embed // 2)
70
+ self.low_up_proj = nn.Linear(cfg.input_dim, cfg.n_embed // 2)
71
+
72
+ modules = []
73
+ for _ in range(1, mlp_depth):
74
+ modules.append(nn.GELU())
75
+ modules.append(nn.Linear(cfg.n_embed, cfg.n_embed))
76
+ modules = nn.Sequential(*modules)
77
+
78
+ elif cfg.projector_type == "hybrid_split_feature_mlp_gelu":
79
+ mlp_depth = cfg.get("depth", 1)
80
+ channel_div = cfg.get("channel_div", 0.5)
81
+ self.high_up_proj = nn.Linear(cfg.input_dim[0], int(cfg.n_embed * channel_div))
82
+ self.low_up_proj = nn.Linear(cfg.input_dim[1], cfg.n_embed - int(cfg.n_embed * channel_div))
83
+
84
+ modules = []
85
+ for _ in range(1, mlp_depth):
86
+ modules.append(nn.GELU())
87
+ modules.append(nn.Linear(cfg.n_embed, cfg.n_embed))
88
+ modules = nn.Sequential(*modules)
89
+
90
+ elif cfg.projector_type == "low_high_split_mlp_gelu":
91
+ mlp_depth = cfg.get("depth", 1)
92
+ modules = []
93
+ for _ in range(1, mlp_depth):
94
+ modules.append(nn.GELU())
95
+ modules.append(nn.Linear(cfg.n_embed // 2, cfg.n_embed // 2))
96
+ modules = nn.Sequential(*modules)
97
+ self.high_layers = nn.Sequential(*modules)
98
+ self.low_layers = copy.deepcopy(modules)
99
+
100
+ else:
101
+ raise ValueError(f"Unknown projector type: {cfg.projector_type}")
102
+
103
+ if cfg.get("token_pooling", False):
104
+ self.token_pooling_layer = nn.Linear(cfg.input_dim * 4, cfg.input_dim)
105
+
106
+ if cfg.get("conv_fusion_high_low_features", False):
107
+ self.fusion_layer = nn.Linear(cfg.input_dim, cfg.input_dim)
108
+ self.layers = modules
109
+
110
+ def forward(self, x):
111
+ if self.cfg.get("token_pooling", False):
112
+ batch_size, wxh, channels = x.shape
113
+ w = h = int(wxh**0.5)
114
+ x = x.view(batch_size, w, h, channels)
115
+ x = x.permute(0, 3, 1, 2)
116
+ # import ipdb; ipdb.set_trace()
117
+ patches = x.unfold(2, 2, 2).unfold(3, 2, 2)
118
+ batch_size, channels, h_patches, w_patches, _, _ = patches.size()
119
+ # 在通道维度上拼接
120
+ patches = patches.contiguous().view(batch_size, channels, h_patches * w_patches, -1)
121
+
122
+ # 通过线性层
123
+ patches = patches.permute(0, 2, 1, 3).contiguous()
124
+ patches = patches.view(batch_size, h_patches * w_patches, channels * 4)
125
+
126
+ x = self.token_pooling_layer(patches)
127
+
128
+ if self.cfg.get("conv_fusion_high_low_features", False):
129
+ x = self.fusion_layer(x[:, 0]) + x[:, 1]
130
+
131
+ if self.cfg.projector_type == 'low_high_hybrid_split_mlp_gelu':
132
+ high_x, low_x = x[0], x[1]
133
+ high_x = self.high_up_proj(high_x)
134
+ low_x = self.low_up_proj(low_x)
135
+ x = torch.concat([high_x, low_x], dim=-1)
136
+
137
+ if self.cfg.projector_type == 'hybrid_split_feature_mlp_gelu':
138
+ high_x = x[...,:self.cfg.input_dim[0]]
139
+ low_x = x[...,self.cfg.input_dim[0]:]
140
+ high_x = self.high_up_proj(high_x)
141
+ low_x = self.low_up_proj(low_x)
142
+ x = torch.concat([high_x, low_x], dim=-1)
143
+
144
+ if self.cfg.projector_type == 'low_high_split_mlp_gelu':
145
+ high_x, low_x = x[0], x[1]
146
+ high_x = self.high_layers(high_x)
147
+ low_x = self.low_layers(low_x)
148
+ x = torch.concat([high_x, low_x], dim=-1)
149
+ return x
150
+
151
+ if self.cfg.projector_type == 'downsample_mlp_gelu' or self.cfg.projector_type == 'normlayer_downsample_mlp_gelu':
152
+ bs, hw, input_dim = x.shape
153
+ h = w = int((hw) ** 0.5)
154
+
155
+ """compute padding"""
156
+ if h % self.cfg.downsample_ratio:
157
+ pad = self.cfg.downsample_ratio - h % self.cfg.downsample_ratio
158
+ else:
159
+ pad = 0
160
+ x = x.reshape(bs, h, w, input_dim)
161
+ if pad > 0:
162
+ x = F.pad(x, (0, 0, 0, pad, 0, pad), "constant", 0)
163
+
164
+ """4 to 1 concat"""
165
+ x = x.permute(0, 3, 1, 2) # B, C, H, W
166
+ x = F.unfold(x, kernel_size=self.cfg.downsample_ratio, stride=self.cfg.downsample_ratio, padding=0) # B, C*4, HW // 4
167
+ x = x.permute(0, 2, 1)
168
+
169
+ return self.layers(x)
170
+
171
+ @staticmethod
172
+ def get_flops_per_sample(cfg):
173
+ if cfg.projector_type == "linear":
174
+ fwd = 2 * cfg.input_dim * cfg.n_embed
175
+
176
+ elif "mlp_gelu" in cfg.projector_type :
177
+ mlp_depth = cfg.get("depth", 1)
178
+ downsample_ratio = cfg.get("downsample_ratio", 1)
179
+ input_dim = sum(cfg.input_dim) if isinstance(cfg.input_dim, list) else cfg.input_dim
180
+ input_dim = input_dim * downsample_ratio * downsample_ratio
181
+ fwd = 2 * input_dim * cfg.n_embed + (mlp_depth - 1) * 2 * cfg.n_embed * cfg.n_embed
182
+ else:
183
+ fwd = 0
184
+
185
+ return fwd * 3
186
+
187
+
188
+ #===================clip============================================================
189
+
190
+ class LayerNormfp32(torch.nn.LayerNorm):
191
+ """Subclass torch's LayerNorm to handle fp16."""
192
+
193
+ def forward(self, x: torch.Tensor):
194
+ orig_type = x.dtype
195
+ ret = super().forward(x.type(torch.float32))
196
+ return ret.type(orig_type)
197
+
198
+
199
+ def get_abs_pos(abs_pos, tgt_size):
200
+ # abs_pos: L, C
201
+ # tgt_size: M
202
+ # return: M, C
203
+
204
+ # print(tgt_size)
205
+ # print(abs_pos.shape)
206
+ # exit()
207
+ dim = abs_pos.size(-1)
208
+ # print(dim)
209
+ abs_pos_new = abs_pos.squeeze(0)
210
+ cls_token, old_pos_embed = abs_pos_new[:1], abs_pos_new[1:]
211
+
212
+
213
+
214
+ src_size = int(math.sqrt(abs_pos_new.shape[0] - 1))
215
+ tgt_size = int(math.sqrt(tgt_size))
216
+ dtype = abs_pos.dtype
217
+
218
+ if src_size != tgt_size:
219
+ old_pos_embed = old_pos_embed.view(1, src_size, src_size, dim).permute(0, 3, 1,
220
+ 2).contiguous()
221
+ old_pos_embed = old_pos_embed.to(torch.float32)
222
+ new_pos_embed = F.interpolate(
223
+ old_pos_embed,
224
+ size=(tgt_size, tgt_size),
225
+ mode='bicubic',
226
+ antialias=True,
227
+ align_corners=False,
228
+ ).to(dtype)
229
+ new_pos_embed = new_pos_embed.permute(0, 2, 3, 1)
230
+ new_pos_embed = new_pos_embed.view(tgt_size * tgt_size, dim)
231
+ vision_pos_embed = torch.cat([cls_token, new_pos_embed], dim=0)
232
+ vision_pos_embed = vision_pos_embed.view(1, tgt_size * tgt_size + 1, dim)
233
+ return vision_pos_embed
234
+ else:
235
+ return abs_pos
236
+
237
+ @torch.jit.script
238
+ def quick_gelu(x):
239
+ return x * torch.sigmoid(1.702 * x)
240
+
241
+
242
+
243
+ class CLIPVisionEmbeddings(nn.Module):
244
+ def __init__(self, hidden_size=1024, image_size=224, patch_size=14, num_channels=3):
245
+ super().__init__()
246
+ self.embed_dim = hidden_size
247
+ self.image_size = image_size
248
+ self.patch_size = patch_size
249
+
250
+ self.class_embedding = torch.nn.Parameter(torch.randn(self.embed_dim))
251
+
252
+ self.patch_embedding = torch.nn.Conv2d(
253
+ in_channels=num_channels,
254
+ out_channels=self.embed_dim,
255
+ kernel_size=self.patch_size,
256
+ stride=self.patch_size,
257
+ bias=False,
258
+ )
259
+
260
+ self.num_patches = (self.image_size // self.patch_size) ** 2
261
+ self.num_positions = self.num_patches + 1
262
+ self.position_embedding = torch.nn.Embedding(self.num_positions, self.embed_dim)
263
+ self.register_buffer(
264
+ "position_ids", torch.arange(self.num_positions).expand((1, -1))
265
+ )
266
+
267
+ def forward(self, pixel_values, patch_embeds):
268
+ batch_size = pixel_values.shape[0]
269
+ # patch_embeds = self.patch_embedding(
270
+ # pixel_values
271
+ # ) # shape = [*, width, grid, grid]
272
+
273
+
274
+ if patch_embeds is not None:
275
+ patch_embeds = patch_embeds
276
+ # print(patch_embeds.shape)
277
+ else:
278
+ patch_embeds = self.patch_embedding(pixel_values)
279
+ # print(111111)
280
+ # shape = [*, width, grid, grid]
281
+ # patch_embeds = patch_embeds.flatten(2).transpose(1, 2)
282
+
283
+ patch_embeds = patch_embeds.flatten(2).transpose(1, 2)
284
+
285
+
286
+ class_embeds = self.class_embedding.expand(batch_size, 1, -1)
287
+ embeddings = torch.cat([class_embeds, patch_embeds], dim=1)
288
+
289
+ # x = torch.cat([cls_token, x], dim=1)
290
+ embeddings = embeddings + get_abs_pos(self.position_embedding(self.position_ids), embeddings.size(1))
291
+ # embeddings = embeddings + self.position_embedding(self.position_ids)
292
+ return embeddings
293
+
294
+
295
+ class NoTPFeedForward(nn.Module):
296
+ def __init__(
297
+ self,
298
+ cfg,
299
+ dim: int,
300
+ hidden_dim: int,
301
+ ):
302
+ super().__init__()
303
+
304
+ self.fc1 = torch.nn.Linear(dim, hidden_dim, bias=True)
305
+ self.fc2 = torch.nn.Linear(hidden_dim, dim, bias=True)
306
+
307
+ def forward(self, x):
308
+ output = self.fc2(quick_gelu(self.fc1(x)))
309
+ return output
310
+
311
+
312
+
313
+
314
+ class NoTPAttention(torch.nn.Module):
315
+ def __init__(self, cfg):
316
+ super().__init__()
317
+ self.num_heads = cfg.num_attention_heads
318
+ self.n_local_heads = cfg.num_attention_heads
319
+ self.head_dim = cfg.hidden_size // cfg.num_attention_heads
320
+ self.max_seq_len = cfg.seq_length
321
+ self.use_flash_attention = cfg.use_flash_attn
322
+
323
+ self.qkv_proj = torch.nn.Linear(cfg.hidden_size, cfg.hidden_size * 3, bias=True)
324
+ self.out_proj = torch.nn.Linear(cfg.hidden_size, cfg.hidden_size, bias=True)
325
+
326
+ # self.core_attention = CoreAttention(cfg, AttnType.self_attn)
327
+
328
+ self.attn_drop = cfg.attention_dropout
329
+
330
+ def forward(
331
+ self,
332
+ x: torch.Tensor,
333
+ ):
334
+ bsz, seqlen, _ = x.shape
335
+ xqkv = self.qkv_proj(x)
336
+ xqkv = xqkv.view(bsz, seqlen, 3, self.num_heads, self.head_dim)
337
+
338
+ if self.use_flash_attention:
339
+
340
+ xq, xk, xv = torch.split(xqkv, 1, dim=2)
341
+ xq = xq.squeeze(2)
342
+ xk = xk.squeeze(2)
343
+ xv = xv.squeeze(2)
344
+ # xq, xk, xv = xqkv[:, :, 0, ...], xqkv[:, :, 1, ...], xqkv[:, :, 2, ...]
345
+
346
+ # (B, num_head, S, head_size)
347
+ xq = xq.permute(0, 2, 1, 3)
348
+ xk = xk.permute(0, 2, 1, 3)
349
+ xv = xv.permute(0, 2, 1, 3)
350
+ # with torch.backends.cuda.sdp_kernel(enable_flash=True, enable_math=False, enable_mem_efficient=False):
351
+ output = torch.nn.functional.scaled_dot_product_attention(xq, xk, xv, attn_mask=None)
352
+ output = output.permute(0, 2, 1, 3).reshape(bsz, seqlen, -1)
353
+ # output = output.permute(0, 2, 1, 3).contiguous().view(bsz, seqlen, -1)
354
+ else:
355
+ # print(22222)
356
+ xq, xk, xv = torch.split(xqkv, 1, dim=2)
357
+ xq = xq.squeeze(2)
358
+ xk = xk.squeeze(2)
359
+ xv = xv.squeeze(2)
360
+ # xq, xk, xv = xqkv[:, :, 0, ...], xqkv[:, :, 1, ...], xqkv[:, :, 2, ...]
361
+
362
+ # (B, num_head, S, head_size)
363
+ xq = xq.permute(0, 2, 1, 3)
364
+ xk = xk.permute(0, 2, 1, 3)
365
+ xv = xv.permute(0, 2, 1, 3)
366
+ # with torch.backends.cuda.sdp_kernel(enable_flash=True, enable_math=False, enable_mem_efficient=False):
367
+ output = torch.nn.functional.scaled_dot_product_attention(xq, xk, xv, attn_mask=None)
368
+ output = output.permute(0, 2, 1, 3).reshape(bsz, seqlen, -1)
369
+ # output = output.permute(0, 2, 1, 3).contiguous().view(bsz, seqlen, -1)
370
+ output = self.out_proj(output)
371
+ return output
372
+
373
+ class NoTPTransformerBlock(nn.Module):
374
+ def __init__(self, cfg, layer_id: int, multiple_of=256):
375
+ super().__init__()
376
+
377
+ self.n_heads = cfg.num_attention_heads
378
+ self.dim = cfg.hidden_size
379
+ self.head_dim = cfg.hidden_size // cfg.num_attention_heads
380
+ self.self_attn = NoTPAttention(cfg)
381
+ self.mlp = NoTPFeedForward(
382
+ cfg, dim=cfg.hidden_size, hidden_dim=cfg.ffn_hidden_size
383
+ )
384
+ self.layer_id = layer_id
385
+ self.layer_norm1 = torch.nn.LayerNorm(
386
+ cfg.hidden_size, eps=cfg.layernorm_epsilon
387
+ )
388
+ self.layer_norm2 = torch.nn.LayerNorm(
389
+ cfg.hidden_size, eps=cfg.layernorm_epsilon
390
+ )
391
+
392
+ def forward(self, x: torch.Tensor):
393
+ residual = self.self_attn.forward(self.layer_norm1(x))
394
+ h = x + residual
395
+ out = h + self.mlp.forward(self.layer_norm2(h))
396
+ return out
397
+
398
+
399
+ class NoTPTransformer(nn.Module):
400
+ def __init__(self, cfg):
401
+ super().__init__()
402
+
403
+ self.cfg = cfg
404
+ # self.recompute_list = self.cfg.get("recompute_list", [])
405
+ self.num_layers = cfg.num_layers # _get_num_layers(cfg)
406
+
407
+ self.layers = torch.nn.ModuleList()
408
+ for layer_id in range(self.num_layers):
409
+ self.layers.append(
410
+ NoTPTransformerBlock(
411
+ cfg,
412
+ layer_id + 1,
413
+ )
414
+ )
415
+
416
+ def forward(
417
+ self,
418
+ hidden_states,
419
+ ):
420
+
421
+ for lid, layer in enumerate(self.layers):
422
+ # if lid in self.recompute_list:
423
+ # def custom(layer_id):
424
+ # def custom_forward(*args, **kwargs):
425
+ # x_ = self.layers[layer_id](*args, **kwargs)
426
+ # return x_
427
+
428
+ # return custom_forward
429
+
430
+ # assert hidden_states.requires_grad == True, logger.warning(
431
+ # "When using recalculation, the input must have grad fn"
432
+ # )
433
+ # hidden_states = tensor_parallel.checkpoint(
434
+ # custom(lid),
435
+ # False,
436
+ # hidden_states.contiguous()
437
+ # )
438
+ # else:
439
+ hidden_states = layer(hidden_states)
440
+
441
+ return hidden_states
442
+
443
+
444
+ # from megatron.core.tensor_parallel.layers import non_tensor_paralleled, local_dp_reduce, local_dp_scatter
445
+
446
+ class VitModel(nn.Module):
447
+ def __init__(
448
+ self,
449
+ cfg,
450
+ freeze_embed=False,
451
+ freeze_pre_norm=False
452
+ ) -> None:
453
+ super().__init__()
454
+
455
+ self.embeddings = CLIPVisionEmbeddings(hidden_size=cfg.hidden_size, image_size=cfg.image_size, patch_size=cfg.patch_size)
456
+
457
+ if freeze_embed:
458
+ for name, param in self.embeddings.named_parameters():
459
+ param.requires_grad = False
460
+
461
+ self.transformer = NoTPTransformer(cfg=cfg)
462
+
463
+ if cfg.get("fp32norm", False):
464
+ logger.info("Load fp32 layernorm for ViT.")
465
+ self.pre_layrnorm = LayerNormfp32(
466
+ cfg.hidden_size,
467
+ eps=cfg.get("pre_layernorm_epsilon", 1e-5),
468
+ )
469
+ else:
470
+ self.pre_layrnorm = torch.nn.LayerNorm(
471
+ cfg.hidden_size,
472
+ eps=cfg.get("pre_layernorm_epsilon", 1e-5),
473
+ )
474
+
475
+ # self.pre_layrnorm = RMSNorm(
476
+ # cfg.hidden_size,
477
+ # eps=cfg.get("pre_layernorm_epsilon", 1e-5),
478
+ # sequence_parallel=False,
479
+ # use_fp32=True,
480
+ # use_optimus=True,
481
+ # )
482
+
483
+ if freeze_pre_norm:
484
+ for name, param in self.pre_layrnorm.named_parameters():
485
+ param.requires_grad = False
486
+
487
+ for p in self.parameters():
488
+ p.micro_dp = True
489
+
490
+ def set_input_tensor(self, input_tensor):
491
+ if not isinstance(input_tensor, list):
492
+ input_tensor = [input_tensor]
493
+ self.transformer.set_input_tensor(input_tensor[0])
494
+
495
+ def __str__(self) -> str:
496
+ return "open_clip"
497
+
498
+ def forward(
499
+ self,
500
+ x,
501
+ patch_embeds
502
+ ):
503
+ x = self.embeddings(x, patch_embeds)
504
+ hidden_states = self.pre_layrnorm(x)
505
+
506
+ # hidden_states, dis = local_dp_scatter(hidden_states)
507
+ output = self.transformer(hidden_states)
508
+
509
+ # output = local_dp_reduce(output, dis)
510
+
511
+ return output
512
+
513
+
514
+ vit_model_cfg = adict(
515
+ num_layers=24,
516
+ hidden_size=1024,
517
+ num_heads = 16,
518
+ num_attention_heads=16,
519
+ ffn_hidden_size=4096,
520
+ seq_length=256,
521
+ max_position_embeddings=256,
522
+ use_flash_attn=False,
523
+ understand_projector_stride=2,
524
+ hidden_dropout = 0.0,
525
+ attention_dropout = 0.0,
526
+ no_persist_layer_norm = False,
527
+ layernorm_epsilon = 1e-5,
528
+ pre_layernorm_epsilon = 1e-5,
529
+ image_size = 224,
530
+ patch_size = 14,
531
+ recompute_list = []
532
+ )
533
+
534
+ def build_clip_l():
535
+ return VitModel(
536
+ cfg=vit_model_cfg,
537
+ freeze_embed=False,
538
+ freeze_pre_norm=False,
539
+ )
540
+
541
+
542
+
543
+
544
+
545
+ #=========================Sam-Vary=================================
546
+
547
+
548
+ def get_abs_pos_sam(abs_pos, tgt_size):
549
+
550
+ dtype = abs_pos.dtype
551
+
552
+ src_size = abs_pos.size(1)
553
+
554
+ if src_size != tgt_size:
555
+ old_pos_embed = abs_pos.permute(0, 3, 1, 2)
556
+ old_pos_embed = old_pos_embed.to(torch.float32)
557
+ new_pos_embed = F.interpolate(
558
+ old_pos_embed,
559
+ size=(tgt_size, tgt_size),
560
+ mode='bicubic',
561
+ antialias=True,
562
+ align_corners=False,
563
+ ).to(dtype)
564
+ new_pos_embed = new_pos_embed.permute(0, 2, 3, 1)
565
+ return new_pos_embed
566
+ else:
567
+ return abs_pos
568
+
569
+
570
+
571
+
572
+ class MLPBlock(nn.Module):
573
+ def __init__(
574
+ self,
575
+ embedding_dim: int,
576
+ mlp_dim: int,
577
+ act: Type[nn.Module] = nn.GELU,
578
+ ) -> None:
579
+ super().__init__()
580
+ self.lin1 = nn.Linear(embedding_dim, mlp_dim)
581
+ self.lin2 = nn.Linear(mlp_dim, embedding_dim)
582
+ self.act = act()
583
+
584
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
585
+ return self.lin2(self.act(self.lin1(x)))
586
+
587
+
588
+ # From https://github.com/facebookresearch/detectron2/blob/main/detectron2/layers/batch_norm.py # noqa
589
+ # Itself from https://github.com/facebookresearch/ConvNeXt/blob/d1fa8f6fef0a165b27399986cc2bdacc92777e40/models/convnext.py#L119 # noqa
590
+ class LayerNorm2d(nn.Module):
591
+ def __init__(self, num_channels: int, eps: float = 1e-6) -> None:
592
+ super().__init__()
593
+ self.weight = nn.Parameter(torch.ones(num_channels))
594
+ self.bias = nn.Parameter(torch.zeros(num_channels))
595
+ self.eps = eps
596
+
597
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
598
+ u = x.mean(1, keepdim=True)
599
+ s = (x - u).pow(2).mean(1, keepdim=True)
600
+ x = (x - u) / torch.sqrt(s + self.eps)
601
+ x = self.weight[:, None, None] * x + self.bias[:, None, None]
602
+ return x
603
+
604
+
605
+ # This class and its supporting functions below lightly adapted from the ViTDet backbone available at: https://github.com/facebookresearch/detectron2/blob/main/detectron2/modeling/backbone/vit.py # noqa
606
+ class ImageEncoderViT(nn.Module):
607
+ def __init__(
608
+ self,
609
+ img_size: int = 1024,
610
+ patch_size: int = 16,
611
+ in_chans: int = 3,
612
+ embed_dim: int = 768,
613
+ depth: int = 12,
614
+ num_heads: int = 12,
615
+ mlp_ratio: float = 4.0,
616
+ out_chans: int = 256,
617
+ qkv_bias: bool = True,
618
+ norm_layer: Type[nn.Module] = nn.LayerNorm,
619
+ act_layer: Type[nn.Module] = nn.GELU,
620
+ use_abs_pos: bool = True,
621
+ use_rel_pos: bool = False,
622
+ rel_pos_zero_init: bool = True,
623
+ window_size: int = 0,
624
+ global_attn_indexes: Tuple[int, ...] = (),
625
+ ) -> None:
626
+ """
627
+ Args:
628
+ img_size (int): Input image size.
629
+ patch_size (int): Patch size.
630
+ in_chans (int): Number of input image channels.
631
+ embed_dim (int): Patch embedding dimension.
632
+ depth (int): Depth of ViT.
633
+ num_heads (int): Number of attention heads in each ViT block.
634
+ mlp_ratio (float): Ratio of mlp hidden dim to embedding dim.
635
+ qkv_bias (bool): If True, add a learnable bias to query, key, value.
636
+ norm_layer (nn.Module): Normalization layer.
637
+ act_layer (nn.Module): Activation layer.
638
+ use_abs_pos (bool): If True, use absolute positional embeddings.
639
+ use_rel_pos (bool): If True, add relative positional embeddings to the attention map.
640
+ rel_pos_zero_init (bool): If True, zero initialize relative positional parameters.
641
+ window_size (int): Window size for window attention blocks.
642
+ global_attn_indexes (list): Indexes for blocks using global attention.
643
+ """
644
+ super().__init__()
645
+ self.img_size = img_size
646
+
647
+ self.patch_embed = PatchEmbed(
648
+ kernel_size=(patch_size, patch_size),
649
+ stride=(patch_size, patch_size),
650
+ in_chans=in_chans,
651
+ embed_dim=embed_dim,
652
+ )
653
+
654
+ self.pos_embed: Optional[nn.Parameter] = None
655
+ if use_abs_pos:
656
+ # Initialize absolute positional embedding with pretrain image size.
657
+ self.pos_embed = nn.Parameter(
658
+ torch.zeros(1, img_size // patch_size, img_size // patch_size, embed_dim)
659
+ )
660
+
661
+ self.blocks = nn.ModuleList()
662
+ for i in range(depth):
663
+ block = Block(
664
+ dim=embed_dim,
665
+ num_heads=num_heads,
666
+ mlp_ratio=mlp_ratio,
667
+ qkv_bias=qkv_bias,
668
+ norm_layer=norm_layer,
669
+ act_layer=act_layer,
670
+ use_rel_pos=use_rel_pos,
671
+ rel_pos_zero_init=rel_pos_zero_init,
672
+ window_size=window_size if i not in global_attn_indexes else 0,
673
+ input_size=(img_size // patch_size, img_size // patch_size),
674
+ )
675
+ self.blocks.append(block)
676
+
677
+ self.neck = nn.Sequential(
678
+ nn.Conv2d(
679
+ embed_dim,
680
+ out_chans,
681
+ kernel_size=1,
682
+ bias=False,
683
+ ),
684
+ LayerNorm2d(out_chans),
685
+ nn.Conv2d(
686
+ out_chans,
687
+ out_chans,
688
+ kernel_size=3,
689
+ padding=1,
690
+ bias=False,
691
+ ),
692
+ LayerNorm2d(out_chans),
693
+ )
694
+
695
+ self.net_2 = nn.Conv2d(256, 512, kernel_size=3, stride=2, padding=1, bias=False)
696
+ self.net_3 = nn.Conv2d(512, 1024, kernel_size=3, stride=2, padding=1, bias=False)
697
+
698
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
699
+ x = self.patch_embed(x)
700
+ if self.pos_embed is not None:
701
+ # x = x + self.pos_embed
702
+ x = x + get_abs_pos_sam(self.pos_embed, x.size(1))
703
+
704
+ for blk in self.blocks:
705
+ x = blk(x)
706
+
707
+ x = self.neck(x.permute(0, 3, 1, 2))
708
+ x2 = self.net_2(x)
709
+ x3 = self.net_3(x2.clone())
710
+
711
+ return x3
712
+
713
+
714
+ class Block(nn.Module):
715
+ """Transformer blocks with support of window attention and residual propagation blocks"""
716
+
717
+ def __init__(
718
+ self,
719
+ dim: int,
720
+ num_heads: int,
721
+ mlp_ratio: float = 4.0,
722
+ qkv_bias: bool = True,
723
+ norm_layer: Type[nn.Module] = nn.LayerNorm,
724
+ act_layer: Type[nn.Module] = nn.GELU,
725
+ use_rel_pos: bool = False,
726
+ rel_pos_zero_init: bool = True,
727
+ window_size: int = 0,
728
+ input_size: Optional[Tuple[int, int]] = None,
729
+ ) -> None:
730
+ """
731
+ Args:
732
+ dim (int): Number of input channels.
733
+ num_heads (int): Number of attention heads in each ViT block.
734
+ mlp_ratio (float): Ratio of mlp hidden dim to embedding dim.
735
+ qkv_bias (bool): If True, add a learnable bias to query, key, value.
736
+ norm_layer (nn.Module): Normalization layer.
737
+ act_layer (nn.Module): Activation layer.
738
+ use_rel_pos (bool): If True, add relative positional embeddings to the attention map.
739
+ rel_pos_zero_init (bool): If True, zero initialize relative positional parameters.
740
+ window_size (int): Window size for window attention blocks. If it equals 0, then
741
+ use global attention.
742
+ input_size (tuple(int, int) or None): Input resolution for calculating the relative
743
+ positional parameter size.
744
+ """
745
+ super().__init__()
746
+ self.norm1 = norm_layer(dim)
747
+ self.attn = Attention(
748
+ dim,
749
+ num_heads=num_heads,
750
+ qkv_bias=qkv_bias,
751
+ use_rel_pos=use_rel_pos,
752
+ rel_pos_zero_init=rel_pos_zero_init,
753
+ input_size=input_size if window_size == 0 else (window_size, window_size),
754
+ )
755
+
756
+ self.norm2 = norm_layer(dim)
757
+ self.mlp = MLPBlock(embedding_dim=dim, mlp_dim=int(dim * mlp_ratio), act=act_layer)
758
+
759
+ self.window_size = window_size
760
+
761
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
762
+ shortcut = x
763
+ x = self.norm1(x)
764
+ # Window partition
765
+ if self.window_size > 0:
766
+ H, W = x.shape[1], x.shape[2]
767
+ x, pad_hw = window_partition(x, self.window_size)
768
+
769
+ x = self.attn(x)
770
+ # Reverse window partition
771
+ if self.window_size > 0:
772
+ x = window_unpartition(x, self.window_size, pad_hw, (H, W))
773
+
774
+ x = shortcut + x
775
+ x = x + self.mlp(self.norm2(x))
776
+
777
+ return x
778
+
779
+
780
+ class Attention(nn.Module):
781
+ """Multi-head Attention block with relative position embeddings."""
782
+
783
+ def __init__(
784
+ self,
785
+ dim: int,
786
+ num_heads: int = 8,
787
+ qkv_bias: bool = True,
788
+ use_rel_pos: bool = False,
789
+ rel_pos_zero_init: bool = True,
790
+ input_size: Optional[Tuple[int, int]] = None,
791
+ ) -> None:
792
+ """
793
+ Args:
794
+ dim (int): Number of input channels.
795
+ num_heads (int): Number of attention heads.
796
+ qkv_bias (bool): If True, add a learnable bias to query, key, value.
797
+ rel_pos (bool): If True, add relative positional embeddings to the attention map.
798
+ rel_pos_zero_init (bool): If True, zero initialize relative positional parameters.
799
+ input_size (tuple(int, int) or None): Input resolution for calculating the relative
800
+ positional parameter size.
801
+ """
802
+ super().__init__()
803
+ self.num_heads = num_heads
804
+ head_dim = dim // num_heads
805
+ self.scale = head_dim**-0.5
806
+
807
+ self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)
808
+ self.proj = nn.Linear(dim, dim)
809
+
810
+ self.use_rel_pos = use_rel_pos
811
+ if self.use_rel_pos:
812
+ assert (
813
+ input_size is not None
814
+ ), "Input size must be provided if using relative positional encoding."
815
+ # initialize relative positional embeddings
816
+ self.rel_pos_h = nn.Parameter(torch.zeros(2 * input_size[0] - 1, head_dim))
817
+ self.rel_pos_w = nn.Parameter(torch.zeros(2 * input_size[1] - 1, head_dim))
818
+
819
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
820
+ B, H, W, _ = x.shape
821
+ # qkv with shape (3, B, nHead, H * W, C)
822
+ qkv = self.qkv(x).reshape(B, H * W, 3, self.num_heads, -1).permute(2, 0, 3, 1, 4)
823
+ # q, k, v with shape (B * nHead, H * W, C)
824
+ q, k, v = qkv.reshape(3, B * self.num_heads, H * W, -1).unbind(0)
825
+
826
+ rel_h, rel_w = None, None
827
+ if self.use_rel_pos:
828
+ rel_h, rel_w = add_decomposed_rel_pos(q, self.rel_pos_h, self.rel_pos_w, (H, W), (H, W))
829
+
830
+ q = q.view(B, self.num_heads, H * W, -1)
831
+ k = k.view(B, self.num_heads, H * W, -1)
832
+ v = v.view(B, self.num_heads, H * W, -1)
833
+
834
+ if self.use_rel_pos:
835
+ rel_h = rel_h.view(B, self.num_heads, rel_h.size(1), rel_h.size(2), rel_h.size(3))
836
+ rel_w = rel_w.view(B, self.num_heads, rel_w.size(1), rel_w.size(2), rel_w.size(3))
837
+ attn_bias = (rel_h + rel_w).view(B, self.num_heads, rel_h.size(2), rel_h.size(3) * rel_w.size(4))
838
+ x = torch.nn.functional.scaled_dot_product_attention(q, k, v, attn_mask=attn_bias)
839
+ # x = _attention_rel_h_rel_w(q, k, v, rel_h, rel_w)
840
+ else:
841
+ x = torch.nn.functional.scaled_dot_product_attention(q, k, v)
842
+
843
+ x = x.view(B, self.num_heads, H, W, -1).permute(0, 2, 3, 1, 4).reshape(B, H, W, -1)
844
+
845
+ x = self.proj(x)
846
+
847
+ return x
848
+
849
+
850
+ def window_partition(x: torch.Tensor, window_size: int) -> Tuple[torch.Tensor, Tuple[int, int]]:
851
+ """
852
+ Partition into non-overlapping windows with padding if needed.
853
+ Args:
854
+ x (tensor): input tokens with [B, H, W, C].
855
+ window_size (int): window size.
856
+
857
+ Returns:
858
+ windows: windows after partition with [B * num_windows, window_size, window_size, C].
859
+ (Hp, Wp): padded height and width before partition
860
+ """
861
+ B, H, W, C = x.shape
862
+
863
+ pad_h = (window_size - H % window_size) % window_size
864
+ pad_w = (window_size - W % window_size) % window_size
865
+ if pad_h > 0 or pad_w > 0:
866
+ x = F.pad(x, (0, 0, 0, pad_w, 0, pad_h))
867
+ Hp, Wp = H + pad_h, W + pad_w
868
+
869
+ x = x.view(B, Hp // window_size, window_size, Wp // window_size, window_size, C)
870
+ windows = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(-1, window_size, window_size, C)
871
+ return windows, (Hp, Wp)
872
+
873
+
874
+ def window_unpartition(
875
+ windows: torch.Tensor, window_size: int, pad_hw: Tuple[int, int], hw: Tuple[int, int]
876
+ ) -> torch.Tensor:
877
+ """
878
+ Window unpartition into original sequences and removing padding.
879
+ Args:
880
+ windows (tensor): input tokens with [B * num_windows, window_size, window_size, C].
881
+ window_size (int): window size.
882
+ pad_hw (Tuple): padded height and width (Hp, Wp).
883
+ hw (Tuple): original height and width (H, W) before padding.
884
+
885
+ Returns:
886
+ x: unpartitioned sequences with [B, H, W, C].
887
+ """
888
+ Hp, Wp = pad_hw
889
+ H, W = hw
890
+ B = windows.shape[0] // (Hp * Wp // window_size // window_size)
891
+ x = windows.view(B, Hp // window_size, Wp // window_size, window_size, window_size, -1)
892
+ x = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(B, Hp, Wp, -1)
893
+
894
+ if Hp > H or Wp > W:
895
+ x = x[:, :H, :W, :].contiguous()
896
+ return x
897
+
898
+
899
+ def get_rel_pos(q_size: int, k_size: int, rel_pos: torch.Tensor) -> torch.Tensor:
900
+ """
901
+ Get relative positional embeddings according to the relative positions of
902
+ query and key sizes.
903
+ Args:
904
+ q_size (int): size of query q.
905
+ k_size (int): size of key k.
906
+ rel_pos (Tensor): relative position embeddings (L, C).
907
+
908
+ Returns:
909
+ Extracted positional embeddings according to relative positions.
910
+ """
911
+ max_rel_dist = int(2 * max(q_size, k_size) - 1)
912
+ # Interpolate rel pos if needed.
913
+ if rel_pos.shape[0] != max_rel_dist:
914
+ # Interpolate rel pos.
915
+ dtype = rel_pos.dtype
916
+ rel_pos = rel_pos.to(torch.float32)
917
+ rel_pos_resized = F.interpolate(
918
+ rel_pos.reshape(1, rel_pos.shape[0], -1).permute(0, 2, 1),
919
+ size=max_rel_dist,
920
+ mode="linear",
921
+ ).to(dtype)
922
+ rel_pos_resized = rel_pos_resized.reshape(-1, max_rel_dist).permute(1, 0)
923
+ else:
924
+ rel_pos_resized = rel_pos
925
+
926
+ # Scale the coords with short length if shapes for q and k are different.
927
+ q_coords = torch.arange(q_size, device=rel_pos.device)[:, None] * max(k_size / q_size, 1.0)
928
+ k_coords = torch.arange(k_size, device=rel_pos.device)[None, :] * max(q_size / k_size, 1.0)
929
+ relative_coords = (q_coords - k_coords) + (k_size - 1) * max(q_size / k_size, 1.0)
930
+
931
+ return rel_pos_resized[relative_coords.long()]
932
+
933
+
934
+ def add_decomposed_rel_pos(
935
+ q: torch.Tensor,
936
+ rel_pos_h: torch.Tensor,
937
+ rel_pos_w: torch.Tensor,
938
+ q_size: Tuple[int, int],
939
+ k_size: Tuple[int, int],
940
+ ) -> torch.Tensor:
941
+ """
942
+ Calculate decomposed Relative Positional Embeddings from :paper:`mvitv2`.
943
+ https://github.com/facebookresearch/mvit/blob/19786631e330df9f3622e5402b4a419a263a2c80/mvit/models/attention.py # noqa B950
944
+ Args:
945
+ q (Tensor): query q in the attention layer with shape (B, q_h * q_w, C).
946
+ rel_pos_h (Tensor): relative position embeddings (Lh, C) for height axis.
947
+ rel_pos_w (Tensor): relative position embeddings (Lw, C) for width axis.
948
+ q_size (Tuple): spatial sequence size of query q with (q_h, q_w).
949
+ k_size (Tuple): spatial sequence size of key k with (k_h, k_w).
950
+
951
+ Returns:
952
+ attn (Tensor): attention map with added relative positional embeddings.
953
+ """
954
+ q_h, q_w = q_size
955
+ k_h, k_w = k_size
956
+ Rh = get_rel_pos(q_h, k_h, rel_pos_h)
957
+ Rw = get_rel_pos(q_w, k_w, rel_pos_w)
958
+
959
+ B, _, dim = q.shape
960
+ r_q = q.reshape(B, q_h, q_w, dim)
961
+ rel_h = torch.einsum("bhwc,hkc->bhwk", r_q, Rh)
962
+ rel_w = torch.einsum("bhwc,wkc->bhwk", r_q, Rw)
963
+ rel_h = rel_h.unsqueeze(-1)
964
+ rel_w = rel_w.unsqueeze(-2)
965
+ rel_h = rel_h.reshape(B, q_h * q_w, k_h, 1)
966
+ rel_w = rel_w.reshape(B, q_h * q_w, 1, k_w)
967
+
968
+ return rel_h, rel_w
969
+
970
+
971
+ class PatchEmbed(nn.Module):
972
+ """
973
+ Image to Patch Embedding.
974
+ """
975
+
976
+ def __init__(
977
+ self,
978
+ kernel_size: Tuple[int, int] = (16, 16),
979
+ stride: Tuple[int, int] = (16, 16),
980
+ padding: Tuple[int, int] = (0, 0),
981
+ in_chans: int = 3,
982
+ embed_dim: int = 768,
983
+ ) -> None:
984
+ """
985
+ Args:
986
+ kernel_size (Tuple): kernel size of the projection layer.
987
+ stride (Tuple): stride of the projection layer.
988
+ padding (Tuple): padding size of the projection layer.
989
+ in_chans (int): Number of input image channels.
990
+ embed_dim (int): Patch embedding dimension.
991
+ """
992
+ super().__init__()
993
+
994
+ self.proj = nn.Conv2d(
995
+ in_chans, embed_dim, kernel_size=kernel_size, stride=stride, padding=padding
996
+ )
997
+
998
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
999
+ x = self.proj(x)
1000
+ # B C H W -> B H W C
1001
+ x = x.permute(0, 2, 3, 1)
1002
+ return x
1003
+
1004
+
1005
+ def build_sam_vit_b(checkpoint=None):
1006
+ return _build_sam(
1007
+ encoder_embed_dim=768,
1008
+ encoder_depth=12,
1009
+ encoder_num_heads=12,
1010
+ encoder_global_attn_indexes=[2, 5, 8, 11],
1011
+ checkpoint=checkpoint,
1012
+ )
1013
+
1014
+ def build_sam_fast_vit_b(checkpoint=None, compile_mode='max-autotune', dtype=torch.bfloat16):
1015
+ image_encoder = build_sam_vit_b(checkpoint).eval().to(dtype)
1016
+ # sam = _apply_eval_dtype_sam(sam, dtype)
1017
+ image_encoder = torch.compile(image_encoder, mode=compile_mode)
1018
+ return image_encoder
1019
+
1020
+
1021
+ def _build_sam(
1022
+ encoder_embed_dim,
1023
+ encoder_depth,
1024
+ encoder_num_heads,
1025
+ encoder_global_attn_indexes,
1026
+ checkpoint=None,
1027
+ ):
1028
+ prompt_embed_dim = 256
1029
+ image_size = 1024
1030
+ vit_patch_size = 16
1031
+ image_embedding_size = image_size // vit_patch_size
1032
+ image_encoder=ImageEncoderViT(
1033
+ depth=encoder_depth,
1034
+ embed_dim=encoder_embed_dim,
1035
+ img_size=image_size,
1036
+ mlp_ratio=4,
1037
+ norm_layer=partial(torch.nn.LayerNorm, eps=1e-6),
1038
+ num_heads=encoder_num_heads,
1039
+ patch_size=vit_patch_size,
1040
+ qkv_bias=True,
1041
+ use_rel_pos=True,
1042
+ global_attn_indexes=encoder_global_attn_indexes,
1043
+ window_size=14,
1044
+ out_chans=prompt_embed_dim,
1045
+ )
1046
+ image_encoder.eval()
1047
+ if checkpoint is not None:
1048
+ # with open(checkpoint, "rb") as f:
1049
+ state_dict = torch.load(checkpoint)
1050
+ # print(state_dict.keys())
1051
+ # for key in state_dict:
1052
+ # image_encoder.load_state_dict({k[14:]: v for k, v in state_dict.items() if 'image_encoder' in k}, strict=False)
1053
+ # ocr-anyting
1054
+ # image_encoder.load_state_dict(state_dict, strict=True)
1055
+ # tob
1056
+ image_encoder.load_state_dict({k[30:]: v for k, v in state_dict.items() if 'vision_tower_high' in k}, strict=True)
1057
+ print(checkpoint)
1058
+ return image_encoder
model-00001-of-000001.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2bc48a7a110061ea58fff65d3169367eebe3aee371ca6968dc2219c1b2855fc6
3
+ size 6672547120
model.safetensors.index.json ADDED
The diff for this file is too large to render. See raw diff
 
modeling_deepseekv2.py ADDED
@@ -0,0 +1,2141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding=utf-8
2
+ # Copyright 2023 DeepSeek-AI and The HuggingFace Inc. team. All rights reserved.
3
+ #
4
+ # This code is based on EleutherAI's GPT-NeoX library and the GPT-NeoX
5
+ # and OPT implementations in this library. It has been modified from its
6
+ # original forms to accommodate minor architectural differences compared
7
+ # to GPT-NeoX and OPT used by the Meta AI team that trained the model.
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+ """ PyTorch DeepSeek model and compatible with both DeepSeekV2 and DeepSeekV3"""
21
+ import math
22
+ import warnings
23
+ from typing import List, Optional, Tuple, Union
24
+ import numpy as np
25
+
26
+ import torch
27
+ import torch.nn.functional as F
28
+ import torch.utils.checkpoint
29
+ import torch.distributed as dist
30
+ from einops import repeat
31
+ from torch import nn
32
+ from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss
33
+
34
+ from transformers.activations import ACT2FN
35
+ from transformers.cache_utils import Cache, DynamicCache
36
+ from transformers.modeling_attn_mask_utils import _prepare_4d_causal_attention_mask
37
+ from transformers.models.llama.modeling_llama import (
38
+ LlamaAttention,
39
+ apply_rotary_pos_emb as _llama_apply_rotary_pos_emb,
40
+ repeat_kv as _llama_repeat_kv,
41
+ # LlamaFlashAttention2
42
+ )
43
+ from transformers.modeling_outputs import (
44
+ BaseModelOutputWithPast,
45
+ CausalLMOutputWithPast,
46
+ SequenceClassifierOutputWithPast,
47
+ )
48
+ from transformers.modeling_utils import PreTrainedModel
49
+ from transformers.pytorch_utils import (
50
+ ALL_LAYERNORM_LAYERS,
51
+ is_torch_greater_or_equal_than_1_13,
52
+ )
53
+ from transformers.utils import (
54
+ add_start_docstrings,
55
+ add_start_docstrings_to_model_forward,
56
+ is_flash_attn_2_available,
57
+ is_flash_attn_greater_or_equal_2_10,
58
+ logging,
59
+ replace_return_docstrings,
60
+ )
61
+ from transformers.utils.import_utils import is_torch_fx_available
62
+
63
+ from .configuration_deepseek_v2 import DeepseekV2Config
64
+
65
+ if is_flash_attn_2_available():
66
+ from flash_attn import flash_attn_func, flash_attn_varlen_func
67
+ from flash_attn.bert_padding import index_first_axis, pad_input, unpad_input # noqa
68
+
69
+ # This makes `_prepare_4d_causal_attention_mask` a leaf function in the FX graph.
70
+ # It means that the function will not be traced through and simply appear as a node in the graph.
71
+ if is_torch_fx_available():
72
+ if not is_torch_greater_or_equal_than_1_13:
73
+ import torch.fx
74
+
75
+ _prepare_4d_causal_attention_mask = torch.fx.wrap(_prepare_4d_causal_attention_mask)
76
+
77
+ logger = logging.get_logger(__name__)
78
+
79
+ _CONFIG_FOR_DOC = "DeepseekV2Config"
80
+
81
+
82
+ def _get_unpad_data(attention_mask):
83
+ seqlens_in_batch = attention_mask.sum(dim=-1, dtype=torch.int32)
84
+ indices = torch.nonzero(attention_mask.flatten(), as_tuple=False).flatten()
85
+ max_seqlen_in_batch = seqlens_in_batch.max().item()
86
+ cu_seqlens = F.pad(
87
+ torch.cumsum(seqlens_in_batch, dim=0, dtype=torch.torch.int32), (1, 0)
88
+ )
89
+ return (
90
+ indices,
91
+ cu_seqlens,
92
+ max_seqlen_in_batch,
93
+ )
94
+
95
+
96
+ class DeepseekV2RMSNorm(nn.Module):
97
+ def __init__(self, hidden_size, eps=1e-6):
98
+ """
99
+ DeepseekV2RMSNorm is equivalent to T5LayerNorm
100
+ """
101
+ super().__init__()
102
+ self.weight = nn.Parameter(torch.ones(hidden_size))
103
+ self.variance_epsilon = eps
104
+
105
+ def forward(self, hidden_states):
106
+ input_dtype = hidden_states.dtype
107
+ hidden_states = hidden_states.to(torch.float32)
108
+ variance = hidden_states.pow(2).mean(-1, keepdim=True)
109
+ hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)
110
+ return self.weight * hidden_states.to(input_dtype)
111
+
112
+
113
+ ALL_LAYERNORM_LAYERS.append(DeepseekV2RMSNorm)
114
+
115
+
116
+
117
+
118
+ class DeepseekV2RotaryEmbedding(nn.Module):
119
+ def __init__(self, dim, max_position_embeddings=2048, base=10000, device=None):
120
+ super().__init__()
121
+
122
+ self.dim = dim
123
+ self.max_position_embeddings = max_position_embeddings
124
+ self.base = base
125
+ inv_freq = 1.0 / (
126
+ self.base ** (torch.arange(0, self.dim, 2).float().to(device) / self.dim)
127
+ )
128
+ self.register_buffer("inv_freq", inv_freq, persistent=False)
129
+
130
+ # Build here to make `torch.jit.trace` work.
131
+ self._set_cos_sin_cache(
132
+ seq_len=max_position_embeddings,
133
+ device=self.inv_freq.device,
134
+ dtype=torch.get_default_dtype(),
135
+ )
136
+ self.max_seq_len_cached = None
137
+
138
+ def _set_cos_sin_cache(self, seq_len, device, dtype):
139
+ self.max_seq_len_cached = seq_len
140
+ t = torch.arange(
141
+ self.max_seq_len_cached, device=device, dtype=self.inv_freq.dtype
142
+ )
143
+
144
+ freqs = torch.outer(t, self.inv_freq.to(t.device))
145
+ # Different from paper, but it uses a different permutation in order to obtain the same calculation
146
+ emb = torch.cat((freqs, freqs), dim=-1)
147
+ self.register_buffer("cos_cached", emb.cos().to(dtype), persistent=False)
148
+ self.register_buffer("sin_cached", emb.sin().to(dtype), persistent=False)
149
+
150
+ def forward(self, x, seq_len=None):
151
+ # x: [bs, num_attention_heads, seq_len, head_size]
152
+ if self.max_seq_len_cached is None or seq_len > self.max_seq_len_cached:
153
+ self._set_cos_sin_cache(seq_len=seq_len, device=x.device, dtype=x.dtype)
154
+
155
+ return (
156
+ self.cos_cached[:seq_len].to(dtype=x.dtype),
157
+ self.sin_cached[:seq_len].to(dtype=x.dtype),
158
+ )
159
+
160
+
161
+ # Copied from transformers.models.llama.modeling_llama.LlamaLinearScalingRotaryEmbedding with Llama->DeepseekV2
162
+ class DeepseekV2LinearScalingRotaryEmbedding(DeepseekV2RotaryEmbedding):
163
+ """DeepseekV2RotaryEmbedding extended with linear scaling. Credits to the Reddit user /u/kaiokendev"""
164
+
165
+ def __init__(
166
+ self,
167
+ dim,
168
+ max_position_embeddings=2048,
169
+ base=10000,
170
+ device=None,
171
+ scaling_factor=1.0,
172
+ ):
173
+ self.scaling_factor = scaling_factor
174
+ super().__init__(dim, max_position_embeddings, base, device)
175
+
176
+ def _set_cos_sin_cache(self, seq_len, device, dtype):
177
+ self.max_seq_len_cached = seq_len
178
+ t = torch.arange(
179
+ self.max_seq_len_cached, device=device, dtype=self.inv_freq.dtype
180
+ )
181
+ t = t / self.scaling_factor
182
+
183
+ freqs = torch.outer(t, self.inv_freq)
184
+ # Different from paper, but it uses a different permutation in order to obtain the same calculation
185
+ emb = torch.cat((freqs, freqs), dim=-1)
186
+ self.register_buffer("cos_cached", emb.cos().to(dtype), persistent=False)
187
+ self.register_buffer("sin_cached", emb.sin().to(dtype), persistent=False)
188
+
189
+
190
+ # Copied from transformers.models.llama.modeling_llama.LlamaDynamicNTKScalingRotaryEmbedding with Llama->DeepseekV2
191
+ class DeepseekV2DynamicNTKScalingRotaryEmbedding(DeepseekV2RotaryEmbedding):
192
+ """DeepseekV2RotaryEmbedding extended with Dynamic NTK scaling. Credits to the Reddit users /u/bloc97 and /u/emozilla"""
193
+
194
+ def __init__(
195
+ self,
196
+ dim,
197
+ max_position_embeddings=2048,
198
+ base=10000,
199
+ device=None,
200
+ scaling_factor=1.0,
201
+ ):
202
+ self.scaling_factor = scaling_factor
203
+ super().__init__(dim, max_position_embeddings, base, device)
204
+
205
+ def _set_cos_sin_cache(self, seq_len, device, dtype):
206
+ self.max_seq_len_cached = seq_len
207
+
208
+ if seq_len > self.max_position_embeddings:
209
+ base = self.base * (
210
+ (self.scaling_factor * seq_len / self.max_position_embeddings)
211
+ - (self.scaling_factor - 1)
212
+ ) ** (self.dim / (self.dim - 2))
213
+ inv_freq = 1.0 / (
214
+ base ** (torch.arange(0, self.dim, 2).float().to(device) / self.dim)
215
+ )
216
+ self.register_buffer("inv_freq", inv_freq, persistent=False)
217
+
218
+ t = torch.arange(
219
+ self.max_seq_len_cached, device=device, dtype=self.inv_freq.dtype
220
+ )
221
+
222
+ freqs = torch.outer(t, self.inv_freq)
223
+ # Different from paper, but it uses a different permutation in order to obtain the same calculation
224
+ emb = torch.cat((freqs, freqs), dim=-1)
225
+ self.register_buffer("cos_cached", emb.cos().to(dtype), persistent=False)
226
+ self.register_buffer("sin_cached", emb.sin().to(dtype), persistent=False)
227
+
228
+
229
+ # Inverse dim formula to find dim based on number of rotations
230
+ def yarn_find_correction_dim(
231
+ num_rotations, dim, base=10000, max_position_embeddings=2048
232
+ ):
233
+ return (dim * math.log(max_position_embeddings / (num_rotations * 2 * math.pi))) / (
234
+ 2 * math.log(base)
235
+ )
236
+
237
+
238
+ # Find dim range bounds based on rotations
239
+ def yarn_find_correction_range(
240
+ low_rot, high_rot, dim, base=10000, max_position_embeddings=2048
241
+ ):
242
+ low = math.floor(
243
+ yarn_find_correction_dim(low_rot, dim, base, max_position_embeddings)
244
+ )
245
+ high = math.ceil(
246
+ yarn_find_correction_dim(high_rot, dim, base, max_position_embeddings)
247
+ )
248
+ return max(low, 0), min(high, dim - 1) # Clamp values just in case
249
+
250
+
251
+ def yarn_get_mscale(scale=1, mscale=1):
252
+ if scale <= 1:
253
+ return 1.0
254
+ return 0.1 * mscale * math.log(scale) + 1.0
255
+
256
+
257
+ def yarn_linear_ramp_mask(min, max, dim):
258
+ if min == max:
259
+ max += 0.001 # Prevent singularity
260
+
261
+ linear_func = (torch.arange(dim, dtype=torch.float32) - min) / (max - min)
262
+ ramp_func = torch.clamp(linear_func, 0, 1)
263
+ return ramp_func
264
+
265
+
266
+ class DeepseekV2YarnRotaryEmbedding(DeepseekV2RotaryEmbedding):
267
+
268
+ def __init__(
269
+ self,
270
+ dim,
271
+ max_position_embeddings=2048,
272
+ base=10000,
273
+ device=None,
274
+ scaling_factor=1.0,
275
+ original_max_position_embeddings=4096,
276
+ beta_fast=32,
277
+ beta_slow=1,
278
+ mscale=1,
279
+ mscale_all_dim=0,
280
+ ):
281
+ self.scaling_factor = scaling_factor
282
+ self.original_max_position_embeddings = original_max_position_embeddings
283
+ self.beta_fast = beta_fast
284
+ self.beta_slow = beta_slow
285
+ self.mscale = mscale
286
+ self.mscale_all_dim = mscale_all_dim
287
+ super().__init__(dim, max_position_embeddings, base, device)
288
+
289
+ def _set_cos_sin_cache(self, seq_len, device, dtype):
290
+ self.max_seq_len_cached = seq_len
291
+ dim = self.dim
292
+
293
+ freq_extra = 1.0 / (
294
+ self.base
295
+ ** (torch.arange(0, dim, 2, dtype=torch.float32, device=device) / dim)
296
+ )
297
+ freq_inter = 1.0 / (
298
+ self.scaling_factor
299
+ * self.base
300
+ ** (torch.arange(0, dim, 2, dtype=torch.float32, device=device) / dim)
301
+ )
302
+
303
+ low, high = yarn_find_correction_range(
304
+ self.beta_fast,
305
+ self.beta_slow,
306
+ dim,
307
+ self.base,
308
+ self.original_max_position_embeddings,
309
+ )
310
+ inv_freq_mask = 1.0 - yarn_linear_ramp_mask(low, high, dim // 2).to(
311
+ device=device, dtype=torch.float32
312
+ )
313
+ inv_freq = freq_inter * (1 - inv_freq_mask) + freq_extra * inv_freq_mask
314
+ self.register_buffer("inv_freq", inv_freq, persistent=False)
315
+
316
+ t = torch.arange(seq_len, device=device, dtype=torch.float32)
317
+
318
+ freqs = torch.outer(t, inv_freq)
319
+
320
+ _mscale = float(
321
+ yarn_get_mscale(self.scaling_factor, self.mscale)
322
+ / yarn_get_mscale(self.scaling_factor, self.mscale_all_dim)
323
+ )
324
+
325
+ emb = torch.cat((freqs, freqs), dim=-1)
326
+ self.register_buffer(
327
+ "cos_cached", (emb.cos() * _mscale).to(dtype), persistent=False
328
+ )
329
+ self.register_buffer(
330
+ "sin_cached", (emb.sin() * _mscale).to(dtype), persistent=False
331
+ )
332
+
333
+
334
+ # Copied from transformers.models.llama.modeling_llama.rotate_half
335
+ def rotate_half(x):
336
+ """Rotates half the hidden dims of the input."""
337
+ x1 = x[..., : x.shape[-1] // 2]
338
+ x2 = x[..., x.shape[-1] // 2 :]
339
+ return torch.cat((-x2, x1), dim=-1)
340
+
341
+
342
+ # Copied from transformers.models.llama.modeling_llama.apply_rotary_pos_emb
343
+ def apply_rotary_pos_emb(q, k, cos, sin, position_ids, unsqueeze_dim=1):
344
+ """Applies Rotary Position Embedding to the query and key tensors.
345
+
346
+ Args:
347
+ q (`torch.Tensor`): The query tensor.
348
+ k (`torch.Tensor`): The key tensor.
349
+ cos (`torch.Tensor`): The cosine part of the rotary embedding.
350
+ sin (`torch.Tensor`): The sine part of the rotary embedding.
351
+ position_ids (`torch.Tensor`):
352
+ The position indices of the tokens corresponding to the query and key tensors. For example, this can be
353
+ used to pass offsetted position ids when working with a KV-cache.
354
+ unsqueeze_dim (`int`, *optional*, defaults to 1):
355
+ The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and
356
+ sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note
357
+ that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and
358
+ k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes
359
+ cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have
360
+ the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2.
361
+ Returns:
362
+ `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding.
363
+ """
364
+ cos = cos[position_ids].unsqueeze(unsqueeze_dim)
365
+ sin = sin[position_ids].unsqueeze(unsqueeze_dim)
366
+
367
+
368
+ # print()
369
+
370
+ b, h, s, d = q.shape
371
+ q = q.view(b, h, s, d // 2, 2).transpose(4, 3).reshape(b, h, s, d)
372
+
373
+ b, h, s, d = k.shape
374
+ k = k.view(b, h, s, d // 2, 2).transpose(4, 3).reshape(b, h, s, d)
375
+
376
+ q_embed = (q * cos) + (rotate_half(q) * sin)
377
+ k_embed = (k * cos) + (rotate_half(k) * sin)
378
+
379
+
380
+ return q_embed, k_embed
381
+
382
+
383
+ class DeepseekV2MLP(nn.Module):
384
+ def __init__(self, config, hidden_size=None, intermediate_size=None):
385
+ super().__init__()
386
+ self.config = config
387
+ self.hidden_size = config.hidden_size if hidden_size is None else hidden_size
388
+ self.intermediate_size = (
389
+ config.intermediate_size if intermediate_size is None else intermediate_size
390
+ )
391
+
392
+ self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
393
+ self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
394
+ self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
395
+ self.act_fn = ACT2FN[config.hidden_act]
396
+
397
+ def forward(self, x):
398
+ down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x))
399
+ return down_proj
400
+
401
+
402
+ class MoEGate(nn.Module):
403
+ def __init__(self, config):
404
+ super().__init__()
405
+ self.config = config
406
+ self.top_k = config.num_experts_per_tok
407
+ self.n_routed_experts = config.n_routed_experts
408
+ self.routed_scaling_factor = config.routed_scaling_factor
409
+ self.scoring_func = config.scoring_func
410
+ self.alpha = config.aux_loss_alpha
411
+ self.seq_aux = config.seq_aux
412
+ self.topk_method = config.topk_method
413
+ self.n_group = config.n_group
414
+ self.topk_group = config.topk_group
415
+
416
+ # topk selection algorithm
417
+ self.norm_topk_prob = config.norm_topk_prob
418
+ self.gating_dim = config.hidden_size
419
+ self.weight = nn.Parameter(
420
+ torch.empty((self.n_routed_experts, self.gating_dim))
421
+ )
422
+ if self.topk_method == "noaux_tc":
423
+ self.e_score_correction_bias = nn.Parameter(
424
+ torch.empty((self.n_routed_experts))
425
+ )
426
+ self.reset_parameters()
427
+
428
+ def reset_parameters(self) -> None:
429
+ import torch.nn.init as init
430
+
431
+ init.kaiming_uniform_(self.weight, a=math.sqrt(5))
432
+
433
+ def forward(self, hidden_states):
434
+ bsz, seq_len, h = hidden_states.shape
435
+ ### compute gating score
436
+ hidden_states = hidden_states.view(-1, h)
437
+ logits = F.linear(
438
+ hidden_states.type(torch.float32), self.weight.type(torch.float32), None
439
+ )
440
+ if self.scoring_func == "softmax":
441
+ scores = logits.softmax(dim=-1, dtype=torch.float32)
442
+ elif self.scoring_func == "sigmoid":
443
+ scores = logits.sigmoid()
444
+ else:
445
+ raise NotImplementedError(
446
+ f"insupportable scoring function for MoE gating: {self.scoring_func}"
447
+ )
448
+
449
+ ### select top-k experts
450
+ if self.topk_method == "greedy":
451
+ topk_weight, topk_idx = torch.topk(
452
+ scores, k=self.top_k, dim=-1, sorted=False
453
+ )
454
+ elif self.topk_method == "group_limited_greedy":
455
+ group_scores = (
456
+ scores.view(bsz * seq_len, self.n_group, -1).max(dim=-1).values
457
+ ) # [n, n_group]
458
+ group_idx = torch.topk(
459
+ group_scores, k=self.topk_group, dim=-1, sorted=False
460
+ )[
461
+ 1
462
+ ] # [n, top_k_group]
463
+ group_mask = torch.zeros_like(group_scores) # [n, n_group]
464
+ group_mask.scatter_(1, group_idx, 1) # [n, n_group]
465
+ score_mask = (
466
+ group_mask.unsqueeze(-1)
467
+ .expand(
468
+ bsz * seq_len, self.n_group, self.n_routed_experts // self.n_group
469
+ )
470
+ .reshape(bsz * seq_len, -1)
471
+ ) # [n, e]
472
+ tmp_scores = scores.masked_fill(~score_mask.bool(), 0.0) # [n, e]
473
+ topk_weight, topk_idx = torch.topk(
474
+ tmp_scores, k=self.top_k, dim=-1, sorted=False
475
+ )
476
+ elif self.topk_method == "noaux_tc":
477
+ assert not self.training
478
+ scores_for_choice = scores.view(bsz * seq_len, -1) + self.e_score_correction_bias.unsqueeze(0)
479
+ group_scores = (
480
+ scores_for_choice.view(bsz * seq_len, self.n_group, -1).topk(2, dim=-1)[0].sum(dim = -1)
481
+ ) # [n, n_group]
482
+ group_idx = torch.topk(
483
+ group_scores, k=self.topk_group, dim=-1, sorted=False
484
+ )[
485
+ 1
486
+ ] # [n, top_k_group]
487
+ group_mask = torch.zeros_like(group_scores) # [n, n_group]
488
+ group_mask.scatter_(1, group_idx, 1) # [n, n_group]
489
+ score_mask = (
490
+ group_mask.unsqueeze(-1)
491
+ .expand(
492
+ bsz * seq_len, self.n_group, self.n_routed_experts // self.n_group
493
+ )
494
+ .reshape(bsz * seq_len, -1)
495
+ ) # [n, e]
496
+ tmp_scores = scores_for_choice.masked_fill(~score_mask.bool(), 0.0) # [n, e]
497
+ _, topk_idx = torch.topk(
498
+ tmp_scores, k=self.top_k, dim=-1, sorted=False
499
+ )
500
+ topk_weight = scores.gather(1, topk_idx)
501
+
502
+ ### norm gate to sum 1
503
+ if self.top_k > 1 and self.norm_topk_prob:
504
+ denominator = topk_weight.sum(dim=-1, keepdim=True) + 1e-20
505
+ topk_weight = topk_weight / denominator * self.routed_scaling_factor
506
+ else:
507
+ topk_weight = topk_weight * self.routed_scaling_factor
508
+ ### expert-level computation auxiliary loss
509
+ if self.training and self.alpha > 0.0:
510
+ scores_for_aux = scores
511
+ aux_topk = self.top_k
512
+ # always compute aux loss based on the naive greedy topk method
513
+ topk_idx_for_aux_loss = topk_idx.view(bsz, -1)
514
+ if self.seq_aux:
515
+ scores_for_seq_aux = scores_for_aux.view(bsz, seq_len, -1)
516
+ ce = torch.zeros(
517
+ bsz, self.n_routed_experts, device=hidden_states.device
518
+ )
519
+ ce.scatter_add_(
520
+ 1,
521
+ topk_idx_for_aux_loss,
522
+ torch.ones(bsz, seq_len * aux_topk, device=hidden_states.device),
523
+ ).div_(seq_len * aux_topk / self.n_routed_experts)
524
+ aux_loss = (ce * scores_for_seq_aux.mean(dim=1)).sum(
525
+ dim=1
526
+ ).mean() * self.alpha
527
+ else:
528
+ mask_ce = F.one_hot(
529
+ topk_idx_for_aux_loss.view(-1), num_classes=self.n_routed_experts
530
+ )
531
+ ce = mask_ce.float().mean(0)
532
+ Pi = scores_for_aux.mean(0)
533
+ fi = ce * self.n_routed_experts
534
+ aux_loss = (Pi * fi).sum() * self.alpha
535
+ else:
536
+ aux_loss = None
537
+ return topk_idx, topk_weight, aux_loss
538
+
539
+
540
+ class AddAuxiliaryLoss(torch.autograd.Function):
541
+ """
542
+ The trick function of adding auxiliary (aux) loss,
543
+ which includes the gradient of the aux loss during backpropagation.
544
+ """
545
+
546
+ @staticmethod
547
+ def forward(ctx, x, loss):
548
+ assert loss.numel() == 1
549
+ ctx.dtype = loss.dtype
550
+ ctx.required_aux_loss = loss.requires_grad
551
+ return x
552
+
553
+ @staticmethod
554
+ def backward(ctx, grad_output):
555
+ grad_loss = None
556
+ if ctx.required_aux_loss:
557
+ grad_loss = torch.ones(1, dtype=ctx.dtype, device=grad_output.device)
558
+ return grad_output, grad_loss
559
+
560
+
561
+ class DeepseekV2MoE(nn.Module):
562
+ """
563
+ A mixed expert module containing shared experts.
564
+ """
565
+
566
+ def __init__(self, config):
567
+ super().__init__()
568
+ self.config = config
569
+ self.num_experts_per_tok = config.num_experts_per_tok
570
+
571
+ if hasattr(config, "ep_size") and config.ep_size > 1:
572
+ assert config.ep_size == dist.get_world_size()
573
+ self.ep_size = config.ep_size
574
+ self.experts_per_rank = config.n_routed_experts // config.ep_size
575
+ self.ep_rank = dist.get_rank()
576
+ self.experts = nn.ModuleList(
577
+ [
578
+ (
579
+ DeepseekV2MLP(
580
+ config, intermediate_size=config.moe_intermediate_size
581
+ )
582
+ if i >= self.ep_rank * self.experts_per_rank
583
+ and i < (self.ep_rank + 1) * self.experts_per_rank
584
+ else None
585
+ )
586
+ for i in range(config.n_routed_experts)
587
+ ]
588
+ )
589
+ else:
590
+ self.ep_size = 1
591
+ self.experts_per_rank = config.n_routed_experts
592
+ self.ep_rank = 0
593
+ self.experts = nn.ModuleList(
594
+ [
595
+ DeepseekV2MLP(
596
+ config, intermediate_size=config.moe_intermediate_size
597
+ )
598
+ for i in range(config.n_routed_experts)
599
+ ]
600
+ )
601
+ self.gate = MoEGate(config)
602
+ if config.n_shared_experts is not None:
603
+ intermediate_size = config.moe_intermediate_size * config.n_shared_experts
604
+ self.shared_experts = DeepseekV2MLP(
605
+ config=config, intermediate_size=intermediate_size
606
+ )
607
+
608
+ def forward(self, hidden_states):
609
+ identity = hidden_states
610
+ orig_shape = hidden_states.shape
611
+ topk_idx, topk_weight, aux_loss = self.gate(hidden_states)
612
+ hidden_states = hidden_states.view(-1, hidden_states.shape[-1])
613
+ flat_topk_idx = topk_idx.view(-1)
614
+ if self.training:
615
+ hidden_states = hidden_states.repeat_interleave(
616
+ self.num_experts_per_tok, dim=0
617
+ )
618
+ y = torch.empty_like(hidden_states)
619
+ for i, expert in enumerate(self.experts):
620
+ y[flat_topk_idx == i] = expert(hidden_states[flat_topk_idx == i])
621
+ y = (y.view(*topk_weight.shape, -1) * topk_weight.unsqueeze(-1)).sum(dim=1)
622
+ y = y.to(hidden_states.dtype).view(*orig_shape)
623
+ y = AddAuxiliaryLoss.apply(y, aux_loss)
624
+ else:
625
+ y = self.moe_infer(hidden_states, topk_idx, topk_weight).view(*orig_shape)
626
+ if self.config.n_shared_experts is not None:
627
+ y = y + self.shared_experts(identity)
628
+ return y
629
+
630
+ @torch.no_grad()
631
+ def moe_infer(self, x, topk_ids, topk_weight):
632
+ cnts = topk_ids.new_zeros((topk_ids.shape[0], len(self.experts)))
633
+ cnts.scatter_(1, topk_ids, 1)
634
+ tokens_per_expert = cnts.sum(dim=0)
635
+ idxs = topk_ids.view(-1).argsort()
636
+ sorted_tokens = x[idxs // topk_ids.shape[1]]
637
+ sorted_tokens_shape = sorted_tokens.shape
638
+ if self.ep_size > 1:
639
+ tokens_per_ep_rank = tokens_per_expert.view(self.ep_size, -1).sum(dim=1)
640
+ tokens_per_expert_group = tokens_per_expert.new_empty(
641
+ tokens_per_expert.shape[0]
642
+ )
643
+ dist.all_to_all_single(tokens_per_expert_group, tokens_per_expert)
644
+ output_splits = (
645
+ tokens_per_expert_group.view(self.ep_size, -1)
646
+ .sum(1)
647
+ .cpu()
648
+ .numpy()
649
+ .tolist()
650
+ )
651
+ gathered_tokens = sorted_tokens.new_empty(
652
+ tokens_per_expert_group.sum(dim=0).cpu().item(), sorted_tokens.shape[1]
653
+ )
654
+ input_split_sizes = tokens_per_ep_rank.cpu().numpy().tolist()
655
+ dist.all_to_all(
656
+ list(gathered_tokens.split(output_splits)),
657
+ list(sorted_tokens.split(input_split_sizes)),
658
+ )
659
+ tokens_per_expert_post_gather = tokens_per_expert_group.view(
660
+ self.ep_size, self.experts_per_rank
661
+ ).sum(dim=0)
662
+ gatherd_idxs = np.zeros(shape=(gathered_tokens.shape[0],), dtype=np.int32)
663
+ s = 0
664
+ for i, k in enumerate(tokens_per_expert_group.cpu().numpy()):
665
+ gatherd_idxs[s : s + k] = i % self.experts_per_rank
666
+ s += k
667
+ gatherd_idxs = gatherd_idxs.argsort()
668
+ sorted_tokens = gathered_tokens[gatherd_idxs]
669
+ tokens_per_expert = tokens_per_expert_post_gather
670
+ tokens_per_expert = tokens_per_expert.cpu().numpy()
671
+
672
+ outputs = []
673
+ start_idx = 0
674
+ for i, num_tokens in enumerate(tokens_per_expert):
675
+ end_idx = start_idx + num_tokens
676
+ if num_tokens == 0:
677
+ continue
678
+ expert = self.experts[i + self.ep_rank * self.experts_per_rank]
679
+ tokens_for_this_expert = sorted_tokens[start_idx:end_idx]
680
+ expert_out = expert(tokens_for_this_expert)
681
+ outputs.append(expert_out)
682
+ start_idx = end_idx
683
+
684
+ outs = torch.cat(outputs, dim=0) if len(outputs) else sorted_tokens.new_empty(0)
685
+ if self.ep_size > 1:
686
+ new_x = torch.empty_like(outs)
687
+ new_x[gatherd_idxs] = outs
688
+ gathered_tokens = new_x.new_empty(*sorted_tokens_shape)
689
+ dist.all_to_all(
690
+ list(gathered_tokens.split(input_split_sizes)),
691
+ list(new_x.split(output_splits)),
692
+ )
693
+ outs = gathered_tokens
694
+
695
+ new_x = torch.empty_like(outs)
696
+ new_x[idxs] = outs
697
+ final_out = (
698
+ new_x.view(*topk_ids.shape, -1)
699
+ .type(topk_weight.dtype)
700
+ .mul_(topk_weight.unsqueeze(dim=-1))
701
+ .sum(dim=1)
702
+ .type(new_x.dtype)
703
+ )
704
+ return final_out
705
+
706
+
707
+ # Copied from transformers.models.llama.modeling_llama.repeat_kv
708
+ def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
709
+ """
710
+ This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch,
711
+ num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim)
712
+ """
713
+ batch, num_key_value_heads, slen, head_dim = hidden_states.shape
714
+ if n_rep == 1:
715
+ return hidden_states
716
+ hidden_states = hidden_states[:, :, None, :, :].expand(
717
+ batch, num_key_value_heads, n_rep, slen, head_dim
718
+ )
719
+ return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)
720
+
721
+
722
+ # Copied from transformers.models.llama.modeling_llama.LlamaAttention with Llama->DeepseekV2
723
+ class DeepseekV2Attention(nn.Module):
724
+ """Multi-headed attention from 'Attention Is All You Need' paper"""
725
+
726
+ def __init__(self, config: DeepseekV2Config, layer_idx: Optional[int] = None):
727
+ super().__init__()
728
+ self.config = config
729
+ self.layer_idx = layer_idx
730
+ if layer_idx is None:
731
+ logger.warning_once(
732
+ f"Instantiating {self.__class__.__name__} without passing `layer_idx` is not recommended and will "
733
+ "to errors during the forward call, if caching is used. Please make sure to provide a `layer_idx` "
734
+ "when creating this class."
735
+ )
736
+
737
+ self.attention_dropout = config.attention_dropout
738
+ self.hidden_size = config.hidden_size
739
+ self.num_heads = config.num_attention_heads
740
+
741
+ self.max_position_embeddings = config.max_position_embeddings
742
+ self.rope_theta = config.rope_theta
743
+ self.q_lora_rank = config.q_lora_rank
744
+ self.qk_rope_head_dim = config.qk_rope_head_dim
745
+ self.kv_lora_rank = config.kv_lora_rank
746
+ self.v_head_dim = config.v_head_dim
747
+ self.qk_nope_head_dim = config.qk_nope_head_dim
748
+ self.q_head_dim = config.qk_nope_head_dim + config.qk_rope_head_dim
749
+
750
+ self.is_causal = True
751
+
752
+ if self.q_lora_rank is None:
753
+ self.q_proj = nn.Linear(
754
+ self.hidden_size, self.num_heads * self.q_head_dim, bias=False
755
+ )
756
+ else:
757
+ self.q_a_proj = nn.Linear(
758
+ self.hidden_size, config.q_lora_rank, bias=config.attention_bias
759
+ )
760
+ self.q_a_layernorm = DeepseekV2RMSNorm(config.q_lora_rank)
761
+ self.q_b_proj = nn.Linear(
762
+ config.q_lora_rank, self.num_heads * self.q_head_dim, bias=False
763
+ )
764
+ # config.kv_lora_rank + config.qk_rope_head_dim,
765
+ self.kv_a_proj_with_mqa = nn.Linear(
766
+ self.hidden_size,
767
+ config.kv_lora_rank + config.qk_rope_head_dim,
768
+ bias=config.attention_bias,
769
+ )
770
+ self.kv_a_layernorm = DeepseekV2RMSNorm(config.kv_lora_rank)
771
+ self.kv_b_proj = nn.Linear(
772
+ config.kv_lora_rank,
773
+ self.num_heads
774
+ * (self.q_head_dim - self.qk_rope_head_dim + self.v_head_dim),
775
+ bias=False,
776
+ )
777
+
778
+ self.o_proj = nn.Linear(
779
+ self.num_heads * self.v_head_dim,
780
+ self.hidden_size,
781
+ bias=config.attention_bias,
782
+ )
783
+ self._init_rope()
784
+
785
+ self.softmax_scale = self.q_head_dim ** (-0.5)
786
+ if self.config.rope_scaling is not None:
787
+ mscale_all_dim = self.config.rope_scaling.get("mscale_all_dim", 0)
788
+ scaling_factor = self.config.rope_scaling["factor"]
789
+ if mscale_all_dim:
790
+ mscale = yarn_get_mscale(scaling_factor, mscale_all_dim)
791
+ self.softmax_scale = self.softmax_scale * mscale * mscale
792
+
793
+ def _init_rope(self):
794
+ if self.config.rope_scaling is None:
795
+ self.rotary_emb = DeepseekV2RotaryEmbedding(
796
+ self.qk_rope_head_dim,
797
+ max_position_embeddings=self.max_position_embeddings,
798
+ base=self.rope_theta,
799
+ )
800
+ # self.rotary_emb = DeepseekV2LinearScalingRotaryEmbedding(
801
+ # self.qk_rope_head_dim,
802
+ # max_position_embeddings=self.max_position_embeddings,
803
+ # scaling_factor=scaling_factor,
804
+ # base=self.rope_theta,
805
+ # )
806
+ else:
807
+ scaling_type = self.config.rope_scaling["type"]
808
+ scaling_factor = self.config.rope_scaling["factor"]
809
+ if scaling_type == "linear":
810
+ self.rotary_emb = DeepseekV2LinearScalingRotaryEmbedding(
811
+ self.qk_rope_head_dim,
812
+ max_position_embeddings=self.max_position_embeddings,
813
+ scaling_factor=scaling_factor,
814
+ base=self.rope_theta,
815
+ )
816
+ elif scaling_type == "dynamic":
817
+ self.rotary_emb = DeepseekV2DynamicNTKScalingRotaryEmbedding(
818
+ self.qk_rope_head_dim,
819
+ max_position_embeddings=self.max_position_embeddings,
820
+ scaling_factor=scaling_factor,
821
+ base=self.rope_theta,
822
+ )
823
+ elif scaling_type == "yarn":
824
+ kwargs = {
825
+ key: self.config.rope_scaling[key]
826
+ for key in [
827
+ "original_max_position_embeddings",
828
+ "beta_fast",
829
+ "beta_slow",
830
+ "mscale",
831
+ "mscale_all_dim",
832
+ ]
833
+ if key in self.config.rope_scaling
834
+ }
835
+ self.rotary_emb = DeepseekV2YarnRotaryEmbedding(
836
+ self.qk_rope_head_dim,
837
+ max_position_embeddings=self.max_position_embeddings,
838
+ scaling_factor=scaling_factor,
839
+ base=self.rope_theta,
840
+ **kwargs,
841
+ )
842
+ else:
843
+ raise ValueError(f"Unknown RoPE scaling type {scaling_type}")
844
+
845
+ def _shape(self, tensor: torch.Tensor, seq_len: int, bsz: int):
846
+ return (
847
+ tensor.view(bsz, seq_len, self.num_heads, self.v_head_dim)
848
+ .transpose(1, 2)
849
+ .contiguous()
850
+ )
851
+
852
+ def forward(
853
+ self,
854
+ hidden_states: torch.Tensor,
855
+ attention_mask: Optional[torch.Tensor] = None,
856
+ position_ids: Optional[torch.LongTensor] = None,
857
+ past_key_value: Optional[Cache] = None,
858
+ output_attentions: bool = False,
859
+ use_cache: bool = False,
860
+ **kwargs,
861
+ ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]:
862
+ if "padding_mask" in kwargs:
863
+ warnings.warn(
864
+ "Passing `padding_mask` is deprecated and will be removed in v4.37. Please make sure use `attention_mask` instead.`"
865
+ )
866
+ bsz, q_len, _ = hidden_states.size()
867
+
868
+ if self.q_lora_rank is None:
869
+ q = self.q_proj(hidden_states)
870
+ else:
871
+ q = self.q_b_proj(self.q_a_layernorm(self.q_a_proj(hidden_states)))
872
+ q = q.view(bsz, q_len, self.num_heads, self.q_head_dim).transpose(1, 2)
873
+
874
+
875
+ q_nope, q_pe = torch.split(
876
+ q, [self.qk_nope_head_dim, self.qk_rope_head_dim], dim=-1
877
+ )
878
+
879
+ compressed_kv = self.kv_a_proj_with_mqa(hidden_states)
880
+ compressed_kv, k_pe = torch.split(
881
+ compressed_kv, [self.kv_lora_rank, self.qk_rope_head_dim], dim=-1
882
+ )
883
+ compressed_kv = self.kv_a_layernorm(compressed_kv)
884
+ k_pe = k_pe.view(bsz, q_len, 1, self.qk_rope_head_dim).transpose(1, 2)
885
+
886
+ kv_seq_len = k_pe.shape[-2]
887
+ if past_key_value is not None:
888
+ if self.layer_idx is None:
889
+ raise ValueError(
890
+ f"The cache structure has changed since version v4.36. If you are using {self.__class__.__name__} "
891
+ "for auto-regressive decoding with k/v caching, please make sure to initialize the attention class "
892
+ "with a layer index."
893
+ )
894
+ kv_seq_len += past_key_value.get_seq_length(self.layer_idx)
895
+
896
+ cos, sin = self.rotary_emb(q_pe, seq_len=kv_seq_len)
897
+ q_pe, k_pe = apply_rotary_pos_emb(q_pe, k_pe, cos, sin, position_ids)
898
+
899
+ if past_key_value is not None:
900
+ cache_kwargs = {"sin": sin, "cos": cos} # Specific to RoPE models
901
+ compressed_kv = compressed_kv.unsqueeze(1)
902
+ k_pe, compressed_kv = past_key_value.update(k_pe, compressed_kv, self.layer_idx, cache_kwargs)
903
+ compressed_kv = compressed_kv.squeeze(1)
904
+
905
+ kv_b_proj = self.kv_b_proj.weight.view(self.num_heads, -1, self.kv_lora_rank)
906
+ q_absorb = kv_b_proj[:, :self.qk_nope_head_dim, :]
907
+ out_absorb = kv_b_proj[:, self.qk_nope_head_dim:, :]
908
+
909
+ q_nope = torch.matmul(q_nope, q_absorb)
910
+ attn_weights = (torch.matmul(q_pe, k_pe.mT) +
911
+ torch.matmul(q_nope, compressed_kv.unsqueeze(-3).mT)) * self.softmax_scale
912
+ if attn_weights.size() != (bsz, self.num_heads, q_len, kv_seq_len):
913
+ raise ValueError(
914
+ f"Attention weights should be of size {(bsz, self.num_heads, q_len, kv_seq_len)}, but is"
915
+ f" {attn_weights.size()}"
916
+ )
917
+ assert attention_mask is not None
918
+ if attention_mask is not None:
919
+ if attention_mask.size() != (bsz, 1, q_len, kv_seq_len):
920
+ raise ValueError(
921
+ f"Attention mask should be of size {(bsz, 1, q_len, kv_seq_len)}, but is {attention_mask.size()}"
922
+ )
923
+ attn_weights = attn_weights + attention_mask
924
+
925
+ # upcast attention to fp32
926
+ attn_weights = nn.functional.softmax(
927
+ attn_weights, dim=-1, dtype=torch.float32
928
+ ).to(q_pe.dtype)
929
+ attn_weights = nn.functional.dropout(
930
+ attn_weights, p=self.attention_dropout, training=self.training
931
+ )
932
+ attn_output = torch.einsum('bhql,blc->bhqc', attn_weights, compressed_kv)
933
+
934
+ attn_output = torch.matmul(attn_output, out_absorb.mT)
935
+
936
+ if attn_output.size() != (bsz, self.num_heads, q_len, self.v_head_dim):
937
+ raise ValueError(
938
+ f"`attn_output` should be of size {(bsz, self.num_heads, q_len, self.v_head_dim)}, but is"
939
+ f" {attn_output.size()}"
940
+ )
941
+
942
+ attn_output = attn_output.transpose(1, 2).contiguous()
943
+
944
+ attn_output = attn_output.reshape(bsz, q_len, self.num_heads * self.v_head_dim)
945
+
946
+ attn_output = self.o_proj(attn_output)
947
+
948
+ if not output_attentions:
949
+ attn_weights = None
950
+
951
+ return attn_output, attn_weights, past_key_value
952
+
953
+
954
+ # Copied from transformers.models.llama.modeling_llama.LlamaFlashAttention2 with Llama->DeepseekV2
955
+ class DeepseekV2FlashAttention2(DeepseekV2Attention):
956
+ """
957
+ DeepseekV2 flash attention module. This module inherits from `DeepseekV2Attention` as the weights of the module stays
958
+ untouched. The only required change would be on the forward pass where it needs to correctly call the public API of
959
+ flash attention and deal with padding tokens in case the input contains any of them.
960
+ """
961
+
962
+ def __init__(self, *args, **kwargs):
963
+ super().__init__(*args, **kwargs)
964
+
965
+ # TODO: Should be removed once Flash Attention for RoCm is bumped to 2.1.
966
+ # flash_attn<2.1 generates top-left aligned causal mask, while what is needed here is bottom-right alignement, that was made default for flash_attn>=2.1. This attribute is used to handle this difference. Reference: https://github.com/Dao-AILab/flash-attention/releases/tag/v2.1.0.
967
+ # Beware that with flash_attn<2.1, using q_seqlen != k_seqlen (except for the case q_seqlen == 1) produces a wrong mask (top-left).
968
+ self._flash_attn_uses_top_left_mask = not is_flash_attn_greater_or_equal_2_10()
969
+
970
+ def forward(
971
+ self,
972
+ hidden_states: torch.Tensor,
973
+ attention_mask: Optional[torch.LongTensor] = None,
974
+ position_ids: Optional[torch.LongTensor] = None,
975
+ past_key_value: Optional[Cache] = None,
976
+ output_attentions: bool = False,
977
+ use_cache: bool = False,
978
+ **kwargs,
979
+ ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]:
980
+ # DeepseekV2FlashAttention2 attention does not support output_attentions
981
+ if "padding_mask" in kwargs:
982
+ warnings.warn(
983
+ "Passing `padding_mask` is deprecated and will be removed in v4.37. Please make sure use `attention_mask` instead.`"
984
+ )
985
+
986
+ # overwrite attention_mask with padding_mask
987
+ attention_mask = kwargs.pop("padding_mask")
988
+
989
+ output_attentions = False
990
+
991
+ bsz, q_len, _ = hidden_states.size()
992
+
993
+ if self.q_lora_rank is None:
994
+ q = self.q_proj(hidden_states)
995
+ else:
996
+ q = self.q_b_proj(self.q_a_layernorm(self.q_a_proj(hidden_states)))
997
+ q = q.view(bsz, q_len, self.num_heads, self.q_head_dim).transpose(1, 2)
998
+ q_nope, q_pe = torch.split(
999
+ q, [self.qk_nope_head_dim, self.qk_rope_head_dim], dim=-1
1000
+ )
1001
+
1002
+ # Flash attention requires the input to have the shape
1003
+ # batch_size x seq_length x head_dim x hidden_dim
1004
+ # therefore we just need to keep the original shape
1005
+ compressed_kv = self.kv_a_proj_with_mqa(hidden_states)
1006
+ compressed_kv, k_pe = torch.split(
1007
+ compressed_kv, [self.kv_lora_rank, self.qk_rope_head_dim], dim=-1
1008
+ )
1009
+ k_pe = k_pe.view(bsz, q_len, 1, self.qk_rope_head_dim).transpose(1, 2)
1010
+ kv = (
1011
+ self.kv_b_proj(self.kv_a_layernorm(compressed_kv))
1012
+ .view(bsz, q_len, self.num_heads, self.qk_nope_head_dim + self.v_head_dim)
1013
+ .transpose(1, 2)
1014
+ )
1015
+
1016
+ k_nope, value_states = torch.split(
1017
+ kv, [self.qk_nope_head_dim, self.v_head_dim], dim=-1
1018
+ )
1019
+ kv_seq_len = value_states.shape[-2]
1020
+
1021
+ kv_seq_len = value_states.shape[-2]
1022
+ if past_key_value is not None:
1023
+ kv_seq_len += past_key_value.get_seq_length(self.layer_idx)
1024
+
1025
+ cos, sin = self.rotary_emb(value_states, seq_len=kv_seq_len)
1026
+ q_pe, k_pe = apply_rotary_pos_emb(q_pe, k_pe, cos, sin, position_ids)
1027
+
1028
+ query_states = k_pe.new_empty(bsz, self.num_heads, q_len, self.q_head_dim)
1029
+ query_states[:, :, :, : self.qk_nope_head_dim] = q_nope
1030
+ query_states[:, :, :, self.qk_nope_head_dim :] = q_pe
1031
+
1032
+ key_states = k_pe.new_empty(bsz, self.num_heads, q_len, self.q_head_dim)
1033
+ key_states[:, :, :, : self.qk_nope_head_dim] = k_nope
1034
+ key_states[:, :, :, self.qk_nope_head_dim :] = k_pe
1035
+
1036
+ if self.q_head_dim != self.v_head_dim:
1037
+ value_states = F.pad(value_states, [0, self.q_head_dim - self.v_head_dim])
1038
+
1039
+ # TODO: support compressed_kv for kv_cache (instead of key_states, value_states) in flash_attention version
1040
+ if past_key_value is not None:
1041
+ cache_kwargs = {"sin": sin, "cos": cos} # Specific to RoPE models
1042
+ key_states, value_states = past_key_value.update(
1043
+ key_states, value_states, self.layer_idx, cache_kwargs
1044
+ )
1045
+
1046
+ # TODO: These transpose are quite inefficient but Flash Attention requires the layout [batch_size, sequence_length, num_heads, head_dim]. We would need to refactor the KV cache
1047
+ # to be able to avoid many of these transpose/reshape/view.
1048
+ query_states = query_states.transpose(1, 2)
1049
+ key_states = key_states.transpose(1, 2)
1050
+ value_states = value_states.transpose(1, 2)
1051
+
1052
+ dropout_rate = self.attention_dropout if self.training else 0.0
1053
+
1054
+ # In PEFT, usually we cast the layer norms in float32 for training stability reasons
1055
+ # therefore the input hidden states gets silently casted in float32. Hence, we need
1056
+ # cast them back in the correct dtype just to be sure everything works as expected.
1057
+ # This might slowdown training & inference so it is recommended to not cast the LayerNorms
1058
+ # in fp32. (DeepseekV2RMSNorm handles it correctly)
1059
+
1060
+ input_dtype = query_states.dtype
1061
+ if input_dtype == torch.float32:
1062
+ # Handle the case where the model is quantized
1063
+ if hasattr(self.config, "_pre_quantization_dtype"):
1064
+ target_dtype = self.config._pre_quantization_dtype
1065
+ elif torch.is_autocast_enabled():
1066
+ target_dtype = torch.get_autocast_gpu_dtype()
1067
+ else:
1068
+ target_dtype = (
1069
+ self.q_proj.weight.dtype
1070
+ if self.q_lora_rank is None
1071
+ else self.q_a_proj.weight.dtype
1072
+ )
1073
+
1074
+ logger.warning_once(
1075
+ f"The input hidden states seems to be silently casted in float32, this might be related to"
1076
+ f" the fact you have upcasted embedding or layer norm layers in float32. We will cast back the input in"
1077
+ f" {target_dtype}."
1078
+ )
1079
+
1080
+ query_states = query_states.to(target_dtype)
1081
+ key_states = key_states.to(target_dtype)
1082
+ value_states = value_states.to(target_dtype)
1083
+
1084
+ attn_output = self._flash_attention_forward(
1085
+ query_states,
1086
+ key_states,
1087
+ value_states,
1088
+ attention_mask,
1089
+ q_len,
1090
+ dropout=dropout_rate,
1091
+ softmax_scale=self.softmax_scale,
1092
+ )
1093
+ if self.q_head_dim != self.v_head_dim:
1094
+ attn_output = attn_output[:, :, :, : self.v_head_dim]
1095
+
1096
+ attn_output = attn_output.reshape(
1097
+ bsz, q_len, self.num_heads * self.v_head_dim
1098
+ ).contiguous()
1099
+ attn_output = self.o_proj(attn_output)
1100
+
1101
+ if not output_attentions:
1102
+ attn_weights = None
1103
+
1104
+ return attn_output, attn_weights, past_key_value
1105
+
1106
+ def _flash_attention_forward(
1107
+ self,
1108
+ query_states,
1109
+ key_states,
1110
+ value_states,
1111
+ attention_mask,
1112
+ query_length,
1113
+ dropout=0.0,
1114
+ softmax_scale=None,
1115
+ ):
1116
+ """
1117
+ Calls the forward method of Flash Attention - if the input hidden states contain at least one padding token
1118
+ first unpad the input, then computes the attention scores and pad the final attention scores.
1119
+
1120
+ Args:
1121
+ query_states (`torch.Tensor`):
1122
+ Input query states to be passed to Flash Attention API
1123
+ key_states (`torch.Tensor`):
1124
+ Input key states to be passed to Flash Attention API
1125
+ value_states (`torch.Tensor`):
1126
+ Input value states to be passed to Flash Attention API
1127
+ attention_mask (`torch.Tensor`):
1128
+ The padding mask - corresponds to a tensor of size `(batch_size, seq_len)` where 0 stands for the
1129
+ position of padding tokens and 1 for the position of non-padding tokens.
1130
+ dropout (`int`, *optional*):
1131
+ Attention dropout
1132
+ softmax_scale (`float`, *optional*):
1133
+ The scaling of QK^T before applying softmax. Default to 1 / sqrt(head_dim)
1134
+ """
1135
+ if not self._flash_attn_uses_top_left_mask:
1136
+ causal = self.is_causal
1137
+ else:
1138
+ # TODO: Remove the `query_length != 1` check once Flash Attention for RoCm is bumped to 2.1. For details, please see the comment in DeepseekV2FlashAttention2 __init__.
1139
+ causal = self.is_causal and query_length != 1
1140
+
1141
+ # Contains at least one padding token in the sequence
1142
+ if attention_mask is not None:
1143
+ batch_size = query_states.shape[0]
1144
+ (
1145
+ query_states,
1146
+ key_states,
1147
+ value_states,
1148
+ indices_q,
1149
+ cu_seq_lens,
1150
+ max_seq_lens,
1151
+ ) = self._upad_input(
1152
+ query_states, key_states, value_states, attention_mask, query_length
1153
+ )
1154
+
1155
+ cu_seqlens_q, cu_seqlens_k = cu_seq_lens
1156
+ max_seqlen_in_batch_q, max_seqlen_in_batch_k = max_seq_lens
1157
+
1158
+ attn_output_unpad = flash_attn_varlen_func(
1159
+ query_states,
1160
+ key_states,
1161
+ value_states,
1162
+ cu_seqlens_q=cu_seqlens_q,
1163
+ cu_seqlens_k=cu_seqlens_k,
1164
+ max_seqlen_q=max_seqlen_in_batch_q,
1165
+ max_seqlen_k=max_seqlen_in_batch_k,
1166
+ dropout_p=dropout,
1167
+ softmax_scale=softmax_scale,
1168
+ causal=causal,
1169
+ )
1170
+
1171
+ attn_output = pad_input(
1172
+ attn_output_unpad, indices_q, batch_size, query_length
1173
+ )
1174
+ else:
1175
+ attn_output = flash_attn_func(
1176
+ query_states,
1177
+ key_states,
1178
+ value_states,
1179
+ dropout,
1180
+ softmax_scale=softmax_scale,
1181
+ causal=causal,
1182
+ )
1183
+
1184
+ return attn_output
1185
+
1186
+ def _upad_input(
1187
+ self, query_layer, key_layer, value_layer, attention_mask, query_length
1188
+ ):
1189
+ indices_k, cu_seqlens_k, max_seqlen_in_batch_k = _get_unpad_data(attention_mask)
1190
+ batch_size, kv_seq_len, num_key_value_heads, head_dim = key_layer.shape
1191
+
1192
+ key_layer = index_first_axis(
1193
+ key_layer.reshape(batch_size * kv_seq_len, num_key_value_heads, head_dim),
1194
+ indices_k,
1195
+ )
1196
+ value_layer = index_first_axis(
1197
+ value_layer.reshape(batch_size * kv_seq_len, num_key_value_heads, head_dim),
1198
+ indices_k,
1199
+ )
1200
+ if query_length == kv_seq_len:
1201
+ query_layer = index_first_axis(
1202
+ query_layer.reshape(batch_size * kv_seq_len, self.num_heads, head_dim),
1203
+ indices_k,
1204
+ )
1205
+ cu_seqlens_q = cu_seqlens_k
1206
+ max_seqlen_in_batch_q = max_seqlen_in_batch_k
1207
+ indices_q = indices_k
1208
+ elif query_length == 1:
1209
+ max_seqlen_in_batch_q = 1
1210
+ cu_seqlens_q = torch.arange(
1211
+ batch_size + 1, dtype=torch.int32, device=query_layer.device
1212
+ ) # There is a memcpy here, that is very bad.
1213
+ indices_q = cu_seqlens_q[:-1]
1214
+ query_layer = query_layer.squeeze(1)
1215
+ else:
1216
+ # The -q_len: slice assumes left padding.
1217
+ attention_mask = attention_mask[:, -query_length:]
1218
+ query_layer, indices_q, cu_seqlens_q, max_seqlen_in_batch_q = unpad_input(
1219
+ query_layer, attention_mask
1220
+ )
1221
+
1222
+ return (
1223
+ query_layer,
1224
+ key_layer,
1225
+ value_layer,
1226
+ indices_q,
1227
+ (cu_seqlens_q, cu_seqlens_k),
1228
+ (max_seqlen_in_batch_q, max_seqlen_in_batch_k),
1229
+ )
1230
+
1231
+
1232
+ class SlidingWindowLlamaAttention(LlamaAttention):
1233
+ """LlamaAttention with sliding window KV cache using a ring buffer during decode."""
1234
+
1235
+ def __init__(self, config, layer_idx):
1236
+ super().__init__(config, layer_idx)
1237
+ # New transformers moved rotary_emb to model level; create our own
1238
+ if not hasattr(self, 'rotary_emb'):
1239
+ from transformers.models.llama.modeling_llama import LlamaRotaryEmbedding
1240
+ self.rotary_emb = LlamaRotaryEmbedding(config=config)
1241
+ # Save sliding_window separately so we can disable it in config to prevent
1242
+ # DynamicCache from truncating prefill tokens
1243
+ self._sliding_window = getattr(config, 'sliding_window', None)
1244
+
1245
+ def forward(self, *args, **kwargs):
1246
+ import math
1247
+
1248
+ # Compatibility: new DynamicCache uses .layers[i].keys/.values instead of .key_cache[i]/.value_cache[i]
1249
+ def _get_kcache(cache, layer_idx):
1250
+ if hasattr(cache, 'key_cache'):
1251
+ return cache.key_cache[layer_idx]
1252
+ return cache.layers[layer_idx].keys
1253
+
1254
+ def _get_vcache(cache, layer_idx):
1255
+ if hasattr(cache, 'value_cache'):
1256
+ return cache.value_cache[layer_idx]
1257
+ return cache.layers[layer_idx].values
1258
+
1259
+ # Extract args
1260
+ def _get(name, idx, default=None):
1261
+ if name in kwargs:
1262
+ return kwargs[name]
1263
+ if len(args) > idx:
1264
+ return args[idx]
1265
+ return default
1266
+
1267
+ hidden_states = _get('hidden_states', 0)
1268
+ attention_mask = _get('attention_mask', 1)
1269
+ position_ids = _get('position_ids', 2)
1270
+ past_kv = _get('past_key_value', 3)
1271
+ if past_kv is None:
1272
+ past_kv = kwargs.get('past_key_values', None)
1273
+ output_attentions = _get('output_attentions', 4, False)
1274
+
1275
+ # Dimensions from config (new transformers removed self.num_heads)
1276
+ num_heads = self.config.num_attention_heads
1277
+ num_kv_heads = self.config.num_key_value_heads
1278
+ head_dim = self.head_dim
1279
+ num_kv_groups = self.num_key_value_groups
1280
+
1281
+ bsz, q_len, _ = hidden_states.size()
1282
+ W = getattr(self.config, '_ring_window', None) # Read from config (set before generate)
1283
+
1284
+ # --- Helper: standard QKV attention ---
1285
+ def _attn_forward(use_cache_update=True):
1286
+ query_states = self.q_proj(hidden_states).view(bsz, q_len, num_heads, head_dim).transpose(1, 2)
1287
+ key_states = self.k_proj(hidden_states).view(bsz, q_len, num_kv_heads, head_dim).transpose(1, 2)
1288
+ value_states = self.v_proj(hidden_states).view(bsz, q_len, num_kv_heads, head_dim).transpose(1, 2)
1289
+
1290
+ cos, sin = self.rotary_emb(value_states, position_ids)
1291
+ query_states, key_states = _llama_apply_rotary_pos_emb(query_states, key_states, cos, sin)
1292
+
1293
+ if past_kv is not None and use_cache_update:
1294
+ key_states, value_states = past_kv.update(key_states, value_states, self.layer_idx)
1295
+
1296
+ k = _llama_repeat_kv(key_states, num_kv_groups)
1297
+ v = _llama_repeat_kv(value_states, num_kv_groups)
1298
+
1299
+ attn_weights = torch.matmul(query_states, k.transpose(2, 3)) / math.sqrt(head_dim)
1300
+ if attention_mask is not None:
1301
+ causal_mask = attention_mask[:, :, :, :k.shape[-2]]
1302
+ attn_weights = attn_weights + causal_mask
1303
+ attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query_states.dtype)
1304
+ attn_weights = nn.functional.dropout(attn_weights, p=self.attention_dropout, training=self.training)
1305
+ attn_output = torch.matmul(attn_weights, v)
1306
+ attn_output = attn_output.transpose(1, 2).contiguous().reshape(bsz, q_len, -1)
1307
+ attn_output = self.o_proj(attn_output)
1308
+ return attn_output, None, past_kv
1309
+
1310
+ # Prefill or no sliding window
1311
+ # True prefill: W disabled, no cache, or first forward (prefill_length not yet recorded)
1312
+ _is_true_prefill = (W is None or past_kv is None or
1313
+ (q_len > 1 and (not hasattr(past_kv, '_prefill_length') or
1314
+ self.layer_idx not in past_kv._prefill_length)))
1315
+ if _is_true_prefill:
1316
+ result = _attn_forward()
1317
+ if W is not None and past_kv is not None and q_len > 1:
1318
+ # Only record prefill_length the FIRST time (don't overwrite on subsequent q_len>1 calls)
1319
+ if not hasattr(past_kv, '_prefill_length'):
1320
+ past_kv._prefill_length = {}
1321
+ if self.layer_idx not in past_kv._prefill_length:
1322
+ past_kv._prefill_length[self.layer_idx] = _get_kcache(past_kv, self.layer_idx).shape[-2]
1323
+ return result
1324
+
1325
+ # Decode path: first decode step -> record prefill_length (only once!)
1326
+ if not hasattr(past_kv, '_prefill_length') or self.layer_idx not in past_kv._prefill_length:
1327
+ if not hasattr(past_kv, '_prefill_length'):
1328
+ past_kv._prefill_length = {}
1329
+ past_kv._prefill_length[self.layer_idx] = _get_kcache(past_kv, self.layer_idx).shape[-2]
1330
+
1331
+ prefill_len = past_kv._prefill_length[self.layer_idx]
1332
+ cur_len = _get_kcache(past_kv, self.layer_idx).shape[-2]
1333
+
1334
+ # Warmup: cat-append until ring region is full
1335
+ if cur_len < prefill_len + W:
1336
+ result = _attn_forward()
1337
+ new_len = _get_kcache(past_kv, self.layer_idx).shape[-2]
1338
+ if new_len >= prefill_len + W:
1339
+ if not hasattr(past_kv, '_ring_pos'):
1340
+ past_kv._ring_pos = {}
1341
+ past_kv._ring_pos[self.layer_idx] = 0
1342
+ return result
1343
+
1344
+ # Steady state: ring in-place overwrite
1345
+ if not hasattr(past_kv, '_ring_pos') or self.layer_idx not in past_kv._ring_pos:
1346
+ past_kv._ring_pos = getattr(past_kv, '_ring_pos', {}) or {}
1347
+ past_kv._ring_pos[self.layer_idx] = 0
1348
+
1349
+ # Ring decode: overwrite ring slots, then attention over full cache
1350
+ ring_pos = past_kv._ring_pos[self.layer_idx]
1351
+ kcache = _get_kcache(past_kv, self.layer_idx)
1352
+ vcache = _get_vcache(past_kv, self.layer_idx)
1353
+
1354
+ # Compute new K, V and apply RoPE, then overwrite ring slots
1355
+ query_states = self.q_proj(hidden_states).view(bsz, q_len, num_heads, head_dim).transpose(1, 2)
1356
+ key_states = self.k_proj(hidden_states).view(bsz, q_len, num_kv_heads, head_dim).transpose(1, 2)
1357
+ value_states = self.v_proj(hidden_states).view(bsz, q_len, num_kv_heads, head_dim).transpose(1, 2)
1358
+ cos, sin = self.rotary_emb(value_states, position_ids)
1359
+ query_states, key_states = _llama_apply_rotary_pos_emb(query_states, key_states, cos, sin)
1360
+
1361
+ # Overwrite ring slots in-place
1362
+ for t in range(q_len):
1363
+ slot = prefill_len + ring_pos
1364
+ kcache[:, :, slot:slot + 1, :] = key_states[:, :, t:t + 1, :]
1365
+ vcache[:, :, slot:slot + 1, :] = value_states[:, :, t:t + 1, :]
1366
+ ring_pos = (ring_pos + 1) % W
1367
+ past_kv._ring_pos[self.layer_idx] = ring_pos
1368
+
1369
+ # Attention over full cache (no causal mask needed for decode q_len=1)
1370
+ k = _llama_repeat_kv(kcache, num_kv_groups)
1371
+ v = _llama_repeat_kv(vcache, num_kv_groups)
1372
+ attn_weights = torch.matmul(query_states, k.transpose(2, 3)) / math.sqrt(head_dim)
1373
+ attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query_states.dtype)
1374
+ attn_output = torch.matmul(attn_weights, v)
1375
+ attn_output = attn_output.transpose(1, 2).contiguous().reshape(bsz, q_len, -1)
1376
+ attn_output = self.o_proj(attn_output)
1377
+ return attn_output, None, past_kv
1378
+
1379
+
1380
+ ATTENTION_CLASSES = {
1381
+ "eager": DeepseekV2Attention,
1382
+ "flash_attention_2": DeepseekV2FlashAttention2,
1383
+
1384
+ "mla_eager": DeepseekV2Attention,
1385
+ "mla_flash_attention_2": DeepseekV2FlashAttention2,
1386
+
1387
+ "mha_eager": SlidingWindowLlamaAttention,
1388
+ # "mha_flash_attention_2": LlamaFlashAttention2
1389
+ }
1390
+
1391
+
1392
+ class DeepseekV2DecoderLayer(nn.Module):
1393
+ def __init__(self, config: DeepseekV2Config, layer_idx: int):
1394
+ super().__init__()
1395
+ self.hidden_size = config.hidden_size
1396
+
1397
+
1398
+ if config.use_mla:
1399
+ attn_implementation = "mla_" + config._attn_implementation
1400
+ else:
1401
+ attn_implementation = "mha_" + config._attn_implementation
1402
+
1403
+ self.self_attn = ATTENTION_CLASSES[attn_implementation](
1404
+ config=config, layer_idx=layer_idx
1405
+ )
1406
+
1407
+ self.mlp = (
1408
+ DeepseekV2MoE(config)
1409
+ if (
1410
+ config.n_routed_experts is not None
1411
+ and layer_idx >= config.first_k_dense_replace
1412
+ and layer_idx % config.moe_layer_freq == 0
1413
+ )
1414
+ else DeepseekV2MLP(config)
1415
+ )
1416
+ self.input_layernorm = DeepseekV2RMSNorm(
1417
+ config.hidden_size, eps=config.rms_norm_eps
1418
+ )
1419
+ self.post_attention_layernorm = DeepseekV2RMSNorm(
1420
+ config.hidden_size, eps=config.rms_norm_eps
1421
+ )
1422
+
1423
+ def forward(
1424
+ self,
1425
+ hidden_states: torch.Tensor,
1426
+ attention_mask: Optional[torch.Tensor] = None,
1427
+ position_ids: Optional[torch.LongTensor] = None,
1428
+ past_key_value: Optional[Tuple[torch.Tensor]] = None,
1429
+ output_attentions: Optional[bool] = False,
1430
+ use_cache: Optional[bool] = False,
1431
+ **kwargs,
1432
+ ) -> Tuple[
1433
+ torch.FloatTensor, Optional[Tuple[torch.FloatTensor, torch.FloatTensor]]
1434
+ ]:
1435
+ """
1436
+ Args:
1437
+ hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)`
1438
+ attention_mask (`torch.FloatTensor`, *optional*):
1439
+ attention mask of size `(batch_size, sequence_length)` if flash attention is used or `(batch_size, 1,
1440
+ query_sequence_length, key_sequence_length)` if default attention is used.
1441
+ output_attentions (`bool`, *optional*):
1442
+ Whether or not to return the attentions tensors of all attention layers. See `attentions` under
1443
+ returned tensors for more detail.
1444
+ use_cache (`bool`, *optional*):
1445
+ If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding
1446
+ (see `past_key_values`).
1447
+ past_key_value (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states
1448
+ """
1449
+ if "padding_mask" in kwargs:
1450
+ warnings.warn(
1451
+ "Passing `padding_mask` is deprecated and will be removed in v4.37. Please make sure use `attention_mask` instead.`"
1452
+ )
1453
+ residual = hidden_states
1454
+
1455
+ hidden_states = self.input_layernorm(hidden_states)
1456
+
1457
+ # Self Attention
1458
+ hidden_states, self_attn_weights, present_key_value = self.self_attn(
1459
+ hidden_states=hidden_states,
1460
+ attention_mask=attention_mask,
1461
+ position_ids=position_ids,
1462
+ past_key_value=past_key_value,
1463
+ output_attentions=output_attentions,
1464
+ use_cache=use_cache,
1465
+ **kwargs,
1466
+ )
1467
+ hidden_states = residual + hidden_states
1468
+
1469
+ # Fully Connected
1470
+ residual = hidden_states
1471
+ hidden_states = self.post_attention_layernorm(hidden_states)
1472
+ hidden_states = self.mlp(hidden_states)
1473
+ hidden_states = residual + hidden_states
1474
+
1475
+ outputs = (hidden_states,)
1476
+
1477
+ if output_attentions:
1478
+ outputs += (self_attn_weights,)
1479
+
1480
+ if use_cache:
1481
+ outputs += (present_key_value,)
1482
+
1483
+ return outputs
1484
+
1485
+
1486
+ DeepseekV2_START_DOCSTRING = r"""
1487
+ This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the
1488
+ library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads
1489
+ etc.)
1490
+
1491
+ This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass.
1492
+ Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage
1493
+ and behavior.
1494
+
1495
+ Parameters:
1496
+ config ([`DeepseekV2Config`]):
1497
+ Model configuration class with all the parameters of the model. Initializing with a config file does not
1498
+ load the weights associated with the model, only the configuration. Check out the
1499
+ [`~PreTrainedModel.from_pretrained`] method to load the model weights.
1500
+ """
1501
+
1502
+
1503
+ @add_start_docstrings(
1504
+ "The bare DeepseekV2 Model outputting raw hidden-states without any specific head on top.",
1505
+ DeepseekV2_START_DOCSTRING,
1506
+ )
1507
+ class DeepseekV2PreTrainedModel(PreTrainedModel):
1508
+ config_class = DeepseekV2Config
1509
+ base_model_prefix = "model"
1510
+ supports_gradient_checkpointing = True
1511
+ _no_split_modules = ["DeepseekV2DecoderLayer"]
1512
+ _skip_keys_device_placement = "past_key_values"
1513
+ _supports_flash_attn_2 = True
1514
+ _supports_cache_class = True
1515
+
1516
+ def _init_weights(self, module):
1517
+ std = self.config.initializer_range
1518
+ if isinstance(module, nn.Linear):
1519
+ module.weight.data.normal_(mean=0.0, std=std)
1520
+ if module.bias is not None:
1521
+ module.bias.data.zero_()
1522
+ elif isinstance(module, nn.Embedding):
1523
+ module.weight.data.normal_(mean=0.0, std=std)
1524
+ if module.padding_idx is not None:
1525
+ module.weight.data[module.padding_idx].zero_()
1526
+
1527
+
1528
+ DeepseekV2_INPUTS_DOCSTRING = r"""
1529
+ Args:
1530
+ input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`):
1531
+ Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide
1532
+ it.
1533
+
1534
+ Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
1535
+ [`PreTrainedTokenizer.__call__`] for details.
1536
+
1537
+ [What are input IDs?](../glossary#input-ids)
1538
+ attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*):
1539
+ Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`:
1540
+
1541
+ - 1 for tokens that are **not masked**,
1542
+ - 0 for tokens that are **masked**.
1543
+
1544
+ [What are attention masks?](../glossary#attention-mask)
1545
+
1546
+ Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
1547
+ [`PreTrainedTokenizer.__call__`] for details.
1548
+
1549
+ If `past_key_values` is used, optionally only the last `input_ids` have to be input (see
1550
+ `past_key_values`).
1551
+
1552
+ If you want to change padding behavior, you should read [`modeling_opt._prepare_decoder_attention_mask`]
1553
+ and modify to your needs. See diagram 1 in [the paper](https://arxiv.org/abs/1910.13461) for more
1554
+ information on the default strategy.
1555
+
1556
+ - 1 indicates the head is **not masked**,
1557
+ - 0 indicates the head is **masked**.
1558
+ position_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
1559
+ Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0,
1560
+ config.n_positions - 1]`.
1561
+
1562
+ [What are position IDs?](../glossary#position-ids)
1563
+ past_key_values (`Cache` or `tuple(tuple(torch.FloatTensor))`, *optional*):
1564
+ Pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention
1565
+ blocks) that can be used to speed up sequential decoding. This typically consists in the `past_key_values`
1566
+ returned by the model at a previous stage of decoding, when `use_cache=True` or `config.use_cache=True`.
1567
+
1568
+ Two formats are allowed:
1569
+ - a [`~cache_utils.Cache`] instance;
1570
+ - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of
1571
+ shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`). This is also known as the legacy
1572
+ cache format.
1573
+
1574
+ The model will output the same cache format that is fed as input. If no `past_key_values` are passed, the
1575
+ legacy cache format will be returned.
1576
+
1577
+ If `past_key_values` are used, the user can optionally input only the last `input_ids` (those that don't
1578
+ have their past key value states given to this model) of shape `(batch_size, 1)` instead of all `input_ids`
1579
+ of shape `(batch_size, sequence_length)`.
1580
+ inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*):
1581
+ Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This
1582
+ is useful if you want more control over how to convert `input_ids` indices into associated vectors than the
1583
+ model's internal embedding lookup matrix.
1584
+ use_cache (`bool`, *optional*):
1585
+ If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see
1586
+ `past_key_values`).
1587
+ output_attentions (`bool`, *optional*):
1588
+ Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned
1589
+ tensors for more detail.
1590
+ output_hidden_states (`bool`, *optional*):
1591
+ Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for
1592
+ more detail.
1593
+ return_dict (`bool`, *optional*):
1594
+ Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple.
1595
+ """
1596
+
1597
+
1598
+ @add_start_docstrings(
1599
+ "The bare DeepseekV2 Model outputting raw hidden-states without any specific head on top.",
1600
+ DeepseekV2_START_DOCSTRING,
1601
+ )
1602
+ class DeepseekV2Model(DeepseekV2PreTrainedModel):
1603
+ """
1604
+ Transformer decoder consisting of *config.num_hidden_layers* layers. Each layer is a [`DeepseekV2DecoderLayer`]
1605
+
1606
+ Args:
1607
+ config: DeepseekV2Config
1608
+ """
1609
+
1610
+ def __init__(self, config: DeepseekV2Config):
1611
+ super().__init__(config)
1612
+ self.padding_idx = config.pad_token_id
1613
+ self.vocab_size = config.vocab_size
1614
+
1615
+ self.embed_tokens = nn.Embedding(
1616
+ config.vocab_size, config.hidden_size, self.padding_idx
1617
+ )
1618
+ self.layers = nn.ModuleList(
1619
+ [
1620
+ DeepseekV2DecoderLayer(config, layer_idx)
1621
+ for layer_idx in range(config.num_hidden_layers)
1622
+ ]
1623
+ )
1624
+ # print(config._attn_implementation)
1625
+ self._use_flash_attention_2 = config._attn_implementation == "flash_attention_2"
1626
+ self.norm = DeepseekV2RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
1627
+
1628
+ self.gradient_checkpointing = False
1629
+ # Initialize weights and apply final processing
1630
+ self.post_init()
1631
+
1632
+ def get_input_embeddings(self):
1633
+ return self.embed_tokens
1634
+
1635
+ def set_input_embeddings(self, value):
1636
+ self.embed_tokens = value
1637
+
1638
+ @add_start_docstrings_to_model_forward(DeepseekV2_INPUTS_DOCSTRING)
1639
+ def forward(
1640
+ self,
1641
+ input_ids: torch.LongTensor = None,
1642
+ attention_mask: Optional[torch.Tensor] = None,
1643
+ position_ids: Optional[torch.LongTensor] = None,
1644
+ past_key_values: Optional[List[torch.FloatTensor]] = None,
1645
+ inputs_embeds: Optional[torch.FloatTensor] = None,
1646
+ use_cache: Optional[bool] = None,
1647
+ output_attentions: Optional[bool] = None,
1648
+ output_hidden_states: Optional[bool] = None,
1649
+ return_dict: Optional[bool] = None,
1650
+ cache_position: Optional[torch.LongTensor] = None
1651
+ ) -> Union[Tuple, BaseModelOutputWithPast]:
1652
+ output_attentions = (
1653
+ output_attentions
1654
+ if output_attentions is not None
1655
+ else self.config.output_attentions
1656
+ )
1657
+ output_hidden_states = (
1658
+ output_hidden_states
1659
+ if output_hidden_states is not None
1660
+ else self.config.output_hidden_states
1661
+ )
1662
+ use_cache = use_cache if use_cache is not None else self.config.use_cache
1663
+
1664
+ return_dict = (
1665
+ return_dict if return_dict is not None else self.config.use_return_dict
1666
+ )
1667
+
1668
+ # retrieve input_ids and inputs_embeds
1669
+ if input_ids is not None and inputs_embeds is not None:
1670
+ raise ValueError(
1671
+ "You cannot specify both input_ids and inputs_embeds at the same time"
1672
+ )
1673
+ elif input_ids is not None:
1674
+ batch_size, seq_length = input_ids.shape[:2]
1675
+ elif inputs_embeds is not None:
1676
+ batch_size, seq_length = inputs_embeds.shape[:2]
1677
+ else:
1678
+ raise ValueError("You have to specify either input_ids or inputs_embeds")
1679
+
1680
+ if self.gradient_checkpointing and self.training:
1681
+ if use_cache:
1682
+ logger.warning_once(
1683
+ "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`transformers."
1684
+ )
1685
+ use_cache = False
1686
+
1687
+ past_key_values_length = 0
1688
+ if use_cache:
1689
+ use_legacy_cache = not isinstance(past_key_values, Cache)
1690
+ if use_legacy_cache:
1691
+ past_key_values = DynamicCache.from_legacy_cache(past_key_values)
1692
+ past_key_values_length = past_key_values.get_seq_length()
1693
+
1694
+ if position_ids is None:
1695
+ device = input_ids.device if input_ids is not None else inputs_embeds.device
1696
+ position_ids = torch.arange(
1697
+ past_key_values_length,
1698
+ seq_length + past_key_values_length,
1699
+ dtype=torch.long,
1700
+ device=device,
1701
+ )
1702
+ position_ids = position_ids.unsqueeze(0)
1703
+
1704
+ if inputs_embeds is None:
1705
+ inputs_embeds = self.embed_tokens(input_ids)
1706
+
1707
+ # Skip 4D causal mask for decode (q_len=1 with KV cache doesn't need it)
1708
+ if seq_length == 1 and past_key_values_length > 0:
1709
+ attention_mask = None
1710
+ elif self._use_flash_attention_2:
1711
+ # 2d mask is passed through the layers
1712
+ attention_mask = (
1713
+ attention_mask
1714
+ if (attention_mask is not None and 0 in attention_mask)
1715
+ else None
1716
+ )
1717
+ else:
1718
+ # 4d mask is passed through the layers
1719
+ attention_mask = _prepare_4d_causal_attention_mask(
1720
+ attention_mask,
1721
+ (batch_size, seq_length),
1722
+ inputs_embeds,
1723
+ past_key_values_length,
1724
+ )
1725
+
1726
+ # embed positions
1727
+ hidden_states = inputs_embeds
1728
+
1729
+ # decoder layers
1730
+ all_hidden_states = () if output_hidden_states else None
1731
+ all_self_attns = () if output_attentions else None
1732
+ next_decoder_cache = None
1733
+
1734
+ for decoder_layer in self.layers:
1735
+ if output_hidden_states:
1736
+ all_hidden_states += (hidden_states,)
1737
+
1738
+ if self.gradient_checkpointing and self.training:
1739
+ layer_outputs = self._gradient_checkpointing_func(
1740
+ decoder_layer.__call__,
1741
+ hidden_states,
1742
+ attention_mask,
1743
+ position_ids,
1744
+ past_key_values,
1745
+ output_attentions,
1746
+ use_cache,
1747
+ )
1748
+ else:
1749
+ layer_outputs = decoder_layer(
1750
+ hidden_states,
1751
+ attention_mask=attention_mask,
1752
+ position_ids=position_ids,
1753
+ past_key_value=past_key_values,
1754
+ output_attentions=output_attentions,
1755
+ use_cache=use_cache,
1756
+ )
1757
+
1758
+ hidden_states = layer_outputs[0]
1759
+
1760
+ if use_cache:
1761
+ next_decoder_cache = layer_outputs[2 if output_attentions else 1]
1762
+
1763
+ if output_attentions:
1764
+ all_self_attns += (layer_outputs[1],)
1765
+
1766
+ hidden_states = self.norm(hidden_states)
1767
+
1768
+ # add hidden states from the last decoder layer
1769
+ if output_hidden_states:
1770
+ all_hidden_states += (hidden_states,)
1771
+
1772
+ next_cache = None
1773
+ if use_cache:
1774
+ next_cache = next_decoder_cache # Always return DynamicCache to preserve custom attributes
1775
+ if not return_dict:
1776
+ return tuple(
1777
+ v
1778
+ for v in [hidden_states, next_cache, all_hidden_states, all_self_attns]
1779
+ if v is not None
1780
+ )
1781
+ return BaseModelOutputWithPast(
1782
+ last_hidden_state=hidden_states,
1783
+ past_key_values=next_cache,
1784
+ hidden_states=all_hidden_states,
1785
+ attentions=all_self_attns,
1786
+ )
1787
+
1788
+
1789
+ class DeepseekV2ForCausalLM(DeepseekV2PreTrainedModel):
1790
+ _tied_weights_keys = ["lm_head.weight"]
1791
+
1792
+ def __init__(self, config):
1793
+ super().__init__(config)
1794
+ self.model = DeepseekV2Model(config)
1795
+ self.vocab_size = config.vocab_size
1796
+ self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
1797
+
1798
+ # Initialize weights and apply final processing
1799
+ self.post_init()
1800
+
1801
+ def get_input_embeddings(self):
1802
+ return self.model.embed_tokens
1803
+
1804
+ def set_input_embeddings(self, value):
1805
+ self.model.embed_tokens = value
1806
+
1807
+ def get_output_embeddings(self):
1808
+ return self.lm_head
1809
+
1810
+ def set_output_embeddings(self, new_embeddings):
1811
+ self.lm_head = new_embeddings
1812
+
1813
+ def set_decoder(self, decoder):
1814
+ self.model = decoder
1815
+
1816
+ def get_decoder(self):
1817
+ return self.model
1818
+
1819
+ @add_start_docstrings_to_model_forward(DeepseekV2_INPUTS_DOCSTRING)
1820
+ @replace_return_docstrings(
1821
+ output_type=CausalLMOutputWithPast, config_class=_CONFIG_FOR_DOC
1822
+ )
1823
+ def forward(
1824
+ self,
1825
+ input_ids: torch.LongTensor = None,
1826
+ attention_mask: Optional[torch.Tensor] = None,
1827
+ position_ids: Optional[torch.LongTensor] = None,
1828
+ past_key_values: Optional[List[torch.FloatTensor]] = None,
1829
+ inputs_embeds: Optional[torch.FloatTensor] = None,
1830
+ labels: Optional[torch.LongTensor] = None,
1831
+ use_cache: Optional[bool] = None,
1832
+ output_attentions: Optional[bool] = None,
1833
+ output_hidden_states: Optional[bool] = None,
1834
+ return_dict: Optional[bool] = None,
1835
+ cache_position: Optional[torch.LongTensor] = None
1836
+ ) -> Union[Tuple, CausalLMOutputWithPast]:
1837
+ r"""
1838
+ Args:
1839
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
1840
+ Labels for computing the masked language modeling loss. Indices should either be in `[0, transformers.,
1841
+ config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
1842
+ (masked), the loss is only computed for the tokens with labels in `[0, transformers., config.vocab_size]`.
1843
+
1844
+ Returns:
1845
+
1846
+ Example:
1847
+
1848
+ ```python
1849
+ >>> from transformers import AutoTokenizer, DeepseekV2ForCausalLM
1850
+
1851
+ >>> model = DeepseekV2ForCausalLM.from_pretrained(PATH_TO_CONVERTED_WEIGHTS)
1852
+ >>> tokenizer = AutoTokenizer.from_pretrained(PATH_TO_CONVERTED_TOKENIZER)
1853
+
1854
+ >>> prompt = "Hey, are you conscious? Can you talk to me?"
1855
+ >>> inputs = tokenizer(prompt, return_tensors="pt")
1856
+
1857
+ >>> # Generate
1858
+ >>> generate_ids = model.generate(inputs.input_ids, max_length=30)
1859
+ >>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
1860
+ "Hey, are you conscious? Can you talk to me?\nI'm not conscious, but I can talk to you."
1861
+ ```"""
1862
+ output_attentions = (
1863
+ output_attentions
1864
+ if output_attentions is not None
1865
+ else self.config.output_attentions
1866
+ )
1867
+ output_hidden_states = (
1868
+ output_hidden_states
1869
+ if output_hidden_states is not None
1870
+ else self.config.output_hidden_states
1871
+ )
1872
+ return_dict = (
1873
+ return_dict if return_dict is not None else self.config.use_return_dict
1874
+ )
1875
+
1876
+ # decoder outputs consists of (dec_features, layer_state, dec_hidden, dec_attn)
1877
+ outputs = self.model(
1878
+ input_ids=input_ids,
1879
+ attention_mask=attention_mask,
1880
+ position_ids=position_ids,
1881
+ past_key_values=past_key_values,
1882
+ inputs_embeds=inputs_embeds,
1883
+ use_cache=use_cache,
1884
+ output_attentions=output_attentions,
1885
+ output_hidden_states=output_hidden_states,
1886
+ return_dict=return_dict,
1887
+ cache_position=cache_position
1888
+ )
1889
+
1890
+ hidden_states = outputs[0]
1891
+ logits = self.lm_head(hidden_states)
1892
+ logits = logits.float()
1893
+
1894
+ loss = None
1895
+ if labels is not None:
1896
+ # Shift so that tokens < n predict n
1897
+ shift_logits = logits[..., :-1, :].contiguous()
1898
+ shift_labels = labels[..., 1:].contiguous()
1899
+ # Flatten the tokens
1900
+ loss_fct = CrossEntropyLoss()
1901
+ shift_logits = shift_logits.view(-1, self.config.vocab_size)
1902
+ shift_labels = shift_labels.view(-1)
1903
+ # Enable model parallelism
1904
+ shift_labels = shift_labels.to(shift_logits.device)
1905
+ loss = loss_fct(shift_logits, shift_labels)
1906
+
1907
+ if not return_dict:
1908
+ output = (logits,) + outputs[1:]
1909
+ return (loss,) + output if loss is not None else output
1910
+
1911
+ return CausalLMOutputWithPast(
1912
+ loss=loss,
1913
+ logits=logits,
1914
+ past_key_values=outputs.past_key_values,
1915
+ hidden_states=outputs.hidden_states,
1916
+ attentions=outputs.attentions,
1917
+ )
1918
+
1919
+ def prepare_inputs_for_generation(
1920
+ self,
1921
+ input_ids,
1922
+ past_key_values=None,
1923
+ attention_mask=None,
1924
+ inputs_embeds=None,
1925
+ **kwargs,
1926
+ ):
1927
+ past_length = 0
1928
+ if past_key_values is not None:
1929
+ if isinstance(past_key_values, Cache):
1930
+ cache_length = past_key_values.get_seq_length()
1931
+ past_length = past_key_values.get_seq_length()
1932
+ max_cache_length = getattr(past_key_values, 'get_max_length', lambda: None)()
1933
+ else:
1934
+ cache_length = past_length = past_key_values[0][0].shape[2]
1935
+ max_cache_length = None
1936
+
1937
+ # Keep only the unprocessed tokens:
1938
+ # 1 - If the length of the attention_mask exceeds the length of input_ids, then we are in a setting where
1939
+ # some of the inputs are exclusively passed as part of the cache (e.g. when passing input_embeds as
1940
+ # input)
1941
+ if attention_mask is not None and attention_mask.shape[1] > input_ids.shape[1]:
1942
+ input_ids = input_ids[:, -(attention_mask.shape[1] - past_length):]
1943
+ # 2 - If the past_length is smaller than input_ids', then input_ids holds all input tokens. We can discard
1944
+ # input_ids based on the past_length.
1945
+ elif past_length < input_ids.shape[1]:
1946
+ input_ids = input_ids[:, past_length:]
1947
+ # 3 - Otherwise (past_length >= input_ids.shape[1]), let's assume input_ids only has unprocessed tokens.
1948
+
1949
+ # If we are about to go beyond the maximum cache length, we need to crop the input attention mask.
1950
+ if (
1951
+ max_cache_length is not None
1952
+ and attention_mask is not None
1953
+ and cache_length + input_ids.shape[1] > max_cache_length
1954
+ ):
1955
+ attention_mask = attention_mask[:, -max_cache_length:]
1956
+
1957
+ position_ids = kwargs.get("position_ids", None)
1958
+ if attention_mask is not None and position_ids is None:
1959
+ # create position_ids on the fly for batch generation
1960
+ position_ids = attention_mask.long().cumsum(-1) - 1
1961
+ position_ids.masked_fill_(attention_mask == 0, 1)
1962
+ if past_key_values:
1963
+ position_ids = position_ids[:, -input_ids.shape[1]:]
1964
+
1965
+ if self.generation_config.cache_implementation == "static":
1966
+ # generation with static cache
1967
+ cache_position = kwargs.get("cache_position", None)
1968
+ if cache_position is None:
1969
+ past_length = 0
1970
+ else:
1971
+ past_length = cache_position[-1] + 1
1972
+ input_ids = input_ids[:, past_length:]
1973
+ position_ids = position_ids[:, past_length:]
1974
+
1975
+ # TODO @gante we should only keep a `cache_position` in generate, and do +=1.
1976
+ # same goes for position ids. Could also help with continued generation.
1977
+ cache_position = torch.arange(past_length, past_length + position_ids.shape[-1], device=position_ids.device)
1978
+
1979
+ # if `inputs_embeds` are passed, we only want to use them in the 1st generation step
1980
+ if inputs_embeds is not None and past_key_values is None:
1981
+ model_inputs = {"inputs_embeds": inputs_embeds}
1982
+ else:
1983
+ # The `contiguous()` here is necessary to have a static stride during decoding. torchdynamo otherwise
1984
+ # recompiles graphs as the stride of the inputs is a guard. Ref: https://github.com/huggingface/transformers/pull/29114
1985
+ # TODO: use `next_tokens` directly instead.
1986
+ model_inputs = {"input_ids": input_ids.contiguous()}
1987
+
1988
+ model_inputs.update(
1989
+ {
1990
+ "position_ids": position_ids.contiguous(),
1991
+ "cache_position": cache_position,
1992
+ "past_key_values": past_key_values,
1993
+ "use_cache": kwargs.get("use_cache"),
1994
+ "attention_mask": attention_mask,
1995
+ }
1996
+ )
1997
+ return model_inputs
1998
+
1999
+ @staticmethod
2000
+ def _reorder_cache(past_key_values, beam_idx):
2001
+ reordered_past = ()
2002
+ for layer_past in past_key_values:
2003
+ reordered_past += (
2004
+ tuple(
2005
+ past_state.index_select(0, beam_idx.to(past_state.device))
2006
+ for past_state in layer_past
2007
+ ),
2008
+ )
2009
+ return reordered_past
2010
+
2011
+
2012
+ @add_start_docstrings(
2013
+ """
2014
+ The DeepseekV2 Model transformer with a sequence classification head on top (linear layer).
2015
+
2016
+ [`DeepseekV2ForSequenceClassification`] uses the last token in order to do the classification, as other causal models
2017
+ (e.g. GPT-2) do.
2018
+
2019
+ Since it does classification on the last token, it requires to know the position of the last token. If a
2020
+ `pad_token_id` is defined in the configuration, it finds the last token that is not a padding token in each row. If
2021
+ no `pad_token_id` is defined, it simply takes the last value in each row of the batch. Since it cannot guess the
2022
+ padding tokens when `inputs_embeds` are passed instead of `input_ids`, it does the same (take the last value in
2023
+ each row of the batch).
2024
+ """,
2025
+ DeepseekV2_START_DOCSTRING,
2026
+ )
2027
+ class DeepseekV2ForSequenceClassification(DeepseekV2PreTrainedModel):
2028
+ def __init__(self, config):
2029
+ super().__init__(config)
2030
+ self.num_labels = config.num_labels
2031
+ self.model = DeepseekV2Model(config)
2032
+ self.score = nn.Linear(config.hidden_size, self.num_labels, bias=False)
2033
+
2034
+ # Initialize weights and apply final processing
2035
+ self.post_init()
2036
+
2037
+ def get_input_embeddings(self):
2038
+ return self.model.embed_tokens
2039
+
2040
+ def set_input_embeddings(self, value):
2041
+ self.model.embed_tokens = value
2042
+
2043
+ @add_start_docstrings_to_model_forward(DeepseekV2_INPUTS_DOCSTRING)
2044
+ def forward(
2045
+ self,
2046
+ input_ids: torch.LongTensor = None,
2047
+ attention_mask: Optional[torch.Tensor] = None,
2048
+ position_ids: Optional[torch.LongTensor] = None,
2049
+ past_key_values: Optional[List[torch.FloatTensor]] = None,
2050
+ inputs_embeds: Optional[torch.FloatTensor] = None,
2051
+ labels: Optional[torch.LongTensor] = None,
2052
+ use_cache: Optional[bool] = None,
2053
+ output_attentions: Optional[bool] = None,
2054
+ output_hidden_states: Optional[bool] = None,
2055
+ return_dict: Optional[bool] = None,
2056
+ ) -> Union[Tuple, SequenceClassifierOutputWithPast]:
2057
+ r"""
2058
+ labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
2059
+ Labels for computing the sequence classification/regression loss. Indices should be in `[0, transformers.,
2060
+ config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
2061
+ `config.num_labels > 1` a classification loss is computed (Cross-Entropy).
2062
+ """
2063
+ return_dict = (
2064
+ return_dict if return_dict is not None else self.config.use_return_dict
2065
+ )
2066
+
2067
+ transformer_outputs = self.model(
2068
+ input_ids,
2069
+ attention_mask=attention_mask,
2070
+ position_ids=position_ids,
2071
+ past_key_values=past_key_values,
2072
+ inputs_embeds=inputs_embeds,
2073
+ use_cache=use_cache,
2074
+ output_attentions=output_attentions,
2075
+ output_hidden_states=output_hidden_states,
2076
+ return_dict=return_dict,
2077
+ )
2078
+ hidden_states = transformer_outputs[0]
2079
+ logits = self.score(hidden_states)
2080
+
2081
+ if input_ids is not None:
2082
+ batch_size = input_ids.shape[0]
2083
+ else:
2084
+ batch_size = inputs_embeds.shape[0]
2085
+
2086
+ if self.config.pad_token_id is None and batch_size != 1:
2087
+ raise ValueError(
2088
+ "Cannot handle batch sizes > 1 if no padding token is defined."
2089
+ )
2090
+ if self.config.pad_token_id is None:
2091
+ sequence_lengths = -1
2092
+ else:
2093
+ if input_ids is not None:
2094
+ sequence_lengths = (
2095
+ torch.eq(input_ids, self.config.pad_token_id).int().argmax(-1) - 1
2096
+ ).to(logits.device)
2097
+ else:
2098
+ sequence_lengths = -1
2099
+
2100
+ pooled_logits = logits[
2101
+ torch.arange(batch_size, device=logits.device), sequence_lengths
2102
+ ]
2103
+
2104
+ loss = None
2105
+ if labels is not None:
2106
+ labels = labels.to(logits.device)
2107
+ if self.config.problem_type is None:
2108
+ if self.num_labels == 1:
2109
+ self.config.problem_type = "regression"
2110
+ elif self.num_labels > 1 and (
2111
+ labels.dtype == torch.long or labels.dtype == torch.int
2112
+ ):
2113
+ self.config.problem_type = "single_label_classification"
2114
+ else:
2115
+ self.config.problem_type = "multi_label_classification"
2116
+
2117
+ if self.config.problem_type == "regression":
2118
+ loss_fct = MSELoss()
2119
+ if self.num_labels == 1:
2120
+ loss = loss_fct(pooled_logits.squeeze(), labels.squeeze())
2121
+ else:
2122
+ loss = loss_fct(pooled_logits, labels)
2123
+ elif self.config.problem_type == "single_label_classification":
2124
+ loss_fct = CrossEntropyLoss()
2125
+ loss = loss_fct(
2126
+ pooled_logits.view(-1, self.num_labels), labels.view(-1)
2127
+ )
2128
+ elif self.config.problem_type == "multi_label_classification":
2129
+ loss_fct = BCEWithLogitsLoss()
2130
+ loss = loss_fct(pooled_logits, labels)
2131
+ if not return_dict:
2132
+ output = (pooled_logits,) + transformer_outputs[1:]
2133
+ return ((loss,) + output) if loss is not None else output
2134
+
2135
+ return SequenceClassifierOutputWithPast(
2136
+ loss=loss,
2137
+ logits=pooled_logits,
2138
+ past_key_values=transformer_outputs.past_key_values,
2139
+ hidden_states=transformer_outputs.hidden_states,
2140
+ attentions=transformer_outputs.attentions,
2141
+ )
modeling_unlimitedocr.py ADDED
@@ -0,0 +1,1299 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from .modeling_deepseekv2 import DeepseekV2Model, DeepseekV2ForCausalLM
2
+ from .configuration_deepseek_v2 import DeepseekV2Config
3
+ from transformers.modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast
4
+ from typing import List, Optional, Tuple, Union
5
+ from transformers.cache_utils import Cache
6
+ import requests
7
+ from PIL import Image, ImageOps, ImageDraw, ImageFont
8
+ from io import BytesIO
9
+ import torch
10
+ import torch.nn as nn
11
+ from torch.nn import CrossEntropyLoss
12
+ from torchvision import transforms
13
+ from torchvision.transforms.functional import InterpolationMode
14
+ import os
15
+ from .deepencoder import build_sam_vit_b, build_clip_l, MlpProjector
16
+ from addict import Dict
17
+ from transformers import TextStreamer
18
+ from .conversation import get_conv_template
19
+ from abc import ABC
20
+ import math
21
+ import re
22
+ from tqdm import tqdm
23
+ import numpy as np
24
+ import time
25
+
26
+
27
+ def load_image(image_path):
28
+
29
+ try:
30
+ image = Image.open(image_path)
31
+
32
+ corrected_image = ImageOps.exif_transpose(image)
33
+
34
+ return corrected_image
35
+
36
+ except Exception as e:
37
+ print(f"error: {e}")
38
+ try:
39
+ return Image.open(image_path)
40
+ except:
41
+ return None
42
+
43
+
44
+ def re_match(text):
45
+ ref_pattern = r'(<\|ref\|>(.*?)<\|/ref\|><\|det\|>(.*?)<\|/det\|>)'
46
+ matches = re.findall(ref_pattern, text, re.DOTALL)
47
+
48
+ det_pattern = r'(<\|det\|>\s*([A-Za-z_][\w-]*)\s*(\[[^\]]+\])\s*<\|/det\|>)'
49
+ for full_match, label, box in re.findall(det_pattern, text, re.DOTALL):
50
+ matches.append((full_match, label, box))
51
+
52
+ mathes_image = []
53
+ mathes_other = []
54
+ for a_match in matches:
55
+ if a_match[1].strip() == 'image' or '<|ref|>image<|/ref|>' in a_match[0]:
56
+ mathes_image.append(a_match[0])
57
+ else:
58
+ mathes_other.append(a_match[0])
59
+ return matches, mathes_image, mathes_other
60
+
61
+
62
+ def extract_coordinates_and_label(ref_text, image_width, image_height):
63
+
64
+ try:
65
+ label_type = ref_text[1]
66
+ cor_list = eval(ref_text[2])
67
+ if cor_list and isinstance(cor_list[0], (int, float)):
68
+ cor_list = [cor_list]
69
+ except Exception as e:
70
+ print(e)
71
+ return None
72
+
73
+ return (label_type, cor_list)
74
+
75
+
76
+ def draw_bounding_boxes(image, refs, ouput_path, image_prefix=''):
77
+
78
+ image_width, image_height = image.size
79
+
80
+ img_draw = image.copy()
81
+ draw = ImageDraw.Draw(img_draw)
82
+
83
+ overlay = Image.new('RGBA', img_draw.size, (0, 0, 0, 0))
84
+ draw2 = ImageDraw.Draw(overlay)
85
+
86
+ # try:
87
+ # except IOError:
88
+ # try:
89
+ # font = ImageFont.truetype("DejaVuSans.ttf", 20)
90
+ # except IOError:
91
+ font = ImageFont.load_default()
92
+
93
+ img_idx = 0
94
+
95
+ for i, ref in enumerate(refs):
96
+ try:
97
+ result = extract_coordinates_and_label(ref, image_width, image_height)
98
+ if result:
99
+ label_type, points_list = result
100
+
101
+ color = (np.random.randint(0, 200), np.random.randint(0, 200), np.random.randint(0, 255))
102
+
103
+ color_a = color + (20, )
104
+ for points in points_list:
105
+ x1, y1, x2, y2 = points
106
+
107
+ x1 = int(x1 / 999 * image_width)
108
+ y1 = int(y1 / 999 * image_height)
109
+
110
+ x2 = int(x2 / 999 * image_width)
111
+ y2 = int(y2 / 999 * image_height)
112
+
113
+ if label_type == 'image':
114
+ try:
115
+ cropped = image.crop((x1, y1, x2, y2))
116
+ cropped.save(f"{ouput_path}/images/{image_prefix}{img_idx}.jpg")
117
+ except Exception as e:
118
+ print(e)
119
+ pass
120
+ img_idx += 1
121
+
122
+ try:
123
+ if label_type == 'title':
124
+ draw.rectangle([x1, y1, x2, y2], outline=color, width=4)
125
+ draw2.rectangle([x1, y1, x2, y2], fill=color_a, outline=(0, 0, 0, 0), width=1)
126
+ else:
127
+ draw.rectangle([x1, y1, x2, y2], outline=color, width=2)
128
+ draw2.rectangle([x1, y1, x2, y2], fill=color_a, outline=(0, 0, 0, 0), width=1)
129
+ text_x = x1
130
+ text_y = max(0, y1 - 15)
131
+
132
+
133
+ text_bbox = draw.textbbox((0, 0), label_type, font=font)
134
+ text_width = text_bbox[2] - text_bbox[0]
135
+ text_height = text_bbox[3] - text_bbox[1]
136
+ draw.rectangle([text_x, text_y, text_x + text_width, text_y + text_height],
137
+ fill=(255, 255, 255, 30))
138
+
139
+ draw.text((text_x, text_y), label_type, font=font, fill=color)
140
+ except:
141
+ pass
142
+ except:
143
+ continue
144
+ img_draw.paste(overlay, (0, 0), overlay)
145
+ return img_draw
146
+
147
+
148
+ def process_image_with_refs(image, ref_texts, output_path, image_prefix=''):
149
+
150
+ result_image = draw_bounding_boxes(image, ref_texts, output_path, image_prefix=image_prefix)
151
+
152
+ return result_image
153
+
154
+
155
+
156
+
157
+
158
+ def find_closest_aspect_ratio(aspect_ratio, target_ratios, width, height, image_size):
159
+ best_ratio_diff = float('inf')
160
+ best_ratio = (1, 1)
161
+ area = width * height
162
+ for ratio in target_ratios:
163
+ target_aspect_ratio = ratio[0] / ratio[1]
164
+ ratio_diff = abs(aspect_ratio - target_aspect_ratio)
165
+ if ratio_diff < best_ratio_diff:
166
+ best_ratio_diff = ratio_diff
167
+ best_ratio = ratio
168
+ elif ratio_diff == best_ratio_diff:
169
+ if area > 0.5 * image_size * image_size * ratio[0] * ratio[1]:
170
+ best_ratio = ratio
171
+ # print(f'width: {width}, height: {height}, best_ratio: {best_ratio}')
172
+ return best_ratio
173
+
174
+
175
+ def dynamic_preprocess(image, min_num=2, max_num=32, image_size=640, use_thumbnail=False):
176
+ orig_width, orig_height = image.size
177
+ aspect_ratio = orig_width / orig_height
178
+
179
+ # calculate the existing image aspect ratio
180
+ target_ratios = set(
181
+ (i, j) for n in range(min_num, max_num + 1) for i in range(1, n + 1) for j in range(1, n + 1) if
182
+ i * j <= max_num and i * j >= min_num)
183
+ # print(target_ratios)
184
+ target_ratios = sorted(target_ratios, key=lambda x: x[0] * x[1])
185
+
186
+ # find the closest aspect ratio to the target
187
+ target_aspect_ratio = find_closest_aspect_ratio(
188
+ aspect_ratio, target_ratios, orig_width, orig_height, image_size)
189
+
190
+ # print(target_aspect_ratio)
191
+ # calculate the target width and height
192
+ target_width = image_size * target_aspect_ratio[0]
193
+ target_height = image_size * target_aspect_ratio[1]
194
+ blocks = target_aspect_ratio[0] * target_aspect_ratio[1]
195
+
196
+ # resize the image
197
+ resized_img = image.resize((target_width, target_height))
198
+ processed_images = []
199
+ for i in range(blocks):
200
+ box = (
201
+ (i % (target_width // image_size)) * image_size,
202
+ (i // (target_width // image_size)) * image_size,
203
+ ((i % (target_width // image_size)) + 1) * image_size,
204
+ ((i // (target_width // image_size)) + 1) * image_size
205
+ )
206
+ # split the image
207
+ split_img = resized_img.crop(box)
208
+ processed_images.append(split_img)
209
+ assert len(processed_images) == blocks
210
+ if use_thumbnail and len(processed_images) != 1:
211
+ thumbnail_img = image.resize((image_size, image_size))
212
+ processed_images.append(thumbnail_img)
213
+ return processed_images, target_aspect_ratio
214
+
215
+
216
+
217
+ def normalize_transform(mean, std):
218
+ if mean is None and std is None:
219
+ transform = None
220
+ elif mean is None and std is not None:
221
+ mean = [0.] * len(std)
222
+ transform = transforms.Normalize(mean=mean, std=std)
223
+ elif mean is not None and std is None:
224
+ std = [1.] * len(mean)
225
+ transform = transforms.Normalize(mean=mean, std=std)
226
+ else:
227
+ transform = transforms.Normalize(mean=mean, std=std)
228
+
229
+ return transform
230
+
231
+
232
+
233
+ def format_messages(
234
+ conversations: List[Dict[str, str]],
235
+ sft_format: str = "deepseek",
236
+ system_prompt: str = "",
237
+ ):
238
+ """
239
+ Applies the SFT template to conversation.
240
+
241
+ Args:
242
+ conversations (List[Dict]): A List of messages.
243
+ sft_format (str, optional): The format of the SFT template to use. Defaults to "deepseek".
244
+ system_prompt (str, optional): The system prompt to use in the SFT template. Defaults to "".
245
+
246
+ Returns:
247
+ sft_prompt (str): The formatted text.
248
+ """
249
+
250
+ conv = get_conv_template(sft_format)
251
+ conv.set_system_message(system_prompt)
252
+ for message in conversations:
253
+ conv.append_message(message["role"], message["content"].strip())
254
+ sft_prompt = conv.get_prompt().strip()
255
+
256
+ return sft_prompt
257
+
258
+
259
+ def text_encode(tokenizer, text: str, bos: bool = True, eos: bool = False):
260
+ t = tokenizer.encode(text, add_special_tokens=False)
261
+ bos_id = 0
262
+ eos_id = 1
263
+ if bos:
264
+ t = [bos_id] + t
265
+ if eos:
266
+ t = t + [eos_id]
267
+
268
+ return t
269
+
270
+ def load_pil_images(conversations: List[Dict[str, str]]) -> List[Image.Image]:
271
+ """
272
+
273
+ Args:
274
+ conversations (List[Dict[str, str]]): the conversations with a list of messages. An example is :
275
+ [
276
+ {
277
+ "role": "User",
278
+ "content": "<image_placeholder>\nExtract all information from this image and convert them into markdown format.",
279
+ "images": ["./examples/table_datasets.png"]
280
+ },
281
+ {"role": "Assistant", "content": ""},
282
+ ]
283
+
284
+ Returns:
285
+ pil_images (List[PIL.Image.Image]): the list of PIL images.
286
+
287
+ """
288
+
289
+ pil_images = []
290
+
291
+ for message in conversations:
292
+ if "images" not in message:
293
+ continue
294
+
295
+ for image_path in message["images"]:
296
+ # print('----------------')
297
+ # print(image_path)
298
+ # print('----------------')
299
+ # exit()
300
+
301
+ # pil_img = Image.open(image_path)
302
+ pil_img = load_image(image_path)
303
+ pil_img = pil_img.convert("RGB")
304
+ pil_images.append(pil_img)
305
+
306
+ return pil_images
307
+
308
+
309
+ class BaseTransform(ABC):
310
+
311
+ def set_rng(self, *args, **kwargs):
312
+ pass
313
+
314
+ def __call__(self, *args, **kwargs) -> torch.Tensor:
315
+ pass
316
+
317
+ @property
318
+ def default_shape(self):
319
+ raise NotImplementedError
320
+
321
+
322
+ class BasicImageTransform(BaseTransform):
323
+ def __init__(
324
+ self,
325
+ mean: Optional[Tuple[float, float, float]] = (0.5, 0.5, 0.5),
326
+ std: Optional[Tuple[float, float, float]] = (0.5, 0.5, 0.5),
327
+ normalize: bool = True
328
+ ):
329
+ self.mean = mean
330
+ self.std = std
331
+
332
+ transform_pipelines = [
333
+ transforms.ToTensor()
334
+ ]
335
+
336
+ normalize = normalize_transform(mean, std) if normalize else nn.Identity()
337
+ if normalize is not None:
338
+ transform_pipelines.append(normalize)
339
+
340
+ self.transform = transforms.Compose(transform_pipelines)
341
+
342
+ def __call__(self, x):
343
+ x = self.transform(x)
344
+ return x
345
+
346
+ class NoEOSTextStreamer(TextStreamer):
347
+ def on_finalized_text(self, text: str, stream_end: bool = False):
348
+
349
+ eos_text = self.tokenizer.decode([self.tokenizer.eos_token_id], skip_special_tokens=False)
350
+ text = text.replace(eos_text, "\n")
351
+ print(text, flush=True, end="")
352
+
353
+
354
+ class SlidingWindowNoRepeatNgramProcessor:
355
+ """Block n-gram repetitions within a sliding window.
356
+ Aligned with SGLang DeepseekOCRNoRepeatNGramLogitProcessor."""
357
+ def __init__(self, ngram_size, window, whitelist_token_ids=None):
358
+ self.ngram_size = ngram_size
359
+ self.window = window
360
+ self.whitelist = set(whitelist_token_ids) if whitelist_token_ids else set()
361
+
362
+ def __call__(self, input_ids, scores):
363
+ for batch_idx in range(input_ids.shape[0]):
364
+ sequence = input_ids[batch_idx].tolist()
365
+ if len(sequence) < self.ngram_size:
366
+ continue
367
+ search_start = max(0, len(sequence) - self.window)
368
+ search_end = len(sequence) - self.ngram_size + 1
369
+ if search_end <= search_start:
370
+ continue
371
+ if self.ngram_size > 1:
372
+ current_prefix = tuple(sequence[-(self.ngram_size - 1):])
373
+ else:
374
+ current_prefix = tuple()
375
+ banned = set()
376
+ for idx in range(search_start, search_end):
377
+ ngram = sequence[idx:idx + self.ngram_size]
378
+ if self.ngram_size == 1 or tuple(ngram[:-1]) == current_prefix:
379
+ banned.add(ngram[-1])
380
+ banned.difference_update(self.whitelist)
381
+ for token_id in banned:
382
+ scores[batch_idx, token_id] = float('-inf')
383
+ return scores
384
+
385
+
386
+ class TPSTextStreamer(TextStreamer):
387
+ """Streamer that prints TPS every `interval` tokens. Set interval=0 to disable."""
388
+ def __init__(self, tokenizer, interval=100, **kwargs):
389
+ super().__init__(tokenizer, **kwargs)
390
+ self.interval = interval
391
+ self.token_count = 0
392
+ self.start_time = None
393
+ self.start_token_count = 0
394
+ self.last_report_count = 0
395
+ self.last_report_time = None
396
+
397
+ def put(self, value):
398
+ import time
399
+ if hasattr(value, 'numel'):
400
+ self.token_count += value.numel()
401
+ else:
402
+ self.token_count += 1
403
+ # 第一次 put 时开始计时(跳过 prefill)
404
+ if self.start_time is None:
405
+ self.start_time = time.time()
406
+ self.last_report_time = self.start_time
407
+ self.last_report_count = self.token_count
408
+ self.start_token_count = self.token_count
409
+ super().put(value)
410
+ return
411
+ if self.interval > 0 and self.token_count - self.last_report_count >= self.interval:
412
+ now = time.time()
413
+ delta_tokens = self.token_count - self.last_report_count
414
+ delta_time = now - self.last_report_time
415
+ recent_tps = delta_tokens / delta_time if delta_time > 0 else 0
416
+ avg_tps = (self.token_count - self.start_token_count) / (now - self.start_time) if (now - self.start_time) > 0 else 0
417
+ print(f"\n[TPS] tokens={self.token_count}, recent={recent_tps:.1f} t/s, avg={avg_tps:.1f} t/s", flush=True)
418
+ self.last_report_count = self.token_count
419
+ self.last_report_time = now
420
+ super().put(value)
421
+
422
+ def on_finalized_text(self, text: str, stream_end: bool = False):
423
+ eos_text = self.tokenizer.decode([self.tokenizer.eos_token_id], skip_special_tokens=False)
424
+ text = text.replace(eos_text, "\n")
425
+ print(text, flush=True, end="")
426
+
427
+
428
+ class UnlimitedOCRConfig(DeepseekV2Config):
429
+ model_type = "unlimited-ocr"
430
+
431
+ class UnlimitedOCRModel(DeepseekV2Model):
432
+ config_class = UnlimitedOCRConfig
433
+
434
+ def __init__(self, config: DeepseekV2Config):
435
+ super(UnlimitedOCRModel, self).__init__(config)
436
+
437
+ self.sam_model = build_sam_vit_b()
438
+ self.vision_model = build_clip_l()
439
+ # self.conv_2 = nn.Conv2d(in_channels=1024, out_channels=2048, kernel_size=2, stride=2)
440
+ n_embed = 1280
441
+ self.projector = MlpProjector(Dict(projector_type="linear", input_dim=2048, n_embed=n_embed))
442
+ embed_std = 1 / torch.sqrt(torch.tensor(n_embed, dtype=torch.float32))
443
+ self.image_newline = nn.Parameter(torch.randn(n_embed) * embed_std)
444
+ self.view_seperator = nn.Parameter(torch.randn(n_embed) * embed_std)
445
+
446
+
447
+
448
+
449
+ def forward(
450
+ self,
451
+ input_ids: torch.LongTensor = None,
452
+ attention_mask: Optional[torch.Tensor] = None,
453
+ position_ids: Optional[torch.LongTensor] = None,
454
+ past_key_values: Optional[List[torch.FloatTensor]] = None,
455
+ inputs_embeds: Optional[torch.FloatTensor] = None,
456
+ use_cache: Optional[bool] = None,
457
+ output_attentions: Optional[bool] = None,
458
+ output_hidden_states: Optional[bool] = None,
459
+ images: Optional[torch.FloatTensor] = None,
460
+ images_seq_mask: Optional[torch.FloatTensor] = None,
461
+ images_spatial_crop: Optional[torch.FloatTensor] = None,
462
+ return_dict: Optional[bool] = None,
463
+ ) -> Union[Tuple, BaseModelOutputWithPast]:
464
+
465
+
466
+
467
+
468
+ if inputs_embeds is None:
469
+ # inputs_embeds = self.embed_tokens(input_ids)
470
+ inputs_embeds = self.get_input_embeddings()(input_ids)
471
+
472
+
473
+
474
+ sam_model = getattr(self, 'sam_model', None)
475
+ # sam_model = self.sam_model
476
+ vision_model = getattr(self, 'vision_model', None)
477
+
478
+
479
+
480
+ if sam_model is not None and images is not None and (input_ids.shape[1] != 1 or self.training) and torch.sum(images[0][1]).item() != 0:
481
+
482
+ idx = 0
483
+
484
+ # sam_model = torch.jit.script(sam_model)
485
+
486
+ # start_time = time.time()
487
+ for image, crop_shape in zip(images, images_spatial_crop):
488
+ images_in_this_batch = []
489
+
490
+ patches = image[0]
491
+ image_ori = image[1]
492
+
493
+ with torch.no_grad():
494
+ # with torch.inference_mode():
495
+
496
+ if torch.sum(patches).item() != 0:
497
+ # P, C, H, W = patches.shape
498
+ crop_flag = 1
499
+ local_features_1 = sam_model(patches)
500
+
501
+ local_features_2 = vision_model(patches, local_features_1)
502
+ # vit_time = time.time()
503
+ local_features = torch.cat((local_features_2[:, 1:], local_features_1.flatten(2).permute(0, 2, 1)), dim=-1)
504
+ local_features = self.projector(local_features)
505
+
506
+
507
+ global_features_1 = sam_model(image_ori)
508
+ global_features_2 = vision_model(image_ori, global_features_1)
509
+ global_features = torch.cat((global_features_2[:, 1:], global_features_1.flatten(2).permute(0, 2, 1)), dim=-1)
510
+ global_features = self.projector(global_features)
511
+
512
+ # print('=====================')
513
+ # print('BASE: ', global_features.shape)
514
+ # print('PATCHES: ', local_features.shape)
515
+ # print('=====================')
516
+
517
+ _, hw, n_dim = global_features.shape
518
+ h = w = int(hw ** 0.5)
519
+
520
+ _2, hw2, n_dim2 = local_features.shape
521
+ h2 = w2 = int(hw2 ** 0.5)
522
+
523
+ width_crop_num, height_crop_num = crop_shape[0], crop_shape[1]
524
+
525
+ global_features = global_features.view(h, w, n_dim)
526
+
527
+ global_features = torch.cat(
528
+ [global_features, self.image_newline[None, None, :].expand(h, 1, n_dim)], dim=1
529
+ )
530
+
531
+ global_features = global_features.view(-1, n_dim)
532
+
533
+
534
+ local_features = local_features.view(height_crop_num, width_crop_num, h2, w2, n_dim2).permute(0, 2, 1, 3, 4).reshape(height_crop_num*h2, width_crop_num*w2, n_dim2)
535
+ local_features = torch.cat(
536
+ [local_features, self.image_newline[None, None, :].expand(height_crop_num * h2, 1, n_dim2)], dim=1
537
+ )
538
+ local_features = local_features.view(-1, n_dim2)
539
+
540
+ global_local_features = torch.cat([local_features, global_features, self.view_seperator[None, :]], dim=0)
541
+ images_in_this_batch.append(global_local_features)
542
+
543
+ # end_time = time.time()
544
+
545
+ # print('sam: ', sam_time - start_time)
546
+ # print('vit: ', vit_time - sam_time)
547
+ # print('all: ', end_time - start_time)
548
+
549
+ # exit()
550
+
551
+ else:
552
+ # Handle single or multiple images in image_ori
553
+ num_imgs = image_ori.shape[0]
554
+ for img_idx in range(num_imgs):
555
+ single_img = image_ori[img_idx:img_idx+1] # [1, 3, H, W]
556
+ global_features_1 = sam_model(single_img)
557
+ global_features_2 = vision_model(single_img, global_features_1)
558
+ global_features = torch.cat((global_features_2[:, 1:], global_features_1.flatten(2).permute(0, 2, 1)), dim=-1)
559
+ global_features = self.projector(global_features)
560
+
561
+ _, hw, n_dim = global_features.shape
562
+ h = w = int(hw ** 0.5)
563
+
564
+ global_features = global_features.view(h, w, n_dim)
565
+
566
+ global_features = torch.cat(
567
+ [global_features, self.image_newline[None, None, :].expand(h, 1, n_dim)], dim=1
568
+ )
569
+
570
+ global_features = global_features.view(-1, n_dim)
571
+
572
+ global_local_features = torch.cat([global_features, self.view_seperator[None, :]], dim=0)
573
+ images_in_this_batch.append(global_local_features)
574
+
575
+
576
+ # print(inputs_embeds.shape)
577
+
578
+ if images_in_this_batch:
579
+ images_in_this_batch = torch.cat(images_in_this_batch, dim=0)
580
+ # exit()
581
+
582
+ inputs_embeds[idx].masked_scatter_(images_seq_mask[idx].unsqueeze(-1).cuda(), images_in_this_batch)
583
+
584
+ idx += 1
585
+
586
+
587
+ return super(UnlimitedOCRModel, self).forward(
588
+ input_ids=None, attention_mask=attention_mask, past_key_values=past_key_values,
589
+ inputs_embeds=inputs_embeds, use_cache=use_cache, position_ids = position_ids,
590
+ output_attentions=output_attentions, output_hidden_states=output_hidden_states,
591
+ return_dict=return_dict
592
+ )
593
+
594
+
595
+ class UnlimitedOCRForCausalLM(DeepseekV2ForCausalLM):
596
+
597
+ config_class = UnlimitedOCRConfig
598
+ # supports_gradient_checkpointing = True
599
+
600
+ def __init__(self, config):
601
+ super(DeepseekV2ForCausalLM, self).__init__(config)
602
+ self.model = UnlimitedOCRModel(config)
603
+
604
+ self.vocab_size = config.vocab_size
605
+
606
+ self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
607
+
608
+ # self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
609
+
610
+ # Initialize weights and apply final processing
611
+ self.post_init()
612
+
613
+ def get_model(self):
614
+ return self.model
615
+
616
+
617
+ def forward(
618
+ self,
619
+ input_ids: torch.LongTensor = None,
620
+ attention_mask: Optional[torch.Tensor] = None,
621
+ position_ids: Optional[torch.LongTensor] = None,
622
+ past_key_values: Optional[List[torch.FloatTensor]] = None,
623
+ inputs_embeds: Optional[torch.FloatTensor] = None,
624
+ labels: Optional[torch.LongTensor] = None,
625
+ use_cache: Optional[bool] = None,
626
+ output_attentions: Optional[bool] = None,
627
+ output_hidden_states: Optional[bool] = None,
628
+ images: Optional[torch.FloatTensor] = None,
629
+ images_seq_mask: Optional[torch.FloatTensor] = None,
630
+ images_spatial_crop: Optional[torch.FloatTensor] = None,
631
+ return_dict: Optional[bool] = None,
632
+
633
+ ) -> Union[Tuple, CausalLMOutputWithPast]:
634
+ output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
635
+ output_hidden_states = (
636
+ output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
637
+ )
638
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
639
+
640
+
641
+
642
+ outputs = self.model(
643
+ input_ids=input_ids,
644
+ past_key_values=past_key_values,
645
+ attention_mask=attention_mask,
646
+ position_ids=position_ids,
647
+ inputs_embeds=inputs_embeds,
648
+ use_cache=use_cache,
649
+ output_attentions=output_attentions,
650
+ output_hidden_states=output_hidden_states,
651
+ images=images,
652
+ images_seq_mask = images_seq_mask,
653
+ images_spatial_crop = images_spatial_crop,
654
+ return_dict=return_dict
655
+
656
+ )
657
+
658
+
659
+
660
+ # print(transformer_outputs)
661
+
662
+ hidden_states = outputs[0]
663
+ logits = self.lm_head(hidden_states)
664
+ logits = logits.float()
665
+
666
+ # logits
667
+
668
+ loss = None
669
+ if labels is not None:
670
+ # Shift so that tokens < n predict n
671
+ shift_logits = logits[..., :-1, :].contiguous()
672
+ shift_labels = labels[..., 1:].contiguous()
673
+ # Flatten the tokens
674
+ loss_fct = CrossEntropyLoss()
675
+ shift_logits = shift_logits.view(-1, self.config.vocab_size)
676
+ shift_labels = shift_labels.view(-1)
677
+ # Enable model parallelism
678
+ shift_labels = shift_labels.to(shift_logits.device)
679
+ loss = loss_fct(shift_logits, shift_labels)
680
+
681
+ if not return_dict:
682
+ output = (logits,) + outputs[1:]
683
+ return (loss,) + output if loss is not None else output
684
+
685
+ return CausalLMOutputWithPast(
686
+ loss=loss,
687
+ logits=logits,
688
+ past_key_values=outputs.past_key_values,
689
+ hidden_states=outputs.hidden_states,
690
+ attentions=outputs.attentions,
691
+ )
692
+
693
+
694
+ def prepare_inputs_for_generation(
695
+ self, input_ids, past_key_values=None, attention_mask=None, inputs_embeds=None, **kwargs
696
+ ):
697
+ # Omit tokens covered by past_key_values
698
+ past_length = 0
699
+ if past_key_values is not None:
700
+ if isinstance(past_key_values, Cache):
701
+ cache_length = past_key_values.get_seq_length()
702
+ past_length = past_key_values.get_seq_length()
703
+ max_cache_length = getattr(past_key_values, 'get_max_length', lambda: None)()
704
+ else:
705
+ cache_length = past_length = past_key_values[0][0].shape[2]
706
+ max_cache_length = None
707
+
708
+ # Ring buffer: cache size is fixed, but we've processed more tokens.
709
+ # Always just take the last token for decode.
710
+ if hasattr(past_key_values, '_prefill_length') and past_length > 0:
711
+ input_ids = input_ids[:, -1:]
712
+ # Keep only the unprocessed tokens:
713
+ # 1 - If the length of the attention_mask exceeds the length of input_ids, then we are in a setting where
714
+ # some of the inputs are exclusively passed as part of the cache (e.g. when passing input_embeds as
715
+ # input)
716
+ elif attention_mask is not None and attention_mask.shape[1] > input_ids.shape[1]:
717
+ input_ids = input_ids[:, -(attention_mask.shape[1] - past_length) :]
718
+ # 2 - If the past_length is smaller than input_ids', then input_ids holds all input tokens. We can discard
719
+ # input_ids based on the past_length.
720
+ elif past_length < input_ids.shape[1]:
721
+ input_ids = input_ids[:, past_length:]
722
+ # 3 - Otherwise (past_length >= input_ids.shape[1]), let's assume input_ids only has unprocessed tokens.
723
+
724
+ # If we are about to go beyond the maximum cache length, we need to crop the input attention mask.
725
+ if (
726
+ max_cache_length is not None
727
+ and attention_mask is not None
728
+ and cache_length + input_ids.shape[1] > max_cache_length
729
+ ):
730
+ attention_mask = attention_mask[:, -max_cache_length:]
731
+
732
+ position_ids = kwargs.get("position_ids", None)
733
+ if attention_mask is not None and position_ids is None:
734
+ # create position_ids on the fly for batch generation
735
+ position_ids = attention_mask.long().cumsum(-1) - 1
736
+ position_ids.masked_fill_(attention_mask == 0, 1)
737
+ if past_key_values:
738
+ position_ids = position_ids[:, -input_ids.shape[1] :]
739
+
740
+ # if self.generation_config.cache_implementation == "static":
741
+ # # generation with static cache
742
+ # cache_position = kwargs.get("cache_position", None)
743
+ # if cache_position is None:
744
+ # past_length = 0
745
+ # else:
746
+ # past_length = cache_position[-1] + 1
747
+ # input_ids = input_ids[:, past_length:]
748
+ # position_ids = position_ids[:, past_length:]
749
+
750
+ # TODO @gante we should only keep a `cache_position` in generate, and do +=1.
751
+ # same goes for position ids. Could also help with continued generation.
752
+ cache_position = torch.arange(past_length, past_length + position_ids.shape[-1], device=position_ids.device)
753
+
754
+ # if `inputs_embeds` are passed, we only want to use them in the 1st generation step
755
+ if inputs_embeds is not None and past_key_values is None:
756
+ model_inputs = {"inputs_embeds": inputs_embeds}
757
+ else:
758
+ model_inputs = {"input_ids": input_ids}
759
+
760
+ # Pass images only on prefill (cache empty or None)
761
+ _is_prefill = (past_key_values is None or
762
+ (isinstance(past_key_values, Cache) and past_key_values.get_seq_length() == 0))
763
+ model_inputs.update(
764
+ {
765
+ "position_ids": position_ids,
766
+ "past_key_values": past_key_values,
767
+ "use_cache": kwargs.get("use_cache"),
768
+ "attention_mask": attention_mask,
769
+ "images": kwargs.get("images", None) if _is_prefill else None,
770
+ "images_seq_mask": kwargs.get("images_seq_mask", None) if _is_prefill else None,
771
+ "images_spatial_crop": kwargs.get("images_spatial_crop", None) if _is_prefill else None,
772
+ }
773
+ )
774
+ return model_inputs
775
+
776
+
777
+ def disable_torch_init(self):
778
+ """
779
+ Disable the redundant torch default initialization to accelerate model creation.
780
+ """
781
+ import torch
782
+ setattr(torch.nn.Linear, "reset_parameters", lambda self: None)
783
+ setattr(torch.nn.LayerNorm, "reset_parameters", lambda self: None)
784
+
785
+
786
+
787
+ def infer(self, tokenizer, prompt='', image_file='', output_path = '', base_size=1024, image_size=640, crop_mode=True, test_compress=False, save_results=False, eval_mode=False, max_length=32768, tps_interval=0, no_repeat_ngram_size=0, ngram_window=0, temperature=0.0):
788
+ self.disable_torch_init()
789
+
790
+ os.makedirs(output_path, exist_ok=True)
791
+ os.makedirs(f'{output_path}/images', exist_ok=True)
792
+
793
+ if prompt and image_file:
794
+ conversation = [
795
+ {
796
+ "role": "<|User|>",
797
+ # "content": "<image>\n<|grounding|>Given the layout of the image. ",
798
+ "content": f'{prompt}',
799
+ # "content": "君不见黄河之水天上来的下一句是什么?",
800
+ # "content": "<image>\nFree OCR. ",
801
+ # "content": "<image>\nParse the figure. ",
802
+ # "content": "<image>\nExtract the text in the image. ",
803
+ "images": [f'{image_file}'],
804
+ },
805
+ {"role": "<|Assistant|>", "content": ""},
806
+ ]
807
+
808
+ elif prompt:
809
+ conversation = [
810
+ {
811
+ "role": "<|User|>",
812
+ # "content": "<image>\n<|grounding|>Given the layout of the image. ",
813
+ "content": f'{prompt}',
814
+ # "content": "君不见黄河之水天上来的下一句是什么?",
815
+ # "content": "<image>\nFree OCR. ",
816
+ # "content": "<image>\nParse the figure. ",
817
+ # "content": "<image>\nExtract the text in the image. ",
818
+ # "images": [f'{image_file}'],
819
+ },
820
+ {"role": "<|Assistant|>", "content": ""},
821
+ ]
822
+ else:
823
+ assert False, f'prompt is none!'
824
+
825
+ prompt = format_messages(conversations=conversation, sft_format='plain', system_prompt='')
826
+
827
+ patch_size = 16
828
+ downsample_ratio = 4
829
+ images = load_pil_images(conversation)
830
+
831
+ valid_img_tokens = 0
832
+ ratio = 1
833
+
834
+ image_draw = images[0].copy()
835
+
836
+ w,h = image_draw.size
837
+ # print(w, h)
838
+ ratio = 1 - ((max(w, h) - min(w, h)) / (max(w, h)))
839
+
840
+
841
+ image_transform=BasicImageTransform(mean=(0.5, 0.5, 0.5), std=(0.5, 0.5, 0.5), normalize=True)
842
+ images_seq_mask = []
843
+
844
+ image_token = '<image>'
845
+ image_token_id = 128815
846
+ text_splits = prompt.split(image_token)
847
+
848
+ images_list, images_crop_list, images_seq_mask = [], [], []
849
+ tokenized_str = []
850
+ images_spatial_crop = []
851
+ for text_sep, image in zip(text_splits, images):
852
+
853
+ tokenized_sep = text_encode(tokenizer, text_sep, bos=False, eos=False)
854
+ tokenized_str += tokenized_sep
855
+ images_seq_mask += [False] * len(tokenized_sep)
856
+
857
+ if crop_mode:
858
+
859
+ if image.size[0] <= 640 and image.size[1] <= 640:
860
+ crop_ratio = [1, 1]
861
+
862
+ else:
863
+ if crop_mode:
864
+ # best_width, best_height = select_best_resolution(image.size, self.candidate_resolutions)
865
+ images_crop_raw, crop_ratio = dynamic_preprocess(image)
866
+ else:
867
+ # best_width, best_height = self.image_size, self.image_size
868
+ crop_ratio = [1, 1]
869
+
870
+ """process the global view"""
871
+ # image = image.resize((base_size, base_size))
872
+ global_view = ImageOps.pad(image, (base_size, base_size),
873
+ color=tuple(int(x * 255) for x in image_transform.mean))
874
+
875
+ if base_size == 1024:
876
+ valid_img_tokens += int(256 * ratio)
877
+ elif base_size == 1280:
878
+ valid_img_tokens += int(400 * ratio)
879
+ # elif base_size == 640:
880
+ # valid_img_tokens += int(100 * ratio)
881
+
882
+
883
+
884
+
885
+
886
+ images_list.append(image_transform(global_view).to(torch.bfloat16))
887
+
888
+ # global_view_tensor = image_transform(global_view).to(torch.bfloat16)
889
+
890
+ width_crop_num, height_crop_num = crop_ratio
891
+
892
+ images_spatial_crop.append([width_crop_num, height_crop_num])
893
+
894
+
895
+ if width_crop_num > 1 or height_crop_num > 1:
896
+ """process the local views"""
897
+
898
+ for i in range(len(images_crop_raw)):
899
+ images_crop_list.append(image_transform(images_crop_raw[i]).to(torch.bfloat16))
900
+
901
+ if image_size == 640:
902
+ valid_img_tokens += len(images_crop_list) * 100
903
+
904
+ num_queries = math.ceil((image_size // patch_size) / downsample_ratio)
905
+ num_queries_base = math.ceil((base_size // patch_size) / downsample_ratio)
906
+
907
+
908
+
909
+ """add image tokens"""
910
+
911
+
912
+
913
+ tokenized_image = ([image_token_id] * num_queries_base + [image_token_id]) * num_queries_base
914
+ tokenized_image += [image_token_id]
915
+ if width_crop_num > 1 or height_crop_num > 1:
916
+ tokenized_image += ([image_token_id] * (num_queries * width_crop_num) + [image_token_id]) * (
917
+ num_queries * height_crop_num)
918
+ tokenized_str += tokenized_image
919
+ images_seq_mask += [True] * len(tokenized_image)
920
+ # num_image_tokens.append(len(tokenized_image))
921
+
922
+ else:
923
+ # best_width, best_height = self.image_size, self.image_size
924
+ # print(image.size, (best_width, best_height)) # check the select_best_resolutions func
925
+
926
+ """process the global view"""
927
+ if image_size <= 640:
928
+ print('directly resize')
929
+ image = image.resize((image_size, image_size))
930
+ # else:
931
+ global_view = ImageOps.pad(image, (image_size, image_size),
932
+ color=tuple(int(x * 255) for x in image_transform.mean))
933
+ images_list.append(image_transform(global_view).to(torch.bfloat16))
934
+
935
+ if base_size == 1024:
936
+ valid_img_tokens += int(256 * ratio)
937
+ elif base_size == 1280:
938
+ valid_img_tokens += int(400 * ratio)
939
+ elif base_size == 640:
940
+ valid_img_tokens += int(100 * 1)
941
+ elif base_size == 512:
942
+ valid_img_tokens += int(64 * 1)
943
+
944
+ width_crop_num, height_crop_num = 1, 1
945
+
946
+ images_spatial_crop.append([width_crop_num, height_crop_num])
947
+
948
+
949
+ """add image tokens"""
950
+ num_queries = math.ceil((image_size // patch_size) / downsample_ratio)
951
+
952
+ tokenized_image = ([image_token_id] * num_queries + [image_token_id]) * num_queries
953
+ tokenized_image += [image_token_id]
954
+ # tokenized_image += ([self.image_token_id] * (num_queries * width_crop_num) + [self.image_token_id]) * (
955
+ # num_queries * height_crop_num)
956
+ tokenized_str += tokenized_image
957
+ images_seq_mask += [True] * len(tokenized_image)
958
+ # num_image_tokens.append(len(tokenized_image))
959
+
960
+
961
+ """process the last text split"""
962
+ tokenized_sep = text_encode(tokenizer, text_splits[-1], bos=False, eos=False)
963
+ tokenized_str += tokenized_sep
964
+ images_seq_mask += [False] * len(tokenized_sep)
965
+
966
+ """add the bos tokens"""
967
+ bos_id = 0
968
+ tokenized_str = [bos_id] + tokenized_str
969
+ images_seq_mask = [False] + images_seq_mask
970
+
971
+
972
+
973
+ input_ids = torch.LongTensor(tokenized_str)
974
+
975
+
976
+
977
+
978
+ images_seq_mask = torch.tensor(images_seq_mask, dtype=torch.bool)
979
+
980
+
981
+ if len(images_list) == 0:
982
+ images_ori = torch.zeros((1, 3, image_size, image_size))
983
+ images_spatial_crop = torch.zeros((1, 2), dtype=torch.long)
984
+ images_crop = torch.zeros((1, 3, base_size, base_size))
985
+
986
+ else:
987
+ images_ori = torch.stack(images_list, dim=0)
988
+ images_spatial_crop = torch.tensor(images_spatial_crop, dtype=torch.long)
989
+ if images_crop_list:
990
+ images_crop = torch.stack(images_crop_list, dim=0)
991
+ else:
992
+ images_crop = torch.zeros((1, 3, base_size, base_size))
993
+
994
+
995
+
996
+ if not eval_mode:
997
+ streamer = TPSTextStreamer(tokenizer, interval=tps_interval, skip_prompt=True, skip_special_tokens=False)
998
+ _orig_sw = getattr(self.config, 'sliding_window_size', None) or getattr(self.config, 'sliding_window', None)
999
+ self.config._ring_window = _orig_sw
1000
+ self.config.sliding_window = None
1001
+ # Build logits processors for ngram
1002
+ gen_kwargs = dict(
1003
+ input_ids=input_ids.unsqueeze(0).cuda(),
1004
+ images=[(images_crop.cuda(), images_ori.cuda())],
1005
+ images_seq_mask=images_seq_mask.unsqueeze(0).cuda(),
1006
+ images_spatial_crop=images_spatial_crop,
1007
+ do_sample=temperature > 0,
1008
+ temperature=temperature if temperature > 0 else None,
1009
+ eos_token_id=tokenizer.eos_token_id,
1010
+ streamer=streamer,
1011
+ max_length=max_length,
1012
+ use_cache=True
1013
+ )
1014
+ if no_repeat_ngram_size > 0 and ngram_window > 0:
1015
+ gen_kwargs['logits_processor'] = [SlidingWindowNoRepeatNgramProcessor(no_repeat_ngram_size, ngram_window)]
1016
+ elif no_repeat_ngram_size > 0:
1017
+ gen_kwargs['no_repeat_ngram_size'] = no_repeat_ngram_size
1018
+ with torch.autocast("cuda", dtype=torch.bfloat16):
1019
+ with torch.no_grad():
1020
+ output_ids = self.generate(**gen_kwargs)
1021
+ self.config.sliding_window = _orig_sw
1022
+
1023
+ else:
1024
+ _orig_sw = getattr(self.config, 'sliding_window_size', None) or getattr(self.config, 'sliding_window', None)
1025
+ self.config._ring_window = _orig_sw
1026
+ self.config.sliding_window = None
1027
+ gen_kwargs = dict(
1028
+ input_ids=input_ids.unsqueeze(0).cuda(),
1029
+ images=[(images_crop.cuda(), images_ori.cuda())],
1030
+ images_seq_mask=images_seq_mask.unsqueeze(0).cuda(),
1031
+ images_spatial_crop=images_spatial_crop,
1032
+ do_sample=temperature > 0,
1033
+ temperature=temperature if temperature > 0 else None,
1034
+ eos_token_id=tokenizer.eos_token_id,
1035
+ max_length=max_length,
1036
+ use_cache=True
1037
+ )
1038
+ if no_repeat_ngram_size > 0 and ngram_window > 0:
1039
+ gen_kwargs['logits_processor'] = [SlidingWindowNoRepeatNgramProcessor(no_repeat_ngram_size, ngram_window)]
1040
+ elif no_repeat_ngram_size > 0:
1041
+ gen_kwargs['no_repeat_ngram_size'] = no_repeat_ngram_size
1042
+ with torch.autocast("cuda", dtype=torch.bfloat16):
1043
+ with torch.no_grad():
1044
+ output_ids = self.generate(**gen_kwargs)
1045
+ self.config.sliding_window = _orig_sw
1046
+
1047
+
1048
+ if '<image>' in conversation[0]['content'] and eval_mode:
1049
+ outputs = tokenizer.decode(output_ids[0, input_ids.unsqueeze(0).cuda().shape[1]:])
1050
+ stop_str = '<|end▁of▁sentence|>'
1051
+ if outputs.endswith(stop_str):
1052
+ outputs = outputs[:-len(stop_str)]
1053
+ # re_match
1054
+ outputs = outputs.strip()
1055
+
1056
+ return outputs
1057
+
1058
+ if '<image>' in conversation[0]['content'] and test_compress:
1059
+ outputs = tokenizer.decode(output_ids[0, input_ids.unsqueeze(0).cuda().shape[1]:])
1060
+ pure_texts_outputs_token_length = len(text_encode(tokenizer, outputs, bos=False, eos=False))
1061
+ print('='*50)
1062
+ print('image size: ', (w, h))
1063
+ print('valid image tokens: ', int(valid_img_tokens))
1064
+ print('output texts tokens (valid): ', pure_texts_outputs_token_length)
1065
+ print('compression ratio: ', round(pure_texts_outputs_token_length/valid_img_tokens, 2))
1066
+ print('='*50)
1067
+
1068
+
1069
+ if '<image>' in conversation[0]['content'] and save_results:
1070
+ outputs = tokenizer.decode(output_ids[0, input_ids.unsqueeze(0).cuda().shape[1]:])
1071
+ stop_str = '<|end▁of▁sentence|>'
1072
+
1073
+ print('='*15 + 'save results:' + '='*15)
1074
+
1075
+ # # # # conv.messages[-1][-1] = outputs
1076
+ if outputs.endswith(stop_str):
1077
+ outputs = outputs[:-len(stop_str)]
1078
+ outputs = outputs.strip()
1079
+
1080
+ matches_ref, matches_images, mathes_other = re_match(outputs)
1081
+ # print(matches_ref)
1082
+ result = process_image_with_refs(image_draw, matches_ref, output_path)
1083
+
1084
+
1085
+ for idx, a_match_image in enumerate(tqdm(matches_images, desc="image")):
1086
+ outputs = outputs.replace(a_match_image, '![](images/' + str(idx) + '.jpg)\n')
1087
+
1088
+ for idx, a_match_other in enumerate(tqdm(mathes_other, desc="other")):
1089
+ outputs = outputs.replace(a_match_other, '').replace('\\coloneqq', ':=').replace('\\eqqcolon', '=:')
1090
+
1091
+
1092
+ # if 'structural formula' in conversation[0]['content']:
1093
+ # outputs = '<smiles>' + outputs + '</smiles>'
1094
+ with open(f'{output_path}/result.md', 'w', encoding = 'utf-8') as afile:
1095
+ afile.write(outputs)
1096
+
1097
+ if 'line_type' in outputs:
1098
+ import matplotlib.pyplot as plt
1099
+ lines = eval(outputs)['Line']['line']
1100
+
1101
+ line_type = eval(outputs)['Line']['line_type']
1102
+ # print(lines)
1103
+
1104
+ endpoints = eval(outputs)['Line']['line_endpoint']
1105
+
1106
+ fig, ax = plt.subplots(figsize=(3,3), dpi=200)
1107
+ ax.set_xlim(-15, 15)
1108
+ ax.set_ylim(-15, 15)
1109
+
1110
+ for idx, line in enumerate(lines):
1111
+ try:
1112
+ p0 = eval(line.split(' -- ')[0])
1113
+ p1 = eval(line.split(' -- ')[-1])
1114
+
1115
+ if line_type[idx] == '--':
1116
+ ax.plot([p0[0], p1[0]], [p0[1], p1[1]], linewidth=0.8, color='k')
1117
+ else:
1118
+ ax.plot([p0[0], p1[0]], [p0[1], p1[1]], linewidth = 0.8, color = 'k')
1119
+
1120
+ ax.scatter(p0[0], p0[1], s=5, color = 'k')
1121
+ ax.scatter(p1[0], p1[1], s=5, color = 'k')
1122
+ except:
1123
+ pass
1124
+
1125
+ for endpoint in endpoints:
1126
+
1127
+ label = endpoint.split(': ')[0]
1128
+ (x, y) = eval(endpoint.split(': ')[1])
1129
+ ax.annotate(label, (x, y), xytext=(1, 1), textcoords='offset points',
1130
+ fontsize=5, fontweight='light')
1131
+
1132
+
1133
+ plt.savefig(f'{output_path}/geo.jpg')
1134
+ plt.close()
1135
+
1136
+ result.save(f"{output_path}/result_with_boxes.jpg")
1137
+
1138
+
1139
+ def infer_multi(self, tokenizer, prompt='', image_files=None, output_path='', image_size=640, save_results=False, max_length=32768, tps_interval=0, no_repeat_ngram_size=0, ngram_window=0, temperature=0.0):
1140
+ """
1141
+ Multi-image inference. Does NOT support crop mode.
1142
+ Prompt uses a single <image> token (e.g. "<image>Multi page parsing.").
1143
+ All images' token sequences are concatenated at that single <image> position,
1144
+ separated by a single image_token_id between each image (same as crop mode separator).
1145
+
1146
+ Args:
1147
+ prompt: text prompt with one <image> token, e.g. "<image>Multi page parsing."
1148
+ image_files: list of image file paths
1149
+ image_size: size to resize each image to
1150
+ save_results: whether to save output to file
1151
+ """
1152
+ self.disable_torch_init()
1153
+
1154
+ if image_files is None or len(image_files) == 0:
1155
+ assert False, 'image_files must be a non-empty list for multi-image inference!'
1156
+
1157
+ os.makedirs(output_path, exist_ok=True)
1158
+ os.makedirs(f'{output_path}/images', exist_ok=True)
1159
+
1160
+ # Prompt contains a single <image>, all image files go into "images" list
1161
+ conversation = [
1162
+ {
1163
+ "role": "<|User|>",
1164
+ "content": f'{prompt}',
1165
+ "images": image_files,
1166
+ },
1167
+ {"role": "<|Assistant|>", "content": ""},
1168
+ ]
1169
+
1170
+ formatted_prompt = format_messages(conversations=conversation, sft_format='plain', system_prompt='')
1171
+
1172
+ patch_size = 16
1173
+ downsample_ratio = 4
1174
+
1175
+ # Load all images
1176
+ images = load_pil_images(conversation)
1177
+
1178
+ image_transform = BasicImageTransform(mean=(0.5, 0.5, 0.5), std=(0.5, 0.5, 0.5), normalize=True)
1179
+
1180
+ image_token = '<image>'
1181
+ image_token_id = 128815
1182
+
1183
+ # Split on the single <image> token -> 2 parts: before and after
1184
+ text_splits = formatted_prompt.split(image_token)
1185
+
1186
+ images_list, images_seq_mask = [], []
1187
+ tokenized_str = []
1188
+ images_spatial_crop = []
1189
+
1190
+ num_queries = math.ceil((image_size // patch_size) / downsample_ratio)
1191
+
1192
+ # Tokenize text before <image>
1193
+ tokenized_sep = text_encode(tokenizer, text_splits[0], bos=False, eos=False)
1194
+ tokenized_str += tokenized_sep
1195
+ images_seq_mask += [False] * len(tokenized_sep)
1196
+
1197
+ # Process all images at the single <image> position
1198
+ for idx, image in enumerate(images):
1199
+ # Match single-image logic: if image_size <= 640, resize all images
1200
+ if image_size <= 640:
1201
+ image = image.resize((image_size, image_size))
1202
+ global_view = ImageOps.pad(image, (image_size, image_size),
1203
+ color=tuple(int(x * 255) for x in image_transform.mean))
1204
+
1205
+ images_list.append(image_transform(global_view).to(torch.bfloat16))
1206
+ images_spatial_crop.append([1, 1])
1207
+
1208
+ # Image tokens for this image (same structure as single-image non-crop mode)
1209
+ tokenized_image = ([image_token_id] * num_queries + [image_token_id]) * num_queries
1210
+ tokenized_image += [image_token_id] # separator token between images
1211
+ tokenized_str += tokenized_image
1212
+ images_seq_mask += [True] * len(tokenized_image)
1213
+
1214
+ # Tokenize text after <image>
1215
+ tokenized_sep = text_encode(tokenizer, text_splits[1], bos=False, eos=False)
1216
+ tokenized_str += tokenized_sep
1217
+ images_seq_mask += [False] * len(tokenized_sep)
1218
+
1219
+ # Add bos token
1220
+ bos_id = 0
1221
+ tokenized_str = [bos_id] + tokenized_str
1222
+ images_seq_mask = [False] + images_seq_mask
1223
+
1224
+ input_ids = torch.LongTensor(tokenized_str)
1225
+ images_seq_mask = torch.tensor(images_seq_mask, dtype=torch.bool)
1226
+
1227
+ # Stack all images as image_ori; dummy_crop is zeros (triggers no-crop branch)
1228
+ images_ori = torch.stack(images_list, dim=0) # [N, 3, H, W]
1229
+ images_spatial_crop = torch.tensor(images_spatial_crop, dtype=torch.long)
1230
+ dummy_crop = torch.zeros((1, 3, image_size, image_size))
1231
+
1232
+ streamer = TPSTextStreamer(tokenizer, interval=tps_interval, skip_prompt=True, skip_special_tokens=False)
1233
+ # Disable config.sliding_window to prevent DynamicCache from truncating prefill tokens.
1234
+ # The ring buffer in SlidingWindowLlamaAttention handles sliding window manually.
1235
+ _orig_sw = getattr(self.config, 'sliding_window_size', None) or getattr(self.config, 'sliding_window', None)
1236
+ self.config._ring_window = _orig_sw # Save for ring buffer to read
1237
+ self.config.sliding_window = None
1238
+ with torch.autocast("cuda", dtype=torch.bfloat16):
1239
+ with torch.no_grad():
1240
+ gen_kwargs = dict(
1241
+ input_ids=input_ids.unsqueeze(0).cuda(),
1242
+ images=[(dummy_crop.cuda(), images_ori.cuda())],
1243
+ images_seq_mask=images_seq_mask.unsqueeze(0).cuda(),
1244
+ images_spatial_crop=images_spatial_crop,
1245
+ do_sample=temperature > 0,
1246
+ temperature=temperature if temperature > 0 else None,
1247
+ eos_token_id=tokenizer.eos_token_id,
1248
+ streamer=streamer,
1249
+ max_length=max_length,
1250
+ use_cache=True
1251
+ )
1252
+ if no_repeat_ngram_size > 0 and ngram_window > 0:
1253
+ gen_kwargs['logits_processor'] = [SlidingWindowNoRepeatNgramProcessor(no_repeat_ngram_size, ngram_window)]
1254
+ elif no_repeat_ngram_size > 0:
1255
+ gen_kwargs['no_repeat_ngram_size'] = no_repeat_ngram_size
1256
+ output_ids = self.generate(**gen_kwargs)
1257
+ self.config.sliding_window = _orig_sw # Restore
1258
+
1259
+ outputs = tokenizer.decode(output_ids[0, input_ids.unsqueeze(0).cuda().shape[1]:])
1260
+ stop_str = '<|end▁of▁sentence|>'
1261
+ if outputs.endswith(stop_str):
1262
+ outputs = outputs[:-len(stop_str)]
1263
+ outputs = outputs.strip()
1264
+
1265
+ output_tokens = len(text_encode(tokenizer, outputs, bos=False, eos=False))
1266
+
1267
+ if save_results:
1268
+ print('=' * 15 + 'save results:' + '=' * 15)
1269
+ pages = outputs.split('<PAGE>')[1:]
1270
+ processed_pages = []
1271
+ for page_idx, page_output in enumerate(pages):
1272
+ page_output = page_output.strip()
1273
+ if page_idx >= len(images):
1274
+ processed_pages.append(page_output)
1275
+ continue
1276
+
1277
+ matches_ref, matches_images, mathes_other = re_match(page_output)
1278
+ image_prefix = f'page_{page_idx}_'
1279
+ result = process_image_with_refs(
1280
+ images[page_idx].copy(),
1281
+ matches_ref,
1282
+ output_path,
1283
+ image_prefix=image_prefix,
1284
+ )
1285
+ result.save(f"{output_path}/result_with_boxes_{page_idx}.jpg")
1286
+
1287
+ for idx, a_match_image in enumerate(tqdm(matches_images, desc=f"image_page_{page_idx}")):
1288
+ page_output = page_output.replace(a_match_image, f'![](images/{image_prefix}{idx}.jpg)\n')
1289
+
1290
+ for idx, a_match_other in enumerate(tqdm(mathes_other, desc=f"other_page_{page_idx}")):
1291
+ page_output = page_output.replace(a_match_other, '').replace('\\coloneqq', ':=').replace('\\eqqcolon', '=:')
1292
+
1293
+ processed_pages.append(page_output)
1294
+
1295
+ outputs = '<PAGE>\n' + '\n<PAGE>\n'.join(processed_pages)
1296
+ with open(f'{output_path}/result.md', 'w', encoding='utf-8') as afile:
1297
+ afile.write(outputs)
1298
+
1299
+ return outputs, output_tokens
processor_config.json ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_special_token": false,
3
+ "candidate_resolutions": [
4
+ [
5
+ 1024,
6
+ 1024
7
+ ]
8
+ ],
9
+ "downsample_ratio": 4,
10
+ "ignore_id": -100,
11
+ "image_mean": [
12
+ 0.5,
13
+ 0.5,
14
+ 0.5
15
+ ],
16
+ "image_std": [
17
+ 0.5,
18
+ 0.5,
19
+ 0.5
20
+ ],
21
+ "image_token": "<image>",
22
+ "mask_prompt": false,
23
+ "normalize": true,
24
+ "pad_token": "<\uff5c\u2581pad\u2581\uff5c>",
25
+ "patch_size": 16,
26
+ "processor_class": "UnlimitedOCRHFProcessor",
27
+ "sft_format": "unlimitedocr"
28
+ }
special_tokens_map.json ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "additional_special_tokens": [
3
+ {
4
+ "content": "<|User|>",
5
+ "lstrip": false,
6
+ "normalized": false,
7
+ "rstrip": false,
8
+ "single_word": false
9
+ },
10
+ {
11
+ "content": "<|Assistant|>",
12
+ "lstrip": false,
13
+ "normalized": false,
14
+ "rstrip": false,
15
+ "single_word": false
16
+ }
17
+ ],
18
+ "bos_token": {
19
+ "content": "<|begin▁of▁sentence|>",
20
+ "lstrip": false,
21
+ "normalized": false,
22
+ "rstrip": false,
23
+ "single_word": false
24
+ },
25
+ "eos_token": {
26
+ "content": "<|end▁of▁sentence|>",
27
+ "lstrip": false,
28
+ "normalized": false,
29
+ "rstrip": false,
30
+ "single_word": false
31
+ },
32
+ "pad_token": {
33
+ "content": "<|▁pad▁|>",
34
+ "lstrip": false,
35
+ "normalized": false,
36
+ "rstrip": false,
37
+ "single_word": false
38
+ }
39
+ }
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json ADDED
The diff for this file is too large to render. See raw diff
 
wheel/sglang-0.0.0.dev11416+g92e8bb79e-py3-none-any.whl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2644a1f349c55f0ca822e70a70679c98475754ec4722c3be1b18a72bac477cd5
3
+ size 12450224