BART Pre-training › Token Masking

Michael BrenndoerferOctober 19, 20254 min read
Language AI HandbookAll chapters
Part 25 of 67Encoder-Decoder Models
Chapter 181BART Pre-training › Token Masking
Reading section 3 of 16 · Token Masking · 4 minSection 3 of 16 · 4 min

Book contents

Section 3 of 16 · 4 min read

BART Pre-training › Token MaskingOne section · Sections in this chapter3 / 16 ↓
Reading tools Definitions & inline links

Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.

Article links

Make inline references clickable

Token masking is the most familiar corruption scheme, directly inherited from BERT's masked language modeling objective. Random tokens are replaced with a special [MASK] token, and the model must predict the original tokens. This approach has proven remarkably effective for learning contextual word representations, and BART includes it as one of its corruption options to benefit from these established strengths.

How It Works

Given a sequence of tokens, we mask each token independently with probability pp (typically 15%, following BERT). The independence means that each token's fate is determined by its own random draw, without consideration of neighboring tokens:

x~i={[MASK]with probability pxiotherwise\tilde{x}_i = \begin{cases} \text{[MASK]} & \text{with probability } p \\ x_i & \text{otherwise} \end{cases}

where:

  • x~i\tilde{x}_i: the ii-th token in the corrupted sequence
  • xix_i: the ii-th token in the original sequence
  • pp: the masking probability (typically 0.15)
  • [MASK]\text{[MASK]}: a special token showing a masked position

This piecewise definition captures a simple stochastic process: for each position ii, flip a biased coin that lands on "mask" with probability pp and "keep" with probability 1−p1-p. The resulting corrupted sequence has the same length as the original, with [MASK] tokens scattered throughout. The specific positions vary each time we corrupt the same document. This provides varied training examples from identical source text.

For example, the sentence "The quick brown fox jumps over the lazy dog" might become "The [MASK] brown fox [MASK] over the lazy [MASK]". Notice that the structure remains intact. We can still see that something describes "brown," that an action connects "fox" to "over," and that some modifier precedes "dog." These structural clues are precisely what the model must learn to exploit.

What the Model Learns

Token masking teaches the model to use bidirectional context for word prediction. To predict "quick," the encoder must understand that something describing "fox" fits between "The" and "brown." The model learns that adjectives typically precede the nouns they modify, that certain adjectives co-occur (quick and brown both describe animals in motion), and that syntactic patterns constrain what words can appear where. This develops strong contextual word representations, the same capability that makes BERT effective for classification and extraction tasks where understanding word meaning in context matters most.

However, token masking has limitations that become apparent when we consider generation tasks. The corruption is always one-to-one: one mask corresponds to exactly one original token. This rigid correspondence means the model never learns to handle situations where the number of output tokens differs from the number of input tokens, an important skill for generation tasks. When summarizing, the model must compress many input tokens into fewer output tokens. When elaborating or explaining, it must expand. Token masking provides no training signal for these variable-length transformations.

In[3]:
Code
import random
from typing import List, Tuple


def token_masking(
    tokens: List[str], mask_prob: float = 0.15, mask_token: str = "[MASK]"
) -> Tuple[List[str], List[str]]:
    """Apply token masking corruption.

    Returns:
        Tuple of (corrupted_tokens, original_tokens)
    """
    corrupted = []
    for token in tokens:
        if random.random() < mask_prob:
            corrupted.append(mask_token)
        else:
            corrupted.append(token)
    return corrupted, tokens
In[4]:
Code
# Example application
random.seed(42)
original = "The quick brown fox jumps over the lazy dog".split()
corrupted, original_out = token_masking(original, mask_prob=0.3)
Out[5]:
Console
Original:  The quick brown fox jumps over the lazy dog
Corrupted: The [MASK] [MASK] [MASK] jumps over the [MASK] dog
Masked positions: [1, 2, 3, 7]

With a 30% masking rate (higher than typical for visibility), several tokens are replaced with the [MASK] placeholder. The decoder must generate all original tokens, but the key learning signal comes from correctly predicting the masked positions. The output shows which token indices were masked, letting us to verify the corruption is working as expected.