Wchodzisz na Hugging Face po świeży model, otwierasz stronę i widzisz listę plików jak menu w barze mlecznym, w którym wszystko nazywa się prawie tak samo. Q4_K_M, Q5_K_S, Q6_K, Q8_0, IQ4_XS, gdzieś niżej jakiś BF16 na 30 gigabajtów. Wszystkie kończą się na .gguf, wszystkie są tego samego modelu, a ty stoisz i myślisz: dobra, ale który? I skąd się to w ogóle wzięło, skoro autor modelu wrzucił coś zupełnie innego?

To jest ten moment, w którym większość ludzi bierze na chybił trafił ten Q4_K_M, bo tak radzą na Reddicie, odpala i idzie dalej. I słusznie — działa. Ale pod tym jednym plikiem stoi cała cicha fabryka: ludzie, narzędzia, konwersje i format, który ktoś kiedyś usiadł i zaprojektował, żebyś ty mógł zrobić dwuklik. Warto wiedzieć, co tam mruczy pod maską — bo dzięki temu przestajesz zgadywać, a zaczynasz wybierać świadomie.

Co to w ogóle jest, ten GGUF

Zacznijmy od rozczarowania, bo lepiej od razu: GGUF to nie jest model. To nie nowa architektura, nie nowy sposób trenowania, nie magiczny AI od ggerganova. To pojemnik. Format pliku — dosłownie „GGML Universal File” — do trzymania modelu na dysku tak, żeby silnik inferencyjny mógł go szybko wczytać i zacząć gadać.1 Model (Llama, Qwen, Mistral — cokolwiek) rodzi się gdzie indziej, w treningu na klastrze, którego rachunku za prąd żaden z nas nie chciałby zobaczyć. GGUF to dopiero opakowanie, w które ten wytrenowany model się przepakowuje na koniec, pod kątem tego, że odpalisz go u siebie na jednej karcie.

Format wymyślił Georgi Gerganov, ten sam, który stoi za llama.cpp i biblioteką ggml.2 GGUF jest następcą kilku starszych formatów o równie uroczych nazwach — GGML, GGMF, GGJT — które po drodze się wykruszyły. I tu pierwsza pułapka, w którą łatwo wdepnąć: GGML i GGUF to nie synonimy. GGML to ten stary, w dużej mierze wyparty format pliku (i przy okazji wciąż nazwa biblioteki tensorowej pod spodem), a GGUF to jego młodszy, mądrzejszy brat z porządnymi metadanymi.1

Co siedzi w tym jednym pliku

To jest właśnie sedno, dla którego GGUF wygrał. Otwórz sobie w głowie taki plik jak pudełko z przegródkami:

  • Nagłówek — na samym początku cztery bajty GGUF (magic number, bajt po bajcie 0x47 0x47 0x55 0x46), zaraz za nimi numer wersji formatu, liczba tensorów i sterta metadanych.1
  • Metadane klucz-wartość — i tu robi się ciekawie. Zamiast beztypowej listy liczb jak w starych formatach, GGUF trzyma nazwane pola w hierarchii z kropkami: general.architecture, llama.context_length, general.quantization_version. Klucz general.architecture (czym ten model właściwie jest) musi być zawsze, a jak model jest skwantowany, to musi być też general.quantization_version.1
  • Tokenizer — w środku, w tym samym pliku. To jest ten myk, którego naprawdę brakowało wcześniej. GGUF potrafi wnieść cały tokenizer: natywne tablice tokenów, scores i merges, albo pełny tokenizer.json prosto z Hugging Face, albo szablony czatu w Jinja.1 Dlatego jeden .gguf wystarcza — nie musisz dociągać pięciu plików obok.
  • Same wagi — na końcu surowe dane tensorów, wyrównane do granicy (domyślnie co 32 bajty, klucz general.alignment), żeby silnik mógł je wczytać przez mmap bez mielenia całego pliku.1
Dlaczego to ważne dla lokalnego LLM

To „wszystko w jednym pliku” jest dokładnie tym, co robi z GGUF format do lokalnej inferencji. Ściągasz jeden plik i masz komplet: wagi, architekturę i tokenizer. Nie ma cyrku z dociąganiem config.json, tokenizer.json i trzech innych obok. Silnik typu llama.cpp bierze go przez mmap i startuje w sekundę, bez deserializacji. Mniej ruchomych części to mniej rzeczy, które ci się rozjadą o 23:00, gdy chcesz tylko o coś zapytać model.

Skąd biorą się wszystkie te warianty

No dobra, a czemu tego samego modelu jest dwadzieścia sztuk? Bo GGUF wspiera całą tęczę typów tensorów: pełną precyzję (F32, F16, BF16), serię K (Q2_K do Q6_K), stare legacy (Q4_0, Q8_0), nowszą serię IQ opartą na macierzy istotności (IQ4_XS, IQ2_XXS) i egzotykę w stylu ternarnego TQ1_0.1 Każdy z tych Q-ów to inny schemat ściśnięcia wag. Q4_K upycha wagę w jakichś 4,5 bita, Q6_K w 6,56, Q2_K w 2,63 — i to są dokładnie te przegródki, w których leży cały kompromis rozmiar/jakość/szybkość.2

I tu druga pułapka: te warianty to nie są różne modele. Q4_K_M, Q5_K_S, Q8_0 tego samego modelu to te same wagi bazowe, tylko skompresowane innym sitem. Grubszy plik = bliżej oryginału i wolniej, chudszy = mniej VRAM-u i szybciej, ale z lekkim ubytkiem jakości. Co ważne, to jest kwantyzacja post-training — bierzesz gotowy, wytrenowany model i ściskasz go po fakcie. Nie mylić z trenowaniem od zera w niskiej precyzji. W nazewnictwo tych literek zagłębialiśmy się osobno tutaj, bo to temat na własny wpis.

Kto to wszystko właściwie robi

Teraz najlepsze. Ten Q4_K_M, który ściągasz — bardzo często nie zrobił go autor modelu. Autor wrzuca zwykle wagi w safetensors i może jedną-dwie wersje GGUF, a resztę tego bufetu produkują ludzie z boku: community-quantizerzy. Konta jak bartowski czy mradermacher (dawniej głośny TheBloke) siedzą i masowo mielą cudze modele na wszystkie możliwe warianty, dzień po dniu, jak taka lokalna piekarnia GGUF-ów.

Jak to robią bez klastra? Dwiema drogami. Pierwsza to skrypt convert_hf_to_gguf.py prosto z repo llama.cpp — łyka wagi z Hugging Face i wypluwa GGUF, obsługuje kupę architektur (w tym multimodalne i MoE), ma opcje --outtype (bierzesz f16, bf16, q8_0… — czym te „szesnastki" różnią się od siebie, jest tu), --vocab-only, --split-max-size do krojenia wielkich plików, a nawet --remote, żeby konwertować prosto z Huba.3 Druga droga jest jeszcze leniwsza: ggml-org/gguf-my-repo, gotowy Space na Hugging Face, gdzie wklejasz repo, klikasz i dostajesz komplet kwantyzacji bez kompilowania czegokolwiek u siebie.4

# klasyczna droga: własny build llama.cpp
python convert_hf_to_gguf.py ./Qwen2.5-7B-Instruct \
  --outtype f16 --outfile qwen2.5-7b-f16.gguf
# a potem osobno kwantyzacja narzędziem llama-quantize do Q4_K_M itd.

Sam Hugging Face traktuje ten format jak pełnoprawnego obywatela: masz filtr library=gguf, który pokazuje wszystko, co gęgnięte (hf.co/models?library=gguf), a na stronie konkretnego pliku podejrzysz metadane i listę tensorów wprost z przeglądarki, bez ściągania.2 Praktyczny wniosek: skoro warianty sypie kto chce, sprawdzaj, czyje repo bierzesz. Zerknij na autora, na to, czy imatrix był użyty, czy karta modelu ma ręce i nogi. Na co patrzeć przy świeżym modelu rozkładaliśmy w osobnej notce.

GGUF kontra safetensors: to nie jest ranking

Skoro autor wrzuca safetensors, a ty odpalasz GGUF — który jest lepszy? Źle postawione pytanie. To dwa pojemniki do dwóch różnych rzeczy.

GGUFsafetensors
Co trzymawagi + architektura + tokenizer, w jednym plikutylko tensory, goła macierz liczb
Metadane / tokenizerw środkuosobno (config.json, tokenizer.json)
Kwantyzacjatak, to jego chleb (Q4_K_M, IQ…)zwykle pełna precyzja lub bf16/fp16
Pod co skrojonyinferencja przez llama.cpp/ggml, CPU/GPUtrening/inferencja w PyTorch, transformers, diffusers
Po co powstałjeden plik gotowy do odpaleniabezpieczna, szybka (zero-copy) alternatywa dla .bin/pickle

Safetensors narodził się z zupełnie innej potrzeby: żeby nie ładować cudzych wag przez pickle (który potrafi odpalić dowolny kod przy wczytaniu) i żeby robić to szybko, bez kopiowania w pamięci.5 To rekomendowany format wag na Hugging Face — ale trzyma wyłącznie tensory. Chcesz z niego odpalić model, musisz dorzucić config i tokenizer obok. GGUF ten cały komplet nosi w sobie i dokłada kwantyzację. Nie „lepszy/gorszy” — inne zadanie. Jak chcesz to potem faktycznie uruchomić garścią flag, jest o tym osobny poradnik.

Wróć do tego menu

Wróć teraz do tego menu na Hugging Face, do listy dwudziestu plików kończących się na .gguf. Już nie wygląda jak bar mleczny, w którym wszystko nazywa się tak samo. Widzisz teraz, że ktoś wziął model wytrenowany na drugim końcu świata, przepuścił go przez convert_hf_to_gguf.py, upchał wagi, architekturę i tokenizer do jednego pudełka z przegródkami, ścisnął sitem Q4_K_M i wrzucił na Huba, żebyś ty mógł go zassać jednym plikiem i usłyszeć, jak mruczy pod biurkiem. Cała ta cicha fabryka — od klastra treningowego, przez konto bartowskiego, po twój dysk — sprowadza się do jednego czterobajtowego napisu na początku pliku: GGUF. Reszta to już tylko ty i pytanie, który wariant dziś bierzesz.


  1. Specyfikacja formatu: struktura pliku, magic number GGUF (0x47 0x47 0x55 0x46), wersje 1–3, wyrównanie general.alignment, wymagane klucze metadanych, typy tensorów i osadzanie tokenizera, historia jako następca GGML/GGMF/GGJT — ggml-org/ggml, docs/gguf.md↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  2. Twórca formatu (@ggerganov), integracja z Hub (tag library=gguf, viewer metadanych i tensorów), narzędzie gguf-my-repo, porównanie z safetensors oraz tabela typów kwantyzacji z bitami-na-wagę — Hugging Face Hub docs, GGUF↩︎ ↩︎ ↩︎

  3. Mechanizm konwersji modeli HF do GGUF, obsługiwane architektury i opcje --outtype, --vocab-only, --split-max-size, --remotellama.cpp, convert_hf_to_gguf.py↩︎

  4. Narzędzie, którym community-quantizerzy konwertują i kwantyzują dowolne wagi HF do GGUF bez lokalnej kompilacji llama.cppggml-org/gguf-my-repo (Hugging Face Space)↩︎

  5. Definicja safetensors jako bezpiecznego (bez deserializacji pickle), zero-copy formatu przechowywania samych tensorów oraz jego rola w ekosystemie transformers/diffusers/candle — Hugging Face, dokumentacja safetensors↩︎