In modern autoregressive Transformer training, maintaining numerical stability across trillions of tokens requires strict control over intermediate activation magnitudes. As models grow deeper and wider, pre-softmax logits in self-attention mechanisms and final vocabulary projection layers frequently drift toward extreme values. When logit values grow unconstrained, standard softmax normalization enters a saturation regime where output probabilities collapse into near one-hot distributions, causing vanishing gradients and training instability.
To counteract this phenomenon without introducing destructive gradient discontinuities, frontier architectures including Google DeepMind's Gemma 2 (Gemma Team, 2024), xAI's Grok-1, and Cohere's Command R+ implement logit soft-capping. By wrapping pre-softmax dot products and final logits in a parameterized hyperbolic tangent function, soft-capping establishes strict numerical boundaries while preserving continuous gradient backpropagation across the real line.
The Softmax Saturation and Logit Explosion Problem
In standard scaled dot-product attention (Vaswani et al., 2017), attention scores are computed as:
where represent query and key projections, and is the per-head projection dimension. Similarly, token generation probabilities over a vocabulary are computed via an unembedding matrix :
During long pre-training runs, gradient updates can cause query and key vectors or unembedding weights to grow in norm. When the magnitude or exceeds values such as 30 to 50, two distinct failure modes occur:
- Gradient Vanishing via Softmax Saturation: The Jacobian matrix of the softmax function with respect to logits is given by:
When a single logit dominates all others (), the assigned probability while . In this limit, for all pairs . The gradient transmitted through the softmax layer vanishes, preventing parameters from updating and causing dead attention heads or frozen unembedding projections.
- Numerical Underflow and Overflow in Reduced Precision: In 16-bit (FP16/BF16) and 8-bit (FP8) floating-point regimes, large dynamic ranges in exponential operations cause numerical overflow () or subnormal underflow during intermediate summation. This leads to NaN loss spikes and aborted training runs.

Mathematical Formulation of Tanh Soft-Capping
A straightforward solution to logit explosion is hard clipping:
However, hard clipping introduces severe gradient distortion. For any input , the derivative , abruptly zeroing gradient flow and creating non-differentiable boundaries at .
Logit soft-capping, adapted from reinforcement learning formulation in neural combinatorial optimization (Bello et al., 2016), applies a smooth hyperbolic tangent transformation scaled by a constant threshold :
Asymptotic and Local Properties
The hyperbolic tangent function exhibits key analytical properties that make it suitable for neural network stabilization:
- Bounded Output Range: For all , the capped value is strictly bounded:
- Near-Identity Behavior Near Zero: The Taylor series expansion of around is:
Substituting :
When , the higher-order terms are negligible, and . Unscaled, well-behaved logits pass through the function virtually unaffected.
- Smooth Gradient Decay: Differentiating the soft-capping function yields:
At , the derivative is exactly 1.0. As increases, the derivative diminishes monotonically and smoothly toward 0 without step discontinuities. Parameters generating excessively large logits experience reduced gradient magnitudes, acting as an implicit, adaptive gradient regularizer.
Architectural Implementations in Production LLMs
In Gemma 2 (Gemma Team, 2024), Google DeepMind implemented dual-stage logit soft-capping across all model scales (2B, 9B, and 27B parameters):
- Attention Logit Soft-Capping (): The attention score computation within every self-attention and cross-attention layer is modified to:
Setting bounds the maximum possible input to the attention softmax, ensuring the minimum probability assigned to any unattended token cannot fall below relative to the maximum token, preserving distributed attention weights.
- Final Layer Vocabulary Soft-Capping (): The logits generated by the final unembedding projection before cross-entropy loss are bounded as:
Setting prevents extreme prediction confidence during training, stabilizing cross-entropy gradients and mitigating overconfident hallucination patterns.
| Architecture | Attention Soft-Cap () | Output Logit Soft-Cap () | Additional Stabilization | | :--- | :--- | :--- | :--- | | Gemma 2 (2B, 9B, 27B) | 50.0 | 30.0 | RMSNorm + Post-Norm | | Grok-1 (314B MoE) | 30.0 | None | RMSNorm | | Command R+ (104B) | 50.0 | None | LayerNorm | | Standard Llama 3 | None | None | RMSNorm + RoPE |
Hardware, Kernel Fusion, and Serving Implications
While mathematically straightforward, logit soft-capping introduces engineering friction into hardware-accelerated attention pipelines:
The FlashAttention Fusion Bottleneck
Standard IO-aware attention algorithms like FlashAttention-2 and FlashAttention-3 achieve high throughput by tiling Query, Key, and Value blocks into GPU SRAM, computing dot products and running online softmax without writing intermediate attention matrices to High Bandwidth Memory (HBM).
When soft-capping is added, the attention kernel must execute an elementwise operation on every scalar dot product prior to exponentiation:
If an inference or training engine relies on standard pre-compiled FlashAttention kernels lacking soft-capping support, it must fall back to naive attention execution: materializing full attention tensors in global GPU memory. For an 8,192-token sequence with 32 heads in 16-bit precision, materializing intermediate attention scores requires 4 GB of transient memory per layer, causing massive throughput degradation and out-of-memory errors.
Modern frameworks resolve this via custom fused kernels:
- PyTorch FlexAttention: Implements dynamic score modification functions through compiler-generated fused kernels (PyTorch FlexAttention, 2024), allowing soft-capping to execute directly inside SRAM tiles without HBM overhead.
- vLLM and SGLang: Integrate specialized CUDA and Triton attention kernels with native soft-capping parameters, preserving PagedAttention throughput for Gemma 2 serving.
Comparison with Alternative Stabilization Techniques
Logit soft-capping operates alongside several alternative architectural methods designed to manage numerical stability during pre-training:
QK-Normalization
Proposed by Dehghani et al. (2023), QK-Norm applies LayerNorm or RMSNorm directly to query and key projection vectors before computing dot products:
Because normalized vectors have bounded norms (), the maximum possible unscaled dot product is bounded by , making . While QK-Norm controls attention scale, it does not stabilize the final vocabulary projection layer ().
Logit Regularization (z-loss)
Introduced in PaLM (Chowdhery et al., 2022), -loss adds an auxiliary penalty to the training objective:
where . The -loss penalty discourages logits from drifting to large values by penalizing the log partition function. However, unlike soft-capping, -loss does not enforce hard numerical upper bounds during individual forward passes.
PyTorch Reference Implementation
The following PyTorch module demonstrates the implementation of scaled dot-product attention with logit soft-capping, including verification of bounded forward activations and continuous gradient properties:
import torch
import torch.nn as nn
import torch.nn.functional as F
class SoftCappedAttention(nn.Module):
def __init__(self, d_model: int, n_heads: int, soft_cap: float = 50.0):
super().__init__()
self.d_model = d_model
self.n_heads = n_heads
self.d_k = d_model // n_heads
self.soft_cap = soft_cap
self.q_proj = nn.Linear(d_model, d_model, bias=False)
self.k_proj = nn.Linear(d_model, d_model, bias=False)
self.v_proj = nn.Linear(d_model, d_model, bias=False)
self.out_proj = nn.Linear(d_model, d_model, bias=False)
def forward(self, x: torch.Tensor, mask: torch.Tensor | None = None) -> torch.Tensor:
batch_size, seq_len, _ = x.shape
# Project and reshape to [batch, heads, seq, d_k]
q = self.q_proj(x).view(batch_size, seq_len, self.n_heads, self.d_k).transpose(1, 2)
k = self.k_proj(x).view(batch_size, seq_len, self.n_heads, self.d_k).transpose(1, 2)
v = self.v_proj(x).view(batch_size, seq_len, self.n_heads, self.d_k).transpose(1, 2)
# Standard scaled dot product
scores = torch.matmul(q, k.transpose(-2, -1)) / (self.d_k ** 0.5)
# Apply tanh logit soft-capping
if self.soft_cap is not None and self.soft_cap > 0.0:
scores = self.soft_cap * torch.tanh(scores / self.soft_cap)
if mask is not None:
scores = scores.masked_fill(mask == 0, float("-inf"))
attn_weights = F.softmax(scores, dim=-1)
context = torch.matmul(attn_weights, v)
# Reshape back to [batch, seq, d_model]
context = context.transpose(1, 2).contiguous().view(batch_size, seq_len, self.d_model)
return self.out_proj(context)
def soft_cap_logits(logits: torch.Tensor, cap_value: float = 30.0) -> torch.Tensor:
"""Applies smooth hyperbolic tangent soft-capping to vocabulary logits."""
return cap_value * torch.tanh(logits / cap_value)
if __name__ == "__main__":
torch.manual_seed(42)
layer = SoftCappedAttention(d_model=256, n_heads=8, soft_cap=50.0)
# Input tensor
inputs = torch.randn(2, 64, 256, requires_grad=True)
out = layer(inputs)
loss = out.sum()
loss.backward()
print(f"Output shape: {out.shape}")
print(f"Input gradients norm: {inputs.grad.norm().item():.4f}")
# Verify asymptotic bounding
extreme_logits = torch.tensor([-200.0, -50.0, 0.0, 50.0, 200.0])
capped = soft_cap_logits(extreme_logits, cap_value=30.0)
print(f"Extreme logits: {extreme_logits.tolist()}")
print(f"Capped logits: {[round(v, 4) for v in capped.tolist()]}")Sources
- Gemma 2: Improving Open Language Models at a Practical Size (Gemma Team, Google DeepMind, 2024)
- Neural Combinatorial Optimization with Reinforcement Learning (Bello et al., 2016)
- Scaling Vision Transformers to 22 Billion Parameters - QK-Norm (Dehghani et al., 2023)
- PaLM: Scaling Language Modeling with Pathways - z-loss (Chowdhery et al., 2022)
- Attention Is All You Need (Vaswani et al., 2017)
- FlexAttention + FlashAttention-4: Fast and Flexible (PyTorch, 2024)



