Modern language models have moved away from the original ReLU non-linearity in their MLP blocks toward gated activations (e.g. SwiGLU). This page explains the structural difference.


ReLU

Formula: output = relu(x @ W)

ReLU simply applies a linear transformation, then threshold negatives to zero.

x  →  Linear (x @ W)  →  ReLU (max(0, z))  →  output
  • max(0, x): negatives become 0, positives pass through unchanged
  • because of this, a feature is either killed completely or passed through linearly
  • No in-between --> no way to say "pass 40% of this feature through"
  • Used in the original 2017 Transformer paper

Sigmoid and tanh in recurrent models

Sigmoid produces a value between zero and one, so it can control how much information a gate passes. Tanh produces a value between minus one and one, so it can supply signed candidate content. Inputs far from zero can make their derivatives small.

Gated Activations

Formula: output = swish(x @ W1) * (x @ W2)

Gated activations use two branches, multiplied element-wise:

x  →  Linear (x @ W1)  →  Swish  ─┐
                                    × →  output
x  →  Linear (x @ W2)  ────────────┘
         ↑ gate branch       ↑ content branch
BranchRole
Gate branch
swish(x @ W1)
A learned, input-dependent valve which controls how much of each feature passes through
Content branch
x @ W2
The signal being modulated

Both branches use the same input x but with different learned weight matrices (W1 and W2).


The Real Difference

The key difference is structural, not about learnable parameters since both approaches have weight matrices.

ReLUGated (SwiGLU)
Branches12 (multiplied together)
Non-linearityFixed (hard threshold)Continuous, input-dependent
Per-dimension controlZero negative values; retain positive valuesMultiply by a learned input-dependent value
ParametersW (one matrix)W1 + W2 (two matrices)
ComputeOne input projection in this comparisonTwo input projections in this comparison
QualityDepends on the model and taskDepends on the model and task

Example: A sigmoid gate of 0.2 passes 20% of a content value. A sigmoid gate of 0.9 passes 90%. SwiGLU uses Swish rather than sigmoid for its gate branch, so its multiplier can be negative or greater than one.


Variants of Gated Activations

VariantGate activationUsed in
GLUSigmoidOriginal gating paper
SwiGLUSwishLlama, Mistral, PaLM
GeGLUGELUVarious modern models

A complete gated feed-forward block usually adds an output projection after the two branches. Hidden width affects its parameter count and computation. Choose the architecture using measured performance for the task. GLU variants paper.


Code

PyTorch: compare the output values

import torch
 
x = torch.tensor([-2.0, 0.0, 2.0])
print(torch.relu(x))                 # [0., 0., 2.]
print(torch.sigmoid(x).round(decimals=3))  # [0.119, 0.500, 0.881]
print(torch.tanh(x).round(decimals=3))     # [-0.964, 0.000, 0.964]
 
content = torch.tensor([10.0, 10.0, 10.0])
gate = torch.sigmoid(x)
gated_content = gate * content
print(gated_content.round(decimals=3))  # [1.192, 5.000, 8.808]

All operations keep the input shape. gate * content multiplies corresponding positions. At the middle position, a gate value of 0.5 passes half of the content value 10.

TensorFlow/Keras

import tensorflow as tf
 
x = tf.constant([-2.0, 0.0, 2.0])
print(tf.nn.relu(x).numpy())
print(tf.math.sigmoid(x).numpy().round(3))
print(tf.math.tanh(x).numpy().round(3))
content = tf.constant([10.0, 10.0, 10.0])
print((tf.math.sigmoid(x) * content).numpy().round(3))

The outputs match the PyTorch example within floating-point rounding. For a Swish gate, use torch.nn.functional.silu(x) or tf.nn.silu(x) in place of sigmoid. The multiplication still occurs element by element.