Image Feature Extraction
Transformers
Safetensors
motif_vision
feature-extraction
motif
vision-transformer
self-supervised
video
custom_code
Instructions to use Motif-Technologies/Motif-Vision-Encoder with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Motif-Technologies/Motif-Vision-Encoder with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-feature-extraction", model="Motif-Technologies/Motif-Vision-Encoder", trust_remote_code=True)# pip install -U transformers accelerate # Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("Motif-Technologies/Motif-Vision-Encoder", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
License->MIT; strip training-only code (init_weights, torch._dynamo config, stochastic depth). Inference forward bit-identical (verified).
Browse files- LICENSE +21 -202
- README.md +2 -2
- modeling_motif.py +11 -166
LICENSE
CHANGED
|
@@ -1,202 +1,21 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
outstanding shares, or (iii) beneficial ownership of such entity.
|
| 23 |
-
|
| 24 |
-
"You" (or "Your") shall mean an individual or Legal Entity
|
| 25 |
-
exercising permissions granted by this License.
|
| 26 |
-
|
| 27 |
-
"Source" form shall mean the preferred form for making modifications,
|
| 28 |
-
including but not limited to software source code, documentation
|
| 29 |
-
source, and configuration files.
|
| 30 |
-
|
| 31 |
-
"Object" form shall mean any form resulting from mechanical
|
| 32 |
-
transformation or translation of a Source form, including but
|
| 33 |
-
not limited to compiled object code, generated documentation,
|
| 34 |
-
and conversions to other media types.
|
| 35 |
-
|
| 36 |
-
"Work" shall mean the work of authorship, whether in Source or
|
| 37 |
-
Object form, made available under the License, as indicated by a
|
| 38 |
-
copyright notice that is included in or attached to the work
|
| 39 |
-
(an example is provided in the Appendix below).
|
| 40 |
-
|
| 41 |
-
"Derivative Works" shall mean any work, whether in Source or Object
|
| 42 |
-
form, that is based on (or derived from) the Work and for which the
|
| 43 |
-
editorial revisions, annotations, elaborations, or other modifications
|
| 44 |
-
represent, as a whole, an original work of authorship. For the purposes
|
| 45 |
-
of this License, Derivative Works shall not include works that remain
|
| 46 |
-
separable from, or merely link (or bind by name) to the interfaces of,
|
| 47 |
-
the Work and Derivative Works thereof.
|
| 48 |
-
|
| 49 |
-
"Contribution" shall mean any work of authorship, including
|
| 50 |
-
the original version of the Work and any modifications or additions
|
| 51 |
-
to that Work or Derivative Works thereof, that is intentionally
|
| 52 |
-
submitted to Licensor for inclusion in the Work by the copyright owner
|
| 53 |
-
or by an individual or Legal Entity authorized to submit on behalf of
|
| 54 |
-
the copyright owner. For the purposes of this definition, "submitted"
|
| 55 |
-
means any form of electronic, verbal, or written communication sent
|
| 56 |
-
to the Licensor or its representatives, including but not limited to
|
| 57 |
-
communication on electronic mailing lists, source code control systems,
|
| 58 |
-
and issue tracking systems that are managed by, or on behalf of, the
|
| 59 |
-
Licensor for the purpose of discussing and improving the Work, but
|
| 60 |
-
excluding communication that is conspicuously marked or otherwise
|
| 61 |
-
designated in writing by the copyright owner as "Not a Contribution."
|
| 62 |
-
|
| 63 |
-
"Contributor" shall mean Licensor and any individual or Legal Entity
|
| 64 |
-
on behalf of whom a Contribution has been received by Licensor and
|
| 65 |
-
subsequently incorporated within the Work.
|
| 66 |
-
|
| 67 |
-
2. Grant of Copyright License. Subject to the terms and conditions of
|
| 68 |
-
this License, each Contributor hereby grants to You a perpetual,
|
| 69 |
-
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 70 |
-
copyright license to reproduce, prepare Derivative Works of,
|
| 71 |
-
publicly display, publicly perform, sublicense, and distribute the
|
| 72 |
-
Work and such Derivative Works in Source or Object form.
|
| 73 |
-
|
| 74 |
-
3. Grant of Patent License. Subject to the terms and conditions of
|
| 75 |
-
this License, each Contributor hereby grants to You a perpetual,
|
| 76 |
-
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 77 |
-
(except as stated in this section) patent license to make, have made,
|
| 78 |
-
use, offer to sell, sell, import, and otherwise transfer the Work,
|
| 79 |
-
where such license applies only to those patent claims licensable
|
| 80 |
-
by such Contributor that are necessarily infringed by their
|
| 81 |
-
Contribution(s) alone or by combination of their Contribution(s)
|
| 82 |
-
with the Work to which such Contribution(s) was submitted. If You
|
| 83 |
-
institute patent litigation against any entity (including a
|
| 84 |
-
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
| 85 |
-
or a Contribution incorporated within the Work constitutes direct
|
| 86 |
-
or contributory patent infringement, then any patent licenses
|
| 87 |
-
granted to You under this License for that Work shall terminate
|
| 88 |
-
as of the date such litigation is filed.
|
| 89 |
-
|
| 90 |
-
4. Redistribution. You may reproduce and distribute copies of the
|
| 91 |
-
Work or Derivative Works thereof in any medium, with or without
|
| 92 |
-
modifications, and in Source or Object form, provided that You
|
| 93 |
-
meet the following conditions:
|
| 94 |
-
|
| 95 |
-
(a) You must give any other recipients of the Work or
|
| 96 |
-
Derivative Works a copy of this License; and
|
| 97 |
-
|
| 98 |
-
(b) You must cause any modified files to carry prominent notices
|
| 99 |
-
stating that You changed the files; and
|
| 100 |
-
|
| 101 |
-
(c) You must retain, in the Source form of any Derivative Works
|
| 102 |
-
that You distribute, all copyright, patent, trademark, and
|
| 103 |
-
attribution notices from the Source form of the Work,
|
| 104 |
-
excluding those notices that do not pertain to any part of
|
| 105 |
-
the Derivative Works; and
|
| 106 |
-
|
| 107 |
-
(d) If the Work includes a "NOTICE" text file as part of its
|
| 108 |
-
distribution, then any Derivative Works that You distribute must
|
| 109 |
-
include a readable copy of the attribution notices contained
|
| 110 |
-
within such NOTICE file, excluding those notices that do not
|
| 111 |
-
pertain to any part of the Derivative Works, in at least one
|
| 112 |
-
of the following places: within a NOTICE text file distributed
|
| 113 |
-
as part of the Derivative Works; within the Source form or
|
| 114 |
-
documentation, if provided along with the Derivative Works; or,
|
| 115 |
-
within a display generated by the Derivative Works, if and
|
| 116 |
-
wherever such third-party notices normally appear. The contents
|
| 117 |
-
of the NOTICE file are for informational purposes only and
|
| 118 |
-
do not modify the License. You may add Your own attribution
|
| 119 |
-
notices within Derivative Works that You distribute, alongside
|
| 120 |
-
or as an addendum to the NOTICE text from the Work, provided
|
| 121 |
-
that such additional attribution notices cannot be construed
|
| 122 |
-
as modifying the License.
|
| 123 |
-
|
| 124 |
-
You may add Your own copyright statement to Your modifications and
|
| 125 |
-
may provide additional or different license terms and conditions
|
| 126 |
-
for use, reproduction, or distribution of Your modifications, or
|
| 127 |
-
for any such Derivative Works as a whole, provided Your use,
|
| 128 |
-
reproduction, and distribution of the Work otherwise complies with
|
| 129 |
-
the conditions stated in this License.
|
| 130 |
-
|
| 131 |
-
5. Submission of Contributions. Unless You explicitly state otherwise,
|
| 132 |
-
any Contribution intentionally submitted for inclusion in the Work
|
| 133 |
-
by You to the Licensor shall be under the terms and conditions of
|
| 134 |
-
this License, without any additional terms or conditions.
|
| 135 |
-
Notwithstanding the above, nothing herein shall supersede or modify
|
| 136 |
-
the terms of any separate license agreement you may have executed
|
| 137 |
-
with Licensor regarding such Contributions.
|
| 138 |
-
|
| 139 |
-
6. Trademarks. This License does not grant permission to use the trade
|
| 140 |
-
names, trademarks, service marks, or product names of the Licensor,
|
| 141 |
-
except as required for reasonable and customary use in describing the
|
| 142 |
-
origin of the Work and reproducing the content of the NOTICE file.
|
| 143 |
-
|
| 144 |
-
7. Disclaimer of Warranty. Unless required by applicable law or
|
| 145 |
-
agreed to in writing, Licensor provides the Work (and each
|
| 146 |
-
Contributor provides its Contributions) on an "AS IS" BASIS,
|
| 147 |
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
| 148 |
-
implied, including, without limitation, any warranties or conditions
|
| 149 |
-
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
| 150 |
-
PARTICULAR PURPOSE. You are solely responsible for determining the
|
| 151 |
-
appropriateness of using or redistributing the Work and assume any
|
| 152 |
-
risks associated with Your exercise of permissions under this License.
|
| 153 |
-
|
| 154 |
-
8. Limitation of Liability. In no event and under no legal theory,
|
| 155 |
-
whether in tort (including negligence), contract, or otherwise,
|
| 156 |
-
unless required by applicable law (such as deliberate and grossly
|
| 157 |
-
negligent acts) or agreed to in writing, shall any Contributor be
|
| 158 |
-
liable to You for damages, including any direct, indirect, special,
|
| 159 |
-
incidental, or consequential damages of any character arising as a
|
| 160 |
-
result of this License or out of the use or inability to use the
|
| 161 |
-
Work (including but not limited to damages for loss of goodwill,
|
| 162 |
-
work stoppage, computer failure or malfunction, or any and all
|
| 163 |
-
other commercial damages or losses), even if such Contributor
|
| 164 |
-
has been advised of the possibility of such damages.
|
| 165 |
-
|
| 166 |
-
9. Accepting Warranty or Additional Liability. While redistributing
|
| 167 |
-
the Work or Derivative Works thereof, You may choose to offer,
|
| 168 |
-
and charge a fee for, acceptance of support, warranty, indemnity,
|
| 169 |
-
or other liability obligations and/or rights consistent with this
|
| 170 |
-
License. However, in accepting such obligations, You may act only
|
| 171 |
-
on Your own behalf and on Your sole responsibility, not on behalf
|
| 172 |
-
of any other Contributor, and only if You agree to indemnify,
|
| 173 |
-
defend, and hold each Contributor harmless for any liability
|
| 174 |
-
incurred by, or claims asserted against, such Contributor by reason
|
| 175 |
-
of your accepting any such warranty or additional liability.
|
| 176 |
-
|
| 177 |
-
END OF TERMS AND CONDITIONS
|
| 178 |
-
|
| 179 |
-
APPENDIX: How to apply the Apache License to your work.
|
| 180 |
-
|
| 181 |
-
To apply the Apache License to your work, attach the following
|
| 182 |
-
boilerplate notice, with the fields enclosed by brackets "[]"
|
| 183 |
-
replaced with your own identifying information. (Don't include
|
| 184 |
-
the brackets!) The text should be enclosed in the appropriate
|
| 185 |
-
comment syntax for the file format. We also recommend that a
|
| 186 |
-
file or class name and description of purpose be included on the
|
| 187 |
-
same "printed page" as the copyright notice for easier
|
| 188 |
-
identification within third-party archives.
|
| 189 |
-
|
| 190 |
-
Copyright [yyyy] [name of copyright owner]
|
| 191 |
-
|
| 192 |
-
Licensed under the Apache License, Version 2.0 (the "License");
|
| 193 |
-
you may not use this file except in compliance with the License.
|
| 194 |
-
You may obtain a copy of the License at
|
| 195 |
-
|
| 196 |
-
http://www.apache.org/licenses/LICENSE-2.0
|
| 197 |
-
|
| 198 |
-
Unless required by applicable law or agreed to in writing, software
|
| 199 |
-
distributed under the License is distributed on an "AS IS" BASIS,
|
| 200 |
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 201 |
-
See the License for the specific language governing permissions and
|
| 202 |
-
limitations under the License.
|
|
|
|
| 1 |
+
MIT License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2026 Motif Technologies
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
+
in the Software without restriction, including without limitation the rights
|
| 8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
+
furnished to do so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
---
|
| 2 |
-
license:
|
| 3 |
library_name: transformers
|
| 4 |
pipeline_tag: image-feature-extraction
|
| 5 |
tags:
|
|
@@ -109,7 +109,7 @@ video. Comparison numbers are the best figures reported by each model's authors.
|
|
| 109 |
|
| 110 |
## License
|
| 111 |
|
| 112 |
-
Released under **
|
| 113 |
respective dataset licenses; downstream users are responsible for compliance with those terms.
|
| 114 |
|
| 115 |
## Citation
|
|
|
|
| 1 |
---
|
| 2 |
+
license: mit
|
| 3 |
library_name: transformers
|
| 4 |
pipeline_tag: image-feature-extraction
|
| 5 |
tags:
|
|
|
|
| 109 |
|
| 110 |
## License
|
| 111 |
|
| 112 |
+
Released under the **MIT License** (see `LICENSE`). The model was trained on data governed by the
|
| 113 |
respective dataset licenses; downstream users are responsible for compliance with those terms.
|
| 114 |
|
| 115 |
## Citation
|
modeling_motif.py
CHANGED
|
@@ -47,30 +47,6 @@ def uncat_with_shapes(flattened: Tensor, shapes: list[tuple[int]], num_tokens: l
|
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
-
def named_apply(
|
| 51 |
-
fn: Callable,
|
| 52 |
-
module: nn.Module,
|
| 53 |
-
name: str = "",
|
| 54 |
-
depth_first: bool = True,
|
| 55 |
-
include_root: bool = False,
|
| 56 |
-
) -> nn.Module:
|
| 57 |
-
"""Apply fn to all submodules (in-place, no replacement)."""
|
| 58 |
-
if not depth_first and include_root:
|
| 59 |
-
fn(module=module, name=name)
|
| 60 |
-
for child_name, child_module in module.named_children():
|
| 61 |
-
child_name = ".".join((name, child_name)) if name else child_name
|
| 62 |
-
named_apply(
|
| 63 |
-
fn=fn,
|
| 64 |
-
module=child_module,
|
| 65 |
-
name=child_name,
|
| 66 |
-
depth_first=depth_first,
|
| 67 |
-
include_root=True,
|
| 68 |
-
)
|
| 69 |
-
if depth_first and include_root:
|
| 70 |
-
fn(module=module, name=name)
|
| 71 |
-
return module
|
| 72 |
-
|
| 73 |
-
|
| 74 |
# ---- rms_norm ----
|
| 75 |
|
| 76 |
|
|
@@ -98,10 +74,6 @@ class RMSNorm(nn.Module):
|
|
| 98 |
self.eps = eps
|
| 99 |
self.weight = nn.Parameter(torch.ones(dim, device=device))
|
| 100 |
|
| 101 |
-
def reset_parameters(self) -> None:
|
| 102 |
-
"""Reset weight to ones."""
|
| 103 |
-
nn.init.ones_(self.weight)
|
| 104 |
-
|
| 105 |
def forward(self, x: Tensor) -> Tensor:
|
| 106 |
"""Apply RMS normalization."""
|
| 107 |
rms = torch.sqrt(x.pow(2).mean(-1, keepdim=True) + self.eps)
|
|
@@ -140,10 +112,6 @@ class LayerScale(nn.Module):
|
|
| 140 |
self.gamma = nn.Parameter(torch.empty(dim, device=device))
|
| 141 |
self.init_values = init_values
|
| 142 |
|
| 143 |
-
def reset_parameters(self) -> None:
|
| 144 |
-
"""Reset gamma to initial values."""
|
| 145 |
-
nn.init.constant_(self.gamma, self.init_values)
|
| 146 |
-
|
| 147 |
def forward(self, x: Tensor) -> Tensor:
|
| 148 |
"""Apply per-channel scaling."""
|
| 149 |
return x.mul_(self.gamma) if self.inplace else x * self.gamma
|
|
@@ -230,13 +198,6 @@ class PatchEmbed(nn.Module):
|
|
| 230 |
|
| 231 |
return x
|
| 232 |
|
| 233 |
-
def reset_parameters(self) -> None:
|
| 234 |
-
"""Reset Conv3d parameters with uniform initialization."""
|
| 235 |
-
k = 1 / (self.in_chans * self.tubelet_size * self.patch_size[0] * self.patch_size[1])
|
| 236 |
-
nn.init.uniform_(self.proj.weight, -math.sqrt(k), math.sqrt(k))
|
| 237 |
-
if self.proj.bias is not None:
|
| 238 |
-
nn.init.uniform_(self.proj.bias, -math.sqrt(k), math.sqrt(k))
|
| 239 |
-
|
| 240 |
|
| 241 |
# ---- rope ----
|
| 242 |
|
|
@@ -850,25 +811,11 @@ import torch
|
|
| 850 |
from torch import Tensor, nn
|
| 851 |
|
| 852 |
|
| 853 |
-
torch._dynamo.config.automatic_dynamic_shapes = False
|
| 854 |
-
torch._dynamo.config.accumulated_cache_size_limit = 1024
|
| 855 |
-
# Per-code-object recompile cap (default 8). With dynamic=False + fullgraph=True,
|
| 856 |
-
# every distinct input shape forces a static recompile of the block. Gram adds the
|
| 857 |
-
# Gram-teacher forward at gram_teacher_crops_size (e.g. 768/1152) on top of the
|
| 858 |
-
# 512/768 image + video + local-crop shapes, pushing the distinct-shape count past
|
| 859 |
-
# 8 → FailOnRecompileLimitHit (hard crash, not the eager-fallback warning seen when
|
| 860 |
-
# fullgraph=False). Raise the cap so all Gram shapes compile; the accumulated cap
|
| 861 |
-
# (1024) still bounds total graphs. Only the shapes that actually occur are compiled,
|
| 862 |
-
# so a high cap costs nothing when Gram is off.
|
| 863 |
-
torch._dynamo.config.recompile_limit = 64
|
| 864 |
-
|
| 865 |
-
|
| 866 |
-
|
| 867 |
class SelfAttentionBlock(nn.Module):
|
| 868 |
-
"""Pre-norm transformer block: Norm -> Attention -> LayerScale ->
|
| 869 |
|
| 870 |
Supports both single-tensor and list-of-tensors forward for efficient multi-crop
|
| 871 |
-
processing
|
| 872 |
|
| 873 |
Args:
|
| 874 |
dim: Model dimension.
|
|
@@ -938,81 +885,17 @@ class SelfAttentionBlock(nn.Module):
|
|
| 938 |
)
|
| 939 |
self.ls2 = LayerScale(dim, init_values=init_values, device=device) if init_values else nn.Identity()
|
| 940 |
|
| 941 |
-
self.sample_drop_ratio = drop_path
|
| 942 |
-
|
| 943 |
-
@staticmethod
|
| 944 |
-
def _maybe_index_rope(
|
| 945 |
-
rope: tuple[Tensor, Tensor] | None,
|
| 946 |
-
indices: Tensor,
|
| 947 |
-
) -> tuple[Tensor, Tensor] | None:
|
| 948 |
-
"""Optionally index into RoPE embeddings for stochastic depth."""
|
| 949 |
-
if rope is None:
|
| 950 |
-
return None
|
| 951 |
-
sin, cos = rope
|
| 952 |
-
assert sin.ndim == cos.ndim
|
| 953 |
-
if sin.ndim == 4:
|
| 954 |
-
return sin[indices], cos[indices]
|
| 955 |
-
else:
|
| 956 |
-
return sin, cos
|
| 957 |
-
|
| 958 |
def _forward_list(self, x_list: list[Tensor], rope_list: list | None = None) -> list[Tensor]:
|
| 959 |
-
"""Forward pass for list of tensors with
|
| 960 |
|
| 961 |
-
|
| 962 |
-
then splits for per-input attention computation (different RoPE per crop).
|
| 963 |
"""
|
| 964 |
-
|
| 965 |
-
|
| 966 |
-
|
| 967 |
-
|
| 968 |
-
|
| 969 |
-
|
| 970 |
-
(torch.randperm(b, device=x.device))[:s]
|
| 971 |
-
for x, b, s in zip(x_list, b_list, sample_subset_sizes)
|
| 972 |
-
]
|
| 973 |
-
x_subset_1_list = [x[idx] for x, idx in zip(x_list, indices_1_list)]
|
| 974 |
-
|
| 975 |
-
if rope_list is not None:
|
| 976 |
-
rope_subset_list = [
|
| 977 |
-
self._maybe_index_rope(rope, idx) for rope, idx in zip(rope_list, indices_1_list)
|
| 978 |
-
]
|
| 979 |
-
else:
|
| 980 |
-
rope_subset_list = rope_list
|
| 981 |
-
|
| 982 |
-
norm1 = [self.norm1(x) for x in x_subset_1_list]
|
| 983 |
-
residual_1_list = self.attn.forward_list(norm1, rope_list=rope_subset_list)
|
| 984 |
-
|
| 985 |
-
x_attn_list = [
|
| 986 |
-
torch.index_add(
|
| 987 |
-
x, dim=0, source=self.ls1(r), index=idx, alpha=scale,
|
| 988 |
-
)
|
| 989 |
-
for x, r, idx, scale in zip(x_list, residual_1_list, indices_1_list, residual_scale_factors)
|
| 990 |
-
]
|
| 991 |
-
|
| 992 |
-
indices_2_list = [
|
| 993 |
-
(torch.randperm(b, device=x.device))[:s]
|
| 994 |
-
for x, b, s in zip(x_list, b_list, sample_subset_sizes)
|
| 995 |
-
]
|
| 996 |
-
x_subset_2_list = [x[idx] for x, idx in zip(x_attn_list, indices_2_list)]
|
| 997 |
-
norm2_list = [self.norm2(x) for x in x_subset_2_list]
|
| 998 |
-
|
| 999 |
-
residual_2_list = self.mlp.forward_list(norm2_list)
|
| 1000 |
-
|
| 1001 |
-
x_ffn = [
|
| 1002 |
-
torch.index_add(
|
| 1003 |
-
xa, dim=0, source=self.ls2(r), index=idx, alpha=scale,
|
| 1004 |
-
)
|
| 1005 |
-
for xa, r, idx, scale in zip(x_attn_list, residual_2_list, indices_2_list, residual_scale_factors)
|
| 1006 |
-
]
|
| 1007 |
-
else:
|
| 1008 |
-
x_out = []
|
| 1009 |
-
for x, rope in zip(x_list, rope_list):
|
| 1010 |
-
x_attn = x + self.ls1(self.attn(self.norm1(x), rope=rope))
|
| 1011 |
-
x_ffn_item = x_attn + self.ls2(self.mlp(self.norm2(x_attn)))
|
| 1012 |
-
x_out.append(x_ffn_item)
|
| 1013 |
-
x_ffn = x_out
|
| 1014 |
-
|
| 1015 |
-
return x_ffn
|
| 1016 |
|
| 1017 |
def forward(
|
| 1018 |
self,
|
|
@@ -1046,7 +929,6 @@ from functools import partial
|
|
| 1046 |
from typing import Any
|
| 1047 |
|
| 1048 |
import torch
|
| 1049 |
-
import torch.nn.init
|
| 1050 |
from torch import Tensor, nn
|
| 1051 |
|
| 1052 |
|
|
@@ -1072,33 +954,6 @@ dtype_dict: dict[str, torch.dtype] = {
|
|
| 1072 |
}
|
| 1073 |
|
| 1074 |
|
| 1075 |
-
def init_weights_vit(module: nn.Module, name: str = "") -> None:
|
| 1076 |
-
"""Initialize weights for ViT components.
|
| 1077 |
-
|
| 1078 |
-
Applied recursively via named_apply to all submodules.
|
| 1079 |
-
|
| 1080 |
-
Args:
|
| 1081 |
-
module: Module to initialize.
|
| 1082 |
-
name: Module name (for logging, unused).
|
| 1083 |
-
"""
|
| 1084 |
-
if isinstance(module, nn.Linear):
|
| 1085 |
-
torch.nn.init.trunc_normal_(module.weight, std=0.02)
|
| 1086 |
-
if module.bias is not None:
|
| 1087 |
-
nn.init.zeros_(module.bias)
|
| 1088 |
-
if hasattr(module, "bias_mask") and module.bias_mask is not None:
|
| 1089 |
-
o = module.out_features
|
| 1090 |
-
module.bias_mask.fill_(1)
|
| 1091 |
-
module.bias_mask[o // 3 : 2 * o // 3].fill_(0)
|
| 1092 |
-
if isinstance(module, nn.LayerNorm):
|
| 1093 |
-
module.reset_parameters()
|
| 1094 |
-
if isinstance(module, LayerScale):
|
| 1095 |
-
module.reset_parameters()
|
| 1096 |
-
if isinstance(module, PatchEmbed):
|
| 1097 |
-
module.reset_parameters()
|
| 1098 |
-
if isinstance(module, RMSNorm):
|
| 1099 |
-
module.reset_parameters()
|
| 1100 |
-
|
| 1101 |
-
|
| 1102 |
class MotifVisionTransformer(nn.Module):
|
| 1103 |
"""Vision Transformer backbone with 3D RoPE for unified image/video processing.
|
| 1104 |
|
|
@@ -1106,9 +961,8 @@ class MotifVisionTransformer(nn.Module):
|
|
| 1106 |
- PatchEmbed (Conv3d) for unified image/video tokenization
|
| 1107 |
- Full 3D axial RoPE positional encoding (T/H/W)
|
| 1108 |
- CLS token + register (storage) tokens
|
| 1109 |
-
- LayerScale
|
| 1110 |
- MLP or SwiGLU FFN variants
|
| 1111 |
-
- FSDP-compatible (SHARD_GRAD_OP strategy)
|
| 1112 |
|
| 1113 |
Token sequence layout: [CLS] + [Register x n_storage_tokens] + [Patch x N_total]
|
| 1114 |
|
|
@@ -1255,15 +1109,6 @@ class MotifVisionTransformer(nn.Module):
|
|
| 1255 |
self.head = nn.Identity()
|
| 1256 |
self.mask_token = nn.Parameter(torch.empty(1, embed_dim, device=device))
|
| 1257 |
|
| 1258 |
-
def init_weights(self) -> None:
|
| 1259 |
-
"""Initialize all model weights."""
|
| 1260 |
-
self.rope_embed._init_weights()
|
| 1261 |
-
nn.init.normal_(self.cls_token, std=0.02)
|
| 1262 |
-
if self.n_storage_tokens > 0:
|
| 1263 |
-
nn.init.normal_(self.storage_tokens, std=0.02)
|
| 1264 |
-
nn.init.zeros_(self.mask_token)
|
| 1265 |
-
named_apply(init_weights_vit, self)
|
| 1266 |
-
|
| 1267 |
def prepare_tokens_with_masks(
|
| 1268 |
self,
|
| 1269 |
x: Tensor,
|
|
|
|
| 47 |
|
| 48 |
|
| 49 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
# ---- rms_norm ----
|
| 51 |
|
| 52 |
|
|
|
|
| 74 |
self.eps = eps
|
| 75 |
self.weight = nn.Parameter(torch.ones(dim, device=device))
|
| 76 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
def forward(self, x: Tensor) -> Tensor:
|
| 78 |
"""Apply RMS normalization."""
|
| 79 |
rms = torch.sqrt(x.pow(2).mean(-1, keepdim=True) + self.eps)
|
|
|
|
| 112 |
self.gamma = nn.Parameter(torch.empty(dim, device=device))
|
| 113 |
self.init_values = init_values
|
| 114 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 115 |
def forward(self, x: Tensor) -> Tensor:
|
| 116 |
"""Apply per-channel scaling."""
|
| 117 |
return x.mul_(self.gamma) if self.inplace else x * self.gamma
|
|
|
|
| 198 |
|
| 199 |
return x
|
| 200 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 201 |
|
| 202 |
# ---- rope ----
|
| 203 |
|
|
|
|
| 811 |
from torch import Tensor, nn
|
| 812 |
|
| 813 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 814 |
class SelfAttentionBlock(nn.Module):
|
| 815 |
+
"""Pre-norm transformer block: Norm -> Attention -> LayerScale -> Residual (x2).
|
| 816 |
|
| 817 |
Supports both single-tensor and list-of-tensors forward for efficient multi-crop
|
| 818 |
+
processing.
|
| 819 |
|
| 820 |
Args:
|
| 821 |
dim: Model dimension.
|
|
|
|
| 885 |
)
|
| 886 |
self.ls2 = LayerScale(dim, init_values=init_values, device=device) if init_values else nn.Identity()
|
| 887 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 888 |
def _forward_list(self, x_list: list[Tensor], rope_list: list | None = None) -> list[Tensor]:
|
| 889 |
+
"""Forward pass for a list of tensors (one per crop), each with its own RoPE.
|
| 890 |
|
| 891 |
+
Pre-norm residual: Norm -> Attention -> LayerScale -> Residual, twice (attn, ffn).
|
|
|
|
| 892 |
"""
|
| 893 |
+
x_out = []
|
| 894 |
+
for x, rope in zip(x_list, rope_list):
|
| 895 |
+
x_attn = x + self.ls1(self.attn(self.norm1(x), rope=rope))
|
| 896 |
+
x_ffn_item = x_attn + self.ls2(self.mlp(self.norm2(x_attn)))
|
| 897 |
+
x_out.append(x_ffn_item)
|
| 898 |
+
return x_out
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 899 |
|
| 900 |
def forward(
|
| 901 |
self,
|
|
|
|
| 929 |
from typing import Any
|
| 930 |
|
| 931 |
import torch
|
|
|
|
| 932 |
from torch import Tensor, nn
|
| 933 |
|
| 934 |
|
|
|
|
| 954 |
}
|
| 955 |
|
| 956 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 957 |
class MotifVisionTransformer(nn.Module):
|
| 958 |
"""Vision Transformer backbone with 3D RoPE for unified image/video processing.
|
| 959 |
|
|
|
|
| 961 |
- PatchEmbed (Conv3d) for unified image/video tokenization
|
| 962 |
- Full 3D axial RoPE positional encoding (T/H/W)
|
| 963 |
- CLS token + register (storage) tokens
|
| 964 |
+
- LayerScale
|
| 965 |
- MLP or SwiGLU FFN variants
|
|
|
|
| 966 |
|
| 967 |
Token sequence layout: [CLS] + [Register x n_storage_tokens] + [Patch x N_total]
|
| 968 |
|
|
|
|
| 1109 |
self.head = nn.Identity()
|
| 1110 |
self.mask_token = nn.Parameter(torch.empty(1, embed_dim, device=device))
|
| 1111 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1112 |
def prepare_tokens_with_masks(
|
| 1113 |
self,
|
| 1114 |
x: Tensor,
|