Что именно появилось в llama.cpp: PR #29887 и его суть
В репозитории llama.cpp появился pull request #29887 от am17an. Изменение добавляет GPU-кэш для MoE-экспертов, которые хранятся в оперативной памяти хоста. На публикацию об этом PR в сообществе LocalLLaMA обратил внимание пользователь /u/jacek2023 (тред с анонсом PR #29887).
Смысл предложения короткий: эксперты MoE-модели, которые не влезли в видеопамять и лежат в RAM, часть времени держать на GPU, чтобы не передавать их по PCIe при каждом обращении. Автор PR описывает изменение как потенциально большое ускорение для MoE-моделей, которые не полностью помещаются в VRAM. Анонс заканчивается приглашением делиться замерами, адресованным владельцам карт с небольшим объёмом памяти.
Дальше начинаются оговорки. Это pull request, а не выпущенная версия: код могут переработать, отклонить или принять спустя месяцы. В исходных материалах нет ни замеров скорости, ни списка поддерживаемых архитектур, ни требований к объёму VRAM и RAM. Всё, что написано ниже про механику MoE и про то, где кэш способен помочь, - объяснение общего принципа, а не обещание конкретных токенов в секунду.
Почему MoE-модели особенно чувствительны к нехватке VRAM
MoE (Mixture of Experts) устроена так: внутри слоя живёт не одна матрица, а набор экспертов, у каждого свои веса. Роутер на каждом слое выбирает нескольких из них под конкретный токен. В типичных конфигурациях это 1-8 экспертов из десятков или сотен, остальные в вычислении не участвуют.
Отсюда главный компромисс архитектуры. Общее число параметров может быть огромным, а активных на один токен - в разы меньше. Модель с десятками миллиардов параметров способна считать всего 2-4 млрд на токен, и именно поэтому MoE так популярны для локального запуска: железо нагружается слабее, чем подсказывает размер файла с весами.
Проблема в том, что хранить всё равно нужно всех экспертов. Если суммарный вес не помещается в VRAM, часть блоков остаётся в оперативной памяти хоста, и перед GPU встаёт задача доставать их оттуда по ходу генерации.
Как работает подкачка экспертов при нехватке VRAM
Картина такая: часть слоёв и экспертов лежит в видеопамяти, остальное - в RAM. Роутер выбрал эксперта, которого на GPU нет, значит его нужно передать по шине. PCIe 4.0 x16 по спецификации даёт около 32 ГБ/с в одну сторону, PCIe 5.0 x16 - примерно вдвое больше. Пропускная способность самой VRAM у потребительских карт измеряется сотнями гигабайт в секунду, у серверных ускорителей с HBM - единицами терабайт в секунду. Разрыв большой, и каждое обращение к отсутствующему эксперту упирается именно в него.
Ситуацию усложняет непредсказуемость. Плотную модель удобно оффлоадить слоями: слой либо на GPU, либо на CPU, и внутри одного прохода решение стабильно. У MoE в каждом слое свой роутер, и на каждом шаге он выбирает разных экспертов. Заранее сказать, какой блок понадобится через токен, нельзя, поэтому подкачка превращается в поток мелких передач, каждая из которых ждёт шину.
Аналогия простая. Плотная модель - это библиотекарь, который разнёс книги по полкам один раз за день. MoE при нехватке VRAM - библиотекарь, который бегает в подвал за каждой книгой, потому что читатели каждый раз спрашивают новые. Чем чаще спрашивают одно и то же, тем обиднее бегать.
Идея GPU-кэша для MoE-экспертов: как это должно работать
Предложение автора PR описывается без деталей кода: раз часть экспертов всё равно передаётся на GPU по ходу работы, почему бы не оставить их там. Кэш занимает свободную видеопамять, хранит экспертов, которые использовались недавно, и подчищает содержимое, когда место заканчивается. При обращении к эксперту, который в кэше есть, передача не нужна вообще.
По замыслу это снижает накладные расходы на подкачку у MoE-моделей, которые не полностью помещаются в VRAM. Ровно так формулирует сам автор изменения: потенциально большое ускорение для моделей, которые не влезают в видеопамять целиком (материал о PR #29887).
Чем GPU-кэш отличается от обычной подкачки
При обычной подкачке любое обращение к отсутствующему на GPU эксперту означает передачу по PCIe. Кэш меняет правило: часть обращений обслуживается локально. Эффект зависит от доли попаданий. Если она близка к нулю, вы получаете подкачку плюс накладные расходы на учёт кэша. Если высока, передачи почти исчезают, и скорость генерации подтягивается к уровню, который даёт полностью резидентная модель.
Механика ближе к кэшу процессора, чем к оффлоаду слоёв: работает не предсказуемость, а повторяемость обращений. В источнике нет ни размера кэша, ни политики вытеснения, ни того, как изменение ведёт себя с разными MoE-архитектурами. Эти детали стоит смотреть в самом PR и в отчётах тех, кто его соберёт.
Кому и в каких сценариях это может дать ускорение
Сценарий, на который рассчитано изменение, описан прямо: MoE-модель не помещается в VRAM целиком. На практике это выглядит так: карта на 8, 12 или 16 ГБ, модель с десятками миллиардов параметров, часть экспертов вынесена в оперативную память. Сейчас каждый промах по VRAM оплачивается передачей по PCIe, и именно эти промахи кэш должен частично убрать.
Шансы на заметный эффект выше, когда обращения к экспертам повторяются. Если на ваших промптах роутер снова и снова выбирает одни и те же несколько экспертов, кэш накопит их и большая часть обращений будет попадать в видеопамять. Насколько такой перекос есть в конкретной модели и на конкретных задачах, показывает только замер.
Ещё один фактор - куда упирается узкое место. Если генерация ограничена вычислениями или пропускной способностью VRAM, ускорение от кэша окажется скромным. Если ограничение в PCIe и в постоянных передачах, эффект может быть ощутимым. Общая логика та же, что и у других попыток ускорить MoE на слабом железе: подкачку активных экспертов во время генерации обсуждали в материале про Hot Expert Reload в llama.cpp.
Когда прироста может не быть
- Модель целиком помещается в VRAM. Подкачки нет, кэшировать нечего.
- Обращения к экспертам почти не повторяются: кэш не успевает накапливать полезное, доля попаданий остаётся низкой.
- Узкое место не PCIe, а вычисления, пропускная способность VRAM или CPU на этапе обработки промпта.
- Кэш мал относительно общего веса экспертов: в видеопамять влезает доли процента, и вытеснение случается раньше, чем эксперт пригодится снова.
- Архитектура модели и её роутинг пока не проверены автором PR, поэтому первые сборки способны оказаться медленнее привычного оффлоада.
Что важно помнить: статус pull request и необходимость проверки
PR #29887 - предложение, а не факт биографии llama.cpp. У пул-реквестов бывают разные судьбы: часть вливают через неделю, часть переписывают по замечаниям мейнтейнеров, часть отклоняют. На момент публикации этой заметки подтверждённых данных о релизе нет, а формулировка про большое ускорение - оценка автора изменения, а не результат независимого тестирования.
Отсюда простое правило: любые цифры ускорения из этого PR проверяются на своей конфигурации. Разница между «на моей карте стало быстрее в два раза» и «у меня не изменилось ничего» объясняется моделью, квантованием, набором экспертов в VRAM и характеристиками PCIe. Универсальных чисел тут не будет (публикация о PR #29887).
Как проверить эффект на своём железе: практические шаги
Если PR к моменту чтения уже доступен в ветке или в сборке, проверить его можно без лаборатории. План такой:
- Убедитесь, что у вас именно тот случай: MoE-модель, которая не помещается в VRAM целиком и часть весов держит в оперативной памяти.
- Соберите версию llama.cpp с PR #29887 или дождитесь сборки. Сравнивать нужно с той же версией без изменения, иначе разница в свежих коммитах смешает результат.
- Зафиксируйте параметры: одинаковые промпты, одинаковый контекст, одинаковая температура и число генерируемых токенов, одинаковое число слоёв на GPU (флаг
-ngl). - Замеряйте отдельно обработку промпта и генерацию:
llama-benchдаёт эту разбивку без ручного хронометража. - Прогоните тест минимум 3-5 раз и смотрите на разброс, а не на лучший результат. Первый прогон часто упирается в прогрев и загрузку весов.
- Наблюдайте за узкими местами: загрузка PCIe, объём занятой VRAM, частота обращений к RAM, загрузка CPU. Если шина простаивает, кэш ни при чём и ускорение искать надо в другом месте.
Если результат нужен уже сейчас, а не после вливания PR, стоит сравнить движки: поведение llama.cpp и vLLM с выгрузкой тензоров в системную память разбирали в сравнении для MoE-моделей. Отдельная ветка llama.cpp, где часть экспертов обрабатывается иначе, описана в материале про expert expansion для MoE: там же есть чек-лист замеров на разных бэкендах.
Итог: что это значит для пользователей llama.cpp
PR #29887 предлагает механизм, которого в llama.cpp не хватало: кэш MoE-экспертов на GPU для случаев, когда модель не влезает в видеопамять. Потенциально это снимает часть расходов на подкачку через PCIe, и именно на такой сценарий рассчитывает автор изменения.
Реальность пока скромнее. Это pull request без замеров и без гарантий вливания, а выигрыш напрямую зависит от доли попаданий в кэш, которую никто не публиковал. Если вы запускаете MoE-модели на карте с ограниченным объёмом памяти, за судьбой PR стоит следить: он в списке тех изменений, которые способны заметно поменять расклад на слабом железе. Планировать апгрейд под него рано.
Смежная ветка работ по ускорению MoE - обработка shared experts в MMVQ-вычислениях, ей посвящён отдельный разбор.