Skip to content

indexer: bound two-level fold workspace - #87

Merged
lukealonso merged 2 commits into
masterfrom
codex/adaptive-indexer-fold-20260728
Jul 29, 2026
Merged

indexer: bound two-level fold workspace#87
lukealonso merged 2 commits into
masterfrom
codex/adaptive-indexer-fold-20260728

Conversation

@voipmonitor

@voipmonitor voipmonitor commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • bound the existing logical-output two-level top-k fold by its full transient candidate allocation
  • automatically use the existing exact streaming-carry route above a 256 MiB default budget
  • keep explicit auto, forced two-level, and forced carry controls
  • add planner boundary, validation, route-selection, and GPU correctness tests

This does not add a new selector or change top-k precision. Both routes are exact. It only chooses which existing fold implementation handles the intermediate candidates.

Motivation

The parallel two-level fold allocates FP32 values plus int32 indices for every query row, fold slice, and top-k entry. On large logical-output DCP prefill profiles, that transient slab can reach several GiB per rank and is included in vLLM's peak non-KV memory profile. The resulting peak reduces the KV cache even though the allocation is not persistent.

Physical-slot output, including the current DCP1 route, already requires streaming carry and is unchanged.

The policy was inspired by Josh Cartu's adaptive-fold study. This PR ports the idea onto current SparkInfer master, derives the complete fold geometry internally, accounts for both candidate tensors and row lengths, validates configuration and dimensions, and adds current integration coverage.

Controls

SPARKINFER_INDEXER_TWO_LEVEL_FOLD=auto|0|1
SPARKINFER_INDEXER_TWO_LEVEL_FOLD_MAX_MIB=256
  • auto: use two-level fold while the candidate allocation fits; otherwise use carry
  • 0: force streaming carry
  • 1: force historical two-level behavior

E2E results

Paired runs used TP8/DCP4/MTP0, FP8 KV, A16, a 1,048,576-token model limit, GPUs 0-7, and otherwise identical source and configuration.

Measurement Baseline Adaptive Delta
KV cache budget 2,442,240 tokens 2,578,944 tokens +136,704 (+5.60%)
64,511-token prefill 5,760 tok/s 5,741 tok/s -0.33%
399,988-token prefill 4,104 tok/s 4,119 tok/s +0.35%
~998.8k-token prefill 3,715 tok/s 3,730 tok/s +0.40%
DCP4 CC1 decode, ctx0 73.1 tok/s 73.1 tok/s 0.00%

The throughput deltas are within run noise. The KV capacity gain was stable across boots.

Validation

  • targeted planner and GPU route tests: 12 passed
  • full long-context GPU suite: 8 passed
  • planner/integration CPU suite: 15 passed, 6 skipped
  • Ruff on touched files: passed
  • paired 64k, 400k, and ~999k prefill plus CC1 decode E2E runs

Summary by CodeRabbit

  • New Features
    • Added adaptive two-level folding for paged top‑k indexing with environment-configurable mode and a memory budget cap.
    • Introduced improved chunk/page geometry handling for more consistent paged processing.
  • Bug Fixes
    • Ensured top‑k accuracy is preserved when adaptively switching between folding and legacy streaming-carry behavior.
    • Added stricter validation for invalid folding policy and geometry inputs.
  • Tests
    • Added CUDA-skipped integration/regression coverage for fold planning decisions, partial final chunk boundaries, and long-context correctness.

Select the existing exact streaming carry when the logical-output two-level candidate slab exceeds a configurable runtime budget. Preserve the parallel fold for smaller workloads and add planner and GPU correctness coverage.\n\nInspired by Josh Cartu's adaptive-fold study.
@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 23113be6-9111-4ea9-abaf-aa4b466e8d50

📥 Commits

Reviewing files that changed from the base of the PR and between 43ab765 and c24a014.

📒 Files selected for processing (2)
  • sparkinfer/attention/nsa_indexer/paged.py
  • tests/attention/test_paged_indexer_integration.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/attention/test_paged_indexer_integration.py
  • sparkinfer/attention/nsa_indexer/paged.py

📝 Walkthrough

Walkthrough

The paged indexer now plans two-level folding from environment-configured policy and memory limits, integrates the plan into index_topk_fp8, centralizes chunk geometry calculations, and adds coverage for route selection, validation, geometry, and logical-output top-k correctness.

Changes

Two-level fold policy

Layer / File(s) Summary
Policy parsing and fold planning
sparkinfer/attention/nsa_indexer/paged.py
Adds environment controls, validates policy and geometry, computes slice plans and candidate slab usage, and selects forced, budgeted, or streaming behavior.
Indexer fold-path integration
sparkinfer/attention/nsa_indexer/paged.py
Replaces inline slice decisions with _plan_two_level_fold(...), conditionally initializes fold buffers, and centralizes per-chunk page and token geometry.
Planner and end-to-end validation
tests/attention/test_paged_indexer_integration.py, tests/attention/test_paged_prefill_topk_long_context.py
Tests memory thresholds, forced and ineligible routes, invalid settings and geometry, partial final chunks, and logical-output top-k correctness.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Environment
  participant index_topk_fp8
  participant _plan_two_level_fold
  participant FoldBuffers
  Environment->>_plan_two_level_fold: Read fold mode and memory budget
  index_topk_fp8->>_plan_two_level_fold: Provide fold dimensions and output mode
  _plan_two_level_fold-->>index_topk_fp8: Return slices, total_slices, and reason
  index_topk_fp8->>FoldBuffers: Allocate fold state when slices are available
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately reflects the main change: bounding the two-level fold workspace for the indexer.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/adaptive-indexer-fold-20260728

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🧹 Nitpick comments (1)
sparkinfer/attention/nsa_indexer/paged.py (1)

909-916: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

fold_plan.reason is computed but never surfaced.

The plan's reason field (e.g. "candidate slab exceeds the memory budget", "forced") captures exactly why the runtime chose two-level fold vs. streaming carry, but index_topk_fp8 never logs or exposes it — only the unit tests read .reason directly. Given this is a new auto-switching behavior that changes memory/perf characteristics silently based on env config, surfacing the reason (e.g., via a debug log or counter) would help diagnose unexpected route flips in production.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sparkinfer/attention/nsa_indexer/paged.py` around lines 909 - 916, Surface
fold_plan.reason in index_topk_fp8 after _plan_two_level_fold returns, using the
module’s existing debug logging or metrics mechanism so operators can identify
why two-level fold was selected. Preserve the current routing behavior and
include the reason for both budget-driven and forced decisions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@sparkinfer/attention/nsa_indexer/paged.py`:
- Around line 102-178: Centralize supertile geometry by adding a shared
_chunk_geometry helper and use it in both _plan_two_level_fold and
index_topk_fp8’s execution loop, preserving the existing chunk boundaries and
token offsets. Add total_slices to _TwoLevelFoldPlan, populate it in
_plan_two_level_fold, and replace the downstream sum over two_level_slices with
that field.
- Around line 67-99: Update the invalid-mode ValueError in
_read_two_level_fold_policy to document all accepted values, including the
off/false/no and on/true/yes aliases, while preserving the existing validation
behavior and reported raw value.

---

Nitpick comments:
In `@sparkinfer/attention/nsa_indexer/paged.py`:
- Around line 909-916: Surface fold_plan.reason in index_topk_fp8 after
_plan_two_level_fold returns, using the module’s existing debug logging or
metrics mechanism so operators can identify why two-level fold was selected.
Preserve the current routing behavior and include the reason for both
budget-driven and forced decisions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 05ec6c78-192e-4e9e-a595-33baeb7f57c4

📥 Commits

Reviewing files that changed from the base of the PR and between f9be272 and 43ab765.

📒 Files selected for processing (3)
  • sparkinfer/attention/nsa_indexer/paged.py
  • tests/attention/test_paged_indexer_integration.py
  • tests/attention/test_paged_prefill_topk_long_context.py

Comment thread sparkinfer/attention/nsa_indexer/paged.py
Comment thread sparkinfer/attention/nsa_indexer/paged.py
@lukealonso
lukealonso merged commit 0b5b771 into master Jul 29, 2026
1 check passed
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.

2 participants