Окна контекста и KV-кэш
У окна контекста есть ценник, и он оплачивается в VRAM. Каждый токен, удерживаемый в контексте, заставляет модель помнить два маленьких вектора на слой, и эта память — KV-кэш — растёт с каждым токеном и незаметно съедает запас, который вы думали, что у вас есть. Это объясняет самые странные провалы локальных LLM: OOM на сороковой реплике, модель, которая будто замедлялась по мере роста чата, карта 8 GB, которая держит «128k контекста» только в буклете.
Что хранит кэш
Вниманию нужны ключевая и значимая проекции каждого прошлого токена, прежде чем оно сможет на него посмотреть. Они вычисляются один раз при префилле и держатся всё время жизни запроса: на слой, на токен — один вектор K и один вектор V из kv_heads × head_dim чисел каждый. Это хранилище и есть KV-кэш, и потому контекст стоит линейно памяти — всегда, для каждого обслуживаемого запроса.
Формула
байт на токен = 2 (K и V) × слои × kv_heads × head_dim × 2 байта (fp16)
Разбор, GQA класса llama-3-8B (32 слоя, 8 KV-голов, head_dim 128):
2 × 32 × 8 × 128 × 2 = 131,072 байта = 128 KB на токен.
При 32k контекста это 32,768 × 128 KB ≈ 4 GB KV-кэша — сравнимо с лежащими рядом весами Q4. Более тощие конфигурации с 4 KV-головами дают около 2 GB на 32k. Порядок величины для моделей класса 8B при fp16 KV: закладывайте 0.5–4 GB на 32k в зависимости от архитектуры. Точные числа для чекпоинта берутся прямо из его config.json — num_key_value_heads, num_hidden_layers и размер головы.
GQA — почему длинный контекст подешевел
Grouped-query attention делит горстку KV-голов между многими головами запросов — скажем, 32 головы запросов обслуживаются 8 KV-головами, — сжимая кэш в 4 раза против полного многоголового внимания при ничтожной потере качества. Без GQA таблица ниже была бы в 4–8 раз больше, а длинный контекст на карте 24 GB остался бы фантазией. Это самый крупный архитектурный подарок локальной работе с длинным контекстом и причина, почему современные модели 7–9B вообще поставляются с окнами 32k–128k.
Как быстро он растёт
Модель класса 8B с GQA при fp16 KV, 128 KB на токен:
| Контекст | Размер KV-кэша | На карте 8 GB |
|---|---|---|
| 4k | ~0.5 GB | незаметно |
| 16k | ~2.1 GB | заметно рядом с 5 GB весов |
| 64k | ~8.4 GB | не влезает, точка |
| 128k | ~16.8 GB | втрое больше самой модели |
Память растёт линейно на токен, но вычисления внимания растут с квадратом контекста — так что длинные контексты одновременно стоят VRAM и времени на токен.
Рычаги, когда KV взрывается
- Квантуйте кэш. q8_0 уменьшает его вдвое, q4_0 — вчетверо, при умеренной цене качества — часто лучший обмен ёмкости во всём стеке. В llama.cpp квантизация KV требует flash attention, см. ниже.
- Обслуживайте более короткий контекст.
-c 8192ничего не стоит, если ваши промпты по 2k. Выделять заявленные 128k «на всякий случай» — резервировать VRAM, который вы никогда продуктивно не используете. - Модели со скользящим окном. Некоторые архитектуры ограничивают KV-окно на слой вне зависимости от номинального контекста — поведение длинного контекста без линейного счёта, ценой некоторого ухудшения вспоминания старого материала.
- Flash attention. В принципе выигрыш вычислений и эффективности ядер — точное внимание без квадратичного раздувания активаций, — а в llama.cpp это ещё и ключ, открывающий квантизацию KV.
llama-server -m model-8b-q4_k_m.gguf -c 65536 -fa --cache-type-k q8_0 --cache-type-v q8_0
Заявленный против эффективного контекста
Модель с заявленными 128k запустится на 128k — кэш влезает и математика сходится. Мыслит ли она на 128k — другое утверждение. Растянутый RoPE и дообучение под длинный контекст удерживают высокие оценки поиска «иголки в стоге», тогда как широкое понимание часто проседает задолго до лимита. Считайте заявленное окно физическим максимумом, предполагайте размягчение качества во второй половине и ищите комьюнити-эвалы длинного контекста конкретного чекпоинта, прежде чем ставить на него воркфлоу.
Потерянные в середине и гигиенические привычки
Позиционное смещение реально: модели сильнее всего смотрят на начало и конец промпта и провисают в середине. Ставьте инструкции и критичные факты в начало или конец; никогда не закапывайте спецификацию, которой модель должна следовать, внутрь вставленного документа. Привычки, которые держат контексты маленькими и острыми:
- Подрезайте или суммаризуйте старые реплики вместо проигрывания всего чата.
- Извлекайте и вставляйте релевантный чанк, а не весь файл.
- Держите системный промпт коротким; он пересылается с каждым запросом.
- Следите за VRAM во время долгих сессий — рост KV это тихая переменная (математика VRAM), а флаги обслуживания, которые им управляют, собраны в параметрах движка.
Связанные разделы: математика VRAM · параметры движка · скорость