Skip to content

test: add batch-composition and prefix-cache-tail cases to the FA2 batch-invariance tests - #8569

Open
kahyunnam wants to merge 2 commits into
flashinfer-ai:mainfrom
kahyunnam:rl/7937-item-3-sglang-46351-item-2
Open

kahyunnam wants to merge 2 commits into
flashinfer-ai:mainfrom
kahyunnam:rl/7937-item-3-sglang-46351-item-2

Conversation

@kahyunnam

Copy link
Copy Markdown
Member

📌 Description

tests/attention/test_batch_invariant_fa2.py only checks that a request's output is unchanged when the batch is truncated; nothing asserts bitwise batch invariance when a request shares a batch with mates of a different shape, which is the case serving engines (vLLM batch-invariant mode, SGLang radix cache) actually hit. This PR adds three parametrised tests (22 cases, fp16, 32 q heads / 8 kv heads, head_dim 128, page 16) that compare o and lse with torch.equal against the same request run alone.

test_batch_decode_tensor_cores_batch_composition (4 cases): a 3000-token tensor-core decode request alone vs batched with 16 short or 16 long mates, under disable_split_kv=True or fixed_split_size=2048. All pass on main.

test_batch_prefill_tensor_cores_batch_composition (6 cases): a 37-token causal FA2 prefill over 3000 KV alone vs with decode-like mates (qo 1), mid mates (qo 64) or long prefill mates (qo 1500), under disable_split_kv=True and under vLLM's batch-invariant flags (fixed_split_size=4096, disable_split_kv=True). Mid and long mates pass; decode-like mates are a strict xfail because FA2 picks cta_tile_q from the batch-average packed query length (#2424), which #2830's fixed_cta_tile_q is meant to fix.

test_batch_prefill_tensor_cores_prefix_cache_tail (12 cases): a cold prefill of L tokens vs a tail-only query of t rows against the same L-long KV, the radix-cache-hit pattern from SGLang #46351. Tails 1, 4 and 16 change the tile and are strict xfails (#2424). Tails 37 and 200 keep the 128 tile but are a non-strict xfail: on B200 the tail is bit-exact whenever L - t is a multiple of 128 (36/36 probed configurations across fp16/bf16, group size 1 and 4, three seeds) and otherwise shows a one-fp32-ulp lse difference and a few output rows flipping one ulp, data dependent. Two aligned-prefix cases, (1024, 256) and (3700, 116), are asserted bit-exact and pass. The misaligned-prefix drift is not covered by #2830 and is left as a non-strict xfail so it is recorded without blocking CI; I will file it separately once the kv-loop bound in prefill.cuh is confirmed as the cause.

🔍 Related Issues

Refs #7937, #2424, #2830. Refs sgl-project/sglang#46351.

🚀 Pull Request Checklist

Thank you for contributing to FlashInfer! Before we review your pull request, please make sure the following items are complete.

✅ Pre-commit Checks

  • I have installed pre-commit by running pip install pre-commit (or used your preferred method).
  • I have installed the hooks with pre-commit install.
  • I have run the hooks manually with pre-commit run --all-files and fixed any reported issues.

🧪 Tests

  • Tests have been added or updated as needed.
  • All tests are passing (unittest, etc.).

pytest tests/attention/test_batch_invariant_fa2.py on B200 (CUDA 13.0): 2026 passed, 10 xfailed, 2 xpassed (the two tail_len=37 non-strict cases, which happen to be bit-exact with seed 0). The new cases alone: 10 passed, 10 xfailed, 2 xpassed. Not run on SM80/SM90/SM120; the aligned-prefix assertions and the strictness of the tile-rule xfails are verified on B200 only.

Reviewer Notes

The strict xfails are intentional: once #2830 lands and vLLM passes fixed_cta_tile_q, they should turn into assertions. If a non-Blackwell CI lane reports an XPASS on a strict case, flipping it to strict=False is the right first move rather than loosening the comparison.

🤖 Generated with Claude Code

kahyunnam and others added 2 commits November 3, 2026 21:45
…tch-invariance tests

The existing cases in tests/attention/test_batch_invariant_fa2.py use uniform batches (every request has the same qo_len and kv_len) and compare a prefix of the batch against a smaller batch of the same shape, so they never exercise a request whose batch-mates have different lengths.
This adds three parametrised cases with heterogeneous batches: tensor-core decode of a 3000-token request alone versus with short or long batch-mates under `disable_split_kv` or `fixed_split_size` (bitwise equal today), FA2 prefill of a 37-token request alone versus with decode-like, mid-size or long prefill mates under `disable_split_kv` and under vLLM's batch-invariant flags, and a prefix-cache tail (only the uncached tail of the query against the full KV) versus the cold prefill of the whole sequence.
The decode-like-mates prefill case and the tails whose packed length is at most 64 are strict xfails: FA2 picks `cta_tile_q` from the batch-average packed query length (flashinfer-ai#2424), so the tile and the bits change with the batch composition; flashinfer-ai#2830 adds the opt-in fixed tile.
Tails whose cached prefix length is not a multiple of 128 are a non-strict xfail: on B200 the LSE differs by one fp32 ulp in most such cases and isolated output rows flip one ulp even with an unchanged tile, while tails whose prefix length is a multiple of 128 are bitwise equal in every probed case, so those two are asserted.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… test

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 22 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 8 included reviews currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 4498f8eb-1f96-4b3b-a188-c24e8a94ddfe
Commits

Reviewing files that changed from the base of the PR and between 098f7c9 and 991fa05.

Files selected for processing: 1
  • tests/attention/test_batch_invariant_fa2.py
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

CodeRabbit Verify

  • Run CodeRabbit Verify to test the changes in this pull request.

@kahyunnam

Copy link
Copy Markdown
Member Author

@flashinfer-bot run tests/attention/test_batch_invariant_fa2.py

@kahyunnam

Copy link
Copy Markdown
Member Author

/bot run tests/attention/test_batch_invariant_fa2.py

@flashinfer-bot

Copy link
Copy Markdown
Collaborator

GitLab MR !2641 has been created, and the CI pipeline #79003457 is currently running. I'll report back once the pipeline job completes.

@flashinfer-bot

Copy link
Copy Markdown
Collaborator

[SUCCESS] Pipeline #79003457: 29/29 executed test jobs passed

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants