blockblockblock commited on
Commit
6db40e4
·
verified ·
1 Parent(s): 31beb3a

Upload folder using huggingface_hub

Browse files
.gitattributes CHANGED
@@ -33,3 +33,12 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ teaser.jpg filter=lfs diff=lfs merge=lfs -text
37
+ assets/decoding_demo.mp4 filter=lfs diff=lfs merge=lfs -text
38
+ assets/demo.mp4 filter=lfs diff=lfs merge=lfs -text
39
+ assets/coco_lvis.png filter=lfs diff=lfs merge=lfs -text
40
+ assets/dense_object_detection.png filter=lfs diff=lfs merge=lfs -text
41
+ assets/layout_ocr.png filter=lfs diff=lfs merge=lfs -text
42
+ assets/referring.png filter=lfs diff=lfs merge=lfs -text
43
+ assets/sspro.png filter=lfs diff=lfs merge=lfs -text
44
+ tokenizer.json filter=lfs diff=lfs merge=lfs -text
LICENSE ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ NVIDIA License
2
+
3
+ 1. Definitions
4
+
5
+ “Licensor” means any person or entity that distributes its Work.
6
+
7
+ “Work” means (a) the original work of authorship made available under this license,
8
+ which may include software, documentation, or other files, and (b) any additions to or
9
+ derivative works thereof that are made available under this license.
10
+
11
+ The terms “reproduce,” “reproduction,” “derivative works,” and “distribution” have the
12
+ meaning as provided under U.S. copyright law; provided, however, that for the purposes
13
+ of this license, derivative works shall not include works that remain separable from, or
14
+ merely link (or bind by name) to the interfaces of, the Work.
15
+
16
+ Works are “made available” under this license by including in or with the Work either
17
+ (a) a copyright notice referencing the applicability of this license to the Work, or
18
+ (b) a copy of this license.
19
+
20
+ 2. License Grant
21
+
22
+ 2.1 Copyright Grant. Subject to the terms and conditions of this license, each Licensor
23
+ grants to you a perpetual, worldwide, non-exclusive, royalty-free, copyright license to
24
+ use, reproduce, prepare derivative works of, publicly display, publicly perform,
25
+ sublicense and distribute its Work and any resulting derivative works in any form.
26
+
27
+ 3. Limitations
28
+
29
+ 3.1 Redistribution. You may reproduce or distribute the Work only if (a) you do so under
30
+ this license, (b) you include a complete copy of this license with your distribution,
31
+ and (c) you retain without modification any copyright, patent, trademark, or attribution
32
+ notices that are present in the Work.
33
+
34
+ 3.2 Derivative Works. You may specify that additional or different terms apply to the
35
+ use, reproduction, and distribution of your derivative works of the Work (“Your Terms”)
36
+ only if (a) Your Terms provide that the use limitation in Section 3.3 applies to your
37
+ derivative works, and (b) you identify the specific derivative works that are subject
38
+ to Your Terms. Notwithstanding Your Terms, this license (including the redistribution
39
+ requirements in Section 3.1) will continue to apply to the Work itself.
40
+
41
+ 3.3 Use Limitation. The Work and any derivative works thereof only may be used or
42
+ intended for use non-commercially. Notwithstanding the foregoing, NVIDIA Corporation
43
+ and its affiliates may use the Work and any derivative works commercially. As used
44
+ herein, “non-commercially” means for research or evaluation purposes only.
45
+
46
+ 3.4 Patent Claims. If you bring or threaten to bring a patent claim against any
47
+ Licensor (including any claim, cross-claim or counterclaim in a lawsuit) to enforce any
48
+ patents that you allege are infringed by any Work, then your rights under this license
49
+ from such Licensor (including the grant in Section 2.1) will terminate immediately.
50
+
51
+ 3.5 Trademarks. This license does not grant any rights to use any Licensor’s or its
52
+ affiliates’ names, logos, or trademarks, except as necessary to reproduce the notices
53
+ described in this license.
54
+
55
+ 3.6 Termination. If you violate any term of this license, then your rights under this
56
+ license (including the grant in Section 2.1) will terminate immediately.
57
+
58
+ 4. Disclaimer of Warranty.
59
+
60
+ THE WORK IS PROVIDED “AS IS” WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
61
+ EXPRESS OR IMPLIED, INCLUDING WARRANTIES OR CONDITIONS OF MERCHANTABILITY, FITNESS FOR
62
+ A PARTICULAR PURPOSE, TITLE OR NON-INFRINGEMENT. YOU BEAR THE RISK OF UNDERTAKING ANY
63
+ ACTIVITIES UNDER THIS LICENSE.
64
+
65
+ 5. Limitation of Liability.
66
+
67
+ EXCEPT AS PROHIBITED BY APPLICABLE LAW, IN NO EVENT AND UNDER NO LEGAL THEORY, WHETHER
68
+ IN TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE SHALL ANY LICENSOR BE LIABLE TO
69
+ YOU FOR DAMAGES, INCLUDING ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
70
+ DAMAGES ARISING OUT OF OR RELATED TO THIS LICENSE, THE USE OR INABILITY TO USE THE WORK
71
+ (INCLUDING BUT NOT LIMITED TO LOSS OF GOODWILL, BUSINESS INTERRUPTION, LOST PROFITS OR
72
+ DATA, COMPUTER FAILURE OR MALFUNCTION, OR ANY OTHER DAMAGES OR LOSSES), EVEN IF THE
73
+ LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
74
+
README.md ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: other
3
+ base_model: nvidia/LocateAnything-3B
4
+ base_model_relation: quantized
5
+ quantized_by: blockblockblock
6
+ library_name: exllamav3
7
+ pipeline_tag: text-generation
8
+ tags:
9
+ - exl3
10
+ - exllamav3
11
+ - quantized
12
+
13
+ quantization_format: exl3
14
+ bits_per_weight: 6.0
15
+ ---
16
+
17
+ <div align="center">
18
+
19
+ # LocateAnything · 3B
20
+
21
+ <sub><code>EXL3</code> &nbsp;·&nbsp; <b>6.0&nbsp;bpw</b> &nbsp;·&nbsp; 3.9&nbsp;GB &nbsp;·&nbsp; Dense</sub>
22
+
23
+ <br/>
24
+
25
+ [![format](https://img.shields.io/badge/format-EXL3-c63010?style=for-the-badge&labelColor=14120e)](https://github.com/turboderp-org/exllamav3)
26
+ [![bpw](https://img.shields.io/badge/bpw-6.0-6b8a76?style=for-the-badge&labelColor=14120e)](#quants)
27
+ [![size](https://img.shields.io/badge/size-3.9_GB-6b8a76?style=for-the-badge&labelColor=14120e)](#quants)
28
+ [![arch](https://img.shields.io/badge/arch-Dense_3B-c63010?style=for-the-badge&labelColor=14120e)](https://huggingface.co/nvidia/LocateAnything-3B)
29
+
30
+ [![base model](https://img.shields.io/badge/Base-nvidia%2FLocateAnything--3B-2a2620?style=flat-square&logo=huggingface&logoColor=white)](https://huggingface.co/nvidia/LocateAnything-3B)
31
+ [![quantized by](https://img.shields.io/badge/Quantized_by-blockblockblock-2a2620?style=flat-square&logo=huggingface&logoColor=white)](https://huggingface.co/blockblockblock)
32
+ [![collection](https://img.shields.io/badge/All_bpws-Collection-c63010?style=flat-square&logo=huggingface&logoColor=white)](https://huggingface.co/collections/blockblockblock/locateanything-3b-exl3-6a205fbdd9aee1d0eba42b33)
33
+
34
+ </div>
35
+
36
+ ---
37
+
38
+ > [!NOTE]
39
+ > An [ExLlamaV3](https://github.com/turboderp-org/exllamav3) build of [`nvidia/LocateAnything-3B`](https://huggingface.co/nvidia/LocateAnything-3B) at **6.0 bits per weight**. See [Quants](#quants) for sibling repos at other bit&#8209;widths or browse the [collection](https://huggingface.co/collections/blockblockblock/locateanything-3b-exl3-6a205fbdd9aee1d0eba42b33).
40
+
41
+ ## Quants
42
+
43
+ <div align="center">
44
+
45
+ | BPW &nbsp; | &nbsp; Head bits &nbsp; | &nbsp; Calibration rows &nbsp; | &nbsp; Size &nbsp; | &nbsp; Status |
46
+ | :---: | :---: | :---: | ---: | :--- |
47
+ | **6.0** | 8 | 250 | **3.9&nbsp;GB** | <kbd>this repo</kbd> |
48
+
49
+ </div>
50
+
51
+ ## Inference
52
+
53
+ <table>
54
+ <thead>
55
+ <tr>
56
+ <th align="left" width="32%">Loader</th>
57
+ <th align="left">Use it for</th>
58
+ </tr>
59
+ </thead>
60
+ <tbody>
61
+ <tr>
62
+ <td><a href="https://github.com/theroyallab/tabbyAPI"><b>TabbyAPI</b></a></td>
63
+ <td>OpenAI&#8209;compatible HTTP server. Drop&#8209;in for OpenAI clients.</td>
64
+ </tr>
65
+ <tr>
66
+ <td><a href="https://github.com/oobabooga/text-generation-webui"><b>text&#8209;generation&#8209;webui</b></a></td>
67
+ <td>Local chat UI. Pick the <i>ExLlamaV3</i> loader from the model dropdown.</td>
68
+ </tr>
69
+ <tr>
70
+ <td><a href="https://github.com/turboderp-org/exllamav3"><b>ExLlamaV3</b></a></td>
71
+ <td>Direct Python API for embedding the model in your own code or pipeline.</td>
72
+ </tr>
73
+ </tbody>
74
+ </table>
75
+
76
+ ## Download
77
+
78
+ ```bash
79
+ pip install -U huggingface_hub
80
+
81
+ hf download \
82
+ blockblockblock/LocateAnything-3B-exl3-6.0bpw \
83
+ --local-dir ./LocateAnything-3B-exl3-6.0bpw
84
+ ```
85
+
86
+ <details>
87
+ <summary><b>Quantization recipe</b> &nbsp;<sub>(advanced, embedded in <code>quantization_config.json</code>)</sub></summary>
88
+
89
+ <br/>
90
+
91
+ | Setting | Value |
92
+ | :--- | :--- |
93
+ | Format | `EXL3` |
94
+ | Bits per weight | `6.0` |
95
+ | Head bits | `8` |
96
+ | Calibration rows | `250` |
97
+ | Codebook | `MCG` |
98
+ | Out&#8209;scales | `always` |
99
+ | Parallel mode | `enabled` |
100
+
101
+ Loaded automatically by every ExLlamaV3 loader; reproduced here for searchability.
102
+
103
+ </details>
104
+
105
+ ## License &amp; use
106
+
107
+ > [!IMPORTANT]
108
+ > Use and license **follow the [base model](https://huggingface.co/nvidia/LocateAnything-3B)**.
109
+ > Quantization adds no additional restrictions. Refer to the upstream repository for terms, citation, and safety documentation.
110
+
111
+ ---
112
+
113
+ <div align="center">
114
+ <sub><i>Quantized with <a href="https://github.com/Honkware/blockquant"><b>BlockQuant</b></a> &nbsp;·&nbsp; convention&nbsp;<code>{org}/{model}-exl3-{bpw}bpw</code></i></sub>
115
+ </div>
added_tokens.json ADDED
@@ -0,0 +1,1040 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "</box>": 151669,
3
+ "</c>": 152680,
4
+ "</img>": 151667,
5
+ "</interval>": 151675,
6
+ "</quad>": 151671,
7
+ "</ref>": 151673,
8
+ "</tool_call>": 151658,
9
+ "<0>": 151677,
10
+ "<1000>": 152677,
11
+ "<100>": 151777,
12
+ "<101>": 151778,
13
+ "<102>": 151779,
14
+ "<103>": 151780,
15
+ "<104>": 151781,
16
+ "<105>": 151782,
17
+ "<106>": 151783,
18
+ "<107>": 151784,
19
+ "<108>": 151785,
20
+ "<109>": 151786,
21
+ "<10>": 151687,
22
+ "<110>": 151787,
23
+ "<111>": 151788,
24
+ "<112>": 151789,
25
+ "<113>": 151790,
26
+ "<114>": 151791,
27
+ "<115>": 151792,
28
+ "<116>": 151793,
29
+ "<117>": 151794,
30
+ "<118>": 151795,
31
+ "<119>": 151796,
32
+ "<11>": 151688,
33
+ "<120>": 151797,
34
+ "<121>": 151798,
35
+ "<122>": 151799,
36
+ "<123>": 151800,
37
+ "<124>": 151801,
38
+ "<125>": 151802,
39
+ "<126>": 151803,
40
+ "<127>": 151804,
41
+ "<128>": 151805,
42
+ "<129>": 151806,
43
+ "<12>": 151689,
44
+ "<130>": 151807,
45
+ "<131>": 151808,
46
+ "<132>": 151809,
47
+ "<133>": 151810,
48
+ "<134>": 151811,
49
+ "<135>": 151812,
50
+ "<136>": 151813,
51
+ "<137>": 151814,
52
+ "<138>": 151815,
53
+ "<139>": 151816,
54
+ "<13>": 151690,
55
+ "<140>": 151817,
56
+ "<141>": 151818,
57
+ "<142>": 151819,
58
+ "<143>": 151820,
59
+ "<144>": 151821,
60
+ "<145>": 151822,
61
+ "<146>": 151823,
62
+ "<147>": 151824,
63
+ "<148>": 151825,
64
+ "<149>": 151826,
65
+ "<14>": 151691,
66
+ "<150>": 151827,
67
+ "<151>": 151828,
68
+ "<152>": 151829,
69
+ "<153>": 151830,
70
+ "<154>": 151831,
71
+ "<155>": 151832,
72
+ "<156>": 151833,
73
+ "<157>": 151834,
74
+ "<158>": 151835,
75
+ "<159>": 151836,
76
+ "<15>": 151692,
77
+ "<160>": 151837,
78
+ "<161>": 151838,
79
+ "<162>": 151839,
80
+ "<163>": 151840,
81
+ "<164>": 151841,
82
+ "<165>": 151842,
83
+ "<166>": 151843,
84
+ "<167>": 151844,
85
+ "<168>": 151845,
86
+ "<169>": 151846,
87
+ "<16>": 151693,
88
+ "<170>": 151847,
89
+ "<171>": 151848,
90
+ "<172>": 151849,
91
+ "<173>": 151850,
92
+ "<174>": 151851,
93
+ "<175>": 151852,
94
+ "<176>": 151853,
95
+ "<177>": 151854,
96
+ "<178>": 151855,
97
+ "<179>": 151856,
98
+ "<17>": 151694,
99
+ "<180>": 151857,
100
+ "<181>": 151858,
101
+ "<182>": 151859,
102
+ "<183>": 151860,
103
+ "<184>": 151861,
104
+ "<185>": 151862,
105
+ "<186>": 151863,
106
+ "<187>": 151864,
107
+ "<188>": 151865,
108
+ "<189>": 151866,
109
+ "<18>": 151695,
110
+ "<190>": 151867,
111
+ "<191>": 151868,
112
+ "<192>": 151869,
113
+ "<193>": 151870,
114
+ "<194>": 151871,
115
+ "<195>": 151872,
116
+ "<196>": 151873,
117
+ "<197>": 151874,
118
+ "<198>": 151875,
119
+ "<199>": 151876,
120
+ "<19>": 151696,
121
+ "<1>": 151678,
122
+ "<200>": 151877,
123
+ "<201>": 151878,
124
+ "<202>": 151879,
125
+ "<203>": 151880,
126
+ "<204>": 151881,
127
+ "<205>": 151882,
128
+ "<206>": 151883,
129
+ "<207>": 151884,
130
+ "<208>": 151885,
131
+ "<209>": 151886,
132
+ "<20>": 151697,
133
+ "<210>": 151887,
134
+ "<211>": 151888,
135
+ "<212>": 151889,
136
+ "<213>": 151890,
137
+ "<214>": 151891,
138
+ "<215>": 151892,
139
+ "<216>": 151893,
140
+ "<217>": 151894,
141
+ "<218>": 151895,
142
+ "<219>": 151896,
143
+ "<21>": 151698,
144
+ "<220>": 151897,
145
+ "<221>": 151898,
146
+ "<222>": 151899,
147
+ "<223>": 151900,
148
+ "<224>": 151901,
149
+ "<225>": 151902,
150
+ "<226>": 151903,
151
+ "<227>": 151904,
152
+ "<228>": 151905,
153
+ "<229>": 151906,
154
+ "<22>": 151699,
155
+ "<230>": 151907,
156
+ "<231>": 151908,
157
+ "<232>": 151909,
158
+ "<233>": 151910,
159
+ "<234>": 151911,
160
+ "<235>": 151912,
161
+ "<236>": 151913,
162
+ "<237>": 151914,
163
+ "<238>": 151915,
164
+ "<239>": 151916,
165
+ "<23>": 151700,
166
+ "<240>": 151917,
167
+ "<241>": 151918,
168
+ "<242>": 151919,
169
+ "<243>": 151920,
170
+ "<244>": 151921,
171
+ "<245>": 151922,
172
+ "<246>": 151923,
173
+ "<247>": 151924,
174
+ "<248>": 151925,
175
+ "<249>": 151926,
176
+ "<24>": 151701,
177
+ "<250>": 151927,
178
+ "<251>": 151928,
179
+ "<252>": 151929,
180
+ "<253>": 151930,
181
+ "<254>": 151931,
182
+ "<255>": 151932,
183
+ "<256>": 151933,
184
+ "<257>": 151934,
185
+ "<258>": 151935,
186
+ "<259>": 151936,
187
+ "<25>": 151702,
188
+ "<260>": 151937,
189
+ "<261>": 151938,
190
+ "<262>": 151939,
191
+ "<263>": 151940,
192
+ "<264>": 151941,
193
+ "<265>": 151942,
194
+ "<266>": 151943,
195
+ "<267>": 151944,
196
+ "<268>": 151945,
197
+ "<269>": 151946,
198
+ "<26>": 151703,
199
+ "<270>": 151947,
200
+ "<271>": 151948,
201
+ "<272>": 151949,
202
+ "<273>": 151950,
203
+ "<274>": 151951,
204
+ "<275>": 151952,
205
+ "<276>": 151953,
206
+ "<277>": 151954,
207
+ "<278>": 151955,
208
+ "<279>": 151956,
209
+ "<27>": 151704,
210
+ "<280>": 151957,
211
+ "<281>": 151958,
212
+ "<282>": 151959,
213
+ "<283>": 151960,
214
+ "<284>": 151961,
215
+ "<285>": 151962,
216
+ "<286>": 151963,
217
+ "<287>": 151964,
218
+ "<288>": 151965,
219
+ "<289>": 151966,
220
+ "<28>": 151705,
221
+ "<290>": 151967,
222
+ "<291>": 151968,
223
+ "<292>": 151969,
224
+ "<293>": 151970,
225
+ "<294>": 151971,
226
+ "<295>": 151972,
227
+ "<296>": 151973,
228
+ "<297>": 151974,
229
+ "<298>": 151975,
230
+ "<299>": 151976,
231
+ "<29>": 151706,
232
+ "<2>": 151679,
233
+ "<300>": 151977,
234
+ "<301>": 151978,
235
+ "<302>": 151979,
236
+ "<303>": 151980,
237
+ "<304>": 151981,
238
+ "<305>": 151982,
239
+ "<306>": 151983,
240
+ "<307>": 151984,
241
+ "<308>": 151985,
242
+ "<309>": 151986,
243
+ "<30>": 151707,
244
+ "<310>": 151987,
245
+ "<311>": 151988,
246
+ "<312>": 151989,
247
+ "<313>": 151990,
248
+ "<314>": 151991,
249
+ "<315>": 151992,
250
+ "<316>": 151993,
251
+ "<317>": 151994,
252
+ "<318>": 151995,
253
+ "<319>": 151996,
254
+ "<31>": 151708,
255
+ "<320>": 151997,
256
+ "<321>": 151998,
257
+ "<322>": 151999,
258
+ "<323>": 152000,
259
+ "<324>": 152001,
260
+ "<325>": 152002,
261
+ "<326>": 152003,
262
+ "<327>": 152004,
263
+ "<328>": 152005,
264
+ "<329>": 152006,
265
+ "<32>": 151709,
266
+ "<330>": 152007,
267
+ "<331>": 152008,
268
+ "<332>": 152009,
269
+ "<333>": 152010,
270
+ "<334>": 152011,
271
+ "<335>": 152012,
272
+ "<336>": 152013,
273
+ "<337>": 152014,
274
+ "<338>": 152015,
275
+ "<339>": 152016,
276
+ "<33>": 151710,
277
+ "<340>": 152017,
278
+ "<341>": 152018,
279
+ "<342>": 152019,
280
+ "<343>": 152020,
281
+ "<344>": 152021,
282
+ "<345>": 152022,
283
+ "<346>": 152023,
284
+ "<347>": 152024,
285
+ "<348>": 152025,
286
+ "<349>": 152026,
287
+ "<34>": 151711,
288
+ "<350>": 152027,
289
+ "<351>": 152028,
290
+ "<352>": 152029,
291
+ "<353>": 152030,
292
+ "<354>": 152031,
293
+ "<355>": 152032,
294
+ "<356>": 152033,
295
+ "<357>": 152034,
296
+ "<358>": 152035,
297
+ "<359>": 152036,
298
+ "<35>": 151712,
299
+ "<360>": 152037,
300
+ "<361>": 152038,
301
+ "<362>": 152039,
302
+ "<363>": 152040,
303
+ "<364>": 152041,
304
+ "<365>": 152042,
305
+ "<366>": 152043,
306
+ "<367>": 152044,
307
+ "<368>": 152045,
308
+ "<369>": 152046,
309
+ "<36>": 151713,
310
+ "<370>": 152047,
311
+ "<371>": 152048,
312
+ "<372>": 152049,
313
+ "<373>": 152050,
314
+ "<374>": 152051,
315
+ "<375>": 152052,
316
+ "<376>": 152053,
317
+ "<377>": 152054,
318
+ "<378>": 152055,
319
+ "<379>": 152056,
320
+ "<37>": 151714,
321
+ "<380>": 152057,
322
+ "<381>": 152058,
323
+ "<382>": 152059,
324
+ "<383>": 152060,
325
+ "<384>": 152061,
326
+ "<385>": 152062,
327
+ "<386>": 152063,
328
+ "<387>": 152064,
329
+ "<388>": 152065,
330
+ "<389>": 152066,
331
+ "<38>": 151715,
332
+ "<390>": 152067,
333
+ "<391>": 152068,
334
+ "<392>": 152069,
335
+ "<393>": 152070,
336
+ "<394>": 152071,
337
+ "<395>": 152072,
338
+ "<396>": 152073,
339
+ "<397>": 152074,
340
+ "<398>": 152075,
341
+ "<399>": 152076,
342
+ "<39>": 151716,
343
+ "<3>": 151680,
344
+ "<400>": 152077,
345
+ "<401>": 152078,
346
+ "<402>": 152079,
347
+ "<403>": 152080,
348
+ "<404>": 152081,
349
+ "<405>": 152082,
350
+ "<406>": 152083,
351
+ "<407>": 152084,
352
+ "<408>": 152085,
353
+ "<409>": 152086,
354
+ "<40>": 151717,
355
+ "<410>": 152087,
356
+ "<411>": 152088,
357
+ "<412>": 152089,
358
+ "<413>": 152090,
359
+ "<414>": 152091,
360
+ "<415>": 152092,
361
+ "<416>": 152093,
362
+ "<417>": 152094,
363
+ "<418>": 152095,
364
+ "<419>": 152096,
365
+ "<41>": 151718,
366
+ "<420>": 152097,
367
+ "<421>": 152098,
368
+ "<422>": 152099,
369
+ "<423>": 152100,
370
+ "<424>": 152101,
371
+ "<425>": 152102,
372
+ "<426>": 152103,
373
+ "<427>": 152104,
374
+ "<428>": 152105,
375
+ "<429>": 152106,
376
+ "<42>": 151719,
377
+ "<430>": 152107,
378
+ "<431>": 152108,
379
+ "<432>": 152109,
380
+ "<433>": 152110,
381
+ "<434>": 152111,
382
+ "<435>": 152112,
383
+ "<436>": 152113,
384
+ "<437>": 152114,
385
+ "<438>": 152115,
386
+ "<439>": 152116,
387
+ "<43>": 151720,
388
+ "<440>": 152117,
389
+ "<441>": 152118,
390
+ "<442>": 152119,
391
+ "<443>": 152120,
392
+ "<444>": 152121,
393
+ "<445>": 152122,
394
+ "<446>": 152123,
395
+ "<447>": 152124,
396
+ "<448>": 152125,
397
+ "<449>": 152126,
398
+ "<44>": 151721,
399
+ "<450>": 152127,
400
+ "<451>": 152128,
401
+ "<452>": 152129,
402
+ "<453>": 152130,
403
+ "<454>": 152131,
404
+ "<455>": 152132,
405
+ "<456>": 152133,
406
+ "<457>": 152134,
407
+ "<458>": 152135,
408
+ "<459>": 152136,
409
+ "<45>": 151722,
410
+ "<460>": 152137,
411
+ "<461>": 152138,
412
+ "<462>": 152139,
413
+ "<463>": 152140,
414
+ "<464>": 152141,
415
+ "<465>": 152142,
416
+ "<466>": 152143,
417
+ "<467>": 152144,
418
+ "<468>": 152145,
419
+ "<469>": 152146,
420
+ "<46>": 151723,
421
+ "<470>": 152147,
422
+ "<471>": 152148,
423
+ "<472>": 152149,
424
+ "<473>": 152150,
425
+ "<474>": 152151,
426
+ "<475>": 152152,
427
+ "<476>": 152153,
428
+ "<477>": 152154,
429
+ "<478>": 152155,
430
+ "<479>": 152156,
431
+ "<47>": 151724,
432
+ "<480>": 152157,
433
+ "<481>": 152158,
434
+ "<482>": 152159,
435
+ "<483>": 152160,
436
+ "<484>": 152161,
437
+ "<485>": 152162,
438
+ "<486>": 152163,
439
+ "<487>": 152164,
440
+ "<488>": 152165,
441
+ "<489>": 152166,
442
+ "<48>": 151725,
443
+ "<490>": 152167,
444
+ "<491>": 152168,
445
+ "<492>": 152169,
446
+ "<493>": 152170,
447
+ "<494>": 152171,
448
+ "<495>": 152172,
449
+ "<496>": 152173,
450
+ "<497>": 152174,
451
+ "<498>": 152175,
452
+ "<499>": 152176,
453
+ "<49>": 151726,
454
+ "<4>": 151681,
455
+ "<500>": 152177,
456
+ "<501>": 152178,
457
+ "<502>": 152179,
458
+ "<503>": 152180,
459
+ "<504>": 152181,
460
+ "<505>": 152182,
461
+ "<506>": 152183,
462
+ "<507>": 152184,
463
+ "<508>": 152185,
464
+ "<509>": 152186,
465
+ "<50>": 151727,
466
+ "<510>": 152187,
467
+ "<511>": 152188,
468
+ "<512>": 152189,
469
+ "<513>": 152190,
470
+ "<514>": 152191,
471
+ "<515>": 152192,
472
+ "<516>": 152193,
473
+ "<517>": 152194,
474
+ "<518>": 152195,
475
+ "<519>": 152196,
476
+ "<51>": 151728,
477
+ "<520>": 152197,
478
+ "<521>": 152198,
479
+ "<522>": 152199,
480
+ "<523>": 152200,
481
+ "<524>": 152201,
482
+ "<525>": 152202,
483
+ "<526>": 152203,
484
+ "<527>": 152204,
485
+ "<528>": 152205,
486
+ "<529>": 152206,
487
+ "<52>": 151729,
488
+ "<530>": 152207,
489
+ "<531>": 152208,
490
+ "<532>": 152209,
491
+ "<533>": 152210,
492
+ "<534>": 152211,
493
+ "<535>": 152212,
494
+ "<536>": 152213,
495
+ "<537>": 152214,
496
+ "<538>": 152215,
497
+ "<539>": 152216,
498
+ "<53>": 151730,
499
+ "<540>": 152217,
500
+ "<541>": 152218,
501
+ "<542>": 152219,
502
+ "<543>": 152220,
503
+ "<544>": 152221,
504
+ "<545>": 152222,
505
+ "<546>": 152223,
506
+ "<547>": 152224,
507
+ "<548>": 152225,
508
+ "<549>": 152226,
509
+ "<54>": 151731,
510
+ "<550>": 152227,
511
+ "<551>": 152228,
512
+ "<552>": 152229,
513
+ "<553>": 152230,
514
+ "<554>": 152231,
515
+ "<555>": 152232,
516
+ "<556>": 152233,
517
+ "<557>": 152234,
518
+ "<558>": 152235,
519
+ "<559>": 152236,
520
+ "<55>": 151732,
521
+ "<560>": 152237,
522
+ "<561>": 152238,
523
+ "<562>": 152239,
524
+ "<563>": 152240,
525
+ "<564>": 152241,
526
+ "<565>": 152242,
527
+ "<566>": 152243,
528
+ "<567>": 152244,
529
+ "<568>": 152245,
530
+ "<569>": 152246,
531
+ "<56>": 151733,
532
+ "<570>": 152247,
533
+ "<571>": 152248,
534
+ "<572>": 152249,
535
+ "<573>": 152250,
536
+ "<574>": 152251,
537
+ "<575>": 152252,
538
+ "<576>": 152253,
539
+ "<577>": 152254,
540
+ "<578>": 152255,
541
+ "<579>": 152256,
542
+ "<57>": 151734,
543
+ "<580>": 152257,
544
+ "<581>": 152258,
545
+ "<582>": 152259,
546
+ "<583>": 152260,
547
+ "<584>": 152261,
548
+ "<585>": 152262,
549
+ "<586>": 152263,
550
+ "<587>": 152264,
551
+ "<588>": 152265,
552
+ "<589>": 152266,
553
+ "<58>": 151735,
554
+ "<590>": 152267,
555
+ "<591>": 152268,
556
+ "<592>": 152269,
557
+ "<593>": 152270,
558
+ "<594>": 152271,
559
+ "<595>": 152272,
560
+ "<596>": 152273,
561
+ "<597>": 152274,
562
+ "<598>": 152275,
563
+ "<599>": 152276,
564
+ "<59>": 151736,
565
+ "<5>": 151682,
566
+ "<600>": 152277,
567
+ "<601>": 152278,
568
+ "<602>": 152279,
569
+ "<603>": 152280,
570
+ "<604>": 152281,
571
+ "<605>": 152282,
572
+ "<606>": 152283,
573
+ "<607>": 152284,
574
+ "<608>": 152285,
575
+ "<609>": 152286,
576
+ "<60>": 151737,
577
+ "<610>": 152287,
578
+ "<611>": 152288,
579
+ "<612>": 152289,
580
+ "<613>": 152290,
581
+ "<614>": 152291,
582
+ "<615>": 152292,
583
+ "<616>": 152293,
584
+ "<617>": 152294,
585
+ "<618>": 152295,
586
+ "<619>": 152296,
587
+ "<61>": 151738,
588
+ "<620>": 152297,
589
+ "<621>": 152298,
590
+ "<622>": 152299,
591
+ "<623>": 152300,
592
+ "<624>": 152301,
593
+ "<625>": 152302,
594
+ "<626>": 152303,
595
+ "<627>": 152304,
596
+ "<628>": 152305,
597
+ "<629>": 152306,
598
+ "<62>": 151739,
599
+ "<630>": 152307,
600
+ "<631>": 152308,
601
+ "<632>": 152309,
602
+ "<633>": 152310,
603
+ "<634>": 152311,
604
+ "<635>": 152312,
605
+ "<636>": 152313,
606
+ "<637>": 152314,
607
+ "<638>": 152315,
608
+ "<639>": 152316,
609
+ "<63>": 151740,
610
+ "<640>": 152317,
611
+ "<641>": 152318,
612
+ "<642>": 152319,
613
+ "<643>": 152320,
614
+ "<644>": 152321,
615
+ "<645>": 152322,
616
+ "<646>": 152323,
617
+ "<647>": 152324,
618
+ "<648>": 152325,
619
+ "<649>": 152326,
620
+ "<64>": 151741,
621
+ "<650>": 152327,
622
+ "<651>": 152328,
623
+ "<652>": 152329,
624
+ "<653>": 152330,
625
+ "<654>": 152331,
626
+ "<655>": 152332,
627
+ "<656>": 152333,
628
+ "<657>": 152334,
629
+ "<658>": 152335,
630
+ "<659>": 152336,
631
+ "<65>": 151742,
632
+ "<660>": 152337,
633
+ "<661>": 152338,
634
+ "<662>": 152339,
635
+ "<663>": 152340,
636
+ "<664>": 152341,
637
+ "<665>": 152342,
638
+ "<666>": 152343,
639
+ "<667>": 152344,
640
+ "<668>": 152345,
641
+ "<669>": 152346,
642
+ "<66>": 151743,
643
+ "<670>": 152347,
644
+ "<671>": 152348,
645
+ "<672>": 152349,
646
+ "<673>": 152350,
647
+ "<674>": 152351,
648
+ "<675>": 152352,
649
+ "<676>": 152353,
650
+ "<677>": 152354,
651
+ "<678>": 152355,
652
+ "<679>": 152356,
653
+ "<67>": 151744,
654
+ "<680>": 152357,
655
+ "<681>": 152358,
656
+ "<682>": 152359,
657
+ "<683>": 152360,
658
+ "<684>": 152361,
659
+ "<685>": 152362,
660
+ "<686>": 152363,
661
+ "<687>": 152364,
662
+ "<688>": 152365,
663
+ "<689>": 152366,
664
+ "<68>": 151745,
665
+ "<690>": 152367,
666
+ "<691>": 152368,
667
+ "<692>": 152369,
668
+ "<693>": 152370,
669
+ "<694>": 152371,
670
+ "<695>": 152372,
671
+ "<696>": 152373,
672
+ "<697>": 152374,
673
+ "<698>": 152375,
674
+ "<699>": 152376,
675
+ "<69>": 151746,
676
+ "<6>": 151683,
677
+ "<700>": 152377,
678
+ "<701>": 152378,
679
+ "<702>": 152379,
680
+ "<703>": 152380,
681
+ "<704>": 152381,
682
+ "<705>": 152382,
683
+ "<706>": 152383,
684
+ "<707>": 152384,
685
+ "<708>": 152385,
686
+ "<709>": 152386,
687
+ "<70>": 151747,
688
+ "<710>": 152387,
689
+ "<711>": 152388,
690
+ "<712>": 152389,
691
+ "<713>": 152390,
692
+ "<714>": 152391,
693
+ "<715>": 152392,
694
+ "<716>": 152393,
695
+ "<717>": 152394,
696
+ "<718>": 152395,
697
+ "<719>": 152396,
698
+ "<71>": 151748,
699
+ "<720>": 152397,
700
+ "<721>": 152398,
701
+ "<722>": 152399,
702
+ "<723>": 152400,
703
+ "<724>": 152401,
704
+ "<725>": 152402,
705
+ "<726>": 152403,
706
+ "<727>": 152404,
707
+ "<728>": 152405,
708
+ "<729>": 152406,
709
+ "<72>": 151749,
710
+ "<730>": 152407,
711
+ "<731>": 152408,
712
+ "<732>": 152409,
713
+ "<733>": 152410,
714
+ "<734>": 152411,
715
+ "<735>": 152412,
716
+ "<736>": 152413,
717
+ "<737>": 152414,
718
+ "<738>": 152415,
719
+ "<739>": 152416,
720
+ "<73>": 151750,
721
+ "<740>": 152417,
722
+ "<741>": 152418,
723
+ "<742>": 152419,
724
+ "<743>": 152420,
725
+ "<744>": 152421,
726
+ "<745>": 152422,
727
+ "<746>": 152423,
728
+ "<747>": 152424,
729
+ "<748>": 152425,
730
+ "<749>": 152426,
731
+ "<74>": 151751,
732
+ "<750>": 152427,
733
+ "<751>": 152428,
734
+ "<752>": 152429,
735
+ "<753>": 152430,
736
+ "<754>": 152431,
737
+ "<755>": 152432,
738
+ "<756>": 152433,
739
+ "<757>": 152434,
740
+ "<758>": 152435,
741
+ "<759>": 152436,
742
+ "<75>": 151752,
743
+ "<760>": 152437,
744
+ "<761>": 152438,
745
+ "<762>": 152439,
746
+ "<763>": 152440,
747
+ "<764>": 152441,
748
+ "<765>": 152442,
749
+ "<766>": 152443,
750
+ "<767>": 152444,
751
+ "<768>": 152445,
752
+ "<769>": 152446,
753
+ "<76>": 151753,
754
+ "<770>": 152447,
755
+ "<771>": 152448,
756
+ "<772>": 152449,
757
+ "<773>": 152450,
758
+ "<774>": 152451,
759
+ "<775>": 152452,
760
+ "<776>": 152453,
761
+ "<777>": 152454,
762
+ "<778>": 152455,
763
+ "<779>": 152456,
764
+ "<77>": 151754,
765
+ "<780>": 152457,
766
+ "<781>": 152458,
767
+ "<782>": 152459,
768
+ "<783>": 152460,
769
+ "<784>": 152461,
770
+ "<785>": 152462,
771
+ "<786>": 152463,
772
+ "<787>": 152464,
773
+ "<788>": 152465,
774
+ "<789>": 152466,
775
+ "<78>": 151755,
776
+ "<790>": 152467,
777
+ "<791>": 152468,
778
+ "<792>": 152469,
779
+ "<793>": 152470,
780
+ "<794>": 152471,
781
+ "<795>": 152472,
782
+ "<796>": 152473,
783
+ "<797>": 152474,
784
+ "<798>": 152475,
785
+ "<799>": 152476,
786
+ "<79>": 151756,
787
+ "<7>": 151684,
788
+ "<800>": 152477,
789
+ "<801>": 152478,
790
+ "<802>": 152479,
791
+ "<803>": 152480,
792
+ "<804>": 152481,
793
+ "<805>": 152482,
794
+ "<806>": 152483,
795
+ "<807>": 152484,
796
+ "<808>": 152485,
797
+ "<809>": 152486,
798
+ "<80>": 151757,
799
+ "<810>": 152487,
800
+ "<811>": 152488,
801
+ "<812>": 152489,
802
+ "<813>": 152490,
803
+ "<814>": 152491,
804
+ "<815>": 152492,
805
+ "<816>": 152493,
806
+ "<817>": 152494,
807
+ "<818>": 152495,
808
+ "<819>": 152496,
809
+ "<81>": 151758,
810
+ "<820>": 152497,
811
+ "<821>": 152498,
812
+ "<822>": 152499,
813
+ "<823>": 152500,
814
+ "<824>": 152501,
815
+ "<825>": 152502,
816
+ "<826>": 152503,
817
+ "<827>": 152504,
818
+ "<828>": 152505,
819
+ "<829>": 152506,
820
+ "<82>": 151759,
821
+ "<830>": 152507,
822
+ "<831>": 152508,
823
+ "<832>": 152509,
824
+ "<833>": 152510,
825
+ "<834>": 152511,
826
+ "<835>": 152512,
827
+ "<836>": 152513,
828
+ "<837>": 152514,
829
+ "<838>": 152515,
830
+ "<839>": 152516,
831
+ "<83>": 151760,
832
+ "<840>": 152517,
833
+ "<841>": 152518,
834
+ "<842>": 152519,
835
+ "<843>": 152520,
836
+ "<844>": 152521,
837
+ "<845>": 152522,
838
+ "<846>": 152523,
839
+ "<847>": 152524,
840
+ "<848>": 152525,
841
+ "<849>": 152526,
842
+ "<84>": 151761,
843
+ "<850>": 152527,
844
+ "<851>": 152528,
845
+ "<852>": 152529,
846
+ "<853>": 152530,
847
+ "<854>": 152531,
848
+ "<855>": 152532,
849
+ "<856>": 152533,
850
+ "<857>": 152534,
851
+ "<858>": 152535,
852
+ "<859>": 152536,
853
+ "<85>": 151762,
854
+ "<860>": 152537,
855
+ "<861>": 152538,
856
+ "<862>": 152539,
857
+ "<863>": 152540,
858
+ "<864>": 152541,
859
+ "<865>": 152542,
860
+ "<866>": 152543,
861
+ "<867>": 152544,
862
+ "<868>": 152545,
863
+ "<869>": 152546,
864
+ "<86>": 151763,
865
+ "<870>": 152547,
866
+ "<871>": 152548,
867
+ "<872>": 152549,
868
+ "<873>": 152550,
869
+ "<874>": 152551,
870
+ "<875>": 152552,
871
+ "<876>": 152553,
872
+ "<877>": 152554,
873
+ "<878>": 152555,
874
+ "<879>": 152556,
875
+ "<87>": 151764,
876
+ "<880>": 152557,
877
+ "<881>": 152558,
878
+ "<882>": 152559,
879
+ "<883>": 152560,
880
+ "<884>": 152561,
881
+ "<885>": 152562,
882
+ "<886>": 152563,
883
+ "<887>": 152564,
884
+ "<888>": 152565,
885
+ "<889>": 152566,
886
+ "<88>": 151765,
887
+ "<890>": 152567,
888
+ "<891>": 152568,
889
+ "<892>": 152569,
890
+ "<893>": 152570,
891
+ "<894>": 152571,
892
+ "<895>": 152572,
893
+ "<896>": 152573,
894
+ "<897>": 152574,
895
+ "<898>": 152575,
896
+ "<899>": 152576,
897
+ "<89>": 151766,
898
+ "<8>": 151685,
899
+ "<900>": 152577,
900
+ "<901>": 152578,
901
+ "<902>": 152579,
902
+ "<903>": 152580,
903
+ "<904>": 152581,
904
+ "<905>": 152582,
905
+ "<906>": 152583,
906
+ "<907>": 152584,
907
+ "<908>": 152585,
908
+ "<909>": 152586,
909
+ "<90>": 151767,
910
+ "<910>": 152587,
911
+ "<911>": 152588,
912
+ "<912>": 152589,
913
+ "<913>": 152590,
914
+ "<914>": 152591,
915
+ "<915>": 152592,
916
+ "<916>": 152593,
917
+ "<917>": 152594,
918
+ "<918>": 152595,
919
+ "<919>": 152596,
920
+ "<91>": 151768,
921
+ "<920>": 152597,
922
+ "<921>": 152598,
923
+ "<922>": 152599,
924
+ "<923>": 152600,
925
+ "<924>": 152601,
926
+ "<925>": 152602,
927
+ "<926>": 152603,
928
+ "<927>": 152604,
929
+ "<928>": 152605,
930
+ "<929>": 152606,
931
+ "<92>": 151769,
932
+ "<930>": 152607,
933
+ "<931>": 152608,
934
+ "<932>": 152609,
935
+ "<933>": 152610,
936
+ "<934>": 152611,
937
+ "<935>": 152612,
938
+ "<936>": 152613,
939
+ "<937>": 152614,
940
+ "<938>": 152615,
941
+ "<939>": 152616,
942
+ "<93>": 151770,
943
+ "<940>": 152617,
944
+ "<941>": 152618,
945
+ "<942>": 152619,
946
+ "<943>": 152620,
947
+ "<944>": 152621,
948
+ "<945>": 152622,
949
+ "<946>": 152623,
950
+ "<947>": 152624,
951
+ "<948>": 152625,
952
+ "<949>": 152626,
953
+ "<94>": 151771,
954
+ "<950>": 152627,
955
+ "<951>": 152628,
956
+ "<952>": 152629,
957
+ "<953>": 152630,
958
+ "<954>": 152631,
959
+ "<955>": 152632,
960
+ "<956>": 152633,
961
+ "<957>": 152634,
962
+ "<958>": 152635,
963
+ "<959>": 152636,
964
+ "<95>": 151772,
965
+ "<960>": 152637,
966
+ "<961>": 152638,
967
+ "<962>": 152639,
968
+ "<963>": 152640,
969
+ "<964>": 152641,
970
+ "<965>": 152642,
971
+ "<966>": 152643,
972
+ "<967>": 152644,
973
+ "<968>": 152645,
974
+ "<969>": 152646,
975
+ "<96>": 151773,
976
+ "<970>": 152647,
977
+ "<971>": 152648,
978
+ "<972>": 152649,
979
+ "<973>": 152650,
980
+ "<974>": 152651,
981
+ "<975>": 152652,
982
+ "<976>": 152653,
983
+ "<977>": 152654,
984
+ "<978>": 152655,
985
+ "<979>": 152656,
986
+ "<97>": 151774,
987
+ "<980>": 152657,
988
+ "<981>": 152658,
989
+ "<982>": 152659,
990
+ "<983>": 152660,
991
+ "<984>": 152661,
992
+ "<985>": 152662,
993
+ "<986>": 152663,
994
+ "<987>": 152664,
995
+ "<988>": 152665,
996
+ "<989>": 152666,
997
+ "<98>": 151775,
998
+ "<990>": 152667,
999
+ "<991>": 152668,
1000
+ "<992>": 152669,
1001
+ "<993>": 152670,
1002
+ "<994>": 152671,
1003
+ "<995>": 152672,
1004
+ "<996>": 152673,
1005
+ "<997>": 152674,
1006
+ "<998>": 152675,
1007
+ "<999>": 152676,
1008
+ "<99>": 151776,
1009
+ "<9>": 151686,
1010
+ "<IMG_CONTEXT>": 151665,
1011
+ "<box>": 151668,
1012
+ "<img>": 151666,
1013
+ "<interval>": 151674,
1014
+ "<null>": 152678,
1015
+ "<quad>": 151670,
1016
+ "<ref>": 151672,
1017
+ "<switch>": 152679,
1018
+ "<text_mask>": 151676,
1019
+ "<tool_call>": 151657,
1020
+ "<|box_end|>": 151649,
1021
+ "<|box_start|>": 151648,
1022
+ "<|endoftext|>": 151643,
1023
+ "<|file_sep|>": 151664,
1024
+ "<|fim_middle|>": 151660,
1025
+ "<|fim_pad|>": 151662,
1026
+ "<|fim_prefix|>": 151659,
1027
+ "<|fim_suffix|>": 151661,
1028
+ "<|im_end|>": 151645,
1029
+ "<|im_start|>": 151644,
1030
+ "<|image_pad|>": 151655,
1031
+ "<|object_ref_end|>": 151647,
1032
+ "<|object_ref_start|>": 151646,
1033
+ "<|quad_end|>": 151651,
1034
+ "<|quad_start|>": 151650,
1035
+ "<|repo_name|>": 151663,
1036
+ "<|video_pad|>": 151656,
1037
+ "<|vision_end|>": 151653,
1038
+ "<|vision_pad|>": 151654,
1039
+ "<|vision_start|>": 151652
1040
+ }
all_results.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "epoch": 0.069,
3
+ "total_flos": 5.6478980657499236e+20,
4
+ "train_loss": 0.02277738807797432,
5
+ "train_runtime": 3535.7374,
6
+ "train_samples": "streaming",
7
+ "train_samples_per_second": 362.018,
8
+ "train_steps_per_second": 1.414
9
+ }
chat_template.jinja ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {%- if tools %}
2
+ {{- '<|im_start|>system\n' }}
3
+ {%- if messages[0]['role'] == 'system' %}
4
+ {{- messages[0]['content'] }}
5
+ {%- else %}
6
+ {{- 'You are Qwen, created by Alibaba Cloud. You are a helpful assistant.' }}
7
+ {%- endif %}
8
+ {{- "\n\n# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within <tools></tools> XML tags:\n<tools>" }}
9
+ {%- for tool in tools %}
10
+ {{- "\n" }}
11
+ {{- tool | tojson }}
12
+ {%- endfor %}
13
+ {{- "\n</tools>\n\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n<tool_call>\n{\"name\": <function-name>, \"arguments\": <args-json-object>}\n</tool_call><|im_end|>\n" }}
14
+ {%- else %}
15
+ {%- if messages[0]['role'] == 'system' %}
16
+ {{- '<|im_start|>system\n' + messages[0]['content'] + '<|im_end|>\n' }}
17
+ {%- else %}
18
+ {{- '<|im_start|>system\nYou are Qwen, created by Alibaba Cloud. You are a helpful assistant.<|im_end|>\n' }}
19
+ {%- endif %}
20
+ {%- endif %}
21
+ {%- for message in messages %}
22
+ {%- if (message.role == "user") or (message.role == "system" and not loop.first) or (message.role == "assistant" and not message.tool_calls) %}
23
+ {{- '<|im_start|>' + message.role + '\n' + message.content + '<|im_end|>' + '\n' }}
24
+ {%- elif message.role == "assistant" %}
25
+ {{- '<|im_start|>' + message.role }}
26
+ {%- if message.content %}
27
+ {{- '\n' + message.content }}
28
+ {%- endif %}
29
+ {%- for tool_call in message.tool_calls %}
30
+ {%- if tool_call.function is defined %}
31
+ {%- set tool_call = tool_call.function %}
32
+ {%- endif %}
33
+ {{- '\n<tool_call>\n{"name": "' }}
34
+ {{- tool_call.name }}
35
+ {{- '", "arguments": ' }}
36
+ {{- tool_call.arguments | tojson }}
37
+ {{- '}\n</tool_call>' }}
38
+ {%- endfor %}
39
+ {{- '<|im_end|>\n' }}
40
+ {%- elif message.role == "tool" %}
41
+ {%- if (loop.index0 == 0) or (messages[loop.index0 - 1].role != "tool") %}
42
+ {{- '<|im_start|>user' }}
43
+ {%- endif %}
44
+ {{- '\n<tool_response>\n' }}
45
+ {{- message.content }}
46
+ {{- '\n</tool_response>' }}
47
+ {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %}
48
+ {{- '<|im_end|>\n' }}
49
+ {%- endif %}
50
+ {%- endif %}
51
+ {%- endfor %}
52
+ {%- if add_generation_prompt %}
53
+ {{- '<|im_start|>assistant\n' }}
54
+ {%- endif %}
chat_template.json ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ {
2
+ "chat_template": "{% set image_count = namespace(value=0) %}{% set video_count = namespace(value=0) %}{% for message in messages %}{% if loop.first and message['role'] != 'system' %}<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n{% endif %}<|im_start|>{{ message['role'] }}\n{% if message['content'] is string %}{{ message['content'] }}<|im_end|>\n{% else %}{% for content in message['content'] %}{% if content['type'] == 'image' or 'image' in content or 'image_url' in content %}{% set image_count.value = image_count.value + 1 %}{% if add_vision_id %}<image {{ image_count.value }}>{% endif %}<image-{{ image_count.value }}>{% elif content['type'] == 'video' or 'video' in content %}{% set video_count.value = video_count.value + 1 %}{% if add_vision_id %}<video {{ video_count.value }}>{% endif %}<video-{{ video_count.value }}>{% elif 'text' in content %}{{ content['text'] }}{% endif %}{% endfor %}<|im_end|>\n{% endif %}{% endfor %}{% if add_generation_prompt %}<|im_start|>assistant\n{% endif %}"
3
+ }
4
+
config.json ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_attn_implementation": "magi",
3
+ "_commit_hash": null,
4
+ "architectures": [
5
+ "LocateAnythingForConditionalGeneration"
6
+ ],
7
+ "auto_map": {
8
+ "AutoConfig": "configuration_locateanything.LocateAnythingConfig",
9
+ "AutoModel": "modeling_locateanything.LocateAnythingForConditionalGeneration"
10
+ },
11
+ "box_end_token_id": 151669,
12
+ "box_start_token_id": 151668,
13
+ "coord_end_token_id": 152677,
14
+ "coord_start_token_id": 151677,
15
+ "image_token_index": 151665,
16
+ "mlp_checkpoint": false,
17
+ "mlp_connector_layers": 2,
18
+ "model_type": "locateanything",
19
+ "none_token_id": 4064,
20
+ "ref_end_token_id": 151673,
21
+ "ref_start_token_id": 151672,
22
+ "template": null,
23
+ "text_config": {
24
+ "_attn_implementation_autoset": true,
25
+ "_name_or_path": "Qwen/Qwen2.5-3B-Instruct",
26
+ "architectures": [
27
+ "Qwen2ForCausalLM"
28
+ ],
29
+ "attention_dropout": 0.0,
30
+ "block_size": 6,
31
+ "bos_token_id": 151643,
32
+ "causal_attn": false,
33
+ "eos_token_id": 151645,
34
+ "hidden_act": "silu",
35
+ "hidden_size": 2048,
36
+ "initializer_range": 0.02,
37
+ "intermediate_size": 11008,
38
+ "max_position_embeddings": 32768,
39
+ "max_window_layers": 70,
40
+ "model_type": "qwen2",
41
+ "null_token_id": 152678,
42
+ "num_attention_heads": 16,
43
+ "num_hidden_layers": 36,
44
+ "num_key_value_heads": 2,
45
+ "rms_norm_eps": 1e-06,
46
+ "rope_scaling": null,
47
+ "rope_theta": 1000000.0,
48
+ "sliding_window": 32768,
49
+ "switch_token_id": 152679,
50
+ "text_mask_token_id": 151676,
51
+ "tie_word_embeddings": true,
52
+ "torch_dtype": "bfloat16",
53
+ "use_cache": false,
54
+ "use_sliding_window": false,
55
+ "vocab_size": 152681
56
+ },
57
+ "torch_dtype": "bfloat16",
58
+ "transformers_version": null,
59
+ "use_backbone_lora": 0,
60
+ "use_llm_lora": 0,
61
+ "vision_config": {
62
+ "_attn_implementation_autoset": true,
63
+ "_name_or_path": "moonshotai/MoonViT-SO-400M",
64
+ "auto_map": {
65
+ "AutoConfig": "moonshotai/MoonViT-SO-400M--configuration_moonvit.MoonViTConfig",
66
+ "AutoModel": "moonshotai/MoonViT-SO-400M--modeling_moonvit.MoonVitPretrainedModel"
67
+ },
68
+ "hidden_size": 1152,
69
+ "init_pos_emb_height": 64,
70
+ "init_pos_emb_width": 64,
71
+ "intermediate_size": 4304,
72
+ "merge_kernel_size": [
73
+ 2,
74
+ 2
75
+ ],
76
+ "model_type": "moonvit",
77
+ "num_attention_heads": 16,
78
+ "num_hidden_layers": 27,
79
+ "patch_size": 14,
80
+ "torch_dtype": "bfloat16"
81
+ },
82
+ "quantization_config": {
83
+ "quant_method": "exl3",
84
+ "version": "0.0.39",
85
+ "bits": 6.0,
86
+ "head_bits": 8,
87
+ "calibration": {
88
+ "rows": 250,
89
+ "cols": 2048
90
+ },
91
+ "out_scales": "always",
92
+ "codebook": "mcg"
93
+ }
94
+ }
configuration_locateanything.py ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # --------------------------------------------------------
2
+ # InternVL
3
+ # Copyright (c) 2023 OpenGVLab
4
+ # Licensed under The MIT License [see LICENSE for details]
5
+ # --------------------------------------------------------
6
+
7
+ import copy
8
+
9
+ from transformers.models.qwen2.configuration_qwen2 import Qwen2Config
10
+ from transformers.models.qwen3.configuration_qwen3 import Qwen3Config
11
+ from transformers.configuration_utils import PretrainedConfig
12
+ from transformers.utils import logging
13
+ logger = logging.get_logger(__name__)
14
+
15
+ class MoonViTConfig(PretrainedConfig):
16
+ model_type = "moonvit"
17
+
18
+ def __init__(
19
+ self,
20
+ patch_size: int = 14,
21
+ init_pos_emb_height: int = 64,
22
+ init_pos_emb_width: int = 64,
23
+ num_attention_heads: int = 16,
24
+ num_hidden_layers: int = 27,
25
+ hidden_size: int = 1152,
26
+ intermediate_size: int = 4304,
27
+ merge_kernel_size: tuple[int, int] = (2, 2),
28
+ **kwargs,
29
+ ):
30
+ super().__init__(**kwargs)
31
+ self.patch_size = patch_size
32
+ # Positional embedding config
33
+ self.init_pos_emb_height = init_pos_emb_height
34
+ self.init_pos_emb_width = init_pos_emb_width
35
+ # Transformer config
36
+ self.num_hidden_layers = num_hidden_layers
37
+ self.num_attention_heads = num_attention_heads
38
+ self.hidden_size = hidden_size
39
+ self.intermediate_size = intermediate_size
40
+ # Patch merger config
41
+ self.merge_kernel_size = merge_kernel_size
42
+
43
+
44
+ class LocateAnythingConfig(PretrainedConfig):
45
+ model_type = 'locateanything'
46
+ is_composition = True
47
+ sub_configs = {"vision_config": MoonViTConfig, "text_config": Qwen2Config}
48
+ def __init__(
49
+ self,
50
+ vision_config=None,
51
+ text_config=None,
52
+ use_backbone_lora=0,
53
+ use_llm_lora=0,
54
+ downsample_ratio=0.5,
55
+ template=None,
56
+ loss_version='v1',
57
+ mlp_checkpoint=False,
58
+ image_token_index=151667,
59
+ box_start_token_id=151668,
60
+ box_end_token_id=151669,
61
+ coord_start_token_id=151677,
62
+ coord_end_token_id=152677,
63
+ ref_start_token_id=151672,
64
+ ref_end_token_id=151673,
65
+ none_token_id=4064,
66
+ **kwargs):
67
+ super().__init__(**kwargs)
68
+
69
+ if vision_config is None:
70
+ vision_config = {'model_type': 'moonvit'}
71
+ logger.info('vision_config is None. Initializing the MoonViTConfig with default values.')
72
+
73
+ if text_config is None:
74
+ text_config = {'architectures': ['Qwen2ForCausalLM']}
75
+ logger.info('text_config is None. Initializing the Qwen2Config config with default values.')
76
+
77
+ if vision_config['model_type'] == 'moonvit':
78
+ self.vision_config = MoonViTConfig(**vision_config)
79
+ else:
80
+ raise ValueError('Unsupported model_type: {}. Only moonvit is supported.'.format(vision_config['model_type']))
81
+
82
+
83
+ if text_config['architectures'][0] == 'Qwen2ForCausalLM':
84
+ self.text_config = Qwen2Config(**text_config)
85
+ elif text_config['architectures'][0] == 'Qwen3ForCausalLM':
86
+ self.text_config = Qwen3Config(**text_config)
87
+ else:
88
+ raise ValueError('Unsupported architecture: {}. Only Qwen2ForCausalLM and Qwen3ForCausalLM are supported.'.format(text_config['architectures'][0]))
89
+ self.use_backbone_lora = use_backbone_lora
90
+ self.use_llm_lora = use_llm_lora
91
+ self.mlp_checkpoint = mlp_checkpoint
92
+ self.downsample_ratio = downsample_ratio
93
+ self.template = template
94
+ self.loss_version = loss_version
95
+ self.tie_word_embeddings = self.text_config.tie_word_embeddings
96
+ self.image_token_index = image_token_index
97
+ self.box_start_token_id = box_start_token_id
98
+ self.box_end_token_id = box_end_token_id
99
+ self.coord_start_token_id = coord_start_token_id
100
+ self.coord_end_token_id = coord_end_token_id
101
+ self.ref_start_token_id = ref_start_token_id
102
+ self.ref_end_token_id = ref_end_token_id
103
+ self.none_token_id = none_token_id
104
+
105
+ def to_dict(self):
106
+ """
107
+ Serializes this instance to a Python dictionary. Override the default [`~PretrainedConfig.to_dict`].
108
+
109
+ Returns:
110
+ `Dict[str, any]`: Dictionary of all the attributes that make up this configuration instance,
111
+ """
112
+ output = copy.deepcopy(self.__dict__)
113
+ output['vision_config'] = self.vision_config.to_dict()
114
+ output['text_config'] = self.text_config.to_dict()
115
+ output['model_type'] = self.__class__.model_type
116
+ output['use_backbone_lora'] = self.use_backbone_lora
117
+ output['use_llm_lora'] = self.use_llm_lora
118
+ output['downsample_ratio'] = self.downsample_ratio
119
+ output['template'] = self.template
120
+ output['image_token_index'] = self.image_token_index
121
+ output['box_start_token_id'] = self.box_start_token_id
122
+ output['box_end_token_id'] = self.box_end_token_id
123
+ output['coord_start_token_id'] = self.coord_start_token_id
124
+ output['coord_end_token_id'] = self.coord_end_token_id
125
+ output['ref_start_token_id'] = self.ref_start_token_id
126
+ output['ref_end_token_id'] = self.ref_end_token_id
127
+ output['none_token_id'] = self.none_token_id
128
+ output['_attn_implementation'] = self._attn_implementation
129
+ if hasattr(self, '_attn_implementation_autoset'):
130
+ output['_attn_implementation_autoset'] = self._attn_implementation_autoset
131
+ return output
configuration_qwen2.py ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding=utf-8
2
+ # Copyright 2024 The Qwen team, Alibaba Group and the HuggingFace Inc. team. All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ """ Qwen2 model configuration"""
16
+
17
+ from transformers.configuration_utils import PretrainedConfig
18
+ from transformers.utils import logging
19
+
20
+
21
+ logger = logging.get_logger(__name__)
22
+
23
+ QWEN2_PRETRAINED_CONFIG_ARCHIVE_MAP = {
24
+ "Qwen/Qwen2-7B-beta": "https://huggingface.co/Qwen/Qwen2-7B-beta/resolve/main/config.json",
25
+ }
26
+
27
+
28
+ class Qwen2Config(PretrainedConfig):
29
+ r"""
30
+ This is the configuration class to store the configuration of a [`Qwen2Model`]. It is used to instantiate a
31
+ Qwen2 model according to the specified arguments, defining the model architecture. Instantiating a configuration
32
+ with the defaults will yield a similar configuration to that of
33
+ Qwen2-7B-beta [Qwen/Qwen2-7B-beta](https://huggingface.co/Qwen/Qwen2-7B-beta).
34
+
35
+ Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the
36
+ documentation from [`PretrainedConfig`] for more information.
37
+
38
+
39
+ Args:
40
+ vocab_size (`int`, *optional*, defaults to 151936):
41
+ Vocabulary size of the Qwen2 model. Defines the number of different tokens that can be represented by the
42
+ `inputs_ids` passed when calling [`Qwen2Model`]
43
+ hidden_size (`int`, *optional*, defaults to 4096):
44
+ Dimension of the hidden representations.
45
+ intermediate_size (`int`, *optional*, defaults to 22016):
46
+ Dimension of the MLP representations.
47
+ num_hidden_layers (`int`, *optional*, defaults to 32):
48
+ Number of hidden layers in the Transformer encoder.
49
+ num_attention_heads (`int`, *optional*, defaults to 32):
50
+ Number of attention heads for each attention layer in the Transformer encoder.
51
+ num_key_value_heads (`int`, *optional*, defaults to 32):
52
+ This is the number of key_value heads that should be used to implement Grouped Query Attention. If
53
+ `num_key_value_heads=num_attention_heads`, the model will use Multi Head Attention (MHA), if
54
+ `num_key_value_heads=1 the model will use Multi Query Attention (MQA) otherwise GQA is used. When
55
+ converting a multi-head checkpoint to a GQA checkpoint, each group key and value head should be constructed
56
+ by meanpooling all the original heads within that group. For more details checkout [this
57
+ paper](https://arxiv.org/pdf/2305.13245.pdf). If it is not specified, will default to `32`.
58
+ hidden_act (`str` or `function`, *optional*, defaults to `"silu"`):
59
+ The non-linear activation function (function or string) in the decoder.
60
+ max_position_embeddings (`int`, *optional*, defaults to 32768):
61
+ The maximum sequence length that this model might ever be used with.
62
+ initializer_range (`float`, *optional*, defaults to 0.02):
63
+ The standard deviation of the truncated_normal_initializer for initializing all weight matrices.
64
+ rms_norm_eps (`float`, *optional*, defaults to 1e-06):
65
+ The epsilon used by the rms normalization layers.
66
+ use_cache (`bool`, *optional*, defaults to `True`):
67
+ Whether or not the model should return the last key/values attentions (not used by all models). Only
68
+ relevant if `config.is_decoder=True`.
69
+ tie_word_embeddings (`bool`, *optional*, defaults to `False`):
70
+ Whether the model's input and output word embeddings should be tied.
71
+ rope_theta (`float`, *optional*, defaults to 10000.0):
72
+ The base period of the RoPE embeddings.
73
+ use_sliding_window (`bool`, *optional*, defaults to `False`):
74
+ Whether to use sliding window attention.
75
+ sliding_window (`int`, *optional*, defaults to 4096):
76
+ Sliding window attention (SWA) window size. If not specified, will default to `4096`.
77
+ max_window_layers (`int`, *optional*, defaults to 28):
78
+ The number of layers that use SWA (Sliding Window Attention). The bottom layers use SWA while the top use full attention.
79
+ attention_dropout (`float`, *optional*, defaults to 0.0):
80
+ The dropout ratio for the attention probabilities.
81
+
82
+ ```python
83
+ >>> from transformers import Qwen2Model, Qwen2Config
84
+
85
+ >>> # Initializing a Qwen2 style configuration
86
+ >>> configuration = Qwen2Config()
87
+
88
+ >>> # Initializing a model from the Qwen2-7B style configuration
89
+ >>> model = Qwen2Model(configuration)
90
+
91
+ >>> # Accessing the model configuration
92
+ >>> configuration = model.config
93
+ ```"""
94
+
95
+ model_type = "qwen2"
96
+ keys_to_ignore_at_inference = ["past_key_values"]
97
+
98
+ def __init__(
99
+ self,
100
+ vocab_size=151936,
101
+ hidden_size=4096,
102
+ intermediate_size=22016,
103
+ num_hidden_layers=32,
104
+ num_attention_heads=32,
105
+ num_key_value_heads=32,
106
+ hidden_act="silu",
107
+ max_position_embeddings=32768,
108
+ initializer_range=0.02,
109
+ rms_norm_eps=1e-6,
110
+ use_cache=True,
111
+ tie_word_embeddings=False,
112
+ rope_theta=10000.0,
113
+ use_sliding_window=False,
114
+ sliding_window=4096,
115
+ max_window_layers=28,
116
+ attention_dropout=0.0,
117
+ **kwargs,
118
+ ):
119
+ self.vocab_size = vocab_size
120
+ self.max_position_embeddings = max_position_embeddings
121
+ self.hidden_size = hidden_size
122
+ self.intermediate_size = intermediate_size
123
+ self.num_hidden_layers = num_hidden_layers
124
+ self.num_attention_heads = num_attention_heads
125
+ self.use_sliding_window = use_sliding_window
126
+ self.sliding_window = sliding_window
127
+ self.max_window_layers = max_window_layers
128
+
129
+ # for backward compatibility
130
+ if num_key_value_heads is None:
131
+ num_key_value_heads = num_attention_heads
132
+
133
+ self.num_key_value_heads = num_key_value_heads
134
+ self.hidden_act = hidden_act
135
+ self.initializer_range = initializer_range
136
+ self.rms_norm_eps = rms_norm_eps
137
+ self.use_cache = use_cache
138
+ self.rope_theta = rope_theta
139
+ self.attention_dropout = attention_dropout
140
+ if kwargs.get('attn_implementation', None) is None:
141
+ self.attn_implementation = kwargs['attn_implementation'] = 'flash_attention_2'
142
+ else:
143
+ self.attn_implementation = kwargs['attn_implementation']
144
+
145
+ super().__init__(
146
+ tie_word_embeddings=tie_word_embeddings,
147
+ **kwargs,
148
+ )
generate_utils.py ADDED
@@ -0,0 +1,504 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved.
2
+ #
3
+ # NVIDIA CORPORATION and its licensors retain all intellectual property
4
+ # and proprietary rights in and to this software, related documentation
5
+ # and any modifications thereto. Any use, reproduction, disclosure or
6
+ # distribution of this software and related documentation without an express
7
+ # license agreement from NVIDIA CORPORATION is strictly prohibited.
8
+
9
+ import torch
10
+ import torch.nn.functional as F
11
+ import torch.distributions as dists
12
+ from typing import Dict, Optional
13
+
14
+
15
+ def get_token_ids_from_config(config) -> Dict[str, int]:
16
+ """Extract all token IDs from the configuration object.
17
+
18
+ Args:
19
+ config: Configuration object (LocateAnythingConfig or similar)
20
+
21
+ Returns:
22
+ Dictionary containing all token IDs
23
+ """
24
+ token_ids = {}
25
+
26
+ # Get from main config
27
+ token_ids['box_start_token_id'] = getattr(config, 'box_start_token_id', 151668)
28
+ token_ids['box_end_token_id'] = getattr(config, 'box_end_token_id', 151669)
29
+ token_ids['coord_start_token_id'] = getattr(config, 'coord_start_token_id', 151677)
30
+ token_ids['coord_end_token_id'] = getattr(config, 'coord_end_token_id', 152677)
31
+ token_ids['ref_start_token_id'] = getattr(config, 'ref_start_token_id', 151672)
32
+ token_ids['ref_end_token_id'] = getattr(config, 'ref_end_token_id', 151673)
33
+ token_ids['none_token_id'] = getattr(config, 'none_token_id', 4064)
34
+
35
+ # Get from text_config
36
+ text_config = getattr(config, 'text_config', None)
37
+ if text_config is not None:
38
+ token_ids['null_token_id'] = getattr(text_config, 'null_token_id', 152678)
39
+ token_ids['im_end_token_id'] = getattr(text_config, 'eos_token_id', 151645)
40
+ token_ids['switch_token_id'] = getattr(text_config, 'switch_token_id', 152679)
41
+ token_ids['default_mask_token_id'] = getattr(text_config, 'text_mask_token_id', 151676)
42
+ else:
43
+ token_ids['null_token_id'] = 152678
44
+ token_ids['im_end_token_id'] = 151645
45
+ token_ids['switch_token_id'] = 152679
46
+ token_ids['default_mask_token_id'] = 151676
47
+
48
+ return token_ids
49
+
50
+
51
+ def top_p_logits(
52
+ logits: torch.Tensor,
53
+ top_p: float = None
54
+ ) -> torch.Tensor:
55
+ sorted_logits, sorted_indices = torch.sort(logits, descending=True)
56
+ cumulative_probs = torch.cumsum(F.softmax(sorted_logits, dim=-1), dim=-1)
57
+ sorted_indices_to_remove = cumulative_probs > top_p
58
+ # Shift the indices to the right to keep the first token above the threshold
59
+ sorted_indices_to_remove[..., 1:] = sorted_indices_to_remove[..., :-1].clone()
60
+ sorted_indices_to_remove[..., 0] = 0
61
+
62
+ mask = torch.zeros_like(logits, dtype=torch.bool, device=logits.device)
63
+ mask = mask.scatter_(-1, sorted_indices, sorted_indices_to_remove)
64
+ logits = logits.masked_fill(mask, torch.finfo(logits.dtype).min)
65
+ return logits
66
+
67
+
68
+ def top_k_logits(
69
+ logits: torch.Tensor,
70
+ top_k: int = None
71
+ ) -> torch.Tensor:
72
+ top_k = min(top_k, logits.size(-1)) # Safety check
73
+ # Remove all tokens with a probability less than the last token of the top-k
74
+ indices_to_remove = logits < torch.topk(logits, top_k)[0][..., -1, None]
75
+ logits = logits.masked_fill(indices_to_remove, torch.finfo(logits.dtype).min)
76
+ return logits
77
+
78
+
79
+ def apply_repetition_penalty(
80
+ logits: torch.Tensor,
81
+ input_ids: torch.Tensor,
82
+ repetition_penalty: float = 1.0
83
+ ) -> torch.Tensor:
84
+ """
85
+ Apply repetition penalty to logits.
86
+
87
+ Args:
88
+ logits: Shape [batch_size, seq_len, vocab_size] or [batch_size, vocab_size]
89
+ input_ids: Previously generated token ids, shape [batch_size, seq_len]
90
+ repetition_penalty: Penalty factor. > 1.0 penalizes repetition, < 1.0 encourages it.
91
+
92
+ Returns:
93
+ Modified logits with repetition penalty applied.
94
+ """
95
+ if repetition_penalty == 1.0:
96
+ return logits
97
+
98
+ # Convert to 3D for vectorized computation
99
+ if logits.dim() == 2:
100
+ logits = logits.unsqueeze(1) # [B, 1, V]
101
+ squeeze_back = True
102
+ else:
103
+ squeeze_back = False
104
+
105
+ batch_size, seq_len, vocab_size = logits.shape
106
+
107
+ # Construct [B, V] bool mask marking tokens that have appeared in each batch
108
+ device = logits.device
109
+ token_mask = torch.zeros(batch_size, vocab_size, dtype=torch.bool, device=device)
110
+ for b in range(batch_size):
111
+ # Apply penalty only based on tokens already generated in this batch
112
+ unique_tokens = input_ids[b].unique()
113
+ # Prevent out-of-bounds: only keep IDs within vocab range
114
+ valid_tokens = unique_tokens[(unique_tokens >= 0) & (unique_tokens < vocab_size)]
115
+ if valid_tokens.numel() > 0:
116
+ token_mask[b, valid_tokens] = True
117
+
118
+ # Expand to [B, L, V] to align with logits
119
+ token_mask = token_mask.unsqueeze(1).expand(-1, seq_len, -1)
120
+
121
+ # Divide positive values by penalty, multiply negative values by penalty
122
+ positive = logits > 0
123
+ negative = ~positive
124
+
125
+ # Apply penalty only at mask positions
126
+ logits = torch.where(token_mask & positive, logits / repetition_penalty, logits)
127
+ logits = torch.where(token_mask & negative, logits * repetition_penalty, logits)
128
+
129
+ if squeeze_back:
130
+ logits = logits.squeeze(1)
131
+
132
+ return logits
133
+
134
+
135
+ def sample_tokens(
136
+ logits: torch.Tensor,
137
+ generated: torch.Tensor,
138
+ token_ids: Dict[str, int],
139
+ **generate_kwargs,
140
+ ):
141
+ batch_size, seq_len, vocab_size = logits.shape
142
+
143
+ repetition_penalty = generate_kwargs.get('repetition_penalty', 1.0)
144
+ temperature = generate_kwargs.get('temperature', 0)
145
+ top_p = generate_kwargs.get('top_p', None)
146
+ top_k = generate_kwargs.get('top_k', None)
147
+
148
+ # Apply repetition penalty based on all previously generated tokens
149
+ if repetition_penalty != 1.0:
150
+ logits = apply_repetition_penalty(logits, generated, repetition_penalty)
151
+
152
+ if temperature > 0:
153
+ logits = logits / temperature
154
+ if top_p is not None and top_p < 1:
155
+ logits = top_p_logits(logits, top_p)
156
+ if top_k is not None:
157
+ logits = top_k_logits(logits, top_k)
158
+
159
+ probs = torch.softmax(logits, dim=-1)
160
+
161
+ if temperature > 0:
162
+ try:
163
+ x0 = dists.Categorical(probs=probs).sample()
164
+ confidence = torch.gather(probs, -1, x0.unsqueeze(-1)).squeeze(-1)
165
+ except Exception:
166
+ confidence, x0 = probs.max(dim=-1)
167
+ else:
168
+ confidence, x0 = probs.max(dim=-1)
169
+
170
+ if seq_len == 1:
171
+ return probs, confidence, x0, None
172
+
173
+ box_avg = []
174
+ fallback_box = torch.zeros(1, dtype=x0.dtype, device=x0.device)
175
+
176
+ for b in range(batch_size):
177
+ decoded_box = decode_bbox_avg(
178
+ logits[b], probs[b], token_ids, keep_k=generate_kwargs.get('keep_k_avg', 4),
179
+ generation_mode=generate_kwargs.get('generation_mode', 'hybrid'),
180
+ )
181
+ if decoded_box is not None:
182
+ box_avg.append(decoded_box)
183
+ else:
184
+ out_ref = decode_ref(logits[b], probs[b], token_ids)
185
+ if out_ref is not None:
186
+ box_avg.append(torch.tensor(out_ref, dtype=x0.dtype, device=x0.device))
187
+ else:
188
+ box_avg.append(fallback_box)
189
+
190
+ box_avg = torch.stack(box_avg)
191
+
192
+ return probs, confidence, x0, box_avg
193
+
194
+
195
+ def sample_tokens_ar(
196
+ logits: torch.Tensor,
197
+ generated: torch.Tensor,
198
+ token_ids: Dict[str, int],
199
+ **generate_kwargs,
200
+ ):
201
+ """
202
+ Lightweight sampling function for AR single-step sampling only.
203
+
204
+ Args:
205
+ logits: [batch_size, vocab_size] or [batch_size, 1, vocab_size]
206
+ generated: [batch_size, seq_len]
207
+ """
208
+ # Convert to 3D for reusing repetition penalty and clipping logic
209
+ if logits.dim() == 2:
210
+ logits = logits.unsqueeze(1) # [B, 1, V]
211
+ batch_size, seq_len, vocab_size = logits.shape
212
+ assert seq_len == 1, "sample_tokens_ar only supports single-step AR sampling (seq_len == 1)"
213
+
214
+ repetition_penalty = generate_kwargs.get('repetition_penalty', 1.0)
215
+ temperature = generate_kwargs.get('temperature', 0)
216
+ top_p = generate_kwargs.get('top_p', None)
217
+ top_k = generate_kwargs.get('top_k', None)
218
+
219
+ # Apply repetition penalty only based on historically generated tokens
220
+ if repetition_penalty != 1.0:
221
+ logits = apply_repetition_penalty(logits, generated, repetition_penalty)
222
+
223
+ if temperature > 0:
224
+ logits = logits / temperature
225
+ if top_p is not None and top_p < 1:
226
+ logits = top_p_logits(logits, top_p)
227
+ if top_k is not None:
228
+ logits = top_k_logits(logits, top_k)
229
+
230
+ probs = torch.softmax(logits, dim=-1)
231
+
232
+ if temperature > 0:
233
+ try:
234
+ x0 = dists.Categorical(probs=probs).sample()
235
+ confidence = torch.gather(probs, -1, x0.unsqueeze(-1)).squeeze(-1)
236
+ except Exception:
237
+ confidence, x0 = probs.max(dim=-1)
238
+ else:
239
+ # For greedy: directly take the token with maximum probability
240
+ confidence, x0 = probs.max(dim=-1)
241
+
242
+ # Keep interface consistent with sample_tokens: return [B, 1, V] / [B, 1] shape
243
+ return probs, confidence, x0, None, None
244
+
245
+
246
+ def is_valid_box_frame(
247
+ probs,
248
+ token_ids: Dict[str, int],
249
+ start_thresh=0.6,
250
+ end_thresh=0.2,
251
+ topk=5,
252
+ ):
253
+ box_start_token_id = token_ids['box_start_token_id']
254
+ box_end_token_id = token_ids['box_end_token_id']
255
+ null_token_id = token_ids['null_token_id']
256
+ im_end_token_id = token_ids['im_end_token_id']
257
+ none_token_id = token_ids['none_token_id'] # none
258
+
259
+ p_start = probs[0, box_start_token_id]
260
+ if p_start >= start_thresh:
261
+ if (probs[1, none_token_id] > 0.2 and
262
+ probs[2, box_end_token_id] > 0.2 and
263
+ probs[3, null_token_id] > 0.1 and
264
+ probs[4, null_token_id] > 0.1):
265
+ return 'empty_box'
266
+
267
+ end_target_ids = torch.tensor([box_end_token_id, null_token_id, im_end_token_id], device=probs.device)
268
+ end_score = probs[5, end_target_ids].sum()
269
+
270
+ if end_score >= end_thresh:
271
+ return 'legal_box'
272
+
273
+ return 'illegal_box'
274
+
275
+
276
+ def decode_bbox_avg(
277
+ logits,
278
+ probs,
279
+ token_ids: Dict[str, int],
280
+ keep_k=5,
281
+ start_thresh=0.7,
282
+ end_thresh=0.2,
283
+ generation_mode: str = 'hybrid',
284
+ ):
285
+ """
286
+ Decode bounding box coordinates using top-k weighted average.
287
+
288
+ Args:
289
+ logits: Logits of shape (6, vocab_size)
290
+ probs: Probability distribution of shape (6, vocab_size)
291
+ token_ids: Dictionary containing all token IDs
292
+ keep_k: Number of top-k candidate tokens to keep at each position
293
+ start_thresh: Confidence threshold for box start token
294
+ end_thresh: Confidence threshold for box end token
295
+
296
+ Returns:
297
+ Decoded bounding box coordinate list in format [box_start, x1, x2, y1, y2, box_end],
298
+ or None if decoding fails
299
+ """
300
+ coord_start_token_id = token_ids['coord_start_token_id']
301
+ coord_end_token_id = token_ids['coord_end_token_id']
302
+ box_start_token_id = token_ids['box_start_token_id']
303
+ box_end_token_id = token_ids['box_end_token_id']
304
+ none_token_id = token_ids['none_token_id']
305
+
306
+ device = logits.device
307
+
308
+ box_type = is_valid_box_frame(
309
+ probs,
310
+ token_ids,
311
+ start_thresh=start_thresh,
312
+ end_thresh=end_thresh,
313
+ topk=keep_k
314
+ )
315
+ if box_type == 'empty_box':
316
+ # Handle the <box>none</box> case first
317
+ return torch.tensor([
318
+ box_start_token_id,
319
+ none_token_id,
320
+ box_end_token_id,
321
+ token_ids['null_token_id'],
322
+ token_ids['null_token_id'],
323
+ token_ids['null_token_id']
324
+ ], dtype=torch.long, device=probs.device)
325
+ elif box_type == 'illegal_box':
326
+ return None
327
+
328
+ # Extract probabilities at positions 1-4 and compute Top-K for all 4 positions at once
329
+ pos_probs, pos_ids = torch.topk(probs[1:5], k=keep_k, dim=-1)
330
+ mask = (pos_ids >= coord_start_token_id) & (pos_ids <= coord_end_token_id)
331
+ has_valid = mask.any(dim=-1) # shape: [4]
332
+ if not has_valid.all():
333
+ return None # not a box, exit...
334
+
335
+ first_valid_idx = mask.long().argmax(dim=-1, keepdim=True) # [4, 1]
336
+ # Extract highest-probability valid_probs[0] and corresponding valid_ids[0]
337
+ first_valid_probs = pos_probs.gather(-1, first_valid_idx).squeeze(-1) # [4]
338
+ first_valid_ids = pos_ids.gather(-1, first_valid_idx).squeeze(-1) # [4]
339
+ if generation_mode == 'hybrid':
340
+ valid_counts = mask.sum(dim=-1) # [4]
341
+ # Compute max/min of valid ids: fill invalid positions with extreme values to avoid interfering with max/min
342
+ LARGE_NUM, SMALL_NUM = 999999, -999999
343
+ valid_ids_for_max = torch.where(mask, pos_ids, torch.tensor(SMALL_NUM, device=device))
344
+ valid_ids_for_min = torch.where(mask, pos_ids, torch.tensor(LARGE_NUM, device=device))
345
+
346
+ valid_max = valid_ids_for_max.max(dim=-1)[0]
347
+ valid_min = valid_ids_for_min.min(dim=-1)[0]
348
+
349
+ is_abnormal = (first_valid_probs < 0.9) & (valid_counts > 1) & ((valid_max - valid_min) > 60)
350
+ # is_abnormal = (first_valid_probs < 0.7) & (valid_counts > 1) & ((valid_max - valid_min) > 80)
351
+
352
+ # Normal positions take top-1 (first_valid_ids); abnormal positions are replaced with 0
353
+ final_coords = torch.where(is_abnormal, torch.tensor(0, device=pos_ids.device), first_valid_ids)
354
+ elif generation_mode == 'fast':
355
+ final_coords = first_valid_ids
356
+
357
+
358
+ start_t = torch.tensor([box_start_token_id], dtype=final_coords.dtype, device=device)
359
+ end_t = torch.tensor([box_end_token_id], dtype=final_coords.dtype, device=device)
360
+
361
+ return torch.cat([start_t, final_coords, end_t])
362
+
363
+
364
+ def decode_ref(
365
+ logits,
366
+ probs,
367
+ token_ids: Dict[str, int],
368
+ keep_k=5,
369
+ start_thresh=0.6,
370
+ ):
371
+ ref_start_token_id = token_ids.get('ref_start_token_id')
372
+ coord_start_token_id = token_ids['coord_start_token_id']
373
+ coord_end_token_id = token_ids['coord_end_token_id']
374
+ device = probs.device
375
+ L = probs.size(0)
376
+
377
+ # 1. Check if the first position is <ref> and its probability meets start_thresh
378
+ # Note: we directly use the probability of the ref token at position 0 for the check
379
+ if probs[0, ref_start_token_id] < start_thresh:
380
+ return None
381
+
382
+ # 2. Extract Top-K probabilities and token IDs for all subsequent positions
383
+ pos_probs, pos_ids = torch.topk(probs[1:], k=keep_k, dim=-1) # shape: [L-1, keep_k]
384
+
385
+ # 3. Build mask: identify coordinate tokens (<0> ~ <1000>)
386
+ is_coord = (pos_ids >= coord_start_token_id) & (pos_ids <= coord_end_token_id)
387
+ # Invert: valid tokens are non-coordinate tokens
388
+ is_valid = ~is_coord # shape: [L-1, keep_k]
389
+
390
+ # Ensure each position has at least one non-coordinate valid token in its Top-K
391
+ has_valid = is_valid.any(dim=-1) # shape: [L-1]
392
+ if not has_valid.all():
393
+ return None
394
+
395
+ # 4. Get the highest-probability valid token
396
+ # Since topk results are sorted in descending order of probability,
397
+ # argmax returns the first index where is_valid is True, i.e., the index of the most probable valid token
398
+ first_valid_idx = is_valid.long().argmax(dim=-1, keepdim=True) # shape: [L-1, 1]
399
+
400
+ # Extract the final token IDs
401
+ final_text_ids = pos_ids.gather(-1, first_valid_idx).squeeze(-1) # shape: [L-1]
402
+
403
+ start_t = torch.tensor([ref_start_token_id], dtype=final_text_ids.dtype, device=device)
404
+
405
+ return torch.cat([start_t, final_text_ids])
406
+
407
+
408
+ def handle_pattern(x0, token_ids: Dict[str, int], generation_mode: str = 'hybrid'):
409
+ """
410
+ Args:
411
+ x0: Token ID list of length 6
412
+ token_ids: Dictionary containing all token IDs
413
+ """
414
+ null_token_id = token_ids['null_token_id']
415
+ im_end_token_id = token_ids['im_end_token_id']
416
+ box_start_token_id = token_ids['box_start_token_id']
417
+ box_end_token_id = token_ids['box_end_token_id']
418
+ none_token_id = token_ids['none_token_id']
419
+ coord_start_token_id = token_ids['coord_start_token_id']
420
+ coord_end_token_id = token_ids['coord_end_token_id']
421
+ ref_end_token_id = token_ids['ref_end_token_id']
422
+
423
+ x0 = x0.tolist()
424
+
425
+ if x0[0] == null_token_id:
426
+ return {
427
+ "type": "im_end",
428
+ "tokens": [im_end_token_id],
429
+ "need_switch_to_ar": False,
430
+ "is_terminal": True,
431
+ }
432
+ elif x0[0] == im_end_token_id:
433
+ return {
434
+ "type": "im_end",
435
+ "tokens": [im_end_token_id],
436
+ "need_switch_to_ar": False,
437
+ "is_terminal": True,
438
+ }
439
+ elif x0[:2] == [box_start_token_id, none_token_id]:
440
+ return {
441
+ "type": "empty_box",
442
+ "tokens": [box_start_token_id, none_token_id, box_end_token_id],
443
+ "need_switch_to_ar": False,
444
+ "is_terminal": False,
445
+ }
446
+ elif x0[0] == box_start_token_id:
447
+ coord_ix = 1
448
+ for coord in x0[1:5]:
449
+ if coord_start_token_id <= coord <= coord_end_token_id:
450
+ coord_ix += 1
451
+ else:
452
+ break
453
+
454
+ # Standard 4-coordinate bbox: <box><x1><x2><y1><y2></box>
455
+ if coord_ix == 5 and x0[5] == box_end_token_id:
456
+ return {
457
+ "type": "coord_box",
458
+ "tokens": x0,
459
+ "need_switch_to_ar": False,
460
+ "is_terminal": False,
461
+ }
462
+ # Two-coordinate pointing: <box><x><y></box>
463
+ # Convention: the first two coordinates are valid coord tokens, the third token is box_end.
464
+ # Remaining positions (if any) are not part of the pattern; truncate at box_end.
465
+ elif coord_ix == 3 and x0[3] == box_end_token_id:
466
+ return {
467
+ "type": "point_box",
468
+ "tokens": x0[:4],
469
+ "need_switch_to_ar": False,
470
+ "is_terminal": False,
471
+ }
472
+ else:
473
+ if generation_mode == 'fast':
474
+ # fast mode: treat as coord_box, stay in MTP
475
+ return {
476
+ "type": "coord_box",
477
+ "tokens": x0,
478
+ "need_switch_to_ar": False,
479
+ "is_terminal": False,
480
+ }
481
+ else:
482
+ # hybrid mode: error_box, switch to AR
483
+ return {
484
+ "type": "error_box",
485
+ "tokens": x0[:coord_ix],
486
+ "need_switch_to_ar": True,
487
+ "is_terminal": False,
488
+ }
489
+
490
+ else:
491
+ for i, token in enumerate(x0):
492
+ if token == null_token_id:
493
+ x0 = x0[:i]
494
+ break
495
+
496
+ if len(x0) >= 2 and x0[-1] == x0[-2] == ref_end_token_id:
497
+ x0 = x0[:-1]
498
+
499
+ return {
500
+ "type": "ref_object",
501
+ "tokens": x0,
502
+ "need_switch_to_ar": False,
503
+ "is_terminal": False,
504
+ }
generation_config.json ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ {
2
+ "_from_model_config": true,
3
+ "bos_token_id": 151643,
4
+ "eos_token_id": 151645,
5
+ "transformers_version": "4.51.0"
6
+ }
image_processing_locateanything.py ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved.
2
+ #
3
+ # NVIDIA CORPORATION and its licensors retain all intellectual property
4
+ # and proprietary rights in and to this software, related documentation
5
+ # and any modifications thereto. Any use, reproduction, disclosure or
6
+ # distribution of this software and related documentation without an express
7
+ # license agreement from NVIDIA CORPORATION is strictly prohibited.
8
+
9
+ """Image processor class for KimiVL."""
10
+
11
+ import math
12
+ import numpy as np
13
+ from PIL import Image
14
+ from typing import Optional, Union
15
+
16
+ import torch
17
+ from torchvision.transforms import functional as TF
18
+ from transformers.image_utils import ImageInput, make_list_of_images, valid_images
19
+ from transformers.image_processing_utils import BaseImageProcessor, BatchFeature
20
+ from transformers.utils import TensorType
21
+ from transformers import AutoImageProcessor
22
+
23
+ MEAN = (0.5, 0.5, 0.5)
24
+ STD = (0.5, 0.5, 0.5)
25
+
26
+
27
+ class LocateAnythingImageProcessor(BaseImageProcessor):
28
+ model_type = "locateanything"
29
+
30
+ def __init__(
31
+ self,
32
+ patch_size: int = 14,
33
+ image_mean: tuple[float, float, float] = MEAN,
34
+ image_std: tuple[float, float, float] = STD,
35
+ in_token_limit: int = 4096,
36
+ merge_kernel_size: list[int, int] = [2, 2],
37
+ **kwargs,
38
+ ):
39
+ super().__init__(**kwargs)
40
+ self.in_token_limit = in_token_limit
41
+ self.patch_size = patch_size
42
+ self.image_mean = image_mean
43
+ self.image_std = image_std
44
+ self.merge_kernel_size = merge_kernel_size
45
+
46
+ def rescale(
47
+ self, image: Image.Image, merge_kernel_size: list[int, int] = [2, 2]
48
+ ) -> Image.Image:
49
+ w, h = image.size
50
+ patch_size = self.patch_size
51
+
52
+ if (w // patch_size) * (h // patch_size) > self.in_token_limit:
53
+ scale = math.sqrt(self.in_token_limit / ((w // patch_size) * (h // patch_size)))
54
+ new_w, new_h = int(w * scale), int(h * scale)
55
+ image = image.resize((new_w, new_h), Image.Resampling.BICUBIC)
56
+
57
+ new_w, new_h = image.size
58
+ pad_size_h = merge_kernel_size[0] * patch_size
59
+ pad_size_w = merge_kernel_size[1] * patch_size
60
+
61
+ target_w = math.ceil(new_w / pad_size_w) * pad_size_w
62
+ target_h = math.ceil(new_h / pad_size_h) * pad_size_h
63
+
64
+ if target_w != new_w or target_h != new_h:
65
+ image = image.resize((target_w, target_h), Image.Resampling.BICUBIC)
66
+
67
+ w, h = image.size
68
+ if w // patch_size >= 512 or h // patch_size >= 512:
69
+ raise ValueError("Exceed pos emb")
70
+
71
+ return image
72
+
73
+ def to_tensor(self, image: Image.Image) -> torch.Tensor:
74
+ return TF.to_tensor(image.convert("RGB"))
75
+
76
+ def normalize(self, image: torch.Tensor) -> torch.Tensor:
77
+ return TF.normalize(image, self.image_mean, self.image_std)
78
+
79
+ def patchify(self, image: torch.Tensor) -> tuple[torch.Tensor, list[int, int]]:
80
+ patch_size = self.patch_size
81
+ C, H, W = image.shape
82
+ patches = image.reshape(C, H // patch_size, patch_size, W // patch_size, patch_size)
83
+ patches = patches.permute(1, 3, 0, 2, 4)
84
+ patches = patches.contiguous().view(-1, C, patch_size, patch_size)
85
+ grid_hw = (H // patch_size, W // patch_size)
86
+ return patches, grid_hw
87
+
88
+ def _preprocess(self, image: ImageInput) -> tuple[torch.Tensor, list[int, int]]:
89
+ """
90
+ Preprocess image and patchify it.
91
+ Args:
92
+ image (`ImageInput`):
93
+ Image to preprocess. Expects pixel values ranging from 0 to 255. If pixel values range from 0 to 1, set `do_rescale=False`.
94
+ Returns:
95
+ patches: torch.Tensor
96
+ grid_hw: list[int, int]
97
+ """
98
+ image = self.rescale(image, self.merge_kernel_size)
99
+ image = self.to_tensor(image)
100
+ image = self.normalize(image)
101
+ patches, grid_hw = self.patchify(image)
102
+ return patches, grid_hw
103
+
104
+ def preprocess(
105
+ self,
106
+ images: ImageInput,
107
+ return_tensors: Optional[Union[str, TensorType]] = None,
108
+ ) -> BatchFeature:
109
+ images = make_list_of_images(images)
110
+
111
+ if not valid_images(images):
112
+ raise ValueError(
113
+ "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, "
114
+ "torch.Tensor, tf.Tensor or jax.ndarray."
115
+ )
116
+
117
+ pixel_values, image_grid_hws = [], []
118
+ for image in images:
119
+ patches, image_grid_hw = self._preprocess(image)
120
+ pixel_values.append(patches)
121
+ image_grid_hws.append(image_grid_hw)
122
+ pixel_values = torch.concat(pixel_values, dim=0)
123
+ image_grid_hws = np.array(image_grid_hws)
124
+ data = {"pixel_values": pixel_values, "image_grid_hws": image_grid_hws}
125
+
126
+ return BatchFeature(data=data, tensor_type=return_tensors)
127
+
128
+ AutoImageProcessor.register("LocateAnythingImageProcessor", LocateAnythingImageProcessor)
mask_magi_utils.py ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved.
2
+ #
3
+ # NVIDIA CORPORATION and its licensors retain all intellectual property
4
+ # and proprietary rights in and to this software, related documentation
5
+ # and any modifications thereto. Any use, reproduction, disclosure or
6
+ # distribution of this software and related documentation without an express
7
+ # license agreement from NVIDIA CORPORATION is strictly prohibited.
8
+
9
+ import torch
10
+
11
+ # MagiAttention attn_type_map convention
12
+ FULL, CAUSAL = 0, 1
13
+
14
+ def build_magi_ranges(kv_len: int, q_len: int, block_size: int, ar_decode: bool=False, device: str = "cpu"):
15
+ """
16
+ Fixed strategy:
17
+ - use_cache=True: Mask blocked_k = (kv_len - block_size - 1) column
18
+ - causal_attn=False: Window interior is FULL (bidirectional)
19
+ - If q_len==kv_len: Use coarse prefix version (fewer ranges)
20
+ - Otherwise: General decode version (recompute rows expanding visible region row by row)
21
+
22
+ Conventions:
23
+ - K/V global length kv_len: [0, kv_len)
24
+ - Current Q is "last q_len tokens"
25
+ - First r=q_len-block_size rows are recomputed; last block_size rows are window
26
+ """
27
+ assert 0 < q_len <= kv_len
28
+
29
+ if ar_decode:
30
+ return {
31
+ "q_ranges": torch.tensor([[0, q_len]], dtype=torch.int32, device=device).contiguous(),
32
+ "k_ranges": torch.tensor([[0, kv_len]], dtype=torch.int32, device=device).contiguous(),
33
+ "attn_type_map": torch.tensor([CAUSAL], dtype=torch.int32, device=device).contiguous(),
34
+ }
35
+
36
+
37
+ assert 0 < block_size <= q_len <= kv_len
38
+ B = block_size
39
+ r = q_len - B
40
+ q_global_start = kv_len - q_len
41
+
42
+ window_start_k = kv_len - B
43
+ blocked_k = window_start_k - 1 # The column that is blocked
44
+
45
+ q_ranges, k_ranges, types = [], [], []
46
+
47
+ # -------- prefix (q_len == kv_len) coarse-grained --------
48
+ if q_len == kv_len:
49
+ prefix_len = window_start_k # kv_len - B
50
+
51
+ # prefix->prefix: causal
52
+ if prefix_len > 0:
53
+ q_ranges += [[0, prefix_len]]
54
+ k_ranges += [[0, prefix_len]]
55
+ types += [CAUSAL]
56
+
57
+ # window->prefix: full, but exclude blocked_k => keys [0, blocked_k)
58
+ if prefix_len > 0 and blocked_k > 0:
59
+ q_ranges += [[prefix_len, kv_len]]
60
+ k_ranges += [[0, blocked_k]]
61
+ types += [FULL]
62
+
63
+ # window->window: full
64
+ q_ranges += [[prefix_len, kv_len]]
65
+ k_ranges += [[prefix_len, kv_len]]
66
+ types += [FULL]
67
+
68
+ return {
69
+ "q_ranges": torch.tensor(q_ranges, dtype=torch.int32, device=device).contiguous(),
70
+ "k_ranges": torch.tensor(k_ranges, dtype=torch.int32, device=device).contiguous(),
71
+ "attn_type_map": torch.tensor(types, dtype=torch.int32, device=device).contiguous(),
72
+ }
73
+
74
+ # -------- decode / general (q_len < kv_len) --------
75
+
76
+ # A) Recomputed rows: expand visible key cutoff row by row (use FULL + single-row q_range for precise shape)
77
+ for i in range(r):
78
+ g = q_global_start + i
79
+ q_ranges.append([i, i + 1])
80
+ k_ranges.append([0, g + 1]) # Allow keys [0, g]
81
+ types.append(FULL)
82
+
83
+ # B) Window rows: allow prefix but block blocked_k; window interior is full
84
+ q_win = [r, q_len]
85
+
86
+ # prefix keys [0, blocked_k)
87
+ if blocked_k > 0:
88
+ q_ranges.append(q_win)
89
+ k_ranges.append([0, blocked_k])
90
+ types.append(FULL)
91
+
92
+ # window keys [window_start_k, kv_len)
93
+ q_ranges.append(q_win)
94
+ k_ranges.append([window_start_k, kv_len])
95
+ types.append(FULL)
96
+
97
+ return {
98
+ "q_ranges": torch.tensor(q_ranges, dtype=torch.int32, device=device).contiguous(),
99
+ "k_ranges": torch.tensor(k_ranges, dtype=torch.int32, device=device).contiguous(),
100
+ "attn_type_map": torch.tensor(types, dtype=torch.int32, device=device).contiguous(),
101
+ }
mask_sdpa_utils.py ADDED
@@ -0,0 +1,232 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved.
2
+ #
3
+ # NVIDIA CORPORATION and its licensors retain all intellectual property
4
+ # and proprietary rights in and to this software, related documentation
5
+ # and any modifications thereto. Any use, reproduction, disclosure or
6
+ # distribution of this software and related documentation without an express
7
+ # license agreement from NVIDIA CORPORATION is strictly prohibited.
8
+
9
+ import torch
10
+
11
+
12
+ def find_prefix_seq_length_by_pe(
13
+ pe: torch.Tensor
14
+ ) -> torch.Tensor:
15
+ """
16
+ Find the sequence length where position encoding drops (indicating prefix boundary).
17
+ Args:
18
+ pe: Position encoding tensor of shape [Batch size, Sequence length ]
19
+ Contains position indices for each token in the sequence.
20
+ Returns:
21
+ torch.Tensor: A tensor of shape [B] containing:
22
+ - The index where position encoding drops for each sequence
23
+ - -1 if no drop occurs in the sequence
24
+ """
25
+ batch_size, seq_len = pe.shape
26
+ prev = pe[:, :-1]
27
+ curr = pe[:, 1:]
28
+ drop_mask = curr < prev # [batch_size, seq_len-1]
29
+
30
+ seq_len = torch.full((batch_size,), -1, dtype=torch.long)
31
+
32
+ for b in range(batch_size):
33
+ drop_pos = torch.nonzero(drop_mask[b], as_tuple=False)
34
+ if drop_pos.numel() > 0:
35
+ i = drop_pos[0].item() + 1 # Take first drop position (+1 because we compared shifted sequences)
36
+ seq_len[b] = i
37
+
38
+ return seq_len
39
+
40
+
41
+
42
+ def update_causal_mask_with_pad_non_visible_2d(
43
+ input_ids: torch.Tensor,
44
+ attn_mask_2d: torch.Tensor,
45
+ text_mask_token_id: int,
46
+ block_size: int = 4,
47
+ causal_attn: bool = False
48
+ ) -> torch.Tensor:
49
+ """
50
+ Updates a 2D attention mask for hole sequence through input_ids and text_mask_token_id
51
+
52
+ Args:
53
+ input_ids: Input token IDs (unused in current implementation)
54
+ attn_mask_2d: 2D attention mask matrix of shape [seq_len, seq_len] where:
55
+ - 0.0 indicates allowed attention
56
+ - -inf indicates masked attention
57
+ text_mask_token_id: ID representing masked tokens
58
+ block_size: Size of the diffusion window
59
+ causal_attn: If True, maintains strict causal masking throughout
60
+
61
+ Returns:
62
+ Modified attention mask with updated visibility patterns
63
+ """
64
+ seq_len = input_ids.shape[0]
65
+ device = input_ids.device
66
+
67
+ # Identify masked tokens and their preceding positions
68
+ input_mask = input_ids.eq(text_mask_token_id)
69
+ input_before_mask = torch.zeros_like(input_mask)
70
+ input_before_mask[:-1] = input_mask[1:]
71
+ mask_cols = (input_mask | input_before_mask)
72
+ non_mask = ~mask_cols
73
+
74
+ rows = torch.arange(seq_len, device=device)[:, None]
75
+ cols = torch.arange(seq_len, device=device)
76
+
77
+ indices = torch.arange(seq_len, device=device)
78
+ prev_non_mask = (indices * non_mask).cummax(dim=0).values
79
+
80
+ max_value = torch.iinfo(indices.dtype).max
81
+ mask_indices = torch.where(non_mask, indices, torch.full_like(indices, max_value))
82
+ reversed_mask_indices = torch.flip(mask_indices, dims=[0])
83
+ reversed_cummin = reversed_mask_indices.cummin(dim=0).values
84
+ next_non_mask = torch.flip(reversed_cummin, dims=[0])
85
+
86
+ infra_mask = (
87
+ (cols > prev_non_mask) &
88
+ (rows >= next_non_mask[None, :]) &
89
+ mask_cols[None, :]
90
+ )
91
+ attn_mask_2d.masked_fill_(infra_mask, -float('inf'))
92
+
93
+ if not causal_attn:
94
+ visible_mask = (
95
+ (rows > prev_non_mask[None, :]) &
96
+ (rows < cols) &
97
+ mask_cols[None, :]
98
+ )
99
+ attn_mask_2d.masked_fill_(visible_mask, 0.0)
100
+
101
+ return attn_mask_2d
102
+
103
+
104
+ def update_causal_mask_for_one_gen_window_2d(
105
+ input_ids: torch.Tensor,
106
+ attn_mask_2d: torch.Tensor,
107
+ block_size: int = 4,
108
+ use_cache: bool = True,
109
+ causal_attn: bool = False
110
+ ) -> torch.Tensor:
111
+ """
112
+ Updates a 2D attention mask for a diffusion window in transformer inference.
113
+
114
+ Args:
115
+ input_ids: Input token IDs (unused in current implementation)
116
+ attn_mask_2d: 2D attention mask matrix of shape [seq_len, seq_len] where:
117
+ - 0.0 indicates allowed attention
118
+ - -inf indicates masked attention
119
+ block_size: Size of the diffusion window
120
+ use_cache: Whether key-value cache is being used
121
+ causal_attn: If True, maintains strict causal masking throughout
122
+
123
+ Returns:
124
+ Modified attention mask with updated visibility patterns
125
+ """
126
+
127
+ if not causal_attn:
128
+ # Make the diffusion window (last block_size tokens) fully visible to itself
129
+ # This allows bidirectional attention within the diffusion window
130
+ attn_mask_2d[-block_size:, -block_size:] = 0.0
131
+ if use_cache:
132
+ # Mask the last token from previous round to prevent recomputation and maintain generation consistency.
133
+ attn_mask_2d[-block_size:, -block_size-1] = -float('inf')
134
+
135
+ return attn_mask_2d
136
+
137
+
138
+ def create_block_diff_mask_by_pe_4d(
139
+ block_size: int,
140
+ x0_len_list: torch.Tensor,
141
+ position_ids: torch.Tensor,
142
+ causal_attn: bool = False
143
+ ) -> tuple[torch.Tensor, torch.Tensor]:
144
+ """Generates a 4D attention mask for block-difference attention patterns.
145
+
146
+ The mask consists of three regions:
147
+ 1. Causal block (top-left): Standard causal attention for `x0` tokens.
148
+ 2. Mutual block (bottom-right): Non-causal attention within the same block for non-`x0` tokens.
149
+ 3. Prefix block (bottom-left): Non-`x0` tokens can attend to a prefix of `x0` tokens.
150
+
151
+ Args:
152
+ block_size (int): Size of processing blocks for non-`x0` tokens.
153
+ x0_len_list (torch.Tensor): Tensor of shape [B] containing lengths of `x0` segments per batch.
154
+ position_ids (torch.Tensor): Tensor of shape [B, seq_len] containing position IDs.
155
+ causal_attn (bool, optional): If True, enforces causal masking in mutual blocks. Defaults to False.
156
+
157
+ Returns:
158
+ tuple[torch.Tensor, torch.Tensor]:
159
+ - A float mask of shape [batch_size, 1, seq_len, seq_len] with `-inf` for masked positions (non visiable).
160
+ - A boolean mask of shape [batch_size, 1, seq_len, seq_len] indicating allowed attention positions.
161
+ """
162
+ batch_size, seq_len = position_ids.shape
163
+ device = position_ids.device
164
+
165
+ # Create position indices [batch_size, seq_len, seq_len]
166
+ q_idx = torch.arange(seq_len, device=device).view(1, seq_len, 1) # [1, seq_len, 1]
167
+ kv_idx = torch.arange(seq_len, device=device).view(1, 1, seq_len) # [1, 1, seq_len]
168
+
169
+ # Broadcast to [B, seq_len, seq_len]
170
+ x0_len = x0_len_list.view(batch_size, 1, 1) # [batch_size, 1, 1]
171
+ x0_flag_q = q_idx < x0_len # [batch_size, seq_len, seq_len]
172
+ x0_flag_kv = kv_idx < x0_len
173
+
174
+ # Block indices calculation [batch_size, seq_len, seq_len]
175
+ q_block_idx = (q_idx - x0_len) // block_size
176
+ kv_block_idx = (kv_idx - x0_len) // block_size
177
+
178
+ # causal block (top-left)
179
+ block_causal = x0_flag_q & x0_flag_kv & (q_idx >= kv_idx)
180
+
181
+ mutual_condition = (q_idx >= kv_idx) if causal_attn else torch.ones_like(q_idx, dtype=torch.bool)
182
+ block_mutual = (
183
+ ~x0_flag_q & ~x0_flag_kv &
184
+ (q_block_idx == kv_block_idx) &
185
+ mutual_condition
186
+ )
187
+
188
+ q_blk = torch.div(q_idx - x0_len, block_size, rounding_mode='floor')
189
+ q_blk_start = (x0_len_list.view(batch_size, 1) + q_blk[:, :, 0] * block_size).clamp(min=0, max=seq_len - 1)
190
+ prefix_len = position_ids.gather(1, q_blk_start)
191
+ prefix_len = prefix_len.unsqueeze(2)
192
+ block_prefix = (~x0_flag_q & x0_flag_kv) & (kv_idx < prefix_len)
193
+
194
+ final_mask = (block_causal | block_mutual | block_prefix)
195
+ customized_mask = torch.full_like(final_mask, float('-inf'), dtype=torch.bfloat16)
196
+ customized_mask.masked_fill_(final_mask, 0.0)
197
+
198
+ return customized_mask.unsqueeze(1).to(device=device), final_mask.unsqueeze(1).to(device=device)
199
+
200
+
201
+ def find_pred_pos_from_input_ids(
202
+ input_ids: torch.LongTensor = None,
203
+ text_mask_token_id: int = None,
204
+ ) -> torch.Tensor:
205
+ """Compute the relative prediction positions for masked tokens in a sequence.
206
+
207
+ For non-masked positions, the output is 0. For masked positions, the value increments
208
+ by 1 for each consecutive mask token, indicating how many steps ahead the prediction is.
209
+
210
+ Args:
211
+ input_ids (torch.LongTensor): Input token IDs of shape [batch_size, seq_len].
212
+ text_mask_token_id (int, optional): Token ID representing masked positions. Defaults to 151666.
213
+
214
+ Returns:
215
+ torch.Tensor: A tensor of shape [batch_size, seq_len] where:
216
+ - 0 indicates a non-masked token.
217
+ - n > 0 indicates the nth consecutive masked token (e.g., 1 = first mask, 2 = second mask, etc.).
218
+ """
219
+ batch_size, seq_len = input_ids.shape
220
+ device = input_ids.device
221
+
222
+ is_mask = (input_ids == text_mask_token_id)
223
+
224
+ base_mask = torch.zeros((batch_size, seq_len), dtype=torch.int8, device=device)
225
+
226
+ for b in range(batch_size):
227
+ for ix in range(1, seq_len):
228
+ if is_mask[b][ix] == True:
229
+ # Increment counter if current token is masked
230
+ base_mask[b][ix] = base_mask[b][ix-1] + 1
231
+
232
+ return base_mask
merges.txt ADDED
The diff for this file is too large to render. See raw diff
 
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e0d0eda3356ef51bece60eaccdb7f763fd93252990cf8ce110f1f3310459631e
3
+ size 3884762184
modeling_locateanything.py ADDED
@@ -0,0 +1,537 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # --------------------------------------------------------
2
+ # NVIDIA
3
+ # Copyright (c) 2025 NVIDIA
4
+ # Licensed under The MIT License [see LICENSE for details]
5
+ # --------------------------------------------------------
6
+
7
+ import time
8
+ from typing import List, Optional, Tuple, Union
9
+
10
+ import numpy as np
11
+ import torch
12
+ from torch import nn
13
+ from torch.nn import CrossEntropyLoss
14
+ from transformers.generation import GenerationMixin
15
+ from transformers.modeling_outputs import CausalLMOutputWithPast
16
+ from transformers.modeling_utils import PreTrainedModel
17
+ from transformers.utils import add_start_docstrings, is_flash_attn_2_available, logging
18
+ from peft import LoraConfig, get_peft_model
19
+
20
+ from .configuration_locateanything import LocateAnythingConfig
21
+ from .modeling_qwen2 import Qwen2ForCausalLM
22
+ from .modeling_vit import MoonVitPretrainedModel
23
+ from transformers.models.qwen3.modeling_qwen3 import Qwen3ForCausalLM
24
+ from .mask_sdpa_utils import *
25
+ from .mask_magi_utils import *
26
+ from .configuration_qwen2 import Qwen2Config
27
+
28
+ from .generate_utils import (
29
+ sample_tokens,
30
+ handle_pattern,
31
+ get_token_ids_from_config,
32
+ )
33
+
34
+ logger = logging.get_logger(__name__)
35
+
36
+
37
+ LOCATEANYTHING_START_DOCSTRING = r"""
38
+ This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the
39
+ library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads
40
+ etc.)
41
+ This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass.
42
+ Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage
43
+ and behavior.
44
+ Parameters:
45
+ config ([`LocateAnythingConfig`]):
46
+ Model configuration class with all the parameters of the model. Initializing with a config file does not
47
+ load the weights associated with the model, only the configuration. Check out the
48
+ [`~PreTrainedModel.from_pretrained`] method to load the model weights.
49
+ """
50
+
51
+ @add_start_docstrings(
52
+ "The bare LocateAnything Model outputting raw hidden-states without any specific head on top.",
53
+ LOCATEANYTHING_START_DOCSTRING,
54
+ )
55
+ class LocateAnythingPreTrainedModel(PreTrainedModel):
56
+ config_class = LocateAnythingConfig
57
+ base_model_prefix = "model"
58
+ main_input_name = 'input_ids'
59
+ supports_gradient_checkpointing = True
60
+ _no_split_modules = ["Qwen2DecoderLayer"]
61
+ _skip_keys_device_placement = "past_key_values"
62
+ _supports_flash_attn_2 = True
63
+ _supports_cache_class = True
64
+ _supports_static_cache = True
65
+ _supports_quantized_cache = True
66
+ _supports_sdpa = True
67
+
68
+ @classmethod
69
+ def _autoset_attn_implementation(cls, config, *args, **kwargs):
70
+ if getattr(config, '_attn_implementation', None) == 'magi':
71
+ return config
72
+ return super()._autoset_attn_implementation(config, *args, **kwargs)
73
+
74
+ def _check_and_adjust_attn_implementation(self, attn_implementation, is_init_check=False):
75
+ if attn_implementation == "magi":
76
+ return "magi"
77
+ return super()._check_and_adjust_attn_implementation(attn_implementation, is_init_check)
78
+
79
+ def _init_weights(self, module):
80
+ std = getattr(self.config, 'initializer_range', None) or self.config.text_config.initializer_range
81
+ if isinstance(module, (nn.Linear, nn.Conv2d)):
82
+ module.weight.data.normal_(mean=0.0, std=std)
83
+ if module.bias is not None:
84
+ module.bias.data.zero_()
85
+ elif isinstance(module, nn.Embedding):
86
+ module.weight.data.normal_(mean=0.0, std=std)
87
+ if module.padding_idx is not None:
88
+ module.weight.data[module.padding_idx].zero_()
89
+
90
+
91
+ class LocateAnythingForConditionalGeneration(LocateAnythingPreTrainedModel, GenerationMixin):
92
+ config_class = LocateAnythingConfig
93
+ def __init__(self, config: LocateAnythingConfig, vision_model=None, language_model=None):
94
+ super().__init__(config)
95
+
96
+ self.template = config.template
97
+ self.mlp_checkpoint = config.mlp_checkpoint
98
+
99
+ logger.info(f'mlp_checkpoint: {self.mlp_checkpoint}')
100
+ if vision_model is not None:
101
+ self.vision_model = vision_model
102
+ else:
103
+ if config.vision_config.model_type == 'moonvit':
104
+ vision_attn_impl = getattr(config.vision_config, '_attn_implementation', None) or 'flash_attention_2'
105
+ if vision_attn_impl == 'flash_attention_2' and not is_flash_attn_2_available():
106
+ logger.warning_once(
107
+ "flash_attn is not available for MoonViT inference; falling back to sdpa."
108
+ )
109
+ vision_attn_impl = 'sdpa'
110
+ config.vision_config._attn_implementation = vision_attn_impl
111
+ self.vision_model = MoonVitPretrainedModel(config.vision_config)
112
+ else:
113
+ raise ValueError(f'Unsupported vision model type: {config.vision_config.model_type}. Only moonvit is supported.')
114
+
115
+ text_attn_impl = (
116
+ getattr(config.text_config, '_attn_implementation', None)
117
+ or getattr(config, '_attn_implementation', None)
118
+ or 'magi'
119
+ )
120
+ config.text_config._attn_implementation = text_attn_impl
121
+
122
+ if language_model is not None:
123
+ self.language_model = language_model
124
+ else:
125
+ if config.text_config.architectures[0] == 'Qwen2ForCausalLM':
126
+ self.language_model = Qwen2ForCausalLM(config.text_config)
127
+ elif config.text_config.architectures[0] == 'Qwen3ForCausalLM':
128
+ self.language_model = Qwen3ForCausalLM(config.text_config)
129
+ else:
130
+ raise ValueError(f'Unsupported language model architecture: {config.text_config.architectures[0]}. Only Qwen2ForCausalLM and Qwen3ForCausalLM are supported.')
131
+
132
+ vit_hidden_size = config.vision_config.hidden_size
133
+ llm_hidden_size = config.text_config.hidden_size
134
+
135
+ # MLP for moonvit (without pixel_shuffle_back, direct mapping)
136
+ self.mlp1 = nn.Sequential(
137
+ nn.LayerNorm(vit_hidden_size*4),
138
+ nn.Linear(vit_hidden_size*4, llm_hidden_size),
139
+ nn.GELU(),
140
+ nn.Linear(llm_hidden_size, llm_hidden_size)
141
+ )
142
+ self.image_token_index = config.image_token_index
143
+ self.neftune_alpha = None
144
+
145
+ if config.use_backbone_lora:
146
+ self.wrap_backbone_lora(r=config.use_backbone_lora, lora_alpha=2 * config.use_backbone_lora)
147
+
148
+ self.use_llm_lora = config.use_llm_lora
149
+ if config.use_llm_lora:
150
+ self.wrap_llm_lora(r=config.use_llm_lora, lora_alpha=2 * config.use_llm_lora)
151
+
152
+ self.token_ids = get_token_ids_from_config(config)
153
+
154
+ # Set _no_split_modules dynamically based on the actual LLM architecture
155
+ arch = config.text_config.architectures[0] if hasattr(config.text_config, 'architectures') and config.text_config.architectures else 'Qwen2ForCausalLM'
156
+ if 'Qwen3' in arch:
157
+ self._no_split_modules = ["Qwen3DecoderLayer"]
158
+ else:
159
+ self._no_split_modules = ["Qwen2DecoderLayer"]
160
+
161
+
162
+ def wrap_backbone_lora(self, r=128, lora_alpha=256, lora_dropout=0.05):
163
+ lora_config = LoraConfig(
164
+ r=r,
165
+ target_modules=['self_attn.q_proj', 'self_attn.k_proj', 'self_attn.v_proj', 'self_attn.out_proj',
166
+ 'mlp.fc1', 'mlp.fc2'],
167
+ lora_alpha=lora_alpha,
168
+ lora_dropout=lora_dropout,
169
+ )
170
+ self.vision_model = get_peft_model(self.vision_model, lora_config)
171
+ self.vision_model.print_trainable_parameters()
172
+
173
+ def wrap_llm_lora(self, r=128, lora_alpha=256, lora_dropout=0.05):
174
+ lora_config = LoraConfig(
175
+ r=r,
176
+ target_modules=['self_attn.q_proj', 'self_attn.k_proj', 'self_attn.v_proj', 'self_attn.o_proj',
177
+ 'mlp.gate_proj', 'mlp.down_proj', 'mlp.up_proj'],
178
+ lora_alpha=lora_alpha,
179
+ lora_dropout=lora_dropout,
180
+ task_type='CAUSAL_LM'
181
+ )
182
+ self.language_model = get_peft_model(self.language_model, lora_config)
183
+ self.language_model.enable_input_require_grads()
184
+ self.language_model.print_trainable_parameters()
185
+ self.use_llm_lora = True
186
+
187
+
188
+ def forward(
189
+ self,
190
+ pixel_values: List[torch.FloatTensor],
191
+ input_ids: torch.LongTensor = None,
192
+ attention_mask: Optional[torch.Tensor] = None,
193
+ position_ids: Optional[torch.LongTensor] = None,
194
+ image_grid_hws: Optional[torch.Tensor] = None,
195
+ image_flags: Optional[torch.Tensor] = None,
196
+ past_key_values: Optional[List[torch.FloatTensor]] = None,
197
+ labels: Optional[torch.LongTensor] = None,
198
+ use_cache: Optional[bool] = None,
199
+ output_attentions: Optional[bool] = None,
200
+ output_hidden_states: Optional[bool] = None,
201
+ return_dict: Optional[bool] = None,
202
+ ) -> Union[Tuple, CausalLMOutputWithPast]:
203
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
204
+
205
+ input_embeds = self.language_model.get_input_embeddings()(input_ids)
206
+
207
+ has_images = image_flags is not None and image_flags.sum() > 0
208
+
209
+ vit_embeds = self.extract_feature(pixel_values, image_grid_hws)
210
+
211
+ B, N, C = input_embeds.shape
212
+ input_embeds = input_embeds.reshape(B * N, C)
213
+
214
+ if has_images:
215
+ filtered_vit_embeds = []
216
+ idx = 0
217
+ for flag in image_flags:
218
+ flag_val = flag.item()
219
+ if flag_val != 0:
220
+ filtered_vit_embeds.extend(vit_embeds[idx:idx + flag_val])
221
+ idx += flag_val
222
+ else:
223
+ idx += 1
224
+
225
+ vit_embeds = filtered_vit_embeds
226
+ vit_embeds = torch.cat(vit_embeds, dim=0)
227
+
228
+ vit_embeds = self.mlp1(vit_embeds)
229
+ input_ids = input_ids.reshape(B * N)
230
+ selected = (input_ids == self.image_token_index)
231
+
232
+ input_embeds[selected] = input_embeds[selected] * 0.0 + vit_embeds[:selected.sum()]
233
+ else:
234
+ if vit_embeds:
235
+ vit_embeds = torch.cat(vit_embeds, dim=0)
236
+ vit_embeds = self.mlp1(vit_embeds)
237
+ input_ids = input_ids.reshape(B * N)
238
+ selected = (input_ids == self.image_token_index)
239
+ if selected.sum() > 0:
240
+ input_embeds[selected] = vit_embeds[:selected.sum()]
241
+
242
+ input_embeds = input_embeds.reshape(B, N, C)
243
+
244
+ outputs = self.language_model(
245
+ inputs_embeds=input_embeds,
246
+ attention_mask=attention_mask,
247
+ position_ids=position_ids,
248
+ past_key_values=past_key_values,
249
+ use_cache=use_cache,
250
+ output_attentions=output_attentions,
251
+ output_hidden_states=output_hidden_states,
252
+ )
253
+ logits = outputs.logits
254
+
255
+ loss = None
256
+ if labels is not None:
257
+ # Shift so that tokens < n predict n
258
+ shift_logits = logits[..., :-1, :].contiguous()
259
+ shift_labels = labels[..., 1:].contiguous()
260
+ # Flatten the tokens
261
+ loss_fct = CrossEntropyLoss()
262
+ shift_logits = shift_logits.view(-1, self.language_model.config.vocab_size)
263
+ shift_labels = shift_labels.view(-1)
264
+ # Enable model parallelism
265
+ shift_labels = shift_labels.to(shift_logits.device)
266
+ loss = loss_fct(shift_logits, shift_labels)
267
+
268
+ if not return_dict:
269
+ output = (logits,) + outputs[1:]
270
+ return (loss,) + output if loss is not None else output
271
+
272
+ return CausalLMOutputWithPast(
273
+ loss=loss,
274
+ logits=logits,
275
+ past_key_values=outputs.past_key_values,
276
+ hidden_states=outputs.hidden_states,
277
+ attentions=outputs.attentions,
278
+ )
279
+
280
+
281
+ def extract_feature(self, pixel_values, image_grid_hws):
282
+ vit_embeds = self.vision_model(pixel_values=pixel_values, grid_hws=image_grid_hws)
283
+
284
+ return vit_embeds
285
+
286
+ def get_input_embeddings(self):
287
+ return self.language_model.get_input_embeddings()
288
+
289
+ def set_input_embeddings(self, value):
290
+ self.language_model.set_input_embeddings(value)
291
+
292
+ def get_output_embeddings(self):
293
+ return self.language_model.get_output_embeddings()
294
+
295
+ def set_output_embeddings(self, new_embeddings):
296
+ self.language_model.set_output_embeddings(new_embeddings)
297
+
298
+ def set_decoder(self, decoder):
299
+ self.language_model.set_decoder(decoder)
300
+
301
+ def get_decoder(self):
302
+ return self.language_model.get_decoder()
303
+
304
+ @torch.no_grad()
305
+ def generate(
306
+ self,
307
+ pixel_values: Optional[torch.FloatTensor] = None,
308
+ input_ids: Optional[torch.FloatTensor] = None,
309
+ attention_mask: Optional[torch.LongTensor] = None,
310
+ visual_features: Optional[torch.FloatTensor] = None,
311
+ image_grid_hws: Optional[torch.Tensor] = None,
312
+ tokenizer = None,
313
+ n_future_tokens: int = 6,
314
+ **generate_kwargs,
315
+ ) -> torch.LongTensor:
316
+
317
+ verbose = generate_kwargs.pop('verbose', False)
318
+ start_time = time.time()
319
+ prefill_time = None
320
+
321
+ pixel_values = pixel_values.to(self.language_model.dtype)
322
+ # Convert numpy array to tensor if needed
323
+ if isinstance(image_grid_hws, np.ndarray):
324
+ image_grid_hws = torch.from_numpy(image_grid_hws).to(pixel_values.device, dtype=torch.int32)
325
+
326
+ batch_size, seq_len = input_ids.shape
327
+ assert batch_size == 1, 'only batch size = 1 is supported now'
328
+ assert generate_kwargs.get('use_cache', False), "Only use_cache=True is supported."
329
+
330
+ generated = input_ids.clone()
331
+ total_gen_length = min(tokenizer.model_max_length, seq_len + generate_kwargs.get('max_new_tokens', 2048))
332
+ iter_round = 0
333
+ past_key_values = None
334
+
335
+ # Extract visual features once before the loop
336
+ if visual_features is not None:
337
+ vit_embeds = visual_features
338
+ elif pixel_values is not None:
339
+ vit_embeds = self.extract_feature(pixel_values, image_grid_hws)
340
+ else:
341
+ vit_embeds = None
342
+
343
+ if image_grid_hws is not None:
344
+ vit_embeds = torch.cat(vit_embeds, dim=0)
345
+ vit_embeds = self.mlp1(vit_embeds)
346
+
347
+ # ==================== Generation Mode ====================
348
+ # 'fast' : MTP only, never fall back to AR
349
+ # 'slow' : AR only, pure auto-regressive decoding
350
+ # 'hybrid' : MTP first, fall back to AR on error, switch back on box_end
351
+ generation_mode = generate_kwargs.get('generation_mode', 'hybrid')
352
+ assert generation_mode in ('fast', 'slow', 'hybrid'), \
353
+ f"Unsupported generation_mode='{generation_mode}'. Use 'fast', 'slow', or 'hybrid'."
354
+
355
+ sampling_history = []
356
+
357
+
358
+ use_mtp = generation_mode in ('fast', 'hybrid')
359
+ switch_to_ar_count = 0
360
+
361
+ # Pre-allocate mask tokens and position ids
362
+ default_mask_token_id = self.token_ids['default_mask_token_id']
363
+ pre_mask_tokens = torch.full(
364
+ (batch_size, n_future_tokens - 1),
365
+ default_mask_token_id,
366
+ dtype=generated.dtype,
367
+ device=generated.device
368
+ )
369
+ max_possible_len = total_gen_length + n_future_tokens
370
+ full_position_ids = torch.arange(0, max_possible_len, device=generated.device).unsqueeze(0)
371
+
372
+
373
+ def _prepare_inputs_in_mtp(generated):
374
+ generated_with_mask = torch.cat(
375
+ (
376
+ generated,
377
+ generated[:, -1].unsqueeze(1),
378
+ pre_mask_tokens
379
+ ),
380
+ dim=1
381
+ ) # [batch_size, seq_len + 1 + n_future_tokens - 1]
382
+
383
+ # Update pe for kvcache
384
+ start_idx = past_key_values[0][0].size(2) if past_key_values is not None else 0
385
+ position_ids = full_position_ids[:, start_idx : generated_with_mask.size(1)].clone()
386
+ position_ids[0, -n_future_tokens:] -= 1
387
+
388
+ prepare_inputs = self.language_model.prepare_inputs_for_generation(
389
+ generated_with_mask,
390
+ past_key_values,
391
+ None,
392
+ inputs_embeds=None,
393
+ use_cache=True,
394
+ position_ids=position_ids
395
+ )
396
+ return prepare_inputs
397
+
398
+
399
+ def _prepare_input_in_ar(generated):
400
+ start_idx = past_key_values[0][0].size(2) if past_key_values is not None else 0
401
+ position_ids = full_position_ids[:, start_idx : generated.size(1)]
402
+ prepare_inputs = self.language_model.prepare_inputs_for_generation(
403
+ generated,
404
+ past_key_values,
405
+ None,
406
+ inputs_embeds=None,
407
+ use_cache=True,
408
+ position_ids=position_ids
409
+ )
410
+ return prepare_inputs
411
+
412
+
413
+ def _sample_token_in_mtp(generated, outputs):
414
+ """Sample tokens using MTP (Multi-Token Prediction) mode."""
415
+ next_token_logits = outputs.logits[:, -n_future_tokens:, :]
416
+ probs, confidence, x0, box_avg = sample_tokens(
417
+ next_token_logits, generated, self.token_ids, keep_k=5, **generate_kwargs
418
+ )
419
+
420
+ is_box_empty = (box_avg[0] == 0).all()
421
+ new_tokens = x0[0] if is_box_empty else box_avg[0]
422
+
423
+ out_pattern = handle_pattern(new_tokens, self.token_ids, generation_mode)
424
+ out_type = out_pattern['type']
425
+ out_token = torch.tensor(out_pattern['tokens'], dtype=x0.dtype, device=x0.device)
426
+
427
+ return out_type, out_token
428
+
429
+
430
+ def _sample_token_in_ar(generated, outputs):
431
+ """Sample a single token using AR (Auto-Regressive) mode."""
432
+ next_token_logits = outputs.logits[:, -1:, :]
433
+ probs, confidence, x0, _ = sample_tokens(
434
+ next_token_logits, generated, self.token_ids, **generate_kwargs
435
+ )
436
+
437
+ out_token = x0[0]
438
+ out_type = 'continue_ar'
439
+ token_val = out_token[0].item()
440
+
441
+ box_end_token_id = self.token_ids['box_end_token_id']
442
+ coord_start_token_id = self.token_ids['coord_start_token_id']
443
+ coord_end_token_id = self.token_ids['coord_end_token_id']
444
+ none_token_id = self.token_ids['none_token_id']
445
+ im_end_token_id = self.token_ids['im_end_token_id']
446
+
447
+ if generation_mode == 'hybrid':
448
+ # Hybrid AR phase: detect box boundaries to switch back to MTP
449
+ if token_val == box_end_token_id:
450
+ out_type = 'box_end_ar'
451
+ elif coord_start_token_id <= token_val <= coord_end_token_id or token_val == none_token_id:
452
+ out_type = 'coord_ar'
453
+ else:
454
+ out_type = 'im_end'
455
+ else:
456
+ # Slow mode: pure AR, only stop on im_end
457
+ if token_val == im_end_token_id:
458
+ out_type = 'im_end'
459
+
460
+ return out_type, out_token
461
+
462
+
463
+ # Generate loop
464
+ while generated.size(1) < total_gen_length:
465
+ iter_round += 1
466
+
467
+ # Step 1: Prepare inputs
468
+ if use_mtp:
469
+ prepare_inputs = _prepare_inputs_in_mtp(generated)
470
+ else:
471
+ prepare_inputs = _prepare_input_in_ar(generated)
472
+
473
+ if iter_round == 1:
474
+ prepare_inputs.update({
475
+ 'visual_features': vit_embeds,
476
+ 'image_token_index': self.config.image_token_index,
477
+ })
478
+
479
+ # Step 2: Model forward & update KV cache
480
+ with torch.no_grad():
481
+ outputs = self.language_model(**prepare_inputs)
482
+
483
+ past_key_values = tuple(
484
+ (kv[0][:, :, :generated.shape[1], :], kv[1][:, :, :generated.shape[1], :])
485
+ for kv in outputs.past_key_values
486
+ )
487
+
488
+ # Step 3: Sample tokens
489
+ if use_mtp:
490
+ out_type, out_token = _sample_token_in_mtp(generated, outputs)
491
+ else:
492
+ out_type, out_token = _sample_token_in_ar(generated, outputs)
493
+
494
+ if verbose:
495
+ sampling_history.append(('ar' if 'ar' in out_type else 'mtp', tokenizer.decode(out_token, skip_special_tokens=False)))
496
+
497
+ generated = torch.cat([generated, out_token.unsqueeze(0)], dim=1)
498
+
499
+ # Step 4: Mode switching & termination
500
+ if out_type == 'im_end':
501
+ break
502
+
503
+ if generation_mode == 'hybrid':
504
+ if out_type == 'error_box':
505
+ use_mtp = False
506
+ switch_to_ar_count += 1
507
+ elif out_type == 'box_end_ar':
508
+ use_mtp = True
509
+ # fast mode: use_mtp stays True always
510
+ # slow mode: use_mtp stays False always
511
+
512
+ if prefill_time is None:
513
+ prefill_time = time.time() - start_time
514
+
515
+ # Decode and return
516
+ generated_ids = generated[:, seq_len:]
517
+ response = tokenizer.batch_decode(generated_ids, skip_special_tokens=False)
518
+
519
+ if verbose:
520
+ end_time = time.time()
521
+ num_tokens = generated_ids.size(1)
522
+ num_boxes = response[0].count("<box>")
523
+ total_time = end_time - start_time
524
+
525
+ out_info = f"\nStatistic Info, num_tokens={num_tokens}; " + \
526
+ f"generate_time(s)={total_time:.4f}; " + \
527
+ f"tps={(num_tokens / total_time):.4f}; " + \
528
+ f"forward_step={iter_round}; " + \
529
+ f"num_boxes={num_boxes}; " + \
530
+ f"bps={(num_boxes / total_time):.4f}; " + \
531
+ f"prefill_time={(prefill_time):.4f}; " + \
532
+ f"switch_to_ar={switch_to_ar_count}\n"
533
+ print(out_info)
534
+
535
+ return response[0], sampling_history, out_info
536
+
537
+ return response[0]
modeling_qwen2.py ADDED
@@ -0,0 +1,1738 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding=utf-8
2
+ # Copyright 2024 The Qwen team, Alibaba Group 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 Qwen2 model."""
21
+ import inspect
22
+ import math
23
+ import copy
24
+ import warnings
25
+ from functools import partial
26
+ from typing import List, Optional, Tuple, Union
27
+
28
+ import torch
29
+ import torch.nn.functional as F
30
+ import torch.utils.checkpoint
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, _prepare_4d_causal_attention_mask_for_sdpa
37
+ from transformers.modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast, SequenceClassifierOutputWithPast
38
+ from transformers.modeling_utils import PreTrainedModel
39
+ from transformers.utils import (
40
+ add_start_docstrings,
41
+ add_start_docstrings_to_model_forward,
42
+ is_flash_attn_2_available,
43
+ is_flash_attn_greater_or_equal_2_10,
44
+ logging,
45
+ replace_return_docstrings,
46
+ )
47
+ from .configuration_qwen2 import Qwen2Config
48
+
49
+ if is_flash_attn_2_available():
50
+ from flash_attn import flash_attn_func, flash_attn_varlen_func
51
+ from flash_attn.bert_padding import index_first_axis, pad_input, unpad_input # noqa
52
+
53
+ _flash_supports_window_size = "window_size" in list(inspect.signature(flash_attn_func).parameters)
54
+
55
+
56
+ logger = logging.get_logger(__name__)
57
+
58
+ # Magi Attention Supported
59
+ _MAGI_AVAILABLE = False
60
+ try:
61
+ from magi_attention.functional.flex_flash_attn import flex_flash_attn_func
62
+ _MAGI_AVAILABLE = True
63
+ except ImportError:
64
+ flex_flash_attn_func = None
65
+
66
+
67
+ _CHECKPOINT_FOR_DOC = "Qwen/Qwen2-7B-beta"
68
+ _CONFIG_FOR_DOC = "Qwen2Config"
69
+
70
+ QWEN2_PRETRAINED_MODEL_ARCHIVE_LIST = [
71
+ "Qwen/Qwen2-7B-beta",
72
+ # See all Qwen2 models at https://huggingface.co/models?filter=qwen2
73
+ ]
74
+
75
+ from .mask_sdpa_utils import (
76
+ find_prefix_seq_length_by_pe,
77
+ update_causal_mask_with_pad_non_visible_2d,
78
+ update_causal_mask_for_one_gen_window_2d,
79
+ create_block_diff_mask_by_pe_4d,
80
+ find_pred_pos_from_input_ids
81
+ )
82
+
83
+ from .mask_magi_utils import build_magi_ranges
84
+
85
+ # Copied from transformers.models.llama.modeling_llama._get_unpad_data
86
+ def _get_unpad_data(attention_mask):
87
+ seqlens_in_batch = attention_mask.sum(dim=-1, dtype=torch.int32)
88
+ indices = torch.nonzero(attention_mask.flatten(), as_tuple=False).flatten()
89
+ max_seqlen_in_batch = seqlens_in_batch.max().item()
90
+ cu_seqlens = F.pad(torch.cumsum(seqlens_in_batch, dim=0, dtype=torch.torch.int32), (1, 0))
91
+ return (
92
+ indices,
93
+ cu_seqlens,
94
+ max_seqlen_in_batch,
95
+ )
96
+
97
+
98
+ # Copied from transformers.models.llama.modeling_llama.LlamaRMSNorm with Llama->Qwen2
99
+ class Qwen2RMSNorm(nn.Module):
100
+ def __init__(self, hidden_size, eps=1e-6):
101
+ """
102
+ Qwen2RMSNorm is equivalent to T5LayerNorm
103
+ """
104
+ super().__init__()
105
+ self.weight = nn.Parameter(torch.ones(hidden_size))
106
+ self.variance_epsilon = eps
107
+
108
+ def forward(self, hidden_states):
109
+ input_dtype = hidden_states.dtype
110
+ hidden_states = hidden_states.to(torch.float32)
111
+ variance = hidden_states.pow(2).mean(-1, keepdim=True)
112
+ hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)
113
+ return self.weight * hidden_states.to(input_dtype)
114
+
115
+
116
+ # Copied from transformers.models.llama.modeling_llama.LlamaRotaryEmbedding with Llama->Qwen2
117
+ class Qwen2RotaryEmbedding(nn.Module):
118
+ def __init__(self, dim, max_position_embeddings=2048, base=10000, device=None):
119
+ super().__init__()
120
+
121
+ self.dim = dim
122
+ self.max_position_embeddings = max_position_embeddings
123
+ self.base = base
124
+ inv_freq = 1.0 / (self.base ** (torch.arange(0, self.dim, 2).float().to(device) / self.dim))
125
+ self.register_buffer("inv_freq", inv_freq, persistent=False)
126
+
127
+ # Build here to make `torch.jit.trace` work.
128
+ self._set_cos_sin_cache(
129
+ seq_len=max_position_embeddings, device=self.inv_freq.device, dtype=torch.get_default_dtype()
130
+ )
131
+
132
+ def _set_cos_sin_cache(self, seq_len, device, dtype):
133
+ self.max_seq_len_cached = seq_len
134
+ t = torch.arange(self.max_seq_len_cached, device=device, dtype=self.inv_freq.dtype)
135
+
136
+ freqs = torch.outer(t, self.inv_freq)
137
+ # Different from paper, but it uses a different permutation in order to obtain the same calculation
138
+ emb = torch.cat((freqs, freqs), dim=-1)
139
+ self.register_buffer("cos_cached", emb.cos().to(dtype), persistent=False)
140
+ self.register_buffer("sin_cached", emb.sin().to(dtype), persistent=False)
141
+
142
+ def forward(self, x, seq_len=None):
143
+ # x: [bs, num_attention_heads, seq_len, head_size]
144
+ if seq_len > self.max_seq_len_cached:
145
+ self._set_cos_sin_cache(seq_len=seq_len, device=x.device, dtype=x.dtype)
146
+
147
+ return (
148
+ self.cos_cached[:seq_len].to(dtype=x.dtype),
149
+ self.sin_cached[:seq_len].to(dtype=x.dtype),
150
+ )
151
+
152
+
153
+ # Copied from transformers.models.llama.modeling_llama.rotate_half
154
+ def rotate_half(x):
155
+ """Rotates half the hidden dims of the input."""
156
+ x1 = x[..., : x.shape[-1] // 2]
157
+ x2 = x[..., x.shape[-1] // 2 :]
158
+ return torch.cat((-x2, x1), dim=-1)
159
+
160
+
161
+ # Copied from transformers.models.llama.modeling_llama.apply_rotary_pos_emb
162
+ def apply_rotary_pos_emb(q, k, cos, sin, position_ids, unsqueeze_dim=1):
163
+ """Applies Rotary Position Embedding to the query and key tensors.
164
+
165
+ Args:
166
+ q (`torch.Tensor`): The query tensor.
167
+ k (`torch.Tensor`): The key tensor.
168
+ cos (`torch.Tensor`): The cosine part of the rotary embedding.
169
+ sin (`torch.Tensor`): The sine part of the rotary embedding.
170
+ position_ids (`torch.Tensor`):
171
+ The position indices of the tokens corresponding to the query and key tensors. For example, this can be
172
+ used to pass offsetted position ids when working with a KV-cache.
173
+ unsqueeze_dim (`int`, *optional*, defaults to 1):
174
+ The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and
175
+ sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note
176
+ that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and
177
+ k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes
178
+ cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have
179
+ the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2.
180
+ Returns:
181
+ `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding.
182
+ """
183
+ cos = cos[position_ids].unsqueeze(unsqueeze_dim)
184
+ sin = sin[position_ids].unsqueeze(unsqueeze_dim)
185
+ q_embed = (q * cos) + (rotate_half(q) * sin)
186
+ k_embed = (k * cos) + (rotate_half(k) * sin)
187
+ return q_embed, k_embed
188
+
189
+
190
+ # Copied from transformers.models.mistral.modeling_mistral.MistralMLP with Mistral->Qwen2
191
+ class Qwen2MLP(nn.Module):
192
+ def __init__(self, config):
193
+ super().__init__()
194
+ self.config = config
195
+ self.hidden_size = config.hidden_size
196
+ self.intermediate_size = config.intermediate_size
197
+ self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
198
+ self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
199
+ self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
200
+ self.act_fn = ACT2FN[config.hidden_act]
201
+
202
+ def forward(self, x):
203
+ return self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x))
204
+
205
+
206
+ # Copied from transformers.models.llama.modeling_llama.repeat_kv
207
+ def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
208
+ """
209
+ This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch,
210
+ num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim)
211
+ """
212
+ batch, num_key_value_heads, slen, head_dim = hidden_states.shape
213
+ if n_rep == 1:
214
+ return hidden_states
215
+ hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim)
216
+ return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)
217
+
218
+
219
+ class Qwen2Attention(nn.Module):
220
+ """
221
+ Multi-headed attention from 'Attention Is All You Need' paper. Modified to use sliding window attention: Longformer
222
+ and "Generating Long Sequences with Sparse Transformers".
223
+ """
224
+
225
+ def __init__(self, config: Qwen2Config, layer_idx: Optional[int] = None):
226
+ super().__init__()
227
+ self.config = config
228
+ self.layer_idx = layer_idx
229
+ if layer_idx is None:
230
+ logger.warning_once(
231
+ f"Instantiating {self.__class__.__name__} without passing `layer_idx` is not recommended and will "
232
+ "to errors during the forward call, if caching is used. Please make sure to provide a `layer_idx` "
233
+ "when creating this class."
234
+ )
235
+
236
+ self.hidden_size = config.hidden_size
237
+ self.num_heads = config.num_attention_heads
238
+ self.head_dim = self.hidden_size // self.num_heads
239
+ self.num_key_value_heads = config.num_key_value_heads
240
+ self.num_key_value_groups = self.num_heads // self.num_key_value_heads
241
+ self.max_position_embeddings = config.max_position_embeddings
242
+ self.rope_theta = config.rope_theta
243
+ self.is_causal = True
244
+ self.attention_dropout = config.attention_dropout
245
+
246
+ if (self.head_dim * self.num_heads) != self.hidden_size:
247
+ raise ValueError(
248
+ f"hidden_size must be divisible by num_heads (got `hidden_size`: {self.hidden_size}"
249
+ f" and `num_heads`: {self.num_heads})."
250
+ )
251
+ self.q_proj = nn.Linear(self.hidden_size, self.num_heads * self.head_dim, bias=True)
252
+ self.k_proj = nn.Linear(self.hidden_size, self.num_key_value_heads * self.head_dim, bias=True)
253
+ self.v_proj = nn.Linear(self.hidden_size, self.num_key_value_heads * self.head_dim, bias=True)
254
+ self.o_proj = nn.Linear(self.num_heads * self.head_dim, self.hidden_size, bias=False)
255
+
256
+ self.rotary_emb = Qwen2RotaryEmbedding(
257
+ self.head_dim,
258
+ max_position_embeddings=self.max_position_embeddings,
259
+ base=self.rope_theta,
260
+ )
261
+
262
+ def forward(
263
+ self,
264
+ hidden_states: torch.Tensor,
265
+ attention_mask: Optional[torch.Tensor] = None,
266
+ position_ids: Optional[torch.LongTensor] = None,
267
+ past_key_value: Optional[Cache] = None,
268
+ output_attentions: bool = False,
269
+ use_cache: bool = False,
270
+ **kwargs,
271
+ ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]:
272
+ if "padding_mask" in kwargs:
273
+ warnings.warn(
274
+ "Passing `padding_mask` is deprecated and will be removed in v4.37. Please make sure use `attention_mask` instead.`"
275
+ )
276
+ bsz, q_len, _ = hidden_states.size()
277
+
278
+ query_states = self.q_proj(hidden_states)
279
+ key_states = self.k_proj(hidden_states)
280
+ value_states = self.v_proj(hidden_states)
281
+
282
+ query_states = query_states.view(bsz, q_len, self.num_heads, self.head_dim).transpose(1, 2)
283
+ key_states = key_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)
284
+ value_states = value_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)
285
+
286
+ kv_seq_len = key_states.shape[-2]
287
+ if past_key_value is not None:
288
+ if self.layer_idx is None:
289
+ raise ValueError(
290
+ f"The cache structure has changed since version v4.36. If you are using {self.__class__.__name__} "
291
+ "for auto-regressive decoding with k/v caching, please make sure to initialize the attention class "
292
+ "with a layer index."
293
+ )
294
+ kv_seq_len += past_key_value.get_seq_length(self.layer_idx)
295
+ cos, sin = self.rotary_emb(value_states, seq_len=kv_seq_len)
296
+ query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin, position_ids)
297
+
298
+ if past_key_value is not None:
299
+ cache_kwargs = {"sin": sin, "cos": cos} # Specific to RoPE models
300
+ key_states, value_states = past_key_value.update(key_states, value_states, self.layer_idx, cache_kwargs)
301
+
302
+ # repeat k/v heads if n_kv_heads < n_heads
303
+ key_states = repeat_kv(key_states, self.num_key_value_groups)
304
+ value_states = repeat_kv(value_states, self.num_key_value_groups)
305
+
306
+ attn_weights = torch.matmul(query_states, key_states.transpose(2, 3)) / math.sqrt(self.head_dim)
307
+
308
+ if attn_weights.size() != (bsz, self.num_heads, q_len, kv_seq_len):
309
+ raise ValueError(
310
+ f"Attention weights should be of size {(bsz, self.num_heads, q_len, kv_seq_len)}, but is"
311
+ f" {attn_weights.size()}"
312
+ )
313
+
314
+ if attention_mask is not None:
315
+ if attention_mask.size() != (bsz, 1, q_len, kv_seq_len):
316
+ raise ValueError(
317
+ f"Attention mask should be of size {(bsz, 1, q_len, kv_seq_len)}, but is {attention_mask.size()}"
318
+ )
319
+
320
+ attn_weights = attn_weights + attention_mask
321
+
322
+ # upcast attention to fp32
323
+ attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query_states.dtype)
324
+ attn_weights = nn.functional.dropout(attn_weights, p=self.attention_dropout, training=self.training)
325
+ attn_output = torch.matmul(attn_weights, value_states)
326
+
327
+ if attn_output.size() != (bsz, self.num_heads, q_len, self.head_dim):
328
+ raise ValueError(
329
+ f"`attn_output` should be of size {(bsz, self.num_heads, q_len, self.head_dim)}, but is"
330
+ f" {attn_output.size()}"
331
+ )
332
+
333
+ attn_output = attn_output.transpose(1, 2).contiguous()
334
+ attn_output = attn_output.reshape(bsz, q_len, self.hidden_size)
335
+
336
+ attn_output = self.o_proj(attn_output)
337
+
338
+ if not output_attentions:
339
+ attn_weights = None
340
+
341
+ return attn_output, attn_weights, past_key_value
342
+
343
+
344
+ class Qwen2FlashAttention2(Qwen2Attention):
345
+ """
346
+ Qwen2 flash attention module, following Qwen2 attention module. This module inherits from `Qwen2Attention`
347
+ as the weights of the module stays untouched. The only required change would be on the forward pass
348
+ where it needs to correctly call the public API of flash attention and deal with padding tokens
349
+ in case the input contains any of them. Additionally, for sliding window attention, we apply SWA only to the bottom
350
+ config.max_window_layers layers.
351
+ """
352
+
353
+ # Copied from transformers.models.llama.modeling_llama.LlamaFlashAttention2.__init__
354
+ def __init__(self, *args, **kwargs):
355
+ super().__init__(*args, **kwargs)
356
+
357
+ # TODO: Should be removed once Flash Attention for RoCm is bumped to 2.1.
358
+ # 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.
359
+ # 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).
360
+ self._flash_attn_uses_top_left_mask = not is_flash_attn_greater_or_equal_2_10()
361
+
362
+ def forward(
363
+ self,
364
+ hidden_states: torch.Tensor,
365
+ attention_mask: Optional[torch.Tensor] = None,
366
+ position_ids: Optional[torch.LongTensor] = None,
367
+ past_key_value: Optional[Cache] = None,
368
+ output_attentions: bool = False,
369
+ use_cache: bool = False,
370
+ **kwargs,
371
+ ):
372
+ if "padding_mask" in kwargs:
373
+ warnings.warn(
374
+ "Passing `padding_mask` is deprecated and will be removed in v4.37. Please make sure use `attention_mask` instead.`"
375
+ )
376
+
377
+ # overwrite attention_mask with padding_mask
378
+ attention_mask = kwargs.pop("padding_mask")
379
+ bsz, q_len, _ = hidden_states.size()
380
+
381
+ query_states = self.q_proj(hidden_states)
382
+ key_states = self.k_proj(hidden_states)
383
+ value_states = self.v_proj(hidden_states)
384
+
385
+ query_states = query_states.view(bsz, q_len, self.num_heads, self.head_dim).transpose(1, 2)
386
+ key_states = key_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)
387
+ value_states = value_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)
388
+
389
+ kv_seq_len = key_states.shape[-2]
390
+ if past_key_value is not None:
391
+ if self.layer_idx is None:
392
+ raise ValueError(
393
+ f"The cache structure has changed since version v4.36. If you are using {self.__class__.__name__} "
394
+ "for auto-regressive decoding with k/v caching, please make sure to initialize the attention class "
395
+ "with a layer index."
396
+ )
397
+ kv_seq_len += past_key_value.get_seq_length(self.layer_idx)
398
+
399
+ # Because the input can be padded, the absolute sequence length depends on the max position id.
400
+ rotary_seq_len = max(kv_seq_len, position_ids[:, -1].max().item()) + 1
401
+ cos, sin = self.rotary_emb(value_states, seq_len=rotary_seq_len)
402
+
403
+ query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin, position_ids)
404
+
405
+ use_sliding_windows = (
406
+ _flash_supports_window_size
407
+ and getattr(self.config, "sliding_window", None) is not None
408
+ and kv_seq_len > self.config.sliding_window
409
+ and self.config.use_sliding_window
410
+ )
411
+
412
+ if not _flash_supports_window_size:
413
+ logger.warning_once(
414
+ "The current flash attention version does not support sliding window attention, for a more memory efficient implementation"
415
+ " make sure to upgrade flash-attn library."
416
+ )
417
+
418
+ if past_key_value is not None:
419
+ # Activate slicing cache only if the config has a value `sliding_windows` attribute
420
+ cache_has_contents = past_key_value.get_seq_length(self.layer_idx) > 0
421
+ if (
422
+ getattr(self.config, "sliding_window", None) is not None
423
+ and kv_seq_len > self.config.sliding_window
424
+ and cache_has_contents
425
+ ):
426
+ slicing_tokens = 1 - self.config.sliding_window
427
+
428
+ past_key = past_key_value[self.layer_idx][0]
429
+ past_value = past_key_value[self.layer_idx][1]
430
+
431
+ past_key = past_key[:, :, slicing_tokens:, :].contiguous()
432
+ past_value = past_value[:, :, slicing_tokens:, :].contiguous()
433
+
434
+ if past_key.shape[-2] != self.config.sliding_window - 1:
435
+ raise ValueError(
436
+ f"past key must have a shape of (`batch_size, num_heads, self.config.sliding_window-1, head_dim`), got"
437
+ f" {past_key.shape}"
438
+ )
439
+
440
+ if attention_mask is not None:
441
+ attention_mask = attention_mask[:, slicing_tokens:]
442
+ attention_mask = torch.cat([attention_mask, torch.ones_like(attention_mask[:, -1:])], dim=-1)
443
+
444
+ cache_kwargs = {"sin": sin, "cos": cos} # Specific to RoPE models
445
+ key_states, value_states = past_key_value.update(key_states, value_states, self.layer_idx, cache_kwargs)
446
+
447
+ # repeat k/v heads if n_kv_heads < n_heads
448
+ key_states = repeat_kv(key_states, self.num_key_value_groups)
449
+ value_states = repeat_kv(value_states, self.num_key_value_groups)
450
+ dropout_rate = 0.0 if not self.training else self.attention_dropout
451
+
452
+ # In PEFT, usually we cast the layer norms in float32 for training stability reasons
453
+ # therefore the input hidden states gets silently casted in float32. Hence, we need
454
+ # cast them back in float16 just to be sure everything works as expected.
455
+ input_dtype = query_states.dtype
456
+ if input_dtype == torch.float32:
457
+ if torch.is_autocast_enabled():
458
+ target_dtype = torch.get_autocast_gpu_dtype()
459
+ # Handle the case where the model is quantized
460
+ elif hasattr(self.config, "_pre_quantization_dtype"):
461
+ target_dtype = self.config._pre_quantization_dtype
462
+ else:
463
+ target_dtype = self.q_proj.weight.dtype
464
+
465
+ logger.warning_once(
466
+ f"The input hidden states seems to be silently casted in float32, this might be related to"
467
+ f" the fact you have upcasted embedding or layer norm layers in float32. We will cast back the input in"
468
+ f" {target_dtype}."
469
+ )
470
+
471
+ query_states = query_states.to(target_dtype)
472
+ key_states = key_states.to(target_dtype)
473
+ value_states = value_states.to(target_dtype)
474
+
475
+ # Reashape to the expected shape for Flash Attention
476
+ query_states = query_states.transpose(1, 2)
477
+ key_states = key_states.transpose(1, 2)
478
+ value_states = value_states.transpose(1, 2)
479
+
480
+ attn_output = self._flash_attention_forward(
481
+ query_states,
482
+ key_states,
483
+ value_states,
484
+ attention_mask,
485
+ q_len,
486
+ dropout=dropout_rate,
487
+ use_sliding_windows=use_sliding_windows,
488
+ )
489
+
490
+ attn_output = attn_output.reshape(bsz, q_len, self.hidden_size).contiguous()
491
+ attn_output = self.o_proj(attn_output)
492
+
493
+ if not output_attentions:
494
+ attn_weights = None
495
+
496
+ return attn_output, attn_weights, past_key_value
497
+
498
+ def _flash_attention_forward(
499
+ self,
500
+ query_states,
501
+ key_states,
502
+ value_states,
503
+ attention_mask,
504
+ query_length,
505
+ dropout=0.0,
506
+ softmax_scale=None,
507
+ use_sliding_windows=False,
508
+ ):
509
+ """
510
+ Calls the forward method of Flash Attention - if the input hidden states contain at least one padding token
511
+ first unpad the input, then computes the attention scores and pad the final attention scores.
512
+
513
+ Args:
514
+ query_states (`torch.Tensor`):
515
+ Input query states to be passed to Flash Attention API
516
+ key_states (`torch.Tensor`):
517
+ Input key states to be passed to Flash Attention API
518
+ value_states (`torch.Tensor`):
519
+ Input value states to be passed to Flash Attention API
520
+ attention_mask (`torch.Tensor`):
521
+ The padding mask - corresponds to a tensor of size `(batch_size, seq_len)` where 0 stands for the
522
+ position of padding tokens and 1 for the position of non-padding tokens.
523
+ dropout (`int`, *optional*):
524
+ Attention dropout
525
+ softmax_scale (`float`, *optional*):
526
+ The scaling of QK^T before applying softmax. Default to 1 / sqrt(head_dim)
527
+ use_sliding_windows (`bool`, *optional*):
528
+ Whether to activate sliding window attention.
529
+ """
530
+ if not self._flash_attn_uses_top_left_mask:
531
+ causal = self.is_causal
532
+ else:
533
+ # TODO: Remove the `query_length != 1` check once Flash Attention for RoCm is bumped to 2.1. For details, please see the comment in LlamaFlashAttention2 __init__.
534
+ causal = self.is_causal and query_length != 1
535
+
536
+ # Decide whether to use SWA or not by layer index.
537
+ if use_sliding_windows and self.layer_idx >= self.config.max_window_layers:
538
+ use_sliding_windows = False
539
+
540
+ # Contains at least one padding token in the sequence
541
+ if attention_mask is not None:
542
+ batch_size = query_states.shape[0]
543
+ query_states, key_states, value_states, indices_q, cu_seq_lens, max_seq_lens = self._upad_input(
544
+ query_states, key_states, value_states, attention_mask, query_length
545
+ )
546
+
547
+ cu_seqlens_q, cu_seqlens_k = cu_seq_lens
548
+ max_seqlen_in_batch_q, max_seqlen_in_batch_k = max_seq_lens
549
+
550
+ if not use_sliding_windows:
551
+ attn_output_unpad = flash_attn_varlen_func(
552
+ query_states,
553
+ key_states,
554
+ value_states,
555
+ cu_seqlens_q=cu_seqlens_q,
556
+ cu_seqlens_k=cu_seqlens_k,
557
+ max_seqlen_q=max_seqlen_in_batch_q,
558
+ max_seqlen_k=max_seqlen_in_batch_k,
559
+ dropout_p=dropout,
560
+ softmax_scale=softmax_scale,
561
+ causal=causal,
562
+ )
563
+ else:
564
+ attn_output_unpad = flash_attn_varlen_func(
565
+ query_states,
566
+ key_states,
567
+ value_states,
568
+ cu_seqlens_q=cu_seqlens_q,
569
+ cu_seqlens_k=cu_seqlens_k,
570
+ max_seqlen_q=max_seqlen_in_batch_q,
571
+ max_seqlen_k=max_seqlen_in_batch_k,
572
+ dropout_p=dropout,
573
+ softmax_scale=softmax_scale,
574
+ causal=causal,
575
+ window_size=(self.config.sliding_window, self.config.sliding_window),
576
+ )
577
+
578
+ attn_output = pad_input(attn_output_unpad, indices_q, batch_size, query_length)
579
+ else:
580
+ if not use_sliding_windows:
581
+ attn_output = flash_attn_func(
582
+ query_states,
583
+ key_states,
584
+ value_states,
585
+ dropout,
586
+ softmax_scale=softmax_scale,
587
+ causal=causal,
588
+ )
589
+ else:
590
+ attn_output = flash_attn_func(
591
+ query_states,
592
+ key_states,
593
+ value_states,
594
+ dropout,
595
+ softmax_scale=softmax_scale,
596
+ causal=causal,
597
+ window_size=(self.config.sliding_window, self.config.sliding_window),
598
+ )
599
+
600
+ return attn_output
601
+
602
+ # Copied from transformers.models.mistral.modeling_mistral.MistralFlashAttention2._upad_input
603
+ def _upad_input(self, query_layer, key_layer, value_layer, attention_mask, query_length):
604
+ batch_size, kv_seq_len, num_heads, head_dim = key_layer.shape
605
+
606
+ # On the first iteration we need to properly re-create the padding mask
607
+ # by slicing it on the proper place
608
+ if kv_seq_len != attention_mask.shape[-1]:
609
+ attention_mask_num_tokens = attention_mask.shape[-1]
610
+ attention_mask = attention_mask[:, attention_mask_num_tokens - kv_seq_len :]
611
+
612
+ indices_k, cu_seqlens_k, max_seqlen_in_batch_k = _get_unpad_data(attention_mask)
613
+
614
+ key_layer = index_first_axis(key_layer.reshape(batch_size * kv_seq_len, num_heads, head_dim), indices_k)
615
+ value_layer = index_first_axis(value_layer.reshape(batch_size * kv_seq_len, num_heads, head_dim), indices_k)
616
+
617
+ if query_length == kv_seq_len:
618
+ query_layer = index_first_axis(
619
+ query_layer.reshape(batch_size * kv_seq_len, num_heads, head_dim), indices_k
620
+ )
621
+ cu_seqlens_q = cu_seqlens_k
622
+ max_seqlen_in_batch_q = max_seqlen_in_batch_k
623
+ indices_q = indices_k
624
+ elif query_length == 1:
625
+ max_seqlen_in_batch_q = 1
626
+ cu_seqlens_q = torch.arange(
627
+ batch_size + 1, dtype=torch.int32, device=query_layer.device
628
+ ) # There is a memcpy here, that is very bad.
629
+ indices_q = cu_seqlens_q[:-1]
630
+ query_layer = query_layer.squeeze(1)
631
+ else:
632
+ # The -q_len: slice assumes left padding.
633
+ attention_mask = attention_mask[:, -query_length:]
634
+ query_layer, indices_q, cu_seqlens_q, max_seqlen_in_batch_q = unpad_input(query_layer, attention_mask)
635
+
636
+ return (
637
+ query_layer,
638
+ key_layer,
639
+ value_layer,
640
+ indices_q,
641
+ (cu_seqlens_q, cu_seqlens_k),
642
+ (max_seqlen_in_batch_q, max_seqlen_in_batch_k),
643
+ )
644
+
645
+
646
+ # Copied from transformers.models.llama.modeling_llama.LlamaSdpaAttention with Llama->Qwen2
647
+ class Qwen2SdpaAttention(Qwen2Attention):
648
+ """
649
+ Qwen2 attention module using torch.nn.functional.scaled_dot_product_attention. This module inherits from
650
+ `Qwen2Attention` as the weights of the module stays untouched. The only changes are on the forward pass to adapt to
651
+ SDPA API.
652
+ """
653
+
654
+ # Adapted from Qwen2Attention.forward
655
+ def forward(
656
+ self,
657
+ hidden_states: torch.Tensor,
658
+ attention_mask: Optional[torch.Tensor] = None,
659
+ position_ids: Optional[torch.LongTensor] = None,
660
+ past_key_value: Optional[Cache] = None,
661
+ output_attentions: bool = False,
662
+ use_cache: bool = False,
663
+ ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]:
664
+ if output_attentions:
665
+ # TODO: Improve this warning with e.g. `model.config.attn_implementation = "manual"` once this is implemented.
666
+ logger.warning_once(
667
+ "Qwen2Model is using Qwen2SdpaAttention, but `torch.nn.functional.scaled_dot_product_attention` does not support `output_attentions=True`. Falling back to the manual attention implementation, "
668
+ 'but specifying the manual implementation will be required from Transformers version v5.0.0 onwards. This warning can be removed using the argument `attn_implementation="eager"` when loading the model.'
669
+ )
670
+ return super().forward(
671
+ hidden_states=hidden_states,
672
+ attention_mask=attention_mask,
673
+ position_ids=position_ids,
674
+ past_key_value=past_key_value,
675
+ output_attentions=output_attentions,
676
+ use_cache=use_cache,
677
+ )
678
+
679
+ bsz, q_len, _ = hidden_states.size()
680
+
681
+ query_states = self.q_proj(hidden_states)
682
+ key_states = self.k_proj(hidden_states)
683
+ value_states = self.v_proj(hidden_states)
684
+
685
+ query_states = query_states.view(bsz, q_len, self.num_heads, self.head_dim).transpose(1, 2)
686
+ key_states = key_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)
687
+ value_states = value_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)
688
+
689
+ kv_seq_len = key_states.shape[-2]
690
+ if past_key_value is not None:
691
+ kv_seq_len += past_key_value.get_seq_length(self.layer_idx)
692
+ cos, sin = self.rotary_emb(value_states, seq_len=kv_seq_len)
693
+
694
+ query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin, position_ids)
695
+
696
+ if past_key_value is not None:
697
+ cache_kwargs = {"sin": sin, "cos": cos} # Specific to RoPE models
698
+ key_states, value_states = past_key_value.update(key_states, value_states, self.layer_idx, cache_kwargs)
699
+
700
+ key_states = repeat_kv(key_states, self.num_key_value_groups)
701
+ value_states = repeat_kv(value_states, self.num_key_value_groups)
702
+
703
+ if attention_mask is not None:
704
+ if attention_mask.size() != (bsz, 1, q_len, kv_seq_len):
705
+ raise ValueError(
706
+ f"Attention mask should be of size {(bsz, 1, q_len, kv_seq_len)}, but is {attention_mask.size()}"
707
+ )
708
+
709
+ # SDPA with memory-efficient backend is currently (torch==2.1.2) bugged with non-contiguous inputs with custom attn_mask,
710
+ # Reference: https://github.com/pytorch/pytorch/issues/112577.
711
+ if query_states.device.type == "cuda" and attention_mask is not None:
712
+ query_states = query_states.contiguous()
713
+ key_states = key_states.contiguous()
714
+ value_states = value_states.contiguous()
715
+
716
+ attn_output = torch.nn.functional.scaled_dot_product_attention(
717
+ query_states,
718
+ key_states,
719
+ value_states,
720
+ attn_mask=attention_mask,
721
+ dropout_p=self.attention_dropout if self.training else 0.0,
722
+ is_causal=False,
723
+ )
724
+
725
+ attn_output = attn_output.transpose(1, 2).contiguous()
726
+ attn_output = attn_output.reshape(bsz, q_len, self.hidden_size)
727
+
728
+ attn_output = self.o_proj(attn_output)
729
+
730
+ return attn_output, None, past_key_value
731
+
732
+
733
+ class Qwen2SdpaAttentionGqa(Qwen2Attention):
734
+ """
735
+ Qwen2 attention module using torch.nn.functional.scaled_dot_product_attention. This module inherits from
736
+ `Qwen2Attention` as the weights of the module stays untouched. The only changes are on the forward pass to adapt to
737
+ SDPA API.
738
+ """
739
+
740
+ # Adapted from Qwen2Attention.forward
741
+ def forward(
742
+ self,
743
+ hidden_states: torch.Tensor,
744
+ attention_mask: Optional[torch.Tensor] = None,
745
+ position_ids: Optional[torch.LongTensor] = None,
746
+ past_key_value: Optional[Cache] = None,
747
+ output_attentions: bool = False,
748
+ use_cache: bool = False,
749
+ ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]:
750
+ if output_attentions:
751
+ # TODO: Improve this warning with e.g. `model.config.attn_implementation = "manual"` once this is implemented.
752
+ logger.warning_once(
753
+ "Qwen2Model is using Qwen2SdpaAttention, but `torch.nn.functional.scaled_dot_product_attention` does not support `output_attentions=True`. Falling back to the manual attention implementation, "
754
+ 'but specifying the manual implementation will be required from Transformers version v5.0.0 onwards. This warning can be removed using the argument `attn_implementation="eager"` when loading the model.'
755
+ )
756
+ return super().forward(
757
+ hidden_states=hidden_states,
758
+ attention_mask=attention_mask,
759
+ position_ids=position_ids,
760
+ past_key_value=past_key_value,
761
+ output_attentions=output_attentions,
762
+ use_cache=use_cache,
763
+ )
764
+
765
+ bsz, q_len, _ = hidden_states.size()
766
+
767
+ query_states = self.q_proj(hidden_states)
768
+ key_states = self.k_proj(hidden_states)
769
+ value_states = self.v_proj(hidden_states)
770
+
771
+ query_states = query_states.view(bsz, q_len, self.num_heads, self.head_dim).transpose(1, 2)
772
+ key_states = key_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)
773
+ value_states = value_states.view(bsz, q_len, self.num_key_value_heads, self.head_dim).transpose(1, 2)
774
+
775
+ kv_seq_len = key_states.shape[-2]
776
+ if past_key_value is not None:
777
+ kv_seq_len += past_key_value.get_seq_length(self.layer_idx)
778
+ cos, sin = self.rotary_emb(value_states, seq_len=kv_seq_len)
779
+
780
+ query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin, position_ids)
781
+
782
+ if past_key_value is not None:
783
+ cache_kwargs = {"sin": sin, "cos": cos} # Specific to RoPE models
784
+ key_states, value_states = past_key_value.update(key_states, value_states, self.layer_idx, cache_kwargs)
785
+
786
+ # key_states = repeat_kv(key_states, self.num_key_value_groups)
787
+ # value_states = repeat_kv(value_states, self.num_key_value_groups)
788
+
789
+ if attention_mask is not None:
790
+ if attention_mask.size() != (bsz, 1, q_len, kv_seq_len):
791
+ raise ValueError(
792
+ f"Attention mask should be of size {(bsz, 1, q_len, kv_seq_len)}, but is {attention_mask.size()}"
793
+ )
794
+
795
+ # SDPA with memory-efficient backend is currently (torch==2.1.2) bugged with non-contiguous inputs with custom attn_mask,
796
+ # Reference: https://github.com/pytorch/pytorch/issues/112577.
797
+ if query_states.device.type == "cuda" and attention_mask is not None:
798
+ query_states = query_states.contiguous()
799
+ key_states = key_states.contiguous()
800
+ value_states = value_states.contiguous()
801
+
802
+ with torch.backends.cuda.sdp_kernel(enable_flash=True,
803
+ enable_math=True,
804
+ enable_mem_efficient=False):
805
+
806
+ attn_output = torch.nn.functional.scaled_dot_product_attention(
807
+ query_states,
808
+ key_states,
809
+ value_states,
810
+ attn_mask=attention_mask,
811
+ enable_gqa=True,
812
+ dropout_p=self.attention_dropout if self.training else 0.0,
813
+ is_causal=False,
814
+ )
815
+
816
+ attn_output = attn_output.transpose(1, 2).contiguous()
817
+ attn_output = attn_output.reshape(bsz, q_len, self.hidden_size)
818
+
819
+ attn_output = self.o_proj(attn_output)
820
+
821
+ return attn_output, None, past_key_value
822
+
823
+
824
+ class Qwen2MagiAttention(Qwen2Attention):
825
+ """
826
+ Qwen2 attention using MagiAttention for efficient training with MTP packing support.
827
+
828
+ MagiAttention uses range-based sparse attention patterns:
829
+ - q_ranges/k_ranges define which query/key ranges attend to each other
830
+ - attn_type_map specifies causal(1) or full(0) attention for each range pair
831
+ """
832
+
833
+ def __init__(self, *args, **kwargs):
834
+ super().__init__(*args, **kwargs)
835
+ if not _MAGI_AVAILABLE:
836
+ raise ImportError(
837
+ "magi_attention is not installed. Install with: pip install magi-attention"
838
+ )
839
+ self.softmax_scale = self.head_dim ** -0.5
840
+
841
+ def forward(
842
+ self,
843
+ hidden_states: torch.Tensor,
844
+ attention_mask: Optional[dict] = None, # magi_plan dict
845
+ position_ids: Optional[torch.LongTensor] = None,
846
+ past_key_value: Optional[Cache] = None,
847
+ output_attentions: bool = False,
848
+ use_cache: bool = False,
849
+ ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]:
850
+ if output_attentions:
851
+ raise NotImplementedError('MagiAttention does not support output_attentions=True')
852
+
853
+ bsz, q_len, _ = hidden_states.size()
854
+ assert bsz == 1, "MagiAttention only supports batch_size=1 (use packing instead)"
855
+
856
+ query_states = self.q_proj(hidden_states)
857
+ key_states = self.k_proj(hidden_states)
858
+ value_states = self.v_proj(hidden_states)
859
+
860
+ # Magi expects [T, H, D] format (no batch dimension)
861
+ query_states = query_states.view(q_len, self.num_heads, self.head_dim)
862
+ key_states = key_states.view(q_len, self.num_key_value_heads, self.head_dim)
863
+ value_states = value_states.view(q_len, self.num_key_value_heads, self.head_dim)
864
+
865
+ kv_seq_len = q_len
866
+ if past_key_value is not None:
867
+ if self.layer_idx is None:
868
+ raise ValueError(
869
+ f"The cache structure has changed since version v4.36. If you are using {self.__class__.__name__} "
870
+ "for auto-regressive decoding with k/v caching, please make sure to initialize the attention class "
871
+ "with a layer index."
872
+ )
873
+ kv_seq_len += past_key_value.get_seq_length(self.layer_idx)
874
+
875
+ cos, sin = self.rotary_emb(value_states.unsqueeze(0).transpose(1, 2), seq_len=kv_seq_len)
876
+
877
+ # Apply RoPE: need [B, H, L, D] format for apply_rotary_pos_emb
878
+ q_for_rope = query_states.unsqueeze(0).transpose(1, 2) # [1, H, L, D]
879
+ k_for_rope = key_states.unsqueeze(0).transpose(1, 2) # [1, Hkv, L, D]
880
+ q_for_rope, k_for_rope = apply_rotary_pos_emb(q_for_rope, k_for_rope, cos, sin, position_ids)
881
+
882
+ # Back to [T, H, D]
883
+ query_states = q_for_rope.squeeze(0).transpose(0, 1).contiguous() # [L, H, D]
884
+ key_states = k_for_rope.squeeze(0).transpose(0, 1).contiguous() # [L, Hkv, D]
885
+
886
+ if past_key_value is not None:
887
+ cache_kwargs = {"sin": sin, "cos": cos}
888
+ # Note: Magi doesn't support KV cache in training, this is for potential future use
889
+ key_states_4d = key_states.unsqueeze(0).transpose(1, 2)
890
+ value_states_4d = value_states.unsqueeze(0).transpose(1, 2)
891
+ key_states_4d, value_states_4d = past_key_value.update(
892
+ key_states_4d, value_states_4d, self.layer_idx, cache_kwargs
893
+ )
894
+ key_states = key_states_4d.squeeze(0).transpose(0, 1).contiguous()
895
+ value_states = value_states_4d.squeeze(0).transpose(0, 1).contiguous()
896
+
897
+ # Run Magi Attention
898
+ # attention_mask is a magi_plan dict with q_ranges, k_ranges, attn_type_map, etc.
899
+
900
+ attn_output, _ = flex_flash_attn_func(
901
+ query_states.contiguous(),
902
+ key_states.contiguous(),
903
+ value_states.contiguous(),
904
+ q_ranges=attention_mask["q_ranges"],
905
+ k_ranges=attention_mask["k_ranges"],
906
+ attn_type_map=attention_mask["attn_type_map"],
907
+ softmax_scale=self.softmax_scale,
908
+ softcap=0.0,
909
+ deterministic=False,
910
+ ) # [T, H, D]
911
+
912
+ # Reshape to [B, L, H*D]
913
+ attn_output = attn_output.view(1, q_len, self.hidden_size)
914
+ attn_output = self.o_proj(attn_output)
915
+
916
+ return attn_output, None, past_key_value
917
+
918
+
919
+ QWEN2_ATTENTION_CLASSES = {
920
+ "eager": Qwen2Attention,
921
+ "flash_attention_2": Qwen2FlashAttention2,
922
+ "sdpa": Qwen2SdpaAttention,
923
+ "magi": Qwen2MagiAttention,
924
+ }
925
+
926
+
927
+ class Qwen2DecoderLayer(nn.Module):
928
+ def __init__(self, config: Qwen2Config, layer_idx: int):
929
+ super().__init__()
930
+ self.hidden_size = config.hidden_size
931
+
932
+ if config._attn_implementation == 'magi' and not _MAGI_AVAILABLE:
933
+ if is_flash_attn_2_available():
934
+ logger.warning_once(
935
+ 'magi_attention not available, falling back to flash_attention_2'
936
+ )
937
+ config._attn_implementation = 'flash_attention_2'
938
+ else:
939
+ logger.warning_once(
940
+ 'magi_attention not available, falling back to sdpa'
941
+ )
942
+ config._attn_implementation = 'sdpa'
943
+ if config._attn_implementation == 'flash_attention_2' and not is_flash_attn_2_available():
944
+ logger.warning_once(
945
+ 'flash_attn is not available, falling back to sdpa'
946
+ )
947
+ config._attn_implementation = 'sdpa'
948
+
949
+ self.self_attn = QWEN2_ATTENTION_CLASSES[config._attn_implementation](config, layer_idx)
950
+
951
+ self.mlp = Qwen2MLP(config)
952
+ self.input_layernorm = Qwen2RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
953
+ self.post_attention_layernorm = Qwen2RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
954
+
955
+ def forward(
956
+ self,
957
+ hidden_states: torch.Tensor,
958
+ attention_mask: Optional[torch.Tensor] = None,
959
+ position_ids: Optional[torch.LongTensor] = None,
960
+ past_key_value: Optional[Tuple[torch.Tensor]] = None,
961
+ output_attentions: Optional[bool] = False,
962
+ use_cache: Optional[bool] = False,
963
+ **kwargs,
964
+ ) -> Tuple[torch.FloatTensor, Optional[Tuple[torch.FloatTensor, torch.FloatTensor]]]:
965
+ if "padding_mask" in kwargs:
966
+ warnings.warn(
967
+ "Passing `padding_mask` is deprecated and will be removed in v4.37. "
968
+ "Please make sure use `attention_mask` instead.`"
969
+ )
970
+ """
971
+ Args:
972
+ hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)`
973
+ attention_mask (`torch.FloatTensor`, *optional*): attention mask of size
974
+ `(batch, sequence_length)` where padding elements are indicated by 0.
975
+ output_attentions (`bool`, *optional*):
976
+ Whether or not to return the attentions tensors of all attention layers. See `attentions` under
977
+ returned tensors for more detail.
978
+ use_cache (`bool`, *optional*):
979
+ If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding
980
+ (see `past_key_values`).
981
+ past_key_value (`Tuple(torch.FloatTensor)`, *optional*): cached past key and value projection states
982
+ """
983
+
984
+ residual = hidden_states
985
+
986
+ hidden_states = self.input_layernorm(hidden_states)
987
+
988
+ # Self Attention
989
+ hidden_states, self_attn_weights, present_key_value = self.self_attn(
990
+ hidden_states=hidden_states,
991
+ attention_mask=attention_mask,
992
+ position_ids=position_ids,
993
+ past_key_value=past_key_value,
994
+ output_attentions=output_attentions,
995
+ use_cache=use_cache,
996
+ )
997
+ hidden_states = residual + hidden_states
998
+
999
+ # Fully Connected
1000
+ residual = hidden_states
1001
+ hidden_states = self.post_attention_layernorm(hidden_states)
1002
+ hidden_states = self.mlp(hidden_states)
1003
+ hidden_states = residual + hidden_states
1004
+
1005
+ outputs = (hidden_states,)
1006
+
1007
+ if output_attentions:
1008
+ outputs += (self_attn_weights,)
1009
+
1010
+ if use_cache:
1011
+ outputs += (present_key_value,)
1012
+
1013
+ return outputs
1014
+
1015
+
1016
+ QWEN2_START_DOCSTRING = r"""
1017
+ This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the
1018
+ library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads
1019
+ etc.)
1020
+
1021
+ This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass.
1022
+ Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage
1023
+ and behavior.
1024
+
1025
+ Parameters:
1026
+ config ([`Qwen2Config`]):
1027
+ Model configuration class with all the parameters of the model. Initializing with a config file does not
1028
+ load the weights associated with the model, only the configuration. Check out the
1029
+ [`~PreTrainedModel.from_pretrained`] method to load the model weights.
1030
+ """
1031
+
1032
+
1033
+ @add_start_docstrings(
1034
+ "The bare Qwen2 Model outputting raw hidden-states without any specific head on top.",
1035
+ QWEN2_START_DOCSTRING,
1036
+ )
1037
+ class Qwen2PreTrainedModel(PreTrainedModel):
1038
+ config_class = Qwen2Config
1039
+ base_model_prefix = "model"
1040
+ supports_gradient_checkpointing = True
1041
+ _no_split_modules = ["Qwen2DecoderLayer"]
1042
+ _skip_keys_device_placement = "past_key_values"
1043
+ _supports_flash_attn_2 = True
1044
+ _supports_sdpa = True
1045
+ _supports_cache_class = True
1046
+
1047
+ @classmethod
1048
+ def _autoset_attn_implementation(cls, config, *args, **kwargs):
1049
+ if getattr(config, '_attn_implementation', None) == 'magi':
1050
+ return config
1051
+ return super()._autoset_attn_implementation(config, *args, **kwargs)
1052
+
1053
+ def _check_and_adjust_attn_implementation(self, attn_implementation, is_init_check=False):
1054
+ if attn_implementation == "magi":
1055
+ return "magi"
1056
+ return super()._check_and_adjust_attn_implementation(attn_implementation, is_init_check)
1057
+
1058
+ def _init_weights(self, module):
1059
+ std = self.config.initializer_range
1060
+ if isinstance(module, nn.Linear):
1061
+ module.weight.data.normal_(mean=0.0, std=std)
1062
+ if module.bias is not None:
1063
+ module.bias.data.zero_()
1064
+ elif isinstance(module, nn.Embedding):
1065
+ module.weight.data.normal_(mean=0.0, std=std)
1066
+ if module.padding_idx is not None:
1067
+ module.weight.data[module.padding_idx].zero_()
1068
+
1069
+
1070
+ QWEN2_INPUTS_DOCSTRING = r"""
1071
+ Args:
1072
+ input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`):
1073
+ Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide
1074
+ it.
1075
+
1076
+ Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
1077
+ [`PreTrainedTokenizer.__call__`] for details.
1078
+
1079
+ [What are input IDs?](../glossary#input-ids)
1080
+ attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*):
1081
+ Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`:
1082
+
1083
+ - 1 for tokens that are **not masked**,
1084
+ - 0 for tokens that are **masked**.
1085
+
1086
+ [What are attention masks?](../glossary#attention-mask)
1087
+
1088
+ Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
1089
+ [`PreTrainedTokenizer.__call__`] for details.
1090
+
1091
+ If `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see
1092
+ `past_key_values`).
1093
+
1094
+ If you want to change padding behavior, you should read [`modeling_opt._prepare_decoder_attention_mask`]
1095
+ and modify to your needs. See diagram 1 in [the paper](https://arxiv.org/abs/1910.13461) for more
1096
+ information on the default strategy.
1097
+
1098
+ - 1 indicates the head is **not masked**,
1099
+ - 0 indicates the head is **masked**.
1100
+ position_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
1101
+ Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0,
1102
+ config.n_positions - 1]`.
1103
+
1104
+ [What are position IDs?](../glossary#position-ids)
1105
+ past_key_values (`Cache` or `tuple(tuple(torch.FloatTensor))`, *optional*):
1106
+ Pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention
1107
+ blocks) that can be used to speed up sequential decoding. This typically consists in the `past_key_values`
1108
+ returned by the model at a previous stage of decoding, when `use_cache=True` or `config.use_cache=True`.
1109
+
1110
+ Two formats are allowed:
1111
+ - a [`~cache_utils.Cache`] instance;
1112
+ - Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of
1113
+ shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`). This is also known as the legacy
1114
+ cache format.
1115
+
1116
+ The model will output the same cache format that is fed as input. If no `past_key_values` are passed, the
1117
+ legacy cache format will be returned.
1118
+
1119
+ If `past_key_values` are used, the user can optionally input only the last `input_ids` (those that don't
1120
+ have their past key value states given to this model) of shape `(batch_size, 1)` instead of all `input_ids`
1121
+ of shape `(batch_size, sequence_length)`.
1122
+ inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*):
1123
+ Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This
1124
+ is useful if you want more control over how to convert `input_ids` indices into associated vectors than the
1125
+ model's internal embedding lookup matrix.
1126
+ use_cache (`bool`, *optional*):
1127
+ If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see
1128
+ `past_key_values`).
1129
+ output_attentions (`bool`, *optional*):
1130
+ Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned
1131
+ tensors for more detail.
1132
+ output_hidden_states (`bool`, *optional*):
1133
+ Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for
1134
+ more detail.
1135
+ return_dict (`bool`, *optional*):
1136
+ Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple.
1137
+ """
1138
+
1139
+
1140
+ @add_start_docstrings(
1141
+ "The bare Qwen2 Model outputting raw hidden-states without any specific head on top.",
1142
+ QWEN2_START_DOCSTRING,
1143
+ )
1144
+ class Qwen2Model(Qwen2PreTrainedModel):
1145
+ """
1146
+ Transformer decoder consisting of *config.num_hidden_layers* layers. Each layer is a [`Qwen2DecoderLayer`]
1147
+
1148
+ Args:
1149
+ config: Qwen2Config
1150
+ """
1151
+
1152
+ def __init__(self, config: Qwen2Config):
1153
+ super().__init__(config)
1154
+ self.padding_idx = config.pad_token_id
1155
+ self.vocab_size = config.vocab_size
1156
+
1157
+ self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx)
1158
+ self.layers = nn.ModuleList(
1159
+ [Qwen2DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
1160
+ )
1161
+ self._attn_implementation = config._attn_implementation
1162
+ self.norm = Qwen2RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
1163
+
1164
+ self.gradient_checkpointing = False
1165
+ # Initialize weights and apply final processing
1166
+ self.post_init()
1167
+
1168
+ self.block_size = getattr(config, 'block_size', 6)
1169
+ self.causal_attn = getattr(config, 'causal_attn', False)
1170
+ self.text_mask_token_id = getattr(config, 'text_mask_token_id', 151676)
1171
+
1172
+
1173
+ def get_input_embeddings(self):
1174
+ return self.embed_tokens
1175
+
1176
+ def set_input_embeddings(self, value):
1177
+ self.embed_tokens = value
1178
+
1179
+ def image_processing(self, input_ids, visual_features, image_token_index):
1180
+ if visual_features is not None:
1181
+ input_embeds = self.get_input_embeddings()(input_ids)
1182
+ B, N, C = input_embeds.shape
1183
+ input_embeds = input_embeds.reshape(B * N, C)
1184
+
1185
+ input_ids = input_ids.reshape(B * N)
1186
+ selected = (input_ids == image_token_index)
1187
+ assert selected.sum() != 0
1188
+ input_embeds[selected] = visual_features.reshape(-1, C).to(input_embeds.device)
1189
+ input_embeds = input_embeds.reshape(B, N, C)
1190
+ else:
1191
+ input_embeds = self.get_input_embeddings()(input_ids)
1192
+ return input_embeds
1193
+
1194
+ @add_start_docstrings_to_model_forward(QWEN2_INPUTS_DOCSTRING)
1195
+ def forward(
1196
+ self,
1197
+ input_ids: torch.LongTensor = None,
1198
+ visual_features: Optional[torch.FloatTensor] = None,
1199
+ image_token_index: int = None,
1200
+ attention_mask: Optional[torch.Tensor] = None,
1201
+ position_ids: Optional[torch.LongTensor] = None,
1202
+ past_key_values: Optional[List[torch.FloatTensor]] = None,
1203
+ inputs_embeds: Optional[torch.FloatTensor] = None,
1204
+ use_cache: Optional[bool] = None,
1205
+ output_attentions: Optional[bool] = None,
1206
+ output_hidden_states: Optional[bool] = None,
1207
+ return_dict: Optional[bool] = None,
1208
+ ) -> Union[Tuple, BaseModelOutputWithPast]:
1209
+ output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
1210
+ output_hidden_states = (
1211
+ output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
1212
+ )
1213
+ use_cache = use_cache if use_cache is not None else self.config.use_cache
1214
+
1215
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
1216
+
1217
+ # retrieve input_ids and inputs_embeds
1218
+ if input_ids is not None and inputs_embeds is not None:
1219
+ raise ValueError("You cannot specify both decoder_input_ids and decoder_inputs_embeds at the same time")
1220
+ elif input_ids is not None:
1221
+ batch_size, seq_length = input_ids.shape
1222
+ elif inputs_embeds is not None:
1223
+ batch_size, seq_length, _ = inputs_embeds.shape
1224
+ else:
1225
+ raise ValueError("You have to specify either decoder_input_ids or decoder_inputs_embeds")
1226
+
1227
+ if self.gradient_checkpointing and self.training:
1228
+ if use_cache:
1229
+ logger.warning_once(
1230
+ "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..."
1231
+ )
1232
+ use_cache = False
1233
+
1234
+ past_key_values_length = 0
1235
+
1236
+ if use_cache:
1237
+ use_legacy_cache = not isinstance(past_key_values, Cache)
1238
+ if use_legacy_cache:
1239
+ if past_key_values is None:
1240
+ past_key_values = DynamicCache()
1241
+ else:
1242
+ past_key_values = DynamicCache.from_legacy_cache(past_key_values)
1243
+ past_key_values_length = past_key_values.get_seq_length()
1244
+
1245
+ if position_ids is None:
1246
+ device = input_ids.device if input_ids is not None else inputs_embeds.device
1247
+ position_ids = torch.arange(
1248
+ past_key_values_length, seq_length + past_key_values_length, dtype=torch.long, device=device
1249
+ )
1250
+ position_ids = position_ids.unsqueeze(0).view(-1, seq_length)
1251
+ else:
1252
+ position_ids = position_ids.view(-1, seq_length).long()
1253
+
1254
+ if inputs_embeds is None:
1255
+ inputs_embeds = self.image_processing(input_ids, visual_features, image_token_index)
1256
+
1257
+ if attention_mask is not None and self._attn_implementation == "magi" and use_cache:
1258
+ is_padding_right = attention_mask[:, -1].sum().item() != batch_size
1259
+ if is_padding_right:
1260
+ raise ValueError(
1261
+ "You are attempting to perform batched generation with padding_side='right'"
1262
+ " this may lead to unexpected behaviour for Flash Attention version of Qwen2. Make sure to "
1263
+ " call `tokenizer.padding_side = 'left'` before tokenizing the input. "
1264
+ )
1265
+
1266
+ device = input_ids.device if input_ids is not None else inputs_embeds.device
1267
+
1268
+ x0_len = find_prefix_seq_length_by_pe(position_ids).to(device=device)
1269
+
1270
+ def _prepare_block_mask_for_inference(attention_mask):
1271
+ attention_mask = _prepare_4d_causal_attention_mask(
1272
+ attention_mask,
1273
+ (batch_size, seq_length),
1274
+ inputs_embeds,
1275
+ past_key_values_length,
1276
+ sliding_window=self.config.sliding_window,
1277
+ )
1278
+ # switch to ar mode
1279
+ if seq_length == 1 or (input_ids is not None and input_ids[0][-1].item() != self.text_mask_token_id):
1280
+ return attention_mask
1281
+
1282
+
1283
+ if attention_mask is None or len(attention_mask.shape) != 4:
1284
+ return attention_mask
1285
+
1286
+ # For SDLM, the generation window should set to bidirectional attention
1287
+ if use_cache:
1288
+ update_mask_func = partial(
1289
+ update_causal_mask_for_one_gen_window_2d,
1290
+ block_size=self.block_size,
1291
+ use_cache=use_cache,
1292
+ causal_attn=self.causal_attn,
1293
+ )
1294
+ else:
1295
+ update_mask_func = partial(
1296
+ update_causal_mask_with_pad_non_visible_2d,
1297
+ block_size=self.block_size,
1298
+ text_mask_token_id=self.text_mask_token_id,
1299
+ causal_attn=self.causal_attn,
1300
+ )
1301
+
1302
+ new_attention_mask = []
1303
+ for b in range(attention_mask.shape[0]):
1304
+ new_attention_mask.append(
1305
+ update_mask_func(
1306
+ input_ids[b],
1307
+ attention_mask[b][0],
1308
+ ).unsqueeze(0)
1309
+ )
1310
+ return torch.stack(new_attention_mask, dim=0)
1311
+
1312
+ def _prepare_block_mask_for_training():
1313
+ block_mask, _ = create_block_diff_mask_by_pe_4d(
1314
+ block_size=self.block_size,
1315
+ x0_len_list=x0_len,
1316
+ position_ids=position_ids,
1317
+ causal_attn=self.causal_attn,
1318
+ )
1319
+ return block_mask
1320
+
1321
+ if self._attn_implementation == "magi":
1322
+ ar_decode = seq_length == 1 or (input_ids is not None and input_ids[0][-1].item() != self.text_mask_token_id)
1323
+ attention_mask = build_magi_ranges(
1324
+ kv_len=seq_length + past_key_values_length,
1325
+ q_len=seq_length,
1326
+ block_size=self.block_size,
1327
+ ar_decode=ar_decode,
1328
+ device=device
1329
+ )
1330
+
1331
+ elif self._attn_implementation == "sdpa":
1332
+ attention_mask = _prepare_block_mask_for_training() if self.training else _prepare_block_mask_for_inference(attention_mask)
1333
+
1334
+ else:
1335
+ raise NotImplementedError(f'{self._attn_implementation=}')
1336
+
1337
+
1338
+ hidden_states = inputs_embeds
1339
+
1340
+ # decoder layers
1341
+ all_hidden_states = () if output_hidden_states else None
1342
+ all_self_attns = () if output_attentions else None
1343
+ next_decoder_cache = None
1344
+
1345
+ for decoder_layer in self.layers:
1346
+ if output_hidden_states:
1347
+ all_hidden_states += (hidden_states,)
1348
+
1349
+ if self.gradient_checkpointing and self.training:
1350
+ layer_outputs = self._gradient_checkpointing_func(
1351
+ decoder_layer.__call__,
1352
+ hidden_states,
1353
+ attention_mask,
1354
+ position_ids,
1355
+ past_key_values,
1356
+ output_attentions,
1357
+ use_cache,
1358
+ )
1359
+ else:
1360
+ layer_outputs = decoder_layer(
1361
+ hidden_states,
1362
+ attention_mask=attention_mask,
1363
+ position_ids=position_ids,
1364
+ past_key_value=past_key_values,
1365
+ output_attentions=output_attentions,
1366
+ use_cache=use_cache,
1367
+ )
1368
+
1369
+ hidden_states = layer_outputs[0]
1370
+
1371
+ if use_cache:
1372
+ next_decoder_cache = layer_outputs[2 if output_attentions else 1]
1373
+
1374
+ if output_attentions:
1375
+ all_self_attns += (layer_outputs[1],)
1376
+
1377
+ hidden_states = self.norm(hidden_states)
1378
+
1379
+ # add hidden states from the last decoder layer
1380
+ if output_hidden_states:
1381
+ all_hidden_states += (hidden_states,)
1382
+
1383
+ next_cache = None
1384
+ if use_cache:
1385
+ next_cache = next_decoder_cache.to_legacy_cache() if use_legacy_cache else next_decoder_cache
1386
+
1387
+ if not return_dict:
1388
+ return tuple(v for v in [hidden_states, next_cache, all_hidden_states, all_self_attns] if v is not None)
1389
+ return BaseModelOutputWithPast(
1390
+ last_hidden_state=hidden_states,
1391
+ past_key_values=next_cache,
1392
+ hidden_states=all_hidden_states,
1393
+ attentions=all_self_attns,
1394
+ )
1395
+
1396
+
1397
+ class Qwen2ForCausalLM(Qwen2PreTrainedModel):
1398
+ _tied_weights_keys = ["lm_head.weight"]
1399
+
1400
+ def __init__(self, config):
1401
+ super().__init__(config)
1402
+ self.model = Qwen2Model(config)
1403
+ self.vocab_size = config.vocab_size
1404
+ self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
1405
+
1406
+ self.text_mask_token_id = getattr(config, 'text_mask_token_id', 151676)
1407
+
1408
+ # Initialize weights and apply final processing
1409
+ self.post_init()
1410
+
1411
+
1412
+ def get_input_embeddings(self):
1413
+ return self.model.embed_tokens
1414
+
1415
+ def set_input_embeddings(self, value):
1416
+ self.model.embed_tokens = value
1417
+
1418
+ def get_output_embeddings(self):
1419
+ return self.lm_head
1420
+
1421
+ def set_output_embeddings(self, new_embeddings):
1422
+ self.lm_head = new_embeddings
1423
+
1424
+ def set_decoder(self, decoder):
1425
+ self.model = decoder
1426
+
1427
+ def get_decoder(self):
1428
+ return self.model
1429
+
1430
+ @add_start_docstrings_to_model_forward(QWEN2_INPUTS_DOCSTRING)
1431
+ @replace_return_docstrings(output_type=CausalLMOutputWithPast, config_class=_CONFIG_FOR_DOC)
1432
+ def forward(
1433
+ self,
1434
+ input_ids: torch.LongTensor = None,
1435
+ visual_features: Optional[torch.FloatTensor] = None,
1436
+ image_token_index: int = None,
1437
+ attention_mask: Optional[torch.Tensor] = None,
1438
+ position_ids: Optional[torch.LongTensor] = None,
1439
+ past_key_values: Optional[List[torch.FloatTensor]] = None,
1440
+ inputs_embeds: Optional[torch.FloatTensor] = None,
1441
+ labels: Optional[torch.LongTensor] = None,
1442
+ use_cache: Optional[bool] = None,
1443
+ output_attentions: Optional[bool] = None,
1444
+ output_hidden_states: Optional[bool] = None,
1445
+ return_dict: Optional[bool] = None,
1446
+ ) -> Union[Tuple, CausalLMOutputWithPast]:
1447
+ r"""
1448
+ Args:
1449
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
1450
+ Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
1451
+ config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
1452
+ (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
1453
+
1454
+ Returns:
1455
+
1456
+ Example:
1457
+
1458
+ ```python
1459
+ >>> from transformers import AutoTokenizer, Qwen2ForCausalLM
1460
+
1461
+ >>> model = Qwen2ForCausalLM.from_pretrained(PATH_TO_CONVERTED_WEIGHTS)
1462
+ >>> tokenizer = AutoTokenizer.from_pretrained(PATH_TO_CONVERTED_TOKENIZER)
1463
+
1464
+ >>> prompt = "Hey, are you conscious? Can you talk to me?"
1465
+ >>> inputs = tokenizer(prompt, return_tensors="pt")
1466
+
1467
+ >>> # Generate
1468
+ >>> generate_ids = model.generate(inputs.input_ids, max_length=30)
1469
+ >>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
1470
+ "Hey, are you conscious? Can you talk to me?\nI'm not conscious, but I can talk to you."
1471
+ ```"""
1472
+
1473
+ output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
1474
+ output_hidden_states = (
1475
+ output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
1476
+ )
1477
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
1478
+
1479
+ # decoder outputs consists of (dec_features, layer_state, dec_hidden, dec_attn)
1480
+ outputs = self.model(
1481
+ input_ids=input_ids,
1482
+ visual_features=visual_features,
1483
+ image_token_index=image_token_index,
1484
+ attention_mask=attention_mask,
1485
+ position_ids=position_ids,
1486
+ past_key_values=past_key_values,
1487
+ inputs_embeds=inputs_embeds,
1488
+ use_cache=use_cache,
1489
+ output_attentions=output_attentions,
1490
+ output_hidden_states=output_hidden_states,
1491
+ return_dict=return_dict,
1492
+ )
1493
+
1494
+ hidden_states = outputs[0]
1495
+ logits = self.lm_head(hidden_states)
1496
+ logits = logits.float()
1497
+
1498
+ loss = None
1499
+ if labels is not None:
1500
+
1501
+ # Shift so that tokens < n predict n
1502
+ shift_logits = logits[..., :-1, :].contiguous()
1503
+ shift_labels = labels[..., 1:].contiguous()
1504
+
1505
+ # Flatten the tokens
1506
+ loss_fct = CrossEntropyLoss()
1507
+ shift_logits = shift_logits.view(-1, self.config.vocab_size)
1508
+
1509
+ shift_labels = shift_labels.view(-1)
1510
+ shift_labels = shift_labels.to(shift_logits.device)
1511
+ loss = loss_fct(shift_logits, shift_labels)
1512
+
1513
+ pos_masks = find_pred_pos_from_input_ids(input_ids, text_mask_token_id=self.text_mask_token_id)
1514
+ shift_input_ids = input_ids[..., :-1].contiguous()
1515
+ shift_pos_masks = pos_masks[:, :-1]
1516
+ shift_input_ids = shift_input_ids.view(-1)
1517
+ max_n_future_tokens = min(4, self.model.block_size)
1518
+ pos_loss_list = torch.zeros(max_n_future_tokens, device=shift_logits.device)
1519
+ shift_pos_masks = shift_pos_masks.reshape(-1)
1520
+
1521
+ for ix in range(max_n_future_tokens):
1522
+ seg_loss = F.cross_entropy(
1523
+ shift_logits[shift_pos_masks == ix],
1524
+ shift_labels[shift_pos_masks == ix],
1525
+ reduction='mean'
1526
+ )
1527
+ pos_loss_list[ix] = seg_loss
1528
+
1529
+
1530
+ if not return_dict:
1531
+ output = (logits,) + outputs[1:]
1532
+ return (loss,) + output if loss is not None else output
1533
+
1534
+ if self.training:
1535
+ return CausalLMOutputWithPast(
1536
+ loss=loss,
1537
+ logits=logits,
1538
+ past_key_values=outputs.past_key_values,
1539
+ hidden_states=outputs.hidden_states,
1540
+ attentions=outputs.attentions,
1541
+ ), pos_loss_list
1542
+
1543
+ return CausalLMOutputWithPast(
1544
+ loss=loss,
1545
+ logits=logits,
1546
+ past_key_values=outputs.past_key_values,
1547
+ hidden_states=outputs.hidden_states,
1548
+ attentions=outputs.attentions,
1549
+ )
1550
+
1551
+ def prepare_inputs_for_generation(
1552
+ self, input_ids, past_key_values=None, attention_mask=None, inputs_embeds=None, **kwargs
1553
+ ):
1554
+ # Omit tokens covered by past_key_values
1555
+ if past_key_values is not None:
1556
+ if isinstance(past_key_values, Cache):
1557
+ cache_length = past_key_values.get_seq_length()
1558
+ past_length = past_key_values.seen_tokens
1559
+ max_cache_length = past_key_values.get_max_length()
1560
+ else:
1561
+ cache_length = past_length = past_key_values[0][0].shape[2]
1562
+ max_cache_length = None
1563
+
1564
+ # Keep only the unprocessed tokens:
1565
+ # 1 - If the length of the attention_mask exceeds the length of input_ids, then we are in a setting where
1566
+ # some of the inputs are exclusively passed as part of the cache (e.g. when passing input_embeds as
1567
+ # input)
1568
+ if attention_mask is not None and attention_mask.shape[1] > input_ids.shape[1]:
1569
+ input_ids = input_ids[:, -(attention_mask.shape[1] - past_length) :]
1570
+ # 2 - If the past_length is smaller than input_ids', then input_ids holds all input tokens. We can discard
1571
+ # input_ids based on the past_length.
1572
+ elif past_length < input_ids.shape[1]:
1573
+ input_ids = input_ids[:, past_length:]
1574
+ # 3 - Otherwise (past_length >= input_ids.shape[1]), let's assume input_ids only has unprocessed tokens.
1575
+
1576
+ # If we are about to go beyond the maximum cache length, we need to crop the input attention mask.
1577
+ if (
1578
+ max_cache_length is not None
1579
+ and attention_mask is not None
1580
+ and cache_length + input_ids.shape[1] > max_cache_length
1581
+ ):
1582
+ attention_mask = attention_mask[:, -max_cache_length:]
1583
+
1584
+ position_ids = kwargs.get("position_ids", None)
1585
+ if attention_mask is not None and position_ids is None:
1586
+ # create position_ids on the fly for batch generation
1587
+ position_ids = attention_mask.long().cumsum(-1) - 1
1588
+ position_ids.masked_fill_(attention_mask == 0, 1)
1589
+ if past_key_values:
1590
+ position_ids = position_ids[:, -input_ids.shape[1] :]
1591
+
1592
+ # if `inputs_embeds` are passed, we only want to use them in the 1st generation step
1593
+ if inputs_embeds is not None and past_key_values is None:
1594
+ model_inputs = {"inputs_embeds": inputs_embeds}
1595
+ else:
1596
+ model_inputs = {"input_ids": input_ids}
1597
+
1598
+ model_inputs.update(
1599
+ {
1600
+ "position_ids": position_ids,
1601
+ "past_key_values": past_key_values,
1602
+ "use_cache": kwargs.get("use_cache"),
1603
+ "attention_mask": attention_mask,
1604
+ }
1605
+ )
1606
+ return model_inputs
1607
+
1608
+ @staticmethod
1609
+ def _reorder_cache(past_key_values, beam_idx):
1610
+ reordered_past = ()
1611
+ for layer_past in past_key_values:
1612
+ reordered_past += (
1613
+ tuple(past_state.index_select(0, beam_idx.to(past_state.device)) for past_state in layer_past),
1614
+ )
1615
+ return reordered_past
1616
+
1617
+
1618
+ @add_start_docstrings(
1619
+ """
1620
+ The Qwen2 Model transformer with a sequence classification head on top (linear layer).
1621
+
1622
+ [`Qwen2ForSequenceClassification`] uses the last token in order to do the classification, as other causal models
1623
+ (e.g. GPT-2) do.
1624
+
1625
+ Since it does classification on the last token, it requires to know the position of the last token. If a
1626
+ `pad_token_id` is defined in the configuration, it finds the last token that is not a padding token in each row. If
1627
+ no `pad_token_id` is defined, it simply takes the last value in each row of the batch. Since it cannot guess the
1628
+ padding tokens when `inputs_embeds` are passed instead of `input_ids`, it does the same (take the last value in
1629
+ each row of the batch).
1630
+ """,
1631
+ QWEN2_START_DOCSTRING,
1632
+ )
1633
+ class Qwen2ForSequenceClassification(Qwen2PreTrainedModel):
1634
+ def __init__(self, config):
1635
+ super().__init__(config)
1636
+ self.num_labels = config.num_labels
1637
+ self.model = Qwen2Model(config)
1638
+ self.score = nn.Linear(config.hidden_size, self.num_labels, bias=False)
1639
+
1640
+ # Initialize weights and apply final processing
1641
+ self.post_init()
1642
+
1643
+ def get_input_embeddings(self):
1644
+ return self.model.embed_tokens
1645
+
1646
+ def set_input_embeddings(self, value):
1647
+ self.model.embed_tokens = value
1648
+
1649
+ @add_start_docstrings_to_model_forward(QWEN2_INPUTS_DOCSTRING)
1650
+ def forward(
1651
+ self,
1652
+ input_ids: torch.LongTensor = None,
1653
+ attention_mask: Optional[torch.Tensor] = None,
1654
+ position_ids: Optional[torch.LongTensor] = None,
1655
+ past_key_values: Optional[List[torch.FloatTensor]] = None,
1656
+ inputs_embeds: Optional[torch.FloatTensor] = None,
1657
+ labels: Optional[torch.LongTensor] = None,
1658
+ use_cache: Optional[bool] = None,
1659
+ output_attentions: Optional[bool] = None,
1660
+ output_hidden_states: Optional[bool] = None,
1661
+ return_dict: Optional[bool] = None,
1662
+ ) -> Union[Tuple, SequenceClassifierOutputWithPast]:
1663
+ r"""
1664
+ labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
1665
+ Labels for computing the sequence classification/regression loss. Indices should be in `[0, ...,
1666
+ config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
1667
+ `config.num_labels > 1` a classification loss is computed (Cross-Entropy).
1668
+ """
1669
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
1670
+
1671
+ transformer_outputs = self.model(
1672
+ input_ids,
1673
+ attention_mask=attention_mask,
1674
+ position_ids=position_ids,
1675
+ past_key_values=past_key_values,
1676
+ inputs_embeds=inputs_embeds,
1677
+ use_cache=use_cache,
1678
+ output_attentions=output_attentions,
1679
+ output_hidden_states=output_hidden_states,
1680
+ return_dict=return_dict,
1681
+ )
1682
+ hidden_states = transformer_outputs[0]
1683
+ logits = self.score(hidden_states)
1684
+
1685
+ if input_ids is not None:
1686
+ batch_size = input_ids.shape[0]
1687
+ else:
1688
+ batch_size = inputs_embeds.shape[0]
1689
+
1690
+ if self.config.pad_token_id is None and batch_size != 1:
1691
+ raise ValueError("Cannot handle batch sizes > 1 if no padding token is defined.")
1692
+ if self.config.pad_token_id is None:
1693
+ sequence_lengths = -1
1694
+ else:
1695
+ if input_ids is not None:
1696
+ # if no pad token found, use modulo instead of reverse indexing for ONNX compatibility
1697
+ sequence_lengths = torch.eq(input_ids, self.config.pad_token_id).int().argmax(-1) - 1
1698
+ sequence_lengths = sequence_lengths % input_ids.shape[-1]
1699
+ sequence_lengths = sequence_lengths.to(logits.device)
1700
+ else:
1701
+ sequence_lengths = -1
1702
+
1703
+ pooled_logits = logits[torch.arange(batch_size, device=logits.device), sequence_lengths]
1704
+
1705
+ loss = None
1706
+ if labels is not None:
1707
+ labels = labels.to(logits.device)
1708
+ if self.config.problem_type is None:
1709
+ if self.num_labels == 1:
1710
+ self.config.problem_type = "regression"
1711
+ elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int):
1712
+ self.config.problem_type = "single_label_classification"
1713
+ else:
1714
+ self.config.problem_type = "multi_label_classification"
1715
+
1716
+ if self.config.problem_type == "regression":
1717
+ loss_fct = MSELoss()
1718
+ if self.num_labels == 1:
1719
+ loss = loss_fct(pooled_logits.squeeze(), labels.squeeze())
1720
+ else:
1721
+ loss = loss_fct(pooled_logits, labels)
1722
+ elif self.config.problem_type == "single_label_classification":
1723
+ loss_fct = CrossEntropyLoss()
1724
+ loss = loss_fct(pooled_logits.view(-1, self.num_labels), labels.view(-1))
1725
+ elif self.config.problem_type == "multi_label_classification":
1726
+ loss_fct = BCEWithLogitsLoss()
1727
+ loss = loss_fct(pooled_logits, labels)
1728
+ if not return_dict:
1729
+ output = (pooled_logits,) + transformer_outputs[1:]
1730
+ return ((loss,) + output) if loss is not None else output
1731
+
1732
+ return SequenceClassifierOutputWithPast(
1733
+ loss=loss,
1734
+ logits=pooled_logits,
1735
+ past_key_values=transformer_outputs.past_key_values,
1736
+ hidden_states=transformer_outputs.hidden_states,
1737
+ attentions=transformer_outputs.attentions,
1738
+ )
modeling_vit.py ADDED
@@ -0,0 +1,615 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved.
2
+ #
3
+ # NVIDIA CORPORATION and its licensors retain all intellectual property
4
+ # and proprietary rights in and to this software, related documentation
5
+ # and any modifications thereto. Any use, reproduction, disclosure or
6
+ # distribution of this software and related documentation without an express
7
+ # license agreement from NVIDIA CORPORATION is strictly prohibited.
8
+
9
+ import math
10
+ from copy import deepcopy
11
+ from typing import Union, Tuple, Sequence, Optional, List
12
+
13
+ import torch
14
+ import torch.nn as nn
15
+ import torch.nn.functional as F
16
+ try:
17
+ from transformers.activations import PytorchGELUTanh
18
+ except ImportError:
19
+ PytorchGELUTanh = lambda: nn.GELU(approximate='tanh')
20
+ from transformers.modeling_utils import PreTrainedModel
21
+ from transformers.utils import is_flash_attn_2_available, logging
22
+
23
+ if is_flash_attn_2_available():
24
+ from flash_attn import flash_attn_varlen_func
25
+ else:
26
+ flash_attn_varlen_func = None
27
+
28
+ from transformers.configuration_utils import PretrainedConfig
29
+
30
+
31
+ logger = logging.get_logger(__name__)
32
+
33
+
34
+ class MoonViTConfig(PretrainedConfig):
35
+ model_type = "moonvit"
36
+
37
+ def __init__(
38
+ self,
39
+ patch_size: int = 14,
40
+ init_pos_emb_height: int = 64,
41
+ init_pos_emb_width: int = 64,
42
+ num_attention_heads: int = 16,
43
+ num_hidden_layers: int = 27,
44
+ hidden_size: int = 1152,
45
+ intermediate_size: int = 4304,
46
+ merge_kernel_size: tuple[int, int] = (2, 2),
47
+ **kwargs,
48
+ ):
49
+ super().__init__(**kwargs)
50
+ self.patch_size = patch_size
51
+ # Positional embedding config
52
+ self.init_pos_emb_height = init_pos_emb_height
53
+ self.init_pos_emb_width = init_pos_emb_width
54
+ # Transformer config
55
+ self.num_hidden_layers = num_hidden_layers
56
+ self.num_attention_heads = num_attention_heads
57
+ self.hidden_size = hidden_size
58
+ self.intermediate_size = intermediate_size
59
+ # Patch merger config
60
+ self.merge_kernel_size = merge_kernel_size
61
+
62
+
63
+ def multihead_attention(
64
+ q: torch.Tensor,
65
+ k: torch.Tensor,
66
+ v: torch.Tensor,
67
+ q_cu_seqlens: Optional[torch.Tensor] = None,
68
+ k_cu_seqlens: Optional[torch.Tensor] = None,
69
+ ):
70
+ """Multi-head attention using flash attention 2.
71
+
72
+ Args:
73
+ q, k, v: tensor of shape (batch_size, seqlen, num_heads, head_dim),
74
+ or (tot_seqlens, num_heads, head_dim) if packing.
75
+ q_cu_seqlens (torch.Tensor): cumulative sequence lengths of q.
76
+ The first element should be 0 and the last element should be q.shape[0].
77
+ k_cu_seqlens (torch.Tensor): cumulative sequence lengths of k.
78
+ The first element should be 0 and the last element should be k.shape[0].
79
+
80
+ Returns:
81
+ output: shape (batch_size, seqlen, dim) or (tot_seqlens, dim) if packing,
82
+ where dim = num_heads * head_dim
83
+ """
84
+ if flash_attn_varlen_func is None:
85
+ logger.warning_once(
86
+ "flash_attn is not available for MoonViT; falling back to sdpa attention."
87
+ )
88
+ return sdpa_attention(
89
+ q,
90
+ k,
91
+ v,
92
+ q_cu_seqlens=q_cu_seqlens,
93
+ k_cu_seqlens=k_cu_seqlens,
94
+ )
95
+
96
+ # Unified format legal check
97
+ assert q.dim() == k.dim() == v.dim() == 3, "q, k, v must have 3 dims"
98
+ assert q_cu_seqlens[-1] == q.shape[0], "q_cu_seqlens must sum to q.shape[0]"
99
+ assert (
100
+ k_cu_seqlens[-1] == k.shape[0] == v.shape[0]
101
+ ), "k_cu_seqlens must sum to k.shape[0]"
102
+ assert q.dtype in [
103
+ torch.bfloat16,
104
+ torch.float16,
105
+ ], f"unsupported dtype {q.dtype} for multihead attn"
106
+
107
+ max_seqlen_q = (q_cu_seqlens[1:] - q_cu_seqlens[:-1]).max().item()
108
+ max_seqlen_k = (k_cu_seqlens[1:] - k_cu_seqlens[:-1]).max().item()
109
+ attn_out = flash_attn_varlen_func(
110
+ q,
111
+ k,
112
+ v,
113
+ q_cu_seqlens,
114
+ k_cu_seqlens,
115
+ max_seqlen_q,
116
+ max_seqlen_k,
117
+ causal=False,
118
+ )
119
+ attn_out = attn_out.flatten(start_dim=-2)
120
+
121
+ return attn_out
122
+
123
+
124
+ def sdpa_attention(
125
+ q: torch.Tensor,
126
+ k: torch.Tensor,
127
+ v: torch.Tensor,
128
+ q_cu_seqlens: Optional[torch.Tensor] = None,
129
+ k_cu_seqlens: Optional[torch.Tensor] = None,
130
+ ) -> torch.Tensor:
131
+ """SDPA attention.
132
+
133
+ Args:
134
+ q, k, v: tensor of shape (batch_size, seqlen, num_heads, head_dim),
135
+ or (tot_seqlens, num_heads, head_dim) if packing.
136
+ """
137
+ seq_length = q.shape[0]
138
+ attention_mask = torch.zeros(
139
+ [1, seq_length, seq_length], device=q.device, dtype=torch.bool
140
+ )
141
+ for i in range(1, len(q_cu_seqlens)):
142
+ attention_mask[
143
+ ...,
144
+ q_cu_seqlens[i - 1] : q_cu_seqlens[i],
145
+ q_cu_seqlens[i - 1] : q_cu_seqlens[i],
146
+ ] = True
147
+ q = q.transpose(0, 1)
148
+ k = k.transpose(0, 1)
149
+ v = v.transpose(0, 1)
150
+ attn_output = F.scaled_dot_product_attention(q, k, v, attention_mask, dropout_p=0.0)
151
+ attn_output = attn_output.transpose(0, 1)
152
+ attn_output = attn_output.reshape(seq_length, -1)
153
+ return attn_output
154
+
155
+
156
+ def eager_attention(
157
+ q: torch.Tensor,
158
+ k: torch.Tensor,
159
+ v: torch.Tensor,
160
+ q_cu_seqlens: Optional[torch.Tensor] = None,
161
+ k_cu_seqlens: Optional[torch.Tensor] = None,
162
+ ) -> torch.Tensor:
163
+ seq_length = q.shape[0]
164
+ attention_mask = torch.zeros(
165
+ [1, seq_length, seq_length], device=q.device, dtype=torch.bool
166
+ )
167
+ for i in range(1, len(q_cu_seqlens)):
168
+ attention_mask[
169
+ ...,
170
+ q_cu_seqlens[i - 1] : q_cu_seqlens[i],
171
+ q_cu_seqlens[i - 1] : q_cu_seqlens[i],
172
+ ] = True
173
+ q = q.transpose(0, 1)
174
+ k = k.transpose(0, 1)
175
+ v = v.transpose(0, 1)
176
+
177
+ attn_weight = q @ k.transpose(-2, -1) / math.sqrt(q.shape[-1])
178
+ attn_weight += attention_mask
179
+ attn_weight = torch.softmax(attn_weight, dim=-1, dtype=torch.float32).to(q.dtype)
180
+
181
+ attn_output = attn_weight @ v
182
+ attn_output = attn_output.transpose(0, 1)
183
+ attn_output = attn_output.reshape(seq_length, -1)
184
+ return attn_output
185
+
186
+
187
+ VL_VISION_ATTENTION_FUNCTIONS = {
188
+ "flash_attention_2": multihead_attention,
189
+ "sdpa": sdpa_attention,
190
+ "eager": eager_attention,
191
+ }
192
+
193
+
194
+ def _apply_rope_input_validation(x, freqs_cis):
195
+ assert x.ndim == freqs_cis.ndim + 1, (x.shape, freqs_cis.shape)
196
+ assert x.shape[:-2] == freqs_cis.shape[:-1], (x.shape, freqs_cis.shape)
197
+ assert x.shape[-1] == 2 * freqs_cis.shape[-1], (x.shape, freqs_cis.shape)
198
+ assert freqs_cis.dtype == torch.complex64, freqs_cis.dtype
199
+
200
+
201
+ def apply_rope(
202
+ xq: torch.Tensor, xk: torch.Tensor, freqs_cis: torch.Tensor
203
+ ) -> tuple[torch.Tensor, torch.Tensor]:
204
+ """
205
+ Args: (The leading dimensions of all inputs should be the same)
206
+ xq: query, tensor of shape (..., num_heads, head_dim)
207
+ xk: key, tensor of shape (..., num_heads, head_dim)
208
+ freqs_cis: tensor of shape (..., head_dim/2), dtype=torch.complex64. It contains the precomputed cis(freqs) for each position in the 2D grid.
209
+ Returns:
210
+ xq_out, xk_out: tensors of shape (..., num_heads, head_dim)
211
+ """
212
+ _apply_rope_input_validation(xq, freqs_cis)
213
+ _apply_rope_input_validation(xk, freqs_cis)
214
+
215
+ freqs_cis = freqs_cis.unsqueeze(-2) # ..., 1, head_dim/2
216
+ # ..., num_heads, head_dim/2
217
+ xq_ = torch.view_as_complex(xq.float().view(*xq.shape[:-1], -1, 2))
218
+ xk_ = torch.view_as_complex(xk.float().view(*xq.shape[:-1], -1, 2))
219
+ xq_out = torch.view_as_real(xq_ * freqs_cis).flatten(-2) # ..., num_heads, head_dim
220
+ xk_out = torch.view_as_real(xk_ * freqs_cis).flatten(-2) # ..., num_heads, head_dim
221
+ return xq_out.type_as(xq), xk_out.type_as(xk)
222
+
223
+
224
+ class Learnable2DInterpPosEmb(nn.Module):
225
+ def __init__(
226
+ self, height: int, width: int, dim: int, interpolation_mode: str = "bicubic"
227
+ ) -> None:
228
+ super().__init__()
229
+ self.height = height
230
+ self.width = width
231
+ self.interpolation_mode = interpolation_mode
232
+ self.weight = nn.Parameter(torch.empty(height, width, dim))
233
+ self.reset_parameters()
234
+
235
+ def reset_parameters(self):
236
+ nn.init.normal_(self.weight)
237
+
238
+ def forward(self, x: torch.Tensor, grid_hws: torch.Tensor) -> torch.Tensor:
239
+ pos_embs = []
240
+ for shape in grid_hws.tolist():
241
+ if shape == self.weight.shape[:-1]:
242
+ pos_embs.append(self.weight.flatten(end_dim=1))
243
+ else:
244
+ pos_embs.append(
245
+ F.interpolate(
246
+ self.weight.permute((2, 0, 1)).unsqueeze(0),
247
+ size=shape,
248
+ mode=self.interpolation_mode,
249
+ )
250
+ .squeeze(0)
251
+ .permute((1, 2, 0))
252
+ .flatten(end_dim=1)
253
+ )
254
+ out = x + torch.cat(pos_embs)
255
+ return out
256
+
257
+
258
+ class MoonVisionPatchEmbed(nn.Module):
259
+
260
+ def __init__(
261
+ self,
262
+ out_dim: int,
263
+ in_dim: int = 3,
264
+ patch_size: Union[int, Tuple[int, int]] = (14, 14),
265
+ pos_emb_height: int = 14,
266
+ pos_emb_width: int = 14,
267
+ ):
268
+ super().__init__()
269
+ assert isinstance(
270
+ patch_size, (int, Sequence)
271
+ ), f"Invalid patch_size type: {type(patch_size)}"
272
+ if isinstance(patch_size, int):
273
+ patch_size = (patch_size, patch_size)
274
+ assert (
275
+ len(patch_size) == 2
276
+ ), f"Expected patch_size to be a tuple of 2, got {patch_size}"
277
+ self.patch_size = patch_size
278
+
279
+ self.proj = nn.Conv2d(
280
+ in_dim, out_dim, kernel_size=patch_size, stride=patch_size
281
+ )
282
+
283
+ self.pos_emb = Learnable2DInterpPosEmb(
284
+ height=pos_emb_height, width=pos_emb_width, dim=out_dim
285
+ )
286
+
287
+ def forward(self, x: torch.Tensor, grid_hws: torch.Tensor) -> torch.Tensor:
288
+ """
289
+ Args:
290
+ x (L, Channels): input tensor
291
+ grid_hws (N, 2): grid height and width
292
+
293
+ Returns:
294
+ (L, Cout) tensor
295
+ """
296
+ x = self.proj(x).view(x.size(0), -1)
297
+ # apply positional embedding
298
+ x = self.pos_emb(x, grid_hws)
299
+ return x
300
+
301
+
302
+ class Rope2DPosEmb(nn.Module):
303
+ """2D rotary position embedding with multi-resolution support.
304
+
305
+ This class is intended to be used in the following way:
306
+ 1. Before training, create an instance of Rope2DPosEmb. This instance will hold the precomputed cis.
307
+ 2. Before each forward pass, call `get_freqs_cis_by_*` to get the `freqs_cis` tensor for this iteration.
308
+ 3. During the forward pass, pass the `freqs_cis` tensor to each attention layer, and call `apply` just before each attention operation.
309
+ The rope is shared across all attention layers and all heads.
310
+
311
+ Refs:
312
+ - RoFormer: https://arxiv.org/abs/2104.09864
313
+ - VisionLLaMA: https://arxiv.org/abs/2403.00522
314
+ - https://github.com/Meituan-AutoML/VisionLLaMA/blob/main/dit/models.py
315
+
316
+ Args:
317
+ dim (int): usually the multi-head attention dimension, should be divisible by 4 (TODO: relax this constraint if needed)
318
+ max_height (int): the maximum height of the 2D grid
319
+ max_width (int): the maximum width of the 2D grid
320
+ theta_base (float): the base of the theta
321
+ device (str): the device to store the precomputed cis
322
+ """
323
+
324
+ def __init__(self, dim: int, max_height: int, max_width: int, theta_base=10000):
325
+ super().__init__()
326
+ self.dim = dim
327
+ assert self.dim % 4 == 0, "dim must be divisible by 4"
328
+ self.max_height = max_height
329
+ self.max_width = max_width
330
+ self.theta_base = theta_base
331
+
332
+ self.freqs_cis = None
333
+
334
+ def extra_repr(self):
335
+ return f"dim={self.dim}, max_height={self.max_height}, max_width={self.max_width}, theta_base={self.theta_base}"
336
+
337
+ def _precompute_freqs_cis(self, device: torch.device) -> torch.Tensor:
338
+ """Calculate the cis(freqs) for each position in the 2D grid.
339
+
340
+ Return: complex tensor of shape (max_height, max_width, dim//2) and value:
341
+ height axis: ret[h, w, 2*i] = cis(h * theta_base**(-4*i/dim))
342
+ weight axis: ret[h, w, 2*i+1] = cis(w * theta_base**(-4*i/dim)) with (i in [0, dim//4))
343
+ note: `cis` is a mathematical notation defined by cis x = cos x + i sin x,
344
+ """
345
+ N = self.max_height * self.max_width
346
+ flat_pos = torch.arange(0, N).float().to(device)
347
+ x_pos = flat_pos % self.max_width
348
+ y_pos = flat_pos // self.max_width
349
+ dim_range = (
350
+ torch.arange(0, self.dim, 4)[: (self.dim // 4)].float().to(device)
351
+ ) # C/4
352
+ freqs = 1.0 / (self.theta_base ** (dim_range / self.dim))
353
+ x_freqs = torch.outer(x_pos, freqs).float() # N, C/4
354
+ y_freqs = torch.outer(y_pos, freqs).float() # N, C/4
355
+ x_cis = torch.polar(torch.ones_like(x_freqs), x_freqs) # N, C/4
356
+ y_cis = torch.polar(torch.ones_like(y_freqs), y_freqs) # N, C/4
357
+ # N, C/4, 2
358
+ freqs_cis = torch.cat(
359
+ [x_cis.unsqueeze(dim=-1), y_cis.unsqueeze(dim=-1)], dim=-1
360
+ )
361
+ # max_height, max_width, C/2
362
+ freqs_cis = freqs_cis.reshape(self.max_height, self.max_width, -1)
363
+ return freqs_cis
364
+
365
+ def get_freqs_cis(self, grid_hws: torch.Tensor) -> torch.Tensor:
366
+ """
367
+ Args:
368
+ grid_hws (torch.Tensor): grid height and width
369
+
370
+ Returns:
371
+ freqs_cis: tensor of shape (sum(t * height * width), dim//2)
372
+ """
373
+ if self.freqs_cis is None:
374
+ self.freqs_cis = self._precompute_freqs_cis(grid_hws.device)
375
+
376
+ shapes = grid_hws.tolist()
377
+ assert all(
378
+ 1 <= h <= self.max_height and 1 <= w <= self.max_width for h, w in shapes
379
+ ), (
380
+ shapes,
381
+ self.max_height,
382
+ self.max_width,
383
+ )
384
+ freqs_cis = torch.cat(
385
+ [self.freqs_cis[:h, :w].reshape(-1, self.dim // 2) for h, w in shapes],
386
+ dim=0,
387
+ )
388
+ return freqs_cis
389
+
390
+
391
+ class MLP2(nn.Module):
392
+ """
393
+ Args:
394
+ dims: [in_dim, hidden_dim, out_dim]
395
+ bias: whether to use bias in linear layer.
396
+ """
397
+
398
+ def __init__(self, dims: list[int], activation, bias=True):
399
+ super().__init__()
400
+ assert len(dims) == 3
401
+ self.fc0 = nn.Linear(dims[0], dims[1], bias=bias)
402
+ self.fc1 = nn.Linear(dims[1], dims[2], bias=bias)
403
+ self.activation = activation
404
+ for m in [self.fc0, self.fc1]:
405
+ nn.init.trunc_normal_(m.weight, std=math.sqrt(2 / m.in_features))
406
+ if m.bias is not None:
407
+ nn.init.zeros_(m.bias)
408
+
409
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
410
+ x = self.fc0(x)
411
+ x = self.activation(x)
412
+ return self.fc1(x)
413
+
414
+
415
+ class MoonVitEncoderLayer(nn.Module):
416
+
417
+ def __init__(
418
+ self,
419
+ num_heads: int,
420
+ hidden_dim: int,
421
+ mlp_dim: int,
422
+ *,
423
+ attn_implementation: str = "eager",
424
+ activation=F.gelu,
425
+ attn_bias: bool = False,
426
+ ):
427
+ super().__init__()
428
+ self.num_heads = num_heads
429
+ self.hidden_dim = hidden_dim
430
+ self.hidden_size_per_attention_head = self.hidden_dim // self.num_heads
431
+ self.attn_implementation = attn_implementation
432
+
433
+ self.norm0 = nn.LayerNorm(hidden_dim)
434
+ self.norm1 = nn.LayerNorm(hidden_dim)
435
+ self.mlp = MLP2([hidden_dim, mlp_dim, hidden_dim], activation)
436
+ self.wqkv = nn.Linear(hidden_dim, hidden_dim * 3, bias=attn_bias)
437
+ self.wo = nn.Linear(hidden_dim, hidden_dim, bias=attn_bias)
438
+
439
+ def attention_qkvpacked(
440
+ self,
441
+ x: torch.Tensor,
442
+ cu_seqlens: torch.Tensor,
443
+ rope_freqs_cis: Optional[torch.Tensor] = None,
444
+ ):
445
+ """
446
+ Args:
447
+ x (torch.Tensor): (batch_size, seqlen, hidden_dim)
448
+ cu_seqlens (torch.Tensor):
449
+ """
450
+ xqkv = self.wqkv(x)
451
+
452
+ qkv_shape = xqkv.size()[:-1] + (
453
+ 3,
454
+ self.num_heads,
455
+ self.hidden_size_per_attention_head,
456
+ )
457
+ # xqkv: (batch_size, seqlen, 3, nheads, headdim)
458
+ xqkv = xqkv.view(*qkv_shape)
459
+ xq, xk, xv = torch.unbind(xqkv, dim=-3)
460
+
461
+ xq, xk = apply_rope(xq, xk, rope_freqs_cis)
462
+
463
+ attn_func = VL_VISION_ATTENTION_FUNCTIONS[self.attn_implementation]
464
+ attn_out = attn_func(
465
+ xq, xk, xv, q_cu_seqlens=cu_seqlens, k_cu_seqlens=cu_seqlens
466
+ )
467
+
468
+ attn_out = self.wo(attn_out)
469
+ return attn_out
470
+
471
+ def forward(
472
+ self,
473
+ hidden_states: torch.Tensor,
474
+ cu_seqlens: torch.Tensor,
475
+ rope_freqs_cis: Union[torch.Tensor, None] = None,
476
+ ) -> torch.Tensor:
477
+ """
478
+ Args:
479
+ hidden_states: non-packed (B, N, D) or packed (L, D). if non-packed, seqlens should be None, if packed, seqlens should be set
480
+
481
+ Returns:
482
+ output: same shape of input, non-packed (B, N, D) for non-packed input, (L, D) for packed input
483
+ """
484
+ residual = hidden_states
485
+ hidden_states = self.norm0(hidden_states)
486
+ attn_out = self.attention_qkvpacked(
487
+ hidden_states, cu_seqlens, rope_freqs_cis=rope_freqs_cis
488
+ )
489
+ hidden_states = residual + attn_out
490
+
491
+ residual = hidden_states
492
+ hidden_states = self.mlp(self.norm1(hidden_states))
493
+ hidden_states = residual + hidden_states
494
+ return hidden_states
495
+
496
+
497
+ class MoonVitEncoder(nn.Module):
498
+
499
+ def __init__(
500
+ self,
501
+ hidden_dim: int,
502
+ num_layers: int,
503
+ block_cfg: dict,
504
+ ) -> None:
505
+ super().__init__()
506
+
507
+ self.rope_2d = Rope2DPosEmb(
508
+ block_cfg["hidden_dim"] // block_cfg["num_heads"], 512, 512
509
+ )
510
+ self.blocks = nn.ModuleList(
511
+ [MoonVitEncoderLayer(**block_cfg) for _ in range(num_layers)]
512
+ )
513
+ self.final_layernorm = nn.LayerNorm(hidden_dim)
514
+
515
+ def forward(
516
+ self, hidden_states: torch.Tensor, grid_hws: torch.Tensor
517
+ ) -> torch.Tensor:
518
+ rope_freqs_cis = self.rope_2d.get_freqs_cis(grid_hws=grid_hws)
519
+
520
+ lengths = torch.cat(
521
+ (
522
+ torch.zeros(1, device=hidden_states.device, dtype=grid_hws.dtype),
523
+ grid_hws[:, 0] * grid_hws[:, 1],
524
+ )
525
+ )
526
+ cu_seqlens = lengths.cumsum(dim=0, dtype=torch.int32)
527
+
528
+ for _, block in enumerate(self.blocks):
529
+ hidden_states = block(
530
+ hidden_states, cu_seqlens, rope_freqs_cis=rope_freqs_cis
531
+ )
532
+
533
+ hidden_states = self.final_layernorm(hidden_states)
534
+
535
+ return hidden_states
536
+
537
+
538
+ def patch_merger(
539
+ x: torch.Tensor,
540
+ grid_hws: torch.Tensor,
541
+ merge_kernel_size: list[int, int] = (2, 2),
542
+ ) -> List[torch.Tensor]:
543
+ d_model = x.size(-1)
544
+
545
+ outputs = []
546
+ pre_sum = 0
547
+ for x_shape in grid_hws.tolist():
548
+ height, width = x_shape[0], x_shape[1]
549
+ # Get the current sequence
550
+ seq = x[pre_sum : pre_sum + height * width]
551
+ # Reshape along self.merge_kernel_size and concat to the last dimension
552
+ kernel_height, kernel_width = merge_kernel_size
553
+ new_height, new_width = height // kernel_height, width // kernel_width
554
+ reshaped_seq = seq.view(
555
+ new_height, kernel_height, new_width, kernel_width, d_model
556
+ )
557
+ reshaped_seq = reshaped_seq.permute(0, 2, 1, 3, 4).contiguous()
558
+ padded_seq = reshaped_seq.view(
559
+ new_height * new_width, -1
560
+ )
561
+ outputs.append(padded_seq)
562
+ pre_sum += height * width
563
+
564
+ return outputs
565
+
566
+
567
+ class MoonVitPretrainedModel(PreTrainedModel):
568
+ config_class = MoonViTConfig
569
+ model_type = "moonvit"
570
+ _no_split_modules = ["PackingTransformer"]
571
+ _supports_flash_attn_2 = True
572
+ _supports_sdpa = True
573
+
574
+ def __init__(self, config: MoonViTConfig, *inputs, **kwargs):
575
+ super().__init__(config, *inputs, **kwargs)
576
+ config = deepcopy(config)
577
+ self.merge_kernel_size = config.merge_kernel_size
578
+ self.patch_size = config.patch_size
579
+ self.patch_embed = MoonVisionPatchEmbed(
580
+ out_dim=config.hidden_size,
581
+ patch_size=config.patch_size,
582
+ pos_emb_height=config.init_pos_emb_height,
583
+ pos_emb_width=config.init_pos_emb_width,
584
+ )
585
+
586
+ self.encoder = MoonVitEncoder(
587
+ hidden_dim=config.hidden_size,
588
+ num_layers=config.num_hidden_layers,
589
+ block_cfg={
590
+ "num_heads": config.num_attention_heads,
591
+ "hidden_dim": config.hidden_size,
592
+ "mlp_dim": config.intermediate_size,
593
+ "activation": PytorchGELUTanh(),
594
+ "attn_bias": True,
595
+ "attn_implementation": config._attn_implementation,
596
+ },
597
+ )
598
+
599
+ def forward(
600
+ self, pixel_values: torch.Tensor, grid_hws: torch.Tensor
601
+ ) -> torch.Tensor:
602
+ """
603
+ Args:
604
+ pixel_values (torch.Tensor): The input pixel values.
605
+ grid_hws (torch.Tensor): The grid height and width.
606
+
607
+ Returns:
608
+ torch.Tensor: The output tokens.
609
+ """
610
+ hidden_states = self.patch_embed(pixel_values, grid_hws)
611
+ hidden_states = self.encoder(hidden_states, grid_hws)
612
+ hidden_states = patch_merger(
613
+ hidden_states, grid_hws, merge_kernel_size=self.merge_kernel_size
614
+ )
615
+ return hidden_states
preprocessor_config.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "auto_map": {
3
+ "AutoImageProcessor": "image_processing_locateanything.LocateAnythingImageProcessor",
4
+ "AutoProcessor": "processing_locateanything.LocateAnythingProcessor"
5
+ },
6
+ "image_mean": [
7
+ 0.5,
8
+ 0.5,
9
+ 0.5
10
+ ],
11
+ "image_processor_type": "LocateAnythingImageProcessor",
12
+ "image_std": [
13
+ 0.5,
14
+ 0.5,
15
+ 0.5
16
+ ],
17
+ "in_token_limit": 25600,
18
+ "merge_kernel_size": [
19
+ 2,
20
+ 2
21
+ ],
22
+ "patch_size": 14,
23
+ "processor_class": "LocateAnythingProcessor"
24
+ }
processing_locateanything.py ADDED
@@ -0,0 +1,678 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding=utf-8
2
+ # Copyright 2024 The HuggingFace Inc. team.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ """
16
+ Processor class for LocateAnything.
17
+ """
18
+
19
+ import math
20
+ import os
21
+ from typing import Iterable, List, Union, Literal
22
+ import base64
23
+ import sys
24
+ import time
25
+ import warnings
26
+ from functools import lru_cache
27
+ from io import BytesIO
28
+ import re
29
+ import requests
30
+ import torch
31
+ import torchvision
32
+ from packaging import version
33
+ from PIL import Image
34
+ from torchvision import io
35
+ from torchvision import transforms
36
+ from torchvision.transforms import InterpolationMode
37
+ from typing import Optional, Any
38
+ import numpy as np
39
+
40
+ from transformers.feature_extraction_utils import BatchFeature
41
+ from transformers.image_utils import ImageInput
42
+ try:
43
+ from transformers.image_utils import VideoInput
44
+ except ImportError:
45
+ VideoInput = None
46
+ from transformers.processing_utils import ProcessingKwargs, ProcessorMixin, Unpack
47
+ from transformers.tokenization_utils_base import PreTokenizedInput, TextInput
48
+ from transformers.utils import logging
49
+ import lmdb
50
+ import cv2
51
+ import pickle
52
+ import decord
53
+
54
+ logger = logging.get_logger(__name__)
55
+
56
+ FPS = 2.0
57
+ MAX_FRAMES = 64
58
+ VIDEO_TOTAL_PIXELS = int(float(os.environ.get('VIDEO_MAX_PIXELS', 32000 * 28 * 28 * 0.9)))
59
+ logger.info(f"set VIDEO_TOTAL_PIXELS: {VIDEO_TOTAL_PIXELS}")
60
+
61
+
62
+ def to_rgb(pil_image: Image.Image) -> Image.Image:
63
+ if pil_image.mode == 'RGBA':
64
+ white_background = Image.new("RGB", pil_image.size, (255, 255, 255))
65
+ white_background.paste(pil_image, mask=pil_image.split()[3]) # Use alpha channel as mask
66
+ return white_background
67
+ else:
68
+ return pil_image.convert("RGB")
69
+
70
+ def read_img_from_lmdb_v2(image_data):
71
+ # special case for AgiBotWorld
72
+ lmdb_file, lmdb_key = image_data['lmdb_file'], image_data['lmdb_key']
73
+ key = lmdb_key.encode('ascii')
74
+ env = lmdb.open(lmdb_file, max_readers=10240, readonly=True, lock=False, readahead=False, meminit=False)
75
+ txn = env.begin()
76
+ value = txn.get(key)
77
+ if value is None:
78
+ print(f"Warning: Key {key} not found.")
79
+ return None
80
+ record = pickle.loads(value)
81
+ image_bgr = cv2.imdecode(np.frombuffer(record['image'], dtype=np.uint8), cv2.IMREAD_COLOR)
82
+ image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)
83
+ image = Image.fromarray(image_rgb)
84
+
85
+ return image
86
+
87
+ def parse_lmdb_image_data(image_data):
88
+ lmdb_file = image_data['lmdb_file']
89
+ if not os.path.exists(lmdb_file):
90
+ if "/home/zhidingy/workspace/libs/eagle/Eagle2/" in lmdb_file:
91
+ image_data['lmdb_file'] = lmdb_file.replace("/home/zhidingy/workspace/libs/eagle/Eagle2/", "")
92
+ else:
93
+ raise ValueError(f"LMDB file {lmdb_file} does not exist")
94
+ # special case for AgiBotWorld
95
+ if 'AgiBotWorld' in image_data['lmdb_file']:
96
+ return read_img_from_lmdb_v2(image_data)
97
+
98
+ try:
99
+ env = lmdb.open(image_data['lmdb_file'], readonly=True, lock=False, max_readers=10240)
100
+ except Exception as e:
101
+ print(f"Failed to open lmdb file {image_data['lmdb_file']}. Error message: {e}", flush=True)
102
+ raise e
103
+
104
+ with env.begin(write=False) as txn:
105
+ try:
106
+ image_bin = txn.get(image_data['lmdb_key'].encode('ascii'))
107
+ buf = BytesIO(image_bin)
108
+ except Exception as e:
109
+ print(f"Failed to get image from lmdb file {image_data['lmdb_file']}. Error message: {e}", flush=True)
110
+ raise e
111
+ try:
112
+ image = Image.open(buf)
113
+ except Exception as e:
114
+ image_np = np.frombuffer(image_bin, dtype=np.uint8)
115
+ image_bgr = cv2.imdecode(image_np, cv2.IMREAD_COLOR)
116
+ image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)
117
+ image = Image.fromarray(image_rgb)
118
+ return image
119
+
120
+ def fetch_image(ele: dict[str, str | Image.Image]) -> Image.Image:
121
+ if "image" in ele:
122
+ image = ele["image"]
123
+ else:
124
+ image = ele["image_url"]
125
+ image_obj = None
126
+ if isinstance(image, Image.Image):
127
+ image_obj = image
128
+ elif isinstance(image, dict) and 'lmdb_file' in image:
129
+ image_obj = parse_lmdb_image_data(image)
130
+ elif image.startswith("http://") or image.startswith("https://"):
131
+ response = requests.get(image, stream=True)
132
+ image_obj = Image.open(BytesIO(response.content))
133
+ elif image.startswith("file://"):
134
+ image_obj = Image.open(image[7:])
135
+ elif image.startswith("data:image"):
136
+ if "base64," in image:
137
+ _, base64_data = image.split("base64,", 1)
138
+ data = base64.b64decode(base64_data)
139
+ image_obj = Image.open(BytesIO(data))
140
+ else:
141
+ image_obj = Image.open(image)
142
+ if image_obj is None:
143
+ raise ValueError(f"Unrecognized image input, support local path, http url, base64 and PIL.Image, got {image}")
144
+ image = to_rgb(image_obj)
145
+
146
+ return image
147
+
148
+
149
+ def get_video_frame_indices(
150
+ ele: dict,
151
+ total_frames: int,
152
+ video_fps: int | float,
153
+ ) -> tuple[torch.Tensor, float]:
154
+ target_fps = ele.get("fps", FPS)
155
+ max_frames = ele.get("max_frames", MAX_FRAMES)
156
+
157
+ nframes = (total_frames / video_fps) * target_fps
158
+ nframes = int(round(nframes))
159
+ nframes = max(1, nframes)
160
+
161
+ if nframes > max_frames:
162
+ nframes = max_frames
163
+
164
+ nframes = min(nframes, total_frames)
165
+
166
+ if nframes == total_frames:
167
+ idx = torch.arange(total_frames).long()
168
+ else:
169
+ idx = torch.linspace(0, total_frames - 1, nframes).round().long()
170
+
171
+ sample_fps = nframes / max(total_frames, 1e-6) * video_fps
172
+
173
+ return idx, sample_fps
174
+
175
+ def _read_video_torchvision(
176
+ ele: dict,
177
+ ) -> (torch.Tensor, float, list):
178
+ """read video using torchvision.io.read_video and return also per-frame timestamps"""
179
+ video_path = ele["video"]
180
+ if version.parse(torchvision.__version__) < version.parse("0.19.0"):
181
+ if "http://" in video_path or "https://" in video_path:
182
+ warnings.warn("torchvision < 0.19.0 does not support http/https video path, please upgrade to 0.19.0.")
183
+ if "file://" in video_path:
184
+ video_path = video_path[7:]
185
+ st = time.time()
186
+
187
+ video, audio, info = io.read_video(
188
+ video_path,
189
+ start_pts=ele.get("video_start", 0.0),
190
+ end_pts=ele.get("video_end", None),
191
+ pts_unit="sec",
192
+ output_format="TCHW",
193
+ )
194
+ total_frames, video_fps = video.size(0), info["video_fps"]
195
+ logger.info(f"torchvision: {video_path=}, {total_frames=}, {video_fps=}, time={time.time() - st:.3f}s")
196
+
197
+ idx, sample_fps = get_video_frame_indices(ele, total_frames, video_fps)
198
+
199
+ start_time = ele.get("video_start", 0.0)
200
+ timestamps = (start_time + idx.to(torch.float32) / video_fps).tolist()
201
+
202
+ video = video[idx]
203
+ return video, sample_fps, timestamps
204
+
205
+
206
+ def is_decord_available() -> bool:
207
+ import importlib.util
208
+ return importlib.util.find_spec("decord") is not None
209
+
210
+ def _read_video_decord(
211
+ ele: dict,
212
+ ) -> (torch.Tensor, float, list):
213
+ """read video using decord.VideoReader and return also per-frame timestamps"""
214
+ video_path = ele["video"]
215
+ st = time.time()
216
+ vr = decord.VideoReader(video_path)
217
+
218
+ total_frames, video_fps = len(vr), vr.get_avg_fps()
219
+ logger.info(f"decord: {video_path=}, {total_frames=}, {video_fps=}, time={time.time() - st:.3f}s")
220
+
221
+ idx_tensor, sample_fps = get_video_frame_indices(ele, total_frames, video_fps)
222
+ idx = idx_tensor.tolist()
223
+
224
+ start_time = ele.get("video_start", 0.0)
225
+ timestamps = [start_time + i / video_fps for i in idx]
226
+
227
+ video = vr.get_batch(idx).asnumpy()
228
+ video = torch.tensor(video).permute(0, 3, 1, 2) # Convert to TCHW format
229
+
230
+ return video, sample_fps, timestamps
231
+
232
+
233
+ VIDEO_READER_BACKENDS = {
234
+ "decord": _read_video_decord,
235
+ "torchvision": _read_video_torchvision,
236
+ }
237
+
238
+
239
+ @lru_cache(maxsize=1)
240
+ def get_video_reader_backend() -> str:
241
+ if is_decord_available():
242
+ video_reader_backend = "decord"
243
+ else:
244
+ video_reader_backend = "torchvision"
245
+ return video_reader_backend
246
+
247
+
248
+ def fetch_video(ele: dict, return_video_sample_fps: bool = False, video_reader_backend: str = "torchvision") -> torch.Tensor | list[Image.Image]:
249
+ """
250
+ Fetches video, samples frames, resizes based on video_total_pixels, and returns as Tensor (TCHW).
251
+ """
252
+ if isinstance(ele["video"], str):
253
+ video_reader_backend = video_reader_backend if video_reader_backend is not None else get_video_reader_backend()
254
+ try:
255
+ video, sample_fps, timestamps = VIDEO_READER_BACKENDS[video_reader_backend](ele)
256
+ except Exception as e:
257
+ logger.warning(f"video_reader_backend {video_reader_backend} error, use torchvision as default, msg: {e}")
258
+ video, sample_fps, timestamps = VIDEO_READER_BACKENDS["torchvision"](ele)
259
+
260
+ nframes, _, height, width = video.shape
261
+
262
+ video_total_pixels = ele.get("video_total_pixels", VIDEO_TOTAL_PIXELS)
263
+ current_pixels = nframes * height * width
264
+
265
+ if current_pixels > video_total_pixels:
266
+ scale_factor = math.sqrt(video_total_pixels / current_pixels)
267
+ new_height = int(height * scale_factor)
268
+ new_width = int(width * scale_factor)
269
+
270
+ video = transforms.functional.resize(
271
+ video,
272
+ [new_height, new_width],
273
+ interpolation=InterpolationMode.BICUBIC,
274
+ antialias=True,
275
+ ).float()
276
+ else:
277
+ video = video.float()
278
+
279
+ if return_video_sample_fps:
280
+ return video, sample_fps, timestamps
281
+ return video
282
+
283
+ else:
284
+ assert isinstance(ele["video"], (list, tuple))
285
+ process_info = ele.copy()
286
+ process_info.pop("type", None)
287
+ process_info.pop("video", None)
288
+
289
+ images = [
290
+ fetch_image({"image": video_element, **process_info})
291
+ for video_element in ele["video"]
292
+ ]
293
+
294
+ nframes = len(images)
295
+ timestamps = [-1 for i in range(nframes)]
296
+
297
+ # For list of images, we return list of PIL images directly,
298
+ # the processor will handle conversion to tensor later.
299
+ if return_video_sample_fps:
300
+ return images, process_info.get("fps", 2.0), timestamps
301
+ return images
302
+
303
+ class LocateAnythingProcessorKwargs(ProcessingKwargs, total=False):
304
+ _defaults = {
305
+ "text_kwargs": {
306
+ "padding": False,
307
+ },
308
+ "images_kwargs": {},
309
+ "videos_kwargs": {},
310
+ }
311
+
312
+
313
+ class LocateAnythingProcessor(ProcessorMixin):
314
+ attributes = ["image_processor", "tokenizer"]
315
+ valid_kwargs = [
316
+ "chat_template",
317
+ "num_image_tokens",
318
+ "image_token",
319
+ "video_token",
320
+ "images_kwargs",
321
+ "videos_kwargs",
322
+ "text_kwargs",
323
+ ]
324
+ image_processor_class = "AutoImageProcessor"
325
+ tokenizer_class = "AutoTokenizer"
326
+
327
+ def __init__(
328
+ self,
329
+ image_processor=None,
330
+ tokenizer=None,
331
+ chat_template=None,
332
+ image_token='<IMG_CONTEXT>',
333
+ video_token='<IMG_CONTEXT>',
334
+ merge_kernel_size=[2, 2], # Note: This might need adjustment based on your patch_size (14*14)
335
+ image_placeholder='image',
336
+ video_placeholder='video',
337
+ image_start_token='<img>',
338
+ image_end_token='</img>',
339
+ **kwargs,
340
+ ):
341
+ self.image_token = tokenizer.image_token if hasattr(tokenizer, "image_token") else image_token
342
+ self.video_token = tokenizer.video_token if hasattr(tokenizer, "video_token") else video_token
343
+ self.image_token_id = (
344
+ tokenizer.image_token_id
345
+ if getattr(tokenizer, "image_token_id", None)
346
+ else tokenizer.convert_tokens_to_ids(self.image_token)
347
+ )
348
+ self.video_token_id = (
349
+ tokenizer.video_token_id
350
+ if getattr(tokenizer, "video_token_id", None)
351
+ else tokenizer.convert_tokens_to_ids(self.video_token)
352
+ )
353
+ self.image_placeholder = image_placeholder
354
+ self.video_placeholder = video_placeholder
355
+ self.merge_kernel_size = merge_kernel_size
356
+ self.image_start_token = image_start_token
357
+ self.image_end_token = image_end_token
358
+ if 'auto_map' in kwargs:
359
+ self.auto_map = kwargs['auto_map']
360
+ super().__init__(image_processor, tokenizer, chat_template=chat_template)
361
+
362
+
363
+ def replace_media_placeholder(self, text, image_list, video_list, timestamps_list, fps_list, **output_kwargs):
364
+
365
+ num_of_images_in_this_sample = 0
366
+ num_of_videos_in_this_sample = 0
367
+ pattern = re.compile(rf"<({self.image_placeholder}|{self.video_placeholder})-(\d+)>")
368
+ unified_frame_list = []
369
+
370
+ def replace_in_text(text):
371
+ def repl(match):
372
+ nonlocal unified_frame_list
373
+ nonlocal num_of_images_in_this_sample
374
+ nonlocal num_of_videos_in_this_sample
375
+ media_type = match.group(1)
376
+ idx_in_list = int(match.group(2)) - 1
377
+ idx_mapper = {0: "first", 1: "second", 2: "third", 3: "fourth", 4: "fifth", 5: "sixth", 6: "seventh", 7: "eighth", 8: "ninth", 9: "tenth"}
378
+
379
+ if media_type == 'image':
380
+ # Call LocateAnythingImageProcessor with a single image in a list
381
+ image_inputs = self.image_processor(images=[image_list[idx_in_list]], **output_kwargs["images_kwargs"])
382
+
383
+ num_of_tokens_list = [int(h * w) // (self.image_processor.merge_kernel_size[0] * self.image_processor.merge_kernel_size[1]) for h, w in image_inputs['image_grid_hws']]
384
+
385
+ special_placeholder = f"<image {idx_in_list+1}>{self.image_start_token}{self.image_token * num_of_tokens_list[0]}{self.image_end_token}"
386
+ unified_frame_list.append(image_inputs)
387
+ num_of_images_in_this_sample += 1
388
+
389
+ elif media_type == 'video':
390
+ video_obj = video_list[idx_in_list]
391
+
392
+ # Convert Tensor TCHW to list of PIL Images for the ImageProcessor
393
+ if isinstance(video_obj, torch.Tensor):
394
+ # video_obj is [T, C, H, W], float, likely 0-255 or standardized
395
+ # LocateAnythingImageProcessor expects PIL or 0-255 inputs usually.
396
+ # We need to convert back to PIL or List[Tensor] compatible with make_list_of_images
397
+ video_frames = []
398
+ for i in range(video_obj.shape[0]):
399
+ frame = video_obj[i] # [C, H, W]
400
+ # Assuming fetch_video returns float tensors.
401
+ # If they are 0-255, convert to uint8.
402
+ if frame.dtype.is_floating_point and frame.max() > 1.0:
403
+ frame = frame.byte()
404
+ elif frame.dtype.is_floating_point:
405
+ frame = (frame * 255).byte()
406
+
407
+ img = transforms.ToPILImage()(frame)
408
+ video_frames.append(img)
409
+ elif isinstance(video_obj, list):
410
+ # Already list of PIL images
411
+ video_frames = video_obj
412
+ else:
413
+ raise ValueError("Unsupported video format")
414
+
415
+ # Call ImageProcessor with list of frames
416
+ video_inputs = self.image_processor(images=video_frames, **output_kwargs["videos_kwargs"])
417
+
418
+ # Calculate tokens per frame
419
+ num_of_tokens_list = [int(h * w) // (self.image_processor.merge_kernel_size[0] * self.image_processor.merge_kernel_size[1]) for h, w in video_inputs['image_grid_hws']]
420
+
421
+ if timestamps_list is not None and -1 not in timestamps_list:
422
+ frame_timestamps = timestamps_list[idx_in_list]
423
+ else:
424
+ frame_timestamps = None
425
+ sampled_fps = fps_list[idx_in_list] if fps_list is not None else None
426
+
427
+ if frame_timestamps is not None:
428
+ # Ensure lengths match (sometimes rounding might cause off-by-one if not careful, but usually safe here)
429
+ if len(frame_timestamps) != len(num_of_tokens_list):
430
+ logger.warning(f"Timestamp mismatch: {len(frame_timestamps)} vs {len(num_of_tokens_list)}")
431
+ min_len = min(len(frame_timestamps), len(num_of_tokens_list))
432
+ frame_timestamps = frame_timestamps[:min_len]
433
+ num_of_tokens_list = num_of_tokens_list[:min_len]
434
+
435
+ special_placeholder = [f"Frame-{i+1}-{frame_timestamps[i]:.2f}s: {self.image_start_token}{self.image_token * num_of_tokens}{self.image_end_token}" for i, num_of_tokens in enumerate(num_of_tokens_list)]
436
+ else:
437
+ special_placeholder = [f"Frame-{i+1}: {self.image_start_token}{self.image_token * num_of_tokens}{self.image_end_token}" for i, num_of_tokens in enumerate(num_of_tokens_list)]
438
+
439
+ if sampled_fps is not None:
440
+ special_placeholder = f"The {idx_mapper[idx_in_list]} video sampled with {sampled_fps:.2f} fps: " + "".join(special_placeholder)
441
+ else:
442
+ special_placeholder = f"The {idx_mapper[idx_in_list]} video: " + "".join(special_placeholder)
443
+
444
+ unified_frame_list.append(video_inputs)
445
+ num_of_videos_in_this_sample += 1
446
+ else:
447
+ raise ValueError(f'Unknown media type: {media_type}')
448
+ return special_placeholder
449
+ return pattern.sub(repl, text)
450
+
451
+ text = replace_in_text(text)
452
+
453
+ if len(unified_frame_list) > 0:
454
+ # Concatenate all pixel values from all images/videos in this sample
455
+ pixel_values = torch.cat([frame['pixel_values'] for frame in unified_frame_list], dim=0)
456
+ # Concatenate grid hws
457
+ image_grid_hws = np.concatenate([frame['image_grid_hws'] for frame in unified_frame_list], axis=0)
458
+ else:
459
+ pixel_values = torch.empty(0)
460
+ image_grid_hws = np.empty(0)
461
+
462
+ return text, pixel_values, image_grid_hws, num_of_images_in_this_sample, num_of_videos_in_this_sample
463
+
464
+ def __call__(
465
+ self,
466
+ images: ImageInput = None,
467
+ text: Union[TextInput, PreTokenizedInput, List[TextInput], List[PreTokenizedInput]] = None,
468
+ audio=None,
469
+ videos: VideoInput = None,
470
+ **kwargs: Unpack[LocateAnythingProcessorKwargs],
471
+ ) -> BatchFeature:
472
+ output_kwargs = self._merge_kwargs(
473
+ LocateAnythingProcessorKwargs,
474
+ tokenizer_init_kwargs=self.tokenizer.init_kwargs,
475
+ **kwargs,
476
+ )
477
+
478
+ if isinstance(text, str):
479
+ text_list = [text]
480
+ elif not isinstance(text, list) and not isinstance(text[0], str):
481
+ raise ValueError("Invalid input text. Please provide a string, or a list of strings")
482
+ elif isinstance(text, list) and isinstance(text[0], str):
483
+ text_list = text
484
+
485
+ if images is None: images = []
486
+ if videos is None: videos = []
487
+
488
+ pixel_values_list = []
489
+ image_grid_hws_list = []
490
+ new_sample_list = []
491
+ image_start_idx = 0
492
+ video_start_idx = 0
493
+ timestamps_batch = output_kwargs['videos_kwargs'].pop("timestamps", None)
494
+ fps_batch = output_kwargs['videos_kwargs'].pop("fps", None)
495
+
496
+ for sample in text_list:
497
+ timestamps_list = timestamps_batch[video_start_idx:] if timestamps_batch is not None else None
498
+ fps_list = fps_batch[video_start_idx:] if fps_batch is not None else None
499
+
500
+ sample, pixel_values, image_grid_hws, num_of_images_in_this_sample, num_of_videos_in_this_sample = self.replace_media_placeholder(
501
+ sample, images[image_start_idx:], videos[video_start_idx:], timestamps_list, fps_list, **output_kwargs
502
+ )
503
+ new_sample_list.append(sample)
504
+
505
+ if pixel_values.numel() > 0:
506
+ pixel_values_list.append(pixel_values)
507
+ image_grid_hws_list.append(image_grid_hws)
508
+
509
+ image_start_idx += num_of_images_in_this_sample
510
+ video_start_idx += num_of_videos_in_this_sample
511
+
512
+ image_inputs = {}
513
+ if len(pixel_values_list) > 0:
514
+ # Concatenate across the batch
515
+ image_inputs['pixel_values'] = torch.cat(pixel_values_list, dim=0)
516
+ image_inputs['image_grid_hws'] = np.concatenate(image_grid_hws_list, axis=0)
517
+
518
+ video_inputs = {} # Video data is merged into image_inputs now
519
+ text_inputs = self.tokenizer(new_sample_list, **output_kwargs["text_kwargs"])
520
+
521
+ return BatchFeature(data={**text_inputs, **image_inputs, **video_inputs})
522
+
523
+ def batch_decode(self, *args, **kwargs):
524
+ return self.tokenizer.batch_decode(*args, **kwargs)
525
+
526
+ def decode(self, *args, **kwargs):
527
+ return self.tokenizer.decode(*args, **kwargs)
528
+
529
+ @property
530
+ def model_input_names(self):
531
+ tokenizer_input_names = self.tokenizer.model_input_names
532
+ image_processor_input_names = self.image_processor.model_input_names
533
+ return list(dict.fromkeys(tokenizer_input_names + image_processor_input_names))
534
+
535
+ def save_pretrained(self, save_directory, **kwargs):
536
+ if os.path.isfile(save_directory):
537
+ raise ValueError(f"Provided path ({save_directory}) should be a directory, not a file")
538
+ os.makedirs(save_directory, exist_ok=True)
539
+ outputs = super().save_pretrained(save_directory, **kwargs)
540
+ return outputs
541
+
542
+ @classmethod
543
+ def from_pretrained(cls, pretrained_model_name_or_path, **kwargs):
544
+ processor = super().from_pretrained(pretrained_model_name_or_path, **kwargs)
545
+ if isinstance(processor, tuple):
546
+ processor = processor[0]
547
+ return processor
548
+
549
+ def process_vision_info(
550
+ self,
551
+ conversations: list[dict] | list[list[dict]],
552
+ return_video_kwargs: bool = False,
553
+ video_reader_backend: str = "torchvision",
554
+ ) -> tuple[list[Image.Image] | None, list[torch.Tensor | list[Image.Image]] | None, Optional[dict]]:
555
+
556
+ vision_infos = self.extract_vision_info(conversations)
557
+ image_inputs = []
558
+ video_inputs = []
559
+ video_sample_fps_list = []
560
+ video_timestamps_list = []
561
+
562
+ for vision_info in vision_infos:
563
+ if "image" in vision_info or "image_url" in vision_info:
564
+ image_inputs.append(fetch_image(vision_info))
565
+ elif "video" in vision_info:
566
+ video_input, video_sample_fps, video_timestamps = fetch_video(vision_info, return_video_sample_fps=True, video_reader_backend=video_reader_backend)
567
+ video_sample_fps_list.append(video_sample_fps)
568
+ video_inputs.append(video_input)
569
+ video_timestamps_list.append(video_timestamps)
570
+ else:
571
+ raise ValueError("image, image_url or video should in content.")
572
+
573
+ if len(image_inputs) == 0:
574
+ image_inputs = None
575
+ if len(video_inputs) == 0:
576
+ video_inputs = None
577
+
578
+ if return_video_kwargs:
579
+ return image_inputs, video_inputs, {'fps': video_sample_fps_list, 'timestamps': video_timestamps_list}
580
+ return image_inputs, video_inputs
581
+
582
+ def extract_vision_info(self, conversations: list[dict] | list[list[dict]]) -> list[dict]:
583
+ vision_infos = []
584
+ if isinstance(conversations[0], dict):
585
+ conversations = [conversations]
586
+ for conversation in conversations:
587
+ for message in conversation:
588
+ if isinstance(message["content"], list):
589
+ for ele in message["content"]:
590
+ if (
591
+ "image" in ele
592
+ or "image_url" in ele
593
+ or "video" in ele
594
+ or ele["type"] in ("image", "image_url", "video")
595
+ ):
596
+ vision_infos.append(ele)
597
+ return vision_infos
598
+
599
+ def py_apply_chat_template(self, messages, tokenize=False, add_generation_prompt=False):
600
+ assert tokenize == False, "tokenize is not supported yet"
601
+ result = ""
602
+ image_count = 0
603
+ video_count = 0
604
+
605
+ message_text = ""
606
+ for idx, message in enumerate(messages):
607
+ if message.get('role') != 'user': continue
608
+ content = message.get('content')
609
+ if isinstance(content, str):
610
+ message_text += content
611
+ elif isinstance(content, list):
612
+ for item in content:
613
+ if isinstance(item, dict) and "text" in item:
614
+ message_text += item["text"]
615
+ elif isinstance(item, str):
616
+ message_text += item
617
+
618
+ for idx, message in enumerate(messages):
619
+ if idx == 0 and message.get('role') != 'system':
620
+ result += "<|im_start|>system\n"
621
+ result += "You are a helpful assistant.\n"
622
+ result += "<|im_end|>\n"
623
+
624
+ result += f"<|im_start|>{message.get('role', '')}\n"
625
+ content = message.get('content')
626
+
627
+ if isinstance(content, str):
628
+ result += content
629
+ result += "<|im_end|>\n"
630
+ else:
631
+ for item in content:
632
+ if (isinstance(item, dict) and (item.get('type') == 'image' or 'image' in item or 'image_url' in item)):
633
+ image_count += 1
634
+ candidate_token = f"<image-{image_count}>"
635
+ if candidate_token not in message_text:
636
+ result += candidate_token
637
+ elif (isinstance(item, dict) and (item.get('type') == 'video' or 'video' in item)):
638
+ video_count += 1
639
+ candidate_token = f"<video-{video_count}>"
640
+ if candidate_token not in message_text:
641
+ result += candidate_token
642
+ elif isinstance(item, dict) and 'text' in item:
643
+ result += item['text']
644
+ elif isinstance(item, str):
645
+ result += item
646
+ result += "<|im_end|>\n"
647
+
648
+ if add_generation_prompt:
649
+ result += "<|im_start|>assistant\n"
650
+
651
+ return result
652
+
653
+
654
+ @classmethod
655
+ def from_args_and_dict(cls, args, processor_dict: dict[str, Any], **kwargs):
656
+ processor_dict = processor_dict.copy()
657
+ return_unused_kwargs = kwargs.pop("return_unused_kwargs", False)
658
+
659
+ if "processor_class" in processor_dict:
660
+ del processor_dict["processor_class"]
661
+
662
+ unused_kwargs = cls.validate_init_kwargs(processor_config=processor_dict, valid_kwargs=cls.valid_kwargs)
663
+ processor = cls(*args, **processor_dict)
664
+
665
+ for key in set(kwargs.keys()):
666
+ if hasattr(processor, key):
667
+ setattr(processor, key, kwargs.pop(key))
668
+
669
+ if isinstance(unused_kwargs, dict):
670
+ kwargs.update(unused_kwargs)
671
+ logger.info(f"Processor {processor}")
672
+ if return_unused_kwargs:
673
+ return processor, kwargs
674
+ else:
675
+ return processor
676
+
677
+
678
+ __all__ = ["LocateAnythingProcessor"]
processor_config.json ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "auto_map": {
3
+ "AutoImageProcessor": "image_processing_locateanything.LocateAnythingImageProcessor",
4
+ "AutoProcessor": "processing_locateanything.LocateAnythingProcessor"
5
+ },
6
+ "image_end_token": "</img>",
7
+ "image_placeholder": "image",
8
+ "image_start_token": "<img>",
9
+ "image_token": "<IMG_CONTEXT>",
10
+ "merge_kernel_size": [
11
+ 2,
12
+ 2
13
+ ],
14
+ "processor_class": "LocateAnythingProcessor",
15
+ "video_placeholder": "video",
16
+ "video_token": "<IMG_CONTEXT>",
17
+ "patch_size": 14
18
+ }
quantization_config.json ADDED
The diff for this file is too large to render. See raw diff
 
special_tokens_map.json ADDED
@@ -0,0 +1,1053 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "additional_special_tokens": [
3
+ "<|im_start|>",
4
+ "<|im_end|>",
5
+ "<|object_ref_start|>",
6
+ "<|object_ref_end|>",
7
+ "<|box_start|>",
8
+ "<|box_end|>",
9
+ "<|quad_start|>",
10
+ "<|quad_end|>",
11
+ "<|vision_start|>",
12
+ "<|vision_end|>",
13
+ "<|vision_pad|>",
14
+ "<|image_pad|>",
15
+ "<|video_pad|>",
16
+ "<IMG_CONTEXT>",
17
+ "<img>",
18
+ "</img>",
19
+ "<box>",
20
+ "</box>",
21
+ "<quad>",
22
+ "</quad>",
23
+ "<ref>",
24
+ "</ref>",
25
+ "<interval>",
26
+ "</interval>",
27
+ "<text_mask>",
28
+ "<0>",
29
+ "<1>",
30
+ "<2>",
31
+ "<3>",
32
+ "<4>",
33
+ "<5>",
34
+ "<6>",
35
+ "<7>",
36
+ "<8>",
37
+ "<9>",
38
+ "<10>",
39
+ "<11>",
40
+ "<12>",
41
+ "<13>",
42
+ "<14>",
43
+ "<15>",
44
+ "<16>",
45
+ "<17>",
46
+ "<18>",
47
+ "<19>",
48
+ "<20>",
49
+ "<21>",
50
+ "<22>",
51
+ "<23>",
52
+ "<24>",
53
+ "<25>",
54
+ "<26>",
55
+ "<27>",
56
+ "<28>",
57
+ "<29>",
58
+ "<30>",
59
+ "<31>",
60
+ "<32>",
61
+ "<33>",
62
+ "<34>",
63
+ "<35>",
64
+ "<36>",
65
+ "<37>",
66
+ "<38>",
67
+ "<39>",
68
+ "<40>",
69
+ "<41>",
70
+ "<42>",
71
+ "<43>",
72
+ "<44>",
73
+ "<45>",
74
+ "<46>",
75
+ "<47>",
76
+ "<48>",
77
+ "<49>",
78
+ "<50>",
79
+ "<51>",
80
+ "<52>",
81
+ "<53>",
82
+ "<54>",
83
+ "<55>",
84
+ "<56>",
85
+ "<57>",
86
+ "<58>",
87
+ "<59>",
88
+ "<60>",
89
+ "<61>",
90
+ "<62>",
91
+ "<63>",
92
+ "<64>",
93
+ "<65>",
94
+ "<66>",
95
+ "<67>",
96
+ "<68>",
97
+ "<69>",
98
+ "<70>",
99
+ "<71>",
100
+ "<72>",
101
+ "<73>",
102
+ "<74>",
103
+ "<75>",
104
+ "<76>",
105
+ "<77>",
106
+ "<78>",
107
+ "<79>",
108
+ "<80>",
109
+ "<81>",
110
+ "<82>",
111
+ "<83>",
112
+ "<84>",
113
+ "<85>",
114
+ "<86>",
115
+ "<87>",
116
+ "<88>",
117
+ "<89>",
118
+ "<90>",
119
+ "<91>",
120
+ "<92>",
121
+ "<93>",
122
+ "<94>",
123
+ "<95>",
124
+ "<96>",
125
+ "<97>",
126
+ "<98>",
127
+ "<99>",
128
+ "<100>",
129
+ "<101>",
130
+ "<102>",
131
+ "<103>",
132
+ "<104>",
133
+ "<105>",
134
+ "<106>",
135
+ "<107>",
136
+ "<108>",
137
+ "<109>",
138
+ "<110>",
139
+ "<111>",
140
+ "<112>",
141
+ "<113>",
142
+ "<114>",
143
+ "<115>",
144
+ "<116>",
145
+ "<117>",
146
+ "<118>",
147
+ "<119>",
148
+ "<120>",
149
+ "<121>",
150
+ "<122>",
151
+ "<123>",
152
+ "<124>",
153
+ "<125>",
154
+ "<126>",
155
+ "<127>",
156
+ "<128>",
157
+ "<129>",
158
+ "<130>",
159
+ "<131>",
160
+ "<132>",
161
+ "<133>",
162
+ "<134>",
163
+ "<135>",
164
+ "<136>",
165
+ "<137>",
166
+ "<138>",
167
+ "<139>",
168
+ "<140>",
169
+ "<141>",
170
+ "<142>",
171
+ "<143>",
172
+ "<144>",
173
+ "<145>",
174
+ "<146>",
175
+ "<147>",
176
+ "<148>",
177
+ "<149>",
178
+ "<150>",
179
+ "<151>",
180
+ "<152>",
181
+ "<153>",
182
+ "<154>",
183
+ "<155>",
184
+ "<156>",
185
+ "<157>",
186
+ "<158>",
187
+ "<159>",
188
+ "<160>",
189
+ "<161>",
190
+ "<162>",
191
+ "<163>",
192
+ "<164>",
193
+ "<165>",
194
+ "<166>",
195
+ "<167>",
196
+ "<168>",
197
+ "<169>",
198
+ "<170>",
199
+ "<171>",
200
+ "<172>",
201
+ "<173>",
202
+ "<174>",
203
+ "<175>",
204
+ "<176>",
205
+ "<177>",
206
+ "<178>",
207
+ "<179>",
208
+ "<180>",
209
+ "<181>",
210
+ "<182>",
211
+ "<183>",
212
+ "<184>",
213
+ "<185>",
214
+ "<186>",
215
+ "<187>",
216
+ "<188>",
217
+ "<189>",
218
+ "<190>",
219
+ "<191>",
220
+ "<192>",
221
+ "<193>",
222
+ "<194>",
223
+ "<195>",
224
+ "<196>",
225
+ "<197>",
226
+ "<198>",
227
+ "<199>",
228
+ "<200>",
229
+ "<201>",
230
+ "<202>",
231
+ "<203>",
232
+ "<204>",
233
+ "<205>",
234
+ "<206>",
235
+ "<207>",
236
+ "<208>",
237
+ "<209>",
238
+ "<210>",
239
+ "<211>",
240
+ "<212>",
241
+ "<213>",
242
+ "<214>",
243
+ "<215>",
244
+ "<216>",
245
+ "<217>",
246
+ "<218>",
247
+ "<219>",
248
+ "<220>",
249
+ "<221>",
250
+ "<222>",
251
+ "<223>",
252
+ "<224>",
253
+ "<225>",
254
+ "<226>",
255
+ "<227>",
256
+ "<228>",
257
+ "<229>",
258
+ "<230>",
259
+ "<231>",
260
+ "<232>",
261
+ "<233>",
262
+ "<234>",
263
+ "<235>",
264
+ "<236>",
265
+ "<237>",
266
+ "<238>",
267
+ "<239>",
268
+ "<240>",
269
+ "<241>",
270
+ "<242>",
271
+ "<243>",
272
+ "<244>",
273
+ "<245>",
274
+ "<246>",
275
+ "<247>",
276
+ "<248>",
277
+ "<249>",
278
+ "<250>",
279
+ "<251>",
280
+ "<252>",
281
+ "<253>",
282
+ "<254>",
283
+ "<255>",
284
+ "<256>",
285
+ "<257>",
286
+ "<258>",
287
+ "<259>",
288
+ "<260>",
289
+ "<261>",
290
+ "<262>",
291
+ "<263>",
292
+ "<264>",
293
+ "<265>",
294
+ "<266>",
295
+ "<267>",
296
+ "<268>",
297
+ "<269>",
298
+ "<270>",
299
+ "<271>",
300
+ "<272>",
301
+ "<273>",
302
+ "<274>",
303
+ "<275>",
304
+ "<276>",
305
+ "<277>",
306
+ "<278>",
307
+ "<279>",
308
+ "<280>",
309
+ "<281>",
310
+ "<282>",
311
+ "<283>",
312
+ "<284>",
313
+ "<285>",
314
+ "<286>",
315
+ "<287>",
316
+ "<288>",
317
+ "<289>",
318
+ "<290>",
319
+ "<291>",
320
+ "<292>",
321
+ "<293>",
322
+ "<294>",
323
+ "<295>",
324
+ "<296>",
325
+ "<297>",
326
+ "<298>",
327
+ "<299>",
328
+ "<300>",
329
+ "<301>",
330
+ "<302>",
331
+ "<303>",
332
+ "<304>",
333
+ "<305>",
334
+ "<306>",
335
+ "<307>",
336
+ "<308>",
337
+ "<309>",
338
+ "<310>",
339
+ "<311>",
340
+ "<312>",
341
+ "<313>",
342
+ "<314>",
343
+ "<315>",
344
+ "<316>",
345
+ "<317>",
346
+ "<318>",
347
+ "<319>",
348
+ "<320>",
349
+ "<321>",
350
+ "<322>",
351
+ "<323>",
352
+ "<324>",
353
+ "<325>",
354
+ "<326>",
355
+ "<327>",
356
+ "<328>",
357
+ "<329>",
358
+ "<330>",
359
+ "<331>",
360
+ "<332>",
361
+ "<333>",
362
+ "<334>",
363
+ "<335>",
364
+ "<336>",
365
+ "<337>",
366
+ "<338>",
367
+ "<339>",
368
+ "<340>",
369
+ "<341>",
370
+ "<342>",
371
+ "<343>",
372
+ "<344>",
373
+ "<345>",
374
+ "<346>",
375
+ "<347>",
376
+ "<348>",
377
+ "<349>",
378
+ "<350>",
379
+ "<351>",
380
+ "<352>",
381
+ "<353>",
382
+ "<354>",
383
+ "<355>",
384
+ "<356>",
385
+ "<357>",
386
+ "<358>",
387
+ "<359>",
388
+ "<360>",
389
+ "<361>",
390
+ "<362>",
391
+ "<363>",
392
+ "<364>",
393
+ "<365>",
394
+ "<366>",
395
+ "<367>",
396
+ "<368>",
397
+ "<369>",
398
+ "<370>",
399
+ "<371>",
400
+ "<372>",
401
+ "<373>",
402
+ "<374>",
403
+ "<375>",
404
+ "<376>",
405
+ "<377>",
406
+ "<378>",
407
+ "<379>",
408
+ "<380>",
409
+ "<381>",
410
+ "<382>",
411
+ "<383>",
412
+ "<384>",
413
+ "<385>",
414
+ "<386>",
415
+ "<387>",
416
+ "<388>",
417
+ "<389>",
418
+ "<390>",
419
+ "<391>",
420
+ "<392>",
421
+ "<393>",
422
+ "<394>",
423
+ "<395>",
424
+ "<396>",
425
+ "<397>",
426
+ "<398>",
427
+ "<399>",
428
+ "<400>",
429
+ "<401>",
430
+ "<402>",
431
+ "<403>",
432
+ "<404>",
433
+ "<405>",
434
+ "<406>",
435
+ "<407>",
436
+ "<408>",
437
+ "<409>",
438
+ "<410>",
439
+ "<411>",
440
+ "<412>",
441
+ "<413>",
442
+ "<414>",
443
+ "<415>",
444
+ "<416>",
445
+ "<417>",
446
+ "<418>",
447
+ "<419>",
448
+ "<420>",
449
+ "<421>",
450
+ "<422>",
451
+ "<423>",
452
+ "<424>",
453
+ "<425>",
454
+ "<426>",
455
+ "<427>",
456
+ "<428>",
457
+ "<429>",
458
+ "<430>",
459
+ "<431>",
460
+ "<432>",
461
+ "<433>",
462
+ "<434>",
463
+ "<435>",
464
+ "<436>",
465
+ "<437>",
466
+ "<438>",
467
+ "<439>",
468
+ "<440>",
469
+ "<441>",
470
+ "<442>",
471
+ "<443>",
472
+ "<444>",
473
+ "<445>",
474
+ "<446>",
475
+ "<447>",
476
+ "<448>",
477
+ "<449>",
478
+ "<450>",
479
+ "<451>",
480
+ "<452>",
481
+ "<453>",
482
+ "<454>",
483
+ "<455>",
484
+ "<456>",
485
+ "<457>",
486
+ "<458>",
487
+ "<459>",
488
+ "<460>",
489
+ "<461>",
490
+ "<462>",
491
+ "<463>",
492
+ "<464>",
493
+ "<465>",
494
+ "<466>",
495
+ "<467>",
496
+ "<468>",
497
+ "<469>",
498
+ "<470>",
499
+ "<471>",
500
+ "<472>",
501
+ "<473>",
502
+ "<474>",
503
+ "<475>",
504
+ "<476>",
505
+ "<477>",
506
+ "<478>",
507
+ "<479>",
508
+ "<480>",
509
+ "<481>",
510
+ "<482>",
511
+ "<483>",
512
+ "<484>",
513
+ "<485>",
514
+ "<486>",
515
+ "<487>",
516
+ "<488>",
517
+ "<489>",
518
+ "<490>",
519
+ "<491>",
520
+ "<492>",
521
+ "<493>",
522
+ "<494>",
523
+ "<495>",
524
+ "<496>",
525
+ "<497>",
526
+ "<498>",
527
+ "<499>",
528
+ "<500>",
529
+ "<501>",
530
+ "<502>",
531
+ "<503>",
532
+ "<504>",
533
+ "<505>",
534
+ "<506>",
535
+ "<507>",
536
+ "<508>",
537
+ "<509>",
538
+ "<510>",
539
+ "<511>",
540
+ "<512>",
541
+ "<513>",
542
+ "<514>",
543
+ "<515>",
544
+ "<516>",
545
+ "<517>",
546
+ "<518>",
547
+ "<519>",
548
+ "<520>",
549
+ "<521>",
550
+ "<522>",
551
+ "<523>",
552
+ "<524>",
553
+ "<525>",
554
+ "<526>",
555
+ "<527>",
556
+ "<528>",
557
+ "<529>",
558
+ "<530>",
559
+ "<531>",
560
+ "<532>",
561
+ "<533>",
562
+ "<534>",
563
+ "<535>",
564
+ "<536>",
565
+ "<537>",
566
+ "<538>",
567
+ "<539>",
568
+ "<540>",
569
+ "<541>",
570
+ "<542>",
571
+ "<543>",
572
+ "<544>",
573
+ "<545>",
574
+ "<546>",
575
+ "<547>",
576
+ "<548>",
577
+ "<549>",
578
+ "<550>",
579
+ "<551>",
580
+ "<552>",
581
+ "<553>",
582
+ "<554>",
583
+ "<555>",
584
+ "<556>",
585
+ "<557>",
586
+ "<558>",
587
+ "<559>",
588
+ "<560>",
589
+ "<561>",
590
+ "<562>",
591
+ "<563>",
592
+ "<564>",
593
+ "<565>",
594
+ "<566>",
595
+ "<567>",
596
+ "<568>",
597
+ "<569>",
598
+ "<570>",
599
+ "<571>",
600
+ "<572>",
601
+ "<573>",
602
+ "<574>",
603
+ "<575>",
604
+ "<576>",
605
+ "<577>",
606
+ "<578>",
607
+ "<579>",
608
+ "<580>",
609
+ "<581>",
610
+ "<582>",
611
+ "<583>",
612
+ "<584>",
613
+ "<585>",
614
+ "<586>",
615
+ "<587>",
616
+ "<588>",
617
+ "<589>",
618
+ "<590>",
619
+ "<591>",
620
+ "<592>",
621
+ "<593>",
622
+ "<594>",
623
+ "<595>",
624
+ "<596>",
625
+ "<597>",
626
+ "<598>",
627
+ "<599>",
628
+ "<600>",
629
+ "<601>",
630
+ "<602>",
631
+ "<603>",
632
+ "<604>",
633
+ "<605>",
634
+ "<606>",
635
+ "<607>",
636
+ "<608>",
637
+ "<609>",
638
+ "<610>",
639
+ "<611>",
640
+ "<612>",
641
+ "<613>",
642
+ "<614>",
643
+ "<615>",
644
+ "<616>",
645
+ "<617>",
646
+ "<618>",
647
+ "<619>",
648
+ "<620>",
649
+ "<621>",
650
+ "<622>",
651
+ "<623>",
652
+ "<624>",
653
+ "<625>",
654
+ "<626>",
655
+ "<627>",
656
+ "<628>",
657
+ "<629>",
658
+ "<630>",
659
+ "<631>",
660
+ "<632>",
661
+ "<633>",
662
+ "<634>",
663
+ "<635>",
664
+ "<636>",
665
+ "<637>",
666
+ "<638>",
667
+ "<639>",
668
+ "<640>",
669
+ "<641>",
670
+ "<642>",
671
+ "<643>",
672
+ "<644>",
673
+ "<645>",
674
+ "<646>",
675
+ "<647>",
676
+ "<648>",
677
+ "<649>",
678
+ "<650>",
679
+ "<651>",
680
+ "<652>",
681
+ "<653>",
682
+ "<654>",
683
+ "<655>",
684
+ "<656>",
685
+ "<657>",
686
+ "<658>",
687
+ "<659>",
688
+ "<660>",
689
+ "<661>",
690
+ "<662>",
691
+ "<663>",
692
+ "<664>",
693
+ "<665>",
694
+ "<666>",
695
+ "<667>",
696
+ "<668>",
697
+ "<669>",
698
+ "<670>",
699
+ "<671>",
700
+ "<672>",
701
+ "<673>",
702
+ "<674>",
703
+ "<675>",
704
+ "<676>",
705
+ "<677>",
706
+ "<678>",
707
+ "<679>",
708
+ "<680>",
709
+ "<681>",
710
+ "<682>",
711
+ "<683>",
712
+ "<684>",
713
+ "<685>",
714
+ "<686>",
715
+ "<687>",
716
+ "<688>",
717
+ "<689>",
718
+ "<690>",
719
+ "<691>",
720
+ "<692>",
721
+ "<693>",
722
+ "<694>",
723
+ "<695>",
724
+ "<696>",
725
+ "<697>",
726
+ "<698>",
727
+ "<699>",
728
+ "<700>",
729
+ "<701>",
730
+ "<702>",
731
+ "<703>",
732
+ "<704>",
733
+ "<705>",
734
+ "<706>",
735
+ "<707>",
736
+ "<708>",
737
+ "<709>",
738
+ "<710>",
739
+ "<711>",
740
+ "<712>",
741
+ "<713>",
742
+ "<714>",
743
+ "<715>",
744
+ "<716>",
745
+ "<717>",
746
+ "<718>",
747
+ "<719>",
748
+ "<720>",
749
+ "<721>",
750
+ "<722>",
751
+ "<723>",
752
+ "<724>",
753
+ "<725>",
754
+ "<726>",
755
+ "<727>",
756
+ "<728>",
757
+ "<729>",
758
+ "<730>",
759
+ "<731>",
760
+ "<732>",
761
+ "<733>",
762
+ "<734>",
763
+ "<735>",
764
+ "<736>",
765
+ "<737>",
766
+ "<738>",
767
+ "<739>",
768
+ "<740>",
769
+ "<741>",
770
+ "<742>",
771
+ "<743>",
772
+ "<744>",
773
+ "<745>",
774
+ "<746>",
775
+ "<747>",
776
+ "<748>",
777
+ "<749>",
778
+ "<750>",
779
+ "<751>",
780
+ "<752>",
781
+ "<753>",
782
+ "<754>",
783
+ "<755>",
784
+ "<756>",
785
+ "<757>",
786
+ "<758>",
787
+ "<759>",
788
+ "<760>",
789
+ "<761>",
790
+ "<762>",
791
+ "<763>",
792
+ "<764>",
793
+ "<765>",
794
+ "<766>",
795
+ "<767>",
796
+ "<768>",
797
+ "<769>",
798
+ "<770>",
799
+ "<771>",
800
+ "<772>",
801
+ "<773>",
802
+ "<774>",
803
+ "<775>",
804
+ "<776>",
805
+ "<777>",
806
+ "<778>",
807
+ "<779>",
808
+ "<780>",
809
+ "<781>",
810
+ "<782>",
811
+ "<783>",
812
+ "<784>",
813
+ "<785>",
814
+ "<786>",
815
+ "<787>",
816
+ "<788>",
817
+ "<789>",
818
+ "<790>",
819
+ "<791>",
820
+ "<792>",
821
+ "<793>",
822
+ "<794>",
823
+ "<795>",
824
+ "<796>",
825
+ "<797>",
826
+ "<798>",
827
+ "<799>",
828
+ "<800>",
829
+ "<801>",
830
+ "<802>",
831
+ "<803>",
832
+ "<804>",
833
+ "<805>",
834
+ "<806>",
835
+ "<807>",
836
+ "<808>",
837
+ "<809>",
838
+ "<810>",
839
+ "<811>",
840
+ "<812>",
841
+ "<813>",
842
+ "<814>",
843
+ "<815>",
844
+ "<816>",
845
+ "<817>",
846
+ "<818>",
847
+ "<819>",
848
+ "<820>",
849
+ "<821>",
850
+ "<822>",
851
+ "<823>",
852
+ "<824>",
853
+ "<825>",
854
+ "<826>",
855
+ "<827>",
856
+ "<828>",
857
+ "<829>",
858
+ "<830>",
859
+ "<831>",
860
+ "<832>",
861
+ "<833>",
862
+ "<834>",
863
+ "<835>",
864
+ "<836>",
865
+ "<837>",
866
+ "<838>",
867
+ "<839>",
868
+ "<840>",
869
+ "<841>",
870
+ "<842>",
871
+ "<843>",
872
+ "<844>",
873
+ "<845>",
874
+ "<846>",
875
+ "<847>",
876
+ "<848>",
877
+ "<849>",
878
+ "<850>",
879
+ "<851>",
880
+ "<852>",
881
+ "<853>",
882
+ "<854>",
883
+ "<855>",
884
+ "<856>",
885
+ "<857>",
886
+ "<858>",
887
+ "<859>",
888
+ "<860>",
889
+ "<861>",
890
+ "<862>",
891
+ "<863>",
892
+ "<864>",
893
+ "<865>",
894
+ "<866>",
895
+ "<867>",
896
+ "<868>",
897
+ "<869>",
898
+ "<870>",
899
+ "<871>",
900
+ "<872>",
901
+ "<873>",
902
+ "<874>",
903
+ "<875>",
904
+ "<876>",
905
+ "<877>",
906
+ "<878>",
907
+ "<879>",
908
+ "<880>",
909
+ "<881>",
910
+ "<882>",
911
+ "<883>",
912
+ "<884>",
913
+ "<885>",
914
+ "<886>",
915
+ "<887>",
916
+ "<888>",
917
+ "<889>",
918
+ "<890>",
919
+ "<891>",
920
+ "<892>",
921
+ "<893>",
922
+ "<894>",
923
+ "<895>",
924
+ "<896>",
925
+ "<897>",
926
+ "<898>",
927
+ "<899>",
928
+ "<900>",
929
+ "<901>",
930
+ "<902>",
931
+ "<903>",
932
+ "<904>",
933
+ "<905>",
934
+ "<906>",
935
+ "<907>",
936
+ "<908>",
937
+ "<909>",
938
+ "<910>",
939
+ "<911>",
940
+ "<912>",
941
+ "<913>",
942
+ "<914>",
943
+ "<915>",
944
+ "<916>",
945
+ "<917>",
946
+ "<918>",
947
+ "<919>",
948
+ "<920>",
949
+ "<921>",
950
+ "<922>",
951
+ "<923>",
952
+ "<924>",
953
+ "<925>",
954
+ "<926>",
955
+ "<927>",
956
+ "<928>",
957
+ "<929>",
958
+ "<930>",
959
+ "<931>",
960
+ "<932>",
961
+ "<933>",
962
+ "<934>",
963
+ "<935>",
964
+ "<936>",
965
+ "<937>",
966
+ "<938>",
967
+ "<939>",
968
+ "<940>",
969
+ "<941>",
970
+ "<942>",
971
+ "<943>",
972
+ "<944>",
973
+ "<945>",
974
+ "<946>",
975
+ "<947>",
976
+ "<948>",
977
+ "<949>",
978
+ "<950>",
979
+ "<951>",
980
+ "<952>",
981
+ "<953>",
982
+ "<954>",
983
+ "<955>",
984
+ "<956>",
985
+ "<957>",
986
+ "<958>",
987
+ "<959>",
988
+ "<960>",
989
+ "<961>",
990
+ "<962>",
991
+ "<963>",
992
+ "<964>",
993
+ "<965>",
994
+ "<966>",
995
+ "<967>",
996
+ "<968>",
997
+ "<969>",
998
+ "<970>",
999
+ "<971>",
1000
+ "<972>",
1001
+ "<973>",
1002
+ "<974>",
1003
+ "<975>",
1004
+ "<976>",
1005
+ "<977>",
1006
+ "<978>",
1007
+ "<979>",
1008
+ "<980>",
1009
+ "<981>",
1010
+ "<982>",
1011
+ "<983>",
1012
+ "<984>",
1013
+ "<985>",
1014
+ "<986>",
1015
+ "<987>",
1016
+ "<988>",
1017
+ "<989>",
1018
+ "<990>",
1019
+ "<991>",
1020
+ "<992>",
1021
+ "<993>",
1022
+ "<994>",
1023
+ "<995>",
1024
+ "<996>",
1025
+ "<997>",
1026
+ "<998>",
1027
+ "<999>",
1028
+ "<1000>",
1029
+ "<null>",
1030
+ "<switch>",
1031
+ {
1032
+ "content": "</c>",
1033
+ "lstrip": false,
1034
+ "normalized": false,
1035
+ "rstrip": false,
1036
+ "single_word": false
1037
+ }
1038
+ ],
1039
+ "eos_token": {
1040
+ "content": "<|im_end|>",
1041
+ "lstrip": false,
1042
+ "normalized": false,
1043
+ "rstrip": false,
1044
+ "single_word": false
1045
+ },
1046
+ "pad_token": {
1047
+ "content": "<|endoftext|>",
1048
+ "lstrip": false,
1049
+ "normalized": false,
1050
+ "rstrip": false,
1051
+ "single_word": false
1052
+ }
1053
+ }
tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:76fbf312c2a3772b8cbde8b6a6c45607962278c72a2f152a41740e96c906fa52
3
+ size 11607003
tokenizer_config.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_prefix_space": false,
3
+ "auto_map": {
4
+ "AutoProcessor": "processing_locateanything.LocateAnythingProcessor"
5
+ },
6
+ "backend": "tokenizers",
7
+ "bos_token": null,
8
+ "clean_up_tokenization_spaces": false,
9
+ "eos_token": "<|im_end|>",
10
+ "errors": "replace",
11
+ "is_local": true,
12
+ "local_files_only": false,
13
+ "model_max_length": 16384,
14
+ "pad_token": "<|endoftext|>",
15
+ "processor_class": "LocateAnythingProcessor",
16
+ "split_special_tokens": false,
17
+ "tokenizer_class": "Qwen2Tokenizer",
18
+ "unk_token": null
19
+ }
trainer_state.json ADDED
The diff for this file is too large to render. See raw diff
 
vocab.json ADDED
The diff for this file is too large to render. See raw diff