Skip to content

spec : save the dynamic ngram cache file - #22055

Open
petersid2022 wants to merge 1 commit into
ggml-org:masterfrom
petersid2022:self-speculation-save-cache
Open

spec : save the dynamic ngram cache file#22055
petersid2022 wants to merge 1 commit into
ggml-org:masterfrom
petersid2022:self-speculation-save-cache

Conversation

@petersid2022

@petersid2022 petersid2022 commented Apr 17, 2026

Copy link
Copy Markdown
Contributor

Overview

  • When we select the COMMON_SPECULATIVE_TYPE_NGRAM_CACHE speculative implementation we create a new common_speculative_state_ngram_cache state using create_state_ngram_cache, where we instantiate the new state by specifying various parameters (e.g, n_draft, save_static and save_dynamic) by hardcoding them.

  • Instead we remove those options and only depend on the existence of lookup_cache_dynamic and lookup_cache_static (both user provided) for enabling the saving and updating the dynamic cache into a file.

  • on object destruction check if the above functionality is supported (i.e. if the lookup_cache_dynamic path is provided by the user) then merge all of the ngram_cache_context from each sequence info and save the final common_ngram_cache to a file using common_ngram_cache_save.

  • catch std::ifstream::failure the way llama-lookup does, so a permission/read failure cannot replace the file

Additional information

Add self‑speculative decoding (no draft model required)#18471

Requirements

@petersid2022
petersid2022 force-pushed the self-speculation-save-cache branch from 2e1c956 to 430c0ca Compare April 18, 2026 13:14
@petersid2022
petersid2022 marked this pull request as ready for review April 18, 2026 13:37
@petersid2022
petersid2022 requested a review from a team as a code owner April 18, 2026 13:37
@petersid2022
petersid2022 force-pushed the self-speculation-save-cache branch 2 times, most recently from d5448ea to ba99720 Compare April 20, 2026 05:49
@petersid2022
petersid2022 requested review from a team, CISC, IMbackK, ggerganov and pwilkin as code owners April 20, 2026 05:49
@petersid2022
petersid2022 force-pushed the self-speculation-save-cache branch 4 times, most recently from cf7a308 to 8ae6c04 Compare April 20, 2026 06:59
@CISC
CISC removed request for a team, CISC, IMbackK and pwilkin April 20, 2026 08:03
@petersid2022
petersid2022 force-pushed the self-speculation-save-cache branch 2 times, most recently from afc3295 to dc2ab62 Compare April 20, 2026 18:29
@petersid2022
petersid2022 force-pushed the self-speculation-save-cache branch 2 times, most recently from 89b10b8 to 5c5bea4 Compare April 29, 2026 11:12
Comment thread common/common.h Outdated
@petersid2022
petersid2022 force-pushed the self-speculation-save-cache branch 4 times, most recently from e3017a4 to 268d95e Compare May 1, 2026 09:55
@ggerganov

Copy link
Copy Markdown
Member

The new parameters are never populated. Did you test this change? What is the goal of this PR?

@ggerganov
ggerganov marked this pull request as draft May 1, 2026 10:16
@petersid2022
petersid2022 force-pushed the self-speculation-save-cache branch 5 times, most recently from b4ad275 to 4fe77aa Compare May 2, 2026 17:56
@petersid2022

Copy link
Copy Markdown
Contributor Author

first of all, thanks for taking the time to review my PR!

TBH, my initial scope for this PR (after coming across the TODO on line 930 of common/speculative.cpp) was to move the save_[state,dynamic] bools from inside create_state_ngram_cache to the more centralized common.h, as the TODO instructed. That would allow for those options to be configurable from the user. Though, after thinking about it some more I decided to drop the booleans and instead rely on the existence or not of path_[static,dynamic] parameter.

The way I went about testing my changes was using the below command:

./build/bin/llama-server --port 1234 -m ~/models/Qwen3.5-9B-Q8_0.gguf --spec-type ngram-cache --lookup-cache-static ~/static.bin --lookup-cache-dynamic ~/dynamic.bin

P.S: In the common_speculative_state_ngram_cache constructor, I noticed that if the common_ngram_cache_load call fails on either one of them we abort execution. Could we instead call common_ngram_cache_save() so that we create the file?

@petersid2022
petersid2022 force-pushed the self-speculation-save-cache branch 3 times, most recently from 719eb8b to 5282e3c Compare May 5, 2026 12:50
lalalune added a commit to elizaOS/llama.cpp that referenced this pull request May 15, 2026
Upstream PR ggml-org/llama.cpp#22055 adds save-on-destruction for the
ngram_cache speculative impl, replacing the older save_dynamic/save_static
bool toggles (which were always false in our tree — dead code).

Hand-port notes:
- common/common.h:343-347 — add n_draft field to
  common_params_speculative_ngram_cache so callers can configure draft size
  without source edits (was hard-coded to 8 via TODO).
- common/speculative.cpp:643-746 — drop save_dynamic/save_static bools, keep
  the static/dynamic cache paths as const members. Constructor signature
  trimmed accordingly.
- common/speculative.cpp:705-731 — new destructor merges every per-seq
  context cache (sinfos[i].ngram_cache_context) into an aggregate, then
  merges that into the base on-disk static + dynamic caches and writes
  them back via common_ngram_cache_save. Our impl is multi-seq (vs
  upstream's single-seq), so we aggregate first.
- common/speculative.cpp:797-810 — create_state_ngram_cache returns
  std::unique_ptr now so the writing destructor only fires on real teardown
  (not when a temporary by-value copy goes out of scope inside the factory).
- common/speculative.cpp:1030-1035 — call site uses std::move into impls.

Skipped: no test for this in upstream PR.

Smoke test on eliza-1-0_8b-32k: model loads, generates coherent text,
prompt 132 t/s / gen 58 t/s (no regression — non-speculative path
unaffected; ngram_cache is opt-in via --spec-type ngram-cache).

Refs: ggml-org/llama.cpp#22055
@Green-Sky

Copy link
Copy Markdown
Collaborator

I just ran into the same TODO, what is the state of this pr?

@petersid2022

Copy link
Copy Markdown
Contributor Author

Hello! I intend to work on this PR very soon.

@petersid2022
petersid2022 force-pushed the self-speculation-save-cache branch from 5282e3c to bec53e3 Compare August 6, 2026 17:19
@petersid2022 petersid2022 changed the title spec : save the dynamic/static ngram cache file spec : save the dynamic ngram cache file Aug 6, 2026
@petersid2022
petersid2022 marked this pull request as ready for review August 6, 2026 19:51
@petersid2022
petersid2022 force-pushed the self-speculation-save-cache branch from bec53e3 to 62666c1 Compare August 12, 2026 11:22
@petersid2022
petersid2022 force-pushed the self-speculation-save-cache branch 2 times, most recently from fd42db4 to 8bb282b Compare August 28, 2026 12:03
* save the cache at the common_speculative_impl_ngram_cache destruction
* catch std::ifstream::failure the way llama-lookup does, so a
  permission/read failure cannot replace the file
@petersid2022
petersid2022 force-pushed the self-speculation-save-cache branch from 8bb282b to 4335d1b Compare August 28, 2026 15:46
@petersid2022

petersid2022 commented Aug 29, 2026

Copy link
Copy Markdown
Contributor Author

@ggerganov kind reminder for a code review of this PR, that simply saves the dynamic ngram cache file (when a path is provided) to the filesystem on object destruction. Thanks in advance!
BR,
Peter Sideris

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants