kv-cache : resolve the partial KV residency set once for the model - #67
Piggidragon wants to merge 5 commits into
Conversation
|
Automated preliminary review by Codex; the repository owner plans a separate manual review. Verdict: FAIL. Blocking
Will slow review
Developmental progress
Reviewed head: e08ca85 |
--kv-gpu-layers was resolved inside each cache, so a cache built from several sub-caches (iSWA, DSA, DSV4, MSA) would have given each of them the full budget and was disabled for all of them. It also counted layers the attention cache does not own, so on a hybrid model most of the budget went to recurrent layers, and it took layers in layer order, which fills the device owning the first layers and leaves the free memory of the others unused. Resolve one set of layer indices for the whole model instead, from the layers the requesting context actually owns, and take them per owning device. An MTP context owns the nextn layers, which sit above the layers of the main context. Assisted-by: Claude Opus 5
The picker excluded every recurrent layer and counted its own choice as the result. Falcon H1 marks all of its layers recurrent yet caches all of them, so a request placed nothing; Nemotron H caches only the non-recurrent layers without an FFN, so part of the budget went to layers the cache then dropped, and the count still said they were resident, which can enable the attention compute offload for nothing. Ask the same ownership filter the hybrid cache uses, and report the layers the caches did place. Assisted-by: Claude Opus 5
e08ca85 to
fe498b7
Compare
A cache built from several sub-caches placed the same layer in each of them. The residency tests get their own invocation instead of running in the arch sweep. Assisted-by: Claude Opus 5
Refresh the PR against llama/dev. Fix router and nextn ownership, scope the sliding-window guard to owned layers, and strengthen placement tests and documentation. Assisted-by: Codex
|
Update for reviewed head The blocking findings from the earlier review of Validation on the published source:
Before merging, finish and assess the fresh Linux, Windows, ARM64, server and WebGPU CI runs. Self-hosted checks are still queued. The previous ARM64 failure was an uninitialized-array warning in The CANN workflow failure occurs before any jobs run. Its unchanged workflow has all jobs commented out. This is an existing workflow issue outside this PR; repair or explicitly accept that CI exception before declaring the checks clear. Coverage limit: local validation used tiny deterministic fixtures on one physical RTX 5070 Ti. The additional CUDA devices were virtual, so physical multi-GPU behavior is still unverified. The known tensor/iSWA mixed-residency combination remains guarded. PR #68's separate capacity-accounting blocker does not block this PR. #67 remains open and unmerged. |
# Conflicts: # tests/test-llama-archs.cpp
Overview
--kv-gpu-layerskeeps part of a host-resident attention cache on the devices. It was resolvedinside each cache, which went wrong three ways:
llama_kv_cacheandllama_memory_hybridoverrideget_supports_partial_kv(); iSWA, DSA, DSV4 and MSA fall through tothe base
false, andcreate_memoryhanded them aspecialized_placementwithgpu_resident_layers = 0. Each sub-cache would otherwise have taken the full budget, so the optionwas disabled for all of them rather than divided.
the free memory of the others unused.
Resolve one set of layer indices for the whole model instead, in
create_memory, from the layers therequesting context actually owns, and take them one per owning device in turn.
get_supports_partial_kvand the
specialized_placementcopy both go away.An MTP context owns the nextn layers, which sit above
hparams.n_layer(); the selection usesn_layer_alland the context type so those still resolve.Two filters exist only because the budget is now resolved once for the whole model rather than per
cache, where each cache applied its own. Neither fixes a defect on
llama/dev; both prevent onehere. An MTP context owns the nextn layers, which sit above
hparams.n_layer(), so the selectionruns over
n_layer_alland filters by context type. A recurrent layer keeps its state outside theattention cache, so it is skipped rather than counted against the budget.
Split out of #57. Independent of the host-cache correctness fix (#66).
Testing
Two GPUs, RTX 4070 (gen4 x16) + RTX 3060 (gen3 x4), CUDA, NCCL, stock clocks. A 15216-token prompt
from this repository's docs,
-c 20480 -n 64 -ngl 99 -nkvo --kv-cpu-pinned -sm layer.An iSWA cache could not use the option at all. gemma-4-26B-A4B:
--kv-gpu-layersignoring kv_gpu_layers)Before, both sub-caches stay entirely in host memory (
CUDA_Host KV buffer size = 400 MiBand300 MiB, no device KV) and the context logspartial GPU KV residency is not supported for this memory layout. After, the budget is dividedacross the sub-caches and the devices. +36% generation, +14% prefill (1513 -> 1723 t/s).
The layers all landed on one device. Qwen3.8-27B-UD-Q5_K_M,
--kv-gpu-layers 4:CUDA0 KV 320 MiB, no CUDA1 KVCUDA0 KV 160 MiB,CUDA1 KV 160 MiBBoth runs allocate identical model and compute buffers and produce the same graph split count, so the
difference is only which device gives up which layers. Against the same model with
--kv-gpu-layers 0(4.36 t/s), taking the layers in order is worth +4.6% and spreading them +23%.tests/test-llama-archs.cppgainstest_mtp_kv_residency, which builds an MTP context with--kv-gpu-layers 0and1and asserts the host-resident context memory actually shrinks. It failsif the budget resolves against the main context's layer range, which is disjoint from the MTP cache's.
test-llama-archs -s 1at 1, 2, 3 and 4 virtual CUDA devices: passes. Built with-DLLAMA_FATAL_WARNINGS=ON.Requirements
Assisted-by:commit trailer.