Inference

KV-кеш

Кеш ключей и значений механизма внимания, устраняющий повторное вычисление токенов в контексте.

Что такое KV-кеш

При авторегрессивной генерации трансформер на каждом шаге должен «смотреть» на все предыдущие токены контекста через механизм self-attention. Без кеширования это означало бы пересчёт матриц ключей (K) и значений (V) для всего контекста на каждом шаге — квадратичная сложность по времени.

KV-кеш решает проблему: вычисленные K и V для каждого токена сохраняются в памяти GPU. При генерации следующего токена используются уже готовые значения из кеша, и нужно вычислить только K, V для нового токена. Это превращает временну́ю сложность из O(n²) в O(n) на каждый декодируемый шаг.

Почему KV-кеш занимает много VRAM

Размер KV-кеша растёт линейно с длиной контекста и числом слоёв:

KV_bytes ≈ 2 × num_layers × seq_len × num_heads × head_dim × bytes_per_elem

Для Llama 3 8B при контексте 8192 токенов в BF16:

  • 32 слоя × 8192 × 32 головы × 128 dim × 2 байта × 2 (K и V) ≈ 4 ГБ

При 100 параллельных запросах это 400 ГБ — отсюда необходимость в PagedAttention и квантизации KV.

Влияние на инференс

  • Prefill-фаза заполняет KV-кеш для всего входного промпта — ресурсоёмкая, но однократная
  • Decode-фаза дочитывает из кеша и добавляет по одному токену
  • Большой кеш → больше параллельных сессий умещается → выше суммарный throughput
  • При нехватке VRAM кеш вытесняется (eviction), что снижает производительность

Связанные термины

  • PagedAttention — алгоритм vLLM для хранения KV-кеша в несмежных блоках
  • prefill — фаза заполнения KV-кеша
  • decode — фаза чтения из KV-кеша
  • prompt caching — переиспользование KV-кеша между запросами
  • контекстное окно — предел длины, ограничивающий размер кеша
  • VRAM — физическая память, где хранится KV-кеш

Готовы запустить GPU-задачу?

Запустить GPU-сервер