Repository navigation
Conversation
…or decode and a share of every prompt chunk; plus --expert-cache-fill-all, --ple-io ram, --conv-cache (multi-conversation cache), async prompt checkpoints, and the prefill/decode kernel speed-ups
|
Thanks @q8atnight - a lot here. #108's kernels are in 0.1.22 in equivalent form and #109 is merged for 0.1.23; 0.1.22 also splits a model across GPUs (layer split). I can't merge the rest as one PR: could you split out (1) the async checkpoint copy-out, (2) the drafter's prompt pass on its own thread, and (3) |
|
Thanks @q8atnight, there's a lot of good work here, with 2x3090 numbers to match. Since #108 and #109 landed and 0.1.26 batches the drafter's prompt pass (0.9 s -> 0.07 s of a 32K prompt), the pieces that still apply are the async checkpoint copy-out and |
|
Split out as you asked, both on current main (0.1.27; they rebase onto 0.1.26 cleanly if you prefer):
Peer tier vs layer split, with numbers: #204. The conversation cache: #189 covers the same mechanism, so no competing PR from us — happy to share our measurements (resume timing, exactness gate, leak test) there. |
|
Thanks @q8atnight for splitting this into #202, #203 and #204, with the conversation cache going to #189. Closing this one in favour of those. |
What
Two-GPU support (closes #36), tested on 2x RTX 3090 with NVLink (P2P also works over PCIe, slower). The second card
is an expert tier, not a pipeline stage - the model's dense part stays on the primary, so the output is
bit-identical to a single card holding the same experts (see Exactness):
--peer-device N(+--peer-reserve-mib,--peer-slots,--peer-adapt-swaps): a second adaptive expert cacheon the other GPU. Decode: the pool launches the peer's share right after publishing the primary's plan; its rows come
back through the same mapped rows. Prompts: per MoE layer the peer computes the rows of the experts it holds
(activations in over P2P, results back group by group), streams a share of the primary's non-resident experts over
its own PCIe link (
STRATA_PF_PEER_STREAM, default 0.35), and does the selection + attention of the last halfof each chunk's queries in QSA layers. Group-sized (compact) peer buffers keep it at ~0.26 GB on the helper card.
--expert-cache-fill-all: auto sizing fills the whole card past the ranked profile pairs--ple-io ram: the n-gram table mmap'd + mlock'ed (no O_DIRECT SSD reads on the prompt/token path)--conv-cache N(+-gib,-min): up to N conversations another request displaced keep their positional cells(KV host copy, pooled indexer keys, drafter K/V) + checkpoints in RAM; switching back reads only the new part
(a 111K chat back in ~1 s instead of ~64 s). Complements serve: the conversation cache keeps its shared prefix; the rest rotates LRU #62 (which keeps the shared prefix of ONE branch).
device sync + pageable copies (~370 ms of GPU idle each)
visionblock may carryenv(e.g.CUDA_VISIBLE_DEVICES=0puts the image encoder on the helper card)STRATA_PREFILL_TIMINGnow also prints the peer GPU's own timelineMeasured (flashbench 1.0, IQ3_S, 262K context, tokens/s, median)
With Q2_0 / IQ2_XS all 24,576 experts fit on the two cards (Q2_0: ~2,170 tok/s prompt at 32K).
Exactness
Gate: a single-GPU config holding N experts vs a two-GPU config holding the same N split across both cards, static
residency (
--adapt-swaps 0 --pcie-frac 0),STRATA_MMQ_NO_STREAMK=1(a debug switch that turns off MMQ stream-k,whose tile split depends on the group's total tiles):
flashbench.py gategreedy outputs IDENTICAL on all prompts,after every step. With stream-k on, results differ only by MMQ's summation order.
Notes
CUDA_VISIBLE_DEVICES=1,0); P2P is enabled both ways at open.--peer-reserve-mibsets it.