Skip to content

[Bug Fix] Preserve decode state across retract-resume of GLM-5.1 - #23346

Merged
ShangmingCai merged 8 commits into
sgl-project:mainfrom
zRzRzRzRzRzRzR:pd-retract-resume-state
May 7, 2026
Merged

ShangmingCai merged 8 commits into
sgl-project:mainfrom
zRzRzRzRzRzRzR:pd-retract-resume-state

Conversation

@zRzRzRzRzRzRzR

Copy link
Copy Markdown
Contributor

PD Disaggregated Decode: Fix State Aliasing on Retract-Resume

GLM-5.1 on PD-disaggregated decode hits three related state-aliasing bugs when a retracted req resumes. Same pattern each time: a slot is freed and reused, but the original owner still references it. Resume reads foreign data and emits garbled output, which can further leak via the radix tree.

  1. MetadataBuffers.get_buf

Return .clone() instead of slice views. The shared slot gets overwritten by the next set_buf; retract-resumed reqs run process_prebuilt much later and end up seeding EAGLE with foreign hidden states and topk.

  1. DecodePreallocQueue._pre_alloc

Trim fill_ids so its length matches fill_len. The last sampled token's KV is never offloaded but gets re-fed on resume, causing a read past the valid req_to_token range. The stale index leaked into the radix tree and corrupted prefix-matched reqs. Added an assert for the invariant.

  1. NSATokenToKVPool

GLM-5.1 carries an extra index_k_with_scale_buffer alongside kv_buffer. Override get_cpu_copy / load_cpu_copy to offload and restore both. Previously only KV was saved, so resume left foreign index/scale in place and NSA sparse indexing picked wrong keys. Also override _clear_buffers to release the extra buffer on teardown, matching sibling KVCache subclasses.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces several improvements to disaggregated execution, including correct metadata population for fill_ids, the addition of .clone() when retrieving buffers to ensure data integrity, and the implementation of CPU offloading for NSA-specific buffers. A review comment identifies an inconsistency in the get_cpu_copy return type within NSATokenToKVPool compared to other pool implementations, which could lead to issues if the system expects a standard list-of-lists format.

Comment on lines +1966 to +1989
def get_cpu_copy(self, indices):
# NSA keeps a page-indexed index_k_with_scale_buffer alongside kv_buffer.
# Retract frees the slots/pages and they get reused by other reqs'
# set_index_k_scale_buffer, so we must offload it here too -- otherwise
# resume restores kv_buffer but leaves foreign index/scale in place and
# NSA attention reads garbage at those token positions.
kv_cache_cpu = super().get_cpu_copy(indices)

page_indices = indices[:: self.page_size] // self.page_size
torch.cuda.synchronize()
index_k_cpu = []
chunk_size = self.cpu_offloading_chunk_size
page_chunk_size = max(1, chunk_size // self.page_size)
for layer_id in range(self.layer_num):
index_k_cpu.append([])
for i in range(0, len(page_indices), page_chunk_size):
chunk_page_indices = page_indices[i : i + page_chunk_size]
idx_cpu = self.index_k_with_scale_buffer[layer_id][
chunk_page_indices
].to("cpu", non_blocking=True)
index_k_cpu[-1].append(idx_cpu)
torch.cuda.synchronize()

return {"kv": kv_cache_cpu, "index_k": index_k_cpu}

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.

medium

The return type of get_cpu_copy in NSATokenToKVPool is changed to a dictionary, whereas the base class KVCache and sibling implementations (like MHATokenToKVPool and MLATokenToKVPool) return a List[List[Tensor]]. While load_cpu_copy is updated to handle this dictionary, this inconsistency might cause issues if other parts of the system expect the standard list-of-lists format for CPU-offloaded KV cache data. Consider if a more unified multi-buffer offloading interface should be introduced in the base class.

@ShangmingCai ShangmingCai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

@ShangmingCai

Copy link
Copy Markdown
Collaborator

/tag-and-rerun-ci

@github-actions github-actions Bot added the run-ci CI: run the baseline test suite on this PR label Apr 21, 2026
@ShangmingCai

Copy link
Copy Markdown
Collaborator

/rerun-stage stage-c-test-8-gpu-h20

@github-actions

Copy link
Copy Markdown
Contributor

✅ Triggered stage-c-test-8-gpu-h20 to run independently (skipping dependencies). View workflow run

@ShangmingCai

Copy link
Copy Markdown
Collaborator

/rerun-stage stage-c-test-8-gpu-h20

@github-actions

Copy link
Copy Markdown
Contributor

✅ Triggered stage-c-test-8-gpu-h20 to run independently (skipping dependencies). View workflow run

@ShangmingCai

Copy link
Copy Markdown
Collaborator

/tag-and-rerun-ci

@ShangmingCai

Copy link
Copy Markdown
Collaborator

/rerun-failed-ci

@JustinTong0323

Copy link
Copy Markdown
Collaborator

/rerun-failed-ci

2 similar comments
@JustinTong0323

Copy link
Copy Markdown
Collaborator

/rerun-failed-ci

@ShangmingCai

Copy link
Copy Markdown
Collaborator

/rerun-failed-ci

@ShangmingCai

Copy link
Copy Markdown
Collaborator

The fill_len logic has been fixed by the decode radix cache PR: f589547

Due to the conflict, I have fixed it to adopt the incoming change from main, which is more robust.

@ShangmingCai

Copy link
Copy Markdown
Collaborator

/rerun-stage stage-c-test-8-gpu-h20

@github-actions

github-actions Bot commented May 6, 2026

Copy link
Copy Markdown
Contributor

✅ Triggered stage-c-test-8-gpu-h20 to run independently (skipping dependencies). View workflow run

@ShangmingCai

Copy link
Copy Markdown
Collaborator

/rerun-failed-ci

@ShangmingCai

Copy link
Copy Markdown
Collaborator

/rerun-test test/registered/disaggregation/test_disaggregation_basic.py

@github-actions

github-actions Bot commented May 7, 2026

Copy link
Copy Markdown
Contributor

✅ 2-gpu-h100 (1 test): View workflow run

cd test/ && python3 registered/disaggregation/test_disaggregation_basic.py

@ShangmingCai
ShangmingCai merged commit ec45603 into sgl-project:main May 7, 2026
317 of 381 checks passed
LLThomas pushed a commit to LLThomas/sglang that referenced this pull request May 8, 2026
@zRzRzRzRzRzRzR
zRzRzRzRzRzRzR deleted the pd-retract-resume-state branch May 10, 2026 19:39
Chronostasys pushed a commit to MindLab-Research/sglang that referenced this pull request Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

run-ci CI: run the baseline test suite on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants