Skip to content

Enable bounded prefix caching for native Bolt - #2942

Merged
bmehta001 merged 31 commits into
mainfrom
feat/bolt-prefix-cache
Nov 14, 2026
Merged

bmehta001 merged 31 commits into
mainfrom
feat/bolt-prefix-cache

Conversation

@bmehta001

@bmehta001 bmehta001 commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Current main integration — 41a782f28

Merged main at 0f8d01c47 without rewriting history. The native stack remains #2942 → #2956 → #2964; upper PR branches were not changed.

  • Keep shared state-described checkpoint layouts, snapshot storage and prefix indexing across Bolt/Qwen; retain Qwen's new unified context-tier implementation.
  • Route Bolt's upstream dynamic prefill and selective auxiliary-row gathering through checkpoint-aware planning. Large eager passes return recurrent slot 7; fixed/R8 tail handling, verification arithmetic, per-generator search.chunk_size, and target-only decode remain supported.
  • Mark restored KV rows dirty so reset clears a restored prefix even when an aligned cache hit performs no target pass.
  • Add actual-model dynamic-prefill regression coverage for default/R8/9/1024/4095/4096 chunk sizes, aligned and unaligned prompts, warm output parity, selected recurrent rows and reset before decoding. Keep existing fixed-R8 prefix qualification explicitly on R8.

Verified: Windows VS 2026 and Linux/WSL Release builds; 568 Windows and 571 Linux tests passed. Each broader run had two explicit skips: no registered WebGPU device, and the actual CUDA PagedAttention padding test requires an admitted GPU plus a compatible runtime. All five disabled-name cases in the selection were explicitly enabled and executed; no negative test filters were used. Repository lintrunner passes for the exact delta against current main; unchanged upstream lint findings were not rewritten.

Not yet hardware-qualified at this head: the new dynamic-checkpoint regression and actual-package numerical/performance parity. All GPUs on the reachable H100 host were occupied; the alternate host timed out. No GPU jobs or deployed services were disturbed. Checkpoint splits/chunk sizes can change prefill floating-point arithmetic, so earlier fixed-R8 hardware results below are historical evidence, not qualification of this integration.


Summary

Enable bounded prefix reuse for native nemotron_bolt, shared by Generators and Engine Requests using the same Model, and consolidate reusable native-prefix infrastructure for Bolt and Qwen.

  • Preserve complete eight-token Bolt checkpoints, including packed dense KV, committed recurrent state and auxiliary context. Restore exact token-prefix matches and recompute unaligned tails without changing target block boundaries.
  • Add the single-slot Bolt Engine adapter with authoritative-history replay, current-turn cached-token accounting and cumulative speculative metrics. Serialize shared CUDA-graph sessions and snapshot access.
  • Fold the reusable direction of Share native prefix checkpoint indexing and storage policy #2948 into this implementation, without importing its older integration base: shared state-described checkpoints, snapshot policy, typed checkpoint indexing, optional publication cleanup and checked packed-buffer accounting.
  • Resolve native batching settings once and explicitly configure memory budgets from that owned policy. Support device_memory_budget_bytes, device_memory_headroom_bytes, gpu_utilization_factor, snapshot tier budgets and snapshot count limits without depending on mutable configuration ordering.
  • Keep backend-specific eligibility, synchronization, rollback and restore/handoff. Qwen indexes remain Engine-session-scoped; Bolt indexes remain Model-scoped.
  • Document Bolt configuration, dense versus unified Qwen state, and an integration contract for enabling prefix caching in another native backend.

The existing native stack (2952) remains ordered #2937 (merged), then #2942. No stack history is rewritten.

Defaults, costs and limitations

Supported non-sliding targets default to prefix caching enabled when engine.dynamic_batching is configured and prefix_caching is omitted. This includes eligible single-slot native Bolt/Qwen configurations, even if the section was added only to request memory controls. A target sliding-attention window defaults off and requires explicit prefix_caching: true; a windowed drafter alone does not opt out the target. Existing unsupported backend/auxiliary combinations remain unsupported.

This default can allocate retained checkpoint storage and perform capture/copy work on cold prefill, even before any reuse occurs; it is not a zero-cost switch. Without an explicit snapshot storage policy, retain at most one device-resident checkpoint. Set prefix_caching: false to use native memory controls without prefix capture/retention. max_snapshots: 0 or explicitly all-zero snapshot tier budgets also disable native reuse. No native prefix cache is created without a configured batching policy section.

Existing byte budgets and count limits bound retention. Explicit RAM/disk tiering adds allocation, transfer and spill-I/O costs. Allocation/spill publication failure may refuse caching; device and restore errors still propagate. Existing demotion-failure, stale-entry cleanup, lease protection and metrics fixes are preserved. CUDA snapshots use releasable non-arena reservations so demotion also releases their physical backing.

Bolt remains a greedy, single-slot CUDA backend requiring a windowed DFlash2 drafter. Only complete eight-token boundaries are cached. Native Bolt prefill remains synchronous; external chunked-prefill scheduling is separate work. Memory controls validate fixed model/state allocations and bound snapshot VRAM; they do not dynamically resize those fixed allocations or impose a hard allocator quota.

The shared helpers are internal, not new public configuration or automatic support for arbitrary models. Paged execution retains its separate block identity and scheduling contracts.

Independent preparation for Bolt execution stack 2955

f5a3965e5 prepares narrow integration seams without importing the unmerged #2921/#2923/#2961/#2963 stack or changing this PR's base.

  • Checkpoint-aware prefill planning splits target passes at the retained eight-token boundary, independently of the executor's maximum width. The current executor still uses fixed R8.
  • The prefill executor returns its selected recurrent row and prediction; checkpoint bindings and prefix restoration are separate from tensor allocation and target forwarding.
  • Generator and native Engine state creation share one checked typed factory. Existing eligibility, CUDA-session ownership, memory controls, cleanup and acknowledgement accounting remain intact.

Windows VS 2026 and Linux/WSL Release builds pass; all 38 focused tests pass on each platform, with no selected skips or disabled cases and no negative filters. Repository lintrunner and whitespace checks pass. The added cases cover checkpoint splitting, auxiliary-window offsets, restored prefixes, large/nonaligned planning widths and short/invalid chunks.

This is preparatory refactoring, not support or qualification for dynamic-R prefill, R1 ordinary decode or target-only Bolt. Large-width tests exercise planning only. Integrating the new executor/selected auxiliary rows, restored-KV dirty-row bookkeeping, and changed prefill numerical policies still requires the execution stack and fresh actual-model GPU qualification.

Review fixes and validation

f5cd7e1cf addresses private greedy defaults versus turn overrides, per-Engine event attribution, acknowledgement-ordered adoption metrics, physical snapshot reclamation, persistent cleanup failures and geometric index growth. Source-matched native qualification, merge-base benchmark spread and copy profiles are posted with explicit provenance and limitations.

2c9ced17a removes the remaining snapshot-cache friend through Entry lifecycle/allocation operations while keeping accounting, spill ownership and offsets private. It also fixes both macOS arm64 compilation failures by matching PrefixCacheMetrics's uint64_t member-pointer type instead of assuming it aliases size_t.

Source / validation layer Result
2c9ced17a: Windows VS 2026 CPU build and selected regressions 448 passed, zero selected failures/skips; disabled-name benchmarks explicitly enabled
2c9ced17a: Linux/WSL CPU build and selected regressions 450 passed, zero selected failures/skips; disabled-name benchmarks explicitly enabled
2c9ced17a: fresh GitHub/Azure CI Both previously failing macOS build lanes pass; remaining CI in progress
f5cd7e1cf: Windows CPU regressions 444 passed
f5cd7e1cf: Linux/H100 shared/native regressions 463 passed, including physical Qwen handoff and changing-size physical-memory reclamation
f5cd7e1cf: actual Bolt H100 regressions All 5 passed, including parity/reuse, ownership teardown, resolved-default admission and cache-event attribution
f5cd7e1cf: cache-disabled merge-base comparison Same H100/model/supported-plugin runtime; short/long TTFT and steady decode differences below 0.1%, with exact output/speculative-counter parity
Current changed C++ files clang-format 20 and whitespace checks passed

The 912 retained f5cd7e1cf test executions had no selected skips; their 23-file source manifest was verified against that commit with checkout line endings accounted for. These results are not represented as a new GPU run of 2c9ced17a. Windows validation is CPU-only.

The Qwen regression uses actual tiny dense/head ONNX sessions and a folded validating target through supported device operations: native RAM/disk capture/restore, physical packed rows/positions/lengths, pending predictions, FastHandoff and resumed prefill/decode across compression boundaries. It does not claim full large-package separate-prefill performance qualification.

Real paged Qwen 27B qualification remains at the earlier revision; the native Flash-Next fixture and real Bolt runs are not substitutes for that workload. Earlier supported-plugin 27B results and runtime provenance remain historical evidence, not final-head requalification.

The fixed-slot Qwen backend currently ingests shared prompts again for every
turn and Request. Restore committed native checkpoints through the existing
bounded snapshot tiers, rebuild DFlash context, and credit only validated
current-turn cached input. Keep the feature opt-in and single-slot.

Changed files:
- docs/paged_attention_engine.md
- src/engine/executor_result.h
- src/engine/fixed_slot_scheduler.h
- src/engine/qwen38_graph_executor.cpp
- src/engine/qwen38_graph_executor.h
- src/engine/scheduled_requests.cpp
- src/models/qwen38_decode_device.h
- src/models/qwen38_dflash_prompt.h
- src/models/qwen38_graph.cpp
- src/models/qwen38_graph.h
- test/cpp/engine/executor_result_tests.cpp
- test/cpp/engine/qwen38_graph_executor_tests.cpp
- test/cpp/engine/qwen38_graph_test_doubles.h

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: fbd11940-c14d-46c7-a724-3b2c65a6cf76
Copilot AI balanced review requested due to automatic review settings November 11, 2026 07:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The change breaks compilation for supported C++17 builds by using std::erase_if and leaves shared-session teardown unsynchronized with concurrent execution.

2 open issues
What changed in this PR

Adds opt-in, bounded prefix reuse for native nemotron_bolt, shared by Generators and Engine Requests using the same Model and backed by the existing snapshot storage system.

Changes:

  • Captures and restores complete eight-token checkpoints using bounded VRAM, RAM, or disk storage.
  • Adds a single-slot Engine adapter with authoritative-history replay, Request-owned completion, and cache/speculative statistics.
  • Adds regression coverage and documents configuration and backend limitations.
File Description
test/​cpp/​engine/​nemotron_bolt_tests.cpp Tests snapshot packing, retention, parity, continuation, and cancellation.
test/​cpp/​engine/​executor_result_tests.cpp Tests cached-token accounting, EOS handling, and malformed progress.
src/​models/​nemotron_bolt.h Declares prefix-cache structures and shared execution locking.
src/​models/​nemotron_bolt.cpp Implements snapshot capture, restoration, and prefix-aware prefill.
src/​engine/​scheduled_requests.cpp Validates and credits cached prompt progress before token commitment.
src/​engine/​request.cpp Preserves Engine EOS behavior for Bolt Requests.
src/​engine/​nemotron_bolt_executor.h Declares the native Bolt Engine dependency factory.
src/​engine/​nemotron_bolt_executor.cpp Implements single-slot execution, history replay, and statistics.
src/​engine/​fixed_slot_scheduler.h Exposes prefix-cache metrics through fixed-slot sessions.
src/​engine/​executor_result.h Adds cached-prefix counts to prefill progress.
src/​engine/​backend_factory.cpp Routes Bolt models to the native Engine adapter.
docs/​paged_attention_engine.md Documents Bolt caching configuration, behavior, and limitations.

Review effort: Balanced

Comment thread src/models/nemotron_bolt.cpp Resolved
Comment thread src/models/nemotron_bolt.h Resolved
Android builds GenAI in C++17 mode. Replace C++20 erase_if calls with
erase-remove and suffix checks with guarded string comparisons, preserving
snapshot cleanup, eviction accounting, and KV classification.

Files changed:
- src/engine/qwen38_graph_executor.cpp
- src/models/qwen38_graph.cpp
- test/cpp/engine/qwen38_graph_test_doubles.h

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: fbd11940-c14d-46c7-a724-3b2c65a6cf76
@bmehta001

Copy link
Copy Markdown
Contributor Author

Fixed Android C++17 compatibility in 30bf467: snapshot pruning now uses erase-remove instead of C++20 std::erase_if.

Validation: 126 Windows/VS 2026 regression tests passed, with no skipped tests. The original source reproduced the erase_if compiler error with the Android NDK; the corrected production translation unit passed both Android and native Linux C++17 compilation. Local Android checks used NDK r29, x86_64/API 27; the PR's full Android CI uses NDK 27.2. LLVM 20 formatting and git diff --check passed.

The push starts fresh CI; no stale-head jobs were manually rerun.

bmehta001 and others added 2 commits November 11, 2026 11:40
Keep CPU and CUDA caches at least as large as the graph's local window so short generations do not fail at prefill. Propagate the capacity to graph-derived per-layer shapes without changing global-layer allocations.

Files changed:
- src/ep/cpu/interface.cpp
- src/ep/cuda/interface.cpp
- src/models/io/static_kv_cache.cpp
- test/cpp/kv_cache_tests.cpp

Validation: five cache tests pass on Windows VS2026 and WSL; A100 CUDA reproduces the baseline failure and passes four fixed runtime fixtures; repository CLANGFORMAT lint passes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 996a8a25-fe6d-45c2-8b19-c38c57c9b7e9
Extract the real range, DFlash eligibility, and cache-policy planning so CPU
tests exercise snapshot storage, untouched capacity, opt-in gates, and leased
single-entry eviction rather than relying solely on the scripted device.
Verified at src/models/qwen38_graph.cpp:1820 and :3561.

Count refused captures, including null results for budgets, disk failures,
and ineligible DFlash checkpoints. Mark state dirty before restore can throw.
Verified at src/engine/qwen38_graph_executor.cpp:130 and :239.

Skip intermediate snapshots unless the last eligible DFlash checkpoint is
needed for a short final chunk. Document single-slot configuration, Engine
scope, and the checkpoint memory-budget exclusion; warn on inactive opt-ins.
Verified at src/models/qwen38_graph.cpp:1810 and :3561 and
docs/paged_attention_engine.md:2441.

Validation: Windows 185 tests, WSL/Linux 187 tests each; selected disabled
microbenchmark explicitly enabled, none skipped. H100 cache-on/off checks
preserved 32-token output across 48 turns. Changed-line clang-format passes.

Changed files:
- docs/paged_attention_engine.md
- src/engine/qwen38_graph_executor.cpp
- src/models/qwen38_decode_device.h
- src/models/qwen38_graph.cpp
- src/models/qwen38_graph.h
- test/cpp/engine/qwen38_graph_executor_tests.cpp
- test/cpp/engine/qwen38_graph_test_doubles.h
- test/cpp/engine/qwen38_prefix_snapshot_tests.cpp

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6b04e9f6-4182-4bfc-bf43-e53068c42638
Resolve #2937 against the backend documentation relocation on main without rewriting PR history. Keep prefix reuse settings in the Qwen guide and replace its stale no-prefix-cache claim.

Conflict-resolution files: docs/paged_attention_engine.md; src/python/py/models/docs/qwen3_8.md. Remaining files are upstream main changes.

Validation: VS 2026 build and 182 focused tests passed; Linux/WSL build and 184 focused tests passed. Disabled-name benchmark explicitly enabled; no selected tests skipped or negative filters. Changed-line clang-format and whitespace checks passed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d81bd60e-20e8-433a-8458-000e64fdd612
@bmehta001

Copy link
Copy Markdown
Contributor Author

Updated in 69fdd02: merged main without rebasing/force-pushing and resolved the shared-session teardown thread. Validation on the pushed commit: Windows VS 2026 CPU build succeeded and all 127 selected Engine regressions passed; Linux CUDA/H100 build succeeded and all 130 selected regressions passed, including the new actual-model destruction-lock regression and both existing Bolt correctness/lifecycle tests. Zero failures or skipped/not-run tests in either selection; the pre-existing disabled microbenchmark was explicitly enabled. clang-format --dry-run --Werror passed for every C++ file in the PR, and whitespace checks passed. GitHub now reports MERGEABLE. Copilot rereview was requested; no new bot review has arrived yet.

Revert 6bbed73. Main already contains #2943, which treats context-covering windows as full attention. Preserve native Qwen prefix caching and restore the shared cache implementation to main.

Files changed: src/ep/cpu/interface.cpp; src/ep/cuda/interface.cpp; src/models/io/static_kv_cache.cpp; test/cpp/kv_cache_tests.cpp.

Validation: Windows cache tests 2/2 and focused Engine tests 182/182; WSL cache tests 2/2 and focused Engine tests 184/184; upstream builder regressions 14/14; changed-line clang-format and whitespace checks passed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d81bd60e-20e8-433a-8458-000e64fdd612

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

bmehta001 and others added 5 commits November 12, 2026 00:02
Avoid replaying aligned native prefill across Generators and Engine Requests
without reusing speculative state or changing target verification boundaries.
Preserve Request-owned completion semantics and current-turn cache accounting.

Files changed:
- docs/paged_attention_engine.md
- src/engine/backend_factory.cpp
- src/engine/executor_result.h
- src/engine/fixed_slot_scheduler.h
- src/engine/nemotron_bolt_executor.cpp
- src/engine/nemotron_bolt_executor.h
- src/engine/request.cpp
- src/engine/scheduled_requests.cpp
- src/models/nemotron_bolt.cpp
- src/models/nemotron_bolt.h
- test/cpp/engine/executor_result_tests.cpp
- test/cpp/engine/nemotron_bolt_tests.cpp

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: fbd11940-c14d-46c7-a724-3b2c65a6cf76
Android builds GenAI in C++17 mode, where std::erase_if is unavailable.
Use erase-remove without changing checkpoint eviction behavior.

Files changed:
- src/models/nemotron_bolt.cpp

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: fbd11940-c14d-46c7-a724-3b2c65a6cf76
Keep CPU and CUDA caches at least as large as the graph's local window so short generations do not fail at prefill. Propagate the capacity to graph-derived per-layer shapes without changing global-layer allocations.

Files changed:
- src/ep/cpu/interface.cpp
- src/ep/cuda/interface.cpp
- src/models/io/static_kv_cache.cpp
- test/cpp/kv_cache_tests.cpp

Validation: five cache tests pass on Windows VS2026 and WSL; A100 CUDA reproduces the baseline failure and passes four fixed runtime fixtures; repository CLANGFORMAT lint passes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 996a8a25-fe6d-45c2-8b19-c38c57c9b7e9
Revert 7a97274. Main already contains #2943, which treats context-covering windows as full attention. Preserve native Bolt prefix caching and restore the shared cache implementation to main.

Files changed: src/ep/cpu/interface.cpp; src/ep/cuda/interface.cpp; src/models/io/static_kv_cache.cpp; test/cpp/kv_cache_tests.cpp.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d81bd60e-20e8-433a-8458-000e64fdd612
Keep the complete construction and destruction lock and its regression test from the former merge commit. Reuse the parent Qwen layer prefix-metrics methods rather than declaring them twice.

Files changed: src/engine/fixed_slot_scheduler.h; src/models/nemotron_bolt.cpp; src/models/nemotron_bolt.h; test/cpp/engine/nemotron_bolt_tests.cpp.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b3ab443c-d6fb-4693-b5f8-d18385dbbe6d
@bmehta001
bmehta001 force-pushed the feat/bolt-prefix-cache branch from e9c52c2 to 04008c7 Compare November 12, 2026 06:13
@bmehta001
bmehta001 changed the base branch from main to feat/qwen-native-prefix-cache November 12, 2026 06:14
@bmehta001
bmehta001 added this pull request to stack #2952 November 12, 2026 06:14
Base automatically changed from feat/qwen-native-prefix-cache to main November 12, 2026 06:30
bmehta001 and others added 2 commits November 12, 2026 01:07
Resolve the overlapping test additions without dropping either branch's coverage. Keep both required headers and remove the duplicate filesystem include.

Conflict resolution: test/cpp/engine/nemotron_bolt_tests.cpp. Other changed files come from main.

Validation: VS 2026 and WSL builds; 144 targeted tests passed on each platform, with three model-dependent GPU tests skipped. Clang-format checks passed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: e311d5a9-0f8b-4d24-b8cf-903dba231d73
Address the six unresolved #2937 review threads in #2942:
- r4547271957: explain the DFlash window/chunk requirement and the explicit
  8192-token H100 configuration; warn once at initialization for short chunks.
- r4547271960: document scheduling-budget chunk remapping and test the
  documented single-slot opt-in with default and explicit chunk sizes.
- r4547271964: state that device_memory_budget_bytes is rejected, not a
  checkpoint budget; apply the same clarification to Bolt.
- r4547271967: omit zero decode KV/index/bank buffers on separate dense
  checkpoints, since FastHandoff rebuilds them from saved dense state.
- r4547271974: preserve the cache-policy creation ordering before the
  single-slot dynamic-batching reset with an explicit comment.
- r4547271984: prune/count evictions even when publication fails; exercise
  evict-then-refuse and evict-then-bad_alloc before re-requesting the old prompt.
Apply the same failed-publication cleanup to Bolt with a real storage-refusal
regression and immediate eviction accounting.

Verified dense-state ownership in src/models/qwen38_graph_prefill.cpp:968-1064,
chunk selection at :478-484, and snapshot eviction/refusal ordering in
src/engine/prefix_snapshot_cache.cpp:572-610.

Files changed:
- docs/paged_attention_engine.md
- src/engine/qwen38_graph_executor.cpp
- src/models/nemotron_bolt.cpp
- src/models/qwen38_graph.cpp
- src/python/py/models/docs/qwen3_8.md
- test/cpp/engine/nemotron_bolt_tests.cpp
- test/cpp/engine/qwen38_graph_executor_tests.cpp
- test/cpp/engine/qwen38_graph_test_doubles.h
- test/cpp/engine/qwen38_prefix_snapshot_tests.cpp

Validation: VS 2026 Windows 200 tests; WSL Linux 202 tests; no skips or
negative filters, including the explicitly enabled disabled microbenchmark.
Changed-line clang-format and staged/unstaged whitespace checks passed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 06cfce86-6a11-4cf7-82b7-297f91a0b519
@bmehta001

Copy link
Copy Markdown
Contributor Author

Addressed all six remaining review threads from #2937 in 1eae3e4, and applied analogous feedback to Bolt:

  • Document Qwen's scheduling-budget chunk remapping, DFlash context-window requirement/caps, and the explicit 8,192-token chunk used by the earlier H100 validation; warn once at native Engine initialization for a too-small effective chunk.
  • State explicitly that Qwen and Bolt reject device_memory_budget_bytes; describe device headroom and alternative snapshot tiers.
  • Skip unused decode KV/index/bank buffers when capturing separate dense-prefill checkpoints; retain the dense state used to reconstruct them.
  • Protect cache-policy initialization ordering with a comment and single-slot configuration coverage.
  • Prune/count evictions even when Qwen or Bolt publication fails. Add regressions for Qwen eviction followed by refusal or bad_alloc, and Bolt eviction followed by a real storage refusal. Remove the vacuous shorter-prompt eviction assertion.

Validation: 200 Windows VS 2026 tests and 202 WSL Linux tests passed, with zero skipped/not-run selected tests. The disabled-name Engine microbenchmark was explicitly enabled; no negative filters. Both cached offline builds succeeded. Changed-line clang-format (20.1.8) and staged/unstaged whitespace checks passed. This follow-up did not rerun real CUDA model inference.

Replied individually to the six original threads and requested a fresh Copilot review on this head.

Pin ORT core 1.32.0 and CUDA plugin 0.4.0-dev.20261110145305 so the unchanged dense-handoff test can load SpeculativePrefixCommit instead of failing before execution.

Files: .github/workflows/linux-gpu-x64-build.yml, .github/workflows/win-cuda-x64-build.yml

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 276e922f-3816-4c82-89a0-0702f676c388
Prepare #2942 for the Bolt execution stack without importing its unmerged commits or enabling unsupported package layouts. Split prefill passes at the retained checkpoint boundary independently of target width, isolate checkpoint bindings and restore bookkeeping, and report the execution-selected recurrent row to the coordinator. Route Generator and Engine construction through one checked typed native-state factory so later package validation has one owner.

Preserve fixed-R8 verification, current eligibility and checkpoint storage, model-session locking, memory controls, failure cleanup, and acknowledgement accounting. Add focused planning tests covering checkpoint boundaries, auxiliary-window offsets, restored prefixes, large/nonaligned target widths, short prompts and nonprogressing chunks.

Windows VS 2026 and Linux WSL Release builds passed; all 38 selected tests passed per platform without skips or exclusions. Repository lintrunner and whitespace checks passed. Large-width coverage is planning only, not new dynamic-prefill or actual-model GPU qualification.

Files changed: src/models/nemotron_bolt.h; src/models/nemotron_bolt.cpp; src/engine/nemotron_bolt_executor.cpp; test/cpp/engine/nemotron_bolt_tests.cpp.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ac28fda8-704a-4048-874c-cf80298541a0

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Shared CUDA-graph lifecycle and GPU-memory reclamation require human runtime qualification because reported GPU runs predate the final revision and final-head actual-model GPU verification is unavailable.

No open issues 🎉

Review effort: Balanced

bmehta001 and others added 5 commits November 13, 2026 13:40
…ding

Keep native checkpoint coordination and shared-session ownership while adopting main's optional drafter, capture policy, and target-only decode path. Prevent target-only states from accessing drafter-dependent checkpoint buffers, preserve fixed-state memory-budget checks, and cover ordinary decoding with populated speculative checkpoints.

Validation: VS 2026 and Linux/WSL Release builds; Windows 167 passed / 2 capability skips; Linux 169 passed / 2 capability skips. No negative test filters. Full PR-delta lintrunner and whitespace checks pass. Actual-model GPU tests were not run.

Files changed (including changes merged from main):
- .github/workflows/win-cuda-x64-build.yml
- cgmanifests/generated/cgmanifest.json
- cmake/deps.txt
- docs/LiLiCorrDrafter.md
- docs/NemotronBolt.md
- docs/metadata_decode.md
- docs/nemotron_speech_timestamps.md
- examples/csharp/ModelASR/Program.cs
- examples/python/model-asr.py
- src/config.cpp
- src/csharp/ASRPostProcessorResult.cs
- src/csharp/NativeMethods.cs
- src/dflash2_drafter.cpp
- src/dflash2_drafter.h
- src/generator/generators.cpp
- src/models/nemotron_bolt.cpp
- src/models/nemotron_bolt.h
- src/models/onnxruntime_api.h
- src/models/onnxruntime_inline.h
- src/models/postprocessing/asr_post_processor.cpp
- src/models/postprocessing/metadata_core_state.cpp
- src/models/postprocessing/metadata_core_state.h
- src/ort_genai.h
- src/ort_genai_c.cpp
- src/ort_genai_c.h
- src/python/py/models/builders/lfm2.py
- test/CMakeLists.txt
- test/cpp/audio_speech_validation_test.cpp
- test/cpp/dflash2_config_test.cpp
- test/cpp/engine/nemotron_bolt_tests.cpp
- test/cpp/engine/shared_initializer_tests.cpp
- test/cpp/model_package_test.cpp
- test/csharp/TestOnnxRuntimeGenAIAPI.cs
- test/models/engine/synthetic-dspark/generate_padded_attention.py
- test/models/engine/synthetic-dspark/padded_attention.onnx
- test/python/builder/test_lfm3.py
- test/python/builder/test_qwen38_package_builders.py
- test/python/test_build_package_gguf.py
- test/python/test_onnxruntime_genai_api.py
- tools/python/qwen38_flash_next/README.md
- tools/python/qwen38_flash_next/build_package.py
- tools/python/qwen38_flash_next/build_package_gguf.py
- tools/python/qwen38_flash_next/graph_builder.py
- tools/python/qwen38_flash_next/package_io.py
- tools/python/qwen38_flash_next/package_paths.py
- tools/python/qwen38_flash_next/precision_options.py

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b730396c-0065-4e06-bac7-70e6eb962060
Use the staged ONNX Runtime DLL for Python CUDA CI rather than the older wheel runtime.

Files changed: .github/workflows/win-cuda-x64-build.yml

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 71f338fc-57ae-4336-8b1a-1ccf6d2ff1f7
Use the complete matching nightly wheel from the CI feed instead of mixing the API 31 Python binding with an API 32 DLL.

Files changed: .github/workflows/win-cuda-x64-build.yml

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 71f338fc-57ae-4336-8b1a-1ccf6d2ff1f7
The released pure-Python EP shim points to a plugin that predates PackedSparseAttentionIndexerMerge. Stage the pinned NuGet plugin used by native tests at that same path.

Files changed: .github/workflows/win-cuda-x64-build.yml

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 71f338fc-57ae-4336-8b1a-1ccf6d2ff1f7
Route dynamic Bolt prefill and selective auxiliary gathering through the
checkpoint-aware plan without discarding upstream verification arithmetic
or target-only decode. Mark restored KV rows dirty so reset clears the
restored prefix even when no target pass runs. Keep Qwen state-described
checkpoints on the unified context-tier implementation.

Add dynamic package regression coverage for chunk widths, selected state
rows, warm parity and reset-before-decode. Document prefill arithmetic
qualification and synchronous Engine prefill.

Files changed:
- benchmark/engine/scenario_dispatcher.cpp
- docs/NemotronBolt.md
- docs/paged_attention_engine.md
- examples/python/README.md
- examples/python/nemotron-bolt-prefill.py
- src/dflash2_drafter.cpp
- src/engine/scheduled_requests.cpp
- src/models/nemotron_bolt.cpp
- src/models/nemotron_bolt.h
- src/models/preprocessing/qwen2_5_vl_image_processor.cpp
- src/models/qwen38_graph.cpp
- src/models/qwen38_graph.h
- src/models/qwen38_graph_plane.cpp
- src/models/qwen_vl_state.cpp
- src/models/qwen_vl_state.h
- src/models/runtime_profiles.cpp
- src/python/py/models/DESIGN.md
- src/python/py/models/README.md
- src/python/py/models/builders/base.py
- src/python/py/models/builders/dflash2.py
- src/python/py/models/builders/onnx_source.py
- src/python/py/models/docs/qwen3_8.md
- src/python/py/models/loaders/LOADERS.md
- src/python/py/models/loaders/component.py
- src/python/py/models/quantization/kv_cache_calibration.py
- test/cpp/dflash2_config_test.cpp
- test/cpp/engine/engine_run_tests.cpp
- test/cpp/engine/nemotron_bolt_tests.cpp
- test/cpp/engine/qwen38_graph_model_tests.cpp
- test/cpp/engine/qwen38_plane_tests.cpp
- test/cpp/qwen_multi_image_vision_test.cpp
- test/cpp/scoped-environment-variable.h
- test/python/builder/test_kv_cache_calibration.py
- test/python/builder/test_quantized_kv_cache.py
- test/python/builder/test_qwen_dflash2_export.py
- test/python/models/test_component_loader.py
- test/python/test_build_package_gguf.py
- test/python/test_nemotron_bolt_prefill.py
- tools/python/qwen38_flash_next/build_package_gguf.py
- tools/python/qwen38_flash_next/package_io.py
- tools/python/qwen38_flash_next/precision_options.py

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: aa4e0c1f-b9cc-448f-b6ad-77ba4d709f35
@bmehta001

Copy link
Copy Markdown
Contributor Author

The matching ORT Python/core/plugin versions expose a real CUDA QSA IndexShare reuse defect: reuse intentionally holds its compressed-state prefix, but the published kernel rejects it when speculative query positions advance. The fix is in microsoft/onnxruntime#34217. On an idle A100, the new regression fails before the fix; afterward 24 ORT CUDA tests and all 114 GenAI Engine Python tests pass, including all 18 IndexShare cases, with zero skips/exclusions. GenAI validation used daa6157 and the unchanged CI core with only the rebuilt plugin substituted. The later concurrent main merge into this branch is preserved. The pinned published plugin still needs the upstream fix; rerunning unchanged MTP tests will not resolve that dependency defect.

@bmehta001
bmehta001 removed this pull request from stack #2958 November 14, 2026 02:21
bmehta001 added a commit that referenced this pull request Nov 14, 2026
Retain runtime-independent snapshot groundwork from #2942 and implement optional no-eviction publication using existing leases. Keep backend and newer-kernel changes out of #2956. Relocate overlapping tests so both merge orders produce the same tree without conflicts.

Files changed:
src/engine/prefix_snapshot_cache.cpp
src/engine/prefix_snapshot_cache.h
test/cpp/dflash2_config_test.cpp
test/cpp/engine/paged_key_value_cache_tests.cpp

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: c34c7a56-b159-4b5d-8001-51daa485e739
Avoid making checkpoint coverage depend on the newer folded completion-ring
publisher. Remove that dedicated regression and its fixtures, restore main's
aligned core/Python/CUDA versions, and retain the other checkpoint tests.

Files changed:
- .github\workflows\linux-gpu-x64-build.yml
- .github\workflows\win-cuda-x64-build.yml
- test\cpp\engine\qwen38_graph_native_tests.cpp
- test\models\engine\synthetic-qwen38\decoder-handoff.onnx
- test\models\engine\synthetic-qwen38\dense-prefill.onnx
- test\models\engine\synthetic-qwen38\generate-dense-handoff.py
- test\models\engine\synthetic-qwen38\head-kv.onnx
- test\models\engine\synthetic-qwen38\head-r2.onnx
- test\models\engine\synthetic-qwen38\qsa.data
- test\models\engine\synthetic-qwen38\qsa.txt

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 71f338fc-57ae-4336-8b1a-1ccf6d2ff1f7
@bmehta001

bmehta001 commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor Author

Supersedes my earlier runtime-upgrade plan: 75a0f6c restores both GPU workflows exactly to main's dependency setup: ORT core/Python 1.31.0, CUDA NuGet plugin 0.3.0-dev.20261009143618, and Python CUDA shim 0.3.0. Linux's build dependency remains 1.26.0, as on main.

Removed only SeparateDenseSnapshotsRestoreAndHandoffAcrossCompressionBoundaries and its seven dedicated fixture files. That synthetic graph explicitly enabled folded execution and used the newer SpeculativePrefixCommit completion-ring publisher; simply removing that node would break folded decode. The remaining checkpoint implementation/tests are unchanged, and no Engine MTP or IndexShare Python tests were edited.

Validation against the actual unmodified main dependencies: VS 2026 Windows CPU build + 51 retained tests passed; Linux/A100 CUDA build + 61 retained tests passed, including all seven native Qwen tests and physical CUDA snapshot reclamation. Three optional native Bolt model tests skipped on each platform because their external model packages are unavailable. C++ formatting (LLVM 20), workflow YAML/action SHA pins, inline PowerShell parsing, and diff checks passed.

The existing IndexShare tests will again capability-skip with main's older runtime; this downgrade does not fix that independently reproduced ORT kernel bug. microsoft/onnxruntime#34217 remains valid and open, but #2942 no longer depends on that newer runtime/plugin. Fresh CI is running; not yet claiming it is green.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

A snapshot restore failure can leave partially written KV rows uncleared because the dirty extent is not recorded before Reset() runs.

1 open issue

Review effort: Balanced

Comment thread src/models/nemotron_bolt.cpp Resolved
Refactor RestorePrefix to update touched_kv_rows_ based on saved tokens size instead of length.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

A critical failure for valid requests, alongside cache-compatibility, allocation-error, and turn-accounting risks, requires human assessment of the change’s impact.

No open issues 🎉

1 resolved since last review

Review effort: Max

@bmehta001
bmehta001 enabled auto-merge (squash) November 14, 2026 05:12
bmehta001 added a commit that referenced this pull request Nov 14, 2026
## Summary

Enable paired prefix reuse for full-attention DFlash directly on `main`,
without depending on #2942 or its newer ORT/CUDA plugin versions.

- Reuse immutable drafter context through target physical block IDs,
with private query spills and leased complete ancestry.
- Snapshot and restore target sliding-window KV and quantization scales
into private rings. Keep existing byte/count budgets; add no public
configuration fields.
- Obtain cache geometry and reuse capabilities from the drafter.
Preserve windowed-drafter and target-only behavior, changed-suffix
warmup, and ingest-only turns.
- Default supported non-sliding targets on; sliding-window targets still
need explicit opt-in and snapshot storage. Disabled storage safely falls
back to ordinary decoding.
- Keep paired-cache, window/scale restore, storage-failure,
cancellation/recovery, and graph-restore qualification regressions.

This main-based change deliberately omits #2942's Bolt/Qwen native
prefix-cache integration, folded Qwen handoff fixtures, and ORT/CUDA
workflow upgrades. Both GPU workflows and existing IndexShare tests
remain exactly as on `main`. #2942 is unchanged. #2964's branch is left
untouched and is not part of this qualification.

## Validation

LLVM 20 changed-line formatting and whitespace checks passed before
pushing. The branch was pushed before builds and model validation so CI
could start promptly.

Windows/Visual Studio 2026, Linux/WSL, and actual MAI qualification are
pending for this new main-based head. Earlier GPU results from the
stacked source are historical, not evidence for this head.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot-Session: c34c7a56-b159-4b5d-8001-51daa485e739
Copilot-Session: 6b94f575-7518-4b0b-b9b1-5c6ff84f8ce6
@bmehta001
bmehta001 merged commit da29a76 into main Nov 14, 2026
68 checks passed
@bmehta001
bmehta001 deleted the feat/bolt-prefix-cache branch November 14, 2026 05:41
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