Можно ли научить маленькую LLM учиться без роста весов? Замеры, баги и честная статистика
Это статья о двух месяцах исследовательской работы над одним вопросом: может ли языковая модель 3B накапливать компетентность не за счёт роста весов. Здесь есть числа, код и баги. Все результаты воспроизводимы: сиды, хеши и протоколы заморожены до прогонов.
Доставка верифицированного решения похожей задачи в контекст 3B‑модели даёт +30 п.п. к решаемости (53% → 83%), повторено на 3 сидах
Обучение на верифицированных решениях (LoRA‑дистилляция, 1 цикл) даёт β = +0.145 (CI95 [+0.0575, +0.250]) — эффект есть, но это одна точка, а не кривая
Сейчас идёт эксперимент: 4 цикла переучивания × 2 траектории × 200 задач — первый замер формы кривой (рост / плато / затухание)
Попутно: почему нейросеть тормозит, когда видеопамять кончается, и как мы поймали NaN‑энтропию на 100% попыток
Постановка
Мейнстрим растит модели масштабом. Мы меряем ортогональное: можно ли растить компетентность маленькой модели без роста весов — через верифицированную память и локальное обучение, с жёстким потолком ресурсов (бытовая GPU 12 GB).
Ключевое различие, вокруг которого построены все эксперименты:
доставка знаний — решение похожей задачи кладётся в контекст, модель его потребляет;
интернализация — модель учится на решениях так, чтобы решать без доставки;
рост через повторение — несколько циклов обучения на одном корпусе (это и есть β(n)).
Это три разных явления, и они требуют трёх разных измерений.
Методология, которая спасала нас чаще, чем идеи
Каждый эксперимент фиксируется до запуска: критерии, сиды, пулы задач, файл замораживается хешем. После — независимый пересчёт из сырых логов кодом, который не писал автор эксперимента.
Это не бюрократия. Два примера, где это окупилось конкретно:
Баг «слепого к веткам резюме». Ключ возобновления прогона не включал имя экспериментальной группы (arm): рестарт прогона молча пропускал контрольные группы как «уже посчитанные». Мы потеряли бы контрольные данные целого эксперимента и узнали бы об этом через сутки GPU. Поймал CPU‑тест полного цикла на крошечной модели за 13 секунд.
NaN‑энтропия на 100% попыток. На игрушечной модели в тестах энтропия считалась идеально. На живой 3B в bf16 — NaN на каждой попытке: модель изредка выдаёт -inf логиты, exp(-inf) = 0, а 0 * (-inf) = NaN в сумме энтропии. Классика, но мы её поймали не глазами, а анализатором, который считает нечисловые значения громко.
Теперь эти проверки — постоянные: read‑only монитор перечитывает живой лог каждые 15 минут.
Методологическая дисциплина (то, что останется при любом исходе)
Верификация‑центричность. Надёжность ответа определяется свойствами верификатора, а не генеративной политикой. Первый полигон — синтетическое программирование: компиляция → тесты → интеграция → регресс. UNKNOWN — допустимое состояние.
Предрегистрация и заморозка. Критерии приёма, сиды, пулы задач фиксируются с хешами ДО прогона. Интерпретация — по замороженной таблице, а не post‑hoc. Реестр того, где прошлые выводы оказались НЕВЕРНЫМИ, ведётся и не переписывается задним числом.
Разделение трёх явлений. «Память помогла» ≠ «система научилась» ≠ «изменилось ядро». Каждый замер спроектирован так, чтобы различать хотя бы два из трёх.
Самоулучшение без права испортить. Обучение и память не имеют права портить подтверждённую компетентность: транзакция «подготовить → верифицировать → commit/rollback», состояние с хеш‑цепочкой и provenance.
Два бага, которые окупили всю дисциплину
1. Ключ возобновления, слепой к веткам. Ключ рестарта прогона не включал имя экспериментальной группы — рестарт молча пропускал контрольные группы как «посчитанные». Контрольные данные целого эксперимента были бы потеряны; поймал CPU‑тест полного цикла на крошечной модели (13 секунд) до расходования GPU‑часов.
2. NaN‑энтропия на 100% попыток. На игрушечной модели в тестах энтропия считалась идеально. На живой 3B в bf16 модель изредка выдаёт -inf логиты: exp(-inf) = 0, а 0 * (-inf) = NaN. Поймал не глазами, а анализатором, который считает нечисловые значения громко. Теперь read‑only монитор перечитывает живой лог каждые 15 минут.
Фрагмент скорера наклона (Тейл‑Сен — медиана попарных наклонов, устойчива к выбросу одного цикла):
def theil_sen(points):
pts = sorted(points)
slopes = [(y2 - y1) / (x2 - x1)
for i, (x1, y1) in enumerate(pts)
for (x2, y2) in pts[i+1:]]
slopes.sort()
m = len(slopes)
return slopes[m // 2] if m % 2 else (slopes[m//2 - 1] + slopes[m//2]) / 2
И транзакционная запись в память: подготовить → верифицировать → commit/rollback (отказ записи не портит состояние):
def submit_episode(self, episode, verifier):
vr = verifier(episode)
if not vr.ok: # невалидное не пишется
self._journal(rec | {"decision": "reject-unverified"})
return rec
entry = self.op.prepare_write(working, episode)
if not self.op.gate(working, episode, signal): # surprise-gate (слот)
return rec # gate-blocked: записано в журнал
self.snapshot = self._commit(entry) # новый хеш-снапшот
Замер 1: доставка знаний работает, и дистанция решает
Архитектура замера: 200 свежих задач одного семейства, никогда не виденных моделью. Для каждой — верифицированное решение соседней задачи: NEAR (высокое пересечение операций) и FAR (низкое). Модель решает задачу в 4 попытках, успех — прохождение полного набора тестов в песочнице.
Результаты (n=40, точный критерий Мак‑Немара, Holm‑коррекция):
Группа | Решаемость | Δ |
|---|---|---|
базовая | 50% | — |
+ NEAR‑референс | 80% | +30 п.п. (p=0.004, Holm 0.008) |
+ FAR‑референс | 45% | −5 п.п. (н.з.) |
+ собственный оракул | 100% | потолок |
Затем воспроизведение на 3 сидах: пул +18.3 п.п. (p=0.0003). Форма подтверждена на промежуточной дистанции (45% → 67.5% → 80%).
Вывод: перенос знания через контекст работает и критически зависит от дистанции. Это канал доставки — он дешевле и предсказуемее обучения.
Замер 2: обучение в весах — один цикл
LoRA‑дистилляция (r=8, 40 шагов) на 80 верифицированных решениях, затем экзамен без доставки:
экзамен: 52.75% → 57.25% (+4.5 п.п., McNemar p=0.011, Holm 0.023)
регрессия на старых задачах: −10 п.п. (улучшение, не деградация)
суммарно β = β_f − β_g = +0.145, CI95 [+0.0575, +0.250]
Это эффект одного цикла. Он ничего не говорит о росте: положительная точка не отличает рост от плато, и мы не CLAIM’им флайвил.
Замер 3 (идёт): форма кривой β(n)
Дизайн: 4 цикла переучивания на фиксированном корпусе × 2 траектории × 3 группы (копит веса / стартует с нуля каждый цикл / вообще не учится). Экзамен 200 задач, фиксированный, идентичный между циклами. Первичная метрика — наклон экзаменационной траектории (Тейл‑Сен) с бутстрап‑CI по траекториям.
Промежуточно (n ещё неполное, без выводов): траектория 0 — 53% → 59% → 55.5% → 54% → 57.5%; вторая траектория повторяет форму. Похоже на «скачок первого цикла → плато», но судит финальный CI, а не глаза.
Инфраструктура, которая осталась
независимый форензик‑чекер: 17 типов проверок целостности прогона (дубли, сиды, армы, чекпойнты, NaN), failure‑injection тестами доказано, что ловит все 15 классов порчи
пересчёт всех исторических результатов из сырых данных: 51/51 проверок сошлись
транзакционный слой памяти: запись → верификация → commit/rollback с provenance и хеш‑цепочкой (7 контрактов как исполняемые тесты)
Что не работает / что не знаем
Обучаемый интерфейс без доставки: +10 п.п., p=0.219 — не установлен
Доставка на другие семейства задач: не измерена (мощности не хватает, нужен дизайн)
Растут ли знания в весах при повторении — решает текущий прогон
Порог «настоящего роста» (n_min) — не изобретён, ждёт данных
Репозиторий и код
Протоколы, сырые данные и анализаторы открыты: экспериментальные раннеры, форензик‑чекер, пересчёт результатов, тесты (286 штук). Задаю вопросы в комментариях — особенно интересен опыт людей, которые меряли continual learning на малых моделях.
Вопросы к сообществу (то, ради чего постим)
Continual learning на малых моделях. Кто мерял форму кривой при многократном переучивании на фиксированном корпусе? Наш ранний паттерн — «скачок первого цикла → плато» — это у вас тоже было, или мы видим артефакт протокола?
Доставка vs интернализация. Есть ли у кого‑то строгий протокол разделения «память помогла» / «научилось» / «изменились веса»? Мы делаем это через контрольные группы (CARRY/RESET/BASE) — видим ли вы дыры?
Верификатор как единственный источник правды. Мы верифицируем только программные задачи (песочница + тесты + мутационный контроль). Как вы решаете задачу верификации для неверифицируемых доменов?
Отрицательные результаты. Как вы их публикуете и структурируете, чтобы их вообще читали? Наш реестр неверных выводов — половина ценности проекта, но честный ноль в статье всегда выглядит слабее, чем цифра.
Любая критика методологии — самый ценный комментарий, который мы можем получить.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.