Skip to content

server: keep speculative checkpoints on device (6 lines) — free for anyone to take upstream - #1

Open
JayToltTech wants to merge 1 commit into
masterfrom
fix/spec-checkpoint-on-device
Open

server: keep speculative checkpoints on device (6 lines) — free for anyone to take upstream#1
JayToltTech wants to merge 1 commit into
masterfrom
fix/spec-checkpoint-on-device

Conversation

@JayToltTech

@JayToltTech JayToltTech commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Overview

Six call sites in tools/server/server-context.cpp gain LLAMA_STATE_SEQ_FLAGS_ON_DEVICE. No new code paths: the library already implements the on-device route, the server never requested it.

A recurrent-hybrid target cannot partially seq_rm, so the server takes a full recurrent-state checkpoint every speculative round and restores it on every rejection. Via the host path that is one synchronous backend read per tensor for every GDN conv+state row, the 4-stream residual and the PLE history. Flat in context, ~600 ms of an ~825 ms round.

The four prompt-cache checkpoint sites are deliberately unchanged: they retain several historical states, not one live round, so the flag's invalidation contract does not hold there.

Measured

Three backends, independent testers:

backend reporter result
Vulkan, gfx1151 (Strix Halo) this fork 4.77 → 25.83 tok/s short; 4.33 → 16.08 at 70k; acceptance unchanged 70-80%
CUDA, RTX 3090 / Windows @mjungnickel18 (on ggml-org#27836) +61% on code; flips MTP from a small loss to a small win
Metal, M5 Pro @ovidiu-morar (on ggml-org#27836) no measurable change; flag verified not a no-op

Consistent reading: a win where per-round host round-trips are expensive, neutral where they are cheap. Not a regression anywhere tested.

Provenance

The ON_DEVICE flag and mechanism are Gaetan Puleo's (c8b681b6f, carried in Nathanw1014/llama.cpp as 08a3255). What is here is only the identification of which call sites need it. Mechanism diagnosis assisted by an AI agent (Claude).

Status

Not submitted upstream, and not intended to be. It exists on this fork for anyone who wants to carry it. No authorship or attribution is claimed or required — anyone is free to take this upstream as their own without credit or consultation.

Not verified

Prompt-cache paths untested beyond being untouched. No VRAM-cost measurement per slot, or scaling with --parallel.

Requirements

  • AI usage disclosure: YES — the mechanism was diagnosed with AI assistance and this description was AI-drafted. That is why this sits on a fork rather than being submitted upstream: llama.cpp prohibits AI-written PR descriptions, and anyone taking this upstream should write their own.

qwen4exp is a recurrent hybrid, so the target context cannot partially seq_rm
and the server classifies it SEQ_RM_TYPE_FULL. Every speculative round then
takes a full recurrent-state checkpoint, and every rejected draft restores one.
Through the host path that means serializing each GDN layer conv+state row, the
4-stream hyper-connection residual and the PLE history into a host vector with
one synchronous backend read per tensor, then pushing it all back.

The cost is flat in context and swamps everything else: with the MTP drafter
attached, decode ran 201 ms/token against 29 ms/token on a tree that keeps the
state on device, and a 120-token generation spent roughly 600 ms of each 825 ms
round in checkpoint traffic. It also inflates the reported prompt eval time,
which runs to first token and so absorbs the first save: 827 ms for an
11-token prompt.

Request ON_DEVICE at the six speculative checkpoint sites so the state stays in
device buffers. The library already implements this path; only the server never
asked for it. Measured on gfx1151 Vulkan, Qwen3.8-Flash-Next UD-Q4_K_XL with a
Q4_K_M MTP head: 4.77 -> 25.83 tok/s at short context, 4.33 -> 16.08 at 70k,
draft acceptance unchanged at 70-80 percent.

The prompt-cache checkpoints are deliberately left host-resident: they retain
several historical states rather than one live round.

Diagnosed by Claude Fable 5. The ON_DEVICE flag and the mechanism come from
Gaetan Puleo (c8b681b6f), carried in Nathanw1014/llama.cpp as 08a3255.

(cherry picked from commit 175b66c)
Copilot AI lite review requested due to automatic review settings September 1, 2026 13:51
@github-actions github-actions Bot added the server label Sep 1, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unconditionally enabling on-device checkpoints can increase persistent backend memory usage per slot and can hard-abort on allocation/mismatch, so it should be gated and/or have a safe fallback to preserve server reliability.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adjusts the llama.cpp server’s speculative-decoding checkpointing to request on-device sequence-state save/load, aiming to avoid expensive host round-trips when restoring state (notably for recurrent/hybrid memories) and improve speculative throughput.

Changes:

  • Add LLAMA_STATE_SEQ_FLAGS_ON_DEVICE to speculative checkpoint save calls (update_tgt / update_dft).
  • Add LLAMA_STATE_SEQ_FLAGS_ON_DEVICE to speculative checkpoint restore calls (load_tgt / load_dft).
File summaries
File Description
tools/server/server-context.cpp Switch speculative checkpoint save/restore to request on-device state storage via LLAMA_STATE_SEQ_FLAGS_ON_DEVICE.
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

//const int64_t t_start = ggml_time_us();

ckpt.update_tgt(ctx_tgt, slot.id, LLAMA_STATE_SEQ_FLAGS_PARTIAL_ONLY);
ckpt.update_tgt(ctx_tgt, slot.id, LLAMA_STATE_SEQ_FLAGS_PARTIAL_ONLY | LLAMA_STATE_SEQ_FLAGS_ON_DEVICE);
@JayToltTech JayToltTech closed this Sep 1, 2026
@JayToltTech JayToltTech reopened this Sep 1, 2026
@JayToltTech JayToltTech changed the title REVIEW: server - keep speculative checkpoints on device (6 lines, 4.77 -> 25.83 tok/s) server: keep speculative checkpoints on device (6 lines) — free for anyone to take upstream Sep 1, 2026
scchow added a commit to scchow/llama.cpp that referenced this pull request Sep 2, 2026
qwen4exp is a recurrent hybrid: the server classifies it SEQ_RM_TYPE_FULL,
so every speculative round checkpoints the full recurrent state (GDN
conv+state, 4-stream HC residual, PLE history). Through the host path that
is a synchronous per-tensor readback + push, ~600 ms of an 825 ms round on
gfx1151; +61% on RTX 3090 CUDA; neutral on Metal (community-verified,
JayToltTech#1). The library already implements the on-device
path; the server just never asked for it.

Signed-off-by: Scott Chow <scott@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants