bigshanedogg commited on
Commit
e32477a
·
verified ·
1 Parent(s): 91e9296

Upload Prompt-Depth-Anything-Small-Transparent (transformers port, original code)

Browse files
LICENSE ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright [yyyy] [name of copyright owner]
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
LICENSE.dinov2 ADDED
@@ -0,0 +1,400 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ Attribution-NonCommercial 4.0 International
3
+
4
+ =======================================================================
5
+
6
+ Creative Commons Corporation ("Creative Commons") is not a law firm and
7
+ does not provide legal services or legal advice. Distribution of
8
+ Creative Commons public licenses does not create a lawyer-client or
9
+ other relationship. Creative Commons makes its licenses and related
10
+ information available on an "as-is" basis. Creative Commons gives no
11
+ warranties regarding its licenses, any material licensed under their
12
+ terms and conditions, or any related information. Creative Commons
13
+ disclaims all liability for damages resulting from their use to the
14
+ fullest extent possible.
15
+
16
+ Using Creative Commons Public Licenses
17
+
18
+ Creative Commons public licenses provide a standard set of terms and
19
+ conditions that creators and other rights holders may use to share
20
+ original works of authorship and other material subject to copyright
21
+ and certain other rights specified in the public license below. The
22
+ following considerations are for informational purposes only, are not
23
+ exhaustive, and do not form part of our licenses.
24
+
25
+ Considerations for licensors: Our public licenses are
26
+ intended for use by those authorized to give the public
27
+ permission to use material in ways otherwise restricted by
28
+ copyright and certain other rights. Our licenses are
29
+ irrevocable. Licensors should read and understand the terms
30
+ and conditions of the license they choose before applying it.
31
+ Licensors should also secure all rights necessary before
32
+ applying our licenses so that the public can reuse the
33
+ material as expected. Licensors should clearly mark any
34
+ material not subject to the license. This includes other CC-
35
+ licensed material, or material used under an exception or
36
+ limitation to copyright. More considerations for licensors:
37
+ wiki.creativecommons.org/Considerations_for_licensors
38
+
39
+ Considerations for the public: By using one of our public
40
+ licenses, a licensor grants the public permission to use the
41
+ licensed material under specified terms and conditions. If
42
+ the licensor's permission is not necessary for any reason--for
43
+ example, because of any applicable exception or limitation to
44
+ copyright--then that use is not regulated by the license. Our
45
+ licenses grant only permissions under copyright and certain
46
+ other rights that a licensor has authority to grant. Use of
47
+ the licensed material may still be restricted for other
48
+ reasons, including because others have copyright or other
49
+ rights in the material. A licensor may make special requests,
50
+ such as asking that all changes be marked or described.
51
+ Although not required by our licenses, you are encouraged to
52
+ respect those requests where reasonable. More_considerations
53
+ for the public:
54
+ wiki.creativecommons.org/Considerations_for_licensees
55
+
56
+ =======================================================================
57
+
58
+ Creative Commons Attribution-NonCommercial 4.0 International Public
59
+ License
60
+
61
+ By exercising the Licensed Rights (defined below), You accept and agree
62
+ to be bound by the terms and conditions of this Creative Commons
63
+ Attribution-NonCommercial 4.0 International Public License ("Public
64
+ License"). To the extent this Public License may be interpreted as a
65
+ contract, You are granted the Licensed Rights in consideration of Your
66
+ acceptance of these terms and conditions, and the Licensor grants You
67
+ such rights in consideration of benefits the Licensor receives from
68
+ making the Licensed Material available under these terms and
69
+ conditions.
70
+
71
+ Section 1 -- Definitions.
72
+
73
+ a. Adapted Material means material subject to Copyright and Similar
74
+ Rights that is derived from or based upon the Licensed Material
75
+ and in which the Licensed Material is translated, altered,
76
+ arranged, transformed, or otherwise modified in a manner requiring
77
+ permission under the Copyright and Similar Rights held by the
78
+ Licensor. For purposes of this Public License, where the Licensed
79
+ Material is a musical work, performance, or sound recording,
80
+ Adapted Material is always produced where the Licensed Material is
81
+ synched in timed relation with a moving image.
82
+
83
+ b. Adapter's License means the license You apply to Your Copyright
84
+ and Similar Rights in Your contributions to Adapted Material in
85
+ accordance with the terms and conditions of this Public License.
86
+
87
+ c. Copyright and Similar Rights means copyright and/or similar rights
88
+ closely related to copyright including, without limitation,
89
+ performance, broadcast, sound recording, and Sui Generis Database
90
+ Rights, without regard to how the rights are labeled or
91
+ categorized. For purposes of this Public License, the rights
92
+ specified in Section 2(b)(1)-(2) are not Copyright and Similar
93
+ Rights.
94
+ d. Effective Technological Measures means those measures that, in the
95
+ absence of proper authority, may not be circumvented under laws
96
+ fulfilling obligations under Article 11 of the WIPO Copyright
97
+ Treaty adopted on December 20, 1996, and/or similar international
98
+ agreements.
99
+
100
+ e. Exceptions and Limitations means fair use, fair dealing, and/or
101
+ any other exception or limitation to Copyright and Similar Rights
102
+ that applies to Your use of the Licensed Material.
103
+
104
+ f. Licensed Material means the artistic or literary work, database,
105
+ or other material to which the Licensor applied this Public
106
+ License.
107
+
108
+ g. Licensed Rights means the rights granted to You subject to the
109
+ terms and conditions of this Public License, which are limited to
110
+ all Copyright and Similar Rights that apply to Your use of the
111
+ Licensed Material and that the Licensor has authority to license.
112
+
113
+ h. Licensor means the individual(s) or entity(ies) granting rights
114
+ under this Public License.
115
+
116
+ i. NonCommercial means not primarily intended for or directed towards
117
+ commercial advantage or monetary compensation. For purposes of
118
+ this Public License, the exchange of the Licensed Material for
119
+ other material subject to Copyright and Similar Rights by digital
120
+ file-sharing or similar means is NonCommercial provided there is
121
+ no payment of monetary compensation in connection with the
122
+ exchange.
123
+
124
+ j. Share means to provide material to the public by any means or
125
+ process that requires permission under the Licensed Rights, such
126
+ as reproduction, public display, public performance, distribution,
127
+ dissemination, communication, or importation, and to make material
128
+ available to the public including in ways that members of the
129
+ public may access the material from a place and at a time
130
+ individually chosen by them.
131
+
132
+ k. Sui Generis Database Rights means rights other than copyright
133
+ resulting from Directive 96/9/EC of the European Parliament and of
134
+ the Council of 11 March 1996 on the legal protection of databases,
135
+ as amended and/or succeeded, as well as other essentially
136
+ equivalent rights anywhere in the world.
137
+
138
+ l. You means the individual or entity exercising the Licensed Rights
139
+ under this Public License. Your has a corresponding meaning.
140
+
141
+ Section 2 -- Scope.
142
+
143
+ a. License grant.
144
+
145
+ 1. Subject to the terms and conditions of this Public License,
146
+ the Licensor hereby grants You a worldwide, royalty-free,
147
+ non-sublicensable, non-exclusive, irrevocable license to
148
+ exercise the Licensed Rights in the Licensed Material to:
149
+
150
+ a. reproduce and Share the Licensed Material, in whole or
151
+ in part, for NonCommercial purposes only; and
152
+
153
+ b. produce, reproduce, and Share Adapted Material for
154
+ NonCommercial purposes only.
155
+
156
+ 2. Exceptions and Limitations. For the avoidance of doubt, where
157
+ Exceptions and Limitations apply to Your use, this Public
158
+ License does not apply, and You do not need to comply with
159
+ its terms and conditions.
160
+
161
+ 3. Term. The term of this Public License is specified in Section
162
+ 6(a).
163
+
164
+ 4. Media and formats; technical modifications allowed. The
165
+ Licensor authorizes You to exercise the Licensed Rights in
166
+ all media and formats whether now known or hereafter created,
167
+ and to make technical modifications necessary to do so. The
168
+ Licensor waives and/or agrees not to assert any right or
169
+ authority to forbid You from making technical modifications
170
+ necessary to exercise the Licensed Rights, including
171
+ technical modifications necessary to circumvent Effective
172
+ Technological Measures. For purposes of this Public License,
173
+ simply making modifications authorized by this Section 2(a)
174
+ (4) never produces Adapted Material.
175
+
176
+ 5. Downstream recipients.
177
+
178
+ a. Offer from the Licensor -- Licensed Material. Every
179
+ recipient of the Licensed Material automatically
180
+ receives an offer from the Licensor to exercise the
181
+ Licensed Rights under the terms and conditions of this
182
+ Public License.
183
+
184
+ b. No downstream restrictions. You may not offer or impose
185
+ any additional or different terms or conditions on, or
186
+ apply any Effective Technological Measures to, the
187
+ Licensed Material if doing so restricts exercise of the
188
+ Licensed Rights by any recipient of the Licensed
189
+ Material.
190
+
191
+ 6. No endorsement. Nothing in this Public License constitutes or
192
+ may be construed as permission to assert or imply that You
193
+ are, or that Your use of the Licensed Material is, connected
194
+ with, or sponsored, endorsed, or granted official status by,
195
+ the Licensor or others designated to receive attribution as
196
+ provided in Section 3(a)(1)(A)(i).
197
+
198
+ b. Other rights.
199
+
200
+ 1. Moral rights, such as the right of integrity, are not
201
+ licensed under this Public License, nor are publicity,
202
+ privacy, and/or other similar personality rights; however, to
203
+ the extent possible, the Licensor waives and/or agrees not to
204
+ assert any such rights held by the Licensor to the limited
205
+ extent necessary to allow You to exercise the Licensed
206
+ Rights, but not otherwise.
207
+
208
+ 2. Patent and trademark rights are not licensed under this
209
+ Public License.
210
+
211
+ 3. To the extent possible, the Licensor waives any right to
212
+ collect royalties from You for the exercise of the Licensed
213
+ Rights, whether directly or through a collecting society
214
+ under any voluntary or waivable statutory or compulsory
215
+ licensing scheme. In all other cases the Licensor expressly
216
+ reserves any right to collect such royalties, including when
217
+ the Licensed Material is used other than for NonCommercial
218
+ purposes.
219
+
220
+ Section 3 -- License Conditions.
221
+
222
+ Your exercise of the Licensed Rights is expressly made subject to the
223
+ following conditions.
224
+
225
+ a. Attribution.
226
+
227
+ 1. If You Share the Licensed Material (including in modified
228
+ form), You must:
229
+
230
+ a. retain the following if it is supplied by the Licensor
231
+ with the Licensed Material:
232
+
233
+ i. identification of the creator(s) of the Licensed
234
+ Material and any others designated to receive
235
+ attribution, in any reasonable manner requested by
236
+ the Licensor (including by pseudonym if
237
+ designated);
238
+
239
+ ii. a copyright notice;
240
+
241
+ iii. a notice that refers to this Public License;
242
+
243
+ iv. a notice that refers to the disclaimer of
244
+ warranties;
245
+
246
+ v. a URI or hyperlink to the Licensed Material to the
247
+ extent reasonably practicable;
248
+
249
+ b. indicate if You modified the Licensed Material and
250
+ retain an indication of any previous modifications; and
251
+
252
+ c. indicate the Licensed Material is licensed under this
253
+ Public License, and include the text of, or the URI or
254
+ hyperlink to, this Public License.
255
+
256
+ 2. You may satisfy the conditions in Section 3(a)(1) in any
257
+ reasonable manner based on the medium, means, and context in
258
+ which You Share the Licensed Material. For example, it may be
259
+ reasonable to satisfy the conditions by providing a URI or
260
+ hyperlink to a resource that includes the required
261
+ information.
262
+
263
+ 3. If requested by the Licensor, You must remove any of the
264
+ information required by Section 3(a)(1)(A) to the extent
265
+ reasonably practicable.
266
+
267
+ 4. If You Share Adapted Material You produce, the Adapter's
268
+ License You apply must not prevent recipients of the Adapted
269
+ Material from complying with this Public License.
270
+
271
+ Section 4 -- Sui Generis Database Rights.
272
+
273
+ Where the Licensed Rights include Sui Generis Database Rights that
274
+ apply to Your use of the Licensed Material:
275
+
276
+ a. for the avoidance of doubt, Section 2(a)(1) grants You the right
277
+ to extract, reuse, reproduce, and Share all or a substantial
278
+ portion of the contents of the database for NonCommercial purposes
279
+ only;
280
+
281
+ b. if You include all or a substantial portion of the database
282
+ contents in a database in which You have Sui Generis Database
283
+ Rights, then the database in which You have Sui Generis Database
284
+ Rights (but not its individual contents) is Adapted Material; and
285
+
286
+ c. You must comply with the conditions in Section 3(a) if You Share
287
+ all or a substantial portion of the contents of the database.
288
+
289
+ For the avoidance of doubt, this Section 4 supplements and does not
290
+ replace Your obligations under this Public License where the Licensed
291
+ Rights include other Copyright and Similar Rights.
292
+
293
+ Section 5 -- Disclaimer of Warranties and Limitation of Liability.
294
+
295
+ a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
296
+ EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
297
+ AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
298
+ ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
299
+ IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
300
+ WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
301
+ PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
302
+ ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
303
+ KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
304
+ ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
305
+
306
+ b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
307
+ TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
308
+ NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
309
+ INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
310
+ COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
311
+ USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
312
+ ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
313
+ DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
314
+ IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
315
+
316
+ c. The disclaimer of warranties and limitation of liability provided
317
+ above shall be interpreted in a manner that, to the extent
318
+ possible, most closely approximates an absolute disclaimer and
319
+ waiver of all liability.
320
+
321
+ Section 6 -- Term and Termination.
322
+
323
+ a. This Public License applies for the term of the Copyright and
324
+ Similar Rights licensed here. However, if You fail to comply with
325
+ this Public License, then Your rights under this Public License
326
+ terminate automatically.
327
+
328
+ b. Where Your right to use the Licensed Material has terminated under
329
+ Section 6(a), it reinstates:
330
+
331
+ 1. automatically as of the date the violation is cured, provided
332
+ it is cured within 30 days of Your discovery of the
333
+ violation; or
334
+
335
+ 2. upon express reinstatement by the Licensor.
336
+
337
+ For the avoidance of doubt, this Section 6(b) does not affect any
338
+ right the Licensor may have to seek remedies for Your violations
339
+ of this Public License.
340
+
341
+ c. For the avoidance of doubt, the Licensor may also offer the
342
+ Licensed Material under separate terms or conditions or stop
343
+ distributing the Licensed Material at any time; however, doing so
344
+ will not terminate this Public License.
345
+
346
+ d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
347
+ License.
348
+
349
+ Section 7 -- Other Terms and Conditions.
350
+
351
+ a. The Licensor shall not be bound by any additional or different
352
+ terms or conditions communicated by You unless expressly agreed.
353
+
354
+ b. Any arrangements, understandings, or agreements regarding the
355
+ Licensed Material not stated herein are separate from and
356
+ independent of the terms and conditions of this Public License.
357
+
358
+ Section 8 -- Interpretation.
359
+
360
+ a. For the avoidance of doubt, this Public License does not, and
361
+ shall not be interpreted to, reduce, limit, restrict, or impose
362
+ conditions on any use of the Licensed Material that could lawfully
363
+ be made without permission under this Public License.
364
+
365
+ b. To the extent possible, if any provision of this Public License is
366
+ deemed unenforceable, it shall be automatically reformed to the
367
+ minimum extent necessary to make it enforceable. If the provision
368
+ cannot be reformed, it shall be severed from this Public License
369
+ without affecting the enforceability of the remaining terms and
370
+ conditions.
371
+
372
+ c. No term or condition of this Public License will be waived and no
373
+ failure to comply consented to unless expressly agreed to by the
374
+ Licensor.
375
+
376
+ d. Nothing in this Public License constitutes or may be interpreted
377
+ as a limitation upon, or waiver of, any privileges and immunities
378
+ that apply to the Licensor or You, including from the legal
379
+ processes of any jurisdiction or authority.
380
+
381
+ =======================================================================
382
+
383
+ Creative Commons is not a party to its public
384
+ licenses. Notwithstanding, Creative Commons may elect to apply one of
385
+ its public licenses to material it publishes and in those instances
386
+ will be considered the “Licensor.” The text of the Creative Commons
387
+ public licenses is dedicated to the public domain under the CC0 Public
388
+ Domain Dedication. Except for the limited purpose of indicating that
389
+ material is shared under a Creative Commons public license or as
390
+ otherwise permitted by the Creative Commons policies published at
391
+ creativecommons.org/policies, Creative Commons does not authorize the
392
+ use of the trademark "Creative Commons" or any other trademark or logo
393
+ of Creative Commons without its prior written consent including,
394
+ without limitation, in connection with any unauthorized modifications
395
+ to any of its public licenses or any other arrangements,
396
+ understandings, or agreements concerning use of licensed material. For
397
+ the avoidance of doubt, this paragraph does not form part of the
398
+ public licenses.
399
+
400
+ Creative Commons may be contacted at creativecommons.org.
NOTICE ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Prompt-Depth-Anything-Small-Transparent -- unofficial transformers-format package (trust_remote_code)
2
+ Packaged by bigshanedogg, 2026. NOT an official release of the original authors.
3
+
4
+ Components
5
+ ----------
6
+ 1. Prompt Depth Anything weights (model.ckpt, prompt-depth-anything-vits-transparent)
7
+ Source: https://huggingface.co/depth-anything/prompt-depth-anything-vits-transparent
8
+ Copyright: Haotong Lin, Sida Peng, Jingxiao Chen, Songyou Peng, Jiaming Sun, Minghuan Liu, Hujun Bao, Jiashi Feng, Xiaowei Zhou, Bingyi Kang
9
+ License: Apache-2.0 -- LICENSE
10
+ 2. Prompt Depth Anything code (promptda/promptda.py, model/, utils/logger.py; vendored into promptda_model.py; load_image / load_depth of utils/io_wrapper.py re-typed in image_processing_prompt_depth_anything.py)
11
+ Source: https://github.com/DepthAnything/PromptDA @ 9161547ca7151e14fcc8f490ad3cc02fa9437483
12
+ Copyright: the Prompt Depth Anything authors
13
+ License: Apache-2.0 -- LICENSE
14
+ 3. DINOv2 code (the repo's torchhub copy of facebookresearch/dinov2; vendored into promptda_dinov2.py)
15
+ Source: https://github.com/DepthAnything/PromptDA/tree/main/torchhub/facebookresearch_dinov2_main @ 9161547ca7151e14fcc8f490ad3cc02fa9437483
16
+ Copyright: Copyright (c) Meta Platforms, Inc. and affiliates.
17
+ License: Apache-2.0 -- LICENSE.dinov2
18
+
19
+ Changes made in this package
20
+ ----------------------------
21
+ - promptda_dinov2.py / promptda_model.py: the official files concatenated into flat files; package-internal imports replaced by relative imports; NestedTensorBlock spelled out where vision_transformer.py imported it as Block. No computation changed.
22
+ - configuration_ / modeling_ / image_processing_ / processing_prompt_depth_anything.py: new transformers wrappers; the model builds DINOv2 with the torchhub hub's arguments instead of torch.hub.load and runs PromptDA.forward; the image processor re-types io_wrapper.load_image / load_depth (that module imports open3d / matplotlib), checked bit-exact.
23
+ - model.safetensors: the Lightning model.ckpt state dict without its 'pipeline.' prefix (as PromptDA.load_checkpoint), converted by save_pretrained, every tensor checked equal; the training state (epoch, loops) dropped.
24
+
25
+ License files
26
+ -------------
27
+ - LICENSE: Apache License 2.0, copy from DepthAnything/PromptDA (code and weights)
28
+ - LICENSE.dinov2: Apache License 2.0, copy from the repo's torchhub/facebookresearch_dinov2_main
README.md ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ library_name: transformers
4
+ base_model: depth-anything/prompt-depth-anything-vits-transparent
5
+ tags:
6
+ - prompt-depth-anything
7
+ - depth-estimation
8
+ - metric-depth
9
+ pipeline_tag: depth-estimation
10
+ ---
11
+
12
+ # Prompt-Depth-Anything-Small-Transparent — transformers format (original code)
13
+
14
+ Unofficial transformers port of **Prompt Depth Anything** (`depth-anything/prompt-depth-anything-vits-transparent`, `model.ckpt`) that runs the
15
+ **original** code. Loads with `trust_remote_code`. `model.safetensors` holds the checkpoint's tensors under their
16
+ original names (without the Lightning `pipeline.` prefix, as the original loader), every tensor checked equal. Fine-tuned for 10K more steps on the HAMMER dataset with the authors' iPhone LiDAR simulation, for transparent objects (README).
17
+
18
+ > **Not an official release.** Prompt Depth Anything was created by Haotong Lin, Sida Peng, Jingxiao Chen, Songyou
19
+ > Peng, Jiaming Sun, Minghuan Liu, Hujun Bao, Jiashi Feng, Xiaowei Zhou and Bingyi Kang —
20
+ > https://github.com/DepthAnything/PromptDA, paper *"Prompting Depth Anything for 4K Resolution Accurate Metric Depth
21
+ > Estimation"* (CVPR 2025).
22
+
23
+ ## What it is
24
+
25
+ Metric depth from an RGB image plus a low-resolution depth prompt (e.g. iPhone LiDAR, 192 × 256, meters).
26
+ `PromptDepthAnythingForDepthEstimation` holds the official `PromptDA`'s submodules and buffers (`pretrained`: DINOv2
27
+ ViT-S/14, `depth_head`: the prompt-conditioned DPT head, `_mean` / `_std`) and computes depth with the official
28
+ `PromptDA.forward`, returning the standard `DepthEstimatorOutput` (`predicted_depth`: (B, H, W), meters); the official
29
+ `predict` is kept. DINOv2 is built from the repo's torchhub copy with the hub's arguments (the original calls
30
+ `torch.hub.load(..., source='local')`). Code vendored from DepthAnything/PromptDA @ 9161547c into `promptda_dinov2.py` /
31
+ `promptda_model.py`; edits: imports, and `Block` → `NestedTensorBlock` where the original imported
32
+ `NestedTensorBlock as Block`. `PromptDepthAnythingProcessor` (`processing_prompt_depth_anything.py`,
33
+ `processor_config.json`) wraps `PromptDepthAnythingImageProcessor`, the original `load_image` / `load_depth`.
34
+
35
+ Verified against the official code (same process, V100): preprocessing (image and prompt depth), `predicted_depth`
36
+ (also as a tuple), `predict`, the hidden states and fp16 autocast outputs are **bit-identical**.
37
+
38
+ ## Usage
39
+
40
+ ```python
41
+ import torch
42
+ from transformers import AutoModelForDepthEstimation, AutoProcessor
43
+
44
+ model = AutoModelForDepthEstimation.from_pretrained("Prompt-Depth-Anything-Small-Transparent", trust_remote_code=True).eval().cuda()
45
+ processor = AutoProcessor.from_pretrained("Prompt-Depth-Anything-Small-Transparent", trust_remote_code=True)
46
+ # image: path (read with imageio, as the original), PIL image or RGB uint8 array; prompt_depth: .png (mm) / .npz path or meters
47
+ inputs = processor(images="image.jpg", prompt_depth="arkit_depth.png", return_tensors="pt").to("cuda")
48
+ with torch.no_grad():
49
+ outputs = model(**inputs) # outputs.predicted_depth: (1, H, W), meters, at the processed image size
50
+ ```
51
+
52
+ - `AutoModel` loads the same class. `output_hidden_states=True` adds the DINOv2 features the head reads; `return_dict=False` returns a tuple.
53
+ - `pixel_values` are RGB in [0, 1]: the model normalises them itself, as the original.
54
+ - The depth is at the processed image size (longer side at most 1008, multiples of 14), as the original (no resizing back).
55
+
56
+ Runtime packages beyond torch / transformers: `opencv-python`, `imageio` (as the original).
57
+
58
+ ## Licensing
59
+
60
+ - Code and weights: **Apache-2.0** — [`LICENSE`](LICENSE) (DepthAnything/PromptDA), as published on `depth-anything/prompt-depth-anything-vits-transparent`.
61
+ - DINOv2 code (the repo's torchhub copy): **Apache-2.0** — [`LICENSE.dinov2`](LICENSE.dinov2).
62
+ - Attribution, sources and the changes made here: [`NOTICE`](NOTICE).
63
+
64
+ ## Citation
65
+
66
+ If you use this model, please cite the original work, as its authors ask:
67
+
68
+ ```bibtex
69
+ @inproceedings{lin2024promptda,
70
+ title={Prompting Depth Anything for 4K Resolution Accurate Metric Depth Estimation},
71
+ author={Lin, Haotong and Peng, Sida and Chen, Jingxiao and Peng, Songyou and Sun, Jiaming and Liu, Minghuan and Bao, Hujun and Feng, Jiashi and Zhou, Xiaowei and Kang, Bingyi},
72
+ journal={arXiv},
73
+ year={2024}
74
+ }
75
+ ```
config.json ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "PromptDepthAnythingForDepthEstimation"
4
+ ],
5
+ "auto_map": {
6
+ "AutoConfig": "configuration_prompt_depth_anything.PromptDepthAnythingConfig",
7
+ "AutoModel": "modeling_prompt_depth_anything.PromptDepthAnythingForDepthEstimation",
8
+ "AutoModelForDepthEstimation": "modeling_prompt_depth_anything.PromptDepthAnythingForDepthEstimation"
9
+ },
10
+ "dtype": "float32",
11
+ "encoder": "vits",
12
+ "max_size": 1008,
13
+ "model_type": "prompt_depth_anything",
14
+ "transformers_version": "5.20.2"
15
+ }
configuration_prompt_depth_anything.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Prompt Depth Anything configuration: the encoder of the official ``PromptDA`` (DepthAnything/PromptDA @ 9161547c,
2
+ promptda/promptda.py); the head arguments follow from it (promptda/model/config.py ``model_configs``)."""
3
+
4
+ from transformers import PreTrainedConfig
5
+
6
+
7
+ class PromptDepthAnythingConfig(PreTrainedConfig):
8
+ r"""
9
+ encoder: "vits" | "vitl" (released; "vitb" also in ``model_configs``): DINOv2 size, DPT features / out_channels, layers.
10
+ max_size: the image preprocessing limit (``load_image``: longer side at most 1008, sides multiples of 14).
11
+ """
12
+
13
+ model_type = "prompt_depth_anything"
14
+
15
+ encoder: str = "vitl"
16
+ max_size: int = 1008
17
+
18
+
19
+ __all__ = ["PromptDepthAnythingConfig"]
image_processing_prompt_depth_anything.py ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Prompt Depth Anything preprocessing: the official ``load_image`` / ``load_depth`` (promptda/utils/io_wrapper.py @
2
+ 9161547c) behind the transformers image-processor interface. That module also imports open3d / matplotlib for
3
+ visualisation, so its two loaders are re-typed here line by line (checked bit-exact against the originals).
4
+
5
+ Image: RGB in [0, 1] (the model normalises it), longer side at most ``max_size`` (cv2 INTER_AREA, sides floored to
6
+ multiples of 14). A path is read with imageio, as the original. Prompt depth: meters, (h, w); a .png path is
7
+ millimeters (/ 1000), a .npz path holds "depth", as the original."""
8
+
9
+ import cv2
10
+ import imageio
11
+ import numpy as np
12
+ import torch
13
+ from PIL import Image
14
+ from transformers.feature_extraction_utils import BatchFeature
15
+ from transformers.image_processing_utils import BaseImageProcessor
16
+
17
+
18
+ def _to_tensor(arr): # io_wrapper.to_tensor_func
19
+ if arr.ndim == 2:
20
+ arr = arr[:, :, np.newaxis]
21
+ return torch.from_numpy(arr).permute(2, 0, 1).unsqueeze(0)
22
+
23
+
24
+ def _ensure_multiple_of(x, multiple_of=14): # io_wrapper.ensure_multiple_of
25
+ return int(x // multiple_of * multiple_of)
26
+
27
+
28
+ class PromptDepthAnythingImageProcessor(BaseImageProcessor):
29
+ model_input_names = ["pixel_values", "prompt_depth"]
30
+
31
+ def __init__(self, max_size: int = 1008, **kwargs):
32
+ super().__init__(**kwargs)
33
+ self.max_size = max_size
34
+
35
+ def load_image(self, image, max_size: int, multiple_of: int = 14):
36
+ # io_wrapper.load_image, also taking a PIL image / RGB uint8 array
37
+ if isinstance(image, str):
38
+ image = np.asarray(imageio.imread(image)).astype(np.float32)
39
+ else:
40
+ image = np.asarray(image.convert("RGB") if isinstance(image, Image.Image) else image).astype(np.float32)
41
+ image = image / 255.
42
+
43
+ max_size = max_size // multiple_of * multiple_of
44
+ if max(image.shape) > max_size:
45
+ h, w = image.shape[:2]
46
+ scale = max_size / max(h, w)
47
+ tar_h = _ensure_multiple_of(h * scale)
48
+ tar_w = _ensure_multiple_of(w * scale)
49
+ image = cv2.resize(image, (tar_w, tar_h), interpolation=cv2.INTER_AREA)
50
+ return _to_tensor(image)
51
+
52
+ @staticmethod
53
+ def load_depth(depth):
54
+ # io_wrapper.load_depth, also taking an array / tensor in meters
55
+ if isinstance(depth, str):
56
+ if depth.endswith('.png'):
57
+ depth = np.asarray(imageio.imread(depth)).astype(np.float32)
58
+ depth = depth / 1000.
59
+ elif depth.endswith('.npz'):
60
+ depth = np.load(depth)['depth']
61
+ else:
62
+ raise ValueError(f"Unsupported depth format: {depth}")
63
+ elif isinstance(depth, torch.Tensor):
64
+ depth = depth.cpu().numpy()
65
+ return _to_tensor(np.asarray(depth))
66
+
67
+ def preprocess(self, images, prompt_depth=None, max_size: int | None = None, return_tensors=None, **kwargs) -> BatchFeature:
68
+ """images: one image or a list (paths, PIL images or RGB uint8 arrays); prompt_depth: one depth map per image
69
+ (paths, or arrays in meters). pixel_values (B, 3, H, W) in [0, 1]; prompt_depth (B, 1, h, w)."""
70
+ if not isinstance(images, (list, tuple)):
71
+ images = [images]
72
+ tensors = [self.load_image(image, max_size or self.max_size)[0] for image in images]
73
+ if len({t.shape for t in tensors}) > 1:
74
+ raise ValueError("images resize to different shapes; process them one at a time")
75
+ data = {"pixel_values": torch.stack(tensors)}
76
+ if prompt_depth is not None:
77
+ if not isinstance(prompt_depth, (list, tuple)):
78
+ prompt_depth = [prompt_depth]
79
+ if len(prompt_depth) != len(images):
80
+ raise ValueError("give one prompt depth per image")
81
+ data["prompt_depth"] = torch.stack([self.load_depth(depth)[0] for depth in prompt_depth])
82
+ return BatchFeature(data, tensor_type=return_tensors)
83
+
84
+
85
+ __all__ = ["PromptDepthAnythingImageProcessor"]
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d5fe3bd10ce1ec52cb442924a83e3710d9fb4a7b2e2bfb940e7dbd54ac1744d6
3
+ size 100360548
modeling_prompt_depth_anything.py ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Prompt Depth Anything (DepthAnything/PromptDA @ 9161547c) as a transformers depth-estimation model.
2
+
3
+ ``PromptDepthAnythingForDepthEstimation`` holds the submodules and buffers of the official ``PromptDA`` under the same
4
+ names (``pretrained``: DINOv2, ``depth_head``: the prompt-conditioned DPT head, ``_mean`` / ``_std``), so the released
5
+ ``model.ckpt`` tensors load by name (without the Lightning ``pipeline.`` prefix, as ``PromptDA.load_checkpoint``), and
6
+ computes depth with the official ``PromptDA.forward`` (prompt depth min-max normalisation, DINOv2, DPT, denormalisation),
7
+ returned as the standard ``DepthEstimatorOutput``. The official class builds DINOv2 with torch.hub.load from the repo's
8
+ local torchhub copy (``hubconf._make_dinov2_model``); here the same vendored ``vit_*`` are called with the hub's
9
+ arguments (``_HUB_KWARGS``).
10
+ """
11
+
12
+ import torch
13
+ from transformers import PreTrainedModel
14
+ from transformers.modeling_outputs import DepthEstimatorOutput
15
+
16
+ from .configuration_prompt_depth_anything import PromptDepthAnythingConfig
17
+ from .promptda_dinov2 import vit_base, vit_large, vit_small
18
+ from .promptda_model import DPTHead, PromptDA, model_configs
19
+
20
+ # torchhub/facebookresearch_dinov2_main/hubconf.py :: _make_dinov2_model defaults (pretrained=False, as PromptDA loads it)
21
+ _HUB_KWARGS = dict(img_size=518, patch_size=14, init_values=1.0, ffn_layer="mlp", block_chunks=0, num_register_tokens=0,
22
+ interpolate_antialias=False, interpolate_offset=0.1)
23
+ _ARCHS = {"vits": vit_small, "vitb": vit_base, "vitl": vit_large}
24
+
25
+
26
+ class PromptDepthAnythingPreTrainedModel(PreTrainedModel):
27
+ config_class = PromptDepthAnythingConfig
28
+ config: PromptDepthAnythingConfig
29
+ base_model_prefix = "prompt_depth_anything"
30
+ main_input_name = "pixel_values"
31
+
32
+
33
+ class PromptDepthAnythingForDepthEstimation(PromptDepthAnythingPreTrainedModel):
34
+ # the official class attributes and methods forward uses
35
+ patch_size = PromptDA.patch_size
36
+ use_bn = PromptDA.use_bn
37
+ use_clstoken = PromptDA.use_clstoken
38
+ output_act = PromptDA.output_act
39
+ normalize = PromptDA.normalize
40
+ denormalize = PromptDA.denormalize
41
+
42
+ def __init__(self, config: PromptDepthAnythingConfig):
43
+ super().__init__(config)
44
+ # PromptDA.__init__ (DINOv2 as hubconf builds it; no checkpoint loading)
45
+ model_config = model_configs[config.encoder]
46
+ self.encoder = config.encoder
47
+ self.model_config = model_config
48
+ self.pretrained = _ARCHS[config.encoder](**_HUB_KWARGS)
49
+ dim = self.pretrained.blocks[0].attn.qkv.in_features
50
+ self.depth_head = DPTHead(nclass=1, in_channels=dim, features=model_config['features'], out_channels=model_config['out_channels'],
51
+ use_bn=self.use_bn, use_clstoken=self.use_clstoken, output_act=self.output_act)
52
+ self.register_buffer('_mean', torch.tensor([0.485, 0.456, 0.406]).view(1, 3, 1, 1))
53
+ self.register_buffer('_std', torch.tensor([0.229, 0.224, 0.225]).view(1, 3, 1, 1))
54
+ self.post_init()
55
+
56
+ def forward(
57
+ self,
58
+ pixel_values: torch.Tensor,
59
+ prompt_depth: torch.Tensor | None = None,
60
+ labels: torch.Tensor | None = None,
61
+ output_attentions: bool | None = None,
62
+ output_hidden_states: bool | None = None,
63
+ return_dict: bool | None = None,
64
+ **kwargs,
65
+ ) -> tuple | DepthEstimatorOutput:
66
+ """pixel_values (B, 3, H, W) RGB in [0, 1], H and W multiples of 14; prompt_depth (B, 1, h, w) in meters (e.g.
67
+ iPhone LiDAR 192 x 256), required (``PromptDepthAnythingProcessor``). ``predicted_depth`` (B, H, W): metric
68
+ depth in meters. ``output_hidden_states``: the DINOv2 features the head reads (per layer, (patch tokens,
69
+ class token))."""
70
+ if labels is not None:
71
+ raise NotImplementedError("Training is not implemented")
72
+ if output_attentions:
73
+ raise NotImplementedError("Attention weights are not returned (the original model does not expose them)")
74
+ return_dict = return_dict if return_dict is not None else self.config.return_dict
75
+ output_hidden_states = output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
76
+ predicted_depth = PromptDA.forward(self, pixel_values, prompt_depth)[:, 0]
77
+ hidden_states = None
78
+ if output_hidden_states:
79
+ hidden_states = tuple(self.pretrained.get_intermediate_layers(
80
+ (pixel_values - self._mean) / self._std, self.model_config['layer_idxs'], return_class_token=True))
81
+ if not return_dict:
82
+ return (predicted_depth,) + ((hidden_states,) if hidden_states is not None else ())
83
+ return DepthEstimatorOutput(predicted_depth=predicted_depth, hidden_states=hidden_states)
84
+
85
+ @torch.no_grad()
86
+ def predict(self, image: torch.Tensor, prompt_depth: torch.Tensor):
87
+ """The official ``PromptDA.predict``: depth (B, 1, H, W) in meters."""
88
+ return PromptDA.forward(self, image, prompt_depth)
89
+
90
+
91
+ __all__ = ["PromptDepthAnythingForDepthEstimation", "PromptDepthAnythingPreTrainedModel"]
processing_prompt_depth_anything.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Prompt Depth Anything processor: ``PromptDepthAnythingImageProcessor`` (the official load_image / load_depth) as its
2
+ only part."""
3
+
4
+ from transformers.processing_utils import ProcessorMixin
5
+
6
+
7
+ class PromptDepthAnythingProcessor(ProcessorMixin):
8
+ attributes = ["image_processor"]
9
+
10
+ def __init__(self, image_processor=None, **kwargs):
11
+ super().__init__(image_processor, **kwargs)
12
+
13
+ def __call__(self, images=None, prompt_depth=None, **kwargs):
14
+ return self.image_processor(images, prompt_depth=prompt_depth, **kwargs)
15
+
16
+
17
+ __all__ = ["PromptDepthAnythingProcessor"]
processor_config.json ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "auto_map": {
3
+ "AutoProcessor": "processing_prompt_depth_anything.PromptDepthAnythingProcessor"
4
+ },
5
+ "image_processor": {
6
+ "auto_map": {
7
+ "AutoImageProcessor": "image_processing_prompt_depth_anything.PromptDepthAnythingImageProcessor",
8
+ "AutoProcessor": "processing_prompt_depth_anything.PromptDepthAnythingProcessor"
9
+ },
10
+ "image_processor_type": "PromptDepthAnythingImageProcessor",
11
+ "max_size": 1008
12
+ },
13
+ "processor_class": "PromptDepthAnythingProcessor"
14
+ }
promptda_dinov2.py ADDED
@@ -0,0 +1,1024 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ruff: noqa
2
+ # fmt: off
3
+ """Prompt Depth Anything, vendored verbatim from DepthAnything/PromptDA @ 9161547ca7151e14fcc8f490ad3cc02fa9437483 (promptda/ and the local torchhub
4
+ copy of facebookresearch/dinov2 it loads): the files below concatenated, package-internal imports replaced by
5
+ relative imports of the other vendored files (generated by scripts/model_ports/common/vendor_flat.py; do not edit by hand). Code license: Apache-2.0."""
6
+
7
+
8
+ # ==============================================================================================================
9
+ # PromptDA/torchhub/facebookresearch_dinov2_main/dinov2/layers/mlp.py
10
+ # ==============================================================================================================
11
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
12
+ # All rights reserved.
13
+ #
14
+ # This source code is licensed under the license found in the
15
+ # LICENSE file in the root directory of this source tree.
16
+
17
+ # References:
18
+ # https://github.com/facebookresearch/dino/blob/master/vision_transformer.py
19
+ # https://github.com/rwightman/pytorch-image-models/tree/master/timm/layers/mlp.py
20
+
21
+
22
+ from typing import Callable, Optional
23
+
24
+ from torch import Tensor, nn
25
+
26
+
27
+ class Mlp(nn.Module):
28
+ def __init__(
29
+ self,
30
+ in_features: int,
31
+ hidden_features: Optional[int] = None,
32
+ out_features: Optional[int] = None,
33
+ act_layer: Callable[..., nn.Module] = nn.GELU,
34
+ drop: float = 0.0,
35
+ bias: bool = True,
36
+ ) -> None:
37
+ super().__init__()
38
+ out_features = out_features or in_features
39
+ hidden_features = hidden_features or in_features
40
+ self.fc1 = nn.Linear(in_features, hidden_features, bias=bias)
41
+ self.act = act_layer()
42
+ self.fc2 = nn.Linear(hidden_features, out_features, bias=bias)
43
+ self.drop = nn.Dropout(drop)
44
+
45
+ def forward(self, x: Tensor) -> Tensor:
46
+ x = self.fc1(x)
47
+ x = self.act(x)
48
+ x = self.drop(x)
49
+ x = self.fc2(x)
50
+ x = self.drop(x)
51
+ return x
52
+
53
+
54
+ # ==============================================================================================================
55
+ # PromptDA/torchhub/facebookresearch_dinov2_main/dinov2/layers/patch_embed.py
56
+ # ==============================================================================================================
57
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
58
+ # All rights reserved.
59
+ #
60
+ # This source code is licensed under the license found in the
61
+ # LICENSE file in the root directory of this source tree.
62
+
63
+ # References:
64
+ # https://github.com/facebookresearch/dino/blob/master/vision_transformer.py
65
+ # https://github.com/rwightman/pytorch-image-models/tree/master/timm/layers/patch_embed.py
66
+
67
+ from typing import Callable, Optional, Tuple, Union
68
+
69
+ from torch import Tensor
70
+ import torch.nn as nn
71
+
72
+
73
+ def make_2tuple(x):
74
+ if isinstance(x, tuple):
75
+ assert len(x) == 2
76
+ return x
77
+
78
+ assert isinstance(x, int)
79
+ return (x, x)
80
+
81
+
82
+ class PatchEmbed(nn.Module):
83
+ """
84
+ 2D image to patch embedding: (B,C,H,W) -> (B,N,D)
85
+
86
+ Args:
87
+ img_size: Image size.
88
+ patch_size: Patch token size.
89
+ in_chans: Number of input image channels.
90
+ embed_dim: Number of linear projection output channels.
91
+ norm_layer: Normalization layer.
92
+ """
93
+
94
+ def __init__(
95
+ self,
96
+ img_size: Union[int, Tuple[int, int]] = 224,
97
+ patch_size: Union[int, Tuple[int, int]] = 16,
98
+ in_chans: int = 3,
99
+ embed_dim: int = 768,
100
+ norm_layer: Optional[Callable] = None,
101
+ flatten_embedding: bool = True,
102
+ ) -> None:
103
+ super().__init__()
104
+
105
+ image_HW = make_2tuple(img_size)
106
+ patch_HW = make_2tuple(patch_size)
107
+ patch_grid_size = (
108
+ image_HW[0] // patch_HW[0],
109
+ image_HW[1] // patch_HW[1],
110
+ )
111
+
112
+ self.img_size = image_HW
113
+ self.patch_size = patch_HW
114
+ self.patches_resolution = patch_grid_size
115
+ self.num_patches = patch_grid_size[0] * patch_grid_size[1]
116
+
117
+ self.in_chans = in_chans
118
+ self.embed_dim = embed_dim
119
+
120
+ self.flatten_embedding = flatten_embedding
121
+
122
+ self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_HW, stride=patch_HW)
123
+ self.norm = norm_layer(embed_dim) if norm_layer else nn.Identity()
124
+
125
+ def forward(self, x: Tensor) -> Tensor:
126
+ _, _, H, W = x.shape
127
+ patch_H, patch_W = self.patch_size
128
+
129
+ assert H % patch_H == 0, f"Input image height {H} is not a multiple of patch height {patch_H}"
130
+ assert W % patch_W == 0, f"Input image width {W} is not a multiple of patch width: {patch_W}"
131
+
132
+ x = self.proj(x) # B C H W
133
+ H, W = x.size(2), x.size(3)
134
+ x = x.flatten(2).transpose(1, 2) # B HW C
135
+ x = self.norm(x)
136
+ if not self.flatten_embedding:
137
+ x = x.reshape(-1, H, W, self.embed_dim) # B H W C
138
+ return x
139
+
140
+ def flops(self) -> float:
141
+ Ho, Wo = self.patches_resolution
142
+ flops = Ho * Wo * self.embed_dim * self.in_chans * (self.patch_size[0] * self.patch_size[1])
143
+ if self.norm is not None:
144
+ flops += Ho * Wo * self.embed_dim
145
+ return flops
146
+
147
+
148
+ # ==============================================================================================================
149
+ # PromptDA/torchhub/facebookresearch_dinov2_main/dinov2/layers/swiglu_ffn.py
150
+ # ==============================================================================================================
151
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
152
+ # All rights reserved.
153
+ #
154
+ # This source code is licensed under the license found in the
155
+ # LICENSE file in the root directory of this source tree.
156
+
157
+ from typing import Callable, Optional
158
+
159
+ from torch import Tensor, nn
160
+ import torch.nn.functional as F
161
+
162
+
163
+ class SwiGLUFFN(nn.Module):
164
+ def __init__(
165
+ self,
166
+ in_features: int,
167
+ hidden_features: Optional[int] = None,
168
+ out_features: Optional[int] = None,
169
+ act_layer: Callable[..., nn.Module] = None,
170
+ drop: float = 0.0,
171
+ bias: bool = True,
172
+ ) -> None:
173
+ super().__init__()
174
+ out_features = out_features or in_features
175
+ hidden_features = hidden_features or in_features
176
+ self.w12 = nn.Linear(in_features, 2 * hidden_features, bias=bias)
177
+ self.w3 = nn.Linear(hidden_features, out_features, bias=bias)
178
+
179
+ def forward(self, x: Tensor) -> Tensor:
180
+ x12 = self.w12(x)
181
+ x1, x2 = x12.chunk(2, dim=-1)
182
+ hidden = F.silu(x1) * x2
183
+ return self.w3(hidden)
184
+
185
+
186
+ try:
187
+ from xformers.ops import SwiGLU
188
+
189
+ XFORMERS_AVAILABLE = True
190
+ except ImportError:
191
+ SwiGLU = SwiGLUFFN
192
+ XFORMERS_AVAILABLE = False
193
+
194
+
195
+ class SwiGLUFFNFused(SwiGLU):
196
+ def __init__(
197
+ self,
198
+ in_features: int,
199
+ hidden_features: Optional[int] = None,
200
+ out_features: Optional[int] = None,
201
+ act_layer: Callable[..., nn.Module] = None,
202
+ drop: float = 0.0,
203
+ bias: bool = True,
204
+ ) -> None:
205
+ out_features = out_features or in_features
206
+ hidden_features = hidden_features or in_features
207
+ hidden_features = (int(hidden_features * 2 / 3) + 7) // 8 * 8
208
+ super().__init__(
209
+ in_features=in_features,
210
+ hidden_features=hidden_features,
211
+ out_features=out_features,
212
+ bias=bias,
213
+ )
214
+
215
+
216
+ # ==============================================================================================================
217
+ # PromptDA/torchhub/facebookresearch_dinov2_main/dinov2/layers/drop_path.py
218
+ # ==============================================================================================================
219
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
220
+ # All rights reserved.
221
+ #
222
+ # This source code is licensed under the license found in the
223
+ # LICENSE file in the root directory of this source tree.
224
+
225
+ # References:
226
+ # https://github.com/facebookresearch/dino/blob/master/vision_transformer.py
227
+ # https://github.com/rwightman/pytorch-image-models/tree/master/timm/layers/drop.py
228
+
229
+
230
+ from torch import nn
231
+
232
+
233
+ def drop_path(x, drop_prob: float = 0.0, training: bool = False):
234
+ if drop_prob == 0.0 or not training:
235
+ return x
236
+ keep_prob = 1 - drop_prob
237
+ shape = (x.shape[0],) + (1,) * (x.ndim - 1) # work with diff dim tensors, not just 2D ConvNets
238
+ random_tensor = x.new_empty(shape).bernoulli_(keep_prob)
239
+ if keep_prob > 0.0:
240
+ random_tensor.div_(keep_prob)
241
+ output = x * random_tensor
242
+ return output
243
+
244
+
245
+ class DropPath(nn.Module):
246
+ """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks)."""
247
+
248
+ def __init__(self, drop_prob=None):
249
+ super(DropPath, self).__init__()
250
+ self.drop_prob = drop_prob
251
+
252
+ def forward(self, x):
253
+ return drop_path(x, self.drop_prob, self.training)
254
+
255
+
256
+ # ==============================================================================================================
257
+ # PromptDA/torchhub/facebookresearch_dinov2_main/dinov2/layers/layer_scale.py
258
+ # ==============================================================================================================
259
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
260
+ # All rights reserved.
261
+ #
262
+ # This source code is licensed under the license found in the
263
+ # LICENSE file in the root directory of this source tree.
264
+
265
+ # Modified from: https://github.com/huggingface/pytorch-image-models/blob/main/timm/models/vision_transformer.py#L103-L110
266
+
267
+ from typing import Union
268
+
269
+ import torch
270
+ from torch import Tensor
271
+ from torch import nn
272
+
273
+
274
+ class LayerScale(nn.Module):
275
+ def __init__(
276
+ self,
277
+ dim: int,
278
+ init_values: Union[float, Tensor] = 1e-5,
279
+ inplace: bool = False,
280
+ ) -> None:
281
+ super().__init__()
282
+ self.inplace = inplace
283
+ self.gamma = nn.Parameter(init_values * torch.ones(dim))
284
+
285
+ def forward(self, x: Tensor) -> Tensor:
286
+ return x.mul_(self.gamma) if self.inplace else x * self.gamma
287
+
288
+
289
+ # ==============================================================================================================
290
+ # PromptDA/torchhub/facebookresearch_dinov2_main/dinov2/layers/attention.py
291
+ # ==============================================================================================================
292
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
293
+ # All rights reserved.
294
+ #
295
+ # This source code is licensed under the license found in the
296
+ # LICENSE file in the root directory of this source tree.
297
+
298
+ # References:
299
+ # https://github.com/facebookresearch/dino/blob/master/vision_transformer.py
300
+ # https://github.com/rwightman/pytorch-image-models/tree/master/timm/models/vision_transformer.py
301
+
302
+ import logging
303
+
304
+ from torch import Tensor
305
+ from torch import nn
306
+
307
+
308
+ logger = logging.getLogger("dinov2")
309
+
310
+
311
+ try:
312
+ from xformers.ops import memory_efficient_attention, unbind, fmha
313
+
314
+ XFORMERS_AVAILABLE = True
315
+ except ImportError:
316
+ logger.warning("xFormers not available")
317
+ XFORMERS_AVAILABLE = False
318
+
319
+
320
+ class Attention(nn.Module):
321
+ def __init__(
322
+ self,
323
+ dim: int,
324
+ num_heads: int = 8,
325
+ qkv_bias: bool = False,
326
+ proj_bias: bool = True,
327
+ attn_drop: float = 0.0,
328
+ proj_drop: float = 0.0,
329
+ ) -> None:
330
+ super().__init__()
331
+ self.num_heads = num_heads
332
+ head_dim = dim // num_heads
333
+ self.scale = head_dim**-0.5
334
+
335
+ self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)
336
+ self.attn_drop = nn.Dropout(attn_drop)
337
+ self.proj = nn.Linear(dim, dim, bias=proj_bias)
338
+ self.proj_drop = nn.Dropout(proj_drop)
339
+
340
+ def forward(self, x: Tensor) -> Tensor:
341
+ B, N, C = x.shape
342
+ qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4)
343
+
344
+ q, k, v = qkv[0] * self.scale, qkv[1], qkv[2]
345
+ attn = q @ k.transpose(-2, -1)
346
+
347
+ attn = attn.softmax(dim=-1)
348
+ attn = self.attn_drop(attn)
349
+
350
+ x = (attn @ v).transpose(1, 2).reshape(B, N, C)
351
+ x = self.proj(x)
352
+ x = self.proj_drop(x)
353
+ return x
354
+
355
+
356
+ class MemEffAttention(Attention):
357
+ def forward(self, x: Tensor, attn_bias=None) -> Tensor:
358
+ if not XFORMERS_AVAILABLE:
359
+ assert attn_bias is None, "xFormers is required for nested tensors usage"
360
+ return super().forward(x)
361
+
362
+ B, N, C = x.shape
363
+ qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads)
364
+
365
+ q, k, v = unbind(qkv, 2)
366
+
367
+ x = memory_efficient_attention(q, k, v, attn_bias=attn_bias)
368
+ x = x.reshape([B, N, C])
369
+
370
+ x = self.proj(x)
371
+ x = self.proj_drop(x)
372
+ return x
373
+
374
+
375
+ # ==============================================================================================================
376
+ # PromptDA/torchhub/facebookresearch_dinov2_main/dinov2/layers/block.py
377
+ # ==============================================================================================================
378
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
379
+ # All rights reserved.
380
+ #
381
+ # This source code is licensed under the license found in the
382
+ # LICENSE file in the root directory of this source tree.
383
+
384
+ # References:
385
+ # https://github.com/facebookresearch/dino/blob/master/vision_transformer.py
386
+ # https://github.com/rwightman/pytorch-image-models/tree/master/timm/layers/patch_embed.py
387
+
388
+ import logging
389
+ from typing import Callable, List, Any, Tuple, Dict
390
+
391
+ import torch
392
+ from torch import nn, Tensor
393
+
394
+
395
+
396
+ logger = logging.getLogger("dinov2")
397
+
398
+
399
+ try:
400
+ from xformers.ops import fmha
401
+ from xformers.ops import scaled_index_add, index_select_cat
402
+
403
+ XFORMERS_AVAILABLE = True
404
+ except ImportError:
405
+ logger.warning("xFormers not available")
406
+ XFORMERS_AVAILABLE = False
407
+
408
+
409
+ class Block(nn.Module):
410
+ def __init__(
411
+ self,
412
+ dim: int,
413
+ num_heads: int,
414
+ mlp_ratio: float = 4.0,
415
+ qkv_bias: bool = False,
416
+ proj_bias: bool = True,
417
+ ffn_bias: bool = True,
418
+ drop: float = 0.0,
419
+ attn_drop: float = 0.0,
420
+ init_values=None,
421
+ drop_path: float = 0.0,
422
+ act_layer: Callable[..., nn.Module] = nn.GELU,
423
+ norm_layer: Callable[..., nn.Module] = nn.LayerNorm,
424
+ attn_class: Callable[..., nn.Module] = Attention,
425
+ ffn_layer: Callable[..., nn.Module] = Mlp,
426
+ ) -> None:
427
+ super().__init__()
428
+ # print(f"biases: qkv: {qkv_bias}, proj: {proj_bias}, ffn: {ffn_bias}")
429
+ self.norm1 = norm_layer(dim)
430
+ self.attn = attn_class(
431
+ dim,
432
+ num_heads=num_heads,
433
+ qkv_bias=qkv_bias,
434
+ proj_bias=proj_bias,
435
+ attn_drop=attn_drop,
436
+ proj_drop=drop,
437
+ )
438
+ self.ls1 = LayerScale(dim, init_values=init_values) if init_values else nn.Identity()
439
+ self.drop_path1 = DropPath(drop_path) if drop_path > 0.0 else nn.Identity()
440
+
441
+ self.norm2 = norm_layer(dim)
442
+ mlp_hidden_dim = int(dim * mlp_ratio)
443
+ self.mlp = ffn_layer(
444
+ in_features=dim,
445
+ hidden_features=mlp_hidden_dim,
446
+ act_layer=act_layer,
447
+ drop=drop,
448
+ bias=ffn_bias,
449
+ )
450
+ self.ls2 = LayerScale(dim, init_values=init_values) if init_values else nn.Identity()
451
+ self.drop_path2 = DropPath(drop_path) if drop_path > 0.0 else nn.Identity()
452
+
453
+ self.sample_drop_ratio = drop_path
454
+
455
+ def forward(self, x: Tensor) -> Tensor:
456
+ def attn_residual_func(x: Tensor) -> Tensor:
457
+ return self.ls1(self.attn(self.norm1(x)))
458
+
459
+ def ffn_residual_func(x: Tensor) -> Tensor:
460
+ return self.ls2(self.mlp(self.norm2(x)))
461
+
462
+ if self.training and self.sample_drop_ratio > 0.1:
463
+ # the overhead is compensated only for a drop path rate larger than 0.1
464
+ x = drop_add_residual_stochastic_depth(
465
+ x,
466
+ residual_func=attn_residual_func,
467
+ sample_drop_ratio=self.sample_drop_ratio,
468
+ )
469
+ x = drop_add_residual_stochastic_depth(
470
+ x,
471
+ residual_func=ffn_residual_func,
472
+ sample_drop_ratio=self.sample_drop_ratio,
473
+ )
474
+ elif self.training and self.sample_drop_ratio > 0.0:
475
+ x = x + self.drop_path1(attn_residual_func(x))
476
+ x = x + self.drop_path1(ffn_residual_func(x)) # FIXME: drop_path2
477
+ else:
478
+ x = x + attn_residual_func(x)
479
+ x = x + ffn_residual_func(x)
480
+ return x
481
+
482
+
483
+ def drop_add_residual_stochastic_depth(
484
+ x: Tensor,
485
+ residual_func: Callable[[Tensor], Tensor],
486
+ sample_drop_ratio: float = 0.0,
487
+ ) -> Tensor:
488
+ # 1) extract subset using permutation
489
+ b, n, d = x.shape
490
+ sample_subset_size = max(int(b * (1 - sample_drop_ratio)), 1)
491
+ brange = (torch.randperm(b, device=x.device))[:sample_subset_size]
492
+ x_subset = x[brange]
493
+
494
+ # 2) apply residual_func to get residual
495
+ residual = residual_func(x_subset)
496
+
497
+ x_flat = x.flatten(1)
498
+ residual = residual.flatten(1)
499
+
500
+ residual_scale_factor = b / sample_subset_size
501
+
502
+ # 3) add the residual
503
+ x_plus_residual = torch.index_add(x_flat, 0, brange, residual.to(dtype=x.dtype), alpha=residual_scale_factor)
504
+ return x_plus_residual.view_as(x)
505
+
506
+
507
+ def get_branges_scales(x, sample_drop_ratio=0.0):
508
+ b, n, d = x.shape
509
+ sample_subset_size = max(int(b * (1 - sample_drop_ratio)), 1)
510
+ brange = (torch.randperm(b, device=x.device))[:sample_subset_size]
511
+ residual_scale_factor = b / sample_subset_size
512
+ return brange, residual_scale_factor
513
+
514
+
515
+ def add_residual(x, brange, residual, residual_scale_factor, scaling_vector=None):
516
+ if scaling_vector is None:
517
+ x_flat = x.flatten(1)
518
+ residual = residual.flatten(1)
519
+ x_plus_residual = torch.index_add(x_flat, 0, brange, residual.to(dtype=x.dtype), alpha=residual_scale_factor)
520
+ else:
521
+ x_plus_residual = scaled_index_add(
522
+ x, brange, residual.to(dtype=x.dtype), scaling=scaling_vector, alpha=residual_scale_factor
523
+ )
524
+ return x_plus_residual
525
+
526
+
527
+ attn_bias_cache: Dict[Tuple, Any] = {}
528
+
529
+
530
+ def get_attn_bias_and_cat(x_list, branges=None):
531
+ """
532
+ this will perform the index select, cat the tensors, and provide the attn_bias from cache
533
+ """
534
+ batch_sizes = [b.shape[0] for b in branges] if branges is not None else [x.shape[0] for x in x_list]
535
+ all_shapes = tuple((b, x.shape[1]) for b, x in zip(batch_sizes, x_list))
536
+ if all_shapes not in attn_bias_cache.keys():
537
+ seqlens = []
538
+ for b, x in zip(batch_sizes, x_list):
539
+ for _ in range(b):
540
+ seqlens.append(x.shape[1])
541
+ attn_bias = fmha.BlockDiagonalMask.from_seqlens(seqlens)
542
+ attn_bias._batch_sizes = batch_sizes
543
+ attn_bias_cache[all_shapes] = attn_bias
544
+
545
+ if branges is not None:
546
+ cat_tensors = index_select_cat([x.flatten(1) for x in x_list], branges).view(1, -1, x_list[0].shape[-1])
547
+ else:
548
+ tensors_bs1 = tuple(x.reshape([1, -1, *x.shape[2:]]) for x in x_list)
549
+ cat_tensors = torch.cat(tensors_bs1, dim=1)
550
+
551
+ return attn_bias_cache[all_shapes], cat_tensors
552
+
553
+
554
+ def drop_add_residual_stochastic_depth_list(
555
+ x_list: List[Tensor],
556
+ residual_func: Callable[[Tensor, Any], Tensor],
557
+ sample_drop_ratio: float = 0.0,
558
+ scaling_vector=None,
559
+ ) -> Tensor:
560
+ # 1) generate random set of indices for dropping samples in the batch
561
+ branges_scales = [get_branges_scales(x, sample_drop_ratio=sample_drop_ratio) for x in x_list]
562
+ branges = [s[0] for s in branges_scales]
563
+ residual_scale_factors = [s[1] for s in branges_scales]
564
+
565
+ # 2) get attention bias and index+concat the tensors
566
+ attn_bias, x_cat = get_attn_bias_and_cat(x_list, branges)
567
+
568
+ # 3) apply residual_func to get residual, and split the result
569
+ residual_list = attn_bias.split(residual_func(x_cat, attn_bias=attn_bias)) # type: ignore
570
+
571
+ outputs = []
572
+ for x, brange, residual, residual_scale_factor in zip(x_list, branges, residual_list, residual_scale_factors):
573
+ outputs.append(add_residual(x, brange, residual, residual_scale_factor, scaling_vector).view_as(x))
574
+ return outputs
575
+
576
+
577
+ class NestedTensorBlock(Block):
578
+ def forward_nested(self, x_list: List[Tensor]) -> List[Tensor]:
579
+ """
580
+ x_list contains a list of tensors to nest together and run
581
+ """
582
+ assert isinstance(self.attn, MemEffAttention)
583
+
584
+ if self.training and self.sample_drop_ratio > 0.0:
585
+
586
+ def attn_residual_func(x: Tensor, attn_bias=None) -> Tensor:
587
+ return self.attn(self.norm1(x), attn_bias=attn_bias)
588
+
589
+ def ffn_residual_func(x: Tensor, attn_bias=None) -> Tensor:
590
+ return self.mlp(self.norm2(x))
591
+
592
+ x_list = drop_add_residual_stochastic_depth_list(
593
+ x_list,
594
+ residual_func=attn_residual_func,
595
+ sample_drop_ratio=self.sample_drop_ratio,
596
+ scaling_vector=self.ls1.gamma if isinstance(self.ls1, LayerScale) else None,
597
+ )
598
+ x_list = drop_add_residual_stochastic_depth_list(
599
+ x_list,
600
+ residual_func=ffn_residual_func,
601
+ sample_drop_ratio=self.sample_drop_ratio,
602
+ scaling_vector=self.ls2.gamma if isinstance(self.ls1, LayerScale) else None,
603
+ )
604
+ return x_list
605
+ else:
606
+
607
+ def attn_residual_func(x: Tensor, attn_bias=None) -> Tensor:
608
+ return self.ls1(self.attn(self.norm1(x), attn_bias=attn_bias))
609
+
610
+ def ffn_residual_func(x: Tensor, attn_bias=None) -> Tensor:
611
+ return self.ls2(self.mlp(self.norm2(x)))
612
+
613
+ attn_bias, x = get_attn_bias_and_cat(x_list)
614
+ x = x + attn_residual_func(x, attn_bias=attn_bias)
615
+ x = x + ffn_residual_func(x)
616
+ return attn_bias.split(x)
617
+
618
+ def forward(self, x_or_x_list):
619
+ if isinstance(x_or_x_list, Tensor):
620
+ return super().forward(x_or_x_list)
621
+ elif isinstance(x_or_x_list, list):
622
+ assert XFORMERS_AVAILABLE, "Please install xFormers for nested tensors usage"
623
+ return self.forward_nested(x_or_x_list)
624
+ else:
625
+ raise AssertionError
626
+
627
+
628
+ # ==============================================================================================================
629
+ # PromptDA/torchhub/facebookresearch_dinov2_main/vision_transformer.py
630
+ # ==============================================================================================================
631
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
632
+ #
633
+ # This source code is licensed under the Apache License, Version 2.0
634
+ # found in the LICENSE file in the root directory of this source tree.
635
+
636
+ # References:
637
+ # https://github.com/facebookresearch/dino/blob/main/vision_transformer.py
638
+ # https://github.com/rwightman/pytorch-image-models/tree/master/timm/models/vision_transformer.py
639
+
640
+ from functools import partial
641
+ import math
642
+ import logging
643
+ from typing import Sequence, Tuple, Union, Callable
644
+
645
+ import torch
646
+ import torch.nn as nn
647
+ import torch.utils.checkpoint
648
+ from torch.nn.init import trunc_normal_
649
+
650
+
651
+
652
+ logger = logging.getLogger("dinov2")
653
+
654
+
655
+ def named_apply(fn: Callable, module: nn.Module, name="", depth_first=True, include_root=False) -> nn.Module:
656
+ if not depth_first and include_root:
657
+ fn(module=module, name=name)
658
+ for child_name, child_module in module.named_children():
659
+ child_name = ".".join((name, child_name)) if name else child_name
660
+ named_apply(fn=fn, module=child_module, name=child_name, depth_first=depth_first, include_root=True)
661
+ if depth_first and include_root:
662
+ fn(module=module, name=name)
663
+ return module
664
+
665
+
666
+ class BlockChunk(nn.ModuleList):
667
+ def forward(self, x):
668
+ for b in self:
669
+ x = b(x)
670
+ return x
671
+
672
+
673
+ class DinoVisionTransformer(nn.Module):
674
+ def __init__(
675
+ self,
676
+ img_size=224,
677
+ patch_size=16,
678
+ in_chans=3,
679
+ embed_dim=768,
680
+ depth=12,
681
+ num_heads=12,
682
+ mlp_ratio=4.0,
683
+ qkv_bias=True,
684
+ ffn_bias=True,
685
+ proj_bias=True,
686
+ drop_path_rate=0.0,
687
+ drop_path_uniform=False,
688
+ init_values=None, # for layerscale: None or 0 => no layerscale
689
+ embed_layer=PatchEmbed,
690
+ act_layer=nn.GELU,
691
+ block_fn=NestedTensorBlock,
692
+ ffn_layer="mlp",
693
+ block_chunks=1,
694
+ num_register_tokens=0,
695
+ interpolate_antialias=False,
696
+ interpolate_offset=0.1,
697
+ ):
698
+ """
699
+ Args:
700
+ img_size (int, tuple): input image size
701
+ patch_size (int, tuple): patch size
702
+ in_chans (int): number of input channels
703
+ embed_dim (int): embedding dimension
704
+ depth (int): depth of transformer
705
+ num_heads (int): number of attention heads
706
+ mlp_ratio (int): ratio of mlp hidden dim to embedding dim
707
+ qkv_bias (bool): enable bias for qkv if True
708
+ proj_bias (bool): enable bias for proj in attn if True
709
+ ffn_bias (bool): enable bias for ffn if True
710
+ drop_path_rate (float): stochastic depth rate
711
+ drop_path_uniform (bool): apply uniform drop rate across blocks
712
+ weight_init (str): weight init scheme
713
+ init_values (float): layer-scale init values
714
+ embed_layer (nn.Module): patch embedding layer
715
+ act_layer (nn.Module): MLP activation layer
716
+ block_fn (nn.Module): transformer block class
717
+ ffn_layer (str): "mlp", "swiglu", "swiglufused" or "identity"
718
+ block_chunks: (int) split block sequence into block_chunks units for FSDP wrap
719
+ num_register_tokens: (int) number of extra cls tokens (so-called "registers")
720
+ interpolate_antialias: (str) flag to apply anti-aliasing when interpolating positional embeddings
721
+ interpolate_offset: (float) work-around offset to apply when interpolating positional embeddings
722
+ """
723
+ super().__init__()
724
+ norm_layer = partial(nn.LayerNorm, eps=1e-6)
725
+
726
+ self.num_features = self.embed_dim = embed_dim # num_features for consistency with other models
727
+ self.num_tokens = 1
728
+ self.n_blocks = depth
729
+ self.num_heads = num_heads
730
+ self.patch_size = patch_size
731
+ self.num_register_tokens = num_register_tokens
732
+ self.interpolate_antialias = interpolate_antialias
733
+ self.interpolate_offset = interpolate_offset
734
+
735
+ self.patch_embed = embed_layer(img_size=img_size, patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim)
736
+ num_patches = self.patch_embed.num_patches
737
+
738
+ self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim))
739
+ self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + self.num_tokens, embed_dim))
740
+ assert num_register_tokens >= 0
741
+ self.register_tokens = (
742
+ nn.Parameter(torch.zeros(1, num_register_tokens, embed_dim)) if num_register_tokens else None
743
+ )
744
+
745
+ if drop_path_uniform is True:
746
+ dpr = [drop_path_rate] * depth
747
+ else:
748
+ dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth)] # stochastic depth decay rule
749
+
750
+ if ffn_layer == "mlp":
751
+ logger.info("using MLP layer as FFN")
752
+ ffn_layer = Mlp
753
+ elif ffn_layer == "swiglufused" or ffn_layer == "swiglu":
754
+ logger.info("using SwiGLU layer as FFN")
755
+ ffn_layer = SwiGLUFFNFused
756
+ elif ffn_layer == "identity":
757
+ logger.info("using Identity layer as FFN")
758
+
759
+ def f(*args, **kwargs):
760
+ return nn.Identity()
761
+
762
+ ffn_layer = f
763
+ else:
764
+ raise NotImplementedError
765
+
766
+ blocks_list = [
767
+ block_fn(
768
+ dim=embed_dim,
769
+ num_heads=num_heads,
770
+ mlp_ratio=mlp_ratio,
771
+ qkv_bias=qkv_bias,
772
+ proj_bias=proj_bias,
773
+ ffn_bias=ffn_bias,
774
+ drop_path=dpr[i],
775
+ norm_layer=norm_layer,
776
+ act_layer=act_layer,
777
+ ffn_layer=ffn_layer,
778
+ init_values=init_values,
779
+ )
780
+ for i in range(depth)
781
+ ]
782
+ if block_chunks > 0:
783
+ self.chunked_blocks = True
784
+ chunked_blocks = []
785
+ chunksize = depth // block_chunks
786
+ for i in range(0, depth, chunksize):
787
+ # this is to keep the block index consistent if we chunk the block list
788
+ chunked_blocks.append([nn.Identity()] * i + blocks_list[i : i + chunksize])
789
+ self.blocks = nn.ModuleList([BlockChunk(p) for p in chunked_blocks])
790
+ else:
791
+ self.chunked_blocks = False
792
+ self.blocks = nn.ModuleList(blocks_list)
793
+
794
+ self.norm = norm_layer(embed_dim)
795
+ self.head = nn.Identity()
796
+
797
+ self.mask_token = nn.Parameter(torch.zeros(1, embed_dim))
798
+
799
+ self.init_weights()
800
+
801
+ def init_weights(self):
802
+ trunc_normal_(self.pos_embed, std=0.02)
803
+ nn.init.normal_(self.cls_token, std=1e-6)
804
+ if self.register_tokens is not None:
805
+ nn.init.normal_(self.register_tokens, std=1e-6)
806
+ named_apply(init_weights_vit_timm, self)
807
+
808
+ def interpolate_pos_encoding(self, x, w, h):
809
+ previous_dtype = x.dtype
810
+ npatch = x.shape[1] - 1
811
+ N = self.pos_embed.shape[1] - 1
812
+ if npatch == N and w == h:
813
+ return self.pos_embed
814
+ pos_embed = self.pos_embed.float()
815
+ class_pos_embed = pos_embed[:, 0]
816
+ patch_pos_embed = pos_embed[:, 1:]
817
+ dim = x.shape[-1]
818
+ w0 = w // self.patch_size
819
+ h0 = h // self.patch_size
820
+ # we add a small number to avoid floating point error in the interpolation
821
+ # see discussion at https://github.com/facebookresearch/dino/issues/8
822
+ # DINOv2 with register modify the interpolate_offset from 0.1 to 0.0
823
+ w0, h0 = w0 + self.interpolate_offset, h0 + self.interpolate_offset
824
+ # w0, h0 = w0 + 0.1, h0 + 0.1
825
+
826
+ sqrt_N = math.sqrt(N)
827
+ sx, sy = float(w0) / sqrt_N, float(h0) / sqrt_N
828
+ patch_pos_embed = nn.functional.interpolate(
829
+ patch_pos_embed.reshape(1, int(sqrt_N), int(sqrt_N), dim).permute(0, 3, 1, 2),
830
+ scale_factor=(sx, sy),
831
+ # (int(w0), int(h0)), # to solve the upsampling shape issue
832
+ mode="bicubic",
833
+ antialias=self.interpolate_antialias
834
+ )
835
+
836
+ assert int(w0) == patch_pos_embed.shape[-2]
837
+ assert int(h0) == patch_pos_embed.shape[-1]
838
+ patch_pos_embed = patch_pos_embed.permute(0, 2, 3, 1).view(1, -1, dim)
839
+ return torch.cat((class_pos_embed.unsqueeze(0), patch_pos_embed), dim=1).to(previous_dtype)
840
+
841
+ def prepare_tokens_with_masks(self, x, masks=None):
842
+ B, nc, w, h = x.shape
843
+ x = self.patch_embed(x)
844
+ if masks is not None:
845
+ x = torch.where(masks.unsqueeze(-1), self.mask_token.to(x.dtype).unsqueeze(0), x)
846
+
847
+ x = torch.cat((self.cls_token.expand(x.shape[0], -1, -1), x), dim=1)
848
+ x = x + self.interpolate_pos_encoding(x, w, h)
849
+
850
+ if self.register_tokens is not None:
851
+ x = torch.cat(
852
+ (
853
+ x[:, :1],
854
+ self.register_tokens.expand(x.shape[0], -1, -1),
855
+ x[:, 1:],
856
+ ),
857
+ dim=1,
858
+ )
859
+
860
+ return x
861
+
862
+ def forward_features_list(self, x_list, masks_list):
863
+ x = [self.prepare_tokens_with_masks(x, masks) for x, masks in zip(x_list, masks_list)]
864
+ for blk in self.blocks:
865
+ x = blk(x)
866
+
867
+ all_x = x
868
+ output = []
869
+ for x, masks in zip(all_x, masks_list):
870
+ x_norm = self.norm(x)
871
+ output.append(
872
+ {
873
+ "x_norm_clstoken": x_norm[:, 0],
874
+ "x_norm_regtokens": x_norm[:, 1 : self.num_register_tokens + 1],
875
+ "x_norm_patchtokens": x_norm[:, self.num_register_tokens + 1 :],
876
+ "x_prenorm": x,
877
+ "masks": masks,
878
+ }
879
+ )
880
+ return output
881
+
882
+ def forward_features(self, x, masks=None):
883
+ if isinstance(x, list):
884
+ return self.forward_features_list(x, masks)
885
+
886
+ x = self.prepare_tokens_with_masks(x, masks)
887
+
888
+ for blk in self.blocks:
889
+ x = blk(x)
890
+
891
+ x_norm = self.norm(x)
892
+ return {
893
+ "x_norm_clstoken": x_norm[:, 0],
894
+ "x_norm_regtokens": x_norm[:, 1 : self.num_register_tokens + 1],
895
+ "x_norm_patchtokens": x_norm[:, self.num_register_tokens + 1 :],
896
+ "x_prenorm": x,
897
+ "masks": masks,
898
+ }
899
+
900
+ def _get_intermediate_layers_not_chunked(self, x, n=1):
901
+ x = self.prepare_tokens_with_masks(x)
902
+ # If n is an int, take the n last blocks. If it's a list, take them
903
+ output, total_block_len = [], len(self.blocks)
904
+ blocks_to_take = range(total_block_len - n, total_block_len) if isinstance(n, int) else n
905
+ for i, blk in enumerate(self.blocks):
906
+ x = blk(x)
907
+ if i in blocks_to_take:
908
+ output.append(x)
909
+ assert len(output) == len(blocks_to_take), f"only {len(output)} / {len(blocks_to_take)} blocks found"
910
+ return output
911
+
912
+ def _get_intermediate_layers_chunked(self, x, n=1):
913
+ x = self.prepare_tokens_with_masks(x)
914
+ output, i, total_block_len = [], 0, len(self.blocks[-1])
915
+ # If n is an int, take the n last blocks. If it's a list, take them
916
+ blocks_to_take = range(total_block_len - n, total_block_len) if isinstance(n, int) else n
917
+ for block_chunk in self.blocks:
918
+ for blk in block_chunk[i:]: # Passing the nn.Identity()
919
+ x = blk(x)
920
+ if i in blocks_to_take:
921
+ output.append(x)
922
+ i += 1
923
+ assert len(output) == len(blocks_to_take), f"only {len(output)} / {len(blocks_to_take)} blocks found"
924
+ return output
925
+
926
+ def get_intermediate_layers(
927
+ self,
928
+ x: torch.Tensor,
929
+ n: Union[int, Sequence] = 1, # Layers or n last layers to take
930
+ reshape: bool = False,
931
+ return_class_token: bool = False,
932
+ norm=True,
933
+ ) -> Tuple[Union[torch.Tensor, Tuple[torch.Tensor]]]:
934
+ if self.chunked_blocks:
935
+ outputs = self._get_intermediate_layers_chunked(x, n)
936
+ else:
937
+ outputs = self._get_intermediate_layers_not_chunked(x, n)
938
+ if norm:
939
+ outputs = [self.norm(out) for out in outputs]
940
+ class_tokens = [out[:, 0] for out in outputs]
941
+ outputs = [out[:, 1 + self.num_register_tokens:] for out in outputs]
942
+ if reshape:
943
+ B, _, w, h = x.shape
944
+ outputs = [
945
+ out.reshape(B, w // self.patch_size, h // self.patch_size, -1).permute(0, 3, 1, 2).contiguous()
946
+ for out in outputs
947
+ ]
948
+ if return_class_token:
949
+ return tuple(zip(outputs, class_tokens))
950
+ return tuple(outputs)
951
+
952
+ def forward(self, *args, is_training=False, **kwargs):
953
+ ret = self.forward_features(*args, **kwargs)
954
+ if is_training:
955
+ return ret
956
+ else:
957
+ return self.head(ret["x_norm_clstoken"])
958
+
959
+
960
+ def init_weights_vit_timm(module: nn.Module, name: str = ""):
961
+ """ViT weight initialization, original timm impl (for reproducibility)"""
962
+ if isinstance(module, nn.Linear):
963
+ trunc_normal_(module.weight, std=0.02)
964
+ if module.bias is not None:
965
+ nn.init.zeros_(module.bias)
966
+
967
+
968
+ def vit_small(patch_size=16, num_register_tokens=0, **kwargs):
969
+ model = DinoVisionTransformer(
970
+ patch_size=patch_size,
971
+ embed_dim=384,
972
+ depth=12,
973
+ num_heads=6,
974
+ mlp_ratio=4,
975
+ block_fn=partial(NestedTensorBlock, attn_class=MemEffAttention),
976
+ num_register_tokens=num_register_tokens,
977
+ **kwargs,
978
+ )
979
+ return model
980
+
981
+
982
+ def vit_base(patch_size=16, num_register_tokens=0, **kwargs):
983
+ model = DinoVisionTransformer(
984
+ patch_size=patch_size,
985
+ embed_dim=768,
986
+ depth=12,
987
+ num_heads=12,
988
+ mlp_ratio=4,
989
+ block_fn=partial(NestedTensorBlock, attn_class=MemEffAttention),
990
+ num_register_tokens=num_register_tokens,
991
+ **kwargs,
992
+ )
993
+ return model
994
+
995
+
996
+ def vit_large(patch_size=16, num_register_tokens=0, **kwargs):
997
+ model = DinoVisionTransformer(
998
+ patch_size=patch_size,
999
+ embed_dim=1024,
1000
+ depth=24,
1001
+ num_heads=16,
1002
+ mlp_ratio=4,
1003
+ block_fn=partial(NestedTensorBlock, attn_class=MemEffAttention),
1004
+ num_register_tokens=num_register_tokens,
1005
+ **kwargs,
1006
+ )
1007
+ return model
1008
+
1009
+
1010
+ def vit_giant2(patch_size=16, num_register_tokens=0, **kwargs):
1011
+ """
1012
+ Close to ViT-giant, with embed-dim 1536 and 24 heads => embed-dim per head 64
1013
+ """
1014
+ model = DinoVisionTransformer(
1015
+ patch_size=patch_size,
1016
+ embed_dim=1536,
1017
+ depth=40,
1018
+ num_heads=24,
1019
+ mlp_ratio=4,
1020
+ block_fn=partial(NestedTensorBlock, attn_class=MemEffAttention),
1021
+ num_register_tokens=num_register_tokens,
1022
+ **kwargs,
1023
+ )
1024
+ return model
promptda_model.py ADDED
@@ -0,0 +1,675 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ruff: noqa
2
+ # fmt: off
3
+ """Prompt Depth Anything, vendored verbatim from DepthAnything/PromptDA @ 9161547ca7151e14fcc8f490ad3cc02fa9437483 (promptda/ and the local torchhub
4
+ copy of facebookresearch/dinov2 it loads): the files below concatenated, package-internal imports replaced by
5
+ relative imports of the other vendored files (generated by scripts/model_ports/common/vendor_flat.py; do not edit by hand). Code license: Apache-2.0."""
6
+
7
+
8
+ # ==============================================================================================================
9
+ # PromptDA/promptda/utils/logger.py
10
+ # ==============================================================================================================
11
+ import os
12
+
13
+
14
+ class Log:
15
+ log_on = True # fast switch
16
+ used_tags = dict() # To keep track of used tags
17
+ _is_main_cached = None # Cache to store the main process check result
18
+
19
+ @staticmethod
20
+ def is_main_process():
21
+ if Log._is_main_cached is not None:
22
+ return Log._is_main_cached
23
+ try:
24
+ from pytorch_lightning.utilities import rank_zero_only
25
+ if rank_zero_only.rank == 0:
26
+ Log._is_main_cached = True
27
+ else:
28
+ Log._is_main_cached = False
29
+ except:
30
+ Log._is_main_cached = True
31
+ return Log._is_main_cached
32
+
33
+ @staticmethod
34
+ def _should_log(tag):
35
+ """
36
+ Determine if the log information should be recorded.
37
+ Conditions: log function is enabled, current process is the main process, and the tag has not been used.
38
+ """
39
+ if not Log.log_on:
40
+ return False
41
+ if not Log.is_main_process():
42
+ return False
43
+ if tag is None:
44
+ return True
45
+ if '__' in tag:
46
+ num = int(tag.split('__')[-1])
47
+ tag = tag.split('__')[0] # can output num same information
48
+ else:
49
+ num = 3 # default 3
50
+
51
+ if tag not in Log.used_tags:
52
+ Log.used_tags[tag] = num
53
+ Log.used_tags[tag] -= 1
54
+ if Log.used_tags[tag] >= 0:
55
+ return True
56
+ else:
57
+ return False
58
+
59
+ @staticmethod
60
+ def info(*args, tag=None):
61
+ """
62
+ Output INFO level log information.
63
+ """
64
+ if Log._should_log(tag):
65
+ print("\033[1;32m[INFO]\033[0;0m", *args)
66
+
67
+ @staticmethod
68
+ def warn(*args, tag=None):
69
+ """
70
+ Output WARN level log information.
71
+ """
72
+ if Log._should_log(tag):
73
+ print("\033[1;35m[WARN]\033[0;0m", *args)
74
+
75
+ @staticmethod
76
+ def error(*args, tag=None):
77
+ print("\033[1;31m[ERROR]\033[0;0m", *args)
78
+
79
+ @staticmethod
80
+ def debug(*args, tag=None):
81
+ """
82
+ Output DEBUG level log information.
83
+ """
84
+ if Log._should_log(tag) and 'HT_DEBUG' in os.environ and os.environ['HT_DEBUG'] == '1':
85
+ print("\033[1;33m[DEBUG]\033[0;0m", *args)
86
+
87
+
88
+ # ==============================================================================================================
89
+ # PromptDA/promptda/model/blocks.py
90
+ # ==============================================================================================================
91
+ import torch.nn as nn
92
+ import torch
93
+ import torch.nn.functional as F
94
+ import os
95
+ import numpy as np
96
+
97
+
98
+ def _make_fusion_block(features, use_bn, size=None):
99
+ return FeatureFusionDepthBlock(
100
+ features,
101
+ nn.ReLU(False),
102
+ deconv=False,
103
+ bn=use_bn,
104
+ expand=False,
105
+ align_corners=True,
106
+ size=size,
107
+ )
108
+
109
+
110
+ def _make_scratch(in_shape, out_shape, groups=1, expand=False):
111
+ scratch = nn.Module()
112
+
113
+ out_shape1 = out_shape
114
+ out_shape2 = out_shape
115
+ out_shape3 = out_shape
116
+ if len(in_shape) >= 4:
117
+ out_shape4 = out_shape
118
+
119
+ if expand:
120
+ out_shape1 = out_shape
121
+ out_shape2 = out_shape*2
122
+ out_shape3 = out_shape*4
123
+ if len(in_shape) >= 4:
124
+ out_shape4 = out_shape*8
125
+
126
+ scratch.layer1_rn = nn.Conv2d(
127
+ in_shape[0], out_shape1, kernel_size=3, stride=1, padding=1, bias=False, groups=groups
128
+ )
129
+ scratch.layer2_rn = nn.Conv2d(
130
+ in_shape[1], out_shape2, kernel_size=3, stride=1, padding=1, bias=False, groups=groups
131
+ )
132
+ scratch.layer3_rn = nn.Conv2d(
133
+ in_shape[2], out_shape3, kernel_size=3, stride=1, padding=1, bias=False, groups=groups
134
+ )
135
+ if len(in_shape) >= 4:
136
+ scratch.layer4_rn = nn.Conv2d(
137
+ in_shape[3], out_shape4, kernel_size=3, stride=1, padding=1, bias=False, groups=groups
138
+ )
139
+
140
+ return scratch
141
+
142
+
143
+ class ResidualConvUnit(nn.Module):
144
+ """Residual convolution module.
145
+ """
146
+
147
+ def __init__(self, features, activation, bn):
148
+ """Init.
149
+
150
+ Args:
151
+ features (int): number of features
152
+ """
153
+ super().__init__()
154
+
155
+ self.bn = bn
156
+
157
+ self.groups = 1
158
+
159
+ self.conv1 = nn.Conv2d(
160
+ features, features, kernel_size=3, stride=1, padding=1, bias=True, groups=self.groups
161
+ )
162
+
163
+ self.conv2 = nn.Conv2d(
164
+ features, features, kernel_size=3, stride=1, padding=1, bias=True, groups=self.groups
165
+ )
166
+
167
+ if self.bn == True:
168
+ self.bn1 = nn.BatchNorm2d(features)
169
+ self.bn2 = nn.BatchNorm2d(features)
170
+
171
+ self.activation = activation
172
+
173
+ self.skip_add = nn.quantized.FloatFunctional()
174
+
175
+ def forward(self, x):
176
+ """Forward pass.
177
+
178
+ Args:
179
+ x (tensor): input
180
+
181
+ Returns:
182
+ tensor: output
183
+ """
184
+
185
+ out = self.activation(x)
186
+ out = self.conv1(out)
187
+ if self.bn == True:
188
+ out = self.bn1(out)
189
+
190
+ out = self.activation(out)
191
+ out = self.conv2(out)
192
+ if self.bn == True:
193
+ out = self.bn2(out)
194
+
195
+ if self.groups > 1:
196
+ out = self.conv_merge(out)
197
+
198
+ return self.skip_add.add(out, x)
199
+
200
+
201
+ class FeatureFusionBlock(nn.Module):
202
+ """Feature fusion block.
203
+ """
204
+
205
+ def __init__(self, features, activation, deconv=False, bn=False, expand=False, align_corners=True, size=None):
206
+ """Init.
207
+
208
+ Args:
209
+ features (int): number of features
210
+ """
211
+ super(FeatureFusionBlock, self).__init__()
212
+
213
+ self.deconv = deconv
214
+ self.align_corners = align_corners
215
+
216
+ self.groups = 1
217
+
218
+ self.expand = expand
219
+ out_features = features
220
+ if self.expand == True:
221
+ out_features = features//2
222
+
223
+ self.out_conv = nn.Conv2d(
224
+ features, out_features, kernel_size=1, stride=1, padding=0, bias=True, groups=1)
225
+
226
+ self.resConfUnit1 = ResidualConvUnit(features, activation, bn)
227
+ self.resConfUnit2 = ResidualConvUnit(features, activation, bn)
228
+
229
+ self.skip_add = nn.quantized.FloatFunctional()
230
+
231
+ self.size = size
232
+
233
+ def forward(self, *xs, size=None):
234
+ """Forward pass.
235
+
236
+ Returns:
237
+ tensor: output
238
+ """
239
+ output = xs[0]
240
+
241
+ if len(xs) == 2:
242
+ res = self.resConfUnit1(xs[1])
243
+ output = self.skip_add.add(output, res)
244
+
245
+ output = self.resConfUnit2(output)
246
+
247
+ if (size is None) and (self.size is None):
248
+ modifier = {"scale_factor": 2}
249
+ elif size is None:
250
+ modifier = {"size": self.size}
251
+ else:
252
+ modifier = {"size": size}
253
+
254
+ output = nn.functional.interpolate(
255
+ output, **modifier, mode="bilinear", align_corners=self.align_corners
256
+ )
257
+
258
+ output = self.out_conv(output)
259
+
260
+ return output
261
+
262
+
263
+ class FeatureFusionControlBlock(FeatureFusionBlock):
264
+ """Feature fusion block.
265
+ """
266
+
267
+ def __init__(self, features, activation, deconv=False, bn=False, expand=False, align_corners=True, size=None):
268
+ """Init.
269
+
270
+ Args:
271
+ features (int): number of features
272
+ """
273
+ super.__init__(features, activation, deconv,
274
+ bn, expand, align_corners, size)
275
+ self.copy_block = FeatureFusionBlock(
276
+ features, activation, deconv, bn, expand, align_corners, size)
277
+
278
+ def forward(self, *xs, size=None):
279
+ """Forward pass.
280
+
281
+ Returns:
282
+ tensor: output
283
+ """
284
+ output = xs[0]
285
+
286
+ if len(xs) == 2:
287
+ res = self.resConfUnit1(xs[1])
288
+ output = self.skip_add.add(output, res)
289
+
290
+ output = self.resConfUnit2(output)
291
+
292
+ if (size is None) and (self.size is None):
293
+ modifier = {"scale_factor": 2}
294
+ elif size is None:
295
+ modifier = {"size": self.size}
296
+ else:
297
+ modifier = {"size": size}
298
+
299
+ output = nn.functional.interpolate(
300
+ output, **modifier, mode="bilinear", align_corners=self.align_corners
301
+ )
302
+
303
+ output = self.out_conv(output)
304
+
305
+ return output
306
+
307
+
308
+ def zero_module(module):
309
+ """
310
+ Zero out the parameters of a module and return it.
311
+ """
312
+ for p in module.parameters():
313
+ p.detach().zero_()
314
+ return module
315
+
316
+
317
+ class FeatureFusionDepthBlock(nn.Module):
318
+ """Feature fusion block.
319
+ """
320
+
321
+ def __init__(self, features, activation, deconv=False, bn=False, expand=False, align_corners=True, size=None):
322
+ """Init.
323
+
324
+ Args:
325
+ features (int): number of features
326
+ """
327
+ super(FeatureFusionDepthBlock, self).__init__()
328
+
329
+ self.deconv = deconv
330
+ self.align_corners = align_corners
331
+
332
+ self.groups = 1
333
+
334
+ self.expand = expand
335
+ out_features = features
336
+ if self.expand == True:
337
+ out_features = features//2
338
+
339
+ self.out_conv = nn.Conv2d(
340
+ features, out_features, kernel_size=1, stride=1, padding=0, bias=True, groups=1)
341
+
342
+ self.resConfUnit1 = ResidualConvUnit(features, activation, bn)
343
+ self.resConfUnit2 = ResidualConvUnit(features, activation, bn)
344
+ self.resConfUnit_depth = nn.Sequential(
345
+ nn.Conv2d(1, features, kernel_size=3, stride=1,
346
+ padding=1, bias=True, groups=1),
347
+ activation,
348
+ nn.Conv2d(features, features, kernel_size=3,
349
+ stride=1, padding=1, bias=True, groups=1),
350
+ activation,
351
+ zero_module(
352
+ nn.Conv2d(features, features, kernel_size=3,
353
+ stride=1, padding=1, bias=True, groups=1)
354
+ )
355
+ )
356
+ self.skip_add = nn.quantized.FloatFunctional()
357
+ self.size = size
358
+
359
+ def forward(self, *xs, prompt_depth=None, size=None):
360
+ """Forward pass.
361
+
362
+ Returns:
363
+ tensor: output
364
+ """
365
+ output = xs[0]
366
+
367
+ if len(xs) == 2:
368
+ res = self.resConfUnit1(xs[1])
369
+ output = self.skip_add.add(output, res)
370
+
371
+ output = self.resConfUnit2(output)
372
+
373
+ if prompt_depth is not None:
374
+ prompt_depth = F.interpolate(
375
+ prompt_depth, output.shape[2:], mode='bilinear', align_corners=False)
376
+ res = self.resConfUnit_depth(prompt_depth)
377
+ output = self.skip_add.add(output, res)
378
+
379
+ if (size is None) and (self.size is None):
380
+ modifier = {"scale_factor": 2}
381
+ elif size is None:
382
+ modifier = {"size": self.size}
383
+ else:
384
+ modifier = {"size": size}
385
+
386
+ output = nn.functional.interpolate(
387
+ output, **modifier, mode="bilinear", align_corners=self.align_corners
388
+ )
389
+
390
+ output = self.out_conv(output)
391
+
392
+ return output
393
+
394
+
395
+ # ==============================================================================================================
396
+ # PromptDA/promptda/model/dpt.py
397
+ # ==============================================================================================================
398
+ # Copyright (c) 2024, Depth Anything V2
399
+ # https://github.com/DepthAnything/Depth-Anything-V2/blob/main/depth_anything_v2/dpt.py
400
+ import torch
401
+ import torch.nn as nn
402
+ import torch.nn.functional as F
403
+
404
+
405
+ class DPTHead(nn.Module):
406
+ def __init__(self,
407
+ nclass,
408
+ in_channels,
409
+ features=256,
410
+ out_channels=[256, 512, 1024, 1024],
411
+ use_bn=False,
412
+ use_clstoken=False,
413
+ output_act='sigmoid'):
414
+ super(DPTHead, self).__init__()
415
+
416
+ self.nclass = nclass
417
+ self.use_clstoken = use_clstoken
418
+
419
+ self.projects = nn.ModuleList([
420
+ nn.Conv2d(
421
+ in_channels=in_channels,
422
+ out_channels=out_channel,
423
+ kernel_size=1,
424
+ stride=1,
425
+ padding=0,
426
+ ) for out_channel in out_channels
427
+ ])
428
+
429
+ self.resize_layers = nn.ModuleList([
430
+ nn.ConvTranspose2d(
431
+ in_channels=out_channels[0],
432
+ out_channels=out_channels[0],
433
+ kernel_size=4,
434
+ stride=4,
435
+ padding=0),
436
+ nn.ConvTranspose2d(
437
+ in_channels=out_channels[1],
438
+ out_channels=out_channels[1],
439
+ kernel_size=2,
440
+ stride=2,
441
+ padding=0),
442
+ nn.Identity(),
443
+ nn.Conv2d(
444
+ in_channels=out_channels[3],
445
+ out_channels=out_channels[3],
446
+ kernel_size=3,
447
+ stride=2,
448
+ padding=1)
449
+ ])
450
+
451
+ if use_clstoken:
452
+ self.readout_projects = nn.ModuleList()
453
+ for _ in range(len(self.projects)):
454
+ self.readout_projects.append(
455
+ nn.Sequential(
456
+ nn.Linear(2 * in_channels, in_channels),
457
+ nn.GELU()))
458
+
459
+ self.scratch = _make_scratch(
460
+ out_channels,
461
+ features,
462
+ groups=1,
463
+ expand=False,
464
+ )
465
+
466
+ self.scratch.stem_transpose = None
467
+
468
+ self.scratch.refinenet1 = _make_fusion_block(
469
+ features, use_bn)
470
+ self.scratch.refinenet2 = _make_fusion_block(
471
+ features, use_bn)
472
+ self.scratch.refinenet3 = _make_fusion_block(
473
+ features, use_bn)
474
+ self.scratch.refinenet4 = _make_fusion_block(
475
+ features, use_bn)
476
+
477
+ head_features_1 = features
478
+ head_features_2 = 32
479
+
480
+ act_func = nn.Sigmoid() if output_act == 'sigmoid' else nn.Identity()
481
+
482
+ if nclass > 1:
483
+ self.scratch.output_conv = nn.Sequential(
484
+ nn.Conv2d(head_features_1, head_features_1,
485
+ kernel_size=3, stride=1, padding=1),
486
+ nn.ReLU(True),
487
+ nn.Conv2d(head_features_1, nclass,
488
+ kernel_size=1, stride=1, padding=0),
489
+ )
490
+ else:
491
+ self.scratch.output_conv1 = nn.Conv2d(
492
+ head_features_1, head_features_1 // 2, kernel_size=3, stride=1, padding=1)
493
+
494
+ self.scratch.output_conv2 = nn.Sequential(
495
+ nn.Conv2d(head_features_1 // 2, head_features_2,
496
+ kernel_size=3, stride=1, padding=1),
497
+ nn.ReLU(True),
498
+ nn.Conv2d(head_features_2, 1, kernel_size=1,
499
+ stride=1, padding=0),
500
+ act_func,
501
+ )
502
+
503
+ def forward(self, out_features, patch_h, patch_w, prompt_depth=None):
504
+ out = []
505
+ for i, x in enumerate(out_features):
506
+ if self.use_clstoken:
507
+ x, cls_token = x[0], x[1]
508
+ readout = cls_token.unsqueeze(1).expand_as(x)
509
+ x = self.readout_projects[i](torch.cat((x, readout), -1))
510
+ else:
511
+ x = x[0]
512
+
513
+ x = x.permute(0, 2, 1).reshape(
514
+ (x.shape[0], x.shape[-1], patch_h, patch_w))
515
+
516
+ x = self.projects[i](x)
517
+ x = self.resize_layers[i](x)
518
+
519
+ out.append(x)
520
+
521
+ layer_1, layer_2, layer_3, layer_4 = out
522
+
523
+ layer_1_rn = self.scratch.layer1_rn(layer_1)
524
+ layer_2_rn = self.scratch.layer2_rn(layer_2)
525
+ layer_3_rn = self.scratch.layer3_rn(layer_3)
526
+ layer_4_rn = self.scratch.layer4_rn(layer_4)
527
+
528
+ path_4 = self.scratch.refinenet4(
529
+ layer_4_rn, size=layer_3_rn.shape[2:], prompt_depth=prompt_depth)
530
+ path_3 = self.scratch.refinenet3(
531
+ path_4, layer_3_rn, size=layer_2_rn.shape[2:], prompt_depth=prompt_depth)
532
+ path_2 = self.scratch.refinenet2(
533
+ path_3, layer_2_rn, size=layer_1_rn.shape[2:], prompt_depth=prompt_depth)
534
+ path_1 = self.scratch.refinenet1(
535
+ path_2, layer_1_rn, prompt_depth=prompt_depth)
536
+ out = self.scratch.output_conv1(path_1)
537
+ out_feat = F.interpolate(
538
+ out, (int(patch_h * 14), int(patch_w * 14)),
539
+ mode="bilinear", align_corners=True)
540
+ out = self.scratch.output_conv2(out_feat)
541
+ return out
542
+
543
+
544
+ # ==============================================================================================================
545
+ # PromptDA/promptda/model/config.py
546
+ # ==============================================================================================================
547
+ model_configs = {
548
+ 'vits': {'encoder': 'vits', 'features': 64, 'out_channels': [48, 96, 192, 384], 'layer_idxs': [2, 5, 8, 11]},
549
+ 'vitb': {'encoder': 'vitb', 'features': 128, 'out_channels': [96, 192, 384, 768], 'layer_idxs': [2, 5, 8, 11]},
550
+ 'vitl': {'encoder': 'vitl', 'features': 256, 'out_channels': [256, 512, 1024, 1024], 'layer_idxs': [4, 11, 17, 23]},
551
+ 'vitg': {'encoder': 'vitg', 'features': 384, 'out_channels': [1536, 1536, 1536, 1536], 'layer_idxs': [9, 19, 29, 39]}
552
+ }
553
+
554
+
555
+ # ==============================================================================================================
556
+ # PromptDA/promptda/promptda.py
557
+ # ==============================================================================================================
558
+ import torch
559
+ import torch.nn as nn
560
+ import os
561
+ from pathlib import Path
562
+ from huggingface_hub import hf_hub_download
563
+
564
+
565
+ class PromptDA(nn.Module):
566
+ patch_size = 14 # patch size of the pretrained dinov2 model
567
+ use_bn = False
568
+ use_clstoken = False
569
+ output_act = 'sigmoid'
570
+
571
+ def __init__(self,
572
+ encoder='vitl',
573
+ ckpt_path='checkpoints/promptda_vitl.ckpt'):
574
+ super().__init__()
575
+ model_config = model_configs[encoder]
576
+
577
+ self.encoder = encoder
578
+ self.model_config = model_config
579
+ module_path = Path(__file__) # From anywhere else: module_path = Path(inspect.getfile(PromptDA))
580
+ package_base_dir = str(Path(*module_path.parts[:-2])) # extract path to PromptDA module, then resolve to repo base dir for dinov2 load
581
+ self.pretrained = torch.hub.load(
582
+ f'{package_base_dir}/torchhub/facebookresearch_dinov2_main',
583
+ 'dinov2_{:}14'.format(encoder),
584
+ source='local',
585
+ pretrained=False)
586
+ dim = self.pretrained.blocks[0].attn.qkv.in_features
587
+ self.depth_head = DPTHead(nclass=1,
588
+ in_channels=dim,
589
+ features=model_config['features'],
590
+ out_channels=model_config['out_channels'],
591
+ use_bn=self.use_bn,
592
+ use_clstoken=self.use_clstoken,
593
+ output_act=self.output_act)
594
+
595
+ # mean and std of the pretrained dinov2 model
596
+ self.register_buffer('_mean', torch.tensor(
597
+ [0.485, 0.456, 0.406]).view(1, 3, 1, 1))
598
+ self.register_buffer('_std', torch.tensor(
599
+ [0.229, 0.224, 0.225]).view(1, 3, 1, 1))
600
+
601
+ self.load_checkpoint(ckpt_path)
602
+
603
+ @classmethod
604
+ def from_pretrained(cls, pretrained_model_name_or_path = None, model_kwargs = None, **hf_kwargs):
605
+ """
606
+ Load a model from a checkpoint file.
607
+ ### Parameters:
608
+ - `pretrained_model_name_or_path`: path to the checkpoint file or repo id.
609
+ - `model_kwargs`: additional keyword arguments to override the parameters in the checkpoint.
610
+ - `hf_kwargs`: additional keyword arguments to pass to the `hf_hub_download` function. Ignored if `pretrained_model_name_or_path` is a local path.
611
+ ### Returns:
612
+ - A new instance of `MoGe` with the parameters loaded from the checkpoint.
613
+ """
614
+ ckpt_path = None
615
+ if Path(pretrained_model_name_or_path).exists():
616
+ ckpt_path = pretrained_model_name_or_path
617
+ else:
618
+ cached_checkpoint_path = hf_hub_download(
619
+ repo_id=pretrained_model_name_or_path,
620
+ repo_type="model",
621
+ filename="model.ckpt",
622
+ **hf_kwargs
623
+ )
624
+ ckpt_path = cached_checkpoint_path
625
+ # model_config = checkpoint['model_config']
626
+ # if model_kwargs is not None:
627
+ # model_config.update(model_kwargs)
628
+ if model_kwargs is None:
629
+ model_kwargs = {}
630
+ model_kwargs.update({'ckpt_path': ckpt_path})
631
+ model = cls(**model_kwargs)
632
+ return model
633
+
634
+ def load_checkpoint(self, ckpt_path):
635
+ if os.path.exists(ckpt_path):
636
+ Log.info(f'Loading checkpoint from {ckpt_path}')
637
+ checkpoint = torch.load(ckpt_path, map_location='cpu')
638
+ self.load_state_dict(
639
+ {k[9:]: v for k, v in checkpoint['state_dict'].items()})
640
+ else:
641
+ Log.warn(f'Checkpoint {ckpt_path} not found')
642
+
643
+ def forward(self, x, prompt_depth=None):
644
+ assert prompt_depth is not None, 'prompt_depth is required'
645
+ prompt_depth, min_val, max_val = self.normalize(prompt_depth)
646
+ h, w = x.shape[-2:]
647
+ features = self.pretrained.get_intermediate_layers(
648
+ (x - self._mean) / self._std, self.model_config['layer_idxs'],
649
+ return_class_token=True)
650
+ patch_h, patch_w = h // self.patch_size, w // self.patch_size
651
+ depth = self.depth_head(features, patch_h, patch_w, prompt_depth)
652
+ depth = self.denormalize(depth, min_val, max_val)
653
+ return depth
654
+
655
+ @torch.no_grad()
656
+ def predict(self,
657
+ image: torch.Tensor,
658
+ prompt_depth: torch.Tensor):
659
+ return self.forward(image, prompt_depth)
660
+
661
+ def normalize(self,
662
+ prompt_depth: torch.Tensor):
663
+ B, C, H, W = prompt_depth.shape
664
+ min_val = torch.quantile(
665
+ prompt_depth.reshape(B, -1), 0., dim=1, keepdim=True)[:, :, None, None]
666
+ max_val = torch.quantile(
667
+ prompt_depth.reshape(B, -1), 1., dim=1, keepdim=True)[:, :, None, None]
668
+ prompt_depth = (prompt_depth - min_val) / (max_val - min_val)
669
+ return prompt_depth, min_val, max_val
670
+
671
+ def denormalize(self,
672
+ depth: torch.Tensor,
673
+ min_val: torch.Tensor,
674
+ max_val: torch.Tensor):
675
+ return depth * (max_val - min_val) + min_val