Encoder Architecture › Stacking Encoder Layers

Michael BrenndoerferUpdated June 15, 20255 min read
Language AI HandbookAll chapters
Part 16 of 67Transformer Architectures
Chapter 111Encoder Architecture › Stacking Encoder Layers
Reading section 6 of 13 · Stacking Encoder Layers · 5 minSection 6 of 13 · 5 min

Book contents

Section 6 of 13 · 5 min read

Encoder Architecture › Stacking Encoder LayersOne section · Sections in this chapter6 / 13 ↓
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

A single encoder layer provides limited representational power. Real models stack many layers, allowing each successive layer to refine the representations further. BERT-Base uses 12 layers, BERT-Large uses 24, and some models go even deeper.

In[22]:
Code
class TransformerEncoder:
    """
    Complete transformer encoder.

    Stacks multiple encoder layers with optional final normalization.
    """

    def __init__(self, n_layers, d_model, n_heads, d_ff):
        """
        Args:
            n_layers: Number of encoder layers
            d_model: Model dimension
            n_heads: Number of attention heads
            d_ff: Feed-forward hidden dimension
        """
        self.n_layers = n_layers
        self.d_model = d_model

        # Stack of encoder layers
        self.layers = [
            EncoderLayer(d_model, n_heads, d_ff) for _ in range(n_layers)
        ]

        # Final layer normalization (used in pre-norm configuration)
        self.final_norm = LayerNorm(d_model)

    def __call__(self, x, mask=None, return_all_layers=False):
        """
        Forward pass through all encoder layers.

        Args:
            x: Input of shape (seq_len, d_model)
            mask: Optional padding mask
            return_all_layers: Whether to return intermediate representations

        Returns:
            Final output (and optionally all layer outputs)
        """
        all_outputs = [x]
        all_attentions = []

        for layer in self.layers:
            x, attn = layer(x, mask)
            all_outputs.append(x)
            all_attentions.append(attn)

        # Apply final normalization
        x = self.final_norm(x)

        if return_all_layers:
            return x, all_outputs, all_attentions
        return x


# Build a 6-layer encoder
n_layers = 6
encoder = TransformerEncoder(n_layers, d_model, n_heads, d_ff)

# Process a sequence
seq_len = 8
x = np.random.randn(seq_len, d_model)
output, all_outputs, all_attentions = encoder(x, return_all_layers=True)
Out[23]:
Console
Transformer Encoder Configuration
----------------------------------------
Number of layers: 6
Model dimension: 256
Attention heads per layer: 8
FFN hidden dimension: 1024

Parameters per layer: 788,736
Total encoder parameters: 4,732,928

Input shape: (8, 256)
Output shape: (8, 256)

Let's visualize how representations evolve through the layers:

Out[24]:
Visualization
Line plot showing representation norms for each token position across 6 encoder layers.
Evolution of token representations through encoder layers. Each layer refines the representations, with early layers capturing local patterns and later layers integrating global context. The representation norm increases slightly due to residual accumulation.

The visualization shows how representations develop across layers. Early layers might have more variable norms as they begin processing the input, while deeper layers tend to stabilize as the residual connections accumulate refined representations.

Attention Entropy Across Layers

A useful diagnostic for understanding encoder behavior is attention entropy, a measure of how concentrated or diffuse each token's attention is. High entropy means attention is spread broadly; low entropy means it focuses on specific positions.

Out[25]:
Visualization
Line plot showing attention entropy for each token position across 6 encoder layers.
Attention entropy across encoder layers. Early layers often show higher entropy (broader attention) as tokens gather general context. Deeper layers may develop more focused patterns as representations specialize. Each line represents one token position's average entropy across attention heads.

Entropy close to the maximum (dotted line) indicates uniform attention, meaning every token attends roughly equally to all positions. Lower entropy indicates more selective attention. Tracking entropy across layers reveals how the encoder progressively refines its attention patterns from broad context gathering to more task-specific focus.