feat(minimax-h3): the ORIGINAL bf16 DiT release is indexable — 13 shards, 66.3 GB - #98
Conversation
9529ed0 to
098ef36
Compare
|
Force-pushed: added a real defect fix that this stack's ASan+UBSan lane exposed.
Now a byte-wise RED-first proven locally, on the same Note the finding surfaced on #99 (whose test reaches the reference loader), not here — but the fix belongs in this PR, because this is the PR that introduces the shipped caller ( |
…rds, 66.3 GB Branch: row/H3-BF16-SHARDED-DIT (helper; CPU-only, no GPU job, no download). Written 2026-08-06 off 075b9f2, REBASED onto f34e0d1 and re-gated before landing; every number below is the POST-REBASE re-run, not the earlier report. Every H3 render so far used a QUANTIZED DiT, and H3 is unusually quantization-sensitive: Q3_K_M -> Q4_K_M alone turned a murky lattice-covered silhouette into a photoreal close-up (ComfyUI PR 15298 attributes it to the partial split-half RoPE producing channel-wise magnitude outliers that corrupt even INT8). "What does FULL PRECISION look like?" could not be asked, because every DiT loader took a SINGLE file while the bf16 release ships 13 safetensors shards totalling 66.3 GB. This is the CHECKPOINT half. The device streamer the real 66.3 GB load needs is the stacked follow-up row/H3-BF16-SHARDED-STREAM, split out so each PR stays inside the 900-line review cap. - MiniMaxH3ShardedCheckpoint::Open(dir) (new minimax_h3_sharded.cpp) resolves tensors through the checkpoint's own model.safetensors.index.json weight map, never by scanning, with one index over every shard — the shape of the in-tree template LoadMiniMaxH3EncoderWeights(const std::vector<SafetensorsFile>&, ...). A tensor the index NAMES but whose shard does not contain it throws BY NAME; skipping it would read as zeros and render. - EnumerateMiniMaxH3ShardedTensors builds the same names+shapes manifest the GGUF and NVFP4 arms build, so ParseMiniMaxH3DitParamsFromGgufManifest derives the geometry from SHAPES ALONE on a sharded checkpoint too. - LoadMiniMaxH3DitFromShards is the host-f32 REFERENCE loader (comparison baseline and the CPU path for reduced checkpoints; ~132 GB on the real release, so not for real runs), and MiniMaxH3IsFp32IslandTensor single-sources the upstream fp32-ISLAND split the three existing streamers each hand-rolled. - examples/minimax_h3_gen accepts --dit <dir> everywhere it accepted a DiT file, for both --dump-params and the run path; every existing --dit form unchanged. Gates (CPU, re-run post-rebase: test_minimax_h3 72/72 cases / 54497 assertions; clean Release build of libvllm.a, test_minimax_h3 and minimax-h3-gen): (1) index + name mapping over a synthetic 4-shard set — every tensor resolves to the shard the index named AND to the bytes written there, a missing-from-shard tensor throws WITH ITS NAME, and the geometry equals the single-file path field for field; (2) real geometry without the weights — a 13-shard release declaring the REAL 535 tensors at REAL shapes with a SPARSE payload (66.3 GB declared, 144 KB on disk) derives the SHIPPED geometry (50 / 5376 / 56 / 128 / 14336 / 24 / 32 / 1x2x2 / 5120), and `minimax-h3-gen --dit <dir> --dump-params` prints all 20 fields on it. Also repairs two gates that f34e0d1 (#95) left RED on main and that block any PR branched from it: docs/ENVIRONMENT.md now documents VT_H3_ACT_DUMP and VT_H3_ACT_CALL (check-env-doc), and the §9 spec table that ran into the next table without a separator now has one (check-agent-record). Also fixes a real latent defect this row's ASan+UBSan lane exposed: MiniMaxH3ReadSafetensorF32 read 16-bit payloads through reinterpret_cast<const uint16_t*>, which is UB on a safetensors file whose JSON header leaves the payload odd-aligned — the format does not require padding, and LoadMiniMaxH3DitFromShards is the first caller to hand it such a file. Now a byte-wise memcpy load. RED-first proven locally on the same sanitizer build: reverting it reproduces CI's `load of misaligned address ... requires 2 byte alignment` at the same line and exits 1; with it, test_minimax_h3 is 73/73 / 55203 under -fsanitize=address,undefined with ZERO findings. The synthetic shard writer stays deliberately UNPADDED so the case remains covered. Honest residuals: NO device load of the real 66.3 GB release ships here, no measured peak RSS, and no bf16-vs-quantized render or speed number. The bf16-vs-quant quality question is UNBLOCKED, not answered. FOLLOWING_AGENTS_PROTOCOL Assisted-by: Claude Opus 5 (1M context)
098ef36 to
016a07d
Compare
What this enables
The MiniMax-H3 bf16 release ships 13 safetensors shards totalling 66.3 GB, and every DiT loader in the tree took a single file. That is why every H3 render so far used a quantized DiT — and H3 is unusually quantization-sensitive (Q3_K_M → Q4_K_M alone turned a murky lattice-covered silhouette into a photoreal close-up; ComfyUI PR 15298 attributes it to the partial split-half RoPE producing channel-wise magnitude outliers that corrupt even INT8). "What does full precision look like?" was not an askable question.
After this PR the original release is indexable:
MiniMaxH3ShardedCheckpoint::Open(dir)(newminimax_h3_sharded.cpp) resolves tensors through the checkpoint's ownmodel.safetensors.index.jsonweight map, never by scanning, with one index over every shard — the shape of the in-tree templateLoadMiniMaxH3EncoderWeights(const std::vector<SafetensorsFile>&, ...). A tensor the index names but whose shard does not contain it throws by name; silently skipping it would read as zeros and render.EnumerateMiniMaxH3ShardedTensorsproduces the same names+shapes manifest the GGUF and NVFP4 arms build, soParseMiniMaxH3DitParamsFromGgufManifestderives the geometry from shapes alone here too.LoadMiniMaxH3DitFromShardsis the host-f32 reference loader (comparison baseline and CPU path for reduced checkpoints).MiniMaxH3IsFp32IslandTensorsingle-sources the upstream fp32-island split the three existing streamers each hand-rolled. It is load-bearing, not a precision nicety:vt::MatmulBTrejects an (f32 activation, bf16 weight) pair.examples/minimax_h3_genaccepts--dit <dir>everywhere it accepted a DiT file. Every existing--ditform is unchanged.This is the checkpoint half. The device streamer the real 66.3 GB load needs is the stacked follow-up
row/H3-BF16-SHARDED-STREAM, split out so each PR stays inside the 900-line review cap (this one is 775 non-exempt lines).Gates I ran, post-rebase
Rebased onto
f34e0d17and re-gated after the rebase — these are the numbers observed here, not the pre-rebase report.test_minimax_h372/72 cases, 54497 assertions, clean Release build oflibvllm.a,test_minimax_h3,minimax-h3-gen.50 / 5376 / 56 / 128 / 14336 / 24 / 32 / 1x2x2 / 5120, andminimax-h3-gen --dit <dir> --dump-paramsprints all 20 fields on it.scripts/agent-preflight.sh --staged: green.Two pre-existing main breakages repaired
f34e0d17(#95) leftmainred on two gates, which blocks any branch off it. Both are repaired here, in the same file/lane:check-env-doc:VT_H3_ACT_DUMPandVT_H3_ACT_CALLshipped undocumented;docs/ENVIRONMENT.mdnow documents both.check-agent-record: a §9 spec table ran straight into the next table with no separator (4 pipes where 3 were expected, 4 lines); it now has one.Verified pre-existing by running both checkers on a pristine
origin/mainworktree first.What is NOT claimed