Repository navigation
Conversation
…th (Niko1221#656) Niko1221#656 lets a long prompt read give way at a chunk boundary to a waiting request whose prompt is under half as long. It compares prompt lengths only. An agent's requests all carry a long system prompt and the history, so a waiting follow-up turn is almost never under half of a fresh read: it waits for the whole read, though it needs a few hundred tokens. The rule now compares tokens left to read on both sides: - a waiting request: its prompt less the start the engine holds for sure - all a slot holds, or a slot's or an earlier read's prompt up to its last turn token (where the engine checkpoints a prompt), while a slot still holds it or the conversation cache parked it (its slots' worth of the latest reads); - the read on the control lines: what its PP lines say is left (reset when a read is sent; a request that arrives no longer clears it). A read gives way only while the waiting request gets a slot at once (an admission: one free slot; a solo read: two), so nobody waits on the control lines for a slot that a parked part needs. Only prompts read to their end are noted. Each slot's held list is packed once; whole prefixes compare with startswith. Tests: a follow-up whose conversation a slot holds is answered before a fresh read of about the same prompt length (fails before this change: 2.25 s against 1.61 s); the rule case by case; its cost (8 slots of 50K tokens, 16 waiting: under 50 ms a check). The server suite passes (457). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Tested on a layer split. Rig: 4× RTX 5080 16 GB (PCIe Gen3), i9-10920X, Qwen3.8-Flash-Next IQ3_S, 262K, int8 KV, Scenario (
So on this setup the read did not give way: the follow-up still waited for (almost) the whole read. It may be that |
|
Follow-up, now on 0.1.40.2 with this PR on top, to rule out the chunk size: same scenario (agent conversation held, a fresh 45K-token read starts, the agent's short follow-up arrives 2 s later). Same rig (4× RTX 5080 split,
The follow-up alone answers in 0.15 s. Even with 8K chunks, so several chunk boundaries inside the read, it waits for the whole read. My reading is that the give-way decision isn't reached on the |
|
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. |
#656 lets a long prompt read give way at a chunk boundary to a waiting request whose prompt is under half as long. It compares prompt lengths only. An agent's requests all carry a long system prompt and the history, so a waiting follow-up turn is almost never under half of a fresh read: it waits for the whole read, though it needs only a few hundred tokens. In a replay of a multi-user agent workload (a 27K-token system prompt, 5-15 users, RTX PRO 5000), 2,086 prompt reads gave way 1 time.
What changes (serve/server.py only)
The rule compares tokens left to read on both sides:
<|im_start|>, where the engine checkpoints a prompt and the next turn resumes), while a slot still holds it or the conversation cache parked it (only its slots' worth of the latest reads);A read gives way only while the waiting request gets a slot at once (an admission: one free slot; a solo read: two, one for its parked part), so a request never waits on the control lines for a slot that a parked part needs to go on. Only prompts read to their end are noted. Each slot's held list is packed once; whole prefixes compare with
startswith(8 slots of 50K tokens and 16 waiting prompts: under 50 ms a check).A wrong guess (an evicted conversation, for example) costs one give-way, and a request gives way at most
YIELDS_MAX(2) times; outputs do not change (batch_interleave_testcovers a read that gives way).Behaviour change: a fresh short prompt no longer makes a long read give way when the read has less than twice that left (the old rule compared full lengths).
Tests
test_a_long_read_gives_way_to_a_follow_up_its_slot_holds: a follow-up whose conversation a slot holds is answered before a fresh read of about the same prompt length. On main it fails (2.25 s against 1.61 s).GiveWayByWhatIsLeft: the rule case by case (partial prefixes, reads noted only at their end, the turn-token resume point, the free-slot condition, the read's own progress) and its cost.Measured (RTX PRO 5000 48 GB, the 0.1.40 engine, only server.py differs)
"parallel": 8with the conversation cache on. Public text (the repository's own code and docs). B's first turn (~20K tokens) is answered; a fresh ~30K-token prompt A starts its read; 1 s later B's second turn arrives (about 24 new tokens). Median of 3 rounds:The engine takes the give-way at the chunk boundary after the one where the server asks (8,192-token chunks here), and not when less than a chunk is left (the third round).
In our own 8-user replay (95% of prompt tokens reused, so 276 of 325 reads needed under 2K new tokens), the new rule gave way 1 time; the time to first token was 1.54 s median / 4.43 s p90 with the old rule and 1.35 s / 4.63 s with the new one (the p90 within noise). The long reads there were mostly two chunks (12-16K new tokens): after the first boundary one chunk or less is left, and the engine does not give way then. So the change matters where a read of three or more chunks meets a cached follow-up.
🤖 Generated with Claude Code