Repository navigation
[Fix] disaggregation: Clean-up and optimize the KV checksum implementation - #39729
Conversation
Review round 2All four points were right; I verified each against the code before fixing. 1. I checked the other two helpers for the same shape: 2. No true-positive e2e — confirmed. Added 3. The all-reduce never ran multi-rank — confirmed. 4. Unconditional collective per iteration — confirmed, and fixed with a rank-invariant gate. A new Your four "dropped" items match what I found as well; the two-page-size one in particular — Still unverified by me: everything that needs a GPU. Lint is green; the e2e and CUDA unit tests need a runner. |
Review round 3All three confirmed and fixed. Two of them are the same failure mode as rounds 1-2, which is worth naming: three separate times now I have added a test that could not fail. 1. The in-CI raise contradicted both injection tests — confirmed. Took your first option: suppress the raise only while the injector is active ( 2. 3. Page id used as a token slot — confirmed. The K/V buffers are Still unverified by me: anything needing a GPU. Lint is green. |
5ceda42 to
b1a7b20
Compare
8192893 to
5bb5de5
Compare
5bb5de5 to
85adabf
Compare
85adabf to
77bc982
Compare
Follow-ups to #39500: all-reduce the mismatch decision across attention TP ranks, verify once rather than after retraction, ship a layout signature beside the digest so an incomparable prefill is skipped instead of aborted, refuse the decode-side radix cache, bound the aux send loops when one engine has an extra metadata buffer, and reset the checksum slot with the bootstrap room. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
77bc982 to
56a6111
Compare
…s clear_slot and aux pointers The KV checksum follow-up calls MetadataBuffers.clear_slot and reads the peer's aux pointer count on Mooncake registration; three CPU unit files built fakes without them and failed 9 tests in base-a-test-cpu. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
|
/tag-and-rerun-ci |
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
… aux pointers _add_remote_peer now checks the peer's metadata-buffer count on the prefill side, which reads disaggregation_mode and kv_args.aux_data_ptrs. The object.__new__ fake in test_tp_mismatch_requires_matching_token_geometry set neither, so it raised AttributeError. Make it a prefill with no aux buffers, which matches the empty dst_aux_mem_descs it registers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e test _handle_kv_checksum_mismatch aborts with "KV checksum mismatch", which has no "abort" in it, so the predicate borrowed from the chunked-prefill abort test classified every injected mismatch as a plain 500 and the test failed on the first one. Match the checksum message instead. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
/rerun-test test/registered/disaggregation/test_disaggregation_kv_checksum.py |
|
🚀 |
Motivation
With
--disaggregation-enable-kv-checksumon, a mismatch on one TP rank hangs the decode engine, and healthy traffic is aborted on several supported configurations. This PR fixes those paths so the flag can be turned on.Modifications
All-reduce the mismatch decision. Corruption is per rank, so a rank-local drop left the TP peers building different batches and hanging on the next collective. The drop set is MAX-reduced over
attn_tp_cpu_groupwithall_reduce_flagsbefore any request is aborted.Verify once. The digest covers whole pages, and after a retraction the restored row's last page holds tokens the decode wrote, so re-verifying on resume was a false mismatch at
page_size > 1. A request is digested when it first enters a batch and its expectation is then cleared.Ship a layout signature with the digest.
kv_layout_signature(kv_args)hashes the page size and the per-page KV and state item lengths; the prefill writes it into slot 1 of thekv_checksumrow. A prefill with another TP width or a PP stage is admitted unverified with one warning instead of aborting every request. A prefill that wrote no digest is skipped silently.Refuse the decode-side radix cache. The digest covers
[0, seq_len)while the prefill then sends only[decode_prefix_len, seq_len), so every prefix hit looks like corruption. The decode logs once at startup and runs without the checksum.Survive a metadata buffer count mismatch. The aux buffers pair positionally, and the Mooncake and NIXL send loops walked the decode's list (Mori's TCP loop the prefill's), so an engine with one more buffer than its peer was an
IndexErrorin a transfer thread. The loops stop at the shorter list and the prefill logs an error at registration naming the optional buffers that can differ. The decode resets the checksum row together with the bootstrap room when a metadata slot is freed, so a later occupant whose prefill writes no digest cannot read the previous one.Test hook.
SGLANG_TEST_DISAGG_KV_CHECKSUM_MISMATCH_PROBflips a decode rank's computed digest with that probability, drawn from a per-rank generator (the globalrandomis seeded identically on every TP rank, so the ranks would otherwise inject the same requests). The in-CI raise is suppressed while it is set.Accuracy Tests
test/registered/unit/disaggregation/test_kv_checksum.py: new cases for the signature, the slot reset, verify-once, the reduced drop set, the signature in the prefill's metadata write, and the injector not tripping the in-CI raise. The CPU-only cases pass on a CPU box; the CUDA cases need a runner.test/registered/disaggregation/test_disaggregation_kv_checksum.py(new,base-c/4-gpu-h100): TP2 on both sides, because at TP1 the reduce is a no-op. Mismatches injected per decode rank at p=0.3 over 16 requests with a multi-chunk prompt: some must abort, some must complete, and both engines must stay up.No GPU here; the CUDA unit cases and the e2e test need a runner.
Checklist
🤖 Generated with Claude Code
CI States
Latest PR Test (Base): 🚫 Run #40182804723
Latest PR Test (Extra): ❌ Run #40182804764
Latest PR Test (AMD ROCm 10): 🚫 Run #40182804728