Параметр -cram в llama.cpp по умолчанию равен 8192. Он управляет размером кэша промпта, и этого значения хватает не всегда: когда контекст перерастает лимит, движок пересчитывает его заново на каждом ходу, и агент теряет скорость. Увеличение -cram убирает повторную обработку и возвращает производительность на длинных многоходовых сценариях (обсуждение параметра в сообществе LocalLLaMA).
Плата за это одна: параметр расходует оперативную память. Видеопамять не затрагивается, поэтому поднимать -cram имеет смысл и на системах, где VRAM уже занята под завязку.
Что такое -cram в llama.cpp и при чём тут кэш промпта
llama.cpp кэширует промпт: при повторном запросе совпадающая часть контекста берется из кэша, а не прогоняется через модель с нуля. Параметр -cram задает, сколько памяти отведено под этот кэш. Значение по умолчанию - 8192.
В агентных сценариях выигрыш от кэша особенно велик, потому что запросы идут потоком. Системный промпт, инструкции и накопленная история остаются между ходами почти неизменными, меняются только новые сообщения и вывод инструментов. Если кэш вмещает эту общую часть, токены не считаются повторно.
Как работает кэш промпта в llama.cpp
Во время обработки промпта токены проходят через слои модели, и формируется состояние, которое затем используется при генерации. Для нового запроса с тем же префиксом это состояние переиспользуется. Чем длиннее общий префикс, тем больше экономия.
Насколько сильно результат зависит от структуры промпта, хорошо видно на примере перестановки вопроса перед контекстом: медианная задержка локальной модели упала, а точность выросла (разбор кэширования префикса в Qwen). Логика та же: неизменная часть переиспользуется, и повторная работа сокращается.
Почему дефолтных 8192 может не хватать
8192 рассчитано на умеренные контексты. Когда промпт разрастается, места в кэше не хватает, и весь контекст приходится пересчитывать заново на каждом ходу. Точную длину, при которой это начинается, источник не называет: порог зависит от модели, объема системной части и того, сколько текста добавляет каждый шаг агента.
Как увеличение -cram ускоряет агентные сценарии
Агент за сеанс делает десятки ходов: планирует, вызывает инструменты, читает их вывод, правит план. Каждый ход - это отдельный запрос к модели, и каждый тянет за собой почти всю прежнюю историю.
Что происходит без увеличения -cram: пересчёт на каждом ходу
Если кэш меньше, чем нужно, неизменная часть контекста в него не помещается и обрабатывается снова и снова. Время уходит на предобработку промпта, а не на полезную генерацию. В цикле из десятков ходов это складывается в ощутимую задержку: вместо одного пересчета получаете десятки. Речь именно о скорости, качество ответов от размера кэша не страдает.
Что меняется после увеличения -cram
Больший кэш удерживает больше неизменного контекста, поэтому повторная обработка сокращается. Заметнее всего выигрыш на длинных многоходовых проектах. Одинакового прироста на всех задачах ждать не стоит: он зависит от модели, длины контекста и железа, а линейным не будет.
Отдельный слой проблемы - повторная оценка промптов в агентных пайплайнах, под которую выпускают специализированные форки, устраняющие это узкое место собственным механизмом (разбор CachyLLama с SSD-кэшированием KV). Параметр -cram решает похожую задачу штатными средствами llama.cpp, без смены сборки, но опирается на объем свободной RAM.
Как подобрать значение -cram: ориентир 20480 для Qwen 27B 3.8
За отправную точку можно взять значение 20480: с моделью Qwen 27B 3.8 при контексте 262K оно показало себя хорошо (личный ориентир из того же обсуждения). Это настройка для конкретной модели и длины контекста, а не универсальное правило.
Логика подбора простая: чем длиннее контекст и чем больше в нем неизменная часть, тем выше может быть полезное значение. Если у вас 200K+ контекста и многоходовой агент, значение в районе 20480 - разумная точка старта. Если контекст в разы меньше, столько памяти под кэш, скорее всего, не понадобится.
Почему 20480 это ориентир, а не правило
Для другой модели и другого контекста значение может оказаться и избыточным, и недостаточным. Плюс увеличение -cram расходует RAM, так что подбор всегда компромисс между скоростью и свободной памятью. Копировать 20480 вслепую на машину с 32 ГБ оперативки и моделью на 70B не стоит.
Как понять, что значение стоит увеличить или уменьшить
Смотрите на поведение в многоходовом запросе. Если на каждом ходу чувствуется повторная обработка и скорость падает по мере роста истории, кэша, вероятно, не хватает: значение можно поднять. Если RAM в дефиците и система упирается в память, значение снижают. Точных метрик для расчета в источнике нет, ориентируйтесь на собственные замеры времени на ход.
Компромиссы: больше RAM, но VRAM не растёт
Главный недостаток увеличения -cram простой: растет потребление оперативной памяти (описание компромисса в исходном сообщении).
Почему VRAM не растёт
Раз потребление VRAM не увеличивается, а RAM растет, кэш промпта живет в оперативной памяти хоста, а не в видеопамяти. Поэтому увеличение -cram не отнимает VRAM у модели и KV-кэша. Это делает параметр удобным для систем, где видеопамять уже на пределе. Контекст на ограниченной VRAM расширяют другими методами, например квантованием KV-кэша (форк NInfer с окном 350K токенов), и -cram с ними не конфликтует.
Когда RAM становится узким местом
Если свободной оперативной памяти мало, увеличение -cram приведет к нехватке и проблемам в работе. Источник описывает значения в мегабайтах, так что переход с 8192 на 20480 добавляет около 12 ГБ RAM. Линейного роста потребления памяти с каждым шагом -cram источник не подтверждает, поэтому перед подъемом значения стоит оценить запас. На машине с десятками свободных гигабайт лишний объем под кэш обычно некритичен, а на плотно забитой системе тот же шаг может стать последней каплей.
Как применить -cram на практике
Принцип простой: при запуске llama.cpp укажите -cram с нужным значением вместо дефолтного 8192. Точный синтаксис зависит от способа запуска - напрямую через llama-cli, через llama-server или через стороннюю обертку. Смысл один: значение попадает в конфигурацию запуска и определяет размер кэша промпта.
Дальше нужен свой агентный сценарий для проверки: например, задача из десяти-пятнадцати последовательных вызовов инструментов с длинной историей. Прогоните ее на дефолтном значении, затем на новом, и сравните время до финального ответа.
Что проверить после изменения -cram
Смотрите на две вещи: скорость обработки на каждом ходу в многоходовом сценарии и потребление оперативной памяти. Если время на ход упало и RAM хватает, значение подобрано удачно. Если появились ошибки с памятью или система начала уходить в swap, значение стоит уменьшить.
Для агентов, которые сами сжимают контекст, отдельно стоит учесть, что компактификация может сбрасывать кэш префилла. Плагин, сохраняющий кэш при сжатии контекста, показывает, насколько это влияет на время работы на локальной модели (разбор opencode-cache-compact).
Итог: кому и когда стоит увеличивать -cram
Увеличивайте -cram, если гоняете llama.cpp в агентных сценариях с длинным контекстом и многими ходами: кэш перестанет пересчитывать одно и то же, и время на ход заметно упадет. Если сценарии короткие или оперативной памяти в дефиците, выигрыш будет скромным, а риск уткнуться в нехватку RAM реальным.
Ориентир 20480 для Qwen 27B 3.8 при 262K берите как отправную точку, а не как обязательную настройку. Держите в голове баланс: VRAM от -cram не растет, а RAM растет. Подбирайте значение под свою модель, длину контекста и свободную память, проверяя результат на своем многоходовом сценарии.