Что такое Overspill и зачем он нужен
Overspill - экспериментальный дисковый тир для движка FreeToken. На машине с RTX 3060 12 ГБ, Ryzen 9 7900 и 64 ГБ DDR5-6000 автору удалось запустить DeepSeek-V4-Flash REAP-150B объёмом около 85 ГБ с FP4-экспертами и получить 2,8-3,4 токена в секунду на декодировании. Для сравнения: llama.cpp на той же машине выдал 0,4-0,5 tok/s, Colibri - 1,1-1,2 tok/s. Замеры опубликованы в отчёте на r/LocalLLaMA.
Проект распространяется под Apache-2.0, код открыт на GitHub. Статус - proof of concept: одна машина, одна крупная модель, WSL2 и один запрос за раз. Автор прямо просит не читать ~3 tok/s как универсальный показатель, потому что цифра выросла из конкретной конфигурации железа.
Ключевая идея: тиры памяти для MoE-экспертов
MoE-модель (mixture of experts) не прогоняет через каждый токен все свои параметры. Роутер выбирает несколько экспертов из слоя, остальные в этот момент простаивают. Отсюда возможность держать неактивные эксперты там, где дешевле: на NVMe.
Overspill раскладывает веса по трём тирам. VRAM - самая быстрая, но всего 12 ГБ. RAM - медленнее, 64 ГБ, в WSL2 доступно 48 ГБ. Диск NVMe - медленный, зато вмещает весь остаток модели. Эксперты, которые не влезли в оперативную память, остаются на диске в виде memory-mapped файла.
Page cache - это область RAM, куда ядро Linux кэширует содержимое файлов при чтении. Приложение не выделяет её явно, ОС сама решает, какие страницы держать в памяти. Overspill использует этот кэш как дополнительный тир: чем больше свободной RAM, тем больше экспертов оседает в ней после первого чтения, и тем реже идут обращения к NVMe.
Стриминг экспертов с SSD уже пробуют в других проектах. Slipstream, форк llama.cpp, запускает Qwen3.6-35B-A3B на MacBook с 36 ГБ RAM со скоростью 13 ток/с. Overspill решает похожую задачу для другого движка и опирается на page cache вместо явного управления буферами.
Чем Overspill отличается от llama.cpp и Colibri
llama.cpp - самый распространённый движок для локального запуска моделей в формате GGUF. На тестовой машине он показал 0,4-0,5 tok/s на декодировании. Colibri, подход к размещению экспертов между диском, RAM и VRAM, дал 1,1-1,2 tok/s и стал источником вдохновения для Overspill. Результат самого Overspill - 2,8-3,4 tok/s, то есть примерно в шесть раз быстрее llama.cpp на том же железе и примерно втрое быстрее Colibri.
Сравнение не бит-идентично. Эксперты во всех трёх прогонах одинаковые, а неэкспертные веса (attention и остальное, около 8 ГБ) llama.cpp хранит в Q8_0, тогда как FreeToken и Colibri используют оригинальный FP8 DeepSeek. Это влияет на качество ответов, но не меняет порядок скорости.
Тестовый стенд и модель: что именно запускали
Конфигурация автора: RTX 3060 12 ГБ, Ryzen 9 7900, 64 ГБ DDR5-6000 (в WSL2 доступно 48 ГБ), NVMe, доступный через WSL2, Windows 11 плюс WSL2 Ubuntu 24.04.
Модель - DeepSeek-V4-Flash REAP-150B из репозитория puwaer/DeepSeek-V4-Flash-0731-reap-150b, около 85 ГБ, эксперты хранятся в FP4 (4 бита на параметр). Объём примерно в семь раз превышает видеопамять карты, и весь расчёт держится на том, что модель разреженная: на каждом шаге нужна лишь часть экспертов.
Два обстоятельства усложняют задачу. WSL2 ограничивает доступную RAM до 48 ГБ из 64 ГБ, поэтому часть экспертов неизбежно уходит на диск. NVMe работает через WSL2, что добавляет накладные расходы на ввод-вывод. Это потребительское железо, а не сервер с сотнями гигабайт памяти.
Результаты: 2,8-3,4 tok/s против 0,4-0,5 у llama.cpp
Условия замеров одинаковые для всех трёх движков: холодный старт, жадное декодирование, одна и та же MoE-модель с FP4-экспертами, одна машина.
| Метрика | Overspill | llama.cpp | Colibri |
|---|---|---|---|
| Декодирование, tok/s | 2,8-3,4 | 0,4-0,5 | 1,1-1,2 |
| TTFT, промпт 6,4k | 102 с | 373 с | около 26 мин |
| TTFT, первый короткий промпт после холодного старта | 43 с | 44 с | 25 с |
| TTFT, следующий короткий промпт | 10 с | 40 с | 18 с |
На промпте 6,4k разрыв по времени до первого токена огромный: 102 секунды против 373 секунд у llama.cpp и примерно 26 минут у Colibri. На коротких промптах картина меняется. Первое обращение после холодного старта Overspill проигрывает Colibri (43 с против 25 с), а на повторном коротком промпте выходит вперёд с 10 секундами против 40 и 18.
Почему цифры могут отличаться на другом железе
Автор прямо говорит: скорость определяют CPU, память и накопитель в не меньшей степени, чем видеокарта. В дисковом пути Overspill математика экспертов считается на CPU, а не на GPU: используется CPU-исполнитель FreeToken, который на Zen 4 Ryzen 9 7900 шёл по пути AVX-512, а сами эксперты стримятся с диска через RAM.
Отсюда практические следствия. Меньше ядер, более медленная DDR5, более медленный SSD или меньше свободной RAM под page cache снизят скорость декодирования. Процессор без AVX-512, а это часть потребительских чипов Intel, переходит на более медленные пути кода.
Поэтому ~3 tok/s стоит читать как результат конкретной сборки, а не как норму для любой машины с 12 ГБ VRAM. Автор приглашает проверить масштабирование на другом железе, поскольку сам тестировал только одну конфигурацию.
Ключевые технические решения Overspill
Список изменений, которые дали ускорение:
- memory-mapping экспертов, не помещающихся в RAM, с использованием page cache как дополнительного тира;
- madvise(WILLNEED) для параллельного чтения экспертов каждого слоя крупными блоками вместо подкачки по одному page fault;
- удержание embedding/output-слоёв в RAM, чтобы освободить часть VRAM;
- более крупные чанки промпта, чтобы реже стримить экспертов;
- выполнение коротких промптов на CPU вместо прогона полного набора экспертов через GPU;
- исправление конвертера чекпоинтов FreeToken, который падал по памяти на моделях крупнее RAM.
Самый заметный эффект дал первый пункт: загрузка экспертов с диска ускорилась примерно в 4 раза.
mmap и page cache: как диск становится частью памяти
mmap отображает файл в адресное пространство процесса. Код обращается к эксперту как к обычному массиву в памяти, а ядро само подгружает нужные страницы с диска. Если эксперт не помещается в RAM, никто не обязан держать его там постоянно: страница живёт в page cache до момента, когда ядру понадобится память под что-то другое.
Практический смысл в том, что приложение не управляет памятью вручную и не падает с OOM, когда экспертов больше, чем RAM. Всё, что успело осесть в свободной памяти, работает как кэш, остальное остаётся на NVMe и читается по требованию.
madvise(WILLNEED): параллельное чтение экспертов
Обычная загрузка через page fault означает, что ядро узнаёт о необходимости страницы в момент обращения и читает её небольшим блоком. Overspill заранее сообщает ядру через madvise(WILLNEED), какие эксперты слоя будут использованы, и Linux читает их параллельно крупными блоками. Как сообщает автор, именно это дало примерно четырёхкратное ускорение загрузки экспертов с диска.
Ограничение простое: механизм опирается на Linux, в тестах это WSL2 Ubuntu 24.04. На других операционных системах такого поведения ждать не стоит.
Перенос embedding/output-слоёв в RAM
Embedding и output-слои занимают немного места, но на карте с 12 ГБ значение имеет каждый освобождённый мегабайт. Перенос этих слоёв в RAM освобождает VRAM под эксперты, которые должны считаться на GPU. Отдельного большого прироста эта мера не даёт, эффект набирается вместе с остальными правками.
Короткие промпты на CPU: экономия на стриминге экспертов
Прогон полного набора экспертов через GPU требует стриминга всех экспертов слоя, и на коротком промпте эти затраты не окупаются. Overspill выполняет короткие промпты на CPU, где эксперты уже могут лежать в RAM или page cache. Для длинных промптов задействуется GPU с крупными чанками: чем крупнее чанк, тем реже приходится стримить экспертов. Это компромисс между временем до первого токена и пропускной способностью.
Ограничения и неудачные эксперименты
Overspill - proof of concept: одна машина, одна крупная модель, WSL2 и один запрос за раз. Параллельные запросы не поддерживаются. Автор не считает себя экспертом и отмечает, что в проекте много «вайбкодинга».
Полноценной оценки качества не было. DeepSeek-модель прогнали через кодинг-тест и несколько задач многоходового tool-calling, но назвать это бенчмарком нельзя. Для проверки корректности использовалась Qwen3.6-35B-A3B, которая целиком помещается в RAM: её вывод совпал со стоковым FreeToken байт в байт на протестированных промптах. Значит, для моделей в пределах RAM Overspill ничего не ломает, а вот качество большой модели на дисковом тире никто системно не измерял.
Исправление конвертера чекпоинтов FreeToken сработало у автора, но он ждёт подтверждения от разработчиков движка: без этого нельзя быть уверенным, что подход корректен, а не просто работает на его стенде.
Почему prefetch RAM→GPU не сработал
Попытка заранее перебрасывать эксперты следующего слоя из RAM в GPU оказалась работоспособной, но на RTX 3060 замедлила работу на 9-29%. Автор предполагает, что передачи конкурируют с вычислениями GPU за ресурсы, и допускает, что причина может быть иной.
Вывод практический: оптимизации на границе RAM и VRAM легко дают регресс вместо ускорения. Похожие истории разбирают в материале про Hot Expert Reload в llama.cpp, где подкачка активных экспертов в VRAM во время генерации тоже зависит от конфигурации и не всегда оправдывает себя.
Стоит ли пробовать Overspill и как воспроизвести
Лицензия Apache-2.0, код открыт на GitHub, автор приглашает проверить масштабирование на другом железе. Готового бинарника нет, гарантий стабильности тоже.
Кому подойдёт Overspill
Проект имеет смысл пробовать, если есть опыт Linux, NVMe, желательно 64 ГБ RAM и CPU с AVX-512, а задача - запустить MoE-модель заметно крупнее VRAM и есть готовность измерять и подкручивать самостоятельно.
Для продакшена он не подходит: один запрос за раз, экспериментальный статус, отсутствие полноценной оценки качества. Пользователям Windows без WSL2, владельцам SATA-SSD и машин с 16 ГБ RAM ждать сопоставимых цифр не стоит.
С чего начать
- Проверить поддержку AVX-512 у процессора: на Zen 4 и новее она есть, у многих потребительских Intel-чипов нет.
- Оценить скорость NVMe и объём свободной RAM. Page cache работает только из свободной памяти, поэтому забитая под завязку система потеряет часть преимущества.
- Подготовить Linux или WSL2 Ubuntu 24.04.
- Клонировать репозиторий Overspill с GitHub и собрать движок по README.
- Скачать DeepSeek-V4-Flash REAP-150B из репозитория puwaer/DeepSeek-V4-Flash-0731-reap-150b.
- Начать с короткого промпта и замерить TTFT, затем прогнать промпт на 6,4k для оценки длинного prefill. Ориентиры автора: 10 и 102 секунды на его конфигурации.
- Сравнить с llama.cpp и Colibri на своей машине: шестикратный разрыв на чужом железе может не воспроизвестись.
Что это значит для локального запуска LLM
Overspill показывает, что диск может стать полноценным тиром памяти для MoE, если ОС умеет читать нужные страницы заранее и крупными блоками. Ключевое условие устойчивости результата - запас свободной RAM: чем больше памяти под page cache, тем реже обращения к NVMe и тем выше скорость.
Подход не отменяет общих закономерностей локального инференса. На серверном железе расклад другой: запуск DeepSeek-V4-Flash на одном B300 дал 770 токенов в секунду, и там ограничения лежат уже не в пропускной способности памяти, а в реализации ядер. Для потребительской машины с 12 ГБ VRAM дисковый тир - способ вообще дотянуться до модели такого класса, а не замена нормальному железу.
Остаются открытые вопросы: воспроизводимость на других конфигурациях, поведение при параллельных запросах и качество вывода большой модели. Кто хочет разобраться в том, как похожие приёмы работают в llama.cpp, найдёт разбор патчей и компромиссов в материале об оптимизации MoE-инференса в llama.cpp. Практический шаг для читателя простой: собрать Overspill на своей машине, замерить TTFT на коротком и длинном промпте и только по своим цифрам решать, стоит ли переносить эксперимент в рабочую практику.