Метрика качества: val_bpb и сравнимость прогонов
Как оценивать достоверность и качество выдачи агента в терминах репозитория. Главная метрика — val_bpb (validation bits per byte), чем ниже, тем лучше. Она не зависит от размера словаря, поэтому архитектурные изменения сравниваются честно. Разбираем, почему изменение принимают только если val_bpb улучшился (иначе откат), и как параллельно следят за peak_vram_mb, чтобы рост памяти не выходил из берегов. Это ваш инструмент критической оценки результата.
Метрика качества: val_bpb и сравнимость прогонов
Цикл агента, разобранный в первом подмодуле, заканчивается одним вопросом: улучшился ли val_bpb? Разберём, что это за число, почему выбрали именно его, и как по нему читать качество каждого прогона.
Почему не обычный loss
После обучения нейросети стандартно смотрят на кросс-энтропийный loss — среднее число бит на предсказание одного токена. Проблема в том, что токен — неудобная единица для сравнений. BPE-словари разного размера кодируют текст по-разному: при большом словаре один токен в среднем покрывает больше символов, и модель получает меньший loss не потому что лучше понимает язык, а просто потому что на каждый шаг приходится больше информации.
Если агент попробовал другой размер словаря или иную схему токенизации — сравнивать два loss-значения напрямую нечестно. Нужна единица, которая не зависит от конкретного словаря.
val_bpb: одна мера на все эксперименты
Bits per byte нормирует информационную стоимость каждого токена на количество байт, которое тот кодирует. Концептуально:
> val_bpb = суммарный loss по всем токенам, взвешенный на длины токенов в байтах, делённый на общее число байт
Именно поэтому prepare.py при подготовке данных сохраняет *таблицы побайтовых длин* (byte-length tables): для каждого ID токена — сколько байт он занимает в оригинальном тексте. Без этих таблиц честный счёт невозможен, а агент мог бы «выиграть» у предыдущего прогона, просто взяв другой словарь. Это то самое читерство, которое prepare.py обязан не допускать — отсюда и запрет его редактировать.
Результат — число, сопоставимое поверх любых архитектурных изменений. val_bpb = 0.87 на одной конфигурации и val_bpb = 0.87 на другой (с другим числом слоёв, другим батчем, другим словарём) — одинаковое качество языкового моделирования.
Чем ниже — тем лучше: идеальная модель тратила бы ровно столько бит, сколько необходимо по теории информации. Реальные языковые модели дают значения в диапазоне примерно 0.7–1.0 bpb.
Логика принятия и отката
Каждый прогон агент заканчивает двумя строками в run.log:
val_bpb: 0.8731
peak_vram_mb: 14820Агент парсит их буквально: grep "^val_bpb:|^peak_vram_mb:" run.log. Никакой интерпретации — только два числа.
flowchart TD
A["Прогон завершён\n(5 мин. wall clock)"] --> B["grep run.log\nval_bpb + peak_vram_mb"]
B --> C{"val_bpb < предыдущего?"}
C -- "Да" --> D["✓ Принять изменение\nкоммит остаётся"]
C -- "Нет / равно" --> E["✗ git reset\nоткат кода"]
D --> F["Запись в results.tsv\nстатус: принято"]
E --> G["Запись в results.tsv\nстатус: отброшено"]
F --> H["Следующая итерация"]
G --> HДальше — простая ветка:
val_bpbснизился по сравнению с текущей лучшей точкой → изменение принимается, коммит остаётся в ветке.val_bpbне снизился (равен или хуже) →git resetк предыдущему состоянию, коммит выбрасывается.
В обоих случаях результат пишется в results.tsv — чтобы было видно, что пробовалось, даже если не сработало.
Никакого «почти улучшилось» или «в пределах погрешности». Равенство — это откат. Жёсткий, но честный критерий: нельзя незаметно дрейфовать к чуть худшим моделям.
peak_vram_mb: второй сторож
peak_vram_mb — пиковое потребление видеопамяти за прогон. Он не влияет напрямую на решение об откате, но выполняет другую роль. Агент может попробовать более широкую архитектуру или увеличить батч — val_bpb при этом улучшится, но если VRAM уже на пределе, следующий эксперимент упадёт с OOM (out of memory). program.md явно предписывает «держать VRAM в разумных пределах» — и это ответственность и агента, и человека, который просматривает results.tsv.
Практически: смотрите на оба числа вместе. Прирост val_bpb ценой резкого роста памяти — настороженный сигнал.
Как читать results.tsv
После ночного прогона в results.tsv могут быть десятки строк. На что смотреть в первую очередь:
1. Тренд val_bpb среди *принятых* изменений — снижается ли? Несколько принятых изменений подряд без прогресса — агент, скорее всего, исчерпал идеи в данном направлении. Стоит скорректировать program.md.
2. Доля отброшенных — 7–9 из 10 отброшенных это нормально; агент активно исследует пространство. Это не провал, это процесс поиска.
3. Рост peak_vram_mb — если память ползёт вверх от итерации к итерации, следующий прогон рискует упасть. Лучше заметить это заранее.
Что это значит для оценки качества
Если вас интересует, «насколько хорошо работает авторесёрч», — val_bpb это и есть ваш инструмент. Не субъективная оценка, не впечатление от сгенерированного текста — конкретная цифра, которая либо снизилась (агент нашёл улучшение), либо нет.
Важная оговорка: val_bpb измеряет качество *языкового моделирования на датасете валидации* — насколько хорошо модель предсказывает текст. Это не то же самое, что качество генерации в диалоге или точность ответов на вопросы. Для задач из вашего брифа — анализ рынка, проверка источников, академические обзоры — эта метрика не применима напрямую. Но в рамках ML-экспериментов, которые ведёт autoresearch, она именно то, что нужно.
---
В следующем подмодуле — как запустить всё это под свою задачу, включая сценарий со слабым железом.
Самопроверка
- Почему нельзя напрямую сравнивать loss моделей с разными размерами BPE-словаря?
- Что хранит prepare.py в таблицах побайтовых длин?
- Когда изменение нужно принять согласно логике статьи?
- Зачем отслеживать peak_vram_mb, если это не влияет напрямую на решение об откате?
- Какое основное ограничение val_bpb как метрики качества?
- val_bpb улучшился, а peak_vram_mb заметно выросла. Как поступить согласно статье?
- Почему статья особо запрещает редактировать prepare.py?
- Высокая доля отброшенных изменений в results.tsv указывает на что?
Домашние задания
Логика принятия: разбор одного решенияtext
Агент завершил прогон с результатом val_bpb: 0.8891 и peak_vram_mb: 12450. Предыдущая лучшая точка имела val_bpb: 0.8754. Распарси эти метрики и определи: будет ли это изменение принято или откачено? Объясни логику решения и скажи, на что нужно обратить внимание с точки зрения peak_vram_mb.
Верно идентифицирован исход (откат, потому что 0.8891 > 0.8754). Объяснение ссылается на критерий из статьи (число бит/байт должно снизиться, иначе откат). Верно описана роль peak_vram_mb: не влияет на решение об откате, но сигнализирует о риске для следующих прогонов.
Анализ ночного прогона: тренды и решенияdocument
Вот данные из results.tsv после ночного прогона (12 попыток улучшить модель). Прогон 1 — базовая точка с val_bpb: 0.8754: | прогон | val_bpb | peak_vram_mb | |--------|---------||--------------| | 1 | 0.8754 | 11200 | | 2 | 0.8712 | 11450 | | 3 | 0.8721 | 11400 | | 4 | 0.8695 | 11600 | | 5 | 0.8708 | 11550 | | 6 | 0.8692 | 12100 | | 7 | 0.8701 | 12050 | | 8 | 0.8698 | 12200 | | 9 | 0.8700 | 12180 | | 10 | 0.8720 | 13400 | | 11 | 0.8750 | 13350 | | 12 | 0.8765 | 13290 | Используя эти данные и логику из статьи, подготовь краткий отчет: - Какие прогоны были приняты, какие откачены? (Помни: принимается, только если val_bpb улучшился сравнительно с лучшей точкой.) - Какой был главный результат ночи (лучшая достигнутая val_bpb)? - Какой риск видишь в данных по памяти? - Какие рекомендации дал бы ты для program.md на следующий день?
Верно идентифицированы принятые прогоны (2, 4, 6) и их значения val_bpb. Названа лучшая точка (прогон 6, val_bpb: 0.8692). Замечено монотонное возрастание peak_vram_mb, определен риск упирания в потолок памяти. Рекомендация логична: либо изменить направление поиска (текущее исчерпано), либо понизить peak_vram_mb перед новыми попытками. Отчет структурирован и легко читается.
Проектирование следующего экспериментаtext
На основе анализа results.tsv из задания 2 пришла очередь планировать следующую ночь экспериментов. Изучив данные, ты замечаешь, что последовательные попытки в одном направлении перестали давать результаты, а память ползет в потолок. Напиши в стиле инструкции к program.md, какой эксперимент ты предложил бы агенту попробовать дальше. Укажи: 1. Точное изменение (например: уменьшить батч-размер с 64 на 48, попробовать другой оптимизатор, изменить расписание learning rate). 2. Гипотеза: почему это может сработать? Ссылайся на конкретные наблюдения из results.tsv. 3. Ограничение по памяти: какой максимальный peak_vram_mb ты установишь для этого эксперимента и почему?
Предложено изменение, отличающееся от перепроб того же направления. Гипотеза объясняет связь между наблюдением (рост памяти, упадок качества в последних прогонах) и предлагаемым решением. Установлено разумное ограничение по peak_vram_mb с обоснованием. Текст написан как инструкция для program.md.
Сдача и проверка заданий — в приложении Learn (Almost) Anything.
