In this post, we will review details about traditional RL and then over the next few posts, we will connect it to the LLM setting.
Think of the simplest scenario, kind of examples that RL is introduced in schools, like the balancing of a CartPole. The objective is to balance the pole for as long as possible -- that's the reward. The state is pole's position, velocity, angle, and angular velocity. The action is force applied to the base of the pole in order to give left or right velocity in order to balance the pole. And finally, the transition dynamics is given by the physics of the pole. This simple scenario is a Markov Decision Process (MDP). Generally speaking, a MDP is a tuple of , where is the state space, is the action space, is the transition dynamics, is the reward function, and is the discount factor. A policy is a mapping from states to distribution over actions, , so if you are in a given state, the policy will tell you which action to take in order to maximize the reward, and that is the goal of any RL setup -- and I will bold it so that we know where we start in RL : The goal of any RL setup is to find the policy that maximizes the sum of expected rewards over time.
Formally, the objective is where is the discount factor and is the horizon.
One can solve for the best policy or learn the algorithm for the best policy using this framework.
In this series of posts, our goal is to understand how traditional RL led to current state-of-the-art RL for LLMs, so this will be more of an in-depth review towards a specific direction rather than a comprehensive review of everything RL.
Goal: The goal is to select actions that maximize the expected sum of reward. But that's the final outcome, we need to find a way in order to achieve it, that happens by choosing actions that lead to high rewards. So let's define a trajectory as a sequence of states, actions, and rewards, , where is the terminal state.
Say we get some reward at the end of the trajectory, , now the question is how do we assign credit to the actions taken in this trajectory? There are two possible ways this happens (a): the environment gives us reward for each step in which case we compute something termed as reward-to-go and use tha to assign credit to each action, or (b) when we only get terminal reward. In this case again there are two ways to address this: (i.) each action in a trajectory receives the same credit or (ii.) we estimate the reward-to-go using different techniques and use that to assign credit to each action individually.
Now lets define reward-to-go, , this is the sum of rewards (also called realized return) from the current step to the end of trajectory. Rewards-to-go are a more accurate representation of reward as it removes the rewards that occured before the action. An action cannot cause past rewards. However, its application is uninformative in scenario when we don't have access to step-wise rewards and (no discounting), which is the common situation when doing RL for LLMs. In this case, at each step what we want to know is "when I took action 'a' in this step, what is the expected return averaging over all future states and actions" -- this naturally leads us to defining another term, action-value function:
. This is the long-term score estimator for an action 'a' taken at state 's'. In case of LLMs, this translates to, if I append token 'a' to the current prefix 's_{t}', and follow the policy to complete the rest of the response, what is the expected final completion reward.
We can use to improve a policy, by choosing actions that maximize the expected return, lets define that as
. Since we want to maximize this terms, we can differentiate it with respect to the parameters ,
, and using the trick we get
which gives,
; therefore
.
This says sample an action 'a', estimate its Q value, and then update the policy in the direction of , this updates the parameters as follows:
increasing the increases the probability of that action and a larger Q-value gives the action a larger update. In case of LLM, is the current prefix, is the sampled token and is the expected completion reward after selecting , this the policy gradient update reinforces tokens that lead to greater expected reward. Note that the \log-score trick which gives us is very easily computable, that is just the cross entropy loss of the sampled token which is done in even normal SFT. In SFT we try to minimize the , which gives the gradient , in RL, for a sampled action , you instead optimize using , so its gradient is , so just the cross-entropy loss weighted by the value at the sampled token.
For an entire trajectory, this is
, which is the policy gradient theorem. So to operationalize the policy gradient theorem, one would just take the average loss over a trajectory where the cross-entropy loss at each token is weighted by the value function at that token.
So we have now landed at the first algorithmic approach, policy gradient theorem, which can be used in to optimize actions to increase reward.
Now let's try to further optimize this approach. One of the issues that plaques the vanilla policy gradient method is the noise. So the above equation of the action-value estimation or even the gradient update happens over an extreme large search-space and in practice we sample N trajectories and compute the gradients and updated over these sampled trajectories and the sampling process can determine the optimization landscape to a large extent.
Consider this example to understand this issue: imagine an environment when your rewards are between 0 and 1, so everything is positive and therefore each trajectory is pushed up by policy gradient update, except that good ones are pushed more than the bad ones (determined by the differences in the magnitude in their absolute reward). Now lets add a constant to all rewards, say shift = +100, so now all rewards are between 100 and 101. The true signal from the sampled data remains the same, but the variance in the optimizer updates becomes way larger, each trajectory is pushed up by 100 * log-prob gradient and the differences between good and bad trajectories becomes harder to distinguish, there a common mode in both the positive and negative trajectories which drowns the learning signal, i.e., high variance. Here's another way to see this issue: consider two actions and whose = 0 and = 1. In this situation it is clear that the optimizer updates should push up the value of , however the gradient signal is the same is we shift these values, so now we get = 50 and = 51 and the optimizer will push up by 50 times its log-prob gradient when infact it should not be encouraged. To deal with this issue, we want to remove the common mode from all trajectories -- this preserves the same training signal while decreasing the variance.
A widely accepted mode that can be subtracted is the value function which is defined as the expected return from a particular state (irrespective of what action is taken), i.e.,
. Now for the above example, if both and are equally likely, and when we subtract this from the action-value function, we get and . This way a each sample carries much more useful signal and the difference between a bad action and good action is very clear and even the gradient update equation decreases the probability of the bad action and increases the probability of the good action
This baseline-centered action-value is termed as advantage:
. This is the relative advantage of taking a good action compared to what an average action in that state would achieve (in term of the expected return), therefore this encourages actions that lead to higher than expected reward and discourages actions that lead to lower than expected reward.
As we established above, advantage is the desired signal we want to optimize, however the environment rarely gives us advantage directly, it usually gives us rewards and that too mostly terminal. So how can we get the advantage? Reconsider the definition of advantage
Lets say we sample a trajectory , and we can compute its reward to-go, that's the monte carlo estimate of according to the definition . Therefore the simplest advantage estimate it , and it requires us to learn to predict . So how should we learn the value function? Since provides us with a sample of expected return from state , we can train the value function to predict using regression, i.e., . This approach of learning the value function is called its Monte-carlo estimate.
However this way of learning the value function has a few issues:
Therefore another approach was proposed to learn the value function called as TD-learning. In TD-learning instead of waiting till the end of the trajectory to estimate the return we use the step reward and the predicted value of the next state, i.e., . And therefore the advantage become . For terminal-only rewards, = 0, so the (at the actual terminal state, the terminal reward replaces the next-state prediction). Here's how TD-learning works:
The above described procedure is termed as one-step TD learning. However, this has issues of the opposite nature to Monte-Carlo estimate, i.e., it has quite high reliance on the critic which means high bias and it can be bad when the critic is inaccurate which they are in the initial part of the training. A middle-ground is reached with the n-step TD learning. In this the target is . In this case the advantage . So this leads to the trade-off, small n leads to higher critic bias, lower variance and larger n leads to lower bias and higher variance.
Generalized advantage estimation (GAE) was proposed to smoothly interpolate between these two extremes. We know . GAE combines with using weights controlled by (geometric weighted average), i.e., = (multiply the RHS by (1 - ) so that the weights sum to 1). There is another way of representing the GAE which comes form When taking geometric weighted average, we get . Therefore
To learn the critic with GAE, we use the same regression based approach as earlier, i.e., , where .
Overall, this setup of learning is called the actor-critic setup, the actor is parametrized by choses the action and the critic parametrized by predicts the expected return.
The overall loop using an actor-critic based optimization has these steps:
Now once we have updated the policy, the sampled trajectories were no longer generated by the new policy -- which means but we now want to optimize . The policy gradient algorithm we have described above is on-policy, i.e., we need trajectories from the policy we want to optimize in order to optimize it. However, collecting trajectories for just one step optimization and then discarding them is not efficient. If possible, we would like to resue the rollouts we generated for several optimization steps. And this is reasonable because one optimization step usually shouldn't move the policy far enough that the sampled trajectories are completely unviable under its probabilities.
However usage of trajectories from earlier policy to update current policy brings up a few problems:
This leads to the introduction of a new concept, importance sampling. The importance sampling ratio computes how much less or more likely is the sampled action under the new policy compared to the old policy.
In general suppose we want to compute the expectation under a distribution , . But now our samples are not from distribution , but another distribution , then we rewrite this as . The ratio corrects for the fact that the samples are not from , but from . When applied to RL, the ratio is equivalently written as .
We first compute the IS ratio using the formula described above and then take this into account when computing the loss. Recall the loss when the samples are on-policy: . Under IS this loss becomes , so just multiply the advantage by the IS ratio.
So recall that the updates of RL looks similar to the SFT cross-entropy loss updates except that each token as a weight given by advantage of that token, now that advantage itself is weighted by the IS ratio of that token.
It is important to note that the above loss formulation only corrects the per-token ratio given a fixed prefix, it does not take into account the probability of the prefix itself. Correcting that would require the cumulative product of IS ratios at all prior token positions. So this formulation of the IS only considers the question "how likely the next token is given that we have this prefix", it does not consider "how likely the new policy is to reach the prefix in the first place". Why do we not do the full correction? This is because the cumulative products would become unstable. Even with just one per-token IS ratio being too small or too large the cumulative product can become exponentially large or small -- and may overflow or underflow numerically -- as trajectory length grows. And therefore we accept some bias from using the old policy's prefix distribution to trade-off some variance.
So importance sampling allows us to reuse previous rollouts for optimizing current policy (under certain conditions) which helps us with the efficiency problem that we pointed out earlier.
However, we cannot use the stale data for infinitely long, eventually the updates push the current policy sufficiently far away from the trajectory sampling policy which makes the updates mathematically unjustified and the stored prefixes become less representative of the prefixes the new policy could generate.
And there is another issue which is the if the advantage of an action-state pair if greater than 0, and if we use the same prefixes, the update steps will keep encouraging this action-state pair until its probability reached 1 (unless the updates are constrained). During training we usually compute the advantage once from the rollout (using ) and treat it fixed (we'll discuss this). Let's define and . The loss for the actor is .
Lets see what happens to the importance sampling ratio of an action-state pair whose . So as actor is updated and its loss goes down (since advantage is fixed and positive), for the loss to go down the IS ratio must increase. Therefore, everytime we optimize this same stored action-state pair, the objective continues to increase the probability of this action-state pair. Similarly if the , then the objective continues to drive down the probability of this action-state pair.
So the number of times we can use the previously sampled trajectories must remain limited because of these reasons:
This raises a question, if the data reuse is limited because the advantage was calculated from and that advantage is stale (which leads to the issue #2 and #3) above why don't we find the advantage of the action-state pairs under the updated policy?
The reason we don't do this is because even though mechanically we could compute the advantages, since the continuation from a action-state pair came from the old policy, the is not a good estimate of the as did not get the correct training target (the policy was not sampled from ). To correctly estimate we would need to start from the stored prefix , take the stored action and then generate the remainder using and score the new completion and use that to train the value function -- the entire motivation of the generation cost we want to avoid in the first place (For a length completion, generating one continuation from every prefix could require approximately: generated tokens), therefore we keep the advantages from the original policy as fixed in the training.
We have established that (a) we want to reuse the sampled trajectories to avoid the cost of generating trajectories with every update step, and (b) we cannot forever reuse the sampled trajectories as they have become stale and the updates from them aren't meaningful. This begets the question, how do we know when to stop using the previously sampled trajectories? The answer to this question cannot be a fixed hyperparameter like 3 or 5, it depends on amount of policy movement which in turn depends on the learning rate, gradients, advantages, etc. We also cannot measure this using the change in parameter space because a large parameter change might only slightly change the output distribution and vice-versa, therefore we need to measure how much the policy's action distribution at the states in the sampled trajectory has changed?
A natural measure of doing this is the KL-divergence between the distributions, i.e.
. It is zero when distributions are identical, large when they are substantially different and measured in output distribution space rather than in parameter space.
Therefore the RL objective now becomes constrained
This inteprets as "improve the policy using the old batch data, but remain inside a region where the old states and advantages are still reasonably representative under the updated policy". How should one solve this constrained optimization problem? There are several ways of solving such optimization problems like:
Projected gradient descent: Performs a step of parameter update and projects it back to the feasible set. However, here the constraint is not on the parameters but on the KL divergence of the output distribution which makes the projection part non-trivial.
Lagrange multipliers: This requires us to optimize: , and the problem moves to choosing the optimum parameter . Too small, makes the KL grow beyond the desired region and too large makes the policy barely move. An adaptive primal-dual version can update both and alternatively, however that can also lead to oscillation.
Conjugate-gradients: (where )and (where F is the Hessian of KL divergence, which is the policy's Fisher information matrix) This leads to the optimization problem taking the form of subject to . For a policy , the fisher matrix identifies which parameter direction most strongly change the policy's action probabilities and thus the above constraint can be interpreted as choosing a parameter update whose resulting policy distribution remains within a said distance (Fisher matrix is the local curvature of KL divergence, i.e., . The KL is zero at and its first derivative if zero there, the fisher matrix captures the second-order change, i.e., measures how much a parameter update changes the model's output distribution -- which is what we exactly need). The optimal direction satisfies: Therefore we need to solve . Constructing or inverting the massive fisher matrix F is very expensive, conjugate gradient approach approximately solve using only Fisher-vector products. After obtaining , we scale it to the KL divergence limit, i.e., . A line search is then uses to check the satisfaction of the KL constraint under non-linear landscape of non-linear neural networks (note that conjugate-gradients assume linearity in local sense its formulation), so it might not satisfy the constraint after prediction, so we might need to reduce the magnitude of until satisfaction. This approach is what was proposed in the paper Trust-region policy optimization (TRPO).
However, as we have seen above the solving this constrained optimization problem using any of the popular three techniques is not easy. Recall the original goal, "how to know when you are too far from the original policy and stop using the sampled trajectories. This alludes to an interesting question which is "can we obtain a conservative update using the already computed IS ratio?"
So we want to move the improve the policy, but stop rewarding the change once it starts exploiting the fixed advantage loop. If , it alludes that we should increase but only upto a threshold, similarly if , it indicates we should decrease , but only upto a threshold. A natural solution to the problem is we clip the update to an acceptable interval , and therefore the objective becomes . However this creates a small problem, dead gradients in the wrong regions. So say for a state-action pair, the stored advantage is , but another minibatch update pushed , if we simply clip , then we won't be able to update the probability of this action-state pair which should be increased (since its ). Similarly, if for another action-state pair and a different minibatch has made , then clipping the IS ratio will not give any gradients to this action-state pair whose probability should be decreased, and therefore important corrective updates would not apply. The best of both worlds (clipped ratios while allowed corrective updates) can be reached if we take the smaller of the claimed improvement, i.e., change the objective . So now when and , , and also when and , (so gradients can still update the actor to change ).
Here are the six possible cases:
| Advantage | IS ratio | |
|---|---|---|
| Both terms are equal, unclipped objective provides gradient | ||
| is smaller, unclipped objective provides gradient | ||
| Upper clipped , no further incentive | ||
| ------ | ------ | ------------------------------------------- |
| Both terms are equal, unclipped objective provides gradient | ||
| Lower clipped , no further incentive | ||
| is smaller, unclipped objective provides gradient |
The min operation is particularly important in the second and sixth cases because it preserves corrective gradients that naive clipping would remove.
This approach is called proximal policy optimization (PPO), one of the most popular RL optimization algorithms. It is important to note that clipping does not guarantee the new policy to satisfy KL divergence constraint, and therefore in practice the KL divergence is monitored and the old batches can be switched out.
Overall here's PPO's algorithm:
The above clipping based approach prevents the current policy from drifting too much from the rollout generation policy, however, the individual small updates can move the model very far from its original behavior. This can be undesirable in certain cases like when the reward does not capture all aspects of the answer (it might capture verifier success, but not language quality, diversity, and factuality). This requires the updated policy to stay near the trusted language model across the entire training run (not just a single rollout update loop). The way this is usually achieved by adding a KL divergence from the original reference model as a penalty to the overall objective.
Note that the KL divergence problem is the same we had earlier at each step, however the solution deployed in this case is different, here its a fixed as a soft penalty coefficient. Why? The reason is that in the previous case, the KL constraint is a hard contraint, we do not want to use previous rollouts when using sufficiently different policy. In this case the constraint is softer, we can go away from the reference policy just not too much. The manner in which the KL constraint is operationalized is by computing the KL divergence on the output token distribution at each state and then averaged over all states. Another way to opertionalize is to directly subtract the KL divergence loss from the reward at each token position.
Reward-to-go provides a valid but high-variance policy-gradient signal. Subtracting state-dependent baseline reduces that variance. Using a learned critic to estimate this baseline is the usual way to go. However there are real disadvantages of using a critic:
These issues begets us to ask, is there an alternate way to estimate the expected return of a initial prompt? Turns out we use the simple way of multiple sampling and averaging its reward as the expected return (kinda obvious, that's what "expected" means). So for a prompt , we sample several completions from an LLM . And we get the rewards corresponding to each of them and the expected return can be estimated as the mean reward . This acts as the value function without the need of the critic. Then the advantage for a particular completion can be computed as . If was better than then the completion was better than the average or worse in the other case. Note that unlike the value function case that provides us with the estimate value for each token, this case assumes all tokens in the completion to have the same advantage, , this is because the group-level reward mean estimates the value of the original prompt , not of the intermediate tokens. Therefore this avoids the critic, but at the cost of eliminating the token-level credits. This approach was introduced in Group-relative Policy Optimization (GRPO) paper. Note that in the original proposed formulation the advantage was also divided by the standard deviation of the group rewards, .
For this approach to work, it is important that we only group completion of the same prompt and not completions of different prompts. This is because the value function can be underestimated or overestimated if we mix a prompt with other hard or easy prompts respectively.
So here's the modified objective function:
Note that the factor gives each completion equal weight, without, longer completions by the virtue of having more tokens will get more gradient. This is an implementation choice. There are 3 valid choices, (a) sequence level sum , (b) all-token mean , and (c) per-completion mean: .
Now lets compare the two very popular approaches for doing RL on LLMs, PPO and GRPO
| Component | PPO | GRPO |
|---|---|---|
| Baseline | Prompt-reward mean over a group | |
| Advantage granularity | per-token level | Completion level |
| Extra model | Critic model | Not required |
| # Rollouts | one rollout is sufficient | Multiple required to estimate the baseline |
| Dependence of rollouts | None | if all rollouts get same reward, we get no signal |
| Terminal rewards | Can propagate through critic/GAE | Same signal broadcast to all tokens |
| Baseline Noise | The noise in the critic | noise in the group rewards |
The two most popular application of RL in LLMs is RLHF and RLVR. RLHF stands for RL from human feedback and RLVR stands for RL from verified reward. RLHF works by training a preference reward model by providing humans with two responses to a prompt and asking them to choose the prefered one. And then optimizing the LLM to increase the reward from this preference model in order to tune its responses to human preferences. This was introduced in the InstructGPT paper Training Language Models to Follow Instructions with Human Feedback (InstructGPT) in 2022.
RLVR on the other hand uses verifiers, so for example a math problem which has one correct answer. There is usually no ambiguity in this reward, if the completion gets correct answer we give 1, otherwise 0. RLVR had led to the increased reasoning ability of LLMs where they can think for longer and can produce better answers.
Name is optional. Sign in to edit or delete your own comments.