Перейти к основному содержимому
  1. Теория на русском языке/
  2. Оптимизация инференса LLM/

Выгрузка KV-кэша (KV cache offloading)

·990 слов·5 минут
Оглавление

Выгрузка KV-кэша — это процесс перемещения attention-данных (ключей и значений) из памяти GPU в более дешёвое хранилище, например, в оперативную память CPU или на диск. Это освобождает ресурсы GPU, но позволяет возобновлять инференс без пересчёта. Такой подход помогает масштабировать LLM-нагрузки, балансируя между производительностью и использованием памяти.

Почему KV-кэш становится узким местом в инференсе LLM?
#

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

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

На самом деле, не все данные KV-кэша должны постоянно находиться в памяти GPU. Во многих реальных сценариях пользователи не взаимодействуют с LLM непрерывно: кто-то делает паузу при вводе или возвращается через часы. В таких случаях их KV-кэш остаётся в памяти GPU, хотя не используется. Аналогично, если несколько пользователей или агентов обращаются к одному диалогу/документу в разное время, один и тот же KV-кэш может простаивать на GPU между сессиями (и не хочется тратить ресурсы GPU только ради пересчёта одного и того же).

В итоге память GPU расходуется неэффективно: она занята неактивными сессиями вместо обслуживания новых запросов. Со временем это ограничивает число одновременных пользователей и снижает общий throughput.

Чтобы решить эти проблемы, KV cache offloading перемещает неактивные или редко используемые данные кэша из памяти GPU в более дешёвое и ёмкое хранилище: оперативную память CPU, локальные SSD или удалённое object storage. Когда пользователь возвращается или другой пользователь обращается к тому же контенту, кэш можно вернуть в память GPU по требованию. Это позволяет избежать дорогого пересчёта и освобождает ресурсы GPU для активных задач.

Как посчитать размер KV-кэша
#

При организации offloading полезно понимать, сколько памяти реально занимает KV-кэш.

В трансформерах каждый attention-слой хранит два вектора (key и value) для каждого токена входа. В каждом слое несколько attention-head’ов, обычно одинаковой размерности.

Для оценки объёма памяти используйте калькулятор:

KV Cache Memory Calculator

Оценка памяти, требуемой для KV-кэша в трансформерных LLM

Режим расчёта:






KV Cache Size: ≈ 0.50 GB
Формула и пояснения

KV Cache Size (GB) = 2 × B × S × L × H × D × (Q / 8) / (1024³)

• ×2 — потому что хранятся и Key, и Value
• (Q / 8) — перевод бит в байты
• / (1024³) — перевод байт в гигабайты

Размер растёт линейно с длиной последовательности. При длинных контекстах KV-cache может стать основным потребителем памяти.

Information

Если вы уже знаете размерность модели, можно упростить формулу, подставив H × D (см. упрощённый расчёт выше).

Когда стоит выгружать KV-кэш для LLM
#

KV cache offloading особенно полезен, если:

  • Вы используете LLM с длинным окном контекста, и KV-кэш быстро превышает объём памяти GPU.
  • Несколько пользователей или агентов работают с одним и тем же контентом/контекстом в разных сессиях (например, разработчики в IDE часто обращаются к одним и тем же фрагментам кода).
  • Ваш деплой ограничен по памяти или вы хотите оптимизировать инфраструктурные расходы.
  • Вы масштабируете инференс на много распределённых воркеров с ограниченными GPU-ресурсами.
  • В нагрузке есть прерывистые или “спящие” сессии, и держать их KV-кэш в памяти GPU нерационально.

Преимущества выгрузки KV-кэша
#

Offloading KV-кэша даёт несколько важных плюсов для масштабирования и оптимизации инференса LLM:

  • Лучшее использование ресурсов. Перемещая неактивные или общие KV-данные из памяти GPU, вы освобождаете место для новых запросов. Это позволяет обслуживать больше пользователей или длиннее последовательности на том же GPU без переполнения памяти.
  • Снижение стоимости вычислений. Память GPU дорогая и ограниченная. Offloading позволяет использовать более дешёвое хранилище (например, RAM CPU или диск), уменьшая потребность в дорогих GPU только ради кэша.
  • Меньше задержка. Offloading позволяет модели пропускать повторные вычисления KV-кэша при инференсе, особенно при перекрывающемся контексте в многоходовых диалогах. Это значительно снижает TTFT и общую задержку. NVIDIA сообщает, что выгрузка KV-кэша может ускорить TTFT до 14 раз для длинных последовательностей по сравнению с пересчётом с нуля.

Компромиссы производительности при offloading KV-кэша
#

Хотя offloading KV-кэша может сильно повысить эффективность памяти и throughput, критична скорость целевого хранилища. Если RAM CPU или диск слишком медленные, накладные расходы на возврат KV-данных в GPU могут свести на нет все плюсы, особенно в задачах с жёсткими требованиями к задержке.

В общем, выгружать кэш стоит только если стоимость передачи данных ниже, чем пересчёт с нуля. Это часто так в длинных диалогах, где важно переиспользовать контекст, а пересчёт был бы дорогим.

Выгрузка KV-кэша с помощью LMCache
#

LMCache — расширение для движков инференса LLM, оптимизирующее инференс за счёт снижения TTFT и увеличения throughput, особенно для длинных контекстов. LMCache поддерживает переиспользование KV-кэшей для повторяющегося контента (не только префиксов) между разными инстансами движка.

LMCache хранит KV-кэши в нескольких уровнях памяти: GPU, DRAM CPU, локальный диск. Это резко снижает избыточные вычисления, ускоряет ответы и экономит GPU-циклы — идеально для задач вроде многоходовых QA, RAG, reasoning по документам.

В бенчмарках связка LMCache + vLLM давала 3–10-кратное снижение задержки в разных сценариях.

Ряд open-source проектов уже интегрировали LMCache для эффективного offloading и переиспользования KV-кэша:

  • llm-d выгружает KV-кэш с помощью LMCache из памяти GPU в более дешёвое и ёмкое хранилище (CPU, сетевые диски).
  • KServe интегрирует LMCache для снижения стоимости инференса и соблюдения SLO по задержке и throughput на масштабе.
  • vLLM использует LMCache для offloading на CPU, шаринга кэша между запросами и дисагрегированного prefill — это улучшает управление памятью и эффективность ресурсов.

LMCache поддерживает offloading KV-кэша в разные типы хранилищ: от локальных (оперативная память CPU, файловая система) до распределённых систем вроде Mooncake и ValKey.

Дополнительные ресурсы
#