Repository navigation
[Engine] evict redundant holders while preserving pinned prefixes - #2443
KeyanHu-git wants to merge 5 commits into
Conversation
|
The eviction rule reads right to me (every pinned prefix keeps one holder, and each eviction re-checks). Two follow-ups, found by reading (C++ test not built here):
|
|
Thanks @qiuzan2001 for checking both interactions. The documentation fix is in 3e0780a. You're right about The accounting needs to agree with repeated Since neither admission API is on main yet, I suggest landing this focused fix first, then updating the accounting in the admission PR that follows. If an admission PR lands first, #2443 will need that adjustment before merging. @Niko1221, could you review the current fix and let us know whether that landing order works for you? |
|
Follow-up: the cache-side accounting is now implemented in 613f78f. Keeping it in the cache defines the eviction contract in one place, while the admission policies remain in their respective PRs.
The updated suite passes 44,581 checks on macOS, Windows and Linux, and full CUDA/HIP/SYCL builds pass. Local combinations with #2253 and #2082 pass 44,641 and 44,651 CPU checks under ASan/UBSan, including admission by evicting a redundant pinned holder. The earlier real-model comparison remains from 44877b3; this follow-up was validated through CPU tests and backend builds. When rebasing #2253 or #2082, please retain this implementation instead of the unpinned-only definition, keep a single copy of the method, and preserve both sets of regression tests. The textual merge conflicts still need resolution. The PR description now records the implementation and validation details. |
|
Thanks for the pull request. We're resetting the tracker for 0.2.0-beta. There are more than 1,300 open issues and pull requests, too many for us to review properly, so we're closing everything that isn't being worked on right now. Closed here does not mean rejected. To reopen it takes about two minutes:
The rules are in CONTRIBUTING.md. |
|
/reopen |
|
Reopened, thank you. A maintainer will pick it up from here. If it conflicts with main, rebase it first; that speeds up review. |
…fixes Preserve one holder for every pinned prefix when evicting redundant parked conversations. Match tokens, image identity and steering mode, and retain the existing preference for unpinned victims. Cover multiple independent pins, multi-pin entries, identity differences, slot and byte pressure, and accounting. With a borrow in progress, the guarded donor is never evicted but still counts as a holder, and make_room's guard precheck uses the same simulated eviction, so it neither refuses a borrow that redundant holders can make room for nor evicts anything before refusing. Fixes Niko1221#2255
Signed-off-by: Keyan Hu <phycheor@gmail.com>
Expose a non-mutating evictable_bytes estimate using the same pin-matching rule as eviction. Track simulated removals so the last holder of each pin is excluded, along with retained KV storage. Keep the normal cache-sized scratch bitmap on the stack and avoid copying snapshot payloads. Cover every assignment of three pins to four conversations, identity separation, retained storage, and the stack/heap scratch boundary. Compare the estimate against actual repeated eviction and verify pin survival. Share the simulation with make_room's guard precheck, so a guarded donor is excluded from the estimate while still holding its pins. Signed-off-by: Keyan Hu <phycheor@gmail.com>
613f78f to
64a2275
Compare
Problem and result
A client that pins the same system prompt on each request can fill every conversation-cache slot with a different branch of that prefix. Upstream protects every holder from eviction, so later conversations cannot be parked even when the byte budget has room.
This change lets redundant holders leave while keeping every pinned prefix recoverable. On 0.2.2, the same 15-request sequence produced these results:
Related discussion
Fixes #2255. The repeated-pin case reported there remains reproducible on current main. Related admission work: #2253 and #2082; this PR supplies cache-owned reclaimable-byte accounting for those callers.
Approach
Evict unpinned entries first, then the oldest entry whose pinned prefixes all have another holder. Prefix identity includes token IDs, image identities and steering mode. A borrowed donor stays protected and counts as a surviving holder.
flowchart LR A[Old branch A] --> P[Shared pinned prefix] B[Branch B] --> P C[Branch C] --> P A --> E[Evict A to admit a new branch] B --> K[Prefix remains recoverable] C --> Kevictable_bytes()simulates the same removals as eviction, so it stops counting a prefix's last holder once earlier copies have gone. The borrow precheck uses that result before making room. Retained active K/V is accounted separately. No cache settings, budgets or snapshot formats change.The ownership rule is shared by slot/byte admission, physical-memory reclamation and session saving. The additional session-save regression checks that reclamation stops when enough memory is available, preserves a borrowed donor, and leaves the selected checkpoint's content and storage intact without allocating memory.
Validation
Base
011c9e60(0.2.2 / engine 0.1.47); production patchaf1e09dd. This update adds tests, documentation and recorded evidence; the production headers are unchanged. Results, inputs, reproduction commands and source hashes.Passed:
icpx. The new shared-pin reclamation case fails on unmodified main.git diff --checkand recomputation of the recorded result table.Failed: the first CUDA invocation omitted the conversation-test build option and could not find that target. The corrected command completed the engine build and both tests successfully.
Not run: CUDA, SYCL and Metal model execution; the real-model comparison was on HIP. The portable replay driver was checked with a protocol fixture; the recorded model run used the original sequential driver with the same commands and settings.
Limits
Eviction searches for redundant holders after no unpinned victim is available; guarded admission and reclaimable-byte queries also simulate this policy. The work depends on entries, checkpoints and prefix length. The real-model evidence covers one GPU and serial requests; it establishes restored cache reuse and matching outputs for that workload. The PR does not change the active checkpoint-retention policy or make physical-memory reclamation equal to logical freed bytes.