Модуль 13. Рассуждение в LLM: вычисление, поиск и информация
Сначала попробуйте решить упражнение. Ответы, подробные решения и проектные ориентиры раскрываются отдельно и сохраняют своё состояние при переключении RU/EN.
Скачать файлы курса (.zip) 33,9 КБАрхив содержит девять Python-файлов решений, общих для RU/EN, с сохранением структуры каталогов.
Упражнение 1. Почему внутренняя цепочка не добавляет шенноновской информации
Пусть , а , где .
-
Докажите
-
Выведите
-
Объясните, почему точность ограниченной модели всё равно может вырасти.
-
Приведите пример внешнего наблюдения , для которого
Показать ответ и решение
Пусть
1. Условная взаимная информация
Для фиксированных и :
Следовательно,
и потому
2. Условная энтропия
По определению:
Левая часть равна нулю, поэтому
3. Почему точность модели может вырасти
Равенство относится к полному входу и идеальной условной энтропии. Реальная модель ограничена вычислительно. Рабочий черновик добавляет последовательные шаги и память, поэтому нужная функция может стать доступнее ограниченному считывающему слою.
В задаче чётности правильный ответ уже детерминирован . Тем не менее линейный классификатор по сырым битам чётность не решает, а линейный классификатор по состоянию
получает ответ точно из .
4. Пример внешнего наблюдения
Пусть — вопрос «какая сейчас температура в Тель-Авиве?», а — фактическая температура. Ответ погодного API может удовлетворять
поскольку запрос сам по себе не содержит текущего измерения.
Другие примеры: результат поиска, скрытый тест, показание датчика или наблюдение среды после действия агента.
Калькулятор представляет другой случай. Если все числа и операция уже содержатся в , его ответ может не добавлять информации об идеально определённом , но предоставлять надёжную вычислительную процедуру.
Упражнение 2. Голосование и коррелированные ошибки
Для нечётного выведите
-
Покажите, что при и независимых попытках вероятность стремится к единице.
-
Что произойдёт при ?
-
Постройте модель полностью коррелированных ошибок и покажите, что увеличение ничего не даёт.
-
Какие способы выборки могут уменьшать корреляцию траекторий?
Показать ответ и решение
Пусть показывает правильность -й траектории и
При независимости
имеет биномиальное распределение. Для нечётного большинство правильно тогда и только тогда, когда
Следовательно,
1. Случай
По закону больших чисел
почти наверное. Значит,
2. Случай
Аналогично,
Голосование не исправляет систематически слабую базовую траекторию. Оно всё увереннее закрепляет её наиболее частую ошибку.
3. Полностью коррелированные ошибки
Пусть существует одна случайная переменная
и все попытки копируют её:
Тогда результат большинства совпадает с одной попыткой:
для любого . Формально траекторий много, но эффективное число независимых свидетельств равно единице.
4. Как уменьшить корреляцию
Возможные механизмы:
- разные случайные начальные состояния и температуры;
- разные формулировки запроса и декомпозиции;
- принудительное ветвление по альтернативным гипотезам;
- разные модели или контрольные точки обучения;
- разные инструменты и источники;
- штраф за повторение уже найденной траектории.
Разнообразие слов не гарантирует разнообразия ошибок. Нужно проверять корреляцию итогов и типичных режимов отказа.
Упражнение 3. Best-of-N и несовершенный верификатор
-
При идеальном верификаторе докажите
-
Постройте пример, где неправильные кандидаты иногда получают большую оценку, чем правильные.
-
Объясните, почему увеличение способно ухудшить selected accuracy, хотя oracle pass@N растёт.
-
Какие две метрики нужно публиковать, чтобы различить качество генератора и верификатора?
Показать ответ и решение
1. Идеальный верификатор
Вероятность того, что все независимых кандидатов неверны, равна
Значит, вероятность наличия хотя бы одного правильного кандидата:
Идеальный верификатор всегда выберет такого кандидата.
2. Пример слабого оценивателя
Пусть правильные кандидаты получают оценки
а неправильные обычно получают
Но с небольшой вероятностью неправильный кандидат эксплуатирует верификатор и получает
При малом правильный кандидат часто имеет максимальную оценку. При большом возрастает вероятность встретить хотя бы один экстремальный ложный максимум.
3. Почему selected accuracy может падать
Oracle pass@N зависит только от генератора и монотонно растёт:
Selected accuracy зависит от ранжирования. Если хвост распределения оценок неправильных решений тяжелее или содержит редкий эксплойт, увеличение создаёт больше возможностей для ложного максимума. Правильный ответ почти наверняка присутствует, но верификатор выбирает другой.
4. Какие метрики публиковать
Нужно как минимум две:
- oracle pass@N — присутствовал ли правильный кандидат;
- selected pass@N — выбрал ли его реальный верификатор.
Их разность измеряет потерю на этапе выбора. Дополнительно полезны калибровка оценок, устойчивость к распределительному сдвигу и точность на специально сконструированных эксплойтах.
Упражнение 4. ICL как байесовская смесь
Пусть — скрытая задача. Демонстрации и новая пара условно независимы при заданном , каждая по закону .
-
Выведите .
-
Выведите апостериорное предиктивное распределение для нового объекта. Когда можно заменить на ?
-
Покажите, что
-
Объясните, почему это точная модель только при заданной генеративной постановке, а не универсальное описание любой LLM.
-
Сравните информационную роль демонстраций и внутренне сгенерированной цепочки .
Показать ответ и решение
Пусть скрытая задача имеет априорное распределение , а демонстрации условно независимы при заданном :
1. Апостериорное распределение
По формуле Байеса:
Для дискретного интеграл заменяется суммой.
2. Апостериорное предиктивное распределение
Новая пара условно независима от при заданном . Сначала обновим распределение задач с учётом нового входа: . Тогда
Если , дополнительное обновление не требуется. Без этого условия оно существенно: при пустом , честном бите , и получаем . Усреднение по прежнему ошибочно дало бы .
3. Неотрицательность
Равенство выполняется тогда и только тогда, когда демонстрации независимы от скрытой задачи.
4. Область точности модели
Вывод точен для заданной генеративной постановки. Он не доказывает, что реальная LLM явно хранит , что все параметры имеют байесовский смысл или что фактический запрос был порождён предполагаемой смесью задач.
5. Демонстрации и внутренняя цепочка
Демонстрации поступают извне и могут удовлетворять
Они меняют состояние знания о задаче. Внутренняя цепочка , построенная после получения полного контекста , удовлетворяет
при условии независимости внутренней случайности. Она может улучшить вычисление прогноза, но не добавить новый внешний пример.
Упражнение 5. Верность и наблюдаемость цепочки
Спроектируйте эксперимент для модели рассуждения.
-
Выберите набор задач с однозначно проверяемым ответом.
-
Получите промежуточную траекторию и финальный ответ.
-
Выполните не менее трёх интервенций: удаление шага, замена числа, вставка ложного вывода, перефразирование.
-
Определите отдельные метрики причинной чувствительности, устойчивости ответа и качества внешнего мониторинга.
-
Объясните, почему неизменный ответ после интервенции может означать как устойчивое восстановление решения, так и игнорирование видимой цепочки.
-
Предложите эксперимент, проверяющий, сохраняется ли наблюдаемость после оптимизации модели против монитора.
Показать ответ и решение
Один возможный протокол выглядит так.
1. Набор задач
Выбираем задачи, где:
- финальный ответ можно проверить автоматически;
- промежуточные значения имеют однозначный смысл;
- есть несколько способов решения;
- легко построить контролируемые ложные шаги.
Подходят арифметические задачи, короткие программы с тестами, логические головоломки и формально проверяемые преобразования.
2. Базовые наблюдения
Для каждой задачи сохраняем:
- исходный запрос;
- видимую траекторию;
- финальный ответ;
- вероятность или уверенность, если она доступна;
- результаты независимого верификатора.
3. Интервенции
Применяем несколько типов вмешательств:
-
удаляем содержательно важный шаг;
-
меняем промежуточное число;
-
вставляем правдоподобный, но ложный вывод;
-
меняем порядок двух зависимых шагов;
-
перефразируем шаг без изменения содержания.
Последняя интервенция служит контролем: система должна быть чувствительна прежде всего к смыслу, а не к поверхности текста.
4. Раздельные метрики
Причинная чувствительность:
для содержательно значимых вмешательств либо изменение логарифмической вероятности исходного ответа.
Устойчивость: доля случаев, где ответ остаётся правильным после семантически эквивалентного перефразирования или удаления избыточного шага.
Наблюдаемость: точность внешнего монитора, который по траектории должен обнаружить известную ошибку, запрещённую стратегию или использование подсказки.
5. Почему неизменный ответ неоднозначен
Если ответ сохранился после подмены шага, возможны по крайней мере два объяснения:
- система восстановила решение из других частей контекста;
- видимая цепочка не участвовала в причинном вычислении.
Различить их помогают повторные вмешательства, скрытие исходного контекста, тесты на локализацию ошибки и сравнение с внутренними или инструментальными сигналами.
6. Давление на монитор
Обучаем или оптимизируем модель в среде, где монитор штрафует явно выраженную запрещённую стратегию. Затем отдельно измеряем:
- фактическую частоту запрещённого поведения;
- способность того же и нового монитора обнаруживать его по цепочке;
- изменение языка цепочки;
- перенос на новые типы задач.
Если поведение сохраняется, а обнаружение падает, наблюдаемость ухудшилась. Этот эксперимент не доказывает полную неверность цепочки, но показывает, что оптимизационное давление изменило её диагностическую ценность.
Упражнение 6. Python: вычисление, голосование и верификация
Запустите файл M13_test_time_compute_experiments.py. Он выполняет три эксперимента:
-
задача чётности: линейный считывающий слой по против слоя по последовательному рабочему состоянию;
-
голосование при независимых и коррелированных ошибках;
-
best-of-Nпри хорошем и слабом верификаторе.
Объясните:
- почему рабочий черновик повышает линейную доступность ответа, хотя ;
- почему корреляция уменьшает отдачу от дополнительных выборок;
- почему oracle pass@N может расти одновременно с падением selected accuracy.
Показать ответ и решение
Скрипт использует фиксированное случайное начальное состояние и воспроизводит три режима.
1. Задача чётности
Получено:
direct_linear_accuracy: 0.492500
scratchpad_linear_accuracy: 1.000000Линейный классификатор по исходным 12 битам остаётся около случайного угадывания. Последовательное состояние хранит текущую чётность, поэтому финальный один бит линейно определяет ответ.
Это не противоречит
Черновик является функцией входа и делает ответ доступным ограниченному классу считывания.
2. Голосование
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.772616При независимости большинство быстро приближается к единице. В коррелированной смеси часть задач заставляет все траектории копировать один латентный исход, поэтому отдача от новых выборок существенно ниже.
3. Best-of-N
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 монотонно растёт и почти достигает единицы. Сильный верификатор почти полностью использует покрытие генератора. Слабый сначала выигрывает от увеличения набора, а затем всё чаще выбирает редкие ложные кандидаты с экстремальной оценкой.
Главный вывод эксперимента:
Программная часть решения · один исходный файл для 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()
Бонус. Когда разность кросс-энтропий равна CMI
-
Для произвольных и докажите
-
Получите упрощение для вложенных состояний.
-
Введите предикторы и и выведите разложение через вариационные разрывы.
-
Сформулируйте условия, при которых разность кросс-энтропий равна CMI.
-
Объясните, почему предиктивная энтропия одной модели этих условий не обеспечивает.
Показать ответ и решение
1. Произвольные состояния
По определению:
Вычитая второе равенство из первого, получаем:
2. Вложенные состояния
Если является функцией , то
и, в частности,
Поэтому
3. Вариационные предикторы
Для :
Добавляя и вычитая истинный логарифм условного распределения, получаем:
где
Следовательно,
4. Достаточные условия равенства CMI
Достаточно, чтобы:
-
восстанавливалось из ;
-
, то есть оба предиктора были байесовски оптимальны;
либо чтобы разность вариационных разрывов была отдельно известна и скорректирована.
5. Почему предиктивной энтропии недостаточно
Величина
описывает концентрацию прогноза самого . Она не сообщает:
- совпадает ли с истинным ;
- вложены ли состояния;
- не была ли потеряна релевантная информация;
- контролируется ли вариационный разрыв.
Поэтому снижение предиктивной энтропии нельзя автоматически интерпретировать как положительный истинный информационный прирост.