Кожна картка локальної моделі тепер хизується вікном у 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 8B | 32 × 8 | ~16 GiB | ~16 GiB | ~100% |
| Qwen2.5 7B | 28 × 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
Один лист на пост. Погодьтеся — або рознесіть.
що це таке?git stash: один файл, не чіпаючи решти
Читається добре? Таке я будую за гроші. найміть мене