Out-00136.safetensors seems to be corrupted with only 16bytes

while downloading

hf download mateogrgic/GLM-5.2-colibri-int4-with-int8-mtp --local-dir /colibri/glm52 the file out-00136.safetensors only downloads 16bytes not the usual tensor file 2.68Gbytes, check jlnsrk/GLM-5.2-colibri-int4 and mateogrgic/GLM-5.2-colibri-int4-with-int8-mtp and both show the same metadata with

curl -sIL “https://huggingface.co/mateogrgic/GLM-5.2-colibri-int4-with-int8-mtp/resolve/main/out-00136.safetensors” | grep -i content-length

content-length: 1004

content-length: 16 <— so it is not an HF download problem, it is either this file is only 16Bytes or there is a problem with this file in the server, anyone can share light into this ?

content-length: 16 <— so it is not an HF download problem, it is either this file is only 16Bytes or there is a problem with this file in the server, anyone can share light into this ?

Not sure. But, anyway, I was able to reproduce essentially the same phenomenon on my side. I still do not know all the details, such as whether this corresponds to an already known issue, but:


The 16-byte result appears to be real, and not merely a failed hf download.

Both repositories contain out-00136.safetensors as a 16-byte Hub object. The original upload commit records it with:

size:   16
sha256: 9bbcbf73561f6bc5d0a17ea6a2081feed2d1304e87602d8c502d9a5c4bd85576

See the original file-upload commit.

I also obtained the same file from both:

Both copies were exactly 16 bytes and had the SHA-256 above.

More importantly, those 16 bytes are not random truncated data. They are structurally consistent with a Safetensors file containing zero tensor entries. The current Safetensors Python library opens it successfully and returns:

[]

for the key list.

My current best explanation is therefore:

out-00136.safetensors is probably an empty output shard produced by the FP8-to-Colibri conversion process after every tensor in the corresponding source shard was excluded from the normal-model conversion pass.

That is strongly supported by the source checkpoint and the currently published converter logic, although it does not yet establish whether the empty file was intentionally retained as a placeholder, accidentally left as a conversion residue, or guaranteed harmless for every consumer.

Recommended default path

I would use the following decision first.

If your local file has this exact size and SHA-256

16 bytes
9bbcbf73561f6bc5d0a17ea6a2081feed2d1304e87602d8c502d9a5c4bd85576

then:

  1. Do not redownload the full 370–400 GB repository solely because of this file.
  2. Leave the 16-byte file in place for now.
  3. Verify the rest of the local repository against the Hub.
  4. Continue with Colibri’s read-only checks and then attempt normal startup.
  5. If loading fails, use the first actual missing-tensor or parser error as the next diagnostic signal.

For a local directory downloaded with --local-dir:

hf cache verify mateogrgic/GLM-5.2-colibri-int4-with-int8-mtp \
  --local-dir /colibri/glm52

The hf cache verify documentation says that it compares local files with the checksums stored on the Hub and can operate on either a cache snapshot or a regular local directory.

After that, from the Colibri c directory:

COLI_MODEL=/colibri/glm52 ./coli doctor
COLI_MODEL=/colibri/glm52 ./coli plan

These commands are documented in the Colibri README. doctor performs a read-only readiness check, while plan reads Safetensors headers and reports the intended RAM/storage placement without starting inference.

If the SHA-256 is different

Then this is a different branch of the problem. A 16-byte file with another hash could instead be:

  • a short proxy/CDN error response;
  • a locally overwritten file;
  • a stale or incomplete cache object;
  • a filesystem problem;
  • or another transfer-path failure.

In that case, investigate the transport/cache path separately rather than applying the empty-shard explanation below.

Minimal checks for Linux/macOS and PowerShell

Linux/macOS

cd /colibri/glm52

wc -c out-00136.safetensors
sha256sum out-00136.safetensors
xxd -g 1 out-00136.safetensors

Expected result:

16
9bbcbf73561f6bc5d0a17ea6a2081feed2d1304e87602d8c502d9a5c4bd85576

Expected bytes:

08 00 00 00 00 00 00 00 7b 7d 20 20 20 20 20 20

PowerShell

(Get-Item .\out-00136.safetensors).Length
(Get-FileHash .\out-00136.safetensors -Algorithm SHA256).Hash.ToLower()
Format-Hex .\out-00136.safetensors

Safetensors parser check

from safetensors import safe_open

path = "out-00136.safetensors"

with safe_open(path, framework="np") as f:
    print(list(f.keys()))

Expected output:

[]

According to the Safetensors format description, the first eight bytes are an unsigned little-endian header length, followed by a UTF-8 JSON object that may be padded with spaces.

Here:

08 00 00 00 00 00 00 00

declares an eight-byte JSON header, and the remaining bytes are:

{}      

That is an empty JSON object followed by whitespace padding.

So this is different from a file whose header was cut off midway. A more precise description would be something like “a parseable zero-key Safetensors file”, rather than simply “a corrupted 16-byte fragment.”

This only describes the file structure. It does not by itself prove that a zero-key shard was intended as part of the model package.

Why the converter appears able to produce exactly this file

I traced the likely source-shard mapping and compared it with the currently published Colibri converter.

1. The source model has 78 normal layers plus one next-token-prediction layer

The official GLM-5.2-FP8 configuration currently declares:

"num_hidden_layers": 78,
"num_nextn_predict_layers": 1

The extra prediction component uses names under:

model.layers.78.*

where the normal model layers are numbered 0 through 77.

2. out-00136 maps to source shard model-00137-of-00141

The current converter enumerates the source shard filenames in sorted order and writes:

out-00000.safetensors
out-00001.safetensors
...

Therefore zero-based output index 136 maps to:

model-00137-of-00141.safetensors

in the official FP8 repository.

I checked the official model.safetensors.index.json, and also independently read the actual Safetensors header of that source shard using HTTP byte ranges rather than downloading the approximately 5.36 GB tensor payload.

The two sources agreed exactly.

That source shard contains 852 tensor keys, and all 852 are under:

model.layers.78.*

The split was:

Type Count
FP8 weights 426
corresponding weight_scale_inv entries 426
total 852

3. The current normal conversion pass retains none of them

In the current classify() implementation, scale sidecars ending in _scale_inv are classified as consumed.

For normal conversion, a tensor whose layer index is greater than or equal to n_layers is classified as skip:

if name.endswith("_scale_inv"):
    return "consumed"

...

if li >= n_layers:
    return "skip"  # MTP layer (78)

Applying that currently published classification logic to the 852 source keys gives:

Classification Count
skip 426
consumed 426
retained in normal output 0

This is consistent with the design: layer 78 is handled separately by the converter’s MTP pass, which writes out-mtp-* files.

4. The normal shard loop still saves the empty output dictionary

The normal conversion loop currently does approximately this:

out = {}
convert_shard(..., out, ...)
save_file(out, outp)

The relevant code is in convert_fp8_to_int4.py.

There is no if out: check in the normal shard loop before save_file().

Interestingly, the separate indexer extraction path already does have such a check:

if out:
    save_file(out, outp)

Therefore, if a normal source shard contains only MTP tensors and their consumed scale sidecars, the following sequence is possible:

source shard contains 852 entries
        ↓
426 MTP weights classified as skip
        ↓
426 scale sidecars classified as consumed
        ↓
normal-pass output dictionary remains empty
        ↓
save_file({}) is still called
        ↓
16-byte zero-key Safetensors file

5. Saving an empty dictionary reproduces the exact object

Using the current Safetensors Python library:

from safetensors.numpy import save_file

save_file({}, "empty.safetensors")

produced:

size:   16
sha256: 9bbcbf73561f6bc5d0a17ea6a2081feed2d1304e87602d8c502d9a5c4bd85576

which is exactly the object present in both repositories.

6. Neighboring shards provide a useful control

The nearby outputs also behave consistently with the number of tensors retained by the normal conversion pass:

Output Retained source keys under current classification Published size
out-00134 426 about 2.69 GB
out-00135 137 about 0.89 GB
out-00136 0 16 bytes
out-00137 342 about 2.15 GB
out-00138 426 about 2.69 GB

Among all 141 source shards, this was the only one for which the currently published normal-pass classification retained zero keys.

Taken together, these observations make an empty conversion output substantially more likely than a random transfer failure.

Important limitation

The public model file was uploaded before the exact converter revision I inspected.

The model card says that the official Colibri converter was used without local modifications, but it does not record a converter commit SHA, command line, dependency versions, or the complete conversion log.

Therefore I think it is reasonable to say:

The published artifact and the currently published converter logic are strongly consistent with this mechanism.

I would not say:

This exact Git commit is proven to have generated the uploaded file.

The converter may have changed between the conversion run and the currently visible revision.

Practical decision tree

Branch A — size and hash match the known empty object

size = 16
sha256 = 9bbcbf...85576
keys = []

Recommended route:

  1. Keep the file.
  2. Do not redownload hundreds of gigabytes because of this object alone.
  3. Run hf cache verify against the complete local directory.
  4. Run coli doctor.
  5. Run coli plan.
  6. Attempt normal model startup.
  7. If startup fails, capture the first actual error and the tensor name involved.

This distinguishes a harmless/no-op file from a real missing-weight failure.

One subtle point: hf cache verify is a transport-integrity check. It answers:

Does my local file match the object currently published on the Hub?

It does not answer:

Was the converter’s published output semantically complete and ideally packaged?

For this particular file, checksum verification is expected to succeed because the Hub object itself is 16 bytes.

Branch B — size is 16 but the hash differs

Inspect its actual content first:

xxd -g 1 out-00136.safetensors
file out-00136.safetensors

Possible signs of a different problem include:

<?xml ...
{"error": ...
AccessDenied
Forbidden

Then collect environment information:

hf version
hf env

and retry only the affected file into a new empty directory:

mkdir /tmp/hf-one-file-test

hf download mateogrgic/GLM-5.2-colibri-int4-with-int8-mtp \
  out-00136.safetensors \
  --local-dir /tmp/hf-one-file-test

Only in this branch would I start comparing:

  • Xet enabled versus disabled;
  • VPN/proxy versus direct connection;
  • local filesystem versus network mount;
  • current versus old huggingface_hub/hf-xet;
  • stale cache versus clean directory.

Branch C — this file matches, but other shards fail verification

That would indicate two separate observations:

  1. out-00136 is the known 16-byte zero-key object.
  2. Some other files have an independent transfer or filesystem problem.

The empty-shard explanation should not be generalized automatically to every small, missing, or mismatched file.

Branch D — verification succeeds and Colibri starts

That would support the interpretation that the file is currently a no-op for this loader.

The current Colibri loader, in c/st.h, enumerates .safetensors files, parses each JSON header, and indexes the tensor names found in that object. An empty JSON object contributes zero tensor records.

This makes it plausible that the current loader simply ignores the file after parsing it.

However, successful loading would still not prove all of the following:

  • that the empty file was intentionally created;
  • that every older or future Colibri version handles it identically;
  • that every third-party tool accepts zero-key Safetensors;
  • that the file can always be deleted without affecting auxiliary scripts;
  • or that the repository packaging is ideal.

Because the file occupies only 16 bytes, leaving it untouched until the maintainer or uploader clarifies the intended contract seems safer than deleting it.

Branch E — Colibri reports a missing tensor

The useful evidence would then be:

  • the exact missing tensor name;
  • whether it belongs to model.layers.78;
  • whether a matching tensor exists in one of the out-mtp-* files;
  • the sizes and hashes of those MTP files;
  • and whether the normal and MTP files came from the same repository revision.

That would move the investigation from “this file looks unexpectedly small” to a concrete checkpoint-component mismatch.

Why this is different from the usual Git LFS, Xet, or interrupted-download cases

There are several common failure modes around large Hugging Face repositories, but they leave different evidence.

Git LFS pointer instead of model data

A Git checkout without functioning Git LFS can leave a small text file resembling:

version https://git-lfs.github.com/spec/v1
oid sha256:...
size ...

That is not what the downloaded 16-byte object contains.

The Hub commit page displays LFS/Xet-style object metadata for this file, including size 16, but the actual downloaded object is the 16-byte Safetensors header described above—not a textual LFS pointer.

Also, your command uses hf download, not git clone, so Git version and Git LFS installation are not the first explanation for this particular observation.

They would still be relevant for someone obtaining the same repository through a Git-based GUI or clone workflow.

Interrupted download

An interrupted multi-gigabyte download normally leaves:

  • a local size different from the Hub metadata;
  • a checksum mismatch;
  • an .incomplete cache object;
  • an IncompleteRead/timeout;
  • or a consistency-check error.

Here, the exact 16-byte object and hash are already recorded in the upstream commit.

Xet/CDN/proxy problems

Those problems are real and can be environment-dependent, but they become the leading branch only when the local bytes differ from the published object, or when other shards also fail verification.

curl -I -L | grep content-length

Your final content-length: 16 happened to point toward the real object size in this case.

As a general diagnostic, however, -L can print headers from several responses in the redirect chain. Extracting only Content-Length removes the HTTP status and the response to which each value belongs.

A more informative version would preserve the complete header chain, for example:

curl -sSIL \
  "https://huggingface.co/mateogrgic/GLM-5.2-colibri-int4-with-int8-mtp/resolve/main/out-00136.safetensors"

or show only selected fields while retaining status boundaries:

curl -sSIL \
  "https://huggingface.co/mateogrgic/GLM-5.2-colibri-int4-with-int8-mtp/resolve/main/out-00136.safetensors" \
  | grep -Ei '^(HTTP/|location:|content-length:|content-range:|x-linked-size:)'

In this investigation, the conclusion does not depend on interpreting the redirect headers because the upstream commit itself records the object as 16 bytes.

What appears known, and what remains unknown

Supported by directly reproducible evidence

  • The file exists as a 16-byte object in both repositories.
  • Both copies have the same SHA-256.
  • The current Safetensors parser opens it and finds zero keys.
  • Saving an empty tensor dictionary reproduces the exact bytes and hash.
  • The corresponding official FP8 source shard contains only layer-78 entries.
  • Under the current converter classification, all of those entries are skipped or consumed in the normal pass.
  • The current normal-pass loop saves the output even when it is empty.
  • The current Colibri loader appears capable of parsing an empty JSON header without adding a tensor.

Strong working hypothesis

The file is an empty normal-pass conversion residue caused by a source shard that contains only MTP tensors and their scale sidecars.

Still uncertain

  • Whether the converter author intentionally wanted numbered empty placeholders.
  • Whether the uploader noticed this file.
  • Which exact converter revision produced the published repository.
  • Whether all Colibri versions and auxiliary tools treat it as a no-op.
  • Whether omitting the file is officially supported.
  • Whether this exact case already has a dedicated issue or fix elsewhere.
  • Whether the model package should include a manifest explaining intentionally omitted/consumed tensors.

So I would currently describe this as:

A real and reproducible packaging/conversion artifact, with a strongly supported likely mechanism, but not yet a proven runtime-breaking model corruption.

Possible upstream improvements

None of these necessarily require treating the model as broken. They are possible ways to make the conversion output easier to audit and less surprising.

Option 1: Do not write zero-key normal shards

The normal conversion loop could mirror the existing indexer-path behavior:

if out:
    save_file(out, outp)

If output-file numbering must remain stable, the converter could instead log the skipped ordinal explicitly.

Option 2: Keep the placeholder, but document it

If the empty file is intentional, a log or model-card note could say something like:

out-00136.safetensors is intentionally empty:
all tensors in source shard model-00137-of-00141 belong to the separately converted MTP component.

That would immediately prevent users from interpreting it as a failed 2.68 GB download.

Option 3: Emit a conversion manifest

A useful manifest could record, per source tensor:

retained in normal model
converted into MTP output
converted into indexer output
consumed as a quantization sidecar
deliberately skipped

It could also record:

  • source repository and revision;
  • converter Git commit;
  • command-line arguments;
  • Python, NumPy, Torch, and Safetensors versions;
  • output filename and SHA-256;
  • source-to-output tensor mapping;
  • and zero-retained shards.

The Hugging Face serialization helpers provide a standard example of generating shards together with a weight_map derived from the actual tensor-to-file assignment: Hugging Face serialization helpers.

Colibri uses a custom runtime format, so it does not need to adopt the Transformers convention literally. The reusable idea is to derive the manifest from the actual output key set, rather than relying only on inherited source-shard ordinals.

Option 4: Add a warning or regression test

Possible converter output:

[137/141] model-00137-of-00141.safetensors
  retained: 0
  consumed: 426
  skipped: 426
  output not written

A regression fixture containing only layer-78 MTP tensors would make this corner case explicit.

coli doctor could also report a non-fatal warning for a zero-key Safetensors file:

warning: out-00136.safetensors contains no tensors

That would preserve compatibility while explaining the unusual object to future users.

There is also a separate, now-closed converter issue #355 concerning mode handling in another conversion path. It is not evidence that this exact empty-shard case has the same cause, but it is another reason to keep converter mode, output naming, and component separation explicit when interpreting generated repositories.

Bottom line

Your observation was valid: the file really is 16 bytes on the Hub.

If your local SHA-256 is:

9bbcbf73561f6bc5d0a17ea6a2081feed2d1304e87602d8c502d9a5c4bd85576

then I would treat it as the known zero-key object rather than a failed download, leave it in place, verify the remaining repository, and continue with coli doctor, coli plan, and normal startup.

The strongest current explanation is that the corresponding source shard contains only layer-78/MTP entries, all of which are excluded from the normal conversion pass, after which the empty output dictionary was still serialized.

What remains to be clarified upstream is not so much “why did Hugging Face truncate this file?” but rather:

Is this empty numbered shard an intentional part of the Colibri container contract, or should the converter skip it or document it explicitly?