English translation is not available yet. Showing Russian content.
Как работает prefix caching и prompt caching у провайдеров?
Краткий тезис
caching|Prefix caching (caching|внутренний кэш KV в инференс-движках vLLM, TGI) и prompt caching (продуктовый кэш KV у провайдеров вроде Anthropic, OpenAI, Gemini) — это техники ускорения генерации и снижения стоимости за счёт повторного использования вычисленных ключей и значений внимания (KV-кэш) для повторяющихся префиксов промпта. Принцип одинаков: если часть промпта (например, system prompt, few-shot примеры) встречается многократно, её KV-кэш сохраняется и переиспользуется для новых запросов, экономя до 90% времени и затрат. Различия — в уровне доступа, времени жизни кэша и API-интерфейсе.
1. Проблема: почему генерация LLM дорогая и медленная?
В основе современных LLM лежит трансформер с механизмом self-attention. При генерации каждого токена модель вычисляет запросы (Q), ключи (K) и значения (V) для всех предыдущих токенов последовательности. Эти вычисления доминируют в задержке (latency) и стоимости (FLOPs, память).
KV-кэш — это матрицы ключей и значений, которые сохраняются в памяти после первого прохода для каждого слоя и головы внимания. При генерации очередного токена модель вычисляет только его Q, а K и V для предыдущих токенов берёт из кэша. Это превращает O(n²) сложность в O(n) на шаг декодирования, но требует памяти ~ O(n) на последовательность.
На практике при работе с длинными системными промптами или однотипными префиксами (сотни/тысячи запросов с одинаковым контекстом) модель тратит ресурсы на пересчёт KV для одного и того же текста снова и снова.
Два подхода к решению:
- Prefix caching — кэширование KV для идентичных начальных сегментов промпта внутри одного инференс-движка (vLLM, TGI). Прозрачно для пользователя, автоматически.
- Prompt caching — кэширование KV на стороне API провайдера, которое пользователь может явно запросить через специальные параметры или заголовки (Anthropic, OpenAI). Часто связано с отдельным биллингом.
2. Как работает KV-кэш в трансформерах (напоминание)
Для понимания кэширования важно вспомнить, как устроен decoder-only transformer (GPT-family, LLaMA).
- Промпт преобразуется в последовательность токенов.
- На каждом слое self-attention вычисляются:
- Для каждого токена получаются векторы ключей и значений. Для последовательности длины L — матрицы K (L × d_k) и V (L × d_v).
- При генерации первого нового токена (prefill-фаза) вычисляются все K и V за один проход. Затем они сохраняются в KV-кэш.
- При генерации каждого последующего токена (decode-фаза) вычисляются только его K и V, которые добавляются в кэш.
Основная идея кэширования префиксов: если новый промпт начинается с той же последовательности токенов, что и предыдущий (например, одинаковый system prompt), то KV для этого префикса можно взять из кэша, не пересчитывая. Это ускоряет prefill-фазу (которая обычно самая долгая для длинных промптов) и экономит вычислительные ресурсы.
3. Prefix caching (vLLM / TGI / TensorRT-LLM)
Prefix caching — это техника, встроенная в инференс-движки (сервера), которые обслуживают множество запросов. Движок вычисляет хэш от префикса промпта (обычно первые N токенов) и сохраняет соответствующий KV-кэш в оперативной памяти (или на GPU). Когда поступает запрос с таким же префиксом, движок находит кэш и дополняет его новыми токенами запроса.
Как реализовано в vLLM:
- vLLM использует механизм prefix caching (раньше назывался Prefix Caching with PrefixPool).
- Каждый блок KV-кэша идентифицируется хэшем последовательности токенов.
- При запросе vLLM разбивает промпт на блоки (обычно фиксированного размера, например, 16 токенов) и для каждого блока проверяет наличие в глобальном кэше.
- Если блок уже закэширован, vLLM не вычисляет для него KV, а просто ссылается на существующий кэш. Для блоков, которых нет — вычисляет и добавляет.
- Кэш вытесняется по LRU (Least Recently Used) при нехватке памяти.
Преимущества prefix caching:
- Прозрачность: пользователь ничего не указывает.
- Экономия памяти GPU (за счёт повторного использования).
- Ускорение prefill-фазы для повторяющихся префиксов.
Ограничения:
- Требует, чтобы префиксы были строго идентичны на уровне токенов (включая пробелы, знаки препинания). Небольшое отличие (например, точка с запятой вместо точки) ломает кэш.
- Кэш живёт в памяти движка, не сохраняется между перезапусками.
- Не подходит для очень длинных префиксов, если не хватает GPU-памяти.
4. Prompt caching (Anthropic / OpenAI / Gemini)
Prompt caching — это функция API, которая позволяет пользователю явно указать, что часть промпта должна быть закэширована на стороне провайдера. Провайдер хранит KV-кэш для этих префиксов и переиспользует его при последующих запросах. Важное отличие от prefix caching: пользователь контролирует, что кэшировать, и платит за хранение кэша (обычно дешевле, чем полный пересчёт).
Anthropic (Claude):
- Использует Prompt Caching для системного сообщения и начала сообщений пользователя.
- Пользователь добавляет параметр
cache_control: {"type": "ephemeral"}к сообщению или системному сообщению. - Anthropic вычисляет KV для этого блока и сохраняет его на определённое время (TTL, например, 5 минут с момента последнего использования).
- Стоимость: закэшированный ввод (cached input) стоит примерно на 90% дешевле, чем полный ввод.
- Пример (API):
response = client.messages.create( system=[{"type": "text", "text": "Вы — эксперт. Отвечайте коротко.", "cache_control": {"type": "ephemeral"}}], messages=[{"role": "user", "content": "Напиши формулу воды."}], model="claude-3-5-sonnet-20241022" )
- В марте 2025 OpenAI анонсировал Prompt Caching для некоторых моделей.
- Пользователь задаёт параметр
cachingв запросе (или он включается автоматически для повторяющихся префиксов). - Детали: кэшируется весь префикс до первого пользовательского сообщения, если длина превышает порог (например, 1024 токена).
- Стоимость: до 50% экономии на вводных токенах.
Google Gemini:
- Имеет Context Caching, где пользователь загружает контекст (документ, системный промпт) и получает уникальный идентификатор кэша.
- При повторных запросах можно передать этот ID, и модель будет использовать закэшированные KV.
- Стоимость хранения кэша — почасовая.
Общий принцип работы prompt caching:
- Пользователь отправляет запрос с маркированным префиксом (или провайдер автоматически определяет повторение).
- Провайдер вычисляет KV для префикса и сохраняет в кластерной памяти с TTL.
- При последующих запросах с тем же префиксом провайдер использует сохранённый кэш, начисляя меньшую стоимость.
- Если кэш не был использован в течение TTL, он удаляется.
Когда prompt caching особенно выгоден:
- System prompt длиной в тысячи токенов (например, ролевая настройка, инструкции для RAG).
- Few-shot примеры — одинаковые пары вопрос-ответ повторяются во многих запросах.
- Документы для RAG — если один и тот же документ подаётся в контекст многим пользователям (но осторожно с privacy).
5. Сравнение prefix caching (движок) vs prompt caching (API)
| Характеристика | Prefix caching (vLLM, TGI) | Prompt caching (Anthropic, OpenAI) |
|---|---|---|
| Уровень | Сервер инференса (on-premise или managed) | API провайдера |
| Прозрачность | Автоматический, не требует изменений в коде | Должен быть явно указан пользователем |
| Контроль | Движок сам решает, что кэшировать (по хэшу) | Пользователь выбирает блок для кэширования |
| Срок жизни | Пока есть память (LRU вытеснение) | TTL (5-10 мин у Anthropic, платное хранение у Gemini) |
| Экономия | Ускорение инференса (latency снижается на prefill) | Снижение стоимости API (до 90%) |
| Требования | Префикс точно совпадает по токенам | Префикс точно совпадает по токенам |
| Поддержка | vLLM, TensorRT-LLM, TGI | Anthropic Claude, OpenAI GPT-4o, Gemini |
| Пример тикета | Много однотипных запросов к одному движку | Длинный system prompt в SaaS-продукте |
6. Требования и ограничения (важно на собеседовании)
- Идентичность префикса на уровне токенов: пробел, перенос строки, пунктуация — всё должно совпадать. Даже разница в токенизации разных моделей (например,
HellovsHello) ломает кэш. - Порядок сообщений: в чат-моделях кэш учитывает всю историю сообщений, а не только текст. Если порядок ролей (system, user, assistant) различается, кэш не сработает.
- Длина префикса: для эффективности обычно нужен достаточно длинный префикс (сотни токенов). Слишком короткий — выгода минимальна.
- Безопасность: кэш может храниться в shared памяти. Провайдеры (Anthropic, OpenAI) заявляют, что изолируют кэши между клиентами, но для чувствительных данных стоит отключать.
- Совместимость с streaming: обычно кэш работает и для стриминга, так как KV общий.
- Fine-tuning и адаптеры: если модель дообучена или используется LoRA, кэш может быть невалиден из-за изменённых весов.
7. Практические соображения и best practices
- Для RAG-систем: можно кэшировать system prompt (инструкции для агента) и часто используемые документы (например, описание схемы API). Но при замене документа нужно инвалидировать кэш.
- Для чат-ботов: кэширование начального приветственного сообщения и системной инструкции снизит latency первого ответа.
- В локальных инференсах: prefix caching в vLLM может значительно увеличить throughput при batch-обработке однотипных запросов (например, тестирование промптов).
- Мониторинг: добавьте логирование, чтобы видеть, какие префиксы кэшируются и как часто hit.
- Инвалидация: при изменении system prompt нужно либо подождать TTL, либо явно сбросить кэш (если API поддерживает).
Пример кода для vLLM (включение prefix caching):
from vllm import LLM, SamplingParams
# Запуск LLM с включенным prefix caching
llm = LLM(model="meta-llama/Llama-2-7b-hf", enable_prefix_caching=True)
# Первый запрос
output = llm.generate("System: Ты помощник.\nUser: Привет", sampling_params)
# Второй запрос с тем же префиксом — кэш сработает
output2 = llm.generate("System: Ты помощник.\nUser: Как дела?", sampling_params)
8. Пет-проект для закрепления
Задача: Создать систему, демонстрирующую экономию от prefix caching на локальном LLM (vLLM) и prompt caching через API Anthropic.
Инструменты: Python, vLLM, Anthropic API, time, psutil.
Шаги:
- Часть 1: vLLM:
- Часть 2: Anthropic Prompt Caching:
- Зарегистрируйтесь в Anthropic, получите API-ключ.
- Отправьте 5 запросов с одинаковым system prompt (длина > 1000 токенов) и разными сообщениями пользователя.
- Для первых двух запросов не используйте caching, для следующих трёх — добавьте
cache_control. - Сравните стоимость (из ответа API есть
usage.cache_creation_input_tokens,usage.cache_read_input_tokens) и время ответа.
Ожидаемый результат:
- В vLLM: ускорение prefill-фазы в 2–5 раз для повторяющихся префиксов.
- В Anthropic: снижение стоимости в 5–10 раз (cached input) и уменьшение latency.
9. Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 208 | KV-кэш и механизм внимания в трансформерах |
| 219 | Оптимизация инференса LLM (quantization, speculative decoding) |
| 840 | Как устроен RAG с длинным контекстом и как уменьшить задержки |
| 841 | Streaming и буферизация токенов |
| 843 | Batch-обработка запросов и throughput |
| 844 | Continuous batching в LLM-движках |
Навигация
- Предыдущий: 841
- Следующий: 843
- Индекс: 00. Индекс разборов