The model page said 8-bit. The checkpoint is 4.49 bits per parameter.
I was working out how much disk Kimi K3.1 Pro would need, and the model page gave me two numbers that cannot both be true. The card says MXFP4 weights / MXFP8 activations. The badge beside the download button says 8-bit
I was working out how much disk Kimi K3.1 Pro would need, and the model page gave me two numbers that cannot both be true. The card says MXFP4 weights / MXFP8 activations. The badge beside the download button says 8-bit precision. So I added up the shards I would actually pull and divided by the parameter count the platform reports, and got 4.49 bits per parameter.
That is not a rounding difference. 2.78 trillion parameters at 8 bits is 2,780 GB; at 4 bits it is 1,390 GB. The 96 shards in that repository come to 1,561 GB. So one of those three numbers is answering a question I did not ask, and if you are sizing a download or a disk you need to know which one it is.
The check is fifteen lines and it runs against the public API:
import json, urllib.request
REPO = "moonshotai/Kimi-K3.1-Pro"
api = json.load(urllib.request.urlopen(
f"https://huggingface.co/api/models/{REPO}?blobs=true"))
files = [f for f in api["siblings"]
if f.get("size")
and f["rfilename"].endswith(".safetensors")
and "/" not in f["rfilename"]]
weight_bytes = sum(f["size"] for f in files)
params = api["safetensors"]["total"]
print(f"{len(files)} shards, {weight_bytes / 1e9:,.1f} GB")
print(f"{params:,} weights, {weight_bytes * 8 / params:.4f} bits each")
Two details in it carry more weight than the arithmetic. ?blobs=true is what makes the endpoint return a size per file at all; without it you get file names and nothing to add up. And the "/" not in ... filter keeps only the shards sitting at the top of the repository, because plenty of repositories keep other copies of the same weights in subfolders. I will come back to that filter, because it is the line that saved me from a wrong answer I had already written down.
For Kimi K3.1 Pro it prints 96 shards, 1,561.3 GB, 2,780,110,363,392 weights, 4.4928 bits each.
Where the 1,561 GB goes
The number stops being mysterious once you subtract the three things a four-bit checkpoint always contains.
| what it is | bytes | GB |
|---|---|---|
| 4-bit weights, at half a byte each | 1,361,370,415,104 | 1,361.4 |
| tensors kept at 16 and 32 bits | 114,761,311,232 | 114.8 |
| block scales, one byte per 32 weights | 85,085,650,944 | 85.1 |
| the three terms together | 1,561,217,377,280 | 1,561.2 |
| the files on disk | 1,561,293,160,568 | 1,561.3 |
| left over | 138,589,683 | 0.139 |
Three terms take you to within 139 MB of the download, which is 0.009% of it. That is what convinced me the 4.49 is a reading of the checkpoint and not a misunderstanding of it: the dtype counts the platform publishes, half a byte per four-bit weight, plus the tensors it left alone, plus one scale byte per 32, lands on the file size.
The interesting part is the middle row. Some of that model is not four bit at all β 114.8 GB of it is kept at 16 and 32 bits, either because quantizing those layers costs quality nobody wanted to spend or because they are too small to be worth packing. Whatever the reason, a "4-bit model" is a description of the bulk, not of every byte.
And the card's parameter count holds up. The platform's counts add to 2,780,110,363,392, which is the card's 2.8T rounded. So the vendor and the platform agree on how many weights there are. They disagree only on what each one costs.
The number that talked me out of my own check
Before I pointed this at Kimi, I had it pointed at a model whose weights I already knew were four bit: openai/gpt-oss-120b. It printed 195.8 GB and 13.405 bits per parameter. That is nonsense on its face β 116.8 billion weights do not cost 13 bits each in a four-bit checkpoint.
The repository holds the same weights three times over: the mxfp4 shards at the top of the tree, original/ at 65.2 GB, and metal/ at 65.2 GB. Every one of them went into my sum. Restricted to the 15 top-level shards it is 65.2 GB, and 4.4680 bits per parameter, and the same three-term breakdown predicts 65.2 GB to the tenth.
The lesson is not "be careful with sums". A checkpoint repository is not a file, it is a directory that may contain several encodings of the same weights, so "how big is this model" has one answer per encoding, and my first instrument did not know which question it was answering. It reported a number three times too large with complete confidence, and it would have gone into this post if I had not had a second model to compare against.
The badge
Both of those repositories are tagged 8-bit by the platform. Neither is tagged 4-bit. gpt-oss-120b also carries mxfp4, so the same tag list will tell you both things about the same repository at the same time.
I do not know how the badge is computed, and I am not going to guess in a sentence that reads like a finding. What I can report is what it says on two checkpoints whose weights are unambiguously four bit, and on both of them it says eight. If the badge is reading the storage dtype, that would explain it: a packed four-bit weight sits inside an unsigned 8-bit container, so the dtype of the tensor is U8 even though two weights share a byte. That is a guess about somebody else's code, it is testable only from the inside, and I have marked it as a guess.
What I can say without guessing is that the badge is a summary, not a measurement of your download, and the arithmetic above is five lines.
What I did not do
I did not download 1.5 TB. I did not load the model. I have no throughput, no VRAM figure, no benchmark for it β every number here came from the two API responses this check reads, and from nothing else.
There is one soft spot in the accounting and it belongs in the post rather than in my notes. Block scales are not exposed per tensor in that API, so I assumed the common one byte per 32 weights. It fits to 0.009%, and I cannot tell from the outside whether that is a correct assumption or a lucky one. If some architecture uses a different block size, the middle of that table would drift and the total would still look plausible, which is the shape of error I like least.
What to do with it
If you are sizing a download, the number you want is the bytes under the path you will actually pull, divided by the weight count the card claims. Compare that to the precision the card names. When they disagree by a factor of two, you are reading two different claims, and the one that describes bytes on a disk is the one your disk will enforce.
The card is the vendor telling you how the model was trained. The badge is the platform telling you what it found in the files. Neither of them is lying here β an 8-bit activation scheme and a 4-bit weight scheme can both be true of the same model, and somewhere between those two facts the word "precision" stopped meaning one thing. Your disk does not have that problem. It will hold 1,561 GB or it will not, and no label changes the answer.
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.