Module 1. Introduction: Reinforcement Learning for LLMs
Try each exercise first. Expand worked answers or project guidance when needed; their open state is shared between RU/EN.
Download course files (.zip) 382.1 KBThe archive preserves the source folder structure, both languages, and supporting files.
Agent, environment, state, action, and reward
Consider two episodes.
- In a corridor, an agent occupies a cell, chooses left or right, and receives for reaching the right terminal.
- A language model sees a prompt and the generated prefix, selects the next token, and a verifier scores the completed response.
Match each object to the concept.
| Object | Concept |
|---|---|
| A. A cell index or the pair “prompt + prefix” | 1. Policy |
| B. A rule for choosing a direction or a next-token distribution | 2. Environment |
| C. One concrete move or one concrete token | 3. State |
| D. Corridor dynamics, or external tools and generation constraints | 4. Reward |
| E. for a terminal, or the final response score | 5. Action |
Write the answer as A-?, B-?, C-?, D-?, E-?.
Show answer and solution
Answer: A-3, B-1, C-5, D-2, E-4.
- A state describes the current situation: a cell, or a prompt plus prefix.
- A policy specifies the choice rule: a direction rule or a token distribution.
- An action is one choice that was actually taken.
- The environment determines transitions and external consequences.
- A reward is scalar feedback after a transition or episode.
The key boundary is between a policy and an action: a distribution is not the same object as one sample from it.
A policy is not the selected action
Choose the single most accurate statement.
-
is the action already selected, while is the probability of that action.
-
is a distribution over actions, is one selection from it, and reward evaluates a consequence.
-
Policy and reward are two names for the same scalar function.
-
A stochastic policy must assign equal probability to every action.
Show answer and solution
Answer: 2.
denotes the full probability distribution over available actions. A concrete is selected from that distribution. Reward then evaluates a consequence; it is neither the action nor its probability.
Option 4 is false because stochastic does not mean uniform. A policy may assign probabilities and to two actions.
The exact sense in which an LLM is a policy
For the token-level abstraction, match notation to meaning.
| Notation | Meaning |
|---|---|
| A. | 1. Transformer weights |
| B. | 2. Prompt plus the generated prefix |
| C. | 3. The next selected token |
| D. | 4. The full next-token probability distribution |
Write the answer as A-?, B-?, C-?, D-?.
Then explain in one sentence why this exact correspondence does not imply that every pretrained LLM was trained with RL.
Show answer and solution
Answer: A-2, B-3, C-4, D-1.
In the token-level formulation,
This is an exact correspondence at the level of the mathematical action-selection model. It does not determine how the weights were obtained: next-token pretraining, supervised learning, and RL can all produce a model that defines a token distribution.
Reward and return
Choose two correct statements. Here, return is the accumulated discounted sum of future rewards.
-
Reward belongs to one transition, while aggregates future rewards from time onward.
-
Return is always equal to the final reward of an episode.
-
When , return includes only the immediate reward .
-
When , every finite episode has the same return.
Show answer and solution
Answers: 1 and 3.
Reward is local to one transition. Return
aggregates future rewards. When , only the immediate term remains.
Option 2 is true only in special tasks with a single nonzero terminal reward and . Option 4 is false: when , return is the ordinary sum of rewards, and different episodes can have different sums.
What creates the feedback loop in online RL
Choose the single most accurate statement.
-
RL does not use gradient descent.
-
RL never uses demonstrations or labeled data.
-
During online collection, the policy affects the distribution of the next experience, while reward usually does not reveal the outcomes of all actions that were not selected.
-
Every scalar loss is a reward, so every optimization problem is RL.
Show answer and solution
Answer: 3.
During online collection, the current policy participates in creating the next dataset. After an update, action frequencies, visited states, and observed outcomes change. Reward normally reports the result of the selected action or trajectory, not a full set of counterfactual outcomes for every alternative.
The other options are false: RL can use gradient descent and demonstrations, and scalar-valued loss alone does not create a decision-making problem.
Separate stages of an LLM pipeline
The four names below are:
- supervised fine-tuning (SFT), learning from demonstrations;
- direct preference optimization (DPO);
- reinforcement learning from human feedback (RLHF), implemented here with proximal policy optimization (PPO); below, PPO-RLHF;
- Best-of-N selection.
Match each operation to its description.
| Operation | Description |
|---|---|
| A. SFT | 1. Generate candidates, select the best one, and leave parameters unchanged |
| B. DPO on fixed pairs | 2. Score fresh rollouts with a reward model, then update the policy and critic |
| C. PPO-RLHF | 3. Maximize demonstration likelihood |
| D. Best-of-N | 4. Optimize a pairwise loss relative to a reference policy |
Write the answer as A-?, B-?, C-?, D-?.
Show answer and solution
Answer: A-3, B-4, C-2, D-1.
- Supervised fine-tuning (SFT) maximizes demonstration likelihood.
- Direct preference optimization (DPO) uses fixed pairs and a pairwise loss relative to a reference policy.
- Reinforcement learning from human feedback (RLHF), implemented here with proximal policy optimization (PPO), collects rollouts and updates the policy; a typical PPO-RLHF system also uses a reward model and critic.
- Best-of-N selects a candidate at inference time and does not by itself change parameters.
Choose the abstraction level
For each task, select the most natural primary model.
-
One prompt, one complete response, and one terminal reward-model score; the derivation does not inspect token-level credit assignment.
-
The derivation needs and token-level Kullback–Leibler divergence.
-
An agent calls a browser, the website state is only partly observed, and calls have different durations.
Options:
- contextual bandit;
- finite token-level Markov decision process (MDP);
- agentic partially observable Markov decision process (POMDP) or semi-Markov decision process (semi-MDP).
Show answer and solution
-
Contextual bandit. The complete response is collapsed into one action followed by one terminal reward.
-
Finite token-level Markov decision process (MDP). The state is the full prefix and the action is the next token.
-
Partially observable Markov decision process (POMDP) or semi-Markov decision process (semi-MDP). External state is hidden and macro-actions can have unequal duration.
No abstraction is permanently “the true one.” The appropriate choice depends on which mechanism must be explicit in a particular derivation.
Why DPO is not simply classical offline RL
Choose two correct statements.
-
DPO uses fixed preference pairs and is therefore offline in the ordinary engineering sense.
-
DPO necessarily trains a value function through Bellman backups.
-
A typical DPO problem does not contain transition tuples and extrapolation error in the same form as classical offline RL.
-
DPO is performed only at inference time and does not update parameters.
Show answer and solution
Answers: 1 and 3.
DPO uses fixed data, so offline is appropriate as an engineering description of data access. A typical DPO problem, however, is not built from transitions , does not perform Bellman backups, and does not reproduce the classical value-extrapolation problem in the same form as offline RL.
A concise accurate description is: DPO is direct offline preference optimization derived from a Kullback–Leibler-regularized human-feedback formulation.
What near/on-policy means for proximal policy optimization
Choose the single most accurate description of proximal policy optimization (PPO).
-
Every sample is used exactly once.
-
A policy snapshot generates a batch, which may then be reused for several minibatch epochs while a surrogate objective uses clipped probability ratios without a hard bound on the actual ratios; acceptable policy lag is part of the protocol.
-
Data may be arbitrarily stale because clipping completely removes off-policy bias.
-
On-policy means only that no replay buffer exists.
Show answer and solution
Answer: 2.
In PPO, a snapshot usually generates the rollouts. One batch may then be processed for several minibatch epochs. The ratio
enters a clipped surrogate objective. Clipping removes the incentive for some further ratio changes but does not enforce a hard bound on actual ratios or KL. This is a near/on-policy protocol, not a promise that every sample is used once. Clipping reduces the risk of an excessively large step, but it does not turn arbitrarily stale data into strictly on-policy data.
Verifiable rewards and group-relative optimization: regime versus algorithm
The two terms are:
- reinforcement learning with verifiable rewards (RLVR);
- group relative policy optimization (GRPO).
Choose the single correct statement.
-
RLVR is a particular clipping formula, while GRPO is a dataset type.
-
RLVR describes a regime in which reward can be checked automatically; GRPO is an algorithm family for updating the policy and may use that reward.
-
By definition, GRPO has no baseline.
-
Every RLVR experiment must use canonical GRPO.
Show answer and solution
Answer: 2.
Reinforcement learning with verifiable rewards (RLVR) describes the source of feedback: correctness can be checked by code, tests, an exact-answer rule, or another automatic procedure.
Group relative policy optimization (GRPO) describes a way to form relative advantages from a group of rollouts and update the policy. GRPO is often used in RLVR, but the terms are not identical: one reward regime allows multiple algorithms, and GRPO can consume other scalar feedback.
Find the component with no policy training
A system generates 32 responses from a frozen LLM, scores them with a rule-based verifier, and returns the best one. What operation is this?
-
PPO
-
GRPO
-
Best-of-N / inference-time selection
-
Offline RL
In one additional sentence, explain what must change for a training loop to appear.
Show answer and solution
Answer: 3 — Best-of-N / inference-time selection.
The model parameters are frozen, so the system performs candidate search and selection rather than policy training. A training loop appears when the scores or selected responses are used to change , for example through a supervised update, preference optimization, or a policy-gradient update on collected rollouts.
Two boundaries: temperature softmax and Kullback–Leibler divergence
Choose two correct statements.
-
For a fixed finite logit vector and pure softmax, entropy is non-decreasing in temperature .
-
This automatically proves entropy monotonicity for every combination of top-, top-, penalties, and hidden transformations in an application programming interface (API).
-
Kullback–Leibler divergence (KL) can limit drift from a reference policy, but it does not itself validate the reward model or proxy objective.
-
Small KL divergence guarantees high true reward.
Show answer and solution
Answers: 1 and 3.
For a pure temperature policy with fixed logits,
This statement does not automatically extend to a complete decoding pipeline with top-, top-, penalties, or hidden transformations.
Kullback–Leibler divergence (KL) measures distributional change relative to a reference policy. It can constrain drift, but it does not prove that the reward model measures the intended property or that a proxy objective matches the true objective.
Return
For rewards and , compute .
Show answer and solution
A backward-recursion check gives
Where the parameter enters the trajectory distribution
For a finite MDP,
Identify which factor depends on in a standard model-free formulation, explain why an update changes the distribution of subsequently collected trajectories, and state what is assumed about and .
Show answer and solution
In a standard model-free formulation, the factors that depend on are
The initial distribution , environment dynamics , and reward rule are treated as fixed with respect to the policy parameters. Updating changes action probabilities, which changes subsequent transitions, visited states, and therefore the entire distribution . If the environment or reward model is updated at the same time, its parameters must be written separately; that is a broader nonstationary system.
For an LLM, the same statement means that an updated model generates a different response distribution; in an agentic system, different actions can also lead to different external states.
Exact corridor baseline
For the symmetric corridor in the main text:
- start at ;
- terminal states are and ;
- the random policy chooses left or right with probability ;
- reward is only upon reaching ;
- the cutoff is 20 actions.
What is the exact value of ? Give a fraction or a decimal.
Show answer and solution
Over two steps from the center, four equally likely outcomes exist:
left, left— absorption at 0;right, right— absorption at 4;left, rightandright, left— return to 2.
The probability of surviving one two-step block is . Avoiding both terminals for 20 actions requires surviving ten blocks:
By symmetry, the probabilities of terminating on the left and right are equal. Hence
The value belongs to the version without a time limit. It is useful intuition but not the exact baseline for the executed protocol.
Probability of a complete response
Suppose a completed three-token response has conditional probabilities
-
Compute .
-
Compute the natural logarithm of the response probability.
-
Show that it equals the sum of the three token log-probabilities.
-
In one sentence, explain why one final reward creates a credit-assignment problem across these tokens.
Show answer and solution
The autoregressive probability of the complete response is the product of the conditional probabilities:
Its natural logarithm is
Separately,
Therefore,
One final reward evaluates the whole response but does not identify which of the three token choices was useful or harmful. That is the credit-assignment problem.
Discounted return
Implement:
def discounted_return(rewards: list[float], gamma: float) -> float:
"""Return G_0 for a non-empty finite reward sequence."""
...Requirements:
- ;
rewardsis a non-empty, finite, one-dimensional sequence;- use the backward recurrence ;
- invalid input must raise
ValueError.
Open checks:
assert abs(discounted_return([1, 0, 0, 10], 0.9) - 8.29) < 1e-12
assert discounted_return([1, 1, 1], 1.0) == 3.0
assert discounted_return([5, 100], 0.0) == 5.0Hidden checks include negative rewards, a one-element sequence, length 1000, nan, an empty list, and outside .
Show answer and solution
from __future__ import annotations
import math
import numpy as np
def discounted_return(rewards: list[float], gamma: float) -> float:
values = np.asarray(rewards, dtype=np.float64)
if values.ndim != 1 or values.size == 0:
raise ValueError("rewards must be a non-empty 1D sequence")
if not np.isfinite(values).all():
raise ValueError("rewards must be finite")
if not math.isfinite(gamma) or not 0.0 <= gamma <= 1.0:
raise ValueError("gamma must lie in [0, 1]")
result = 0.0
for reward in values[::-1]:
result = float(reward) + gamma * result
return float(result)The backward recurrence avoids explicitly computing powers and makes one pass: time and additional memory.
Numerically stable temperature softmax
Implement:
def softmax_with_temperature(
logits: np.ndarray,
temperature: float,
) -> np.ndarray:
...Requirements:
- input is a non-empty, finite, one-dimensional array;
temperatureis finite and strictly positive;- computation remains stable for logits around 1000;
- output is finite, non-negative, and sums to 1;
- adding one constant to every logit leaves the answer unchanged.
Open checks:
p = softmax_with_temperature(np.array([2.0, 1.0, 0.0]), 1.0)
assert np.isfinite(p).all()
assert abs(float(p.sum()) - 1.0) < 1e-14
q = softmax_with_temperature(np.array([1002.0, 1001.0, 1000.0]), 1.0)
assert np.allclose(p, q, atol=2e-14, rtol=0)Show answer and solution
import math
import numpy as np
def softmax_with_temperature(
logits: np.ndarray,
temperature: float,
) -> np.ndarray:
z = np.asarray(logits, dtype=np.float64)
if z.ndim != 1 or z.size == 0:
raise ValueError("logits must be a non-empty 1D array")
if not np.isfinite(z).all():
raise ValueError("logits must be finite")
if not math.isfinite(temperature) or temperature <= 0.0:
raise ValueError("temperature must be finite and positive")
scaled = z / temperature
scaled -= scaled.max()
weights = np.exp(scaled)
return weights / weights.sum()Subtracting the maximum uses softmax shift invariance and prevents overflow. The common multiplicative factor cancels between numerator and denominator, so probabilities are unchanged.
Policy entropy and the temperature curve
Implement:
def categorical_entropy(probabilities: np.ndarray) -> float:
...
def policy_entropy(logits: np.ndarray, temperature: float) -> float:
...Requirements:
- entropy is measured in nats;
- zero probabilities use the convention ;
- negative probabilities and sums different from 1 are rejected;
- for
logits=[2,1,0,-1], values from the main-text grid are reproduced within ; - on
np.geomspace(0.1, 10, 100), entropy is non-decreasing up to numerical tolerance .
Optional output: save temperature_entropy_student.png and state in the caption that monotonicity applies to pure softmax.
Open checks:
p = softmax_with_temperature(np.array([2.0, 1.0, 0.0]), 1.0)
assert abs(categorical_entropy(p) - 0.8323956) < 1e-6
assert abs(categorical_entropy([0.25, 0.25, 0.25, 0.25]) - np.log(4)) < 1e-12
assert abs(categorical_entropy([1.0, 0.0, 0.0])) < 1e-12Show answer and solution
import math
import numpy as np
def softmax_with_temperature(logits: np.ndarray, temperature: float) -> np.ndarray:
z = np.asarray(logits, dtype=np.float64)
if z.ndim != 1 or z.size == 0 or not np.isfinite(z).all():
raise ValueError("logits must be a non-empty finite 1D array")
if not math.isfinite(temperature) or temperature <= 0.0:
raise ValueError("temperature must be finite and positive")
scaled = z / temperature
shifted = scaled - np.max(scaled)
weights = np.exp(shifted)
return weights / weights.sum()
def categorical_entropy(probabilities: np.ndarray) -> float:
p = np.asarray(probabilities, dtype=np.float64)
if p.ndim != 1 or p.size == 0 or not np.isfinite(p).all():
raise ValueError("probabilities must be a non-empty finite 1D array")
if np.any(p < 0.0):
raise ValueError("probabilities must be non-negative")
if not math.isclose(float(p.sum()), 1.0, rel_tol=1e-10, abs_tol=1e-12):
raise ValueError("probabilities must sum to 1")
positive = p > 0.0
return float(-np.sum(p[positive] * np.log(p[positive])))
def policy_entropy(logits: np.ndarray, temperature: float) -> float:
return categorical_entropy(softmax_with_temperature(logits, temperature))To reproduce the table:
logits = np.array([2.0, 1.0, 0.0, -1.0])
for temperature in [0.25, 0.5, 1.0, 2.0, 4.0, 10.0]:
print(temperature, f"{policy_entropy(logits, temperature):.6f}")The output is 0.093113, 0.455429, 0.947537, 1.245050, 1.348243, 1.380071.
Monte Carlo evaluation of the corridor
Implement:
def run_corridor_episode(
rng: np.random.Generator,
*,
max_steps: int = 20,
) -> float:
...
def estimate_corridor_value(
n_episodes: int,
*,
seed: int = 7,
max_steps: int = 20,
) -> float:
...Protocol:
- states
0,1,2,3,4, starting at2; - action
0means left, action1means right; rng.integers(0, 2)selects the action;- terminal
0returns0.0, terminal4returns1.0; - timeout returns
0.0; - create exactly one
np.random.default_rng(seed)for the whole experiment.
Open checks:
assert abs(estimate_corridor_value(1000, seed=7, max_steps=20) - 0.494) < 1e-15
estimate = estimate_corridor_value(20_000, seed=23, max_steps=20)
assert abs(estimate - 0.49951171875) < 0.02Explain why comparison with 0.5 is useful intuition, while the exact baseline for this run is 1023/2048.
Show answer and solution
import numpy as np
def run_corridor_episode(
rng: np.random.Generator,
*,
max_steps: int = 20,
) -> float:
if not isinstance(max_steps, int) or isinstance(max_steps, bool) or max_steps <= 0:
raise ValueError("max_steps must be a positive integer")
state = 2
for _ in range(max_steps):
action = int(rng.integers(0, 2))
state += -1 if action == 0 else 1
if state == 0:
return 0.0
if state == 4:
return 1.0
return 0.0
def estimate_corridor_value(
n_episodes: int,
*,
seed: int = 7,
max_steps: int = 20,
) -> float:
if not isinstance(n_episodes, int) or isinstance(n_episodes, bool) or n_episodes <= 0:
raise ValueError("n_episodes must be a positive integer")
rng = np.random.default_rng(seed)
returns = [run_corridor_episode(rng, max_steps=max_steps) for _ in range(n_episodes)]
return float(np.mean(returns))Verified values:
N=1000, seed=7, max_steps=20 -> 0.494
N=20000, seed=23, max_steps=20 -> 0.4933
exact finite-horizon value -> 0.49951171875Without a step limit, corridor symmetry gives probability 0.5 for the right terminal. With a 20-step limit, some trajectories reach neither boundary and receive reward 0.0. To survive each pair of steps, the process must return from state 1 or 3 to state 2, which happens with probability 1/2. The probability of remaining nonterminal through ten such pairs is therefore . Symmetry splits the remaining probability equally between the left and right terminals, so the exact probability of the right terminal is
A random estimate need not match the exact value in every run. It should behave according to Bernoulli variance, with typical error decreasing approximately as .