feat(MODEL-MM-dots3-note): W2 — the whole 38006-tensor index, with the towers named as deferrals (#699) - #1847
Merged
Merged
Conversation
localai-bot
force-pushed
the
row/MODEL-MM-dots3-note-W2
branch
2 times, most recently
from
August 24, 2026 13:15
fccc4da to
9843fe3
Compare
…e towers named as deferrals (#699) W1 accounted 1614 tensors over a four-layer slice of the released shard index and left the other 36392 unread. This reads the index in full and joins it to the safetensors header of all 133 files it names. The buckets are 35381 language, 2195 vision and 430 audio, and every case states all three by number. "Nothing was left over" is also true of a classifier that counts the towers as language, which is the mutation the #1805 review found passing. At W1's scale that was a latent hole. At this scale it would make "100% accounted" cover 2625 weights nobody loads. A deferral is now a record, not a counter. `Dots3NoteDeferredTowers()` names the prefix, the one file each tower ships in, the brick that owes it and what it is, and the classifier dispatches on that table instead of on two prefix literals. The load refusal prints the table, so a reader can tell an unknown tensor from a deferred one. Three facts the slice could not reach. The backbone has exactly four distinct layer shapes, so the 1/2 repeat holds and no layer breaks it. The full and sliding split derived from the shipped indexer tensors matches `config.layer_types` exactly, which is two independent sources agreeing. And the checkpoint carries 62 F32 tensors in two families, not one: the 45 language `e_score_correction_bias` W1 predicted, and 17 vision `router_bias` tensors it could not see. The released index also states `indexer_rope_layout: "leading"` and `indexer_rope_converted_from: "tail"` in its metadata block. Upstream never reads either key. W3 owes the consumption, so the finding is pinned in an assertion rather than left in a report. No tensor byte was downloaded. The fixture is a headers-only projection built from 266 HTTP Range requests over the 133 shard headers, 4770592 bytes in total, against a checkpoint of 576886825984. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
…d and what it found (#699, #1846) The spec, the matrix row and the feature table all still said the name map was 1614 tensors over a four-layer slice. It is 38006 over the whole released index, so the records say that instead. Spec §4.4 is the new evidence section: what was fetched and how much of it, the three facts the slice could not reach, and the one finding. The finding gets its own issue. The released index declares `indexer_rope_layout: "leading"` and `indexer_rope_converted_from: "tail"` in its metadata block, and no upstream code reads either key. W3 slices the indexer head, so W3 owes it, and #1846 says so where a W3 implementer will look. The porting inventory records that W2 re-read its own upstream anchors at `185cada36b` rather than inheriting W1's revision. That is what its own point (b) asks for, because upstream is still moving here. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
… not see (#699) The mutation run came back RED on 14 rows and GREEN on one. Deleting the `VT_CHECK` that refused a language name inside a deferred tower left the whole gate passing, because no config can make `EnumerateDots3NoteTensors` emit a `vision_encoder.` or `audio_encoder.` name. Every name it emits is `model.`- or `lm_head`-prefixed by construction. An assertion no input can reach is not a guard. The invariant is real, so the tower case asserts it over the real map, and a replacement mutation adds a vision tensor to the name map and takes the gate red on five cases. The rest of the change is runtime. The gate ran for 3m17s at -O0, and the cost was not the assertion count: each whole-tower `CHECK_THROWS_WITH_AS` re-runs a 35381-tensor load. The refusal cases now load once and read the message, and the two hot per-tensor loops report one assertion per defect class with the first offender named. That also stops a single classifier defect printing 2197 failure lines. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
… towers ship (#699) Spec §4.4 gains the evidence the W2 entry already pointed at. Fifteen mutations, every one applied to the tracked source or the committed fixture, rebuilt, run and reverted with the tree verified byte-for-byte. Every row compiled and every row went red, and the compiler exit status sits beside each one, because a mutation that fails to build reads as a passing test. Two rows carry a story rather than a number. One guard came back green and was deleted rather than kept, and a replacement mutation injects the defect it was meant to catch. One row exited 135 with no summary on a box at 92% disk; re-run alone it compiled clean and went red on five cases, and both readings are on record because a crash is not a red test. The section also states what the two towers ship, for the bricks that own them. W2 does not port either one, but it read their whole tensor list, and a few of those facts would otherwise cost W6 and W7 a rediscovery: the vision blocks carry a three-tensor SwiGLU and a router spelled differently from the language tower's, and the audio tower has no learned positional embedding at all, because `use_rope` is true and upstream sets `embed_positions` to None. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
…and name the real cause of the exit 135 (#699, #1860) The review found that the crash this spec blamed on disk pressure was a shared temp directory. `TempConfig` and `TempCheckpoint` built their paths from a per-process `static int counter`, so two concurrent runs of the same binary used the same directory. Each constructor rewrote a file the other had mmapped, and each destructor removed the other's directory. The mode matters more than the crash. SIGBUS kills a block-buffered doctest before it prints, so the run reports no result rather than a failure, and no result reads like a run still in progress. This row has no oracle, so this file is the only instrument it has, and a second agent building on this box is routine. Measured both ways on one box within a minute, at 45 GB free and 34 GB of free RAM: the counter arm gives exit 1 and exit 135 with no summary from either process, and the fixed arm gives exit 0 twice. The counter arm needed `[[maybe_unused]]` to compile, because a mutation that fails to build reads as a passing test. `getpid` is not used. MSVC spells it `_getpid` behind another header, and a random word plus the steady clock is unique for the same reason a pid is. The same shape in five other test files is #1860, and this commit does not touch them. Three smaller review findings go with it. `Dots3NoteAccounting::deferred()` had no production caller and its second check was unreachable by the same argument that deleted the M12 guard, so it goes rather than being staged. The classifier dispatched `else ++acc.audio`, which would count a third registered tower as audio; it now dispatches on the table index and reports a counter-less tower as unaccounted. The mapper anchor cited W1's line, not the line at the revision W2 says it re-read. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
localai-bot
force-pushed
the
row/MODEL-MM-dots3-note-W2
branch
from
August 24, 2026 16:38
9843fe3 to
927d9a8
Compare
Brings the branch current so check-commit-trailers and check-commit-style run rather than skip; a skipped gate is not a passed gate. merge-tree reported the merge clean beforehand and no conflict arose. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
jefby
pushed a commit
to jefby/vllm.cpp
that referenced
this pull request
Aug 25, 2026
mudler#699) (mudler#1847) W2 of the dots3-note row (mudler#699): the weight map read over the WHOLE released index, extending W1's 1614-tensor slice to all 38006. ACCOUNTING: 38006/38006, buckets asserted BY NUMBER -- 35381 language / 2195 vision / 430 audio -- zero unaccounted, missing, duplicated or invented. Read from the released `model.safetensors.index.json` at revision `1e1e7b0cd37a3a48a6c8d7fa55d5f9d14377006b` joined to the safetensors headers of all 133 shards: **266 HTTP Range requests, 4770592 bytes, ZERO tensor bytes** against a 576886825984-byte checkpoint. The index's `weight_map` and the 133 headers agree on the name set exactly. THE FIXTURE IS NOT CIRCULAR, and a reviewer proved it rather than accepting it: it carries the 2625 tower names our enumerator never emits, plus dtypes and shapes the enumerator has no source for, and it matched the live release with zero name, file, dtype or shape mismatches. An accounting checked against a fixture generated from our own enumerator would prove only self-consistency. WHAT THE FULL INDEX SHOWED THAT THE SLICE COULD NOT: * Exactly FOUR distinct backbone layer shapes (19 / 789 / 784 / 18 tensors). W1's "the remaining 42 layers repeat 1/2 exactly" holds; no layer breaks it. * The full/sliding split read off the shipped `indexer.wk` tensors EQUALS `config.layer_types` -- two independent released artifacts agreeing, which is stronger than trusting either alone. * 62 F32 tensors in TWO families, not one: the 45 language `e_score_correction_bias` W1 predicted, PLUS 17 `vision_encoder.blocks.{25..41}.mlp.router_bias` a language-only slice was blind to. Both families are dtype-gated, and an `other_dtype.empty()` sweep pins the remaining 37944 to BF16, so the checkpoint's whole memory format is gated rather than its names alone. * The index metadata declares `indexer_rope_layout: "leading"` and `indexer_rope_converted_from: "tail"`, and NOTHING in vLLM `main` reads either key -- verified by grep with a control. That is which HALF of the 128-wide head rotates, a different axis from §4 trap 2's GPT-J-vs-NeoX pairing. Filed as mudler#1846; W3 inherits it. THE GATE CRASHED INTO SILENCE, AND THE RECORDED CAUSE WAS WRONG. Review found that an exit-135 in the mutation table had been attributed to a 92%-full disk. The real cause is `TempConfig`/`TempCheckpoint` building `/tmp/dots3_note_*_<N>` from a PER-PROCESS `static int counter`: two concurrent runs of the same binary share directories, each rewriting a file the other has mmapped, and because doctest's stdout is block-buffered the report dies with the process -- so it reads as NO RESULT rather than a failure. Reproduced 3/3 by the reviewer at 47 GB free, then again by the implementer, whose RED arm gave exit 1 and exit 135 with NEITHER run printing a summary. Fixed here with a process-unique path; the house-wide half (the same shape in at least six other test files) is mudler#1860. That mattered disproportionately: under spec §6.4 option B this row has NO oracle, so this file is the only instrument it has. Also from review: an unreachable-by-construction guard was deleted rather than kept as a dead check, with the invariant preserved as a reachable assertion; a test-only accessor with no production caller was deleted; the tower classifier now dispatches on the table index so a third registered tower cannot be silently counted as audio; and an upstream anchor that had been inherited rather than re-read was corrected to `:70-78` at `185cada36b`. A FRAMING CORRECTED IN THREE PLACES: the 17 fp32 `router_bias` tensors are NOT spec R5. R5/§2.4 is the FP32 dynamic ACTIVATION SCALES in `note_vision_fused_moe_fp8`; this bf16 checkpoint ships no scale tensors at all (census: 37944 BF16 + 62 F32, all named parameters). The finding is real; R5 stays wholly owed by W6. Gate: `test_dots3_note_scaffold`, 26 cases / 110818 assertions, CPU-only, no GPU lease. Sixteen mutations, every one with its compiler exit status recorded, including one contributed by the review that the implementer's table lacked -- deleting the production call site of `AccountDots3NoteTensors` -- which comes back RED, so the map is genuinely reached through `load_weights` rather than only exercised by tests. CI on the reviewed head `927d9a8dd`: `build-test-cpu` (the full ctest), `cuda-fat-build`, BOTH `sanitize-cpu` arms, arm64, vulkan, newest-gcc all pass. Unlike W1, the full suite is reproduced green rather than left unreproduced. The two `windows-msvc-*` failures are mudler#584, byte-identical to a PR predating W1. Operator gate rerun rather than taken on report: 0 behind main at merge, `check-commit-trailers` and `check-commit-style` both RUN and pass (they SKIP on a behind branch, and a skip is not a pass), `check-agent-record` and `check-model-checklist` OK, issue index append-only with zero deletions. Row stays SPIKE. The forward still refuses by name. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
W2 of the dots3-note row (#699). W1 accounted 1614 tensors over a four-layer
slice of the released shard index and left the other 36392 unread. This reads
the index in full and joins it to the safetensors header of all 133 files it
names.
What changed
The accounting is 38006 / 38006: 35381 language, 2195 vision, 430 audio,
zero unaccounted, zero missing, zero duplicated, zero invented. Every case that
touches the buckets states all three by number.
That polarity is the point of the brick. "Nothing was left over" is also true of
a classifier that counts the two towers as language, which is the mutation the
#1805 review found passing (M15). At W1's scale it was a latent hole. At this
scale it would make "100% accounted" cover 2625 weights nobody loads.
A deferral is now a record rather than a counter.
Dots3NoteDeferredTowers()names the prefix, the one file each tower ships in, the brick that owes it and
what it is;
AccountDots3NoteTensorsdispatches on that table instead of on twoprefix literals; and the load refusal prints the table, so an unknown tensor is
distinguishable from a deferred one in the message a user gets.
Why the change is needed
Spec §6.4 records that this row has no oracle on any host we own, so there is no
token gate downstream of these assertions. A weight nobody loads reads as zeros
and renders. The name map is the only instrument that says the port knows what
the checkpoint contains.
Three things the slice could not reach
The backbone has exactly four distinct layer shapes.
{0}dense + fullat 19 tensors, the 12 full + MoE layers
{1, 5, ... 45}at 789, the 33sliding + MoE layers at 784, and
{46}at 18. W1 recorded "the remaining 42backbone layers repeat layers 1/2 exactly" as a claim about a checkpoint
nobody had read. It holds, and a fifth class would have meant the port was
reading some layer with the wrong map.
The full/sliding split read off the weights matches
config.layer_typesexactly. The DSA indexer ships only on the full class, so the shipped
indexer.wknames give the schedule independently of the config. Twoindependent released artifacts agreeing is stronger than either alone.
The checkpoint carries 62 F32 tensors in two families, not one. The 45
language
mlp.gate.e_score_correction_biasW1 predicted, and 17vision_encoder.blocks.{25..41}.mlp.router_biasits language-only slicecould not see. Their widths are the vision pyramid's own routed-expert
counts: fp32 learned router statistics inside an otherwise BF16 tower. The
census closes at 37944 BF16 + 62 F32 with no third dtype anywhere.
This is not spec R5, which an earlier draft of this description claimed.
R5 and §2.4 are the FP32 dynamic activation scales in
note_vision_fused_moe_fp8, and the bf16 checkpoint ships no scale tensorsat all — every one of its 38006 entries is a named parameter. R5 stays wholly
owed by W6.
And one finding
The index's
metadatablock declaresindexer_rope_layout: "leading"andindexer_rope_converted_from: "tail".git grep indexer_rope_layoutover vLLMorigin/mainreturns nothing, so upstream reads neither key. It agrees withwhat upstream's code does anyway, and it is not spec §4 trap 2: trap 2 is
about which pairs the rope rotates, this is about which half of the 128-wide
index head it rotates. Both are numerically silent on a row with no oracle.
W2 pins both values in an assertion and consumes neither, because W2 writes no
maths. #1846 owns it and W3 owes the slice.
How a reviewer can verify it
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_CXX_FLAGS_DEBUG=-O0 -DCMAKE_C_FLAGS_DEBUG=-O0 \ -DVLLM_CPP_BUILD_EXAMPLES=OFF -DVLLM_CPP_SERVER=OFF ninja -C build test_dots3_note_scaffold ./build/tests/test_dots3_note_scaffoldObserved:
test cases: 26 | 26 passed,assertions: 110821 | 110821 passed,exit 0, about 170 s at
-O0of which roughly 135 s predates W2. CPU-only. NoGPU lease was taken and none was needed.
The fixture is reproducible from the release. The committed
config.jsonwas re-fetched at the same revision and is byte-identical, sha25699b7de680dd456111c36efb8749f8ae7177328e97b65a3e39a6700cbc1173833. The indexis sha256
95a364b468a93ccad6adcb9c3aa110cb7a1411c2575c334c39022f9f84d456e1.No tensor byte was downloaded. The fixture is a headers-only projection:
266 HTTP Range requests over the 133 shard headers, 4770592 bytes in total,
against a checkpoint of 576886825984 bytes.
The mutation table is spec §4.4: fifteen rows, every one applied to the tracked
source or the committed fixture, rebuilt, run and reverted with the tree
verified byte-for-byte, and every one RED with
compile_err=0printed besideit. Two rows are worth reading rather than counting. One guard came back GREEN
— an
AccountDots3NoteTensorsVT_CHECKthat no input can reach — and it wasDELETED rather than kept, with M12b replacing it by injecting the defect it was
meant to catch. One row exited 135 with no
doctestsummary while the box satat 92% disk; re-run alone it compiled clean and went red on 5 cases, and both
readings are on record, because a crash is not a red test.
What the fresh review changed
The review returned PASS with one MEDIUM and four LOW, and all five are fixed on
this head.
F1, MEDIUM, and it corrected a recorded measurement.
TempConfigandTempCheckpointbuilt their/tmppaths from a per-processstatic int counter, so two concurrent runs of this binary shared one directory: eachconstructor rewrote a file the other had mmapped through
SafetensorsFile::Open, and each destructor removed the other's. That is theexit 135 this spec first blamed on disk pressure, and the cause was wrong. Both
paths are now process-unique, and the RED-before pair is measured here rather
than inherited — two concurrent runs at 45 GB free and 34 GB of free RAM:
UniqueTempDir(fixed)static int counter(RED)Bus error (core dumped)Neither RED process printed a summary, which is the hazard: SIGBUS kills a
block-buffered doctest, so the mode is no result, and no result reads like a
run still in progress. The RED arm needed
[[maybe_unused]]to compile, becausea mutation that fails to build reads as a passing test.
getpidis not used —MSVC spells it
_getpidbehind another header. The same shape in five othertest files is #1860 and is not touched here.
F2, LOW.
Dots3NoteAccounting::deferred()had no production caller and itssecond check was unreachable by exactly the argument that deleted the M12 guard,
so it is deleted rather than staged.
F3, LOW. The classifier ended
else ++acc.audio, so a third registeredtower would have been counted as audio. It now dispatches on the table index and
reports a counter-less tower as unaccounted, so the load refuses naming it.
F4, LOW. The mapper anchor cited
multimodal.py:53-62, which is W1's line atc205726108. At185cada36b, the revision W2 says it re-read, it is:70-78.Corrected in the source comment and in the porting inventory.
F5, LOW. The test docblock still described W1 only. It now describes what the
file gates.
The review also ran a mutation this branch's own table lacked — deleting the
production call site of
AccountDots3NoteTensorsinLoadDots3NoteWeights—and it came back RED, so the map is reached through the registry rather than
only exercised by helpers. That row is recorded in spec §4.4.
What remains unverified or out of scope
The forward still refuses by name, and so do GGUF and every arm past the name
map. No maths, no attention, no MoE execution, no towers, no MTP: those are
W3 to W10.
The row stays
SPIKE. Reading a weight map is not porting a model.Every number owed under spec §6.4 option B stays owed: no throughput, latency
or memory axis is claimable for this model, because the oracle does not run on
any host this project owns.
The full 599-test
ctestsuite was not run locally for this change andtherefore stands unreproduced here, in either direction.
scripts/agent-preflight.shpassed clean,
check-commit-trailersandcheck-commit-styleboth pass overorigin/main..HEADon a rebased branch, andtest_dots3_note_scaffoldis theonly target this change can affect. CPU-only: no CUDA, Vulkan, Metal or
sanitizer build ran here, and CI owns those lanes.
CI
Green after the rebase onto
c14fee79b, except the two Windows lanes, andneither is this change.
build-test-cpupasses, which is the lane that runs the wholectest --test-dir build --output-on-failure, so the full suite IS reproducedgreen on x86.
build-newest-gcc,build-test-cpu-arm64,build-test-vulkan,cuda-fat-build, bothsanitize-cpuarms,device-leakage,agent-record,documentation-checkpointandcommit-protocol-tagall pass.windows-msvc-cpuandwindows-msvc-vulkanfail, and the log names the cause:test_openai_api_server.exe exited with status -1073740791, which isSTATUS_STACK_BUFFER_OVERRUN. That is #584, and it is not attributable to thisbranch — PR #1776 shows the byte-identical failure on a run from 2026-08-23,
before W1 landed any dots3 code at all. Every
.vcxprojin the log links, sothe compile defect these lanes carried until this morning is gone: that one was
the
[[noreturn]]-on-a-non-void-ForwardDevicedeclaration W1 landed, #1840fixed it on
mainatc14fee79b, and the rebase picks the fix up. What is leftis the runtime crash #1840's own body predicted would be unmasked.
Refs #699. Closes nothing: #699 tracks the whole row.
FOLLOWING_AGENTS_PROTOCOL
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]