Skip to content

loader: diagnose a missing core tensor instead of just naming it (#586)#614

Merged
JustVugg merged 1 commit into
JustVugg:devfrom
ZacharyZcR:fix/586-missing-tensor-diagnostics
Jul 25, 2026
Merged

loader: diagnose a missing core tensor instead of just naming it (#586)#614
JustVugg merged 1 commit into
JustVugg:devfrom
ZacharyZcR:fix/586-missing-tensor-diagnostics

Conversation

@ZacharyZcR

Copy link
Copy Markdown
Contributor

Picks up the gap you identified at the end of #586:

we think the error message itself is the real gap here β€” "missing model.norm.weight" gives you no way to know the container is just incomplete. We're looking at making the engine say that explicitly (how many shards/tensors it found, which core ones are missing, "looks like an incomplete download").

That thread took three rounds to reach the answer, and the reasoning that got there is mechanical enough for the engine to do itself: the final norm and lm_head are written into the last shards, so a truncated transfer indexes nearly every tensor and then dies on the first one from the gap.

What it prints now

out-NNNNN converter layout, truncated tail β€” @xbais's exact situation (125 files, out-00000..out-00121):

missing model.norm.weight

  indexed 4821 tensors from 125 shard file(s)
  shards numbered 00000..00121, 122 file(s) (contiguous: a gap would be at the tail)

  'model.norm.weight' is written into one of the LAST shards, so a container whose tail
  never arrived indexes almost everything and then fails exactly here.
  An incomplete transfer is far more likely than a corrupt engine. Re-running the
  download resumes only the missing shards; the HF xet backend is known to stall
  mid-transfer (#452), so disable it:
      HF_HUB_DISABLE_XET=1 hf download <repo> --local-dir <model-dir>
  If your shard count is already complete, that IS a bug worth reporting.

HF layout, where -of-NNNNN gives an authoritative total, so the gap is stated as a fact rather than an inference:

  indexed 4500 tensors from 122 shard file(s)
  shard filenames declare 144 shards, but only 122 are here -- 22 MISSING

The conclusion follows the evidence. With every declared shard present, advising a re-download would send the user round a loop that cannot help, so it flips:

  shard filenames declare 144 shards and 144 are here

  'model.norm.weight' is a core tensor the engine cannot run without, and every shard the
  filenames declare is present -- so this is NOT the usual truncated download.
  Either the container was built without this tensor, or the engine is looking
  for the wrong name. Please report it with this output.

Zero indexed tensors is a different failure wearing the same message, and is reported as one:

  No safetensors tensors were indexed at all. --model must point AT the
  container directory -- the one holding the *.safetensors shards.

Gaps in the middle print (GAPS in the numbering) rather than the tail inference, and a non-tail tensor name drops the "LAST shards" sentence, which would be false for an expert weight.

Scope

st_die_missing() in st.h, wired into ld() and the fatal branch of the expert-tensor load. The non-fatal probe branch at colibri.c:1488 keeps its one-line missing log on purpose β€” it runs per expert and must not flood. No loading behaviour changes; this only replaces fprintf + exit(1) on paths that were already fatal.

Verification

make -C c colibri ARCH=x86-64-v3 clean, make check 197 passed / 13 skipped.

The five reporting branches were exercised directly, by building a throwaway harness that includes st.h and hand-populates a shards struct (paths/n/nfd) for each layout β€” truncated out-* tail, HF -of- gap, complete HF container, mid-numbering hole with an expert tensor name, and zero tensors. The outputs above are that harness's real output, not hand-written samples. The harness is not part of this PR since it would need a Makefile target of its own; happy to add it as a proper test if you'd rather have the branches locked down in CI.

Not reproduced against a genuinely truncated 372 GB container β€” I don't have one β€” so the shard-arithmetic is verified against synthesised layouts, not a real interrupted download.

"missing model.norm.weight" told the user nothing about why, so JustVugg#586 took
three rounds of back-and-forth to land on the real cause -- a container
whose tail shards never downloaded. The maintainer's reasoning there is
mechanical enough for the engine to do it: the final norm and lm_head are
written into the LAST shards, so a truncated transfer indexes nearly every
tensor and then dies on the first one from the gap.

st_die_missing() reports what was actually found -- tensors indexed, shard
files read, and what the filenames say about completeness. The HF layout
declares its total in `-of-NNNNN`, so a gap is stated exactly ("declare 144
shards, but only 122 are here -- 22 MISSING"); the converter's out-NNNNN
layout has no total, but contiguous numbering still shows the gap must be at
the tail, which is the JustVugg#586 case.

The conclusion follows that evidence rather than always advising a
re-download: with every declared shard present it says so and asks for a bug
report instead, since re-downloading could not help. Zero indexed tensors is
reported as a --model path problem, which is a different failure wearing the
same message.

Wired into ld() and the fatal branch of the expert-tensor load. The
non-fatal probe path keeps its one-line "missing" log -- it is called per
expert and must not flood.

Refs JustVugg#586, JustVugg#583
@JustVugg
JustVugg merged commit 21e7a35 into JustVugg:dev Jul 25, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants