Skip to content

[Bugfix] Wrong Answer in PD disaggregation [P w/o SPS | D w/ SPS]#17212

Merged
ShangmingCai merged 3 commits intosgl-project:mainfrom
Ch3ngY1:feat/pdd_eagle_wrong_answer_fix
Jan 18, 2026
Merged

[Bugfix] Wrong Answer in PD disaggregation [P w/o SPS | D w/ SPS]#17212
ShangmingCai merged 3 commits intosgl-project:mainfrom
Ch3ngY1:feat/pdd_eagle_wrong_answer_fix

Conversation

@Ch3ngY1
Copy link
Contributor

@Ch3ngY1 Ch3ngY1 commented Jan 16, 2026

Motivation

After SGLang v0.5.2, when deploying a PD-disaggregated MHA model (e.g., GLM4.5 Air FP8), if speculative decoding parameters are not configured on the Prefill node but are configured on the Decode node, the service may return incorrect responses.

Modifications

Investigation showed that KV transfer caused incorrect Value cache on the Decode (D) node, so we updated the corresponding logic accordingly.

Accuracy Tests

Deploy Scripts:

# prefill
python3 -m sglang.launch_server \
    --model-path /dev/shm/GLM-4.5-Air-FP8 \
    --disaggregation-mode prefill \
    --tp-size 4 \
    --mem-fraction-static 0.8 \
    --kv-cache-dtype fp8_e4m3 \
    --host 0.0.0.0 \
    --attention-backend fa3 \
    --port 30001 \
    --chunked-prefill-size $((16384 * 4)) \
    # --speculative-algo EAGLE --speculative-num-steps 2 --speculative-eagle-topk 1 --speculative-num-draft-tokens 3
# decode
python3 -m sglang.launch_server \
    --model-path /dev/shm/GLM-4.5-Air-FP8 \
    --disaggregation-mode decode \
    --tp-size 4 \
    --mem-fraction-static 0.8 \
    --kv-cache-dtype fp8_e4m3 \
    --host 0.0.0.0 \
    --attention-backend fa3 \
    --port 30011 \
    --speculative-algo EAGLE --speculative-num-steps 2 --speculative-eagle-topk 1 --speculative-num-draft-tokens 3

Running evaluation with

python benchmark/gsm8k/bench_sglang.py     --host http://127.0.0.1     --port 30000     --num-questions 1319     --parallel 256

Results

# P with Speculative Decoding
100%|████████████████████████████████████████████████████████████| 1319/1319 [00:56<00:00, 23.24it/s]
Accuracy: 0.920
Invalid: 0.000
Latency: 57.106 s
Output throughput: 2379.669 token/s

# P without Speculative Decoding without this PR
100%|████████████████████████████████████████████████████████████| 1319/1319 [04:54<00:00,  4.48it/s]
Accuracy: 0.011
Invalid: 0.313
Latency: 294.957 s
Output throughput: 2248.717 token/s

# P without Speculative Decoding with this PR
100%|████████████████████████████████████████████████████████████| 1319/1319 [01:02<00:00, 21.20it/s]
Accuracy: 0.916
Invalid: 0.000
Latency: 62.603 s
Output throughput: 2246.093 token/s

Benchmarking and Profiling

The bench serving results for the multi-turn chat are as follows. We first use the first 10,000 samples for KV-cache warmup, and then benchmark the remaining 10,000 samples. The results are shown below.

  • Device = H200 * 8
  • P = 2xTP2
  • D = 2xTP2
# Prefill with speculative decoding: 
# Round1 --> Sample ID [0, 10000)

============ Serving Benchmark Result ============
Backend:                                 vllm      
Traffic request rate:                    40.0      
Max request concurrency:                 not set   
Successful requests:                     10000     
Benchmark duration (s):                  282.80    
Total input tokens:                      25873815  
Total generated tokens:                  1876513   
Total generated tokens (retokenized):    1869016   
Request throughput (req/s):              35.36     
Input token throughput (tok/s):          91490.07  
Output token throughput (tok/s):         6635.37   
Total token throughput (tok/s):          98125.43  
Concurrency:                             784.53    
----------------End-to-End Latency----------------
Mean E2E Latency (ms):                   22186.77  
Median E2E Latency (ms):                 23569.19  
---------------Time to First Token----------------
Mean TTFT (ms):                          19182.07  
Median TTFT (ms):                        20462.93  
P99 TTFT (ms):                           26864.65  
---------------Inter-Token Latency----------------
Mean ITL (ms):                           34.28     
Median ITL (ms):                         33.80     
P95 ITL (ms):                            43.10     
P99 ITL (ms):                            62.13     
Max ITL (ms):                            992.52    
Mean TPOT (ms):                          16.09     
Median TPOT (ms):                        16.28     
P95 TPOT (ms):                           18.65     
P99 TPOT (ms):                           21.74     
Max TPOT (ms):                           34.69     
==================================================

# Round2 --> Sample ID [10000, 20000)

============ Serving Benchmark Result ============
Backend:                                 vllm      
Traffic request rate:                    40.0      
Max request concurrency:                 not set   
Successful requests:                     10000     
Benchmark duration (s):                  275.27    
Total input tokens:                      25997995  
Total generated tokens:                  1876513   
Total generated tokens (retokenized):    1868842   
Request throughput (req/s):              36.33     
Input token throughput (tok/s):          94446.92  
Output token throughput (tok/s):         6817.10   
Total token throughput (tok/s):          101264.02 
Concurrency:                             195.73    
----------------End-to-End Latency----------------
Mean E2E Latency (ms):                   5387.78   
Median E2E Latency (ms):                 5333.12   
---------------Time to First Token----------------
Mean TTFT (ms):                          2439.15   
Median TTFT (ms):                        2320.33   
P99 TTFT (ms):                           4927.51   
---------------Inter-Token Latency----------------
Mean ITL (ms):                           33.58     
Median ITL (ms):                         33.55     
P95 ITL (ms):                            41.72     
P99 ITL (ms):                            53.83     
Max ITL (ms):                            481.44    
Mean TPOT (ms):                          15.79     
Median TPOT (ms):                        16.04     
P95 TPOT (ms):                           17.97     
P99 TPOT (ms):                           18.68     
Max TPOT (ms):                           20.51     
==================================================
# with this PR, Prefill without speculative decoding: 
# Round1 --> Sample ID [0, 10000)

============ Serving Benchmark Result ============
Backend:                                 vllm      
Traffic request rate:                    40.0      
Max request concurrency:                 not set   
Successful requests:                     10000     
Benchmark duration (s):                  272.63    
Total input tokens:                      25873815  
Total generated tokens:                  1876533   
Total generated tokens (retokenized):    1845595   
Request throughput (req/s):              36.68     
Input token throughput (tok/s):          94905.18  
Output token throughput (tok/s):         6883.12   
Total token throughput (tok/s):          101788.30 
Concurrency:                             235.95    
----------------End-to-End Latency----------------
Mean E2E Latency (ms):                   6432.56   
Median E2E Latency (ms):                 4249.37   
---------------Time to First Token----------------
Mean TTFT (ms):                          3562.08   
Median TTFT (ms):                        1218.30   
P99 TTFT (ms):                           15838.37  
---------------Inter-Token Latency----------------
Mean ITL (ms):                           35.46     
Median ITL (ms):                         34.48     
P95 ITL (ms):                            45.19     
P99 ITL (ms):                            71.50     
Max ITL (ms):                            3195.92   
Mean TPOT (ms):                          15.47     
Median TPOT (ms):                        15.12     
P95 TPOT (ms):                           20.75     
P99 TPOT (ms):                           24.14     
Max TPOT (ms):                           37.20     
==================================================

# Round2 --> Sample ID [10000, 20000)

============ Serving Benchmark Result ============
Backend:                                 vllm      
Traffic request rate:                    40.0      
Max request concurrency:                 not set   
Successful requests:                     10000     
Benchmark duration (s):                  271.78    
Total input tokens:                      25997995  
Total generated tokens:                  1876323   
Total generated tokens (retokenized):    1664673   
Request throughput (req/s):              36.79     
Input token throughput (tok/s):          95658.17  
Output token throughput (tok/s):         6903.83   
Total token throughput (tok/s):          102561.99 
Concurrency:                             131.76    
----------------End-to-End Latency----------------
Mean E2E Latency (ms):                   3580.96   
Median E2E Latency (ms):                 3495.13   
---------------Time to First Token----------------
Mean TTFT (ms):                          448.86    
Median TTFT (ms):                        423.63    
P99 TTFT (ms):                           940.30    
---------------Inter-Token Latency----------------
Mean ITL (ms):                           36.30     
Median ITL (ms):                         34.45     
P95 ITL (ms):                            49.14     
P99 ITL (ms):                            77.42     
Max ITL (ms):                            3771.21   
Mean TPOT (ms):                          16.94     
Median TPOT (ms):                        16.28     
P95 TPOT (ms):                           23.44     
P99 TPOT (ms):                           28.65     
Max TPOT (ms):                           41.04     
==================================================


deploy TTFT-R1 TPOT-R1 TTFT-R2 TPOT-R2
P with SPS 19182.07 16.09 2439.15 15.79
P without SPS 3562.08 15.47 448.86 16.94

Checklist

Review Process

  1. Ping Merge Oncalls to start the PR flow. See the PR Merge Process.
  2. Get approvals from CODEOWNERS and other reviewers.
  3. Trigger CI tests with comments or contact authorized users to do so.
    • /tag-run-ci-label, /rerun-failed-ci, /tag-and-rerun-ci
  4. After green CI and required approvals, ask Merge Oncalls to merge.

…speculative decoding while D w/ speculative decoding.
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @Ch3ngY1, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request resolves a critical bug affecting PD-disaggregated SGLang deployments where speculative decoding is active solely on the decode stage. By correcting the KV cache transfer logic, particularly for Value cache pointers, the change ensures the model produces accurate responses and maintains performance, as demonstrated by the provided accuracy and benchmark results.

Highlights

  • Bug Fix for PD-Disaggregation with Speculative Decoding: Addresses an issue in SGLang v0.5.2 where PD-disaggregated MHA models produced incorrect responses when speculative decoding was enabled only on the Decode node. The problem stemmed from incorrect Value cache handling during KV transfer.
  • KV Cache Transfer Logic Update: Modified the get_mha_kv_ptrs_with_pp function in conn.py to correctly index dst_v_ptrs when the Decode node has more KV layers than the Prefill node (e.g., due to draft model KV). This prevents an empty Value Cache and ensures accurate data transfer.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

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 addresses a critical bug in PD disaggregation where incorrect responses were returned when the Decode node used speculative decoding while the Prefill node did not. The root cause was identified as an incorrect Value cache transfer. The fix introduces a specific logic branch to handle this scenario by correctly calculating the offsets for the destination KV pointers, ensuring the Value cache is populated correctly. The provided accuracy tests and benchmarks demonstrate that the fix is effective, significantly improving accuracy from 0.011 to 0.916 in the problematic configuration. The change is well-targeted and appears correct. I have no further comments.

@ShangmingCai ShangmingCai self-assigned this Jan 16, 2026
@ShangmingCai
Copy link
Collaborator

/rerun-stage unit-test-backend-8-gpu-h20

@github-actions
Copy link
Contributor

✅ Triggered unit-test-backend-8-gpu-h20 to run independently (skipping dependencies).

@github-actions
Copy link
Contributor

🔗 View workflow run

@ShangmingCai
Copy link
Collaborator

/tag-and-rerun-ci

@ShangmingCai
Copy link
Collaborator

image PDxPP-related tests have passed. Let me run some basic tests, if CI is flaky, we can bypass since this is a clear PR with simple change.

@ShangmingCai
Copy link
Collaborator

image All related tests has passed. GB200 failure is irrelevant.

@ShangmingCai ShangmingCai merged commit bb6055b into sgl-project:main Jan 18, 2026
479 of 515 checks passed
DotSlash-A pushed a commit to DotSlash-A/sglang that referenced this pull request Jan 19, 2026
* fix(ci): recover from corrupted MMMU parquet cache (sgl-project#17256)

* [diffusion] feat: support default 4-step inference for Flux2-Klein distilled models (sgl-project#17225)

Signed-off-by: Lancer <maruixiang6688@gmail.com>

* Add runner utilization report workflow (sgl-project#17234)

* cli: support sglang version (sgl-project#17250)

* Use swa radix cache and memory pool for gpt-oss model (sgl-project#17261)

* [VLM][Reland] Refactor load_mm_data to improve performance (sgl-project#16152)

Co-authored-by: luoyuan.luo <luoyuan.luo@antgroup.com>

* [Tiny] Improve docs (sgl-project#17264)

* [diffusion] fix: set guidance_scale default to None (sgl-project#17182)

* Tiny fix comment typo (sgl-project#17287)

* [SPEC_V2] Enable cudagraph draft_extend for trtllm_mla_backend and Acclen Fix for DP under cudagraph mode (sgl-project#16974)

* Add kl test for swa radix cache (sgl-project#17281)

* fix: Handle multiple named chat templates in HuggingFace tokenizers (sgl-project#17236)

Signed-off-by: Xinyuan Tong <xinyuantong.cs@gmail.com>

* Move radix cache related tests (sgl-project#17295)

* [Refactor] Add `-fp4-gemm-backend` to replace `SGLANG_FLASHINFER_FP4_GEMM_BACKEND` (sgl-project#16534)

Co-authored-by: Vincent Zhong <207368749+vincentzed@users.noreply.github.com>

* [Bugfix] Fix PD accuracy when MTP is not configured on the prefill node (sgl-project#17212)

Co-authored-by: Shangming Cai <csmthu@gmail.com>

* [Diffusion] Apply jit qk_norm to flux1 (sgl-project#17296)

* [Refactor] Split out deepseek v2 weight loader function into mixin (sgl-project#16649)

* [NPU]Support GPT-OSS for NPU (sgl-project#14197)

* [jit-kernel] Add CuTe DSL GDN Decode Kernel (sgl-project#15631)

Co-authored-by: Jinyan Chen <jinyanc@nvidia.com>

* [GLM 4.7] Add RTX 6000 Pro aka sm120 (sgl-project#17235)

Co-authored-by: root <root@ubuntu-nvidia.localdomain>

* Update CODEOWNERS for multimodal_gen (sgl-project#17308)

Co-authored-by: Xiaoyu Zhang <35585791+BBuf@users.noreply.github.com>

* [Feature] overlap LoRA weight loading with compute (sgl-project#15512)

* [PD] Optimize MHA models pp util calculation logic (sgl-project#17306)

* [Minor] Correct sglang version when installing from source (sgl-project#17315)

* Use dsv3 optimized routing `fused_topk_deepseek` instead of `moe_fused_gate` (sgl-project#15347)

* [DeepSeek v3.2] Opt MTP decode cuda batch sizes and nsa implementation (sgl-project#16961)

* Update code sync scripts (sgl-project#17319)

* [Auto Sync] Update tokenizer_manager.py (20260119) (sgl-project#17317)

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* support new qwen3_coder_detector (sgl-project#16744)

Co-authored-by: liugaoji.lgj <liugaoji.lgj@alibaba-inc.com>

* Fix kernel selection in biased_grouped_topk_gpu (sgl-project#17325)

* KV Cache Events with Attention DP bug fix (sgl-project#16030) (sgl-project#16412)

* [Perf] fuse q, k norm for Flux2Attention (sgl-project#17241)

Co-authored-by: Minglei Zhu <zminglei@linkedin.com>

* [CI] Add partition to stage-b-test-large-1-gpu (11->12) (sgl-project#17245)

* fix(ci): rate limit and permission errors in trace publishing (sgl-project#17238)

* Revert "[Perf] fuse q, k norm for Flux2Attention (sgl-project#17241)" (sgl-project#17332)

* Migrate performance, accuracy, and quantization tests to CI registry (sgl-project#17177)

Co-authored-by: Kangyan-Zhou <zky314343421@gmail.com>

* Inclusion of nvfp4 blockscale in EPLB Rebalance (sgl-project#17158)

* [Refactor] Set `fp4-gemm-backend=auto` on SM100 and rename `fp4-gemm-backend` with `flashinfer_` prefix (sgl-project#17309)

* [Diffusion] Apply qknorm to flux2 and apply lightx2v rms_norm_one_pass kernel(without residual) (sgl-project#17305)

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* Fix v32 continue_final_message not work (sgl-project#16567)

* Evict swa kv cache during decoding (sgl-project#17220)

* [RadixTree][1/N Refactor]: Support unified match_prefix params (sgl-project#17142)

Co-authored-by: yizhang2077 <1109276519@qq.com>
Co-authored-by: pansicheng <sicheng.pan.chn@gmail.com>

* [AMD CI] Migrate and Add More Testcases (sgl-project#17116)

Co-authored-by: yctseng0211 <yctseng@amd.com>

* [AMD] CI - add partitions for stage-b-test-small-1-gpu-amd (sgl-project#17345)

* Restore deepseek_v2.py to main's code, except the utils

* Ran `pre-commit`

---------

Signed-off-by: Lancer <maruixiang6688@gmail.com>
Signed-off-by: Xinyuan Tong <xinyuantong.cs@gmail.com>
Co-authored-by: Hudson Xing <1277646412@qq.com>
Co-authored-by: Lancer <402430575@qq.com>
Co-authored-by: Alison Shao <54658187+alisonshao@users.noreply.github.com>
Co-authored-by: Mick <mickjagger19@icloud.com>
Co-authored-by: Ke Bao <ispobaoke@gmail.com>
Co-authored-by: Yuan Luo <yuan.luo@hotmail.com>
Co-authored-by: luoyuan.luo <luoyuan.luo@antgroup.com>
Co-authored-by: Mohammad Miadh Angkad <mangkad.bsdsba2027@aim.edu>
Co-authored-by: Changyi Yang <112288487+ChangyiYang@users.noreply.github.com>
Co-authored-by: YAMY <74099316+YAMY1234@users.noreply.github.com>
Co-authored-by: Xinyuan Tong <115166877+JustinTong0323@users.noreply.github.com>
Co-authored-by: b8zhong <b8zhong@uwaterloo.ca>
Co-authored-by: Vincent Zhong <207368749+vincentzed@users.noreply.github.com>
Co-authored-by: Ch3ngY1 <91232537+Ch3ngY1@users.noreply.github.com>
Co-authored-by: Shangming Cai <csmthu@gmail.com>
Co-authored-by: Xiaoyu Zhang <35585791+BBuf@users.noreply.github.com>
Co-authored-by: Jerry Ji <jerryjilol@gmail.com>
Co-authored-by: Todobe <43903496+Todobe@users.noreply.github.com>
Co-authored-by: Jinyan Chen <93358689+liz-badada@users.noreply.github.com>
Co-authored-by: Jinyan Chen <jinyanc@nvidia.com>
Co-authored-by: Koushik Dutta <koush@koushikdutta.com>
Co-authored-by: root <root@ubuntu-nvidia.localdomain>
Co-authored-by: Glen Liu <62917497+glenliu21@users.noreply.github.com>
Co-authored-by: Baizhou Zhang <sobereddiezhang@gmail.com>
Co-authored-by: Lee Nau <lnau@nvidia.com>
Co-authored-by: Yongfei Xu <xuyongfei.xyf@antgroup.com>
Co-authored-by: Lianmin Zheng <lianminzheng@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Gaoji Liu <34803073+attack204@users.noreply.github.com>
Co-authored-by: liugaoji.lgj <liugaoji.lgj@alibaba-inc.com>
Co-authored-by: yudian0504 <138860534+yudian0504@users.noreply.github.com>
Co-authored-by: Kartik Ramesh <kartikx2000@gmail.com>
Co-authored-by: Minglei Zhu <mingleizhu1122@gmail.com>
Co-authored-by: Minglei Zhu <zminglei@linkedin.com>
Co-authored-by: Kangyan-Zhou <zky314343421@gmail.com>
Co-authored-by: Shu Wang <shuw@nvidia.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: ybyang <10629930+whybeyoung@users.noreply.github.com>
Co-authored-by: zhangheng <hzh0425@apache.org>
Co-authored-by: yizhang2077 <1109276519@qq.com>
Co-authored-by: pansicheng <sicheng.pan.chn@gmail.com>
Co-authored-by: Bingxu Chen <Bingxu.Chen@amd.com>
Co-authored-by: yctseng0211 <yctseng@amd.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants