Skip to content

server: fix the off-by-two in the SWA reuse threshold - #30580

Merged
ggerganov merged 1 commit into
ggml-org:masterfrom
ServeurpersoCom:swa-reuse-threshold
Oct 15, 2026
Merged

ggerganov merged 1 commit into
ggml-org:masterfrom
ServeurpersoCom:swa-reuse-threshold

Conversation

@ServeurpersoCom

Copy link
Copy Markdown
Contributor

Overview

Found on master while testing #30574: after a slot restore on Gemma 4, the next turn reprocessed 71 tokens instead of 23, even though the restored state holds everything the turn needs.

Since #23981 a saved SWA state keeps only the cells inside its window, so a state read back from a slot file or from the RAM prompt cache starts at pos_max - n_swa + 1. The first evaluated token attends to the positions above pos - n_swa, so this is enough, but the reuse threshold asks for pos_min < pos - n_swa, two cells more than the window. The state is rejected and the slot rolls back to the previous checkpoint, which can be far behind or missing.

The SWA threshold now matches the window. A state without SWA keeps the exact bound, since the recurrent state must end right before the evaluated token.

Additional information

Gemma 4 E4B, tokens reprocessed on the turn after the state comes back:

  • slot save, erase and restore: master 71, this PR 23, same as a slot that was never saved
  • RAM prompt cache, switching back to a conversation: master 53, this PR 17

test_slot_restore_swa_window and test_prompt_cache_swa_window give tinygemma3 a 64 token window through the new override_kv harness field, and fail without this change. The rest of the server suite has the same results as master.

Requirements

The first evaluated token attends to the positions above
pos - n_swa, so a SWA state starting at pos - n_swa + 1 holds the
whole window, but the reuse threshold asked for two more cells.
A saved SWA state keeps only the cells inside its window, so a
state read back from a slot file or from the RAM prompt cache was
always rejected and the slot rolled back to a checkpoint.

The SWA threshold now matches the window, while a state without SWA
keeps the exact bound. The test harness gains override_kv, used to
give the SWA test model a window smaller than the test context.
@ServeurpersoCom
ServeurpersoCom requested a review from a team as a code owner October 15, 2026 08:55
@am17an

am17an commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

@ggerganov isn't this the same I mentioned to you earlier? i.e. SWA state-restore is not bit-exact

@ggerganov

Copy link
Copy Markdown
Member

No, the thing we discussed was about producing the same logits. This here is about reusing a valid saved state in a situation that master's logic currently discards.

@ggerganov ggerganov added the merge ready A maintainer can use this label to indicate that they consider the changes final and ready to merge. label Oct 15, 2026
@ggerganov
ggerganov merged commit 61ad80b into ggml-org:master Oct 15, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge ready A maintainer can use this label to indicate that they consider the changes final and ready to merge. server

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants