Module 13. Reasoning in LLMs: computation, search, and information
Try each exercise first. Expand worked answers or project guidance when needed; their open state is shared between RU/EN.
Download course files (.zip) 33.9 KBThe archive preserves the folder structure of nine Python solution files shared by RU/EN.
Exercise 1. Why an internal chain adds no Shannon information
Let and , where .
-
Prove
-
Derive
-
Explain why a restricted model can nevertheless become more accurate.
-
Give an external observation for which
Show answer and solution
Let
1. Conditional mutual information
For fixed and ,
Therefore
and
2. Conditional entropy
By definition,
The left-hand side is zero, so
3. Why model accuracy can still improve
The equality concerns the complete input and the Bayes-optimal conditional entropy. A real model is computationally restricted. A scratchpad supplies sequential steps and memory, so the target function may become accessible to a restricted readout.
In parity, the answer is already determined by . A linear classifier on the raw bits cannot recover it, while a linear classifier on the state
reads the answer exactly from .
4. An external observation
Let ask for the current temperature in Tel Aviv and let be the actual temperature. A weather API response may satisfy
because the prompt itself contains no current measurement.
Other examples include a retrieval result, a hidden test, a sensor measurement, or an environmental observation following an agent action.
A calculator is a different case. If every operand and operation is already in , its output may add no information about a deterministic , while still supplying a reliable computation.
Exercise 2. Voting and correlated errors
For odd , derive
-
Show that for and independent attempts the probability tends to one.
-
What happens for ?
-
Construct a fully correlated error model and show that increasing provides no benefit.
-
Which sampling mechanisms might reduce trajectory correlation?
Show answer and solution
Let indicate whether trajectory is correct, with
Under independence,
is binomial. For odd , the majority is correct exactly when
Hence
1. The case
The law of large numbers gives
almost surely, and therefore
2. The case
Similarly,
Voting does not repair a systematically weak base trajectory; it amplifies its most common error.
3. Fully correlated errors
Let one latent variable
be copied by every attempt:
Then majority voting is identical to one attempt:
for every . The nominal sample count is large, but the effective number of independent observations is one.
4. Reducing correlation
Possible mechanisms include:
- different random seeds and temperatures;
- different prompt formulations and decompositions;
- forced branching over alternative assumptions;
- different models or checkpoints;
- different tools and evidence sources;
- penalties for reproducing an existing trajectory.
Lexical diversity is not the same as error diversity. Correlations in answers and failure modes should be measured directly.
Exercise 3. Best-of-(N) with an imperfect verifier
-
With an ideal verifier, prove
-
Construct an example in which incorrect candidates sometimes receive higher scores than correct ones.
-
Explain why increasing can lower selected accuracy while oracle pass@N rises.
-
Which two metrics should be reported to separate generator and verifier quality?
Show answer and solution
1. Ideal verifier
All independent candidates are wrong with probability
Therefore the probability that at least one candidate is correct is
An ideal verifier always selects it.
2. A weak scorer
Suppose correct candidates receive
while incorrect candidates usually receive
With a small probability , however, an incorrect candidate exploits the verifier and receives
For small , a correct candidate often has the largest score. For large , the probability of at least one extreme false maximum grows.
3. Why selected accuracy can decline
Oracle pass@N depends only on the generator and increases monotonically:
Selected accuracy depends on ranking. If incorrect-score tails are heavier or contain a rare exploit mode, larger creates more chances for a false maximum. A correct answer may be present almost surely while the verifier selects another candidate.
4. Metrics to report
At minimum, report:
- oracle pass@N: was a correct candidate present?
- selected pass@N: did the actual verifier choose it?
Their difference measures selection loss. Verifier calibration, distribution-shift robustness, and accuracy on deliberately constructed exploits are also useful.
Exercise 4. ICL as a Bayesian mixture
Let be a latent task. The demonstrations and the new pair are conditionally independent given , each with law .
-
Derive .
-
Derive the posterior predictive distribution for a new input. When may be replaced by ?
-
Show that
-
Explain why this is exact only for the stated generative model rather than a universal description of every LLM.
-
Compare the information roles of demonstrations and an internally generated chain .
Show answer and solution
Let latent task have prior , with demonstrations conditionally independent given :
1. Posterior
Bayes’ rule gives
For discrete , replace the integral with a sum.
2. Posterior predictive
The new pair is conditionally independent of given . First update the task distribution using the new input: . Then
If , no additional update is needed. Without that condition it matters: for empty , a fair bit , , and , we obtain . Averaging over the old would incorrectly give .
3. Nonnegativity of
Equality holds exactly when the demonstrations are independent of the latent task.
4. Scope of the model
The derivation is exact for the specified generative setting. It does not prove that a real LLM explicitly stores , that all model parameters have a Bayesian interpretation, or that the actual prompt came from the assumed task mixture.
5. Demonstrations versus an internal chain
Demonstrations arrive externally and may satisfy
They update the state of knowledge about the task. An internal chain built after observing the full context satisfies
under the private-randomness assumption. It can improve computation without adding a new external example.
Exercise 5. Faithfulness and monitorability
Design an experiment for a reasoning model.
-
Choose tasks with unambiguous, checkable answers.
-
Obtain an intermediate trajectory and a final answer.
-
Apply at least three interventions: remove a step, change a number, insert a false inference, or paraphrase the explanation.
-
Define separate metrics for causal sensitivity, answer robustness, and external monitoring quality.
-
Explain why an unchanged answer may indicate either robust reconstruction or disregard for the visible chain.
-
Propose a test of whether monitorability survives optimization against the monitor.
Show answer and solution
One possible protocol is as follows.
1. Task set
Choose tasks for which:
- the final answer is automatically checkable;
- intermediate quantities have unambiguous meanings;
- several solution methods exist;
- controlled false steps can be constructed.
Arithmetic, short programs with tests, logic puzzles, and formally checkable transformations are suitable.
2. Baseline observations
For each task, store:
- the original prompt;
- the visible trajectory;
- the final answer;
- probability or confidence, when available;
- independent verifier results.
3. Interventions
Apply several interventions:
-
delete a materially important step;
-
change an intermediate number;
-
insert a plausible but false inference;
-
swap two dependent steps;
-
paraphrase a step without changing its meaning.
The last intervention is a control: the system should be more sensitive to semantics than to surface form.
4. Separate metrics
Causal sensitivity:
or the change in log probability of the original answer under semantically important interventions.
Robustness: the fraction of cases that remain correct after semantically equivalent paraphrases or removal of redundant steps.
Monitorability: the accuracy of an external monitor tasked with detecting a known error, prohibited strategy, or use of a hint from the trajectory.
5. Why an unchanged answer is ambiguous
If the answer survives a step replacement, at least two explanations are possible:
- the system reconstructed the solution from other context;
- the visible chain did not participate in the causal computation.
Repeated interventions, masking the original context, error-localization tests, and independent tool signals help distinguish them.
6. Pressure against the monitor
Train or optimize the model in an environment where a monitor penalizes explicit mention of a prohibited strategy. Then measure separately:
- the actual rate of prohibited behavior;
- the ability of the original and a new monitor to detect it from the chain;
- changes in the language of the chain;
- transfer to new task types.
If behavior persists while detection falls, monitorability has degraded. This does not prove complete unfaithfulness, but it shows that optimization changed the trajectory’s diagnostic value.
Exercise 6. Python: computation, voting, and verification
Run M13_test_time_compute_experiments.py. It contains three experiments:
-
parity: a linear readout from versus a readout from a sequential working state;
-
voting under independent and correlated errors;
-
best-of- under a good and a weak verifier.
Explain:
- why the scratchpad makes the answer linearly accessible even though ;
- why correlation reduces the return from additional samples;
- why oracle pass@N can rise while selected accuracy falls.
Show answer and solution
The script uses a fixed seed and reproduces three regimes.
1. Parity
direct_linear_accuracy: 0.492500
scratchpad_linear_accuracy: 1.000000A linear classifier on the raw 12 bits remains near chance. The sequential state stores running parity, so its final bit determines the answer linearly.
This does not contradict
The scratchpad is a function of the input and makes the answer accessible to a restricted readout.
2. Voting
N= 1: independent=0.620000, correlated=0.620296
N= 3: independent=0.676544, correlated=0.646168
N= 5: independent=0.716509, correlated=0.665120
N= 9: independent=0.773776, correlated=0.690492
N= 15: independent=0.831285, correlated=0.715040
N= 25: independent=0.890677, correlated=0.742372
N= 51: independent=0.959769, correlated=0.772616Under independence, majority accuracy rapidly approaches one. In the correlated mixture, some tasks force every trajectory to copy one latent outcome, sharply reducing the return from additional samples.
3. Best-of-
N= 1: oracle=0.197786, strong=0.197786, weak=0.197786
N= 2: oracle=0.360929, strong=0.360043, weak=0.331514
N= 4: oracle=0.589200, strong=0.586186, weak=0.482800
N= 8: oracle=0.834543, strong=0.829214, weak=0.604886
N= 16: oracle=0.970971, strong=0.966643, weak=0.629143
N= 32: oracle=0.999329, strong=0.998271, weak=0.537686
N= 64: oracle=1.000000, strong=0.999800, weak=0.349900
N=128: oracle=1.000000, strong=0.999986, weak=0.143071Oracle pass@N rises monotonically and approaches one. A strong verifier nearly realizes generator coverage. A weak verifier improves at first and then increasingly selects rare false candidates with extreme scores.
The central distinction is
Code solution · the same source file for RU/EN
from __future__ import annotations
"""Reproducible experiments for Module 13.
The script demonstrates three separate mechanisms:
1. a sequential scratchpad can make parity linearly accessible without adding
Shannon information beyond the input;
2. correlated reasoning errors sharply reduce the gain from self-consistency;
3. oracle pass@N may rise while a weak verifier's selected accuracy eventually
declines because extreme false positives become more likely.
"""
from math import comb
from pathlib import Path
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
SEED = 13
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "generated_experiment"
OUT.mkdir(exist_ok=True)
def parity_experiment(rng: np.random.Generator) -> dict[str, float]:
n_bits = 12
n_train = 12_000
n_test = 6_000
x_train = rng.integers(0, 2, size=(n_train, n_bits), dtype=np.int8)
x_test = rng.integers(0, 2, size=(n_test, n_bits), dtype=np.int8)
y_train = np.bitwise_xor.reduce(x_train, axis=1)
y_test = np.bitwise_xor.reduce(x_test, axis=1)
direct = LogisticRegression(C=1.0, max_iter=2_000, random_state=SEED)
direct.fit(x_train, y_train)
direct_acc = accuracy_score(y_test, direct.predict(x_test))
# Sequential scratchpad state S_t = parity of the first t bits.
s_train = np.bitwise_xor.accumulate(x_train, axis=1)
s_test = np.bitwise_xor.accumulate(x_test, axis=1)
# A linear readout from the final one-bit state now solves the task.
scratch = LogisticRegression(C=1.0, max_iter=2_000, random_state=SEED)
scratch.fit(s_train[:, [-1]], y_train)
scratch_acc = accuracy_score(y_test, scratch.predict(s_test[:, [-1]]))
fig, ax = plt.subplots(figsize=(7.2, 4.6))
ax.bar(["Linear readout\non raw bits", "Linear readout\non final scratch state"],
[direct_acc, scratch_acc])
ax.axhline(0.5, linestyle="--", linewidth=1.2, label="chance")
ax.set_ylim(0.0, 1.05)
ax.set_ylabel("Test accuracy")
ax.set_title("Parity: sequential state changes accessibility, not input information")
ax.legend()
fig.tight_layout()
fig.savefig(OUT / "M13_parity_scratchpad.png", dpi=180, bbox_inches="tight", pad_inches=0.08)
plt.close(fig)
return {
"direct_linear_accuracy": float(direct_acc),
"scratchpad_linear_accuracy": float(scratch_acc),
}
def independent_majority_probability(n: int, p: float) -> float:
threshold = n // 2 + 1
return float(sum(comb(n, r) * p**r * (1.0 - p)**(n - r)
for r in range(threshold, n + 1)))
def self_consistency_experiment(
rng: np.random.Generator, p: float = 0.62,
) -> dict[str, list[float]]:
rho = 0.55
n_values = np.array([1, 3, 5, 9, 15, 25, 51], dtype=int)
n_tasks = 250_000
independent = np.array([independent_majority_probability(int(n), p)
for n in n_values])
# Correlated model: on a fraction rho of tasks, all trajectories share one
# latent Bernoulli outcome; otherwise trajectories are independent.
correlated_values: list[float] = []
for n in n_values:
shared_mask = rng.random(n_tasks) < rho
shared_outcome = rng.random(n_tasks) < p
independent_draws = rng.random((n_tasks, int(n))) < p
votes = independent_draws.sum(axis=1)
independent_majority = votes >= (int(n) // 2 + 1)
majority = np.where(shared_mask, shared_outcome, independent_majority)
correlated_values.append(float(majority.mean()))
correlated = np.array(correlated_values)
fig, ax = plt.subplots(figsize=(7.4, 4.8))
ax.plot(n_values, independent, marker="o", label="independent errors")
ax.plot(n_values, correlated, marker="s", label=f"correlated mixture (rho={rho:.2f})")
ax.axhline(p, linestyle="--", linewidth=1.1, label="single trajectory")
ax.set_xlabel("Number of trajectories N")
ax.set_ylabel("Majority-vote accuracy")
ax.set_ylim(0.0, 1.01)
ax.set_title("Self-consistency: correlation reduces effective sample count")
ax.legend()
fig.tight_layout()
fig.savefig(OUT / "M13_self_consistency.png", dpi=180, bbox_inches="tight", pad_inches=0.08)
plt.close(fig)
return {
"N": n_values.tolist(),
"independent": independent.tolist(),
"correlated": correlated.tolist(),
}
def best_of_n_experiment(rng: np.random.Generator) -> dict[str, list[float]]:
p_correct = 0.20
n_values = np.array([1, 2, 4, 8, 16, 32, 64, 128], dtype=int)
n_tasks = 70_000
oracle: list[float] = []
selected_good: list[float] = []
selected_weak: list[float] = []
for n in n_values:
correct = rng.random((n_tasks, int(n))) < p_correct
oracle.append(float(correct.any(axis=1).mean()))
# Strong verifier: well-separated, light-tailed score distributions.
score_good = np.where(
correct,
rng.normal(2.0, 0.45, size=correct.shape),
rng.normal(0.0, 0.55, size=correct.shape),
)
chosen_good = np.argmax(score_good, axis=1)
selected_good.append(float(correct[np.arange(n_tasks), chosen_good].mean()))
# Weak verifier: correct candidates are usually preferred, but a small
# fraction of incorrect candidates receive exploitatively high scores.
base_wrong = rng.normal(0.0, 0.75, size=correct.shape)
exploit = rng.random(correct.shape) < 0.018
exploit_score = rng.normal(3.8, 0.45, size=correct.shape)
wrong_score = np.where(exploit, exploit_score, base_wrong)
score_weak = np.where(
correct,
rng.normal(1.35, 0.55, size=correct.shape),
wrong_score,
)
chosen_weak = np.argmax(score_weak, axis=1)
selected_weak.append(float(correct[np.arange(n_tasks), chosen_weak].mean()))
oracle_arr = np.array(oracle)
good_arr = np.array(selected_good)
weak_arr = np.array(selected_weak)
fig, ax = plt.subplots(figsize=(7.6, 4.9))
ax.plot(n_values, oracle_arr, marker="o", label="oracle pass@N")
ax.plot(n_values, good_arr, marker="s", label="selected by strong verifier")
ax.plot(n_values, weak_arr, marker="^", label="selected by weak verifier")
ax.set_xscale("log", base=2)
ax.set_xticks(n_values, [str(x) for x in n_values])
ax.set_xlabel("Number of candidates N")
ax.set_ylabel("Accuracy")
ax.set_ylim(0.0, 1.02)
ax.set_title("Best-of-N: more candidates expose both solutions and verifier exploits")
ax.legend()
fig.tight_layout()
fig.savefig(OUT / "M13_best_of_n.png", dpi=180, bbox_inches="tight", pad_inches=0.08)
plt.close(fig)
return {
"N": n_values.tolist(),
"oracle_pass_at_n": oracle_arr.tolist(),
"selected_strong": good_arr.tolist(),
"selected_weak": weak_arr.tolist(),
}
def main() -> None:
rng = np.random.default_rng(SEED)
parity = parity_experiment(rng)
self_consistency = self_consistency_experiment(rng)
best_of_n = best_of_n_experiment(rng)
print("=== Parity and scratchpad ===")
for key, value in parity.items():
print(f"{key}: {value:.6f}")
print("\n=== Self-consistency ===")
for n, ind, corr in zip(self_consistency["N"],
self_consistency["independent"],
self_consistency["correlated"]):
print(f"N={n:3d}: independent={ind:.6f}, correlated={corr:.6f}")
print("\n=== Best-of-N ===")
for n, oracle, strong, weak in zip(best_of_n["N"],
best_of_n["oracle_pass_at_n"],
best_of_n["selected_strong"],
best_of_n["selected_weak"]):
print(f"N={n:3d}: oracle={oracle:.6f}, strong={strong:.6f}, weak={weak:.6f}")
if __name__ == "__main__":
main()
Bonus. When a cross-entropy difference equals CMI
-
For arbitrary and , prove
-
Derive the simplification for nested states.
-
Introduce predictors and and derive the decomposition through their variational gaps.
-
State conditions under which the cross-entropy difference equals CMI.
-
Explain why the predictive entropy of a single model does not establish those conditions.
Show answer and solution
1. Arbitrary states
By definition,
Subtracting gives
2. Nested states
If is a function of , then
and consequently
Thus
3. Variational predictors
For ,
Adding and subtracting the true conditional log probability gives
where
Therefore
4. Sufficient conditions for equality with CMI
It is sufficient that:
-
is recoverable from ;
-
, so both predictors are Bayes-optimal;
or, more generally, that the difference between the variational gaps is known and corrected.
5. Why predictive entropy is insufficient
The quantity
describes concentration of ’s own prediction. It does not establish:
- that ;
- that the states are nested;
- that no relevant information was lost;
- that the variational gap is controlled.
A decrease in predictive entropy therefore cannot automatically be interpreted as positive true information gain.