Wymagania: 16 GB VRAM. Zjeżdżasz na dół karty modelu, widzisz to jedno zdanie, zerkasz na
swoją kartę do gier z jej ośmioma gigabajtami — z czego połowę i tak zżera przeglądarka — i
serce ci lekko siada. A bywa gorzej: czasem nawet tej jednej liczby nie ma, jest za to tabelka
z dwudziestoma wariantami pliku, każdy waży inaczej, i dalej nie wiesz, czy w ogóle podchodzić,
czy zaraz przywita cię „CUDA out of memory", cała na biało. To codzienność — połowa pytań „will it fit?" to ludzie, którzy kupili
GPU do gier, a teraz próbują wcisnąć na nie model wielkości małego miasta.
Dobra wiadomość: nie musisz zgadywać. VRAM da się policzyć na palcach, z grubsza, w głowie,
zanim cokolwiek ściągniesz. Nie do grama — do grama policzy ci llama.cpp przy starcie —
ale na tyle dokładnie, żeby wiedzieć, czy w ogóle podchodzić. O to cała sztuka:
zamiast wróżyć z rozmiaru pliku, umieć powiedzieć „7B w Q4 to jakieś pięć giga plus
zapas, wejdzie" — i mieć rację.
Wzór na palcach
Cały fundament mieści się w jednej linijce:
rozmiar wag (GB) ≈ liczba parametrów (mld) × bity na wagę / 8
I tyle. Bierzesz, ile model ma miliardów parametrów, mnożysz przez to, ile bitów zajmuje
jedna waga w danym formacie, dzielisz przez osiem (bo bajt ma osiem bitów) i masz gramaturę
samych wag w gigabajtach. Model 8B w kwantyzacji Q4, gdzie na wagę schodzi jakieś 4,5 bita?
8 × 4,5 / 8 ≈ 4,5 GB. I to nie jest teoretyczna wróżba — realny plik Q4_K_M dla
Llamy 3.1 8B waży 4,92 GB.1 Zgadza się co do joty, a właściwie co do paru setek megabajtów.
To „bity na wagę" (po angielsku bits-per-weight, bpw) to sedno całej zabawy z kwantyzacją.
Surowy model trenuje się zwykle w 16 bitach na wagę. Kwantyzacja to nic innego jak zapisanie
tych samych wag ciaśniej — w 8, 5, 4, a nawet 2 bitach — już po treningu, bez ruszania
architektury. Nie myl tego z trenowaniem od zera w niskiej precyzji; to dwie różne bajki.
Jak działają nazwy w stylu Q4_K_M i skąd te dziwne litery, rozgryzaliśmy osobno
tutaj.
Skąd biorą się ułamkowe bity
Tu pierwsza pułapka, na którą łapie się każdy początkujący: „Q4 to przecież cztery bity,
nie?". No właśnie nie do końca. Gdyby świat był prosty, Q4_0 (stary, prościutki typ)
brałby równe 4,5 bita na wagę — bo pakuje 32 wagi w blok i dokłada do nich trochę metadanych
o skali.2 Ale nowsze formaty, tak zwane K-quanty (Q2_K do Q6_K, z dopiskami _S,
_M, _L), są sprytniejsze: mieszają precyzję między różnymi warstwami modelu. Te tensory,
od których jakość naprawdę zależy, dostają więcej bitów, reszcie się skąpi. Efekt? Liczba
bitów na wagę wychodzi ułamkowa.
Konkretnie, dla Llamy 3.1 8B według oficjalnej tabeli llama.cpp:2
| Format | Bity na wagę | Rozmiar (tabela llama.cpp) | Realny plik GGUF |
|---|---|---|---|
Q4_K_M | 4,8944 | 4,58 GiB | 4,92 GB |
Q5_K_M | 5,7036 | 5,33 GiB | 5,73 GB |
Q6_K | ~6,5 | — | 6,60 GB |
Q8_0 | ~8,50 | — | 8,54 GB |
F16 | 16,0005 | 14,96 GiB | — |
Widzisz tę drobną rozbieżność między kolumnami? Jedna to GiB (liczone po 1024), druga GB
(po 1000), plus K-quant miesza precyzję tensorów — stąd Q4_K_M ma prawie 4,9 bita, a nie
równe 4,5.1 Do liczenia na palcach nic to nie zmienia: bierzesz „mniej więcej 4,5–5
bita dla Q4" i tak trafiasz w wynik z dokładnością do zapasu, który i tak musisz zostawić.
Jest jeszcze cała rodzina IQ-quantów (IQ2_XXS, IQ3_S i spółka), które schodzą poniżej
trzech bitów, ważąc jakość specjalną macierzą istotności — ale to temat na osobny wieczór.2
Ile zważy „ten twój" model
Przełóżmy wzór na cztery rozmiary, które realnie krążą po lokalnym światku. To są same wagi, bez narzutu — o narzucie za chwilę:
| Model | Q4_K_M | Q5_K_M | Q8_0 |
|---|---|---|---|
| Llama 3.1 8B1 | 4,92 GB | 5,73 GB | 8,54 GB |
| Mistral Nemo 12B3 | 7,48 GB | 8,73 GB | 13,02 GB |
| Qwen2.5 14B4 | 8,99 GB | 10,51 GB | 15,70 GB |
Popatrz na to przez chwilę, bo tu widać całą matematykę życia lokalnego LLM-owca. Masz kartę 8 GB? Ósemka w Q4 wchodzi na luzie, w Q5 już z zadyszką, a Q8 nawet nie podchodź. Dwunastka w Q4 to 7,5 GB samych wag — teoretycznie „się mieści", tylko że na sam narzut nie zostaje już nic. A czternastka w Q4 to prawie dziewięć giga — twoje 8 GB kończy się, zanim się zaczęło. Dlatego „te swoje 8 GB" znika tak szybko: liczysz gramaturę wag, cieszysz się, że wchodzi, a potem uruchamiasz i okazuje się, że o czymś zapomniałeś.
Czego zapominasz: KV-cache i bufory
O to zapominasz. Rozmiar pliku GGUF to tylko wagi. Do tego dochodzi KV-cache — pamięć, w której model trzyma przetworzone klucze i wartości dla każdego tokena, który model już wygenerował lub wczytał z promptu. I to jest ten cichy złodziej VRAM-u, bo rośnie liniowo z długością kontekstu. Im dłuższa rozmowa, tym większy żłób na pamięć.
Ile dokładnie? Też się liczy na palcach. Na jeden token przypada:
KV na token = 2 (klucz + wartość) × liczba_warstw × n_head_kv × head_dim × bajty_na_element
Dla Llamy 3.1 8B te liczby to: 32 warstwy, n_head_kv = 8, head_dim = 128, a KV-cache
domyślnie leci w f16, czyli 2 bajty na element5 (co to za f16 i czemu nie bf16 — tu). Wrzuć to do wzoru:
2 × 32 × 8 × 128 × 2 bajty = 128 KiB na token. Przy kontekście 8192 tokenów robi się z tego
równiutki 1 GiB — tyle dokłada sam cache do tego, co już zjadły wagi. Rozbieramy ten mechanizm
dokładniej tutaj, ale zasada do zapamiętania jest prosta: dłuższy
kontekst = więcej VRAM-u, po prostu.
Zwróć uwagę na n_head_kv = 8 — pełna liczba głów uwagi w tym modelu jest większa, ale dzięki
GQA (grouped-query attention, mechanizm współdzielenia głów klucza/wartości) do cache liczy się
tylko ta zredukowana ósemka. Bez GQA, na starej architekturze, ten narzut potrafił być
wielokrotnie większy. Do tego dochodzą jeszcze bufory obliczeniowe samego procesu inferencji.
Dlatego świętą zasadą jest: zostaw 1–2 GB zapasu ponad rozmiar wag. Kto liczy VRAM tylko
z gramatury pliku GGUF, ten regularnie ląduje na „out of memory" przy trzecim akapicie rozmowy.
Jak zejść niżej, gdy nie wchodzi
Powiedzmy, że policzyłeś i wychodzi za dużo. Masz trzy dźwignie, w tej właśnie kolejności.
Raz — kwantyzacja niżej. To najprostszy ruch: zamiast Q8 bierzesz Q5, zamiast Q5 bierzesz Q4. Czternastka w Q8 to 15,7 GB, a w Q4 już tylko 8,99 GB4 — prawie połowa mniej, a jakość spada zaskakująco mało, bo K-quanty oszczędzają mądrze. Q4_K_M to nie bez powodu domyślny wybór połowy internetu.
Dwa — kwantyzacja KV-cache. Skoro cache potrafi dołożyć giga przy dłuższym kontekście, to
jego też można ścisnąć. llama-server ma na to flagi -ctk / --cache-type-k i -ctv /
--cache-type-v, osobno dla kluczy i wartości; domyślnie oba stoją na f16, ale przyjmują też
q8_0, q4_0 i całą listę innych typów.6 Ściśnięcie cache z f16 do q8_0 to znów
zejście z jego rozmiaru mniej więcej o połowę.
llama-server -m qwen2.5-14b-instruct-q4_k_m.gguf \
-ngl all -c 8192 -fa on \
-ctk q8_0 -ctv q8_0
Widzisz to -fa on? To nie ozdoba. Flaga -fa / --flash-attn (przyjmuje on/off/auto,
domyślnie auto) włącza Flash Attention — a kwantyzacja KV-cache do typów poniżej f16
praktycznie wymaga włączonej Flash Attention.6 Ustawisz -ctk q4_0 bez -fa on i
w najlepszym razie nic nie zyskasz, w najgorszym nie ruszy. Więc: najpierw Flash Attention,
potem duś cache.
Trzy — przytnij kontekst albo zrzuć część warstw na CPU. To ostateczność, bo krótszy
kontekst to mniejsza pamięć modelu, a offload na CPU (flaga -ngl z liczbą mniejszą niż
„wszystko") spowalnia generację. Ale gdy 12B w Q4 nie chce wejść na 8 GB nawet po ściśnięciu
cache — czasem to jedyny sposób, żeby w ogóle ruszyło. Cała ta chirurgia flagami to osobny
rozdział, który rozpisaliśmy tu.
Zrób to sam: rachunek w trzy sekundy
Następnym razem, gdy staniesz przed nowym modelem, przelicz go w głowie, zanim klikniesz pobieranie:
- Wagi:
parametry × bity / 8. Ósemka w Q4 →8 × 4,5 / 8 ≈ 4,5 GB. Albo zerknij na realny plik na Hugging Face i weź gotową liczbę. - Cache: przy zwykłym kontekście (4–8k) dorzuć z grubsza 0,5–1 GB dla modelu klasy 7–14B
z GQA. Planujesz 32k albo więcej? Licz się z kilkoma gigabajtami i od razu myśl o
-fa onplus-ctk q8_0. - Zapas: dorzuć 1–2 GB na bufory i oddech.
Suma większa niż twój VRAM? Schodzisz z kwantyzacją albo duszisz cache — w tej kolejności. Suma mniejsza? Ściągaj śmiało, wejdzie.
Bo cała sztuka z VRAM-em nie polega na wróżeniu, tylko na tym jednym prostym mnożeniu na
palcach — parametry razy bity, przez osiem, plus zapas. Kiedy raz je poczujesz, folder models
przestaje być loterią, a zaczyna być tym, czym powinien: półką, na której z góry wiesz, co się
zmieści, a co poleży, aż dokupisz kartę „na później". A dokupisz. Wszyscy dokupujemy.
Przypisy · źródła
Realne rozmiary plików GGUF dla Meta-Llama-3.1-8B-Instruct (
Q4_K_M= 4,92 GB,Q5_K_M= 5,73 GB,Q6_K= 6,60 GB,Q8_0= 8,54 GB), bartowski/Meta-Llama-3.1-8B-Instruct-GGUF. ↩︎ ↩︎ ↩︎llama.cpp, tabela typów kwantyzacji z wartościami bits-per-weight i rozmiarami dla Llama 3.1 8B (
Q4_K_M= 4,8944 bpw / 4,58 GiB,Q5_K_M= 5,7036 bpw / 5,33 GiB,F16= 16,0005 bpw / 14,96 GiB;Q4_0= 4,5 bpw), tools/quantize/README.md. ↩︎ ↩︎ ↩︎Realne rozmiary plików GGUF dla Mistral-Nemo-Instruct-2407 (12B):
Q4_K_M= 7,48 GB,Q5_K_M= 8,73 GB,Q8_0= 13,02 GB, bartowski/Mistral-Nemo-Instruct-2407-GGUF. ↩︎Realne rozmiary plików GGUF dla Qwen2.5-14B-Instruct:
Q4_K_M= 8,99 GB,Q5_K_M= 10,51 GB,Q8_0= 15,70 GB, bartowski/Qwen2.5-14B-Instruct-GGUF. ↩︎ ↩︎llama.cpp, parametry KV-cache dla Llama 3 8B (
n_layer= 32,n_head_kv= 8,head_dim= 128,n_embd_k_gqa/v_gqa= 1024) i potwierdzenie domyślnego typu cachef16, GitHub Discussion #7949 — KV Cache Dimension. ↩︎llama.cpp, opis flag
llama-server:-ctk/--cache-type-k,-ctv/--cache-type-v(domyślnief16, dozwolone m.in.q8_0,q4_0) oraz-fa/--flash-attn(on/off/auto, domyślnieauto); kwantyzacja KV-cache poniżejf16wymaga Flash Attention, tools/server/README.md. ↩︎ ↩︎