def __call__(
        self, inputs: torch.Tensor,
        modality_masking=None,
        special_tokens_mask: Optional[torch.Tensor] = None
    ) -> Tuple[torch.Tensor, torch.Tensor]:
        """
        expand modality_masking into
            None: traditional bert masking.
            "no": no masking.
            "full": all [MASK] token for generation.
            "gen": autoregressive generation.
        """
        """
        Prepare masked tokens inputs/labels for masked language modeling:
        80% MASK, 10% random, 10% original.
        """
        labels = inputs.clone()
        # We sample a few tokens in each sequence for MLM training
        # (with probability `self.mlm_probability`)
        if modality_masking is not None:
            if modality_masking == "full":
                probability_matrix = torch.full(labels.shape, 1.)
            elif modality_masking == "no":
                probability_matrix = torch.full(labels.shape, 0.)
            elif modality_masking.startswith("textgen"):
                # [CLS] [SEP] <s> ...
                inputs, labels = self.textgen(inputs)
                if "mask" not in modality_masking:
                    return inputs, labels
                inputs = self.mask_input(inputs, special_tokens_mask)
                return inputs, labels
            elif modality_masking == "mask":
                inputs = self.mask_input(inputs, special_tokens_mask)
                labels = torch.full(inputs.shape, -100)
                return inputs, labels
            elif modality_masking == "inverse":
                probability_matrix = torch.full(labels.shape, 1. - self.mlm_probability)
            else:
                raise ValueError("unknown modality masking.", modality_masking)
        else:
            probability_matrix = torch.full(labels.shape, self.mlm_probability)

        if special_tokens_mask is None:
            special_tokens_mask = self.get_special_tokens_mask(
                labels.tolist(), already_has_special_tokens=True
            )
            special_tokens_mask = torch.tensor(
                special_tokens_mask, dtype=torch.bool)
        else:
            special_tokens_mask = special_tokens_mask.bool()

        probability_matrix.masked_fill_(special_tokens_mask, value=0.0)
        masked_indices = torch.bernoulli(probability_matrix).bool()
        labels[~masked_indices] = -100  # We only compute loss on masked tokens

        # 80% of the time,
        # we replace masked input tokens with tokenizer.mask_token ([MASK])
        indices_replaced = (
            torch.bernoulli(
                torch.full(labels.shape, 0.8)).bool() & masked_indices
        )
        inputs[indices_replaced] = self.tokenizer.convert_tokens_to_ids(
            self.tokenizer.mask_token
        )

        # 10% of the time, we replace masked input tokens with random word
        indices_random = (
            torch.bernoulli(torch.full(labels.shape, 0.5)).bool()
            & masked_indices
            & ~indices_replaced
        )
        random_words = torch.randint(
            len(self.tokenizer), labels.shape, dtype=torch.long
        )
        inputs[indices_random] = random_words[indices_random]

        # The rest of the time (10% of the time) we keep the masked input
        # tokens unchanged
        return inputs, labels

        expand modality_masking into
            None: traditional bert masking.
            "no": no masking.
            "full": all [MASK] token for generation.
            "gen": autoregressive generation.
        
structured_prompting/fairseq-version/fairseq/examples/MMPT/mmpt/processors/how2processor.py