Learn (Almost) Anything
КаталогСкачать курс

Авторесёрч: автономные ML-эксперименты

Как оценивать достоверность и качество выдачи агента в терминах репозитория. Главная метрика — val_bpb (validation bits per byte), чем ниже, тем лучше. Она не зависит от размера словаря, поэтому архитектурные изменения сравниваются честно. Разбираем, почему изменение принимают только если val_bpb улучшился (иначе откат), и как параллельно следят за peak_vram_mb, чтобы рост памяти не выходил из берегов. Это ваш инструмент критической оценки результата.

ruМини-курс6 уроков1 модуль9
автономные ML-экспериментыML-экспериментыавтономный цикл ML-экспериментовML-экспериментовавторесёрчавтономныеэкспериментыавтономныйциклэкспериментов

Метрика качества: 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.

Шкала типичных значений val_bpb: от ~0.7 (сильные модели) до ~1.0 и выше (слабые), чем ниже — тем лучше.

Логика принятия и отката

Каждый прогон агент заканчивает двумя строками в 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
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 снизился по сравнению с текущей лучшей точкой → изменение принимается, коммит остаётся в ветке.
  • 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 могут быть десятки строк. На что смотреть в первую очередь:

Пример файла results.tsv после ночного прогона: колонки run_id, val_bpb, peak_vram_mb и статус принято/отброшено.

1. Тренд val_bpb среди *принятых* изменений — снижается ли? Несколько принятых изменений подряд без прогресса — агент, скорее всего, исчерпал идеи в данном направлении. Стоит скорректировать program.md.

2. Доля отброшенных — 7–9 из 10 отброшенных это нормально; агент активно исследует пространство. Это не провал, это процесс поиска.

3. Рост peak_vram_mb — если память ползёт вверх от итерации к итерации, следующий прогон рискует упасть. Лучше заметить это заранее.

ИнтерактивПринять или откатить?
Проверьте понимание логики принятия изменений. Выберите, какой из трёх прогонов будет отброшен агентом.

Что это значит для оценки качества

Если вас интересует, «насколько хорошо работает авторесёрч», — val_bpb это и есть ваш инструмент. Не субъективная оценка, не впечатление от сгенерированного текста — конкретная цифра, которая либо снизилась (агент нашёл улучшение), либо нет.

Важная оговорка: val_bpb измеряет качество *языкового моделирования на датасете валидации* — насколько хорошо модель предсказывает текст. Это не то же самое, что качество генерации в диалоге или точность ответов на вопросы. Для задач из вашего брифа — анализ рынка, проверка источников, академические обзоры — эта метрика не применима напрямую. Но в рамках ML-экспериментов, которые ведёт autoresearch, она именно то, что нужно.

---

В следующем подмодуле — как запустить всё это под свою задачу, включая сценарий со слабым железом.

Самопроверка

  1. Почему нельзя напрямую сравнивать loss моделей с разными размерами BPE-словаря?
  2. Что хранит prepare.py в таблицах побайтовых длин?
  3. Когда изменение нужно принять согласно логике статьи?
  4. Зачем отслеживать peak_vram_mb, если это не влияет напрямую на решение об откате?
  5. Какое основное ограничение val_bpb как метрики качества?
  6. val_bpb улучшился, а peak_vram_mb заметно выросла. Как поступить согласно статье?
  7. Почему статья особо запрещает редактировать prepare.py?
  8. Высокая доля отброшенных изменений в 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.

Источники

  1. karpathy/autoresearch — GitHub