Skip to content

Bank striping across N devices: WASTE_BANK_SHARDS, record-granularity round-robin - #53

Open
mfethe1 wants to merge 1 commit into
sqliteai:mainfrom
mfethe1:feature/lenny/bank-striping
Open

Bank striping across N devices: WASTE_BANK_SHARDS, record-granularity round-robin#53
mfethe1 wants to merge 1 commit into
sqliteai:mainfrom
mfethe1:feature/lenny/bank-striping

Conversation

@mfethe1

@mfethe1 mfethe1 commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

What

Optional multi-device expert-bank striping. Set WASTE_BANK_SHARDS=/mnt/a,/mnt/b and each layer's bank opens as N shard files (bank basename in each dir); expert e is read from shard e % N at offset (e / N) * rec_bytes. tools/split_banks.py produces and byte-verifies shard sets. Unset env = exact current behavior — unstriped is the N=1 case of the same code path.

Why

Per-token demand is top-k experts of a single layer — one file today, so one device serves every expert read of a token. Round-robin record placement spreads a token's reads across devices, so effective bandwidth scales toward min(N, readers) with the existing async reader pool (WASTE_IO_THREADS). On a 2-drive rig this targets ~1.8-2x; on 4 NVMe with more readers, more.

No container format change: shards are plain files named after each bank. Fail-closed: any missing or short shard refuses the load.

Evidence

  • tiny.waste split across 2 dirs: logits byte-identical to unstriped (sha256 de62689a…, argmax + max-logit equal) — correctness gate is identity, not tolerance
  • tools/split_banks.py --mode verify: every record byte-identical post-split
  • make check 48 passed / 0 failed (13 skips: no real container locally)
  • ASan+UBSan striped run: 0 findings, same-build striped==unstriped byte-exact

Not claimed

No device A/B numbers yet — needs a 2-drive rig with a real container. This PR is the mechanism; the bandwidth measurement follows on hardware.

@mfethe1
mfethe1 force-pushed the feature/lenny/bank-striping branch from 55948c0 to 09ada61 Compare August 27, 2026 08:07
WASTE_BANK_SHARDS=dirA,dirB,... opens each layer's bank as N shard files,
expert e on shard e%N at offset (e/N)*rec_bytes. Round-robin because the
per-token demand is k experts of ONE layer — layer-granularity placement
would leave every read of a token on one drive. Unstriped is the N=1 case
of the same code path; env unset = exact prior behavior.

- waste_bank: fd[16] + n_shards; all 6 deref sites migrated
- load: manifest-driven shard open, fail-closed on short shard sets
- bank_fetch: shard+offset resolution, byte-exact by construction
- tools/split_banks.py: split + byte-for-byte verify modes
- evidence: tiny.waste striped across 2 dirs, logits byte-identical
  (sha de62689a...), make check 48/0, ASan+UBSan striped run clean 0 findings
@mfethe1
mfethe1 force-pushed the feature/lenny/bank-striping branch from 09ada61 to bc710d5 Compare August 27, 2026 08:13
@mfethe1

mfethe1 commented Aug 27, 2026

Copy link
Copy Markdown
Contributor Author

Repointed the PR branch to a clean single-commit base on current main (878352b) — it was previously stacked on the unmerged #48 branch, which made the diff carry unrelated commits and left mergeable_state: dirty.

Verified on the rebased head before pushing: make check 44 passed / 0 failed / 13 skipped; split_banks.py split+verify roundtrip on a fresh make_test_container fixture (all records byte-identical across shards); logits byte-identical striped vs unstriped (--json sha256 match on both arms); ASan/UBSan clean in the local suite. CI is now 9/9 green on bc710d5 and the diff is exactly the three intended files (src/model.c, src/model.h, tools/split_banks.py). The striping behavior is unchanged from the original description — only the base and the missing SPDX header in the new tool are different.

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.

1 participant