All writing
War story · Lab

The BF16 file that was not BF16

We asked the converter for bf16 and named the file after our request. What came out was 96 percent MXFP4 by parameter count, and it cost us a failed quantize before anyone looked inside.

18 Oct 26 · 5 min · by Stephen Robinson

On 31 August a research pass over our model archive did something we do not do often enough: it measured files instead of reading their names. One of them was called DeepSeek-V4-Flash-0731-REAP-abl-BF16.gguf. It was 101,155,862,464 bytes, which is 94.21 GiB. A true BF16 file with 180 billion parameters would be about twice that.

The file was not BF16. Its header said general.file_type = 38, which in llama.cpp is MOSTLY_MXFP4_MOE. BF16 is 32. The name was wrong by a lot.

What was actually inside

We parsed the tensor table of the real file, not a sibling’s build log. It holds 1,328 tensors:

  • 641 in f32
  • 365 in q8_0
  • 190 in bf16
  • 129 in mxfp4
  • 3 in i32

The 129 mxfp4 tensors are the routed experts, and they are where nearly all the weight lives. By parameter count the file is 96.0 percent MXFP4 and 0.8 percent BF16. By bytes it is 90.9 percent MXFP4 and 2.8 percent BF16. Both numbers are correct. They use different denominators, and the work item had quoted the first one. The whole file averages 4.485 bits per weight, which is a quantized model, not a master.

How a flag turns into a lie

The model came from a pruned build whose source weights are fp8 safetensors (e4m3). We converted it with convert_hf_to_gguf and passed --outtype bf16. The output was named after that flag.

Our first theory, written into the research notes, was that the converter passed the fp8 tensors through without upcasting them. That was wrong, and the reason matters. The build log shows the converter doing something more active. It printed repacked routed experts to MXFP4, and it converted the float32 attn_output_a and attn_output_b tensors to Q8_0. The --outtype bf16 request was honored only for the 190 residual tensors that the converter had no special rule for.

So the flag is a request, not a guarantee. Source-driven special cases run first. The only truthful record of what you built is the file type in the header and the tensor histogram, and the filename is just whatever you typed.

The harm had already happened

It would be easy to file this as a cosmetic naming bug. The same build log says otherwise. On 5 August, someone ran a quantize step using this file as the source. It stopped at tensor 7 of 1,328 with:

requantizing from type q8_0 is disabled

The forge run ended with FORGE FAILED. A compute window was spent trying to quantize from a “master” that was already quantized. That one fact moved the ticket from a nice-to-have to a provenance error: a name asserting a precision the file did not have.

There were three such files, not one. A byte-identical copy sat in a rescue directory, and a pre-abliteration sibling in the same rescue area (101,155,862,496 bytes) had the identical defect. The fp8 safetensors beside them is not a true master either.

What we did not do

We did not rename anything, and we did not delete anything. Our archive rule is that files are deprecated and marked, not removed. There is also a practical reason: the build log and several records point at those exact names, so a rename would orphan them.

We also considered a registry row for the file and a forge-time naming guard, and measured our way out of both.

  • Registry row. The one existing registry entry that corrects a misleading directory name sits next to a README that still uses the word it was meant to retire. A correction in a database nobody reads at the point of use does not help the next person standing in the directory.
  • Naming guard. Nineteen artifacts carry BF16 in their name or path, but none of them references fp8, e4m3, or mxfp4. This model was the only fp8-sourced line we ever had, and we have since retired it for the cluster on throughput. A guard would fire on nothing.

What we did instead

A plain text marker beside each file, named <exact filename>.PROVENANCE.txt. The first line says the file is mislabeled. The body gives the measured size, the file type, the tensor census, the mechanism, and a pointer to the failed quantize.

We wrote a small script to place them. It defaults to a dry run. It refuses paths that go through the shared-share view of the array and insists on a direct disk path. It checks each target’s size and GGUF magic before writing, writes to a temp file and moves it into place, and asserts that the weight file’s size and modification time did not change. It has 18 tests.

We skipped sha256 in the markers on purpose. The archive host’s CPUs have no SHA instructions, and hashing three 94 GiB files would have taken about half an hour to answer a question nobody was asking. Byte size is enough identity here.

The live run printed three PLAN lines on the dry run and three WROTE lines on apply. All three weight files kept their original sizes and timestamps. One footnote on our own paperwork: the spec expected a particular count of provenance files on that disk, and the host showed a different one, one before and four after. The spec had counted across disks. The check ran on one. Small thing, but it is the same mistake in miniature: a number that was true somewhere else.

Lessons

  • After any conversion, read the file type and the tensor histogram before you name the output. Name the file after what was produced, never after the flag.
  • A model sourced from fp8 or natively quantized weights has no true BF16 master unless you dequantize it explicitly. Assume nothing.
  • When the cause in your notes says “passed through,” check whether it was actually transformed. Our first theory was close and still wrong, and the log had the answer the whole time.
  • Fix mislabels where people look, which is beside the file, and never with a rename that breaks every reference to it.
  • Measure before you build the systemic fix. Ours would have guarded a population of zero.
More from the journal

Everything here happened on the hardware this site is about. If this one was useful, the rest of the ledger is one click away.