dgenerate-ultralytics-headless 8.3.253__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (299) hide show
  1. dgenerate_ultralytics_headless-8.3.253.dist-info/METADATA +405 -0
  2. dgenerate_ultralytics_headless-8.3.253.dist-info/RECORD +299 -0
  3. dgenerate_ultralytics_headless-8.3.253.dist-info/WHEEL +5 -0
  4. dgenerate_ultralytics_headless-8.3.253.dist-info/entry_points.txt +3 -0
  5. dgenerate_ultralytics_headless-8.3.253.dist-info/licenses/LICENSE +661 -0
  6. dgenerate_ultralytics_headless-8.3.253.dist-info/top_level.txt +1 -0
  7. tests/__init__.py +23 -0
  8. tests/conftest.py +59 -0
  9. tests/test_cli.py +131 -0
  10. tests/test_cuda.py +216 -0
  11. tests/test_engine.py +157 -0
  12. tests/test_exports.py +309 -0
  13. tests/test_integrations.py +151 -0
  14. tests/test_python.py +777 -0
  15. tests/test_solutions.py +371 -0
  16. ultralytics/__init__.py +48 -0
  17. ultralytics/assets/bus.jpg +0 -0
  18. ultralytics/assets/zidane.jpg +0 -0
  19. ultralytics/cfg/__init__.py +1028 -0
  20. ultralytics/cfg/datasets/Argoverse.yaml +78 -0
  21. ultralytics/cfg/datasets/DOTAv1.5.yaml +37 -0
  22. ultralytics/cfg/datasets/DOTAv1.yaml +36 -0
  23. ultralytics/cfg/datasets/GlobalWheat2020.yaml +68 -0
  24. ultralytics/cfg/datasets/HomeObjects-3K.yaml +32 -0
  25. ultralytics/cfg/datasets/ImageNet.yaml +2025 -0
  26. ultralytics/cfg/datasets/Objects365.yaml +447 -0
  27. ultralytics/cfg/datasets/SKU-110K.yaml +58 -0
  28. ultralytics/cfg/datasets/TT100K.yaml +346 -0
  29. ultralytics/cfg/datasets/VOC.yaml +102 -0
  30. ultralytics/cfg/datasets/VisDrone.yaml +87 -0
  31. ultralytics/cfg/datasets/african-wildlife.yaml +25 -0
  32. ultralytics/cfg/datasets/brain-tumor.yaml +22 -0
  33. ultralytics/cfg/datasets/carparts-seg.yaml +44 -0
  34. ultralytics/cfg/datasets/coco-pose.yaml +64 -0
  35. ultralytics/cfg/datasets/coco.yaml +118 -0
  36. ultralytics/cfg/datasets/coco128-seg.yaml +101 -0
  37. ultralytics/cfg/datasets/coco128.yaml +101 -0
  38. ultralytics/cfg/datasets/coco8-grayscale.yaml +103 -0
  39. ultralytics/cfg/datasets/coco8-multispectral.yaml +104 -0
  40. ultralytics/cfg/datasets/coco8-pose.yaml +47 -0
  41. ultralytics/cfg/datasets/coco8-seg.yaml +101 -0
  42. ultralytics/cfg/datasets/coco8.yaml +101 -0
  43. ultralytics/cfg/datasets/construction-ppe.yaml +32 -0
  44. ultralytics/cfg/datasets/crack-seg.yaml +22 -0
  45. ultralytics/cfg/datasets/dog-pose.yaml +52 -0
  46. ultralytics/cfg/datasets/dota8-multispectral.yaml +38 -0
  47. ultralytics/cfg/datasets/dota8.yaml +35 -0
  48. ultralytics/cfg/datasets/hand-keypoints.yaml +50 -0
  49. ultralytics/cfg/datasets/kitti.yaml +27 -0
  50. ultralytics/cfg/datasets/lvis.yaml +1240 -0
  51. ultralytics/cfg/datasets/medical-pills.yaml +21 -0
  52. ultralytics/cfg/datasets/open-images-v7.yaml +663 -0
  53. ultralytics/cfg/datasets/package-seg.yaml +22 -0
  54. ultralytics/cfg/datasets/signature.yaml +21 -0
  55. ultralytics/cfg/datasets/tiger-pose.yaml +41 -0
  56. ultralytics/cfg/datasets/xView.yaml +155 -0
  57. ultralytics/cfg/default.yaml +130 -0
  58. ultralytics/cfg/models/11/yolo11-cls-resnet18.yaml +17 -0
  59. ultralytics/cfg/models/11/yolo11-cls.yaml +33 -0
  60. ultralytics/cfg/models/11/yolo11-obb.yaml +50 -0
  61. ultralytics/cfg/models/11/yolo11-pose.yaml +51 -0
  62. ultralytics/cfg/models/11/yolo11-seg.yaml +50 -0
  63. ultralytics/cfg/models/11/yolo11.yaml +50 -0
  64. ultralytics/cfg/models/11/yoloe-11-seg.yaml +48 -0
  65. ultralytics/cfg/models/11/yoloe-11.yaml +48 -0
  66. ultralytics/cfg/models/12/yolo12-cls.yaml +32 -0
  67. ultralytics/cfg/models/12/yolo12-obb.yaml +48 -0
  68. ultralytics/cfg/models/12/yolo12-pose.yaml +49 -0
  69. ultralytics/cfg/models/12/yolo12-seg.yaml +48 -0
  70. ultralytics/cfg/models/12/yolo12.yaml +48 -0
  71. ultralytics/cfg/models/rt-detr/rtdetr-l.yaml +53 -0
  72. ultralytics/cfg/models/rt-detr/rtdetr-resnet101.yaml +45 -0
  73. ultralytics/cfg/models/rt-detr/rtdetr-resnet50.yaml +45 -0
  74. ultralytics/cfg/models/rt-detr/rtdetr-x.yaml +57 -0
  75. ultralytics/cfg/models/v10/yolov10b.yaml +45 -0
  76. ultralytics/cfg/models/v10/yolov10l.yaml +45 -0
  77. ultralytics/cfg/models/v10/yolov10m.yaml +45 -0
  78. ultralytics/cfg/models/v10/yolov10n.yaml +45 -0
  79. ultralytics/cfg/models/v10/yolov10s.yaml +45 -0
  80. ultralytics/cfg/models/v10/yolov10x.yaml +45 -0
  81. ultralytics/cfg/models/v3/yolov3-spp.yaml +49 -0
  82. ultralytics/cfg/models/v3/yolov3-tiny.yaml +40 -0
  83. ultralytics/cfg/models/v3/yolov3.yaml +49 -0
  84. ultralytics/cfg/models/v5/yolov5-p6.yaml +62 -0
  85. ultralytics/cfg/models/v5/yolov5.yaml +51 -0
  86. ultralytics/cfg/models/v6/yolov6.yaml +56 -0
  87. ultralytics/cfg/models/v8/yoloe-v8-seg.yaml +48 -0
  88. ultralytics/cfg/models/v8/yoloe-v8.yaml +48 -0
  89. ultralytics/cfg/models/v8/yolov8-cls-resnet101.yaml +28 -0
  90. ultralytics/cfg/models/v8/yolov8-cls-resnet50.yaml +28 -0
  91. ultralytics/cfg/models/v8/yolov8-cls.yaml +32 -0
  92. ultralytics/cfg/models/v8/yolov8-ghost-p2.yaml +58 -0
  93. ultralytics/cfg/models/v8/yolov8-ghost-p6.yaml +60 -0
  94. ultralytics/cfg/models/v8/yolov8-ghost.yaml +50 -0
  95. ultralytics/cfg/models/v8/yolov8-obb.yaml +49 -0
  96. ultralytics/cfg/models/v8/yolov8-p2.yaml +57 -0
  97. ultralytics/cfg/models/v8/yolov8-p6.yaml +59 -0
  98. ultralytics/cfg/models/v8/yolov8-pose-p6.yaml +60 -0
  99. ultralytics/cfg/models/v8/yolov8-pose.yaml +50 -0
  100. ultralytics/cfg/models/v8/yolov8-rtdetr.yaml +49 -0
  101. ultralytics/cfg/models/v8/yolov8-seg-p6.yaml +59 -0
  102. ultralytics/cfg/models/v8/yolov8-seg.yaml +49 -0
  103. ultralytics/cfg/models/v8/yolov8-world.yaml +51 -0
  104. ultralytics/cfg/models/v8/yolov8-worldv2.yaml +49 -0
  105. ultralytics/cfg/models/v8/yolov8.yaml +49 -0
  106. ultralytics/cfg/models/v9/yolov9c-seg.yaml +41 -0
  107. ultralytics/cfg/models/v9/yolov9c.yaml +41 -0
  108. ultralytics/cfg/models/v9/yolov9e-seg.yaml +64 -0
  109. ultralytics/cfg/models/v9/yolov9e.yaml +64 -0
  110. ultralytics/cfg/models/v9/yolov9m.yaml +41 -0
  111. ultralytics/cfg/models/v9/yolov9s.yaml +41 -0
  112. ultralytics/cfg/models/v9/yolov9t.yaml +41 -0
  113. ultralytics/cfg/trackers/botsort.yaml +21 -0
  114. ultralytics/cfg/trackers/bytetrack.yaml +12 -0
  115. ultralytics/data/__init__.py +26 -0
  116. ultralytics/data/annotator.py +66 -0
  117. ultralytics/data/augment.py +2801 -0
  118. ultralytics/data/base.py +435 -0
  119. ultralytics/data/build.py +437 -0
  120. ultralytics/data/converter.py +855 -0
  121. ultralytics/data/dataset.py +834 -0
  122. ultralytics/data/loaders.py +704 -0
  123. ultralytics/data/scripts/download_weights.sh +18 -0
  124. ultralytics/data/scripts/get_coco.sh +61 -0
  125. ultralytics/data/scripts/get_coco128.sh +18 -0
  126. ultralytics/data/scripts/get_imagenet.sh +52 -0
  127. ultralytics/data/split.py +138 -0
  128. ultralytics/data/split_dota.py +344 -0
  129. ultralytics/data/utils.py +798 -0
  130. ultralytics/engine/__init__.py +1 -0
  131. ultralytics/engine/exporter.py +1580 -0
  132. ultralytics/engine/model.py +1125 -0
  133. ultralytics/engine/predictor.py +508 -0
  134. ultralytics/engine/results.py +1522 -0
  135. ultralytics/engine/trainer.py +977 -0
  136. ultralytics/engine/tuner.py +449 -0
  137. ultralytics/engine/validator.py +387 -0
  138. ultralytics/hub/__init__.py +166 -0
  139. ultralytics/hub/auth.py +151 -0
  140. ultralytics/hub/google/__init__.py +174 -0
  141. ultralytics/hub/session.py +422 -0
  142. ultralytics/hub/utils.py +162 -0
  143. ultralytics/models/__init__.py +9 -0
  144. ultralytics/models/fastsam/__init__.py +7 -0
  145. ultralytics/models/fastsam/model.py +79 -0
  146. ultralytics/models/fastsam/predict.py +169 -0
  147. ultralytics/models/fastsam/utils.py +23 -0
  148. ultralytics/models/fastsam/val.py +38 -0
  149. ultralytics/models/nas/__init__.py +7 -0
  150. ultralytics/models/nas/model.py +98 -0
  151. ultralytics/models/nas/predict.py +56 -0
  152. ultralytics/models/nas/val.py +38 -0
  153. ultralytics/models/rtdetr/__init__.py +7 -0
  154. ultralytics/models/rtdetr/model.py +63 -0
  155. ultralytics/models/rtdetr/predict.py +88 -0
  156. ultralytics/models/rtdetr/train.py +89 -0
  157. ultralytics/models/rtdetr/val.py +216 -0
  158. ultralytics/models/sam/__init__.py +25 -0
  159. ultralytics/models/sam/amg.py +275 -0
  160. ultralytics/models/sam/build.py +365 -0
  161. ultralytics/models/sam/build_sam3.py +377 -0
  162. ultralytics/models/sam/model.py +169 -0
  163. ultralytics/models/sam/modules/__init__.py +1 -0
  164. ultralytics/models/sam/modules/blocks.py +1067 -0
  165. ultralytics/models/sam/modules/decoders.py +495 -0
  166. ultralytics/models/sam/modules/encoders.py +794 -0
  167. ultralytics/models/sam/modules/memory_attention.py +298 -0
  168. ultralytics/models/sam/modules/sam.py +1160 -0
  169. ultralytics/models/sam/modules/tiny_encoder.py +979 -0
  170. ultralytics/models/sam/modules/transformer.py +344 -0
  171. ultralytics/models/sam/modules/utils.py +512 -0
  172. ultralytics/models/sam/predict.py +3940 -0
  173. ultralytics/models/sam/sam3/__init__.py +3 -0
  174. ultralytics/models/sam/sam3/decoder.py +546 -0
  175. ultralytics/models/sam/sam3/encoder.py +529 -0
  176. ultralytics/models/sam/sam3/geometry_encoders.py +415 -0
  177. ultralytics/models/sam/sam3/maskformer_segmentation.py +286 -0
  178. ultralytics/models/sam/sam3/model_misc.py +199 -0
  179. ultralytics/models/sam/sam3/necks.py +129 -0
  180. ultralytics/models/sam/sam3/sam3_image.py +339 -0
  181. ultralytics/models/sam/sam3/text_encoder_ve.py +307 -0
  182. ultralytics/models/sam/sam3/vitdet.py +547 -0
  183. ultralytics/models/sam/sam3/vl_combiner.py +160 -0
  184. ultralytics/models/utils/__init__.py +1 -0
  185. ultralytics/models/utils/loss.py +466 -0
  186. ultralytics/models/utils/ops.py +315 -0
  187. ultralytics/models/yolo/__init__.py +7 -0
  188. ultralytics/models/yolo/classify/__init__.py +7 -0
  189. ultralytics/models/yolo/classify/predict.py +90 -0
  190. ultralytics/models/yolo/classify/train.py +202 -0
  191. ultralytics/models/yolo/classify/val.py +216 -0
  192. ultralytics/models/yolo/detect/__init__.py +7 -0
  193. ultralytics/models/yolo/detect/predict.py +122 -0
  194. ultralytics/models/yolo/detect/train.py +227 -0
  195. ultralytics/models/yolo/detect/val.py +507 -0
  196. ultralytics/models/yolo/model.py +430 -0
  197. ultralytics/models/yolo/obb/__init__.py +7 -0
  198. ultralytics/models/yolo/obb/predict.py +56 -0
  199. ultralytics/models/yolo/obb/train.py +79 -0
  200. ultralytics/models/yolo/obb/val.py +302 -0
  201. ultralytics/models/yolo/pose/__init__.py +7 -0
  202. ultralytics/models/yolo/pose/predict.py +65 -0
  203. ultralytics/models/yolo/pose/train.py +110 -0
  204. ultralytics/models/yolo/pose/val.py +248 -0
  205. ultralytics/models/yolo/segment/__init__.py +7 -0
  206. ultralytics/models/yolo/segment/predict.py +109 -0
  207. ultralytics/models/yolo/segment/train.py +69 -0
  208. ultralytics/models/yolo/segment/val.py +307 -0
  209. ultralytics/models/yolo/world/__init__.py +5 -0
  210. ultralytics/models/yolo/world/train.py +173 -0
  211. ultralytics/models/yolo/world/train_world.py +178 -0
  212. ultralytics/models/yolo/yoloe/__init__.py +22 -0
  213. ultralytics/models/yolo/yoloe/predict.py +162 -0
  214. ultralytics/models/yolo/yoloe/train.py +287 -0
  215. ultralytics/models/yolo/yoloe/train_seg.py +122 -0
  216. ultralytics/models/yolo/yoloe/val.py +206 -0
  217. ultralytics/nn/__init__.py +27 -0
  218. ultralytics/nn/autobackend.py +964 -0
  219. ultralytics/nn/modules/__init__.py +182 -0
  220. ultralytics/nn/modules/activation.py +54 -0
  221. ultralytics/nn/modules/block.py +1947 -0
  222. ultralytics/nn/modules/conv.py +669 -0
  223. ultralytics/nn/modules/head.py +1183 -0
  224. ultralytics/nn/modules/transformer.py +793 -0
  225. ultralytics/nn/modules/utils.py +159 -0
  226. ultralytics/nn/tasks.py +1768 -0
  227. ultralytics/nn/text_model.py +356 -0
  228. ultralytics/py.typed +1 -0
  229. ultralytics/solutions/__init__.py +41 -0
  230. ultralytics/solutions/ai_gym.py +108 -0
  231. ultralytics/solutions/analytics.py +264 -0
  232. ultralytics/solutions/config.py +107 -0
  233. ultralytics/solutions/distance_calculation.py +123 -0
  234. ultralytics/solutions/heatmap.py +125 -0
  235. ultralytics/solutions/instance_segmentation.py +86 -0
  236. ultralytics/solutions/object_blurrer.py +89 -0
  237. ultralytics/solutions/object_counter.py +190 -0
  238. ultralytics/solutions/object_cropper.py +87 -0
  239. ultralytics/solutions/parking_management.py +280 -0
  240. ultralytics/solutions/queue_management.py +93 -0
  241. ultralytics/solutions/region_counter.py +133 -0
  242. ultralytics/solutions/security_alarm.py +151 -0
  243. ultralytics/solutions/similarity_search.py +219 -0
  244. ultralytics/solutions/solutions.py +828 -0
  245. ultralytics/solutions/speed_estimation.py +114 -0
  246. ultralytics/solutions/streamlit_inference.py +260 -0
  247. ultralytics/solutions/templates/similarity-search.html +156 -0
  248. ultralytics/solutions/trackzone.py +88 -0
  249. ultralytics/solutions/vision_eye.py +67 -0
  250. ultralytics/trackers/__init__.py +7 -0
  251. ultralytics/trackers/basetrack.py +115 -0
  252. ultralytics/trackers/bot_sort.py +257 -0
  253. ultralytics/trackers/byte_tracker.py +469 -0
  254. ultralytics/trackers/track.py +116 -0
  255. ultralytics/trackers/utils/__init__.py +1 -0
  256. ultralytics/trackers/utils/gmc.py +339 -0
  257. ultralytics/trackers/utils/kalman_filter.py +482 -0
  258. ultralytics/trackers/utils/matching.py +154 -0
  259. ultralytics/utils/__init__.py +1450 -0
  260. ultralytics/utils/autobatch.py +118 -0
  261. ultralytics/utils/autodevice.py +205 -0
  262. ultralytics/utils/benchmarks.py +728 -0
  263. ultralytics/utils/callbacks/__init__.py +5 -0
  264. ultralytics/utils/callbacks/base.py +233 -0
  265. ultralytics/utils/callbacks/clearml.py +146 -0
  266. ultralytics/utils/callbacks/comet.py +625 -0
  267. ultralytics/utils/callbacks/dvc.py +197 -0
  268. ultralytics/utils/callbacks/hub.py +110 -0
  269. ultralytics/utils/callbacks/mlflow.py +134 -0
  270. ultralytics/utils/callbacks/neptune.py +126 -0
  271. ultralytics/utils/callbacks/platform.py +453 -0
  272. ultralytics/utils/callbacks/raytune.py +42 -0
  273. ultralytics/utils/callbacks/tensorboard.py +123 -0
  274. ultralytics/utils/callbacks/wb.py +188 -0
  275. ultralytics/utils/checks.py +1020 -0
  276. ultralytics/utils/cpu.py +85 -0
  277. ultralytics/utils/dist.py +123 -0
  278. ultralytics/utils/downloads.py +529 -0
  279. ultralytics/utils/errors.py +35 -0
  280. ultralytics/utils/events.py +113 -0
  281. ultralytics/utils/export/__init__.py +7 -0
  282. ultralytics/utils/export/engine.py +237 -0
  283. ultralytics/utils/export/imx.py +325 -0
  284. ultralytics/utils/export/tensorflow.py +231 -0
  285. ultralytics/utils/files.py +219 -0
  286. ultralytics/utils/git.py +137 -0
  287. ultralytics/utils/instance.py +484 -0
  288. ultralytics/utils/logger.py +506 -0
  289. ultralytics/utils/loss.py +849 -0
  290. ultralytics/utils/metrics.py +1563 -0
  291. ultralytics/utils/nms.py +337 -0
  292. ultralytics/utils/ops.py +664 -0
  293. ultralytics/utils/patches.py +201 -0
  294. ultralytics/utils/plotting.py +1047 -0
  295. ultralytics/utils/tal.py +404 -0
  296. ultralytics/utils/torch_utils.py +984 -0
  297. ultralytics/utils/tqdm.py +443 -0
  298. ultralytics/utils/triton.py +112 -0
  299. ultralytics/utils/tuner.py +168 -0
@@ -0,0 +1,529 @@
1
+ # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
+
3
+ # Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved
4
+ # Based on https://github.com/IDEA-Research/GroundingDINO
5
+ from __future__ import annotations
6
+
7
+ import torch
8
+ from torch import nn
9
+
10
+ from ultralytics.nn.modules.utils import _get_clones
11
+
12
+ from .model_misc import get_valid_ratio
13
+
14
+
15
+ class TransformerEncoderLayer(nn.Module):
16
+ """Transformer encoder layer that performs self-attention followed by cross-attention.
17
+
18
+ This layer was previously called TransformerDecoderLayer but was renamed to better reflect its role in the
19
+ architecture. It processes input sequences through self-attention and then cross-attention with another input
20
+ (typically image features).
21
+
22
+ The layer supports both pre-norm and post-norm configurations, as well as positional encoding at different stages of
23
+ the attention mechanism.
24
+ """
25
+
26
+ def __init__(
27
+ self,
28
+ d_model: int,
29
+ dim_feedforward: int,
30
+ dropout: float,
31
+ pos_enc_at_attn: bool,
32
+ pos_enc_at_cross_attn_keys: bool,
33
+ pos_enc_at_cross_attn_queries: bool,
34
+ pre_norm: bool,
35
+ self_attention: nn.Module = None,
36
+ cross_attention: nn.Module = None,
37
+ ):
38
+ """Initialize a transformer encoder layer.
39
+
40
+ Args:
41
+ cross_attention: Cross-attention module for attending to image features
42
+ d_model: Model dimension/hidden size
43
+ dim_feedforward: Dimension of the feedforward network
44
+ dropout: Dropout probability
45
+ pos_enc_at_attn: Whether to add positional encodings at self-attention
46
+ pos_enc_at_cross_attn_keys: Whether to add positional encodings to keys in cross-attention
47
+ pos_enc_at_cross_attn_queries: Whether to add positional encodings to queries in cross-attention
48
+ pre_norm: Whether to use pre-norm (True) or post-norm (False) architecture
49
+ self_attention: Self-attention module
50
+ """
51
+ super().__init__()
52
+ self.d_model = d_model
53
+ self.dim_feedforward = dim_feedforward
54
+ self.dropout_value = dropout
55
+ self.self_attn = self_attention or nn.MultiheadAttention(num_heads=8, dropout=0.1, embed_dim=256)
56
+ self.cross_attn_image = cross_attention or nn.MultiheadAttention(num_heads=8, dropout=0.1, embed_dim=256)
57
+
58
+ # Implementation of Feedforward model
59
+ self.linear1 = nn.Linear(d_model, dim_feedforward)
60
+ self.dropout = nn.Dropout(dropout)
61
+ self.linear2 = nn.Linear(dim_feedforward, d_model)
62
+
63
+ self.norm1 = nn.LayerNorm(d_model)
64
+ self.norm2 = nn.LayerNorm(d_model)
65
+ self.norm3 = nn.LayerNorm(d_model)
66
+ self.dropout1 = nn.Dropout(dropout)
67
+ self.dropout2 = nn.Dropout(dropout)
68
+ self.dropout3 = nn.Dropout(dropout)
69
+
70
+ self.activation = nn.ReLU()
71
+ self.pre_norm = pre_norm
72
+
73
+ self.pos_enc_at_attn = pos_enc_at_attn
74
+ self.pos_enc_at_cross_attn_queries = pos_enc_at_cross_attn_queries
75
+ self.pos_enc_at_cross_attn_keys = pos_enc_at_cross_attn_keys
76
+
77
+ self.layer_idx = None
78
+
79
+ def forward_post(
80
+ self,
81
+ tgt: torch.Tensor,
82
+ memory: torch.Tensor,
83
+ tgt_mask: torch.Tensor = None,
84
+ memory_mask: torch.Tensor = None,
85
+ tgt_key_padding_mask: torch.Tensor = None,
86
+ memory_key_padding_mask: torch.Tensor = None,
87
+ pos: torch.Tensor = None,
88
+ query_pos: torch.Tensor = None,
89
+ **kwargs,
90
+ ) -> torch.Tensor:
91
+ """Forward pass for post-norm architecture.
92
+
93
+ In post-norm architecture, normalization is applied after attention and feedforward operations.
94
+
95
+ Args:
96
+ tgt: Input tensor to be processed
97
+ memory: Memory tensor for cross-attention
98
+ tgt_mask: Mask for self-attention
99
+ memory_mask: Mask for cross-attention
100
+ tgt_key_padding_mask: Key padding mask for self-attention
101
+ memory_key_padding_mask: Key padding mask for cross-attention
102
+ pos: Positional encoding for memory
103
+ query_pos: Positional encoding for query
104
+ **kwargs: Additional keyword arguments
105
+
106
+ Returns:
107
+ Processed tensor
108
+ """
109
+ q = k = tgt + query_pos if self.pos_enc_at_attn else tgt
110
+
111
+ # Self attention
112
+ tgt2 = self.self_attn(
113
+ q, k, value=tgt, attn_mask=tgt_mask, key_padding_mask=tgt_key_padding_mask, need_weights=False
114
+ )[0]
115
+ tgt = tgt + self.dropout1(tgt2)
116
+ tgt = self.norm1(tgt)
117
+
118
+ # Cross attention to image
119
+ tgt2 = self.cross_attn_image(
120
+ query=tgt + query_pos if self.pos_enc_at_cross_attn_queries else tgt,
121
+ key=memory + pos if self.pos_enc_at_cross_attn_keys else memory,
122
+ value=memory,
123
+ attn_mask=memory_mask,
124
+ key_padding_mask=memory_key_padding_mask,
125
+ need_weights=False,
126
+ )[0]
127
+ tgt = tgt + self.dropout2(tgt2)
128
+ tgt = self.norm2(tgt)
129
+
130
+ # FFN
131
+ tgt2 = self.linear2(self.dropout(self.activation(self.linear1(tgt))))
132
+ tgt = tgt + self.dropout3(tgt2)
133
+ tgt = self.norm3(tgt)
134
+ return tgt
135
+
136
+ def forward_pre(
137
+ self,
138
+ tgt: torch.Tensor,
139
+ memory: torch.Tensor,
140
+ dac: bool = False,
141
+ tgt_mask: torch.Tensor = None,
142
+ memory_mask: torch.Tensor = None,
143
+ tgt_key_padding_mask: torch.Tensor = None,
144
+ memory_key_padding_mask: torch.Tensor = None,
145
+ pos: torch.Tensor = None,
146
+ query_pos: torch.Tensor = None,
147
+ ) -> torch.Tensor:
148
+ """Forward pass for pre-norm architecture.
149
+
150
+ In pre-norm architecture, normalization is applied before attention and feedforward operations.
151
+
152
+ Args:
153
+ tgt: Input tensor to be processed
154
+ memory: Memory tensor for cross-attention
155
+ dac: Whether to use Divide-and-Conquer attention
156
+ tgt_mask: Mask for self-attention
157
+ memory_mask: Mask for cross-attention
158
+ tgt_key_padding_mask: Key padding mask for self-attention
159
+ memory_key_padding_mask: Key padding mask for cross-attention
160
+ pos: Positional encoding for memory
161
+ query_pos: Positional encoding for query
162
+
163
+ Returns:
164
+ Processed tensor
165
+ """
166
+ if dac:
167
+ # we only apply self attention to the first half of the queries
168
+ assert tgt.shape[0] % 2 == 0
169
+ other_tgt = tgt[tgt.shape[0] // 2 :]
170
+ tgt = tgt[: tgt.shape[0] // 2]
171
+ tgt2 = self.norm1(tgt).contiguous()
172
+ q = k = tgt2 + query_pos if self.pos_enc_at_attn else tgt2
173
+ tgt2 = self.self_attn(q, k, value=tgt2, attn_mask=tgt_mask, key_padding_mask=tgt_key_padding_mask)[0]
174
+ tgt = tgt + self.dropout1(tgt2)
175
+ if dac:
176
+ # Recombine
177
+ tgt = torch.cat((tgt, other_tgt), dim=0)
178
+ tgt2 = self.norm2(tgt)
179
+ memory = memory.to(tgt2.dtype).contiguous()
180
+ tgt2 = self.cross_attn_image(
181
+ query=tgt2 + query_pos if self.pos_enc_at_cross_attn_queries else tgt2,
182
+ key=memory + pos if self.pos_enc_at_cross_attn_keys else memory,
183
+ value=memory,
184
+ attn_mask=memory_mask,
185
+ key_padding_mask=memory_key_padding_mask,
186
+ )[0]
187
+ tgt = tgt + self.dropout2(tgt2)
188
+ tgt2 = self.norm3(tgt)
189
+ tgt2 = self.linear2(self.dropout(self.activation(self.linear1(tgt2))))
190
+ tgt = tgt + self.dropout3(tgt2)
191
+ return tgt
192
+
193
+ def forward(
194
+ self,
195
+ tgt: torch.Tensor,
196
+ memory: torch.Tensor,
197
+ dac: bool = False,
198
+ tgt_mask: torch.Tensor = None,
199
+ memory_mask: torch.Tensor = None,
200
+ tgt_key_padding_mask: torch.Tensor = None,
201
+ memory_key_padding_mask: torch.Tensor = None,
202
+ pos: torch.Tensor = None,
203
+ query_pos: torch.Tensor = None,
204
+ ) -> torch.Tensor:
205
+ """Forward pass for the transformer encoder layer.
206
+
207
+ Args:
208
+ tgt: Input tensor to be processed
209
+ memory: Memory tensor (e.g., image features) for cross-attention
210
+ dac: Whether to use Divide-and-Conquer attention (only apply self-attention to first half)
211
+ tgt_mask: Mask for self-attention
212
+ memory_mask: Mask for cross-attention
213
+ tgt_key_padding_mask: Key padding mask for self-attention
214
+ memory_key_padding_mask: Key padding mask for cross-attention
215
+ pos: Positional encoding for memory
216
+ query_pos: Positional encoding for query
217
+
218
+ Returns:
219
+ Processed tensor after self-attention, cross-attention, and feedforward network
220
+ """
221
+ fwd_fn = self.forward_pre if self.pre_norm else self.forward_post
222
+ return fwd_fn(
223
+ tgt,
224
+ memory,
225
+ dac=dac,
226
+ tgt_mask=tgt_mask,
227
+ memory_mask=memory_mask,
228
+ tgt_key_padding_mask=tgt_key_padding_mask,
229
+ memory_key_padding_mask=memory_key_padding_mask,
230
+ pos=pos,
231
+ query_pos=query_pos,
232
+ # attn_bias=attn_bias,
233
+ # **kwds,
234
+ )
235
+
236
+
237
+ class TransformerEncoder(nn.Module):
238
+ """Transformer encoder that processes multi-level features.
239
+
240
+ This encoder takes multi-level features (e.g., from a backbone network) and processes them through a stack of
241
+ transformer encoder layers. It supports features from multiple levels (e.g., different resolutions) and can apply
242
+ activation checkpointing for memory efficiency during training.
243
+
244
+ Args:
245
+ layer: The encoder layer to be stacked multiple times
246
+ num_layers: Number of encoder layers to stack
247
+ d_model: Model dimension/hidden size
248
+ num_feature_levels: Number of feature levels to process
249
+ frozen: Whether to freeze the parameters of this module
250
+ use_act_checkpoint: Whether to use activation checkpointing during training
251
+ """
252
+
253
+ def __init__(
254
+ self,
255
+ layer: nn.Module,
256
+ num_layers: int,
257
+ d_model: int,
258
+ num_feature_levels: int,
259
+ frozen: bool = False,
260
+ use_act_checkpoint: bool = False,
261
+ ):
262
+ """Initialize the transformer encoder."""
263
+ super().__init__()
264
+ self.layers = _get_clones(layer, num_layers)
265
+ self.num_layers = num_layers
266
+
267
+ self.num_feature_levels = num_feature_levels
268
+ self.level_embed = None
269
+ if num_feature_levels > 1:
270
+ self.level_embed = nn.Parameter(torch.Tensor(num_feature_levels, d_model))
271
+
272
+ if frozen:
273
+ for p in self.parameters():
274
+ p.requires_grad_(False)
275
+
276
+ self.use_act_checkpoint = use_act_checkpoint
277
+
278
+ # assign layer index to each layer so that some layers can decide what to do
279
+ # based on which layer index they are (e.g. cross attention to memory bank only
280
+ # in selected layers)
281
+ for layer_idx, layer in enumerate(self.layers):
282
+ layer.layer_idx = layer_idx
283
+
284
+ def _prepare_multilevel_features(self, srcs, masks, pos_embeds):
285
+ """Prepare multi-level features for transformer encoder."""
286
+ assert len(srcs) == self.num_feature_levels, "mismatch between expected and received # of feature levels"
287
+
288
+ src_flatten = []
289
+ mask_flatten = []
290
+ lvl_pos_embed_flatten = []
291
+ spatial_shapes = []
292
+ has_mask = masks is not None and masks[0] is not None
293
+ for lvl, (src, mask, pos_embed) in enumerate(zip(srcs, masks, pos_embeds)):
294
+ _, _, h, w = src.shape
295
+ spatial_shape = (h, w)
296
+ spatial_shapes.append(spatial_shape)
297
+
298
+ src = src.flatten(2).transpose(1, 2) # bs, hw, c
299
+ if has_mask:
300
+ mask = mask.flatten(1)
301
+ pos_embed = pos_embed.flatten(2).transpose(1, 2) # bs, hw, c
302
+ if self.level_embed is not None:
303
+ lvl_pos_embed = pos_embed + self.level_embed[lvl].view(1, 1, -1)
304
+ else:
305
+ lvl_pos_embed = pos_embed
306
+ lvl_pos_embed_flatten.append(lvl_pos_embed)
307
+ src_flatten.append(src)
308
+ if has_mask:
309
+ mask_flatten.append(mask)
310
+ src_flatten = torch.cat(src_flatten, 1) # bs, \sum{hxw}, c
311
+ mask_flatten = torch.cat(mask_flatten, 1) if has_mask else None # bs, \sum{hxw}
312
+ lvl_pos_embed_flatten = torch.cat(lvl_pos_embed_flatten, 1) # bs, \sum{hxw}, c
313
+ spatial_shapes = torch.tensor(spatial_shapes, dtype=torch.long, device=src_flatten.device)
314
+ level_start_index = torch.cat(
315
+ (
316
+ spatial_shapes.new_zeros((1,)),
317
+ spatial_shapes.prod(1).cumsum(0)[:-1],
318
+ )
319
+ )
320
+ if has_mask:
321
+ valid_ratios = torch.stack([get_valid_ratio(m) for m in masks], 1)
322
+ else:
323
+ valid_ratios = torch.ones(
324
+ (src_flatten.shape[0], self.num_feature_levels, 2),
325
+ device=src_flatten.device,
326
+ dtype=src_flatten.dtype,
327
+ )
328
+
329
+ return (
330
+ src_flatten,
331
+ mask_flatten,
332
+ lvl_pos_embed_flatten,
333
+ level_start_index,
334
+ valid_ratios,
335
+ spatial_shapes,
336
+ )
337
+
338
+ def forward(
339
+ self,
340
+ src: list[torch.Tensor],
341
+ src_key_padding_masks: list[torch.Tensor] | None = None,
342
+ pos: list[torch.Tensor] | None = None,
343
+ prompt: torch.Tensor = None,
344
+ prompt_key_padding_mask: torch.Tensor = None,
345
+ encoder_extra_kwargs: dict | None = None,
346
+ ) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]:
347
+ """Process multi-level features through the transformer encoder.
348
+
349
+ Args:
350
+ src: List of multi-level features, each with shape (batch_size, channels, height, width)
351
+ src_key_padding_masks: List of padding masks for each feature level, each with shape (batch_size, height,
352
+ width)
353
+ pos: List of positional embeddings for each feature level, each with shape (batch_size, channels, height,
354
+ width)
355
+ prompt: Optional text/prompt features to attend to, with shape (seq_len, batch_size, d_model)
356
+ prompt_key_padding_mask: Optional padding mask for prompt, with shape (batch_size, seq_len)
357
+ encoder_extra_kwargs: Optional additional arguments to pass to each encoder layer
358
+
359
+ Returns:
360
+ A tuple containing:
361
+ - output: Processed features with shape (seq_len, batch_size, d_model)
362
+ - key_padding_masks_flatten: Flattened padding masks
363
+ - lvl_pos_embed_flatten: Flattened positional embeddings
364
+ - level_start_index: Starting indices for each feature level
365
+ - spatial_shapes: Spatial dimensions of each feature level
366
+ - valid_ratios: Valid ratios for each feature level
367
+ """
368
+ assert len(src) == self.num_feature_levels, "must be equal to num_feature_levels"
369
+ if src_key_padding_masks is not None:
370
+ assert len(src_key_padding_masks) == self.num_feature_levels
371
+ if pos is not None:
372
+ assert len(pos) == self.num_feature_levels
373
+ # Flatten multilevel feats and add level pos embeds
374
+ (
375
+ src_flatten,
376
+ key_padding_masks_flatten,
377
+ lvl_pos_embed_flatten,
378
+ level_start_index,
379
+ valid_ratios,
380
+ spatial_shapes,
381
+ ) = self._prepare_multilevel_features(src, src_key_padding_masks, pos)
382
+
383
+ output = src_flatten
384
+ for layer in self.layers:
385
+ layer_kwargs = {}
386
+
387
+ assert isinstance(layer, TransformerEncoderLayer)
388
+ layer_kwargs["memory"] = prompt
389
+ layer_kwargs["memory_key_padding_mask"] = prompt_key_padding_mask
390
+ layer_kwargs["query_pos"] = lvl_pos_embed_flatten
391
+ layer_kwargs["tgt"] = output
392
+ layer_kwargs["tgt_key_padding_mask"] = key_padding_masks_flatten
393
+
394
+ if self.training:
395
+ assert self.use_act_checkpoint, "activation ckpt not enabled in encoder"
396
+ if encoder_extra_kwargs is not None:
397
+ layer_kwargs.update(encoder_extra_kwargs)
398
+ output = layer(**layer_kwargs)
399
+ # return as seq first
400
+ return (
401
+ output.transpose(0, 1),
402
+ (key_padding_masks_flatten.transpose(0, 1) if key_padding_masks_flatten is not None else None),
403
+ lvl_pos_embed_flatten.transpose(0, 1),
404
+ level_start_index,
405
+ spatial_shapes,
406
+ valid_ratios,
407
+ )
408
+
409
+
410
+ class TransformerEncoderFusion(TransformerEncoder):
411
+ """Transformer encoder that fuses text and image features.
412
+
413
+ This encoder extends TransformerEncoder to handle both text and image features, with the ability to add pooled text
414
+ features to image features for better cross-modal fusion. It supports torch.compile for performance optimization.
415
+
416
+ Args:
417
+ layer: The encoder layer to be stacked multiple times
418
+ num_layers: Number of encoder layers to stack
419
+ d_model: Model dimension/hidden size
420
+ num_feature_levels: Number of feature levels to process
421
+ add_pooled_text_to_img_feat: Whether to add pooled text features to image features
422
+ pool_text_with_mask: Whether to use the mask when pooling text features
423
+ compile_mode: Mode for torch.compile, or None to disable compilation
424
+ **kwargs: Additional arguments to pass to the parent class
425
+ """
426
+
427
+ def __init__(
428
+ self,
429
+ layer: nn.Module,
430
+ num_layers: int,
431
+ d_model: int,
432
+ num_feature_levels: int,
433
+ add_pooled_text_to_img_feat: bool = True,
434
+ pool_text_with_mask: bool = False,
435
+ compile_mode: str | None = None,
436
+ **kwargs,
437
+ ):
438
+ """Initialize the transformer encoder with text-image fusion."""
439
+ super().__init__(
440
+ layer,
441
+ num_layers,
442
+ d_model,
443
+ num_feature_levels,
444
+ **kwargs,
445
+ )
446
+ self.add_pooled_text_to_img_feat = add_pooled_text_to_img_feat
447
+ if self.add_pooled_text_to_img_feat:
448
+ self.text_pooling_proj = nn.Linear(d_model, d_model)
449
+ self.pool_text_with_mask = pool_text_with_mask
450
+ if compile_mode is not None:
451
+ self.forward = torch.compile(self.forward, mode=compile_mode, fullgraph=True)
452
+
453
+ def forward(
454
+ self,
455
+ src: list[torch.Tensor],
456
+ prompt: torch.Tensor,
457
+ src_key_padding_mask: list[torch.Tensor] | None = None,
458
+ src_pos: list[torch.Tensor] | None = None,
459
+ prompt_key_padding_mask: torch.Tensor = None,
460
+ feat_sizes: list[int] | None = None,
461
+ encoder_extra_kwargs: dict | None = None,
462
+ ):
463
+ """Forward pass for the transformer encoder with text-image fusion."""
464
+ # Restore spatial shapes of vision
465
+ bs = src[0].shape[1] # seq first
466
+ if feat_sizes is not None:
467
+ assert len(feat_sizes) == len(src)
468
+ if src_key_padding_mask is None:
469
+ src_key_padding_mask = [None] * len(src)
470
+ for i, (h, w) in enumerate(feat_sizes):
471
+ src[i] = src[i].reshape(h, w, bs, -1).permute(2, 3, 0, 1)
472
+ src_pos[i] = src_pos[i].reshape(h, w, bs, -1).permute(2, 3, 0, 1)
473
+ src_key_padding_mask[i] = (
474
+ src_key_padding_mask[i].reshape(h, w, bs).permute(2, 0, 1)
475
+ if src_key_padding_mask[i] is not None
476
+ else None
477
+ )
478
+ else:
479
+ assert all(x.dim == 4 for x in src), "expected list of (bs, c, h, w) tensors"
480
+
481
+ if self.add_pooled_text_to_img_feat:
482
+ # Fusion: Add mean pooled text to image features
483
+ pooled_text = pool_text_feat(prompt, prompt_key_padding_mask, self.pool_text_with_mask)
484
+ pooled_text = self.text_pooling_proj(pooled_text)[..., None, None] # prompt is seq first
485
+ src = [x.add_(pooled_text) for x in src]
486
+
487
+ (
488
+ out,
489
+ key_padding_masks_flatten,
490
+ lvl_pos_embed_flatten,
491
+ level_start_index,
492
+ spatial_shapes,
493
+ valid_ratios,
494
+ ) = super().forward(
495
+ src,
496
+ src_key_padding_masks=src_key_padding_mask,
497
+ pos=src_pos,
498
+ prompt=prompt.transpose(0, 1),
499
+ prompt_key_padding_mask=prompt_key_padding_mask,
500
+ encoder_extra_kwargs=encoder_extra_kwargs,
501
+ )
502
+
503
+ return {
504
+ "memory": out,
505
+ "padding_mask": key_padding_masks_flatten,
506
+ "pos_embed": lvl_pos_embed_flatten,
507
+ "memory_text": prompt,
508
+ "level_start_index": level_start_index,
509
+ "spatial_shapes": spatial_shapes,
510
+ "valid_ratios": valid_ratios,
511
+ }
512
+
513
+
514
+ def pool_text_feat(prompt, prompt_mask, pool_with_mask):
515
+ """Mean-pool the prompt embeddings over the valid tokens only."""
516
+ # prompt has shape (seq, bs, dim)
517
+ if not pool_with_mask:
518
+ return prompt.mean(dim=0)
519
+
520
+ # prompt_mask has shape (bs, seq), where False is valid and True is padding
521
+ assert prompt_mask.dim() == 2
522
+ # is_valid has shape (seq, bs, 1), where 1 is valid and 0 is padding
523
+ is_valid = (~prompt_mask).float().permute(1, 0)[..., None]
524
+ # num_valid has shape (bs, 1)
525
+ num_valid = torch.clamp(torch.sum(is_valid, dim=0), min=1.0)
526
+
527
+ # mean pool over all the valid tokens
528
+ pooled_text = (prompt * is_valid).sum(dim=0) / num_valid
529
+ return pooled_text