Skip to content

fix: preserve document-relative QSA blocks in packed attention - #236

Closed
taking-lying-flat wants to merge 1 commit into
modelscope:mainfrom
taking-lying-flat:fix/qsa-packed-block-grid
Closed

taking-lying-flat wants to merge 1 commit into
modelscope:mainfrom
taking-lying-flat:fix/qsa-packed-block-grid

Conversation

@taking-lying-flat

@taking-lying-flat taking-lying-flat commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Packed QSA selections use document-relative blocks, but the attention bitmap currently groups tokens by their absolute packed position. If a document starts at an offset not divisible by the compression ratio, sparse attention can include keys the indexer excluded. For example, with document lengths [3, 20] and block size 4, a selection of [3, 4, 5, 6, 11] expands to [3, ..., 11].

Preserve the document's block-grid offset when constructing the bitmap and pass it to the existing kernel offset argument. Forward and backward share tile-mask construction and index compaction, including the physical key tiles crossed by shifted blocks. The compressed bitmap shape stays unchanged.

A local regression, kept outside this PR, compares outputs and Q/K/V gradients against a dense mask built directly from the selected indices. It covers aligned and unaligned documents, multiple block sizes, and forward/backward tile boundaries. Removing either tile-list correction makes the regression fail. This PR changes only the production kernel wrapper.

Validation:

  • In the local validation checkout, with the uncommitted regression added: PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 TRITON_INTERPRET=1 OMP_NUM_THREADS=2 MKL_NUM_THREADS=2 .venv/bin/python -m pytest tests/test_qsa_sparse_kernels.py -q: 7 passed, 1 skipped. This executes the Triton kernels through the CPU interpreter; the CUDA long-context test is skipped. The extra regression cases are not part of this PR.
  • Local equivalence checks for the compaction refactor: 1,152 exact before/after comparisons passed, including empty/sparse/full masks, non-contiguous inputs, optional/zero/shifted origins, and tile boundaries. Six before/after PyTorch operator traces were identical.
  • flake8, isort --check-only --diff, and yapf --diff on the production file, using the repository-pinned versions: passed.
  • git diff --check: passed.

CUDA compilation, GPU performance, and full-model training have not been validated.

Duplicate check: the open QSA PRs #217 and #222 address device registration and CP key-length bounds, respectively. This fixes the block coordinates of packed selections.

AI assistance was used to investigate, implement, and test this change.

@taking-lying-flat
taking-lying-flat force-pushed the fix/qsa-packed-block-grid branch from 5f9f3eb to 0f4b6be Compare October 20, 2026 13:09
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.

1 participant