Назад до блога

128k контексту на десктопі — брехня. Його з'їв KV-кеш.

22 вересня 2026 р.

Кожна картка локальної моделі тепер хизується вікном у 128k. На десктопі ця цифра — договір оренди, який ваша RAM підписує не читаючи. Що визначає, докуди ви дотягнете довгий документ, — не ваги. Це KV-кеш, і він масштабується з контекстом як податок, узгоджений у чужій валюті.

Вікно контексту — не функція, яку вмикають. Це оренда пам’яті, яку ви платите щосекунди роботи сервера.

Скільки RAM насправді коштує контекст 128k?

Арифметика публічна і коротка. Як розкладає Transformer Inference Arithmetic, KV-кеш зберігає два тензори — ключі та значення — для кожного шару, кожної KV-голови, кожного токена:

cache_bytes = 2 × шари × контекст × kv_голови × head_dim × байт_на_елемент

Візьмімо Llama 3.1 8B: 32 шари, 8 KV-голов, head_dim 128 — прямо з config.json на Hugging Face. При 131 072 токенах у fp16 (2 байти):

2 × 32 × 131072 × 8 × 128 × 2 = 17 179 869 184 байти ≈ 16 GiB

Ваги тієї ж моделі у fp16 важать близько 16 GiB. При максимальному контексті кеш так само великий, як модель, до якої він належить. «8B-модель, що поміщається у 16 GiB» мовчки стає проблемою на 32 GiB, щойно ви піднімаєте num_ctx до 128k.

Чому кеш росте разом із вікном?

Бо увага зобов’язана порівняти кожен токен з усіма попередніми, а інференс авторегресійний — нічого не перераховується, все запам’ятовується. У цьому весь трюк, що робить генерацію швидкою: ключі та значення кожного токена обчислюються один раз і зберігаються. Пам’ять на токен стала, отже загальна витрата лінійна за контекстом. 128k — не «число побільше». Це 128× кешу вікна в 1k, виділеного на всю сесію.

Grouped-query attention (GQA) — знижка на боці моделі: менше KV-голов, стрункіший кеш. Qwen2.5 7B використовує 28 шарів і лише 4 KV-голови (config тут), тож те саме вікно 128k коштує близько 7 GiB у fp16 — справжнє полегшення і одна з причин, чому ці моделі дружні до скромних машин.

Модель (fp16)Шари × KV-головиKV-кеш @ 128kВагиКеш до ваг
Llama 3.1 8B32 × 8~16 GiB~16 GiB~100%
Qwen2.5 7B28 × 4~7 GiB~15 GiB~47%

Порахуйте самі — вся перевірка уміщається ось у цьому:

def kv_cache_gib(layers, kv_heads, head_dim, ctx, bytes_per=2):
    return 2 * layers * ctx * kv_heads * head_dim * bytes_per / 2**30

print(kv_cache_gib(32, 8, 128, 131_072))  # Llama 3.1 8B  -> 16.0
print(kv_cache_gib(28, 4, 128, 131_072))  # Qwen2.5 7B    -> 7.0

Про що маркетингова цифра мовчить

Ось чесна бухгалтерія цього аргументу — включно з місцями, де він гнеться:

  • Prefill — другий рахунок. До першого токена відповіді весь prompt обробляється разом. Prompt на 100k токенів — це 100k токенів пережувати до першого символу. На 3060 це хвилини, а не мілісекунди.
  • Sliding-window моделі ламають розрахунок — на вашу користь. Архітектури типу Mistral обмежують увагу фіксованим вікном на шар, і кеш перестає рости. Проста формула їх переоцінює. Цей текст — про трансформери з повною увагою, тобто більшість того, що люди запускають.
  • Квантування KV реальне, але часткове. llama.cpp вміє тримати KV у q8_0 — кеш приблизно вдвічі менший за певного ризику для якості. Половина від 16 GiB — це все ще 8 GiB.
  • У спеках рідко вказують KV-голови. Доведеться копатися в config.json — що саме по собі каже, як ця цифра задумана для читання.

Ніщо з цього не робить довгий контекст марним. RAG існує саме тому, що забивати вікно — дорогий спосіб сказати «прочитай розділ 4». Але картка, що друкує «128k» без рахунку за пам’ять, продає машину за максимальною швидкістю і ні словом про бензобак.

Ніхто не читає 128 000 токенів. Ваша RAM платить за них усе одно — за кожен.

Ліки нудні: виставляйте контекст за тим, що ваше навантаження реально використовує. Вікно 32k коштує чверть кешу 128k і покриває майже будь-який prompt, який розробник-одинак справді надсилає. Це та сама дисципліна обліку, що й в арифметиці RAM для локальних LLM: розмір моделі — лише половина бюджету, а рівні квантування стискають ваги, але розрахунок кешу не чіпають.

Якщо кеш — справжня ціна контексту, чому картки продають вікно і ніколи — рахунок? І раунд сповіді: який найбільший контекст ви реально заповнили до останнього токена — чи виправдав результат гігабайти? Коментарі відкриті; наступна частина серії стане на бік того, хто програв.

FAQ

Скільки RAM потребує вікно контексту 128k?

Для Llama 3.1 8B у fp16 сам лише KV-кеш важить близько 16 GiB при 131 072 токенах — приблизно стільки ж, скільки ваги моделі. Формула: 2 × шари × контекст × KV-голови × head_dim × байти.

Чому довгий контекст споживає більше пам'яті?

Кожен токен у кеші зберігає тензори ключів і значень для кожного шару уваги. Подвоїли контекст — подвоївся кеш. Алокація існує, навіть якщо вікно ви ніколи не заповните.

Як зменшити пам'ять KV-кешу в локальних LLM?

Виставте контекст за реальним використанням, беріть моделі з grouped-query attention (менше KV-голов), квантуйте KV-кеш у q8 там, де підтримує рантайм, або використовуйте sliding-window та гібридні архітектури.

— mrsaynothing

— mrsaynothing

Думки проходять навантажувальне тестування перед релізом. Здебільшого.

Наступний аргумент — на email

Один лист на пост. Погодьтеся — або рознесіть.

self-hosted · без третіх сторін · відписка в один клік

що це таке?

git stash: один файл, не чіпаючи решти

Читається добре? Таке я будую за гроші. найміть мене