Перейти к содержанию
Новое AiManual теперь в MAX Подписаться
Публикация AiManual

CachyLLama: персистентный SSD-кэш KV для мгновенного warm-старта LLM

Форк llama.cpp с персистентным SSD-кэшем KV-состояний сокращает повторную обработку промпта с 143 секунд до менее 1 секунды на dual-MI50. Разбор архитектуры, бе

Коротко

Что будет в материале

  1. 01

    Проблема холодного старта в агентных сессиях

  2. 02

    CachyLLama: многоуровневый кэш как решение

  3. 03

    Бенчмарк на dual-MI50: цифры и конфигурация

  4. 04

    Практическое применение: когда CachyLLama незаменим

Проблема холодного старта в агентных сессиях

Запускаете агента с длинным системным промптом на 15 тысяч токенов. Сервер падает, модель нужно перезагрузить, или вы просто экспериментируете с параметрами сэмплинга. Каждый перезапуск превращается в ожидание: llama.cpp заново вычисляет KV-кэш для всего контекста. На слабом железе это минуты простоя.

Конкретный пример: конфигурация с двумя AMD MI50, промпт длиной 15700 токенов. Холодный старт - полная обработка промпта - занимает 143 секунды. Полторы сотни секунд, в течение которых GPU загружены вычислением attention для токенов, которые не изменились. Для агентных сессий с частыми перезапусками это неприемлемо.

Проблема архитектурная. Стандартный llama.cpp не сохраняет KV-состояния между запусками. Кэш живёт только в оперативной памяти текущего процесса. Уронили процесс - потеряли кэш. Сменили модель - начинайте сначала. Эта механика особенно болезненна для сценариев с долгоживущими агентами, где контекст накапливается часами, а перезапуск требуется при любом изменении конфигурации.

Мы уже разбирали смежную проблему в материале про Cache-Hunter и инвалидацию кэша в локальных обвязках: даже незначительное изменение системного промпта или списка инструментов сбрасывает кэш префиллов, и вы теряете токены на пустых пересчётах. CachyLLama атакует корень проблемы - отсутствие персистентности между запусками.

CachyLLama: многоуровневый кэш как решение

CachyLLama - форк llama.cpp, добавляющий персистентный слой для KV-состояний. Ключевое отличие от апстрима: кэш пишется на SSD и выживает после перезапуска процесса. Для тех же 15700 токенов на dual-MI50 warm start занимает менее одной секунды. Ускорение - более чем в 140 раз.

Механика прямолинейна. При первом прогоне промпта CachyLLama вычисляет KV-кэш стандартным образом, но дополнительно сериализует его на диск. При повторном запуске с идентичными параметрами модели и тем же промптом кэш читается с SSD напрямую в память, минуя вычисление attention для всех слоёв трансформера. Процессор и GPU загружены только операцией десериализации.

Это решение закрывает узкую, но критическую задачу. Стандартные методы оптимизации инференса - квантизация весов, спекулятивное декодирование, батчинг - снижают стоимость одного токена, но не устраняют повторную работу. CachyLLama устраняет саму необходимость повторной работы для неизменного контекста.

Как устроен персистентный KV-кэш

Архитектура кэша двухуровневая. Первый уровень - стандартный оперативный кэш в RAM, идентичный тому, что использует llama.cpp. Он обслуживает текущую сессию: каждый новый токен добавляет пары ключ-значение для всех слоёв модели, и механизм attention читает их при генерации следующего токена.

Второй уровень - персистентный слой на SSD. После завершения префилла (обработки промпта) CachyLLama сериализует полный набор KV-тензоров в файл на диске. Формат хранения - бинарный дамп тензоров с метаданными: хэш конфигурации модели, длина контекста, параметры квантизации кэша. При warm-старте загрузчик проверяет соответствие хэша и параметров, затем отображает файл в память или читает последовательно - в зависимости от реализации бэкенда.

Восстановление контекста исключает повторное вычисление attention. Модель получает готовые ключи и значения для всех позиций промпта и сразу переходит к декодированию первого токена ответа. Вычислительная сложность warm-старта - O(N) на чтение с диска против O(N²) на вычисление attention для холодного старта, где N - длина контекста.

Для сравнения: подход с холодным кэшированием KV, разобранный в статье про запуск трёх сессий Qwen3.5 122B на Mac Studio, даёт 16-кратное ускорение префилла через чтение кэша с SSD, но не затрагивает персистентность между перезапусками сервера. CachyLLama идёт дальше - кэш живёт на диске постоянно.

Бенчмарк на dual-MI50: цифры и конфигурация

Тестовый стенд: две AMD Instinct MI50 с 32 ГБ HBM2 каждая, соединённые через PCIe-шину. Модель - LLaMA-подобная архитектура (предположительно 70B-класса в 4-битной квантизации), размещённая на двух картах с разбиением по слоям. Промпт - 15700 токенов, типичный объём для агентной сессии с историей диалога и системными инструкциями.

Методика замера холодного старта: запуск llama.cpp с пустым кэшем, полный префилл промпта с вычислением KV-кэша для всех слоёв, замер времени от старта процесса до готовности первого токена декодирования. Результат: 143 секунды. Основное время уходит на операции умножения матриц для attention - на MI50 без специализированных тензорных ядер это узкое место.

Методика замера warm-старта: предварительно сохранённый на NVMe SSD кэш, запуск CachyLLama с флагом загрузки кэша, замер от старта процесса до готовности первого токена. Результат: менее 1 секунды. Время уходит на чтение файла кэша с диска, десериализацию тензоров и размещение их в памяти GPU.

Разрыв в 140+ раз объясняется разницей в вычислительной сложности. Холодный старт требует O(N²) операций для каждого слоя attention - на 15700 токенов это сотни гигафлопс. Warm-старт ограничен пропускной способностью SSD: файл кэша размером в несколько гигабайт читается за доли секунды на современном NVMe-накопителе.

Выигрыш растёт с длиной контекста. Для 4000 токенов ускорение будет скромнее - возможно, 10-20 крат. Для 32000 токенов разрыв станет ещё драматичнее, поскольку холодный префилл масштабируется квадратично, а загрузка с диска - линейно. На медленных GPU вроде MI50 эффект выражен сильнее, чем на H100 с их тензорными ядрами и высокой пропускной способностью памяти.

Практическое применение: когда CachyLLama незаменим

Первый сценарий - долгоживущие агенты с перезапусками. Агент работает часами, накапливает контекст в десятки тысяч токенов, затем сервер нужно перезагрузить для обновления модели или системного промпта. Без персистентного кэша каждый перезапуск отбрасывает сессию на старт. CachyLLama сохраняет контекст на диске и восстанавливает его мгновенно.

Второй сценарий - отладка промптов. Инженер итеративно правит системный промпт, меняет примеры few-shot, подбирает параметры сэмплинга. Каждая итерация требует перезапуска инференса с тем же контекстом. 143 секунды ожидания на итерацию превращают отладку в многочасовой процесс. С CachyLLama цикл «изменил-проверил» занимает секунды.

Третий сценарий - частое переключение между сессиями. Сервер обслуживает нескольких пользователей или агентов с разными контекстами. При переключении контекст выгружается из памяти и загружается заново. Персистентный кэш позволяет хранить образы сессий на диске и подгружать их по требованию без повторного префилла.

Четвёртый сценарий - ограниченный бюджет на железо. Разработчик использует старые GPU (MI50, P40, M40) или вовсе CPU-инференс. На таком оборудовании холодный префилл длинного контекста особенно болезнен. CachyLLama компенсирует слабость железа за счёт однократного вычисления кэша и многократного использования.

Объём кэша на диске линейно зависит от длины контекста, размера модели и разрядности хранения. Для 70B-модели с 15700 токенами в FP16 файл кэша занимает примерно 2-3 ГБ на слой attention, умноженные на количество слоёв - суммарно десятки гигабайт. Квантизация KV-кэша (FP8, INT8) пропорционально снижает объём. Подходы вроде KVarN и Precision Tail из BeeLLama.cpp v0.4.0 могут сократить размер кэша без существенной потери качества.

Ограничения и риски подхода

Персистентный кэш жёстко привязан к конфигурации. Хэш модели, параметры квантизации, длина контекста, порядок слоёв - любое изменение инвалидирует кэш. Сменили квантизацию с Q4_K_M на Q5_K_M - кэш непригоден. Обновили веса модели через LoRA-адаптер - кэш непригоден. Перенесли кэш на другую машину с иным разбиением по GPU - кэш непригоден.

Объём дискового пространства - значительный. Для агентной сессии с контекстом 100 тысяч токенов на 70B-модели файл кэша может превысить 100 ГБ в FP16. Несколько таких сессий быстро заполнят потребительский SSD. Квантизация кэша частично решает проблему, но вносит компромисс по качеству генерации.

Износ SSD - реальный фактор при частой записи. Каждый префилл пишет на диск десятки гигабайт. При сотнях перезапусков в день ресурс записи накопителя расходуется заметно. Для эксплуатации в режиме 24/7 разумно использовать серверные SSD с высоким TBW или выделенный диск под кэш, который не жалко заменить.

Для однократных запросов выигрыша нет. Если вы отправляете одиночный промпт и не планируете перезапусков, CachyLLama только добавит накладные расходы на запись кэша на диск. Инструмент заточен под сценарии с повторным использованием контекста.

Совместимость с апстримом llama.cpp неполная. Форк может отставать от основной ветки по новым фичам - поддержке новых архитектур, оптимизациям инференса, бэкендам. Перед внедрением проверьте, что нужная вам модель и конфигурация поддерживаются в актуальной версии CachyLLama.

Как начать использовать CachyLLama

Шаг первый: клонируйте репозиторий форка. Актуальный URL и инструкции по сборке ищите в официальном репозитории проекта на GitHub. Сборка аналогична llama.cpp - CMake с флагами под вашу платформу (ROCm для AMD, CUDA для NVIDIA, Vulkan/OpenCL для универсальных бэкендов).

Шаг второй: настройте пути хранения кэша. CachyLLama добавляет параметры командной строки для указания директории кэша и префикса файлов. Рекомендуется выделить отдельный раздел на быстром NVMe-накопителе - скорость чтения напрямую влияет на время warm-старта.

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

Шаг четвёртый: повторный запуск с флагом загрузки кэша. Сервер читает файл с диска, размещает тензоры в памяти GPU и сразу переходит к декодированию. Время warm-старта - от долей секунды до нескольких секунд в зависимости от объёма кэша и скорости накопителя.

Конфигурация кэша требует дисциплины. При изменении модели или параметров старый кэш нужно инвалидировать вручную или положиться на проверку хэша, которую делает загрузчик. Храните несколько версий кэша для разных конфигураций, если переключаетесь между ними.

Сравнение с альтернативными методами оптимизации

Квантизация весов (GPTQ, AWQ, GGUF) уменьшает размер модели и снижает требования к памяти, но не решает проблему повторного префилла. Модель в INT4 занимает меньше места, но attention для 15700 токенов всё равно вычисляется заново при каждом запуске. CachyLLama и квантизация ортогональны - их можно комбинировать.

Квантизация KV-кэша (FP8, INT8, KVarN) сокращает объём хранимого кэша и ускоряет операции с ним в памяти, но не добавляет персистентности. BeeLLama.cpp с Precision Tail решает задачу удержания качества на длинных контекстах, а CachyLLama - задачу сохранения кэша между запусками. Два форка атакуют разные аспекты одной проблемы.

Pruning и дистилляция требуют переобучения модели и меняют её поведение. Это стратегический выбор архитектуры, а не операционная оптимизация инференса. CachyLLama не трогает веса модели и не влияет на качество генерации - только на время доступа к контексту.

Многопоточные форки llama.cpp (например, с оптимизациями под NUMA или распределённым инференсом через RPC, как в нашем разборе запуска GLM-5.2 на 16 MI50) ускоряют вычисление одного токена, но не избавляют от повторной работы. CachyLLama устраняет саму причину повторной работы для неизменного контекста.

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

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