Eight GGUF builds of one model: the filename does not tell you what is inside

GGUF quant naming, audited across eight builds of one model. A file called UD-Q4_K_XL holds no Q4_K, and none had the silent experts people warn about.

0:00
Eight GGUF builds of one model: the filename does not tell you what is inside

Picking a local model has become a filename problem. You find the model you want, open the files tab, and choose between a dozen builds whose names differ by a few characters: Q4_0, Q4_K_M, UD-Q4_K_XL, MXFP4_MOE. The names look like specifications. We read the tensor tables of eight builds of the same model to see whether they behave like specifications, and one of them contains none of the format its filename advertises.

The model is Gemma 4 26B-A4B, a mixture-of-experts model with 128 experts and 8 active per token. We audited Google’s own release plus seven community builds carrying millions of downloads between them. No weights were downloaded. A GGUF keeps its header, metadata and complete tensor table at the front of the file, so a range request for the first 16 MB is enough to enumerate every tensor and its quantisation type. Eight builds cost about 128 MB of reading against roughly 140 GB of weights.

Do community MoE GGUF builds have silent experts?

We started because of a warning that circulates whenever a large mixture-of-experts model gets community quants: that uneven compression leaves some experts effectively dead, while the model card still reports the original expert count. For a MoE model that would be serious. The router would keep sending tokens to experts that no longer hold useful weights.

We found no evidence of it in any of the eight builds.

Every one reports expert_count: 128 and expert_used_count: 8 in its metadata. More to the point, the expert weights in this architecture are fused: each layer holds one ffn_gate_up_exps tensor and one ffn_down_exps tensor, and the expert dimension is a dimension of that tensor. In all eight builds, across all 30 blocks, that dimension is 128. There is nowhere for a dropped expert to hide. A build that had quietly lost experts would show a smaller dimension than its metadata claims, and none does.

That is a negative result and it is worth publishing as one. The claim is repeated confidently and it did not survive contact with the files.

The real problem is a different one, and we only found it because we were looking at the tensor tables anyway.

Why a file named UD-Q4_K_XL contains no Q4_K

unsloth’s gemma-4-26B-A4B-it-qat-GGUF repository offers a single build, gemma-4-26B-A4B-it-qat-UD-Q4_K_XL.gguf. The name follows a convention readers of quantised models know well: Q4_K is the K-quant family, and the XL suffix marks the most generous mix in that family.

The file contains 266 Q4_0 tensors and 392 F32 tensors. There is not a single Q4_K tensor in it. No Q5_K, no Q6_K either.

Bar chart: the UD-Q4_K_XL build holds 266 Q4_0 tensors, 392 F32 tensors and zero Q4_K tensors.
The build advertises a K-quant mix in its filename. Its tensor table holds none.

The file is not lying about itself. Read its metadata and it is candid: general.file_type is 2, which is Q4_0, and general.name reads “Gemma-4 26B-A4B IT (smart Q4_0, QAT-lossless)”. That is an accurate description. This is a quantisation-aware-trained model, so shipping it as Q4_0 rather than converting it to a K-quant mix is a defensible choice, arguably the correct one.

The gap is between the metadata and the filename. The metadata says Q4_0 and the filename says Q4_K_XL, and the filename is what appears in a download list, a model picker, and every guide that tells you which file to pull. Anyone selecting on the name is selecting on something the file does not claim about itself.

How much do GGUF builds of the same model differ?

Enough that “the same quant” is not a useful phrase.

Four of the eight builds are nominally the same thing: the Q4_0 QAT release. They differ anyway, in the small number of tensors each quantiser decides to protect at higher precision.

BuildBody tensorsPromoted tensor
google (official)205 Q4_01 at Q6_K
lmstudio-community205 Q4_01 at Q6_K
ggml-org205 Q4_01 at Q8_0
unsloth UD-Q4_K_XL206 Q4_0none

Three organisations, three answers, on a file they all describe the same way.

Widen to all eight and the expert tensors diverge further. Every build handles the two expert tensor classes separately, and almost none handles them the same way:

Buildffn_gate_up_expsffn_down_exps
google, lmstudio-community, ggml-org, unsloth UDQ4_0Q4_0
unsloth MXFP4_MOEMXFP4Q5_1
AtomicChat Q4_K_MQ4_KQ5_0 and Q8_0
AtomicChat Q2_KQ2_KQ4_0
bartowski IQ2_XXSIQ2_XXSIQ4_NL

Two patterns stand out. AtomicChat’s Q4_K_M does not use one type for ffn_down_exps; it promotes 14 specific layers to Q8_0 (blocks 0, 1, 2, 5, 8, 11, 14, 17, 20, 23, 26, 27, 28, 29) and leaves the other 16 at Q5_0. That is first three, last four, and roughly every third block in between: a deliberate schedule, and one nobody else in the set uses.

And quantisers disagree about which end of the network to protect. unsloth’s MXFP4 build promotes the final block, 29, in both expert classes. bartowski’s IQ2_XXS build promotes the first block, 0. Same architecture, opposite instincts.

The spread in how many distinct quantisation types a build uses is the cleanest summary:

Horizontal bar chart of distinct quantisation types per build, ranging from one to eight.
One build ships a single type across the whole file. Another uses eight.

None of this is misconduct. Every one of these choices is a reasonable engineering decision by someone who has thought about where precision matters. The point is narrower: the filename compresses all of it into a label, and the label is doing work it cannot support. Our own NVFP4 vs Q4_K_M piece ran into the same wall from the other direction, where a nominally 4.5-bit format shipped at 5.43 to 5.60 bits per weight because conversion was partial by design.

How to check a GGUF before you download it

The method costs about 16 MB per file and needs no special tooling.

A GGUF starts with the magic bytes GGUF, a version, a tensor count and a metadata count, followed by the metadata key-value pairs and then one record per tensor giving its name, shape, quantisation type and offset. All of it sits before the weights. An HTTP range request for the first chunk of the file gets you the entire table.

Three things are worth reading once you have it:

  • general.file_type and general.name. These often describe the file more honestly than its filename does, as they did here.
  • The type histogram. Count tensors by quantisation type. A file whose name promises a K-quant mix and whose histogram shows none is telling you something.
  • For a MoE model, the expert dimension. Confirm the fused expert tensors carry the expert count the metadata advertises, per layer, across every block.

One trap worth naming, because we fell into it. The tensor type is stored as an integer, and we mapped those integers from memory on the first pass. We had 39 as NVFP4, which made unsloth’s MXFP4 build look as though it contained no MXFP4. Checking llama.cpp’s ggml.h shows 39 is MXFP4 and 40 is NVFP4. The filename was accurate and our table was not. Read the enum from the source before drawing a conclusion from it. The same enum puts Q1_0 at 41, which confirms the type-41 tensors we found in the Bonsai 27B teardown.

The practical version of all this is short. If you are choosing between builds of a model you intend to rely on, and especially a mixture-of-experts model where the experts dominate the weights, spend the 16 MB. The tensor table answers in seconds what the filename only gestures at, and on current evidence the two do not always agree.

Share this