Перейти к содержимому
Ступень 1111.4 Расти дальше

Воспроизводим статьи

Как дорасти от «понимаю статью» до «умею»: выбрать посильную работу, выписать паспорт постановки, собрать минимальную версию, честно сравнить свои числа с числами статьи и написать отчёт — на примере гроккинга (Power et al., 2022) и списка из восьми статей, посильных на 4×RTX 4080.

УРОКstage-11/11-4-growth/01-reproduce-papers.mdx2 ч 30 минУрок 1 из 5
После урока вы сможете
  • Оценить, посильна ли статья, по вычислениям (6·N·D), данным и коду, и выбрать масштаб под свою машину
  • Выписать паспорт постановки статьи и сверить его с кодом авторов, отделяя факты от догадок
  • Сравнить свои числа с числами статьи по нескольким seed и разобрать расхождения по чек-листу
  • Воспроизвести гроккинг на модульной арифметике и написать отчёт о воспроизведении

В уроке 9.2.2 вы научились читать статьи в три прохода. Третий проход Кешав описывает как «мысленно переизобрести статью». Для ML-статьи лучший третий проход — переизобрести её на самом деле: написать код, обучить, получить свои числа. Это и есть воспроизведение статьивоспроизведение статьиEN paper reproductionПовторить результат статьи своими руками: выписать постановку, собрать минимальную версию, сравнить свои числа с числами статьи с учётом разброса и объяснить расхождения в отчёте..

Почему это лучший способ дорасти от «понимаю» до «умею»:

  • Всплывают все детали, которых нет в тексте. Как разбили данные, чем инициализировали веса, на какие параметры действует weight decay, считали ли точность по всему набору. Пока вы читаете, эти вопросы не возникают. Когда код не сходится с рисунком статьи, вы находите ответы сами — и запоминаете их навсегда.
  • Это лучшее доказательство навыка. Отчёт «повторил рисунок 1 статьи X, вот код, вот мои кривые по трём seed, вот что не совпало и почему» говорит работодателю больше, чем сертификат. Как оформить такой проект в портфолио — в уроке 11.3.6.
  • Так работает наука. Обе истории из урока 9.2.2 — «aha moment» в R1-Zero и простой базлайн против DeepSeek-OCR — начались с проверки чужого результата своими руками. А Карпатый построил вокруг воспроизведения целую лекцию — «Let’s reproduce GPT-2 (124M)».

В этом уроке — метод из семи шагов, полный разбор статьи о гроккинге и список статей, которые реально повторить на вашей машине. Домашняя работа модуля — воспроизвести гроккинг самим.

flowchart TD
S1["1 · Выбрать статью<br/>вычисления, данные, код"] --> S2["2 · Прочитать в 3 прохода<br/>с прицелом на детали"]
S2 --> S3["3 · Паспорт постановки<br/>значение, источник, уверенность"]
S3 --> S4["4 · Минимальная версия<br/>самый маленький опыт с эффектом"]
S4 --> S5["5 · Сравнить числа<br/>несколько seed, интервал"]
S5 --> D{"Совпало?"}
D -->|"нет"| S6["6 · Расхождения<br/>одно изменение за раз"]
S6 --> S4
D -->|"да или понятно, почему нет"| S7["7 · Отчёт"]
Воспроизведение — цикл: шаги 4–6 повторяются, пока расхождение не станет понятным

Первая ошибка новичка — взять статью, которую невозможно повторить: модель на 70B, закрытые данные, тысячи GPU-часов. Проверьте четыре вещи до того, как потратите вечер на чтение.

КритерийЧто проверитьКрасный флаг
ВычисленияFLOPs по формуле 6⋅N⋅D6 \cdot N \cdot D и время на вашей машинебольше недели даже в уменьшенном масштабе
Данныеоткрыты ли, сколько весят, нужна ли разметка«внутренний датасет компании»
Кодесть ли код авторов, есть ли независимые воспроизведенияни кода, ни гиперпараметров в приложении
Проверяемый результатрисунок или число, которое можно сравнитьтолько «модель стала лучше» без таблиц

Оценку времени вы уже умеете делать с урока 5.1.1:

C≈6⋅N⋅D,t≈CnGPU⋅пик⋅MFU.C \approx 6 \cdot N \cdot D, \qquad t \approx \frac{C}{n_{GPU} \cdot \text{пик} \cdot \text{MFU}}.

Здесь NN — число параметров, DD — число токенов, которые модель увидит за обучение, MFUутилизация FLOPs модели (MFU)EN model FLOPs utilization (MFU)Доля пиковой производительности железа, которая уходит на полезные вычисления модели. Для больших распределённых обучений типичны 30–50 %. — доля пиковой скорости, которую реально удаётся получить. Два примера на крайних точках:

  • Гроккинг. В коде авторов модель на 422 тысячи параметров, 10510^5 шагов по 512 примеров, у каждого на входе около 6 токенов (<eos> a ∘ b = c): C=6⋅4.2⋅105⋅3.1⋅108≈7.7⋅1014C = 6 \cdot 4.2 \cdot 10^5 \cdot 3.1 \cdot 10^8 \approx 7.7 \cdot 10^{14} FLOPs. Даже при MFU 5% (крошечная модель почти всё время ждёт запуска ядер) это 7.7⋅1014/(48.7⋅1012⋅0.05)≈3207.7 \cdot 10^{14} / (48.7 \cdot 10^{12} \cdot 0.05) \approx 320 с на одной RTX 4080 в FP32. Минуты.
  • GPT-2 124M на 10 млрд токенов. C=6⋅1.24⋅108⋅1010=7.4⋅1018C = 6 \cdot 1.24 \cdot 10^8 \cdot 10^{10} = 7.4 \cdot 10^{18}. На четырёх картах в BF16 (пик 97.5 TFLOPS) при MFU 30% — 7.4⋅1018/(4⋅97.5⋅1012⋅0.3)≈63 6007.4 \cdot 10^{18} / (4 \cdot 97.5 \cdot 10^{12} \cdot 0.3) \approx 63\,600 с, почти 18 часов. Ночь и ещё день — тоже посильно, но уже проект, а не вечер.

Начинайте со статей «на минуты и часы». Первое воспроизведение учит методу, и лучше, если цикл «запустил → увидел расхождение → поправил» занимает минуты, а не сутки.

Шаг 2. Прочитать в три прохода — с прицелом на детали

Заголовок раздела «Шаг 2. Прочитать в три прохода — с прицелом на детали»

Читаете так же, как в уроке 9.2.2, но на втором и третьем проходе ищете то, что нужно для кода:

  • Приложение (Appendix). Гиперпараметры почти всегда там, а не в основном тексте.
  • Подписи к рисункам. «Mean over 3 seeds», «50% of data», «with weight decay 1» часто есть только в подписи.
  • Сноски и раздел про оценку. Какая именно метрика, на каком наборе, сколько прогонов.
  • Код авторов — часть статьи. Читайте его как ещё одно приложение: значения по умолчанию в argparse, скрипты запуска, конфиги. Но помните: значение по умолчанию в коде ≠ значение в опыте статьи. Скрипт запуска или конфиг могли его переопределить.

Всё найденное сведите в одну таблицу — воспроизводимостьвоспроизводимостьEN reproducibilityВозможность получить тот же результат, повторно запустив тот же код на тех же данных. начинается с неё. У каждой строки три поля: значение, где нашли (страница, рисунок, файл и строка кода) и уверенность: «в тексте статьи», «в коде авторов», «в чужом воспроизведении», «наша догадка». Пустая ячейка «где нашли» — это кандидат номер один в причины будущего расхождения.

Минимальный набор строк: задача и данные, разбиение train/val, архитектура и число параметров, инициализация, оптимизатор и все его параметры, расписание learning rate, размер батча и число шагов, регуляризация, метрика и протокол оценки, число seed, железо и время.

Не пытайтесь сразу повторить всё. Найдите самый маленький опыт, в котором эффект ещё виден: меньше модель, меньше данных, проще задача. Каждое упрощение запишите в паспорт отдельной колонкой «у меня» с причиной. Именно этот список отличий потом объяснит половину расхождений.

Порядок сборки — как в рецепте Карпатого из урока 10.1.1: проверить данные глазами, переобучить один крошечный батч до нулевого loss, сравнить с тривиальным базлайномбазовое решение, бейзлайнEN baselineПростейшая модель (среднее, самый частый класс), с которой сравнивают всё остальное. и только потом запускать полный прогон.

Сравнивать можно на трёх уровнях, и в отчёте надо честно сказать, какой достигнут:

УровеньЧто совпадаетКогда достаточно
Качественноеформа эффекта: кривая, знак, порядок величинновое явление, другая постановка, меньший масштаб
Количественноечисло статьи внутри интервала по вашим seed с допускомта же постановка, тот же масштаб
Точноедо битатолько тот же код, данные, версии библиотек и железо

Для количественного сравнения нужны несколько seed: 3 — минимум, 5 — лучше. Инструменты — из уроков 1.3.4 и 11.1.3: среднее, стандартная ошибка и 95%-интервал. При 3 seed множитель не 1.96, а квантиль распределения Стьюдента 4.30: по трём точкам разброс оценивается плохо, и интервал честно шире. Пример: точности 0.90,0.92,0.910.90, 0.92, 0.91 дают интервал 0.91±4.30⋅0.01/3=0.91±0.0250.91 \pm 4.30 \cdot 0.01/\sqrt3 = 0.91 \pm 0.025. Число статьи 0.93 внутри — совпало. Число 0.95 снаружи — не совпало, ищем причину. Это правило вы закодируете в задании ниже.

Расхождение — не провал, а самая полезная часть работы. Проверяйте подозреваемых в порядке «дёшево проверить, часто виноват»:

ПодозреваемыйТипичный пример
Данные и разбиениедругая доля train, утечка пар из train в val, другая предобработка
Скрытые гиперпараметрыweight decay применяется ко всем параметрам или только к матрицам; β₂ Adam 0.98 вместо 0.999
Детали реализацииинициализация, место LayerNorm, с какой позиции читается ответ
Протокол оценкиточность по батчу вместо всего набора, train-режим вместо eval
Разбросодин seed против среднего по трём
Бюджетвы остановились на 6 тысячах шагов, авторы шли до 100 тысяч
Численные эффектыTF32 и BF16 против FP32, недетерминированные ядра GPU

Метод — абляцияабляционный эксперимент, абляцияEN ablation studyУбрать или заменить один компонент и сравнить с полной моделью, чтобы измерить вклад этого компонента. наоборот: одно изменение за раз. Если есть код авторов, запустите его и двигайтесь от него к своему по одному отличию, пока числа не разойдутся. Это бинарный поиск по различиям, и он почти всегда находит виноватого за несколько прогонов.

Отчёт короче статьи, но строже: в нём нельзя смешивать то, что написано в статье, и то, что вы предполагаете. Шаблон из домашней работы: что воспроизводим (утверждение одной фразой и номер рисунка), паспорт «статья против меня» с причиной каждого отличия, таблица результатов по seed, что совпало, что нет, почему (гипотезы и как проверили), что делать дальше. Публикуйте его вместе с кодом: README в репозитории на GitHub, пост на Хабре или Чжиху.

Grokking: Generalization Beyond Overfitting on Small Algorithmic Datasets — Алетея Пауэр, Юрий Бурда, Харри Эдвардс, Игорь Бабушкин и Ведант Мисра из OpenAI. Впервые её показали на воркшопе MATH-AI конференции ICLR 2021, на arXiv она вышла в январе 2022 года (arXiv:2201.02177).

Задача. Таблицы бинарных операций a∘b=ca \circ b = c по модулю простого числа 97: сложение, вычитание, деление, многочлены вроде a2+b2a^2 + b^2, композиция перестановок. Это модульная арифметикамодульная арифметикаEN modular arithmeticАрифметика остатков: (a + b) mod p — остаток от деления суммы на p, как часы с p делениями. Таблицы таких операций — «маленькие алгоритмические датасеты» из статьи о гроккинге.: (a+b) mod p(a + b) \bmod p — остаток от деления суммы на pp, как стрелка на часах с pp делениями. Часть клеток таблицы дают модели, остальные — валидация. Ответ нельзя «подсмотреть»: чтобы заполнить пустые клетки, модель должна понять операцию.

Главное наблюдение — гроккинггроккингEN grokkingЗапоздалое обобщение: модель давно выучила train (точность ≈ 100%), на валидации долго держится на уровне угадывания, а потом точность на валидации резко растёт почти до 100%. Описан в статье Power et al. (2022) на модульной арифметике; weight decay сильно ускоряет переход. В китайских текстах часто пишут просто Grokking.. Маленький трансформер быстро запоминает обучающие клетки: точность на train около 100%, на валидации — угадывание. Классический совет — остановить обучение, ведь началось переобучениепереобучениеEN overfitting. Если же продолжать, то намного позже точность на валидации резко поднимается почти до 100%. Обобщение приходит далеко за точкой переобучения — отсюда название статьи.

Ещё два результата, ради которых стоит читать дальше: чем меньше доля данных в train, тем дольше приходится оптимизировать до обобщения, а среди вмешательств, которые пробовали авторы, weight decay заметнее всего ускорял обобщение (сверьте по рисунку с вмешательствами в оригинале).

Паспорт ниже собран по коду авторов openai/grok и открытым воспроизведениям; что нужно сверить с текстом статьи, так и помечено.

ЧтоЗначениеГде нашли
Задачаp=97p = 97; сложение, вычитание, деление, многочлены, перестановки S5S_5grok/data.py
Рисунок 1деление a/b mod 97a / b \bmod 97, половина таблицы в trainоткрытые воспроизведения teddykoker/grokking и danielmamay/grokking; сверьте по оригиналу
Модельтрансформер-декодер: 2 слоя, ширина 128, 4 головы; по нашему подсчёту 422K параметровgrok/training.py, значения по умолчанию
ОптимизаторAdamW, lr 10−310^{-3}, β=(0.9,0.98)\beta = (0.9, 0.98), линейный разогрев 10 шаговgrok/training.py
Weight decayв коде по умолчанию 0; в danielmamay/grokking и у Nanda et al. — 1сверьте по оригиналу, какой стоял в главных опытах
Батчmin(512, половина train)grok/data.py
Шаговдо 10510^5grok/training.py
Метрикаточность на всех клетках, не попавших в traingrok/training.py

Строка про weight decay — учебный пример ловушки из шага 2: значение по умолчанию в коде (0) почти наверняка не то, с которым получены главные кривые. Воспроизведения берут 1. Пока не сверено с текстом, в отчёте это «уверенность: чужое воспроизведение».

Цель — увидеть эффект на CPU за минуту. Поэтому пять сознательных отличий:

ОтличиеСтатья (код)У насЗачем
Операцияделение на рис. 1сложениегрокает быстрее
Модельтрансформер 422KMLP: эмбеддинги aa и bb → 128 → 97, 24K параметровшаг на CPU в десятки раз дешевле
Доля train50%30%задержка обобщения заметнее
Батч512весь train, 2822 парыдетерминированно и проще
lr и wd10−310^{-3} и (по воспроизведениям) 13⋅10−33 \cdot 10^{-3} и 2быстрее весь процесс

Почему именно weight decay так важен? В AdamWAdamWEN AdamW (Adam with decoupled weight decay)Adam, в котором затухание весов применяется отдельно от адаптивного шага. Оптимизатор по умолчанию для обучения LLM. он «развязан» с градиентом (урок 1.4.2): на каждом шаге веса умножаются на 1−ηλ1 - \eta\lambda. При η=3⋅10−3\eta = 3 \cdot 10^{-3} и λ=2\lambda = 2 это 0.994, и за 1000 шагов без градиента вес сжался бы в 0.9941000≈0.00250.994^{1000} \approx 0.0025 раза. Запоминающее решение требует больших весов, обобщающее обходится маленькими. Weight decayзатухание весов (weight decay)EN weight decayНа каждом шаге веса умножаются на (1 − ηλ) — «притягиваются» к нулю. Для обычного SGD равносильно L2-регуляризации, для Adam — нет. всё время давит в сторону маленьких — и в конце концов выдавливает модель из запоминания в обобщение.

Все прогоны — на одном ядре CPU, код из эталона домашней работы. Шаги измерены с точностью до шага записи журнала (25 или 50).

Настройкаseedtrain ≥ 0.99val ≥ 0.95во сколько раз позжевремя
MLP, доля 0.3, wd 2037517254.645 с
MLP, доля 0.3, wd 2142527006.451 с
MLP, доля 0.3, wd 2242518254.360 с
MLP, доля 0.3, wd 10200710035.5109 с
MLP, доля 0.3, wd 11200830041.584 с
трансформер, 1 слой, d=64d = 64, p=59p = 59, доля 0.5, wd 10100150015103 с (1800 шагов)

Как выглядит прогон с wd 1 и seed 0:

Шаг02001000200030005000600070008000
train accuracy0.011.001.001.001.001.001.001.001.00
val accuracy0.010.0010.0010.0050.0060.0430.220.921.00
val loss4.611.019.523.820.812.05.50.260.00

Три тысячи шагов модель знает train наизусть и ниже угадывания на val: 0.001 при случайных 1/97≈0.011/97 \approx 0.01. Val loss тем временем растёт с 4.6 до 23.8. Причина: чтобы train loss стремился к нулю, логиты становятся огромными, и на незнакомых парах модель уверенно называет неправильный ответ, а cross-entropyперекрёстная энтропияEN cross-entropy за уверенную ошибку растёт неограниченно. Затем weight decay берёт своё: val loss начинает падать задолго до скачка точности, и между шагами 6000 и 7000 val accuracy взлетает с 0.22 до 0.92.

Совпало качественно. Во всех шести прогонах train выучен за 100–425 шагов, обобщение приходит в 4–40 раз позже, а weight decay управляет задержкой: wd 2 даёт гроккинг на шагах 1725–2700, wd 1 — на 7100–8300, то есть в 3–4 раза позже.

Не совпало — и это полезно записать.

  1. Масштаб времени. У нас тысячи шагов, в статье бюджет до 10510^5. Постановки разные, поэтому номера шагов напрямую не сравниваем: это качественное воспроизведение.
  2. Трансформер сразу угадывает половину val. При доле 0.5 точность на val застывает на 0.48 задолго до гроккинга. Гипотеза: модель выучила коммутативность a+b=b+aa + b = b + a. Проверка заняла минуту: среди пар val, у которых зеркальная пара (b,a)(b, a) есть в train, модель права в 99.8% случаев, среди остальных — в 0.6%. MLP так не умеет: у него aa и bb входят в разные веса первого слоя.
  3. Разброс огромный. Одна и та же настройка с тремя seed даёт 1725, 2700 и 1825 шагов. В черновом скрипте в train попадал на один пример больше (округление вместо отбрасывания дробной части) — и шаг гроккинга для seed 0 сдвинулся с 1725 на 1850. Один прогон не доказывает ничего, сравнение настроек — только по нескольким seed.
  4. Кривые трансформера шумные. При lr 3⋅10−33 \cdot 10^{-3} train accuracy периодически проваливается до 0.3–0.5, у MLP кривые гладкие. Гипотеза — слишком большие шаги Adam при почти нулевом loss. В отчёте: «не проверено».

Почему так происходит. Нил Нанда и соавторы разобрали обученную модель по весам (методы урока 9.3.1): сеть складывает по модулю через тригонометрию — числа становятся углами на окружности, сложение — поворотом. Этот механизм строится ещё во время «плато», а weight decay вычищает запоминание. Группа Цзымина Лю (Omnigrok) смотрит на норму весов: запоминающее решение находится при большой норме, обобщающее — при меньшей, и weight decay медленно ведёт туда. Пошаговый разбор — в наборе 1.5.2 курса ARENA (путеводитель).

Все номера arXiv — из материалов нашего курса, рядом указан урок, где статья разобрана. Время — оценка по порядку величины по формуле из шага 1 и нашему опыту, а не замер; проверьте на своей машине на коротком прогоне.

СтатьяЧто воспроизвестиОценка времениУрок
ResNet, arXiv:1512.03385CIFAR-10: «обычные» сети на 20 и 56 слоёв (у 56 ошибка выше даже на train) и остаточные той же глубины≈ час на модель, 4 модели параллельно — вечер3.4.2
FlashAttention, arXiv:2205.14135время и память внимания (прямой + обратный проход) от длины последовательности: обычное против FlashAttentionвечер на одной карте5.7.2
Speculative Decoding, arXiv:2211.17192измерить долю принятия α\alpha для пары «маленькая + большая модель» и сравнить ускорение с формулой (1−αk+1)/(1−α)(1 - \alpha^{k+1})/(1 - \alpha)вечер на одной карте7.1.2
LoRA, arXiv:2106.09685одна задача GLUE с моделью уровня RoBERTa-base: полное дообучение против LoRA с рангами 1, 4, 8, 64 — проверить утверждение статьи, что маленького ранга хватает1–2 вечера, ранги на разных картах6.2.1
TinyStories, arXiv:2305.07759модели на единицы и десятки миллионов параметров пишут связные сказки; оценка — LLM-судья из урока 7.3.2часы на модель5.6.2
Chinchilla, arXiv:2203.15556мини-IsoFLOP: 3 бюджета (101610^{16}, 3⋅10163 \cdot 10^{16}, 101710^{17}) × 6 размеров модели, оптимальный размер для каждого бюджета≈ 8.4⋅10178.4 \cdot 10^{17} FLOPs: 2 ч при MFU 30%, реально — полдня5.1.1
DPO, arXiv:2305.18290опыт с управляемой тональностью на отзывах IMDb: награда классификатора против KL от референса для DPO (модель — сверьте по статье)день6.3.3
Understanding R1-Zero-Like Training (Dr. GRPO), arXiv:2503.20783смещение GRPO по длине: по статье, длина неверных ответов растёт у GRPO и не растёт у Dr. GRPO; повторить на маленькой базовой модели в verl1–2 дня на 4 картах6.4.3

Порядок — от простого к сложному. ResNet и FlashAttention повторяются почти наверняка, и на них удобно отточить метод. Последняя строка — сама по себе статья-проверка чужого результата: воспроизводя её, вы проверяете проверяющих.

Соберите два инструмента, которые пригодятся в каждом воспроизведении: оценку «посильно ли это» по 6⋅N⋅D6 \cdot N \cdot D и правилу 16 байт на параметр для AdamW (урок 5.4.1) и вердикт «совпало ли с статьёй» по интервалу из нескольких seed.

Бюджет воспроизведения и вердикт по seednumpy · нужен интернет6 тестов
"""Бюджет воспроизведения и вердикт «совпало ли с статьёй»."""
import numpy as np

# Квантили распределения Стьюдента t(0.975, df) для 95%-интервала по n = df + 1 seed. Готово.
T975 = {1: 12.706, 2: 4.303, 3: 3.182, 4: 2.776, 5: 2.571, 6: 2.447, 7: 2.365, 8: 2.306, 9: 2.262, 10: 2.228,
        11: 2.201, 12: 2.179, 13: 2.160, 14: 2.145, 15: 2.131, 16: 2.120, 17: 2.110, 18: 2.101, 19: 2.093, 20: 2.086}


def t_quantile(df):
    """Множитель для 95%-интервала при df степенях свободы (при df > 20 — почти нормальные 1.96). Готово."""
    return T975.get(df, 1.96)


def train_flops(n_params, n_tokens):
    """FLOPs обучения по правилу 6·N·D (урок 5.1.1): прямой проход 2·N·D, обратный 4·N·D."""
    # TODO
    ...


def gpu_hours(flops, peak_tflops, mfu, n_gpus=1):
    """Часы реального времени: FLOPs / (n_gpus · пик · MFU), пик в TFLOPS (10^12 FLOP/с)."""
    # TODO
    ...


def fits_on_gpu(n_params, gpu_mem_gb, bytes_per_param=16, reserve=0.2):
    """Влезет ли обучение с AdamW на одну карту: n_params · bytes_per_param (в ГБ = 10^9 байт)
    не больше доли (1 − reserve) памяти карты; reserve — запас на активации и фрагментацию."""
    # TODO
    ...


def seed_interval(values):
    """(среднее, нижняя граница, верхняя граница) 95%-интервала среднего по seed:
    mean ± t · SE, где SE = std(ddof=1) / √n, t = t_quantile(n − 1). Меньше двух значений — ValueError."""
    # TODO
    ...


def verdict(my_values, paper_value, rel_tol=0.0):
    """Сравнение с числом из статьи. Интервал seed_interval расширяем на rel_tol · |paper_value| в обе стороны.
    Число статьи внутри → "совпало"; иначе "выше статьи", если наше среднее больше, или "ниже статьи"."""
    # TODO
    ...


if __name__ == "__main__":
    # Гроккинг по коду авторов: 422K параметров, батч 512 примеров × ~6 токенов («<eos> a ∘ b = c»), 10^5 шагов
    c = train_flops(422_241, 512 * 6 * 100_000)
    print("гроккинг, FLOPs:", c)
    print(seed_interval([0.90, 0.92, 0.91]))
Проверь себя6 вопросов
1 Во время «плато» гроккинга train loss падает к нулю, а val loss растёт с 4.6 до 23.8. Почему?
2 В AdamW с η=10−3\eta = 10^{-3} и λ=1\lambda = 1 каждый шаг умножает веса на 1−ηλ1 - \eta\lambda. Во сколько раз сжался бы вес за 1000 шагов без градиента? Ответ — множитель, округлите до двух знаков.
3 Что из этого обязательно должно быть в паспорте постановки, прежде чем сравнивать свои числа со статьёй? Выберите все верные.Можно выбрать несколько ответов
4 Три seed дали точность 0.90, 0.92 и 0.91, в статье — 0.95. 95%-интервал по трём seed: 0.91±0.0250.91 \pm 0.025. Что пишем в отчёте?
5 Трансформер на сложении по модулю 59 при доле train 0.5 почти сразу угадывает 48% val, задолго до гроккинга. Что объясняет это лучше всего?
6 Вы впервые воспроизводите статью. Какую выбрать?
  • Воспроизведение — это третий проход чтения, доведённый до кода: выбрать посильное, выписать паспорт, собрать минимальную версию, сравнить по нескольким seed, разобрать расхождения, написать отчёт.
  • Посильность считается заранее: 6⋅N⋅D6 \cdot N \cdot D и t=C/(nGPU⋅пик⋅MFU)t = C / (n_{GPU} \cdot \text{пик} \cdot \text{MFU}). Гроккинг — минуты, GPT-2 124M — около суток на четырёх картах.
  • Код авторов — часть статьи, но значения по умолчанию в нём не обязательно те, что в опытах статьи.
  • Гроккинг воспроизводится качественно за минуту на CPU: train выучен к шагу ≈ 400, обобщение — к шагу ≈ 2000 при wd 2 и ≈ 7500 при wd 1. Разброс между seed в 1.6 раза — один прогон ничего не доказывает.
  • Расхождения — самая ценная часть отчёта, если у каждого есть гипотеза и проверка (или честное «не проверено»).

Дальше: «Вклад в open source» — следующий шаг после воспроизведения: найти в чужом репозитории баг или недостающую функцию и прислать исправление.