Что такое tiny-sparse-lab и какую задачу он решает
tiny-sparse-lab - небольшой открытый исследовательский стенд, который автор собрал для экспериментов с условной N-gram/Engram-памятью. Модели в нём настолько малы, что контролируемые прогоны идут на одной машине: датацентр и очередь на кластер не нужны, а значит можно быстро перебирать гипотезы и ловить эффекты, которые на большой модели утонут в шуме (пост автора в r/LocalLLaMA). Речь о масштабе примерно 10M-100M параметров. Этого мало для практичного чата, зато хватает, чтобы изолировать конкретный механизм памяти.
Идея Engram/N-gram-памяти в общем виде такая: часть знаний выносится в отдельную таблицу, к которой модель обращается по ключу (токену, n-грамме или семантической структуре). Таблица разрежена, на каждый запрос активируется небольшая доля записей, остальное лежит мёртвым грузом и не жжёт вычисления.
Стенд разводит две задачи, которые легко перепутать:
- переносимость обученной Engram-таблицы: можно ли отсоединить выученную таблицу от одной модели, заморозить её и привить модели другого размера через крошечную проекцию или гейт;
- компиляция структурированных знаний во внешнюю разреженную память: собрать память напрямую из Wikidata, WordNet, ответов API и формул, а нейросеть научить языку, маршрутизации, композиции и рассуждению.
Исходный вопрос автора звучал так: если модель выучила полезную информацию в Engram/PLE-таблице, получится ли отсоединить таблицу, заморозить, привить к модели другого размера через крошечную проекцию/гейт и восстановить информацию? Пока это вопрос, а не результат.
Как устроена внешняя разреженная память из структурированных фактов
Конвейер укладывается в четыре шага: structured facts → memory compiler → frozen sparse memory → small neural recipient. Автор не стал заставлять Model A выучивать значения Engram через LM-тренировку. Он собрал внешнюю память напрямую из структурированных фактов и обучил небольшие модели ей пользоваться (описание подхода в исходном посте).
Источники для компиляции: Wikidata, WordNet, вызовы API, формулы и другие структуры, где факт уже отделён от текста. У таких данных есть ключ и значение, поэтому их не нужно вылавливать из корпуса: memory compiler раскладывает готовые пары в разреженную таблицу, а модель обращается к ней по адресу.
Схема разводит роли. Нейросеть отвечает за язык, маршрутизацию, композицию и рассуждение. Знания живут в таблице, заморожены и в градиентных обновлениях не участвуют. Адресация бывает разной: token-addressed memory (ключ - токен), raw-byte-addressed memory (ключ - сырые байты) и structured semantic memory (ключ - семантическая структура).
От обычного RAG это отличается по двум пунктам. Память компилируется заранее, а не собирается из документов на каждый запрос. И она замораживается: при обучении реципиента обновляется только адаптер, а не сами записи. Обратная сторона в том, что пополнение знаний превращается в отдельную операцию над таблицей, а не в дообучение модели.
Автор отдельно оговаривает: он не предлагает сводить рассуждение к поиску. Напротив, подчёркивает обратное. Рассуждение остаётся работой нейросети, память лишь поставляет факты.
Отличие от обучения знаний через LM-тренировку
Два подхода отвечают на один вопрос по-разному. В первом знания зашиты в веса: чтобы добавить или поправить факт, нужен градиентный шаг, а значит датасет, вычисления и риск забыть старое. Во втором знания лежат отдельно, а модель учится ими пользоваться.
Практические следствия, на которые ссылается автор: обновление знаний без переобучения модели, хранение таблицы в RAM или на SSD с подгрузкой нужных частей, меньший объём весов, который обязан помещаться в GPU VRAM. Ни одно из этих следствий экспериментом пока не подтверждено. Это гипотезы, а не измеренные преимущества.
Результаты экспериментов: синтетический пилот и 120 smoke-тестов
Первый результат получился случайно. Автор шёл к тому, чтобы модель выучила Engram-значения через обычную тренировку, а вместо этого построил внешнюю память напрямую из структурированных фактов и обучил небольшие модели её потреблять. Синтетический пилот дал такой разброс точности:
| Состояние памяти | Точность |
|---|---|
| корректная | 1.000 |
| неполная | 0.5625 |
| случайная | 0.125 |
| отключённая | 0.125 |
| конфликтующая | 0.000 |
Читать таблицу стоит с оговоркой. Эксперимент крошечный и синтетический, и автор прямо не заявляет по его итогам общего результата. Разница между случайной и отключённой памятью нулевая, а конфликтующие записи обнуляют точность целиком: модель не выбирает между противоречащими фактами, а ломается.
Дальше запустили куда более крупный стенд переносимости: 120 контролируемых smoke-прогонов. В них вошли token-addressed, raw-byte-addressed и structured semantic memory, две ширины реципиента, сиды 17/41/73 и контроли disabled, random, corrupted, frozen, adapter, joint и native-memory (разбор прогона в исходном посте).
Что сработало: инфраструктура. Artifact identity checks, изоляция реципиента, adapter-only update auditing, подмена памяти, A→B→A replay и retrieval traces отработали как задумано. Это скучная часть, и она важнее, чем кажется: без неё любой положительный результат нельзя было бы отличить от утечки данных между моделями.
Что не сработало: поведение. Точность осталась нулевой по всем направлениям. Тесты были намеренно двухшаговыми smoke-тестами, то есть проверяли, что машинерия собирается, запускается и не течёт, а не то, что память переносится. Итог автор формулирует без прикрас: прогон подтвердил работу экспериментальной инфраструктуры, а не переносимость.
Что именно проверяли в smoke-тестах
Три типа памяти покрывали разные схемы адресации: токены, сырые байты и семантические структуры. Две ширины реципиента нужны, чтобы увидеть, зависит ли эффект от размера принимающей модели. Три сида (17, 41, 73) отсекают удачное совпадение инициализации.
Контроли закрывают основные способы обмануть себя. Disabled и random дают базовый уровень без полезной памяти. Corrupted проверяет, ломается ли поведение предсказуемым образом при порче таблицы. Frozen отделяет эффект заморозки. Adapter показывает, что даёт обучение одной проекции. Joint проверяет совместное обучение таблицы и адаптера. Native-memory отвечает на вопрос, справляется ли встроенная память реципиента лучше привнесённой.
Нулевая точность на двух шагах обновления ожидаема. Модель успевает прочитать адрес, но не успевает связать запись с задачей, где нужен перенос на новый пример. Содержательный сигнал дадут более длинные прогоны и задачи с отложенной проверкой.
Переносимость обученной Engram-таблицы: как её проверить
План выглядит так: обучить обычную N-gram-память совместно с Source Model A, экспортировать только обученную таблицу, заморозить Model B и саму таблицу, обучить только крошечный адаптер реципиента и проверить, выживают ли отложенные записи памяти при трансплантации.
Ключевое слово здесь «отложенные». Если записи, которых адаптер не касался, восстанавливаются, информация действительно переехала вместе с таблицей. Если работает только то, что попало в адаптер, переноса нет, есть обычное запоминание на новом месте.
Запланированные контроли:
- только адаптер реципиента, без полезной памяти;
- случайная память;
- перестановочная (permuted) обученная память;
- реальная обученная память;
- реальная обученная память в режиме zero-shot;
- реальная обученная память плюс адаптер;
- нативная память реципиента.
Набор закрывает три подмены. Случайная и перестановочная память проверяют, что важен контент, а не сам факт наличия таблицы. Zero-shot отделяет вклад адаптера от вклада записей. Нативная память задаёт верхнюю границу: если Model B со своей памятью обходит вариант с трансплантацией, подход проигрывает обычному обучению и теряет смысл.
Ограничения и открытые вопросы
Список ограничений короткий и жёсткий. Оба прогона синтетические. 120 smoke-тестов намеренно короткие, поэтому поведенческая точность нулевая. Прогон подтвердил работу инфраструктуры, а не переносимость памяти. Общего результата автор не заявляет.
Не проверено главное: масштабируется ли схема на реальные структурированные данные и на модели, где поведение вообще можно измерять. Неясно, как память поведёт себя при росте таблицы, при конфликтах между записями и на задачах, где нужны цепочки выводов, а не отдельные факты.
Отдельный незакрытый вопрос - сравнение с обучением знаний через LM-тренировку при сопоставимых вычислениях. Без такого сравнения нельзя утверждать, что компиляция знаний экономит ресурсы. Она меняет точку, в которой тратятся вычисления, и это не одно и то же.
RAM/SSD-тиры для статической памяти: аппаратный взгляд
Если знания лежат отдельно от весов, их размещение перестаёт диктоваться видеопамятью. Логика тиров: горячие записи держать в VRAM, основную таблицу в системной RAM, редкие части на NVMe SSD и подгружать по требованию. Для локальной сборки потолок тогда задаёт не один объём VRAM, а связка памяти и пропускной способности шины.
Схема перекликается с тем, что уже происходит в inference-движках для MoE-моделей: часть весов живёт в системной памяти и подгружается по ходу генерации. Как это выглядит на практике и где упирается в шину, разобрано в материале про ускорение MoE-инференса в llama.cpp на RTX 4080: прирост есть, но он упирается в пропускную способность и политику кэширования.
Разница в том, что статическая память не меняется во время инференса. Её можно скомпилировать один раз, хранить в сжатом виде и не пересчитывать. Второе следствие: обновление знаний становится операцией над таблицей, а не переобучением. Пока это концепция, а не измеренный результат.
Сравнение подходов: учить знания через LM-тренировку или подавать извне
| Критерий | Знания в весах (LM-тренировка) | Знания во внешней памяти |
|---|---|---|
| Добавление факта | Градиентный шаг, датасет, риск забыть старое | Запись в таблицу или перекомпиляция памяти |
| Вычисления на обучение | Растут вместе с объёмом знаний | Зависят от компилятора, а не от числа эпох |
| Память при инференсе | Объём весов в VRAM или с offload | Тиры VRAM / RAM / SSD с подгрузкой |
| Проверяемость | Низкая: факт растворён в миллионах параметров | Высокая: запись можно открыть, поправить, удалить |
| Рассуждение и композиция | Модель учит их вместе с фактами | Остаются на модели, факты приходят снаружи |
Аргумент автора: при сопоставимых вычислениях компиляция знаний во внешнюю память может оказаться эффективнее, потому что не тратит градиентные шаги на запоминание справочных данных. Убедительных экспериментальных данных в пользу этого пока нет ни у него, ни в разобранных материалах.
Практический выбор зависит от задачи. Статические справочные знания (идентификаторы, единицы измерения, химические формулы, связи между сущностями) удобно держать вовне. Динамические и контекстные вещи - стиль, формат рассуждения, поведение в диалоге - по-прежнему разумнее учить. В открытых моделях знания сегодня зашиты в веса, и даже там вокруг памяти идёт отдельная дискуссия: требования к RAM и VRAM при локальном запуске разобраны в материале про архитектуру Qwen3.8-Flash-Next и запуск локально.
Запрос к сообществу: prior work и недостающие контроли
Открытые вопросы, которые автор адресует сообществу:
- какие есть prior work по компиляции структурированных знаний в разреженную память, включая сходные идеи и известные провалы;
- какие контроли стоит добавить к плану переносимости, чтобы результат нельзя было объяснить утечкой или запоминанием адаптера;
- как корректно сравнить LM-тренировку и внешнюю подачу знаний при сопоставимых вычислениях;
- есть ли работы, где статическая память разнесена по RAM/SSD-тирам и подгружается по требованию.
Это открытое исследование, и обратная связь влияет на следующий прогон. Автор готов делиться кодом и данными, а найденные prior work и контроли могут изменить сам дизайн эксперимента. Если вы видели похожую работу или знаете, какой контроль закрывает дыру в плане, обсуждение стоит вести в исходном посте.
Для регулярного поиска таких работ пригодится Daily Papers на Hugging Face: он помогает отслеживать свежие публикации по памяти моделей и быстро проверять, не описан ли похожий подход раньше.