Repository navigation
Stage-2 g0 (MLA + indexer) disk restore at 3584 boundaries (GLM53_KV_OFFLOAD_RESTORE, default off) + stage-3 mamba differential harness - #100
Conversation
…#54743) The OffloadingConnector cannot boot on this hybrid layout: the image's build_offloading_config builds an offload group config for every KV-cache group and asserts tokens_per_block % tokens_per_hash == 0 across all of them, so the KpoolTailSpec scratch group (block 4, hash grid 64) crashes it at boot. Port our upstream PR vllm-project/vllm#54743 onto the image tree (vllm 0.1.dev20051+g487ecf187, mid-generation: the scheduler NamedTuple already carries group_idx, the config boundary does not): - OffloadingGroupConfig gains group_idx (original boot index, required); - build_offloading_config scopes the groups tuple to eligible groups: prefix-cacheable (via the image's participates_in_prefix_caching name) minus the fork policy exclusion of draft-model attention groups (is_eagle_group, or exact SlidingWindowSpec under an EAGLE speculative config) unless GLM53_KV_OFFLOAD_DRAFTER=1; the divisibility assert still guards eligible groups; one boot line names the eligible set ({0, 2, 3, 4, 5} on this deployment); - scheduler port: group_states sized by the FULL group count, every config<->state pairing through group_idx, _group_config_by_idx for the two subscripts, full-length GPULoadStoreSpec group_sizes/block_indices with zeros for ineligible groups (the worker layout is built from ALL groups and stays unchanged), supports_partial_tail additionally requires every group eligible; - [I]-specific adaptation: a fail-closed single-type unwrap for the image's UniformTypeKVCacheSpecs group wrappers, without which the connector's FullAttentionSpec assert crashes on group 0 and mamba groups lose their alignment/CoW classification. Fail-closed patcher per repo convention: all anchors in all three files preflight before any write; MARK sentinels; idempotent (marks-only already-present check, because patch_kv_offload_store_local.py later edits inside these regions); atomic replace; drift => nonzero. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…53_KV_OFFLOAD) Stage 1 of the disk KV-offload plan: the tier writes, nothing reads it back (restore short-circuited behind GLM53_KV_OFFLOAD_RESTORE=0). The stock fs secondary tier is byte-invalid on this 2-node TP pair: TieringOffloadingSpec builds every secondary tier scheduler-side against the scheduler node's staging memoryview, and rank 1's staging mmap lives on the other Spark - the tier would persist rank-0 bytes plus uninitialised garbage as rank-1 halves. So the disk write moves to the workers: - TransferJob gains an optional glm53_store_meta side-channel (versioned picklable dict): ordered keys aligned with the job's block order plus boundary-manifest candidates (cumulative chunk-hash chains); - each worker, after its GPU->CPU DMA completes, writes its own bytes from its own staging mmap to its own NVMe (per-rank namespaced root; rank = initialized TP rank cross-checked against the connector config, mismatch disables the writer) and only then acks the job - staging stays pinned until every worker acks, so bytes cannot be evicted under the writer; - every chunk gets a versioned header: magic, namespace hash (model, vllm version, build id, TP, KV dtype, hash algo, num_speculative_tokens, per -group real page sizes, KDA state-ABI descriptor), ORIGINAL group index, per-layer segment table (conv/temporal split with shape/dtype/stride for KDA layers), boundary token index, payload CRC; payload = real (unpadded) bytes only - the slot-share padding never reaches disk; - boundary manifests publish per-rank only after all four mamba payloads and the cumulative full-attention chunks are durable (fsync file+dir, tmp+rename); a crash between group writes leaves orphans, never a live half-boundary; a key that failed to write this boot can never be manifested (failed-key ledger); - inline keep-K manifest retention (GLM53_KV_OFFLOAD_KEEP_BOUNDARIES, default 2): a manifest is superseded once it is beyond the K most recent boundaries of EVERY chain containing it; full-attention chunks stay dense; - failure semantics: failed write = unlink + log + lost store; ENOSPC pauses the writer; serving is never blocked on the tier. kv_offload_store_gc.py: standalone verifier/GC (header+CRC walk, orphan and corrupt reporting, manifest cross-reference, keep-K sweep; DRY-RUN default). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…on both ranks - Knobs with caller-export setness capture: GLM53_KV_OFFLOAD (0|1 strict, default 0), GLM53_KV_OFFLOAD_DIR (absolute, no quotes/whitespace; local NVMe on each Spark, mounted rw at /data/glm53-kv-offload on both ranks), GLM53_KV_OFFLOAD_CPU_GB (1..64), GLM53_KV_OFFLOAD_RESTORE (stage-1 hard rule: 1 is REFUSED), GLM53_KV_OFFLOAD_DRAFTER, and GLM53_KV_OFFLOAD_KEEP_BOUNDARIES (0..1024) - all validated inside the pre-stop gate, so a bad knob or a missing/truncated/mis-pointed overlay artifact exits 2 before restart stops the healthy pair. - knob=0 adds NOTHING beyond the replayed env: no --kv-transfer-config, no store mount, no mkdir - serving is byte-identical to a build without the tier. knob=1 appends identical connector JSON to both rank inner scripts (TieringOffloadingSpec, cpu_bytes_to_use, blocks_per_chunk=1, NO secondary tiers - the worker-local writer is the disk tier; the scheduler-side fs tier is byte-invalid on 2-node TP), mounts the store dir on both nodes and ships both overlays over the scp -> /tmp -> mount chain. - GLM53_OVERLAY_ORDER pins one apply list emitted verbatim into BOTH rank inner scripts (the kv-offload pair is order-dependent: scope must precede store_local, which refuses an unscoped tree); the prefix-cache overlay slots from PRs MiaAI-Lab#83/MiaAI-Lab#84 ride along as [ -f ]-guarded entries. - Dockerfile: bake both overlays after the real-tree preflight test; ship the GC tool and tests into /opt/glm53. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…d tier
tests/fixtures/: byte-exact pinned captures of the five in-image sources the
overlays patch (vllm 0.1.dev20051+g487ecf187, sha256s in the fixtures
README) - the patchers preflight/apply against the REAL text and the tests
exec the PATCHED modules under a stubbed vllm namespace
(tests/_kv_offload_stub_env.py), so anchor drift or a broken port fails on
the host, not on the server.
- test_kv_offload_scope.py: patcher preflight/idempotence/tamper/half-patch
on the fixtures; eligibility predicate matrix (kpool never, drafter only
under EAGLE context, strict 0/1 env); patched-runtime drive: eligible
{0,2,3,4,5}, original-index keys, full-length group_sizes with zeros at
1/6, num_kv_cache_groups=7, mamba alignment 3584, store-only lookup
short-circuit (manager.lookup never called), no-scratch uniform model
unchanged, misaligned cacheable group still asserts.
- test_kv_offload_store_local.py: header codec round-trip + truncation at
every region + CRC flips; store-job meta 1:1 alignment with block order +
cumulative manifest candidates + TransferJob pickle; writer on a
miniature 7-group layout: real-bytes payloads, KDA conv/temporal segment
split, manifest publish ordering, failed-key ledger, keep-K retention,
ENOSPC pause with no partial files, TP-rank disagreement disable,
delayed-ack drain; GC dry-run/sweep/keep-K incl. cumulative full-attn
protection.
- test_launcher_kv_offload.py: knob guard matrix, pre-stop gate (bad knob /
missing / truncated / mis-pointed overlay => rc=2 with zero docker/ssh
calls), knob=0 no-mount parity, knob=1 both-rank env/mount/scp/JSON-shape
parity with a synthetic one-rank mismatch, overlay order pin.
- test_kpool_tail_slotmap.py / test_xgrammar_termination.py: launcher-wiring
assertions moved to the GLM53_OVERLAY_ORDER list (same shape as the
kv-capacity-log branch); test_warm_restart_stdout.py: the -S JSON-builder
count is now 4 (2 speculative + 2 kv-offload).
- README overlay/test table rows; docs/DESIGN-kv-offload-store-only.md.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rdening (Codex adversarial pass) Adversarial diff review (CODEX-OFFLOAD1-REVIEW.md) verdict DO-NOT-SHIP; every finding adopted or rebutted in writing: 1 (BLOCKER, adopted) reset_cache() frees ALL staging rows regardless of pending disk work and the very next step can DMA new stores into them, so async mmap reads could tear a payload under a valid CRC. The writer now SNAPSHOTS the job's bytes synchronously at DMA completion (get_finished, before this rank's ack; or right after worker.wait() on the flush/reset path via a new capture hook) and writes from private, budget-capped buffers; acks are never deferred; shutdown/mmap-cleanup coupling is gone. Regression test: staging rows zeroed after capture, disk bytes unchanged; flush-path capture test. 2 (MAJOR, adopted) the launcher JSON now sets offload_prompt_only=false (upstream defaults true and would silently skip decoded tokens); the test stub mirrors the upstream default instead of masking it. 3 (MAJOR, adopted) namespace record is fsynced and VALIDATED against an existing file (mismatch disables the writer); GLM53_KV_OFFLOAD_BUILD_ID is derived from the recipe checkout SHA and replayed to both ranks; dedup and manifest publication header-VERIFY identity (namespace+hash+group) for mamba AND cumulative full-attn chunks, with per-chunk [hash, len, crc] recorded for full groups (plan §4 wording honored). 4 (MAJOR, adopted) temp names gain the writer thread id; the GC scans and sweeps stale *.tmp.*, infers mamba groups from chunk HEADERS (orphans are found even when a crash predates the first manifest), and applies the writer's leaf-walk keep-set so forked chains keep shared divergence ancestors; forked-chain, zero-manifest-orphan and stale-temp tests added. 5 (MAJOR, partially adopted) both patchers gain --check-injected (compiles every injected source standalone) and the pre-stop artifact gate runs it; the residual exposure (an anchor mismatch surfacing only in-container) is the repo-wide overlay contract and is documented, not new to this pair. 6 (MINOR, adopted) the TP-rank fallback now logs its reason and records rank provenance in the namespace record; the cross-check still disables the writer on disagreement, and the two-node R0 receipt covers the fallback path live. Full suite 33 passed; store tests now 60+ checks incl. the snapshot regression. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…temp GC Codex confirm pass on 32f993e (CODEX-OFFLOAD1-REVIEW.md appendix): findings 1/2/5 PASS, rebuttals accepted, two residuals — both adopted: - RESIDUAL MAJOR: the namespace record appended keep_boundaries/rank_source AFTER hashing but compared the WHOLE record byte-exact on the next boot, so changing retention K (or the rank-derivation path flipping between TP group and config fallback) spuriously disabled the writer. The record now separates {fenced, info}: the fenced portion alone is hashed and exact-compared; info fields are diagnostics. An unparseable record still fails closed. Tests C22b-d (K change reuses the store; corrupted record disables). - RESIDUAL MINOR: namespace-record temps live BESIDE the per-rank base (the store root); the GC now scans that root non-recursively for glm53kv_*.json.tmp.* in addition to the recursive base scan. Test D9/D10 updated to plant and sweep one. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…re scheduler receipt) Read-only captures from the live container running the identical vllm tree (0.1.dev20051+g487ecf187; the four stage-1 offloading fixture sha256s were re-verified against it byte-exact). offloading_connector.py and single_type_kv_cache_manager.py are stage-2 patch targets; the core sched/scheduler.py is pinned as the RECEIPT for the single-group invalid-block path (the hybrid-allocator TODO at :2954-2955) that gates the restore eligibility predicate — Codex OFFLOAD2 finding 1. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ookup, disk loads, T4, T2 Stage 2 of the disk KV-offload plan: restore for group 0 ONLY (MLA + indexer KV) at 3584 boundaries, on single-TOTAL-group layouts; INERT with a named boot log line on the live 7-group hybrid (zero hit uplift by design — the hybrid min plus the core's single-group invalid path). Five patch targets: worker-meta manifest-event channel (+/-/F; the per-job store failure bit is on the wire and load-bearing at lookup), scheduler disk lookup (AND across ranks, keys/hashes only, single-flight gate with self-heal, preemption load-job guard, zero-cow manifest candidates), worker synchronous pread->verify->scatter loader (full segment-table equality, per-(chunk,rank) failure => zero-fill + invalid ids + the job always completes), facade get_block_ids_with_load_errors, and the single_type reachable_boundaries T2 hook (request.glm53_restored_boundary, end-exclusive). Codex chain: CODEX-OFFLOAD2-PLAN.md (advisory DO-NOT-PROCEED, 5 BLOCKER + 10 MAJOR, all adopted/rebutted pre-build). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The stage-1 unconditional refusal becomes the stage-2 dependency rule, still fail-closed pre-stop with zero host calls. The restore overlay rides every stage-1 artifact site: guard list, --check-injected, scp, both-rank mounts, GLM53_OVERLAY_ORDER (scope -> store_local -> restore_g0). offload_prompt_only:false and all stage-1 knobs unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…/T2, launcher matrix, venv checks) test_kv_offload_restore_g0.py drives the PATCHED module text end-to-end: eligibility matrix (hybrid INERT, single-group ACTIVE, eligible+excluded INERT), AND-across-ranks registry, single-flight gate, disk-job shape with zero manager calls and preserved stage-1 bookkeeping, preemption guard, byte-exact loader round-trip against real writer output, the T4 failure matrix (job always completes; suffix zero-filled; ids reported), the manifest-event channel (validated dedup, event-only meta, aggregate with a legacy meta, pickle), the facade drain, and T2 on the patched single_type text including the end-exclusive mamba mask convention. Launcher suite extended (RESTORE dependency rule, overlay order, both-rank replay). Venv checks feature-detect the CPU vLLM tree. pytest 40 + standalone runners all green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…res + protocol; NOT evidence) Park-at-boundary fixtures with stubbed KDA state tensors at the receipted ABI (conv (10,12288) bf16 + temporal (32,128,128) fp32, real page 2,342,912 B, 9/9/8/8 layers, num_spec=7 in every header, slot-share padding never on disk) and the exact bit-comparator stage 3 will run against real captures (a flipped bit localizes to its (group, layer, tensor)). The guarded live protocol script pins the stage-3 acceptance gate, step 0 = receipt the still-open mamba state-index convention; it refuses to run on this branch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…receipts scope) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…T-SHIP -> all adopted/rebutted) BLOCKER f1: _build_store_jobs now DEFERS store creation for a request whose registered job is a disk load (new site R11) instead of reaching the is_store assert; test drives the abort-during-load path on the patched text. f2: build_load_spec hash-count guard fixed to (chunks * hashes_per_chunk) scale + geometry validation in the eligibility predicate. f3: the loader is now try/finally (idempotent done-append; ids reported atomically before best-effort zero-fill); unidentifiable destinations deliberately PROPAGATE (fail-stop, the stage-1 store-error rationale) - rebuttal recorded. f4: loader checks spec_kind/block_size + the manifest chain arithmetic + the per-chunk [len,crc] ledger; writer dedup validation and the stage-1 chunk dedup (new site W13) are payload-verifying. f5: 64-char lowercase-hex validation before any path construction from wire/manifest data. f6: bounded seek+read with a 256 MiB hard cap checked pre-read. f7: rank range validation + exact rank-set quorum. f8: per-rank writer-generation fencing (boot-id change retracts that rank), capped registry (fail closed), capped failed-key ledger (overflow POISONS the lookup - losing failure knowledge would be fail-open), capped event queues. f9 REBUTTED (sticky failed keys mirror the stage-1 writer ledger by design). f10: the already-present patcher path now runs full verified_state (tamper-with-marks refused). f11: coverage batch B12-B16 + C10-C15 (also fixed two latent test bugs the batch exposed: C8's leaked tampered file, B14's reused boundary). f12: harness ABI check strengthened (kind/layer/stride/offset/provenance); terminal-chunk fixture scope documented. Suites: pytest 40 + six standalone runners green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…IP -> adopted/rebutted) f2: eligibility geometry (tpc == hpc x tokens_per_hash). f4: writer dedup validator now verifies the FULL expected chunk shape (spec_kind, block size, tp_rank/world, segment table, payload_len-before-read bound) for every referenced chunk. f8: the event-queue cap applies to '+' only -- dropping '-'/'F' would be fail-open; those always ride (bounded by prior publishes/writes). f9 (rebuttal rejected, adopted): scheduler failed keys are per-rank AND writer-generation-scoped -- a restarted writer's clean republish is no longer permanently suppressed; overflow still poisons the lookup fail-closed. f11: B16 now drives a genuinely ABORTED request through finished_req_ids (the BLOCKER route). NEW-1: R9/R11 act only on Glm53RestoreState-tracked disk-job ids; any other non-store job keeps the stock crash semantics (test B18 plants a foreign load and expects the stock AssertionError). NEW-2 REBUTTED with evidence: '+' emission lives in _register_manifest, which BOTH publish branches call (test D3 observes the re-announcement); the scheduler-restart gap is the documented same-boot stage-2 scope. NEW-3: W13 dedup bounded by payload-length equality before the verifying read. Suites: pytest 40 + six standalone runners green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Self-heal discards the vanished job id from the disk-job set (no stale-id accumulation); the W13 dedup condition reordered so identity checks precede the bounded payload-verifying read (a same-sized foreign file no longer pays a full read), with the anchor widened to consume the whole original condition. Chain complete: advisory DO-NOT-PROCEED -> review DO-NOT-SHIP -> confirm DO-NOT-SHIP (one misread rebutted with evidence) -> final confirm SHIP-WITH-CHANGES -> minors adopted. Suites: pytest 40 + six standalone runners green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
vLLM's VllmConfig validation refuses OffloadingConnector together with PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True (the VMM allocator can remap KV-cache virtual addresses onto different physical pages under pinned/registered KV memory). The launcher exported the value unconditionally to both ranks, so the first GLM53_KV_OFFLOAD=1 boot failed fast at config validation — found live in the MiaAI-Lab#99 receipt window; the check is unreachable from the host-side stubs. knob=1 boots now drop the env on both ranks (torch default allocator, logged); knob=0 boots keep the stock entry — container env byte-identical to a build without the tier. Launcher test: C3b (knob=0 keeps it, both ranks) + D1b (knob=1 drops it, both ranks). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Live receipts — stage-2 restore, inert-on-live (server window 2026-09-01/02)Same window and deploy set as the #99 receipts (staged 1. Inert-on-live receipt — CAPTUREDBoot with This proves the group-0 disk-restore lookup is disabled by the seven-group eligibility gate on this layout; it does not exercise disk loading, the worker restore path, T4 handling, or event transport (those are rows 2/3/5). Serving rates vs #99's knob=1 boot (same cold ~26K-prefill probe, 6 reps each arm, reps 4–6 quoted for both arms):
The reps-4–6 ranges overlap but are not identical; this cold-prefill sample does not independently establish the body's "within noise" criterion (no decode-rate comparison was captured). 4. Kill-switch receipts — CAPTURED
2, 3. Probe fork-trace and T4 fault receipts — PENDING, with reasonThe restore path requires exactly one TOTAL KV-cache group (the PR's own eligibility rule). This branch ships no runnable single-full-attention-group probe config: exercising it needs a different model served under a purpose-built config (single group, no drafter, no mamba), which cannot be derived from this repo's launcher without designing a new deployment — out of scope for a window that must return the production pair. Rows 2 (fork-trace: WAITING_FOR_REMOTE_KVS → disk load job → GPU prefix hit) and 3 (T4: corrupt chunk / deleted manifest → zero-fill + invalid_block_ids + recompute, fresh-session control) therefore remain open — and per the body they gate merge-eligibility until captured. The wire path is covered host-side by 5. Event-channel receipt — PARTIAL, with reasonFrom the source: the worker appends manifest events on publication and forwards them in worker metadata even when restore is INERT, and the scheduler consumes them into the registry; only End state: stores deleted on both ranks, production deploy (next3 972370a, knobs absent) restored and healthy. The stage-1 receipts, including the launcher defect found and fixed live ( |
…NGES, 3 minors adopted) 1. Test harness: _env_of_worker only counts KEY=value tokens immediately following -e, so a drifted worker env assignment fails the env checks instead of passing on a stray token. 2. Comment/log accuracy: vLLM rejects OffloadingConnector under expandable_segments:True UNLESS the CuMem allocator is enabled (not on this deployment) - start.sh comment, launcher log line, D1b test comment. 3. (PR body edit, no code) blast-radius claim corrected + allocator-drop disclosure paragraph; see CODEX-087B5EA-REVIEW.md disposition. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Single-group probe receipts — rows 2/3 stay open, and we found out why (test-rig window 2026-09-02)We built and ran the single-full-attention-group probe this PR's pending rows called for. The probe booted ACTIVE and ran end-to-end up to the worker restore stage — where it hit a fail-closed guard in this branch's own v1 loader: restore is blocked at the worker pread stage for this dense mapped layout. Rows 2 and 3 therefore remain open, now with a precise, receipted reason and three branch gaps filed below. Row 5's evidence is substantially strengthened. Raw transcripts in our receipts mirror; condensed excerpts here. Probe config (disclosed dense deviation). Boot gate + eligibility — selected live excerpts (module paths abbreviated by vLLM itself; both ranks shown): What ran and was proven live:
The worker's generic load-failure handling was live-receipted for this mapped-layout guard (fail-closed, invalid-block report, zero-fill); this did not exercise row 3's bit-flip/deleted-manifest cases. The request then died with an API 500 instead of recomputing — finding B. Branch gaps found (all three verified in source; each needs a reviewed branch commit before rows 2/3 can close)A. The v1 restore loader cannot restore any canonical-mapped (dense fused-KV) layout — by its own fail-closed design. B. The launcher never sets C. Recompute alone may still not converge: no per-boundary failure suppression. After a load failure the overlay clears its single-flight gate but does not quarantine the failed boundary in the cross-rank registry — the scheduler can be offered the same permanently-failing suffix again. The branch needs reviewed per-request/boundary failure suppression plus an integrated scheduler test before row 3's "output equals cold control" can be captured even on a restorable layout. Row status after this window
Also disclosed: (i) boots carried a local env passthrough in Boot provenance. Three boot attempts failed pre-receipt (a stale baked self-check unrelated to the branch; a root-owned weight-cache permission error from the download fallback; and vLLM's zero-tolerance memory-profiling assertion racing the prior tenant's teardown on unified-memory hardware). Attempt 4 was the single advisory-authorized retry: prior logs retained, containers/stores reset first, no rsync/download/other tenant active, and three consecutive 10 s Every deviation and boot retry in this window ran under adversarial advisory gates (three rig advisories + this comment's posting gate); dispositions archived with the receipts. Submitted by nood-co1 on behalf of Blockbrain Labs (https://x.com/blockbrain_labs, GitHub org blockbrain-ai). Measured on our 2× NVIDIA DGX Spark deployment. |
…-only # Conflicts: # .env.example # README.md # start.sh
|
Updated to current main (e25aa70) the stacked way: the refreshed #99 branch (26ca3cd, which now contains main) was merged INTO this branch — merge commit ca2e31e, plain push, no force-push; the full tested stack (stage-1 SHAs, 22e1817, c5dd69d, the stage-2/3 review chain) remains ancestors. The merge was conflict-free: main's changes arrived pre-resolved through #99, and this branch's stage-2 delta (restore knob unlock, patch_kv_offload_restore_g0.py, stage-3 harness) did not overlap them. Verified post-merge: upstream/main and #9926ca3cd are both ancestors; |
|
Community triage note (full sweep: #147): one deployment-relevant finding to flag — on this model's 7-group hybrid KV layout the restore path here is inert: the mamba groups have no restore source and the core scheduler load-failure path is single-group, which matches your own ZERO-hit-uplift headline. As of today #58 is the only offload PR with a working measured restore. Tagged triage/skip for this deployment. |
|
Thank you for the most honest PR in this queue — the adversarial-review process, the live receipts, and especially the single-group probe that chased down why rows 2/3 stayed open are a model for how this work should be reported. We're closing for this deployment on the strength of your own headline: on this model's 7-group hybrid KV layout the restore path is inert — the mamba groups have no restore source and the core scheduler load-failure path is single-group — so there is zero hit uplift to adopt, and the staged rewrite's allocator surface isn't free. This is a layout-mismatch close, not a quality judgment. The fair way back: reopen (or a fresh stage PR) when a stage actually restores the mamba/hybrid groups on this 7-group layout with a hit-uplift receipt on a 2-node TP=2 boot. Until then #58's measured restore covers the offload need, and the cache-capacity work is proceeding via the per-group retention line (#130/#83). |
Stage-2 g0 (MLA + indexer) disk restore at 3584 boundaries (
GLM53_KV_OFFLOAD_RESTORE, default off) + the stage-3 mamba differential harnessStacks on #99 (
pr/kv-offload-store-only): this branch ispr/kv-offload-mla-restore= #99 + additive commits; review the diff againstthat branch. Codex gates: advisory on the design BEFORE coding
(CODEX-OFFLOAD2-PLAN.md: DO-NOT-PROCEED, 5 BLOCKER + 10 MAJOR — every finding
adopted or rebutted in writing before the build), adversarial review of the
final diff (CODEX-OFFLOAD2-REVIEW.md: DO-NOT-SHIP, 1 BLOCKER + 8 MAJOR +
2 MINOR — every finding adopted or rebutted; fixes in the review-fixes
commit; confirm pass appended there). Host suites green (pytest 40 + six
standalone runners, 0 failures). Live
receipts are posted in the thread; rows 1 and 4 are captured, row 5 is
partial, and rows 2/3 remain open for the reasons in the Receipts section
below.
The honest headline
A group-0-only restore yields ZERO hit uplift on GLM-5.3-Flash itself, by
design — and this PR says so up front. The connector's reconciled external
hit is the min across all KV-cache groups; the four mamba (KDA) groups have
no restore source in this stage. Independently, the core scheduler's
invalid-block path is single-group (pinned fixture
tests/fixtures/image_487ecf187_core_sched_scheduler.py:2954-2955, the(req_block_ids,) = …get_block_ids(req_id)under the hybrid-allocator TODO)— a load-failure report on the 7-group layout would crash the core. The
restore path therefore requires exactly one TOTAL KV-cache group and is
INERT on this deployment with one boot log line naming the reason;
serving with
GLM53_KV_OFFLOAD_RESTORE=0(default) matches #99 at theserve-argv level (live capture); byte-for-byte runtime parity is a host-test
property, not a live receipt.
What stage 2 delivers instead: the restore machinery and host-side tests.
The 2026-09-02 dense single-full-attention-group probe live-receipted the
path through scheduler lookup and disk-job creation, but not successful
worker restore. It is not the exact MLA+indexer shape of g0, and the T4
recompute contract remains unproven live. These are the prerequisites
stage 3 (mamba restore, the actual TTFT win) needs underneath it.
What this ships
overlay/patch_kv_offload_restore_g0.py(five patch targets)writer announces manifest availability over the worker→scheduler metadata
channel (
+validated publish /-retention supersede /Fwritefailure); the scheduler ANDs
+across ranks (plan §4 C2 — "workersreport it; the scheduler takes the min across ranks") and never touches
the filesystem. Contiguity is content-addressing: block hashes are
prefix-chained, so boundary-hash equality implies the whole chain.
The per-job store failure bit is on the wire and load-bearing: a
boundary whose g0 chunk failed to write on any rank is never offered
(closes the recorded stage-1 limit).
manager.prepare_loadentirely (CPU staging is a bounce, not a tier);the load job's
src_specis a versioned plain dict with entries aligned1:1 to the dst blocks;
WAITING_FOR_REMOTE_KVSand thecache_blocksre-entry are the stock core chain.
pread → header identity (namespace/hash/group/spec/rank/world) → payload
CRC → exact segment-table equality against this rank's own spec
derivation → scatter into the GPU canonical tensors. Restore
concurrency = 1. Manifest re-validated on each rank at load time.
failed chunk and every later chunk's dst blocks, reports their ids via
get_block_ids_with_load_errors(facade override; the model-runner mixinconsumes it into
invalid_block_ids), and the job still completes — thecore's
kv_load_failure_policy=recomputetruncates at the failed chunkand recomputes. All roads lead to reprefill, never a served half-restore.
request.glm53_restored_boundary(end-exclusive) rides intoreachable_boundariesin the single_type manager'scache_blocks, sosparse retention masks can never silently drop a restored boundary's
re-entry (dense masks unaffected; the anchor also applies verbatim to
upstream's tree — retention exists at HEAD).
_build_store_jobscan hit the stockis_storeasserts on a disk loadjob (flush skips it; store creation is deferred while a load is
registered); the single-flight gate self-heals; stale completions are
discarded by the existing
_stale_job_threshold; per-rank writergenerations are fenced; every registry/queue is bounded fail-closed.
groups (hybrid layouts byte-identical to Stage-1 store-only disk KV tier: eligible-group scoping + worker-local per-rank store (GLM53_KV_OFFLOAD, default off) #99) — without this the probe
layout had nothing to look up.
Launcher
GLM53_KV_OFFLOAD_RESTORE=1is accepted IFFGLM53_KV_OFFLOAD=1(refusedfail-closed pre-stop otherwise, zero docker/ssh calls); the restore overlay
rides the same artifact-guard /
--check-injected/ scp / mount / ordermachinery as the stage-1 pair (order pinned scope → store_local →
restore_g0);
offload_prompt_only:falseand every stage-1 knob unchanged.Stage-3 mamba cross-boot differential harness (design + fixtures ONLY)
tests/_mamba_differential.py+tests/test_mamba_differential_harness.py:park-at-boundary fixtures with stubbed KDA state tensors at the receipted ABI
(conv (10,12288) bf16 + temporal (32,128,128) fp32, real page 2,342,912 B,
9/9/8/8 layers, num_spec=7 in every header, padding never on disk) and the
exact bit-comparator stage 3 will run (a flipped bit localizes to its
(group, layer, tensor)).
tests/stage3_mamba_differential_protocol.shpinsthe live protocol (step 0 = receipt the still-open mamba state-index
convention) and refuses to run on this branch. This is an ABI/codec fixture
comparator, not stage-3 evidence — no live state was captured.
New pinned fixtures (read-only captures, sha256 in
tests/fixtures/README.md)offloading_connector.pyandsingle_type_kv_cache_manager.py(patchtargets) plus the core
sched/scheduler.py(receipt only, not patched) —captured from the live container running the identical vllm tree
(0.1.dev20051+g487ecf187; the four actual offloading patch-target fixture
sha256s were re-verified against it byte-exact; the core scheduler capture
is a non-target receipt — see the 2026-09-02 receipts comment's P3
exception).
Tests (host-side, all green: pytest 40 + 6 standalone runners)
tests/test_kv_offload_restore_g0.pytests/test_mamba_differential_harness.pytests/test_kv_offload_restore_venv.pytests/test_launcher_kv_offload.py(extended)Receipts (status 2026-09-02; history in the thread's receipts comments)
Rows 1 and 4 are captured. Rows 2/3 were run live on a purpose-built
single-group probe (2026-09-02 receipts comment) and remain open on three
branch gaps that run found: (A) the v1 loader's fail-closed mapped-layout
guard means no dense model can exercise the restore chain (
ACTIVEprovesscheduler eligibility, not worker restorability); (B) the launcher leaves
kv_load_failure_policyat the image defaultfail, so load failures 500the request instead of the designed degrade-to-recompute; (C) no
per-boundary failure suppression exists after a failed load. Each needs a
reviewed branch commit before rows 2/3 can close:
GLM53_KV_OFFLOAD=1 GLM53_KV_OFFLOAD_RESTORE=1; the boot log shows[glm53-kv-offload-restore] restore INERT on this layout: layout has 7 KV-cache groups (5 eligible)…on the head; serving probes green;decode/prefill ranges overlap Stage-1 store-only disk KV tier: eligible-group scoping + worker-local per-rank store (GLM53_KV_OFFLOAD, default off) #99's knob=1 sample, but this capture does
not establish the body's "within noise" criterion (no decode-rate
comparison was captured).
plan §5/F5) — OPEN, blocked on gap A (then B): park a session past
the store cascade; new request hits the disk lookup → async-load path
evidenced by
WAITING_FOR_REMOTE_KVSstate occupancy (the core logs thein-state line at DEBUG only and never logs the transition pair), the
disk load job N restored …line on BOTH ranks, zero load errors, and afollow-up request served as an ordinary GPU prefix hit with zero disk
traffic. 2026-09-02: everything upstream of the worker pread is
live-receipted on the dense probe (cascade, lookup/offer, state entry,
job creation on both ranks); the pread stage requires an MLA-layout
model or v1.1 inverse-scatter support.
recompute path applies only when
kv_load_failure_policy="recompute"isexplicitly configured; the current launcher does not set it and has not
proven live reprefill): corrupt one
chunk file (bit flip) and delete one manifest on one rank → restore
degrades to recompute (invalid-block log + recompute), output equals the
cold-path control, fresh-session control green. The null-block exclusion
is host-suite evidence (
test_kv_offload_restore_g0.py); live logs carryonly counts. 2026-09-02: the worker half (fail-closed, invalid-block
report, zero-fill) is live-receipted; the scheduler recompute half needs
kv_load_failure_policy="recompute"pinned by the launcher plusper-boundary failure suppression.
RESTORE=1withoutOFFLOAD=1refusedpre-stop with rc=2 and the serving container's
StartedAtunchanged(live); the zero docker/ssh-call property is established by launcher stub
tests, not the live transcript.
RESTORE=0adds no restore arguments;the live capture establishes serve-argv parity only, not byte-for-byte
runtime parity with Stage-1 store-only disk KV tier: eligible-group scoping + worker-local per-rank store (GLM53_KV_OFFLOAD, default off) #99.
overlay logs neither publish counts nor the scheduler AND, so the
literal wording is not observable. Live-receipted instead: writers up on
both ranks and a real boundary offered from disk with the load job
created on BOTH ranks — per the overlay source a boundary is offered
only after the scheduler ANDs
+events from both ranks, so this issource-backed indirect evidence the cross-rank registry ANDed live.
Submitted by nood-co1 on behalf of Blockbrain Labs (https://x.com/blockbrain_labs, GitHub org blockbrain-ai). Measured on our 2× NVIDIA DGX Spark deployment.