Repository navigation
Multi gpu: Layer split: pinned arena, lent prompt buffers, tested planner (2 x 2080 Ti decode +34%, 29K prompts +61%) - #223
giostrives wants to merge 5 commits into
Conversation
…A 12.0 failed) It names kernels only for the STRATA_VERIFY_NODES debug dump. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A split capped the arena's pinned registration at 8 GiB on every platform. The cap is a WDDM workaround (pinning all of it into two contexts left the driver refusing later allocations on the 5080 + 3090 rig), but on Linux it cost the split the PCIe share of every missed expert past the first 8 GiB of layers, and made its prompt path stage most experts through host copies. One GPU pins all 33 GiB on the same machine. The cap now applies under WDDM only (layer_split::arena_pin_cap, tested). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One GPU has always borrowed the top slots of its expert cache for the prompt path's buffers and refilled them after the prompt. A split instead gave every card its own 2048-token buffers for the whole session (~1.5 GiB a card) and read prompts in 2048-token chunks, a third of one card's auto 6144. Now every card lends from its own cache and all of them read the same chunk (the rows handed from card to card are that size): layer_split::plan_lend picks the largest chunk every card can lend, with the rule one card used. At a prompt, each card lays its buffers out in its own slots; a residency entry is lent or refilled on the card that owns its layer (slot numbers are per card). --no-prefill-borrow keeps the old behaviour. A later card's reserve counted the drafter it already holds (1 GiB): 1.3 GiB of the second 2080 Ti stayed free for the whole session. It is now 128 MiB for the drafter's head over the vocabulary. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-off term The placement's cost model moves out of main() into layer_split::Planner: the same fill (each card's layers' profiled pairs, hottest first, stopping at the first that does not fit), the same search (every placement for two or three cards, in proportion to speed beyond), and the same per-layer time from SMs x clock. Each later card now adds a hand-off per window (STRATA_SPLIT_HANDOFF_MS, 1 ms), so a card that holds little does not come for free, and the routing curve's exponent is a parameter (STRATA_SPLIT_MASS_EXP), since it differs between models. split_pays() compares a split with one card, for the start-up decision that is still to come. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sults/2026-09-30-layer-split-2080ti) One card 33.9 tok/s decode, 618-801 tok/s prompts; the split before 35.8 and 391-535; the split now 45.3-47.3 and 609-1,290 (+61% over one card at 29K). A K sweep (18/25/31/36) where auto's K=25 is the best measured, a fixed-cache check that lending and refilling both cards' slots leaves the answers byte-identical, the harness and the raw results. docs/MULTI_GPU.md gets the table. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
This PR partially overlaps with #216, @gopinath87607 . What I did extra here is some more tests, removing the memory pin for Linux and adding a planner. I'm happy to rebase and adapt these changes (removing some of them) after the other PR. |
|
Thanks @giostrives, great measurements. #216 covers the per-card loans and the reserve, so please open a new PR on top of it once it lands, with only the full expert-arena pin on Linux and the planner in |
|
#216 is in 0.1.30. As discussed, a new PR with just the Linux full-arena pin, the planner ( |
On 2 x RTX 2080 Ti the layer split was barely faster than one card for decode and about 30% slower for prompts. This branch fixes how the split is set up. On this setup the split is now the faster configuration for both decode and long prompts.
Changes
Related
The first commit is the same fix as #209 (cudaFuncGetName guarded for CUDA < 12.3). If #209 lands first, I'll drop the commit and rebase. Otherwise this MR carries it, and #209 can be closed as superseded.
Results
Qwen3.8-Flash-Next IQ2_XS, 2 x RTX 2080 Ti 11 GB, i7-7700K, 32K context, int8 KV, --spec 4. Same harness for every row, and every needle was found.
Testing