Gated Linear Units › SwiGLU: The Modern Standard
Language AI HandbookAll chapters Gated Linear Units › SwiGLU: The Modern StandardOne section · Sections in this chapter5 / 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
The original GLU with sigmoid gating works, but researchers discovered an even better formulation. SwiGLU, introduced by Shazeer in 2020, has become the dominant choice across modern LLMs, including frontier models such as LLaMA and Mistral. Understanding why SwiGLU outperforms the original GLU reveals important insights about activation function design.
The Limitation of Sigmoid Gating
Recall that the original GLU uses sigmoid to produce gate values between 0 and 1. While this works well for controlling information flow, sigmoid has a subtle limitation: it saturates at both ends. For very large positive inputs, the gate is always ~1; for very large negative inputs, always ~0. This saturation can limit expressiveness and cause gradient flow issues in deep networks.
From Sigmoid to Swish: A Self-Gating Activation
Swish (also called SiLU for Sigmoid Linear Unit) offers an elegant solution. Instead of using sigmoid as a separate gate, Swish embeds gating directly into the activation function:
where is the input value and is the sigmoid function.
This formula is deceptively simple but powerful. Let's understand what it does:
- For large positive : , so (passes through like a linear function)
- For large negative : , so (suppressed like ReLU)
- For small near zero: both and contribute, creating a smooth transition
The key insight is that Swish is self-gating: the input determines its own gate value. This creates an implicit "soft attention" where each value decides how much of itself to pass through.
The SwiGLU Formula
SwiGLU combines Swish with the two-pathway GLU structure:
where:
- : the input vector
- : the first projection matrix (Swish-activated pathway)
- : the second projection matrix (linear pathway)
- : element-wise multiplication (Hadamard product)
Expanding Swish reveals the full structure:
The Asymmetry Explained
Notice something different from the original GLU: the asymmetry. In SwiGLU:
- The first pathway () passes through Swish, which includes self-gating
- The second pathway () remains completely linear
This differs from the original GLU where sigmoid was applied specifically to the "gate" pathway and the "value" pathway was linear. In SwiGLU, the Swish-activated pathway acts as a kind of self-gated value, while the linear pathway provides additional expressiveness through the multiplication.
The combination creates a rich interaction: you have two different views of the input (through and ), one filtered through self-gating nonlinearity, combined multiplicatively. This gives the network more degrees of freedom than either a simple activation or the original GLU.
Why SwiGLU Outperforms the Original
Several factors contribute to SwiGLU's success:
- Unbounded positive values: Unlike sigmoid (which saturates at 1), Swish can output arbitrarily large positive values, matching the range of ReLU-family activations
- Smooth gradients: Swish is differentiable everywhere with smooth gradients, avoiding the sharp transitions at zero that ReLU has
- Self-gating property: The formula means each dimension gates itself, creating input-dependent behavior without explicit gate parameters
- Better gradient flow: The linear term in Swish ensures gradients can flow even for extreme inputs, helping train deep networks
The gradient behavior is particularly important for training deep networks. Let's visualize how gradients flow differently through each activation:

Implementation
Let's implement SwiGLU and see these properties in action:
def swish(x):
"""Swish (SiLU) activation: x * sigmoid(x)."""
return x * sigmoid(x)
def swiglu(x, W, V):
"""
SwiGLU activation (biases often omitted in modern implementations).
Args:
x: Input, shape (..., d_model)
W: First projection weights, shape (d_model, d_ff)
V: Second projection weights, shape (d_model, d_ff)
Returns:
Output, shape (..., d_ff)
"""
return swish(x @ W) * (x @ V)
def ffn_swiglu(x, W, V, W2):
"""
Feed-forward network with SwiGLU activation.
Modern implementations typically omit biases.
"""
hidden = swiglu(x, W, V)
return hidden @ W2
# Initialize weights for SwiGLU FFN
W_swi = np.random.randn(d_model_ffn, d_ff) * np.sqrt(2.0 / (d_model_ffn + d_ff))
V_swi = np.random.randn(d_model_ffn, d_ff) * np.sqrt(2.0 / (d_model_ffn + d_ff))
W2_swi = np.random.randn(d_ff, d_model_ffn) * np.sqrt(
2.0 / (d_ff + d_model_ffn)
)
# Test
x_single = np.random.randn(d_model_ffn)
y_swiglu = ffn_swiglu(x_single, W_swi, V_swi, W2_swi)SwiGLU FFN example: Input shape: (512,) Output shape: (512,) Output norm: 7.2403
The output norm provides a rough measure of the magnitude of the transformation. With Xavier initialization, we expect the output norm to be similar to the input norm, indicating stable signal propagation through the network.
Let's examine the self-gating behavior of Swish more closely by looking at how the implicit gate values (the sigmoid component) distribute for random inputs:


Let's also visualize how Swish compares to other activation functions and how this affects the gating behavior:

