← All posts
Machine Learning

Trust Region Policy Optimization (TRPO)

Overview

How Trust Region Policy Optimization (TRPO) keeps policy updates stable by limiting how much a model's behavior can change, explained step by step with KL divergence, importance sampling, the Fisher information matrix, and the natural gradient. Part 2 of a series on policy optimization for LLMs.

TRPO cover: a policy update step kept inside a trust region around the current model

Introduction

Part 1 ended with a problem. The policy gradient tells us which direction to move the model, but not how far. If the step is too small, learning crawls. If it is too large, the model starts writing bad answers, learns from those bad answers, and falls into a death spiral from which it does not recover. So before anything else, we need an answer to a simple question: how large can an update be before it becomes dangerous?

The obvious answer is to turn down the learning rate. But the learning rate only controls how much the weights move, and the weights are not what we care about. What matters is how much the model’s output changes: the probabilities it assigns to each next token. In a large network, the two are only loosely connected. Moving one weight by may barely change the output, while moving another by just may change which token the model picks. A learning rate that is safe for the sensitive weights is painfully slow for all the others, and one that is fast enough for the others is dangerous for the sensitive ones. There is no single right value.

In 2015, Trust Region Policy Optimization (TRPO) [1] took a different route: instead of limiting how far the weights move, it limits how far the output moves. Before each update, TRPO fixes the maximum amount by which the model’s next-token probabilities are allowed to change. Every new model within that limit is considered safe, and together they form the trust region: the neighborhood around the current model where we can trust our estimate of whether an update helps. Figure 1 shows the idea, with three steps in the same direction from the current parameters , but of different sizes:

trust region (safe zone) θ reward start θold collapse! too small: slow just right too large: collapse
Figure 1. Same direction, three step sizes. A small step improves the reward only slightly. A step within the trust region reaches the peak. A step that is too large overshoots the peak and the reward collapses.

The small step is safe but barely helps. The large step overshoots the peak, and the reward collapses. The step that stays inside the trust region is the one we want, and the rest of this post is about how TRPO finds it.

Throughout this post, are the current parameters and is the model before the update, while and are the parameters and the model after it. To find the right step, TRPO has to answer three questions. First, how do we measure how much the output has changed? This is the job of the KL divergence. Second, how do we evaluate a new model without generating new answers for it? This is where importance sampling comes in. And third, how do we find the best update inside the trust region? This question takes us from the TRPO objective, through the Fisher information matrix and the natural gradient, all the way to conjugate gradient and line search.

Measuring “How Far”: KL Divergence

At every step, an LLM outputs a probability distribution over its vocabulary. So to measure how much the model has changed, we need to compare two distributions: the old model’s and the new model’s. The standard tool for this is the Kullback–Leibler (KL) divergence [2]:

Here is the old model’s distribution, is the new model’s, and runs over every token in the vocabulary. For each token, the ratio compares its probability under the two models: if they agree, the ratio is , , and the token adds nothing. Each term is weighted by , so tokens the old model picks often count more. The total is when the two distributions are identical and grows as they become more different. (The KL is not symmetric, , which is why it is called a divergence rather than a distance.)

Example: comparing two updates

For the prompt “The cat sat on the”, suppose the old model and two possible updates assign these next-token probabilities:

Next token Old model Update A Update B
mat 0.70 0.65 0.10
sofa 0.20 0.24 0.20
roof 0.10 0.11 0.70

Update A changes the probabilities slightly, while Update B makes “roof” the top choice instead of “mat”. Using Eq. (1):

Update B is about 200 times farther from the old model than Update A, which matches our intuition. And we got this number without looking at a single weight: the KL only depends on the outputs.

That was one prediction. An LLM makes a prediction at every token of every response, so TRPO averages the KL over all the states the old model visits:

TRPO requires this average KL to stay below a small number , for example . This is the size of the trust region: with , Update A would be allowed and Update B would not.

We can now check whether a new model is inside the trust region. The next question is how to check whether it is actually better than the old one.

Reusing Old Samples: Importance Sampling

To know whether a new model is better, we need to estimate how good its answers are, for example, the average reward they would get. The direct way is to let generate answers and score them. But generation is the slowest part of RL for LLMs, and while searching for the best update we want to evaluate many candidate models. Instead, we want to reuse the answers that has already generated. Importance sampling lets us do exactly that.

Example: reweighting old samples

Suppose a prompt has only two possible answers: a good one with reward and a bad one with reward . The old model generated answers: 2 good and 2 bad. For each answer, we also ask both models how likely they are to produce it. This does not require generating anything: we feed the answer into the model and read off its probability in a single forward pass, the same way the SFT loss is computed (this is called teacher forcing, explained in the details below).

Answer Reward Old samples Old prob. New prob.
good 1 2 0.5 0.75
bad 0 2 0.5 0.25

If we simply average the rewards of our 4 samples, we get . But that is the old model’s average reward: the samples are half good and half bad because they came from the old model. The new model gives the good answer more often, so our samples contain too few good answers to represent it.

We can fix this by changing how much each sample counts. The new model gives the good answer times as often as the old model, so each good sample should count as 1.5 samples. It gives the bad answer only times as often, so each bad sample should count as half a sample. This factor, , is called the importance weight:

With the weights, our 2 good samples count as and our 2 bad samples as , which is exactly what 4 samples from the new model would look like on average. And indeed, the new model’s true average reward is . For a real LLM, we could never check this directly, because there are far too many possible answers to add up. Importance sampling gives us the answer anyway.

Details: getting the new model’s probabilities with teacher forcing

How do we get the New prob. column without sampling from the new model? First, it helps to separate two terms. At each position, a model outputs a probability distribution: a probability for every token in its vocabulary, adding up to . A probability is a single number taken from that list, such as the probability of one specific token.

Now compare two operations on an answer like “on the mat” for the prompt “The cat sat”:

  • Generating the answer needs one forward pass per token. At each step, the model outputs a distribution, we sample a token from it, and feed that token back in to get the next distribution. Each step has to wait for the previous one.
  • Scoring an answer that already exists needs only one forward pass. The whole text “The cat sat on the mat” is known, so we feed it in at once. The model outputs a distribution at every position in parallel, and we just read off the probability of the token that is actually there:
Position (what the model has seen) Distribution the model outputs Token actually there Probability we read
The cat sat on 0.60, down 0.30, still 0.10 on 0.60
The cat sat on the 0.90, a 0.10 the 0.90
The cat sat on the mat 0.80, sofa 0.15, roof 0.05 mat 0.80

Multiplying these gives the probability of the whole answer:

This is called teacher forcing, and it is the same way the SFT loss is computed. So the new model never writes anything: we only use it to score the answers the old model has already written.

In general, if we sample from a distribution but want the average under another distribution , we weight each sample by :

In our example, is the old model, is the new model, and is the reward.

Derivation: why importance sampling works

The expected value of under is each value multiplied by its probability, all added up:

Multiply and divide each term by , which changes nothing since , and move to the front:

The right-hand side has the same shape as Eq. (4), with instead of . So it is the expected value of the bracketed term under , which gives Eq. (3).

For an LLM, the same weight is applied to every token of every response, given its state . It is called the probability ratio:

There is one more change. In the example, we weighted the reward of each answer, but TRPO weights the advantage of each token (Eq. (3) in Part 1) instead. As in the policy gradient, the reward only says how good the whole answer was, while the advantage says whether each token was better or worse than expected, which is what the model needs to learn which tokens to make more or less likely. Weighting each token’s advantage by its probability ratio gives the surrogate objective:

“Surrogate” means substitute. The objective we really care about is the new model’s actual performance, but measuring it would require generating new answers. stands in for it, using only the old model’s answers. To make larger, the new model has to make tokens with a positive advantage more likely () and tokens with a negative advantage less likely (), the same idea as the policy gradient. In fact, at every ratio is , and the gradient of is exactly the policy gradient in Eq. (2) in Part 1.

There is a catch, though. The estimate is only reliable when the new model is close to the old one. If they are very different, some ratios become very large, a few tokens dominate the average, and the estimate becomes noisy. This gives a second reason for the trust region: besides keeping the policy from breaking, it keeps accurate.

This probability ratio is also the core of PPO.

We now have both pieces: tells us how good a new model is, and the KL tells us how far it is from the old one.

The TRPO Objective

TRPO combines the two pieces into one optimization problem:

In plain words: find the new model that improves the surrogate objective the most, while keeping the change in its output within .

Why does this make training stable? Let be the model’s true performance (its expected reward), the same objective whose gradient we took in Eq. (2) in Part 1. The TRPO paper [1], building on earlier work by Kakade and Langford [3], proves that:

In words: the new model’s true performance is at least the old performance, plus the surrogate objective, minus a penalty that grows with the KL divergence. Here is like but takes the largest KL over all states instead of the average, and is a positive constant that depends on the size of the largest advantage. So if an update improves the surrogate and keeps the KL small, the true performance cannot decrease. This is the monotonic improvement guarantee, exactly what vanilla policy gradient lacked.

The formulation is clean, but how do we actually solve it? This is where the Fisher matrix comes in.

The Fisher Information Matrix

Eq. (7) is hard to solve directly, because and the KL depend on billions of parameters in complicated ways. But the trust region gives us a shortcut. Every update is small, so we only need to know how these two functions behave near the current parameters . And near a single point, even complicated functions look like simple shapes.

Figure 2 shows the two shapes TRPO uses. Near , the objective looks like a straight line, and the KL looks like a quadratic, a curve shaped like a bowl.

θold 1st order: line L(θ) accurate here Objective: a line is enough θold 1st order: flat, always 0 2nd order: quadratic KL KL: a line says 0, a quadratic is needed
Figure 2. Near , the objective looks like a straight line (left), while the KL looks like a quadratic (right). A straight line cannot describe the KL: at it is flat and always .

Replacing a function with a simple shape near a point is called a Taylor approximation. A straight line uses the function’s slope (its first derivative), so it is called a first-order approximation. A quadratic also uses its curvature (its second derivative), so it is called a second-order approximation. Let’s look at each shape, writing for the update step.

Details: the Taylor expansion

Univariate case. Near a point , after a small step , a smooth function can be approximated using its derivatives at :

The value and the first-order term together give a straight line, the tangent to at : the first derivative is the slope, so the line tells us which way the function goes and how fast. Adding the second-order term bends this line into a curve (a parabola): the second derivative is the curvature, how fast the slope itself changes. The approximation is very accurate near and gets worse as grows, which is why it suits a method that only takes small steps.

Multivariate case. For a function of all parameters , the step becomes a vector , and the derivatives become vectors and matrices. The first derivative is taken with respect to each parameter, one at a time. Collecting these slopes gives the gradient, a vector:

For the second derivative, each entry of this gradient is itself a function of all parameters, so we differentiate each entry again with respect to every parameter. entries, each differentiated by parameters, gives an matrix, the Hessian:

Row holds the derivatives of the -th gradient entry. The diagonal entries are the curvature along each parameter on its own, just like . The off-diagonal entries describe how two parameters interact. For smooth functions (with continuous second derivatives), the order of differentiation does not matter, so and the Hessian is symmetric.

With the gradient and the Hessian, the Taylor approximation for the multivariable case is:

The first-order term is simply the matrix product of the gradient and the step, which gives a single number. In coordinates, it reads : every slope times its step, all added up. The second-order term is a quadratic form: the step appears on both sides of the Hessian, and the result is again a single number. In coordinates, the -th entry of is , and multiplying by weights each entry by and adds them up:

In TRPO, is replaced by (keeping only the line) and by the KL (keeping the quadratic term), and the KL’s Hessian is the matrix .

Approximating the Objective

We have just seen the full Taylor approximation with its second-order term, but for the objective we will not need it. For a small step, the second-order term is much smaller than the first-order term: it grows with instead of , so a step of contributes only about . And the objective only has to tell us which direction improves the model. How far to go is decided by the KL, and that is where the second-order term and the Hessian will matter. So for , we keep only the first two terms, the value and the slope:

Both terms are easy to fill in. At , every probability ratio is , so the value is : on average, the old model’s own tokens are neither better nor worse than expected. And the slope at is exactly the policy gradient, which we call . So the objective becomes a straight line through zero:

For each parameter, this multiplies its slope by how far we move it, , and adds everything up.

Approximating the KL Divergence

For the KL, we cannot stop at the first-order term. Applying the same Taylor approximation, this time with all three terms, gives:

where is the Hessian of the KL at . This time, the first two terms both vanish. The value is the KL of the old model with itself, which is . And since the KL is never negative, sits at the very bottom of a valley, where the ground is flat, so the slope is as well (right panel of Figure 2).

Derivation: why the KL’s slope is zero

Write out the average KL from Eq. (2), using the formula in Eq. (1) and dropping for readability:

Only the second term depends on . Using , its gradient is:

At , the denominator becomes and cancels with the factor in front:

The probabilities always add up to , so their total cannot change in any direction.

Since the first two terms are zero, we keep only the last one, the second-order term. It describes the shape of the valley, a quadratic:

With both approximations, the hard problem in Eq. (7) becomes a much simpler one: go as far as possible along a straight line, while keeping the quadratic below :

The matrix is an matrix that describes how steep the walls of the valley are in every direction. This matrix has a name, the Fisher Information Matrix, and the whole trust region now depends on it: the steeper the walls in some direction, the smaller the step we can take that way. So before we use it, let’s see what tells us about the model.

What the Fisher Matrix Tells Us

Each entry of tells us how steep the KL’s walls are in some direction, which is the same as asking: if we move the parameters in this direction, how much does the model’s output change? A large value means the output is sensitive in that direction, and even a small step changes it a lot. A small value means the output barely reacts.

This is exactly what we were missing at the start of this post: a way to know which weights are sensitive and which are not, something a single learning rate cannot capture.

Example: one sensitive, one insensitive parameter

Consider a model with two parameters, where

The output is very sensitive to and not very sensitive to . Take a step of along each one. By Eq. (10), moving gives a KL of , while moving gives only . The same distance in parameter space changes the output 100 times more in one direction than in the other.

So the trust region, the set of steps whose KL stays below , is not a circle in parameter space. It is an ellipse: narrow along sensitive directions, where only tiny steps are safe, and wide along insensitive ones, where large steps are fine.

Computing the Fisher Matrix

As a Hessian, would require second derivatives of the whole network, which are expensive to compute. Fortunately, it can be rewritten using first derivatives only (see the derivation below):

The gradient inside, , is called the score function. It is the same gradient as in the policy gradient: the direction that makes token more likely. So is the average outer product of the score function with itself. In practice, it is estimated from sampled tokens:

Derivation: from second to first derivatives

Start from the KL itself and take its second derivative:

To continue, we need the second derivative of a log. The gradient of a log is , and differentiating it once more with the quotient rule gives:

Substituting this into (writing for and dropping the to keep the lines short) gives:

Splitting the bracket into its two parts, the two minus signs in the second part cancel:

At , the in the denominator of the first part becomes :

so it cancels with the in front:

In the second part, a sum over weighted by is simply an expectation over :

In the first part, we can move the derivative outside the sum:

Here is the sum of the probabilities of all tokens, which is always . Substituting :

The derivative of a constant is , so the first part disappears, and only the second part survives:

Writing the token and its state explicitly gives Eq. (12).

Solving for the Update Step

We now have everything we need to update the model. The policy gradient tells us which direction improves the objective, and the Fisher matrix tells us how sensitive the model is in each direction. What is still missing is the actual update step : how far to move each parameter. It comes from solving the simplified problem in Eq. (11): go as far as possible along the line , while keeping the quadratic below :

Unlike Eq. (7), this problem can be solved exactly. We will find the answer in three parts: where the best step ends, which direction it points, and how long it is.

Where the best step ends. The objective is a straight line, so it keeps growing as long as we keep moving in a good direction. There is no reason to stop early, so the best step goes all the way to the edge of the trust region, where the constraint holds with equality:

In parameter space, this edge is an ellipse: the set of all steps whose KL is exactly .

Which direction it points. The best step lies somewhere on this ellipse, but where? The standard tool for maximizing a function under an equality constraint like this one is Lagrange multipliers [4], and the idea behind them is geometric, as shown in Figure 3.

edge: ½ ΔθᵀFΔθ = δ θold actual update: Δθ ∝ F⁻¹g candidate step sliding improves the objective edge direction at A part of g along the edge g A FΔθ FΔθ B g same direction: g = λ FΔθ
Figure 3. The edge of the trust region is an ellipse, and (purple) always points straight out of it. Point is only a candidate (dashed arrow): there, and point in different directions, and part of points along the edge, so sliding along the edge (dotted orange) would still improve the objective. At the best point , and point in the same direction and differ only in length, . The sliding is only a way of reasoning about where is: the actual update (green) goes straight from to , along .

Pick any point on the edge, such as , and split into two parts: one that points along the edge, and one that points straight out of it. If the part along the edge is not zero, we can slide a little along the edge in that direction. The KL stays exactly , but increases, so cannot be the best point. Sliding stops helping only where the part of along the edge is zero, that is, where points straight out of the ellipse, like at . This is the best step.

What does “straight out of the edge” mean mathematically? Let . Along the edge, stays equal to , just like the height stays the same along a contour line on a map. The gradient points in the direction where increases fastest, and since does not change along the edge, must be perpendicular to it, just as uphill on a map is always perpendicular to the contour lines. So points straight out of the edge. For our quadratic, it is:

which is the many-variable version of , using the symmetry of . This is the purple arrow in Figure 3.

So at , both and point straight out of the edge. Two vectors pointing in the same direction differ only in length, so one is a scaled version of the other:

The scaling factor is called the Lagrange multiplier. Multiplying both sides by gives:

This fixes the direction of the step: it points along . Its length is still unknown, because we do not know yet.

How long it is. To find , we use the fact that the best step ends exactly on the edge. Starting from the edge condition and substituting the direction from Eq. (14):

Here we used , since is symmetric, and . Solving for :

The TRPO update. Putting the direction and the length together gives the full update step:

The direction, , is called the natural gradient [5], [6]. The ordinary gradient treats all parameters the same, while multiplying by divides each direction by its sensitivity, so the step becomes smaller along sensitive directions and larger along insensitive ones. The length, , stretches or shrinks the step so that it ends exactly on the edge of the trust region, where the KL equals . Notice that there is no learning rate in this update. Its role is taken by , which is easier to interpret: the maximum change in the model’s output allowed per update.

Computing the Update for Large Models

Eq. (15) gives the ideal update, but it cannot be computed as written for an LLM. The problem is . For a 7-billion-parameter model, has entries, about 98 exabytes of memory in 16-bit precision, millions of times more than a GPU has. It cannot be stored, let alone inverted. TRPO works around this with two techniques: conjugate gradient to compute the direction without ever building , and line search to make sure the final step is actually safe.

Conjugate gradient. Look again at Eq. (15). We never need the matrix itself, only the vector . Finding this vector is the same as solving:

The conjugate gradient (CG) algorithm [7] solves this kind of equation step by step (for a gentle introduction, see [8]). It starts from a guess and improves it, and the key point is that it never needs itself, only products of with some vector . These Fisher-vector products can be computed with two backward passes through the network, using memory proportional to instead of . In practice, about 10 CG iterations give a good enough approximation of . And once we have , the step size in Eq. (15) is easy to compute, because .

Details: the conjugate gradient iterations

The idea behind CG is that solving is the same as finding the lowest point of the quadratic

because its gradient, , is zero exactly when . CG walks downhill on step by step, keeping track of three things at each iteration :

  • , the current guess for , starting from .
  • , the residual, which measures how far the current guess is from solving Eq. (16). It is also the downhill direction of , since . When , the guess is exact.
  • , the search direction: the direction in which the guess is moved in this iteration. The first direction is simply downhill, .

In each iteration, CG first decides how far to move along . Along this direction, . Substituting this into and expanding, where the two cross terms are equal () because is symmetric:

In the last line, the first bracket is , and by the definition of the residual. This is a parabola in . Its lowest point is where its derivative with respect to is zero:

This is the best distance to move along . CG then moves the guess by and updates the residual.

Next, CG picks a new search direction: the new residual plus a little of the previous direction. The amount is chosen so that each new direction is conjugate to the previous ones (), which means a step along a new direction never undoes the progress made along the earlier ones. Because each step already went to the lowest point along its direction, the new residual is perpendicular to the previous direction (), which also simplifies to . Put together, one iteration is:

Notice that only ever appears as a product with a vector, never on its own. Since is the Hessian of the KL, each Fisher-vector product can be computed with a trick known as a Hessian-vector product [9]:

First compute the gradient of the KL (one backward pass), take its dot product with to get a single number, then take the gradient of that number (a second backward pass). In practice, a small damping term is added, using instead of for a small , to keep CG numerically stable.

Line search. The step from Eq. (15) relies on the linear and quadratic approximations, which are only accurate close to . If the full step goes too far, the actual KL may end up larger than , or the surrogate objective may not actually improve. So before accepting the step, TRPO checks it with the exact and KL, and shrinks it if needed:

With , this tries the full step, then half, then a quarter, and so on. TRPO accepts the first step where the actual KL is within and actually improves. If no step passes after about 10 tries, it skips the update. This is called a backtracking line search [4]. Each check only needs forward passes on the batch we already have, so no new text has to be generated.

The TRPO Algorithm, Step by Step

Putting all the pieces together, TRPO alternates between generating responses with the current model and computing one constrained update from them:

Algorithm 1 Trust Region Policy Optimization

Lines 3 and 4 are the only ones that generate text or need rewards. Everything after them works on the same batch: the gradient, the conjugate gradient iterations, and the line search need only forward and backward passes through the network. This is also where the cost of TRPO comes from, as we see next.

Limitations of TRPO

TRPO solved the stability problem of vanilla policy gradient. But its second-order method comes at a high cost, especially for LLMs:

  • It’s expensive. Each update needs about 10 conjugate gradient iterations, each with an extra pass through the network, plus more forward passes for the line search. For an LLM, where a single pass is already costly, this multiplies the training cost.
  • It doesn’t fit the standard training loop. Deep learning models are trained with first-order optimizers like Adam, which take many small steps on mini-batches. TRPO instead computes one carefully constrained step per large batch, which does not fit this setup.
  • It’s hard to implement. Fisher-vector products, conjugate gradient, and line search add a lot of complexity. TRPO is also incompatible with architectures that share parameters between the policy and the value model, or that include noise such as dropout [10].
  • The guarantee is only approximate. The monotonic improvement theory assumes the exact objective, but the algorithm uses Taylor approximations and an averaged KL. The line search reduces this gap but does not remove it.

TRPO showed that limiting how much the policy changes in each update makes RL stable. The open question was whether the same stability could be achieved with ordinary first-order gradient descent.

This is the question PPO answered, and it is the topic of Part 3.

References

  1. Schulman, J., Levine, S., Moritz, P., Jordan, M. I., & Abbeel, P. (2015). Trust Region Policy Optimization. ICML.
  2. Kullback, S., & Leibler, R. A. (1951). On Information and Sufficiency. The Annals of Mathematical Statistics, 22(1), 79–86.
  3. Kakade, S., & Langford, J. (2002). Approximately Optimal Approximate Reinforcement Learning. ICML.
  4. Nocedal, J., & Wright, S. J. (2006). Numerical Optimization (2nd ed.). Springer.
  5. Amari, S. (1998). Natural Gradient Works Efficiently in Learning. Neural Computation, 10(2), 251–276.
  6. Kakade, S. M. (2001). A Natural Policy Gradient. NeurIPS.
  7. Hestenes, M. R., & Stiefel, E. (1952). Methods of Conjugate Gradients for Solving Linear Systems. Journal of Research of the National Bureau of Standards, 49(6), 409–436.
  8. Shewchuk, J. R. (1994). An Introduction to the Conjugate Gradient Method Without the Agonizing Pain. Carnegie Mellon University.
  9. Pearlmutter, B. A. (1994). Fast Exact Multiplication by the Hessian. Neural Computation, 6(1), 147–160.
  10. Schulman, J., Wolski, F., Dhariwal, P., Radford, A., & Klimov, O. (2017). Proximal Policy Optimization Algorithms. arXiv:1707.06347.
Mir Sazzat Hossain

Mir Sazzat Hossain

Junior Research Scientist at CCDS, IUB. Working on computer vision, domain adaptation, and the occasional radio-galaxy problem.

Related posts

Comments

Join the discussion here or continue it on GitHub.