Skip to content
mlmentorship

Sequence packing with block-diagonal masks

Concatenate multiple short examples into one fixed-length sequence to eliminate padding waste. The single largest throughput win for training on skewed-length corpora.

Published · 4 min read ·Role-specific ·Advanced

Visual quick review

Visual first · depth when needed

Map packed-example boundaries to reset position IDs and a causal block-diagonal attention mask that permits no cross-example attention.

Preparing the visual…

Summary

Sequence packing concatenates multiple training examples back-to-back into a single fixed-length sequence and uses a block-diagonal attention mask so each example only attends within itself, eliminating the FLOPs and memory wasted on padding tokens.

Most NLP corpora have heavily skewed length distributions: many short examples, few long ones. With naive padding to the longest example in the batch, the wasted-token ratio is

For C4-like web text this is often 50–80%. Padded positions cost full FLOPs and memory but contribute nothing to the loss. Sequence packing recovers nearly all of that throughput.

The mechanism

  1. Pick a fixed packed length (e.g., 8192).
  2. Concatenate examples until adding the next would exceed . Record the boundaries (cumulative sequence lengths, often called cu_seqlens).
  3. Build a block-diagonal attention mask: token in example cannot attend to any token in .
  4. Compute attention with a kernel that respects cu_seqlens (FlashAttention-2 supports this natively via the varlen API).
  5. Apply the loss only on response tokens within each example (mask the boundaries and any prompt tokens for SFT).

Position IDs reset at each example boundary so position 0 is the start of each packed example.

Learning objective: map packed-example boundaries to reset position IDs and a causal block-diagonal attention mask that permits no cross-example attention.

Learning objective

How can one token row still behave like three separate examples?

1 · PACK TOKENS, KEEP BOUNDARIES

slot012345
examplee1e1e1e2e2e3
position012010

Boundaries: `cu_seqlens = [0, 3, 5, 6]`
The intervals [0, 3), [3, 5), and [5, 6) recover the three examples without padding.

2 · MASK BY EXAMPLE AND TIME

q \ ke1:0e1:1e1:2e2:0e2:1e3:0
e1:0AFFXXX
e1:1AAFXXX
e1:2AAAXXX
e2:0XXXAFX
e2:1XXXAAX
e3:0XXXXXA

A = attend · F = future · X = other example
Only the three lower-triangular diagonal blocks participate in attention.

Read it this way: first use the cumulative boundaries to split the physical row into logical examples and restart positions at each boundary. Then read each mask row as one query: it may attend backward inside its own example (A), never forward in causal training (F), and never across an example boundary (X). Packing removes padding; boundaries preserve the same attention problem each example had before concatenation. Loss masking is a separate per-token decision. Original worked example informed by Krell et al. (2021) and the FlashAttention variable-length interface.

Numbers

For pretraining on web text packed at :

  • Wasted tokens drop from ~50% (naive batching) to <2% (just the slack at the end of the packed sequence).
  • Throughput per GPU roughly doubles.
  • Quality is unchanged when the mask is correct.

Most modern training stacks pack by default. Llama, Mistral, Qwen, and major SFT toolkits (axolotl, TRL) all support it.

Common implementation pitfalls

  • Forgetting to reset positions. If position IDs continue across boundaries, attention learns to treat packed boundaries as long-range dependencies and quality drops.
  • Wrong loss masking. Loss must not flow from one example to another; mask boundaries explicitly.
  • Mixing prompt and response in SFT without masking. For SFT, mask out prompt tokens from the loss within each packed example.
  • Using a kernel that doesn’t support varlen. Without FlashAttention-2 varlen (or equivalent), the block-diagonal mask materializes the full matrix and you lose the speedup.

When not to pack

  • Very long single examples that fill or exceed on their own (no concatenation possible; padding is already minimal).
  • When examples have inter-document context that should attend across boundaries (rare).
  • During inference, where examples come one at a time.