# llama.cpp: сохранить кеш слота и проверить восстановление

Источник: https://modelium.tech/zhurnal/llama-cpp-slot-cache-save-restore/

Сервер llama.cpp может записать состояние слота в файл через `--slot-save-path` и вернуть его командой `restore`. Ответ с числом восстановленных токенов ещё не доказывает, что следующий запрос использовал кеш: проверьте поле `timings.cache_n` на том же тестовом префиксе. Файл может содержать данные запроса, а восстановление после перезапуска или обновления сборки не гарантировано.

Если вы повторяете длинное начало запроса к локальной модели, llama.cpp умеет сохранить состояние его обработки на диск. **Слот** — отдельное место, где сервер обрабатывает запрос; у него есть номер, который можно увидеть по адресу `/slots`. Это **не архив переписки и не способ убрать сведения из запроса**: файл кеша может содержать токены (небольшие части текста) и рабочее состояние модели. Сначала проверьте путь на выдуманных данных и только на изолированной машине. [s1](#src-s1) [s3](#src-s3)

**Инструкция сверена с исходниками от 8 октября 2026 года**, коммит llama.cpp `de7fa0a`; пример модели — Qwen3-0.6B-GGUF, ревизия `23749fe`. **Modelium не запускал сервер или модель**: описанное ниже — ожидаемый протокол проверки, не наши измерения. Уровень инженерный: понадобится уже собранный `llama-server`, терминал и локальный тестовый файл модели. [s1](#src-s1) [s2](#src-s2) [s5](#src-s5)

## Что подготовить, прежде чем сохранять состояние?

Для Linux возьмите уже работающий `llama-server` и файл `Qwen3-0.6B-Q8_0.gguf` из закреплённой карточки `Qwen/Qwen3-0.6B-GGUF`. Карточка и отдельный файл LICENSE этого репозитория указывают Apache-2.0; условия **другого** GGUF проверяйте отдельно. [Начальный запуск llama.cpp](/zhurnal/llama-cpp/) сделайте до этой проверки. Источники не задают универсальный минимум RAM/VRAM для такого опыта: вес GGUF и размер файла кеша не равны требованиям к памяти. Сеть нужна для предварительной загрузки бинарника и весов; сам тест по `127.0.0.1` не требует облачного API. [s1](#src-s1) [s5](#src-s5) [s6](#src-s6)

Работайте только на отдельной однопользовательской машине. Создайте каталог для состояний, доступный лишь вашей учётной записи: `umask 077; mkdir -p "$HOME/llama-slot-test"; chmod 700 "$HOME/llama-slot-test"`. Проверьте, что внутри **нет старого** `probe-1.bin`, особенно символьной ссылки, и что каталог не общий том. Путь ниже заканчивается `/` и должен быть под контролем того же пользователя, что запускает сервер. Исходный код объединяет каталог с переданным именем файла; upstream описывал перезапись через заранее помещённую в каталог ссылку. Даже закрытая issue **не доказывает**, что ваш бинарник безопасен на общем томе. Не запускайте тест от root, на многопользовательском хосте или с настоящими документами. [s3](#src-s3) [s7](#src-s7)

## Как записать кеш одного слота?

- На Linux-хосте запустите **один** слот с тем же GGUF: `llama-server -m ./Qwen3-0.6B-Q8_0.gguf -c 4096 -np 1 --host 127.0.0.1 --port 8080 --no-webui --cors-origins localhost --slot-save-path "$HOME/llama-slot-test/"`. Если бинарник лежит в каталоге сборки, укажите его полный путь. Привязка к `127.0.0.1` не запрещает доступ *другому локальному пользователю*, поэтому пример рассчитан только на отдельную однопользовательскую машину; API-ключ и сетевой периметр нужны в другой среде. Дождитесь успешного `curl -fsS http://127.0.0.1:8080/health`, затем откройте `curl -fsS http://127.0.0.1:8080/slots` и убедитесь, что ID свободного слота — `0`. Если он иной, используйте его фактическое значение далее. [s1](#src-s1) [s2](#src-s2)

- Отправьте выдуманный ввод: `curl -fsS http://127.0.0.1:8080/completion -H 'Content-Type: application/json' -d '{"prompt":"Учебная запись: встреча 12 мая. Участник А обещал прислать черновик. Участник Б проверит дату. Итог встречи: черновик ещё не утверждён.\nВопрос: что проверит участник Б?","n_predict":16,"id_slot":0,"cache_prompt":true,"stream":false}'`. Убедитесь, что ответ содержит `timings` и что запрос завершился; сам ответ модели сверьте с написанным здесь исходником. Это **пример ввода**, не обещание точной формулировки ответа. Если `/slots` показал другой ID, замените `0` и в этом запросе. [s1](#src-s1) [s2](#src-s2)

- После завершения запроса сохраните слот: `curl -fsS -X POST 'http://127.0.0.1:8080/slots/0?action=save' -H 'Content-Type: application/json' -d '{"filename":"probe-1.bin"}'`. Ожидаются `n_saved` и `n_written` больше нуля; на своём компьютере убедитесь, что файл появился в закрытом каталоге, является **обычным файлом**, а не ссылкой, и не доступен другим пользователям. Это доказательство записи, **не доказательство** ускорения следующего запроса. [s1](#src-s1) [s2](#src-s2) [s3](#src-s3)

## Как отличить настоящее восстановление от прочитанного файла?

Не перезапуская сервер, сначала выполните `curl -fsS -X POST 'http://127.0.0.1:8080/slots/0?action=erase'`, затем `curl -fsS -X POST 'http://127.0.0.1:8080/slots/0?action=restore' -H 'Content-Type: application/json' -d '{"filename":"probe-1.bin"}'`. В ответах ожидаются `n_erased`, затем `n_restored` и `n_read` больше нуля. В тестах проекта показана работа с тем же состоянием между слотами одного процесса; **это не журнал собственного запуска Modelium**. При ошибке «не помещается в контекст» не увеличивайте память вслепую: сверяйте модель, `-c`, слот и ревизию бинарника. [s1](#src-s1) [s2](#src-s2) [s3](#src-s3)

Теперь повторите `POST /completion` с тем же слотом и длинным началом: `curl -fsS http://127.0.0.1:8080/completion -H 'Content-Type: application/json' -d '{"prompt":"Учебная запись: встреча 12 мая. Участник А обещал прислать черновик. Участник Б проверит дату. Итог встречи: черновик ещё не утверждён.\nВопрос: что проверит участник Б? Ответьте одной фразой.","n_predict":16,"id_slot":0,"cache_prompt":true,"stream":false}'`. Если выше `/slots` показал другой ID, замените `0` во всех запросах. Проверьте `timings.cache_n`: положительное число означает, что некоторую часть общего префикса сервер взял из кеша; `timings.prompt_n` показывает, сколько токенов пришлось обработать заново. `n_restored > 0` **само по себе** не означает `cache_n > 0`. Если после восстановления `cache_n=0`, считайте тест неуспешным, а не заявляйте, что запуск ускорился. Сравнение времени без одинаковых условий нагрузки также не доказывает ускорения. [s1](#src-s1) [s2](#src-s2) [s4](#src-s4)

## Когда файл нельзя считать надёжной копией?

Отдельное сообщение разработчика описывает случай: после **перезапуска** сервер вернул `n_restored > 0`, но следующий запрос обработал весь префикс заново (`cache_n=0`); issue оставалась открытой при проверке 9 октября. Это отчёт для указанной там сборки и мультимодальной модели, **не доказательство**, что так ведут себя все версии и текстовый Qwen из примера. Если нужен перенос состояния через перезапуск, повторите отрицательный/положительный тест именно после остановки и запуска **того же бинарника и той же модели**; пока `cache_n` не подтвердил повторное использование, храните исходный ввод для безопасной повторной обработки. При обновлении версии или параметров кеша совместимость файлов тоже не обещана — [разбор изменения формата состояния llama.cpp](/zhurnal/llama-cpp-b11411-kv-cache-rotation-state-compatibility/) показывает реальную причину отказаться от старой копии. [s3](#src-s3) [s4](#src-s4)

Не сохраняйте реальные письма, клиентские данные и ключи в открытом каталоге или резервной копии без отдельного решения о хранении. Файл удаляйте только когда он больше не нужен; команда `erase` очищает слот **в памяти сервера**, но не удаляет `probe-1.bin` с диска. Для разъяснения ID и доступного контекста откройте [гайд по слотам](/zhurnal/llama-cpp-server-slots/) — это основной следующий шаг перед тестом на своей нагрузке. [s1](#src-s1) [s2](#src-s2) [s3](#src-s3) [s7](#src-s7)

## Источники

1. [llama.cpp HTTP server: параметры, слоты, completion timings](https://github.com/ggml-org/llama.cpp/blob/de7fa0a3c6a2e1b4cd9f22eb8d6bf5b12dbdb63b/tools/server/README.md) — получено 2026-10-09
2. [llama.cpp: тест сохранения, стирания и восстановления слота](https://github.com/ggml-org/llama.cpp/blob/de7fa0a3c6a2e1b4cd9f22eb8d6bf5b12dbdb63b/tools/server/tests/unit/test_slot_save.py) — получено 2026-10-09
3. [llama.cpp: реализация записи и чтения состояния слота](https://github.com/ggml-org/llama.cpp/blob/de7fa0a3c6a2e1b4cd9f22eb8d6bf5b12dbdb63b/tools/server/server-context.cpp) — получено 2026-10-09
4. [llama.cpp issue 26676: отчёт о restore без повторного использования KV после перезапуска](https://github.com/ggml-org/llama.cpp/issues/26676) — получено 2026-10-09
5. [Qwen3-0.6B-GGUF: закреплённая карточка и перечень файлов](https://huggingface.co/api/models/Qwen/Qwen3-0.6B-GGUF/revision/23749fefcc72300e3a2ad315e1317431b06b590a) — получено 2026-10-09
6. [Qwen3-0.6B-GGUF: условия лицензии репозитория](https://huggingface.co/Qwen/Qwen3-0.6B-GGUF/blob/23749fefcc72300e3a2ad315e1317431b06b590a/LICENSE) — получено 2026-10-09
7. [llama.cpp issue 26315: запись через символьную ссылку вне каталога слотов](https://github.com/ggml-org/llama.cpp/issues/26315) — получено 2026-10-09
