Prefill cache (prefix/prompt caching) — как кэшировать «префикс» и ускорять LLM

Prefill cache — это техника повторного использования уже посчитанных представлений префикса (общей части ввода: системного промпта, инструкций, неизменной «шапки») между запросами. В отличие от KV cache, который хранится внутри одной сессии для уже обработанных токенов, prefill cache позволяет делиться префиксом между разными запросами/пользователями, избегая повторного «разгона» модели на одинаковом начале.

Prefill cache (prefix/prompt caching) — как кэшировать «префикс» и ускорять LLM

Кратко: один раз «прочитали» длинный пролог — далее новые запросы стартуют уже с готовым состоянием внимания для этой части.

Префилл (Prefill cache) vs декод и где тут кэш

  • Prefill — модель обрабатывает весь ввод (промпт) батчем и строит ключи/значения (K/V) для каждого токена.
  • Decode — модель дописывает ответ по одному токену, обращаясь к уже накопленному KV.
  • Prefill cache — хранит часть KV, соответствующую общему префиксу, чтобы не пересчитывать её снова при следующем запросе с тем же префиксом.

Чем prefill cache отличается от KV cache

Критерий Prefill cache (prefix/prompt) KV cache (сеансовый)
Область действия Между разными запросами/сессиями Внутри одной последовательности/сессии
Содержимое KV только для общего префикса KV для всех уже пройденных токенов
Жизненный цикл Живёт в «пуле» префиксов, переиспользуется Растёт/сбрасывается по мере генерации
Экономия Ускоряет старт и длинные «шапки» Ускоряет пошаговую генерацию

На практике оба механизма комплементарны и часто реализуются вместе.

Когда это даёт наибольший эффект

  • Длинный system prompt и/или «инструкция бренда», одинаковая для всех диалогов.
  • Шаблонные прологи RAG (например, одинаковая схема цитирования).
  • Агентные пайплайны с повторяющимися «рамками ответа».
  • Обработка множества коротких запросов поверх одного и того же контекстного пролога.

Если «шапка» занимает тысячи токенов, экономия префилла даёт кратный рост throughput.

Совместимость и позиционирование (важно)

Чтобы кэш «пришился», должны совпасть:

  • Модель и версия (веса, токенизатор, RoPE-параметры/интерполяция).
  • Позиционная система (обычно RoPE): кэшированный префикс должен начинаться с позиции 0 или использовать согласованные смещения.
  • Лора/адаптеры: если подключены, префикс кэшируется под конкретным набором адаптеров.
  • Токенизация: одинаковые опции разбиения (спец-токены, нормализация).

Температура, top-k/top-p и прочие параметры декодирования на совместимость не влияют — они относятся к выбору токена, а не к самим представлениям.

Где и как хранить кэш префиксов

  • Paged/блочный KV-пул: разбивайте префикс на страницы (блоки) и регистрируйте карту страниц → дешёвая «пришивка» без копирования массивов.
  • GPU/CPU-иерархия: «горячие» префиксы держать на GPU, «тёплые» — в пинованной CPU-памяти; редкие — выгружать.
  • Идентификация префикса: детерминированный хеш от последовательности токенов (+ метаданные модели/адаптеров).
  • Шардирование: крупные кэши распределяйте по устройствам; избегайте переполнения одного GPU.

Сколько памяти это ест (оценка)

Prefill cache фактически хранит подмножество KV:

bytes_prefix ≈ n_layers × len(prefix) × n_kv_heads × head_dim × 2 × sizeof(dtype)

Если префикс длиной 2k токенов и dtype fp16, память сравнима с KV такого же размера (см. формулу на странице KV cache). Экономия достигается тем, что этот объём делится между многими запросами.

Хеширование и инвалидация

  • Ключ кэша: hash(tokens) ⊕ hash(model_id) ⊕ hash(adapters) ⊕ pos_scheme.
  • Инвалидация при смене модели/адаптера/позиционных настроек.
  • Коллизии крайне нежелательны — используйте криптостойкие хеши и храните длину/префикс для верификации.
  • Ставьте TTL/LRU-политику: редкие префиксы можно вытеснять.

Типичный пайплайн с prefill cache

  1. Разбор запроса → детектируем общий префикс, токенизируем.
  2. Проверка кэша по ключу: есть ли страницы для этого префикса.
  3. Пришивка: связываем текущую последовательность с уже посчитанным KV префикса (позиция t=|prefix|).
  4. Prefill остатка (если есть частично общий пролог) и decode ответа.
  5. Обновление политики: счётчики обращений, LRU, миграция между уровнями памяти.

Частые ошибки и как их избежать

  • Сдвиг позиций: пришили кэш, но RoPE-фазы не совпали — деградация качества. Решение: фиксируйте нумерацию позиций; общий префикс должен начинаться с нуля.
  • Смешение разных адаптеров: кэш собран с LoRA v1, а запрос — с v2. Держите метаданные адаптеров в ключе.
  • Фрагментация и копирования: огромные memcpy «съедают» выигрыш. Используйте блочный (paged) пул KV.
  • Слишком агрессивная квантовка: INT8/FP8 для KV возможны, но проверяйте длинные ответы и логико-арифметические задачи.
  • Мелкие префиксы: кэширование 50–100 токенов редко окупается — накладные расходы выше выгоды.

Оценка выигрыша (прикидка)

Пусть P — длина общего префикса, Q — длина уникальной части ввода, A — длина ответа. Время без кэша ≈ T(prefill(P+Q)) + T(decode(A)). С кэшем ≈ T(prefill(Q)) + T(decode(A)). При P ≫ Q ускорение на старте может быть кратным; общий throughput кластера растёт за счёт снятия «узкого места» префилла.

Практические пресеты

Сценарий Рекомендации
Общий system prompt на тысячи токенов Вынесите в единый prefix cache, держите на GPU; инвалидация только при смене версии модели
Агент с шаблонными «рамками» Разделите пролог на модули-префиксы (инструкция, формат ответа), кэшируйте модульно
RAG с единым стилем цитирования Кэшируйте именно инструктивную часть, а не документы; сами документы динамичны
Мульти-модельный парк Раздельные пулы по model_id; запрещайте смешение префиксов между моделями
Ограниченная память INT8/FP8 для KV префикса + хранение «тёплых» страниц в CPU, промоушен по LRU

Вопросы и ответы (FAQ)

Это увеличивает максимальное контекстное окно?

Нет. Prefill cache экономит расчёт общего префикса, но предел окна задаётся архитектурой/позиционными кодировками (см. контекстное окно).

Можно ли кэшировать «кусок середины»?

Обычно — нет: кэшируют префикс (начало). Некоторые рантаймы поддерживают модульные «префиксы», но порядок и позиции должны совпадать.

Совместим ли prefill cache с top-k/top-p/температурой?

Да. Эти параметры влияют на выбор токена в декоде, а не на совместимость префиксных представлений (см. top-k и top-p).

Это то же самое, что prefix-tuning/prompt-tuning?

Нет. Prefill cache — инференс-оптимизация. Prompt-/prefix-tuning — методы дообучения (см. fine-tuning).

См. также

Task Runner