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-сервер