mirror of
https://github.com/kvcache-ai/ktransformers.git
synced 2026-11-05 01:07:28 +00:00
[GH-ISSUE #2227] Borrowed Prefill: lend the GPU's idle dense-weight VRAM to the prefill chunk — 3-4x faster hybrid prefill on 16 GB cards, same KV pool #1308
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
kvcache-ai/ktransformers#1308
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @05yuki on GitHub (Oct 7, 2026).
Original GitHub issue: https://github.com/kvcache-ai/ktransformers/issues/2227
Sharing a patch set for the KT hybrid (CPU experts in kt-kernel, SGLang on the GPU) in case it is useful to others here, and to ask whether any of it is worth upstreaming.
The problem. With the GPU-streamed prefill, every chunk pays a fixed cost to move a layer's experts over PCIe, so a bigger chunk is faster. On a 16 GB card the chunk is capped by what decode leaves free: attention weights, hot experts, KV pool, CUDA graphs. Meanwhile, during a prefill, the decoder-layer weights that sit in VRAM do nothing until their layer runs.
What the patch does. Before a long prefill it pauses the decoder-layer weights with torch_memory_saver (physical memory released, virtual addresses kept, so the decode CUDA graphs stay valid), streams each layer's weights back from a pinned host copy just before that layer runs, and puts everything back before the next decode step. Prefill-only buffers live in a second region that is resident only during prefill. The KV pool is untouched by default: a calibration launch measures the chunk that fits, and a guard refuses any chunk that would shrink the pool.
Numbers (2x RTX 5070 Ti 16 GB, dual EPYC 7452, single stream, base and lend measured the same day with the same prompts):
V4.1 prefills a 989K-token prompt to the end at the full 1,048,576-token KV pool on these two cards.
Repo, patches per tree, and the write-up: https://github.com/05yuki/kt-prefill-lend
Upstream question. The lend itself sits on our GPU-streamed prefill, which is not in upstream SGLang, so the whole thing does not transplant as a PR. Two pieces are independent of it and I would be glad to send either if there is interest:
kt_kernel/utils/loader.py.deepseek_v4.py'sload_weights, the ~100K routed-expert tensors that live on the CPU each go through the name remap, the expert-mapping scan and a weight_loader call that returns at once; skipping them right after the remap (using the same logical -> physical -> local mapping the loader applies) removes most of that Python time.Happy to open either as a PR against the branch you prefer.