Skip to content

server : skip checkpoints beyond pos_next - #24411

Merged
ggerganov merged 2 commits into
ggml-org:masterfrom
aldehir:fix-checkpoint-restore
Jun 11, 2026
Merged

ggerganov merged 2 commits into
ggml-org:masterfrom
aldehir:fix-checkpoint-restore

Conversation

@aldehir

@aldehir aldehir commented Jun 10, 2026 •

Copy link
Copy Markdown
Contributor

Overview

While working on #24176, I noticed all the Gemma 4 models (12B and 26B in particular) were forgetful when sending a second identical initial message after a series of turns (e.g. the same agentic test case twice). I also noticed the issue did not appear when using cache_prompt = false.

I threw Fable at it, and it found an issue with checkpoints and SWA models. Here is a minimal repro to demonstrate the issue: checkpoint-restore-repro.py

master

=== request 1: first turn, baseline ===
finish_reason=stop content='pineapple'
=== grow turn 1: finish_reason=stop, 123 chars ===
=== grow turn 2: finish_reason=stop, 122 chars ===
=== grow turn 3: finish_reason=length, 108 chars ===
=== request 2: first turn again, diverges from the cached session ===
finish_reason=length content='0000 status=200 latency_ms=17\n2026-06-10T12:00:00Z service-a request_id=a-0000 status=200 latency_ms=17\n2026-06-10T12:01:07Z service-a request_id=a-0001 status=200 latency_ms=20\n2026-06-10T12:02:14Z service-a request_id=a-0002 status=200 latency_ms=23\n2026-06-10T12:03:21Z service-a request_id=a-0003'
FAIL: corrupted response after cache reuse (finish_reason=length, 850 chars)

PR

=== request 1: first turn, baseline ===
finish_reason=stop content='pineapple'
=== grow turn 1: finish_reason=stop, 123 chars ===
=== grow turn 2: finish_reason=stop, 122 chars ===
=== grow turn 3: finish_reason=length, 108 chars ===
=== request 2: first turn again, diverges from the cached session ===
finish_reason=stop content='pineapple'
PASS: secret word returned after cache reuse

Is this a legitimate issue and fix? It appears to have fixed the issues I was seeing.

Requirements

@aldehir
aldehir requested a review from a team as a code owner June 10, 2026 11:57
@aldehir
aldehir requested a review from ggerganov June 10, 2026 11:58
@ggerganov

Copy link
Copy Markdown
Member

This is a regression introduced by #23981. After the change, the checkpoint server information claims to cover a larger position range than it actually does (due to the new masking logic during saving the checkpoint).

I think a better fix would be to reflect the correct position range.

Something like this probably:

diff --git a/tools/server/server-context.cpp b/tools/server/server-context.cpp
index bdfa51718..1cff8ad61 100644
--- a/tools/server/server-context.cpp
+++ b/tools/server/server-context.cpp
@@ -2046,7 +2046,7 @@ private:
 
         auto & cur = slot.prompt.checkpoints.emplace_back();
 
-        cur.update_pos(slot.prompt.n_tokens() - n_tokens_cur, pos_min, pos_max);
+        cur.update_pos(slot.prompt.n_tokens() - n_tokens_cur, pos_max - n_swa, pos_max);
 
         cur.update_tgt(ctx_tgt,       slot.id, LLAMA_STATE_SEQ_FLAGS_PARTIAL_ONLY);
         cur.update_dft(ctx_dft.get(), slot.id, LLAMA_STATE_SEQ_FLAGS_PARTIAL_ONLY);

@ggerganov
ggerganov merged commit db94854 into ggml-org:master Jun 11, 2026
21 of 25 checks passed
@aldehir
aldehir deleted the fix-checkpoint-restore branch June 11, 2026 07:25
@aldehir

aldehir commented Jun 11, 2026 •

Copy link
Copy Markdown
Contributor Author

I tested your recommendation and it also fixes the issue. Also looks like it improves cache reuse, as it is selecting a checkpoint closer to the end in my limited testing. That said, I don't fully understand the implications.

@ggerganov

Copy link
Copy Markdown
Member

Yup, I'll follow-up on this. It needs some unit tests and a more robust way to determine the position range of the saved checkpoints.

anaisbetts pushed a commit to anaisbetts/llama.cpp that referenced this pull request Jun 16, 2026
* server : skip checkpoints beyond pos_next

* cont : update comment + TODO + ref

---------

Co-authored-by: Georgi Gerganov <ggerganov@gmail.com>
(cherry picked from commit db94854)
(cherry picked from commit b4267b2bc8aee70edb578a00f43992eae872ae5d)
adrianhoehne pushed a commit to adrianhoehne/llama.cpp that referenced this pull request Jul 5, 2026
* server : skip checkpoints beyond pos_next

* cont : update comment + TODO + ref

---------

Co-authored-by: Georgi Gerganov <ggerganov@gmail.com>
zommiommy pushed a commit to zommiommy/llama.cpp that referenced this pull request Aug 18, 2026
* server : skip checkpoints beyond pos_next

* cont : update comment + TODO + ref

---------

Co-authored-by: Georgi Gerganov <ggerganov@gmail.com>
zbrad pushed a commit to zbrad/llama.cpp that referenced this pull request Sep 10, 2026
* server : skip checkpoints beyond pos_next

* cont : update comment + TODO + ref

---------

Co-authored-by: Georgi Gerganov <ggerganov@gmail.com>
frostyautumnleaf pushed a commit to frostyautumnleaf/llama.cpp that referenced this pull request Oct 5, 2026
* server : skip checkpoints beyond pos_next

* cont : update comment + TODO + ref

---------

Co-authored-by: Georgi Gerganov <ggerganov@gmail.com>
Jackson57279 added a commit to Zapdev-labs/llama.cpp that referenced this pull request Oct 8, 2026
SWA caches only serialize the cells inside the sliding window, so a saved
sequence state covers a narrower position range than the memory reports.
Stamp checkpoints with the serialized range instead of the full memory
range, so checkpoint reuse does not overclaim coverage and reuse closer
checkpoints correctly.

Add llama_memory_state_pos_min/max to query the saved coverage for a
given set of save flags. The default is the memory range; caches that
serialize less data (SWA masking, PARTIAL_ONLY saves, joint caches)
narrow it accordingly.

Refs: ggml-org#24411 (comment)

Assisted-by: Devin

Co-authored-by: Jackson Wheeler <jackson@email.zapdev.link>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants