Każda karta modelu lokalnego chłubi się dziś oknem 128k. Na desktopie ta liczba to umowa najmu, którą twój RAM podpisuje bez czytania. O tym, jak daleko przepchniesz długi dokument, nie decydują wagi — decyduje cache KV, a on skaluje się z kontekstem jak podatek ustalony w cudzej walucie.
Okno kontekstu nie jest funkcją, którą się włącza. To najem pamięci, który płacisz przez każdą sekundę działania serwera.
Ile RAM naprawdę kosztuje kontekst 128k?
Arytmetyka jest publiczna i krótka. Jak rozkłada Transformer Inference Arithmetic, cache KV trzyma dwa tensory — klucze i wartości — dla każdej warstwy, każdej głowicy KV, każdego tokenu:
cache_bytes = 2 × warstwy × kontekst × głowice_kv × head_dim × bajty_na_element Weź Llama 3.1 8B: 32 warstwy, 8 głowic KV, head_dim 128, prosto z config.json na Hugging Face. Przy 131 072 tokenach w fp16 (2 bajty):
2 × 32 × 131072 × 8 × 128 × 2 = 17 179 869 184 bajtów ≈ 16 GiB Wagi tego samego modelu w fp16 ważą około 16 GiB. Przy maksymalnym kontekście cache jest tak duży jak model, do którego należy. „Model 8B, który mieści się w 16 GiB” po cichu staje się problemem 32 GiB w chwili, gdy podnosisz num_ctx do 128k.
Dlaczego cache rośnie wraz z oknem?
Bo uwaga musi porównać każdy token ze wszystkimi przed nim, a inferencja jest autoregresyjna — nic nie liczy się od nowa, wszystko się pamięta. W tym cały trik, który czyni generację szybką: klucze i wartości każdego tokenu liczone są raz i zapisywane. Zapotrzebowanie na token jest stałe, więc całość rośnie liniowo z kontekstem. 128k to nie „większa liczba” — to 128× cache okna 1k, alokowany na całą sesję.
Grouped-query attention (GQA) to zniżka po stronie modelu: mniej głowic KV, smuklejszy cache. Qwen2.5 7B ma 28 warstw i tylko 4 głowice KV (config tutaj), więc to samo okno 128k kosztuje około 7 GiB w fp16 — realna ulga i jeden z powodów, dla których te modele wydają się łagodniejsze dla skromnych maszyn.
| Model (fp16) | Warstwy × głowice KV | Cache KV @ 128k | Wagi | Cache vs wagi |
|---|---|---|---|---|
| Llama 3.1 8B | 32 × 8 | ~16 GiB | ~16 GiB | ~100 % |
| Qwen2.5 7B | 28 × 4 | ~7 GiB | ~15 GiB | ~47 % |
Policz sam — to cała weryfikacja:
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 Czego liczba z marketingu nie mówi
Oto uczciwy rejestr tego argumentu — łącznie z miejscami, w których się wygina:
- Prefill to drugi rachunek. Zanim pojawi się pierwszy token odpowiedzi, cały prompt przetwarzany jest naraz. Prompt 100k tokenów to 100k tokenów do przeżucia przed pierwszym znakiem. Na 3060 to minuty, nie milisekundy.
- Modele sliding-window łamią rachunek — na twoją korzyść. Architektury pokroju Mistral ograniczają uwagę do stałego okna na warstwę, więc cache przestaje rosnąć. Prosty wzór je przelicza. Ten tekst dotyczy transformerów z pełną uwagą — czyli większości tego, co ludzie odpalają.
- Kwantyzacja KV jest realna, ale częściowa. llama.cpp może trzymać KV w q8_0, tniąc cache mniej więcej o połowę przy pewnym ryzyku jakości. Połowa z 16 GiB to wciąż 8 GiB.
- Specyfikacje rzadko podają głowice KV. Trzeba ich szukać w config.json — co samo w sobie mówi, jak ta liczba ma być czytana.
Nic z tego nie czyni długiego kontekstu bezużytecznym. RAG istnieje właśnie dlatego, że zapełnianie okna to drogi sposób powiedzenia „przeczytaj sekcję 4”. Ale karta, która drukuje „128k” bez rachunku za pamięć, sprzedaje auto za prędkość maksymalną i nigdy nie wspomni o baku.
Nikt nie czyta 128 000 tokenów. Twój RAM i tak za nie płaci — za każdy z osobna.
Remedium jest nudne: ustaw kontekst na to, czego twoja praca naprawdę używa. Okno 32k kosztuje jedną czwartą cache 128k i pokrywa niemal każdy prompt, jaki pojedynczy developer faktycznie wysyła. To ta sama dyscyplina rejestru co w arytmetyce RAM dla lokalnych LLM — rozmiar modelu to połowa budżetu, a poziomy kwantyzacji kurczą wagi, ale rachunki cache nie ruszają.
Skoro cache to prawdziwa cena kontekstu, dlaczego karty sprzedają okno i nigdy rachunku? I runda spowiedzi: jaki największy kontekst wypełniłeś naprawdę do ostatniego tokenu — i czy wynik usprawiedliwił gigabajty? Komentarze otwarte; kolejna część serii wejdzie w buty stronie przegranej.
FAQ
Ile RAM zużywa okno kontekstu 128k?
Dla Llama 3.1 8B w fp16 sam cache KV waży około 16 GiB przy 131 072 tokenach — mniej więcej tyle, co wagi modelu. Wzór: 2 × warstwy × kontekst × głowice KV × head_dim × bajty.
Dlaczego długi kontekst zużywa więcej pamięci?
Każdy token w cache przechowuje tensory kluczy i wartości dla każdej warstwy uwagi. Podwajasz kontekst — podwaja się cache. Alokacja istnieje, nawet jeśli nigdy nie wypełnisz okna.
Jak zmniejszyć pamięć cache KV w lokalnych LLM?
Ustaw kontekst na to, czego naprawdę używasz, wybieraj modele z grouped-query attention (mniej głowic KV), kwantyzuj cache KV do q8 tam, gdzie runtime wspiera, albo sięgaj po architektury sliding-window i hybrydowe.
— mrsaynothing
— mrsaynothing
Opinie load-testowane przed publikacją. Zwykle.
Otrzymaj następny argument mailem
Jeden mail na wpis. Zgódź się albo rozbierz na części.
co to jest?git stash: jeden plik bez gubienia reszty
Podobają się teksty? Tak buduję zawodowo. zatrudnij mnie