Team Ai
Apppublic

xdecoder/Instruct-X-Decoder

sourceHugging Faceafl-3.0updated 3y agoView on Hugging Face
163likes
xdecoder.py700 linesDownload Raw Back to decoder
1# Copyright (c) Facebook, Inc. and its affiliates.2# Modified by Bowen Cheng from: https://github.com/facebookresearch/detr/blob/master/models/detr.py3 4# --------------------------------------------------------5# X-Decoder -- Generalized Decoding for Pixel, Image, and Language6# Copyright (c) 2022 Microsoft7# Licensed under The MIT License [see LICENSE for details]8# Written by Xueyan Zou (xueyan@cs.wisc.edu), Jianwei Yang (jianwyan@microsoft.com)9# --------------------------------------------------------10 11 12import logging13from typing import Optional14 15import torch16from torch import nn, Tensor17from torch.nn import functional as F18 19from timm.models.layers import trunc_normal_20from detectron2.layers import Conv2d21import fvcore.nn.weight_init as weight_init22 23from .registry import register_decoder24from ...utils import configurable25from ...modules import PositionEmbeddingSine26 27 28class SelfAttentionLayer(nn.Module):29 30    def __init__(self, d_model, nhead, dropout=0.0,31                 activation="relu", normalize_before=False):32        super().__init__()33        self.self_attn = nn.MultiheadAttention(d_model, nhead, dropout=dropout)34 35        self.norm = nn.LayerNorm(d_model)36        self.dropout = nn.Dropout(dropout)37 38        self.activation = _get_activation_fn(activation)39        self.normalize_before = normalize_before40 41        self._reset_parameters()42    43    def _reset_parameters(self):44        for p in self.parameters():45            if p.dim() > 1:46                nn.init.xavier_uniform_(p)47 48    def with_pos_embed(self, tensor, pos: Optional[Tensor]):49        return tensor if pos is None else tensor + pos50 51    def forward_post(self, tgt,52                     tgt_mask: Optional[Tensor] = None,53                     tgt_key_padding_mask: Optional[Tensor] = None,54                     query_pos: Optional[Tensor] = None):55        q = k = self.with_pos_embed(tgt, query_pos)56        tgt2 = self.self_attn(q, k, value=tgt, attn_mask=tgt_mask,57                              key_padding_mask=tgt_key_padding_mask)[0]58        tgt = tgt + self.dropout(tgt2)59        tgt = self.norm(tgt)60 61        return tgt62 63    def forward_pre(self, tgt,64                    tgt_mask: Optional[Tensor] = None,65                    tgt_key_padding_mask: Optional[Tensor] = None,66                    query_pos: Optional[Tensor] = None):67        tgt2 = self.norm(tgt)68        q = k = self.with_pos_embed(tgt2, query_pos)69        tgt2 = self.self_attn(q, k, value=tgt2, attn_mask=tgt_mask,70                              key_padding_mask=tgt_key_padding_mask)[0]71        tgt = tgt + self.dropout(tgt2)72        73        return tgt74 75    def forward(self, tgt,76                tgt_mask: Optional[Tensor] = None,77                tgt_key_padding_mask: Optional[Tensor] = None,78                query_pos: Optional[Tensor] = None):79        if self.normalize_before:80            return self.forward_pre(tgt, tgt_mask,81                                    tgt_key_padding_mask, query_pos)82        return self.forward_post(tgt, tgt_mask,83                                 tgt_key_padding_mask, query_pos)84 85 86class CrossAttentionLayer(nn.Module):87 88    def __init__(self, d_model, nhead, dropout=0.0,89                 activation="relu", normalize_before=False):90        super().__init__()91        self.multihead_attn = nn.MultiheadAttention(d_model, nhead, dropout=dropout)92 93        self.norm = nn.LayerNorm(d_model)94        self.dropout = nn.Dropout(dropout)95 96        self.activation = _get_activation_fn(activation)97        self.normalize_before = normalize_before98 99        self._reset_parameters()100    101    def _reset_parameters(self):102        for p in self.parameters():103            if p.dim() > 1:104                nn.init.xavier_uniform_(p)105 106    def with_pos_embed(self, tensor, pos: Optional[Tensor]):107        return tensor if pos is None else tensor + pos108 109    def forward_post(self, tgt, memory,110                     memory_mask: Optional[Tensor] = None,111                     memory_key_padding_mask: Optional[Tensor] = None,112                     pos: Optional[Tensor] = None,113                     query_pos: Optional[Tensor] = None):114        tgt2, avg_attn = self.multihead_attn(query=self.with_pos_embed(tgt, query_pos),115                                   key=self.with_pos_embed(memory, pos),116                                   value=memory, attn_mask=memory_mask,117                                   key_padding_mask=memory_key_padding_mask)118        tgt = tgt + self.dropout(tgt2)119        tgt = self.norm(tgt)120        return tgt, avg_attn121 122    def forward_pre(self, tgt, memory,123                    memory_mask: Optional[Tensor] = None,124                    memory_key_padding_mask: Optional[Tensor] = None,125                    pos: Optional[Tensor] = None,126                    query_pos: Optional[Tensor] = None):127        tgt2 = self.norm(tgt)128        tgt2, avg_attn = self.multihead_attn(query=self.with_pos_embed(tgt2, query_pos),129                                   key=self.with_pos_embed(memory, pos),130                                   value=memory, attn_mask=memory_mask,131                                   key_padding_mask=memory_key_padding_mask)132        tgt = tgt + self.dropout(tgt2)133 134        return tgt, avg_attn135 136    def forward(self, tgt, memory,137                memory_mask: Optional[Tensor] = None,138                memory_key_padding_mask: Optional[Tensor] = None,139                pos: Optional[Tensor] = None,140                query_pos: Optional[Tensor] = None):141        if self.normalize_before:142            return self.forward_pre(tgt, memory, memory_mask,143                                    memory_key_padding_mask, pos, query_pos)144        return self.forward_post(tgt, memory, memory_mask,145                                 memory_key_padding_mask, pos, query_pos)146 147 148class FFNLayer(nn.Module):149 150    def __init__(self, d_model, dim_feedforward=2048, dropout=0.0,151                 activation="relu", normalize_before=False):152        super().__init__()153        # Implementation of Feedforward model154        self.linear1 = nn.Linear(d_model, dim_feedforward)155        self.dropout = nn.Dropout(dropout)156        self.linear2 = nn.Linear(dim_feedforward, d_model)157 158        self.norm = nn.LayerNorm(d_model)159 160        self.activation = _get_activation_fn(activation)161        self.normalize_before = normalize_before162 163        self._reset_parameters()164    165    def _reset_parameters(self):166        for p in self.parameters():167            if p.dim() > 1:168                nn.init.xavier_uniform_(p)169 170    def with_pos_embed(self, tensor, pos: Optional[Tensor]):171        return tensor if pos is None else tensor + pos172 173    def forward_post(self, tgt):174        tgt2 = self.linear2(self.dropout(self.activation(self.linear1(tgt))))175        tgt = tgt + self.dropout(tgt2)176        tgt = self.norm(tgt)177        return tgt178 179    def forward_pre(self, tgt):180        tgt2 = self.norm(tgt)181        tgt2 = self.linear2(self.dropout(self.activation(self.linear1(tgt2))))182        tgt = tgt + self.dropout(tgt2)183        return tgt184 185    def forward(self, tgt):186        if self.normalize_before:187            return self.forward_pre(tgt)188        return self.forward_post(tgt)189 190 191def _get_activation_fn(activation):192    """Return an activation function given a string"""193    if activation == "relu":194        return F.relu195    if activation == "gelu":196        return F.gelu197    if activation == "glu":198        return F.glu199    raise RuntimeError(F"activation should be relu/gelu, not {activation}.")200 201 202class MLP(nn.Module):203    """ Very simple multi-layer perceptron (also called FFN)"""204 205    def __init__(self, input_dim, hidden_dim, output_dim, num_layers):206        super().__init__()207        self.num_layers = num_layers208        h = [hidden_dim] * (num_layers - 1)209        self.layers = nn.ModuleList(nn.Linear(n, k) for n, k in zip([input_dim] + h, h + [output_dim]))210 211    def forward(self, x):212        for i, layer in enumerate(self.layers):213            x = F.relu(layer(x)) if i < self.num_layers - 1 else layer(x)214        return x215 216 217class MultiScaleMaskedTransformerDecoder(nn.Module):218 219    _version = 2220 221    @configurable222    def __init__(223        self,224        lang_encoder: nn.Module,225        in_channels,226        mask_classification=True,227        *,228        hidden_dim: int,229        dim_proj: int,230        num_queries: int,231        contxt_len: int,232        nheads: int,233        dim_feedforward: int,234        dec_layers: int,235        pre_norm: bool,236        mask_dim: int,237        task_switch: dict,238        captioning_step: int,239        enforce_input_project: bool,240    ):241        """242        NOTE: this interface is experimental.243        Args:244            in_channels: channels of the input features245            mask_classification: whether to add mask classifier or not246            num_classes: number of classes247            hidden_dim: Transformer feature dimension248            num_queries: number of queries249            nheads: number of heads250            dim_feedforward: feature dimension in feedforward network251            enc_layers: number of Transformer encoder layers252            dec_layers: number of Transformer decoder layers253            pre_norm: whether to use pre-LayerNorm or not254            mask_dim: mask feature dimension255            enforce_input_project: add input project 1x1 conv even if input256                channels and hidden dim is identical257        """258        super().__init__()259        assert mask_classification, "Only support mask classification model"260        self.mask_classification = mask_classification261 262        # positional encoding263        N_steps = hidden_dim // 2264        self.pe_layer = PositionEmbeddingSine(N_steps, normalize=True)265        266        # define Transformer decoder here267        self.num_heads = nheads268        self.num_layers = dec_layers269        self.contxt_len = contxt_len270        self.transformer_self_attention_layers = nn.ModuleList()271        self.transformer_cross_attention_layers = nn.ModuleList()272        self.transformer_ffn_layers = nn.ModuleList()273 274        for _ in range(self.num_layers):275            self.transformer_self_attention_layers.append(276                SelfAttentionLayer(277                    d_model=hidden_dim,278                    nhead=nheads,279                    dropout=0.0,280                    normalize_before=pre_norm,281                )282            )283 284            self.transformer_cross_attention_layers.append(285                CrossAttentionLayer(286                    d_model=hidden_dim,287                    nhead=nheads,288                    dropout=0.0,289                    normalize_before=pre_norm,290                )291            )292 293            self.transformer_ffn_layers.append(294                FFNLayer(295                    d_model=hidden_dim,296                    dim_feedforward=dim_feedforward,297                    dropout=0.0,298                    normalize_before=pre_norm,299                )300            )301 302        self.decoder_norm = nn.LayerNorm(hidden_dim)303 304        self.num_queries = num_queries305        # learnable query features306        self.query_feat = nn.Embedding(num_queries, hidden_dim)307        # learnable query p.e.308        self.query_embed = nn.Embedding(num_queries, hidden_dim)309        310        # level embedding (we always use 3 scales)311        self.num_feature_levels = 3312        self.level_embed = nn.Embedding(self.num_feature_levels, hidden_dim)313        self.input_proj = nn.ModuleList()314        315        for _ in range(self.num_feature_levels):316            if in_channels != hidden_dim or enforce_input_project:317                self.input_proj.append(Conv2d(in_channels, hidden_dim, kernel_size=1))318                weight_init.c2_xavier_fill(self.input_proj[-1])319            else:320                self.input_proj.append(nn.Sequential())321 322        self.task_switch = task_switch323 324        # output FFNs325        self.lang_encoder = lang_encoder326        if self.task_switch['mask']:327            self.mask_embed = MLP(hidden_dim, hidden_dim, mask_dim, 3)328 329        self.class_embed = nn.Parameter(torch.empty(hidden_dim, dim_proj))330        trunc_normal_(self.class_embed, std=.02)331 332        if task_switch['bbox']:333            self.bbox_embed = MLP(hidden_dim, hidden_dim, 4, 3)334 335        # Caption Project and query336        if task_switch['captioning']:337            self.caping_embed = nn.Parameter(torch.empty(hidden_dim, dim_proj))338            trunc_normal_(self.caping_embed, std=.02)339            # self.query_feat_caping = nn.Embedding(contxt_len, hidden_dim)340            self.pos_embed_caping = nn.Embedding(contxt_len, hidden_dim)341            self.captioning_step = captioning_step342 343        # register self_attn_mask to avoid information leakage, it includes interaction between object query, class query and caping query344        self_attn_mask = torch.zeros((1, num_queries + contxt_len, num_queries + contxt_len)).bool()345        self_attn_mask[:, :num_queries, num_queries:] = True # object+class query does not attend with caption query.346        self_attn_mask[:, num_queries:, num_queries:] = torch.triu(torch.ones((1, contxt_len, contxt_len)), diagonal=1).bool() # caption query only attend with previous token.347        self_attn_mask[:, :num_queries-1, num_queries-1:num_queries] = True # object query does not attend with class query.348        self_attn_mask[:, num_queries-1:num_queries, :num_queries-1] = True # class query does not attend with object query.349        self.register_buffer("self_attn_mask", self_attn_mask)350 351 352    @classmethod353    def from_config(cls, cfg, in_channels, lang_encoder, mask_classification, extra):354        ret = {}355 356        ret["lang_encoder"] = lang_encoder357        ret["in_channels"] = in_channels358        ret["mask_classification"] = mask_classification359 360        enc_cfg = cfg['MODEL']['ENCODER']361        dec_cfg = cfg['MODEL']['DECODER']362        363        ret["hidden_dim"] = dec_cfg['HIDDEN_DIM']364        ret["dim_proj"] = cfg['MODEL']['DIM_PROJ']365        ret["num_queries"] = dec_cfg['NUM_OBJECT_QUERIES']366        ret["contxt_len"] = cfg['MODEL']['TEXT']['CONTEXT_LENGTH']367        368        # Transformer parameters:369        ret["nheads"] = dec_cfg['NHEADS']370        ret["dim_feedforward"] = dec_cfg['DIM_FEEDFORWARD']371 372        # NOTE: because we add learnable query features which requires supervision,373        # we add minus 1 to decoder layers to be consistent with our loss374        # implementation: that is, number of auxiliary losses is always375        # equal to number of decoder layers. With learnable query features, the number of376        # auxiliary losses equals number of decoders plus 1.377        assert dec_cfg['DEC_LAYERS'] >= 1378        ret["dec_layers"] = dec_cfg['DEC_LAYERS'] - 1379        ret["pre_norm"] = dec_cfg['PRE_NORM']380        ret["enforce_input_project"] = dec_cfg['ENFORCE_INPUT_PROJ']381        ret["mask_dim"] = enc_cfg['MASK_DIM']382 383        ret["task_switch"] = extra['task_switch']384        ret["captioning_step"] = dec_cfg['CAPTIONING'].get('STEP', 50)385 386        return ret387 388    def forward(self, x, mask_features, mask=None, target_queries=None, target_vlp=None, task='seg', extra={}):389        if task == 'captioning_infer':390            return self.forward_captioning(x, mask_features, mask=mask, target_queries=target_queries, target_vlp=target_vlp, task=task, extra=extra)391        # x is a list of multi-scale feature392        assert len(x) == self.num_feature_levels393        src = []394        pos = []395        size_list = []396        397        # disable mask, it does not affect performance398        del mask399        for i in range(self.num_feature_levels):400            size_list.append(x[i].shape[-2:])401            pos.append(self.pe_layer(x[i], None).flatten(2))402            src.append(self.input_proj[i](x[i]).flatten(2) + self.level_embed.weight[i][None, :, None])403 404            # flatten NxCxHxW to HWxNxC405            pos[-1] = pos[-1].permute(2, 0, 1)406            src[-1] = src[-1].permute(2, 0, 1)407 408        _, bs, _ = src[0].shape409 410        # QxNxC411        query_embed = self.query_embed.weight.unsqueeze(1).repeat(1, bs, 1)412        output = self.query_feat.weight.unsqueeze(1).repeat(1, bs, 1)413 414        predictions_class = []415        predictions_mask = []416        predictions_bbox = []417        predictions_caption = []418        predictions_captioning = []419        420        self_tgt_mask = None421        if self.training and task == 'vlp' and self.task_switch['captioning']:422            # output = torch.cat((output, self.query_feat_caping.weight.unsqueeze(1).repeat(1, bs, 1)), dim=0) # concat object query, class token and caption token.423            caping_lang_embed = torch.cat([caption['caption_tokens'] for caption in target_vlp], dim=0).transpose(0, 1) # language output424            _caping_lang_embed = caping_lang_embed.detach().clone()425            output = torch.cat((output, _caping_lang_embed), dim=0) # concat object query, class token and caption token.426            caping_lang_embed += self.pos_embed_caping.weight.unsqueeze(1).repeat(1, bs, 1)427            query_embed = torch.cat((query_embed, caping_lang_embed), dim=0) # may not add at the beginning.428            self_tgt_mask = self.self_attn_mask.repeat(output.shape[1]*self.num_heads, 1, 1)429        elif (((self.training and task == 'seg') or (task == 'grounding_eval')) and self.task_switch['grounding']) \430                or ((self.training and task == 'openimage') and self.task_switch['openimage']['grounding']):431            self_tgt_mask = self.self_attn_mask[:,:self.num_queries,:self.num_queries].repeat(output.shape[1]*self.num_heads, 1, 1)432            grounding_tokens = extra['grounding_tokens']433            _grounding_tokens = grounding_tokens.detach().clone()434            # initialize with negative attention at the beginning.435            pad_tgt_mask = torch.ones((1, self.num_queries + (self.num_queries-1) + len(grounding_tokens), self.num_queries + (self.num_queries-1) + len(grounding_tokens)), device=self_tgt_mask.device).bool().repeat(output.shape[1]*self.num_heads, 1, 1)436            pad_tgt_mask[:,:self.num_queries,:self.num_queries] = self_tgt_mask437            pad_tgt_mask[:,self.num_queries:,self.num_queries:] = False # grounding tokens could attend with eatch other438            self_tgt_mask = pad_tgt_mask439            output = torch.cat((output, output[:-1]), dim=0)440            query_embed = torch.cat((query_embed, query_embed[:-1]), dim=0) # also pad language embdding to fix embedding441        else:442            self_tgt_mask = self.self_attn_mask[:,:self.num_queries,:self.num_queries].repeat(output.shape[1]*self.num_heads, 1, 1)443 444        # prediction heads on learnable query features445        results = self.forward_prediction_heads(output, mask_features, attn_mask_target_size=size_list[0], task=task)446        attn_mask = results["attn_mask"]447        predictions_class.append(results["outputs_class"])448        predictions_mask.append(results["outputs_mask"])449        predictions_bbox.append(results["outputs_bbox"])450        predictions_caption.append(results["outputs_caption"])451        predictions_captioning.append(results["outputs_captionting"])452        453        for i in range(self.num_layers):454            level_index = i % self.num_feature_levels455            attn_mask[torch.where(attn_mask.sum(-1) == attn_mask.shape[-1])] = False456 457            if self.training and task == 'vlp' and self.task_switch['captioning']:458                attn_mask = torch.cat((attn_mask, torch.zeros_like(attn_mask[:, :self.contxt_len, :])), dim=1)459            # attention: cross-attention first460            output, avg_attn = self.transformer_cross_attention_layers[i](461                output, src[level_index],462                memory_mask=attn_mask,463                memory_key_padding_mask=None,  # here we do not apply masking on padded region464                pos=pos[level_index], query_pos=query_embed465            )466 467            if (((self.training and task == 'seg') or (task == 'grounding_eval')) and self.task_switch['grounding']) \468                    or ((self.training and task == 'openimage') and self.task_switch['openimage']['grounding']):469                output = torch.cat((output, _grounding_tokens), dim=0)470                query_embed = torch.cat((query_embed, grounding_tokens), dim=0)471 472            output = self.transformer_self_attention_layers[i](473                output, tgt_mask=self_tgt_mask,474                tgt_key_padding_mask=None,475                query_pos=query_embed476            )477            478            # FFN479            output = self.transformer_ffn_layers[i](480                output481            )482 483            if ((self.training and task == 'seg') or (task == 'grounding_eval')) and self.task_switch['grounding'] \484                    or ((self.training and task == 'openimage') and self.task_switch['openimage']['grounding']):485                _grounding_tokens = output[-len(_grounding_tokens):]486                output = output[:-len(_grounding_tokens)]487                query_embed = query_embed[:-len(_grounding_tokens)]488 489            results = self.forward_prediction_heads(output, mask_features, attn_mask_target_size=size_list[(i + 1) % self.num_feature_levels], layer_id=i, task=task)490            attn_mask = results["attn_mask"]491            predictions_class.append(results["outputs_class"])492            predictions_mask.append(results["outputs_mask"])493            predictions_bbox.append(results["outputs_bbox"])494            predictions_caption.append(results["outputs_caption"])495            predictions_captioning.append(results["outputs_captionting"])496 497        assert len(predictions_class) == self.num_layers + 1498        if task == 'vlp':499            out = {'pred_captionings': predictions_captioning[-1], 500                   'pred_captions': predictions_caption[-1], 501                   'aux_outputs': [{'pred_captionings': x, 'pred_captions': y } for x, y in zip(predictions_captioning[:-1], predictions_caption[:-1])]}502            return out503        else:504            out = {505                'pred_logits': predictions_class[-1],506                'pred_masks': predictions_mask[-1],507                'pred_boxes': predictions_bbox[-1],508                'pred_captions': predictions_caption[-1],509                'aux_outputs': self._set_aux_loss(510                    predictions_class if self.mask_classification else None, predictions_mask, predictions_bbox, predictions_caption511                )512            }513            return out514 515    def forward_captioning(self, x, mask_features, mask = None, target_queries = None, target_vlp = None, task='seg', extra={}):516        # x is a list of multi-scale feature517        assert len(x) == self.num_feature_levels518        src = []519        pos = []520        size_list = []521        522        # disable mask, it does not affect performance523        del mask524        for i in range(self.num_feature_levels):525            size_list.append(x[i].shape[-2:])526            pos.append(self.pe_layer(x[i], None).flatten(2))527            src.append(self.input_proj[i](x[i]).flatten(2) + self.level_embed.weight[i][None, :, None])528 529            # flatten NxCxHxW to HWxNxC530            pos[-1] = pos[-1].permute(2, 0, 1)531            src[-1] = src[-1].permute(2, 0, 1)532 533        _, bs, _ = src[0].shape534 535        # QxNxC536        query_embed_ = self.query_embed.weight.unsqueeze(1).repeat(1, bs, 1)537        query_feat = self.query_feat.weight.unsqueeze(1).repeat(1, bs, 1)        538        caping_lang_token = extra['start_token'].repeat(bs, 1)539        start_id = 0540        if 'token' in extra:541            caping_lang_token[:,:len(extra['token'][0])] = extra['token']542            start_id = len(extra['token'][0])-1543        # query_feat_caping = self.query_feat_caping.weight.unsqueeze(1).repeat(1, bs, 1)544        pos_embed_caping = self.pos_embed_caping.weight.unsqueeze(1).repeat(1, bs, 1)545        # prepare token embedding for evaluation546        token_embs = self.lang_encoder.lang_encoder.token_embedding.weight547        # token_embs = (token_embs / token_embs.norm(dim=-1, keepdim=True) + 1e-7)548        549        for cap_idx in range(start_id, self.captioning_step):550            caping_lang_embed = self.lang_encoder.forward_language_token((caping_lang_token,))[0].transpose(0, 1)551            output = torch.cat((query_feat, caping_lang_embed), dim=0) # concat object query, class token and caption token.552            caping_lang_embed += pos_embed_caping553            query_embed = torch.cat((query_embed_, caping_lang_embed), dim=0) # may not add at the beginning.554            # output = torch.cat((query_feat, query_feat_caping), dim=0) # concat object query, class token and caption token.555 556            # prediction heads on learnable query features557            results = self.forward_prediction_heads(output, mask_features, attn_mask_target_size=size_list[0], task=task)558            attn_mask = results["attn_mask"]559        560            for i in range(self.num_layers):561                level_index = i % self.num_feature_levels562                attn_mask[torch.where(attn_mask.sum(-1) == attn_mask.shape[-1])] = False563                attn_mask = torch.cat((attn_mask, torch.zeros_like(attn_mask[:, :self.contxt_len, :])), dim=1)564                self_tgt_mask = self.self_attn_mask.repeat(output.shape[1]*self.num_heads, 1, 1)565 566                if extra['captioning_mask'] is not None:567                    bs,nq,wh = attn_mask.shape568                    assert bs==self.num_heads, "Only support single image referring captioning."569                    cap_mask = extra['captioning_mask']570                    attn_mask = attn_mask.reshape(bs,nq,size_list[i%3][0],size_list[i%3][1])571                    cap_mask = F.interpolate(cap_mask[None,].float(), size_list[i%3], mode='nearest').bool()[0,0]572                    attn_mask[:,self.num_queries:, cap_mask] = True573                    attn_mask = attn_mask.reshape(bs,nq,wh)574                575                # attention: cross-attention first576                output, avg_attn = self.transformer_cross_attention_layers[i](577                    output, src[level_index],578                    memory_mask=attn_mask,579                    memory_key_padding_mask=None,  # here we do not apply masking on padded region580                    pos=pos[level_index], query_pos=query_embed581                )582 583                output = self.transformer_self_attention_layers[i](584                    output, tgt_mask=self_tgt_mask,585                    tgt_key_padding_mask=None,586                    query_pos=query_embed587                )588                589                # FFN590                output = self.transformer_ffn_layers[i](591                    output592                )593 594                results = self.forward_prediction_heads(output, mask_features, attn_mask_target_size=size_list[(i + 1) % self.num_feature_levels], layer_id=i, task=task)595                attn_mask = results["attn_mask"]596            597            pred_captions_gen = results['outputs_captionting']598            # pred_captions_gen = (pred_captions_gen / pred_captions_gen.norm(dim=-1, keepdim=True) + 1e-7)599            pred_captions_gen = pred_captions_gen @ token_embs.t()600            caping_lang_token[:,cap_idx+1] = pred_captions_gen[:,cap_idx].max(-1)[1]601            602        texts = self.lang_encoder.tokenizer.batch_decode(caping_lang_token, skip_special_tokens=False)603        texts_new = []604        605        for x in texts:606            x = x.split('<|endoftext|>')[0]607            x = x.replace('<|endoftext|>','')608            x = x.replace('<|startoftext|>','')609            x = x.strip()610            texts_new.append(x)611 612        out = {'pred_captionings': caping_lang_token,613               'pred_texts': texts_new}614        return out615 616 617    def forward_prediction_heads(self, output, mask_features, attn_mask_target_size, layer_id=-1, task='seg'):618        decoder_output = self.decoder_norm(output)619        decoder_output = decoder_output.transpose(0, 1)620 621        # extract image captioning token from decoder output.622        if self.task_switch['captioning'] and (task == 'vlp' or task == 'captioning_infer'):623            outputs_captionting = decoder_output[:,self.num_queries:] @ self.caping_embed624        else:625            outputs_captionting = None626 627        # recompute class token output.628        norm_decoder_output = decoder_output / (decoder_output.norm(dim=-1, keepdim=True) + 1e-7)629        obj_token = norm_decoder_output[:,:self.num_queries-1]630        cls_token = norm_decoder_output[:,self.num_queries-1:self.num_queries]631 632        sim = (cls_token @ obj_token.transpose(1,2)).softmax(-1)[:,0,:,None] # TODO include class token.633        cls_token = (sim * decoder_output[:,:self.num_queries-1]).sum(dim=1, keepdim=True)634 635        if (((self.training and task == 'seg') or (task == 'grounding_eval')) and self.task_switch['grounding']) \636                or ((self.training and task == 'openimage') and self.task_switch['openimage']['grounding']):637            decoder_output = torch.cat((decoder_output[:,:self.num_queries-1], cls_token, decoder_output[:,self.num_queries:2*self.num_queries-1]), dim=1)638        else:639            decoder_output = torch.cat((decoder_output[:,:self.num_queries-1], cls_token), dim=1)640 641        # compute class, mask and bbox.642        class_embed = decoder_output @ self.class_embed643        # HACK do not compute similarity if mask is not on644        outputs_class = self.lang_encoder.compute_similarity(class_embed, fake=(((not self.task_switch['mask']) and self.training) or (task == 'openimage')))645 646        if self.task_switch['mask'] or self.task_switch['openimage']['mask']:647            mask_embed = self.mask_embed(decoder_output)648            outputs_mask = torch.einsum("bqc,bchw->bqhw", mask_embed, mask_features)649 650            # NOTE: prediction is of higher-resolution651            # [B, Q, H, W] -> [B, Q, H*W] -> [B, h, Q, H*W] -> [B*h, Q, HW]652            attn_mask = F.interpolate(outputs_mask, size=attn_mask_target_size, mode="bilinear", align_corners=False)653 654            # must use bool type655            # If a BoolTensor is provided, positions with ``True`` are not allowed to attend while ``False`` values will be unchanged.656            attn_mask = (attn_mask.sigmoid().flatten(2).unsqueeze(1).repeat(1, self.num_heads, 1, 1).flatten(0, 1) < 0.5).bool()657            attn_mask = attn_mask.detach()658 659            # NOTE: fill False for cls token (JY)660            attn_mask[:, self.num_queries:self.num_queries+1].fill_(False)661        else:662            outputs_mask = None663            attn_mask = torch.zeros((list(decoder_output.shape[:2]) + [attn_mask_target_size[0]*attn_mask_target_size[1]]), device=decoder_output.device).repeat(self.num_heads, 1, 1).bool()664 665        outputs_bbox = [None for i in range(len(decoder_output))]666        if self.task_switch['bbox']:667            outputs_bbox = self.bbox_embed(decoder_output)668 669        outputs_caption = None670        if self.task_switch['caption']:671            outputs_caption = class_embed672            673 674        results = {675            "outputs_class": outputs_class,676            "outputs_mask": outputs_mask,677            "outputs_bbox": outputs_bbox,678            "attn_mask": attn_mask,679            "outputs_caption": outputs_caption,680            "outputs_captionting": outputs_captionting,681        }682        return results683 684    @torch.jit.unused685    def _set_aux_loss(self, outputs_class, outputs_seg_masks, outputs_boxes, outputs_captions):686        # this is a workaround to make torchscript happy, as torchscript687        # doesn't support dictionary with non-homogeneous values, such688        # as a dict having both a Tensor and a list.689        if self.mask_classification:690            return [691                {"pred_logits": a, "pred_masks": b, "pred_boxes": c, "pred_captions": d}692                for a, b, c, d in zip(outputs_class[:-1], outputs_seg_masks[:-1], outputs_boxes[:-1], outputs_captions[:-1])693            ]694        else:695            return [{"pred_masks": b} for b in outputs_seg_masks[:-1]]696 697 698@register_decoder699def get_masked_transformer_decoder(cfg, in_channels, lang_encoder, mask_classification, extra):700    return MultiScaleMaskedTransformerDecoder(cfg, in_channels, lang_encoder, mask_classification, extra)