
> GGUF vs safetensors — the runtime decides, not the format▋
The same model in three containers: 397 MB of Q4_K_M GGUF, 1.20 GB of BF16 GGUF, 1.50 GB of BF16 safetensors. The bytes are the record's honest numbers — the runtime decides.
mrsaynothing· 14 October 2026· 6 min read
DuckDuckGo autocompletes gguf vs safetensors as if it were a cage fight between two file extensions. It is a gate check. Pick GGUF and one shelf of runtimes opens — llama.cpp, Ollama, LM Studio, Jan. Pick safetensors and a different shelf opens — transformers, vLLM, ComfyUI. The format is the list of doors that will open; everything else follows. The lie this piece refuses: that the fight is decided by speed numbers nobody has matched on the same box. What the record gives you for free — and what most arguments skip — is what each container weighs, and where each one can even be opened.
What are you actually choosing between?
GGUF is a single-file container built by the llama.cpp authors, and quantization is baked into it per tensor — the quantization ladder everyone argues about only exists inside this format. One file carries weights, tokenizer and chat template: the file is the distribution. Safetensors is a serialization container — a JSON header plus raw tensor bytes — and it carries whatever precision the training repo shipped, usually BF16 or FP16. It does not quantize; it stores.
Safetensors is named after its single job: making sure nobody gets pickled at model-load time. Python's pickle executes code on unpack; safetensors executes nothing — that is the whole security pitch, and it is why the Hugging Face ecosystem standardised on it.
Weigh the same model in each container and the philosophies show in the bytes. On 14 October 2026, the same Qwen3-0.6B shipped as: Q4_K_M GGUF, 396,705,472 bytes (397 MB) · BF16 GGUF, 1,198,182,848 bytes (1.20 GB) · BF16 safetensors, 1,503,300,328 bytes (1.50 GB). The quantized container holds a quarter of the full-precision one because it holds a quarter of the precision — and every one of those numbers is one curl -I away from your own terminal, no benchmark rig required. Whether the missing precision costs you quality is a fidelity question the bytes cannot answer; the quant levels piece covers what each rung gives up.
The format is not a preference. It is the list of runtimes that will open your file.
What do the bytes say?
The honest rule for a record-read piece: only numbers the record states, attributed, no bench cosplay. The table is one model, three containers, exact bytes as shipped — check them yourself before trusting any of it.
| Container | Precision | Bytes as shipped | Share of full-precision |
|---|---|---|---|
| GGUF Q4_K_M | 4-bit quantized | 396,705,472 (397 MB) | 26% |
| GGUF BF16 | full, llama.cpp packing | 1,198,182,848 (1.20 GB) | 80% |
| safetensors BF16 | full, raw tensors | 1,503,300,328 (1.50 GB) | 100% |
verify: curl -sIL https://huggingface.co/unsloth/Qwen3-0.6B-GGUF/resolve/main/Qwen3-0.6B-Q4_K_M.gguf | grep -i content-length → the byte count, same day or any day · same one-liner against the BF16 and safetensors files
Read the table the honest way. The 26% is the quantization ladder's whole promise: four bits where sixteen were, on disk and in RAM. The gap between the two full-precision rows — 1.20 against 1.50 GB — is packing overhead, not physics: llama.cpp's BF16 packing stores the same tensors leaner than the raw dump. What the bytes cannot say is speed or quality; a tokens-per-second column with no matched box behind it is forum noise, and this piece refuses to print one. The llama.cpp-versus-Ollama read hit the same wall from the engine side: same file, same math, different wrapper.
What the record cannot tell you
Three walls, stated plainly. One: quality — Q4 against BF16 is a fidelity trade, and no byte count measures it. Two: speed — load times and tokens per second belong to a matched bench on a named box, which this piece does not have, so it prints none. Three: scale — byte ratios from a 0.6B model hold shape at 70B, but the absolute waits you will feel at 70B are a different article on different hardware.
Where does each format actually run?
This is the part that actually decides. GGUF opens in llama.cpp, Ollama, LM Studio, Jan — the single-file local ecosystem. vLLM reads GGUF too, through its plugin, on GPU, with caveats. Safetensors opens in transformers, vLLM natively, ComfyUI, and Apple's MLX tooling. The overlap at the edges is instructive: Ollama — the appliance built on a GGUF engine — still ships an MLX runner so Apple Silicon users can load safetensors-derived weights. Even the appliance hedges.
| You already run | Your format picks itself | Why |
|---|---|---|
| Ollama, LM Studio or llama-server | GGUF | Their engines eat GGUF natively; quantized files fit small disks |
| A Python/transformers pipeline | safetensors | from_pretrained is the native path; no conversion step to maintain |
| vLLM on a GPU server | safetensors | Native, no plugin, no GGUF caveats — the GGUF caveats themselves |
| ComfyUI or an image pipeline | safetensors | The diffusion ecosystem trades in safetensors checkpoints |
| A small disk and a small box | GGUF Q4_K_M | 397 MB against 1.50 GB for the same weights |
GGUF makes quantization the default; safetensors makes full precision the default. That default is most of the decision.
Which one should you serve?
Check what is already installed before checking any table. If the machine answers to ollama run, you live in GGUF country — take the Q4_K_M file and stop reading forums. If your day is Python, or your serving layer is vLLM, safetensors was never really a choice; it is the ecosystem's native tongue. Converting between the two is possible and almost never worth it: every conversion is a new place for the weights to silently differ.
The mandatory honesty line, house style: I've read the record, not run it. Every number on this page comes from the files as shipped, pulled the morning this post went up — no bench rig, no tokens-per-second cosplay. What the record does establish is the shape of the trade — a quarter of the bytes for the quantized container, two runtimes that barely overlap, and a default precision on each side that quietly decides for most people. The whole cluster — runners, formats, quant levels, the lot — is indexed on the local-LLM hub.
Nobody ever switched format for speed. They switched runtime for a feature, and the format came along as the ticket.
So, two questions back over the wall: which format does your daily driver actually open — and what would a fair bench of these three containers look like on your hardware? Name the box and the model in the comments; the best-specified one sets the next piece's spec sheet.
$ Related entries · local llm
Jujutsu v0.46, reviewed: what changed and who should move
Second read of jj, two weeks on: v0.46.0 ships worktree colocation, the record grew 216 stars and the undo gap widened. What changed, what breaks, who moves.
2026-10-13 · 7 min read

vLLM GGUF FAQ: Ten Search Questions, Answered
Ten real search questions about vLLM and GGUF — CPU support, serve syntax, quant coverage, the tokenizer trap — answered from the docs and our tested posts.
2026-10-09 · 6 min read

llama.cpp vs Ollama — which one should you run?
The record read, not run: Ollama pins its llama.cpp engine at b11351 while upstream ships b11443. One is an appliance, one is the engine room.
2026-10-06 · 5 min read

GGUF VRAM Calculator: Check Before You Download
Model size, quant and context in — weights, KV cache and a per-card verdict out. The GGUF VRAM calculator answers will-it-fit before the download starts.
2026-10-02 · 4 min read
