Потеря KV-кэша в llama-server: как сохранить и восстановить сессию (2026) | AiManual
AiManual Logo Ai / Manual.
06 Июл 2026 Гайд

Как исправить потерю KV-кэша в llama-server: руководство по сохранению и восстановлению сессий

Подробный гайд по сохранению и восстановлению KV-кэша в llama-server. Решаем проблему потери контекста при длинных сессиях. Код, настройки, советы.

Вы запустили llama-server, крутите длинный диалог с AI-ассистентом, и вдруг - бац! Сервер упал, или вы решили обновить модель, а может, просто слот перегрузился. И вся ваша предыдущая беседа - коту под хвост. Модель снова переваривает гигабайты истории, а вы ждёте минуты, пока она "вспомнит", о чём речь. Знакомо? Это она, потеря KV-кэша. Сегодня разберемся, как заставить llama-server запоминать контекст между перезапусками и сохранять сессии без боли.

Почему ваш контекст сгорает каждый раз

KV-кэш (Key-Value cache) - это шпаргалка модели. Каждый раз, когда модель генерирует токен, она сохраняет промежуточные вычисления для всех предыдущих токенов. Без этого кэша пришлось бы пересчитывать весь промпт с нуля на каждый новый токен. В llama-server кэш живёт в оперативной памяти и умирает вместе с процессом. По умолчанию:

  • При перезапуске сервера кэш полностью сбрасывается.
  • При превышении --ctx-size старые токены вытесняются (скользящее окно).
  • При смене модели или изменении параметров квантования кэш становится невалидным.

Эту проблему усугубляет и повторная обработка больших промптов при использовании прокси-инструментов вроде llama-swap. Если вы не контролируете кэш, каждый новый запрос будет пережевывать всю историю заново.

Что нам даёт сохранение KV-кэша

Начиная с llama.cpp b2400 (актуальные билды июля 2026 уже давно это умеют), llama-server поддерживает флаги для дампа и загрузки KV-кэша в файл. Это значит, что вы можете:

  • Сохранить сессию перед выключением сервера.
  • Восстановить её при следующем старте без повторной обработки истории.
  • Перенести кэш на другую машину (если модель и квантование совпадают).
  • Замораживать состояние слота в многопользовательских сценариях.

Важно: кэш привязан к конкретной модели и её квантованию. Если вы обновите модель или смените тип квантования, старый кэш придётся выбросить. Подробнее о том, почему это критично, читайте в статье Почему coding agent 'глупеет' на длинном контексте.

Пошаговый план: от запуска до реставрации

1 Проверяем версию и флаги

Убедитесь, что ваша сборка llama-server поддерживает флаги --kv-cache-file и --slot-save-path. Запустите:

./llama-server --help 2>&1 | grep -i 'kv-cache'

Если вывод пустой - обновите llama.cpp до последней версии. Я рекомендую билды от llama.cpp b3020 или новее. Проверку на наличие критических уязвимостей тоже не забывайте - обязательно прочитайте Как проверить версию и не стать жертвой RCE-атаки.

2 Запускаем сервер с сохранением кэша

Укажите файл, куда будет сохраняться кэш при корректном завершении:

./llama-server -m /path/to/model.gguf \
    --ctx-size 8192 \
    --kv-cache-file /data/llama-cache/session.bin \
    --host 0.0.0.0 --port 8080

Теперь при получении сигнала SIGTERM (или SIGINT) сервер запишет текущий кэш в файл /data/llama-cache/session.bin.

3 Восстанавливаем сессию

При следующем запуске укажите тот же файл - кэш загрузится автоматически (если файл существует и валиден):

./llama-server -m /path/to/model.gguf \
    --ctx-size 8192 \
    --kv-cache-file /data/llama-cache/session.bin

Сервер найдёт файл, загрузит кэш и продолжит работу с того места, где остановился. Никакой повторной обработки промпта.

Важный нюанс: если размер файла кэша больше, чем --ctx-size, загрузка провалится. Всегда задавайте --ctx-size не меньше, чем при сохранении. Иначе получите ошибку и пустой кэш.

Сохранение слотов для многопользовательского режима

Если вы используете --parallel или --slots, вам пригодится флаг --slot-save-path. Он сохраняет и восстанавливает состояние каждого слота отдельно в указанную директорию:

./llama-server -m model.gguf \
    --parallel 4 \
    --slot-save-path /data/slots/ \
    --ctx-size 4096

В директории появятся файлы вида slot0.bin, slot1.bin. При следующем запуске они подгрузятся автоматически, и каждый пользователь продолжит свой диалог.

Автоматизация: systemd и корректное завершение

Чтобы кэш гарантированно сохранялся, нужно отправлять корректный сигнал. Если вы просто убьёте процесс kill -9, файл не запишется. Используйте в systemd unit:

[Service]
ExecStart=/opt/llama-server -m /models/model.gguf --kv-cache-file /cache/session.bin
KillSignal=SIGTERM
TimeoutStopSec=30

При systemctl stop сервер получит SIGTERM, запишет кэш и завершится. После запуска кэш восстановится.

Типичные ошибки и как их обойти

Даже с правильными флагами можно наступить на грабли. Вот что я видел в бою:

Ошибка Причина Решение
Файл кэша создаётся, но при загрузке сервер игнорирует его Модель не совпадает (даже хеш файла модели проверяется) Используйте одну и ту же модель и квантование. Если модель обновляли - удалите старый кэш.
При restore сервер падает с segmentation fault Размер кэша не соответствует выделенному контексту Задайте --ctx-size >= тому, что был при сохранении.
Кэш сохраняется, но модель забывает половину диалога Сработало скользящее окно (контекст переполнен) Увеличьте --ctx-size или используйте внешнее управление историей (например, суммаризацию).
💡
Если вы используете прокси-сервер вроде llama-swap, обязательно настройте --slot-save-path на уровне дочерних процессов. Иначе при переключении между моделями кэш будет сбрасываться - об этом подробнее в статье Prompt Caching в llama.cpp: почему не работает и как настроить.

Борьба с памятью: не дайте кэшу сожрать весь RAM

KV-кэш даже с файловым дампом остаётся в памяти. На больших контекстах (32K токенов) он может занимать десятки гигабайт. Плюс фрагментация кучи glibc может неожиданно удвоить потребление. Что делать:

  • Включите offloading KV-кэша на GPU (--no-kv-offload - отключает, по умолчанию кэш на GPU, если используется CUDA).
  • Используйте квантование кэша (--cache-type-k и --cache-type-v). q4_0 даёт 4-кратное сжатие с минимальной потерей качества.
  • Мониторьте /proc/meminfo и не забывайте про лимиты cgroups.

Кстати, есть целый список багов llama.cpp, которые незаметно ломают пайплайн. Некоторые из них связаны именно с некорректной работой кэша при переключении слотов.

Когда сохранение кэша не спасёт (и что делать вместо этого)

Бывают ситуации, когда файловый кэш бесполезен:

  • Сменилась архитектура модели. При апгрейде с LLaMA 2 на LLaMA 3 кэш придётся пересчитать.
  • Вы перешли на другую машину с другим GPU. Кэш может быть непереносим из-за разных CUDA-ядер.
  • Контекст слишком длинный. Файл кэша на 100K токенов весит ~10 ГБ - его долго загружать и сохранять.

В таких случаях советую использовать внешнее управление историей: пишите промпт в базу данных (SQLite, Redis) и при каждом новом запросе формируйте контекст заново, но уменьшайте его за счёт суммаризации или RAG. А для костылей с инвалидацией кэша в инструментах вроде Claude Code есть отдельное решение - как исправить инвалидацию KV-кэша в llama.cpp при использовании Claude Code.

Итог: три правила, которые нужно запомнить

  1. Всегда запускайте сервер с флагом --kv-cache-file - это единственный способ пережить перезагрузку.
  2. Корректно завершайте процесс через SIGTERM (kill -15), а не SIGKILL.
  3. Следите за размером кэша - он не может превышать --ctx-size и должен помещаться в файловую систему.

И если вы всё-таки столкнулись с внезапной утечкой памяти или падением сервера из-за кэша, не стесняйтесь заглянуть в исходники llama.cpp. Но перед этим проверьте, не попали ли вы под недавнюю уязвимость Bleeding Llama, которая может маскироваться под обычную потерю кэша. Успешных сохранений!

Подписаться на канал