Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

KL Divergence

TLDR

  • Kullback-Leibler (KL) Divergence is a common metric used when working with distributions

    • It measures the non-symmetric “distance” between two distributions

  • KL Divergence is used commonly in RL to measure how “far” policies have updated

    • Different RL algorithms use forward, backward, or Jeffrey’s divergence in their calculations

  • Calculating KL Divergence exactly can be expensive so approximations are often used

KL Divergence Primer

RL Implementations commonly include KL Divergence in both their mathematical formulas and their code implementation. At its core, it’s a simple concept, but tracing its implementation in practice can be a confusing mess of approximations paired with computational stability tricks. This makes it hard to understand how the high-level concept maps to the specific code implementation or paper you’re studying. And unfortunately, a faulty implementation of KL Divergence can break our entire training objective. So, before starting a big training run, ensuring it’s correct ahead of time will save you many headaches.

Let’s talk through practical KL divergence in the LLM context with three levels

  • Level 1: A basic working intuition of the concept

  • Level 2: A deeper explanation of the common approximators you’ll see

  • Level 3: A full explanation with code of why approximations are needed, and then a deep explanation of forward and reverse KL

Level 1: Intuition

KL Divergence measures the “difference” between two distributions. This is useful because in Reinforcement Learning, we want to compare versions of model outputs with each other during training.

Divergence not distance

We don’t use the word ‘distance’ for a reason; even putting ‘difference’ in quotes. This is because KL Divergence is not symmetric. More on this later.

Source
<Figure size 640x480 with 1 Axes>

We can use KL Divergence to make sure our policy updates are not too big, which is why you see it as a penalty term for weight updates.

In Reinforcement Learning literature, p and q are often denoted by

Source
<Figure size 640x480 with 1 Axes>

Level 2: KL Divergence Approximation

KL Divergence is not always simple to calculate. From John Schulman’s blog

  1. Computing it exactly requires too much computation or memory.

  2. There’s no closed form expression.

  3. We can simplify code by just storing the log-prob, not the whole distribution. This is a reasonable choice if KL is just being used as a diagnostic, as is often the case in reinforcement learning.

John then goes on to derive these three estimators, and shows that the third estimator is the best because it has no bias and a lower variance than the other estimators.

true tensor(0.0050)
tensor(-0.0074) tensor(20.0014)
tensor(0.0026) tensor(1.4189)
tensor(0.0001) tensor(1.4177)

Why Approximations are Fine

Approximations are okay because KL Divergence is just a regularizer in our loss term, so exact divergence is not needed. Additionally, because it’s weighted (often with β\beta) and clipped in many implementations, it matters even less that it’s exact. It just needs to be relatively unbiased.

For a good explanation of the Deepseek implementation of KL, which uses k3 as noted above, watch this video from Yacine. https://www.youtube.com/watch?v=iHf6mMiiNOw

Level 3: All the details

This section details an LLM-specific scenario where we are sampling over multi-step categorical distributions.

With LLMs we have two axes of complexity

  1. Large vocab/action size VV - Often 64,000 or higher

  2. Long generation sequences TT - With reasoning traces 5000 token sequences or more

If a method requires calculating or storing these V×VV \times V conditional probability matrices, its complexity becomes exponential in the sequence length, O(VT)O(V^T). This will take both huge amounts of memory and computational calculation.

To illustrate let’s go through an exact calculation with a restricted example, before then going through two approximations.

Setup

Consider a token space of 5, where each word is a token. Additionally we’ll artificially construct a two-step generation.

In this example

  • Step 1 is likes

  • Step 2 is salad

For the first step, because we only have one preceding token, our probability space has a shape of (5,), with one probability for each token that could possibly be generated.

We’ll also define the probabilities for both policy πrefπ_{ref} and a trained policy πθπ_θ. We need both because these are the policies/probability distributions that we want to measure the divergence from.

For the second step, however, our probability is conditional because it depends on what token is selected in the step prior which is why our joint probability space is 5x55x5. If we were to include a third step the shape would be 5x5x55x5x5, from this you can already get a sense of just the memory needs for full KL divergence calculation.

Exact Calculation

Now that we have our first step and second step probability tensors we can calculate KL Divergence. The formula for KL divergence is usually stated as such

DKL(P∥Q)=∑x∈XP(x)log⁡P(x)Q(x)D_{\text{KL}}(P \parallel Q) = \sum_{x \in \mathcal{X}} P(x) \log \frac{P(x)}{Q(x)}

This formula is a bit misleading at a glance because it can be misunderstood that x is of shape (1,X)(1,X). As alluded above though in LLM cases what’s actually needed is the joint probability over the entire generated token sequence. Here is the same equation as above, but in notation that makes the combinatorial complexity much more obvious.

DKL(Pjoint∣∣Qjoint)=∑x1⋯∑xTP(x1,…,xT)log⁡(P(x1,…,xT)Q(x1,…,xT))D_{KL}(P_{\text{joint}} || Q_{\text{joint}}) = \sum_{x_1} \cdots \sum_{x_T} P(x_1, \dots, x_T) \log \left( \frac{P(x_1, \dots, x_T)}{Q(x_1, \dots, x_T)} \right)

With our sample token sequence we can calculate the exact KL divergence for reference.

(25,)
np.float64(0.3568151101092548)

Linear Approximation: Drop the Conditional

The first approximation we can make is to drop the conditional dependence. We just calculate the KL at each token generation step and ignore the branching paths.

np.float64(0.2871928094770909)

For multiple steps we can take the mean over token steps as well, just as in the calculations above from John Schulman’s example.

KL Divergence Approximated just from Sampled Token sequence

The example above reduces the exponential joint probability calculations to a O(V)O(V) linear complexity, However, we still may not want to store the entire token probability matrices (V, T) for a vocabulary of size V and a sequence of length T, because this still takes up memory, especially if we also include batch dimensions.

We can simplify further by approximating KL just from probabilities of the sampled tokens. The code below looks more complex, however in practice this code is already needed as part of the sampler, and we are just storing the bare minimum number of floats.


--- KL PENALTY CALCULATION FOR TRAJECTORY: Ravin -> likes -> salad ---
Step 1 ('likes'):
  P_pol(likes) = 0.78, P_ref(likes) = 0.60
  Log-Ratio: ln(0.78 / 0.60) = 0.262364
Step 2 ('salad' | 'likes'):
  P_pol(salad|likes) = 0.95, P_ref(salad|likes) = 0.80
  Log-Ratio: ln(0.95 / 0.80) = 0.171850
-------------------------------------------------------------------
Total KL Penalty (Sum of Log-Ratios): 0.434215 nats

Forward/Mode Seeking vs Reverse/Mode Covering

In RL, but also other algorithms such as Variational Inference in Bayes, we use KL Divergence as part of the optimization target. We have a “true” distribution that we are trying to approximate with the distribution our model is estimating. As mentioned before KL divergence helps us measure how “far” our estimated distribution is However an important property of KL Divergence is that it’s not symmetric.

DKL(P∥Q)≠DKL(Q∥P)D_{\text{KL}}(P \parallel Q) \neq D_{\text{KL}}(Q \parallel P)

Reversing the terms here actually has such a big effect that there are two names depending on the order of the terms and whether we are minimizing or maximizing. To understand in the context of LLM RL, let’s replace the PP and QQ with πθ\pi_{\theta} and πref\pi_{\text{ref}}. In RL, typically

  • πθ\pi_{\theta} - The weights that we are actively optimizing

  • πref\pi_{\text{ref}} - The weights (or policy) that are fixed, also sometimes called the anchor

We can also rewrite our equation above as

DKL(πθ∥πref)≠DKL(πref∥πθ)D_{\text{KL}}(\pi_{\theta} \parallel \pi_{\text{ref}}) \neq D_{\text{KL}}(\pi_{\text{ref}} \parallel \pi_{\theta})

Now one of these sides is forward KL and the other is reverse KL. The choice of which one you use will affect the behavior of your final LLMs. In LLMs and RL, the general intuition is

  • Forward/Inclusive/Mode Covering RL will keep diversity covering all the modes. For example, in the health example, it’ll keep Ravin’s behavior of picking a variety of foods.

  • Reverse/exclusive/Mode Seeking RL will collapse diversity, pushing the distribution to “pick” one of the modes.

Which one is which, though, depends on both the order of the terms, and also whether we are minimizing or maximizing the KL component of our loss, which also depends on whether we are adding or subtracting the KL term in our policy optimization target.

To make matters even more complicated, there’s also a concept called Jeffreys’ Divergence, which is a combination of both of these.

Jeffreys′Divergence=DKL(πθ∥πref)+DKL(πref∥πθ)Jeffreys' Divergence = D_{\text{KL}}(\pi_{\theta} \parallel \pi_{\text{ref}}) + D_{\text{KL}}(\pi_{\text{ref}} \parallel \pi_{\theta})

Verifying Which One You’re Working With

This can all get confusing so the easiest way to check is just re-implement a minimal example in code, and verify every detail is exactly correct. That is

  • The order of the terms in the KL approximator

  • Minimization or maximization by your optimizer

  • The sign of your KL component

Here is an example where we implement the KL objective from the Deepseek Math GRPO paper, where they maximize a negative reverse KL. We first create a bimodal reference distribution. We need a bimodal reference so we can tell later whether the optimization is mode-covering or mode-seeking.

<Figure size 640x480 with 1 Axes>

We can then implement a basic optimizer that fits a normal distribution’s mean and scale per our optimization target.

Source
<Figure size 1200x400 with 2 Axes>

Other Implementations

I again want to stress that the choice of forward, backward, or Jeffreys’ Divergence is a choice. In the BOND paper the authors choose to use Jeffrey’s Divergence to balance between mode seeking and mode covering. They write

The choice of the divergence metric used in BOND is of crucial importance: different divergences can steer the policy to very different solutions. Here, we propose the Jeffreys divergence as a robust distribution matching objective. The Jeffreys divergence (Jeffreys, 1946) between two distributions is defined as:

Jeffreysβ(p∥q):=(1−β)⋅KL(q∥p)⏟Forward KL+β⋅KL(p∥q)⏟Backward KL.J^{\beta}_{\text{effreys}}(p \| q) := (1 - \beta) \cdot \underbrace{\text{KL}(q \| p)}_{\text{Forward KL}} + \beta \cdot \underbrace{\text{KL}(p \| q)}_{\text{Backward KL}}.

The (generalized) Jeffreys divergence is a weighted average (with weight 𝛽 ∈ [0, 1]) between the forward and backward KL divergence. Notably, when fine-tuning policy 𝑝, the forward KL(𝑞 ∥ 𝑝) encourages that generations likely under 𝑞 are also likely under 𝑝, thus encouraging a mode-covering behavior. Instead, the reverse KL( 𝑝 ∥ 𝑞) is well-known to have a mode-seeking effect, steering policy 𝑝 to produce generations that have a high likelihood according to 𝑞 (Agarwal et al., 2024). While the forward KL may produce over-spread distributions, the backward KL can lead to policy and entropy collapses. Instead, we empirically show that the Jeffreys divergence inherits the best of both divergences, producing better aligned policies.

Suggested Prompts

  • Where is KL Divergence used outside of its application with LLMs? What about with LLMs?

  • When would we prefer forward, backward, and symmetric KL?

  • What are the challenges with calculating KL Divergence?

References