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.
- dgenerate_ultralytics_headless-8.3.253.dist-info/METADATA +405 -0
- dgenerate_ultralytics_headless-8.3.253.dist-info/RECORD +299 -0
- dgenerate_ultralytics_headless-8.3.253.dist-info/WHEEL +5 -0
- dgenerate_ultralytics_headless-8.3.253.dist-info/entry_points.txt +3 -0
- dgenerate_ultralytics_headless-8.3.253.dist-info/licenses/LICENSE +661 -0
- dgenerate_ultralytics_headless-8.3.253.dist-info/top_level.txt +1 -0
- tests/__init__.py +23 -0
- tests/conftest.py +59 -0
- tests/test_cli.py +131 -0
- tests/test_cuda.py +216 -0
- tests/test_engine.py +157 -0
- tests/test_exports.py +309 -0
- tests/test_integrations.py +151 -0
- tests/test_python.py +777 -0
- tests/test_solutions.py +371 -0
- ultralytics/__init__.py +48 -0
- ultralytics/assets/bus.jpg +0 -0
- ultralytics/assets/zidane.jpg +0 -0
- ultralytics/cfg/__init__.py +1028 -0
- ultralytics/cfg/datasets/Argoverse.yaml +78 -0
- ultralytics/cfg/datasets/DOTAv1.5.yaml +37 -0
- ultralytics/cfg/datasets/DOTAv1.yaml +36 -0
- ultralytics/cfg/datasets/GlobalWheat2020.yaml +68 -0
- ultralytics/cfg/datasets/HomeObjects-3K.yaml +32 -0
- ultralytics/cfg/datasets/ImageNet.yaml +2025 -0
- ultralytics/cfg/datasets/Objects365.yaml +447 -0
- ultralytics/cfg/datasets/SKU-110K.yaml +58 -0
- ultralytics/cfg/datasets/TT100K.yaml +346 -0
- ultralytics/cfg/datasets/VOC.yaml +102 -0
- ultralytics/cfg/datasets/VisDrone.yaml +87 -0
- ultralytics/cfg/datasets/african-wildlife.yaml +25 -0
- ultralytics/cfg/datasets/brain-tumor.yaml +22 -0
- ultralytics/cfg/datasets/carparts-seg.yaml +44 -0
- ultralytics/cfg/datasets/coco-pose.yaml +64 -0
- ultralytics/cfg/datasets/coco.yaml +118 -0
- ultralytics/cfg/datasets/coco128-seg.yaml +101 -0
- ultralytics/cfg/datasets/coco128.yaml +101 -0
- ultralytics/cfg/datasets/coco8-grayscale.yaml +103 -0
- ultralytics/cfg/datasets/coco8-multispectral.yaml +104 -0
- ultralytics/cfg/datasets/coco8-pose.yaml +47 -0
- ultralytics/cfg/datasets/coco8-seg.yaml +101 -0
- ultralytics/cfg/datasets/coco8.yaml +101 -0
- ultralytics/cfg/datasets/construction-ppe.yaml +32 -0
- ultralytics/cfg/datasets/crack-seg.yaml +22 -0
- ultralytics/cfg/datasets/dog-pose.yaml +52 -0
- ultralytics/cfg/datasets/dota8-multispectral.yaml +38 -0
- ultralytics/cfg/datasets/dota8.yaml +35 -0
- ultralytics/cfg/datasets/hand-keypoints.yaml +50 -0
- ultralytics/cfg/datasets/kitti.yaml +27 -0
- ultralytics/cfg/datasets/lvis.yaml +1240 -0
- ultralytics/cfg/datasets/medical-pills.yaml +21 -0
- ultralytics/cfg/datasets/open-images-v7.yaml +663 -0
- ultralytics/cfg/datasets/package-seg.yaml +22 -0
- ultralytics/cfg/datasets/signature.yaml +21 -0
- ultralytics/cfg/datasets/tiger-pose.yaml +41 -0
- ultralytics/cfg/datasets/xView.yaml +155 -0
- ultralytics/cfg/default.yaml +130 -0
- ultralytics/cfg/models/11/yolo11-cls-resnet18.yaml +17 -0
- ultralytics/cfg/models/11/yolo11-cls.yaml +33 -0
- ultralytics/cfg/models/11/yolo11-obb.yaml +50 -0
- ultralytics/cfg/models/11/yolo11-pose.yaml +51 -0
- ultralytics/cfg/models/11/yolo11-seg.yaml +50 -0
- ultralytics/cfg/models/11/yolo11.yaml +50 -0
- ultralytics/cfg/models/11/yoloe-11-seg.yaml +48 -0
- ultralytics/cfg/models/11/yoloe-11.yaml +48 -0
- ultralytics/cfg/models/12/yolo12-cls.yaml +32 -0
- ultralytics/cfg/models/12/yolo12-obb.yaml +48 -0
- ultralytics/cfg/models/12/yolo12-pose.yaml +49 -0
- ultralytics/cfg/models/12/yolo12-seg.yaml +48 -0
- ultralytics/cfg/models/12/yolo12.yaml +48 -0
- ultralytics/cfg/models/rt-detr/rtdetr-l.yaml +53 -0
- ultralytics/cfg/models/rt-detr/rtdetr-resnet101.yaml +45 -0
- ultralytics/cfg/models/rt-detr/rtdetr-resnet50.yaml +45 -0
- ultralytics/cfg/models/rt-detr/rtdetr-x.yaml +57 -0
- ultralytics/cfg/models/v10/yolov10b.yaml +45 -0
- ultralytics/cfg/models/v10/yolov10l.yaml +45 -0
- ultralytics/cfg/models/v10/yolov10m.yaml +45 -0
- ultralytics/cfg/models/v10/yolov10n.yaml +45 -0
- ultralytics/cfg/models/v10/yolov10s.yaml +45 -0
- ultralytics/cfg/models/v10/yolov10x.yaml +45 -0
- ultralytics/cfg/models/v3/yolov3-spp.yaml +49 -0
- ultralytics/cfg/models/v3/yolov3-tiny.yaml +40 -0
- ultralytics/cfg/models/v3/yolov3.yaml +49 -0
- ultralytics/cfg/models/v5/yolov5-p6.yaml +62 -0
- ultralytics/cfg/models/v5/yolov5.yaml +51 -0
- ultralytics/cfg/models/v6/yolov6.yaml +56 -0
- ultralytics/cfg/models/v8/yoloe-v8-seg.yaml +48 -0
- ultralytics/cfg/models/v8/yoloe-v8.yaml +48 -0
- ultralytics/cfg/models/v8/yolov8-cls-resnet101.yaml +28 -0
- ultralytics/cfg/models/v8/yolov8-cls-resnet50.yaml +28 -0
- ultralytics/cfg/models/v8/yolov8-cls.yaml +32 -0
- ultralytics/cfg/models/v8/yolov8-ghost-p2.yaml +58 -0
- ultralytics/cfg/models/v8/yolov8-ghost-p6.yaml +60 -0
- ultralytics/cfg/models/v8/yolov8-ghost.yaml +50 -0
- ultralytics/cfg/models/v8/yolov8-obb.yaml +49 -0
- ultralytics/cfg/models/v8/yolov8-p2.yaml +57 -0
- ultralytics/cfg/models/v8/yolov8-p6.yaml +59 -0
- ultralytics/cfg/models/v8/yolov8-pose-p6.yaml +60 -0
- ultralytics/cfg/models/v8/yolov8-pose.yaml +50 -0
- ultralytics/cfg/models/v8/yolov8-rtdetr.yaml +49 -0
- ultralytics/cfg/models/v8/yolov8-seg-p6.yaml +59 -0
- ultralytics/cfg/models/v8/yolov8-seg.yaml +49 -0
- ultralytics/cfg/models/v8/yolov8-world.yaml +51 -0
- ultralytics/cfg/models/v8/yolov8-worldv2.yaml +49 -0
- ultralytics/cfg/models/v8/yolov8.yaml +49 -0
- ultralytics/cfg/models/v9/yolov9c-seg.yaml +41 -0
- ultralytics/cfg/models/v9/yolov9c.yaml +41 -0
- ultralytics/cfg/models/v9/yolov9e-seg.yaml +64 -0
- ultralytics/cfg/models/v9/yolov9e.yaml +64 -0
- ultralytics/cfg/models/v9/yolov9m.yaml +41 -0
- ultralytics/cfg/models/v9/yolov9s.yaml +41 -0
- ultralytics/cfg/models/v9/yolov9t.yaml +41 -0
- ultralytics/cfg/trackers/botsort.yaml +21 -0
- ultralytics/cfg/trackers/bytetrack.yaml +12 -0
- ultralytics/data/__init__.py +26 -0
- ultralytics/data/annotator.py +66 -0
- ultralytics/data/augment.py +2801 -0
- ultralytics/data/base.py +435 -0
- ultralytics/data/build.py +437 -0
- ultralytics/data/converter.py +855 -0
- ultralytics/data/dataset.py +834 -0
- ultralytics/data/loaders.py +704 -0
- ultralytics/data/scripts/download_weights.sh +18 -0
- ultralytics/data/scripts/get_coco.sh +61 -0
- ultralytics/data/scripts/get_coco128.sh +18 -0
- ultralytics/data/scripts/get_imagenet.sh +52 -0
- ultralytics/data/split.py +138 -0
- ultralytics/data/split_dota.py +344 -0
- ultralytics/data/utils.py +798 -0
- ultralytics/engine/__init__.py +1 -0
- ultralytics/engine/exporter.py +1580 -0
- ultralytics/engine/model.py +1125 -0
- ultralytics/engine/predictor.py +508 -0
- ultralytics/engine/results.py +1522 -0
- ultralytics/engine/trainer.py +977 -0
- ultralytics/engine/tuner.py +449 -0
- ultralytics/engine/validator.py +387 -0
- ultralytics/hub/__init__.py +166 -0
- ultralytics/hub/auth.py +151 -0
- ultralytics/hub/google/__init__.py +174 -0
- ultralytics/hub/session.py +422 -0
- ultralytics/hub/utils.py +162 -0
- ultralytics/models/__init__.py +9 -0
- ultralytics/models/fastsam/__init__.py +7 -0
- ultralytics/models/fastsam/model.py +79 -0
- ultralytics/models/fastsam/predict.py +169 -0
- ultralytics/models/fastsam/utils.py +23 -0
- ultralytics/models/fastsam/val.py +38 -0
- ultralytics/models/nas/__init__.py +7 -0
- ultralytics/models/nas/model.py +98 -0
- ultralytics/models/nas/predict.py +56 -0
- ultralytics/models/nas/val.py +38 -0
- ultralytics/models/rtdetr/__init__.py +7 -0
- ultralytics/models/rtdetr/model.py +63 -0
- ultralytics/models/rtdetr/predict.py +88 -0
- ultralytics/models/rtdetr/train.py +89 -0
- ultralytics/models/rtdetr/val.py +216 -0
- ultralytics/models/sam/__init__.py +25 -0
- ultralytics/models/sam/amg.py +275 -0
- ultralytics/models/sam/build.py +365 -0
- ultralytics/models/sam/build_sam3.py +377 -0
- ultralytics/models/sam/model.py +169 -0
- ultralytics/models/sam/modules/__init__.py +1 -0
- ultralytics/models/sam/modules/blocks.py +1067 -0
- ultralytics/models/sam/modules/decoders.py +495 -0
- ultralytics/models/sam/modules/encoders.py +794 -0
- ultralytics/models/sam/modules/memory_attention.py +298 -0
- ultralytics/models/sam/modules/sam.py +1160 -0
- ultralytics/models/sam/modules/tiny_encoder.py +979 -0
- ultralytics/models/sam/modules/transformer.py +344 -0
- ultralytics/models/sam/modules/utils.py +512 -0
- ultralytics/models/sam/predict.py +3940 -0
- ultralytics/models/sam/sam3/__init__.py +3 -0
- ultralytics/models/sam/sam3/decoder.py +546 -0
- ultralytics/models/sam/sam3/encoder.py +529 -0
- ultralytics/models/sam/sam3/geometry_encoders.py +415 -0
- ultralytics/models/sam/sam3/maskformer_segmentation.py +286 -0
- ultralytics/models/sam/sam3/model_misc.py +199 -0
- ultralytics/models/sam/sam3/necks.py +129 -0
- ultralytics/models/sam/sam3/sam3_image.py +339 -0
- ultralytics/models/sam/sam3/text_encoder_ve.py +307 -0
- ultralytics/models/sam/sam3/vitdet.py +547 -0
- ultralytics/models/sam/sam3/vl_combiner.py +160 -0
- ultralytics/models/utils/__init__.py +1 -0
- ultralytics/models/utils/loss.py +466 -0
- ultralytics/models/utils/ops.py +315 -0
- ultralytics/models/yolo/__init__.py +7 -0
- ultralytics/models/yolo/classify/__init__.py +7 -0
- ultralytics/models/yolo/classify/predict.py +90 -0
- ultralytics/models/yolo/classify/train.py +202 -0
- ultralytics/models/yolo/classify/val.py +216 -0
- ultralytics/models/yolo/detect/__init__.py +7 -0
- ultralytics/models/yolo/detect/predict.py +122 -0
- ultralytics/models/yolo/detect/train.py +227 -0
- ultralytics/models/yolo/detect/val.py +507 -0
- ultralytics/models/yolo/model.py +430 -0
- ultralytics/models/yolo/obb/__init__.py +7 -0
- ultralytics/models/yolo/obb/predict.py +56 -0
- ultralytics/models/yolo/obb/train.py +79 -0
- ultralytics/models/yolo/obb/val.py +302 -0
- ultralytics/models/yolo/pose/__init__.py +7 -0
- ultralytics/models/yolo/pose/predict.py +65 -0
- ultralytics/models/yolo/pose/train.py +110 -0
- ultralytics/models/yolo/pose/val.py +248 -0
- ultralytics/models/yolo/segment/__init__.py +7 -0
- ultralytics/models/yolo/segment/predict.py +109 -0
- ultralytics/models/yolo/segment/train.py +69 -0
- ultralytics/models/yolo/segment/val.py +307 -0
- ultralytics/models/yolo/world/__init__.py +5 -0
- ultralytics/models/yolo/world/train.py +173 -0
- ultralytics/models/yolo/world/train_world.py +178 -0
- ultralytics/models/yolo/yoloe/__init__.py +22 -0
- ultralytics/models/yolo/yoloe/predict.py +162 -0
- ultralytics/models/yolo/yoloe/train.py +287 -0
- ultralytics/models/yolo/yoloe/train_seg.py +122 -0
- ultralytics/models/yolo/yoloe/val.py +206 -0
- ultralytics/nn/__init__.py +27 -0
- ultralytics/nn/autobackend.py +964 -0
- ultralytics/nn/modules/__init__.py +182 -0
- ultralytics/nn/modules/activation.py +54 -0
- ultralytics/nn/modules/block.py +1947 -0
- ultralytics/nn/modules/conv.py +669 -0
- ultralytics/nn/modules/head.py +1183 -0
- ultralytics/nn/modules/transformer.py +793 -0
- ultralytics/nn/modules/utils.py +159 -0
- ultralytics/nn/tasks.py +1768 -0
- ultralytics/nn/text_model.py +356 -0
- ultralytics/py.typed +1 -0
- ultralytics/solutions/__init__.py +41 -0
- ultralytics/solutions/ai_gym.py +108 -0
- ultralytics/solutions/analytics.py +264 -0
- ultralytics/solutions/config.py +107 -0
- ultralytics/solutions/distance_calculation.py +123 -0
- ultralytics/solutions/heatmap.py +125 -0
- ultralytics/solutions/instance_segmentation.py +86 -0
- ultralytics/solutions/object_blurrer.py +89 -0
- ultralytics/solutions/object_counter.py +190 -0
- ultralytics/solutions/object_cropper.py +87 -0
- ultralytics/solutions/parking_management.py +280 -0
- ultralytics/solutions/queue_management.py +93 -0
- ultralytics/solutions/region_counter.py +133 -0
- ultralytics/solutions/security_alarm.py +151 -0
- ultralytics/solutions/similarity_search.py +219 -0
- ultralytics/solutions/solutions.py +828 -0
- ultralytics/solutions/speed_estimation.py +114 -0
- ultralytics/solutions/streamlit_inference.py +260 -0
- ultralytics/solutions/templates/similarity-search.html +156 -0
- ultralytics/solutions/trackzone.py +88 -0
- ultralytics/solutions/vision_eye.py +67 -0
- ultralytics/trackers/__init__.py +7 -0
- ultralytics/trackers/basetrack.py +115 -0
- ultralytics/trackers/bot_sort.py +257 -0
- ultralytics/trackers/byte_tracker.py +469 -0
- ultralytics/trackers/track.py +116 -0
- ultralytics/trackers/utils/__init__.py +1 -0
- ultralytics/trackers/utils/gmc.py +339 -0
- ultralytics/trackers/utils/kalman_filter.py +482 -0
- ultralytics/trackers/utils/matching.py +154 -0
- ultralytics/utils/__init__.py +1450 -0
- ultralytics/utils/autobatch.py +118 -0
- ultralytics/utils/autodevice.py +205 -0
- ultralytics/utils/benchmarks.py +728 -0
- ultralytics/utils/callbacks/__init__.py +5 -0
- ultralytics/utils/callbacks/base.py +233 -0
- ultralytics/utils/callbacks/clearml.py +146 -0
- ultralytics/utils/callbacks/comet.py +625 -0
- ultralytics/utils/callbacks/dvc.py +197 -0
- ultralytics/utils/callbacks/hub.py +110 -0
- ultralytics/utils/callbacks/mlflow.py +134 -0
- ultralytics/utils/callbacks/neptune.py +126 -0
- ultralytics/utils/callbacks/platform.py +453 -0
- ultralytics/utils/callbacks/raytune.py +42 -0
- ultralytics/utils/callbacks/tensorboard.py +123 -0
- ultralytics/utils/callbacks/wb.py +188 -0
- ultralytics/utils/checks.py +1020 -0
- ultralytics/utils/cpu.py +85 -0
- ultralytics/utils/dist.py +123 -0
- ultralytics/utils/downloads.py +529 -0
- ultralytics/utils/errors.py +35 -0
- ultralytics/utils/events.py +113 -0
- ultralytics/utils/export/__init__.py +7 -0
- ultralytics/utils/export/engine.py +237 -0
- ultralytics/utils/export/imx.py +325 -0
- ultralytics/utils/export/tensorflow.py +231 -0
- ultralytics/utils/files.py +219 -0
- ultralytics/utils/git.py +137 -0
- ultralytics/utils/instance.py +484 -0
- ultralytics/utils/logger.py +506 -0
- ultralytics/utils/loss.py +849 -0
- ultralytics/utils/metrics.py +1563 -0
- ultralytics/utils/nms.py +337 -0
- ultralytics/utils/ops.py +664 -0
- ultralytics/utils/patches.py +201 -0
- ultralytics/utils/plotting.py +1047 -0
- ultralytics/utils/tal.py +404 -0
- ultralytics/utils/torch_utils.py +984 -0
- ultralytics/utils/tqdm.py +443 -0
- ultralytics/utils/triton.py +112 -0
- 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
|