perf(text2semantic): pass only active KV cache prefix to SDPA - #1312
perf(text2semantic): pass only active KV cache prefix to SDPA#1312quantumxiaol wants to merge 2 commits into
Conversation
Whale-Dolphin
left a comment
There was a problem hiding this comment.
The active-prefix optimization is effective. I verified the current head on an NVIDIA H200 with S2-Pro FP16 through the official text2semantic CLI: eager warm throughput improved from 9.22 to 19.73 tok/s (2.14x), and torch.compile warm throughput improved from 68.60 to 113.33 tok/s (1.65x).
Before merging, please retain regression tests in the repository for the behavior this PR changes:
- Compare full-cache attention with active-prefix attention on a small deterministic fixture, with an explicit numerical tolerance and argmax assertion rather than requiring bitwise equality.
- Cover kv_len boundary validation and the prefill/decode progression, including the first decode position and the maximum valid prefix.
- Add an end-to-end autoregressive decode regression that exercises the real kv_len call chain and checks output shape, finite logits, and a defined token or distribution-level quality contract.
This is important because my FP16 comparison was not bitwise identical: the first five decode positions kept the same argmax, but the maximum absolute logit difference was 0.078125, and same-seed full generations diverged in 170 of 630 acoustic code elements after autoregressive propagation. This does not by itself indicate a quality regression, but the acceptable numerical and generation behavior needs to be encoded in tests so future SDPA or cache changes cannot silently break it.
|
Thanks for the independent H200 validation and the regression-test I added the requested regression coverage in commit
The end-to-end fixture uses Local result: The |
Is this PR adding new feature or fix a BUG?
Performance optimization for the native PyTorch autoregressive inference path.
Problem
During cached generation, the physical KV cache is preallocated at
max_seq_len. At every decode step, the current implementation expands thefull-capacity K/V tensors with
repeat_interleaveand passes the full K/Vsequence to SDPA. For S2-Pro, this means expanding and passing a key sequence
length of 32768 to SDPA even when only a few hundred positions have been
populated.
This describes the tensors supplied to SDPA; it does not assume how a
particular SDPA backend handles the masked, unpopulated tail internally.
Change
This change keeps the physical KV cache at full capacity but limits attention
to the active prefix:
kv_len=T;iuseskv_len=T+i+1;The regular full-sequence
forward()path used for training does not use theinference KV cache and is unchanged. The new slicing is gated by
self.kv_cache is not Noneand is exercised by cachedforward_generate()inference.
Benchmark results
S2-Pro, FP16, native PyTorch CLI inference, prompt length 234,
max_seq_len=32768. Throughput is the median of three warm samples:torch.compileCUDA environment: Quadro GV100 32 GB, PyTorch 2.8.0+cu128, Triton 3.4.0.
Generated lengths differed slightly because FP16/kernel differences can change
stochastic sampling trajectories, so throughput is normalized by the number of
generated tokens.
The memory values are decimal GB, matching the existing log calculation
torch.cuda.max_memory_reserved() / 1e9.The same change was also validated on Apple MPS (M4 Pro 48 GB, FP16,
max_seq_len=4096), where semantic generation improved from 4.08 to8.31 frames/s (2.04x). The MPS service metric and CUDA CLI tok/s are not
directly comparable; only their within-device A/B ratios are reported.
Cold compile time is excluded from the throughput comparison. The existing
Bandwidth achievedlog value is also excluded because it is derived frommodel size and tok/s rather than measured hardware DRAM bandwidth.
Correctness and compatibility validation
while the physical KV cache retains full capacity.
full-cache attention with a masked tail (
rtol=1e-5,atol=1e-6).torch.compilegeneration completed successfully.TORCH_LOGS=recompiles, the compiled active-KV path recompiled oncewhen
kv_lenfirst changed, not once per token; warm throughput remainedstable at approximately 32.7 tok/s.
and manually listened to; no audible regression was observed.
The benchmark results above were collected from
c4146e7.The current draft contains only the two production source changes; the
standalone correctness tests used for validation remain available in that
commit.
Is this pull request related to any issue? If yes, please link the issue.
Closes #1310